[cfe] Handle synthesized super initializers in super-parameters
Part of https://github.com/dart-lang/sdk/issues/47525
Change-Id: I768dce70465a77a94609af03b21c64d4bf4a1386
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/223800
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index e7890ff..44ee19e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1049,78 +1049,6 @@
];
}
- if (libraryBuilder.enableSuperParametersInLibrary) {
- if (initializers.isNotEmpty && initializers.last is SuperInitializer) {
- SuperInitializer superInitializer =
- initializers.last as SuperInitializer;
- Arguments arguments = superInitializer.arguments;
-
- List<VariableDeclaration>? positionalSuperParameters;
- List<VariableDeclaration>? namedSuperParameters;
-
- List<FormalParameterBuilder>? formals =
- (member as ConstructorBuilder).formals;
- if (formals != null) {
- for (FormalParameterBuilder formal in formals) {
- if (formal.isSuperInitializingFormal) {
- if (formal.isNamed) {
- (namedSuperParameters ??= <VariableDeclaration>[])
- .add(formal.variable!);
- } else {
- (positionalSuperParameters ??= <VariableDeclaration>[])
- .add(formal.variable!);
- }
- }
- }
-
- if (positionalSuperParameters != null) {
- if (arguments.positional.isNotEmpty) {
- addProblem(fasta.messagePositionalSuperParametersAndArguments,
- arguments.fileOffset, noLength,
- context: <LocatedMessage>[
- fasta.messageSuperInitializerParameter.withLocation(uri,
- positionalSuperParameters.first.fileOffset, noLength)
- ]);
- } else {
- for (VariableDeclaration positional
- in positionalSuperParameters) {
- arguments.positional.add(
- new VariableGetImpl(positional, forNullGuardedAccess: false)
- ..fileOffset = positional.fileOffset);
- }
- }
- }
- if (namedSuperParameters != null) {
- // TODO(cstefantsova): Report name conflicts.
- for (VariableDeclaration named in namedSuperParameters) {
- arguments.named.add(new NamedExpression(
- named.name!,
- new VariableGetImpl(named, forNullGuardedAccess: false)
- ..fileOffset = named.fileOffset)
- ..fileOffset = named.fileOffset);
- }
- }
- }
-
- LocatedMessage? message = checkArgumentsForFunction(
- superInitializer.target.function,
- arguments,
- arguments.fileOffset, <TypeParameter>[]);
- if (message != null) {
- initializers[initializers.length - 1] = buildInvalidInitializer(
- buildUnresolvedError(
- forest.createNullLiteral(superInitializer.fileOffset),
- constructorNameForDiagnostics(
- superInitializer.target.name.text),
- arguments,
- superInitializer.fileOffset,
- isSuper: true,
- message: message,
- kind: UnresolvedKind.Constructor));
- }
- }
- }
-
_initializers ??= <Initializer>[];
_initializers!.addAll(initializers);
}
@@ -1748,15 +1676,87 @@
typeInferrer.flowAnalysis.declare(parameter.variable!, true);
}
}
- if (_initializers != null) {
+
+ List<Expression>? positionalSuperParametersAsArguments;
+ List<NamedExpression>? namedSuperParametersAsArguments;
+ if (formals != null) {
+ for (FormalParameterBuilder formal in formals) {
+ if (formal.isSuperInitializingFormal) {
+ if (formal.isNamed) {
+ (namedSuperParametersAsArguments ??= <NamedExpression>[]).add(
+ new NamedExpression(
+ formal.name,
+ new VariableGetImpl(formal.variable!,
+ forNullGuardedAccess: false)
+ ..fileOffset = formal.charOffset)
+ ..fileOffset = formal.charOffset);
+ } else {
+ (positionalSuperParametersAsArguments ??= <Expression>[]).add(
+ new VariableGetImpl(formal.variable!,
+ forNullGuardedAccess: false)
+ ..fileOffset = formal.charOffset);
+ }
+ }
+ }
+ }
+
+ List<Initializer>? initializers = _initializers;
+ if (initializers != null) {
+ if (libraryBuilder.enableSuperParametersInLibrary) {
+ if (initializers.isNotEmpty && initializers.last is SuperInitializer) {
+ SuperInitializer superInitializer =
+ initializers.last as SuperInitializer;
+ Arguments arguments = superInitializer.arguments;
+
+ if (positionalSuperParametersAsArguments != null) {
+ if (arguments.positional.isNotEmpty) {
+ addProblem(fasta.messagePositionalSuperParametersAndArguments,
+ arguments.fileOffset, noLength,
+ context: <LocatedMessage>[
+ fasta.messageSuperInitializerParameter.withLocation(
+ uri,
+ (positionalSuperParametersAsArguments.first
+ as VariableGet)
+ .variable
+ .fileOffset,
+ noLength)
+ ]);
+ } else {
+ arguments.positional.addAll(positionalSuperParametersAsArguments);
+ }
+ }
+ if (namedSuperParametersAsArguments != null) {
+ // TODO(cstefantsova): Report name conflicts.
+ arguments.named.addAll(namedSuperParametersAsArguments);
+ }
+
+ LocatedMessage? message = checkArgumentsForFunction(
+ superInitializer.target.function,
+ arguments,
+ arguments.fileOffset, <TypeParameter>[]);
+ if (message != null) {
+ initializers[initializers.length - 1] = buildInvalidInitializer(
+ buildUnresolvedError(
+ forest.createNullLiteral(superInitializer.fileOffset),
+ constructorNameForDiagnostics(
+ superInitializer.target.name.text),
+ arguments,
+ superInitializer.fileOffset,
+ isSuper: true,
+ message: message,
+ kind: UnresolvedKind.Constructor));
+ }
+ }
+ }
+
Map<Initializer, InitializerInferenceResult> inferenceResults =
<Initializer, InitializerInferenceResult>{};
- for (Initializer initializer in _initializers!) {
+ for (Initializer initializer in initializers) {
inferenceResults[initializer] =
typeInferrer.inferInitializer(this, initializer);
}
if (!builder.isExternal) {
- for (Initializer initializer in _initializers!) {
+ for (Initializer initializer in initializers) {
builder.addInitializer(initializer, this,
inferenceResult: inferenceResults[initializer]!);
}
@@ -1772,7 +1772,14 @@
/// >unless the enclosing class is class Object.
Constructor? superTarget = lookupConstructor(emptyName, isSuper: true);
Initializer initializer;
- Arguments arguments = forest.createArgumentsEmpty(noLocation);
+ Arguments arguments;
+ if (libraryBuilder.enableSuperParametersInLibrary) {
+ arguments = forest.createArguments(
+ noLocation, positionalSuperParametersAsArguments ?? <Expression>[],
+ named: namedSuperParametersAsArguments);
+ } else {
+ arguments = forest.createArgumentsEmpty(noLocation);
+ }
if (superTarget == null ||
checkArgumentsForFunction(superTarget.function, arguments,
builder.charOffset, const <TypeParameter>[]) !=
diff --git a/pkg/front_end/testcases/super_parameters/simple.dart.strong.expect b/pkg/front_end/testcases/super_parameters/simple.dart.strong.expect
index a1ba70a..2738e5e 100644
--- a/pkg/front_end/testcases/super_parameters/simple.dart.strong.expect
+++ b/pkg/front_end/testcases/super_parameters/simple.dart.strong.expect
@@ -1,11 +1,4 @@
library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/super_parameters/simple.dart:11:3: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
-// B(super.foo);
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -17,9 +10,7 @@
}
class B extends self::A {
constructor •(dynamic foo) → self::B
- : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/super_parameters/simple.dart:11:3: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
- B(super.foo);
- ^"
+ : super self::A::•(foo)
;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/super_parameters/simple.dart.strong.transformed.expect b/pkg/front_end/testcases/super_parameters/simple.dart.strong.transformed.expect
index a1ba70a..2738e5e 100644
--- a/pkg/front_end/testcases/super_parameters/simple.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/super_parameters/simple.dart.strong.transformed.expect
@@ -1,11 +1,4 @@
library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/super_parameters/simple.dart:11:3: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
-// B(super.foo);
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -17,9 +10,7 @@
}
class B extends self::A {
constructor •(dynamic foo) → self::B
- : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/super_parameters/simple.dart:11:3: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
- B(super.foo);
- ^"
+ : super self::A::•(foo)
;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/super_parameters/simple.dart.weak.expect b/pkg/front_end/testcases/super_parameters/simple.dart.weak.expect
index a1ba70a..2738e5e 100644
--- a/pkg/front_end/testcases/super_parameters/simple.dart.weak.expect
+++ b/pkg/front_end/testcases/super_parameters/simple.dart.weak.expect
@@ -1,11 +1,4 @@
library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/super_parameters/simple.dart:11:3: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
-// B(super.foo);
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -17,9 +10,7 @@
}
class B extends self::A {
constructor •(dynamic foo) → self::B
- : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/super_parameters/simple.dart:11:3: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
- B(super.foo);
- ^"
+ : super self::A::•(foo)
;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/super_parameters/simple.dart.weak.modular.expect b/pkg/front_end/testcases/super_parameters/simple.dart.weak.modular.expect
index a1ba70a..2738e5e 100644
--- a/pkg/front_end/testcases/super_parameters/simple.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/super_parameters/simple.dart.weak.modular.expect
@@ -1,11 +1,4 @@
library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/super_parameters/simple.dart:11:3: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
-// B(super.foo);
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -17,9 +10,7 @@
}
class B extends self::A {
constructor •(dynamic foo) → self::B
- : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/super_parameters/simple.dart:11:3: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
- B(super.foo);
- ^"
+ : super self::A::•(foo)
;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/super_parameters/simple.dart.weak.transformed.expect b/pkg/front_end/testcases/super_parameters/simple.dart.weak.transformed.expect
index a1ba70a..2738e5e 100644
--- a/pkg/front_end/testcases/super_parameters/simple.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/super_parameters/simple.dart.weak.transformed.expect
@@ -1,11 +1,4 @@
library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/super_parameters/simple.dart:11:3: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
-// B(super.foo);
-// ^
-//
import self as self;
import "dart:core" as core;
@@ -17,9 +10,7 @@
}
class B extends self::A {
constructor •(dynamic foo) → self::B
- : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/super_parameters/simple.dart:11:3: Error: The superclass, 'A', has no unnamed constructor that takes no arguments.
- B(super.foo);
- ^"
+ : super self::A::•(foo)
;
}
static method main() → dynamic {}