| 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 analyzer.src.generated.resolver; | 5 library analyzer.src.generated.resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 // static String _HASHCODE_GETTER_NAME = "hashCode"; | 45 // static String _HASHCODE_GETTER_NAME = "hashCode"; |
| 46 | 46 |
| 47 static String _NULL_TYPE_NAME = "Null"; | 47 static String _NULL_TYPE_NAME = "Null"; |
| 48 | 48 |
| 49 static String _TO_INT_METHOD_NAME = "toInt"; | 49 static String _TO_INT_METHOD_NAME = "toInt"; |
| 50 | 50 |
| 51 /** | 51 /** |
| 52 * The class containing the AST nodes being visited, or `null` if we are not i
n the scope of | 52 * The class containing the AST nodes being visited, or `null` if we are not i
n the scope of |
| 53 * a class. | 53 * a class. |
| 54 */ | 54 */ |
| 55 ClassElementImpl _enclosingClass; | 55 ClassElement _enclosingClass; |
| 56 | 56 |
| 57 /** | 57 /** |
| 58 * A flag indicating whether a surrounding member (compilation unit or class) | 58 * A flag indicating whether a surrounding member (compilation unit or class) |
| 59 * is deprecated. | 59 * is deprecated. |
| 60 */ | 60 */ |
| 61 bool inDeprecatedMember; | 61 bool inDeprecatedMember; |
| 62 | 62 |
| 63 /** | 63 /** |
| 64 * The error reporter by which errors will be reported. | 64 * The error reporter by which errors will be reported. |
| 65 */ | 65 */ |
| (...skipping 14 matching lines...) Expand all Loading... |
| 80 * The type system primitives | 80 * The type system primitives |
| 81 */ | 81 */ |
| 82 TypeSystem _typeSystem; | 82 TypeSystem _typeSystem; |
| 83 | 83 |
| 84 /** | 84 /** |
| 85 * The current library | 85 * The current library |
| 86 */ | 86 */ |
| 87 LibraryElement _currentLibrary; | 87 LibraryElement _currentLibrary; |
| 88 | 88 |
| 89 /** | 89 /** |
| 90 * The inheritance manager used to find overridden methods. | |
| 91 */ | |
| 92 InheritanceManager _manager; | |
| 93 | |
| 94 /** | |
| 95 * Create a new instance of the [BestPracticesVerifier]. | 90 * Create a new instance of the [BestPracticesVerifier]. |
| 96 * | 91 * |
| 97 * @param errorReporter the error reporter | 92 * @param errorReporter the error reporter |
| 98 */ | 93 */ |
| 99 BestPracticesVerifier(this._errorReporter, TypeProvider typeProvider, | 94 BestPracticesVerifier( |
| 100 this._currentLibrary, this._manager, | 95 this._errorReporter, TypeProvider typeProvider, this._currentLibrary, |
| 101 {TypeSystem typeSystem}) | 96 {TypeSystem typeSystem}) |
| 102 : _nullType = typeProvider.nullType, | 97 : _nullType = typeProvider.nullType, |
| 103 _futureNullType = typeProvider.futureNullType, | 98 _futureNullType = typeProvider.futureNullType, |
| 104 _typeSystem = typeSystem ?? new TypeSystemImpl() { | 99 _typeSystem = typeSystem ?? new TypeSystemImpl() { |
| 105 inDeprecatedMember = _currentLibrary.isDeprecated; | 100 inDeprecatedMember = _currentLibrary.isDeprecated; |
| 106 } | 101 } |
| 107 | 102 |
| 108 @override | 103 @override |
| 109 Object visitAnnotation(Annotation node) { | 104 Object visitAnnotation(Annotation node) { |
| 110 if (node.elementAnnotation?.isFactory == true) { | 105 if (node.elementAnnotation?.isFactory == true) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 | 152 |
| 158 @override | 153 @override |
| 159 Object visitBinaryExpression(BinaryExpression node) { | 154 Object visitBinaryExpression(BinaryExpression node) { |
| 160 _checkForDivisionOptimizationHint(node); | 155 _checkForDivisionOptimizationHint(node); |
| 161 _checkForDeprecatedMemberUse(node.bestElement, node); | 156 _checkForDeprecatedMemberUse(node.bestElement, node); |
| 162 return super.visitBinaryExpression(node); | 157 return super.visitBinaryExpression(node); |
| 163 } | 158 } |
| 164 | 159 |
| 165 @override | 160 @override |
| 166 Object visitClassDeclaration(ClassDeclaration node) { | 161 Object visitClassDeclaration(ClassDeclaration node) { |
| 167 ClassElementImpl outerClass = _enclosingClass; | 162 ClassElement outerClass = _enclosingClass; |
| 168 bool wasInDeprecatedMember = inDeprecatedMember; | 163 bool wasInDeprecatedMember = inDeprecatedMember; |
| 169 ClassElement element = AbstractClassElementImpl.getImpl(node.element); | 164 ClassElement element = node.element; |
| 170 if (element != null && element.isDeprecated) { | 165 if (element != null && element.isDeprecated) { |
| 171 inDeprecatedMember = true; | 166 inDeprecatedMember = true; |
| 172 } | 167 } |
| 173 try { | 168 try { |
| 174 _enclosingClass = element; | 169 _enclosingClass = element; |
| 175 // Commented out until we decide that we want this hint in the analyzer | 170 // Commented out until we decide that we want this hint in the analyzer |
| 176 // checkForOverrideEqualsButNotHashCode(node); | 171 // checkForOverrideEqualsButNotHashCode(node); |
| 177 return super.visitClassDeclaration(node); | 172 return super.visitClassDeclaration(node); |
| 178 } finally { | 173 } finally { |
| 179 _enclosingClass = outerClass; | 174 _enclosingClass = outerClass; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 _checkForMissingReturn(node.returnType, node.body); | 276 _checkForMissingReturn(node.returnType, node.body); |
| 282 _checkForUnnecessaryNoSuchMethod(node); | 277 _checkForUnnecessaryNoSuchMethod(node); |
| 283 return super.visitMethodDeclaration(node); | 278 return super.visitMethodDeclaration(node); |
| 284 } finally { | 279 } finally { |
| 285 inDeprecatedMember = wasInDeprecatedMember; | 280 inDeprecatedMember = wasInDeprecatedMember; |
| 286 } | 281 } |
| 287 } | 282 } |
| 288 | 283 |
| 289 @override | 284 @override |
| 290 Object visitMethodInvocation(MethodInvocation node) { | 285 Object visitMethodInvocation(MethodInvocation node) { |
| 291 Expression realTarget = node.realTarget; | |
| 292 _checkForAbstractSuperMemberReference(realTarget, node.methodName); | |
| 293 _checkForCanBeNullAfterNullAware( | 286 _checkForCanBeNullAfterNullAware( |
| 294 realTarget, node.operator, null, node.methodName); | 287 node.realTarget, node.operator, null, node.methodName); |
| 295 DartType staticInvokeType = node.staticInvokeType; | 288 DartType staticInvokeType = node.staticInvokeType; |
| 296 if (staticInvokeType is InterfaceType) { | 289 if (staticInvokeType is InterfaceType) { |
| 297 MethodElement methodElement = staticInvokeType.lookUpMethod( | 290 MethodElement methodElement = staticInvokeType.lookUpMethod( |
| 298 FunctionElement.CALL_METHOD_NAME, _currentLibrary); | 291 FunctionElement.CALL_METHOD_NAME, _currentLibrary); |
| 299 _checkForDeprecatedMemberUse(methodElement, node); | 292 _checkForDeprecatedMemberUse(methodElement, node); |
| 300 } | 293 } |
| 301 return super.visitMethodInvocation(node); | 294 return super.visitMethodInvocation(node); |
| 302 } | 295 } |
| 303 | 296 |
| 304 @override | 297 @override |
| 305 Object visitPostfixExpression(PostfixExpression node) { | 298 Object visitPostfixExpression(PostfixExpression node) { |
| 306 _checkForDeprecatedMemberUse(node.bestElement, node); | 299 _checkForDeprecatedMemberUse(node.bestElement, node); |
| 307 return super.visitPostfixExpression(node); | 300 return super.visitPostfixExpression(node); |
| 308 } | 301 } |
| 309 | 302 |
| 310 @override | 303 @override |
| 311 Object visitPrefixExpression(PrefixExpression node) { | 304 Object visitPrefixExpression(PrefixExpression node) { |
| 312 _checkForDeprecatedMemberUse(node.bestElement, node); | 305 _checkForDeprecatedMemberUse(node.bestElement, node); |
| 313 return super.visitPrefixExpression(node); | 306 return super.visitPrefixExpression(node); |
| 314 } | 307 } |
| 315 | 308 |
| 316 @override | 309 @override |
| 317 Object visitPropertyAccess(PropertyAccess node) { | 310 Object visitPropertyAccess(PropertyAccess node) { |
| 318 Expression realTarget = node.realTarget; | |
| 319 _checkForAbstractSuperMemberReference(realTarget, node.propertyName); | |
| 320 _checkForCanBeNullAfterNullAware( | 311 _checkForCanBeNullAfterNullAware( |
| 321 realTarget, node.operator, node.propertyName, null); | 312 node.realTarget, node.operator, node.propertyName, null); |
| 322 return super.visitPropertyAccess(node); | 313 return super.visitPropertyAccess(node); |
| 323 } | 314 } |
| 324 | 315 |
| 325 @override | 316 @override |
| 326 Object visitRedirectingConstructorInvocation( | 317 Object visitRedirectingConstructorInvocation( |
| 327 RedirectingConstructorInvocation node) { | 318 RedirectingConstructorInvocation node) { |
| 328 _checkForDeprecatedMemberUse(node.staticElement, node); | 319 _checkForDeprecatedMemberUse(node.staticElement, node); |
| 329 return super.visitRedirectingConstructorInvocation(node); | 320 return super.visitRedirectingConstructorInvocation(node); |
| 330 } | 321 } |
| 331 | 322 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 // the is not case | 402 // the is not case |
| 412 _errorReporter.reportErrorForNode( | 403 _errorReporter.reportErrorForNode( |
| 413 HintCode.TYPE_CHECK_IS_NOT_NULL, node); | 404 HintCode.TYPE_CHECK_IS_NOT_NULL, node); |
| 414 } | 405 } |
| 415 return true; | 406 return true; |
| 416 } | 407 } |
| 417 } | 408 } |
| 418 return false; | 409 return false; |
| 419 } | 410 } |
| 420 | 411 |
| 421 void _checkForAbstractSuperMemberReference( | |
| 422 Expression target, SimpleIdentifier name) { | |
| 423 if (target is SuperExpression) { | |
| 424 Element element = name.staticElement; | |
| 425 if (element is ExecutableElement && element.isAbstract) { | |
| 426 if (!_enclosingClass.hasNoSuchMethod) { | |
| 427 ExecutableElement concrete = null; | |
| 428 if (element.kind == ElementKind.METHOD) { | |
| 429 concrete = _enclosingClass.lookUpInheritedConcreteMethod( | |
| 430 element.displayName, _currentLibrary); | |
| 431 } else if (element.kind == ElementKind.GETTER) { | |
| 432 concrete = _enclosingClass.lookUpInheritedConcreteGetter( | |
| 433 element.displayName, _currentLibrary); | |
| 434 } else if (element.kind == ElementKind.SETTER) { | |
| 435 concrete = _enclosingClass.lookUpInheritedConcreteSetter( | |
| 436 element.displayName, _currentLibrary); | |
| 437 } | |
| 438 if (concrete == null) { | |
| 439 _errorReporter.reportTypeErrorForNode( | |
| 440 HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE, | |
| 441 name, | |
| 442 [element.kind.displayName, name.name]); | |
| 443 } | |
| 444 } | |
| 445 } | |
| 446 } | |
| 447 } | |
| 448 | |
| 449 /** | 412 /** |
| 450 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. | 413 * This verifies that the passed expression can be assigned to its correspondi
ng parameters. |
| 451 * | 414 * |
| 452 * This method corresponds to ErrorVerifier.checkForArgumentTypeNotAssignable. | 415 * This method corresponds to ErrorVerifier.checkForArgumentTypeNotAssignable. |
| 453 * | 416 * |
| 454 * TODO (jwren) In the ErrorVerifier there are other warnings that we could ha
ve a corresponding | 417 * TODO (jwren) In the ErrorVerifier there are other warnings that we could ha
ve a corresponding |
| 455 * hint for: see other callers of ErrorVerifier.checkForArgumentTypeNotAssigna
ble(..). | 418 * hint for: see other callers of ErrorVerifier.checkForArgumentTypeNotAssigna
ble(..). |
| 456 * | 419 * |
| 457 * @param expression the expression to evaluate | 420 * @param expression the expression to evaluate |
| 458 * @param expectedStaticType the expected static type of the parameter | 421 * @param expectedStaticType the expected static type of the parameter |
| (...skipping 3862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4321 // dead code analysis | 4284 // dead code analysis |
| 4322 unit.accept( | 4285 unit.accept( |
| 4323 new DeadCodeVerifier(errorReporter, typeSystem: _context.typeSystem)); | 4286 new DeadCodeVerifier(errorReporter, typeSystem: _context.typeSystem)); |
| 4324 unit.accept(_usedLocalElementsVisitor); | 4287 unit.accept(_usedLocalElementsVisitor); |
| 4325 // dart2js analysis | 4288 // dart2js analysis |
| 4326 if (_enableDart2JSHints) { | 4289 if (_enableDart2JSHints) { |
| 4327 unit.accept(new Dart2JSVerifier(errorReporter)); | 4290 unit.accept(new Dart2JSVerifier(errorReporter)); |
| 4328 } | 4291 } |
| 4329 // Dart best practices | 4292 // Dart best practices |
| 4330 unit.accept(new BestPracticesVerifier( | 4293 unit.accept(new BestPracticesVerifier( |
| 4331 errorReporter, _context.typeProvider, _library, _manager, | 4294 errorReporter, _context.typeProvider, _library, |
| 4332 typeSystem: _context.typeSystem)); | 4295 typeSystem: _context.typeSystem)); |
| 4333 unit.accept(new OverrideVerifier(errorReporter, _manager)); | 4296 unit.accept(new OverrideVerifier(errorReporter, _manager)); |
| 4334 // Find to-do comments | 4297 // Find to-do comments |
| 4335 new ToDoFinder(errorReporter).findIn(unit); | 4298 new ToDoFinder(errorReporter).findIn(unit); |
| 4336 // pub analysis | 4299 // pub analysis |
| 4337 // TODO(danrubel/jwren) Commented out until bugs in the pub verifier are | 4300 // TODO(danrubel/jwren) Commented out until bugs in the pub verifier are |
| 4338 // fixed | 4301 // fixed |
| 4339 // unit.accept(new PubVerifier(context, errorReporter)); | 4302 // unit.accept(new PubVerifier(context, errorReporter)); |
| 4340 } | 4303 } |
| 4341 } | 4304 } |
| (...skipping 2971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7313 DartType contextType = node.staticInvokeType; | 7276 DartType contextType = node.staticInvokeType; |
| 7314 if (contextType is FunctionType) { | 7277 if (contextType is FunctionType) { |
| 7315 DartType originalType = node.function.staticType; | 7278 DartType originalType = node.function.staticType; |
| 7316 DartType returnContextType = InferenceContext.getContext(node); | 7279 DartType returnContextType = InferenceContext.getContext(node); |
| 7317 TypeSystem ts = typeSystem; | 7280 TypeSystem ts = typeSystem; |
| 7318 if (returnContextType != null && | 7281 if (returnContextType != null && |
| 7319 node.typeArguments == null && | 7282 node.typeArguments == null && |
| 7320 originalType is FunctionType && | 7283 originalType is FunctionType && |
| 7321 originalType.typeFormals.isNotEmpty && | 7284 originalType.typeFormals.isNotEmpty && |
| 7322 ts is StrongTypeSystemImpl) { | 7285 ts is StrongTypeSystemImpl) { |
| 7323 contextType = ts.inferGenericFunctionCall( | 7286 contextType = ts.inferGenericFunctionCall(typeProvider, originalType, |
| 7324 typeProvider, | 7287 DartType.EMPTY_LIST, DartType.EMPTY_LIST, originalType.returnType, r
eturnContextType); |
| 7325 originalType, | |
| 7326 DartType.EMPTY_LIST, | |
| 7327 DartType.EMPTY_LIST, | |
| 7328 originalType.returnType, | |
| 7329 returnContextType); | |
| 7330 } | 7288 } |
| 7331 | 7289 |
| 7332 InferenceContext.setType(node.argumentList, contextType); | 7290 InferenceContext.setType(node.argumentList, contextType); |
| 7333 } | 7291 } |
| 7334 } | 7292 } |
| 7335 | 7293 |
| 7336 void _inferFormalParameterList(FormalParameterList node, DartType type) { | 7294 void _inferFormalParameterList(FormalParameterList node, DartType type) { |
| 7337 if (typeAnalyzer.inferFormalParameterList(node, type)) { | 7295 if (typeAnalyzer.inferFormalParameterList(node, type)) { |
| 7338 // TODO(leafp): This gets dropped on the floor if we're in the field | 7296 // TODO(leafp): This gets dropped on the floor if we're in the field |
| 7339 // inference task. We should probably keep these infos. | 7297 // inference task. We should probably keep these infos. |
| (...skipping 3894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11234 return null; | 11192 return null; |
| 11235 } | 11193 } |
| 11236 if (identical(node.staticElement, variable)) { | 11194 if (identical(node.staticElement, variable)) { |
| 11237 if (node.inSetterContext()) { | 11195 if (node.inSetterContext()) { |
| 11238 result = true; | 11196 result = true; |
| 11239 } | 11197 } |
| 11240 } | 11198 } |
| 11241 return null; | 11199 return null; |
| 11242 } | 11200 } |
| 11243 } | 11201 } |
| OLD | NEW |