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 |