[fasta] Fix erroneous dependence of inference on named parameters order
Change-Id: I7013b4c4340a7d6fd543a21f14ac318ff0ecb4d7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106080
Reviewed-by: Aske Simon Christensen <askesc@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 597ce11..d61cbca 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -748,8 +748,13 @@
bType = substitution.substituteType(bType);
}
if (aType != bType) {
- FormalParameterBuilder<KernelTypeBuilder> parameter =
- a.formals[aPositional.length + aCount];
+ FormalParameterBuilder<KernelTypeBuilder> parameter;
+ for (int i = aPositional.length; i < a.formals.length; ++i) {
+ if (a.formals[i].name == name) {
+ parameter = a.formals[i];
+ break;
+ }
+ }
if (a.parent == cls && parameter.type == null) {
result = inferParameterType(
cls, a, parameter, bType, hadTypesInferred, hierarchy);
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart
new file mode 100644
index 0000000..d5210c1
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2019, 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.
+
+// The test checks that override-based inference for named parameters isn't
+// affected by the name-based ordering of the parameters.
+
+class A {
+ foo({bool c = true, bool a}) {}
+}
+
+class B extends A {
+ foo({c = true, bool a}) {}
+}
+
+class C extends B {
+ foo({bool c = true, bool a}) {}
+}
+
+// A1, B1, and C1 are similar to A, B, and C, only they have the names of the
+// named parameters swapped, to test that the alternative ordering works.
+
+class A1 {
+ foo({bool a = true, bool c}) {}
+}
+
+class B1 extends A1 {
+ foo({a = true, bool c}) {}
+}
+
+class C1 extends B1 {
+ foo({bool a = true, bool c}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.hierarchy.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.hierarchy.expect
new file mode 100644
index 0000000..9fb9b41
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.hierarchy.expect
@@ -0,0 +1,133 @@
+Object:
+ superclasses:
+ interfaces:
+ classMembers:
+ Object._haveSameRuntimeType
+ Object.toString
+ Object.runtimeType
+ Object._toString
+ Object._simpleInstanceOf
+ Object._hashCodeRnd
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._objectHashCode
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ A.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ -> A
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+C:
+ superclasses:
+ Object
+ -> A
+ -> B
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ C.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+A1:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ A1.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B1:
+ superclasses:
+ Object
+ -> A1
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ B1.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+C1:
+ superclasses:
+ Object
+ -> A1
+ -> B1
+ interfaces:
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ C1.foo
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.expect
new file mode 100644
index 0000000..498e65c
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class A1 extends core::Object {
+ synthetic constructor •() → self::A1
+ : super core::Object::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class B1 extends self::A1 {
+ synthetic constructor •() → self::B1
+ : super self::A1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class C1 extends self::B1 {
+ synthetic constructor •() → self::C1
+ : super self::B1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.transformed.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.transformed.expect
new file mode 100644
index 0000000..498e65c
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.legacy.transformed.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class A1 extends core::Object {
+ synthetic constructor •() → self::A1
+ : super core::Object::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class B1 extends self::A1 {
+ synthetic constructor •() → self::B1
+ : super self::A1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class C1 extends self::B1 {
+ synthetic constructor •() → self::C1
+ : super self::B1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.outline.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.outline.expect
new file mode 100644
index 0000000..7a732b2
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.outline.expect
@@ -0,0 +1,42 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ method foo({core::bool c, core::bool a}) → dynamic
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ ;
+ method foo({core::bool c, core::bool a}) → dynamic
+ ;
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ ;
+ method foo({core::bool c, core::bool a}) → dynamic
+ ;
+}
+class A1 extends core::Object {
+ synthetic constructor •() → self::A1
+ ;
+ method foo({core::bool a, core::bool c}) → dynamic
+ ;
+}
+class B1 extends self::A1 {
+ synthetic constructor •() → self::B1
+ ;
+ method foo({core::bool a, core::bool c}) → dynamic
+ ;
+}
+class C1 extends self::B1 {
+ synthetic constructor •() → self::C1
+ ;
+ method foo({core::bool a, core::bool c}) → dynamic
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.expect
new file mode 100644
index 0000000..498e65c
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class A1 extends core::Object {
+ synthetic constructor •() → self::A1
+ : super core::Object::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class B1 extends self::A1 {
+ synthetic constructor •() → self::B1
+ : super self::A1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class C1 extends self::B1 {
+ synthetic constructor •() → self::C1
+ : super self::B1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.transformed.expect b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.transformed.expect
new file mode 100644
index 0000000..498e65c
--- /dev/null
+++ b/pkg/front_end/testcases/override_inference_named_parameters_ordering.dart.strong.transformed.expect
@@ -0,0 +1,41 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class B extends self::A {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class C extends self::B {
+ synthetic constructor •() → self::C
+ : super self::B::•()
+ ;
+ method foo({core::bool c = true, core::bool a = null}) → dynamic {}
+}
+class A1 extends core::Object {
+ synthetic constructor •() → self::A1
+ : super core::Object::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class B1 extends self::A1 {
+ synthetic constructor •() → self::B1
+ : super self::A1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+class C1 extends self::B1 {
+ synthetic constructor •() → self::C1
+ : super self::B1::•()
+ ;
+ method foo({core::bool a = true, core::bool c = null}) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index ef897a2..32535ad 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -757,6 +757,7 @@
override_check_two_substitutions: TextSerializationFailure # Was: Pass
override_check_with_covariant_modifier: TypeCheckError # Issue #31620
override_inference_for_setters: TextSerializationFailure
+override_inference_named_parameters_ordering: TextSerializationFailure
part_as_entry_point: TextSerializationFailure # Was: Pass
part_as_entry_point_lib: TextSerializationFailure # Was: Pass
part_not_part_of: TextSerializationFailure