| 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 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1117 | 1117 |
| 1118 /** | 1118 /** |
| 1119 * Verify that the given [constructor] declaration does not violate any of the | 1119 * Verify that the given [constructor] declaration does not violate any of the |
| 1120 * error codes relating to the initialization of fields in the enclosing | 1120 * error codes relating to the initialization of fields in the enclosing |
| 1121 * class. | 1121 * class. |
| 1122 * | 1122 * |
| 1123 * See [_initialFieldElementsMap], | 1123 * See [_initialFieldElementsMap], |
| 1124 * [StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR], and | 1124 * [StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR], and |
| 1125 * [CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES]. | 1125 * [CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES]. |
| 1126 */ | 1126 */ |
| 1127 bool _checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) { | 1127 bool _checkForAllFinalInitializedErrorCodes( |
| 1128 if (node.factoryKeyword != null || | 1128 ConstructorDeclaration constructor) { |
| 1129 node.redirectedConstructor != null || | 1129 if (constructor.factoryKeyword != null || |
| 1130 node.externalKeyword != null) { | 1130 constructor.redirectedConstructor != null || |
| 1131 constructor.externalKeyword != null) { |
| 1131 return false; | 1132 return false; |
| 1132 } | 1133 } |
| 1133 // Ignore if native class. | 1134 // Ignore if native class. |
| 1134 if (_isInNativeClass) { | 1135 if (_isInNativeClass) { |
| 1135 return false; | 1136 return false; |
| 1136 } | 1137 } |
| 1137 bool foundError = false; | 1138 bool foundError = false; |
| 1138 HashMap<FieldElement, INIT_STATE> fieldElementsMap = | 1139 HashMap<FieldElement, INIT_STATE> fieldElementsMap = |
| 1139 new HashMap<FieldElement, INIT_STATE>.from(_initialFieldElementsMap); | 1140 new HashMap<FieldElement, INIT_STATE>.from(_initialFieldElementsMap); |
| 1140 // Visit all of the field formal parameters | 1141 // Visit all of the field formal parameters |
| 1141 NodeList<FormalParameter> formalParameters = node.parameters.parameters; | 1142 NodeList<FormalParameter> formalParameters = |
| 1143 constructor.parameters.parameters; |
| 1142 for (FormalParameter formalParameter in formalParameters) { | 1144 for (FormalParameter formalParameter in formalParameters) { |
| 1143 FormalParameter parameter = formalParameter; | 1145 FormalParameter parameter = formalParameter; |
| 1144 if (parameter is DefaultFormalParameter) { | 1146 if (parameter is DefaultFormalParameter) { |
| 1145 parameter = (parameter as DefaultFormalParameter).parameter; | 1147 parameter = (parameter as DefaultFormalParameter).parameter; |
| 1146 } | 1148 } |
| 1147 if (parameter is FieldFormalParameter) { | 1149 if (parameter is FieldFormalParameter) { |
| 1148 FieldElement fieldElement = | 1150 FieldElement fieldElement = |
| 1149 (parameter.element as FieldFormalParameterElementImpl).field; | 1151 (parameter.element as FieldFormalParameterElementImpl).field; |
| 1150 INIT_STATE state = fieldElementsMap[fieldElement]; | 1152 INIT_STATE state = fieldElementsMap[fieldElement]; |
| 1151 if (state == INIT_STATE.NOT_INIT) { | 1153 if (state == INIT_STATE.NOT_INIT) { |
| 1152 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL; | 1154 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL; |
| 1153 } else if (state == INIT_STATE.INIT_IN_DECLARATION) { | 1155 } else if (state == INIT_STATE.INIT_IN_DECLARATION) { |
| 1154 if (fieldElement.isFinal || fieldElement.isConst) { | 1156 if (fieldElement.isFinal || fieldElement.isConst) { |
| 1155 _errorReporter.reportErrorForNode( | 1157 _errorReporter.reportErrorForNode( |
| 1156 StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCT
OR, | 1158 StaticWarningCode.FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCT
OR, |
| 1157 formalParameter.identifier, [fieldElement.displayName]); | 1159 formalParameter.identifier, [fieldElement.displayName]); |
| 1158 foundError = true; | 1160 foundError = true; |
| 1159 } | 1161 } |
| 1160 } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) { | 1162 } else if (state == INIT_STATE.INIT_IN_FIELD_FORMAL) { |
| 1161 if (fieldElement.isFinal || fieldElement.isConst) { | 1163 if (fieldElement.isFinal || fieldElement.isConst) { |
| 1162 _errorReporter.reportErrorForNode( | 1164 _errorReporter.reportErrorForNode( |
| 1163 CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, | 1165 CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES, |
| 1164 formalParameter.identifier, [fieldElement.displayName]); | 1166 formalParameter.identifier, [fieldElement.displayName]); |
| 1165 foundError = true; | 1167 foundError = true; |
| 1166 } | 1168 } |
| 1167 } | 1169 } |
| 1168 } | 1170 } |
| 1169 } | 1171 } |
| 1170 // Visit all of the initializers | 1172 // Visit all of the initializers |
| 1171 NodeList<ConstructorInitializer> initializers = node.initializers; | 1173 NodeList<ConstructorInitializer> initializers = constructor.initializers; |
| 1172 for (ConstructorInitializer constructorInitializer in initializers) { | 1174 for (ConstructorInitializer constructorInitializer in initializers) { |
| 1173 if (constructorInitializer is RedirectingConstructorInvocation) { | 1175 if (constructorInitializer is RedirectingConstructorInvocation) { |
| 1174 return false; | 1176 return false; |
| 1175 } | 1177 } |
| 1176 if (constructorInitializer is ConstructorFieldInitializer) { | 1178 if (constructorInitializer is ConstructorFieldInitializer) { |
| 1177 ConstructorFieldInitializer constructorFieldInitializer = | 1179 ConstructorFieldInitializer constructorFieldInitializer = |
| 1178 constructorInitializer; | 1180 constructorInitializer; |
| 1179 SimpleIdentifier fieldName = constructorFieldInitializer.fieldName; | 1181 SimpleIdentifier fieldName = constructorFieldInitializer.fieldName; |
| 1180 Element element = fieldName.staticElement; | 1182 Element element = fieldName.staticElement; |
| 1181 if (element is FieldElement) { | 1183 if (element is FieldElement) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1212 notInitFinalFields.add(fieldElement); | 1214 notInitFinalFields.add(fieldElement); |
| 1213 } | 1215 } |
| 1214 } | 1216 } |
| 1215 }); | 1217 }); |
| 1216 // Visit all of the states in the map to ensure that none were never | 1218 // Visit all of the states in the map to ensure that none were never |
| 1217 // initialized. | 1219 // initialized. |
| 1218 fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) { | 1220 fieldElementsMap.forEach((FieldElement fieldElement, INIT_STATE state) { |
| 1219 if (state == INIT_STATE.NOT_INIT) { | 1221 if (state == INIT_STATE.NOT_INIT) { |
| 1220 if (fieldElement.isConst) { | 1222 if (fieldElement.isConst) { |
| 1221 _errorReporter.reportErrorForNode( | 1223 _errorReporter.reportErrorForNode( |
| 1222 CompileTimeErrorCode.CONST_NOT_INITIALIZED, node.returnType, | 1224 CompileTimeErrorCode.CONST_NOT_INITIALIZED, |
| 1223 [fieldElement.name]); | 1225 constructor.returnType, [fieldElement.name]); |
| 1224 foundError = true; | 1226 foundError = true; |
| 1225 } | 1227 } |
| 1226 } | 1228 } |
| 1227 }); | 1229 }); |
| 1228 if (notInitFinalFields.isNotEmpty) { | 1230 if (notInitFinalFields.isNotEmpty) { |
| 1229 foundError = true; | 1231 foundError = true; |
| 1230 AnalysisErrorWithProperties analysisError; | 1232 AnalysisErrorWithProperties analysisError; |
| 1231 if (notInitFinalFields.length == 1) { | 1233 if (notInitFinalFields.length == 1) { |
| 1232 analysisError = _errorReporter.newErrorWithProperties( | 1234 analysisError = _errorReporter.newErrorWithProperties( |
| 1233 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1, | 1235 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_1, |
| 1234 node.returnType, [notInitFinalFields[0].name]); | 1236 constructor.returnType, [notInitFinalFields[0].name]); |
| 1235 } else if (notInitFinalFields.length == 2) { | 1237 } else if (notInitFinalFields.length == 2) { |
| 1236 analysisError = _errorReporter.newErrorWithProperties( | 1238 analysisError = _errorReporter.newErrorWithProperties( |
| 1237 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2, | 1239 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_2, |
| 1238 node.returnType, [ | 1240 constructor.returnType, [ |
| 1239 notInitFinalFields[0].name, | 1241 notInitFinalFields[0].name, |
| 1240 notInitFinalFields[1].name | 1242 notInitFinalFields[1].name |
| 1241 ]); | 1243 ]); |
| 1242 } else { | 1244 } else { |
| 1243 analysisError = _errorReporter.newErrorWithProperties( | 1245 analysisError = _errorReporter.newErrorWithProperties( |
| 1244 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS, | 1246 StaticWarningCode.FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS, |
| 1245 node.returnType, [ | 1247 constructor.returnType, [ |
| 1246 notInitFinalFields[0].name, | 1248 notInitFinalFields[0].name, |
| 1247 notInitFinalFields[1].name, | 1249 notInitFinalFields[1].name, |
| 1248 notInitFinalFields.length - 2 | 1250 notInitFinalFields.length - 2 |
| 1249 ]); | 1251 ]); |
| 1250 } | 1252 } |
| 1251 analysisError.setProperty( | 1253 analysisError.setProperty( |
| 1252 ErrorProperty.NOT_INITIALIZED_FIELDS, notInitFinalFields); | 1254 ErrorProperty.NOT_INITIALIZED_FIELDS, notInitFinalFields); |
| 1253 _errorReporter.reportError(analysisError); | 1255 _errorReporter.reportError(analysisError); |
| 1254 } | 1256 } |
| 1255 return foundError; | 1257 return foundError; |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1552 for (ExecutableElement overriddenElement in overriddenExecutables) { | 1554 for (ExecutableElement overriddenElement in overriddenExecutables) { |
| 1553 if (_checkForAllInvalidOverrideErrorCodes(executableElement, | 1555 if (_checkForAllInvalidOverrideErrorCodes(executableElement, |
| 1554 overriddenElement, parameters, parameterLocations, errorNameTarget)) { | 1556 overriddenElement, parameters, parameterLocations, errorNameTarget)) { |
| 1555 return true; | 1557 return true; |
| 1556 } | 1558 } |
| 1557 } | 1559 } |
| 1558 return false; | 1560 return false; |
| 1559 } | 1561 } |
| 1560 | 1562 |
| 1561 /** | 1563 /** |
| 1562 * Check the given [field] declaration against override-error codes. | 1564 * Check the given field [declaration] against override-error codes. |
| 1563 * | 1565 * |
| 1564 * See [_checkForAllInvalidOverrideErrorCodes]. | 1566 * See [_checkForAllInvalidOverrideErrorCodes]. |
| 1565 */ | 1567 */ |
| 1566 bool _checkForAllInvalidOverrideErrorCodesForField(FieldDeclaration node) { | 1568 bool _checkForAllInvalidOverrideErrorCodesForField( |
| 1567 if (_enclosingClass == null || node.isStatic) { | 1569 FieldDeclaration declaration) { |
| 1570 if (_enclosingClass == null || declaration.isStatic) { |
| 1568 return false; | 1571 return false; |
| 1569 } | 1572 } |
| 1570 bool hasProblems = false; | 1573 bool hasProblems = false; |
| 1571 VariableDeclarationList fields = node.fields; | 1574 VariableDeclarationList fields = declaration.fields; |
| 1572 for (VariableDeclaration field in fields.variables) { | 1575 for (VariableDeclaration field in fields.variables) { |
| 1573 FieldElement element = field.element as FieldElement; | 1576 FieldElement element = field.element as FieldElement; |
| 1574 if (element == null) { | 1577 if (element == null) { |
| 1575 continue; | 1578 continue; |
| 1576 } | 1579 } |
| 1577 PropertyAccessorElement getter = element.getter; | 1580 PropertyAccessorElement getter = element.getter; |
| 1578 PropertyAccessorElement setter = element.setter; | 1581 PropertyAccessorElement setter = element.setter; |
| 1579 SimpleIdentifier fieldName = field.name; | 1582 SimpleIdentifier fieldName = field.name; |
| 1580 if (getter != null) { | 1583 if (getter != null) { |
| 1581 if (_checkForAllInvalidOverrideErrorCodesForExecutable(getter, | 1584 if (_checkForAllInvalidOverrideErrorCodesForExecutable(getter, |
| 1582 ParameterElementImpl.EMPTY_ARRAY, AstNode.EMPTY_LIST, fieldName)) { | 1585 ParameterElementImpl.EMPTY_ARRAY, AstNode.EMPTY_LIST, fieldName)) { |
| 1583 hasProblems = true; | 1586 hasProblems = true; |
| 1584 } | 1587 } |
| 1585 } | 1588 } |
| 1586 if (setter != null) { | 1589 if (setter != null) { |
| 1587 if (_checkForAllInvalidOverrideErrorCodesForExecutable( | 1590 if (_checkForAllInvalidOverrideErrorCodesForExecutable( |
| 1588 setter, setter.parameters, <AstNode>[fieldName], fieldName)) { | 1591 setter, setter.parameters, <AstNode>[fieldName], fieldName)) { |
| 1589 hasProblems = true; | 1592 hasProblems = true; |
| 1590 } | 1593 } |
| 1591 } | 1594 } |
| 1592 } | 1595 } |
| 1593 return hasProblems; | 1596 return hasProblems; |
| 1594 } | 1597 } |
| 1595 | 1598 |
| 1596 /** | 1599 /** |
| 1597 * Check the given [method] declaration against override-error codes. | 1600 * Check the given [method] declaration against override-error codes. |
| 1598 * | 1601 * |
| 1599 * See [_checkForAllInvalidOverrideErrorCodes]. | 1602 * See [_checkForAllInvalidOverrideErrorCodes]. |
| 1600 */ | 1603 */ |
| 1601 bool _checkForAllInvalidOverrideErrorCodesForMethod(MethodDeclaration node) { | 1604 bool _checkForAllInvalidOverrideErrorCodesForMethod( |
| 1605 MethodDeclaration method) { |
| 1602 if (_enclosingClass == null || | 1606 if (_enclosingClass == null || |
| 1603 node.isStatic || | 1607 method.isStatic || |
| 1604 node.body is NativeFunctionBody) { | 1608 method.body is NativeFunctionBody) { |
| 1605 return false; | 1609 return false; |
| 1606 } | 1610 } |
| 1607 ExecutableElement executableElement = node.element; | 1611 ExecutableElement executableElement = method.element; |
| 1608 if (executableElement == null) { | 1612 if (executableElement == null) { |
| 1609 return false; | 1613 return false; |
| 1610 } | 1614 } |
| 1611 SimpleIdentifier methodName = node.name; | 1615 SimpleIdentifier methodName = method.name; |
| 1612 if (methodName.isSynthetic) { | 1616 if (methodName.isSynthetic) { |
| 1613 return false; | 1617 return false; |
| 1614 } | 1618 } |
| 1615 FormalParameterList formalParameterList = node.parameters; | 1619 FormalParameterList formalParameterList = method.parameters; |
| 1616 NodeList<FormalParameter> parameterList = | 1620 NodeList<FormalParameter> parameterList = |
| 1617 formalParameterList != null ? formalParameterList.parameters : null; | 1621 formalParameterList != null ? formalParameterList.parameters : null; |
| 1618 List<AstNode> parameters = | 1622 List<AstNode> parameters = |
| 1619 parameterList != null ? new List.from(parameterList) : null; | 1623 parameterList != null ? new List.from(parameterList) : null; |
| 1620 return _checkForAllInvalidOverrideErrorCodesForExecutable(executableElement, | 1624 return _checkForAllInvalidOverrideErrorCodesForExecutable(executableElement, |
| 1621 executableElement.parameters, parameters, methodName); | 1625 executableElement.parameters, parameters, methodName); |
| 1622 } | 1626 } |
| 1623 | 1627 |
| 1624 /** | 1628 /** |
| 1625 * Verify that all classes of the given [withClause] are valid. | 1629 * Verify that all classes of the given [withClause] are valid. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1661 return problemReported; | 1665 return problemReported; |
| 1662 } | 1666 } |
| 1663 | 1667 |
| 1664 /** | 1668 /** |
| 1665 * Check for errors related to the redirected constructors. | 1669 * Check for errors related to the redirected constructors. |
| 1666 * | 1670 * |
| 1667 * See [StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE], | 1671 * See [StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE], |
| 1668 * [StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE], and | 1672 * [StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION_TYPE], and |
| 1669 * [StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR]. | 1673 * [StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR]. |
| 1670 */ | 1674 */ |
| 1671 bool _checkForAllRedirectConstructorErrorCodes(ConstructorDeclaration node) { | 1675 bool _checkForAllRedirectConstructorErrorCodes( |
| 1676 ConstructorDeclaration declaration) { |
| 1672 // | 1677 // |
| 1673 // Prepare redirected constructor node | 1678 // Prepare redirected constructor node |
| 1674 // | 1679 // |
| 1675 ConstructorName redirectedConstructor = node.redirectedConstructor; | 1680 ConstructorName redirectedConstructor = declaration.redirectedConstructor; |
| 1676 if (redirectedConstructor == null) { | 1681 if (redirectedConstructor == null) { |
| 1677 return false; | 1682 return false; |
| 1678 } | 1683 } |
| 1679 // | 1684 // |
| 1680 // Prepare redirected constructor type | 1685 // Prepare redirected constructor type |
| 1681 // | 1686 // |
| 1682 ConstructorElement redirectedElement = redirectedConstructor.staticElement; | 1687 ConstructorElement redirectedElement = redirectedConstructor.staticElement; |
| 1683 if (redirectedElement == null) { | 1688 if (redirectedElement == null) { |
| 1684 // | 1689 // |
| 1685 // If the element is null, we check for the | 1690 // If the element is null, we check for the |
| 1686 // REDIRECT_TO_MISSING_CONSTRUCTOR case | 1691 // REDIRECT_TO_MISSING_CONSTRUCTOR case |
| 1687 // | 1692 // |
| 1688 TypeName constructorTypeName = redirectedConstructor.type; | 1693 TypeName constructorTypeName = redirectedConstructor.type; |
| 1689 DartType redirectedType = constructorTypeName.type; | 1694 DartType redirectedType = constructorTypeName.type; |
| 1690 if (redirectedType != null && | 1695 if (redirectedType != null && |
| 1691 redirectedType.element != null && | 1696 redirectedType.element != null && |
| 1692 !redirectedType.isDynamic) { | 1697 !redirectedType.isDynamic) { |
| 1693 // | 1698 // |
| 1694 // Prepare the constructor name | 1699 // Prepare the constructor name |
| 1695 // | 1700 // |
| 1696 String constructorStrName = constructorTypeName.name.name; | 1701 String constructorStrName = constructorTypeName.name.name; |
| 1697 if (redirectedConstructor.name != null) { | 1702 if (redirectedConstructor.name != null) { |
| 1698 constructorStrName += ".${redirectedConstructor.name.name}"; | 1703 constructorStrName += ".${redirectedConstructor.name.name}"; |
| 1699 } | 1704 } |
| 1700 ErrorCode errorCode = (node.constKeyword != null | 1705 ErrorCode errorCode = (declaration.constKeyword != null |
| 1701 ? CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR | 1706 ? CompileTimeErrorCode.REDIRECT_TO_MISSING_CONSTRUCTOR |
| 1702 : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR); | 1707 : StaticWarningCode.REDIRECT_TO_MISSING_CONSTRUCTOR); |
| 1703 _errorReporter.reportErrorForNode(errorCode, redirectedConstructor, [ | 1708 _errorReporter.reportErrorForNode(errorCode, redirectedConstructor, [ |
| 1704 constructorStrName, | 1709 constructorStrName, |
| 1705 redirectedType.displayName | 1710 redirectedType.displayName |
| 1706 ]); | 1711 ]); |
| 1707 return true; | 1712 return true; |
| 1708 } | 1713 } |
| 1709 return false; | 1714 return false; |
| 1710 } | 1715 } |
| 1711 FunctionType redirectedType = redirectedElement.type; | 1716 FunctionType redirectedType = redirectedElement.type; |
| 1712 DartType redirectedReturnType = redirectedType.returnType; | 1717 DartType redirectedReturnType = redirectedType.returnType; |
| 1713 // | 1718 // |
| 1714 // Report specific problem when return type is incompatible | 1719 // Report specific problem when return type is incompatible |
| 1715 // | 1720 // |
| 1716 FunctionType constructorType = node.element.type; | 1721 FunctionType constructorType = declaration.element.type; |
| 1717 DartType constructorReturnType = constructorType.returnType; | 1722 DartType constructorReturnType = constructorType.returnType; |
| 1718 if (!redirectedReturnType.isAssignableTo(constructorReturnType)) { | 1723 if (!redirectedReturnType.isAssignableTo(constructorReturnType)) { |
| 1719 _errorReporter.reportErrorForNode( | 1724 _errorReporter.reportErrorForNode( |
| 1720 StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, | 1725 StaticWarningCode.REDIRECT_TO_INVALID_RETURN_TYPE, |
| 1721 redirectedConstructor, [redirectedReturnType, constructorReturnType]); | 1726 redirectedConstructor, [redirectedReturnType, constructorReturnType]); |
| 1722 return true; | 1727 return true; |
| 1723 } | 1728 } |
| 1724 // | 1729 // |
| 1725 // Check parameters | 1730 // Check parameters |
| 1726 // | 1731 // |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1741 * constructor and the return type is not assignable to `null`; that is, we | 1746 * constructor and the return type is not assignable to `null`; that is, we |
| 1742 * don't have `return;` if the enclosing method has a return type. | 1747 * don't have `return;` if the enclosing method has a return type. |
| 1743 * | 1748 * |
| 1744 * Check that the return type matches the type of the declared return type in | 1749 * Check that the return type matches the type of the declared return type in |
| 1745 * the enclosing method or function. | 1750 * the enclosing method or function. |
| 1746 * | 1751 * |
| 1747 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR], | 1752 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR], |
| 1748 * [StaticWarningCode.RETURN_WITHOUT_VALUE], and | 1753 * [StaticWarningCode.RETURN_WITHOUT_VALUE], and |
| 1749 * [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. | 1754 * [StaticTypeWarningCode.RETURN_OF_INVALID_TYPE]. |
| 1750 */ | 1755 */ |
| 1751 bool _checkForAllReturnStatementErrorCodes(ReturnStatement node) { | 1756 bool _checkForAllReturnStatementErrorCodes(ReturnStatement statement) { |
| 1752 FunctionType functionType = | 1757 FunctionType functionType = |
| 1753 _enclosingFunction == null ? null : _enclosingFunction.type; | 1758 _enclosingFunction == null ? null : _enclosingFunction.type; |
| 1754 DartType expectedReturnType = functionType == null | 1759 DartType expectedReturnType = functionType == null |
| 1755 ? DynamicTypeImpl.instance | 1760 ? DynamicTypeImpl.instance |
| 1756 : functionType.returnType; | 1761 : functionType.returnType; |
| 1757 Expression returnExpression = node.expression; | 1762 Expression returnExpression = statement.expression; |
| 1758 // RETURN_IN_GENERATIVE_CONSTRUCTOR | 1763 // RETURN_IN_GENERATIVE_CONSTRUCTOR |
| 1759 bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && | 1764 bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && |
| 1760 !(_enclosingFunction as ConstructorElement).isFactory; | 1765 !(_enclosingFunction as ConstructorElement).isFactory; |
| 1761 if (isGenerativeConstructor) { | 1766 if (isGenerativeConstructor) { |
| 1762 if (returnExpression == null) { | 1767 if (returnExpression == null) { |
| 1763 return false; | 1768 return false; |
| 1764 } | 1769 } |
| 1765 _errorReporter.reportErrorForNode( | 1770 _errorReporter.reportErrorForNode( |
| 1766 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, | 1771 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, |
| 1767 returnExpression); | 1772 returnExpression); |
| 1768 return true; | 1773 return true; |
| 1769 } | 1774 } |
| 1770 // RETURN_WITHOUT_VALUE | 1775 // RETURN_WITHOUT_VALUE |
| 1771 if (returnExpression == null) { | 1776 if (returnExpression == null) { |
| 1772 if (_inGenerator || | 1777 if (_inGenerator || |
| 1773 _computeReturnTypeForMethod(null) | 1778 _computeReturnTypeForMethod(null) |
| 1774 .isAssignableTo(expectedReturnType)) { | 1779 .isAssignableTo(expectedReturnType)) { |
| 1775 return false; | 1780 return false; |
| 1776 } | 1781 } |
| 1777 _hasReturnWithoutValue = true; | 1782 _hasReturnWithoutValue = true; |
| 1778 _errorReporter.reportErrorForNode( | 1783 _errorReporter.reportErrorForNode( |
| 1779 StaticWarningCode.RETURN_WITHOUT_VALUE, node); | 1784 StaticWarningCode.RETURN_WITHOUT_VALUE, statement); |
| 1780 return true; | 1785 return true; |
| 1781 } else if (_inGenerator) { | 1786 } else if (_inGenerator) { |
| 1782 // RETURN_IN_GENERATOR | 1787 // RETURN_IN_GENERATOR |
| 1783 _errorReporter.reportErrorForNode( | 1788 _errorReporter.reportErrorForNode( |
| 1784 CompileTimeErrorCode.RETURN_IN_GENERATOR, node); | 1789 CompileTimeErrorCode.RETURN_IN_GENERATOR, statement); |
| 1785 } | 1790 } |
| 1786 // RETURN_OF_INVALID_TYPE | 1791 // RETURN_OF_INVALID_TYPE |
| 1787 return _checkForReturnOfInvalidType(returnExpression, expectedReturnType); | 1792 return _checkForReturnOfInvalidType(returnExpression, expectedReturnType); |
| 1788 } | 1793 } |
| 1789 | 1794 |
| 1790 /** | 1795 /** |
| 1791 * Verify that the export namespace of the given export [directive] does not | 1796 * Verify that the export namespace of the given export [directive] does not |
| 1792 * export any name already exported by another export directive. The | 1797 * export any name already exported by another export directive. The |
| 1793 * [exportElement] is the [ExportElement] retrieved from the node. If the | 1798 * [exportElement] is the [ExportElement] retrieved from the node. If the |
| 1794 * element in the node was `null`, then this method is not called. The | 1799 * element in the node was `null`, then this method is not called. The |
| 1795 * [exportedLibrary] is the library element containing the exported element. | 1800 * [exportedLibrary] is the library element containing the exported element. |
| 1796 * | 1801 * |
| 1797 * See [CompileTimeErrorCode.AMBIGUOUS_EXPORT]. | 1802 * See [CompileTimeErrorCode.AMBIGUOUS_EXPORT]. |
| 1798 */ | 1803 */ |
| 1799 bool _checkForAmbiguousExport(ExportDirective node, | 1804 bool _checkForAmbiguousExport(ExportDirective directive, |
| 1800 ExportElement exportElement, LibraryElement exportedLibrary) { | 1805 ExportElement exportElement, LibraryElement exportedLibrary) { |
| 1801 if (exportedLibrary == null) { | 1806 if (exportedLibrary == null) { |
| 1802 return false; | 1807 return false; |
| 1803 } | 1808 } |
| 1804 // check exported names | 1809 // check exported names |
| 1805 Namespace namespace = | 1810 Namespace namespace = |
| 1806 new NamespaceBuilder().createExportNamespaceForDirective(exportElement); | 1811 new NamespaceBuilder().createExportNamespaceForDirective(exportElement); |
| 1807 Map<String, Element> definedNames = namespace.definedNames; | 1812 Map<String, Element> definedNames = namespace.definedNames; |
| 1808 for (String name in definedNames.keys) { | 1813 for (String name in definedNames.keys) { |
| 1809 Element element = definedNames[name]; | 1814 Element element = definedNames[name]; |
| 1810 Element prevElement = _exportedElements[name]; | 1815 Element prevElement = _exportedElements[name]; |
| 1811 if (element != null && prevElement != null && prevElement != element) { | 1816 if (element != null && prevElement != null && prevElement != element) { |
| 1812 _errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_EXPORT, | 1817 _errorReporter.reportErrorForNode(CompileTimeErrorCode.AMBIGUOUS_EXPORT, |
| 1813 node, [ | 1818 directive, [ |
| 1814 name, | 1819 name, |
| 1815 prevElement.library.definingCompilationUnit.displayName, | 1820 prevElement.library.definingCompilationUnit.displayName, |
| 1816 element.library.definingCompilationUnit.displayName | 1821 element.library.definingCompilationUnit.displayName |
| 1817 ]); | 1822 ]); |
| 1818 return true; | 1823 return true; |
| 1819 } else { | 1824 } else { |
| 1820 _exportedElements[name] = element; | 1825 _exportedElements[name] = element; |
| 1821 } | 1826 } |
| 1822 } | 1827 } |
| 1823 return false; | 1828 return false; |
| 1824 } | 1829 } |
| 1825 | 1830 |
| 1826 /** | 1831 /** |
| 1827 * Verify that the given [expression] can be assigned to its corresponding | 1832 * Verify that the given [expression] can be assigned to its corresponding |
| 1828 * parameters. The [expectedStaticType] is the expected static type of the | 1833 * parameters. The [expectedStaticType] is the expected static type of the |
| 1829 * parameter. The [actualStaticType] is the actual static type of the | 1834 * parameter. The [actualStaticType] is the actual static type of the |
| 1830 * argument. The [expectedPropagatedType] is the expected propagated type of | 1835 * argument. |
| 1831 * the parameter, may be `null`. The [actualPropagatedType] is the expected | |
| 1832 * propagated type of the parameter, may be `null`. | |
| 1833 * | 1836 * |
| 1834 * This method corresponds to | 1837 * This method corresponds to |
| 1835 * [BestPracticesVerifier.checkForArgumentTypeNotAssignable]. | 1838 * [BestPracticesVerifier.checkForArgumentTypeNotAssignable]. |
| 1836 * | 1839 * |
| 1837 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], | 1840 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], |
| 1838 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], | 1841 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], |
| 1839 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], | 1842 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], |
| 1840 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], | 1843 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], |
| 1841 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], | 1844 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], |
| 1842 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and | 1845 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1873 } | 1876 } |
| 1874 ParameterElement staticParameterElement = argument.staticParameterElement; | 1877 ParameterElement staticParameterElement = argument.staticParameterElement; |
| 1875 DartType staticParameterType = | 1878 DartType staticParameterType = |
| 1876 staticParameterElement == null ? null : staticParameterElement.type; | 1879 staticParameterElement == null ? null : staticParameterElement.type; |
| 1877 return _checkForArgumentTypeNotAssignableWithExpectedTypes(argument, | 1880 return _checkForArgumentTypeNotAssignableWithExpectedTypes(argument, |
| 1878 staticParameterType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); | 1881 staticParameterType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); |
| 1879 } | 1882 } |
| 1880 | 1883 |
| 1881 /** | 1884 /** |
| 1882 * Verify that the given [expression] can be assigned to its corresponding | 1885 * Verify that the given [expression] can be assigned to its corresponding |
| 1883 * parameters. The [expectedStaticType] is the expected static type. The | 1886 * parameters. The [expectedStaticType] is the expected static type. |
| 1884 * [expectedPropagatedType] is the expected propagated type, may be `null`. | |
| 1885 * | 1887 * |
| 1886 * This method corresponds to | 1888 * This method corresponds to |
| 1887 * [BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes]. | 1889 * [BestPracticesVerifier.checkForArgumentTypeNotAssignableWithExpectedTypes]. |
| 1888 * | 1890 * |
| 1889 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], | 1891 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE], |
| 1890 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], | 1892 * [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], |
| 1891 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], | 1893 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], |
| 1892 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], | 1894 * [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], |
| 1893 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], | 1895 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], |
| 1894 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and | 1896 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2022 } | 2024 } |
| 2023 return false; | 2025 return false; |
| 2024 } | 2026 } |
| 2025 | 2027 |
| 2026 /** | 2028 /** |
| 2027 * Verify that the given [switchCase] is terminated with 'break', 'continue', | 2029 * Verify that the given [switchCase] is terminated with 'break', 'continue', |
| 2028 * 'return' or 'throw'. | 2030 * 'return' or 'throw'. |
| 2029 * | 2031 * |
| 2030 * see [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]. | 2032 * see [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]. |
| 2031 */ | 2033 */ |
| 2032 bool _checkForCaseBlockNotTerminated(SwitchCase node) { | 2034 bool _checkForCaseBlockNotTerminated(SwitchCase switchCase) { |
| 2033 NodeList<Statement> statements = node.statements; | 2035 NodeList<Statement> statements = switchCase.statements; |
| 2034 if (statements.isEmpty) { | 2036 if (statements.isEmpty) { |
| 2035 // fall-through without statements at all | 2037 // fall-through without statements at all |
| 2036 AstNode parent = node.parent; | 2038 AstNode parent = switchCase.parent; |
| 2037 if (parent is SwitchStatement) { | 2039 if (parent is SwitchStatement) { |
| 2038 SwitchStatement switchStatement = parent; | 2040 SwitchStatement switchStatement = parent; |
| 2039 NodeList<SwitchMember> members = switchStatement.members; | 2041 NodeList<SwitchMember> members = switchStatement.members; |
| 2040 int index = members.indexOf(node); | 2042 int index = members.indexOf(switchCase); |
| 2041 if (index != -1 && index < members.length - 1) { | 2043 if (index != -1 && index < members.length - 1) { |
| 2042 return false; | 2044 return false; |
| 2043 } | 2045 } |
| 2044 } | 2046 } |
| 2045 // no other switch member after this one | 2047 // no other switch member after this one |
| 2046 } else { | 2048 } else { |
| 2047 Statement statement = statements[statements.length - 1]; | 2049 Statement statement = statements[statements.length - 1]; |
| 2048 // terminated with statement | 2050 // terminated with statement |
| 2049 if (statement is BreakStatement || | 2051 if (statement is BreakStatement || |
| 2050 statement is ContinueStatement || | 2052 statement is ContinueStatement || |
| 2051 statement is ReturnStatement) { | 2053 statement is ReturnStatement) { |
| 2052 return false; | 2054 return false; |
| 2053 } | 2055 } |
| 2054 // terminated with 'throw' expression | 2056 // terminated with 'throw' expression |
| 2055 if (statement is ExpressionStatement) { | 2057 if (statement is ExpressionStatement) { |
| 2056 Expression expression = statement.expression; | 2058 Expression expression = statement.expression; |
| 2057 if (expression is ThrowExpression) { | 2059 if (expression is ThrowExpression) { |
| 2058 return false; | 2060 return false; |
| 2059 } | 2061 } |
| 2060 } | 2062 } |
| 2061 } | 2063 } |
| 2062 // report error | 2064 // report error |
| 2063 _errorReporter.reportErrorForToken( | 2065 _errorReporter.reportErrorForToken( |
| 2064 StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, node.keyword); | 2066 StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, switchCase.keyword); |
| 2065 return true; | 2067 return true; |
| 2066 } | 2068 } |
| 2067 | 2069 |
| 2068 /** | 2070 /** |
| 2069 * Verify that the switch cases in the given switch [statement] are terminated | 2071 * Verify that the switch cases in the given switch [statement] are terminated |
| 2070 * with 'break', 'continue', 'return' or 'throw'. | 2072 * with 'break', 'continue', 'return' or 'throw'. |
| 2071 * | 2073 * |
| 2072 * See [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]. | 2074 * See [StaticWarningCode.CASE_BLOCK_NOT_TERMINATED]. |
| 2073 */ | 2075 */ |
| 2074 bool _checkForCaseBlocksNotTerminated(SwitchStatement node) { | 2076 bool _checkForCaseBlocksNotTerminated(SwitchStatement statement) { |
| 2075 bool foundError = false; | 2077 bool foundError = false; |
| 2076 NodeList<SwitchMember> members = node.members; | 2078 NodeList<SwitchMember> members = statement.members; |
| 2077 int lastMember = members.length - 1; | 2079 int lastMember = members.length - 1; |
| 2078 for (int i = 0; i < lastMember; i++) { | 2080 for (int i = 0; i < lastMember; i++) { |
| 2079 SwitchMember member = members[i]; | 2081 SwitchMember member = members[i]; |
| 2080 if (member is SwitchCase && _checkForCaseBlockNotTerminated(member)) { | 2082 if (member is SwitchCase && _checkForCaseBlockNotTerminated(member)) { |
| 2081 foundError = true; | 2083 foundError = true; |
| 2082 } | 2084 } |
| 2083 } | 2085 } |
| 2084 return foundError; | 2086 return foundError; |
| 2085 } | 2087 } |
| 2086 | 2088 |
| 2087 /** | 2089 /** |
| 2088 * Verify that the given [method] declaration is abstract only if the | 2090 * Verify that the given [method] declaration is abstract only if the |
| 2089 * enclosing class is also abstract. | 2091 * enclosing class is also abstract. |
| 2090 * | 2092 * |
| 2091 * See [StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER]. | 2093 * See [StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER]. |
| 2092 */ | 2094 */ |
| 2093 bool _checkForConcreteClassWithAbstractMember(MethodDeclaration node) { | 2095 bool _checkForConcreteClassWithAbstractMember(MethodDeclaration method) { |
| 2094 if (node.isAbstract && | 2096 if (method.isAbstract && |
| 2095 _enclosingClass != null && | 2097 _enclosingClass != null && |
| 2096 !_enclosingClass.isAbstract) { | 2098 !_enclosingClass.isAbstract) { |
| 2097 SimpleIdentifier nameNode = node.name; | 2099 SimpleIdentifier nameNode = method.name; |
| 2098 String memberName = nameNode.name; | 2100 String memberName = nameNode.name; |
| 2099 ExecutableElement overriddenMember; | 2101 ExecutableElement overriddenMember; |
| 2100 if (node.isGetter) { | 2102 if (method.isGetter) { |
| 2101 overriddenMember = _enclosingClass.lookUpInheritedConcreteGetter( | 2103 overriddenMember = _enclosingClass.lookUpInheritedConcreteGetter( |
| 2102 memberName, _currentLibrary); | 2104 memberName, _currentLibrary); |
| 2103 } else if (node.isSetter) { | 2105 } else if (method.isSetter) { |
| 2104 overriddenMember = _enclosingClass.lookUpInheritedConcreteSetter( | 2106 overriddenMember = _enclosingClass.lookUpInheritedConcreteSetter( |
| 2105 memberName, _currentLibrary); | 2107 memberName, _currentLibrary); |
| 2106 } else { | 2108 } else { |
| 2107 overriddenMember = _enclosingClass.lookUpInheritedConcreteMethod( | 2109 overriddenMember = _enclosingClass.lookUpInheritedConcreteMethod( |
| 2108 memberName, _currentLibrary); | 2110 memberName, _currentLibrary); |
| 2109 } | 2111 } |
| 2110 if (overriddenMember == null) { | 2112 if (overriddenMember == null) { |
| 2111 _errorReporter.reportErrorForNode( | 2113 _errorReporter.reportErrorForNode( |
| 2112 StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, nameNode, [ | 2114 StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER, nameNode, [ |
| 2113 memberName, | 2115 memberName, |
| 2114 _enclosingClass.displayName | 2116 _enclosingClass.displayName |
| 2115 ]); | 2117 ]); |
| 2116 return true; | 2118 return true; |
| 2117 } | 2119 } |
| 2118 } | 2120 } |
| 2119 return false; | 2121 return false; |
| 2120 } | 2122 } |
| 2121 | 2123 |
| 2122 /** | 2124 /** |
| 2123 * Verify all possible conflicts of the given [constructor]'s name with other | 2125 * Verify all possible conflicts of the given [constructor]'s name with other |
| 2124 * constructors and members of the same class. The [constructorElement] is the | 2126 * constructors and members of the same class. The [constructorElement] is the |
| 2125 * constructor's element. | 2127 * constructor's element. |
| 2126 * | 2128 * |
| 2127 * See [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT], | 2129 * See [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT], |
| 2128 * [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME], | 2130 * [CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME], |
| 2129 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD], and | 2131 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD], and |
| 2130 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD]. | 2132 * [CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD]. |
| 2131 */ | 2133 */ |
| 2132 bool _checkForConflictingConstructorNameAndMember( | 2134 bool _checkForConflictingConstructorNameAndMember( |
| 2133 ConstructorDeclaration node, ConstructorElement constructorElement) { | 2135 ConstructorDeclaration constructor, |
| 2134 SimpleIdentifier constructorName = node.name; | 2136 ConstructorElement constructorElement) { |
| 2137 SimpleIdentifier constructorName = constructor.name; |
| 2135 String name = constructorElement.name; | 2138 String name = constructorElement.name; |
| 2136 ClassElement classElement = constructorElement.enclosingElement; | 2139 ClassElement classElement = constructorElement.enclosingElement; |
| 2137 // constructors | 2140 // constructors |
| 2138 List<ConstructorElement> constructors = classElement.constructors; | 2141 List<ConstructorElement> constructors = classElement.constructors; |
| 2139 for (ConstructorElement otherConstructor in constructors) { | 2142 for (ConstructorElement otherConstructor in constructors) { |
| 2140 if (identical(otherConstructor, constructorElement)) { | 2143 if (identical(otherConstructor, constructorElement)) { |
| 2141 continue; | 2144 continue; |
| 2142 } | 2145 } |
| 2143 if (name == otherConstructor.name) { | 2146 if (name == otherConstructor.name) { |
| 2144 if (name == null || name.length == 0) { | 2147 if (name == null || name.length == 0) { |
| 2145 _errorReporter.reportErrorForNode( | 2148 _errorReporter.reportErrorForNode( |
| 2146 CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, node); | 2149 CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_DEFAULT, constructor); |
| 2147 } else { | 2150 } else { |
| 2148 _errorReporter.reportErrorForNode( | 2151 _errorReporter.reportErrorForNode( |
| 2149 CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME, node, [name]); | 2152 CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR_NAME, constructor, |
| 2153 [name]); |
| 2150 } | 2154 } |
| 2151 return true; | 2155 return true; |
| 2152 } | 2156 } |
| 2153 } | 2157 } |
| 2154 // conflict with class member | 2158 // conflict with class member |
| 2155 if (constructorName != null && | 2159 if (constructorName != null && |
| 2156 constructorElement != null && | 2160 constructorElement != null && |
| 2157 !constructorName.isSynthetic) { | 2161 !constructorName.isSynthetic) { |
| 2158 // fields | 2162 // fields |
| 2159 FieldElement field = classElement.getField(name); | 2163 FieldElement field = classElement.getField(name); |
| 2160 if (field != null) { | 2164 if (field != null) { |
| 2161 _errorReporter.reportErrorForNode( | 2165 _errorReporter.reportErrorForNode( |
| 2162 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, node, | 2166 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD, |
| 2163 [name]); | 2167 constructor, [name]); |
| 2164 return true; | 2168 return true; |
| 2165 } | 2169 } |
| 2166 // methods | 2170 // methods |
| 2167 MethodElement method = classElement.getMethod(name); | 2171 MethodElement method = classElement.getMethod(name); |
| 2168 if (method != null) { | 2172 if (method != null) { |
| 2169 _errorReporter.reportErrorForNode( | 2173 _errorReporter.reportErrorForNode( |
| 2170 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, node, | 2174 CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD, |
| 2171 [name]); | 2175 constructor, [name]); |
| 2172 return true; | 2176 return true; |
| 2173 } | 2177 } |
| 2174 } | 2178 } |
| 2175 return false; | 2179 return false; |
| 2176 } | 2180 } |
| 2177 | 2181 |
| 2178 /** | 2182 /** |
| 2179 * Verify that the [enclosingClass] does not have a method and getter pair | 2183 * Verify that the [_enclosingClass] does not have a method and getter pair |
| 2180 * with the same name on, via inheritance. | 2184 * with the same name on, via inheritance. |
| 2181 * | 2185 * |
| 2182 * See [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD], and | 2186 * See [CompileTimeErrorCode.CONFLICTING_GETTER_AND_METHOD], and |
| 2183 * [CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER]. | 2187 * [CompileTimeErrorCode.CONFLICTING_METHOD_AND_GETTER]. |
| 2184 */ | 2188 */ |
| 2185 bool _checkForConflictingGetterAndMethod() { | 2189 bool _checkForConflictingGetterAndMethod() { |
| 2186 if (_enclosingClass == null) { | 2190 if (_enclosingClass == null) { |
| 2187 return false; | 2191 return false; |
| 2188 } | 2192 } |
| 2189 bool hasProblem = false; | 2193 bool hasProblem = false; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2226 _enclosingClass.displayName, | 2230 _enclosingClass.displayName, |
| 2227 inherited.enclosingElement.displayName, | 2231 inherited.enclosingElement.displayName, |
| 2228 name | 2232 name |
| 2229 ]); | 2233 ]); |
| 2230 } | 2234 } |
| 2231 // done | 2235 // done |
| 2232 return hasProblem; | 2236 return hasProblem; |
| 2233 } | 2237 } |
| 2234 | 2238 |
| 2235 /** | 2239 /** |
| 2236 * Verify that the superclass of the [enclosingClass] does not declare | 2240 * Verify that the superclass of the [_enclosingClass] does not declare |
| 2237 * accessible static members with the same name as the instance | 2241 * accessible static members with the same name as the instance |
| 2238 * getters/setters declared in [enclosingClass]. | 2242 * getters/setters declared in [_enclosingClass]. |
| 2239 * | 2243 * |
| 2240 * See [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER],
and | 2244 * See [StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER],
and |
| 2241 * [StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER]. | 2245 * [StaticWarningCode.CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER]. |
| 2242 */ | 2246 */ |
| 2243 bool _checkForConflictingInstanceGetterAndSuperclassMember() { | 2247 bool _checkForConflictingInstanceGetterAndSuperclassMember() { |
| 2244 if (_enclosingClass == null) { | 2248 if (_enclosingClass == null) { |
| 2245 return false; | 2249 return false; |
| 2246 } | 2250 } |
| 2247 InterfaceType enclosingType = _enclosingClass.type; | 2251 InterfaceType enclosingType = _enclosingClass.type; |
| 2248 // check every accessor | 2252 // check every accessor |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2301 | 2305 |
| 2302 /** | 2306 /** |
| 2303 * Verify that the enclosing class does not have a setter with the same name | 2307 * Verify that the enclosing class does not have a setter with the same name |
| 2304 * as the given instance method declaration. | 2308 * as the given instance method declaration. |
| 2305 * | 2309 * |
| 2306 * TODO(jwren) add other "conflicting" error codes into algorithm/ data | 2310 * TODO(jwren) add other "conflicting" error codes into algorithm/ data |
| 2307 * structure. | 2311 * structure. |
| 2308 * | 2312 * |
| 2309 * See [StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER]. | 2313 * See [StaticWarningCode.CONFLICTING_INSTANCE_METHOD_SETTER]. |
| 2310 */ | 2314 */ |
| 2311 bool _checkForConflictingInstanceMethodSetter(ClassDeclaration node) { | 2315 bool _checkForConflictingInstanceMethodSetter(ClassDeclaration declaration) { |
| 2312 // Reference all of the class members in this class. | 2316 // Reference all of the class members in this class. |
| 2313 NodeList<ClassMember> classMembers = node.members; | 2317 NodeList<ClassMember> classMembers = declaration.members; |
| 2314 if (classMembers.isEmpty) { | 2318 if (classMembers.isEmpty) { |
| 2315 return false; | 2319 return false; |
| 2316 } | 2320 } |
| 2317 // Create a HashMap to track conflicting members, and then loop through | 2321 // Create a HashMap to track conflicting members, and then loop through |
| 2318 // members in the class to construct the HashMap, at the same time, | 2322 // members in the class to construct the HashMap, at the same time, |
| 2319 // look for violations. Don't add members if they are part of a conflict, | 2323 // look for violations. Don't add members if they are part of a conflict, |
| 2320 // this prevents multiple warnings for one issue. | 2324 // this prevents multiple warnings for one issue. |
| 2321 bool foundError = false; | 2325 bool foundError = false; |
| 2322 HashMap<String, ClassMember> memberHashMap = | 2326 HashMap<String, ClassMember> memberHashMap = |
| 2323 new HashMap<String, ClassMember>(); | 2327 new HashMap<String, ClassMember>(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2395 return foundError; | 2399 return foundError; |
| 2396 } | 2400 } |
| 2397 | 2401 |
| 2398 /** | 2402 /** |
| 2399 * Verify that the enclosing class does not have an instance member with the | 2403 * Verify that the enclosing class does not have an instance member with the |
| 2400 * same name as the given static [method] declaration. | 2404 * same name as the given static [method] declaration. |
| 2401 * | 2405 * |
| 2402 * See [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]. | 2406 * See [StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER]. |
| 2403 */ | 2407 */ |
| 2404 bool _checkForConflictingStaticGetterAndInstanceSetter( | 2408 bool _checkForConflictingStaticGetterAndInstanceSetter( |
| 2405 MethodDeclaration node) { | 2409 MethodDeclaration method) { |
| 2406 if (!node.isStatic) { | 2410 if (!method.isStatic) { |
| 2407 return false; | 2411 return false; |
| 2408 } | 2412 } |
| 2409 // prepare name | 2413 // prepare name |
| 2410 SimpleIdentifier nameNode = node.name; | 2414 SimpleIdentifier nameNode = method.name; |
| 2411 if (nameNode == null) { | 2415 if (nameNode == null) { |
| 2412 return false; | 2416 return false; |
| 2413 } | 2417 } |
| 2414 String name = nameNode.name; | 2418 String name = nameNode.name; |
| 2415 // prepare enclosing type | 2419 // prepare enclosing type |
| 2416 if (_enclosingClass == null) { | 2420 if (_enclosingClass == null) { |
| 2417 return false; | 2421 return false; |
| 2418 } | 2422 } |
| 2419 InterfaceType enclosingType = _enclosingClass.type; | 2423 InterfaceType enclosingType = _enclosingClass.type; |
| 2420 // try to find setter | 2424 // try to find setter |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2437 return true; | 2441 return true; |
| 2438 } | 2442 } |
| 2439 | 2443 |
| 2440 /** | 2444 /** |
| 2441 * Verify that the enclosing class does not have an instance member with the | 2445 * Verify that the enclosing class does not have an instance member with the |
| 2442 * same name as the given static [method] declaration. | 2446 * same name as the given static [method] declaration. |
| 2443 * | 2447 * |
| 2444 * See [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]. | 2448 * See [StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER]. |
| 2445 */ | 2449 */ |
| 2446 bool _checkForConflictingStaticSetterAndInstanceMember( | 2450 bool _checkForConflictingStaticSetterAndInstanceMember( |
| 2447 MethodDeclaration node) { | 2451 MethodDeclaration method) { |
| 2448 if (!node.isStatic) { | 2452 if (!method.isStatic) { |
| 2449 return false; | 2453 return false; |
| 2450 } | 2454 } |
| 2451 // prepare name | 2455 // prepare name |
| 2452 SimpleIdentifier nameNode = node.name; | 2456 SimpleIdentifier nameNode = method.name; |
| 2453 if (nameNode == null) { | 2457 if (nameNode == null) { |
| 2454 return false; | 2458 return false; |
| 2455 } | 2459 } |
| 2456 String name = nameNode.name; | 2460 String name = nameNode.name; |
| 2457 // prepare enclosing type | 2461 // prepare enclosing type |
| 2458 if (_enclosingClass == null) { | 2462 if (_enclosingClass == null) { |
| 2459 return false; | 2463 return false; |
| 2460 } | 2464 } |
| 2461 InterfaceType enclosingType = _enclosingClass.type; | 2465 InterfaceType enclosingType = _enclosingClass.type; |
| 2462 // try to find member | 2466 // try to find member |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2485 return true; | 2489 return true; |
| 2486 } | 2490 } |
| 2487 | 2491 |
| 2488 /** | 2492 /** |
| 2489 * Verify all conflicts between type variable and enclosing class. | 2493 * Verify all conflicts between type variable and enclosing class. |
| 2490 * TODO(scheglov) | 2494 * TODO(scheglov) |
| 2491 * | 2495 * |
| 2492 * See [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS], and | 2496 * See [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS], and |
| 2493 * [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]. | 2497 * [CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER]. |
| 2494 */ | 2498 */ |
| 2495 bool _checkForConflictingTypeVariableErrorCodes(ClassDeclaration node) { | 2499 bool _checkForConflictingTypeVariableErrorCodes( |
| 2500 ClassDeclaration declaration) { |
| 2496 bool problemReported = false; | 2501 bool problemReported = false; |
| 2497 for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) { | 2502 for (TypeParameterElement typeParameter in _enclosingClass.typeParameters) { |
| 2498 String name = typeParameter.name; | 2503 String name = typeParameter.name; |
| 2499 // name is same as the name of the enclosing class | 2504 // name is same as the name of the enclosing class |
| 2500 if (_enclosingClass.name == name) { | 2505 if (_enclosingClass.name == name) { |
| 2501 _errorReporter.reportErrorForOffset( | 2506 _errorReporter.reportErrorForOffset( |
| 2502 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, | 2507 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS, |
| 2503 typeParameter.nameOffset, name.length, [name]); | 2508 typeParameter.nameOffset, name.length, [name]); |
| 2504 problemReported = true; | 2509 problemReported = true; |
| 2505 } | 2510 } |
| 2506 // check members | 2511 // check members |
| 2507 if (_enclosingClass.getMethod(name) != null || | 2512 if (_enclosingClass.getMethod(name) != null || |
| 2508 _enclosingClass.getGetter(name) != null || | 2513 _enclosingClass.getGetter(name) != null || |
| 2509 _enclosingClass.getSetter(name) != null) { | 2514 _enclosingClass.getSetter(name) != null) { |
| 2510 _errorReporter.reportErrorForOffset( | 2515 _errorReporter.reportErrorForOffset( |
| 2511 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER, | 2516 CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER, |
| 2512 typeParameter.nameOffset, name.length, [name]); | 2517 typeParameter.nameOffset, name.length, [name]); |
| 2513 problemReported = true; | 2518 problemReported = true; |
| 2514 } | 2519 } |
| 2515 } | 2520 } |
| 2516 return problemReported; | 2521 return problemReported; |
| 2517 } | 2522 } |
| 2518 | 2523 |
| 2519 /** | 2524 /** |
| 2520 * Verify that if the given [constructor] declaration is 'const' then there | 2525 * Verify that if the given [constructor] declaration is 'const' then there |
| 2521 * are no invocations of non-'const' super constructors. | 2526 * are no invocations of non-'const' super constructors. |
| 2522 * | 2527 * |
| 2523 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]. | 2528 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER]. |
| 2524 */ | 2529 */ |
| 2525 bool _checkForConstConstructorWithNonConstSuper(ConstructorDeclaration node) { | 2530 bool _checkForConstConstructorWithNonConstSuper( |
| 2531 ConstructorDeclaration constructor) { |
| 2526 if (!_isEnclosingConstructorConst) { | 2532 if (!_isEnclosingConstructorConst) { |
| 2527 return false; | 2533 return false; |
| 2528 } | 2534 } |
| 2529 // OK, const factory, checked elsewhere | 2535 // OK, const factory, checked elsewhere |
| 2530 if (node.factoryKeyword != null) { | 2536 if (constructor.factoryKeyword != null) { |
| 2531 return false; | 2537 return false; |
| 2532 } | 2538 } |
| 2533 // check for mixins | 2539 // check for mixins |
| 2534 if (_enclosingClass.mixins.length != 0) { | 2540 if (_enclosingClass.mixins.length != 0) { |
| 2535 _errorReporter.reportErrorForNode( | 2541 _errorReporter.reportErrorForNode( |
| 2536 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN, node.returnType); | 2542 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN, |
| 2543 constructor.returnType); |
| 2537 return true; | 2544 return true; |
| 2538 } | 2545 } |
| 2539 // try to find and check super constructor invocation | 2546 // try to find and check super constructor invocation |
| 2540 for (ConstructorInitializer initializer in node.initializers) { | 2547 for (ConstructorInitializer initializer in constructor.initializers) { |
| 2541 if (initializer is SuperConstructorInvocation) { | 2548 if (initializer is SuperConstructorInvocation) { |
| 2542 SuperConstructorInvocation superInvocation = initializer; | 2549 SuperConstructorInvocation superInvocation = initializer; |
| 2543 ConstructorElement element = superInvocation.staticElement; | 2550 ConstructorElement element = superInvocation.staticElement; |
| 2544 if (element == null || element.isConst) { | 2551 if (element == null || element.isConst) { |
| 2545 return false; | 2552 return false; |
| 2546 } | 2553 } |
| 2547 _errorReporter.reportErrorForNode( | 2554 _errorReporter.reportErrorForNode( |
| 2548 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, | 2555 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, |
| 2549 superInvocation, [element.enclosingElement.displayName]); | 2556 superInvocation, [element.enclosingElement.displayName]); |
| 2550 return true; | 2557 return true; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2562 supertype.element.unnamedConstructor; | 2569 supertype.element.unnamedConstructor; |
| 2563 if (unnamedConstructor == null) { | 2570 if (unnamedConstructor == null) { |
| 2564 return false; | 2571 return false; |
| 2565 } | 2572 } |
| 2566 if (unnamedConstructor.isConst) { | 2573 if (unnamedConstructor.isConst) { |
| 2567 return false; | 2574 return false; |
| 2568 } | 2575 } |
| 2569 // default constructor is not 'const', report problem | 2576 // default constructor is not 'const', report problem |
| 2570 _errorReporter.reportErrorForNode( | 2577 _errorReporter.reportErrorForNode( |
| 2571 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, | 2578 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER, |
| 2572 node.returnType, [supertype.displayName]); | 2579 constructor.returnType, [supertype.displayName]); |
| 2573 return true; | 2580 return true; |
| 2574 } | 2581 } |
| 2575 | 2582 |
| 2576 /** | 2583 /** |
| 2577 * Verify that if the given constructor [declaration] is 'const' then there | 2584 * Verify that if the given [constructor] declaration is 'const' then there |
| 2578 * are no non-final instance variable. The [constructorElement] is the | 2585 * are no non-final instance variable. The [constructorElement] is the |
| 2579 * constructor element. | 2586 * constructor element. |
| 2580 * | 2587 * |
| 2581 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]. | 2588 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD]. |
| 2582 */ | 2589 */ |
| 2583 bool _checkForConstConstructorWithNonFinalField( | 2590 bool _checkForConstConstructorWithNonFinalField( |
| 2584 ConstructorDeclaration node, ConstructorElement constructorElement) { | 2591 ConstructorDeclaration constructor, |
| 2592 ConstructorElement constructorElement) { |
| 2585 if (!_isEnclosingConstructorConst) { | 2593 if (!_isEnclosingConstructorConst) { |
| 2586 return false; | 2594 return false; |
| 2587 } | 2595 } |
| 2588 // check if there is non-final field | 2596 // check if there is non-final field |
| 2589 ClassElement classElement = constructorElement.enclosingElement; | 2597 ClassElement classElement = constructorElement.enclosingElement; |
| 2590 if (!classElement.hasNonFinalField) { | 2598 if (!classElement.hasNonFinalField) { |
| 2591 return false; | 2599 return false; |
| 2592 } | 2600 } |
| 2593 // report problem | 2601 // report problem |
| 2594 _errorReporter.reportErrorForNode( | 2602 _errorReporter.reportErrorForNode( |
| 2595 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, node); | 2603 CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, |
| 2604 constructor); |
| 2596 return true; | 2605 return true; |
| 2597 } | 2606 } |
| 2598 | 2607 |
| 2599 /** | 2608 /** |
| 2600 * Verify that the given 'const' instance creation [expression] is not | 2609 * Verify that the given 'const' instance creation [expression] is not |
| 2601 * creating a deferred type. The [constructorName] is the constructor name, | 2610 * creating a deferred type. The [constructorName] is the constructor name, |
| 2602 * always non-`null`. The [typeName] is the name of the type defining the | 2611 * always non-`null`. The [typeName] is the name of the type defining the |
| 2603 * constructor, always non-`null`. | 2612 * constructor, always non-`null`. |
| 2604 * | 2613 * |
| 2605 * See [CompileTimeErrorCode.CONST_DEFERRED_CLASS]. | 2614 * See [CompileTimeErrorCode.CONST_DEFERRED_CLASS]. |
| 2606 */ | 2615 */ |
| 2607 bool _checkForConstDeferredClass(InstanceCreationExpression node, | 2616 bool _checkForConstDeferredClass(InstanceCreationExpression expression, |
| 2608 ConstructorName constructorName, TypeName typeName) { | 2617 ConstructorName constructorName, TypeName typeName) { |
| 2609 if (typeName.isDeferred) { | 2618 if (typeName.isDeferred) { |
| 2610 _errorReporter.reportErrorForNode( | 2619 _errorReporter.reportErrorForNode( |
| 2611 CompileTimeErrorCode.CONST_DEFERRED_CLASS, constructorName, | 2620 CompileTimeErrorCode.CONST_DEFERRED_CLASS, constructorName, |
| 2612 [typeName.name.name]); | 2621 [typeName.name.name]); |
| 2613 return true; | 2622 return true; |
| 2614 } | 2623 } |
| 2615 return false; | 2624 return false; |
| 2616 } | 2625 } |
| 2617 | 2626 |
| 2618 /** | 2627 /** |
| 2619 * Verify that the given throw [expression] is not enclosed in a 'const' | 2628 * Verify that the given throw [expression] is not enclosed in a 'const' |
| 2620 * constructor declaration. | 2629 * constructor declaration. |
| 2621 * | 2630 * |
| 2622 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION]. | 2631 * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION]. |
| 2623 */ | 2632 */ |
| 2624 bool _checkForConstEvalThrowsException(ThrowExpression node) { | 2633 bool _checkForConstEvalThrowsException(ThrowExpression expression) { |
| 2625 if (_isEnclosingConstructorConst) { | 2634 if (_isEnclosingConstructorConst) { |
| 2626 _errorReporter.reportErrorForNode( | 2635 _errorReporter.reportErrorForNode( |
| 2627 CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, node); | 2636 CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION, expression); |
| 2628 return true; | 2637 return true; |
| 2629 } | 2638 } |
| 2630 return false; | 2639 return false; |
| 2631 } | 2640 } |
| 2632 | 2641 |
| 2633 /** | 2642 /** |
| 2634 * Verify that the given normal formal [parameter] is not 'const'. | 2643 * Verify that the given normal formal [parameter] is not 'const'. |
| 2635 * | 2644 * |
| 2636 * See [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]. | 2645 * See [CompileTimeErrorCode.CONST_FORMAL_PARAMETER]. |
| 2637 */ | 2646 */ |
| 2638 bool _checkForConstFormalParameter(NormalFormalParameter node) { | 2647 bool _checkForConstFormalParameter(NormalFormalParameter parameter) { |
| 2639 if (node.isConst) { | 2648 if (parameter.isConst) { |
| 2640 _errorReporter.reportErrorForNode( | 2649 _errorReporter.reportErrorForNode( |
| 2641 CompileTimeErrorCode.CONST_FORMAL_PARAMETER, node); | 2650 CompileTimeErrorCode.CONST_FORMAL_PARAMETER, parameter); |
| 2642 return true; | 2651 return true; |
| 2643 } | 2652 } |
| 2644 return false; | 2653 return false; |
| 2645 } | 2654 } |
| 2646 | 2655 |
| 2647 /** | 2656 /** |
| 2648 * Verify that the given instance creation [expression] is not being invoked | 2657 * Verify that the given instance creation [expression] is not being invoked |
| 2649 * on an abstract class. The [typeName] is the [TypeName] of the | 2658 * on an abstract class. The [typeName] is the [TypeName] of the |
| 2650 * [ConstructorName] from the [InstanceCreationExpression], this is the AST | 2659 * [ConstructorName] from the [InstanceCreationExpression], this is the AST |
| 2651 * node that the error is attached to. The [type] is the type being | 2660 * node that the error is attached to. The [type] is the type being |
| 2652 * constructed with this [InstanceCreationExpression]. | 2661 * constructed with this [InstanceCreationExpression]. |
| 2653 * | 2662 * |
| 2654 * See [StaticWarningCode.CONST_WITH_ABSTRACT_CLASS], and | 2663 * See [StaticWarningCode.CONST_WITH_ABSTRACT_CLASS], and |
| 2655 * [StaticWarningCode.NEW_WITH_ABSTRACT_CLASS]. | 2664 * [StaticWarningCode.NEW_WITH_ABSTRACT_CLASS]. |
| 2656 */ | 2665 */ |
| 2657 bool _checkForConstOrNewWithAbstractClass( | 2666 bool _checkForConstOrNewWithAbstractClass( |
| 2658 InstanceCreationExpression node, TypeName typeName, InterfaceType type) { | 2667 InstanceCreationExpression expression, TypeName typeName, |
| 2668 InterfaceType type) { |
| 2659 if (type.element.isAbstract) { | 2669 if (type.element.isAbstract) { |
| 2660 ConstructorElement element = node.staticElement; | 2670 ConstructorElement element = expression.staticElement; |
| 2661 if (element != null && !element.isFactory) { | 2671 if (element != null && !element.isFactory) { |
| 2662 if ((node.keyword as sc.KeywordToken).keyword == sc.Keyword.CONST) { | 2672 if ((expression.keyword as sc.KeywordToken).keyword == |
| 2673 sc.Keyword.CONST) { |
| 2663 _errorReporter.reportErrorForNode( | 2674 _errorReporter.reportErrorForNode( |
| 2664 StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName); | 2675 StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName); |
| 2665 } else { | 2676 } else { |
| 2666 _errorReporter.reportErrorForNode( | 2677 _errorReporter.reportErrorForNode( |
| 2667 StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName); | 2678 StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName); |
| 2668 } | 2679 } |
| 2669 return true; | 2680 return true; |
| 2670 } | 2681 } |
| 2671 } | 2682 } |
| 2672 return false; | 2683 return false; |
| 2673 } | 2684 } |
| 2674 | 2685 |
| 2675 /** | 2686 /** |
| 2676 * Verify that the given instance creation [expression] is not being invoked | 2687 * Verify that the given instance creation [expression] is not being invoked |
| 2677 * on an enum. The [typeName] is the [TypeName] of the [ConstructorName] from | 2688 * on an enum. The [typeName] is the [TypeName] of the [ConstructorName] from |
| 2678 * the [InstanceCreationExpression], this is the AST node that the error is | 2689 * the [InstanceCreationExpression], this is the AST node that the error is |
| 2679 * attached to. The [type] is the type being constructed with this | 2690 * attached to. The [type] is the type being constructed with this |
| 2680 * [InstanceCreationExpression]. | 2691 * [InstanceCreationExpression]. |
| 2681 * | 2692 * |
| 2682 * See [CompileTimeErrorCode.INSTANTIATE_ENUM]. | 2693 * See [CompileTimeErrorCode.INSTANTIATE_ENUM]. |
| 2683 */ | 2694 */ |
| 2684 bool _checkForConstOrNewWithEnum( | 2695 bool _checkForConstOrNewWithEnum(InstanceCreationExpression expression, |
| 2685 InstanceCreationExpression node, TypeName typeName, InterfaceType type) { | 2696 TypeName typeName, InterfaceType type) { |
| 2686 if (type.element.isEnum) { | 2697 if (type.element.isEnum) { |
| 2687 _errorReporter.reportErrorForNode( | 2698 _errorReporter.reportErrorForNode( |
| 2688 CompileTimeErrorCode.INSTANTIATE_ENUM, typeName); | 2699 CompileTimeErrorCode.INSTANTIATE_ENUM, typeName); |
| 2689 return true; | 2700 return true; |
| 2690 } | 2701 } |
| 2691 return false; | 2702 return false; |
| 2692 } | 2703 } |
| 2693 | 2704 |
| 2694 /** | 2705 /** |
| 2695 * Verify that the given 'const' instance creation [expression] is not being | 2706 * Verify that the given 'const' instance creation [expression] is not being |
| 2696 * invoked on a constructor that is not 'const'. | 2707 * invoked on a constructor that is not 'const'. |
| 2697 * | 2708 * |
| 2698 * This method assumes that the instance creation was tested to be 'const' | 2709 * This method assumes that the instance creation was tested to be 'const' |
| 2699 * before being called. | 2710 * before being called. |
| 2700 * | 2711 * |
| 2701 * See [CompileTimeErrorCode.CONST_WITH_NON_CONST]. | 2712 * See [CompileTimeErrorCode.CONST_WITH_NON_CONST]. |
| 2702 */ | 2713 */ |
| 2703 bool _checkForConstWithNonConst(InstanceCreationExpression node) { | 2714 bool _checkForConstWithNonConst(InstanceCreationExpression expression) { |
| 2704 ConstructorElement constructorElement = node.staticElement; | 2715 ConstructorElement constructorElement = expression.staticElement; |
| 2705 if (constructorElement != null && !constructorElement.isConst) { | 2716 if (constructorElement != null && !constructorElement.isConst) { |
| 2706 _errorReporter.reportErrorForNode( | 2717 _errorReporter.reportErrorForNode( |
| 2707 CompileTimeErrorCode.CONST_WITH_NON_CONST, node); | 2718 CompileTimeErrorCode.CONST_WITH_NON_CONST, expression); |
| 2708 return true; | 2719 return true; |
| 2709 } | 2720 } |
| 2710 return false; | 2721 return false; |
| 2711 } | 2722 } |
| 2712 | 2723 |
| 2713 /** | 2724 /** |
| 2714 * Verify that the given [typeName] does not reference any type parameters. | 2725 * Verify that the given [typeName] does not reference any type parameters. |
| 2715 * | 2726 * |
| 2716 * See [CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS]. | 2727 * See [CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETERS]. |
| 2717 */ | 2728 */ |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2749 * invoked on the resolved constructor. The [constructorName] is the | 2760 * invoked on the resolved constructor. The [constructorName] is the |
| 2750 * constructor name, always non-`null`. The [typeName] is the name of the type | 2761 * constructor name, always non-`null`. The [typeName] is the name of the type |
| 2751 * defining the constructor, always non-`null`. | 2762 * defining the constructor, always non-`null`. |
| 2752 * | 2763 * |
| 2753 * This method assumes that the instance creation was tested to be 'const' | 2764 * This method assumes that the instance creation was tested to be 'const' |
| 2754 * before being called. | 2765 * before being called. |
| 2755 * | 2766 * |
| 2756 * See [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR], and | 2767 * See [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR], and |
| 2757 * [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]. | 2768 * [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT]. |
| 2758 */ | 2769 */ |
| 2759 bool _checkForConstWithUndefinedConstructor(InstanceCreationExpression node, | 2770 bool _checkForConstWithUndefinedConstructor( |
| 2760 ConstructorName constructorName, TypeName typeName) { | 2771 InstanceCreationExpression expression, ConstructorName constructorName, |
| 2772 TypeName typeName) { |
| 2761 // OK if resolved | 2773 // OK if resolved |
| 2762 if (node.staticElement != null) { | 2774 if (expression.staticElement != null) { |
| 2763 return false; | 2775 return false; |
| 2764 } | 2776 } |
| 2765 DartType type = typeName.type; | 2777 DartType type = typeName.type; |
| 2766 if (type is InterfaceType) { | 2778 if (type is InterfaceType) { |
| 2767 ClassElement element = type.element; | 2779 ClassElement element = type.element; |
| 2768 if (element != null && element.isEnum) { | 2780 if (element != null && element.isEnum) { |
| 2769 // We have already reported the error. | 2781 // We have already reported the error. |
| 2770 return false; | 2782 return false; |
| 2771 } | 2783 } |
| 2772 } | 2784 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2786 } | 2798 } |
| 2787 return true; | 2799 return true; |
| 2788 } | 2800 } |
| 2789 | 2801 |
| 2790 /** | 2802 /** |
| 2791 * Verify that there are no default parameters in the given function type | 2803 * Verify that there are no default parameters in the given function type |
| 2792 * [alias]. | 2804 * [alias]. |
| 2793 * | 2805 * |
| 2794 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]. | 2806 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS]. |
| 2795 */ | 2807 */ |
| 2796 bool _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) { | 2808 bool _checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias alias) { |
| 2797 bool result = false; | 2809 bool result = false; |
| 2798 FormalParameterList formalParameterList = node.parameters; | 2810 FormalParameterList formalParameterList = alias.parameters; |
| 2799 NodeList<FormalParameter> parameters = formalParameterList.parameters; | 2811 NodeList<FormalParameter> parameters = formalParameterList.parameters; |
| 2800 for (FormalParameter formalParameter in parameters) { | 2812 for (FormalParameter formalParameter in parameters) { |
| 2801 if (formalParameter is DefaultFormalParameter) { | 2813 if (formalParameter is DefaultFormalParameter) { |
| 2802 DefaultFormalParameter defaultFormalParameter = formalParameter; | 2814 DefaultFormalParameter defaultFormalParameter = formalParameter; |
| 2803 if (defaultFormalParameter.defaultValue != null) { | 2815 if (defaultFormalParameter.defaultValue != null) { |
| 2804 _errorReporter.reportErrorForNode( | 2816 _errorReporter.reportErrorForNode( |
| 2805 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, node); | 2817 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS, alias); |
| 2806 result = true; | 2818 result = true; |
| 2807 } | 2819 } |
| 2808 } | 2820 } |
| 2809 } | 2821 } |
| 2810 return result; | 2822 return result; |
| 2811 } | 2823 } |
| 2812 | 2824 |
| 2813 /** | 2825 /** |
| 2814 * Verify that the given default formal [parameter] is not part of a function | 2826 * Verify that the given default formal [parameter] is not part of a function |
| 2815 * typed parameter. | 2827 * typed parameter. |
| 2816 * | 2828 * |
| 2817 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]. | 2829 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER]. |
| 2818 */ | 2830 */ |
| 2819 bool _checkForDefaultValueInFunctionTypedParameter( | 2831 bool _checkForDefaultValueInFunctionTypedParameter( |
| 2820 DefaultFormalParameter node) { | 2832 DefaultFormalParameter parameter) { |
| 2821 // OK, not in a function typed parameter. | 2833 // OK, not in a function typed parameter. |
| 2822 if (!_isInFunctionTypedFormalParameter) { | 2834 if (!_isInFunctionTypedFormalParameter) { |
| 2823 return false; | 2835 return false; |
| 2824 } | 2836 } |
| 2825 // OK, no default value. | 2837 // OK, no default value. |
| 2826 if (node.defaultValue == null) { | 2838 if (parameter.defaultValue == null) { |
| 2827 return false; | 2839 return false; |
| 2828 } | 2840 } |
| 2829 // Report problem. | 2841 // Report problem. |
| 2830 _errorReporter.reportErrorForNode( | 2842 _errorReporter.reportErrorForNode( |
| 2831 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, node); | 2843 CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER, |
| 2844 parameter); |
| 2832 return true; | 2845 return true; |
| 2833 } | 2846 } |
| 2834 | 2847 |
| 2835 /** | 2848 /** |
| 2836 * Verify that any deferred imports in the given compilation [unit] have a | 2849 * Verify that any deferred imports in the given compilation [unit] have a |
| 2837 * unique prefix. | 2850 * unique prefix. |
| 2838 * | 2851 * |
| 2839 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. | 2852 * See [CompileTimeErrorCode.SHARED_DEFERRED_PREFIX]. |
| 2840 */ | 2853 */ |
| 2841 bool _checkForDeferredPrefixCollisions(CompilationUnit node) { | 2854 bool _checkForDeferredPrefixCollisions(CompilationUnit unit) { |
| 2842 bool foundError = false; | 2855 bool foundError = false; |
| 2843 NodeList<Directive> directives = node.directives; | 2856 NodeList<Directive> directives = unit.directives; |
| 2844 int count = directives.length; | 2857 int count = directives.length; |
| 2845 if (count > 0) { | 2858 if (count > 0) { |
| 2846 HashMap<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = | 2859 HashMap<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = |
| 2847 new HashMap<PrefixElement, List<ImportDirective>>(); | 2860 new HashMap<PrefixElement, List<ImportDirective>>(); |
| 2848 for (int i = 0; i < count; i++) { | 2861 for (int i = 0; i < count; i++) { |
| 2849 Directive directive = directives[i]; | 2862 Directive directive = directives[i]; |
| 2850 if (directive is ImportDirective) { | 2863 if (directive is ImportDirective) { |
| 2851 ImportDirective importDirective = directive; | 2864 ImportDirective importDirective = directive; |
| 2852 SimpleIdentifier prefix = importDirective.prefix; | 2865 SimpleIdentifier prefix = importDirective.prefix; |
| 2853 if (prefix != null) { | 2866 if (prefix != null) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2936 return true; | 2949 return true; |
| 2937 } | 2950 } |
| 2938 | 2951 |
| 2939 /** | 2952 /** |
| 2940 * Verify that if the given list [literal] has type arguments then there is | 2953 * Verify that if the given list [literal] has type arguments then there is |
| 2941 * exactly one. The [typeArguments] are the type arguments. | 2954 * exactly one. The [typeArguments] are the type arguments. |
| 2942 * | 2955 * |
| 2943 * See [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS]. | 2956 * See [StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS]. |
| 2944 */ | 2957 */ |
| 2945 bool _checkForExpectedOneListTypeArgument( | 2958 bool _checkForExpectedOneListTypeArgument( |
| 2946 ListLiteral node, TypeArgumentList typeArguments) { | 2959 ListLiteral literal, TypeArgumentList typeArguments) { |
| 2947 // check number of type arguments | 2960 // check number of type arguments |
| 2948 int num = typeArguments.arguments.length; | 2961 int num = typeArguments.arguments.length; |
| 2949 if (num == 1) { | 2962 if (num == 1) { |
| 2950 return false; | 2963 return false; |
| 2951 } | 2964 } |
| 2952 // report problem | 2965 // report problem |
| 2953 _errorReporter.reportErrorForNode( | 2966 _errorReporter.reportErrorForNode( |
| 2954 StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments, | 2967 StaticTypeWarningCode.EXPECTED_ONE_LIST_TYPE_ARGUMENTS, typeArguments, |
| 2955 [num]); | 2968 [num]); |
| 2956 return true; | 2969 return true; |
| 2957 } | 2970 } |
| 2958 | 2971 |
| 2959 /** | 2972 /** |
| 2960 * Verify that the given export ([node]) has a unique name among other | 2973 * Verify that the given export [directive] has a unique name among other |
| 2961 * exported libraries. The [exportElement] is the [ExportElement] retrieved | 2974 * exported libraries. The [exportElement] is the [ExportElement] retrieved |
| 2962 * from the node, if the element in the node was `null`, then this method is | 2975 * from the node, if the element in the node was `null`, then this method is |
| 2963 * not called. The [exportedLibrary] is the library element containing the | 2976 * not called. The [exportedLibrary] is the library element containing the |
| 2964 * exported element. | 2977 * exported element. |
| 2965 * | 2978 * |
| 2966 * See [CompileTimeErrorCode.EXPORT_DUPLICATED_LIBRARY_NAME]. | 2979 * See [CompileTimeErrorCode.EXPORT_DUPLICATED_LIBRARY_NAME]. |
| 2967 */ | 2980 */ |
| 2968 bool _checkForExportDuplicateLibraryName(ExportDirective node, | 2981 bool _checkForExportDuplicateLibraryName(ExportDirective directive, |
| 2969 ExportElement exportElement, LibraryElement exportedLibrary) { | 2982 ExportElement exportElement, LibraryElement exportedLibrary) { |
| 2970 if (exportedLibrary == null) { | 2983 if (exportedLibrary == null) { |
| 2971 return false; | 2984 return false; |
| 2972 } | 2985 } |
| 2973 String name = exportedLibrary.name; | 2986 String name = exportedLibrary.name; |
| 2974 // check if there is other exported library with the same name | 2987 // check if there is other exported library with the same name |
| 2975 LibraryElement prevLibrary = _nameToExportElement[name]; | 2988 LibraryElement prevLibrary = _nameToExportElement[name]; |
| 2976 if (prevLibrary != null) { | 2989 if (prevLibrary != null) { |
| 2977 if (prevLibrary != exportedLibrary) { | 2990 if (prevLibrary != exportedLibrary) { |
| 2978 if (name.isEmpty) { | 2991 if (name.isEmpty) { |
| 2979 _errorReporter.reportErrorForNode( | 2992 _errorReporter.reportErrorForNode( |
| 2980 StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_UNNAMED, node, [ | 2993 StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_UNNAMED, directive, [ |
| 2981 prevLibrary.definingCompilationUnit.displayName, | 2994 prevLibrary.definingCompilationUnit.displayName, |
| 2982 exportedLibrary.definingCompilationUnit.displayName | 2995 exportedLibrary.definingCompilationUnit.displayName |
| 2983 ]); | 2996 ]); |
| 2984 } else { | 2997 } else { |
| 2985 _errorReporter.reportErrorForNode( | 2998 _errorReporter.reportErrorForNode( |
| 2986 StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAMED, node, [ | 2999 StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_NAMED, directive, [ |
| 2987 prevLibrary.definingCompilationUnit.displayName, | 3000 prevLibrary.definingCompilationUnit.displayName, |
| 2988 exportedLibrary.definingCompilationUnit.displayName, | 3001 exportedLibrary.definingCompilationUnit.displayName, |
| 2989 name | 3002 name |
| 2990 ]); | 3003 ]); |
| 2991 } | 3004 } |
| 2992 return true; | 3005 return true; |
| 2993 } | 3006 } |
| 2994 } else { | 3007 } else { |
| 2995 _nameToExportElement[name] = exportedLibrary; | 3008 _nameToExportElement[name] = exportedLibrary; |
| 2996 } | 3009 } |
| 2997 // OK | 3010 // OK |
| 2998 return false; | 3011 return false; |
| 2999 } | 3012 } |
| 3000 | 3013 |
| 3001 /** | 3014 /** |
| 3002 * Check that if the visiting library is not system, then any given library | 3015 * Check that if the visiting library is not system, then any given library |
| 3003 * should not be SDK internal library. The [exportElement] is the | 3016 * should not be SDK internal library. The [exportElement] is the |
| 3004 * [ExportElement] retrieved from the node, if the element in the node was | 3017 * [ExportElement] retrieved from the node, if the element in the node was |
| 3005 * `null`, then this method is not called. | 3018 * `null`, then this method is not called. |
| 3006 * | 3019 * |
| 3007 * See [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY]. | 3020 * See [CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY]. |
| 3008 */ | 3021 */ |
| 3009 bool _checkForExportInternalLibrary( | 3022 bool _checkForExportInternalLibrary( |
| 3010 ExportDirective node, ExportElement exportElement) { | 3023 ExportDirective directive, ExportElement exportElement) { |
| 3011 if (_isInSystemLibrary) { | 3024 if (_isInSystemLibrary) { |
| 3012 return false; | 3025 return false; |
| 3013 } | 3026 } |
| 3014 // should be private | 3027 // should be private |
| 3015 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; | 3028 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; |
| 3016 String uri = exportElement.uri; | 3029 String uri = exportElement.uri; |
| 3017 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); | 3030 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); |
| 3018 if (sdkLibrary == null) { | 3031 if (sdkLibrary == null) { |
| 3019 return false; | 3032 return false; |
| 3020 } | 3033 } |
| 3021 if (!sdkLibrary.isInternal) { | 3034 if (!sdkLibrary.isInternal) { |
| 3022 return false; | 3035 return false; |
| 3023 } | 3036 } |
| 3024 // report problem | 3037 // report problem |
| 3025 _errorReporter.reportErrorForNode( | 3038 _errorReporter.reportErrorForNode( |
| 3026 CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, node, [node.uri]); | 3039 CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, directive, |
| 3040 [directive.uri]); |
| 3027 return true; | 3041 return true; |
| 3028 } | 3042 } |
| 3029 | 3043 |
| 3030 /** | 3044 /** |
| 3031 * Verify that the given extends [clause] does not extend a deferred class. | 3045 * Verify that the given extends [clause] does not extend a deferred class. |
| 3032 * | 3046 * |
| 3033 * See [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS]. | 3047 * See [CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS]. |
| 3034 */ | 3048 */ |
| 3035 bool _checkForExtendsDeferredClass(ExtendsClause node) { | 3049 bool _checkForExtendsDeferredClass(ExtendsClause clause) { |
| 3036 if (node == null) { | 3050 if (clause == null) { |
| 3037 return false; | 3051 return false; |
| 3038 } | 3052 } |
| 3039 return _checkForExtendsOrImplementsDeferredClass( | 3053 return _checkForExtendsOrImplementsDeferredClass( |
| 3040 node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); | 3054 clause.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); |
| 3041 } | 3055 } |
| 3042 | 3056 |
| 3043 /** | 3057 /** |
| 3044 * Verify that the given type [alias] does not extend a deferred class. | 3058 * Verify that the given type [alias] does not extend a deferred class. |
| 3045 * | 3059 * |
| 3046 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. | 3060 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. |
| 3047 */ | 3061 */ |
| 3048 bool _checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias node) { | 3062 bool _checkForExtendsDeferredClassInTypeAlias(ClassTypeAlias alias) { |
| 3049 if (node == null) { | 3063 if (alias == null) { |
| 3050 return false; | 3064 return false; |
| 3051 } | 3065 } |
| 3052 return _checkForExtendsOrImplementsDeferredClass( | 3066 return _checkForExtendsOrImplementsDeferredClass( |
| 3053 node.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); | 3067 alias.superclass, CompileTimeErrorCode.EXTENDS_DEFERRED_CLASS); |
| 3054 } | 3068 } |
| 3055 | 3069 |
| 3056 /** | 3070 /** |
| 3057 * Verify that the given extends [clause] does not extend classes such as | 3071 * Verify that the given extends [clause] does not extend classes such as |
| 3058 * 'num' or 'String'. | 3072 * 'num' or 'String'. |
| 3059 * | 3073 * |
| 3060 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. | 3074 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. |
| 3061 */ | 3075 */ |
| 3062 bool _checkForExtendsDisallowedClass(ExtendsClause node) { | 3076 bool _checkForExtendsDisallowedClass(ExtendsClause clause) { |
| 3063 if (node == null) { | 3077 if (clause == null) { |
| 3064 return false; | 3078 return false; |
| 3065 } | 3079 } |
| 3066 return _checkForExtendsOrImplementsDisallowedClass( | 3080 return _checkForExtendsOrImplementsDisallowedClass( |
| 3067 node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); | 3081 clause.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); |
| 3068 } | 3082 } |
| 3069 | 3083 |
| 3070 /** | 3084 /** |
| 3071 * Verify that the given type [alias] does not extend classes such as 'num' or | 3085 * Verify that the given type [alias] does not extend classes such as 'num' or |
| 3072 * 'String'. | 3086 * 'String'. |
| 3073 * | 3087 * |
| 3074 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. | 3088 * See [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]. |
| 3075 */ | 3089 */ |
| 3076 bool _checkForExtendsDisallowedClassInTypeAlias(ClassTypeAlias node) { | 3090 bool _checkForExtendsDisallowedClassInTypeAlias(ClassTypeAlias alias) { |
| 3077 if (node == null) { | 3091 if (alias == null) { |
| 3078 return false; | 3092 return false; |
| 3079 } | 3093 } |
| 3080 return _checkForExtendsOrImplementsDisallowedClass( | 3094 return _checkForExtendsOrImplementsDisallowedClass( |
| 3081 node.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); | 3095 alias.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS); |
| 3082 } | 3096 } |
| 3083 | 3097 |
| 3084 /** | 3098 /** |
| 3085 * Verify that the given [typeName] does not extend, implement or mixin | 3099 * Verify that the given [typeName] does not extend, implement or mixin |
| 3086 * classes that are deferred. | 3100 * classes that are deferred. |
| 3087 * | 3101 * |
| 3088 * See [_checkForExtendsDeferredClass], | 3102 * See [_checkForExtendsDeferredClass], |
| 3089 * [_checkForExtendsDeferredClassInTypeAlias], | 3103 * [_checkForExtendsDeferredClassInTypeAlias], |
| 3090 * [_checkForImplementsDeferredClass], | 3104 * [_checkForImplementsDeferredClass], |
| 3091 * [_checkForAllMixinErrorCodes], | 3105 * [_checkForAllMixinErrorCodes], |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3157 | 3171 |
| 3158 /** | 3172 /** |
| 3159 * Verify that the given constructor field [initializer] has compatible field | 3173 * Verify that the given constructor field [initializer] has compatible field |
| 3160 * and initializer expression types. The [staticElement] is the static element | 3174 * and initializer expression types. The [staticElement] is the static element |
| 3161 * from the name in the [ConstructorFieldInitializer]. | 3175 * from the name in the [ConstructorFieldInitializer]. |
| 3162 * | 3176 * |
| 3163 * See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and | 3177 * See [CompileTimeErrorCode.CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE], and |
| 3164 * [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE]. | 3178 * [StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGNABLE]. |
| 3165 */ | 3179 */ |
| 3166 bool _checkForFieldInitializerNotAssignable( | 3180 bool _checkForFieldInitializerNotAssignable( |
| 3167 ConstructorFieldInitializer node, Element staticElement) { | 3181 ConstructorFieldInitializer initializer, Element staticElement) { |
| 3168 // prepare field element | 3182 // prepare field element |
| 3169 if (staticElement is! FieldElement) { | 3183 if (staticElement is! FieldElement) { |
| 3170 return false; | 3184 return false; |
| 3171 } | 3185 } |
| 3172 FieldElement fieldElement = staticElement as FieldElement; | 3186 FieldElement fieldElement = staticElement as FieldElement; |
| 3173 // prepare field type | 3187 // prepare field type |
| 3174 DartType fieldType = fieldElement.type; | 3188 DartType fieldType = fieldElement.type; |
| 3175 // prepare expression type | 3189 // prepare expression type |
| 3176 Expression expression = node.expression; | 3190 Expression expression = initializer.expression; |
| 3177 if (expression == null) { | 3191 if (expression == null) { |
| 3178 return false; | 3192 return false; |
| 3179 } | 3193 } |
| 3180 // test the static type of the expression | 3194 // test the static type of the expression |
| 3181 DartType staticType = getStaticType(expression); | 3195 DartType staticType = getStaticType(expression); |
| 3182 if (staticType == null) { | 3196 if (staticType == null) { |
| 3183 return false; | 3197 return false; |
| 3184 } | 3198 } |
| 3185 if (staticType.isAssignableTo(fieldType)) { | 3199 if (staticType.isAssignableTo(fieldType)) { |
| 3186 return false; | 3200 return false; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3223 // return true; | 3237 // return true; |
| 3224 } | 3238 } |
| 3225 | 3239 |
| 3226 /** | 3240 /** |
| 3227 * Verify that the given field formal [parameter] is in a constructor | 3241 * Verify that the given field formal [parameter] is in a constructor |
| 3228 * declaration. | 3242 * declaration. |
| 3229 * | 3243 * |
| 3230 * See [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]. | 3244 * See [CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR]. |
| 3231 */ | 3245 */ |
| 3232 bool _checkForFieldInitializingFormalRedirectingConstructor( | 3246 bool _checkForFieldInitializingFormalRedirectingConstructor( |
| 3233 FieldFormalParameter node) { | 3247 FieldFormalParameter parameter) { |
| 3234 ConstructorDeclaration constructor = | 3248 ConstructorDeclaration constructor = |
| 3235 node.getAncestor((node) => node is ConstructorDeclaration); | 3249 parameter.getAncestor((node) => node is ConstructorDeclaration); |
| 3236 if (constructor == null) { | 3250 if (constructor == null) { |
| 3237 _errorReporter.reportErrorForNode( | 3251 _errorReporter.reportErrorForNode( |
| 3238 CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, node); | 3252 CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, |
| 3253 parameter); |
| 3239 return true; | 3254 return true; |
| 3240 } | 3255 } |
| 3241 // constructor cannot be a factory | 3256 // constructor cannot be a factory |
| 3242 if (constructor.factoryKeyword != null) { | 3257 if (constructor.factoryKeyword != null) { |
| 3243 _errorReporter.reportErrorForNode( | 3258 _errorReporter.reportErrorForNode( |
| 3244 CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, node); | 3259 CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, |
| 3260 parameter); |
| 3245 return true; | 3261 return true; |
| 3246 } | 3262 } |
| 3247 // constructor cannot have a redirection | 3263 // constructor cannot have a redirection |
| 3248 for (ConstructorInitializer initializer in constructor.initializers) { | 3264 for (ConstructorInitializer initializer in constructor.initializers) { |
| 3249 if (initializer is RedirectingConstructorInvocation) { | 3265 if (initializer is RedirectingConstructorInvocation) { |
| 3250 _errorReporter.reportErrorForNode( | 3266 _errorReporter.reportErrorForNode( |
| 3251 CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, | 3267 CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, |
| 3252 node); | 3268 parameter); |
| 3253 return true; | 3269 return true; |
| 3254 } | 3270 } |
| 3255 } | 3271 } |
| 3256 // OK | 3272 // OK |
| 3257 return false; | 3273 return false; |
| 3258 } | 3274 } |
| 3259 | 3275 |
| 3260 /** | 3276 /** |
| 3261 * Verify that the given variable declaration [list] has only initialized | 3277 * Verify that the given variable declaration [list] has only initialized |
| 3262 * variables if the list is final or const. | 3278 * variables if the list is final or const. |
| 3263 * | 3279 * |
| 3264 * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and | 3280 * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and |
| 3265 * [StaticWarningCode.FINAL_NOT_INITIALIZED]. | 3281 * [StaticWarningCode.FINAL_NOT_INITIALIZED]. |
| 3266 */ | 3282 */ |
| 3267 bool _checkForFinalNotInitialized(VariableDeclarationList node) { | 3283 bool _checkForFinalNotInitialized(VariableDeclarationList list) { |
| 3268 if (_isInNativeClass) { | 3284 if (_isInNativeClass) { |
| 3269 return false; | 3285 return false; |
| 3270 } | 3286 } |
| 3271 bool foundError = false; | 3287 bool foundError = false; |
| 3272 if (!node.isSynthetic) { | 3288 if (!list.isSynthetic) { |
| 3273 NodeList<VariableDeclaration> variables = node.variables; | 3289 NodeList<VariableDeclaration> variables = list.variables; |
| 3274 for (VariableDeclaration variable in variables) { | 3290 for (VariableDeclaration variable in variables) { |
| 3275 if (variable.initializer == null) { | 3291 if (variable.initializer == null) { |
| 3276 if (node.isConst) { | 3292 if (list.isConst) { |
| 3277 _errorReporter.reportErrorForNode( | 3293 _errorReporter.reportErrorForNode( |
| 3278 CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, | 3294 CompileTimeErrorCode.CONST_NOT_INITIALIZED, variable.name, |
| 3279 [variable.name.name]); | 3295 [variable.name.name]); |
| 3280 } else if (node.isFinal) { | 3296 } else if (list.isFinal) { |
| 3281 _errorReporter.reportErrorForNode( | 3297 _errorReporter.reportErrorForNode( |
| 3282 StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, | 3298 StaticWarningCode.FINAL_NOT_INITIALIZED, variable.name, |
| 3283 [variable.name.name]); | 3299 [variable.name.name]); |
| 3284 } | 3300 } |
| 3285 foundError = true; | 3301 foundError = true; |
| 3286 } | 3302 } |
| 3287 } | 3303 } |
| 3288 } | 3304 } |
| 3289 return foundError; | 3305 return foundError; |
| 3290 } | 3306 } |
| 3291 | 3307 |
| 3292 /** | 3308 /** |
| 3293 * Verify that final fields in the given clas [declaration] that are declared, | 3309 * Verify that final fields in the given clas [declaration] that are declared, |
| 3294 * without any constructors in the enclosing class, are initialized. Cases in | 3310 * without any constructors in the enclosing class, are initialized. Cases in |
| 3295 * which there is at least one constructor are handled at the end of | 3311 * which there is at least one constructor are handled at the end of |
| 3296 * [_checkForAllFinalInitializedErrorCodes]. | 3312 * [_checkForAllFinalInitializedErrorCodes]. |
| 3297 * | 3313 * |
| 3298 * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and | 3314 * See [CompileTimeErrorCode.CONST_NOT_INITIALIZED], and |
| 3299 * [StaticWarningCode.FINAL_NOT_INITIALIZED]. | 3315 * [StaticWarningCode.FINAL_NOT_INITIALIZED]. |
| 3300 */ | 3316 */ |
| 3301 bool _checkForFinalNotInitializedInClass(ClassDeclaration node) { | 3317 bool _checkForFinalNotInitializedInClass(ClassDeclaration declaration) { |
| 3302 NodeList<ClassMember> classMembers = node.members; | 3318 NodeList<ClassMember> classMembers = declaration.members; |
| 3303 for (ClassMember classMember in classMembers) { | 3319 for (ClassMember classMember in classMembers) { |
| 3304 if (classMember is ConstructorDeclaration) { | 3320 if (classMember is ConstructorDeclaration) { |
| 3305 return false; | 3321 return false; |
| 3306 } | 3322 } |
| 3307 } | 3323 } |
| 3308 bool foundError = false; | 3324 bool foundError = false; |
| 3309 for (ClassMember classMember in classMembers) { | 3325 for (ClassMember classMember in classMembers) { |
| 3310 if (classMember is FieldDeclaration && | 3326 if (classMember is FieldDeclaration && |
| 3311 _checkForFinalNotInitialized(classMember.fields)) { | 3327 _checkForFinalNotInitialized(classMember.fields)) { |
| 3312 foundError = true; | 3328 foundError = true; |
| 3313 } | 3329 } |
| 3314 } | 3330 } |
| 3315 return foundError; | 3331 return foundError; |
| 3316 } | 3332 } |
| 3317 | 3333 |
| 3318 /** | 3334 /** |
| 3319 * If the current function is async, async*, or sync*, verify that its | 3335 * If the current function is async, async*, or sync*, verify that its |
| 3320 * declared return type is assignable to Future, Stream, or Iterable, | 3336 * declared return type is assignable to Future, Stream, or Iterable, |
| 3321 * respectively. If not, report the error using [node]. | 3337 * respectively. If not, report the error using [returnType]. |
| 3322 */ | 3338 */ |
| 3323 void _checkForIllegalReturnType(TypeName node) { | 3339 void _checkForIllegalReturnType(TypeName returnType) { |
| 3324 if (node == null) { | 3340 if (returnType == null) { |
| 3325 // No declared return type, so the return type must be dynamic, which is | 3341 // No declared return type, so the return type must be dynamic, which is |
| 3326 // assignable to everything. | 3342 // assignable to everything. |
| 3327 return; | 3343 return; |
| 3328 } | 3344 } |
| 3329 if (_enclosingFunction.isAsynchronous) { | 3345 if (_enclosingFunction.isAsynchronous) { |
| 3330 if (_enclosingFunction.isGenerator) { | 3346 if (_enclosingFunction.isGenerator) { |
| 3331 if (!_enclosingFunction.returnType | 3347 if (!_enclosingFunction.returnType |
| 3332 .isAssignableTo(_typeProvider.streamDynamicType)) { | 3348 .isAssignableTo(_typeProvider.streamDynamicType)) { |
| 3333 _errorReporter.reportErrorForNode( | 3349 _errorReporter.reportErrorForNode( |
| 3334 StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE, node); | 3350 StaticTypeWarningCode.ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE, |
| 3351 returnType); |
| 3335 } | 3352 } |
| 3336 } else { | 3353 } else { |
| 3337 if (!_enclosingFunction.returnType | 3354 if (!_enclosingFunction.returnType |
| 3338 .isAssignableTo(_typeProvider.futureDynamicType)) { | 3355 .isAssignableTo(_typeProvider.futureDynamicType)) { |
| 3339 _errorReporter.reportErrorForNode( | 3356 _errorReporter.reportErrorForNode( |
| 3340 StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, node); | 3357 StaticTypeWarningCode.ILLEGAL_ASYNC_RETURN_TYPE, returnType); |
| 3341 } | 3358 } |
| 3342 } | 3359 } |
| 3343 } else if (_enclosingFunction.isGenerator) { | 3360 } else if (_enclosingFunction.isGenerator) { |
| 3344 if (!_enclosingFunction.returnType | 3361 if (!_enclosingFunction.returnType |
| 3345 .isAssignableTo(_typeProvider.iterableDynamicType)) { | 3362 .isAssignableTo(_typeProvider.iterableDynamicType)) { |
| 3346 _errorReporter.reportErrorForNode( | 3363 _errorReporter.reportErrorForNode( |
| 3347 StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, node); | 3364 StaticTypeWarningCode.ILLEGAL_SYNC_GENERATOR_RETURN_TYPE, |
| 3365 returnType); |
| 3348 } | 3366 } |
| 3349 } | 3367 } |
| 3350 } | 3368 } |
| 3351 | 3369 |
| 3352 /** | 3370 /** |
| 3353 * Verify that the given implements [clause] does not implement classes that | 3371 * Verify that the given implements [clause] does not implement classes that |
| 3354 * are deferred. | 3372 * are deferred. |
| 3355 * | 3373 * |
| 3356 * See [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS]. | 3374 * See [CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS]. |
| 3357 */ | 3375 */ |
| 3358 bool _checkForImplementsDeferredClass(ImplementsClause node) { | 3376 bool _checkForImplementsDeferredClass(ImplementsClause clause) { |
| 3359 if (node == null) { | 3377 if (clause == null) { |
| 3360 return false; | 3378 return false; |
| 3361 } | 3379 } |
| 3362 bool foundError = false; | 3380 bool foundError = false; |
| 3363 for (TypeName type in node.interfaces) { | 3381 for (TypeName type in clause.interfaces) { |
| 3364 if (_checkForExtendsOrImplementsDeferredClass( | 3382 if (_checkForExtendsOrImplementsDeferredClass( |
| 3365 type, CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS)) { | 3383 type, CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS)) { |
| 3366 foundError = true; | 3384 foundError = true; |
| 3367 } | 3385 } |
| 3368 } | 3386 } |
| 3369 return foundError; | 3387 return foundError; |
| 3370 } | 3388 } |
| 3371 | 3389 |
| 3372 /** | 3390 /** |
| 3373 * Verify that the given implements [clause] does not implement classes such | 3391 * Verify that the given implements [clause] does not implement classes such |
| 3374 * as 'num' or 'String'. | 3392 * as 'num' or 'String'. |
| 3375 * | 3393 * |
| 3376 * See [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]. | 3394 * See [CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS]. |
| 3377 */ | 3395 */ |
| 3378 bool _checkForImplementsDisallowedClass(ImplementsClause node) { | 3396 bool _checkForImplementsDisallowedClass(ImplementsClause clause) { |
| 3379 if (node == null) { | 3397 if (clause == null) { |
| 3380 return false; | 3398 return false; |
| 3381 } | 3399 } |
| 3382 bool foundError = false; | 3400 bool foundError = false; |
| 3383 for (TypeName type in node.interfaces) { | 3401 for (TypeName type in clause.interfaces) { |
| 3384 if (_checkForExtendsOrImplementsDisallowedClass( | 3402 if (_checkForExtendsOrImplementsDisallowedClass( |
| 3385 type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) { | 3403 type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)) { |
| 3386 foundError = true; | 3404 foundError = true; |
| 3387 } | 3405 } |
| 3388 } | 3406 } |
| 3389 return foundError; | 3407 return foundError; |
| 3390 } | 3408 } |
| 3391 | 3409 |
| 3392 /** | 3410 /** |
| 3393 * Verify that if the given [identifier] is part of a constructor initializer, | 3411 * Verify that if the given [identifier] is part of a constructor initializer, |
| 3394 * then it does not implicitly reference 'this' expression. | 3412 * then it does not implicitly reference 'this' expression. |
| 3395 * | 3413 * |
| 3396 * See [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER], and | 3414 * See [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER], and |
| 3397 * [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]. | 3415 * [CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC]. |
| 3398 * TODO(scheglov) rename thid method | 3416 * TODO(scheglov) rename thid method |
| 3399 */ | 3417 */ |
| 3400 bool _checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) { | 3418 bool _checkForImplicitThisReferenceInInitializer( |
| 3419 SimpleIdentifier identifier) { |
| 3401 if (!_isInConstructorInitializer && | 3420 if (!_isInConstructorInitializer && |
| 3402 !_isInStaticMethod && | 3421 !_isInStaticMethod && |
| 3403 !_isInFactory && | 3422 !_isInFactory && |
| 3404 !_isInInstanceVariableInitializer && | 3423 !_isInInstanceVariableInitializer && |
| 3405 !_isInStaticVariableDeclaration) { | 3424 !_isInStaticVariableDeclaration) { |
| 3406 return false; | 3425 return false; |
| 3407 } | 3426 } |
| 3408 // prepare element | 3427 // prepare element |
| 3409 Element element = node.staticElement; | 3428 Element element = identifier.staticElement; |
| 3410 if (!(element is MethodElement || element is PropertyAccessorElement)) { | 3429 if (!(element is MethodElement || element is PropertyAccessorElement)) { |
| 3411 return false; | 3430 return false; |
| 3412 } | 3431 } |
| 3413 // static element | 3432 // static element |
| 3414 ExecutableElement executableElement = element as ExecutableElement; | 3433 ExecutableElement executableElement = element as ExecutableElement; |
| 3415 if (executableElement.isStatic) { | 3434 if (executableElement.isStatic) { |
| 3416 return false; | 3435 return false; |
| 3417 } | 3436 } |
| 3418 // not a class member | 3437 // not a class member |
| 3419 Element enclosingElement = element.enclosingElement; | 3438 Element enclosingElement = element.enclosingElement; |
| 3420 if (enclosingElement is! ClassElement) { | 3439 if (enclosingElement is! ClassElement) { |
| 3421 return false; | 3440 return false; |
| 3422 } | 3441 } |
| 3423 // comment | 3442 // comment |
| 3424 AstNode parent = node.parent; | 3443 AstNode parent = identifier.parent; |
| 3425 if (parent is CommentReference) { | 3444 if (parent is CommentReference) { |
| 3426 return false; | 3445 return false; |
| 3427 } | 3446 } |
| 3428 // qualified method invocation | 3447 // qualified method invocation |
| 3429 if (parent is MethodInvocation) { | 3448 if (parent is MethodInvocation) { |
| 3430 MethodInvocation invocation = parent; | 3449 MethodInvocation invocation = parent; |
| 3431 if (identical(invocation.methodName, node) && | 3450 if (identical(invocation.methodName, identifier) && |
| 3432 invocation.realTarget != null) { | 3451 invocation.realTarget != null) { |
| 3433 return false; | 3452 return false; |
| 3434 } | 3453 } |
| 3435 } | 3454 } |
| 3436 // qualified property access | 3455 // qualified property access |
| 3437 if (parent is PropertyAccess) { | 3456 if (parent is PropertyAccess) { |
| 3438 PropertyAccess access = parent; | 3457 PropertyAccess access = parent; |
| 3439 if (identical(access.propertyName, node) && access.realTarget != null) { | 3458 if (identical(access.propertyName, identifier) && |
| 3459 access.realTarget != null) { |
| 3440 return false; | 3460 return false; |
| 3441 } | 3461 } |
| 3442 } | 3462 } |
| 3443 if (parent is PrefixedIdentifier) { | 3463 if (parent is PrefixedIdentifier) { |
| 3444 PrefixedIdentifier prefixed = parent; | 3464 PrefixedIdentifier prefixed = parent; |
| 3445 if (identical(prefixed.identifier, node)) { | 3465 if (identical(prefixed.identifier, identifier)) { |
| 3446 return false; | 3466 return false; |
| 3447 } | 3467 } |
| 3448 } | 3468 } |
| 3449 // report problem | 3469 // report problem |
| 3450 if (_isInStaticMethod) { | 3470 if (_isInStaticMethod) { |
| 3451 _errorReporter.reportErrorForNode( | 3471 _errorReporter.reportErrorForNode( |
| 3452 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, node); | 3472 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC, identifier); |
| 3453 } else if (_isInFactory) { | 3473 } else if (_isInFactory) { |
| 3454 _errorReporter.reportErrorForNode( | 3474 _errorReporter.reportErrorForNode( |
| 3455 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, node); | 3475 CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY, identifier); |
| 3456 } else { | 3476 } else { |
| 3457 _errorReporter.reportErrorForNode( | 3477 _errorReporter.reportErrorForNode( |
| 3458 CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, node); | 3478 CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER, |
| 3479 identifier); |
| 3459 } | 3480 } |
| 3460 return true; | 3481 return true; |
| 3461 } | 3482 } |
| 3462 | 3483 |
| 3463 /** | 3484 /** |
| 3464 * Verify that the given import [directive] has a unique name among other | 3485 * Verify that the given import [directive] has a unique name among other |
| 3465 * imported libraries. The [importElement] is the [ImportElement] retrieved | 3486 * imported libraries. The [importElement] is the [ImportElement] retrieved |
| 3466 * from the node, if the element in the node was `null`, then this method is | 3487 * from the node, if the element in the node was `null`, then this method is |
| 3467 * not called. | 3488 * not called. |
| 3468 * | 3489 * |
| 3469 * See [CompileTimeErrorCode.IMPORT_DUPLICATED_LIBRARY_NAME]. | 3490 * See [CompileTimeErrorCode.IMPORT_DUPLICATED_LIBRARY_NAME]. |
| 3470 */ | 3491 */ |
| 3471 bool _checkForImportDuplicateLibraryName( | 3492 bool _checkForImportDuplicateLibraryName( |
| 3472 ImportDirective node, ImportElement importElement) { | 3493 ImportDirective directive, ImportElement importElement) { |
| 3473 // prepare imported library | 3494 // prepare imported library |
| 3474 LibraryElement nodeLibrary = importElement.importedLibrary; | 3495 LibraryElement nodeLibrary = importElement.importedLibrary; |
| 3475 if (nodeLibrary == null) { | 3496 if (nodeLibrary == null) { |
| 3476 return false; | 3497 return false; |
| 3477 } | 3498 } |
| 3478 String name = nodeLibrary.name; | 3499 String name = nodeLibrary.name; |
| 3479 // check if there is another imported library with the same name | 3500 // check if there is another imported library with the same name |
| 3480 LibraryElement prevLibrary = _nameToImportElement[name]; | 3501 LibraryElement prevLibrary = _nameToImportElement[name]; |
| 3481 if (prevLibrary != null) { | 3502 if (prevLibrary != null) { |
| 3482 if (prevLibrary != nodeLibrary) { | 3503 if (prevLibrary != nodeLibrary) { |
| 3483 if (name.isEmpty) { | 3504 if (name.isEmpty) { |
| 3484 _errorReporter.reportErrorForNode( | 3505 _errorReporter.reportErrorForNode( |
| 3485 StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_UNNAMED, node, [ | 3506 StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_UNNAMED, directive, [ |
| 3486 prevLibrary.definingCompilationUnit.displayName, | 3507 prevLibrary.definingCompilationUnit.displayName, |
| 3487 nodeLibrary.definingCompilationUnit.displayName | 3508 nodeLibrary.definingCompilationUnit.displayName |
| 3488 ]); | 3509 ]); |
| 3489 } else { | 3510 } else { |
| 3490 _errorReporter.reportErrorForNode( | 3511 _errorReporter.reportErrorForNode( |
| 3491 StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAMED, node, [ | 3512 StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAMED, directive, [ |
| 3492 prevLibrary.definingCompilationUnit.displayName, | 3513 prevLibrary.definingCompilationUnit.displayName, |
| 3493 nodeLibrary.definingCompilationUnit.displayName, | 3514 nodeLibrary.definingCompilationUnit.displayName, |
| 3494 name | 3515 name |
| 3495 ]); | 3516 ]); |
| 3496 } | 3517 } |
| 3497 return true; | 3518 return true; |
| 3498 } | 3519 } |
| 3499 } else { | 3520 } else { |
| 3500 _nameToImportElement[name] = nodeLibrary; | 3521 _nameToImportElement[name] = nodeLibrary; |
| 3501 } | 3522 } |
| 3502 // OK | 3523 // OK |
| 3503 return false; | 3524 return false; |
| 3504 } | 3525 } |
| 3505 | 3526 |
| 3506 /** | 3527 /** |
| 3507 * Check that if the visiting library is not system, then any given library | 3528 * Check that if the visiting library is not system, then any given library |
| 3508 * should not be SDK internal library. The [importElement] is the | 3529 * should not be SDK internal library. The [importElement] is the |
| 3509 * [ImportElement] retrieved from the node, if the element in the node was | 3530 * [ImportElement] retrieved from the node, if the element in the node was |
| 3510 * `null`, then this method is not called | 3531 * `null`, then this method is not called |
| 3511 * | 3532 * |
| 3512 * See [CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY]. | 3533 * See [CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY]. |
| 3513 */ | 3534 */ |
| 3514 bool _checkForImportInternalLibrary( | 3535 bool _checkForImportInternalLibrary( |
| 3515 ImportDirective node, ImportElement importElement) { | 3536 ImportDirective directive, ImportElement importElement) { |
| 3516 if (_isInSystemLibrary) { | 3537 if (_isInSystemLibrary) { |
| 3517 return false; | 3538 return false; |
| 3518 } | 3539 } |
| 3519 // should be private | 3540 // should be private |
| 3520 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; | 3541 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk; |
| 3521 String uri = importElement.uri; | 3542 String uri = importElement.uri; |
| 3522 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); | 3543 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri); |
| 3523 if (sdkLibrary == null) { | 3544 if (sdkLibrary == null) { |
| 3524 return false; | 3545 return false; |
| 3525 } | 3546 } |
| 3526 if (!sdkLibrary.isInternal) { | 3547 if (!sdkLibrary.isInternal) { |
| 3527 return false; | 3548 return false; |
| 3528 } | 3549 } |
| 3529 // report problem | 3550 // report problem |
| 3530 _errorReporter.reportErrorForNode( | 3551 _errorReporter.reportErrorForNode( |
| 3531 CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, node, [node.uri]); | 3552 CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, directive, |
| 3553 [directive.uri]); |
| 3532 return true; | 3554 return true; |
| 3533 } | 3555 } |
| 3534 | 3556 |
| 3535 /** | 3557 /** |
| 3536 * For each class declaration, this method is called which verifies that all | 3558 * For each class declaration, this method is called which verifies that all |
| 3537 * inherited members are inherited consistently. | 3559 * inherited members are inherited consistently. |
| 3538 * | 3560 * |
| 3539 * See [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]. | 3561 * See [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]. |
| 3540 */ | 3562 */ |
| 3541 bool _checkForInconsistentMethodInheritance() { | 3563 bool _checkForInconsistentMethodInheritance() { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3660 superclassType = superclassElement.supertype; | 3682 superclassType = superclassElement.supertype; |
| 3661 superclassElement = | 3683 superclassElement = |
| 3662 superclassType == null ? null : superclassType.element; | 3684 superclassType == null ? null : superclassType.element; |
| 3663 } | 3685 } |
| 3664 } | 3686 } |
| 3665 return false; | 3687 return false; |
| 3666 } | 3688 } |
| 3667 | 3689 |
| 3668 /** | 3690 /** |
| 3669 * Verify that an 'int' can be assigned to the parameter corresponding to the | 3691 * Verify that an 'int' can be assigned to the parameter corresponding to the |
| 3670 * given [expression]. This is used for prefix and postfix expressions where | 3692 * given [argument]. This is used for prefix and postfix expressions where |
| 3671 * the argument value is implicit. | 3693 * the argument value is implicit. |
| 3672 * | 3694 * |
| 3673 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. | 3695 * See [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]. |
| 3674 */ | 3696 */ |
| 3675 bool _checkForIntNotAssignable(Expression argument) { | 3697 bool _checkForIntNotAssignable(Expression argument) { |
| 3676 if (argument == null) { | 3698 if (argument == null) { |
| 3677 return false; | 3699 return false; |
| 3678 } | 3700 } |
| 3679 ParameterElement staticParameterElement = argument.staticParameterElement; | 3701 ParameterElement staticParameterElement = argument.staticParameterElement; |
| 3680 DartType staticParameterType = | 3702 DartType staticParameterType = |
| 3681 staticParameterElement == null ? null : staticParameterElement.type; | 3703 staticParameterElement == null ? null : staticParameterElement.type; |
| 3682 return _checkForArgumentTypeNotAssignable(argument, staticParameterType, | 3704 return _checkForArgumentTypeNotAssignable(argument, staticParameterType, |
| 3683 _intType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); | 3705 _intType, StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE); |
| 3684 } | 3706 } |
| 3685 | 3707 |
| 3686 /** | 3708 /** |
| 3687 * Verify that the given [annotation] isn't defined in a deferred library. | 3709 * Verify that the given [annotation] isn't defined in a deferred library. |
| 3688 * | 3710 * |
| 3689 * See [CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY]. | 3711 * See [CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY]. |
| 3690 */ | 3712 */ |
| 3691 bool _checkForInvalidAnnotationFromDeferredLibrary(Annotation node) { | 3713 bool _checkForInvalidAnnotationFromDeferredLibrary(Annotation annotation) { |
| 3692 Identifier nameIdentifier = node.name; | 3714 Identifier nameIdentifier = annotation.name; |
| 3693 if (nameIdentifier is PrefixedIdentifier) { | 3715 if (nameIdentifier is PrefixedIdentifier) { |
| 3694 if (nameIdentifier.isDeferred) { | 3716 if (nameIdentifier.isDeferred) { |
| 3695 _errorReporter.reportErrorForNode( | 3717 _errorReporter.reportErrorForNode( |
| 3696 CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY, | 3718 CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY, |
| 3697 node.name); | 3719 annotation.name); |
| 3698 return true; | 3720 return true; |
| 3699 } | 3721 } |
| 3700 } | 3722 } |
| 3701 return false; | 3723 return false; |
| 3702 } | 3724 } |
| 3703 | 3725 |
| 3704 /** | 3726 /** |
| 3705 * Verify that the given left hand side ([lhs]) and right hand side ([rhs]) | 3727 * Verify that the given left hand side ([lhs]) and right hand side ([rhs]) |
| 3706 * represent a valid assignment. | 3728 * represent a valid assignment. |
| 3707 * | 3729 * |
| (...skipping 20 matching lines...) Expand all Loading... |
| 3728 } | 3750 } |
| 3729 | 3751 |
| 3730 /** | 3752 /** |
| 3731 * Given an [assignment] using a compound assignment operator, this verifies | 3753 * Given an [assignment] using a compound assignment operator, this verifies |
| 3732 * that the given assignment is valid. The [lhs] is the left hand side | 3754 * that the given assignment is valid. The [lhs] is the left hand side |
| 3733 * expression. The [rhs] is the right hand side expression. | 3755 * expression. The [rhs] is the right hand side expression. |
| 3734 * | 3756 * |
| 3735 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT]. | 3757 * See [StaticTypeWarningCode.INVALID_ASSIGNMENT]. |
| 3736 */ | 3758 */ |
| 3737 bool _checkForInvalidCompoundAssignment( | 3759 bool _checkForInvalidCompoundAssignment( |
| 3738 AssignmentExpression node, Expression lhs, Expression rhs) { | 3760 AssignmentExpression assignment, Expression lhs, Expression rhs) { |
| 3739 if (lhs == null) { | 3761 if (lhs == null) { |
| 3740 return false; | 3762 return false; |
| 3741 } | 3763 } |
| 3742 VariableElement leftVariableElement = getVariableElement(lhs); | 3764 VariableElement leftVariableElement = getVariableElement(lhs); |
| 3743 DartType leftType = (leftVariableElement == null) | 3765 DartType leftType = (leftVariableElement == null) |
| 3744 ? getStaticType(lhs) | 3766 ? getStaticType(lhs) |
| 3745 : leftVariableElement.type; | 3767 : leftVariableElement.type; |
| 3746 MethodElement invokedMethod = node.staticElement; | 3768 MethodElement invokedMethod = assignment.staticElement; |
| 3747 if (invokedMethod == null) { | 3769 if (invokedMethod == null) { |
| 3748 return false; | 3770 return false; |
| 3749 } | 3771 } |
| 3750 DartType rightType = invokedMethod.type.returnType; | 3772 DartType rightType = invokedMethod.type.returnType; |
| 3751 if (leftType == null || rightType == null) { | 3773 if (leftType == null || rightType == null) { |
| 3752 return false; | 3774 return false; |
| 3753 } | 3775 } |
| 3754 if (!rightType.isAssignableTo(leftType)) { | 3776 if (!rightType.isAssignableTo(leftType)) { |
| 3755 _errorReporter.reportTypeErrorForNode( | 3777 _errorReporter.reportTypeErrorForNode( |
| 3756 StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightType, leftType]); | 3778 StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightType, leftType]); |
| 3757 return true; | 3779 return true; |
| 3758 } | 3780 } |
| 3759 return false; | 3781 return false; |
| 3760 } | 3782 } |
| 3761 | 3783 |
| 3762 /** | 3784 /** |
| 3763 * Check the given [initializer] to ensure that the field being initialized is | 3785 * Check the given [initializer] to ensure that the field being initialized is |
| 3764 * a valid field. The [fieldName] is the field name from the | 3786 * a valid field. The [fieldName] is the field name from the |
| 3765 * [ConstructorFieldInitializer]. The [staticElement] is the static element | 3787 * [ConstructorFieldInitializer]. The [staticElement] is the static element |
| 3766 * from the name in the [ConstructorFieldInitializer]. | 3788 * from the name in the [ConstructorFieldInitializer]. |
| 3767 */ | 3789 */ |
| 3768 void _checkForInvalidField(ConstructorFieldInitializer node, | 3790 void _checkForInvalidField(ConstructorFieldInitializer initializer, |
| 3769 SimpleIdentifier fieldName, Element staticElement) { | 3791 SimpleIdentifier fieldName, Element staticElement) { |
| 3770 if (staticElement is FieldElement) { | 3792 if (staticElement is FieldElement) { |
| 3771 FieldElement fieldElement = staticElement; | 3793 FieldElement fieldElement = staticElement; |
| 3772 if (fieldElement.isSynthetic) { | 3794 if (fieldElement.isSynthetic) { |
| 3773 _errorReporter.reportErrorForNode( | 3795 _errorReporter.reportErrorForNode( |
| 3774 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, | 3796 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, |
| 3775 [fieldName]); | 3797 initializer, [fieldName]); |
| 3776 } else if (fieldElement.isStatic) { | 3798 } else if (fieldElement.isStatic) { |
| 3777 _errorReporter.reportErrorForNode( | 3799 _errorReporter.reportErrorForNode( |
| 3778 CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, | 3800 CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, initializer, |
| 3779 [fieldName]); | 3801 [fieldName]); |
| 3780 } | 3802 } |
| 3781 } else { | 3803 } else { |
| 3782 _errorReporter.reportErrorForNode( | 3804 _errorReporter.reportErrorForNode( |
| 3783 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, node, | 3805 CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTENT_FIELD, initializer, |
| 3784 [fieldName]); | 3806 [fieldName]); |
| 3785 return; | 3807 return; |
| 3786 } | 3808 } |
| 3787 } | 3809 } |
| 3788 | 3810 |
| 3789 /** | 3811 /** |
| 3790 * Check to see whether the given function [body] has a modifier associated | 3812 * Check to see whether the given function [body] has a modifier associated |
| 3791 * with it, and report it as an error if it does. | 3813 * with it, and report it as an error if it does. |
| 3792 */ | 3814 */ |
| 3793 bool _checkForInvalidModifierOnBody( | 3815 bool _checkForInvalidModifierOnBody( |
| 3794 FunctionBody body, CompileTimeErrorCode errorCode) { | 3816 FunctionBody body, CompileTimeErrorCode errorCode) { |
| 3795 sc.Token keyword = body.keyword; | 3817 sc.Token keyword = body.keyword; |
| 3796 if (keyword != null) { | 3818 if (keyword != null) { |
| 3797 _errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]); | 3819 _errorReporter.reportErrorForToken(errorCode, keyword, [keyword.lexeme]); |
| 3798 return true; | 3820 return true; |
| 3799 } | 3821 } |
| 3800 return false; | 3822 return false; |
| 3801 } | 3823 } |
| 3802 | 3824 |
| 3803 /** | 3825 /** |
| 3804 * Verify that the usage of the given 'this' is valid. | 3826 * Verify that the usage of the given 'this' is valid. |
| 3805 * | 3827 * |
| 3806 * See [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]. | 3828 * See [CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS]. |
| 3807 */ | 3829 */ |
| 3808 bool _checkForInvalidReferenceToThis(ThisExpression node) { | 3830 bool _checkForInvalidReferenceToThis(ThisExpression expression) { |
| 3809 if (!_isThisInValidContext(node)) { | 3831 if (!_isThisInValidContext(expression)) { |
| 3810 _errorReporter.reportErrorForNode( | 3832 _errorReporter.reportErrorForNode( |
| 3811 CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, node); | 3833 CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, expression); |
| 3812 return true; | 3834 return true; |
| 3813 } | 3835 } |
| 3814 return false; | 3836 return false; |
| 3815 } | 3837 } |
| 3816 | 3838 |
| 3817 /** | 3839 /** |
| 3818 * Checks to ensure that the given list of type [arguments] does not have a | 3840 * Checks to ensure that the given list of type [arguments] does not have a |
| 3819 * type parameter as a type argument. The [errorCode] is either | 3841 * type parameter as a type argument. The [errorCode] is either |
| 3820 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or | 3842 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST] or |
| 3821 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP]. | 3843 * [CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP]. |
| 3822 */ | 3844 */ |
| 3823 bool _checkForInvalidTypeArgumentInConstTypedLiteral( | 3845 bool _checkForInvalidTypeArgumentInConstTypedLiteral( |
| 3824 NodeList<TypeName> arguments, ErrorCode errorCode) { | 3846 NodeList<TypeName> arguments, ErrorCode errorCode) { |
| 3825 bool foundError = false; | 3847 bool foundError = false; |
| 3826 for (TypeName typeName in arguments) { | 3848 for (TypeName typeName in arguments) { |
| 3827 if (typeName.type is TypeParameterType) { | 3849 if (typeName.type is TypeParameterType) { |
| 3828 _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); | 3850 _errorReporter.reportErrorForNode(errorCode, typeName, [typeName.name]); |
| 3829 foundError = true; | 3851 foundError = true; |
| 3830 } | 3852 } |
| 3831 } | 3853 } |
| 3832 return foundError; | 3854 return foundError; |
| 3833 } | 3855 } |
| 3834 | 3856 |
| 3835 /** | 3857 /** |
| 3836 * Verify that the elements given [ListLiteral] are subtypes of the specified | 3858 * Verify that the elements given list [literal] are subtypes of the specified |
| 3837 * element type. The [typeArguments] are the type arguments. | 3859 * element type. The [typeArguments] are the type arguments. |
| 3838 * | 3860 * |
| 3839 * See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and | 3861 * See [CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE], and |
| 3840 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]. | 3862 * [StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]. |
| 3841 */ | 3863 */ |
| 3842 bool _checkForListElementTypeNotAssignable( | 3864 bool _checkForListElementTypeNotAssignable( |
| 3843 ListLiteral node, TypeArgumentList typeArguments) { | 3865 ListLiteral literal, TypeArgumentList typeArguments) { |
| 3844 NodeList<TypeName> typeNames = typeArguments.arguments; | 3866 NodeList<TypeName> typeNames = typeArguments.arguments; |
| 3845 if (typeNames.length < 1) { | 3867 if (typeNames.length < 1) { |
| 3846 return false; | 3868 return false; |
| 3847 } | 3869 } |
| 3848 DartType listElementType = typeNames[0].type; | 3870 DartType listElementType = typeNames[0].type; |
| 3849 // Check every list element. | 3871 // Check every list element. |
| 3850 bool hasProblems = false; | 3872 bool hasProblems = false; |
| 3851 for (Expression element in node.elements) { | 3873 for (Expression element in literal.elements) { |
| 3852 if (node.constKeyword != null) { | 3874 if (literal.constKeyword != null) { |
| 3853 // TODO(paulberry): this error should be based on the actual type of the | 3875 // TODO(paulberry): this error should be based on the actual type of the |
| 3854 // list element, not the static type. See dartbug.com/21119. | 3876 // list element, not the static type. See dartbug.com/21119. |
| 3855 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(element, | 3877 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(element, |
| 3856 listElementType, | 3878 listElementType, |
| 3857 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { | 3879 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { |
| 3858 hasProblems = true; | 3880 hasProblems = true; |
| 3859 } | 3881 } |
| 3860 } | 3882 } |
| 3861 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(element, | 3883 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(element, |
| 3862 listElementType, | 3884 listElementType, |
| 3863 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { | 3885 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE)) { |
| 3864 hasProblems = true; | 3886 hasProblems = true; |
| 3865 } | 3887 } |
| 3866 } | 3888 } |
| 3867 return hasProblems; | 3889 return hasProblems; |
| 3868 } | 3890 } |
| 3869 | 3891 |
| 3870 /** | 3892 /** |
| 3871 * Verify that the key/value of entries of the given map [literal] are | 3893 * Verify that the key/value of entries of the given map [literal] are |
| 3872 * subtypes of the key/value types specified in the type arguments. The | 3894 * subtypes of the key/value types specified in the type arguments. The |
| 3873 * [typeArguments] are the type arguments. | 3895 * [typeArguments] are the type arguments. |
| 3874 * | 3896 * |
| 3875 * See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], | 3897 * See [CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], |
| 3876 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], | 3898 * [CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE], |
| 3877 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and | 3899 * [StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE], and |
| 3878 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. | 3900 * [StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE]. |
| 3879 */ | 3901 */ |
| 3880 bool _checkForMapTypeNotAssignable( | 3902 bool _checkForMapTypeNotAssignable( |
| 3881 MapLiteral node, TypeArgumentList typeArguments) { | 3903 MapLiteral literal, TypeArgumentList typeArguments) { |
| 3882 // Prepare maps key/value types. | 3904 // Prepare maps key/value types. |
| 3883 NodeList<TypeName> typeNames = typeArguments.arguments; | 3905 NodeList<TypeName> typeNames = typeArguments.arguments; |
| 3884 if (typeNames.length < 2) { | 3906 if (typeNames.length < 2) { |
| 3885 return false; | 3907 return false; |
| 3886 } | 3908 } |
| 3887 DartType keyType = typeNames[0].type; | 3909 DartType keyType = typeNames[0].type; |
| 3888 DartType valueType = typeNames[1].type; | 3910 DartType valueType = typeNames[1].type; |
| 3889 // Check every map entry. | 3911 // Check every map entry. |
| 3890 bool hasProblems = false; | 3912 bool hasProblems = false; |
| 3891 NodeList<MapLiteralEntry> entries = node.entries; | 3913 NodeList<MapLiteralEntry> entries = literal.entries; |
| 3892 for (MapLiteralEntry entry in entries) { | 3914 for (MapLiteralEntry entry in entries) { |
| 3893 Expression key = entry.key; | 3915 Expression key = entry.key; |
| 3894 Expression value = entry.value; | 3916 Expression value = entry.value; |
| 3895 if (node.constKeyword != null) { | 3917 if (literal.constKeyword != null) { |
| 3896 // TODO(paulberry): this error should be based on the actual type of the | 3918 // TODO(paulberry): this error should be based on the actual type of the |
| 3897 // list element, not the static type. See dartbug.com/21119. | 3919 // list element, not the static type. See dartbug.com/21119. |
| 3898 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(key, keyType, | 3920 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(key, keyType, |
| 3899 CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) { | 3921 CheckedModeCompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) { |
| 3900 hasProblems = true; | 3922 hasProblems = true; |
| 3901 } | 3923 } |
| 3902 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(value, | 3924 if (_checkForArgumentTypeNotAssignableWithExpectedTypes(value, |
| 3903 valueType, | 3925 valueType, |
| 3904 CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) { | 3926 CheckedModeCompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) { |
| 3905 hasProblems = true; | 3927 hasProblems = true; |
| 3906 } | 3928 } |
| 3907 } | 3929 } |
| 3908 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | 3930 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( |
| 3909 key, keyType, StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) { | 3931 key, keyType, StaticWarningCode.MAP_KEY_TYPE_NOT_ASSIGNABLE)) { |
| 3910 hasProblems = true; | 3932 hasProblems = true; |
| 3911 } | 3933 } |
| 3912 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( | 3934 if (_checkForArgumentTypeNotAssignableWithExpectedTypes( |
| 3913 value, valueType, StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) { | 3935 value, valueType, StaticWarningCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE)) { |
| 3914 hasProblems = true; | 3936 hasProblems = true; |
| 3915 } | 3937 } |
| 3916 } | 3938 } |
| 3917 return hasProblems; | 3939 return hasProblems; |
| 3918 } | 3940 } |
| 3919 | 3941 |
| 3920 /** | 3942 /** |
| 3921 * Verify that the [enclosingClass] does not define members with the same name | 3943 * Verify that the [_enclosingClass] does not define members with the same nam
e |
| 3922 * as the enclosing class. | 3944 * as the enclosing class. |
| 3923 * | 3945 * |
| 3924 * See [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]. | 3946 * See [CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME]. |
| 3925 */ | 3947 */ |
| 3926 bool _checkForMemberWithClassName() { | 3948 bool _checkForMemberWithClassName() { |
| 3927 if (_enclosingClass == null) { | 3949 if (_enclosingClass == null) { |
| 3928 return false; | 3950 return false; |
| 3929 } | 3951 } |
| 3930 String className = _enclosingClass.name; | 3952 String className = _enclosingClass.name; |
| 3931 if (className == null) { | 3953 if (className == null) { |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4091 } | 4113 } |
| 4092 return true; | 4114 return true; |
| 4093 } | 4115 } |
| 4094 | 4116 |
| 4095 /** | 4117 /** |
| 4096 * Verify that the given function [body] does not contain return statements | 4118 * Verify that the given function [body] does not contain return statements |
| 4097 * that both have and do not have return values. | 4119 * that both have and do not have return values. |
| 4098 * | 4120 * |
| 4099 * See [StaticWarningCode.MIXED_RETURN_TYPES]. | 4121 * See [StaticWarningCode.MIXED_RETURN_TYPES]. |
| 4100 */ | 4122 */ |
| 4101 bool _checkForMixedReturns(BlockFunctionBody node) { | 4123 bool _checkForMixedReturns(BlockFunctionBody body) { |
| 4102 if (_hasReturnWithoutValue) { | 4124 if (_hasReturnWithoutValue) { |
| 4103 return false; | 4125 return false; |
| 4104 } | 4126 } |
| 4105 int withCount = _returnsWith.length; | 4127 int withCount = _returnsWith.length; |
| 4106 int withoutCount = _returnsWithout.length; | 4128 int withoutCount = _returnsWithout.length; |
| 4107 if (withCount > 0 && withoutCount > 0) { | 4129 if (withCount > 0 && withoutCount > 0) { |
| 4108 for (int i = 0; i < withCount; i++) { | 4130 for (int i = 0; i < withCount; i++) { |
| 4109 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, | 4131 _errorReporter.reportErrorForToken(StaticWarningCode.MIXED_RETURN_TYPES, |
| 4110 _returnsWith[i].returnKeyword); | 4132 _returnsWith[i].returnKeyword); |
| 4111 } | 4133 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4175 [mixinElement.name]); | 4197 [mixinElement.name]); |
| 4176 } | 4198 } |
| 4177 return false; | 4199 return false; |
| 4178 } | 4200 } |
| 4179 | 4201 |
| 4180 /** | 4202 /** |
| 4181 * Verify that the given [constructor] has at most one 'super' initializer. | 4203 * Verify that the given [constructor] has at most one 'super' initializer. |
| 4182 * | 4204 * |
| 4183 * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]. | 4205 * See [CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS]. |
| 4184 */ | 4206 */ |
| 4185 bool _checkForMultipleSuperInitializers(ConstructorDeclaration node) { | 4207 bool _checkForMultipleSuperInitializers(ConstructorDeclaration constructor) { |
| 4186 int numSuperInitializers = 0; | 4208 int numSuperInitializers = 0; |
| 4187 for (ConstructorInitializer initializer in node.initializers) { | 4209 for (ConstructorInitializer initializer in constructor.initializers) { |
| 4188 if (initializer is SuperConstructorInvocation) { | 4210 if (initializer is SuperConstructorInvocation) { |
| 4189 numSuperInitializers++; | 4211 numSuperInitializers++; |
| 4190 if (numSuperInitializers > 1) { | 4212 if (numSuperInitializers > 1) { |
| 4191 _errorReporter.reportErrorForNode( | 4213 _errorReporter.reportErrorForNode( |
| 4192 CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer); | 4214 CompileTimeErrorCode.MULTIPLE_SUPER_INITIALIZERS, initializer); |
| 4193 } | 4215 } |
| 4194 } | 4216 } |
| 4195 } | 4217 } |
| 4196 return numSuperInitializers > 0; | 4218 return numSuperInitializers > 0; |
| 4197 } | 4219 } |
| 4198 | 4220 |
| 4199 /** | 4221 /** |
| 4200 * Checks to ensure that the given native function [body] is in SDK code. | 4222 * Checks to ensure that the given native function [body] is in SDK code. |
| 4201 * | 4223 * |
| 4202 * See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]. | 4224 * See [ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE]. |
| 4203 */ | 4225 */ |
| 4204 bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) { | 4226 bool _checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody body) { |
| 4205 if (!_isInSystemLibrary && !_hasExtUri) { | 4227 if (!_isInSystemLibrary && !_hasExtUri) { |
| 4206 _errorReporter.reportErrorForNode( | 4228 _errorReporter.reportErrorForNode( |
| 4207 ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, node); | 4229 ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE, body); |
| 4208 return true; | 4230 return true; |
| 4209 } | 4231 } |
| 4210 return false; | 4232 return false; |
| 4211 } | 4233 } |
| 4212 | 4234 |
| 4213 /** | 4235 /** |
| 4214 * Verify that the given instance creation [expression] invokes an existing | 4236 * Verify that the given instance creation [expression] invokes an existing |
| 4215 * constructor. The [constructorName] is the constructor name. The [typeName] | 4237 * constructor. The [constructorName] is the constructor name. The [typeName] |
| 4216 * is the name of the type defining the constructor. | 4238 * is the name of the type defining the constructor. |
| 4217 * | 4239 * |
| 4218 * This method assumes that the instance creation was tested to be 'new' | 4240 * This method assumes that the instance creation was tested to be 'new' |
| 4219 * before being called. | 4241 * before being called. |
| 4220 * | 4242 * |
| 4221 * See [StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR]. | 4243 * See [StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR]. |
| 4222 */ | 4244 */ |
| 4223 bool _checkForNewWithUndefinedConstructor(InstanceCreationExpression node, | 4245 bool _checkForNewWithUndefinedConstructor( |
| 4224 ConstructorName constructorName, TypeName typeName) { | 4246 InstanceCreationExpression expression, ConstructorName constructorName, |
| 4247 TypeName typeName) { |
| 4225 // OK if resolved | 4248 // OK if resolved |
| 4226 if (node.staticElement != null) { | 4249 if (expression.staticElement != null) { |
| 4227 return false; | 4250 return false; |
| 4228 } | 4251 } |
| 4229 DartType type = typeName.type; | 4252 DartType type = typeName.type; |
| 4230 if (type is InterfaceType) { | 4253 if (type is InterfaceType) { |
| 4231 ClassElement element = type.element; | 4254 ClassElement element = type.element; |
| 4232 if (element != null && element.isEnum) { | 4255 if (element != null && element.isEnum) { |
| 4233 // We have already reported the error. | 4256 // We have already reported the error. |
| 4234 return false; | 4257 return false; |
| 4235 } | 4258 } |
| 4236 } | 4259 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4252 return true; | 4275 return true; |
| 4253 } | 4276 } |
| 4254 | 4277 |
| 4255 /** | 4278 /** |
| 4256 * Check that if the given class [declaration] implicitly calls default | 4279 * Check that if the given class [declaration] implicitly calls default |
| 4257 * constructor of its superclass, there should be such default constructor - | 4280 * constructor of its superclass, there should be such default constructor - |
| 4258 * implicit or explicit. | 4281 * implicit or explicit. |
| 4259 * | 4282 * |
| 4260 * See [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]. | 4283 * See [CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT]. |
| 4261 */ | 4284 */ |
| 4262 bool _checkForNoDefaultSuperConstructorImplicit(ClassDeclaration node) { | 4285 bool _checkForNoDefaultSuperConstructorImplicit( |
| 4286 ClassDeclaration declaration) { |
| 4263 // do nothing if mixin errors have already been reported for this class. | 4287 // do nothing if mixin errors have already been reported for this class. |
| 4264 ClassElementImpl enclosingClass = _enclosingClass; | 4288 ClassElementImpl enclosingClass = _enclosingClass; |
| 4265 if (enclosingClass.mixinErrorsReported) { | 4289 if (enclosingClass.mixinErrorsReported) { |
| 4266 return false; | 4290 return false; |
| 4267 } | 4291 } |
| 4268 // do nothing if there is explicit constructor | 4292 // do nothing if there is explicit constructor |
| 4269 List<ConstructorElement> constructors = _enclosingClass.constructors; | 4293 List<ConstructorElement> constructors = _enclosingClass.constructors; |
| 4270 if (!constructors[0].isSynthetic) { | 4294 if (!constructors[0].isSynthetic) { |
| 4271 return false; | 4295 return false; |
| 4272 } | 4296 } |
| 4273 // prepare super | 4297 // prepare super |
| 4274 InterfaceType superType = _enclosingClass.supertype; | 4298 InterfaceType superType = _enclosingClass.supertype; |
| 4275 if (superType == null) { | 4299 if (superType == null) { |
| 4276 return false; | 4300 return false; |
| 4277 } | 4301 } |
| 4278 ClassElement superElement = superType.element; | 4302 ClassElement superElement = superType.element; |
| 4279 // try to find default generative super constructor | 4303 // try to find default generative super constructor |
| 4280 ConstructorElement superUnnamedConstructor = | 4304 ConstructorElement superUnnamedConstructor = |
| 4281 superElement.unnamedConstructor; | 4305 superElement.unnamedConstructor; |
| 4282 if (superUnnamedConstructor != null) { | 4306 if (superUnnamedConstructor != null) { |
| 4283 if (superUnnamedConstructor.isFactory) { | 4307 if (superUnnamedConstructor.isFactory) { |
| 4284 _errorReporter.reportErrorForNode( | 4308 _errorReporter.reportErrorForNode( |
| 4285 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.name, | 4309 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, declaration.name, |
| 4286 [superUnnamedConstructor]); | 4310 [superUnnamedConstructor]); |
| 4287 return true; | 4311 return true; |
| 4288 } | 4312 } |
| 4289 if (superUnnamedConstructor.isDefaultConstructor && | 4313 if (superUnnamedConstructor.isDefaultConstructor && |
| 4290 _enclosingClass | 4314 _enclosingClass |
| 4291 .isSuperConstructorAccessible(superUnnamedConstructor)) { | 4315 .isSuperConstructorAccessible(superUnnamedConstructor)) { |
| 4292 return true; | 4316 return true; |
| 4293 } | 4317 } |
| 4294 } | 4318 } |
| 4295 // report problem | 4319 // report problem |
| 4296 _errorReporter.reportErrorForNode( | 4320 _errorReporter.reportErrorForNode( |
| 4297 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, node.name, | 4321 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT, |
| 4298 [superType.displayName]); | 4322 declaration.name, [superType.displayName]); |
| 4299 return true; | 4323 return true; |
| 4300 } | 4324 } |
| 4301 | 4325 |
| 4302 /** | 4326 /** |
| 4303 * Check that the given class declaration overrides all members required by | 4327 * Check that the given class declaration overrides all members required by |
| 4304 * its superclasses and interfaces. The [classNameNode] is the | 4328 * its superclasses and interfaces. The [classNameNode] is the |
| 4305 * [SimpleIdentifier] to be used if there is a violation, this is either the | 4329 * [SimpleIdentifier] to be used if there is a violation, this is either the |
| 4306 * named from the [ClassDeclaration] or from the [ClassTypeAlias]. | 4330 * named from the [ClassDeclaration] or from the [ClassTypeAlias]. |
| 4307 * | 4331 * |
| 4308 * See [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], | 4332 * See [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE], |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4491 } | 4515 } |
| 4492 return false; | 4516 return false; |
| 4493 } | 4517 } |
| 4494 | 4518 |
| 4495 /** | 4519 /** |
| 4496 * Verify that the given assert [statement] has either a 'bool' or | 4520 * Verify that the given assert [statement] has either a 'bool' or |
| 4497 * '() -> bool' input. | 4521 * '() -> bool' input. |
| 4498 * | 4522 * |
| 4499 * See [StaticTypeWarningCode.NON_BOOL_EXPRESSION]. | 4523 * See [StaticTypeWarningCode.NON_BOOL_EXPRESSION]. |
| 4500 */ | 4524 */ |
| 4501 bool _checkForNonBoolExpression(AssertStatement node) { | 4525 bool _checkForNonBoolExpression(AssertStatement statement) { |
| 4502 Expression expression = node.condition; | 4526 Expression expression = statement.condition; |
| 4503 DartType type = getStaticType(expression); | 4527 DartType type = getStaticType(expression); |
| 4504 if (type is InterfaceType) { | 4528 if (type is InterfaceType) { |
| 4505 if (!type.isAssignableTo(_boolType)) { | 4529 if (!type.isAssignableTo(_boolType)) { |
| 4506 _errorReporter.reportErrorForNode( | 4530 _errorReporter.reportErrorForNode( |
| 4507 StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression); | 4531 StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression); |
| 4508 return true; | 4532 return true; |
| 4509 } | 4533 } |
| 4510 } else if (type is FunctionType) { | 4534 } else if (type is FunctionType) { |
| 4511 FunctionType functionType = type; | 4535 FunctionType functionType = type; |
| 4512 if (functionType.typeArguments.length == 0 && | 4536 if (functionType.typeArguments.length == 0 && |
| (...skipping 22 matching lines...) Expand all Loading... |
| 4535 } | 4559 } |
| 4536 | 4560 |
| 4537 /** | 4561 /** |
| 4538 * Verify the given map [literal] either: | 4562 * Verify the given map [literal] either: |
| 4539 * * has `const modifier` | 4563 * * has `const modifier` |
| 4540 * * has explicit type arguments | 4564 * * has explicit type arguments |
| 4541 * * is not start of the statement | 4565 * * is not start of the statement |
| 4542 * | 4566 * |
| 4543 * See [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]. | 4567 * See [CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT]. |
| 4544 */ | 4568 */ |
| 4545 bool _checkForNonConstMapAsExpressionStatement(MapLiteral node) { | 4569 bool _checkForNonConstMapAsExpressionStatement(MapLiteral literal) { |
| 4546 // "const" | 4570 // "const" |
| 4547 if (node.constKeyword != null) { | 4571 if (literal.constKeyword != null) { |
| 4548 return false; | 4572 return false; |
| 4549 } | 4573 } |
| 4550 // has type arguments | 4574 // has type arguments |
| 4551 if (node.typeArguments != null) { | 4575 if (literal.typeArguments != null) { |
| 4552 return false; | 4576 return false; |
| 4553 } | 4577 } |
| 4554 // prepare statement | 4578 // prepare statement |
| 4555 Statement statement = | 4579 Statement statement = |
| 4556 node.getAncestor((node) => node is ExpressionStatement); | 4580 literal.getAncestor((node) => node is ExpressionStatement); |
| 4557 if (statement == null) { | 4581 if (statement == null) { |
| 4558 return false; | 4582 return false; |
| 4559 } | 4583 } |
| 4560 // OK, statement does not start with map | 4584 // OK, statement does not start with map |
| 4561 if (!identical(statement.beginToken, node.beginToken)) { | 4585 if (!identical(statement.beginToken, literal.beginToken)) { |
| 4562 return false; | 4586 return false; |
| 4563 } | 4587 } |
| 4564 // report problem | 4588 // report problem |
| 4565 _errorReporter.reportErrorForNode( | 4589 _errorReporter.reportErrorForNode( |
| 4566 CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, node); | 4590 CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION_STATEMENT, literal); |
| 4567 return true; | 4591 return true; |
| 4568 } | 4592 } |
| 4569 | 4593 |
| 4570 /** | 4594 /** |
| 4571 * Verify that the given method [declaration] of operator `[]=`, has `void` | 4595 * Verify that the given method [declaration] of operator `[]=`, has `void` |
| 4572 * return type. | 4596 * return type. |
| 4573 * | 4597 * |
| 4574 * See [StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR]. | 4598 * See [StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR]. |
| 4575 */ | 4599 */ |
| 4576 bool _checkForNonVoidReturnTypeForOperator(MethodDeclaration node) { | 4600 bool _checkForNonVoidReturnTypeForOperator(MethodDeclaration declaration) { |
| 4577 // check that []= operator | 4601 // check that []= operator |
| 4578 SimpleIdentifier name = node.name; | 4602 SimpleIdentifier name = declaration.name; |
| 4579 if (name.name != "[]=") { | 4603 if (name.name != "[]=") { |
| 4580 return false; | 4604 return false; |
| 4581 } | 4605 } |
| 4582 // check return type | 4606 // check return type |
| 4583 TypeName typeName = node.returnType; | 4607 TypeName typeName = declaration.returnType; |
| 4584 if (typeName != null) { | 4608 if (typeName != null) { |
| 4585 DartType type = typeName.type; | 4609 DartType type = typeName.type; |
| 4586 if (type != null && !type.isVoid) { | 4610 if (type != null && !type.isVoid) { |
| 4587 _errorReporter.reportErrorForNode( | 4611 _errorReporter.reportErrorForNode( |
| 4588 StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, typeName); | 4612 StaticWarningCode.NON_VOID_RETURN_FOR_OPERATOR, typeName); |
| 4589 } | 4613 } |
| 4590 } | 4614 } |
| 4591 // no warning | 4615 // no warning |
| 4592 return false; | 4616 return false; |
| 4593 } | 4617 } |
| 4594 | 4618 |
| 4595 /** | 4619 /** |
| 4596 * Verify the given setter has no return type or the `void` return type. | 4620 * Verify the [typeName], used as the return type of a setter, is valid |
| 4621 * (either `null` or the type 'void'). |
| 4597 * | 4622 * |
| 4598 * See [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER]. | 4623 * See [StaticWarningCode.NON_VOID_RETURN_FOR_SETTER]. |
| 4599 */ | 4624 */ |
| 4600 bool _checkForNonVoidReturnTypeForSetter(TypeName typeName) { | 4625 bool _checkForNonVoidReturnTypeForSetter(TypeName typeName) { |
| 4601 if (typeName != null) { | 4626 if (typeName != null) { |
| 4602 DartType type = typeName.type; | 4627 DartType type = typeName.type; |
| 4603 if (type != null && !type.isVoid) { | 4628 if (type != null && !type.isVoid) { |
| 4604 _errorReporter.reportErrorForNode( | 4629 _errorReporter.reportErrorForNode( |
| 4605 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, typeName); | 4630 StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, typeName); |
| 4606 } | 4631 } |
| 4607 } | 4632 } |
| 4608 return false; | 4633 return false; |
| 4609 } | 4634 } |
| 4610 | 4635 |
| 4611 /** | 4636 /** |
| 4612 * Verify the given operator-method [declaration], does not have an optional | 4637 * Verify the given operator-method [declaration], does not have an optional |
| 4613 * parameter. This method assumes that the method declaration was tested to be | 4638 * parameter. This method assumes that the method declaration was tested to be |
| 4614 * an operator declaration before being called. | 4639 * an operator declaration before being called. |
| 4615 * | 4640 * |
| 4616 * See [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]. | 4641 * See [CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR]. |
| 4617 */ | 4642 */ |
| 4618 bool _checkForOptionalParameterInOperator(MethodDeclaration node) { | 4643 bool _checkForOptionalParameterInOperator(MethodDeclaration declaration) { |
| 4619 FormalParameterList parameterList = node.parameters; | 4644 FormalParameterList parameterList = declaration.parameters; |
| 4620 if (parameterList == null) { | 4645 if (parameterList == null) { |
| 4621 return false; | 4646 return false; |
| 4622 } | 4647 } |
| 4623 bool foundError = false; | 4648 bool foundError = false; |
| 4624 NodeList<FormalParameter> formalParameters = parameterList.parameters; | 4649 NodeList<FormalParameter> formalParameters = parameterList.parameters; |
| 4625 for (FormalParameter formalParameter in formalParameters) { | 4650 for (FormalParameter formalParameter in formalParameters) { |
| 4626 if (formalParameter.kind.isOptional) { | 4651 if (formalParameter.kind.isOptional) { |
| 4627 _errorReporter.reportErrorForNode( | 4652 _errorReporter.reportErrorForNode( |
| 4628 CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, | 4653 CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OPERATOR, |
| 4629 formalParameter); | 4654 formalParameter); |
| 4630 foundError = true; | 4655 foundError = true; |
| 4631 } | 4656 } |
| 4632 } | 4657 } |
| 4633 return foundError; | 4658 return foundError; |
| 4634 } | 4659 } |
| 4635 | 4660 |
| 4636 /** | 4661 /** |
| 4637 * Check that the given named optional [parameter] does not begin with '_'. | 4662 * Check that the given named optional [parameter] does not begin with '_'. |
| 4638 * | 4663 * |
| 4639 * See [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]. | 4664 * See [CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER]. |
| 4640 */ | 4665 */ |
| 4641 bool _checkForPrivateOptionalParameter(FormalParameter node) { | 4666 bool _checkForPrivateOptionalParameter(FormalParameter parameter) { |
| 4642 // should be named parameter | 4667 // should be named parameter |
| 4643 if (node.kind != ParameterKind.NAMED) { | 4668 if (parameter.kind != ParameterKind.NAMED) { |
| 4644 return false; | 4669 return false; |
| 4645 } | 4670 } |
| 4646 // name should start with '_' | 4671 // name should start with '_' |
| 4647 SimpleIdentifier name = node.identifier; | 4672 SimpleIdentifier name = parameter.identifier; |
| 4648 if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) { | 4673 if (name.isSynthetic || !StringUtilities.startsWithChar(name.name, 0x5F)) { |
| 4649 return false; | 4674 return false; |
| 4650 } | 4675 } |
| 4651 // report problem | 4676 // report problem |
| 4652 _errorReporter.reportErrorForNode( | 4677 _errorReporter.reportErrorForNode( |
| 4653 CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, node); | 4678 CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMETER, parameter); |
| 4654 return true; | 4679 return true; |
| 4655 } | 4680 } |
| 4656 | 4681 |
| 4657 /** | 4682 /** |
| 4658 * Check whether the given constructor [declaration] is the redirecting | 4683 * Check whether the given constructor [declaration] is the redirecting |
| 4659 * generative constructor and references itself directly or indirectly. The | 4684 * generative constructor and references itself directly or indirectly. The |
| 4660 * [constructorElement] is the constructor element. | 4685 * [constructorElement] is the constructor element. |
| 4661 * | 4686 * |
| 4662 * See [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]. | 4687 * See [CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT]. |
| 4663 */ | 4688 */ |
| 4664 bool _checkForRecursiveConstructorRedirect( | 4689 bool _checkForRecursiveConstructorRedirect(ConstructorDeclaration declaration, |
| 4665 ConstructorDeclaration node, ConstructorElement constructorElement) { | 4690 ConstructorElement constructorElement) { |
| 4666 // we check generative constructor here | 4691 // we check generative constructor here |
| 4667 if (node.factoryKeyword != null) { | 4692 if (declaration.factoryKeyword != null) { |
| 4668 return false; | 4693 return false; |
| 4669 } | 4694 } |
| 4670 // try to find redirecting constructor invocation and analyzer it for | 4695 // try to find redirecting constructor invocation and analyzer it for |
| 4671 // recursion | 4696 // recursion |
| 4672 for (ConstructorInitializer initializer in node.initializers) { | 4697 for (ConstructorInitializer initializer in declaration.initializers) { |
| 4673 if (initializer is RedirectingConstructorInvocation) { | 4698 if (initializer is RedirectingConstructorInvocation) { |
| 4674 // OK if no cycle | 4699 // OK if no cycle |
| 4675 if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) { | 4700 if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) { |
| 4676 return false; | 4701 return false; |
| 4677 } | 4702 } |
| 4678 // report error | 4703 // report error |
| 4679 _errorReporter.reportErrorForNode( | 4704 _errorReporter.reportErrorForNode( |
| 4680 CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer); | 4705 CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_REDIRECT, initializer); |
| 4681 return true; | 4706 return true; |
| 4682 } | 4707 } |
| 4683 } | 4708 } |
| 4684 // OK, no redirecting constructor invocation | 4709 // OK, no redirecting constructor invocation |
| 4685 return false; | 4710 return false; |
| 4686 } | 4711 } |
| 4687 | 4712 |
| 4688 /** | 4713 /** |
| 4689 * Check whether the given constructor [declaration] has redirected | 4714 * Check whether the given constructor [declaration] has redirected |
| 4690 * constructor and references itself directly or indirectly. The | 4715 * constructor and references itself directly or indirectly. The |
| 4691 * [constructorElement] is the constructor element. | 4716 * constructor [element] is the element introduced by the declaration. |
| 4692 * | 4717 * |
| 4693 * See [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]. | 4718 * See [CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT]. |
| 4694 */ | 4719 */ |
| 4695 bool _checkForRecursiveFactoryRedirect( | 4720 bool _checkForRecursiveFactoryRedirect( |
| 4696 ConstructorDeclaration node, ConstructorElement constructorElement) { | 4721 ConstructorDeclaration declaration, ConstructorElement element) { |
| 4697 // prepare redirected constructor | 4722 // prepare redirected constructor |
| 4698 ConstructorName redirectedConstructorNode = node.redirectedConstructor; | 4723 ConstructorName redirectedConstructorNode = |
| 4724 declaration.redirectedConstructor; |
| 4699 if (redirectedConstructorNode == null) { | 4725 if (redirectedConstructorNode == null) { |
| 4700 return false; | 4726 return false; |
| 4701 } | 4727 } |
| 4702 // OK if no cycle | 4728 // OK if no cycle |
| 4703 if (!_hasRedirectingFactoryConstructorCycle(constructorElement)) { | 4729 if (!_hasRedirectingFactoryConstructorCycle(element)) { |
| 4704 return false; | 4730 return false; |
| 4705 } | 4731 } |
| 4706 // report error | 4732 // report error |
| 4707 _errorReporter.reportErrorForNode( | 4733 _errorReporter.reportErrorForNode( |
| 4708 CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT, | 4734 CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT, |
| 4709 redirectedConstructorNode); | 4735 redirectedConstructorNode); |
| 4710 return true; | 4736 return true; |
| 4711 } | 4737 } |
| 4712 | 4738 |
| 4713 /** | 4739 /** |
| 4714 * Check that the class [element] is not a superinterface to itself. | 4740 * Check that the class [element] is not a superinterface to itself. |
| 4715 * | 4741 * |
| 4716 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], | 4742 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], |
| 4717 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], a
nd | 4743 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], a
nd |
| 4718 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]
. | 4744 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]
. |
| 4719 */ | 4745 */ |
| 4720 bool _checkForRecursiveInterfaceInheritance(ClassElement classElt) { | 4746 bool _checkForRecursiveInterfaceInheritance(ClassElement element) { |
| 4721 if (classElt == null) { | 4747 if (element == null) { |
| 4722 return false; | 4748 return false; |
| 4723 } | 4749 } |
| 4724 return _safeCheckForRecursiveInterfaceInheritance( | 4750 return _safeCheckForRecursiveInterfaceInheritance( |
| 4725 classElt, new List<ClassElement>()); | 4751 element, new List<ClassElement>()); |
| 4726 } | 4752 } |
| 4727 | 4753 |
| 4728 /** | 4754 /** |
| 4729 * Check that the given constructor [declaration] has a valid combination of | 4755 * Check that the given constructor [declaration] has a valid combination of |
| 4730 * redirected constructor invocation(s), super constructor invocations and | 4756 * redirected constructor invocation(s), super constructor invocations and |
| 4731 * field initializers. | 4757 * field initializers. |
| 4732 * | 4758 * |
| 4733 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR]
, | 4759 * See [CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR]
, |
| 4734 * [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR], | 4760 * [CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR], |
| 4735 * [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS], | 4761 * [CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS], |
| 4736 * [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR], and | 4762 * [CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR], and |
| 4737 * [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR]. | 4763 * [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR]. |
| 4738 */ | 4764 */ |
| 4739 bool _checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) { | 4765 bool _checkForRedirectingConstructorErrorCodes( |
| 4766 ConstructorDeclaration declaration) { |
| 4740 bool errorReported = false; | 4767 bool errorReported = false; |
| 4741 // | 4768 // |
| 4742 // Check for default values in the parameters | 4769 // Check for default values in the parameters |
| 4743 // | 4770 // |
| 4744 ConstructorName redirectedConstructor = node.redirectedConstructor; | 4771 ConstructorName redirectedConstructor = declaration.redirectedConstructor; |
| 4745 if (redirectedConstructor != null) { | 4772 if (redirectedConstructor != null) { |
| 4746 for (FormalParameter parameter in node.parameters.parameters) { | 4773 for (FormalParameter parameter in declaration.parameters.parameters) { |
| 4747 if (parameter is DefaultFormalParameter && | 4774 if (parameter is DefaultFormalParameter && |
| 4748 parameter.defaultValue != null) { | 4775 parameter.defaultValue != null) { |
| 4749 _errorReporter.reportErrorForNode( | 4776 _errorReporter.reportErrorForNode( |
| 4750 CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUC
TOR, | 4777 CompileTimeErrorCode.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUC
TOR, |
| 4751 parameter.identifier); | 4778 parameter.identifier); |
| 4752 errorReported = true; | 4779 errorReported = true; |
| 4753 } | 4780 } |
| 4754 } | 4781 } |
| 4755 } | 4782 } |
| 4756 // check if there are redirected invocations | 4783 // check if there are redirected invocations |
| 4757 int numRedirections = 0; | 4784 int numRedirections = 0; |
| 4758 for (ConstructorInitializer initializer in node.initializers) { | 4785 for (ConstructorInitializer initializer in declaration.initializers) { |
| 4759 if (initializer is RedirectingConstructorInvocation) { | 4786 if (initializer is RedirectingConstructorInvocation) { |
| 4760 if (numRedirections > 0) { | 4787 if (numRedirections > 0) { |
| 4761 _errorReporter.reportErrorForNode( | 4788 _errorReporter.reportErrorForNode( |
| 4762 CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS, | 4789 CompileTimeErrorCode.MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS, |
| 4763 initializer); | 4790 initializer); |
| 4764 errorReported = true; | 4791 errorReported = true; |
| 4765 } | 4792 } |
| 4766 if (node.factoryKeyword == null) { | 4793 if (declaration.factoryKeyword == null) { |
| 4767 RedirectingConstructorInvocation invocation = initializer; | 4794 RedirectingConstructorInvocation invocation = initializer; |
| 4768 ConstructorElement redirectingElement = invocation.staticElement; | 4795 ConstructorElement redirectingElement = invocation.staticElement; |
| 4769 if (redirectingElement == null) { | 4796 if (redirectingElement == null) { |
| 4770 String enclosingTypeName = _enclosingClass.displayName; | 4797 String enclosingTypeName = _enclosingClass.displayName; |
| 4771 String constructorStrName = enclosingTypeName; | 4798 String constructorStrName = enclosingTypeName; |
| 4772 if (invocation.constructorName != null) { | 4799 if (invocation.constructorName != null) { |
| 4773 constructorStrName += ".${invocation.constructorName.name}"; | 4800 constructorStrName += ".${invocation.constructorName.name}"; |
| 4774 } | 4801 } |
| 4775 _errorReporter.reportErrorForNode( | 4802 _errorReporter.reportErrorForNode( |
| 4776 CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR, | 4803 CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR, |
| 4777 invocation, [constructorStrName, enclosingTypeName]); | 4804 invocation, [constructorStrName, enclosingTypeName]); |
| 4778 } else { | 4805 } else { |
| 4779 if (redirectingElement.isFactory) { | 4806 if (redirectingElement.isFactory) { |
| 4780 _errorReporter.reportErrorForNode( | 4807 _errorReporter.reportErrorForNode( |
| 4781 CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CON
STRUCTOR, | 4808 CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CON
STRUCTOR, |
| 4782 initializer); | 4809 initializer); |
| 4783 } | 4810 } |
| 4784 } | 4811 } |
| 4785 } | 4812 } |
| 4786 numRedirections++; | 4813 numRedirections++; |
| 4787 } | 4814 } |
| 4788 } | 4815 } |
| 4789 // check for other initializers | 4816 // check for other initializers |
| 4790 if (numRedirections > 0) { | 4817 if (numRedirections > 0) { |
| 4791 for (ConstructorInitializer initializer in node.initializers) { | 4818 for (ConstructorInitializer initializer in declaration.initializers) { |
| 4792 if (initializer is SuperConstructorInvocation) { | 4819 if (initializer is SuperConstructorInvocation) { |
| 4793 _errorReporter.reportErrorForNode( | 4820 _errorReporter.reportErrorForNode( |
| 4794 CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, | 4821 CompileTimeErrorCode.SUPER_IN_REDIRECTING_CONSTRUCTOR, |
| 4795 initializer); | 4822 initializer); |
| 4796 errorReported = true; | 4823 errorReported = true; |
| 4797 } | 4824 } |
| 4798 if (initializer is ConstructorFieldInitializer) { | 4825 if (initializer is ConstructorFieldInitializer) { |
| 4799 _errorReporter.reportErrorForNode( | 4826 _errorReporter.reportErrorForNode( |
| 4800 CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, | 4827 CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, |
| 4801 initializer); | 4828 initializer); |
| 4802 errorReported = true; | 4829 errorReported = true; |
| 4803 } | 4830 } |
| 4804 } | 4831 } |
| 4805 } | 4832 } |
| 4806 // done | 4833 // done |
| 4807 return errorReported; | 4834 return errorReported; |
| 4808 } | 4835 } |
| 4809 | 4836 |
| 4810 /** | 4837 /** |
| 4811 * Check whether the given constructor [declaration] has redirected | 4838 * Check whether the given constructor [declaration] has redirected |
| 4812 * constructor and references itself directly or indirectly. The | 4839 * constructor and references itself directly or indirectly. The |
| 4813 * [constructorElement] is the constructor element. | 4840 * constructor [element] is the element introduced by the declaration. |
| 4814 * | 4841 * |
| 4815 * See [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]. | 4842 * See [CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR]. |
| 4816 */ | 4843 */ |
| 4817 bool _checkForRedirectToNonConstConstructor( | 4844 bool _checkForRedirectToNonConstConstructor( |
| 4818 ConstructorDeclaration node, ConstructorElement constructorElement) { | 4845 ConstructorDeclaration declaration, ConstructorElement element) { |
| 4819 // prepare redirected constructor | 4846 // prepare redirected constructor |
| 4820 ConstructorName redirectedConstructorNode = node.redirectedConstructor; | 4847 ConstructorName redirectedConstructorNode = |
| 4848 declaration.redirectedConstructor; |
| 4821 if (redirectedConstructorNode == null) { | 4849 if (redirectedConstructorNode == null) { |
| 4822 return false; | 4850 return false; |
| 4823 } | 4851 } |
| 4824 // prepare element | 4852 // prepare element |
| 4825 if (constructorElement == null) { | 4853 if (element == null) { |
| 4826 return false; | 4854 return false; |
| 4827 } | 4855 } |
| 4828 // OK, it is not 'const' | 4856 // OK, it is not 'const' |
| 4829 if (!constructorElement.isConst) { | 4857 if (!element.isConst) { |
| 4830 return false; | 4858 return false; |
| 4831 } | 4859 } |
| 4832 // prepare redirected constructor | 4860 // prepare redirected constructor |
| 4833 ConstructorElement redirectedConstructor = | 4861 ConstructorElement redirectedConstructor = element.redirectedConstructor; |
| 4834 constructorElement.redirectedConstructor; | |
| 4835 if (redirectedConstructor == null) { | 4862 if (redirectedConstructor == null) { |
| 4836 return false; | 4863 return false; |
| 4837 } | 4864 } |
| 4838 // OK, it is also 'const' | 4865 // OK, it is also 'const' |
| 4839 if (redirectedConstructor.isConst) { | 4866 if (redirectedConstructor.isConst) { |
| 4840 return false; | 4867 return false; |
| 4841 } | 4868 } |
| 4842 // report error | 4869 // report error |
| 4843 _errorReporter.reportErrorForNode( | 4870 _errorReporter.reportErrorForNode( |
| 4844 CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, | 4871 CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONSTRUCTOR, |
| 4845 redirectedConstructorNode); | 4872 redirectedConstructorNode); |
| 4846 return true; | 4873 return true; |
| 4847 } | 4874 } |
| 4848 | 4875 |
| 4849 /** | 4876 /** |
| 4850 * Check that the given rethrow [expression] is inside of a catch clause. | 4877 * Check that the given rethrow [expression] is inside of a catch clause. |
| 4851 * | 4878 * |
| 4852 * See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]. | 4879 * See [CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH]. |
| 4853 */ | 4880 */ |
| 4854 bool _checkForRethrowOutsideCatch(RethrowExpression node) { | 4881 bool _checkForRethrowOutsideCatch(RethrowExpression expression) { |
| 4855 if (!_isInCatchClause) { | 4882 if (!_isInCatchClause) { |
| 4856 _errorReporter.reportErrorForNode( | 4883 _errorReporter.reportErrorForNode( |
| 4857 CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, node); | 4884 CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, expression); |
| 4858 return true; | 4885 return true; |
| 4859 } | 4886 } |
| 4860 return false; | 4887 return false; |
| 4861 } | 4888 } |
| 4862 | 4889 |
| 4863 /** | 4890 /** |
| 4864 * Check that if the the given constructor [declaration] is generative, then | 4891 * Check that if the the given constructor [declaration] is generative, then |
| 4865 * it does not have an expression function body. | 4892 * it does not have an expression function body. |
| 4866 * | 4893 * |
| 4867 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]. | 4894 * See [CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR]. |
| 4868 */ | 4895 */ |
| 4869 bool _checkForReturnInGenerativeConstructor(ConstructorDeclaration node) { | 4896 bool _checkForReturnInGenerativeConstructor( |
| 4897 ConstructorDeclaration declaration) { |
| 4870 // ignore factory | 4898 // ignore factory |
| 4871 if (node.factoryKeyword != null) { | 4899 if (declaration.factoryKeyword != null) { |
| 4872 return false; | 4900 return false; |
| 4873 } | 4901 } |
| 4874 // block body (with possible return statement) is checked elsewhere | 4902 // block body (with possible return statement) is checked elsewhere |
| 4875 FunctionBody body = node.body; | 4903 FunctionBody body = declaration.body; |
| 4876 if (body is! ExpressionFunctionBody) { | 4904 if (body is! ExpressionFunctionBody) { |
| 4877 return false; | 4905 return false; |
| 4878 } | 4906 } |
| 4879 // report error | 4907 // report error |
| 4880 _errorReporter.reportErrorForNode( | 4908 _errorReporter.reportErrorForNode( |
| 4881 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body); | 4909 CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONSTRUCTOR, body); |
| 4882 return true; | 4910 return true; |
| 4883 } | 4911 } |
| 4884 | 4912 |
| 4885 /** | 4913 /** |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4970 StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]); | 4998 StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMBER, name, [name.name]); |
| 4971 return true; | 4999 return true; |
| 4972 } | 5000 } |
| 4973 | 5001 |
| 4974 /** | 5002 /** |
| 4975 * Check that the type of the expression in the given 'switch' [statement] is | 5003 * Check that the type of the expression in the given 'switch' [statement] is |
| 4976 * assignable to the type of the 'case' members. | 5004 * assignable to the type of the 'case' members. |
| 4977 * | 5005 * |
| 4978 * See [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE]. | 5006 * See [StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGNABLE]. |
| 4979 */ | 5007 */ |
| 4980 bool _checkForSwitchExpressionNotAssignable(SwitchStatement node) { | 5008 bool _checkForSwitchExpressionNotAssignable(SwitchStatement statement) { |
| 4981 // prepare 'switch' expression type | 5009 // prepare 'switch' expression type |
| 4982 Expression expression = node.expression; | 5010 Expression expression = statement.expression; |
| 4983 DartType expressionType = getStaticType(expression); | 5011 DartType expressionType = getStaticType(expression); |
| 4984 if (expressionType == null) { | 5012 if (expressionType == null) { |
| 4985 return false; | 5013 return false; |
| 4986 } | 5014 } |
| 4987 // compare with type of the first 'case' | 5015 // compare with type of the first 'case' |
| 4988 NodeList<SwitchMember> members = node.members; | 5016 NodeList<SwitchMember> members = statement.members; |
| 4989 for (SwitchMember switchMember in members) { | 5017 for (SwitchMember switchMember in members) { |
| 4990 if (switchMember is! SwitchCase) { | 5018 if (switchMember is! SwitchCase) { |
| 4991 continue; | 5019 continue; |
| 4992 } | 5020 } |
| 4993 SwitchCase switchCase = switchMember as SwitchCase; | 5021 SwitchCase switchCase = switchMember as SwitchCase; |
| 4994 // prepare 'case' type | 5022 // prepare 'case' type |
| 4995 Expression caseExpression = switchCase.expression; | 5023 Expression caseExpression = switchCase.expression; |
| 4996 DartType caseType = getStaticType(caseExpression); | 5024 DartType caseType = getStaticType(caseExpression); |
| 4997 // check types | 5025 // check types |
| 4998 if (expressionType.isAssignableTo(caseType)) { | 5026 if (expressionType.isAssignableTo(caseType)) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5009 return false; | 5037 return false; |
| 5010 } | 5038 } |
| 5011 | 5039 |
| 5012 /** | 5040 /** |
| 5013 * Verify that the given function type [alias] does not reference itself | 5041 * Verify that the given function type [alias] does not reference itself |
| 5014 * directly. | 5042 * directly. |
| 5015 * | 5043 * |
| 5016 * See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]. | 5044 * See [CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF]. |
| 5017 */ | 5045 */ |
| 5018 bool _checkForTypeAliasCannotReferenceItself_function( | 5046 bool _checkForTypeAliasCannotReferenceItself_function( |
| 5019 FunctionTypeAlias node) { | 5047 FunctionTypeAlias alias) { |
| 5020 FunctionTypeAliasElement element = node.element; | 5048 FunctionTypeAliasElement element = alias.element; |
| 5021 if (!_hasTypedefSelfReference(element)) { | 5049 if (!_hasTypedefSelfReference(element)) { |
| 5022 return false; | 5050 return false; |
| 5023 } | 5051 } |
| 5024 _errorReporter.reportErrorForNode( | 5052 _errorReporter.reportErrorForNode( |
| 5025 CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, node); | 5053 CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF, alias); |
| 5026 return true; | 5054 return true; |
| 5027 } | 5055 } |
| 5028 | 5056 |
| 5029 /** | 5057 /** |
| 5030 * Verify that the given type [name] is not a deferred type. | 5058 * Verify that the given type [name] is not a deferred type. |
| 5031 * | 5059 * |
| 5032 * See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS]. | 5060 * See [StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS]. |
| 5033 */ | 5061 */ |
| 5034 bool _checkForTypeAnnotationDeferredClass(TypeName node) { | 5062 bool _checkForTypeAnnotationDeferredClass(TypeName name) { |
| 5035 if (node != null && node.isDeferred) { | 5063 if (name != null && name.isDeferred) { |
| 5036 _errorReporter.reportErrorForNode( | 5064 _errorReporter.reportErrorForNode( |
| 5037 StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, node, [node.name]); | 5065 StaticWarningCode.TYPE_ANNOTATION_DEFERRED_CLASS, name, [name.name]); |
| 5038 } | 5066 } |
| 5039 return false; | 5067 return false; |
| 5040 } | 5068 } |
| 5041 | 5069 |
| 5042 /** | 5070 /** |
| 5043 * Verify that the type arguments in the given type [name] are all within | 5071 * Verify that the type arguments in the given [typeName] are all within |
| 5044 * their bounds. | 5072 * their bounds. |
| 5045 * | 5073 * |
| 5046 * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]. | 5074 * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]. |
| 5047 */ | 5075 */ |
| 5048 bool _checkForTypeArgumentNotMatchingBounds(TypeName node) { | 5076 bool _checkForTypeArgumentNotMatchingBounds(TypeName typeName) { |
| 5049 if (node.typeArguments == null) { | 5077 if (typeName.typeArguments == null) { |
| 5050 return false; | 5078 return false; |
| 5051 } | 5079 } |
| 5052 // prepare Type | 5080 // prepare Type |
| 5053 DartType type = node.type; | 5081 DartType type = typeName.type; |
| 5054 if (type == null) { | 5082 if (type == null) { |
| 5055 return false; | 5083 return false; |
| 5056 } | 5084 } |
| 5057 // prepare ClassElement | 5085 // prepare ClassElement |
| 5058 Element element = type.element; | 5086 Element element = type.element; |
| 5059 if (element is! ClassElement) { | 5087 if (element is! ClassElement) { |
| 5060 return false; | 5088 return false; |
| 5061 } | 5089 } |
| 5062 ClassElement classElement = element as ClassElement; | 5090 ClassElement classElement = element as ClassElement; |
| 5063 // prepare type parameters | 5091 // prepare type parameters |
| 5064 List<DartType> typeParameters = classElement.type.typeArguments; | 5092 List<DartType> typeParameters = classElement.type.typeArguments; |
| 5065 List<TypeParameterElement> boundingElts = classElement.typeParameters; | 5093 List<TypeParameterElement> boundingElts = classElement.typeParameters; |
| 5066 // iterate over each bounded type parameter and corresponding argument | 5094 // iterate over each bounded type parameter and corresponding argument |
| 5067 NodeList<TypeName> typeNameArgList = node.typeArguments.arguments; | 5095 NodeList<TypeName> typeNameArgList = typeName.typeArguments.arguments; |
| 5068 List<DartType> typeArguments = (type as InterfaceType).typeArguments; | 5096 List<DartType> typeArguments = (type as InterfaceType).typeArguments; |
| 5069 int loopThroughIndex = | 5097 int loopThroughIndex = |
| 5070 math.min(typeNameArgList.length, boundingElts.length); | 5098 math.min(typeNameArgList.length, boundingElts.length); |
| 5071 bool foundError = false; | 5099 bool foundError = false; |
| 5072 for (int i = 0; i < loopThroughIndex; i++) { | 5100 for (int i = 0; i < loopThroughIndex; i++) { |
| 5073 TypeName argTypeName = typeNameArgList[i]; | 5101 TypeName argTypeName = typeNameArgList[i]; |
| 5074 DartType argType = argTypeName.type; | 5102 DartType argType = argTypeName.type; |
| 5075 DartType boundType = boundingElts[i].bound; | 5103 DartType boundType = boundingElts[i].bound; |
| 5076 if (argType != null && boundType != null) { | 5104 if (argType != null && boundType != null) { |
| 5077 if (typeArguments.length != 0 && | 5105 if (typeArguments.length != 0 && |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5093 } | 5121 } |
| 5094 return foundError; | 5122 return foundError; |
| 5095 } | 5123 } |
| 5096 | 5124 |
| 5097 /** | 5125 /** |
| 5098 * Check whether the given type [name] is a type parameter being used to | 5126 * Check whether the given type [name] is a type parameter being used to |
| 5099 * define a static member. | 5127 * define a static member. |
| 5100 * | 5128 * |
| 5101 * See [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]. | 5129 * See [StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC]. |
| 5102 */ | 5130 */ |
| 5103 bool _checkForTypeParameterReferencedByStatic(TypeName node) { | 5131 bool _checkForTypeParameterReferencedByStatic(TypeName name) { |
| 5104 if (_isInStaticMethod || _isInStaticVariableDeclaration) { | 5132 if (_isInStaticMethod || _isInStaticVariableDeclaration) { |
| 5105 DartType type = node.type; | 5133 DartType type = name.type; |
| 5106 if (type is TypeParameterType) { | 5134 if (type is TypeParameterType) { |
| 5107 _errorReporter.reportErrorForNode( | 5135 _errorReporter.reportErrorForNode( |
| 5108 StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, node); | 5136 StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, name); |
| 5109 return true; | 5137 return true; |
| 5110 } | 5138 } |
| 5111 } | 5139 } |
| 5112 return false; | 5140 return false; |
| 5113 } | 5141 } |
| 5114 | 5142 |
| 5115 /** | 5143 /** |
| 5116 * Check whether the given type [parameter] is a supertype of its bound. | 5144 * Check whether the given type [parameter] is a supertype of its bound. |
| 5117 * | 5145 * |
| 5118 * See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND]. | 5146 * See [StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND]. |
| 5119 */ | 5147 */ |
| 5120 bool _checkForTypeParameterSupertypeOfItsBound(TypeParameter node) { | 5148 bool _checkForTypeParameterSupertypeOfItsBound(TypeParameter parameter) { |
| 5121 TypeParameterElement element = node.element; | 5149 TypeParameterElement element = parameter.element; |
| 5122 // prepare bound | 5150 // prepare bound |
| 5123 DartType bound = element.bound; | 5151 DartType bound = element.bound; |
| 5124 if (bound == null) { | 5152 if (bound == null) { |
| 5125 return false; | 5153 return false; |
| 5126 } | 5154 } |
| 5127 // OK, type parameter is not supertype of its bound | 5155 // OK, type parameter is not supertype of its bound |
| 5128 if (!bound.isMoreSpecificThan(element.type)) { | 5156 if (!bound.isMoreSpecificThan(element.type)) { |
| 5129 return false; | 5157 return false; |
| 5130 } | 5158 } |
| 5131 // report problem | 5159 // report problem |
| 5132 _errorReporter.reportErrorForNode( | 5160 _errorReporter.reportErrorForNode( |
| 5133 StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, node, | 5161 StaticTypeWarningCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, parameter, |
| 5134 [element.displayName]); | 5162 [element.displayName]); |
| 5135 return true; | 5163 return true; |
| 5136 } | 5164 } |
| 5137 | 5165 |
| 5138 /** | 5166 /** |
| 5139 * Check that if the given generative [constructor] has neither an explicit | 5167 * Check that if the given generative [constructor] has neither an explicit |
| 5140 * super constructor invocation nor a redirecting constructor invocation, that | 5168 * super constructor invocation nor a redirecting constructor invocation, that |
| 5141 * the superclass has a default generative constructor. | 5169 * the superclass has a default generative constructor. |
| 5142 * | 5170 * |
| 5143 * See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT], | 5171 * See [CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT], |
| 5144 * [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and | 5172 * [CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR], and |
| 5145 * [StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]. | 5173 * [StaticWarningCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT]. |
| 5146 */ | 5174 */ |
| 5147 bool _checkForUndefinedConstructorInInitializerImplicit( | 5175 bool _checkForUndefinedConstructorInInitializerImplicit( |
| 5148 ConstructorDeclaration node) { | 5176 ConstructorDeclaration constructor) { |
| 5149 if (_enclosingClass == null) { | 5177 if (_enclosingClass == null) { |
| 5150 return false; | 5178 return false; |
| 5151 } | 5179 } |
| 5152 // do nothing if mixin errors have already been reported for this class. | 5180 // do nothing if mixin errors have already been reported for this class. |
| 5153 ClassElementImpl enclosingClass = _enclosingClass; | 5181 ClassElementImpl enclosingClass = _enclosingClass; |
| 5154 if (enclosingClass.mixinErrorsReported) { | 5182 if (enclosingClass.mixinErrorsReported) { |
| 5155 return false; | 5183 return false; |
| 5156 } | 5184 } |
| 5157 // | 5185 // |
| 5158 // Ignore if the constructor is not generative. | 5186 // Ignore if the constructor is not generative. |
| 5159 // | 5187 // |
| 5160 if (node.factoryKeyword != null) { | 5188 if (constructor.factoryKeyword != null) { |
| 5161 return false; | 5189 return false; |
| 5162 } | 5190 } |
| 5163 // | 5191 // |
| 5164 // Ignore if the constructor has either an implicit super constructor | 5192 // Ignore if the constructor has either an implicit super constructor |
| 5165 // invocation or a redirecting constructor invocation. | 5193 // invocation or a redirecting constructor invocation. |
| 5166 // | 5194 // |
| 5167 for (ConstructorInitializer constructorInitializer in node.initializers) { | 5195 for (ConstructorInitializer constructorInitializer |
| 5196 in constructor.initializers) { |
| 5168 if (constructorInitializer is SuperConstructorInvocation || | 5197 if (constructorInitializer is SuperConstructorInvocation || |
| 5169 constructorInitializer is RedirectingConstructorInvocation) { | 5198 constructorInitializer is RedirectingConstructorInvocation) { |
| 5170 return false; | 5199 return false; |
| 5171 } | 5200 } |
| 5172 } | 5201 } |
| 5173 // | 5202 // |
| 5174 // Check to see whether the superclass has a non-factory unnamed | 5203 // Check to see whether the superclass has a non-factory unnamed |
| 5175 // constructor. | 5204 // constructor. |
| 5176 // | 5205 // |
| 5177 InterfaceType superType = _enclosingClass.supertype; | 5206 InterfaceType superType = _enclosingClass.supertype; |
| 5178 if (superType == null) { | 5207 if (superType == null) { |
| 5179 return false; | 5208 return false; |
| 5180 } | 5209 } |
| 5181 ClassElement superElement = superType.element; | 5210 ClassElement superElement = superType.element; |
| 5182 ConstructorElement superUnnamedConstructor = | 5211 ConstructorElement superUnnamedConstructor = |
| 5183 superElement.unnamedConstructor; | 5212 superElement.unnamedConstructor; |
| 5184 if (superUnnamedConstructor != null) { | 5213 if (superUnnamedConstructor != null) { |
| 5185 if (superUnnamedConstructor.isFactory) { | 5214 if (superUnnamedConstructor.isFactory) { |
| 5186 _errorReporter.reportErrorForNode( | 5215 _errorReporter.reportErrorForNode( |
| 5187 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node.returnType, | 5216 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, |
| 5188 [superUnnamedConstructor]); | 5217 constructor.returnType, [superUnnamedConstructor]); |
| 5189 return true; | 5218 return true; |
| 5190 } | 5219 } |
| 5191 if (!superUnnamedConstructor.isDefaultConstructor || | 5220 if (!superUnnamedConstructor.isDefaultConstructor || |
| 5192 !_enclosingClass | 5221 !_enclosingClass |
| 5193 .isSuperConstructorAccessible(superUnnamedConstructor)) { | 5222 .isSuperConstructorAccessible(superUnnamedConstructor)) { |
| 5194 int offset; | 5223 int offset; |
| 5195 int length; | 5224 int length; |
| 5196 { | 5225 { |
| 5197 Identifier returnType = node.returnType; | 5226 Identifier returnType = constructor.returnType; |
| 5198 SimpleIdentifier name = node.name; | 5227 SimpleIdentifier name = constructor.name; |
| 5199 offset = returnType.offset; | 5228 offset = returnType.offset; |
| 5200 length = (name != null ? name.end : returnType.end) - offset; | 5229 length = (name != null ? name.end : returnType.end) - offset; |
| 5201 } | 5230 } |
| 5202 _errorReporter.reportErrorForOffset( | 5231 _errorReporter.reportErrorForOffset( |
| 5203 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, offset, | 5232 CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT, offset, |
| 5204 length, [superType.displayName]); | 5233 length, [superType.displayName]); |
| 5205 } | 5234 } |
| 5206 return false; | 5235 return false; |
| 5207 } | 5236 } |
| 5208 _errorReporter.reportErrorForNode( | 5237 _errorReporter.reportErrorForNode( |
| 5209 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, | 5238 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, |
| 5210 node.returnType, [superElement.name]); | 5239 constructor.returnType, [superElement.name]); |
| 5211 return true; | 5240 return true; |
| 5212 } | 5241 } |
| 5213 | 5242 |
| 5214 /** | 5243 /** |
| 5215 * Check that if the given [name] is a reference to a static member it is | 5244 * Check that if the given [name] is a reference to a static member it is |
| 5216 * defined in the enclosing class rather than in a superclass. | 5245 * defined in the enclosing class rather than in a superclass. |
| 5217 * | 5246 * |
| 5218 * See [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER
]. | 5247 * See [StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER
]. |
| 5219 */ | 5248 */ |
| 5220 bool _checkForUnqualifiedReferenceToNonLocalStaticMember( | 5249 bool _checkForUnqualifiedReferenceToNonLocalStaticMember( |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5233 } | 5262 } |
| 5234 if (identical(enclosingElement, _enclosingClass)) { | 5263 if (identical(enclosingElement, _enclosingClass)) { |
| 5235 return false; | 5264 return false; |
| 5236 } | 5265 } |
| 5237 _errorReporter.reportErrorForNode( | 5266 _errorReporter.reportErrorForNode( |
| 5238 StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, | 5267 StaticTypeWarningCode.UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER, |
| 5239 name, [name.name]); | 5268 name, [name.name]); |
| 5240 return true; | 5269 return true; |
| 5241 } | 5270 } |
| 5242 | 5271 |
| 5243 void _checkForValidField(FieldFormalParameter node) { | 5272 void _checkForValidField(FieldFormalParameter parameter) { |
| 5244 ParameterElement element = node.element; | 5273 ParameterElement element = parameter.element; |
| 5245 if (element is FieldFormalParameterElement) { | 5274 if (element is FieldFormalParameterElement) { |
| 5246 FieldElement fieldElement = element.field; | 5275 FieldElement fieldElement = element.field; |
| 5247 if (fieldElement == null || fieldElement.isSynthetic) { | 5276 if (fieldElement == null || fieldElement.isSynthetic) { |
| 5248 _errorReporter.reportErrorForNode( | 5277 _errorReporter.reportErrorForNode( |
| 5249 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, | 5278 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, |
| 5250 node, [node.identifier.name]); | 5279 parameter, [parameter.identifier.name]); |
| 5251 } else { | 5280 } else { |
| 5252 ParameterElement parameterElement = node.element; | 5281 ParameterElement parameterElement = parameter.element; |
| 5253 if (parameterElement is FieldFormalParameterElementImpl) { | 5282 if (parameterElement is FieldFormalParameterElementImpl) { |
| 5254 FieldFormalParameterElementImpl fieldFormal = parameterElement; | 5283 FieldFormalParameterElementImpl fieldFormal = parameterElement; |
| 5255 DartType declaredType = fieldFormal.type; | 5284 DartType declaredType = fieldFormal.type; |
| 5256 DartType fieldType = fieldElement.type; | 5285 DartType fieldType = fieldElement.type; |
| 5257 if (fieldElement.isSynthetic) { | 5286 if (fieldElement.isSynthetic) { |
| 5258 _errorReporter.reportErrorForNode( | 5287 _errorReporter.reportErrorForNode( |
| 5259 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, | 5288 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, |
| 5260 node, [node.identifier.name]); | 5289 parameter, [parameter.identifier.name]); |
| 5261 } else if (fieldElement.isStatic) { | 5290 } else if (fieldElement.isStatic) { |
| 5262 _errorReporter.reportErrorForNode( | 5291 _errorReporter.reportErrorForNode( |
| 5263 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, | 5292 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, |
| 5264 [node.identifier.name]); | 5293 parameter, [parameter.identifier.name]); |
| 5265 } else if (declaredType != null && | 5294 } else if (declaredType != null && |
| 5266 fieldType != null && | 5295 fieldType != null && |
| 5267 !declaredType.isAssignableTo(fieldType)) { | 5296 !declaredType.isAssignableTo(fieldType)) { |
| 5268 _errorReporter.reportTypeErrorForNode( | 5297 _errorReporter.reportTypeErrorForNode( |
| 5269 StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, | 5298 StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE, |
| 5270 node, [declaredType, fieldType]); | 5299 parameter, [declaredType, fieldType]); |
| 5271 } | 5300 } |
| 5272 } else { | 5301 } else { |
| 5273 if (fieldElement.isSynthetic) { | 5302 if (fieldElement.isSynthetic) { |
| 5274 _errorReporter.reportErrorForNode( | 5303 _errorReporter.reportErrorForNode( |
| 5275 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, | 5304 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD, |
| 5276 node, [node.identifier.name]); | 5305 parameter, [parameter.identifier.name]); |
| 5277 } else if (fieldElement.isStatic) { | 5306 } else if (fieldElement.isStatic) { |
| 5278 _errorReporter.reportErrorForNode( | 5307 _errorReporter.reportErrorForNode( |
| 5279 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, node, | 5308 CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_STATIC_FIELD, |
| 5280 [node.identifier.name]); | 5309 parameter, [parameter.identifier.name]); |
| 5281 } | 5310 } |
| 5282 } | 5311 } |
| 5283 } | 5312 } |
| 5284 } | 5313 } |
| 5285 // else { | 5314 // else { |
| 5286 // // TODO(jwren) Report error, constructor initializer variable is a top
level element | 5315 // // TODO(jwren) Report error, constructor initializer variable is a top
level element |
| 5287 // // (Either here or in ErrorVerifier.checkForAllFinalInitializedErrorCo
des) | 5316 // // (Either here or in ErrorVerifier.checkForAllFinalInitializedErrorCo
des) |
| 5288 // } | 5317 // } |
| 5289 } | 5318 } |
| 5290 | 5319 |
| 5291 /** | 5320 /** |
| 5292 * Verify that the given [getter] does not have a return type of 'void'. | 5321 * Verify that the given [getter] does not have a return type of 'void'. |
| 5293 * | 5322 * |
| 5294 * See [StaticWarningCode.VOID_RETURN_FOR_GETTER]. | 5323 * See [StaticWarningCode.VOID_RETURN_FOR_GETTER]. |
| 5295 */ | 5324 */ |
| 5296 bool _checkForVoidReturnType(MethodDeclaration node) { | 5325 bool _checkForVoidReturnType(MethodDeclaration getter) { |
| 5297 TypeName returnType = node.returnType; | 5326 TypeName returnType = getter.returnType; |
| 5298 if (returnType == null || returnType.name.name != "void") { | 5327 if (returnType == null || returnType.name.name != "void") { |
| 5299 return false; | 5328 return false; |
| 5300 } | 5329 } |
| 5301 _errorReporter.reportErrorForNode( | 5330 _errorReporter.reportErrorForNode( |
| 5302 StaticWarningCode.VOID_RETURN_FOR_GETTER, returnType); | 5331 StaticWarningCode.VOID_RETURN_FOR_GETTER, returnType); |
| 5303 return true; | 5332 return true; |
| 5304 } | 5333 } |
| 5305 | 5334 |
| 5306 /** | 5335 /** |
| 5307 * Verify the given operator-method [declaration], has correct number of | 5336 * Verify the given operator-method [declaration], has correct number of |
| 5308 * parameters. | 5337 * parameters. |
| 5309 * | 5338 * |
| 5310 * This method assumes that the method declaration was tested to be an | 5339 * This method assumes that the method declaration was tested to be an |
| 5311 * operator declaration before being called. | 5340 * operator declaration before being called. |
| 5312 * | 5341 * |
| 5313 * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR]. | 5342 * See [CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR]. |
| 5314 */ | 5343 */ |
| 5315 bool _checkForWrongNumberOfParametersForOperator(MethodDeclaration node) { | 5344 bool _checkForWrongNumberOfParametersForOperator( |
| 5345 MethodDeclaration declaration) { |
| 5316 // prepare number of parameters | 5346 // prepare number of parameters |
| 5317 FormalParameterList parameterList = node.parameters; | 5347 FormalParameterList parameterList = declaration.parameters; |
| 5318 if (parameterList == null) { | 5348 if (parameterList == null) { |
| 5319 return false; | 5349 return false; |
| 5320 } | 5350 } |
| 5321 int numParameters = parameterList.parameters.length; | 5351 int numParameters = parameterList.parameters.length; |
| 5322 // prepare operator name | 5352 // prepare operator name |
| 5323 SimpleIdentifier nameNode = node.name; | 5353 SimpleIdentifier nameNode = declaration.name; |
| 5324 if (nameNode == null) { | 5354 if (nameNode == null) { |
| 5325 return false; | 5355 return false; |
| 5326 } | 5356 } |
| 5327 String name = nameNode.name; | 5357 String name = nameNode.name; |
| 5328 // check for exact number of parameters | 5358 // check for exact number of parameters |
| 5329 int expected = -1; | 5359 int expected = -1; |
| 5330 if ("[]=" == name) { | 5360 if ("[]=" == name) { |
| 5331 expected = 2; | 5361 expected = 2; |
| 5332 } else if ("<" == name || | 5362 } else if ("<" == name || |
| 5333 ">" == name || | 5363 ">" == name || |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5448 } | 5478 } |
| 5449 return false; | 5479 return false; |
| 5450 } | 5480 } |
| 5451 | 5481 |
| 5452 /** | 5482 /** |
| 5453 * Verify that if the given class [declaration] implements the class Function | 5483 * Verify that if the given class [declaration] implements the class Function |
| 5454 * that it has a concrete implementation of the call method. | 5484 * that it has a concrete implementation of the call method. |
| 5455 * | 5485 * |
| 5456 * See [StaticWarningCode.FUNCTION_WITHOUT_CALL]. | 5486 * See [StaticWarningCode.FUNCTION_WITHOUT_CALL]. |
| 5457 */ | 5487 */ |
| 5458 bool _checkImplementsFunctionWithoutCall(ClassDeclaration node) { | 5488 bool _checkImplementsFunctionWithoutCall(ClassDeclaration declaration) { |
| 5459 if (node.isAbstract) { | 5489 if (declaration.isAbstract) { |
| 5460 return false; | 5490 return false; |
| 5461 } | 5491 } |
| 5462 ClassElement classElement = node.element; | 5492 ClassElement classElement = declaration.element; |
| 5463 if (classElement == null) { | 5493 if (classElement == null) { |
| 5464 return false; | 5494 return false; |
| 5465 } | 5495 } |
| 5466 if (!classElement.type.isSubtypeOf(_typeProvider.functionType)) { | 5496 if (!classElement.type.isSubtypeOf(_typeProvider.functionType)) { |
| 5467 return false; | 5497 return false; |
| 5468 } | 5498 } |
| 5469 // If there is a noSuchMethod method, then don't report the warning, | 5499 // If there is a noSuchMethod method, then don't report the warning, |
| 5470 // see dartbug.com/16078 | 5500 // see dartbug.com/16078 |
| 5471 if (classElement.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME) != | 5501 if (classElement.getMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME) != |
| 5472 null) { | 5502 null) { |
| 5473 return false; | 5503 return false; |
| 5474 } | 5504 } |
| 5475 ExecutableElement callMethod = _inheritanceManager.lookupMember( | 5505 ExecutableElement callMethod = _inheritanceManager.lookupMember( |
| 5476 classElement, FunctionElement.CALL_METHOD_NAME); | 5506 classElement, FunctionElement.CALL_METHOD_NAME); |
| 5477 if (callMethod == null || | 5507 if (callMethod == null || |
| 5478 callMethod is! MethodElement || | 5508 callMethod is! MethodElement || |
| 5479 (callMethod as MethodElement).isAbstract) { | 5509 (callMethod as MethodElement).isAbstract) { |
| 5480 _errorReporter.reportErrorForNode( | 5510 _errorReporter.reportErrorForNode( |
| 5481 StaticWarningCode.FUNCTION_WITHOUT_CALL, node.name); | 5511 StaticWarningCode.FUNCTION_WITHOUT_CALL, declaration.name); |
| 5482 return true; | 5512 return true; |
| 5483 } | 5513 } |
| 5484 return false; | 5514 return false; |
| 5485 } | 5515 } |
| 5486 | 5516 |
| 5487 /** | 5517 /** |
| 5488 * Verify that the given class [declaration] does not have the same class in | 5518 * Verify that the given class [declaration] does not have the same class in |
| 5489 * the 'extends' and 'implements' clauses. | 5519 * the 'extends' and 'implements' clauses. |
| 5490 * | 5520 * |
| 5491 * See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]. | 5521 * See [CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS]. |
| 5492 */ | 5522 */ |
| 5493 bool _checkImplementsSuperClass(ClassDeclaration node) { | 5523 bool _checkImplementsSuperClass(ClassDeclaration declaration) { |
| 5494 // prepare super type | 5524 // prepare super type |
| 5495 InterfaceType superType = _enclosingClass.supertype; | 5525 InterfaceType superType = _enclosingClass.supertype; |
| 5496 if (superType == null) { | 5526 if (superType == null) { |
| 5497 return false; | 5527 return false; |
| 5498 } | 5528 } |
| 5499 // prepare interfaces | 5529 // prepare interfaces |
| 5500 ImplementsClause implementsClause = node.implementsClause; | 5530 ImplementsClause implementsClause = declaration.implementsClause; |
| 5501 if (implementsClause == null) { | 5531 if (implementsClause == null) { |
| 5502 return false; | 5532 return false; |
| 5503 } | 5533 } |
| 5504 // check interfaces | 5534 // check interfaces |
| 5505 bool hasProblem = false; | 5535 bool hasProblem = false; |
| 5506 for (TypeName interfaceNode in implementsClause.interfaces) { | 5536 for (TypeName interfaceNode in implementsClause.interfaces) { |
| 5507 if (interfaceNode.type == superType) { | 5537 if (interfaceNode.type == superType) { |
| 5508 hasProblem = true; | 5538 hasProblem = true; |
| 5509 _errorReporter.reportErrorForNode( | 5539 _errorReporter.reportErrorForNode( |
| 5510 CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, interfaceNode, | 5540 CompileTimeErrorCode.IMPLEMENTS_SUPER_CLASS, interfaceNode, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 5532 StaticTypeAnalyzer.flattenFutures(_typeProvider, staticReturnType) | 5562 StaticTypeAnalyzer.flattenFutures(_typeProvider, staticReturnType) |
| 5533 ]); | 5563 ]); |
| 5534 } | 5564 } |
| 5535 return staticReturnType; | 5565 return staticReturnType; |
| 5536 } | 5566 } |
| 5537 | 5567 |
| 5538 /** | 5568 /** |
| 5539 * Return the error code that should be used when the given class [element] | 5569 * Return the error code that should be used when the given class [element] |
| 5540 * references itself directly. | 5570 * references itself directly. |
| 5541 */ | 5571 */ |
| 5542 ErrorCode _getBaseCaseErrorCode(ClassElement classElt) { | 5572 ErrorCode _getBaseCaseErrorCode(ClassElement element) { |
| 5543 InterfaceType supertype = classElt.supertype; | 5573 InterfaceType supertype = element.supertype; |
| 5544 if (supertype != null && _enclosingClass == supertype.element) { | 5574 if (supertype != null && _enclosingClass == supertype.element) { |
| 5545 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTE
NDS; | 5575 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTE
NDS; |
| 5546 } | 5576 } |
| 5547 List<InterfaceType> mixins = classElt.mixins; | 5577 List<InterfaceType> mixins = element.mixins; |
| 5548 for (int i = 0; i < mixins.length; i++) { | 5578 for (int i = 0; i < mixins.length; i++) { |
| 5549 if (_enclosingClass == mixins[i].element) { | 5579 if (_enclosingClass == mixins[i].element) { |
| 5550 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WI
TH; | 5580 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WI
TH; |
| 5551 } | 5581 } |
| 5552 } | 5582 } |
| 5553 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEM
ENTS; | 5583 return CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEM
ENTS; |
| 5554 } | 5584 } |
| 5555 | 5585 |
| 5556 /** | 5586 /** |
| 5557 * Given an [expression] in a switch case whose value is expected to be an | 5587 * Given an [expression] in a switch case whose value is expected to be an |
| 5558 * enum constant, return the name of the constant. | 5588 * enum constant, return the name of the constant. |
| 5559 */ | 5589 */ |
| 5560 String _getConstantName(Expression expression) { | 5590 String _getConstantName(Expression expression) { |
| 5561 // TODO(brianwilkerson) Convert this to return the element representing the | 5591 // TODO(brianwilkerson) Convert this to return the element representing the |
| 5562 // constant. | 5592 // constant. |
| 5563 if (expression is SimpleIdentifier) { | 5593 if (expression is SimpleIdentifier) { |
| 5564 return expression.name; | 5594 return expression.name; |
| 5565 } else if (expression is PrefixedIdentifier) { | 5595 } else if (expression is PrefixedIdentifier) { |
| 5566 return expression.identifier.name; | 5596 return expression.identifier.name; |
| 5567 } else if (expression is PropertyAccess) { | 5597 } else if (expression is PropertyAccess) { |
| 5568 return expression.propertyName.name; | 5598 return expression.propertyName.name; |
| 5569 } | 5599 } |
| 5570 return null; | 5600 return null; |
| 5571 } | 5601 } |
| 5572 | 5602 |
| 5573 /** | 5603 /** |
| 5574 * Return the return type of the given [getter]. | 5604 * Return the return type of the given [getter]. |
| 5575 */ | 5605 */ |
| 5576 DartType _getGetterType(PropertyAccessorElement propertyAccessorElement) { | 5606 DartType _getGetterType(PropertyAccessorElement getter) { |
| 5577 FunctionType functionType = propertyAccessorElement.type; | 5607 FunctionType functionType = getter.type; |
| 5578 if (functionType != null) { | 5608 if (functionType != null) { |
| 5579 return functionType.returnType; | 5609 return functionType.returnType; |
| 5580 } else { | 5610 } else { |
| 5581 return null; | 5611 return null; |
| 5582 } | 5612 } |
| 5583 } | 5613 } |
| 5584 | 5614 |
| 5585 /** | 5615 /** |
| 5586 * Return the type of the first and only parameter of the given [setter]. | 5616 * Return the type of the first and only parameter of the given [setter]. |
| 5587 */ | 5617 */ |
| 5588 DartType _getSetterType(PropertyAccessorElement propertyAccessorElement) { | 5618 DartType _getSetterType(PropertyAccessorElement setter) { |
| 5589 // Get the parameters for MethodDeclaration or FunctionDeclaration | 5619 // Get the parameters for MethodDeclaration or FunctionDeclaration |
| 5590 List<ParameterElement> setterParameters = | 5620 List<ParameterElement> setterParameters = setter.parameters; |
| 5591 propertyAccessorElement.parameters; | |
| 5592 // If there are no setter parameters, return no type. | 5621 // If there are no setter parameters, return no type. |
| 5593 if (setterParameters.length == 0) { | 5622 if (setterParameters.length == 0) { |
| 5594 return null; | 5623 return null; |
| 5595 } | 5624 } |
| 5596 return setterParameters[0].type; | 5625 return setterParameters[0].type; |
| 5597 } | 5626 } |
| 5598 | 5627 |
| 5599 /** | 5628 /** |
| 5600 * Given a list of [directives] that have the same prefix, generate an error | 5629 * Given a list of [directives] that have the same prefix, generate an error |
| 5601 * if there is more than one import and any of those imports is deferred. | 5630 * if there is more than one import and any of those imports is deferred. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 5615 } | 5644 } |
| 5616 } | 5645 } |
| 5617 } | 5646 } |
| 5618 return foundError; | 5647 return foundError; |
| 5619 } | 5648 } |
| 5620 | 5649 |
| 5621 /** | 5650 /** |
| 5622 * Return `true` if the given [constructor] redirects to itself, directly or | 5651 * Return `true` if the given [constructor] redirects to itself, directly or |
| 5623 * indirectly. | 5652 * indirectly. |
| 5624 */ | 5653 */ |
| 5625 bool _hasRedirectingFactoryConstructorCycle(ConstructorElement element) { | 5654 bool _hasRedirectingFactoryConstructorCycle(ConstructorElement constructor) { |
| 5626 Set<ConstructorElement> constructors = new HashSet<ConstructorElement>(); | 5655 Set<ConstructorElement> constructors = new HashSet<ConstructorElement>(); |
| 5627 ConstructorElement current = element; | 5656 ConstructorElement current = constructor; |
| 5628 while (current != null) { | 5657 while (current != null) { |
| 5629 if (constructors.contains(current)) { | 5658 if (constructors.contains(current)) { |
| 5630 return identical(current, element); | 5659 return identical(current, constructor); |
| 5631 } | 5660 } |
| 5632 constructors.add(current); | 5661 constructors.add(current); |
| 5633 current = current.redirectedConstructor; | 5662 current = current.redirectedConstructor; |
| 5634 if (current is ConstructorMember) { | 5663 if (current is ConstructorMember) { |
| 5635 current = (current as ConstructorMember).baseElement; | 5664 current = (current as ConstructorMember).baseElement; |
| 5636 } | 5665 } |
| 5637 } | 5666 } |
| 5638 return false; | 5667 return false; |
| 5639 } | 5668 } |
| 5640 | 5669 |
| 5641 /** | 5670 /** |
| 5642 * Return `true` if the given [element] has direct or indirect reference to | 5671 * Return `true` if the given [element] has direct or indirect reference to |
| 5643 * itself from anywhere except a class element or type parameter bounds. | 5672 * itself from anywhere except a class element or type parameter bounds. |
| 5644 */ | 5673 */ |
| 5645 bool _hasTypedefSelfReference(Element target) { | 5674 bool _hasTypedefSelfReference(Element element) { |
| 5646 Set<Element> checked = new HashSet<Element>(); | 5675 Set<Element> checked = new HashSet<Element>(); |
| 5647 List<Element> toCheck = new List<Element>(); | 5676 List<Element> toCheck = new List<Element>(); |
| 5648 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference elementVisi
tor = | 5677 GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference elementVisi
tor = |
| 5649 new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference( | 5678 new GeneralizingElementVisitor_ErrorVerifier_hasTypedefSelfReference( |
| 5650 toCheck); | 5679 toCheck); |
| 5651 toCheck.add(target); | 5680 toCheck.add(element); |
| 5652 bool firstIteration = true; | 5681 bool firstIteration = true; |
| 5653 while (true) { | 5682 while (true) { |
| 5654 Element current; | 5683 Element current; |
| 5655 // get next element | 5684 // get next element |
| 5656 while (true) { | 5685 while (true) { |
| 5657 // may be no more elements to check | 5686 // may be no more elements to check |
| 5658 if (toCheck.isEmpty) { | 5687 if (toCheck.isEmpty) { |
| 5659 return false; | 5688 return false; |
| 5660 } | 5689 } |
| 5661 // try to get next element | 5690 // try to get next element |
| 5662 current = toCheck.removeAt(toCheck.length - 1); | 5691 current = toCheck.removeAt(toCheck.length - 1); |
| 5663 if (target == current) { | 5692 if (element == current) { |
| 5664 if (firstIteration) { | 5693 if (firstIteration) { |
| 5665 firstIteration = false; | 5694 firstIteration = false; |
| 5666 break; | 5695 break; |
| 5667 } else { | 5696 } else { |
| 5668 return true; | 5697 return true; |
| 5669 } | 5698 } |
| 5670 } | 5699 } |
| 5671 if (current != null && !checked.contains(current)) { | 5700 if (current != null && !checked.contains(current)) { |
| 5672 break; | 5701 break; |
| 5673 } | 5702 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5685 return true; | 5714 return true; |
| 5686 } else if (type is InterfaceType) { | 5715 } else if (type is InterfaceType) { |
| 5687 MethodElement callMethod = | 5716 MethodElement callMethod = |
| 5688 type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _currentLibrary); | 5717 type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _currentLibrary); |
| 5689 return callMethod != null; | 5718 return callMethod != null; |
| 5690 } | 5719 } |
| 5691 return false; | 5720 return false; |
| 5692 } | 5721 } |
| 5693 | 5722 |
| 5694 /** | 5723 /** |
| 5695 * Return `true` iff the given class [element] has a method, getter or setter | 5724 * Return `true` iff the given [classElement] has a concrete method, getter or |
| 5696 * that matches the name of the given executable [element] in either the class | 5725 * setter that matches the name of the given [executableElement] in either the |
| 5697 * itself, or one of its' mixins that is concrete. | 5726 * class itself, or one of its' mixins. |
| 5698 * | 5727 * |
| 5699 * By "match", only the name of the member is tested to match, it does not | 5728 * By "match", only the name of the member is tested to match, it does not |
| 5700 * have to equal or be a subtype of the given executable element, this is due | 5729 * have to equal or be a subtype of the given executable element, this is due |
| 5701 * to the specific use where this method is used in | 5730 * to the specific use where this method is used in |
| 5702 * [_checkForNonAbstractClassInheritsAbstractMember]. | 5731 * [_checkForNonAbstractClassInheritsAbstractMember]. |
| 5703 */ | 5732 */ |
| 5704 bool _isMemberInClassOrMixin( | 5733 bool _isMemberInClassOrMixin( |
| 5705 ExecutableElement executableElt, ClassElement classElt) { | 5734 ExecutableElement executableElement, ClassElement classElement) { |
| 5706 ExecutableElement foundElt = null; | 5735 ExecutableElement foundElt = null; |
| 5707 String executableName = executableElt.name; | 5736 String executableName = executableElement.name; |
| 5708 if (executableElt is MethodElement) { | 5737 if (executableElement is MethodElement) { |
| 5709 foundElt = classElt.getMethod(executableName); | 5738 foundElt = classElement.getMethod(executableName); |
| 5710 if (foundElt != null && !(foundElt as MethodElement).isAbstract) { | 5739 if (foundElt != null && !(foundElt as MethodElement).isAbstract) { |
| 5711 return true; | 5740 return true; |
| 5712 } | 5741 } |
| 5713 List<InterfaceType> mixins = classElt.mixins; | 5742 List<InterfaceType> mixins = classElement.mixins; |
| 5714 for (int i = 0; i < mixins.length && foundElt == null; i++) { | 5743 for (int i = 0; i < mixins.length && foundElt == null; i++) { |
| 5715 foundElt = mixins[i].getMethod(executableName); | 5744 foundElt = mixins[i].getMethod(executableName); |
| 5716 } | 5745 } |
| 5717 if (foundElt != null && !(foundElt as MethodElement).isAbstract) { | 5746 if (foundElt != null && !(foundElt as MethodElement).isAbstract) { |
| 5718 return true; | 5747 return true; |
| 5719 } | 5748 } |
| 5720 } else if (executableElt is PropertyAccessorElement) { | 5749 } else if (executableElement is PropertyAccessorElement) { |
| 5721 PropertyAccessorElement propertyAccessorElement = executableElt; | 5750 PropertyAccessorElement propertyAccessorElement = executableElement; |
| 5722 if (propertyAccessorElement.isGetter) { | 5751 if (propertyAccessorElement.isGetter) { |
| 5723 foundElt = classElt.getGetter(executableName); | 5752 foundElt = classElement.getGetter(executableName); |
| 5724 } | 5753 } |
| 5725 if (foundElt == null && propertyAccessorElement.isSetter) { | 5754 if (foundElt == null && propertyAccessorElement.isSetter) { |
| 5726 foundElt = classElt.getSetter(executableName); | 5755 foundElt = classElement.getSetter(executableName); |
| 5727 } | 5756 } |
| 5728 if (foundElt != null && | 5757 if (foundElt != null && |
| 5729 !(foundElt as PropertyAccessorElement).isAbstract) { | 5758 !(foundElt as PropertyAccessorElement).isAbstract) { |
| 5730 return true; | 5759 return true; |
| 5731 } | 5760 } |
| 5732 List<InterfaceType> mixins = classElt.mixins; | 5761 List<InterfaceType> mixins = classElement.mixins; |
| 5733 for (int i = 0; i < mixins.length && foundElt == null; i++) { | 5762 for (int i = 0; i < mixins.length && foundElt == null; i++) { |
| 5734 foundElt = mixins[i].getGetter(executableName); | 5763 foundElt = mixins[i].getGetter(executableName); |
| 5735 if (foundElt == null) { | 5764 if (foundElt == null) { |
| 5736 foundElt = mixins[i].getSetter(executableName); | 5765 foundElt = mixins[i].getSetter(executableName); |
| 5737 } | 5766 } |
| 5738 } | 5767 } |
| 5739 if (foundElt != null && | 5768 if (foundElt != null && |
| 5740 !(foundElt as PropertyAccessorElement).isAbstract) { | 5769 !(foundElt as PropertyAccessorElement).isAbstract) { |
| 5741 return true; | 5770 return true; |
| 5742 } | 5771 } |
| 5743 } | 5772 } |
| 5744 return false; | 5773 return false; |
| 5745 } | 5774 } |
| 5746 | 5775 |
| 5747 /** | 5776 /** |
| 5748 * Return `true` if the given 'this' [expression] is in a valid context. | 5777 * Return `true` if the given 'this' [expression] is in a valid context. |
| 5749 */ | 5778 */ |
| 5750 bool _isThisInValidContext(ThisExpression node) { | 5779 bool _isThisInValidContext(ThisExpression expression) { |
| 5751 for (AstNode n = node; n != null; n = n.parent) { | 5780 for (AstNode node = expression.parent; node != null; node = node.parent) { |
| 5752 if (n is CompilationUnit) { | 5781 if (node is CompilationUnit) { |
| 5753 return false; | 5782 return false; |
| 5754 } | 5783 } |
| 5755 if (n is ConstructorDeclaration) { | 5784 if (node is ConstructorDeclaration) { |
| 5756 return n.factoryKeyword == null; | 5785 return node.factoryKeyword == null; |
| 5757 } | 5786 } |
| 5758 if (n is ConstructorInitializer) { | 5787 if (node is ConstructorInitializer) { |
| 5759 return false; | 5788 return false; |
| 5760 } | 5789 } |
| 5761 if (n is MethodDeclaration) { | 5790 if (node is MethodDeclaration) { |
| 5762 return !n.isStatic; | 5791 return !node.isStatic; |
| 5763 } | 5792 } |
| 5764 } | 5793 } |
| 5765 return false; | 5794 return false; |
| 5766 } | 5795 } |
| 5767 | 5796 |
| 5768 /** | 5797 /** |
| 5769 * Return `true` if the given [identifier] is in a location where it is | 5798 * Return `true` if the given [identifier] is in a location where it is |
| 5770 * allowed to resolve to a static member of a supertype. | 5799 * allowed to resolve to a static member of a supertype. |
| 5771 */ | 5800 */ |
| 5772 bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed( | 5801 bool _isUnqualifiedReferenceToNonLocalStaticMemberAllowed( |
| 5773 SimpleIdentifier node) { | 5802 SimpleIdentifier identifier) { |
| 5774 if (node.inDeclarationContext()) { | 5803 if (identifier.inDeclarationContext()) { |
| 5775 return true; | 5804 return true; |
| 5776 } | 5805 } |
| 5777 AstNode parent = node.parent; | 5806 AstNode parent = identifier.parent; |
| 5778 if (parent is ConstructorName || | 5807 if (parent is ConstructorName || |
| 5779 parent is MethodInvocation || | 5808 parent is MethodInvocation || |
| 5780 parent is PropertyAccess || | 5809 parent is PropertyAccess || |
| 5781 parent is SuperConstructorInvocation) { | 5810 parent is SuperConstructorInvocation) { |
| 5782 return true; | 5811 return true; |
| 5783 } | 5812 } |
| 5784 if (parent is PrefixedIdentifier && identical(parent.identifier, node)) { | 5813 if (parent is PrefixedIdentifier && |
| 5814 identical(parent.identifier, identifier)) { |
| 5785 return true; | 5815 return true; |
| 5786 } | 5816 } |
| 5787 if (parent is Annotation && identical(parent.constructorName, node)) { | 5817 if (parent is Annotation && identical(parent.constructorName, identifier)) { |
| 5788 return true; | 5818 return true; |
| 5789 } | 5819 } |
| 5790 if (parent is CommentReference) { | 5820 if (parent is CommentReference) { |
| 5791 CommentReference commentReference = parent; | 5821 CommentReference commentReference = parent; |
| 5792 if (commentReference.newKeyword != null) { | 5822 if (commentReference.newKeyword != null) { |
| 5793 return true; | 5823 return true; |
| 5794 } | 5824 } |
| 5795 } | 5825 } |
| 5796 return false; | 5826 return false; |
| 5797 } | 5827 } |
| 5798 | 5828 |
| 5799 bool _isUserDefinedObject(EvaluationResultImpl result) => result == null || | 5829 bool _isUserDefinedObject(EvaluationResultImpl result) => result == null || |
| 5800 (result.value != null && result.value.isUserDefinedObject); | 5830 (result.value != null && result.value.isUserDefinedObject); |
| 5801 | 5831 |
| 5802 /** | 5832 /** |
| 5803 * Check that the given class [element] is not a superinterface to itself. The | 5833 * Check that the given class [element] is not a superinterface to itself. The |
| 5804 * [path] is a list containing the potentially cyclic implements path. | 5834 * [path] is a list containing the potentially cyclic implements path. |
| 5805 * | 5835 * |
| 5806 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], | 5836 * See [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE], |
| 5807 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], | 5837 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS], |
| 5808 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]
, | 5838 * [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS]
, |
| 5809 * and [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH]. | 5839 * and [CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH]. |
| 5810 */ | 5840 */ |
| 5811 bool _safeCheckForRecursiveInterfaceInheritance( | 5841 bool _safeCheckForRecursiveInterfaceInheritance( |
| 5812 ClassElement classElt, List<ClassElement> path) { | 5842 ClassElement element, List<ClassElement> path) { |
| 5813 // Detect error condition. | 5843 // Detect error condition. |
| 5814 int size = path.length; | 5844 int size = path.length; |
| 5815 // If this is not the base case (size > 0), and the enclosing class is the | 5845 // If this is not the base case (size > 0), and the enclosing class is the |
| 5816 // given class element then an error an error. | 5846 // given class element then an error an error. |
| 5817 if (size > 0 && _enclosingClass == classElt) { | 5847 if (size > 0 && _enclosingClass == element) { |
| 5818 String enclosingClassName = _enclosingClass.displayName; | 5848 String enclosingClassName = _enclosingClass.displayName; |
| 5819 if (size > 1) { | 5849 if (size > 1) { |
| 5820 // Construct a string showing the cyclic implements path: | 5850 // Construct a string showing the cyclic implements path: |
| 5821 // "A, B, C, D, A" | 5851 // "A, B, C, D, A" |
| 5822 String separator = ", "; | 5852 String separator = ", "; |
| 5823 StringBuffer buffer = new StringBuffer(); | 5853 StringBuffer buffer = new StringBuffer(); |
| 5824 for (int i = 0; i < size; i++) { | 5854 for (int i = 0; i < size; i++) { |
| 5825 buffer.write(path[i].displayName); | 5855 buffer.write(path[i].displayName); |
| 5826 buffer.write(separator); | 5856 buffer.write(separator); |
| 5827 } | 5857 } |
| 5828 buffer.write(classElt.displayName); | 5858 buffer.write(element.displayName); |
| 5829 _errorReporter.reportErrorForOffset( | 5859 _errorReporter.reportErrorForOffset( |
| 5830 CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, | 5860 CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE, |
| 5831 _enclosingClass.nameOffset, enclosingClassName.length, [ | 5861 _enclosingClass.nameOffset, enclosingClassName.length, [ |
| 5832 enclosingClassName, | 5862 enclosingClassName, |
| 5833 buffer.toString() | 5863 buffer.toString() |
| 5834 ]); | 5864 ]); |
| 5835 return true; | 5865 return true; |
| 5836 } else { | 5866 } else { |
| 5837 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or | 5867 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or |
| 5838 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or | 5868 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or |
| 5839 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH | 5869 // RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH |
| 5840 _errorReporter.reportErrorForOffset(_getBaseCaseErrorCode(classElt), | 5870 _errorReporter.reportErrorForOffset(_getBaseCaseErrorCode(element), |
| 5841 _enclosingClass.nameOffset, enclosingClassName.length, | 5871 _enclosingClass.nameOffset, enclosingClassName.length, |
| 5842 [enclosingClassName]); | 5872 [enclosingClassName]); |
| 5843 return true; | 5873 return true; |
| 5844 } | 5874 } |
| 5845 } | 5875 } |
| 5846 if (path.indexOf(classElt) > 0) { | 5876 if (path.indexOf(element) > 0) { |
| 5847 return false; | 5877 return false; |
| 5848 } | 5878 } |
| 5849 path.add(classElt); | 5879 path.add(element); |
| 5850 // n-case | 5880 // n-case |
| 5851 InterfaceType supertype = classElt.supertype; | 5881 InterfaceType supertype = element.supertype; |
| 5852 if (supertype != null && | 5882 if (supertype != null && |
| 5853 _safeCheckForRecursiveInterfaceInheritance(supertype.element, path)) { | 5883 _safeCheckForRecursiveInterfaceInheritance(supertype.element, path)) { |
| 5854 return true; | 5884 return true; |
| 5855 } | 5885 } |
| 5856 List<InterfaceType> interfaceTypes = classElt.interfaces; | 5886 List<InterfaceType> interfaceTypes = element.interfaces; |
| 5857 for (InterfaceType interfaceType in interfaceTypes) { | 5887 for (InterfaceType interfaceType in interfaceTypes) { |
| 5858 if (_safeCheckForRecursiveInterfaceInheritance( | 5888 if (_safeCheckForRecursiveInterfaceInheritance( |
| 5859 interfaceType.element, path)) { | 5889 interfaceType.element, path)) { |
| 5860 return true; | 5890 return true; |
| 5861 } | 5891 } |
| 5862 } | 5892 } |
| 5863 List<InterfaceType> mixinTypes = classElt.mixins; | 5893 List<InterfaceType> mixinTypes = element.mixins; |
| 5864 for (InterfaceType mixinType in mixinTypes) { | 5894 for (InterfaceType mixinType in mixinTypes) { |
| 5865 if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) { | 5895 if (_safeCheckForRecursiveInterfaceInheritance(mixinType.element, path)) { |
| 5866 return true; | 5896 return true; |
| 5867 } | 5897 } |
| 5868 } | 5898 } |
| 5869 path.removeAt(path.length - 1); | 5899 path.removeAt(path.length - 1); |
| 5870 return false; | 5900 return false; |
| 5871 } | 5901 } |
| 5872 | 5902 |
| 5873 /** | 5903 /** |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5937 toCheck.add(type.element); | 5967 toCheck.add(type.element); |
| 5938 // type arguments | 5968 // type arguments |
| 5939 if (type is InterfaceType) { | 5969 if (type is InterfaceType) { |
| 5940 InterfaceType interfaceType = type; | 5970 InterfaceType interfaceType = type; |
| 5941 for (DartType typeArgument in interfaceType.typeArguments) { | 5971 for (DartType typeArgument in interfaceType.typeArguments) { |
| 5942 _addTypeToCheck(typeArgument); | 5972 _addTypeToCheck(typeArgument); |
| 5943 } | 5973 } |
| 5944 } | 5974 } |
| 5945 } | 5975 } |
| 5946 } | 5976 } |
| OLD | NEW |