[cfe] Disentangle type inference and default value copying in super-parameters
Part of https://github.com/dart-lang/sdk/issues/47525
Change-Id: Ia8f14aa5995f50719bc95d8b26c3bd5a40d6f967
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/229148
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
index c880b78..dcaf732 100644
--- a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
@@ -357,45 +357,42 @@
if (formal.isSuperInitializingFormal) {
superInitializingFormalIndex++;
bool hasImmediatelyDeclaredInitializer = formal.hasDeclaredInitializer;
- if (formal.type == null) {
- DartType? type;
- if (formal.isPositional) {
- if (superInitializingFormalIndex < superFormals.length) {
- FormalParameterBuilder correspondingSuperFormal =
- superFormals[superInitializingFormalIndex];
- formal.hasDeclaredInitializer =
- hasImmediatelyDeclaredInitializer ||
- correspondingSuperFormal.hasDeclaredInitializer;
- if (!hasImmediatelyDeclaredInitializer) {
- (positionalSuperParameters ??= <int>[]).add(formalIndex);
- }
- type = correspondingSuperFormal.variable!.type;
- } else {
- // TODO(cstefantsova): Report an error.
+ FormalParameterBuilder? correspondingSuperFormal;
+
+ if (formal.isPositional) {
+ if (superInitializingFormalIndex < superFormals.length) {
+ correspondingSuperFormal =
+ superFormals[superInitializingFormalIndex];
+ formal.hasDeclaredInitializer = hasImmediatelyDeclaredInitializer ||
+ correspondingSuperFormal.hasDeclaredInitializer;
+ if (!hasImmediatelyDeclaredInitializer) {
+ (positionalSuperParameters ??= <int>[]).add(formalIndex);
}
} else {
- FormalParameterBuilder? correspondingSuperFormal;
- for (FormalParameterBuilder superFormal in superFormals) {
- if (superFormal.isNamed && superFormal.name == formal.name) {
- correspondingSuperFormal = superFormal;
- break;
- }
- }
-
- if (correspondingSuperFormal != null) {
- formal.hasDeclaredInitializer =
- hasImmediatelyDeclaredInitializer ||
- correspondingSuperFormal.hasDeclaredInitializer;
- if (!hasImmediatelyDeclaredInitializer) {
- (namedSuperParameters ??= <String>[]).add(formal.name);
- }
- type = correspondingSuperFormal.variable!.type;
- } else {
- // TODO(cstefantsova): Report an error.
+ // TODO(cstefantsova): Report an error.
+ }
+ } else {
+ for (FormalParameterBuilder superFormal in superFormals) {
+ if (superFormal.isNamed && superFormal.name == formal.name) {
+ correspondingSuperFormal = superFormal;
+ break;
}
}
+ if (correspondingSuperFormal != null) {
+ formal.hasDeclaredInitializer = hasImmediatelyDeclaredInitializer ||
+ correspondingSuperFormal.hasDeclaredInitializer;
+ if (!hasImmediatelyDeclaredInitializer) {
+ (namedSuperParameters ??= <String>[]).add(formal.name);
+ }
+ } else {
+ // TODO(cstefantsova): Report an error.
+ }
+ }
+
+ if (formal.type == null) {
+ DartType? type = correspondingSuperFormal?.variable?.type;
if (substitution.isNotEmpty && type != null) {
type = substitute(type, substitution);
}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart
new file mode 100644
index 0000000..f5b1bd9
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class S {
+ int s1;
+ int s2;
+ S([this.s1 = 1, this.s2 = 2]);
+}
+
+class C extends S {
+ int c1;
+ C(this.c1, [int super.s1, int x = 0, int super.s2]);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.strong.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.strong.expect
new file mode 100644
index 0000000..3bd8f09
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.strong.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class S extends core::Object {
+ field core::int s1;
+ field core::int s2;
+ constructor •([core::int s1 = #C1, core::int s2 = #C2]) → self::S
+ : self::S::s1 = s1, self::S::s2 = s2, super core::Object::•()
+ ;
+}
+class C extends self::S {
+ field core::int c1;
+ constructor •(core::int c1, [dynamic s1 = #C1, core::int x = #C3, dynamic s2 = #C2]) → self::C
+ : self::C::c1 = c1, super self::S::•(s1, s2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 1
+ #C2 = 2
+ #C3 = 0
+}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.strong.transformed.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.strong.transformed.expect
new file mode 100644
index 0000000..3bd8f09
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class S extends core::Object {
+ field core::int s1;
+ field core::int s2;
+ constructor •([core::int s1 = #C1, core::int s2 = #C2]) → self::S
+ : self::S::s1 = s1, self::S::s2 = s2, super core::Object::•()
+ ;
+}
+class C extends self::S {
+ field core::int c1;
+ constructor •(core::int c1, [dynamic s1 = #C1, core::int x = #C3, dynamic s2 = #C2]) → self::C
+ : self::C::c1 = c1, super self::S::•(s1, s2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 1
+ #C2 = 2
+ #C3 = 0
+}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.textual_outline.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.textual_outline.expect
new file mode 100644
index 0000000..7acd1b7
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.textual_outline.expect
@@ -0,0 +1,10 @@
+class S {
+ int s1;
+ int s2;
+ S([this.s1 = 1, this.s2 = 2]);
+}
+class C extends S {
+ int c1;
+ C(this.c1, [int super.s1, int x = 0, int super.s2]);
+}
+main() {}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.expect
new file mode 100644
index 0000000..3bd8f09
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class S extends core::Object {
+ field core::int s1;
+ field core::int s2;
+ constructor •([core::int s1 = #C1, core::int s2 = #C2]) → self::S
+ : self::S::s1 = s1, self::S::s2 = s2, super core::Object::•()
+ ;
+}
+class C extends self::S {
+ field core::int c1;
+ constructor •(core::int c1, [dynamic s1 = #C1, core::int x = #C3, dynamic s2 = #C2]) → self::C
+ : self::C::c1 = c1, super self::S::•(s1, s2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 1
+ #C2 = 2
+ #C3 = 0
+}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.modular.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.modular.expect
new file mode 100644
index 0000000..3bd8f09
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.modular.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class S extends core::Object {
+ field core::int s1;
+ field core::int s2;
+ constructor •([core::int s1 = #C1, core::int s2 = #C2]) → self::S
+ : self::S::s1 = s1, self::S::s2 = s2, super core::Object::•()
+ ;
+}
+class C extends self::S {
+ field core::int c1;
+ constructor •(core::int c1, [dynamic s1 = #C1, core::int x = #C3, dynamic s2 = #C2]) → self::C
+ : self::C::c1 = c1, super self::S::•(s1, s2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 1
+ #C2 = 2
+ #C3 = 0
+}
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.outline.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.outline.expect
new file mode 100644
index 0000000..aae570e
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.outline.expect
@@ -0,0 +1,18 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class S extends core::Object {
+ field core::int s1;
+ field core::int s2;
+ constructor •([core::int s1 = 1, core::int s2 = 2]) → self::S
+ ;
+}
+class C extends self::S {
+ field core::int c1;
+ constructor •(core::int c1, [dynamic s1 = 1, core::int x = 0, dynamic s2 = 2]) → self::C
+ : self::C::c1 = c1
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.transformed.expect b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.transformed.expect
new file mode 100644
index 0000000..3bd8f09
--- /dev/null
+++ b/pkg/front_end/testcases/super_parameters/super_parameters_with_types_and_default_values.dart.weak.transformed.expect
@@ -0,0 +1,24 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class S extends core::Object {
+ field core::int s1;
+ field core::int s2;
+ constructor •([core::int s1 = #C1, core::int s2 = #C2]) → self::S
+ : self::S::s1 = s1, self::S::s2 = s2, super core::Object::•()
+ ;
+}
+class C extends self::S {
+ field core::int c1;
+ constructor •(core::int c1, [dynamic s1 = #C1, core::int x = #C3, dynamic s2 = #C2]) → self::C
+ : self::C::c1 = c1, super self::S::•(s1, s2)
+ ;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = 1
+ #C2 = 2
+ #C3 = 0
+}
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 86a420c..751ebe1 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -100,10 +100,10 @@
general/issue43363: FormatterCrash
general/issue45490: FormatterCrash
general/issue45700.crash: FormatterCrash
-general/issue_46886: FormatterCrash
general/issue47495: FormatterCrash
general/issue47728_2: FormatterCrash
general/issue47728_3: FormatterCrash
+general/issue_46886: FormatterCrash
general/macro_class: FormatterCrash
general/many_errors: FormatterCrash
general/missing_prefix_name: FormatterCrash
@@ -219,6 +219,7 @@
super_parameters/simple_inference: FormatterCrash
super_parameters/simple_named_super_parameters: FormatterCrash
super_parameters/simple_positional_super_parameters: FormatterCrash
+super_parameters/super_parameters_with_types_and_default_values: FormatterCrash
super_parameters/synthesized_super_constructor_with_parameters: FormatterCrash
super_parameters/type_alias_in_supertype: FormatterCrash
super_parameters/typed_super_parameter: FormatterCrash