Chromium Code Reviews| 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.error_verifier; | 5 library analyzer.src.generated.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/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 */ | 269 */ |
| 270 HashMap<String, Element> _exportedElements = new HashMap<String, Element>(); | 270 HashMap<String, Element> _exportedElements = new HashMap<String, Element>(); |
| 271 | 271 |
| 272 /** | 272 /** |
| 273 * A set of the names of the variable initializers we are visiting now. | 273 * A set of the names of the variable initializers we are visiting now. |
| 274 */ | 274 */ |
| 275 HashSet<String> _namesForReferenceToDeclaredVariableInInitializer = | 275 HashSet<String> _namesForReferenceToDeclaredVariableInInitializer = |
| 276 new HashSet<String>(); | 276 new HashSet<String>(); |
| 277 | 277 |
| 278 /** | 278 /** |
| 279 * The elements that will be defined later in the current scope, but right | |
| 280 * now are not declared. | |
| 281 */ | |
| 282 HiddenElements _hiddenElements = null; | |
| 283 | |
| 284 /** | |
| 279 * A list of types used by the [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS] | 285 * A list of types used by the [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS] |
| 280 * and [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS] error codes. | 286 * and [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS] error codes. |
| 281 */ | 287 */ |
| 282 List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT; | 288 List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT; |
| 283 | 289 |
| 284 /** | 290 /** |
| 285 * If `true`, mixins are allowed to inherit from types other than Object, and | 291 * If `true`, mixins are allowed to inherit from types other than Object, and |
| 286 * are allowed to reference `super`. | 292 * are allowed to reference `super`. |
| 287 */ | 293 */ |
| 288 final bool enableSuperMixins; | 294 final bool enableSuperMixins; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 381 _checkForAssignability(node.rightOperand, _boolType, | 387 _checkForAssignability(node.rightOperand, _boolType, |
| 382 StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]); | 388 StaticTypeWarningCode.NON_BOOL_OPERAND, [lexeme]); |
| 383 } else { | 389 } else { |
| 384 _checkForArgumentTypeNotAssignableForArgument(node.rightOperand); | 390 _checkForArgumentTypeNotAssignableForArgument(node.rightOperand); |
| 385 } | 391 } |
| 386 return super.visitBinaryExpression(node); | 392 return super.visitBinaryExpression(node); |
| 387 } | 393 } |
| 388 | 394 |
| 389 @override | 395 @override |
| 390 Object visitBlock(Block node) { | 396 Object visitBlock(Block node) { |
| 391 _checkDuplicateDeclarationInStatements(node.statements); | 397 _hiddenElements = new HiddenElements(_hiddenElements, node); |
| 392 return super.visitBlock(node); | 398 try { |
| 399 _checkDuplicateDeclarationInStatements(node.statements); | |
| 400 return super.visitBlock(node); | |
| 401 } finally { | |
| 402 _hiddenElements = _hiddenElements.outerElements; | |
| 403 } | |
| 393 } | 404 } |
| 394 | 405 |
| 395 @override | 406 @override |
| 396 Object visitBlockFunctionBody(BlockFunctionBody node) { | 407 Object visitBlockFunctionBody(BlockFunctionBody node) { |
| 397 bool wasInAsync = _inAsync; | 408 bool wasInAsync = _inAsync; |
| 398 bool wasInGenerator = _inGenerator; | 409 bool wasInGenerator = _inGenerator; |
| 399 bool previousHasReturnWithoutValue = _hasReturnWithoutValue; | 410 bool previousHasReturnWithoutValue = _hasReturnWithoutValue; |
| 400 _hasReturnWithoutValue = false; | 411 _hasReturnWithoutValue = false; |
| 401 List<ReturnStatement> previousReturnsWith = _returnsWith; | 412 List<ReturnStatement> previousReturnsWith = _returnsWith; |
| 402 List<ReturnStatement> previousReturnsWithout = _returnsWithout; | 413 List<ReturnStatement> previousReturnsWithout = _returnsWithout; |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 740 _checkForNonBoolCondition(node.condition); | 751 _checkForNonBoolCondition(node.condition); |
| 741 } | 752 } |
| 742 if (node.variables != null) { | 753 if (node.variables != null) { |
| 743 _checkDuplicateVariables(node.variables); | 754 _checkDuplicateVariables(node.variables); |
| 744 } | 755 } |
| 745 return super.visitForStatement(node); | 756 return super.visitForStatement(node); |
| 746 } | 757 } |
| 747 | 758 |
| 748 @override | 759 @override |
| 749 Object visitFunctionDeclaration(FunctionDeclaration node) { | 760 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 761 ExecutableElement functionElement = node.element; | |
| 762 if (functionElement != null && | |
| 763 functionElement.enclosingElement is! CompilationUnitElement) { | |
| 764 _hiddenElements.declare(functionElement); | |
| 765 } | |
| 750 ExecutableElement outerFunction = _enclosingFunction; | 766 ExecutableElement outerFunction = _enclosingFunction; |
| 751 try { | 767 try { |
| 752 SimpleIdentifier identifier = node.name; | 768 SimpleIdentifier identifier = node.name; |
| 753 String methodName = ""; | 769 String methodName = ""; |
| 754 if (identifier != null) { | 770 if (identifier != null) { |
| 755 methodName = identifier.name; | 771 methodName = identifier.name; |
| 756 } | 772 } |
| 757 _enclosingFunction = node.element; | 773 _enclosingFunction = functionElement; |
| 758 TypeName returnType = node.returnType; | 774 TypeName returnType = node.returnType; |
| 759 if (node.isSetter || node.isGetter) { | 775 if (node.isSetter || node.isGetter) { |
| 760 _checkForMismatchedAccessorTypes(node, methodName); | 776 _checkForMismatchedAccessorTypes(node, methodName); |
| 761 if (node.isSetter) { | 777 if (node.isSetter) { |
| 762 FunctionExpression functionExpression = node.functionExpression; | 778 FunctionExpression functionExpression = node.functionExpression; |
| 763 if (functionExpression != null) { | 779 if (functionExpression != null) { |
| 764 _checkForWrongNumberOfParametersForSetter( | 780 _checkForWrongNumberOfParametersForSetter( |
| 765 identifier, functionExpression.parameters); | 781 identifier, functionExpression.parameters); |
| 766 } | 782 } |
| 767 _checkForNonVoidReturnTypeForSetter(returnType); | 783 _checkForNonVoidReturnTypeForSetter(returnType); |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1104 // - DefaultFormalParameter contains a simple one, so it gets here, | 1120 // - DefaultFormalParameter contains a simple one, so it gets here, |
| 1105 // - FieldFormalParameter error should be reported on the field, | 1121 // - FieldFormalParameter error should be reported on the field, |
| 1106 // - FunctionTypedFormalParameter is a function type, not dynamic. | 1122 // - FunctionTypedFormalParameter is a function type, not dynamic. |
| 1107 _checkForImplicitDynamicIdentifier(node, node.identifier); | 1123 _checkForImplicitDynamicIdentifier(node, node.identifier); |
| 1108 | 1124 |
| 1109 return super.visitSimpleFormalParameter(node); | 1125 return super.visitSimpleFormalParameter(node); |
| 1110 } | 1126 } |
| 1111 | 1127 |
| 1112 @override | 1128 @override |
| 1113 Object visitSimpleIdentifier(SimpleIdentifier node) { | 1129 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 1130 _checkForReferenceBeforeDeclaration(node); | |
| 1114 _checkForImplicitThisReferenceInInitializer(node); | 1131 _checkForImplicitThisReferenceInInitializer(node); |
| 1115 if (!_isUnqualifiedReferenceToNonLocalStaticMemberAllowed(node)) { | 1132 if (!_isUnqualifiedReferenceToNonLocalStaticMemberAllowed(node)) { |
| 1116 _checkForUnqualifiedReferenceToNonLocalStaticMember(node); | 1133 _checkForUnqualifiedReferenceToNonLocalStaticMember(node); |
| 1117 } | 1134 } |
| 1118 return super.visitSimpleIdentifier(node); | 1135 return super.visitSimpleIdentifier(node); |
| 1119 } | 1136 } |
| 1120 | 1137 |
| 1121 @override | 1138 @override |
| 1122 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { | 1139 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { |
| 1123 _isInConstructorInitializer = true; | 1140 _isInConstructorInitializer = true; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1213 bool wasInInstanceVariableInitializer = _isInInstanceVariableInitializer; | 1230 bool wasInInstanceVariableInitializer = _isInInstanceVariableInitializer; |
| 1214 _isInInstanceVariableInitializer = _isInInstanceVariableDeclaration; | 1231 _isInInstanceVariableInitializer = _isInInstanceVariableDeclaration; |
| 1215 try { | 1232 try { |
| 1216 if (initializerNode != null) { | 1233 if (initializerNode != null) { |
| 1217 initializerNode.accept(this); | 1234 initializerNode.accept(this); |
| 1218 } | 1235 } |
| 1219 } finally { | 1236 } finally { |
| 1220 _isInInstanceVariableInitializer = wasInInstanceVariableInitializer; | 1237 _isInInstanceVariableInitializer = wasInInstanceVariableInitializer; |
| 1221 _namesForReferenceToDeclaredVariableInInitializer.remove(name); | 1238 _namesForReferenceToDeclaredVariableInInitializer.remove(name); |
| 1222 } | 1239 } |
| 1240 // declare the variable | |
| 1241 AstNode grandparent = node.parent.parent; | |
| 1242 if (grandparent is! TopLevelVariableDeclaration && | |
| 1243 grandparent is! FieldDeclaration) { | |
| 1244 VariableElement element = node.element; | |
| 1245 if (element != null) { | |
| 1246 _hiddenElements.declare(element); | |
| 1247 } | |
| 1248 } | |
| 1223 // done | 1249 // done |
| 1224 return null; | 1250 return null; |
| 1225 } | 1251 } |
| 1226 | 1252 |
| 1227 @override | 1253 @override |
| 1228 Object visitVariableDeclarationList(VariableDeclarationList node) { | 1254 Object visitVariableDeclarationList(VariableDeclarationList node) { |
| 1229 _checkForTypeAnnotationDeferredClass(node.type); | 1255 _checkForTypeAnnotationDeferredClass(node.type); |
| 1230 return super.visitVariableDeclarationList(node); | 1256 return super.visitVariableDeclarationList(node); |
| 1231 } | 1257 } |
| 1232 | 1258 |
| (...skipping 4180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5413 // OK, it is also 'const' | 5439 // OK, it is also 'const' |
| 5414 if (redirectedConstructor.isConst) { | 5440 if (redirectedConstructor.isConst) { |
| 5415 return; | 5441 return; |
| 5416 } | 5442 } |
| 5417 | 5443 |
| 5418 _errorReporter.reportErrorForNode( | 5444 _errorReporter.reportErrorForNode( |
| 5419 CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, | 5445 CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, |
| 5420 redirectedConstructorNode); | 5446 redirectedConstructorNode); |
| 5421 } | 5447 } |
| 5422 | 5448 |
| 5449 void _checkForReferenceBeforeDeclaration(SimpleIdentifier node) { | |
| 5450 if (!node.inDeclarationContext() && | |
| 5451 _hiddenElements != null && | |
| 5452 _hiddenElements.contains(node.staticElement)) { | |
| 5453 _errorReporter.reportErrorForNode( | |
| 5454 CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, | |
| 5455 node, | |
| 5456 [node.name]); | |
| 5457 } | |
| 5458 } | |
| 5459 | |
| 5423 /** | 5460 /** |
| 5424 * Check that the given rethrow [expression] is inside of a catch clause. | 5461 * Check that the given rethrow [expression] is inside of a catch clause. |
| 5425 * | 5462 * |
| 5426 * See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]. | 5463 * See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]. |
| 5427 */ | 5464 */ |
| 5428 void _checkForRethrowOutsideCatch(RethrowExpression expression) { | 5465 void _checkForRethrowOutsideCatch(RethrowExpression expression) { |
| 5429 if (!_isInCatchClause) { | 5466 if (!_isInCatchClause) { |
| 5430 _errorReporter.reportErrorForNode( | 5467 _errorReporter.reportErrorForNode( |
| 5431 CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, expression); | 5468 CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, expression); |
| 5432 } | 5469 } |
| (...skipping 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6602 // type arguments | 6639 // type arguments |
| 6603 if (type is InterfaceType) { | 6640 if (type is InterfaceType) { |
| 6604 for (DartType typeArgument in type.typeArguments) { | 6641 for (DartType typeArgument in type.typeArguments) { |
| 6605 _addTypeToCheck(typeArgument); | 6642 _addTypeToCheck(typeArgument); |
| 6606 } | 6643 } |
| 6607 } | 6644 } |
| 6608 } | 6645 } |
| 6609 } | 6646 } |
| 6610 | 6647 |
| 6611 /** | 6648 /** |
| 6649 * A record of the elements that will be declared in some scope (block), but are | |
| 6650 * not yet declared. | |
| 6651 */ | |
| 6652 class HiddenElements { | |
| 6653 /** | |
| 6654 * The elements hidden in outer scopes, or `null` if this is the outermost | |
| 6655 * scope. | |
| 6656 */ | |
| 6657 final HiddenElements outerElements; | |
| 6658 | |
| 6659 /** | |
| 6660 * A set containing the elements that will be declared in this scope, but are | |
| 6661 * not yet declared. | |
| 6662 */ | |
| 6663 Set<Element> _elements = new HashSet<Element>(); | |
| 6664 | |
| 6665 /** | |
| 6666 * Initialize a newly created set of hidden elements to include all of the | |
| 6667 * elements defined in the set of [outerElements] and all of the elements | |
| 6668 * declared in the given [block]. | |
| 6669 */ | |
| 6670 HiddenElements(this.outerElements, Block block) { | |
| 6671 _initializeElements(block); | |
| 6672 } | |
| 6673 | |
| 6674 /** | |
| 6675 * Return `true` if this set of elements contains the given [element]. | |
| 6676 */ | |
| 6677 bool contains(Element element) { | |
| 6678 if (_elements.contains(element)) { | |
| 6679 return true; | |
| 6680 } else if (outerElements != null) { | |
| 6681 return outerElements.contains(element); | |
| 6682 } | |
| 6683 return false; | |
| 6684 } | |
| 6685 | |
| 6686 /** | |
| 6687 * Record that the given [element] has been declared, so it is no longer | |
| 6688 * hidden. | |
| 6689 */ | |
| 6690 void declare(Element element) { | |
| 6691 _elements.remove(element); | |
| 6692 } | |
| 6693 | |
| 6694 /** | |
| 6695 * Initialize the list of elements that are not yet declared to be all of the | |
| 6696 * elements declared somewhere in the given [block]. | |
| 6697 */ | |
| 6698 void _initializeElements(Block block) { | |
| 6699 for (var element in BlockScope.elementsInBlock(block)) { | |
| 6700 _elements.add(element); | |
| 6701 } | |
|
scheglov
2016/09/02 23:46:50
I think here it also could be written more concise
Brian Wilkerson
2016/09/03 17:12:37
I went with "_elements.addAll(BlockScope.elementsI
| |
| 6702 } | |
| 6703 } | |
| 6704 | |
| 6705 /** | |
| 6612 * A class used to compute a list of the constants whose value needs to be | 6706 * A class used to compute a list of the constants whose value needs to be |
| 6613 * computed before errors can be computed by the [VerifyUnitTask]. | 6707 * computed before errors can be computed by the [VerifyUnitTask]. |
| 6614 */ | 6708 */ |
| 6615 class RequiredConstantsComputer extends RecursiveAstVisitor { | 6709 class RequiredConstantsComputer extends RecursiveAstVisitor { |
| 6616 /** | 6710 /** |
| 6617 * The source with which any pending errors will be associated. | 6711 * The source with which any pending errors will be associated. |
| 6618 */ | 6712 */ |
| 6619 final Source source; | 6713 final Source source; |
| 6620 | 6714 |
| 6621 /** | 6715 /** |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6722 class _InvocationCollector extends RecursiveAstVisitor { | 6816 class _InvocationCollector extends RecursiveAstVisitor { |
| 6723 final List<String> superCalls = <String>[]; | 6817 final List<String> superCalls = <String>[]; |
| 6724 | 6818 |
| 6725 @override | 6819 @override |
| 6726 visitMethodInvocation(MethodInvocation node) { | 6820 visitMethodInvocation(MethodInvocation node) { |
| 6727 if (node.target is SuperExpression) { | 6821 if (node.target is SuperExpression) { |
| 6728 superCalls.add(node.methodName.name); | 6822 superCalls.add(node.methodName.name); |
| 6729 } | 6823 } |
| 6730 } | 6824 } |
| 6731 } | 6825 } |
| OLD | NEW |