| 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 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 * [StaticWarningCode.MIXED_RETURN_TYPES] and | 191 * [StaticWarningCode.MIXED_RETURN_TYPES] and |
| 192 * [StaticWarningCode.RETURN_WITHOUT_VALUE] from being generated in the same | 192 * [StaticWarningCode.RETURN_WITHOUT_VALUE] from being generated in the same |
| 193 * function body. | 193 * function body. |
| 194 */ | 194 */ |
| 195 bool _hasReturnWithoutValue = false; | 195 bool _hasReturnWithoutValue = false; |
| 196 | 196 |
| 197 /** | 197 /** |
| 198 * The class containing the AST nodes being visited, or `null` if we are not | 198 * The class containing the AST nodes being visited, or `null` if we are not |
| 199 * in the scope of a class. | 199 * in the scope of a class. |
| 200 */ | 200 */ |
| 201 ClassElement _enclosingClass; | 201 ClassElementImpl _enclosingClass; |
| 202 | 202 |
| 203 /** | 203 /** |
| 204 * The method or function that we are currently visiting, or `null` if we are | 204 * The method or function that we are currently visiting, or `null` if we are |
| 205 * not inside a method or function. | 205 * not inside a method or function. |
| 206 */ | 206 */ |
| 207 ExecutableElement _enclosingFunction; | 207 ExecutableElement _enclosingFunction; |
| 208 | 208 |
| 209 /** | 209 /** |
| 210 * The return statements found in the method or function that we are currently | 210 * The return statements found in the method or function that we are currently |
| 211 * visiting that have a return value. | 211 * visiting that have a return value. |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 _isInCatchClause = true; | 413 _isInCatchClause = true; |
| 414 _checkForTypeAnnotationDeferredClass(node.exceptionType); | 414 _checkForTypeAnnotationDeferredClass(node.exceptionType); |
| 415 return super.visitCatchClause(node); | 415 return super.visitCatchClause(node); |
| 416 } finally { | 416 } finally { |
| 417 _isInCatchClause = previousIsInCatchClause; | 417 _isInCatchClause = previousIsInCatchClause; |
| 418 } | 418 } |
| 419 } | 419 } |
| 420 | 420 |
| 421 @override | 421 @override |
| 422 Object visitClassDeclaration(ClassDeclaration node) { | 422 Object visitClassDeclaration(ClassDeclaration node) { |
| 423 ClassElement outerClass = _enclosingClass; | 423 ClassElementImpl outerClass = _enclosingClass; |
| 424 try { | 424 try { |
| 425 _isInNativeClass = node.nativeClause != null; | 425 _isInNativeClass = node.nativeClause != null; |
| 426 _enclosingClass = node.element; | 426 _enclosingClass = ClassElementImpl.getImpl(node.element); |
| 427 ExtendsClause extendsClause = node.extendsClause; | 427 ExtendsClause extendsClause = node.extendsClause; |
| 428 ImplementsClause implementsClause = node.implementsClause; | 428 ImplementsClause implementsClause = node.implementsClause; |
| 429 WithClause withClause = node.withClause; | 429 WithClause withClause = node.withClause; |
| 430 _checkForBuiltInIdentifierAsName( | 430 _checkForBuiltInIdentifierAsName( |
| 431 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME); | 431 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE_NAME); |
| 432 _checkForMemberWithClassName(); | 432 _checkForMemberWithClassName(); |
| 433 _checkForNoDefaultSuperConstructorImplicit(node); | 433 _checkForNoDefaultSuperConstructorImplicit(node); |
| 434 _checkForConflictingTypeVariableErrorCodes(node); | 434 _checkForConflictingTypeVariableErrorCodes(node); |
| 435 // Only do error checks on the clause nodes if there is a non-null clause | 435 // Only do error checks on the clause nodes if there is a non-null clause |
| 436 if (implementsClause != null || | 436 if (implementsClause != null || |
| (...skipping 28 matching lines...) Expand all Loading... |
| 465 _enclosingClass = outerClass; | 465 _enclosingClass = outerClass; |
| 466 } | 466 } |
| 467 } | 467 } |
| 468 | 468 |
| 469 /** | 469 /** |
| 470 * Implementation of this method should be synchronized with | 470 * Implementation of this method should be synchronized with |
| 471 * [visitClassDeclaration]. | 471 * [visitClassDeclaration]. |
| 472 */ | 472 */ |
| 473 void visitClassDeclarationIncrementally(ClassDeclaration node) { | 473 void visitClassDeclarationIncrementally(ClassDeclaration node) { |
| 474 _isInNativeClass = node.nativeClause != null; | 474 _isInNativeClass = node.nativeClause != null; |
| 475 _enclosingClass = node.element; | 475 _enclosingClass = ClassElementImpl.getImpl(node.element); |
| 476 // initialize initialFieldElementsMap | 476 // initialize initialFieldElementsMap |
| 477 if (_enclosingClass != null) { | 477 if (_enclosingClass != null) { |
| 478 List<FieldElement> fieldElements = _enclosingClass.fields; | 478 List<FieldElement> fieldElements = _enclosingClass.fields; |
| 479 _initialFieldElementsMap = new HashMap<FieldElement, INIT_STATE>(); | 479 _initialFieldElementsMap = new HashMap<FieldElement, INIT_STATE>(); |
| 480 for (FieldElement fieldElement in fieldElements) { | 480 for (FieldElement fieldElement in fieldElements) { |
| 481 if (!fieldElement.isSynthetic) { | 481 if (!fieldElement.isSynthetic) { |
| 482 _initialFieldElementsMap[fieldElement] = fieldElement.initializer == | 482 _initialFieldElementsMap[fieldElement] = fieldElement.initializer == |
| 483 null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; | 483 null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; |
| 484 } | 484 } |
| 485 } | 485 } |
| 486 } | 486 } |
| 487 } | 487 } |
| 488 | 488 |
| 489 @override | 489 @override |
| 490 Object visitClassTypeAlias(ClassTypeAlias node) { | 490 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 491 _checkForBuiltInIdentifierAsName( | 491 _checkForBuiltInIdentifierAsName( |
| 492 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); | 492 node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME); |
| 493 ClassElement outerClassElement = _enclosingClass; | 493 ClassElementImpl outerClassElement = _enclosingClass; |
| 494 try { | 494 try { |
| 495 _enclosingClass = node.element; | 495 _enclosingClass = ClassElementImpl.getImpl(node.element); |
| 496 ImplementsClause implementsClause = node.implementsClause; | 496 ImplementsClause implementsClause = node.implementsClause; |
| 497 // Only check for all of the inheritance logic around clauses if there | 497 // Only check for all of the inheritance logic around clauses if there |
| 498 // isn't an error code such as "Cannot extend double" already on the | 498 // isn't an error code such as "Cannot extend double" already on the |
| 499 // class. | 499 // class. |
| 500 if (!_checkForExtendsDisallowedClassInTypeAlias(node) && | 500 if (!_checkForExtendsDisallowedClassInTypeAlias(node) && |
| 501 !_checkForImplementsDisallowedClass(implementsClause) && | 501 !_checkForImplementsDisallowedClass(implementsClause) && |
| 502 !_checkForAllMixinErrorCodes(node.withClause)) { | 502 !_checkForAllMixinErrorCodes(node.withClause)) { |
| 503 _checkForExtendsDeferredClassInTypeAlias(node); | 503 _checkForExtendsDeferredClassInTypeAlias(node); |
| 504 _checkForImplementsDeferredClass(implementsClause); | 504 _checkForImplementsDeferredClass(implementsClause); |
| 505 _checkForRecursiveInterfaceInheritance(_enclosingClass); | 505 _checkForRecursiveInterfaceInheritance(_enclosingClass); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 } | 601 } |
| 602 | 602 |
| 603 @override | 603 @override |
| 604 Object visitDoStatement(DoStatement node) { | 604 Object visitDoStatement(DoStatement node) { |
| 605 _checkForNonBoolCondition(node.condition); | 605 _checkForNonBoolCondition(node.condition); |
| 606 return super.visitDoStatement(node); | 606 return super.visitDoStatement(node); |
| 607 } | 607 } |
| 608 | 608 |
| 609 @override | 609 @override |
| 610 Object visitEnumDeclaration(EnumDeclaration node) { | 610 Object visitEnumDeclaration(EnumDeclaration node) { |
| 611 ClassElement outerClass = _enclosingClass; | 611 ClassElementImpl outerClass = _enclosingClass; |
| 612 try { | 612 try { |
| 613 _isInNativeClass = false; | 613 _isInNativeClass = false; |
| 614 _enclosingClass = node.element; | 614 _enclosingClass = ClassElementImpl.getImpl(node.element); |
| 615 return super.visitEnumDeclaration(node); | 615 return super.visitEnumDeclaration(node); |
| 616 } finally { | 616 } finally { |
| 617 _enclosingClass = outerClass; | 617 _enclosingClass = outerClass; |
| 618 } | 618 } |
| 619 } | 619 } |
| 620 | 620 |
| 621 @override | 621 @override |
| 622 Object visitExportDirective(ExportDirective node) { | 622 Object visitExportDirective(ExportDirective node) { |
| 623 ExportElement exportElement = node.element; | 623 ExportElement exportElement = node.element; |
| 624 if (exportElement != null) { | 624 if (exportElement != null) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 674 Object visitFieldFormalParameter(FieldFormalParameter node) { | 674 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 675 _checkForValidField(node); | 675 _checkForValidField(node); |
| 676 _checkForConstFormalParameter(node); | 676 _checkForConstFormalParameter(node); |
| 677 _checkForPrivateOptionalParameter(node); | 677 _checkForPrivateOptionalParameter(node); |
| 678 _checkForFieldInitializingFormalRedirectingConstructor(node); | 678 _checkForFieldInitializingFormalRedirectingConstructor(node); |
| 679 _checkForTypeAnnotationDeferredClass(node.type); | 679 _checkForTypeAnnotationDeferredClass(node.type); |
| 680 return super.visitFieldFormalParameter(node); | 680 return super.visitFieldFormalParameter(node); |
| 681 } | 681 } |
| 682 | 682 |
| 683 @override | 683 @override |
| 684 Object visitForEachStatement(ForEachStatement node) { |
| 685 _checkForInIterable(node); |
| 686 return super.visitForEachStatement(node); |
| 687 } |
| 688 |
| 689 @override |
| 684 Object visitForStatement(ForStatement node) { | 690 Object visitForStatement(ForStatement node) { |
| 685 if (node.condition != null) { | 691 if (node.condition != null) { |
| 686 _checkForNonBoolCondition(node.condition); | 692 _checkForNonBoolCondition(node.condition); |
| 687 } | 693 } |
| 688 return super.visitForStatement(node); | 694 return super.visitForStatement(node); |
| 689 } | 695 } |
| 690 | 696 |
| 691 @override | 697 @override |
| 692 Object visitForEachStatement(ForEachStatement node) { | |
| 693 _checkForInIterable(node); | |
| 694 return super.visitForEachStatement(node); | |
| 695 } | |
| 696 | |
| 697 @override | |
| 698 Object visitFunctionDeclaration(FunctionDeclaration node) { | 698 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 699 ExecutableElement outerFunction = _enclosingFunction; | 699 ExecutableElement outerFunction = _enclosingFunction; |
| 700 try { | 700 try { |
| 701 SimpleIdentifier identifier = node.name; | 701 SimpleIdentifier identifier = node.name; |
| 702 String methodName = ""; | 702 String methodName = ""; |
| 703 if (identifier != null) { | 703 if (identifier != null) { |
| 704 methodName = identifier.name; | 704 methodName = identifier.name; |
| 705 } | 705 } |
| 706 _enclosingFunction = node.element; | 706 _enclosingFunction = node.element; |
| 707 TypeName returnType = node.returnType; | 707 TypeName returnType = node.returnType; |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 */ | 1156 */ |
| 1157 void _checkAssertMessage(AssertStatement statement) { | 1157 void _checkAssertMessage(AssertStatement statement) { |
| 1158 Expression expression = statement.message; | 1158 Expression expression = statement.message; |
| 1159 if (expression != null && !enableAssertMessage) { | 1159 if (expression != null && !enableAssertMessage) { |
| 1160 _errorReporter.reportErrorForNode( | 1160 _errorReporter.reportErrorForNode( |
| 1161 CompileTimeErrorCode.EXTRA_ARGUMENT_TO_ASSERT, expression); | 1161 CompileTimeErrorCode.EXTRA_ARGUMENT_TO_ASSERT, expression); |
| 1162 } | 1162 } |
| 1163 } | 1163 } |
| 1164 | 1164 |
| 1165 /** | 1165 /** |
| 1166 * Given a list of [directives] that have the same prefix, generate an error |
| 1167 * if there is more than one import and any of those imports is deferred. |
| 1168 * |
| 1169 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. |
| 1170 */ |
| 1171 void _checkDeferredPrefixCollision(List<ImportDirective> directives) { |
| 1172 int count = directives.length; |
| 1173 if (count > 1) { |
| 1174 for (int i = 0; i < count; i++) { |
| 1175 Token deferredToken = directives[i].deferredKeyword; |
| 1176 if (deferredToken != null) { |
| 1177 _errorReporter.reportErrorForToken( |
| 1178 CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken); |
| 1179 } |
| 1180 } |
| 1181 } |
| 1182 } |
| 1183 |
| 1184 /** |
| 1166 * Verify that the given list of [typeArguments] contains exactly two | 1185 * Verify that the given list of [typeArguments] contains exactly two |
| 1167 * elements. | 1186 * elements. |
| 1168 * | 1187 * |
| 1169 * See [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]. | 1188 * See [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]. |
| 1170 */ | 1189 */ |
| 1171 void _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { | 1190 void _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { |
| 1172 int num = typeArguments.arguments.length; | 1191 int num = typeArguments.arguments.length; |
| 1173 if (num != 2) { | 1192 if (num != 2) { |
| 1174 _errorReporter.reportErrorForNode( | 1193 _errorReporter.reportErrorForNode( |
| 1175 StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, | 1194 StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, |
| (...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1716 VariableDeclarationList fields = declaration.fields; | 1735 VariableDeclarationList fields = declaration.fields; |
| 1717 for (VariableDeclaration field in fields.variables) { | 1736 for (VariableDeclaration field in fields.variables) { |
| 1718 FieldElement element = field.element as FieldElement; | 1737 FieldElement element = field.element as FieldElement; |
| 1719 if (element == null) { | 1738 if (element == null) { |
| 1720 continue; | 1739 continue; |
| 1721 } | 1740 } |
| 1722 PropertyAccessorElement getter = element.getter; | 1741 PropertyAccessorElement getter = element.getter; |
| 1723 PropertyAccessorElement setter = element.setter; | 1742 PropertyAccessorElement setter = element.setter; |
| 1724 SimpleIdentifier fieldName = field.name; | 1743 SimpleIdentifier fieldName = field.name; |
| 1725 if (getter != null) { | 1744 if (getter != null) { |
| 1726 _checkForAllInvalidOverrideErrorCodesForExecutable(getter, | 1745 _checkForAllInvalidOverrideErrorCodesForExecutable( |
| 1727 ParameterElement.EMPTY_LIST, AstNode.EMPTY_LIST, fieldName); | 1746 getter, ParameterElement.EMPTY_LIST, AstNode.EMPTY_LIST, fieldName); |
| 1728 } | 1747 } |
| 1729 if (setter != null) { | 1748 if (setter != null) { |
| 1730 _checkForAllInvalidOverrideErrorCodesForExecutable( | 1749 _checkForAllInvalidOverrideErrorCodesForExecutable( |
| 1731 setter, setter.parameters, <AstNode>[fieldName], fieldName); | 1750 setter, setter.parameters, <AstNode>[fieldName], fieldName); |
| 1732 } | 1751 } |
| 1733 } | 1752 } |
| 1734 } | 1753 } |
| 1735 | 1754 |
| 1736 /** | 1755 /** |
| 1737 * Check the given [method] declaration against override-error codes. | 1756 * Check the given [method] declaration against override-error codes. |
| (...skipping 1863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3601 if (errors == null || errors.isEmpty) { | 3620 if (errors == null || errors.isEmpty) { |
| 3602 return; | 3621 return; |
| 3603 } | 3622 } |
| 3604 for (AnalysisError error in errors) { | 3623 for (AnalysisError error in errors) { |
| 3605 _errorReporter.reportError(error); | 3624 _errorReporter.reportError(error); |
| 3606 } | 3625 } |
| 3607 return; | 3626 return; |
| 3608 } | 3627 } |
| 3609 | 3628 |
| 3610 /** | 3629 /** |
| 3630 * Check for a type mis-match between the iterable expression and the |
| 3631 * assigned variable in a for-in statement. |
| 3632 */ |
| 3633 void _checkForInIterable(ForEachStatement node) { |
| 3634 // Ignore malformed for statements. |
| 3635 if (node.identifier == null && node.loopVariable == null) { |
| 3636 return; |
| 3637 } |
| 3638 |
| 3639 DartType iterableType = getStaticType(node.iterable); |
| 3640 if (iterableType.isDynamic) { |
| 3641 return; |
| 3642 } |
| 3643 |
| 3644 // The type of the loop variable. |
| 3645 SimpleIdentifier variable = node.identifier != null |
| 3646 ? node.identifier |
| 3647 : node.loopVariable.identifier; |
| 3648 DartType variableType = getStaticType(variable); |
| 3649 |
| 3650 DartType loopType = node.awaitKeyword != null |
| 3651 ? _typeProvider.streamType |
| 3652 : _typeProvider.iterableType; |
| 3653 |
| 3654 // Use an explicit string instead of [loopType] to remove the "<E>". |
| 3655 String loopTypeName = node.awaitKeyword != null ? "Stream" : "Iterable"; |
| 3656 |
| 3657 // The object being iterated has to implement Iterable<T> for some T that |
| 3658 // is assignable to the variable's type. |
| 3659 // TODO(rnystrom): Move this into mostSpecificTypeArgument()? |
| 3660 iterableType = iterableType.resolveToBound(_typeProvider.objectType); |
| 3661 DartType bestIterableType = |
| 3662 _typeSystem.mostSpecificTypeArgument(iterableType, loopType); |
| 3663 |
| 3664 // Allow it to be a supertype of Iterable<T> (basically just Object) and do |
| 3665 // an implicit downcast to Iterable<dynamic>. |
| 3666 if (bestIterableType == null) { |
| 3667 if (_typeSystem.isSubtypeOf(loopType, iterableType)) { |
| 3668 bestIterableType = DynamicTypeImpl.instance; |
| 3669 } |
| 3670 } |
| 3671 |
| 3672 if (bestIterableType == null) { |
| 3673 _errorReporter.reportTypeErrorForNode( |
| 3674 StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE, |
| 3675 node.iterable, |
| 3676 [iterableType, loopTypeName]); |
| 3677 } else if (!_typeSystem.isAssignableTo(bestIterableType, variableType)) { |
| 3678 _errorReporter.reportTypeErrorForNode( |
| 3679 StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE, |
| 3680 node.iterable, |
| 3681 [iterableType, loopTypeName, variableType]); |
| 3682 } |
| 3683 } |
| 3684 |
| 3685 /** |
| 3611 * Check that the given [typeReference] is not a type reference and that then | 3686 * Check that the given [typeReference] is not a type reference and that then |
| 3612 * the [name] is reference to an instance member. | 3687 * the [name] is reference to an instance member. |
| 3613 * | 3688 * |
| 3614 * See [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]. | 3689 * See [StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER]. |
| 3615 */ | 3690 */ |
| 3616 void _checkForInstanceAccessToStaticMember( | 3691 void _checkForInstanceAccessToStaticMember( |
| 3617 ClassElement typeReference, SimpleIdentifier name) { | 3692 ClassElement typeReference, SimpleIdentifier name) { |
| 3618 // OK, in comment | 3693 // OK, in comment |
| 3619 if (_isInComment) { | 3694 if (_isInComment) { |
| 3620 return; | 3695 return; |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4125 * that both have and do not have return values. | 4200 * that both have and do not have return values. |
| 4126 * | 4201 * |
| 4127 * See [StaticWarningCode.MIXED_RETURN_TYPES]. | 4202 * See [StaticWarningCode.MIXED_RETURN_TYPES]. |
| 4128 */ | 4203 */ |
| 4129 void _checkForMixedReturns(BlockFunctionBody body) { | 4204 void _checkForMixedReturns(BlockFunctionBody body) { |
| 4130 if (_hasReturnWithoutValue) { | 4205 if (_hasReturnWithoutValue) { |
| 4131 return; | 4206 return; |
| 4132 } | 4207 } |
| 4133 if (_returnsWith.isNotEmpty && _returnsWithout.isNotEmpty) { | 4208 if (_returnsWith.isNotEmpty && _returnsWithout.isNotEmpty) { |
| 4134 for (ReturnStatement returnWith in _returnsWith) { | 4209 for (ReturnStatement returnWith in _returnsWith) { |
| 4135 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, | 4210 _errorReporter.reportErrorForToken( |
| 4136 returnWith.returnKeyword); | 4211 StaticWarningCode.MIXED_RETURN_TYPES, returnWith.returnKeyword); |
| 4137 } | 4212 } |
| 4138 for (ReturnStatement returnWithout in _returnsWithout) { | 4213 for (ReturnStatement returnWithout in _returnsWithout) { |
| 4139 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, | 4214 _errorReporter.reportErrorForToken( |
| 4140 returnWithout.returnKeyword); | 4215 StaticWarningCode.MIXED_RETURN_TYPES, returnWithout.returnKeyword); |
| 4141 } | 4216 } |
| 4142 } | 4217 } |
| 4143 } | 4218 } |
| 4144 | 4219 |
| 4145 /** | 4220 /** |
| 4146 * Verify that the given mixin does not have an explicitly declared | 4221 * Verify that the given mixin does not have an explicitly declared |
| 4147 * constructor. The [mixinName] is the node to report problem on. The | 4222 * constructor. The [mixinName] is the node to report problem on. The |
| 4148 * [mixinElement] is the mixing to evaluate. | 4223 * [mixinElement] is the mixing to evaluate. |
| 4149 * | 4224 * |
| 4150 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]. | 4225 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4161 } | 4236 } |
| 4162 } | 4237 } |
| 4163 return false; | 4238 return false; |
| 4164 } | 4239 } |
| 4165 | 4240 |
| 4166 /** | 4241 /** |
| 4167 * Report the error [CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS] if | 4242 * Report the error [CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS] if |
| 4168 * appropriate. | 4243 * appropriate. |
| 4169 */ | 4244 */ |
| 4170 void _checkForMixinHasNoConstructors(AstNode node) { | 4245 void _checkForMixinHasNoConstructors(AstNode node) { |
| 4171 if ((_enclosingClass as ClassElementImpl).doesMixinLackConstructors) { | 4246 if (_enclosingClass.doesMixinLackConstructors) { |
| 4172 ErrorCode errorCode = CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS; | 4247 ErrorCode errorCode = CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS; |
| 4173 _errorReporter | 4248 _errorReporter |
| 4174 .reportErrorForNode(errorCode, node, [_enclosingClass.supertype]); | 4249 .reportErrorForNode(errorCode, node, [_enclosingClass.supertype]); |
| 4175 } | 4250 } |
| 4176 } | 4251 } |
| 4177 | 4252 |
| 4178 /** | 4253 /** |
| 4179 * Verify that the given mixin has the 'Object' superclass. The [mixinName] is | 4254 * Verify that the given mixin has the 'Object' superclass. The [mixinName] is |
| 4180 * the node to report problem on. The [mixinElement] is the mixing to | 4255 * the node to report problem on. The [mixinElement] is the mixing to |
| 4181 * evaluate. | 4256 * evaluate. |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4304 /** | 4379 /** |
| 4305 * Check that if the given class [declaration] implicitly calls default | 4380 * Check that if the given class [declaration] implicitly calls default |
| 4306 * constructor of its superclass, there should be such default constructor - | 4381 * constructor of its superclass, there should be such default constructor - |
| 4307 * implicit or explicit. | 4382 * implicit or explicit. |
| 4308 * | 4383 * |
| 4309 * See [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]. | 4384 * See [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]. |
| 4310 */ | 4385 */ |
| 4311 void _checkForNoDefaultSuperConstructorImplicit( | 4386 void _checkForNoDefaultSuperConstructorImplicit( |
| 4312 ClassDeclaration declaration) { | 4387 ClassDeclaration declaration) { |
| 4313 // do nothing if mixin errors have already been reported for this class. | 4388 // do nothing if mixin errors have already been reported for this class. |
| 4314 ClassElementImpl enclosingClass = _enclosingClass; | 4389 if (_enclosingClass.doesMixinLackConstructors) { |
| 4315 if (enclosingClass.doesMixinLackConstructors) { | |
| 4316 return; | 4390 return; |
| 4317 } | 4391 } |
| 4318 // do nothing if there is explicit constructor | 4392 // do nothing if there is explicit constructor |
| 4319 List<ConstructorElement> constructors = _enclosingClass.constructors; | 4393 List<ConstructorElement> constructors = _enclosingClass.constructors; |
| 4320 if (!constructors[0].isSynthetic) { | 4394 if (!constructors[0].isSynthetic) { |
| 4321 return; | 4395 return; |
| 4322 } | 4396 } |
| 4323 // prepare super | 4397 // prepare super |
| 4324 InterfaceType superType = _enclosingClass.supertype; | 4398 InterfaceType superType = _enclosingClass.supertype; |
| 4325 if (superType == null) { | 4399 if (superType == null) { |
| (...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5159 * See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT], | 5233 * See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT], |
| 5160 * [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and | 5234 * [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and |
| 5161 * [StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]. | 5235 * [StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]. |
| 5162 */ | 5236 */ |
| 5163 void _checkForUndefinedConstructorInInitializerImplicit( | 5237 void _checkForUndefinedConstructorInInitializerImplicit( |
| 5164 ConstructorDeclaration constructor) { | 5238 ConstructorDeclaration constructor) { |
| 5165 if (_enclosingClass == null) { | 5239 if (_enclosingClass == null) { |
| 5166 return; | 5240 return; |
| 5167 } | 5241 } |
| 5168 // do nothing if mixin errors have already been reported for this class. | 5242 // do nothing if mixin errors have already been reported for this class. |
| 5169 ClassElementImpl enclosingClass = _enclosingClass; | 5243 if (_enclosingClass.doesMixinLackConstructors) { |
| 5170 if (enclosingClass.doesMixinLackConstructors) { | |
| 5171 return; | 5244 return; |
| 5172 } | 5245 } |
| 5173 | 5246 |
| 5174 // Ignore if the constructor is not generative. | 5247 // Ignore if the constructor is not generative. |
| 5175 if (constructor.factoryKeyword != null) { | 5248 if (constructor.factoryKeyword != null) { |
| 5176 return; | 5249 return; |
| 5177 } | 5250 } |
| 5178 | 5251 |
| 5179 // Ignore if the constructor has either an implicit super constructor | 5252 // Ignore if the constructor has either an implicit super constructor |
| 5180 // invocation or a redirecting constructor invocation. | 5253 // invocation or a redirecting constructor invocation. |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5228 * | 5301 * |
| 5229 * See [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER
]. | 5302 * See [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER
]. |
| 5230 */ | 5303 */ |
| 5231 void _checkForUnqualifiedReferenceToNonLocalStaticMember( | 5304 void _checkForUnqualifiedReferenceToNonLocalStaticMember( |
| 5232 SimpleIdentifier name) { | 5305 SimpleIdentifier name) { |
| 5233 Element element = name.staticElement; | 5306 Element element = name.staticElement; |
| 5234 if (element == null || element is TypeParameterElement) { | 5307 if (element == null || element is TypeParameterElement) { |
| 5235 return; | 5308 return; |
| 5236 } | 5309 } |
| 5237 Element enclosingElement = element.enclosingElement; | 5310 Element enclosingElement = element.enclosingElement; |
| 5311 if (identical(enclosingElement, _enclosingClass)) { |
| 5312 return; |
| 5313 } |
| 5238 if (enclosingElement is! ClassElement) { | 5314 if (enclosingElement is! ClassElement) { |
| 5239 return; | 5315 return; |
| 5240 } | 5316 } |
| 5241 if ((element is MethodElement && !element.isStatic) || | 5317 if ((element is MethodElement && !element.isStatic) || |
| 5242 (element is PropertyAccessorElement && !element.isStatic)) { | 5318 (element is PropertyAccessorElement && !element.isStatic)) { |
| 5243 return; | 5319 return; |
| 5244 } | 5320 } |
| 5245 if (identical(enclosingElement, _enclosingClass)) { | |
| 5246 return; | |
| 5247 } | |
| 5248 _errorReporter.reportErrorForNode( | 5321 _errorReporter.reportErrorForNode( |
| 5249 StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, | 5322 StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, |
| 5250 name, | 5323 name, |
| 5251 [name.name]); | 5324 [name.name]); |
| 5252 } | 5325 } |
| 5253 | 5326 |
| 5254 void _checkForValidField(FieldFormalParameter parameter) { | 5327 void _checkForValidField(FieldFormalParameter parameter) { |
| 5255 ParameterElement element = parameter.element; | 5328 ParameterElement element = parameter.element; |
| 5256 if (element is FieldFormalParameterElement) { | 5329 if (element is FieldFormalParameterElement) { |
| 5257 FieldElement fieldElement = element.field; | 5330 FieldElement fieldElement = element.field; |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5398 NodeList<FormalParameter> parameters = parameterList.parameters; | 5471 NodeList<FormalParameter> parameters = parameterList.parameters; |
| 5399 if (parameters.length != 1 || | 5472 if (parameters.length != 1 || |
| 5400 parameters[0].kind != ParameterKind.REQUIRED) { | 5473 parameters[0].kind != ParameterKind.REQUIRED) { |
| 5401 _errorReporter.reportErrorForNode( | 5474 _errorReporter.reportErrorForNode( |
| 5402 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, | 5475 CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER, |
| 5403 setterName); | 5476 setterName); |
| 5404 } | 5477 } |
| 5405 } | 5478 } |
| 5406 | 5479 |
| 5407 /** | 5480 /** |
| 5408 * Check for a type mis-match between the iterable expression and the | |
| 5409 * assigned variable in a for-in statement. | |
| 5410 */ | |
| 5411 void _checkForInIterable(ForEachStatement node) { | |
| 5412 // Ignore malformed for statements. | |
| 5413 if (node.identifier == null && node.loopVariable == null) { | |
| 5414 return; | |
| 5415 } | |
| 5416 | |
| 5417 DartType iterableType = getStaticType(node.iterable); | |
| 5418 if (iterableType.isDynamic) { | |
| 5419 return; | |
| 5420 } | |
| 5421 | |
| 5422 // The type of the loop variable. | |
| 5423 SimpleIdentifier variable = node.identifier != null | |
| 5424 ? node.identifier | |
| 5425 : node.loopVariable.identifier; | |
| 5426 DartType variableType = getStaticType(variable); | |
| 5427 | |
| 5428 DartType loopType = node.awaitKeyword != null | |
| 5429 ? _typeProvider.streamType | |
| 5430 : _typeProvider.iterableType; | |
| 5431 | |
| 5432 // Use an explicit string instead of [loopType] to remove the "<E>". | |
| 5433 String loopTypeName = node.awaitKeyword != null ? "Stream" : "Iterable"; | |
| 5434 | |
| 5435 // The object being iterated has to implement Iterable<T> for some T that | |
| 5436 // is assignable to the variable's type. | |
| 5437 // TODO(rnystrom): Move this into mostSpecificTypeArgument()? | |
| 5438 iterableType = iterableType.resolveToBound(_typeProvider.objectType); | |
| 5439 DartType bestIterableType = | |
| 5440 _typeSystem.mostSpecificTypeArgument(iterableType, loopType); | |
| 5441 | |
| 5442 // Allow it to be a supertype of Iterable<T> (basically just Object) and do | |
| 5443 // an implicit downcast to Iterable<dynamic>. | |
| 5444 if (bestIterableType == null) { | |
| 5445 if (_typeSystem.isSubtypeOf(loopType, iterableType)) { | |
| 5446 bestIterableType = DynamicTypeImpl.instance; | |
| 5447 } | |
| 5448 } | |
| 5449 | |
| 5450 if (bestIterableType == null) { | |
| 5451 _errorReporter.reportTypeErrorForNode( | |
| 5452 StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE, | |
| 5453 node.iterable, | |
| 5454 [iterableType, loopTypeName]); | |
| 5455 } else if (!_typeSystem.isAssignableTo(bestIterableType, variableType)) { | |
| 5456 _errorReporter.reportTypeErrorForNode( | |
| 5457 StaticTypeWarningCode.FOR_IN_OF_INVALID_ELEMENT_TYPE, | |
| 5458 node.iterable, | |
| 5459 [iterableType, loopTypeName, variableType]); | |
| 5460 } | |
| 5461 } | |
| 5462 | |
| 5463 /** | |
| 5464 * Check for a type mis-match between the yielded type and the declared | 5481 * Check for a type mis-match between the yielded type and the declared |
| 5465 * return type of a generator function. | 5482 * return type of a generator function. |
| 5466 * | 5483 * |
| 5467 * This method should only be called in generator functions. | 5484 * This method should only be called in generator functions. |
| 5468 */ | 5485 */ |
| 5469 void _checkForYieldOfInvalidType( | 5486 void _checkForYieldOfInvalidType( |
| 5470 Expression yieldExpression, bool isYieldEach) { | 5487 Expression yieldExpression, bool isYieldEach) { |
| 5471 assert(_inGenerator); | 5488 assert(_inGenerator); |
| 5472 if (_enclosingFunction == null) { | 5489 if (_enclosingFunction == null) { |
| 5473 return; | 5490 return; |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5678 // Get the parameters for MethodDeclaration or FunctionDeclaration | 5695 // Get the parameters for MethodDeclaration or FunctionDeclaration |
| 5679 List<ParameterElement> setterParameters = setter.parameters; | 5696 List<ParameterElement> setterParameters = setter.parameters; |
| 5680 // If there are no setter parameters, return no type. | 5697 // If there are no setter parameters, return no type. |
| 5681 if (setterParameters.length == 0) { | 5698 if (setterParameters.length == 0) { |
| 5682 return null; | 5699 return null; |
| 5683 } | 5700 } |
| 5684 return setterParameters[0].type; | 5701 return setterParameters[0].type; |
| 5685 } | 5702 } |
| 5686 | 5703 |
| 5687 /** | 5704 /** |
| 5688 * Given a list of [directives] that have the same prefix, generate an error | |
| 5689 * if there is more than one import and any of those imports is deferred. | |
| 5690 * | |
| 5691 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. | |
| 5692 */ | |
| 5693 void _checkDeferredPrefixCollision(List<ImportDirective> directives) { | |
| 5694 int count = directives.length; | |
| 5695 if (count > 1) { | |
| 5696 for (int i = 0; i < count; i++) { | |
| 5697 Token deferredToken = directives[i].deferredKeyword; | |
| 5698 if (deferredToken != null) { | |
| 5699 _errorReporter.reportErrorForToken( | |
| 5700 CompileTimeErrorCode.SHARED_DEFERRED_PREFIX, deferredToken); | |
| 5701 } | |
| 5702 } | |
| 5703 } | |
| 5704 } | |
| 5705 | |
| 5706 /** | |
| 5707 * Return `true` if the given [classElement] has a noSuchMethod() method | 5705 * Return `true` if the given [classElement] has a noSuchMethod() method |
| 5708 * distinct from the one declared in class Object, as per the Dart Language | 5706 * distinct from the one declared in class Object, as per the Dart Language |
| 5709 * Specification (section 10.4). | 5707 * Specification (section 10.4). |
| 5710 */ | 5708 */ |
| 5711 bool _hasNoSuchMethod(ClassElement classElement) { | 5709 bool _hasNoSuchMethod(ClassElement classElement) { |
| 5712 MethodElement method = classElement.lookUpMethod( | 5710 MethodElement method = classElement.lookUpMethod( |
| 5713 FunctionElement.NO_SUCH_METHOD_METHOD_NAME, classElement.library); | 5711 FunctionElement.NO_SUCH_METHOD_METHOD_NAME, classElement.library); |
| 5714 if (method == null) { | 5712 if (method == null) { |
| 5715 return false; | 5713 return false; |
| 5716 } | 5714 } |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6058 class _InvocationCollector extends RecursiveAstVisitor { | 6056 class _InvocationCollector extends RecursiveAstVisitor { |
| 6059 final List<String> superCalls = <String>[]; | 6057 final List<String> superCalls = <String>[]; |
| 6060 | 6058 |
| 6061 @override | 6059 @override |
| 6062 visitMethodInvocation(MethodInvocation node) { | 6060 visitMethodInvocation(MethodInvocation node) { |
| 6063 if (node.target is SuperExpression) { | 6061 if (node.target is SuperExpression) { |
| 6064 superCalls.add(node.methodName.name); | 6062 superCalls.add(node.methodName.name); |
| 6065 } | 6063 } |
| 6066 } | 6064 } |
| 6067 } | 6065 } |
| OLD | NEW |