Mixin superclass does not include mmembers of implemented interfaces.

R=brianwilkerson@google.com

Change-Id: Ie457a148c1e35977566451861e6aab28ea8cb091
Reviewed-on: https://dart-review.googlesource.com/c/90660
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index e8c9902..d8bdecf 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -94,7 +94,7 @@
   /**
    * The version of data format, should be incremented on every format change.
    */
-  static const int DATA_VERSION = 76;
+  static const int DATA_VERSION = 77;
 
   /**
    * The number of exception contexts allowed to write. Once this field is
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
index 799dbc8..40f988c 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
@@ -84,8 +84,10 @@
       }
 
       if (classElement.isMixin) {
+        var superClassCandidates = <Name, List<FunctionType>>{};
         for (var constraint in type.superclassConstraints) {
           var interfaceObj = getInterface(constraint);
+          _addCandidates(superClassCandidates, interfaceObj);
           _addCandidates(namedCandidates, interfaceObj);
         }
 
@@ -93,9 +95,9 @@
 
         // `mixin M on S1, S2 {}` can call using `super` any instance member
         // from its superclass constraints, whether it is abstract or concrete.
-        Map<Name, FunctionType> mixinSuperClass = {};
-        _findMostSpecificFromNamedCandidates(mixinSuperClass, namedCandidates);
-        superImplemented.add(mixinSuperClass);
+        var superClass = <Name, FunctionType>{};
+        _findMostSpecificFromNamedCandidates(superClass, superClassCandidates);
+        superImplemented.add(superClass);
       } else {
         if (type.superclass != null) {
           superInterface = getInterface(type.superclass);
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 10e01f6..6471484 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -7,7 +7,6 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
-import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager2.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -496,13 +495,6 @@
       var calleeType = _getCalleeType(node, targetType);
       _setResolution(node, calleeType);
 
-      ClassElementImpl receiverSuperClass = AbstractClassElementImpl.getImpl(
-        receiverType.element.supertype.element,
-      );
-      if (receiverSuperClass.hasNoSuchMethod) {
-        return;
-      }
-
       _resolver.errorReporter.reportErrorForNode(
           CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
           nameNode,
diff --git a/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart b/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart
index 60497d0..07fb0e8 100644
--- a/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart
+++ b/pkg/analyzer/test/src/dart/element/inheritance_manager2_test.dart
@@ -417,6 +417,38 @@
     expect(_getSuper('B', 'foo'), isNull);
   }
 
+  test_getMember_super_forMixin_interface() async {
+    addTestFile('''
+abstract class A {
+  void foo();
+}
+
+mixin M implements A {}
+''');
+    await resolveTestFile();
+
+    expect(
+      _getSuperForElement(findElement.mixin('M'), 'foo'),
+      isNull,
+    );
+  }
+
+  test_getMember_super_forMixin_superclassConstraint() async {
+    addTestFile('''
+abstract class A {
+  void foo();
+}
+
+mixin M on A {}
+''');
+    await resolveTestFile();
+
+    expect(
+      _getSuperForElement(findElement.mixin('M'), 'foo'),
+      same(findElement.method('foo', of: 'A')),
+    );
+  }
+
   test_getMember_super_fromMixin() async {
     addTestFile('''
 mixin M {
@@ -496,7 +528,12 @@
   }
 
   ExecutableElement _getSuper(String className, String name) {
-    var type = findElement.class_(className).type;
+    var element = findElement.class_(className);
+    return _getSuperForElement(element, name);
+  }
+
+  ExecutableElement _getSuperForElement(ClassElement element, String name) {
+    var type = element.type;
     return manager
         .getMember(type, new Name(null, name), forSuper: true)
         ?.element;
diff --git a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
index a10b0e1..f25fe19 100644
--- a/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/method_invocation_test.dart
@@ -43,6 +43,30 @@
     assertSuperExpression(invocation.target);
   }
 
+  test_error_abstractSuperMemberReference_mixin_implements() async {
+    addTestFile(r'''
+class A {
+  void foo(int _) {}
+}
+
+mixin M implements A {
+  void bar() {
+    super.foo(0);
+  }
+}
+''');
+    await resolveTestFile();
+    assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+
+    var invocation = findNode.methodInvocation('foo(0)');
+    assertMethodInvocation(
+      invocation,
+      findElement.method('foo', of: 'A'),
+      '(int) → void',
+    );
+    assertSuperExpression(invocation.target);
+  }
+
   test_error_abstractSuperMemberReference_mixinHasNoSuchMethod() async {
     addTestFile('''
 class A {