| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library engine.resolver.error_verifier; | 5 library engine.resolver.error_verifier; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import "dart:math" as math; | 8 import "dart:math" as math; |
| 9 | 9 |
| 10 import 'package:analyzer/src/generated/static_type_analyzer.dart'; | 10 import 'package:analyzer/src/generated/static_type_analyzer.dart'; |
| (...skipping 2139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2150 if (method.isGetter) { | 2150 if (method.isGetter) { |
| 2151 overriddenMember = _enclosingClass.lookUpInheritedConcreteGetter( | 2151 overriddenMember = _enclosingClass.lookUpInheritedConcreteGetter( |
| 2152 memberName, _currentLibrary); | 2152 memberName, _currentLibrary); |
| 2153 } else if (method.isSetter) { | 2153 } else if (method.isSetter) { |
| 2154 overriddenMember = _enclosingClass.lookUpInheritedConcreteSetter( | 2154 overriddenMember = _enclosingClass.lookUpInheritedConcreteSetter( |
| 2155 memberName, _currentLibrary); | 2155 memberName, _currentLibrary); |
| 2156 } else { | 2156 } else { |
| 2157 overriddenMember = _enclosingClass.lookUpInheritedConcreteMethod( | 2157 overriddenMember = _enclosingClass.lookUpInheritedConcreteMethod( |
| 2158 memberName, _currentLibrary); | 2158 memberName, _currentLibrary); |
| 2159 } | 2159 } |
| 2160 if (overriddenMember == null) { | 2160 if (overriddenMember == null && !_hasNoSuchMethod(_enclosingClass)) { |
| 2161 _errorReporter.reportErrorForNode( | 2161 _errorReporter.reportErrorForNode( |
| 2162 StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, | 2162 StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, |
| 2163 nameNode, | 2163 nameNode, |
| 2164 [memberName, _enclosingClass.displayName]); | 2164 [memberName, _enclosingClass.displayName]); |
| 2165 return true; | 2165 return true; |
| 2166 } | 2166 } |
| 2167 } | 2167 } |
| 2168 return false; | 2168 return false; |
| 2169 } | 2169 } |
| 2170 | 2170 |
| (...skipping 2244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4415 * See [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], | 4415 * See [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], |
| 4416 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO], | 4416 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO], |
| 4417 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE], | 4417 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE], |
| 4418 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR], and | 4418 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR], and |
| 4419 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS]. | 4419 * [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS]. |
| 4420 */ | 4420 */ |
| 4421 bool _checkForNonAbstractClassInheritsAbstractMember( | 4421 bool _checkForNonAbstractClassInheritsAbstractMember( |
| 4422 SimpleIdentifier classNameNode) { | 4422 SimpleIdentifier classNameNode) { |
| 4423 if (_enclosingClass.isAbstract) { | 4423 if (_enclosingClass.isAbstract) { |
| 4424 return false; | 4424 return false; |
| 4425 } else if (_hasNoSuchMethod(_enclosingClass)) { |
| 4426 return false; |
| 4425 } | 4427 } |
| 4426 // | 4428 // |
| 4427 // Store in local sets the set of all method and accessor names | 4429 // Store in local sets the set of all method and accessor names |
| 4428 // | 4430 // |
| 4429 MethodElement method = | |
| 4430 _enclosingClass.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME); | |
| 4431 if (method != null) { | |
| 4432 // If the enclosing class declares the method noSuchMethod(), then return. | |
| 4433 // From Spec: It is a static warning if a concrete class does not have an | |
| 4434 // implementation for a method in any of its superinterfaces unless it | |
| 4435 // declares its own noSuchMethod method (7.10). | |
| 4436 return false; | |
| 4437 } | |
| 4438 HashSet<ExecutableElement> missingOverrides = | 4431 HashSet<ExecutableElement> missingOverrides = |
| 4439 new HashSet<ExecutableElement>(); | 4432 new HashSet<ExecutableElement>(); |
| 4440 // | 4433 // |
| 4441 // Loop through the set of all executable elements declared in the implicit | 4434 // Loop through the set of all executable elements declared in the implicit |
| 4442 // interface. | 4435 // interface. |
| 4443 // | 4436 // |
| 4444 MemberMap membersInheritedFromInterfaces = _inheritanceManager | 4437 MemberMap membersInheritedFromInterfaces = _inheritanceManager |
| 4445 .getMapOfMembersInheritedFromInterfaces(_enclosingClass); | 4438 .getMapOfMembersInheritedFromInterfaces(_enclosingClass); |
| 4446 MemberMap membersInheritedFromSuperclasses = _inheritanceManager | 4439 MemberMap membersInheritedFromSuperclasses = _inheritanceManager |
| 4447 .getMapOfMembersInheritedFromClasses(_enclosingClass); | 4440 .getMapOfMembersInheritedFromClasses(_enclosingClass); |
| (...skipping 1141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5589 ClassElement classElement = declaration.element; | 5582 ClassElement classElement = declaration.element; |
| 5590 if (classElement == null) { | 5583 if (classElement == null) { |
| 5591 return false; | 5584 return false; |
| 5592 } | 5585 } |
| 5593 if (!_typeSystem.isSubtypeOf( | 5586 if (!_typeSystem.isSubtypeOf( |
| 5594 classElement.type, _typeProvider.functionType)) { | 5587 classElement.type, _typeProvider.functionType)) { |
| 5595 return false; | 5588 return false; |
| 5596 } | 5589 } |
| 5597 // If there is a noSuchMethod method, then don't report the warning, | 5590 // If there is a noSuchMethod method, then don't report the warning, |
| 5598 // see dartbug.com/16078 | 5591 // see dartbug.com/16078 |
| 5599 if (classElement.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME) != | 5592 if (_hasNoSuchMethod(classElement)) { |
| 5600 null) { | |
| 5601 return false; | 5593 return false; |
| 5602 } | 5594 } |
| 5603 ExecutableElement callMethod = _inheritanceManager.lookupMember( | 5595 ExecutableElement callMethod = _inheritanceManager.lookupMember( |
| 5604 classElement, FunctionElement.CALL_METHOD_NAME); | 5596 classElement, FunctionElement.CALL_METHOD_NAME); |
| 5605 if (callMethod == null || | 5597 if (callMethod == null || |
| 5606 callMethod is! MethodElement || | 5598 callMethod is! MethodElement || |
| 5607 (callMethod as MethodElement).isAbstract) { | 5599 (callMethod as MethodElement).isAbstract) { |
| 5608 _errorReporter.reportErrorForNode( | 5600 _errorReporter.reportErrorForNode( |
| 5609 StaticWarningCode.FUNCTION_WITHOUT_CALL, declaration.name); | 5601 StaticWarningCode.FUNCTION_WITHOUT_CALL, declaration.name); |
| 5610 return true; | 5602 return true; |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5740 _errorReporter.reportErrorForToken( | 5732 _errorReporter.reportErrorForToken( |
| 5741 CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken); | 5733 CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken); |
| 5742 foundError = true; | 5734 foundError = true; |
| 5743 } | 5735 } |
| 5744 } | 5736 } |
| 5745 } | 5737 } |
| 5746 return foundError; | 5738 return foundError; |
| 5747 } | 5739 } |
| 5748 | 5740 |
| 5749 /** | 5741 /** |
| 5742 * Return `true` if the given [classElement] has a noSuchMethod() method |
| 5743 * distinct from the one declared in class Object, as per the Dart Language |
| 5744 * Specification (section 10.4). |
| 5745 */ |
| 5746 bool _hasNoSuchMethod(ClassElement classElement) { |
| 5747 MethodElement method = classElement.lookUpMethod( |
| 5748 FunctionElement.NO_SUCH_METHOD_METHOD_NAME, classElement.library); |
| 5749 if (method == null) { |
| 5750 return false; |
| 5751 } |
| 5752 ClassElement definingClass = |
| 5753 method.getAncestor((Element element) => element is ClassElement); |
| 5754 return definingClass != null && !definingClass.type.isObject; |
| 5755 } |
| 5756 |
| 5757 /** |
| 5750 * Return `true` if the given [constructor] redirects to itself, directly or | 5758 * Return `true` if the given [constructor] redirects to itself, directly or |
| 5751 * indirectly. | 5759 * indirectly. |
| 5752 */ | 5760 */ |
| 5753 bool _hasRedirectingFactoryConstructorCycle(ConstructorElement constructor) { | 5761 bool _hasRedirectingFactoryConstructorCycle(ConstructorElement constructor) { |
| 5754 Set<ConstructorElement> constructors = new HashSet<ConstructorElement>(); | 5762 Set<ConstructorElement> constructors = new HashSet<ConstructorElement>(); |
| 5755 ConstructorElement current = constructor; | 5763 ConstructorElement current = constructor; |
| 5756 while (current != null) { | 5764 while (current != null) { |
| 5757 if (constructors.contains(current)) { | 5765 if (constructors.contains(current)) { |
| 5758 return identical(current, constructor); | 5766 return identical(current, constructor); |
| 5759 } | 5767 } |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6063 toCheck.add(type.element); | 6071 toCheck.add(type.element); |
| 6064 // type arguments | 6072 // type arguments |
| 6065 if (type is InterfaceType) { | 6073 if (type is InterfaceType) { |
| 6066 InterfaceType interfaceType = type; | 6074 InterfaceType interfaceType = type; |
| 6067 for (DartType typeArgument in interfaceType.typeArguments) { | 6075 for (DartType typeArgument in interfaceType.typeArguments) { |
| 6068 _addTypeToCheck(typeArgument); | 6076 _addTypeToCheck(typeArgument); |
| 6069 } | 6077 } |
| 6070 } | 6078 } |
| 6071 } | 6079 } |
| 6072 } | 6080 } |
| OLD | NEW |