Report InheritedMembersConflict correctly

Notice that no conflict is reported when an inherited
setter is in conflict with an inherited member. This is
implemented in a later CL.

Before we would only use InheritedMembersConflict when merging
interfaces, but as the new test cases demonstrate, that's not
sufficient.

Change-Id: I690dde1b59499d3ee0967b3f118b0b3b58898442
Reviewed-on: https://dart-review.googlesource.com/c/88941
Reviewed-by: Dmitry Stefantsov <dmitryas@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 505559d..5ee5ae1 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
@@ -93,7 +93,7 @@
       return a;
     }
     if (isInheritanceConflict(a, b)) {
-      reportInheritanceConflict(cls, a, b, mergeKind);
+      reportInheritanceConflict(cls, a, b);
     }
     Declaration result = a;
     if (mergeKind == MergeKind.interfaces) {
@@ -120,10 +120,10 @@
     return result;
   }
 
-  void reportInheritanceConflict(KernelClassBuilder cls, Declaration a,
-      Declaration b, MergeKind mergeKind) {
+  void reportInheritanceConflict(
+      KernelClassBuilder cls, Declaration a, Declaration b) {
     String name = a.fullNameForErrors;
-    if (mergeKind == MergeKind.interfaces) {
+    if (a.parent != cls) {
       cls.addProblem(messageInheritedMembersConflict, cls.charOffset,
           cls.fullNameForErrors.length,
           context: <LocatedMessage>[
diff --git a/pkg/front_end/testcases/abstract_members.dart b/pkg/front_end/testcases/abstract_members.dart
index 058cbe9..86b3dae 100644
--- a/pkg/front_end/testcases/abstract_members.dart
+++ b/pkg/front_end/testcases/abstract_members.dart
@@ -55,4 +55,44 @@
   noSuchMethod(_);
 }
 
+class C {
+  void interfaceMethod1(_) {}
+}
+
+// This class should have an error, the method C.interfaceMethod1 conflicts
+// with the field Interface2.interfaceMethod1.
+abstract class D extends C implements Interface2 {}
+
+class E {
+  void set interfaceMethod1(_) {}
+}
+
+// This class should have an error, the setter E.interfaceMethod1 conflicts
+// with the method Interface1.interfaceMethod1.
+abstract class F extends E implements Interface1 {}
+
+class Foo {
+  void foo() {}
+}
+
+class G {
+  void set foo(_) {}
+}
+
+// This class should have an error, the setter G.foo conflicts with the method
+// Foo.foo.
+abstract class H extends G implements Foo {}
+
+class Bar {
+  Object get foo => null;
+}
+
+class I {
+  Object foo() {}
+}
+
+// This class should have an error, the getter Bar.foo conflicts with the
+// method I.foo.
+abstract class J extends I implements Bar {}
+
 main() {}
diff --git a/pkg/front_end/testcases/abstract_members.dart.legacy.expect b/pkg/front_end/testcases/abstract_members.dart.legacy.expect
index 0c85dd2..dd5cc31 100644
--- a/pkg/front_end/testcases/abstract_members.dart.legacy.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.legacy.expect
@@ -89,6 +89,26 @@
 // pkg/front_end/testcases/abstract_members.dart:16:8: Context: 'Interface3.interfaceMethod3' is defined here.
 //   void interfaceMethod3() {}
 //        ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:64:16: Error: Can't inherit members that conflict with each other.
+// abstract class D extends C implements Interface2 {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:59:8: Context: This is one inherited member.
+//   void interfaceMethod1(_) {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: This is the other inherited member.
+//   var interfaceMethod1;
+//       ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:96:16: Error: Can't inherit members that conflict with each other.
+// abstract class J extends I implements Bar {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:91:10: Context: This is one inherited member.
+//   Object foo() {}
+//          ^^^
+// pkg/front_end/testcases/abstract_members.dart:87:14: Context: This is the other inherited member.
+//   Object get foo => null;
+//              ^^^
 
 // Unhandled errors:
 //
@@ -130,6 +150,14 @@
 // 
 // class MyMock3 extends B {
 //       ^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:64:16: Error: Can't inherit members that conflict with each other.
+// abstract class D extends C implements Interface2 {}
+//                ^
+//
+// pkg/front_end/testcases/abstract_members.dart:96:16: Error: Can't inherit members that conflict with each other.
+// abstract class J extends I implements Bar {}
+//                ^
 
 library;
 import self as self;
@@ -235,4 +263,61 @@
   no-such-method-forwarder set property2(dynamic _) → void
     return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#property2=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method interfaceMethod1(dynamic _) → void {}
+}
+abstract class D extends self::C implements self::Interface2 {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → self::E
+    : super core::Object::•()
+    ;
+  set interfaceMethod1(dynamic _) → void {}
+}
+abstract class F extends self::E implements self::Interface1 {
+  synthetic constructor •() → self::F
+    : super self::E::•()
+    ;
+}
+class Foo extends core::Object {
+  synthetic constructor •() → self::Foo
+    : super core::Object::•()
+    ;
+  method foo() → void {}
+}
+class G extends core::Object {
+  synthetic constructor •() → self::G
+    : super core::Object::•()
+    ;
+  set foo(dynamic _) → void {}
+}
+abstract class H extends self::G implements self::Foo {
+  synthetic constructor •() → self::H
+    : super self::G::•()
+    ;
+}
+class Bar extends core::Object {
+  synthetic constructor •() → self::Bar
+    : super core::Object::•()
+    ;
+  get foo() → core::Object
+    return null;
+}
+class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  method foo() → core::Object {}
+}
+abstract class J extends self::I implements self::Bar {
+  synthetic constructor •() → self::J
+    : super self::I::•()
+    ;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect b/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
index 7e489f3..22ee2e5 100644
--- a/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.legacy.transformed.expect
@@ -38,6 +38,14 @@
 // 
 // class MyMock3 extends B {
 //       ^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:64:16: Error: Can't inherit members that conflict with each other.
+// abstract class D extends C implements Interface2 {}
+//                ^
+//
+// pkg/front_end/testcases/abstract_members.dart:96:16: Error: Can't inherit members that conflict with each other.
+// abstract class J extends I implements Bar {}
+//                ^
 
 library;
 import self as self;
@@ -143,4 +151,61 @@
   no-such-method-forwarder set property2(dynamic _) → void
     return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#property2=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method interfaceMethod1(dynamic _) → void {}
+}
+abstract class D extends self::C implements self::Interface2 {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → self::E
+    : super core::Object::•()
+    ;
+  set interfaceMethod1(dynamic _) → void {}
+}
+abstract class F extends self::E implements self::Interface1 {
+  synthetic constructor •() → self::F
+    : super self::E::•()
+    ;
+}
+class Foo extends core::Object {
+  synthetic constructor •() → self::Foo
+    : super core::Object::•()
+    ;
+  method foo() → void {}
+}
+class G extends core::Object {
+  synthetic constructor •() → self::G
+    : super core::Object::•()
+    ;
+  set foo(dynamic _) → void {}
+}
+abstract class H extends self::G implements self::Foo {
+  synthetic constructor •() → self::H
+    : super self::G::•()
+    ;
+}
+class Bar extends core::Object {
+  synthetic constructor •() → self::Bar
+    : super core::Object::•()
+    ;
+  get foo() → core::Object
+    return null;
+}
+class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  method foo() → core::Object {}
+}
+abstract class J extends self::I implements self::Bar {
+  synthetic constructor •() → self::J
+    : super self::I::•()
+    ;
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/abstract_members.dart.outline.expect b/pkg/front_end/testcases/abstract_members.dart.outline.expect
index e2bf105..a352fbd 100644
--- a/pkg/front_end/testcases/abstract_members.dart.outline.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.outline.expect
@@ -89,6 +89,26 @@
 // pkg/front_end/testcases/abstract_members.dart:16:8: Context: 'Interface3.interfaceMethod3' is defined here.
 //   void interfaceMethod3() {}
 //        ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:64:16: Error: Can't inherit members that conflict with each other.
+// abstract class D extends C implements Interface2 {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:59:8: Context: This is one inherited member.
+//   void interfaceMethod1(_) {}
+//        ^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: This is the other inherited member.
+//   var interfaceMethod1;
+//       ^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/abstract_members.dart:96:16: Error: Can't inherit members that conflict with each other.
+// abstract class J extends I implements Bar {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:91:10: Context: This is one inherited member.
+//   Object foo() {}
+//          ^^^
+// pkg/front_end/testcases/abstract_members.dart:87:14: Context: This is the other inherited member.
+//   Object get foo => null;
+//              ^^^
 
 library;
 import self as self;
@@ -195,5 +215,57 @@
   no-such-method-forwarder set property2(dynamic _) → void
     return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#property2=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    ;
+  method interfaceMethod1(dynamic _) → void
+    ;
+}
+abstract class D extends self::C implements self::Interface2 {
+  synthetic constructor •() → self::D
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → self::E
+    ;
+  set interfaceMethod1(dynamic _) → void
+    ;
+}
+abstract class F extends self::E implements self::Interface1 {
+  synthetic constructor •() → self::F
+    ;
+}
+class Foo extends core::Object {
+  synthetic constructor •() → self::Foo
+    ;
+  method foo() → void
+    ;
+}
+class G extends core::Object {
+  synthetic constructor •() → self::G
+    ;
+  set foo(dynamic _) → void
+    ;
+}
+abstract class H extends self::G implements self::Foo {
+  synthetic constructor •() → self::H
+    ;
+}
+class Bar extends core::Object {
+  synthetic constructor •() → self::Bar
+    ;
+  get foo() → core::Object
+    ;
+}
+class I extends core::Object {
+  synthetic constructor •() → self::I
+    ;
+  method foo() → core::Object
+    ;
+}
+abstract class J extends self::I implements self::Bar {
+  synthetic constructor •() → self::J
+    ;
+}
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/abstract_members.dart.strong.expect b/pkg/front_end/testcases/abstract_members.dart.strong.expect
index c568386..65ea5ee 100644
--- a/pkg/front_end/testcases/abstract_members.dart.strong.expect
+++ b/pkg/front_end/testcases/abstract_members.dart.strong.expect
@@ -10,6 +10,46 @@
 //   var interfaceMethod1;
 //       ^
 //
+// pkg/front_end/testcases/abstract_members.dart:64:16: Error: Can't inherit members that conflict with each other.
+// abstract class D extends C implements Interface2 {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:59:8: Context: This is one inherited member.
+//   void interfaceMethod1(_) {}
+//        ^
+// pkg/front_end/testcases/abstract_members.dart:12:7: Context: This is the other inherited member.
+//   var interfaceMethod1;
+//       ^
+//
+// pkg/front_end/testcases/abstract_members.dart:72:16: Error: Can't inherit members that conflict with each other.
+// abstract class F extends E implements Interface1 {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:6:8: Context: This is one inherited member.
+//   void interfaceMethod1() {}
+//        ^
+// pkg/front_end/testcases/abstract_members.dart:67:12: Context: This is the other inherited member.
+//   void set interfaceMethod1(_) {}
+//            ^
+//
+// pkg/front_end/testcases/abstract_members.dart:84:16: Error: Can't inherit members that conflict with each other.
+// abstract class H extends G implements Foo {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:75:8: Context: This is one inherited member.
+//   void foo() {}
+//        ^
+// pkg/front_end/testcases/abstract_members.dart:79:12: Context: This is the other inherited member.
+//   void set foo(_) {}
+//            ^
+//
+// pkg/front_end/testcases/abstract_members.dart:96:16: Error: Can't inherit members that conflict with each other.
+// abstract class J extends I implements Bar {}
+//                ^
+// pkg/front_end/testcases/abstract_members.dart:91:10: Context: This is one inherited member.
+//   Object foo() {}
+//          ^
+// pkg/front_end/testcases/abstract_members.dart:87:14: Context: This is the other inherited member.
+//   Object get foo => null;
+//              ^
+//
 // pkg/front_end/testcases/abstract_members.dart:33:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
 //  - 'interfaceMethod2'
 //  - 'abstractMethod'
@@ -104,6 +144,22 @@
 // abstract class A implements Interface1, Interface2, Interface3 {
 //                ^
 //
+// pkg/front_end/testcases/abstract_members.dart:64:16: Error: Can't inherit members that conflict with each other.
+// abstract class D extends C implements Interface2 {}
+//                ^
+//
+// pkg/front_end/testcases/abstract_members.dart:72:16: Error: Can't inherit members that conflict with each other.
+// abstract class F extends E implements Interface1 {}
+//                ^
+//
+// pkg/front_end/testcases/abstract_members.dart:84:16: Error: Can't inherit members that conflict with each other.
+// abstract class H extends G implements Foo {}
+//                ^
+//
+// pkg/front_end/testcases/abstract_members.dart:96:16: Error: Can't inherit members that conflict with each other.
+// abstract class J extends I implements Bar {}
+//                ^
+//
 // pkg/front_end/testcases/abstract_members.dart:33:7: Error: The non-abstract class 'MyClass' is missing implementations for these members:
 //  - 'interfaceMethod2'
 //  - 'abstractMethod'
@@ -245,4 +301,61 @@
   no-such-method-forwarder set property2(dynamic _) → void
     return this.{self::MyMock3::noSuchMethod}(new core::_InvocationMirror::_withType(#property2=, 2, const <core::Type>[], core::List::unmodifiable<dynamic>(<dynamic>[_]), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
 }
+class C extends core::Object {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+  method interfaceMethod1(dynamic _) → void {}
+}
+abstract class D extends self::C implements self::Interface2 {
+  synthetic constructor •() → self::D
+    : super self::C::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → self::E
+    : super core::Object::•()
+    ;
+  set interfaceMethod1(dynamic _) → void {}
+}
+abstract class F extends self::E implements self::Interface1 {
+  synthetic constructor •() → self::F
+    : super self::E::•()
+    ;
+}
+class Foo extends core::Object {
+  synthetic constructor •() → self::Foo
+    : super core::Object::•()
+    ;
+  method foo() → void {}
+}
+class G extends core::Object {
+  synthetic constructor •() → self::G
+    : super core::Object::•()
+    ;
+  set foo(dynamic _) → void {}
+}
+abstract class H extends self::G implements self::Foo {
+  synthetic constructor •() → self::H
+    : super self::G::•()
+    ;
+}
+class Bar extends core::Object {
+  synthetic constructor •() → self::Bar
+    : super core::Object::•()
+    ;
+  get foo() → core::Object
+    return null;
+}
+class I extends core::Object {
+  synthetic constructor •() → self::I
+    : super core::Object::•()
+    ;
+  method foo() → core::Object {}
+}
+abstract class J extends self::I implements self::Bar {
+  synthetic constructor •() → self::J
+    : super self::I::•()
+    ;
+}
 static method main() → dynamic {}