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 {