[cfe][InternalNodes] Add InternalSuperInitializer

This adds InternalSuperInitializer as the node created from the body builder.

This prepares for detaching the internal ArgumentsImpl node from the public Arguments node.

Change-Id: I34e33395ac24b4ef7172b4b890a3736b7c6b9477
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/465901
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fragment/constructor/declaration.dart b/pkg/front_end/lib/src/fragment/constructor/declaration.dart
index 4241b24..8e5e0a7 100644
--- a/pkg/front_end/lib/src/fragment/constructor/declaration.dart
+++ b/pkg/front_end/lib/src/fragment/constructor/declaration.dart
@@ -24,6 +24,7 @@
 import '../../builder/type_builder.dart';
 import '../../builder/variable_builder.dart';
 import '../../kernel/body_builder_context.dart';
+import '../../kernel/internal_ast.dart';
 import '../../kernel/kernel_helper.dart';
 import '../../kernel/resolver.dart';
 import '../../kernel/type_algorithms.dart';
@@ -461,10 +462,18 @@
       return null;
     }
 
-    if (initializers != null &&
-        initializers.isNotEmpty &&
-        initializers.last is SuperInitializer) {
-      superTarget = (initializers.last as SuperInitializer).target;
+    Initializer? lastInitializer =
+        initializers != null && initializers.isNotEmpty
+        ? initializers.last
+        : null;
+    // TODO(johnniwinther): This method is currently called with initializers
+    // in an uninferred state for non-const constructors with super parameters
+    // and in an inferred state for const constructors with super parameters.
+    // Avoid this inconsistency by calling this before inference.
+    if (lastInitializer is SuperInitializer) {
+      superTarget = lastInitializer.target;
+    } else if (lastInitializer is InternalSuperInitializer) {
+      superTarget = lastInitializer.target;
     } else {
       MemberLookupResult? result = superclassBuilder.findConstructorOrFactory(
         "",
diff --git a/pkg/front_end/lib/src/kernel/body_builder.dart b/pkg/front_end/lib/src/kernel/body_builder.dart
index b2e4370..7f168ca 100644
--- a/pkg/front_end/lib/src/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/kernel/body_builder.dart
@@ -656,7 +656,7 @@
       return node.buildSimpleRead();
     } else if (node is Expression) {
       return node;
-    } else if (node is SuperInitializer) {
+    } else if (node is InternalSuperInitializer) {
       return buildProblem(
         message: cfe.codeSuperAsExpression,
         fileUri: uri,
@@ -9949,7 +9949,7 @@
   Initializer buildSuperInitializer(
     bool isSynthetic,
     Constructor constructor,
-    Arguments arguments, [
+    ArgumentsImpl arguments, [
     int charOffset = -1,
   ]) {
     if (_context.isConstConstructor && !constructor.isConst) {
@@ -9960,9 +9960,11 @@
       );
     }
     _needsImplicitSuperInitializer = false;
-    return new SuperInitializer(constructor, arguments)
-      ..fileOffset = charOffset
-      ..isSynthetic = isSynthetic;
+    return new InternalSuperInitializer(
+      constructor,
+      arguments,
+      isSynthetic: isSynthetic,
+    )..fileOffset = charOffset;
   }
 
   @override
diff --git a/pkg/front_end/lib/src/kernel/internal_ast.dart b/pkg/front_end/lib/src/kernel/internal_ast.dart
index 8e0da3f..9a91006 100644
--- a/pkg/front_end/lib/src/kernel/internal_ast.dart
+++ b/pkg/front_end/lib/src/kernel/internal_ast.dart
@@ -4997,3 +4997,40 @@
     return "InternalRedirectingInitializer(${toStringInternal()})";
   }
 }
+
+class InternalSuperInitializer extends InternalInitializer {
+  final Constructor target;
+  ArgumentsImpl arguments;
+
+  @override
+  final bool isSynthetic;
+
+  InternalSuperInitializer(
+    this.target,
+    this.arguments, {
+    required this.isSynthetic,
+  }) {
+    arguments.parent = this;
+  }
+
+  @override
+  InitializerInferenceResult acceptInference(InferenceVisitorImpl visitor) {
+    return visitor.visitInternalSuperInitializer(this);
+  }
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  void toTextInternal(AstPrinter printer) {
+    printer.write('super');
+    if (target.name.text.isNotEmpty) {
+      printer.write('.');
+      printer.write(target.name.text);
+    }
+    printer.writeArguments(arguments, includeTypeArguments: false);
+  }
+
+  @override
+  String toString() {
+    return "InternalSuperInitializer(${toStringInternal()})";
+  }
+}
diff --git a/pkg/front_end/lib/src/kernel/resolver.dart b/pkg/front_end/lib/src/kernel/resolver.dart
index 05d7407..f5ebfb2 100644
--- a/pkg/front_end/lib/src/kernel/resolver.dart
+++ b/pkg/front_end/lib/src/kernel/resolver.dart
@@ -1183,7 +1183,7 @@
         );
       }
       Initializer last = initializers.last;
-      if (last is SuperInitializer) {
+      if (last is InternalSuperInitializer) {
         if (bodyBuilderContext.isEnumClass) {
           initializers[initializers.length - 1] = _buildInvalidInitializer(
             problemReporting.buildProblem(
@@ -1196,8 +1196,7 @@
           )..parent = last.parent;
           needsImplicitSuperInitializer = false;
         } else if (libraryFeatures.superParameters.isEnabled) {
-          ArgumentsImpl arguments = last.arguments as ArgumentsImpl;
-
+          ArgumentsImpl arguments = last.arguments;
           if (positionalSuperParametersAsArguments != null) {
             if (arguments.positional.isNotEmpty) {
               problemReporting.addProblem(
@@ -1524,38 +1523,28 @@
               fileUri,
             );
           }
-          initializer = new SuperInitializer(superTarget, arguments)
-            ..fileOffset = bodyBuilderContext.memberNameOffset
-            ..isSynthetic = true;
+          initializer = new InternalSuperInitializer(
+            superTarget,
+            arguments,
+            isSynthetic: true,
+          )..fileOffset = bodyBuilderContext.memberNameOffset;
           needsImplicitSuperInitializer = false;
         }
       }
-      if (libraryFeatures.superParameters.isEnabled) {
-        InitializerInferenceResult inferenceResult = bodyBuilderContext
-            .inferInitializer(
-              typeInferrer: context.typeInferrer,
-              fileUri: fileUri,
-              initializer: initializer,
-            );
-        if (!bodyBuilderContext.addInferredInitializer(
-          compilerContext,
-          problemReporting,
-          inferenceResult,
-          fileUri,
-        )) {
-          // Erroneous initializer, implicit super call is not needed.
-          needsImplicitSuperInitializer = false;
-        }
-      } else {
-        if (!bodyBuilderContext.addInitializer(
-          compilerContext,
-          problemReporting,
-          initializer,
-          fileUri,
-        )) {
-          // Erroneous initializer, implicit super call is not needed.
-          needsImplicitSuperInitializer = false;
-        }
+      InitializerInferenceResult inferenceResult = bodyBuilderContext
+          .inferInitializer(
+            typeInferrer: context.typeInferrer,
+            fileUri: fileUri,
+            initializer: initializer,
+          );
+      if (!bodyBuilderContext.addInferredInitializer(
+        compilerContext,
+        problemReporting,
+        inferenceResult,
+        fileUri,
+      )) {
+        // Erroneous initializer, implicit super call is not needed.
+        needsImplicitSuperInitializer = false;
       }
     }
     if (body == null && !bodyBuilderContext.isExternalConstructor) {
diff --git a/pkg/front_end/lib/src/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/type_inference/inference_visitor.dart
index 1b24c4b..e021d72 100644
--- a/pkg/front_end/lib/src/type_inference/inference_visitor.dart
+++ b/pkg/front_end/lib/src/type_inference/inference_visitor.dart
@@ -12652,7 +12652,14 @@
   }
 
   @override
+  // Coverage-ignore(suite): Not run.
   InitializerInferenceResult visitSuperInitializer(SuperInitializer node) {
+    _unhandledInitializer(node);
+  }
+
+  InitializerInferenceResult visitInternalSuperInitializer(
+    InternalSuperInitializer node,
+  ) {
     ensureMemberType(node.target);
 
     Supertype asSuperClass = hierarchyBuilder.getClassAsInstanceOf(
@@ -12679,12 +12686,14 @@
       const UnknownType(),
       node.fileOffset,
       new InvocationTargetFunctionType(functionType),
-      node.arguments as ArgumentsImpl,
+      node.arguments,
       skipTypeArgumentInference: true,
       staticTarget: node.target,
     );
     return new InitializerInferenceResult.fromInvocationInferenceResult(
-      node,
+      new SuperInitializer(node.target, node.arguments)
+        ..fileOffset = node.fileOffset
+        ..isSynthetic = node.isSynthetic,
       inferenceResult,
     );
   }