[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