| Index: pkg/analyzer/lib/src/generated/resolver.dart
|
| diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
|
| index a24bd1e811d0983e3960621a2267bb28eed46501..f986b355526a5b8e79000a8a5fbf931954cccf08 100644
|
| --- a/pkg/analyzer/lib/src/generated/resolver.dart
|
| +++ b/pkg/analyzer/lib/src/generated/resolver.dart
|
| @@ -52,7 +52,7 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
|
| * The class containing the AST nodes being visited, or `null` if we are not in the scope of
|
| * a class.
|
| */
|
| - ClassElement _enclosingClass;
|
| + ClassElementImpl _enclosingClass;
|
|
|
| /**
|
| * A flag indicating whether a surrounding member (compilation unit or class)
|
| @@ -87,12 +87,17 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
|
| LibraryElement _currentLibrary;
|
|
|
| /**
|
| + * The inheritance manager used to find overridden methods.
|
| + */
|
| + InheritanceManager _manager;
|
| +
|
| + /**
|
| * Create a new instance of the [BestPracticesVerifier].
|
| *
|
| * @param errorReporter the error reporter
|
| */
|
| - BestPracticesVerifier(
|
| - this._errorReporter, TypeProvider typeProvider, this._currentLibrary,
|
| + BestPracticesVerifier(this._errorReporter, TypeProvider typeProvider,
|
| + this._currentLibrary, this._manager,
|
| {TypeSystem typeSystem})
|
| : _nullType = typeProvider.nullType,
|
| _futureNullType = typeProvider.futureNullType,
|
| @@ -159,9 +164,9 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
|
|
|
| @override
|
| Object visitClassDeclaration(ClassDeclaration node) {
|
| - ClassElement outerClass = _enclosingClass;
|
| + ClassElementImpl outerClass = _enclosingClass;
|
| bool wasInDeprecatedMember = inDeprecatedMember;
|
| - ClassElement element = node.element;
|
| + ClassElement element = AbstractClassElementImpl.getImpl(node.element);
|
| if (element != null && element.isDeprecated) {
|
| inDeprecatedMember = true;
|
| }
|
| @@ -283,8 +288,10 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
|
|
|
| @override
|
| Object visitMethodInvocation(MethodInvocation node) {
|
| + Expression realTarget = node.realTarget;
|
| + _checkForAbstractSuperMemberReference(realTarget, node.methodName);
|
| _checkForCanBeNullAfterNullAware(
|
| - node.realTarget, node.operator, null, node.methodName);
|
| + realTarget, node.operator, null, node.methodName);
|
| DartType staticInvokeType = node.staticInvokeType;
|
| if (staticInvokeType is InterfaceType) {
|
| MethodElement methodElement = staticInvokeType.lookUpMethod(
|
| @@ -308,8 +315,10 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
|
|
|
| @override
|
| Object visitPropertyAccess(PropertyAccess node) {
|
| + Expression realTarget = node.realTarget;
|
| + _checkForAbstractSuperMemberReference(realTarget, node.propertyName);
|
| _checkForCanBeNullAfterNullAware(
|
| - node.realTarget, node.operator, node.propertyName, null);
|
| + realTarget, node.operator, node.propertyName, null);
|
| return super.visitPropertyAccess(node);
|
| }
|
|
|
| @@ -409,6 +418,34 @@ class BestPracticesVerifier extends RecursiveAstVisitor<Object> {
|
| return false;
|
| }
|
|
|
| + void _checkForAbstractSuperMemberReference(
|
| + Expression target, SimpleIdentifier name) {
|
| + if (target is SuperExpression) {
|
| + Element element = name.staticElement;
|
| + if (element is ExecutableElement && element.isAbstract) {
|
| + if (!_enclosingClass.hasNoSuchMethod) {
|
| + ExecutableElement concrete = null;
|
| + if (element.kind == ElementKind.METHOD) {
|
| + concrete = _enclosingClass.lookUpInheritedConcreteMethod(
|
| + element.displayName, _currentLibrary);
|
| + } else if (element.kind == ElementKind.GETTER) {
|
| + concrete = _enclosingClass.lookUpInheritedConcreteGetter(
|
| + element.displayName, _currentLibrary);
|
| + } else if (element.kind == ElementKind.SETTER) {
|
| + concrete = _enclosingClass.lookUpInheritedConcreteSetter(
|
| + element.displayName, _currentLibrary);
|
| + }
|
| + if (concrete == null) {
|
| + _errorReporter.reportTypeErrorForNode(
|
| + HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
|
| + name,
|
| + [element.kind.displayName, name.name]);
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| /**
|
| * This verifies that the passed expression can be assigned to its corresponding parameters.
|
| *
|
| @@ -4291,7 +4328,7 @@ class HintGenerator {
|
| }
|
| // Dart best practices
|
| unit.accept(new BestPracticesVerifier(
|
| - errorReporter, _context.typeProvider, _library,
|
| + errorReporter, _context.typeProvider, _library, _manager,
|
| typeSystem: _context.typeSystem));
|
| unit.accept(new OverrideVerifier(errorReporter, _manager));
|
| // Find to-do comments
|
| @@ -7283,8 +7320,13 @@ class ResolverVisitor extends ScopedVisitor {
|
| originalType is FunctionType &&
|
| originalType.typeFormals.isNotEmpty &&
|
| ts is StrongTypeSystemImpl) {
|
| - contextType = ts.inferGenericFunctionCall(typeProvider, originalType,
|
| - DartType.EMPTY_LIST, DartType.EMPTY_LIST, originalType.returnType, returnContextType);
|
| + contextType = ts.inferGenericFunctionCall(
|
| + typeProvider,
|
| + originalType,
|
| + DartType.EMPTY_LIST,
|
| + DartType.EMPTY_LIST,
|
| + originalType.returnType,
|
| + returnContextType);
|
| }
|
|
|
| InferenceContext.setType(node.argumentList, contextType);
|
|
|