Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(233)

Side by Side Diff: pkg/analyzer/lib/src/generated/error_verifier.dart

Issue 2306223002: Move more error detection out of Scope (Closed)
Patch Set: clean-up Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698