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 |