| 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 engine.resolver.error_verifier; | 5 library engine.resolver.error_verifier; |
| 6 | 6 |
| 7 import "dart:math" as math; | 7 import "dart:math" as math; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'package:analyzer/src/generated/static_type_analyzer.dart'; | 10 import 'package:analyzer/src/generated/static_type_analyzer.dart'; |
| (...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1098 * See [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]. | 1098 * See [StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS]. |
| 1099 */ | 1099 */ |
| 1100 bool _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { | 1100 bool _checkExpectedTwoMapTypeArguments(TypeArgumentList typeArguments) { |
| 1101 // check number of type arguments | 1101 // check number of type arguments |
| 1102 int num = typeArguments.arguments.length; | 1102 int num = typeArguments.arguments.length; |
| 1103 if (num == 2) { | 1103 if (num == 2) { |
| 1104 return false; | 1104 return false; |
| 1105 } | 1105 } |
| 1106 // report problem | 1106 // report problem |
| 1107 _errorReporter.reportErrorForNode( | 1107 _errorReporter.reportErrorForNode( |
| 1108 StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArguments, [ | 1108 StaticTypeWarningCode.EXPECTED_TWO_MAP_TYPE_ARGUMENTS, typeArguments, |
| 1109 num | 1109 [num]); |
| 1110 ]); | |
| 1111 return true; | 1110 return true; |
| 1112 } | 1111 } |
| 1113 | 1112 |
| 1114 /** | 1113 /** |
| 1115 * This verifies that the passed constructor declaration does not violate any
of the error codes | 1114 * This verifies that the passed constructor declaration does not violate any
of the error codes |
| 1116 * relating to the initialization of fields in the enclosing class. | 1115 * relating to the initialization of fields in the enclosing class. |
| 1117 * | 1116 * |
| 1118 * @param node the [ConstructorDeclaration] to evaluate | 1117 * @param node the [ConstructorDeclaration] to evaluate |
| 1119 * @return `true` if and only if an error code is generated on the passed node | 1118 * @return `true` if and only if an error code is generated on the passed node |
| 1120 * See [_initialFieldElementsMap], | 1119 * See [_initialFieldElementsMap], |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1200 } | 1199 } |
| 1201 } | 1200 } |
| 1202 } | 1201 } |
| 1203 } | 1202 } |
| 1204 // Visit all of the states in the map to ensure that none were never | 1203 // Visit all of the states in the map to ensure that none were never |
| 1205 // initialized. | 1204 // initialized. |
| 1206 fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) { | 1205 fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) { |
| 1207 if (state == INIT_STATE.NOT_INIT) { | 1206 if (state == INIT_STATE.NOT_INIT) { |
| 1208 if (fieldElement.isConst) { | 1207 if (fieldElement.isConst) { |
| 1209 _errorReporter.reportErrorForNode( | 1208 _errorReporter.reportErrorForNode( |
| 1210 CompileTimeErrorCode.CONST_NOT_INITIALIZED, node.returnType, [ | 1209 CompileTimeErrorCode.CONST_NOT_INITIALIZED, node.returnType, |
| 1211 fieldElement.name | 1210 [fieldElement.name]); |
| 1212 ]); | |
| 1213 foundError = true; | 1211 foundError = true; |
| 1214 } else if (fieldElement.isFinal) { | 1212 } else if (fieldElement.isFinal) { |
| 1215 _errorReporter.reportErrorForNode( | 1213 _errorReporter.reportErrorForNode( |
| 1216 StaticWarningCode.FINAL_NOT_INITIALIZED, node.returnType, [ | 1214 StaticWarningCode.FINAL_NOT_INITIALIZED, node.returnType, |
| 1217 fieldElement.name | 1215 [fieldElement.name]); |
| 1218 ]); | |
| 1219 foundError = true; | 1216 foundError = true; |
| 1220 } | 1217 } |
| 1221 } | 1218 } |
| 1222 }); | 1219 }); |
| 1223 return foundError; | 1220 return foundError; |
| 1224 } | 1221 } |
| 1225 | 1222 |
| 1226 /** | 1223 /** |
| 1227 * This checks the passed executable element against override-error codes. | 1224 * This checks the passed executable element against override-error codes. |
| 1228 * | 1225 * |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1674 // | 1671 // |
| 1675 // Prepare the constructor name | 1672 // Prepare the constructor name |
| 1676 // | 1673 // |
| 1677 String constructorStrName = constructorTypeName.name.name; | 1674 String constructorStrName = constructorTypeName.name.name; |
| 1678 if (redirectedConstructor.name != null) { | 1675 if (redirectedConstructor.name != null) { |
| 1679 constructorStrName += ".${redirectedConstructor.name.name}"; | 1676 constructorStrName += ".${redirectedConstructor.name.name}"; |
| 1680 } | 1677 } |
| 1681 ErrorCode errorCode = (node.constKeyword != null | 1678 ErrorCode errorCode = (node.constKeyword != null |
| 1682 ? CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR | 1679 ? CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR |
| 1683 : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR); | 1680 : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR); |
| 1684 _errorReporter.reportErrorForNode(errorCode, redirectedConstructor, | 1681 _errorReporter.reportErrorForNode(errorCode, redirectedConstructor, [ |
| 1685 [constructorStrName, redirectedType.displayName]); | 1682 constructorStrName, |
| 1683 redirectedType.displayName |
| 1684 ]); |
| 1686 return true; | 1685 return true; |
| 1687 } | 1686 } |
| 1688 return false; | 1687 return false; |
| 1689 } | 1688 } |
| 1690 FunctionType redirectedType = redirectedElement.type; | 1689 FunctionType redirectedType = redirectedElement.type; |
| 1691 DartType redirectedReturnType = redirectedType.returnType; | 1690 DartType redirectedReturnType = redirectedType.returnType; |
| 1692 // | 1691 // |
| 1693 // Report specific problem when return type is incompatible | 1692 // Report specific problem when return type is incompatible |
| 1694 // | 1693 // |
| 1695 FunctionType constructorType = node.element.type; | 1694 FunctionType constructorType = node.element.type; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1749 return true; | 1748 return true; |
| 1750 } | 1749 } |
| 1751 // RETURN_WITHOUT_VALUE | 1750 // RETURN_WITHOUT_VALUE |
| 1752 if (returnExpression == null) { | 1751 if (returnExpression == null) { |
| 1753 if (_inGenerator || | 1752 if (_inGenerator || |
| 1754 _computeReturnTypeForMethod(null) | 1753 _computeReturnTypeForMethod(null) |
| 1755 .isAssignableTo(expectedReturnType)) { | 1754 .isAssignableTo(expectedReturnType)) { |
| 1756 return false; | 1755 return false; |
| 1757 } | 1756 } |
| 1758 _hasReturnWithoutValue = true; | 1757 _hasReturnWithoutValue = true; |
| 1759 _errorReporter | 1758 _errorReporter.reportErrorForNode( |
| 1760 .reportErrorForNode(StaticWarningCode.RETURN_WITHOUT_VALUE, node); | 1759 StaticWarningCode.RETURN_WITHOUT_VALUE, node); |
| 1761 return true; | 1760 return true; |
| 1762 } else if (_inGenerator) { | 1761 } else if (_inGenerator) { |
| 1763 // RETURN_IN_GENERATOR | 1762 // RETURN_IN_GENERATOR |
| 1764 _errorReporter | 1763 _errorReporter.reportErrorForNode( |
| 1765 .reportErrorForNode(CompileTimeErrorCode.RETURN_IN_GENERATOR, node); | 1764 CompileTimeErrorCode.RETURN_IN_GENERATOR, node); |
| 1766 } | 1765 } |
| 1767 // RETURN_OF_INVALID_TYPE | 1766 // RETURN_OF_INVALID_TYPE |
| 1768 return _checkForReturnOfInvalidType(returnExpression, expectedReturnType); | 1767 return _checkForReturnOfInvalidType(returnExpression, expectedReturnType); |
| 1769 } | 1768 } |
| 1770 | 1769 |
| 1771 /** | 1770 /** |
| 1772 * This verifies that the export namespace of the passed export directive does
not export any name | 1771 * This verifies that the export namespace of the passed export directive does
not export any name |
| 1773 * already exported by other export directive. | 1772 * already exported by other export directive. |
| 1774 * | 1773 * |
| 1775 * @param node the export directive node to report problem on | 1774 * @param node the export directive node to report problem on |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2159 } | 2158 } |
| 2160 } | 2159 } |
| 2161 // conflict with class member | 2160 // conflict with class member |
| 2162 if (constructorName != null && | 2161 if (constructorName != null && |
| 2163 constructorElement != null && | 2162 constructorElement != null && |
| 2164 !constructorName.isSynthetic) { | 2163 !constructorName.isSynthetic) { |
| 2165 // fields | 2164 // fields |
| 2166 FieldElement field = classElement.getField(name); | 2165 FieldElement field = classElement.getField(name); |
| 2167 if (field != null) { | 2166 if (field != null) { |
| 2168 _errorReporter.reportErrorForNode( | 2167 _errorReporter.reportErrorForNode( |
| 2169 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, node, [ | 2168 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, node, |
| 2170 name | 2169 [name]); |
| 2171 ]); | |
| 2172 return true; | 2170 return true; |
| 2173 } | 2171 } |
| 2174 // methods | 2172 // methods |
| 2175 MethodElement method = classElement.getMethod(name); | 2173 MethodElement method = classElement.getMethod(name); |
| 2176 if (method != null) { | 2174 if (method != null) { |
| 2177 _errorReporter.reportErrorForNode( | 2175 _errorReporter.reportErrorForNode( |
| 2178 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, | 2176 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, |
| 2179 [name]); | 2177 [name]); |
| 2180 return true; | 2178 return true; |
| 2181 } | 2179 } |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2379 addThisMemberToTheMap = false; | 2377 addThisMemberToTheMap = false; |
| 2380 } | 2378 } |
| 2381 } else if (isSetter) { | 2379 } else if (isSetter) { |
| 2382 String methodName = name.name; | 2380 String methodName = name.name; |
| 2383 ClassMember conflictingMethod = memberHashMap[methodName]; | 2381 ClassMember conflictingMethod = memberHashMap[methodName]; |
| 2384 if (conflictingMethod != null && | 2382 if (conflictingMethod != null && |
| 2385 conflictingMethod is MethodDeclaration && | 2383 conflictingMethod is MethodDeclaration && |
| 2386 !conflictingMethod.isGetter) { | 2384 !conflictingMethod.isGetter) { |
| 2387 // report problem | 2385 // report problem |
| 2388 _errorReporter.reportErrorForNode( | 2386 _errorReporter.reportErrorForNode( |
| 2389 StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2, name, | 2387 StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER2, name, [ |
| 2390 [_enclosingClass.displayName, name.name]); | 2388 _enclosingClass.displayName, |
| 2389 name.name |
| 2390 ]); |
| 2391 foundError = true; | 2391 foundError = true; |
| 2392 addThisMemberToTheMap = false; | 2392 addThisMemberToTheMap = false; |
| 2393 } | 2393 } |
| 2394 } | 2394 } |
| 2395 // Finally, add this member into the HashMap. | 2395 // Finally, add this member into the HashMap. |
| 2396 if (addThisMemberToTheMap) { | 2396 if (addThisMemberToTheMap) { |
| 2397 if (method.isSetter) { | 2397 if (method.isSetter) { |
| 2398 memberHashMap["${name.name}="] = method; | 2398 memberHashMap["${name.name}="] = method; |
| 2399 } else { | 2399 } else { |
| 2400 memberHashMap[name.name] = method; | 2400 memberHashMap[name.name] = method; |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2622 * @param node the instance creation expression to evaluate | 2622 * @param node the instance creation expression to evaluate |
| 2623 * @param constructorName the constructor name, always non-`null` | 2623 * @param constructorName the constructor name, always non-`null` |
| 2624 * @param typeName the name of the type defining the constructor, always non-`
null` | 2624 * @param typeName the name of the type defining the constructor, always non-`
null` |
| 2625 * @return `true` if and only if an error code is generated on the passed node | 2625 * @return `true` if and only if an error code is generated on the passed node |
| 2626 * See [CompileTimeErrorCode.CONST_DEFERRED_CLASS]. | 2626 * See [CompileTimeErrorCode.CONST_DEFERRED_CLASS]. |
| 2627 */ | 2627 */ |
| 2628 bool _checkForConstDeferredClass(InstanceCreationExpression node, | 2628 bool _checkForConstDeferredClass(InstanceCreationExpression node, |
| 2629 ConstructorName constructorName, TypeName typeName) { | 2629 ConstructorName constructorName, TypeName typeName) { |
| 2630 if (typeName.isDeferred) { | 2630 if (typeName.isDeferred) { |
| 2631 _errorReporter.reportErrorForNode( | 2631 _errorReporter.reportErrorForNode( |
| 2632 CompileTimeErrorCode.CONST_DEFERRED_CLASS, constructorName, [ | 2632 CompileTimeErrorCode.CONST_DEFERRED_CLASS, constructorName, |
| 2633 typeName.name.name | 2633 [typeName.name.name]); |
| 2634 ]); | |
| 2635 return true; | 2634 return true; |
| 2636 } | 2635 } |
| 2637 return false; | 2636 return false; |
| 2638 } | 2637 } |
| 2639 | 2638 |
| 2640 /** | 2639 /** |
| 2641 * This verifies that the passed throw expression is not enclosed in a 'const'
constructor | 2640 * This verifies that the passed throw expression is not enclosed in a 'const'
constructor |
| 2642 * declaration. | 2641 * declaration. |
| 2643 * | 2642 * |
| 2644 * @param node the throw expression expression to evaluate | 2643 * @param node the throw expression expression to evaluate |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2986 */ | 2985 */ |
| 2987 bool _checkForExpectedOneListTypeArgument( | 2986 bool _checkForExpectedOneListTypeArgument( |
| 2988 ListLiteral node, TypeArgumentList typeArguments) { | 2987 ListLiteral node, TypeArgumentList typeArguments) { |
| 2989 // check number of type arguments | 2988 // check number of type arguments |
| 2990 int num = typeArguments.arguments.length; | 2989 int num = typeArguments.arguments.length; |
| 2991 if (num == 1) { | 2990 if (num == 1) { |
| 2992 return false; | 2991 return false; |
| 2993 } | 2992 } |
| 2994 // report problem | 2993 // report problem |
| 2995 _errorReporter.reportErrorForNode( | 2994 _errorReporter.reportErrorForNode( |
| 2996 StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments, [ | 2995 StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments, |
| 2997 num | 2996 [num]); |
| 2998 ]); | |
| 2999 return true; | 2997 return true; |
| 3000 } | 2998 } |
| 3001 | 2999 |
| 3002 /** | 3000 /** |
| 3003 * This verifies the passed import has unique name among other exported librar
ies. | 3001 * This verifies the passed import has unique name among other exported librar
ies. |
| 3004 * | 3002 * |
| 3005 * @param node the export directive to evaluate | 3003 * @param node the export directive to evaluate |
| 3006 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the | 3004 * @param exportElement the [ExportElement] retrieved from the node, if the el
ement in the |
| 3007 * node was `null`, then this method is not called | 3005 * node was `null`, then this method is not called |
| 3008 * @param exportedLibrary the library element containing the exported element | 3006 * @param exportedLibrary the library element containing the exported element |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3333 if (_isInNativeClass) { | 3331 if (_isInNativeClass) { |
| 3334 return false; | 3332 return false; |
| 3335 } | 3333 } |
| 3336 bool foundError = false; | 3334 bool foundError = false; |
| 3337 if (!node.isSynthetic) { | 3335 if (!node.isSynthetic) { |
| 3338 NodeList<VariableDeclaration> variables = node.variables; | 3336 NodeList<VariableDeclaration> variables = node.variables; |
| 3339 for (VariableDeclaration variable in variables) { | 3337 for (VariableDeclaration variable in variables) { |
| 3340 if (variable.initializer == null) { | 3338 if (variable.initializer == null) { |
| 3341 if (node.isConst) { | 3339 if (node.isConst) { |
| 3342 _errorReporter.reportErrorForNode( | 3340 _errorReporter.reportErrorForNode( |
| 3343 CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, [ | 3341 CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, |
| 3344 variable.name.name | 3342 [variable.name.name]); |
| 3345 ]); | |
| 3346 } else if (node.isFinal) { | 3343 } else if (node.isFinal) { |
| 3347 _errorReporter.reportErrorForNode( | 3344 _errorReporter.reportErrorForNode( |
| 3348 StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, [ | 3345 StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, |
| 3349 variable.name.name | 3346 [variable.name.name]); |
| 3350 ]); | |
| 3351 } | 3347 } |
| 3352 foundError = true; | 3348 foundError = true; |
| 3353 } | 3349 } |
| 3354 } | 3350 } |
| 3355 } | 3351 } |
| 3356 return foundError; | 3352 return foundError; |
| 3357 } | 3353 } |
| 3358 | 3354 |
| 3359 /** | 3355 /** |
| 3360 * This verifies that final fields that are declared, without any constructors
in the enclosing | 3356 * This verifies that final fields that are declared, without any constructors
in the enclosing |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3661 // OK, top-level element | 3657 // OK, top-level element |
| 3662 if (executableElement.enclosingElement is! ClassElement) { | 3658 if (executableElement.enclosingElement is! ClassElement) { |
| 3663 return false; | 3659 return false; |
| 3664 } | 3660 } |
| 3665 // OK, instance member | 3661 // OK, instance member |
| 3666 if (!executableElement.isStatic) { | 3662 if (!executableElement.isStatic) { |
| 3667 return false; | 3663 return false; |
| 3668 } | 3664 } |
| 3669 // report problem | 3665 // report problem |
| 3670 _errorReporter.reportErrorForNode( | 3666 _errorReporter.reportErrorForNode( |
| 3671 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name, [ | 3667 StaticTypeWarningCode.INSTANCE_ACCESS_TO_STATIC_MEMBER, name, |
| 3672 name.name | 3668 [name.name]); |
| 3673 ]); | |
| 3674 return true; | 3669 return true; |
| 3675 } | 3670 } |
| 3676 | 3671 |
| 3677 /** | 3672 /** |
| 3678 * This checks whether the given [executableElement] collides with the name of
a static | 3673 * This checks whether the given [executableElement] collides with the name of
a static |
| 3679 * method in one of its superclasses, and reports the appropriate warning if i
t does. | 3674 * method in one of its superclasses, and reports the appropriate warning if i
t does. |
| 3680 * | 3675 * |
| 3681 * @param executableElement the method to check. | 3676 * @param executableElement the method to check. |
| 3682 * @param errorNameTarget the node to report problems on. | 3677 * @param errorNameTarget the node to report problems on. |
| 3683 * @return `true` if and only if a warning was generated. | 3678 * @return `true` if and only if a warning was generated. |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3859 * @param fieldName the field name from the [ConstructorFieldInitializer] | 3854 * @param fieldName the field name from the [ConstructorFieldInitializer] |
| 3860 * @param staticElement the static element from the name in the | 3855 * @param staticElement the static element from the name in the |
| 3861 * [ConstructorFieldInitializer] | 3856 * [ConstructorFieldInitializer] |
| 3862 */ | 3857 */ |
| 3863 void _checkForInvalidField(ConstructorFieldInitializer node, | 3858 void _checkForInvalidField(ConstructorFieldInitializer node, |
| 3864 SimpleIdentifier fieldName, Element staticElement) { | 3859 SimpleIdentifier fieldName, Element staticElement) { |
| 3865 if (staticElement is FieldElement) { | 3860 if (staticElement is FieldElement) { |
| 3866 FieldElement fieldElement = staticElement; | 3861 FieldElement fieldElement = staticElement; |
| 3867 if (fieldElement.isSynthetic) { | 3862 if (fieldElement.isSynthetic) { |
| 3868 _errorReporter.reportErrorForNode( | 3863 _errorReporter.reportErrorForNode( |
| 3869 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, [ | 3864 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, |
| 3870 fieldName | 3865 [fieldName]); |
| 3871 ]); | |
| 3872 } else if (fieldElement.isStatic) { | 3866 } else if (fieldElement.isStatic) { |
| 3873 _errorReporter.reportErrorForNode( | 3867 _errorReporter.reportErrorForNode( |
| 3874 CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [ | 3868 CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, |
| 3875 fieldName | 3869 [fieldName]); |
| 3876 ]); | |
| 3877 } | 3870 } |
| 3878 } else { | 3871 } else { |
| 3879 _errorReporter.reportErrorForNode( | 3872 _errorReporter.reportErrorForNode( |
| 3880 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, [ | 3873 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, |
| 3881 fieldName | 3874 [fieldName]); |
| 3882 ]); | |
| 3883 return; | 3875 return; |
| 3884 } | 3876 } |
| 3885 } | 3877 } |
| 3886 | 3878 |
| 3887 /** | 3879 /** |
| 3888 * Check to see whether the given function body has a modifier associated with
it, and report it | 3880 * Check to see whether the given function body has a modifier associated with
it, and report it |
| 3889 * as an error if it does. | 3881 * as an error if it does. |
| 3890 * | 3882 * |
| 3891 * @param body the function body being checked | 3883 * @param body the function body being checked |
| 3892 * @param errorCode the error code to be reported if a modifier is found | 3884 * @param errorCode the error code to be reported if a modifier is found |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4197 if (constantName != null) { | 4189 if (constantName != null) { |
| 4198 constantNames.remove(constantName); | 4190 constantNames.remove(constantName); |
| 4199 } | 4191 } |
| 4200 } | 4192 } |
| 4201 int nameCount = constantNames.length; | 4193 int nameCount = constantNames.length; |
| 4202 if (nameCount == 0) { | 4194 if (nameCount == 0) { |
| 4203 return false; | 4195 return false; |
| 4204 } | 4196 } |
| 4205 for (int i = 0; i < nameCount; i++) { | 4197 for (int i = 0; i < nameCount; i++) { |
| 4206 _errorReporter.reportErrorForNode( | 4198 _errorReporter.reportErrorForNode( |
| 4207 CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, statement, [ | 4199 CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, statement, |
| 4208 constantNames[i] | 4200 [constantNames[i]]); |
| 4209 ]); | |
| 4210 } | 4201 } |
| 4211 return true; | 4202 return true; |
| 4212 } | 4203 } |
| 4213 | 4204 |
| 4214 /** | 4205 /** |
| 4215 * This verifies that the given function body does not contain return statemen
ts that both have | 4206 * This verifies that the given function body does not contain return statemen
ts that both have |
| 4216 * and do not have return values. | 4207 * and do not have return values. |
| 4217 * | 4208 * |
| 4218 * @param node the function body being tested | 4209 * @param node the function body being tested |
| 4219 * @return `true` if and only if an error code is generated on the passed node | 4210 * @return `true` if and only if an error code is generated on the passed node |
| (...skipping 25 matching lines...) Expand all Loading... |
| 4245 * @param mixinName the node to report problem on | 4236 * @param mixinName the node to report problem on |
| 4246 * @param mixinElement the mixing to evaluate | 4237 * @param mixinElement the mixing to evaluate |
| 4247 * @return `true` if and only if an error code is generated on the passed node | 4238 * @return `true` if and only if an error code is generated on the passed node |
| 4248 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]. | 4239 * See [CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR]. |
| 4249 */ | 4240 */ |
| 4250 bool _checkForMixinDeclaresConstructor( | 4241 bool _checkForMixinDeclaresConstructor( |
| 4251 TypeName mixinName, ClassElement mixinElement) { | 4242 TypeName mixinName, ClassElement mixinElement) { |
| 4252 for (ConstructorElement constructor in mixinElement.constructors) { | 4243 for (ConstructorElement constructor in mixinElement.constructors) { |
| 4253 if (!constructor.isSynthetic && !constructor.isFactory) { | 4244 if (!constructor.isSynthetic && !constructor.isFactory) { |
| 4254 _errorReporter.reportErrorForNode( | 4245 _errorReporter.reportErrorForNode( |
| 4255 CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, mixinName, [ | 4246 CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR, mixinName, |
| 4256 mixinElement.name | 4247 [mixinElement.name]); |
| 4257 ]); | |
| 4258 return true; | 4248 return true; |
| 4259 } | 4249 } |
| 4260 } | 4250 } |
| 4261 return false; | 4251 return false; |
| 4262 } | 4252 } |
| 4263 | 4253 |
| 4264 /** | 4254 /** |
| 4265 * This verifies that the passed mixin has the 'Object' superclass. | 4255 * This verifies that the passed mixin has the 'Object' superclass. |
| 4266 * | 4256 * |
| 4267 * @param mixinName the node to report problem on | 4257 * @param mixinName the node to report problem on |
| 4268 * @param mixinElement the mixing to evaluate | 4258 * @param mixinElement the mixing to evaluate |
| 4269 * @return `true` if and only if an error code is generated on the passed node | 4259 * @return `true` if and only if an error code is generated on the passed node |
| 4270 * See [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]. | 4260 * See [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT]. |
| 4271 */ | 4261 */ |
| 4272 bool _checkForMixinInheritsNotFromObject( | 4262 bool _checkForMixinInheritsNotFromObject( |
| 4273 TypeName mixinName, ClassElement mixinElement) { | 4263 TypeName mixinName, ClassElement mixinElement) { |
| 4274 InterfaceType mixinSupertype = mixinElement.supertype; | 4264 InterfaceType mixinSupertype = mixinElement.supertype; |
| 4275 if (mixinSupertype != null) { | 4265 if (mixinSupertype != null) { |
| 4276 if (!mixinSupertype.isObject || | 4266 if (!mixinSupertype.isObject || |
| 4277 !mixinElement.isTypedef && mixinElement.mixins.length != 0) { | 4267 !mixinElement.isTypedef && mixinElement.mixins.length != 0) { |
| 4278 _errorReporter.reportErrorForNode( | 4268 _errorReporter.reportErrorForNode( |
| 4279 CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, mixinName, [ | 4269 CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, mixinName, |
| 4280 mixinElement.name | 4270 [mixinElement.name]); |
| 4281 ]); | |
| 4282 return true; | 4271 return true; |
| 4283 } | 4272 } |
| 4284 } | 4273 } |
| 4285 return false; | 4274 return false; |
| 4286 } | 4275 } |
| 4287 | 4276 |
| 4288 /** | 4277 /** |
| 4289 * This verifies that the passed mixin does not reference 'super'. | 4278 * This verifies that the passed mixin does not reference 'super'. |
| 4290 * | 4279 * |
| 4291 * @param mixinName the node to report problem on | 4280 * @param mixinName the node to report problem on |
| 4292 * @param mixinElement the mixing to evaluate | 4281 * @param mixinElement the mixing to evaluate |
| 4293 * @return `true` if and only if an error code is generated on the passed node | 4282 * @return `true` if and only if an error code is generated on the passed node |
| 4294 * See [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]. | 4283 * See [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER]. |
| 4295 */ | 4284 */ |
| 4296 bool _checkForMixinReferencesSuper( | 4285 bool _checkForMixinReferencesSuper( |
| 4297 TypeName mixinName, ClassElement mixinElement) { | 4286 TypeName mixinName, ClassElement mixinElement) { |
| 4298 if (mixinElement.hasReferenceToSuper) { | 4287 if (mixinElement.hasReferenceToSuper) { |
| 4299 _errorReporter.reportErrorForNode( | 4288 _errorReporter.reportErrorForNode( |
| 4300 CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, mixinName, [ | 4289 CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, mixinName, |
| 4301 mixinElement.name | 4290 [mixinElement.name]); |
| 4302 ]); | |
| 4303 } | 4291 } |
| 4304 return false; | 4292 return false; |
| 4305 } | 4293 } |
| 4306 | 4294 |
| 4307 /** | 4295 /** |
| 4308 * This verifies that the passed constructor has at most one 'super' initializ
er. | 4296 * This verifies that the passed constructor has at most one 'super' initializ
er. |
| 4309 * | 4297 * |
| 4310 * @param node the constructor declaration to evaluate | 4298 * @param node the constructor declaration to evaluate |
| 4311 * @return `true` if and only if an error code is generated on the passed node | 4299 * @return `true` if and only if an error code is generated on the passed node |
| 4312 * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]. | 4300 * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]. |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4408 if (superType == null) { | 4396 if (superType == null) { |
| 4409 return false; | 4397 return false; |
| 4410 } | 4398 } |
| 4411 ClassElement superElement = superType.element; | 4399 ClassElement superElement = superType.element; |
| 4412 // try to find default generative super constructor | 4400 // try to find default generative super constructor |
| 4413 ConstructorElement superUnnamedConstructor = | 4401 ConstructorElement superUnnamedConstructor = |
| 4414 superElement.unnamedConstructor; | 4402 superElement.unnamedConstructor; |
| 4415 if (superUnnamedConstructor != null) { | 4403 if (superUnnamedConstructor != null) { |
| 4416 if (superUnnamedConstructor.isFactory) { | 4404 if (superUnnamedConstructor.isFactory) { |
| 4417 _errorReporter.reportErrorForNode( | 4405 _errorReporter.reportErrorForNode( |
| 4418 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.name, [ | 4406 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.name, |
| 4419 superUnnamedConstructor | 4407 [superUnnamedConstructor]); |
| 4420 ]); | |
| 4421 return true; | 4408 return true; |
| 4422 } | 4409 } |
| 4423 if (superUnnamedConstructor.isDefaultConstructor && | 4410 if (superUnnamedConstructor.isDefaultConstructor && |
| 4424 _enclosingClass | 4411 _enclosingClass |
| 4425 .isSuperConstructorAccessible(superUnnamedConstructor)) { | 4412 .isSuperConstructorAccessible(superUnnamedConstructor)) { |
| 4426 return true; | 4413 return true; |
| 4427 } | 4414 } |
| 4428 } | 4415 } |
| 4429 // report problem | 4416 // report problem |
| 4430 _errorReporter.reportErrorForNode( | 4417 _errorReporter.reportErrorForNode( |
| 4431 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, node.name, [ | 4418 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, node.name, |
| 4432 superType.displayName | 4419 [superType.displayName]); |
| 4433 ]); | |
| 4434 return true; | 4420 return true; |
| 4435 } | 4421 } |
| 4436 | 4422 |
| 4437 /** | 4423 /** |
| 4438 * This checks that passed class declaration overrides all members required by
its superclasses | 4424 * This checks that passed class declaration overrides all members required by
its superclasses |
| 4439 * and interfaces. | 4425 * and interfaces. |
| 4440 * | 4426 * |
| 4441 * @param classNameNode the [SimpleIdentifier] to be used if there is a violat
ion, this is | 4427 * @param classNameNode the [SimpleIdentifier] to be used if there is a violat
ion, this is |
| 4442 * either the named from the [ClassDeclaration] or from the [ClassTyp
eAlias]. | 4428 * either the named from the [ClassDeclaration] or from the [ClassTyp
eAlias]. |
| 4443 * @return `true` if and only if an error code is generated on the passed node | 4429 * @return `true` if and only if an error code is generated on the passed node |
| (...skipping 862 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5306 DartType bound = element.bound; | 5292 DartType bound = element.bound; |
| 5307 if (bound == null) { | 5293 if (bound == null) { |
| 5308 return false; | 5294 return false; |
| 5309 } | 5295 } |
| 5310 // OK, type parameter is not supertype of its bound | 5296 // OK, type parameter is not supertype of its bound |
| 5311 if (!bound.isMoreSpecificThan(element.type)) { | 5297 if (!bound.isMoreSpecificThan(element.type)) { |
| 5312 return false; | 5298 return false; |
| 5313 } | 5299 } |
| 5314 // report problem | 5300 // report problem |
| 5315 _errorReporter.reportErrorForNode( | 5301 _errorReporter.reportErrorForNode( |
| 5316 StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, node, [ | 5302 StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, node, |
| 5317 element.displayName | 5303 [element.displayName]); |
| 5318 ]); | |
| 5319 return true; | 5304 return true; |
| 5320 } | 5305 } |
| 5321 | 5306 |
| 5322 /** | 5307 /** |
| 5323 * This checks that if the passed generative constructor has neither an explic
it super constructor | 5308 * This checks that if the passed generative constructor has neither an explic
it super constructor |
| 5324 * invocation nor a redirecting constructor invocation, that the superclass ha
s a default | 5309 * invocation nor a redirecting constructor invocation, that the superclass ha
s a default |
| 5325 * generative constructor. | 5310 * generative constructor. |
| 5326 * | 5311 * |
| 5327 * @param node the constructor declaration to evaluate | 5312 * @param node the constructor declaration to evaluate |
| 5328 * @return `true` if and only if an error code is generated on the passed node | 5313 * @return `true` if and only if an error code is generated on the passed node |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5363 InterfaceType superType = _enclosingClass.supertype; | 5348 InterfaceType superType = _enclosingClass.supertype; |
| 5364 if (superType == null) { | 5349 if (superType == null) { |
| 5365 return false; | 5350 return false; |
| 5366 } | 5351 } |
| 5367 ClassElement superElement = superType.element; | 5352 ClassElement superElement = superType.element; |
| 5368 ConstructorElement superUnnamedConstructor = | 5353 ConstructorElement superUnnamedConstructor = |
| 5369 superElement.unnamedConstructor; | 5354 superElement.unnamedConstructor; |
| 5370 if (superUnnamedConstructor != null) { | 5355 if (superUnnamedConstructor != null) { |
| 5371 if (superUnnamedConstructor.isFactory) { | 5356 if (superUnnamedConstructor.isFactory) { |
| 5372 _errorReporter.reportErrorForNode( | 5357 _errorReporter.reportErrorForNode( |
| 5373 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.returnType, [ | 5358 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.returnType, |
| 5374 superUnnamedConstructor | 5359 [superUnnamedConstructor]); |
| 5375 ]); | |
| 5376 return true; | 5360 return true; |
| 5377 } | 5361 } |
| 5378 if (!superUnnamedConstructor.isDefaultConstructor || | 5362 if (!superUnnamedConstructor.isDefaultConstructor || |
| 5379 !_enclosingClass | 5363 !_enclosingClass |
| 5380 .isSuperConstructorAccessible(superUnnamedConstructor)) { | 5364 .isSuperConstructorAccessible(superUnnamedConstructor)) { |
| 5381 int offset; | 5365 int offset; |
| 5382 int length; | 5366 int length; |
| 5383 { | 5367 { |
| 5384 Identifier returnType = node.returnType; | 5368 Identifier returnType = node.returnType; |
| 5385 SimpleIdentifier name = node.name; | 5369 SimpleIdentifier name = node.name; |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5658 } | 5642 } |
| 5659 if (!classElement.type.isSubtypeOf(_typeProvider.functionType)) { | 5643 if (!classElement.type.isSubtypeOf(_typeProvider.functionType)) { |
| 5660 return false; | 5644 return false; |
| 5661 } | 5645 } |
| 5662 // If there is a noSuchMethod method, then don't report the warning, | 5646 // If there is a noSuchMethod method, then don't report the warning, |
| 5663 // see dartbug.com/16078 | 5647 // see dartbug.com/16078 |
| 5664 if (classElement.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME) != | 5648 if (classElement.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME) != |
| 5665 null) { | 5649 null) { |
| 5666 return false; | 5650 return false; |
| 5667 } | 5651 } |
| 5668 ExecutableElement callMethod = | 5652 ExecutableElement callMethod = _inheritanceManager.lookupMember( |
| 5669 _inheritanceManager.lookupMember(classElement, "call"); | 5653 classElement, FunctionElement.CALL_METHOD_NAME); |
| 5670 if (callMethod == null || | 5654 if (callMethod == null || |
| 5671 callMethod is! MethodElement || | 5655 callMethod is! MethodElement || |
| 5672 (callMethod as MethodElement).isAbstract) { | 5656 (callMethod as MethodElement).isAbstract) { |
| 5673 _errorReporter.reportErrorForNode( | 5657 _errorReporter.reportErrorForNode( |
| 5674 StaticWarningCode.FUNCTION_WITHOUT_CALL, node.name); | 5658 StaticWarningCode.FUNCTION_WITHOUT_CALL, node.name); |
| 5675 return true; | 5659 return true; |
| 5676 } | 5660 } |
| 5677 return false; | 5661 return false; |
| 5678 } | 5662 } |
| 5679 | 5663 |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6049 _enclosingClass.nameOffset, enclosingClassName.length, [ | 6033 _enclosingClass.nameOffset, enclosingClassName.length, [ |
| 6050 enclosingClassName, | 6034 enclosingClassName, |
| 6051 buffer.toString() | 6035 buffer.toString() |
| 6052 ]); | 6036 ]); |
| 6053 return true; | 6037 return true; |
| 6054 } else { | 6038 } else { |
| 6055 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or | 6039 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or |
| 6056 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or | 6040 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or |
| 6057 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH | 6041 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH |
| 6058 _errorReporter.reportErrorForOffset(_getBaseCaseErrorCode(classElt), | 6042 _errorReporter.reportErrorForOffset(_getBaseCaseErrorCode(classElt), |
| 6059 _enclosingClass.nameOffset, enclosingClassName.length, [ | 6043 _enclosingClass.nameOffset, enclosingClassName.length, |
| 6060 enclosingClassName | 6044 [enclosingClassName]); |
| 6061 ]); | |
| 6062 return true; | 6045 return true; |
| 6063 } | 6046 } |
| 6064 } | 6047 } |
| 6065 if (path.indexOf(classElt) > 0) { | 6048 if (path.indexOf(classElt) > 0) { |
| 6066 return false; | 6049 return false; |
| 6067 } | 6050 } |
| 6068 path.add(classElt); | 6051 path.add(classElt); |
| 6069 // n-case | 6052 // n-case |
| 6070 InterfaceType supertype = classElt.supertype; | 6053 InterfaceType supertype = classElt.supertype; |
| 6071 if (supertype != null && | 6054 if (supertype != null && |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6161 toCheck.add(type.element); | 6144 toCheck.add(type.element); |
| 6162 // type arguments | 6145 // type arguments |
| 6163 if (type is InterfaceType) { | 6146 if (type is InterfaceType) { |
| 6164 InterfaceType interfaceType = type; | 6147 InterfaceType interfaceType = type; |
| 6165 for (DartType typeArgument in interfaceType.typeArguments) { | 6148 for (DartType typeArgument in interfaceType.typeArguments) { |
| 6166 _addTypeToCheck(typeArgument); | 6149 _addTypeToCheck(typeArgument); |
| 6167 } | 6150 } |
| 6168 } | 6151 } |
| 6169 } | 6152 } |
| 6170 } | 6153 } |
| OLD | NEW |