[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,
);
}