[fasta] Make forwarding stubs operators if their source are operators
Change-Id: I516c0ac9ccf93770cc331b1c7569df1a1c16659c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/102160
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 dafd56c3..5aa6fb8 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
@@ -2313,6 +2313,9 @@
ProcedureKind kind = ProcedureKind.Method;
if (bestSoFar.isField || bestSoFar.isSetter || bestSoFar.isGetter) {
kind = isSetter ? ProcedureKind.Setter : ProcedureKind.Getter;
+ } else if (bestSoFar.target is Procedure &&
+ bestSoFar.target.kind == ProcedureKind.Operator) {
+ kind = ProcedureKind.Operator;
}
if (modifyKernel) {
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart b/pkg/front_end/testcases/forwarding_stub_for_operator.dart
new file mode 100644
index 0000000..e604fe0
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart
@@ -0,0 +1,29 @@
+// 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.
+
+//------------------------------------------------------------------------------
+
+class A {
+ dynamic operator+(covariant int a) => null;
+}
+
+class B {
+ dynamic operator+(dynamic b) => null;
+}
+
+abstract class C implements A, B {}
+
+//------------------------------------------------------------------------------
+
+class D {
+ dynamic operator+(dynamic d) => null;
+}
+
+class E extends D {
+ dynamic operator+(covariant int e);
+}
+
+//------------------------------------------------------------------------------
+
+main() {}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.hierarchy.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.hierarchy.expect
new file mode 100644
index 0000000..d5d1da9
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.hierarchy.expect
@@ -0,0 +1,123 @@
+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
+ A.+
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+B:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ B.+
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+C:
+ Longest path to Object: 2
+ superclasses:
+ Object
+ interfaces: A, B
+ classMembers:
+ Object.toString
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+ interfaceMembers:
+ Object.toString
+ C.A.+%B.+
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ interfaceSetters:
+
+D:
+ superclasses:
+ Object
+ interfaces:
+ classMembers:
+ Object.toString
+ D.+
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
+
+E:
+ superclasses:
+ Object
+ -> D
+ interfaces:
+ classMembers:
+ Object.toString
+ E.D.+%E.+
+ Object.runtimeType
+ Object._simpleInstanceOf
+ Object._instanceOf
+ Object.noSuchMethod
+ Object._identityHashCode
+ Object.hashCode
+ Object._simpleInstanceOfFalse
+ Object._simpleInstanceOfTrue
+ Object.==
+ classSetters:
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.expect
new file mode 100644
index 0000000..84a1b42
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ operator +(covariant core::int a) → dynamic
+ return null;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ operator +(dynamic b) → dynamic
+ return null;
+}
+abstract class C extends core::Object implements self::A, self::B {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+ synthetic constructor •() → self::D
+ : super core::Object::•()
+ ;
+ operator +(dynamic d) → dynamic
+ return null;
+}
+class E extends self::D {
+ synthetic constructor •() → self::E
+ : super self::D::•()
+ ;
+ forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+ return super.{self::D::+}(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.transformed.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.transformed.expect
new file mode 100644
index 0000000..84a1b42
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.legacy.transformed.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ operator +(covariant core::int a) → dynamic
+ return null;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ operator +(dynamic b) → dynamic
+ return null;
+}
+abstract class C extends core::Object implements self::A, self::B {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+ synthetic constructor •() → self::D
+ : super core::Object::•()
+ ;
+ operator +(dynamic d) → dynamic
+ return null;
+}
+class E extends self::D {
+ synthetic constructor •() → self::E
+ : super self::D::•()
+ ;
+ forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+ return super.{self::D::+}(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.outline.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.outline.expect
new file mode 100644
index 0000000..14a8eef
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.outline.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ ;
+ operator +(covariant core::int a) → dynamic
+ ;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ ;
+ operator +(dynamic b) → dynamic
+ ;
+}
+abstract class C extends core::Object implements self::A, self::B {
+ synthetic constructor •() → self::C
+ ;
+ abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+ synthetic constructor •() → self::D
+ ;
+ operator +(dynamic d) → dynamic
+ ;
+}
+class E extends self::D {
+ synthetic constructor •() → self::E
+ ;
+ forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+ return super.{self::D::+}(e);
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.expect
new file mode 100644
index 0000000..84a1b42
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ operator +(covariant core::int a) → dynamic
+ return null;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ operator +(dynamic b) → dynamic
+ return null;
+}
+abstract class C extends core::Object implements self::A, self::B {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+ synthetic constructor •() → self::D
+ : super core::Object::•()
+ ;
+ operator +(dynamic d) → dynamic
+ return null;
+}
+class E extends self::D {
+ synthetic constructor •() → self::E
+ : super self::D::•()
+ ;
+ forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+ return super.{self::D::+}(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.transformed.expect b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.transformed.expect
new file mode 100644
index 0000000..84a1b42
--- /dev/null
+++ b/pkg/front_end/testcases/forwarding_stub_for_operator.dart.strong.transformed.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → self::A
+ : super core::Object::•()
+ ;
+ operator +(covariant core::int a) → dynamic
+ return null;
+}
+class B extends core::Object {
+ synthetic constructor •() → self::B
+ : super core::Object::•()
+ ;
+ operator +(dynamic b) → dynamic
+ return null;
+}
+abstract class C extends core::Object implements self::A, self::B {
+ synthetic constructor •() → self::C
+ : super core::Object::•()
+ ;
+ abstract forwarding-stub operator +(covariant dynamic b) → dynamic;
+}
+class D extends core::Object {
+ synthetic constructor •() → self::D
+ : super core::Object::•()
+ ;
+ operator +(dynamic d) → dynamic
+ return null;
+}
+class E extends self::D {
+ synthetic constructor •() → self::E
+ : super self::D::•()
+ ;
+ forwarding-stub forwarding-semi-stub operator +(covariant core::int e) → dynamic
+ return super.{self::D::+}(e);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 820f52c..0147dc9 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -98,6 +98,7 @@
fibonacci: TextSerializationFailure # Was: Pass
for_in_scope: TextSerializationFailure # Was: Pass
for_in_without_declaration: TextSerializationFailure
+forwarding_stub_for_operator: TextSerializationFailure
function_in_field: TextSerializationFailure # Was: Pass
function_type_assignments: TextSerializationFailure # Was: Pass
function_type_default_value: TextSerializationFailure