| 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 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
| 6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
| 7 | 7 |
| 8 library engine.resolver; | 8 library engine.resolver; |
| 9 | 9 |
| 10 import 'dart:collection'; | 10 import 'dart:collection'; |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 return argument is SimpleStringLiteral; | 345 return argument is SimpleStringLiteral; |
| 346 } | 346 } |
| 347 | 347 |
| 348 /** | 348 /** |
| 349 * Checks if given [Annotation] is an annotation with required name. | 349 * Checks if given [Annotation] is an annotation with required name. |
| 350 */ | 350 */ |
| 351 bool _isAngularAnnotation(Annotation annotation, String name) { | 351 bool _isAngularAnnotation(Annotation annotation, String name) { |
| 352 Element element = annotation.element; | 352 Element element = annotation.element; |
| 353 if (element is ConstructorElement) { | 353 if (element is ConstructorElement) { |
| 354 ConstructorElement constructorElement = element; | 354 ConstructorElement constructorElement = element; |
| 355 return constructorElement.returnType.displayName == name; | 355 if (constructorElement.returnType.displayName != name) { |
| 356 return false; |
| 357 } |
| 358 return _isAngularLibraryElement(constructorElement); |
| 356 } | 359 } |
| 357 return false; | 360 return false; |
| 358 } | 361 } |
| 359 | 362 |
| 363 /** |
| 364 * Checks if the given [Element] is a part of the Angular library. |
| 365 */ |
| 366 bool _isAngularLibraryElement(Element element) { |
| 367 LibraryElement library = element.library; |
| 368 return library != null && library.name != null && library.name.startsWith("a
ngular"); |
| 369 } |
| 370 |
| 360 void _parseComponent() { | 371 void _parseComponent() { |
| 361 bool isValid = true; | 372 bool isValid = true; |
| 362 // publishAs | 373 // publishAs |
| 363 String name = null; | 374 String name = null; |
| 364 int nameOffset = -1; | 375 int nameOffset = -1; |
| 365 if (_hasStringArgument(_PUBLISH_AS)) { | 376 if (_hasStringArgument(_PUBLISH_AS)) { |
| 366 name = _getStringArgument(_PUBLISH_AS); | 377 name = _getStringArgument(_PUBLISH_AS); |
| 367 nameOffset = _getStringArgumentOffset(_PUBLISH_AS); | 378 nameOffset = _getStringArgumentOffset(_PUBLISH_AS); |
| 368 } | 379 } |
| 369 // selector | 380 // selector |
| (...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 } | 914 } |
| 904 } | 915 } |
| 905 // | 916 // |
| 906 // Hint case: test propagated type information | 917 // Hint case: test propagated type information |
| 907 // | 918 // |
| 908 // Compute the best types to use. | 919 // Compute the best types to use. |
| 909 DartType expectedBestType = expectedPropagatedType != null ? expectedPropaga
tedType : expectedStaticType; | 920 DartType expectedBestType = expectedPropagatedType != null ? expectedPropaga
tedType : expectedStaticType; |
| 910 DartType actualBestType = actualPropagatedType != null ? actualPropagatedTyp
e : actualStaticType; | 921 DartType actualBestType = actualPropagatedType != null ? actualPropagatedTyp
e : actualStaticType; |
| 911 if (actualBestType != null && expectedBestType != null) { | 922 if (actualBestType != null && expectedBestType != null) { |
| 912 if (!actualBestType.isAssignableTo(expectedBestType)) { | 923 if (!actualBestType.isAssignableTo(expectedBestType)) { |
| 913 _errorReporter.reportErrorForNode(hintCode, expression, [actualBestType.
displayName, expectedBestType.displayName]); | 924 _errorReporter.reportTypeErrorForNode(hintCode, expression, [actualBestT
ype, expectedBestType]); |
| 914 return true; | 925 return true; |
| 915 } | 926 } |
| 916 } | 927 } |
| 917 return false; | 928 return false; |
| 918 } | 929 } |
| 919 | 930 |
| 920 /** | 931 /** |
| 921 * This verifies that the passed argument can be assigned to its corresponding
parameter. | 932 * This verifies that the passed argument can be assigned to its corresponding
parameter. |
| 922 * | 933 * |
| 923 * This method corresponds to ErrorCode.checkForArgumentTypeNotAssignableForAr
gument. | 934 * This method corresponds to ErrorCode.checkForArgumentTypeNotAssignableForAr
gument. |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 DartType leftType = (leftVariableElement == null) ? ErrorVerifier.getStaticT
ype(lhs) : leftVariableElement.type; | 1086 DartType leftType = (leftVariableElement == null) ? ErrorVerifier.getStaticT
ype(lhs) : leftVariableElement.type; |
| 1076 DartType staticRightType = ErrorVerifier.getStaticType(rhs); | 1087 DartType staticRightType = ErrorVerifier.getStaticType(rhs); |
| 1077 if (!staticRightType.isAssignableTo(leftType)) { | 1088 if (!staticRightType.isAssignableTo(leftType)) { |
| 1078 // The warning was generated on this rhs | 1089 // The warning was generated on this rhs |
| 1079 return false; | 1090 return false; |
| 1080 } | 1091 } |
| 1081 // Test for, and then generate the hint | 1092 // Test for, and then generate the hint |
| 1082 DartType bestRightType = rhs.bestType; | 1093 DartType bestRightType = rhs.bestType; |
| 1083 if (leftType != null && bestRightType != null) { | 1094 if (leftType != null && bestRightType != null) { |
| 1084 if (!bestRightType.isAssignableTo(leftType)) { | 1095 if (!bestRightType.isAssignableTo(leftType)) { |
| 1085 String leftName = leftType.displayName; | 1096 _errorReporter.reportTypeErrorForNode(HintCode.INVALID_ASSIGNMENT, rhs,
[bestRightType, leftType]); |
| 1086 String rightName = bestRightType.displayName; | |
| 1087 if (leftName == rightName) { | |
| 1088 Element leftElement = leftType.element; | |
| 1089 Element rightElement = bestRightType.element; | |
| 1090 if (leftElement != null && rightElement != null) { | |
| 1091 leftName = leftElement.extendedDisplayName; | |
| 1092 rightName = rightElement.extendedDisplayName; | |
| 1093 } | |
| 1094 } | |
| 1095 _errorReporter.reportErrorForNode(HintCode.INVALID_ASSIGNMENT, rhs, [rig
htName, leftName]); | |
| 1096 return true; | 1097 return true; |
| 1097 } | 1098 } |
| 1098 } | 1099 } |
| 1099 return false; | 1100 return false; |
| 1100 } | 1101 } |
| 1101 | 1102 |
| 1102 /** | 1103 /** |
| 1103 * Check that the imported library does not define a loadLibrary function. The
import has already | 1104 * Check that the imported library does not define a loadLibrary function. The
import has already |
| 1104 * been determined to be deferred when this is called. | 1105 * been determined to be deferred when this is called. |
| 1105 * | 1106 * |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1184 * @return `true` if and only if a hint code is generated on the passed node | 1185 * @return `true` if and only if a hint code is generated on the passed node |
| 1185 * @see HintCode#UNNECESSARY_CAST | 1186 * @see HintCode#UNNECESSARY_CAST |
| 1186 */ | 1187 */ |
| 1187 bool _checkForUnnecessaryCast(AsExpression node) { | 1188 bool _checkForUnnecessaryCast(AsExpression node) { |
| 1188 Expression expression = node.expression; | 1189 Expression expression = node.expression; |
| 1189 TypeName typeName = node.type; | 1190 TypeName typeName = node.type; |
| 1190 DartType lhsType = expression.staticType; | 1191 DartType lhsType = expression.staticType; |
| 1191 DartType rhsType = typeName.type; | 1192 DartType rhsType = typeName.type; |
| 1192 // TODO(jwren) After dartbug.com/13732, revisit this, we should be able to r
emove the | 1193 // TODO(jwren) After dartbug.com/13732, revisit this, we should be able to r
emove the |
| 1193 // !(x instanceof TypeParameterType) checks. | 1194 // !(x instanceof TypeParameterType) checks. |
| 1194 if (lhsType != null && rhsType != null && !lhsType.isDynamic && !rhsType.isD
ynamic && lhsType is! TypeParameterType && rhsType is! TypeParameterType && lhsT
ype.isSubtypeOf(rhsType)) { | 1195 if (lhsType != null && rhsType != null && !lhsType.isDynamic && !rhsType.isD
ynamic && lhsType is! TypeParameterType && rhsType is! TypeParameterType && lhsT
ype.isMoreSpecificThan(rhsType)) { |
| 1195 _errorReporter.reportErrorForNode(HintCode.UNNECESSARY_CAST, node, []); | 1196 _errorReporter.reportErrorForNode(HintCode.UNNECESSARY_CAST, node, []); |
| 1196 return true; | 1197 return true; |
| 1197 } | 1198 } |
| 1198 return false; | 1199 return false; |
| 1199 } | 1200 } |
| 1200 | 1201 |
| 1201 /** | 1202 /** |
| 1202 * Check for situations where the result of a method or function is used, when
it returns 'void'. | 1203 * Check for situations where the result of a method or function is used, when
it returns 'void'. |
| 1203 * | 1204 * |
| 1204 * TODO(jwren) Many other situations of use could be covered. We currently cov
er the cases var x = | 1205 * TODO(jwren) Many other situations of use could be covered. We currently cov
er the cases var x = |
| (...skipping 2141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3346 * A collection holding the function types defined in a class that need to hav
e their type | 3347 * A collection holding the function types defined in a class that need to hav
e their type |
| 3347 * arguments set to the types of the type parameters for the class, or `null`
if we are not | 3348 * arguments set to the types of the type parameters for the class, or `null`
if we are not |
| 3348 * currently processing nodes within a class. | 3349 * currently processing nodes within a class. |
| 3349 */ | 3350 */ |
| 3350 List<FunctionTypeImpl> _functionTypesToFix = null; | 3351 List<FunctionTypeImpl> _functionTypesToFix = null; |
| 3351 | 3352 |
| 3352 /** | 3353 /** |
| 3353 * A table mapping field names to field elements for the fields defined in the
current class, or | 3354 * A table mapping field names to field elements for the fields defined in the
current class, or |
| 3354 * `null` if we are not in the scope of a class. | 3355 * `null` if we are not in the scope of a class. |
| 3355 */ | 3356 */ |
| 3356 Map<String, FieldElement> _fieldMap; | 3357 HashMap<String, FieldElement> _fieldMap; |
| 3357 | 3358 |
| 3358 /** | 3359 /** |
| 3359 * Initialize a newly created element builder to build the elements for a comp
ilation unit. | 3360 * Initialize a newly created element builder to build the elements for a comp
ilation unit. |
| 3360 * | 3361 * |
| 3361 * @param initialHolder the element holder associated with the compilation uni
t being built | 3362 * @param initialHolder the element holder associated with the compilation uni
t being built |
| 3362 */ | 3363 */ |
| 3363 ElementBuilder(ElementHolder initialHolder) { | 3364 ElementBuilder(ElementHolder initialHolder) { |
| 3364 _currentHolder = initialHolder; | 3365 _currentHolder = initialHolder; |
| 3365 } | 3366 } |
| 3366 | 3367 |
| (...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3980 return null; | 3981 return null; |
| 3981 } | 3982 } |
| 3982 | 3983 |
| 3983 /** | 3984 /** |
| 3984 * Build the table mapping field names to field elements for the fields define
d in the current | 3985 * Build the table mapping field names to field elements for the fields define
d in the current |
| 3985 * class. | 3986 * class. |
| 3986 * | 3987 * |
| 3987 * @param fields the field elements defined in the current class | 3988 * @param fields the field elements defined in the current class |
| 3988 */ | 3989 */ |
| 3989 void _buildFieldMap(List<FieldElement> fields) { | 3990 void _buildFieldMap(List<FieldElement> fields) { |
| 3990 _fieldMap = new Map<String, FieldElement>(); | 3991 _fieldMap = new HashMap<String, FieldElement>(); |
| 3991 int count = fields.length; | 3992 int count = fields.length; |
| 3992 for (int i = 0; i < count; i++) { | 3993 for (int i = 0; i < count; i++) { |
| 3993 FieldElement field = fields[i]; | 3994 FieldElement field = fields[i]; |
| 3994 _fieldMap[field.name] = field; | 3995 _fieldMap[field.name] = field; |
| 3995 } | 3996 } |
| 3996 } | 3997 } |
| 3997 | 3998 |
| 3998 /** | 3999 /** |
| 3999 * Creates the [ConstructorElement]s array with the single default constructor
element. | 4000 * Creates the [ConstructorElement]s array with the single default constructor
element. |
| 4000 * | 4001 * |
| (...skipping 2432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6433 * | 6434 * |
| 6434 * @param reportError if `true` then compile-time error should be reported; if
`false` | 6435 * @param reportError if `true` then compile-time error should be reported; if
`false` |
| 6435 * then compile-time warning | 6436 * then compile-time warning |
| 6436 * @param argumentList the list of arguments being passed to the element | 6437 * @param argumentList the list of arguments being passed to the element |
| 6437 * @param parameters the of the function that will be invoked with the argumen
ts | 6438 * @param parameters the of the function that will be invoked with the argumen
ts |
| 6438 * @return the parameters that correspond to the arguments | 6439 * @return the parameters that correspond to the arguments |
| 6439 */ | 6440 */ |
| 6440 List<ParameterElement> _resolveArgumentsToParameters(bool reportError, Argumen
tList argumentList, List<ParameterElement> parameters) { | 6441 List<ParameterElement> _resolveArgumentsToParameters(bool reportError, Argumen
tList argumentList, List<ParameterElement> parameters) { |
| 6441 List<ParameterElement> requiredParameters = new List<ParameterElement>(); | 6442 List<ParameterElement> requiredParameters = new List<ParameterElement>(); |
| 6442 List<ParameterElement> positionalParameters = new List<ParameterElement>(); | 6443 List<ParameterElement> positionalParameters = new List<ParameterElement>(); |
| 6443 Map<String, ParameterElement> namedParameters = new Map<String, ParameterEle
ment>(); | 6444 HashMap<String, ParameterElement> namedParameters = new HashMap<String, Para
meterElement>(); |
| 6444 for (ParameterElement parameter in parameters) { | 6445 for (ParameterElement parameter in parameters) { |
| 6445 ParameterKind kind = parameter.parameterKind; | 6446 ParameterKind kind = parameter.parameterKind; |
| 6446 if (kind == ParameterKind.REQUIRED) { | 6447 if (kind == ParameterKind.REQUIRED) { |
| 6447 requiredParameters.add(parameter); | 6448 requiredParameters.add(parameter); |
| 6448 } else if (kind == ParameterKind.POSITIONAL) { | 6449 } else if (kind == ParameterKind.POSITIONAL) { |
| 6449 positionalParameters.add(parameter); | 6450 positionalParameters.add(parameter); |
| 6450 } else { | 6451 } else { |
| 6451 namedParameters[parameter.name] = parameter; | 6452 namedParameters[parameter.name] = parameter; |
| 6452 } | 6453 } |
| 6453 } | 6454 } |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6931 /** | 6932 /** |
| 6932 * The scope in which this scope is lexically enclosed. | 6933 * The scope in which this scope is lexically enclosed. |
| 6933 */ | 6934 */ |
| 6934 final Scope enclosingScope; | 6935 final Scope enclosingScope; |
| 6935 | 6936 |
| 6936 /** | 6937 /** |
| 6937 * A table mapping names that will be defined in this scope, but right now are
not initialized. | 6938 * A table mapping names that will be defined in this scope, but right now are
not initialized. |
| 6938 * According to the scoping rules these names are hidden, even if they were de
fined in an outer | 6939 * According to the scoping rules these names are hidden, even if they were de
fined in an outer |
| 6939 * scope. | 6940 * scope. |
| 6940 */ | 6941 */ |
| 6941 Map<String, Element> _hiddenElements = new Map<String, Element>(); | 6942 HashMap<String, Element> _hiddenElements = new HashMap<String, Element>(); |
| 6942 | 6943 |
| 6943 /** | 6944 /** |
| 6944 * A flag indicating whether there are any names defined in this scope. | 6945 * A flag indicating whether there are any names defined in this scope. |
| 6945 */ | 6946 */ |
| 6946 bool _hasHiddenName = false; | 6947 bool _hasHiddenName = false; |
| 6947 | 6948 |
| 6948 /** | 6949 /** |
| 6949 * Initialize a newly created scope enclosed within another scope. | 6950 * Initialize a newly created scope enclosed within another scope. |
| 6950 * | 6951 * |
| 6951 * @param enclosingScope the scope in which this scope is lexically enclosed | 6952 * @param enclosingScope the scope in which this scope is lexically enclosed |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7123 bool _isInFunctionTypedFormalParameter = false; | 7124 bool _isInFunctionTypedFormalParameter = false; |
| 7124 | 7125 |
| 7125 /** | 7126 /** |
| 7126 * This is set to `true` iff the visitor is currently visiting a static method
. By "method" | 7127 * This is set to `true` iff the visitor is currently visiting a static method
. By "method" |
| 7127 * here getter, setter and operator declarations are also implied since they a
re all represented | 7128 * here getter, setter and operator declarations are also implied since they a
re all represented |
| 7128 * with a [MethodDeclaration] in the AST structure. | 7129 * with a [MethodDeclaration] in the AST structure. |
| 7129 */ | 7130 */ |
| 7130 bool _isInStaticMethod = false; | 7131 bool _isInStaticMethod = false; |
| 7131 | 7132 |
| 7132 /** | 7133 /** |
| 7134 * This is set to `true` iff the visitor is currently visiting a factory const
ructor. |
| 7135 */ |
| 7136 bool _isInFactory = false; |
| 7137 |
| 7138 /** |
| 7133 * This is set to `true` iff the visitor is currently visiting code in the SDK
. | 7139 * This is set to `true` iff the visitor is currently visiting code in the SDK
. |
| 7134 */ | 7140 */ |
| 7135 bool _isInSystemLibrary = false; | 7141 bool _isInSystemLibrary = false; |
| 7136 | 7142 |
| 7137 /** | 7143 /** |
| 7138 * A flag indicating whether the current library contains at least one import
directive with a URI | 7144 * A flag indicating whether the current library contains at least one import
directive with a URI |
| 7139 * that uses the "dart-ext" scheme. | 7145 * that uses the "dart-ext" scheme. |
| 7140 */ | 7146 */ |
| 7141 bool _hasExtUri = false; | 7147 bool _hasExtUri = false; |
| 7142 | 7148 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7180 * When set the map maps the set of [FieldElement]s in the class to an | 7186 * When set the map maps the set of [FieldElement]s in the class to an |
| 7181 * [INIT_STATE#NOT_INIT] or [INIT_STATE#INIT_IN_DECLARATION]. <code>checkFor*<
/code> | 7187 * [INIT_STATE#NOT_INIT] or [INIT_STATE#INIT_IN_DECLARATION]. <code>checkFor*<
/code> |
| 7182 * methods, specifically [checkForAllFinalInitializedErrorCodes], | 7188 * methods, specifically [checkForAllFinalInitializedErrorCodes], |
| 7183 * can make a copy of the map to compute error code states. <code>checkFor*</c
ode> methods should | 7189 * can make a copy of the map to compute error code states. <code>checkFor*</c
ode> methods should |
| 7184 * only ever make a copy, or read from this map after it has been set in | 7190 * only ever make a copy, or read from this map after it has been set in |
| 7185 * [visitClassDeclaration]. | 7191 * [visitClassDeclaration]. |
| 7186 * | 7192 * |
| 7187 * @see #visitClassDeclaration(ClassDeclaration) | 7193 * @see #visitClassDeclaration(ClassDeclaration) |
| 7188 * @see #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration) | 7194 * @see #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration) |
| 7189 */ | 7195 */ |
| 7190 Map<FieldElement, INIT_STATE> _initialFieldElementsMap; | 7196 HashMap<FieldElement, INIT_STATE> _initialFieldElementsMap; |
| 7191 | 7197 |
| 7192 /** | 7198 /** |
| 7193 * A table mapping name of the library to the export directive which export th
is library. | 7199 * A table mapping name of the library to the export directive which export th
is library. |
| 7194 */ | 7200 */ |
| 7195 Map<String, LibraryElement> _nameToExportElement = new Map<String, LibraryElem
ent>(); | 7201 HashMap<String, LibraryElement> _nameToExportElement = new HashMap<String, Lib
raryElement>(); |
| 7196 | 7202 |
| 7197 /** | 7203 /** |
| 7198 * A table mapping name of the library to the import directive which import th
is library. | 7204 * A table mapping name of the library to the import directive which import th
is library. |
| 7199 */ | 7205 */ |
| 7200 Map<String, LibraryElement> _nameToImportElement = new Map<String, LibraryElem
ent>(); | 7206 HashMap<String, LibraryElement> _nameToImportElement = new HashMap<String, Lib
raryElement>(); |
| 7201 | 7207 |
| 7202 /** | 7208 /** |
| 7203 * A table mapping names to the exported elements. | 7209 * A table mapping names to the exported elements. |
| 7204 */ | 7210 */ |
| 7205 Map<String, Element> _exportedElements = new Map<String, Element>(); | 7211 HashMap<String, Element> _exportedElements = new HashMap<String, Element>(); |
| 7206 | 7212 |
| 7207 /** | 7213 /** |
| 7208 * A set of the names of the variable initializers we are visiting now. | 7214 * A set of the names of the variable initializers we are visiting now. |
| 7209 */ | 7215 */ |
| 7210 Set<String> _namesForReferenceToDeclaredVariableInInitializer = new Set<String
>(); | 7216 Set<String> _namesForReferenceToDeclaredVariableInInitializer = new Set<String
>(); |
| 7211 | 7217 |
| 7212 /** | 7218 /** |
| 7213 * A list of types used by the [CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS]
and | 7219 * A list of types used by the [CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS]
and |
| 7214 * [CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS] error codes. | 7220 * [CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS] error codes. |
| 7215 */ | 7221 */ |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7378 _checkForRecursiveInterfaceInheritance(_enclosingClass); | 7384 _checkForRecursiveInterfaceInheritance(_enclosingClass); |
| 7379 _checkForConflictingGetterAndMethod(); | 7385 _checkForConflictingGetterAndMethod(); |
| 7380 _checkForConflictingInstanceGetterAndSuperclassMember(); | 7386 _checkForConflictingInstanceGetterAndSuperclassMember(); |
| 7381 _checkImplementsSuperClass(node); | 7387 _checkImplementsSuperClass(node); |
| 7382 _checkImplementsFunctionWithoutCall(node); | 7388 _checkImplementsFunctionWithoutCall(node); |
| 7383 } | 7389 } |
| 7384 } | 7390 } |
| 7385 // initialize initialFieldElementsMap | 7391 // initialize initialFieldElementsMap |
| 7386 if (_enclosingClass != null) { | 7392 if (_enclosingClass != null) { |
| 7387 List<FieldElement> fieldElements = _enclosingClass.fields; | 7393 List<FieldElement> fieldElements = _enclosingClass.fields; |
| 7388 _initialFieldElementsMap = new Map<FieldElement, INIT_STATE>(); | 7394 _initialFieldElementsMap = new HashMap<FieldElement, INIT_STATE>(); |
| 7389 for (FieldElement fieldElement in fieldElements) { | 7395 for (FieldElement fieldElement in fieldElements) { |
| 7390 if (!fieldElement.isSynthetic) { | 7396 if (!fieldElement.isSynthetic) { |
| 7391 _initialFieldElementsMap[fieldElement] = fieldElement.initializer ==
null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; | 7397 _initialFieldElementsMap[fieldElement] = fieldElement.initializer ==
null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; |
| 7392 } | 7398 } |
| 7393 } | 7399 } |
| 7394 } | 7400 } |
| 7395 _checkForFinalNotInitializedInClass(node); | 7401 _checkForFinalNotInitializedInClass(node); |
| 7396 _checkForDuplicateDefinitionInheritance(); | 7402 _checkForDuplicateDefinitionInheritance(); |
| 7397 _checkForConflictingInstanceMethodSetter(node); | 7403 _checkForConflictingInstanceMethodSetter(node); |
| 7398 return super.visitClassDeclaration(node); | 7404 return super.visitClassDeclaration(node); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7446 return super.visitConditionalExpression(node); | 7452 return super.visitConditionalExpression(node); |
| 7447 } | 7453 } |
| 7448 | 7454 |
| 7449 @override | 7455 @override |
| 7450 Object visitConstructorDeclaration(ConstructorDeclaration node) { | 7456 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 7451 ExecutableElement outerFunction = _enclosingFunction; | 7457 ExecutableElement outerFunction = _enclosingFunction; |
| 7452 try { | 7458 try { |
| 7453 ConstructorElement constructorElement = node.element; | 7459 ConstructorElement constructorElement = node.element; |
| 7454 _enclosingFunction = constructorElement; | 7460 _enclosingFunction = constructorElement; |
| 7455 _isEnclosingConstructorConst = node.constKeyword != null; | 7461 _isEnclosingConstructorConst = node.constKeyword != null; |
| 7462 _isInFactory = node.factoryKeyword != null; |
| 7456 _checkForConstConstructorWithNonFinalField(node, constructorElement); | 7463 _checkForConstConstructorWithNonFinalField(node, constructorElement); |
| 7457 _checkForConstConstructorWithNonConstSuper(node); | 7464 _checkForConstConstructorWithNonConstSuper(node); |
| 7458 _checkForConflictingConstructorNameAndMember(node, constructorElement); | 7465 _checkForConflictingConstructorNameAndMember(node, constructorElement); |
| 7459 _checkForAllFinalInitializedErrorCodes(node); | 7466 _checkForAllFinalInitializedErrorCodes(node); |
| 7460 _checkForRedirectingConstructorErrorCodes(node); | 7467 _checkForRedirectingConstructorErrorCodes(node); |
| 7461 _checkForMultipleSuperInitializers(node); | 7468 _checkForMultipleSuperInitializers(node); |
| 7462 _checkForRecursiveConstructorRedirect(node, constructorElement); | 7469 _checkForRecursiveConstructorRedirect(node, constructorElement); |
| 7463 if (!_checkForRecursiveFactoryRedirect(node, constructorElement)) { | 7470 if (!_checkForRecursiveFactoryRedirect(node, constructorElement)) { |
| 7464 _checkForAllRedirectConstructorErrorCodes(node); | 7471 _checkForAllRedirectConstructorErrorCodes(node); |
| 7465 } | 7472 } |
| 7466 _checkForUndefinedConstructorInInitializerImplicit(node); | 7473 _checkForUndefinedConstructorInInitializerImplicit(node); |
| 7467 _checkForRedirectToNonConstConstructor(node, constructorElement); | 7474 _checkForRedirectToNonConstConstructor(node, constructorElement); |
| 7468 _checkForReturnInGenerativeConstructor(node); | 7475 _checkForReturnInGenerativeConstructor(node); |
| 7469 return super.visitConstructorDeclaration(node); | 7476 return super.visitConstructorDeclaration(node); |
| 7470 } finally { | 7477 } finally { |
| 7471 _isEnclosingConstructorConst = false; | 7478 _isEnclosingConstructorConst = false; |
| 7479 _isInFactory = false; |
| 7472 _enclosingFunction = outerFunction; | 7480 _enclosingFunction = outerFunction; |
| 7473 } | 7481 } |
| 7474 } | 7482 } |
| 7475 | 7483 |
| 7476 @override | 7484 @override |
| 7477 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { | 7485 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { |
| 7478 _isInConstructorInitializer = true; | 7486 _isInConstructorInitializer = true; |
| 7479 try { | 7487 try { |
| 7480 SimpleIdentifier fieldName = node.fieldName; | 7488 SimpleIdentifier fieldName = node.fieldName; |
| 7481 Element staticElement = fieldName.staticElement; | 7489 Element staticElement = fieldName.staticElement; |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8003 */ | 8011 */ |
| 8004 bool _checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) { | 8012 bool _checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) { |
| 8005 if (node.factoryKeyword != null || node.redirectedConstructor != null || nod
e.externalKeyword != null) { | 8013 if (node.factoryKeyword != null || node.redirectedConstructor != null || nod
e.externalKeyword != null) { |
| 8006 return false; | 8014 return false; |
| 8007 } | 8015 } |
| 8008 // Ignore if native class. | 8016 // Ignore if native class. |
| 8009 if (_isInNativeClass) { | 8017 if (_isInNativeClass) { |
| 8010 return false; | 8018 return false; |
| 8011 } | 8019 } |
| 8012 bool foundError = false; | 8020 bool foundError = false; |
| 8013 Map<FieldElement, INIT_STATE> fieldElementsMap = new Map<FieldElement, INIT_
STATE>.from(_initialFieldElementsMap); | 8021 HashMap<FieldElement, INIT_STATE> fieldElementsMap = new HashMap<FieldElemen
t, INIT_STATE>.from(_initialFieldElementsMap); |
| 8014 // Visit all of the field formal parameters | 8022 // Visit all of the field formal parameters |
| 8015 NodeList<FormalParameter> formalParameters = node.parameters.parameters; | 8023 NodeList<FormalParameter> formalParameters = node.parameters.parameters; |
| 8016 for (FormalParameter formalParameter in formalParameters) { | 8024 for (FormalParameter formalParameter in formalParameters) { |
| 8017 FormalParameter parameter = formalParameter; | 8025 FormalParameter parameter = formalParameter; |
| 8018 if (parameter is DefaultFormalParameter) { | 8026 if (parameter is DefaultFormalParameter) { |
| 8019 parameter = (parameter as DefaultFormalParameter).parameter; | 8027 parameter = (parameter as DefaultFormalParameter).parameter; |
| 8020 } | 8028 } |
| 8021 if (parameter is FieldFormalParameter) { | 8029 if (parameter is FieldFormalParameter) { |
| 8022 FieldElement fieldElement = (parameter.element as FieldFormalParameterEl
ementImpl).field; | 8030 FieldElement fieldElement = (parameter.element as FieldFormalParameterEl
ementImpl).field; |
| 8023 INIT_STATE state = fieldElementsMap[fieldElement]; | 8031 INIT_STATE state = fieldElementsMap[fieldElement]; |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8104 */ | 8112 */ |
| 8105 bool _checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement
, ExecutableElement overriddenExecutable, List<ParameterElement> parameters, Lis
t<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) { | 8113 bool _checkForAllInvalidOverrideErrorCodes(ExecutableElement executableElement
, ExecutableElement overriddenExecutable, List<ParameterElement> parameters, Lis
t<AstNode> parameterLocations, SimpleIdentifier errorNameTarget) { |
| 8106 bool isGetter = false; | 8114 bool isGetter = false; |
| 8107 bool isSetter = false; | 8115 bool isSetter = false; |
| 8108 if (executableElement is PropertyAccessorElement) { | 8116 if (executableElement is PropertyAccessorElement) { |
| 8109 PropertyAccessorElement accessorElement = executableElement; | 8117 PropertyAccessorElement accessorElement = executableElement; |
| 8110 isGetter = accessorElement.isGetter; | 8118 isGetter = accessorElement.isGetter; |
| 8111 isSetter = accessorElement.isSetter; | 8119 isSetter = accessorElement.isSetter; |
| 8112 } | 8120 } |
| 8113 String executableElementName = executableElement.name; | 8121 String executableElementName = executableElement.name; |
| 8114 // SWC.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC | |
| 8115 if (overriddenExecutable == null) { | |
| 8116 if (!isGetter && !isSetter && !executableElement.isOperator) { | |
| 8117 Set<ClassElement> visitedClasses = new Set<ClassElement>(); | |
| 8118 InterfaceType superclassType = _enclosingClass.supertype; | |
| 8119 ClassElement superclassElement = superclassType == null ? null : supercl
assType.element; | |
| 8120 bool executableElementPrivate = Identifier.isPrivateName(executableEleme
ntName); | |
| 8121 while (superclassElement != null && !visitedClasses.contains(superclassE
lement)) { | |
| 8122 visitedClasses.add(superclassElement); | |
| 8123 LibraryElement superclassLibrary = superclassElement.library; | |
| 8124 // Check fields. | |
| 8125 List<FieldElement> fieldElts = superclassElement.fields; | |
| 8126 for (FieldElement fieldElt in fieldElts) { | |
| 8127 // We need the same name. | |
| 8128 if (fieldElt.name != executableElementName) { | |
| 8129 continue; | |
| 8130 } | |
| 8131 // Ignore if private in a different library - cannot collide. | |
| 8132 if (executableElementPrivate && _currentLibrary != superclassLibrary
) { | |
| 8133 continue; | |
| 8134 } | |
| 8135 // instance vs. static | |
| 8136 if (fieldElt.isStatic) { | |
| 8137 _errorReporter.reportErrorForNode(StaticWarningCode.INSTANCE_METHO
D_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [ | |
| 8138 executableElementName, | |
| 8139 fieldElt.enclosingElement.displayName]); | |
| 8140 return true; | |
| 8141 } | |
| 8142 } | |
| 8143 // Check methods. | |
| 8144 List<MethodElement> methodElements = superclassElement.methods; | |
| 8145 for (MethodElement methodElement in methodElements) { | |
| 8146 // We need the same name. | |
| 8147 if (methodElement.name != executableElementName) { | |
| 8148 continue; | |
| 8149 } | |
| 8150 // Ignore if private in a different library - cannot collide. | |
| 8151 if (executableElementPrivate && _currentLibrary != superclassLibrary
) { | |
| 8152 continue; | |
| 8153 } | |
| 8154 // instance vs. static | |
| 8155 if (methodElement.isStatic) { | |
| 8156 _errorReporter.reportErrorForNode(StaticWarningCode.INSTANCE_METHO
D_NAME_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [ | |
| 8157 executableElementName, | |
| 8158 methodElement.enclosingElement.displayName]); | |
| 8159 return true; | |
| 8160 } | |
| 8161 } | |
| 8162 superclassType = superclassElement.supertype; | |
| 8163 superclassElement = superclassType == null ? null : superclassType.ele
ment; | |
| 8164 } | |
| 8165 } | |
| 8166 return false; | |
| 8167 } | |
| 8168 FunctionType overridingFT = executableElement.type; | 8122 FunctionType overridingFT = executableElement.type; |
| 8169 FunctionType overriddenFT = overriddenExecutable.type; | 8123 FunctionType overriddenFT = overriddenExecutable.type; |
| 8170 InterfaceType enclosingType = _enclosingClass.type; | 8124 InterfaceType enclosingType = _enclosingClass.type; |
| 8171 overriddenFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheri
tance(overriddenFT, executableElementName, enclosingType); | 8125 overriddenFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheri
tance(overriddenFT, executableElementName, enclosingType); |
| 8172 if (overridingFT == null || overriddenFT == null) { | 8126 if (overridingFT == null || overriddenFT == null) { |
| 8173 return false; | 8127 return false; |
| 8174 } | 8128 } |
| 8175 DartType overridingFTReturnType = overridingFT.returnType; | 8129 DartType overridingFTReturnType = overridingFT.returnType; |
| 8176 DartType overriddenFTReturnType = overriddenFT.returnType; | 8130 DartType overriddenFTReturnType = overriddenFT.returnType; |
| 8177 List<DartType> overridingNormalPT = overridingFT.normalParameterTypes; | 8131 List<DartType> overridingNormalPT = overridingFT.normalParameterTypes; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 8203 // The overridden method expected the overriding method to have overridi
ngParamName, | 8157 // The overridden method expected the overriding method to have overridi
ngParamName, |
| 8204 // but it does not. | 8158 // but it does not. |
| 8205 _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVERRIDE_NAM
ED, errorNameTarget, [ | 8159 _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_OVERRIDE_NAM
ED, errorNameTarget, [ |
| 8206 overriddenParamName, | 8160 overriddenParamName, |
| 8207 overriddenExecutable.enclosingElement.displayName]); | 8161 overriddenExecutable.enclosingElement.displayName]); |
| 8208 return true; | 8162 return true; |
| 8209 } | 8163 } |
| 8210 } | 8164 } |
| 8211 // SWC.INVALID_METHOD_OVERRIDE_RETURN_TYPE | 8165 // SWC.INVALID_METHOD_OVERRIDE_RETURN_TYPE |
| 8212 if (overriddenFTReturnType != VoidTypeImpl.instance && !overridingFTReturnTy
pe.isAssignableTo(overriddenFTReturnType)) { | 8166 if (overriddenFTReturnType != VoidTypeImpl.instance && !overridingFTReturnTy
pe.isAssignableTo(overriddenFTReturnType)) { |
| 8213 _errorReporter.reportErrorForNode(!isGetter ? StaticWarningCode.INVALID_ME
THOD_OVERRIDE_RETURN_TYPE : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYP
E, errorNameTarget, [ | 8167 _errorReporter.reportTypeErrorForNode(!isGetter ? StaticWarningCode.INVALI
D_METHOD_OVERRIDE_RETURN_TYPE : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN
_TYPE, errorNameTarget, [ |
| 8214 overridingFTReturnType.displayName, | 8168 overridingFTReturnType, |
| 8215 overriddenFTReturnType.displayName, | 8169 overriddenFTReturnType, |
| 8216 overriddenExecutable.enclosingElement.displayName]); | 8170 overriddenExecutable.enclosingElement.displayName]); |
| 8217 return true; | 8171 return true; |
| 8218 } | 8172 } |
| 8219 // SWC.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE | 8173 // SWC.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE |
| 8220 if (parameterLocations == null) { | 8174 if (parameterLocations == null) { |
| 8221 return false; | 8175 return false; |
| 8222 } | 8176 } |
| 8223 int parameterIndex = 0; | 8177 int parameterIndex = 0; |
| 8224 for (int i = 0; i < overridingNormalPT.length; i++) { | 8178 for (int i = 0; i < overridingNormalPT.length; i++) { |
| 8225 if (!overridingNormalPT[i].isAssignableTo(overriddenNormalPT[i])) { | 8179 if (!overridingNormalPT[i].isAssignableTo(overriddenNormalPT[i])) { |
| 8226 _errorReporter.reportErrorForNode(!isSetter ? StaticWarningCode.INVALID_
METHOD_OVERRIDE_NORMAL_PARAM_TYPE : StaticWarningCode.INVALID_SETTER_OVERRIDE_NO
RMAL_PARAM_TYPE, parameterLocations[parameterIndex], [ | 8180 _errorReporter.reportTypeErrorForNode(!isSetter ? StaticWarningCode.INVA
LID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE : StaticWarningCode.INVALID_SETTER_OVERRID
E_NORMAL_PARAM_TYPE, parameterLocations[parameterIndex], [ |
| 8227 overridingNormalPT[i].displayName, | 8181 overridingNormalPT[i], |
| 8228 overriddenNormalPT[i].displayName, | 8182 overriddenNormalPT[i], |
| 8229 overriddenExecutable.enclosingElement.displayName]); | 8183 overriddenExecutable.enclosingElement.displayName]); |
| 8230 return true; | 8184 return true; |
| 8231 } | 8185 } |
| 8232 parameterIndex++; | 8186 parameterIndex++; |
| 8233 } | 8187 } |
| 8234 // SWC.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE | 8188 // SWC.INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE |
| 8235 for (int i = 0; i < overriddenPositionalPT.length; i++) { | 8189 for (int i = 0; i < overriddenPositionalPT.length; i++) { |
| 8236 if (!overridingPositionalPT[i].isAssignableTo(overriddenPositionalPT[i]))
{ | 8190 if (!overridingPositionalPT[i].isAssignableTo(overriddenPositionalPT[i]))
{ |
| 8237 _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_METHOD_OVERR
IDE_OPTIONAL_PARAM_TYPE, parameterLocations[parameterIndex], [ | 8191 _errorReporter.reportTypeErrorForNode(StaticWarningCode.INVALID_METHOD_O
VERRIDE_OPTIONAL_PARAM_TYPE, parameterLocations[parameterIndex], [ |
| 8238 overridingPositionalPT[i].displayName, | 8192 overridingPositionalPT[i], |
| 8239 overriddenPositionalPT[i].displayName, | 8193 overriddenPositionalPT[i], |
| 8240 overriddenExecutable.enclosingElement.displayName]); | 8194 overriddenExecutable.enclosingElement.displayName]); |
| 8241 return true; | 8195 return true; |
| 8242 } | 8196 } |
| 8243 parameterIndex++; | 8197 parameterIndex++; |
| 8244 } | 8198 } |
| 8245 // SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE & SWC.INVALID_OVERRIDE_DIFFE
RENT_DEFAULT_VALUES | 8199 // SWC.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE & SWC.INVALID_OVERRIDE_DIFFE
RENT_DEFAULT_VALUES |
| 8246 JavaIterator<MapEntry<String, DartType>> overriddenNamedPTIterator = new Jav
aIterator(getMapEntrySet(overriddenNamedPT)); | 8200 JavaIterator<MapEntry<String, DartType>> overriddenNamedPTIterator = new Jav
aIterator(getMapEntrySet(overriddenNamedPT)); |
| 8247 while (overriddenNamedPTIterator.hasNext) { | 8201 while (overriddenNamedPTIterator.hasNext) { |
| 8248 MapEntry<String, DartType> overriddenNamedPTEntry = overriddenNamedPTItera
tor.next(); | 8202 MapEntry<String, DartType> overriddenNamedPTEntry = overriddenNamedPTItera
tor.next(); |
| 8249 DartType overridingType = overridingNamedPT[overriddenNamedPTEntry.getKey(
)]; | 8203 DartType overridingType = overridingNamedPT[overriddenNamedPTEntry.getKey(
)]; |
| 8250 if (overridingType == null) { | 8204 if (overridingType == null) { |
| 8251 // Error, this is never reached- INVALID_OVERRIDE_NAMED would have been
created above if | 8205 // Error, this is never reached- INVALID_OVERRIDE_NAMED would have been
created above if |
| 8252 // this could be reached. | 8206 // this could be reached. |
| 8253 continue; | 8207 continue; |
| 8254 } | 8208 } |
| 8255 if (!overriddenNamedPTEntry.getValue().isAssignableTo(overridingType)) { | 8209 if (!overriddenNamedPTEntry.getValue().isAssignableTo(overridingType)) { |
| 8256 // lookup the parameter for the error to select | 8210 // lookup the parameter for the error to select |
| 8257 ParameterElement parameterToSelect = null; | 8211 ParameterElement parameterToSelect = null; |
| 8258 AstNode parameterLocationToSelect = null; | 8212 AstNode parameterLocationToSelect = null; |
| 8259 for (int i = 0; i < parameters.length; i++) { | 8213 for (int i = 0; i < parameters.length; i++) { |
| 8260 ParameterElement parameter = parameters[i]; | 8214 ParameterElement parameter = parameters[i]; |
| 8261 if (parameter.parameterKind == ParameterKind.NAMED && overriddenNamedP
TEntry.getKey() == parameter.name) { | 8215 if (parameter.parameterKind == ParameterKind.NAMED && overriddenNamedP
TEntry.getKey() == parameter.name) { |
| 8262 parameterToSelect = parameter; | 8216 parameterToSelect = parameter; |
| 8263 parameterLocationToSelect = parameterLocations[i]; | 8217 parameterLocationToSelect = parameterLocations[i]; |
| 8264 break; | 8218 break; |
| 8265 } | 8219 } |
| 8266 } | 8220 } |
| 8267 if (parameterToSelect != null) { | 8221 if (parameterToSelect != null) { |
| 8268 _errorReporter.reportErrorForNode(StaticWarningCode.INVALID_METHOD_OVE
RRIDE_NAMED_PARAM_TYPE, parameterLocationToSelect, [ | 8222 _errorReporter.reportTypeErrorForNode(StaticWarningCode.INVALID_METHOD
_OVERRIDE_NAMED_PARAM_TYPE, parameterLocationToSelect, [ |
| 8269 overridingType.displayName, | 8223 overridingType, |
| 8270 overriddenNamedPTEntry.getValue().displayName, | 8224 overriddenNamedPTEntry.getValue(), |
| 8271 overriddenExecutable.enclosingElement.displayName]); | 8225 overriddenExecutable.enclosingElement.displayName]); |
| 8272 return true; | 8226 return true; |
| 8273 } | 8227 } |
| 8274 } | 8228 } |
| 8275 } | 8229 } |
| 8276 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES | 8230 // SWC.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES |
| 8277 // | 8231 // |
| 8278 // Create three arrays: an array of the optional parameter ASTs (FormalParam
eters), an array of | 8232 // Create three arrays: an array of the optional parameter ASTs (FormalParam
eters), an array of |
| 8279 // the optional parameters elements from our method, and finally an array of
the optional | 8233 // the optional parameters elements from our method, and finally an array of
the optional |
| 8280 // parameter elements from the method we are overriding. | 8234 // parameter elements from the method we are overriding. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8366 * | 8320 * |
| 8367 * @param executableElement a non-null [ExecutableElement] to evaluate | 8321 * @param executableElement a non-null [ExecutableElement] to evaluate |
| 8368 * @param parameters the parameters of the executable element | 8322 * @param parameters the parameters of the executable element |
| 8369 * @param errorNameTarget the node to report problems on | 8323 * @param errorNameTarget the node to report problems on |
| 8370 * @return `true` if and only if an error code is generated on the passed node | 8324 * @return `true` if and only if an error code is generated on the passed node |
| 8371 */ | 8325 */ |
| 8372 bool _checkForAllInvalidOverrideErrorCodesForExecutable(ExecutableElement exec
utableElement, List<ParameterElement> parameters, List<AstNode> parameterLocatio
ns, SimpleIdentifier errorNameTarget) { | 8326 bool _checkForAllInvalidOverrideErrorCodesForExecutable(ExecutableElement exec
utableElement, List<ParameterElement> parameters, List<AstNode> parameterLocatio
ns, SimpleIdentifier errorNameTarget) { |
| 8373 // | 8327 // |
| 8374 // Compute the overridden executable from the InheritanceManager | 8328 // Compute the overridden executable from the InheritanceManager |
| 8375 // | 8329 // |
| 8376 ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritan
ce(_enclosingClass, executableElement.name); | 8330 List<ExecutableElement> overriddenExecutables = _inheritanceManager.lookupOv
errides(_enclosingClass, executableElement.name); |
| 8377 // | 8331 if (overriddenExecutables.isEmpty) { |
| 8378 // If the result is a MultiplyInheritedExecutableElement call | 8332 // Nothing is overridden, so we just have to check if the new name collide
s |
| 8379 // checkForAllInvalidOverrideErrorCodes on all of the elements, until an err
or is found. | 8333 // with a static defined in the superclass. |
| 8380 // | 8334 // TODO(paulberry): currently we don't do this check if the new element |
| 8381 if (overriddenExecutable is MultiplyInheritedExecutableElement) { | 8335 // overrides a method in an interface (see issue 18947). |
| 8382 MultiplyInheritedExecutableElement multiplyInheritedElement = overriddenEx
ecutable; | 8336 return _checkForInstanceMethodNameCollidesWithSuperclassStatic(executableE
lement, errorNameTarget); |
| 8383 List<ExecutableElement> overriddenElement = multiplyInheritedElement.inher
itedElements; | 8337 } |
| 8384 for (int i = 0; i < overriddenElement.length; i++) { | 8338 for (ExecutableElement overriddenElement in overriddenExecutables) { |
| 8385 if (_checkForAllInvalidOverrideErrorCodes(executableElement, overriddenE
lement[i], parameters, parameterLocations, errorNameTarget)) { | 8339 if (_checkForAllInvalidOverrideErrorCodes(executableElement, overriddenEle
ment, parameters, parameterLocations, errorNameTarget)) { |
| 8386 return true; | 8340 return true; |
| 8387 } | |
| 8388 } | 8341 } |
| 8389 return false; | |
| 8390 } | 8342 } |
| 8391 // | 8343 return false; |
| 8392 // Otherwise, just call checkForAllInvalidOverrideErrorCodes. | |
| 8393 // | |
| 8394 return _checkForAllInvalidOverrideErrorCodes(executableElement, overriddenEx
ecutable, parameters, parameterLocations, errorNameTarget); | |
| 8395 } | 8344 } |
| 8396 | 8345 |
| 8397 /** | 8346 /** |
| 8398 * This checks the passed field declaration against override-error codes. | 8347 * This checks the passed field declaration against override-error codes. |
| 8399 * | 8348 * |
| 8400 * @param node the [MethodDeclaration] to evaluate | 8349 * @param node the [MethodDeclaration] to evaluate |
| 8401 * @return `true` if and only if an error code is generated on the passed node | 8350 * @return `true` if and only if an error code is generated on the passed node |
| 8402 * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement) | 8351 * @see #checkForAllInvalidOverrideErrorCodes(ExecutableElement) |
| 8403 */ | 8352 */ |
| 8404 bool _checkForAllInvalidOverrideErrorCodesForField(FieldDeclaration node) { | 8353 bool _checkForAllInvalidOverrideErrorCodesForField(FieldDeclaration node) { |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8641 * @see CompileTimeErrorCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE | 8590 * @see CompileTimeErrorCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE |
| 8642 * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE | 8591 * @see StaticWarningCode#MAP_KEY_TYPE_NOT_ASSIGNABLE |
| 8643 * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE | 8592 * @see StaticWarningCode#MAP_VALUE_TYPE_NOT_ASSIGNABLE |
| 8644 */ | 8593 */ |
| 8645 bool _checkForArgumentTypeNotAssignable(Expression expression, DartType expect
edStaticType, DartType actualStaticType, ErrorCode errorCode) { | 8594 bool _checkForArgumentTypeNotAssignable(Expression expression, DartType expect
edStaticType, DartType actualStaticType, ErrorCode errorCode) { |
| 8646 // | 8595 // |
| 8647 // Warning case: test static type information | 8596 // Warning case: test static type information |
| 8648 // | 8597 // |
| 8649 if (actualStaticType != null && expectedStaticType != null) { | 8598 if (actualStaticType != null && expectedStaticType != null) { |
| 8650 if (!actualStaticType.isAssignableTo(expectedStaticType)) { | 8599 if (!actualStaticType.isAssignableTo(expectedStaticType)) { |
| 8651 _errorReporter.reportErrorForNode(errorCode, expression, [ | 8600 _errorReporter.reportTypeErrorForNode(errorCode, expression, [actualStat
icType, expectedStaticType]); |
| 8652 actualStaticType.displayName, | |
| 8653 expectedStaticType.displayName]); | |
| 8654 return true; | 8601 return true; |
| 8655 } | 8602 } |
| 8656 } | 8603 } |
| 8657 return false; | 8604 return false; |
| 8658 } | 8605 } |
| 8659 | 8606 |
| 8660 /** | 8607 /** |
| 8661 * This verifies that the passed argument can be assigned to its corresponding
parameter. | 8608 * This verifies that the passed argument can be assigned to its corresponding
parameter. |
| 8662 * | 8609 * |
| 8663 * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAss
ignableForArgument. | 8610 * This method corresponds to BestPracticesVerifier.checkForArgumentTypeNotAss
ignableForArgument. |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9080 bool _checkForConflictingInstanceMethodSetter(ClassDeclaration node) { | 9027 bool _checkForConflictingInstanceMethodSetter(ClassDeclaration node) { |
| 9081 // Reference all of the class members in this class. | 9028 // Reference all of the class members in this class. |
| 9082 NodeList<ClassMember> classMembers = node.members; | 9029 NodeList<ClassMember> classMembers = node.members; |
| 9083 if (classMembers.isEmpty) { | 9030 if (classMembers.isEmpty) { |
| 9084 return false; | 9031 return false; |
| 9085 } | 9032 } |
| 9086 // Create a HashMap to track conflicting members, and then loop through memb
ers in the class to | 9033 // Create a HashMap to track conflicting members, and then loop through memb
ers in the class to |
| 9087 // construct the HashMap, at the same time, look for violations. Don't add
members if they are | 9034 // construct the HashMap, at the same time, look for violations. Don't add
members if they are |
| 9088 // part of a conflict, this prevents multiple warnings for one issue. | 9035 // part of a conflict, this prevents multiple warnings for one issue. |
| 9089 bool foundError = false; | 9036 bool foundError = false; |
| 9090 Map<String, ClassMember> memberHashMap = new Map<String, ClassMember>(); | 9037 HashMap<String, ClassMember> memberHashMap = new HashMap<String, ClassMember
>(); |
| 9091 for (ClassMember classMember in classMembers) { | 9038 for (ClassMember classMember in classMembers) { |
| 9092 if (classMember is MethodDeclaration) { | 9039 if (classMember is MethodDeclaration) { |
| 9093 MethodDeclaration method = classMember; | 9040 MethodDeclaration method = classMember; |
| 9094 if (method.isStatic) { | 9041 if (method.isStatic) { |
| 9095 continue; | 9042 continue; |
| 9096 } | 9043 } |
| 9097 // prepare name | 9044 // prepare name |
| 9098 SimpleIdentifier name = method.name; | 9045 SimpleIdentifier name = method.name; |
| 9099 if (name == null) { | 9046 if (name == null) { |
| 9100 continue; | 9047 continue; |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9546 * | 9493 * |
| 9547 * @param node the compilation unit containing the imports to be checked | 9494 * @param node the compilation unit containing the imports to be checked |
| 9548 * @return `true` if an error was generated | 9495 * @return `true` if an error was generated |
| 9549 * @see CompileTimeErrorCode#SHARED_DEFERRED_PREFIX | 9496 * @see CompileTimeErrorCode#SHARED_DEFERRED_PREFIX |
| 9550 */ | 9497 */ |
| 9551 bool _checkForDeferredPrefixCollisions(CompilationUnit node) { | 9498 bool _checkForDeferredPrefixCollisions(CompilationUnit node) { |
| 9552 bool foundError = false; | 9499 bool foundError = false; |
| 9553 NodeList<Directive> directives = node.directives; | 9500 NodeList<Directive> directives = node.directives; |
| 9554 int count = directives.length; | 9501 int count = directives.length; |
| 9555 if (count > 0) { | 9502 if (count > 0) { |
| 9556 Map<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = new Map<
PrefixElement, List<ImportDirective>>(); | 9503 HashMap<PrefixElement, List<ImportDirective>> prefixToDirectivesMap = new
HashMap<PrefixElement, List<ImportDirective>>(); |
| 9557 for (int i = 0; i < count; i++) { | 9504 for (int i = 0; i < count; i++) { |
| 9558 Directive directive = directives[i]; | 9505 Directive directive = directives[i]; |
| 9559 if (directive is ImportDirective) { | 9506 if (directive is ImportDirective) { |
| 9560 ImportDirective importDirective = directive; | 9507 ImportDirective importDirective = directive; |
| 9561 SimpleIdentifier prefix = importDirective.prefix; | 9508 SimpleIdentifier prefix = importDirective.prefix; |
| 9562 if (prefix != null) { | 9509 if (prefix != null) { |
| 9563 Element element = prefix.staticElement; | 9510 Element element = prefix.staticElement; |
| 9564 if (element is PrefixElement) { | 9511 if (element is PrefixElement) { |
| 9565 PrefixElement prefixElement = element; | 9512 PrefixElement prefixElement = element; |
| 9566 List<ImportDirective> elements = prefixToDirectivesMap[prefixEleme
nt]; | 9513 List<ImportDirective> elements = prefixToDirectivesMap[prefixEleme
nt]; |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9879 // test the static type of the expression | 9826 // test the static type of the expression |
| 9880 DartType staticType = getStaticType(expression); | 9827 DartType staticType = getStaticType(expression); |
| 9881 if (staticType == null) { | 9828 if (staticType == null) { |
| 9882 return false; | 9829 return false; |
| 9883 } | 9830 } |
| 9884 if (staticType.isAssignableTo(fieldType)) { | 9831 if (staticType.isAssignableTo(fieldType)) { |
| 9885 return false; | 9832 return false; |
| 9886 } | 9833 } |
| 9887 // report problem | 9834 // report problem |
| 9888 if (_isEnclosingConstructorConst) { | 9835 if (_isEnclosingConstructorConst) { |
| 9889 _errorReporter.reportErrorForNode(CompileTimeErrorCode.CONST_FIELD_INITIAL
IZER_NOT_ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]
); | 9836 _errorReporter.reportTypeErrorForNode(CompileTimeErrorCode.CONST_FIELD_INI
TIALIZER_NOT_ASSIGNABLE, expression, [staticType, fieldType]); |
| 9890 } else { | 9837 } else { |
| 9891 _errorReporter.reportErrorForNode(StaticWarningCode.FIELD_INITIALIZER_NOT_
ASSIGNABLE, expression, [staticType.displayName, fieldType.displayName]); | 9838 _errorReporter.reportTypeErrorForNode(StaticWarningCode.FIELD_INITIALIZER_
NOT_ASSIGNABLE, expression, [staticType, fieldType]); |
| 9892 } | 9839 } |
| 9893 return true; | 9840 return true; |
| 9894 } | 9841 } |
| 9895 | 9842 |
| 9896 /** | 9843 /** |
| 9897 * This verifies that the passed field formal parameter is in a constructor de
claration. | 9844 * This verifies that the passed field formal parameter is in a constructor de
claration. |
| 9898 * | 9845 * |
| 9899 * @param node the field formal parameter to test | 9846 * @param node the field formal parameter to test |
| 9900 * @return `true` if and only if an error code is generated on the passed node | 9847 * @return `true` if and only if an error code is generated on the passed node |
| 9901 * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR | 9848 * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10022 /** | 9969 /** |
| 10023 * This verifies that if the passed identifier is part of constructor initiali
zer, then it does | 9970 * This verifies that if the passed identifier is part of constructor initiali
zer, then it does |
| 10024 * not reference implicitly 'this' expression. | 9971 * not reference implicitly 'this' expression. |
| 10025 * | 9972 * |
| 10026 * @param node the simple identifier to test | 9973 * @param node the simple identifier to test |
| 10027 * @return `true` if and only if an error code is generated on the passed node | 9974 * @return `true` if and only if an error code is generated on the passed node |
| 10028 * @see CompileTimeErrorCode#IMPLICIT_THIS_REFERENCE_IN_INITIALIZER | 9975 * @see CompileTimeErrorCode#IMPLICIT_THIS_REFERENCE_IN_INITIALIZER |
| 10029 * @see CompileTimeErrorCode#INSTANCE_MEMBER_ACCESS_FROM_STATIC TODO(scheglov)
rename thid method | 9976 * @see CompileTimeErrorCode#INSTANCE_MEMBER_ACCESS_FROM_STATIC TODO(scheglov)
rename thid method |
| 10030 */ | 9977 */ |
| 10031 bool _checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) { | 9978 bool _checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) { |
| 10032 if (!_isInConstructorInitializer && !_isInStaticMethod && !_isInInstanceVari
ableInitializer && !_isInStaticVariableDeclaration) { | 9979 if (!_isInConstructorInitializer && !_isInStaticMethod && !_isInFactory && !
_isInInstanceVariableInitializer && !_isInStaticVariableDeclaration) { |
| 10033 return false; | 9980 return false; |
| 10034 } | 9981 } |
| 10035 // prepare element | 9982 // prepare element |
| 10036 Element element = node.staticElement; | 9983 Element element = node.staticElement; |
| 10037 if (!(element is MethodElement || element is PropertyAccessorElement)) { | 9984 if (!(element is MethodElement || element is PropertyAccessorElement)) { |
| 10038 return false; | 9985 return false; |
| 10039 } | 9986 } |
| 10040 // static element | 9987 // static element |
| 10041 ExecutableElement executableElement = element as ExecutableElement; | 9988 ExecutableElement executableElement = element as ExecutableElement; |
| 10042 if (executableElement.isStatic) { | 9989 if (executableElement.isStatic) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 10068 } | 10015 } |
| 10069 if (parent is PrefixedIdentifier) { | 10016 if (parent is PrefixedIdentifier) { |
| 10070 PrefixedIdentifier prefixed = parent; | 10017 PrefixedIdentifier prefixed = parent; |
| 10071 if (identical(prefixed.identifier, node)) { | 10018 if (identical(prefixed.identifier, node)) { |
| 10072 return false; | 10019 return false; |
| 10073 } | 10020 } |
| 10074 } | 10021 } |
| 10075 // report problem | 10022 // report problem |
| 10076 if (_isInStaticMethod) { | 10023 if (_isInStaticMethod) { |
| 10077 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INSTANCE_MEMBER_ACC
ESS_FROM_STATIC, node, []); | 10024 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INSTANCE_MEMBER_ACC
ESS_FROM_STATIC, node, []); |
| 10025 } else if (_isInFactory) { |
| 10026 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INSTANCE_MEMBER_ACC
ESS_FROM_FACTORY, node, []); |
| 10078 } else { | 10027 } else { |
| 10079 _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPLICIT_THIS_REFER
ENCE_IN_INITIALIZER, node, []); | 10028 _errorReporter.reportErrorForNode(CompileTimeErrorCode.IMPLICIT_THIS_REFER
ENCE_IN_INITIALIZER, node, []); |
| 10080 } | 10029 } |
| 10081 return true; | 10030 return true; |
| 10082 } | 10031 } |
| 10083 | 10032 |
| 10084 /** | 10033 /** |
| 10085 * This verifies the passed import has unique name among other imported librar
ies. | 10034 * This verifies the passed import has unique name among other imported librar
ies. |
| 10086 * | 10035 * |
| 10087 * @param node the import directive to evaluate | 10036 * @param node the import directive to evaluate |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10197 // OK, instance member | 10146 // OK, instance member |
| 10198 if (!executableElement.isStatic) { | 10147 if (!executableElement.isStatic) { |
| 10199 return false; | 10148 return false; |
| 10200 } | 10149 } |
| 10201 // report problem | 10150 // report problem |
| 10202 _errorReporter.reportErrorForNode(StaticTypeWarningCode.INSTANCE_ACCESS_TO_S
TATIC_MEMBER, name, [name.name]); | 10151 _errorReporter.reportErrorForNode(StaticTypeWarningCode.INSTANCE_ACCESS_TO_S
TATIC_MEMBER, name, [name.name]); |
| 10203 return true; | 10152 return true; |
| 10204 } | 10153 } |
| 10205 | 10154 |
| 10206 /** | 10155 /** |
| 10156 * This checks whether the given [executableElement] collides with the name of
a static |
| 10157 * method in one of its superclasses, and reports the appropriate warning if i
t does. |
| 10158 * |
| 10159 * @param executableElement the method to check. |
| 10160 * @param errorNameTarget the node to report problems on. |
| 10161 * @return `true` if and only if a warning was generated. |
| 10162 * @see StaticTypeWarningCode#INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_ST
ATIC |
| 10163 */ |
| 10164 bool _checkForInstanceMethodNameCollidesWithSuperclassStatic(ExecutableElement
executableElement, SimpleIdentifier errorNameTarget) { |
| 10165 String executableElementName = executableElement.name; |
| 10166 if (executableElement is! PropertyAccessorElement && !executableElement.isOp
erator) { |
| 10167 Set<ClassElement> visitedClasses = new Set<ClassElement>(); |
| 10168 InterfaceType superclassType = _enclosingClass.supertype; |
| 10169 ClassElement superclassElement = superclassType == null ? null : superclas
sType.element; |
| 10170 bool executableElementPrivate = Identifier.isPrivateName(executableElement
Name); |
| 10171 while (superclassElement != null && !visitedClasses.contains(superclassEle
ment)) { |
| 10172 visitedClasses.add(superclassElement); |
| 10173 LibraryElement superclassLibrary = superclassElement.library; |
| 10174 // Check fields. |
| 10175 List<FieldElement> fieldElts = superclassElement.fields; |
| 10176 for (FieldElement fieldElt in fieldElts) { |
| 10177 // We need the same name. |
| 10178 if (fieldElt.name != executableElementName) { |
| 10179 continue; |
| 10180 } |
| 10181 // Ignore if private in a different library - cannot collide. |
| 10182 if (executableElementPrivate && _currentLibrary != superclassLibrary)
{ |
| 10183 continue; |
| 10184 } |
| 10185 // instance vs. static |
| 10186 if (fieldElt.isStatic) { |
| 10187 _errorReporter.reportErrorForNode(StaticWarningCode.INSTANCE_METHOD_
NAME_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [ |
| 10188 executableElementName, |
| 10189 fieldElt.enclosingElement.displayName]); |
| 10190 return true; |
| 10191 } |
| 10192 } |
| 10193 // Check methods. |
| 10194 List<MethodElement> methodElements = superclassElement.methods; |
| 10195 for (MethodElement methodElement in methodElements) { |
| 10196 // We need the same name. |
| 10197 if (methodElement.name != executableElementName) { |
| 10198 continue; |
| 10199 } |
| 10200 // Ignore if private in a different library - cannot collide. |
| 10201 if (executableElementPrivate && _currentLibrary != superclassLibrary)
{ |
| 10202 continue; |
| 10203 } |
| 10204 // instance vs. static |
| 10205 if (methodElement.isStatic) { |
| 10206 _errorReporter.reportErrorForNode(StaticWarningCode.INSTANCE_METHOD_
NAME_COLLIDES_WITH_SUPERCLASS_STATIC, errorNameTarget, [ |
| 10207 executableElementName, |
| 10208 methodElement.enclosingElement.displayName]); |
| 10209 return true; |
| 10210 } |
| 10211 } |
| 10212 superclassType = superclassElement.supertype; |
| 10213 superclassElement = superclassType == null ? null : superclassType.eleme
nt; |
| 10214 } |
| 10215 } |
| 10216 return false; |
| 10217 } |
| 10218 |
| 10219 /** |
| 10207 * This verifies that an 'int' can be assigned to the parameter corresponding
to the given | 10220 * This verifies that an 'int' can be assigned to the parameter corresponding
to the given |
| 10208 * expression. This is used for prefix and postfix expressions where the argum
ent value is | 10221 * expression. This is used for prefix and postfix expressions where the argum
ent value is |
| 10209 * implicit. | 10222 * implicit. |
| 10210 * | 10223 * |
| 10211 * @param argument the expression to which the operator is being applied | 10224 * @param argument the expression to which the operator is being applied |
| 10212 * @return `true` if and only if an error code is generated on the passed node | 10225 * @return `true` if and only if an error code is generated on the passed node |
| 10213 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE | 10226 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE |
| 10214 */ | 10227 */ |
| 10215 bool _checkForIntNotAssignable(Expression argument) { | 10228 bool _checkForIntNotAssignable(Expression argument) { |
| 10216 if (argument == null) { | 10229 if (argument == null) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10248 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT | 10261 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT |
| 10249 */ | 10262 */ |
| 10250 bool _checkForInvalidAssignment(Expression lhs, Expression rhs) { | 10263 bool _checkForInvalidAssignment(Expression lhs, Expression rhs) { |
| 10251 if (lhs == null || rhs == null) { | 10264 if (lhs == null || rhs == null) { |
| 10252 return false; | 10265 return false; |
| 10253 } | 10266 } |
| 10254 VariableElement leftVariableElement = getVariableElement(lhs); | 10267 VariableElement leftVariableElement = getVariableElement(lhs); |
| 10255 DartType leftType = (leftVariableElement == null) ? getStaticType(lhs) : lef
tVariableElement.type; | 10268 DartType leftType = (leftVariableElement == null) ? getStaticType(lhs) : lef
tVariableElement.type; |
| 10256 DartType staticRightType = getStaticType(rhs); | 10269 DartType staticRightType = getStaticType(rhs); |
| 10257 if (!staticRightType.isAssignableTo(leftType)) { | 10270 if (!staticRightType.isAssignableTo(leftType)) { |
| 10258 String leftName = leftType.displayName; | 10271 _errorReporter.reportTypeErrorForNode(StaticTypeWarningCode.INVALID_ASSIGN
MENT, rhs, [staticRightType, leftType]); |
| 10259 String rightName = staticRightType.displayName; | |
| 10260 if (leftName == rightName) { | |
| 10261 Element leftElement = leftType.element; | |
| 10262 Element rightElement = staticRightType.element; | |
| 10263 if (leftElement != null && rightElement != null) { | |
| 10264 leftName = leftElement.extendedDisplayName; | |
| 10265 rightName = rightElement.extendedDisplayName; | |
| 10266 } | |
| 10267 } | |
| 10268 _errorReporter.reportErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT
, rhs, [rightName, leftName]); | |
| 10269 return true; | 10272 return true; |
| 10270 } | 10273 } |
| 10271 return false; | 10274 return false; |
| 10272 } | 10275 } |
| 10273 | 10276 |
| 10274 /** | 10277 /** |
| 10275 * Given an assignment using a compound assignment operator, this verifies tha
t the given | 10278 * Given an assignment using a compound assignment operator, this verifies tha
t the given |
| 10276 * assignment is valid. | 10279 * assignment is valid. |
| 10277 * | 10280 * |
| 10278 * @param node the assignment expression being tested | 10281 * @param node the assignment expression being tested |
| (...skipping 10 matching lines...) Expand all Loading... |
| 10289 DartType leftType = (leftVariableElement == null) ? getStaticType(lhs) : lef
tVariableElement.type; | 10292 DartType leftType = (leftVariableElement == null) ? getStaticType(lhs) : lef
tVariableElement.type; |
| 10290 MethodElement invokedMethod = node.staticElement; | 10293 MethodElement invokedMethod = node.staticElement; |
| 10291 if (invokedMethod == null) { | 10294 if (invokedMethod == null) { |
| 10292 return false; | 10295 return false; |
| 10293 } | 10296 } |
| 10294 DartType rightType = invokedMethod.type.returnType; | 10297 DartType rightType = invokedMethod.type.returnType; |
| 10295 if (leftType == null || rightType == null) { | 10298 if (leftType == null || rightType == null) { |
| 10296 return false; | 10299 return false; |
| 10297 } | 10300 } |
| 10298 if (!rightType.isAssignableTo(leftType)) { | 10301 if (!rightType.isAssignableTo(leftType)) { |
| 10299 String leftName = leftType.displayName; | 10302 _errorReporter.reportTypeErrorForNode(StaticTypeWarningCode.INVALID_ASSIGN
MENT, rhs, [rightType, leftType]); |
| 10300 String rightName = rightType.displayName; | |
| 10301 if (leftName == rightName) { | |
| 10302 Element leftElement = leftType.element; | |
| 10303 Element rightElement = rightType.element; | |
| 10304 if (leftElement != null && rightElement != null) { | |
| 10305 leftName = leftElement.extendedDisplayName; | |
| 10306 rightName = rightElement.extendedDisplayName; | |
| 10307 } | |
| 10308 } | |
| 10309 _errorReporter.reportErrorForNode(StaticTypeWarningCode.INVALID_ASSIGNMENT
, rhs, [rightName, leftName]); | |
| 10310 return true; | 10303 return true; |
| 10311 } | 10304 } |
| 10312 return false; | 10305 return false; |
| 10313 } | 10306 } |
| 10314 | 10307 |
| 10315 /** | 10308 /** |
| 10316 * Check the given initializer to ensure that the field being initialized is a
valid field. | 10309 * Check the given initializer to ensure that the field being initialized is a
valid field. |
| 10317 * | 10310 * |
| 10318 * @param node the field initializer being checked | 10311 * @param node the field initializer being checked |
| 10319 * @param fieldName the field name from the [ConstructorFieldInitializer] | 10312 * @param fieldName the field name from the [ConstructorFieldInitializer] |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10529 getterType = _getGetterType(propertyAccessorElement); | 10522 getterType = _getGetterType(propertyAccessorElement); |
| 10530 setterType = _getSetterType(counterpartAccessor); | 10523 setterType = _getSetterType(counterpartAccessor); |
| 10531 } else if (propertyAccessorElement.isSetter) { | 10524 } else if (propertyAccessorElement.isSetter) { |
| 10532 setterType = _getSetterType(propertyAccessorElement); | 10525 setterType = _getSetterType(propertyAccessorElement); |
| 10533 getterType = _getGetterType(counterpartAccessor); | 10526 getterType = _getGetterType(counterpartAccessor); |
| 10534 } | 10527 } |
| 10535 // If either types are not assignable to each other, report an error (if the
getter is null, | 10528 // If either types are not assignable to each other, report an error (if the
getter is null, |
| 10536 // it is dynamic which is assignable to everything). | 10529 // it is dynamic which is assignable to everything). |
| 10537 if (setterType != null && getterType != null && !getterType.isAssignableTo(s
etterType)) { | 10530 if (setterType != null && getterType != null && !getterType.isAssignableTo(s
etterType)) { |
| 10538 if (enclosingClassForCounterpart == null) { | 10531 if (enclosingClassForCounterpart == null) { |
| 10539 _errorReporter.reportErrorForNode(StaticWarningCode.MISMATCHED_GETTER_AN
D_SETTER_TYPES, accessorDeclaration, [ | 10532 _errorReporter.reportTypeErrorForNode(StaticWarningCode.MISMATCHED_GETTE
R_AND_SETTER_TYPES, accessorDeclaration, [accessorTextName, setterType, getterTy
pe]); |
| 10540 accessorTextName, | |
| 10541 setterType.displayName, | |
| 10542 getterType.displayName]); | |
| 10543 return true; | 10533 return true; |
| 10544 } else { | 10534 } else { |
| 10545 _errorReporter.reportErrorForNode(StaticWarningCode.MISMATCHED_GETTER_AN
D_SETTER_TYPES_FROM_SUPERTYPE, accessorDeclaration, [ | 10535 _errorReporter.reportTypeErrorForNode(StaticWarningCode.MISMATCHED_GETTE
R_AND_SETTER_TYPES_FROM_SUPERTYPE, accessorDeclaration, [ |
| 10546 accessorTextName, | 10536 accessorTextName, |
| 10547 setterType.displayName, | 10537 setterType, |
| 10548 getterType.displayName, | 10538 getterType, |
| 10549 enclosingClassForCounterpart.displayName]); | 10539 enclosingClassForCounterpart.displayName]); |
| 10550 } | 10540 } |
| 10551 } | 10541 } |
| 10552 return false; | 10542 return false; |
| 10553 } | 10543 } |
| 10554 | 10544 |
| 10555 /** | 10545 /** |
| 10556 * This verifies that the given function body does not contain return statemen
ts that both have | 10546 * This verifies that the given function body does not contain return statemen
ts that both have |
| 10557 * and do not have return values. | 10547 * and do not have return values. |
| 10558 * | 10548 * |
| (...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11278 * @param expectedReturnType the expressed return type by the enclosing method
or function | 11268 * @param expectedReturnType the expressed return type by the enclosing method
or function |
| 11279 * @return `true` if and only if an error code is generated on the passed node | 11269 * @return `true` if and only if an error code is generated on the passed node |
| 11280 * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE | 11270 * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE |
| 11281 */ | 11271 */ |
| 11282 bool _checkForReturnOfInvalidType(Expression returnExpression, DartType expect
edReturnType) { | 11272 bool _checkForReturnOfInvalidType(Expression returnExpression, DartType expect
edReturnType) { |
| 11283 DartType staticReturnType = getStaticType(returnExpression); | 11273 DartType staticReturnType = getStaticType(returnExpression); |
| 11284 if (expectedReturnType.isVoid) { | 11274 if (expectedReturnType.isVoid) { |
| 11285 if (staticReturnType.isVoid || staticReturnType.isDynamic || staticReturnT
ype.isBottom) { | 11275 if (staticReturnType.isVoid || staticReturnType.isDynamic || staticReturnT
ype.isBottom) { |
| 11286 return false; | 11276 return false; |
| 11287 } | 11277 } |
| 11288 _errorReporter.reportErrorForNode(StaticTypeWarningCode.RETURN_OF_INVALID_
TYPE, returnExpression, [ | 11278 _errorReporter.reportTypeErrorForNode(StaticTypeWarningCode.RETURN_OF_INVA
LID_TYPE, returnExpression, [ |
| 11289 staticReturnType.displayName, | 11279 staticReturnType, |
| 11290 expectedReturnType.displayName, | 11280 expectedReturnType, |
| 11291 _enclosingFunction.displayName]); | 11281 _enclosingFunction.displayName]); |
| 11292 return true; | 11282 return true; |
| 11293 } | 11283 } |
| 11294 bool isStaticAssignable = staticReturnType.isAssignableTo(expectedReturnType
); | 11284 bool isStaticAssignable = staticReturnType.isAssignableTo(expectedReturnType
); |
| 11295 if (isStaticAssignable) { | 11285 if (isStaticAssignable) { |
| 11296 return false; | 11286 return false; |
| 11297 } | 11287 } |
| 11298 _errorReporter.reportErrorForNode(StaticTypeWarningCode.RETURN_OF_INVALID_TY
PE, returnExpression, [ | 11288 _errorReporter.reportTypeErrorForNode(StaticTypeWarningCode.RETURN_OF_INVALI
D_TYPE, returnExpression, [ |
| 11299 staticReturnType.displayName, | 11289 staticReturnType, |
| 11300 expectedReturnType.displayName, | 11290 expectedReturnType, |
| 11301 _enclosingFunction.displayName]); | 11291 _enclosingFunction.displayName]); |
| 11302 return true; | 11292 return true; |
| 11303 } | 11293 } |
| 11304 | 11294 |
| 11305 /** | 11295 /** |
| 11306 * This checks the given "typeReference" and that the "name" is not the refere
nce to an instance | 11296 * This checks the given "typeReference" and that the "name" is not the refere
nce to an instance |
| 11307 * member. | 11297 * member. |
| 11308 * | 11298 * |
| 11309 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, | 11299 * @param typeReference the resolved [ClassElement] of the left hand side of t
he expression, |
| 11310 * or `null`, aka, the class element of 'C' in 'C.x', see | 11300 * or `null`, aka, the class element of 'C' in 'C.x', see |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11437 if (typeArguments.length != 0 && typeArguments.length == typeParameters.
length) { | 11427 if (typeArguments.length != 0 && typeArguments.length == typeParameters.
length) { |
| 11438 boundType = boundType.substitute2(typeArguments, typeParameters); | 11428 boundType = boundType.substitute2(typeArguments, typeParameters); |
| 11439 } | 11429 } |
| 11440 if (!argType.isSubtypeOf(boundType)) { | 11430 if (!argType.isSubtypeOf(boundType)) { |
| 11441 ErrorCode errorCode; | 11431 ErrorCode errorCode; |
| 11442 if (_isInConstInstanceCreation) { | 11432 if (_isInConstInstanceCreation) { |
| 11443 errorCode = CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS; | 11433 errorCode = CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS; |
| 11444 } else { | 11434 } else { |
| 11445 errorCode = StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS; | 11435 errorCode = StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS; |
| 11446 } | 11436 } |
| 11447 _errorReporter.reportErrorForNode(errorCode, argTypeName, [argType.dis
playName, boundType.displayName]); | 11437 _errorReporter.reportTypeErrorForNode(errorCode, argTypeName, [argType
, boundType]); |
| 11448 foundError = true; | 11438 foundError = true; |
| 11449 } | 11439 } |
| 11450 } | 11440 } |
| 11451 } | 11441 } |
| 11452 return foundError; | 11442 return foundError; |
| 11453 } | 11443 } |
| 11454 | 11444 |
| 11455 /** | 11445 /** |
| 11456 * This checks that if the passed type name is a type parameter being used to
define a static | 11446 * This checks that if the passed type name is a type parameter being used to
define a static |
| 11457 * member. | 11447 * member. |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11592 ParameterElement parameterElement = node.element; | 11582 ParameterElement parameterElement = node.element; |
| 11593 if (parameterElement is FieldFormalParameterElementImpl) { | 11583 if (parameterElement is FieldFormalParameterElementImpl) { |
| 11594 FieldFormalParameterElementImpl fieldFormal = parameterElement; | 11584 FieldFormalParameterElementImpl fieldFormal = parameterElement; |
| 11595 DartType declaredType = fieldFormal.type; | 11585 DartType declaredType = fieldFormal.type; |
| 11596 DartType fieldType = fieldElement.type; | 11586 DartType fieldType = fieldElement.type; |
| 11597 if (fieldElement.isSynthetic) { | 11587 if (fieldElement.isSynthetic) { |
| 11598 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_
FORMAL_FOR_NON_EXISTANT_FIELD, node, [node.identifier.name]); | 11588 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_
FORMAL_FOR_NON_EXISTANT_FIELD, node, [node.identifier.name]); |
| 11599 } else if (fieldElement.isStatic) { | 11589 } else if (fieldElement.isStatic) { |
| 11600 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_
FORMAL_FOR_STATIC_FIELD, node, [node.identifier.name]); | 11590 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_
FORMAL_FOR_STATIC_FIELD, node, [node.identifier.name]); |
| 11601 } else if (declaredType != null && fieldType != null && !declaredType.
isAssignableTo(fieldType)) { | 11591 } else if (declaredType != null && fieldType != null && !declaredType.
isAssignableTo(fieldType)) { |
| 11602 _errorReporter.reportErrorForNode(StaticWarningCode.FIELD_INITIALIZI
NG_FORMAL_NOT_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName
]); | 11592 _errorReporter.reportTypeErrorForNode(StaticWarningCode.FIELD_INITIA
LIZING_FORMAL_NOT_ASSIGNABLE, node, [declaredType, fieldType]); |
| 11603 } | 11593 } |
| 11604 } else { | 11594 } else { |
| 11605 if (fieldElement.isSynthetic) { | 11595 if (fieldElement.isSynthetic) { |
| 11606 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_
FORMAL_FOR_NON_EXISTANT_FIELD, node, [node.identifier.name]); | 11596 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_
FORMAL_FOR_NON_EXISTANT_FIELD, node, [node.identifier.name]); |
| 11607 } else if (fieldElement.isStatic) { | 11597 } else if (fieldElement.isStatic) { |
| 11608 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_
FORMAL_FOR_STATIC_FIELD, node, [node.identifier.name]); | 11598 _errorReporter.reportErrorForNode(CompileTimeErrorCode.INITIALIZING_
FORMAL_FOR_STATIC_FIELD, node, [node.identifier.name]); |
| 11609 } | 11599 } |
| 11610 } | 11600 } |
| 11611 } | 11601 } |
| 11612 } | 11602 } |
| (...skipping 1456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13069 * This is a map between the set of [LibraryElement]s that the current library
imports, and | 13059 * This is a map between the set of [LibraryElement]s that the current library
imports, and |
| 13070 * a list of [ImportDirective]s that imports the library. In cases where the c
urrent library | 13060 * a list of [ImportDirective]s that imports the library. In cases where the c
urrent library |
| 13071 * imports a library with a single directive (such as `import lib1.dart;`), th
e library | 13061 * imports a library with a single directive (such as `import lib1.dart;`), th
e library |
| 13072 * element will map to a list of one [ImportDirective], which will then be rem
oved from the | 13062 * element will map to a list of one [ImportDirective], which will then be rem
oved from the |
| 13073 * [unusedImports] list. In cases where the current library imports a library
with multiple | 13063 * [unusedImports] list. In cases where the current library imports a library
with multiple |
| 13074 * directives (such as `import lib1.dart; import lib1.dart show C;`), the | 13064 * directives (such as `import lib1.dart; import lib1.dart show C;`), the |
| 13075 * [LibraryElement] will be mapped to a list of the import directives, and the
namespace | 13065 * [LibraryElement] will be mapped to a list of the import directives, and the
namespace |
| 13076 * will need to be used to compute the correct [ImportDirective] being used, s
ee | 13066 * will need to be used to compute the correct [ImportDirective] being used, s
ee |
| 13077 * [namespaceMap]. | 13067 * [namespaceMap]. |
| 13078 */ | 13068 */ |
| 13079 Map<LibraryElement, List<ImportDirective>> _libraryMap; | 13069 HashMap<LibraryElement, List<ImportDirective>> _libraryMap; |
| 13080 | 13070 |
| 13081 /** | 13071 /** |
| 13082 * In cases where there is more than one import directive per library element,
this mapping is | 13072 * In cases where there is more than one import directive per library element,
this mapping is |
| 13083 * used to determine which of the multiple import directives are used by gener
ating a | 13073 * used to determine which of the multiple import directives are used by gener
ating a |
| 13084 * [Namespace] for each of the imports to do lookups in the same way that they
are done from | 13074 * [Namespace] for each of the imports to do lookups in the same way that they
are done from |
| 13085 * the [ElementResolver]. | 13075 * the [ElementResolver]. |
| 13086 */ | 13076 */ |
| 13087 Map<ImportDirective, Namespace> _namespaceMap; | 13077 HashMap<ImportDirective, Namespace> _namespaceMap; |
| 13088 | 13078 |
| 13089 /** | 13079 /** |
| 13090 * This is a map between prefix elements and the import directives from which
they are derived. In | 13080 * This is a map between prefix elements and the import directives from which
they are derived. In |
| 13091 * cases where a type is referenced via a prefix element, the import directive
can be marked as | 13081 * cases where a type is referenced via a prefix element, the import directive
can be marked as |
| 13092 * used (removed from the unusedImports) by looking at the resolved `lib` in `
lib.X`, | 13082 * used (removed from the unusedImports) by looking at the resolved `lib` in `
lib.X`, |
| 13093 * instead of looking at which library the `lib.X` resolves. | 13083 * instead of looking at which library the `lib.X` resolves. |
| 13094 * | 13084 * |
| 13095 * TODO (jwren) Since multiple [ImportDirective]s can share the same [PrefixEl
ement], | 13085 * TODO (jwren) Since multiple [ImportDirective]s can share the same [PrefixEl
ement], |
| 13096 * it is possible to have an unreported unused import in situations where two
imports use the same | 13086 * it is possible to have an unreported unused import in situations where two
imports use the same |
| 13097 * prefix and at least one import directive is used. | 13087 * prefix and at least one import directive is used. |
| 13098 */ | 13088 */ |
| 13099 Map<PrefixElement, List<ImportDirective>> _prefixElementMap; | 13089 HashMap<PrefixElement, List<ImportDirective>> _prefixElementMap; |
| 13100 | 13090 |
| 13101 /** | 13091 /** |
| 13102 * Create a new instance of the [ImportsVerifier]. | 13092 * Create a new instance of the [ImportsVerifier]. |
| 13103 * | 13093 * |
| 13104 * @param errorReporter the error reporter | 13094 * @param errorReporter the error reporter |
| 13105 */ | 13095 */ |
| 13106 ImportsVerifier(LibraryElement library) { | 13096 ImportsVerifier(LibraryElement library) { |
| 13107 this._currentLibrary = library; | 13097 this._currentLibrary = library; |
| 13108 this._unusedImports = new List<ImportDirective>(); | 13098 this._unusedImports = new List<ImportDirective>(); |
| 13109 this._duplicateImports = new List<ImportDirective>(); | 13099 this._duplicateImports = new List<ImportDirective>(); |
| 13110 this._libraryMap = new Map<LibraryElement, List<ImportDirective>>(); | 13100 this._libraryMap = new HashMap<LibraryElement, List<ImportDirective>>(); |
| 13111 this._namespaceMap = new Map<ImportDirective, Namespace>(); | 13101 this._namespaceMap = new HashMap<ImportDirective, Namespace>(); |
| 13112 this._prefixElementMap = new Map<PrefixElement, List<ImportDirective>>(); | 13102 this._prefixElementMap = new HashMap<PrefixElement, List<ImportDirective>>()
; |
| 13113 } | 13103 } |
| 13114 | 13104 |
| 13115 /** | 13105 /** |
| 13116 * Any time after the defining compilation unit has been visited by this visit
or, this method can | 13106 * Any time after the defining compilation unit has been visited by this visit
or, this method can |
| 13117 * be called to report an [HintCode#DUPLICATE_IMPORT] hint for each of the imp
ort directives | 13107 * be called to report an [HintCode#DUPLICATE_IMPORT] hint for each of the imp
ort directives |
| 13118 * in the [duplicateImports] list. | 13108 * in the [duplicateImports] list. |
| 13119 * | 13109 * |
| 13120 * @param errorReporter the error reporter to report the set of [HintCode#DUPL
ICATE_IMPORT] | 13110 * @param errorReporter the error reporter to report the set of [HintCode#DUPL
ICATE_IMPORT] |
| 13121 * hints to | 13111 * hints to |
| 13122 */ | 13112 */ |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13239 if (_unusedImports.isEmpty) { | 13229 if (_unusedImports.isEmpty) { |
| 13240 return null; | 13230 return null; |
| 13241 } | 13231 } |
| 13242 // If the prefixed identifier references some A.B, where A is a library pref
ix, then we can | 13232 // If the prefixed identifier references some A.B, where A is a library pref
ix, then we can |
| 13243 // lookup the associated ImportDirective in prefixElementMap and remove it f
rom the | 13233 // lookup the associated ImportDirective in prefixElementMap and remove it f
rom the |
| 13244 // unusedImports list. | 13234 // unusedImports list. |
| 13245 SimpleIdentifier prefixIdentifier = node.prefix; | 13235 SimpleIdentifier prefixIdentifier = node.prefix; |
| 13246 Element element = prefixIdentifier.staticElement; | 13236 Element element = prefixIdentifier.staticElement; |
| 13247 if (element is PrefixElement) { | 13237 if (element is PrefixElement) { |
| 13248 List<ImportDirective> importDirectives = _prefixElementMap[element]; | 13238 List<ImportDirective> importDirectives = _prefixElementMap[element]; |
| 13249 for (ImportDirective importDirective in importDirectives) { | 13239 if (importDirectives != null) { |
| 13250 _unusedImports.remove(importDirective); | 13240 for (ImportDirective importDirective in importDirectives) { |
| 13241 _unusedImports.remove(importDirective); |
| 13242 } |
| 13251 } | 13243 } |
| 13252 return null; | 13244 return null; |
| 13253 } | 13245 } |
| 13254 // Otherwise, pass the prefixed identifier element and name onto visitIdenti
fier. | 13246 // Otherwise, pass the prefixed identifier element and name onto visitIdenti
fier. |
| 13255 return _visitIdentifier(element, prefixIdentifier.name); | 13247 return _visitIdentifier(element, prefixIdentifier.name); |
| 13256 } | 13248 } |
| 13257 | 13249 |
| 13258 @override | 13250 @override |
| 13259 Object visitSimpleIdentifier(SimpleIdentifier node) { | 13251 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 13260 if (_unusedImports.isEmpty) { | 13252 if (_unusedImports.isEmpty) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13315 importList = new List<ImportDirective>(); | 13307 importList = new List<ImportDirective>(); |
| 13316 _libraryMap[libraryElement] = importList; | 13308 _libraryMap[libraryElement] = importList; |
| 13317 } | 13309 } |
| 13318 importList.add(importDirective); | 13310 importList.add(importDirective); |
| 13319 } | 13311 } |
| 13320 | 13312 |
| 13321 Object _visitIdentifier(Element element, String name) { | 13313 Object _visitIdentifier(Element element, String name) { |
| 13322 if (element == null) { | 13314 if (element == null) { |
| 13323 return null; | 13315 return null; |
| 13324 } | 13316 } |
| 13325 // If the element is multiply defined then call this method recursively for
each of the conflicting elements. | 13317 // If the element is multiply defined then call this method recursively for
each of the |
| 13318 // conflicting elements. |
| 13326 if (element is MultiplyDefinedElement) { | 13319 if (element is MultiplyDefinedElement) { |
| 13327 MultiplyDefinedElement multiplyDefinedElement = element; | 13320 MultiplyDefinedElement multiplyDefinedElement = element; |
| 13328 for (Element elt in multiplyDefinedElement.conflictingElements) { | 13321 for (Element elt in multiplyDefinedElement.conflictingElements) { |
| 13329 _visitIdentifier(elt, name); | 13322 _visitIdentifier(elt, name); |
| 13330 } | 13323 } |
| 13331 return null; | 13324 return null; |
| 13332 } else if (element is PrefixElement) { | 13325 } else if (element is PrefixElement) { |
| 13333 List<ImportDirective> importDirectives = _prefixElementMap[element]; | 13326 List<ImportDirective> importDirectives = _prefixElementMap[element]; |
| 13334 for (ImportDirective importDirective in importDirectives) { | 13327 if (importDirectives != null) { |
| 13335 _unusedImports.remove(importDirective); | 13328 for (ImportDirective importDirective in importDirectives) { |
| 13329 _unusedImports.remove(importDirective); |
| 13330 } |
| 13336 } | 13331 } |
| 13337 return null; | 13332 return null; |
| 13338 } else if (element.enclosingElement is! CompilationUnitElement) { | 13333 } else if (element.enclosingElement is! CompilationUnitElement) { |
| 13339 // Identifiers that aren't a prefix element and whose enclosing element is
n't a | 13334 // Identifiers that aren't a prefix element and whose enclosing element is
n't a |
| 13340 // CompilationUnit are ignored- this covers the case the identifier is a r
elative-reference, | 13335 // CompilationUnit are ignored- this covers the case the identifier is a r
elative-reference, |
| 13341 // a reference to an identifier not imported by this library. | 13336 // a reference to an identifier not imported by this library. |
| 13342 return null; | 13337 return null; |
| 13343 } | 13338 } |
| 13344 LibraryElement containingLibrary = element.library; | 13339 LibraryElement containingLibrary = element.library; |
| 13345 if (containingLibrary == null) { | 13340 if (containingLibrary == null) { |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13528 /** | 13523 /** |
| 13529 * Given some array of [ExecutableElement]s, this method creates a synthetic e
lement as | 13524 * Given some array of [ExecutableElement]s, this method creates a synthetic e
lement as |
| 13530 * described in 8.1.1: | 13525 * described in 8.1.1: |
| 13531 * | 13526 * |
| 13532 * Let <i>numberOfPositionals</i>(<i>f</i>) denote the number of positional pa
rameters of a | 13527 * Let <i>numberOfPositionals</i>(<i>f</i>) denote the number of positional pa
rameters of a |
| 13533 * function <i>f</i>, and let <i>numberOfRequiredParams</i>(<i>f</i>) denote t
he number of | 13528 * function <i>f</i>, and let <i>numberOfRequiredParams</i>(<i>f</i>) denote t
he number of |
| 13534 * required parameters of a function <i>f</i>. Furthermore, let <i>s</i> denot
e the set of all | 13529 * required parameters of a function <i>f</i>. Furthermore, let <i>s</i> denot
e the set of all |
| 13535 * named parameters of the <i>m<sub>1</sub>, …, m<sub>k</sub></i>. Then
let | 13530 * named parameters of the <i>m<sub>1</sub>, …, m<sub>k</sub></i>. Then
let |
| 13536 * * <i>h = max(numberOfPositionals(m<sub>i</sub>)),</i> | 13531 * * <i>h = max(numberOfPositionals(m<sub>i</sub>)),</i> |
| 13537 * * <i>r = min(numberOfRequiredParams(m<sub>i</sub>)), for all <i>i</i>, 1 <=
i <= k.</i> | 13532 * * <i>r = min(numberOfRequiredParams(m<sub>i</sub>)), for all <i>i</i>, 1 <=
i <= k.</i> |
| 13538 * If <i>r <= h</i> then <i>I</i> has a method named <i>n</i>, with <i>r</i> r
equired parameters | 13533 * Then <i>I</i> has a method named <i>n</i>, with <i>r</i> required parameter
s of type |
| 13539 * of type <b>dynamic</b>, <i>h</i> positional parameters of type <b>dynamic</
b>, named parameters | 13534 * <b>dynamic</b>, <i>h</i> positional parameters of type <b>dynamic</b>, name
d parameters |
| 13540 * <i>s</i> of type <b>dynamic</b> and return type <b>dynamic</b>. | 13535 * <i>s</i> of type <b>dynamic</b> and return type <b>dynamic</b>. |
| 13541 * | 13536 * |
| 13542 * TODO (jwren) Associate a propagated type to the synthetic method element us
ing least upper | 13537 * TODO (jwren) Associate a propagated type to the synthetic method element us
ing least upper |
| 13543 * bounds instead of dynamic | 13538 * bounds instead of dynamic |
| 13544 */ | 13539 */ |
| 13545 static ExecutableElement _computeMergedExecutableElement(List<ExecutableElemen
t> elementArrayToMerge) { | 13540 static ExecutableElement _computeMergedExecutableElement(List<ExecutableElemen
t> elementArrayToMerge) { |
| 13546 int h = _getNumOfPositionalParameters(elementArrayToMerge[0]); | 13541 int h = _getNumOfPositionalParameters(elementArrayToMerge[0]); |
| 13547 int r = _getNumOfRequiredParameters(elementArrayToMerge[0]); | 13542 int r = _getNumOfRequiredParameters(elementArrayToMerge[0]); |
| 13548 Set<String> namedParametersList = new Set<String>(); | 13543 Set<String> namedParametersList = new Set<String>(); |
| 13549 for (int i = 1; i < elementArrayToMerge.length; i++) { | 13544 for (int i = 1; i < elementArrayToMerge.length; i++) { |
| 13550 ExecutableElement element = elementArrayToMerge[i]; | 13545 ExecutableElement element = elementArrayToMerge[i]; |
| 13551 int numOfPositionalParams = _getNumOfPositionalParameters(element); | 13546 int numOfPositionalParams = _getNumOfPositionalParameters(element); |
| 13552 if (h < numOfPositionalParams) { | 13547 if (h < numOfPositionalParams) { |
| 13553 h = numOfPositionalParams; | 13548 h = numOfPositionalParams; |
| 13554 } | 13549 } |
| 13555 int numOfRequiredParams = _getNumOfRequiredParameters(element); | 13550 int numOfRequiredParams = _getNumOfRequiredParameters(element); |
| 13556 if (r > numOfRequiredParams) { | 13551 if (r > numOfRequiredParams) { |
| 13557 r = numOfRequiredParams; | 13552 r = numOfRequiredParams; |
| 13558 } | 13553 } |
| 13559 namedParametersList.addAll(_getNamedParameterNames(element)); | 13554 namedParametersList.addAll(_getNamedParameterNames(element)); |
| 13560 } | 13555 } |
| 13561 if (r > h) { | |
| 13562 return null; | |
| 13563 } | |
| 13564 return _createSyntheticExecutableElement(elementArrayToMerge, elementArrayTo
Merge[0].displayName, r, h - r, new List.from(namedParametersList)); | 13556 return _createSyntheticExecutableElement(elementArrayToMerge, elementArrayTo
Merge[0].displayName, r, h - r, new List.from(namedParametersList)); |
| 13565 } | 13557 } |
| 13566 | 13558 |
| 13567 /** | 13559 /** |
| 13568 * Used by [computeMergedExecutableElement] to actually create the | 13560 * Used by [computeMergedExecutableElement] to actually create the |
| 13569 * synthetic element. | 13561 * synthetic element. |
| 13570 * | 13562 * |
| 13571 * @param elementArrayToMerge the array used to create the synthetic element | 13563 * @param elementArrayToMerge the array used to create the synthetic element |
| 13572 * @param name the name of the method, getter or setter | 13564 * @param name the name of the method, getter or setter |
| 13573 * @param numOfRequiredParameters the number of required parameters | 13565 * @param numOfRequiredParameters the number of required parameters |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13678 | 13670 |
| 13679 /** | 13671 /** |
| 13680 * The [LibraryElement] that is managed by this manager. | 13672 * The [LibraryElement] that is managed by this manager. |
| 13681 */ | 13673 */ |
| 13682 LibraryElement _library; | 13674 LibraryElement _library; |
| 13683 | 13675 |
| 13684 /** | 13676 /** |
| 13685 * This is a mapping between each [ClassElement] and a map between the [String
] member | 13677 * This is a mapping between each [ClassElement] and a map between the [String
] member |
| 13686 * names and the associated [ExecutableElement] in the mixin and superclass ch
ain. | 13678 * names and the associated [ExecutableElement] in the mixin and superclass ch
ain. |
| 13687 */ | 13679 */ |
| 13688 Map<ClassElement, MemberMap> _classLookup; | 13680 HashMap<ClassElement, MemberMap> _classLookup; |
| 13689 | 13681 |
| 13690 /** | 13682 /** |
| 13691 * This is a mapping between each [ClassElement] and a map between the [String
] member | 13683 * This is a mapping between each [ClassElement] and a map between the [String
] member |
| 13692 * names and the associated [ExecutableElement] in the interface set. | 13684 * names and the associated [ExecutableElement] in the interface set. |
| 13693 */ | 13685 */ |
| 13694 Map<ClassElement, MemberMap> _interfaceLookup; | 13686 HashMap<ClassElement, MemberMap> _interfaceLookup; |
| 13695 | 13687 |
| 13696 /** | 13688 /** |
| 13697 * A map between each visited [ClassElement] and the set of [AnalysisError]s f
ound on | 13689 * A map between each visited [ClassElement] and the set of [AnalysisError]s f
ound on |
| 13698 * the class element. | 13690 * the class element. |
| 13699 */ | 13691 */ |
| 13700 Map<ClassElement, Set<AnalysisError>> _errorsInClassElement = new Map<ClassEle
ment, Set<AnalysisError>>(); | 13692 HashMap<ClassElement, Set<AnalysisError>> _errorsInClassElement = new HashMap<
ClassElement, Set<AnalysisError>>(); |
| 13701 | 13693 |
| 13702 /** | 13694 /** |
| 13703 * Initialize a newly created inheritance manager. | 13695 * Initialize a newly created inheritance manager. |
| 13704 * | 13696 * |
| 13705 * @param library the library element context that the inheritance mappings ar
e being generated | 13697 * @param library the library element context that the inheritance mappings ar
e being generated |
| 13706 */ | 13698 */ |
| 13707 InheritanceManager(LibraryElement library) { | 13699 InheritanceManager(LibraryElement library) { |
| 13708 this._library = library; | 13700 this._library = library; |
| 13709 _classLookup = new Map<ClassElement, MemberMap>(); | 13701 _classLookup = new HashMap<ClassElement, MemberMap>(); |
| 13710 _interfaceLookup = new Map<ClassElement, MemberMap>(); | 13702 _interfaceLookup = new HashMap<ClassElement, MemberMap>(); |
| 13711 } | 13703 } |
| 13712 | 13704 |
| 13713 /** | 13705 /** |
| 13714 * Return the set of [AnalysisError]s found on the passed [ClassElement], or | 13706 * Return the set of [AnalysisError]s found on the passed [ClassElement], or |
| 13715 * `null` if there are none. | 13707 * `null` if there are none. |
| 13716 * | 13708 * |
| 13717 * @param classElt the class element to query | 13709 * @param classElt the class element to query |
| 13718 * @return the set of [AnalysisError]s found on the passed [ClassElement], or | 13710 * @return the set of [AnalysisError]s found on the passed [ClassElement], or |
| 13719 * `null` if there are none | 13711 * `null` if there are none |
| 13720 */ | 13712 */ |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13793 */ | 13785 */ |
| 13794 FunctionType lookupMemberType(InterfaceType interfaceType, String memberName)
{ | 13786 FunctionType lookupMemberType(InterfaceType interfaceType, String memberName)
{ |
| 13795 ExecutableElement iteratorMember = lookupMember(interfaceType.element, membe
rName); | 13787 ExecutableElement iteratorMember = lookupMember(interfaceType.element, membe
rName); |
| 13796 if (iteratorMember == null) { | 13788 if (iteratorMember == null) { |
| 13797 return null; | 13789 return null; |
| 13798 } | 13790 } |
| 13799 return substituteTypeArgumentsInMemberFromInheritance(iteratorMember.type, m
emberName, interfaceType); | 13791 return substituteTypeArgumentsInMemberFromInheritance(iteratorMember.type, m
emberName, interfaceType); |
| 13800 } | 13792 } |
| 13801 | 13793 |
| 13802 /** | 13794 /** |
| 13795 * Determine the set of methods which is overridden by the given class member.
If no member is |
| 13796 * inherited, an empty list is returned. If one of the inherited members is a |
| 13797 * [MultiplyInheritedExecutableElement], then it is expanded into its constitu
ent inherited |
| 13798 * elements. |
| 13799 * |
| 13800 * @param classElt the class to query |
| 13801 * @param memberName the name of the class member to query |
| 13802 * @return a list of overridden methods |
| 13803 */ |
| 13804 List<ExecutableElement> lookupOverrides(ClassElement classElt, String memberNa
me) { |
| 13805 List<ExecutableElement> result = new List<ExecutableElement>(); |
| 13806 if (memberName == null || memberName.isEmpty) { |
| 13807 return result; |
| 13808 } |
| 13809 List<MemberMap> interfaceMaps = _gatherInterfaceLookupMaps(classElt, new Set
<ClassElement>()); |
| 13810 if (interfaceMaps != null) { |
| 13811 for (MemberMap interfaceMap in interfaceMaps) { |
| 13812 ExecutableElement overriddenElement = interfaceMap.get(memberName); |
| 13813 if (overriddenElement != null) { |
| 13814 if (overriddenElement is MultiplyInheritedExecutableElement) { |
| 13815 MultiplyInheritedExecutableElement multiplyInheritedElement = overri
ddenElement; |
| 13816 for (ExecutableElement element in multiplyInheritedElement.inherited
Elements) { |
| 13817 result.add(element); |
| 13818 } |
| 13819 } else { |
| 13820 result.add(overriddenElement); |
| 13821 } |
| 13822 } |
| 13823 } |
| 13824 } |
| 13825 return result; |
| 13826 } |
| 13827 |
| 13828 /** |
| 13803 * Set the new library element context. | 13829 * Set the new library element context. |
| 13804 * | 13830 * |
| 13805 * @param library the new library element | 13831 * @param library the new library element |
| 13806 */ | 13832 */ |
| 13807 void set libraryElement(LibraryElement library) { | 13833 void set libraryElement(LibraryElement library) { |
| 13808 this._library = library; | 13834 this._library = library; |
| 13809 } | 13835 } |
| 13810 | 13836 |
| 13811 /** | 13837 /** |
| 13812 * This method takes some inherited [FunctionType], and resolves all the param
eterized types | 13838 * This method takes some inherited [FunctionType], and resolves all the param
eterized types |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14005 * @param classElt the class element to query | 14031 * @param classElt the class element to query |
| 14006 * @param visitedInterfaces a set of visited classes passed back into this met
hod when it calls | 14032 * @param visitedInterfaces a set of visited classes passed back into this met
hod when it calls |
| 14007 * itself recursively | 14033 * itself recursively |
| 14008 * @return a mapping between the set of all string names of the members inheri
ted from the passed | 14034 * @return a mapping between the set of all string names of the members inheri
ted from the passed |
| 14009 * [ClassElement] interface hierarchy, and the associated [ExecutableE
lement] | 14035 * [ClassElement] interface hierarchy, and the associated [ExecutableE
lement] |
| 14010 */ | 14036 */ |
| 14011 MemberMap _computeInterfaceLookupMap(ClassElement classElt, Set<ClassElement>
visitedInterfaces) { | 14037 MemberMap _computeInterfaceLookupMap(ClassElement classElt, Set<ClassElement>
visitedInterfaces) { |
| 14012 MemberMap resultMap = _interfaceLookup[classElt]; | 14038 MemberMap resultMap = _interfaceLookup[classElt]; |
| 14013 if (resultMap != null) { | 14039 if (resultMap != null) { |
| 14014 return resultMap; | 14040 return resultMap; |
| 14041 } |
| 14042 List<MemberMap> lookupMaps = _gatherInterfaceLookupMaps(classElt, visitedInt
erfaces); |
| 14043 if (lookupMaps == null) { |
| 14044 resultMap = new MemberMap(); |
| 14015 } else { | 14045 } else { |
| 14016 resultMap = new MemberMap(); | 14046 HashMap<String, List<ExecutableElement>> unionMap = _unionInterfaceLookupM
aps(lookupMaps); |
| 14047 resultMap = _resolveInheritanceLookup(classElt, unionMap); |
| 14017 } | 14048 } |
| 14049 _interfaceLookup[classElt] = resultMap; |
| 14050 return resultMap; |
| 14051 } |
| 14052 |
| 14053 /** |
| 14054 * Collect a list of interface lookup maps whose elements correspond to all of
the classes |
| 14055 * directly above [classElt] in the class hierarchy (the direct superclass if
any, all |
| 14056 * mixins, and all direct superinterfaces). Each item in the list is the inter
face lookup map |
| 14057 * returned by [computeInterfaceLookupMap] for the corresponding super, except
with type |
| 14058 * parameters appropriately substituted. |
| 14059 * |
| 14060 * @param classElt the class element to query |
| 14061 * @param visitedInterfaces a set of visited classes passed back into this met
hod when it calls |
| 14062 * itself recursively |
| 14063 * @return `null` if there was a problem (such as a loop in the class hierarch
y) or if there |
| 14064 * are no classes above this one in the class hierarchy. Otherwise, a
list of interface |
| 14065 * lookup maps. |
| 14066 */ |
| 14067 List<MemberMap> _gatherInterfaceLookupMaps(ClassElement classElt, Set<ClassEle
ment> visitedInterfaces) { |
| 14018 InterfaceType supertype = classElt.supertype; | 14068 InterfaceType supertype = classElt.supertype; |
| 14019 ClassElement superclassElement = supertype != null ? supertype.element : nul
l; | 14069 ClassElement superclassElement = supertype != null ? supertype.element : nul
l; |
| 14020 List<InterfaceType> mixins = classElt.mixins; | 14070 List<InterfaceType> mixins = classElt.mixins; |
| 14021 List<InterfaceType> interfaces = classElt.interfaces; | 14071 List<InterfaceType> interfaces = classElt.interfaces; |
| 14022 // Recursively collect the list of mappings from all of the interface types | 14072 // Recursively collect the list of mappings from all of the interface types |
| 14023 List<MemberMap> lookupMaps = new List<MemberMap>(); | 14073 List<MemberMap> lookupMaps = new List<MemberMap>(); |
| 14024 // | 14074 // |
| 14025 // Superclass element | 14075 // Superclass element |
| 14026 // | 14076 // |
| 14027 if (superclassElement != null) { | 14077 if (superclassElement != null) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 14039 _substituteTypeParametersDownHierarchy(supertype, map); | 14089 _substituteTypeParametersDownHierarchy(supertype, map); |
| 14040 // | 14090 // |
| 14041 // Add any members from the super type into the map as well. | 14091 // Add any members from the super type into the map as well. |
| 14042 // | 14092 // |
| 14043 _recordMapWithClassMembers(map, supertype, true); | 14093 _recordMapWithClassMembers(map, supertype, true); |
| 14044 lookupMaps.add(map); | 14094 lookupMaps.add(map); |
| 14045 } finally { | 14095 } finally { |
| 14046 visitedInterfaces.remove(superclassElement); | 14096 visitedInterfaces.remove(superclassElement); |
| 14047 } | 14097 } |
| 14048 } else { | 14098 } else { |
| 14049 MemberMap map = _interfaceLookup[classElt]; | 14099 return null; |
| 14050 if (map != null) { | |
| 14051 lookupMaps.add(map); | |
| 14052 } else { | |
| 14053 _interfaceLookup[superclassElement] = resultMap; | |
| 14054 return resultMap; | |
| 14055 } | |
| 14056 } | 14100 } |
| 14057 } | 14101 } |
| 14058 // | 14102 // |
| 14059 // Mixin elements | 14103 // Mixin elements |
| 14060 // | 14104 // |
| 14061 for (int i = mixins.length - 1; i >= 0; i--) { | 14105 for (int i = mixins.length - 1; i >= 0; i--) { |
| 14062 InterfaceType mixinType = mixins[i]; | 14106 InterfaceType mixinType = mixins[i]; |
| 14063 ClassElement mixinElement = mixinType.element; | 14107 ClassElement mixinElement = mixinType.element; |
| 14064 if (mixinElement != null) { | 14108 if (mixinElement != null) { |
| 14065 if (!visitedInterfaces.contains(mixinElement)) { | 14109 if (!visitedInterfaces.contains(mixinElement)) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 14076 _substituteTypeParametersDownHierarchy(mixinType, map); | 14120 _substituteTypeParametersDownHierarchy(mixinType, map); |
| 14077 // | 14121 // |
| 14078 // Add any members from the mixin type into the map as well. | 14122 // Add any members from the mixin type into the map as well. |
| 14079 // | 14123 // |
| 14080 _recordMapWithClassMembers(map, mixinType, true); | 14124 _recordMapWithClassMembers(map, mixinType, true); |
| 14081 lookupMaps.add(map); | 14125 lookupMaps.add(map); |
| 14082 } finally { | 14126 } finally { |
| 14083 visitedInterfaces.remove(mixinElement); | 14127 visitedInterfaces.remove(mixinElement); |
| 14084 } | 14128 } |
| 14085 } else { | 14129 } else { |
| 14086 MemberMap map = _interfaceLookup[classElt]; | 14130 return null; |
| 14087 if (map != null) { | |
| 14088 lookupMaps.add(map); | |
| 14089 } else { | |
| 14090 _interfaceLookup[mixinElement] = resultMap; | |
| 14091 return resultMap; | |
| 14092 } | |
| 14093 } | 14131 } |
| 14094 } | 14132 } |
| 14095 } | 14133 } |
| 14096 // | 14134 // |
| 14097 // Interface elements | 14135 // Interface elements |
| 14098 // | 14136 // |
| 14099 for (InterfaceType interfaceType in interfaces) { | 14137 for (InterfaceType interfaceType in interfaces) { |
| 14100 ClassElement interfaceElement = interfaceType.element; | 14138 ClassElement interfaceElement = interfaceType.element; |
| 14101 if (interfaceElement != null) { | 14139 if (interfaceElement != null) { |
| 14102 if (!visitedInterfaces.contains(interfaceElement)) { | 14140 if (!visitedInterfaces.contains(interfaceElement)) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 14113 _substituteTypeParametersDownHierarchy(interfaceType, map); | 14151 _substituteTypeParametersDownHierarchy(interfaceType, map); |
| 14114 // | 14152 // |
| 14115 // And add any members from the interface into the map as well. | 14153 // And add any members from the interface into the map as well. |
| 14116 // | 14154 // |
| 14117 _recordMapWithClassMembers(map, interfaceType, true); | 14155 _recordMapWithClassMembers(map, interfaceType, true); |
| 14118 lookupMaps.add(map); | 14156 lookupMaps.add(map); |
| 14119 } finally { | 14157 } finally { |
| 14120 visitedInterfaces.remove(interfaceElement); | 14158 visitedInterfaces.remove(interfaceElement); |
| 14121 } | 14159 } |
| 14122 } else { | 14160 } else { |
| 14123 MemberMap map = _interfaceLookup[classElt]; | 14161 return null; |
| 14124 if (map != null) { | |
| 14125 lookupMaps.add(map); | |
| 14126 } else { | |
| 14127 _interfaceLookup[interfaceElement] = resultMap; | |
| 14128 return resultMap; | |
| 14129 } | |
| 14130 } | 14162 } |
| 14131 } | 14163 } |
| 14132 } | 14164 } |
| 14133 if (lookupMaps.length == 0) { | 14165 if (lookupMaps.length == 0) { |
| 14134 _interfaceLookup[classElt] = resultMap; | 14166 return null; |
| 14135 return resultMap; | |
| 14136 } | 14167 } |
| 14137 // | 14168 return lookupMaps; |
| 14138 // Union all of the lookupMaps together into unionMap, grouping the Executab
leElements into a | 14169 } |
| 14139 // list where none of the elements are equal where equality is determined by
having equal | 14170 |
| 14140 // function types. (We also take note too of the kind of the element: ()->in
t and () -> int may | 14171 /** |
| 14141 // not be equal if one is a getter and the other is a method.) | 14172 * Given some [ClassElement], this method finds and returns the [ExecutableEle
ment] of |
| 14142 // | 14173 * the passed name in the class element. Static members, members in super type
s and members not |
| 14143 Map<String, List<ExecutableElement>> unionMap = new Map<String, List<Executa
bleElement>>(); | 14174 * accessible from the current library are not considered. |
| 14144 for (MemberMap lookupMap in lookupMaps) { | 14175 * |
| 14145 int lookupMapSize = lookupMap.size; | 14176 * @param classElt the class element to query |
| 14146 for (int i = 0; i < lookupMapSize; i++) { | 14177 * @param memberName the name of the member to lookup in the class |
| 14147 // Get the string key, if null, break. | 14178 * @return the found [ExecutableElement], or `null` if no such member was foun
d |
| 14148 String key = lookupMap.getKey(i); | 14179 */ |
| 14149 if (key == null) { | 14180 ExecutableElement _lookupMemberInClass(ClassElement classElt, String memberNam
e) { |
| 14150 break; | 14181 List<MethodElement> methods = classElt.methods; |
| 14151 } | 14182 for (MethodElement method in methods) { |
| 14152 // Get the list value out of the unionMap | 14183 if (memberName == method.name && method.isAccessibleIn(_library) && !metho
d.isStatic) { |
| 14153 List<ExecutableElement> list = unionMap[key]; | 14184 return method; |
| 14154 // If we haven't created such a map for this key yet, do create it and p
ut the list entry | |
| 14155 // into the unionMap. | |
| 14156 if (list == null) { | |
| 14157 list = new List<ExecutableElement>(); | |
| 14158 unionMap[key] = list; | |
| 14159 } | |
| 14160 // Fetch the entry out of this lookupMap | |
| 14161 ExecutableElement newExecutableElementEntry = lookupMap.getValue(i); | |
| 14162 if (list.isEmpty) { | |
| 14163 // If the list is empty, just the new value | |
| 14164 list.add(newExecutableElementEntry); | |
| 14165 } else { | |
| 14166 // Otherwise, only add the newExecutableElementEntry if it isn't alrea
dy in the list, this | |
| 14167 // covers situation where a class inherits two methods (or two getters
) that are | |
| 14168 // identical. | |
| 14169 bool alreadyInList = false; | |
| 14170 bool isMethod1 = newExecutableElementEntry is MethodElement; | |
| 14171 for (ExecutableElement executableElementInList in list) { | |
| 14172 bool isMethod2 = executableElementInList is MethodElement; | |
| 14173 if (isMethod1 == isMethod2 && executableElementInList.type == newExe
cutableElementEntry.type) { | |
| 14174 alreadyInList = true; | |
| 14175 break; | |
| 14176 } | |
| 14177 } | |
| 14178 if (!alreadyInList) { | |
| 14179 list.add(newExecutableElementEntry); | |
| 14180 } | |
| 14181 } | |
| 14182 } | 14185 } |
| 14183 } | 14186 } |
| 14184 // | 14187 List<PropertyAccessorElement> accessors = classElt.accessors; |
| 14185 // Loop through the entries in the unionMap, adding them to the resultMap ap
propriately. | 14188 for (PropertyAccessorElement accessor in accessors) { |
| 14186 // | 14189 if (memberName == accessor.name && accessor.isAccessibleIn(_library) && !a
ccessor.isStatic) { |
| 14190 return accessor; |
| 14191 } |
| 14192 } |
| 14193 return null; |
| 14194 } |
| 14195 |
| 14196 /** |
| 14197 * Record the passed map with the set of all members (methods, getters and set
ters) in the type |
| 14198 * into the passed map. |
| 14199 * |
| 14200 * @param map some non-`null` map to put the methods and accessors from the pa
ssed |
| 14201 * [ClassElement] into |
| 14202 * @param type the type that will be recorded into the passed map |
| 14203 * @param doIncludeAbstract `true` if abstract members will be put into the ma
p |
| 14204 */ |
| 14205 void _recordMapWithClassMembers(MemberMap map, InterfaceType type, bool doIncl
udeAbstract) { |
| 14206 List<MethodElement> methods = type.methods; |
| 14207 for (MethodElement method in methods) { |
| 14208 if (method.isAccessibleIn(_library) && !method.isStatic && (doIncludeAbstr
act || !method.isAbstract)) { |
| 14209 map.put(method.name, method); |
| 14210 } |
| 14211 } |
| 14212 List<PropertyAccessorElement> accessors = type.accessors; |
| 14213 for (PropertyAccessorElement accessor in accessors) { |
| 14214 if (accessor.isAccessibleIn(_library) && !accessor.isStatic && (doIncludeA
bstract || !accessor.isAbstract)) { |
| 14215 map.put(accessor.name, accessor); |
| 14216 } |
| 14217 } |
| 14218 } |
| 14219 |
| 14220 /** |
| 14221 * This method is used to report errors on when they are found computing inher
itance information. |
| 14222 * See [ErrorVerifier#checkForInconsistentMethodInheritance] to see where thes
e generated |
| 14223 * error codes are reported back into the analysis engine. |
| 14224 * |
| 14225 * @param classElt the location of the source for which the exception occurred |
| 14226 * @param offset the offset of the location of the error |
| 14227 * @param length the length of the location of the error |
| 14228 * @param errorCode the error code to be associated with this error |
| 14229 * @param arguments the arguments used to build the error message |
| 14230 */ |
| 14231 void _reportError(ClassElement classElt, int offset, int length, ErrorCode err
orCode, List<Object> arguments) { |
| 14232 Set<AnalysisError> errorSet = _errorsInClassElement[classElt]; |
| 14233 if (errorSet == null) { |
| 14234 errorSet = new Set<AnalysisError>(); |
| 14235 _errorsInClassElement[classElt] = errorSet; |
| 14236 } |
| 14237 errorSet.add(new AnalysisError.con2(classElt.source, offset, length, errorCo
de, arguments)); |
| 14238 } |
| 14239 |
| 14240 /** |
| 14241 * Given the set of methods defined by classes above [classElt] in the class h
ierarchy, |
| 14242 * apply the appropriate inheritance rules to determine those methods inherite
d by or overridden |
| 14243 * by [classElt]. Also report static warnings |
| 14244 * [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE] and |
| 14245 * [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD] if ap
propriate. |
| 14246 * |
| 14247 * @param classElt the class element to query. |
| 14248 * @param unionMap a mapping from method name to the set of unique (in terms o
f signature) methods |
| 14249 * defined in superclasses of [classElt]. |
| 14250 * @return the inheritance lookup map for [classElt]. |
| 14251 */ |
| 14252 MemberMap _resolveInheritanceLookup(ClassElement classElt, HashMap<String, Lis
t<ExecutableElement>> unionMap) { |
| 14253 MemberMap resultMap = new MemberMap(); |
| 14187 for (MapEntry<String, List<ExecutableElement>> entry in getMapEntrySet(union
Map)) { | 14254 for (MapEntry<String, List<ExecutableElement>> entry in getMapEntrySet(union
Map)) { |
| 14188 String key = entry.getKey(); | 14255 String key = entry.getKey(); |
| 14189 List<ExecutableElement> list = entry.getValue(); | 14256 List<ExecutableElement> list = entry.getValue(); |
| 14190 int numOfEltsWithMatchingNames = list.length; | 14257 int numOfEltsWithMatchingNames = list.length; |
| 14191 if (numOfEltsWithMatchingNames == 1) { | 14258 if (numOfEltsWithMatchingNames == 1) { |
| 14192 // | 14259 // |
| 14193 // Example: class A inherits only 1 method named 'm'. Since it is the o
nly such method, it | 14260 // Example: class A inherits only 1 method named 'm'. Since it is the o
nly such method, it |
| 14194 // is inherited. | 14261 // is inherited. |
| 14195 // Another example: class A inherits 2 methods named 'm' from 2 differen
t interfaces, but | 14262 // Another example: class A inherits 2 methods named 'm' from 2 differen
t interfaces, but |
| 14196 // they both have the same signature, so it is the method inherited. | 14263 // they both have the same signature, so it is the method inherited. |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14292 // '(int) -> dynamic' and one has the function type '(num) -> dyna
mic'. Since they are | 14359 // '(int) -> dynamic' and one has the function type '(num) -> dyna
mic'. Since they are |
| 14293 // both a subtype of the other, a synthetic function '(dynamic) ->
dynamic' is | 14360 // both a subtype of the other, a synthetic function '(dynamic) ->
dynamic' is |
| 14294 // inherited. | 14361 // inherited. |
| 14295 // Tests: test_getMapOfMembersInheritedFromInterfaces_union_multip
leSubtypes_* | 14362 // Tests: test_getMapOfMembersInheritedFromInterfaces_union_multip
leSubtypes_* |
| 14296 // | 14363 // |
| 14297 List<ExecutableElement> elementArrayToMerge = new List<ExecutableE
lement>(subtypesOfAllOtherTypesIndexes.length); | 14364 List<ExecutableElement> elementArrayToMerge = new List<ExecutableE
lement>(subtypesOfAllOtherTypesIndexes.length); |
| 14298 for (int i = 0; i < elementArrayToMerge.length; i++) { | 14365 for (int i = 0; i < elementArrayToMerge.length; i++) { |
| 14299 elementArrayToMerge[i] = elements[subtypesOfAllOtherTypesIndexes
[i]]; | 14366 elementArrayToMerge[i] = elements[subtypesOfAllOtherTypesIndexes
[i]]; |
| 14300 } | 14367 } |
| 14301 ExecutableElement mergedExecutableElement = _computeMergedExecutab
leElement(elementArrayToMerge); | 14368 ExecutableElement mergedExecutableElement = _computeMergedExecutab
leElement(elementArrayToMerge); |
| 14302 if (mergedExecutableElement != null) { | 14369 resultMap.put(key, mergedExecutableElement); |
| 14303 resultMap.put(key, mergedExecutableElement); | |
| 14304 } | |
| 14305 } | 14370 } |
| 14306 } | 14371 } |
| 14307 } else { | 14372 } else { |
| 14308 _reportError(classElt, classElt.nameOffset, classElt.displayName.lengt
h, StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, [key]); | 14373 _reportError(classElt, classElt.nameOffset, classElt.displayName.lengt
h, StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, [key]); |
| 14309 } | 14374 } |
| 14310 } | 14375 } |
| 14311 } | 14376 } |
| 14312 _interfaceLookup[classElt] = resultMap; | |
| 14313 return resultMap; | 14377 return resultMap; |
| 14314 } | 14378 } |
| 14315 | 14379 |
| 14316 /** | 14380 /** |
| 14317 * Given some [ClassElement], this method finds and returns the [ExecutableEle
ment] of | |
| 14318 * the passed name in the class element. Static members, members in super type
s and members not | |
| 14319 * accessible from the current library are not considered. | |
| 14320 * | |
| 14321 * @param classElt the class element to query | |
| 14322 * @param memberName the name of the member to lookup in the class | |
| 14323 * @return the found [ExecutableElement], or `null` if no such member was foun
d | |
| 14324 */ | |
| 14325 ExecutableElement _lookupMemberInClass(ClassElement classElt, String memberNam
e) { | |
| 14326 List<MethodElement> methods = classElt.methods; | |
| 14327 for (MethodElement method in methods) { | |
| 14328 if (memberName == method.name && method.isAccessibleIn(_library) && !metho
d.isStatic) { | |
| 14329 return method; | |
| 14330 } | |
| 14331 } | |
| 14332 List<PropertyAccessorElement> accessors = classElt.accessors; | |
| 14333 for (PropertyAccessorElement accessor in accessors) { | |
| 14334 if (memberName == accessor.name && accessor.isAccessibleIn(_library) && !a
ccessor.isStatic) { | |
| 14335 return accessor; | |
| 14336 } | |
| 14337 } | |
| 14338 return null; | |
| 14339 } | |
| 14340 | |
| 14341 /** | |
| 14342 * Record the passed map with the set of all members (methods, getters and set
ters) in the type | |
| 14343 * into the passed map. | |
| 14344 * | |
| 14345 * @param map some non-`null` map to put the methods and accessors from the pa
ssed | |
| 14346 * [ClassElement] into | |
| 14347 * @param type the type that will be recorded into the passed map | |
| 14348 * @param doIncludeAbstract `true` if abstract members will be put into the ma
p | |
| 14349 */ | |
| 14350 void _recordMapWithClassMembers(MemberMap map, InterfaceType type, bool doIncl
udeAbstract) { | |
| 14351 List<MethodElement> methods = type.methods; | |
| 14352 for (MethodElement method in methods) { | |
| 14353 if (method.isAccessibleIn(_library) && !method.isStatic && (doIncludeAbstr
act || !method.isAbstract)) { | |
| 14354 map.put(method.name, method); | |
| 14355 } | |
| 14356 } | |
| 14357 List<PropertyAccessorElement> accessors = type.accessors; | |
| 14358 for (PropertyAccessorElement accessor in accessors) { | |
| 14359 if (accessor.isAccessibleIn(_library) && !accessor.isStatic && (doIncludeA
bstract || !accessor.isAbstract)) { | |
| 14360 map.put(accessor.name, accessor); | |
| 14361 } | |
| 14362 } | |
| 14363 } | |
| 14364 | |
| 14365 /** | |
| 14366 * This method is used to report errors on when they are found computing inher
itance information. | |
| 14367 * See [ErrorVerifier#checkForInconsistentMethodInheritance] to see where thes
e generated | |
| 14368 * error codes are reported back into the analysis engine. | |
| 14369 * | |
| 14370 * @param classElt the location of the source for which the exception occurred | |
| 14371 * @param offset the offset of the location of the error | |
| 14372 * @param length the length of the location of the error | |
| 14373 * @param errorCode the error code to be associated with this error | |
| 14374 * @param arguments the arguments used to build the error message | |
| 14375 */ | |
| 14376 void _reportError(ClassElement classElt, int offset, int length, ErrorCode err
orCode, List<Object> arguments) { | |
| 14377 Set<AnalysisError> errorSet = _errorsInClassElement[classElt]; | |
| 14378 if (errorSet == null) { | |
| 14379 errorSet = new Set<AnalysisError>(); | |
| 14380 _errorsInClassElement[classElt] = errorSet; | |
| 14381 } | |
| 14382 errorSet.add(new AnalysisError.con2(classElt.source, offset, length, errorCo
de, arguments)); | |
| 14383 } | |
| 14384 | |
| 14385 /** | |
| 14386 * Loop through all of the members in some [MemberMap], performing type parame
ter | 14381 * Loop through all of the members in some [MemberMap], performing type parame
ter |
| 14387 * substitutions using a passed supertype. | 14382 * substitutions using a passed supertype. |
| 14388 * | 14383 * |
| 14389 * @param superType the supertype to substitute into the members of the [Membe
rMap] | 14384 * @param superType the supertype to substitute into the members of the [Membe
rMap] |
| 14390 * @param map the MemberMap to perform the substitutions on | 14385 * @param map the MemberMap to perform the substitutions on |
| 14391 */ | 14386 */ |
| 14392 void _substituteTypeParametersDownHierarchy(InterfaceType superType, MemberMap
map) { | 14387 void _substituteTypeParametersDownHierarchy(InterfaceType superType, MemberMap
map) { |
| 14393 for (int i = 0; i < map.size; i++) { | 14388 for (int i = 0; i < map.size; i++) { |
| 14394 ExecutableElement executableElement = map.getValue(i); | 14389 ExecutableElement executableElement = map.getValue(i); |
| 14395 if (executableElement is MethodMember) { | 14390 if (executableElement is MethodMember) { |
| 14396 executableElement = MethodMember.from(executableElement as MethodMember,
superType); | 14391 executableElement = MethodMember.from(executableElement as MethodMember,
superType); |
| 14397 map.setValue(i, executableElement); | 14392 map.setValue(i, executableElement); |
| 14398 } else if (executableElement is PropertyAccessorMember) { | 14393 } else if (executableElement is PropertyAccessorMember) { |
| 14399 executableElement = PropertyAccessorMember.from(executableElement as Pro
pertyAccessorMember, superType); | 14394 executableElement = PropertyAccessorMember.from(executableElement as Pro
pertyAccessorMember, superType); |
| 14400 map.setValue(i, executableElement); | 14395 map.setValue(i, executableElement); |
| 14401 } | 14396 } |
| 14402 } | 14397 } |
| 14403 } | 14398 } |
| 14399 |
| 14400 /** |
| 14401 * Union all of the [lookupMaps] together into a single map, grouping the Exec
utableElements |
| 14402 * into a list where none of the elements are equal where equality is determin
ed by having equal |
| 14403 * function types. (We also take note too of the kind of the element: ()->int
and () -> int may |
| 14404 * not be equal if one is a getter and the other is a method.) |
| 14405 * |
| 14406 * @param lookupMaps the maps to be unioned together. |
| 14407 * @return the resulting union map. |
| 14408 */ |
| 14409 HashMap<String, List<ExecutableElement>> _unionInterfaceLookupMaps(List<Member
Map> lookupMaps) { |
| 14410 HashMap<String, List<ExecutableElement>> unionMap = new HashMap<String, List
<ExecutableElement>>(); |
| 14411 for (MemberMap lookupMap in lookupMaps) { |
| 14412 int lookupMapSize = lookupMap.size; |
| 14413 for (int i = 0; i < lookupMapSize; i++) { |
| 14414 // Get the string key, if null, break. |
| 14415 String key = lookupMap.getKey(i); |
| 14416 if (key == null) { |
| 14417 break; |
| 14418 } |
| 14419 // Get the list value out of the unionMap |
| 14420 List<ExecutableElement> list = unionMap[key]; |
| 14421 // If we haven't created such a map for this key yet, do create it and p
ut the list entry |
| 14422 // into the unionMap. |
| 14423 if (list == null) { |
| 14424 list = new List<ExecutableElement>(); |
| 14425 unionMap[key] = list; |
| 14426 } |
| 14427 // Fetch the entry out of this lookupMap |
| 14428 ExecutableElement newExecutableElementEntry = lookupMap.getValue(i); |
| 14429 if (list.isEmpty) { |
| 14430 // If the list is empty, just the new value |
| 14431 list.add(newExecutableElementEntry); |
| 14432 } else { |
| 14433 // Otherwise, only add the newExecutableElementEntry if it isn't alrea
dy in the list, this |
| 14434 // covers situation where a class inherits two methods (or two getters
) that are |
| 14435 // identical. |
| 14436 bool alreadyInList = false; |
| 14437 bool isMethod1 = newExecutableElementEntry is MethodElement; |
| 14438 for (ExecutableElement executableElementInList in list) { |
| 14439 bool isMethod2 = executableElementInList is MethodElement; |
| 14440 if (isMethod1 == isMethod2 && executableElementInList.type == newExe
cutableElementEntry.type) { |
| 14441 alreadyInList = true; |
| 14442 break; |
| 14443 } |
| 14444 } |
| 14445 if (!alreadyInList) { |
| 14446 list.add(newExecutableElementEntry); |
| 14447 } |
| 14448 } |
| 14449 } |
| 14450 } |
| 14451 return unionMap; |
| 14452 } |
| 14404 } | 14453 } |
| 14405 | 14454 |
| 14406 /** | 14455 /** |
| 14407 * Instances of the class `LabelScope` represent a scope in which a single label
is defined. | 14456 * Instances of the class `LabelScope` represent a scope in which a single label
is defined. |
| 14408 */ | 14457 */ |
| 14409 class LabelScope { | 14458 class LabelScope { |
| 14410 /** | 14459 /** |
| 14411 * The label scope enclosing this label scope. | 14460 * The label scope enclosing this label scope. |
| 14412 */ | 14461 */ |
| 14413 final LabelScope _outerScope; | 14462 final LabelScope _outerScope; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14503 LibraryElementImpl _libraryElement; | 14552 LibraryElementImpl _libraryElement; |
| 14504 | 14553 |
| 14505 /** | 14554 /** |
| 14506 * A list containing all of the libraries that are imported into this library. | 14555 * A list containing all of the libraries that are imported into this library. |
| 14507 */ | 14556 */ |
| 14508 List<Library> _importedLibraries = _EMPTY_ARRAY; | 14557 List<Library> _importedLibraries = _EMPTY_ARRAY; |
| 14509 | 14558 |
| 14510 /** | 14559 /** |
| 14511 * A table mapping URI-based directive to the actual URI value. | 14560 * A table mapping URI-based directive to the actual URI value. |
| 14512 */ | 14561 */ |
| 14513 Map<UriBasedDirective, String> _directiveUris = new Map<UriBasedDirective, Str
ing>(); | 14562 HashMap<UriBasedDirective, String> _directiveUris = new HashMap<UriBasedDirect
ive, String>(); |
| 14514 | 14563 |
| 14515 /** | 14564 /** |
| 14516 * A flag indicating whether this library explicitly imports core. | 14565 * A flag indicating whether this library explicitly imports core. |
| 14517 */ | 14566 */ |
| 14518 bool explicitlyImportsCore = false; | 14567 bool explicitlyImportsCore = false; |
| 14519 | 14568 |
| 14520 /** | 14569 /** |
| 14521 * A list containing all of the libraries that are exported from this library. | 14570 * A list containing all of the libraries that are exported from this library. |
| 14522 */ | 14571 */ |
| 14523 List<Library> _exportedLibraries = _EMPTY_ARRAY; | 14572 List<Library> _exportedLibraries = _EMPTY_ARRAY; |
| 14524 | 14573 |
| 14525 /** | 14574 /** |
| 14526 * A table mapping the sources for the compilation units in this library to th
eir corresponding | 14575 * A table mapping the sources for the compilation units in this library to th
eir corresponding |
| 14527 * AST structures. | 14576 * AST structures. |
| 14528 */ | 14577 */ |
| 14529 Map<Source, ResolvableCompilationUnit> _astMap = new Map<Source, ResolvableCom
pilationUnit>(); | 14578 HashMap<Source, ResolvableCompilationUnit> _astMap = new HashMap<Source, Resol
vableCompilationUnit>(); |
| 14530 | 14579 |
| 14531 /** | 14580 /** |
| 14532 * The library scope used when resolving elements within this library's compil
ation units. | 14581 * The library scope used when resolving elements within this library's compil
ation units. |
| 14533 */ | 14582 */ |
| 14534 LibraryScope _libraryScope; | 14583 LibraryScope _libraryScope; |
| 14535 | 14584 |
| 14536 /** | 14585 /** |
| 14537 * An empty array that can be used to initialize lists of libraries. | 14586 * An empty array that can be used to initialize lists of libraries. |
| 14538 */ | 14587 */ |
| 14539 static List<Library> _EMPTY_ARRAY = new List<Library>(0); | 14588 static List<Library> _EMPTY_ARRAY = new List<Library>(0); |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14971 } | 15020 } |
| 14972 | 15021 |
| 14973 /** | 15022 /** |
| 14974 * Add all of the non-synthetic getters and setters defined in the given compi
lation unit that | 15023 * Add all of the non-synthetic getters and setters defined in the given compi
lation unit that |
| 14975 * have no corresponding accessor to one of the given collections. | 15024 * have no corresponding accessor to one of the given collections. |
| 14976 * | 15025 * |
| 14977 * @param getters the map to which getters are to be added | 15026 * @param getters the map to which getters are to be added |
| 14978 * @param setters the list to which setters are to be added | 15027 * @param setters the list to which setters are to be added |
| 14979 * @param unit the compilation unit defining the accessors that are potentiall
y being added | 15028 * @param unit the compilation unit defining the accessors that are potentiall
y being added |
| 14980 */ | 15029 */ |
| 14981 void _collectAccessors(Map<String, PropertyAccessorElement> getters, List<Prop
ertyAccessorElement> setters, CompilationUnitElement unit) { | 15030 void _collectAccessors(HashMap<String, PropertyAccessorElement> getters, List<
PropertyAccessorElement> setters, CompilationUnitElement unit) { |
| 14982 for (PropertyAccessorElement accessor in unit.accessors) { | 15031 for (PropertyAccessorElement accessor in unit.accessors) { |
| 14983 if (accessor.isGetter) { | 15032 if (accessor.isGetter) { |
| 14984 if (!accessor.isSynthetic && accessor.correspondingSetter == null) { | 15033 if (!accessor.isSynthetic && accessor.correspondingSetter == null) { |
| 14985 getters[accessor.displayName] = accessor; | 15034 getters[accessor.displayName] = accessor; |
| 14986 } | 15035 } |
| 14987 } else { | 15036 } else { |
| 14988 if (!accessor.isSynthetic && accessor.correspondingGetter == null) { | 15037 if (!accessor.isSynthetic && accessor.correspondingGetter == null) { |
| 14989 setters.add(accessor); | 15038 setters.add(accessor); |
| 14990 } | 15039 } |
| 14991 } | 15040 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15032 } | 15081 } |
| 15033 | 15082 |
| 15034 /** | 15083 /** |
| 15035 * Look through all of the compilation units defined for the given library, lo
oking for getters | 15084 * Look through all of the compilation units defined for the given library, lo
oking for getters |
| 15036 * and setters that are defined in different compilation units but that have t
he same names. If | 15085 * and setters that are defined in different compilation units but that have t
he same names. If |
| 15037 * any are found, make sure that they have the same variable element. | 15086 * any are found, make sure that they have the same variable element. |
| 15038 * | 15087 * |
| 15039 * @param libraryElement the library defining the compilation units to be proc
essed | 15088 * @param libraryElement the library defining the compilation units to be proc
essed |
| 15040 */ | 15089 */ |
| 15041 void _patchTopLevelAccessors(LibraryElementImpl libraryElement) { | 15090 void _patchTopLevelAccessors(LibraryElementImpl libraryElement) { |
| 15042 Map<String, PropertyAccessorElement> getters = new Map<String, PropertyAcces
sorElement>(); | 15091 HashMap<String, PropertyAccessorElement> getters = new HashMap<String, Prope
rtyAccessorElement>(); |
| 15043 List<PropertyAccessorElement> setters = new List<PropertyAccessorElement>(); | 15092 List<PropertyAccessorElement> setters = new List<PropertyAccessorElement>(); |
| 15044 _collectAccessors(getters, setters, libraryElement.definingCompilationUnit); | 15093 _collectAccessors(getters, setters, libraryElement.definingCompilationUnit); |
| 15045 for (CompilationUnitElement unit in libraryElement.parts) { | 15094 for (CompilationUnitElement unit in libraryElement.parts) { |
| 15046 _collectAccessors(getters, setters, unit); | 15095 _collectAccessors(getters, setters, unit); |
| 15047 } | 15096 } |
| 15048 for (PropertyAccessorElement setter in setters) { | 15097 for (PropertyAccessorElement setter in setters) { |
| 15049 PropertyAccessorElement getter = getters[setter.displayName]; | 15098 PropertyAccessorElement getter = getters[setter.displayName]; |
| 15050 if (getter != null) { | 15099 if (getter != null) { |
| 15051 PropertyInducingElementImpl variable = getter.variable as PropertyInduci
ngElementImpl; | 15100 PropertyInducingElementImpl variable = getter.variable as PropertyInduci
ngElementImpl; |
| 15052 variable.setter = setter; | 15101 variable.setter = setter; |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15241 Library _coreLibrary; | 15290 Library _coreLibrary; |
| 15242 | 15291 |
| 15243 /** | 15292 /** |
| 15244 * The object used to access the types from the core library. | 15293 * The object used to access the types from the core library. |
| 15245 */ | 15294 */ |
| 15246 TypeProvider _typeProvider; | 15295 TypeProvider _typeProvider; |
| 15247 | 15296 |
| 15248 /** | 15297 /** |
| 15249 * A table mapping library sources to the information being maintained for tho
se libraries. | 15298 * A table mapping library sources to the information being maintained for tho
se libraries. |
| 15250 */ | 15299 */ |
| 15251 Map<Source, Library> _libraryMap = new Map<Source, Library>(); | 15300 HashMap<Source, Library> _libraryMap = new HashMap<Source, Library>(); |
| 15252 | 15301 |
| 15253 /** | 15302 /** |
| 15254 * A collection containing the libraries that are being resolved together. | 15303 * A collection containing the libraries that are being resolved together. |
| 15255 */ | 15304 */ |
| 15256 Set<Library> _librariesInCycles; | 15305 Set<Library> _librariesInCycles; |
| 15257 | 15306 |
| 15258 /** | 15307 /** |
| 15259 * Initialize a newly created library resolver to resolve libraries within the
given context. | 15308 * Initialize a newly created library resolver to resolve libraries within the
given context. |
| 15260 * | 15309 * |
| 15261 * @param analysisContext the analysis context in which the library is being a
nalyzed | 15310 * @param analysisContext the analysis context in which the library is being a
nalyzed |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15299 instrumentation.data3("fullName", librarySource.fullName); | 15348 instrumentation.data3("fullName", librarySource.fullName); |
| 15300 // | 15349 // |
| 15301 // Create the objects representing the library being resolved and the core
library. | 15350 // Create the objects representing the library being resolved and the core
library. |
| 15302 // | 15351 // |
| 15303 Library targetLibrary = _createLibraryWithUnit(librarySource, modification
Stamp, unit); | 15352 Library targetLibrary = _createLibraryWithUnit(librarySource, modification
Stamp, unit); |
| 15304 _coreLibrary = _libraryMap[_coreLibrarySource]; | 15353 _coreLibrary = _libraryMap[_coreLibrarySource]; |
| 15305 if (_coreLibrary == null) { | 15354 if (_coreLibrary == null) { |
| 15306 // This will be true unless the library being analyzed is the core libra
ry. | 15355 // This will be true unless the library being analyzed is the core libra
ry. |
| 15307 _coreLibrary = createLibrary(_coreLibrarySource); | 15356 _coreLibrary = createLibrary(_coreLibrarySource); |
| 15308 if (_coreLibrary == null) { | 15357 if (_coreLibrary == null) { |
| 15309 throw new AnalysisException("Core library does not exist"); | 15358 LibraryResolver2.missingCoreLibrary(analysisContext, _coreLibrarySourc
e); |
| 15310 } | 15359 } |
| 15311 } | 15360 } |
| 15312 instrumentation.metric3("createLibrary", "complete"); | 15361 instrumentation.metric3("createLibrary", "complete"); |
| 15313 // | 15362 // |
| 15314 // Compute the set of libraries that need to be resolved together. | 15363 // Compute the set of libraries that need to be resolved together. |
| 15315 // | 15364 // |
| 15316 _computeEmbeddedLibraryDependencies(targetLibrary, unit); | 15365 _computeEmbeddedLibraryDependencies(targetLibrary, unit); |
| 15317 _librariesInCycles = _computeLibrariesInCycles(targetLibrary); | 15366 _librariesInCycles = _computeLibrariesInCycles(targetLibrary); |
| 15318 // | 15367 // |
| 15319 // Build the element models representing the libraries being resolved. Thi
s is done in three | 15368 // Build the element models representing the libraries being resolved. Thi
s is done in three |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15383 instrumentation.data3("fullName", librarySource.fullName); | 15432 instrumentation.data3("fullName", librarySource.fullName); |
| 15384 // | 15433 // |
| 15385 // Create the objects representing the library being resolved and the core
library. | 15434 // Create the objects representing the library being resolved and the core
library. |
| 15386 // | 15435 // |
| 15387 Library targetLibrary = createLibrary(librarySource); | 15436 Library targetLibrary = createLibrary(librarySource); |
| 15388 _coreLibrary = _libraryMap[_coreLibrarySource]; | 15437 _coreLibrary = _libraryMap[_coreLibrarySource]; |
| 15389 if (_coreLibrary == null) { | 15438 if (_coreLibrary == null) { |
| 15390 // This will be true unless the library being analyzed is the core libra
ry. | 15439 // This will be true unless the library being analyzed is the core libra
ry. |
| 15391 _coreLibrary = _createLibraryOrNull(_coreLibrarySource); | 15440 _coreLibrary = _createLibraryOrNull(_coreLibrarySource); |
| 15392 if (_coreLibrary == null) { | 15441 if (_coreLibrary == null) { |
| 15393 throw new AnalysisException("Core library does not exist"); | 15442 LibraryResolver2.missingCoreLibrary(analysisContext, _coreLibrarySourc
e); |
| 15394 } | 15443 } |
| 15395 } | 15444 } |
| 15396 instrumentation.metric3("createLibrary", "complete"); | 15445 instrumentation.metric3("createLibrary", "complete"); |
| 15397 // | 15446 // |
| 15398 // Compute the set of libraries that need to be resolved together. | 15447 // Compute the set of libraries that need to be resolved together. |
| 15399 // | 15448 // |
| 15400 _computeLibraryDependencies(targetLibrary); | 15449 _computeLibraryDependencies(targetLibrary); |
| 15401 _librariesInCycles = _computeLibrariesInCycles(targetLibrary); | 15450 _librariesInCycles = _computeLibrariesInCycles(targetLibrary); |
| 15402 // | 15451 // |
| 15403 // Build the element models representing the libraries being resolved. Thi
s is done in three | 15452 // Build the element models representing the libraries being resolved. Thi
s is done in three |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15465 return library; | 15514 return library; |
| 15466 } | 15515 } |
| 15467 | 15516 |
| 15468 /** | 15517 /** |
| 15469 * Add a dependency to the given map from the referencing library to the refer
enced library. | 15518 * Add a dependency to the given map from the referencing library to the refer
enced library. |
| 15470 * | 15519 * |
| 15471 * @param dependencyMap the map to which the dependency is to be added | 15520 * @param dependencyMap the map to which the dependency is to be added |
| 15472 * @param referencingLibrary the library that references the referenced librar
y | 15521 * @param referencingLibrary the library that references the referenced librar
y |
| 15473 * @param referencedLibrary the library referenced by the referencing library | 15522 * @param referencedLibrary the library referenced by the referencing library |
| 15474 */ | 15523 */ |
| 15475 void _addDependencyToMap(Map<Library, List<Library>> dependencyMap, Library re
ferencingLibrary, Library referencedLibrary) { | 15524 void _addDependencyToMap(HashMap<Library, List<Library>> dependencyMap, Librar
y referencingLibrary, Library referencedLibrary) { |
| 15476 List<Library> dependentLibraries = dependencyMap[referencedLibrary]; | 15525 List<Library> dependentLibraries = dependencyMap[referencedLibrary]; |
| 15477 if (dependentLibraries == null) { | 15526 if (dependentLibraries == null) { |
| 15478 dependentLibraries = new List<Library>(); | 15527 dependentLibraries = new List<Library>(); |
| 15479 dependencyMap[referencedLibrary] = dependentLibraries; | 15528 dependencyMap[referencedLibrary] = dependentLibraries; |
| 15480 } | 15529 } |
| 15481 dependentLibraries.add(referencingLibrary); | 15530 dependentLibraries.add(referencingLibrary); |
| 15482 } | 15531 } |
| 15483 | 15532 |
| 15484 /** | 15533 /** |
| 15485 * Given a library that is part of a cycle that includes the root library, add
to the given set of | 15534 * Given a library that is part of a cycle that includes the root library, add
to the given set of |
| 15486 * libraries all of the libraries reachable from the root library that are als
o included in the | 15535 * libraries all of the libraries reachable from the root library that are als
o included in the |
| 15487 * cycle. | 15536 * cycle. |
| 15488 * | 15537 * |
| 15489 * @param library the library to be added to the collection of libraries in cy
cles | 15538 * @param library the library to be added to the collection of libraries in cy
cles |
| 15490 * @param librariesInCycle a collection of the libraries that are in the cycle | 15539 * @param librariesInCycle a collection of the libraries that are in the cycle |
| 15491 * @param dependencyMap a table mapping libraries to the collection of librari
es from which those | 15540 * @param dependencyMap a table mapping libraries to the collection of librari
es from which those |
| 15492 * libraries are referenced | 15541 * libraries are referenced |
| 15493 */ | 15542 */ |
| 15494 void _addLibrariesInCycle(Library library, Set<Library> librariesInCycle, Map<
Library, List<Library>> dependencyMap) { | 15543 void _addLibrariesInCycle(Library library, Set<Library> librariesInCycle, Hash
Map<Library, List<Library>> dependencyMap) { |
| 15495 if (librariesInCycle.add(library)) { | 15544 if (librariesInCycle.add(library)) { |
| 15496 List<Library> dependentLibraries = dependencyMap[library]; | 15545 List<Library> dependentLibraries = dependencyMap[library]; |
| 15497 if (dependentLibraries != null) { | 15546 if (dependentLibraries != null) { |
| 15498 for (Library dependentLibrary in dependentLibraries) { | 15547 for (Library dependentLibrary in dependentLibraries) { |
| 15499 _addLibrariesInCycle(dependentLibrary, librariesInCycle, dependencyMap
); | 15548 _addLibrariesInCycle(dependentLibrary, librariesInCycle, dependencyMap
); |
| 15500 } | 15549 } |
| 15501 } | 15550 } |
| 15502 } | 15551 } |
| 15503 } | 15552 } |
| 15504 | 15553 |
| 15505 /** | 15554 /** |
| 15506 * Add the given library, and all libraries reachable from it that have not al
ready been visited, | 15555 * Add the given library, and all libraries reachable from it that have not al
ready been visited, |
| 15507 * to the given dependency map. | 15556 * to the given dependency map. |
| 15508 * | 15557 * |
| 15509 * @param library the library currently being added to the dependency map | 15558 * @param library the library currently being added to the dependency map |
| 15510 * @param dependencyMap the dependency map being computed | 15559 * @param dependencyMap the dependency map being computed |
| 15511 * @param visitedLibraries the libraries that have already been visited, used
to prevent infinite | 15560 * @param visitedLibraries the libraries that have already been visited, used
to prevent infinite |
| 15512 * recursion | 15561 * recursion |
| 15513 */ | 15562 */ |
| 15514 void _addToDependencyMap(Library library, Map<Library, List<Library>> dependen
cyMap, Set<Library> visitedLibraries) { | 15563 void _addToDependencyMap(Library library, HashMap<Library, List<Library>> depe
ndencyMap, Set<Library> visitedLibraries) { |
| 15515 if (visitedLibraries.add(library)) { | 15564 if (visitedLibraries.add(library)) { |
| 15516 for (Library referencedLibrary in library.importsAndExports) { | 15565 for (Library referencedLibrary in library.importsAndExports) { |
| 15517 _addDependencyToMap(dependencyMap, library, referencedLibrary); | 15566 _addDependencyToMap(dependencyMap, library, referencedLibrary); |
| 15518 _addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries); | 15567 _addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries); |
| 15519 } | 15568 } |
| 15520 if (!library.explicitlyImportsCore && !identical(library, _coreLibrary)) { | 15569 if (!library.explicitlyImportsCore && !identical(library, _coreLibrary)) { |
| 15521 _addDependencyToMap(dependencyMap, library, _coreLibrary); | 15570 _addDependencyToMap(dependencyMap, library, _coreLibrary); |
| 15522 } | 15571 } |
| 15523 } | 15572 } |
| 15524 } | 15573 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 15549 | 15598 |
| 15550 /** | 15599 /** |
| 15551 * Every library now has a corresponding [LibraryElement], so it is now possib
le to resolve | 15600 * Every library now has a corresponding [LibraryElement], so it is now possib
le to resolve |
| 15552 * the import and export directives. | 15601 * the import and export directives. |
| 15553 * | 15602 * |
| 15554 * @throws AnalysisException if the defining compilation unit for any of the l
ibraries could not | 15603 * @throws AnalysisException if the defining compilation unit for any of the l
ibraries could not |
| 15555 * be accessed | 15604 * be accessed |
| 15556 */ | 15605 */ |
| 15557 void _buildDirectiveModels() { | 15606 void _buildDirectiveModels() { |
| 15558 for (Library library in _librariesInCycles) { | 15607 for (Library library in _librariesInCycles) { |
| 15559 Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixEle
mentImpl>(); | 15608 HashMap<String, PrefixElementImpl> nameToPrefixMap = new HashMap<String, P
refixElementImpl>(); |
| 15560 List<ImportElement> imports = new List<ImportElement>(); | 15609 List<ImportElement> imports = new List<ImportElement>(); |
| 15561 List<ExportElement> exports = new List<ExportElement>(); | 15610 List<ExportElement> exports = new List<ExportElement>(); |
| 15562 for (Directive directive in library.definingCompilationUnit.directives) { | 15611 for (Directive directive in library.definingCompilationUnit.directives) { |
| 15563 if (directive is ImportDirective) { | 15612 if (directive is ImportDirective) { |
| 15564 ImportDirective importDirective = directive; | 15613 ImportDirective importDirective = directive; |
| 15565 String uriContent = importDirective.uriContent; | 15614 String uriContent = importDirective.uriContent; |
| 15566 if (DartUriResolver.isDartExtUri(uriContent)) { | 15615 if (DartUriResolver.isDartExtUri(uriContent)) { |
| 15567 library.libraryElement.hasExtUri = true; | 15616 library.libraryElement.hasExtUri = true; |
| 15568 } | 15617 } |
| 15569 Source importedSource = importDirective.source; | 15618 Source importedSource = importDirective.source; |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15685 * Compute a dependency map of libraries reachable from the given library. A d
ependency map is a | 15734 * Compute a dependency map of libraries reachable from the given library. A d
ependency map is a |
| 15686 * table that maps individual libraries to a list of the libraries that either
import or export | 15735 * table that maps individual libraries to a list of the libraries that either
import or export |
| 15687 * those libraries. | 15736 * those libraries. |
| 15688 * | 15737 * |
| 15689 * This map is used to compute all of the libraries involved in a cycle that i
nclude the root | 15738 * This map is used to compute all of the libraries involved in a cycle that i
nclude the root |
| 15690 * library. Given that we only add libraries that are reachable from the root
library, when we | 15739 * library. Given that we only add libraries that are reachable from the root
library, when we |
| 15691 * work backward we are guaranteed to only get libraries in the cycle. | 15740 * work backward we are guaranteed to only get libraries in the cycle. |
| 15692 * | 15741 * |
| 15693 * @param library the library currently being added to the dependency map | 15742 * @param library the library currently being added to the dependency map |
| 15694 */ | 15743 */ |
| 15695 Map<Library, List<Library>> _computeDependencyMap(Library library) { | 15744 HashMap<Library, List<Library>> _computeDependencyMap(Library library) { |
| 15696 Map<Library, List<Library>> dependencyMap = new Map<Library, List<Library>>(
); | 15745 HashMap<Library, List<Library>> dependencyMap = new HashMap<Library, List<Li
brary>>(); |
| 15697 _addToDependencyMap(library, dependencyMap, new Set<Library>()); | 15746 _addToDependencyMap(library, dependencyMap, new Set<Library>()); |
| 15698 return dependencyMap; | 15747 return dependencyMap; |
| 15699 } | 15748 } |
| 15700 | 15749 |
| 15701 /** | 15750 /** |
| 15702 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the | 15751 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the |
| 15703 * class [Library] to represent them, and record the references in the library
objects. | 15752 * class [Library] to represent them, and record the references in the library
objects. |
| 15704 * | 15753 * |
| 15705 * @param library the library to be processed to find libraries that have not
yet been traversed | 15754 * @param library the library to be processed to find libraries that have not
yet been traversed |
| 15706 * @throws AnalysisException if some portion of the library graph could not be
traversed | 15755 * @throws AnalysisException if some portion of the library graph could not be
traversed |
| (...skipping 20 matching lines...) Expand all Loading... |
| 15727 | 15776 |
| 15728 /** | 15777 /** |
| 15729 * Return a collection containing all of the libraries reachable from the give
n library that are | 15778 * Return a collection containing all of the libraries reachable from the give
n library that are |
| 15730 * contained in a cycle that includes the given library. | 15779 * contained in a cycle that includes the given library. |
| 15731 * | 15780 * |
| 15732 * @param library the library that must be included in any cycles whose member
s are to be returned | 15781 * @param library the library that must be included in any cycles whose member
s are to be returned |
| 15733 * @return all of the libraries referenced by the given library that have a ci
rcular reference | 15782 * @return all of the libraries referenced by the given library that have a ci
rcular reference |
| 15734 * back to the given library | 15783 * back to the given library |
| 15735 */ | 15784 */ |
| 15736 Set<Library> _computeLibrariesInCycles(Library library) { | 15785 Set<Library> _computeLibrariesInCycles(Library library) { |
| 15737 Map<Library, List<Library>> dependencyMap = _computeDependencyMap(library); | 15786 HashMap<Library, List<Library>> dependencyMap = _computeDependencyMap(librar
y); |
| 15738 Set<Library> librariesInCycle = new Set<Library>(); | 15787 Set<Library> librariesInCycle = new Set<Library>(); |
| 15739 _addLibrariesInCycle(library, librariesInCycle, dependencyMap); | 15788 _addLibrariesInCycle(library, librariesInCycle, dependencyMap); |
| 15740 return librariesInCycle; | 15789 return librariesInCycle; |
| 15741 } | 15790 } |
| 15742 | 15791 |
| 15743 /** | 15792 /** |
| 15744 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the | 15793 * Recursively traverse the libraries reachable from the given library, creati
ng instances of the |
| 15745 * class [Library] to represent them, and record the references in the library
objects. | 15794 * class [Library] to represent them, and record the references in the library
objects. |
| 15746 * | 15795 * |
| 15747 * @param library the library to be processed to find libraries that have not
yet been traversed | 15796 * @param library the library to be processed to find libraries that have not
yet been traversed |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15955 return analysisContext.sourceFactory.resolveUri(librarySource, uriContent); | 16004 return analysisContext.sourceFactory.resolveUri(librarySource, uriContent); |
| 15956 } | 16005 } |
| 15957 } | 16006 } |
| 15958 | 16007 |
| 15959 /** | 16008 /** |
| 15960 * Instances of the class `LibraryResolver` are used to resolve one or more mutu
ally dependent | 16009 * Instances of the class `LibraryResolver` are used to resolve one or more mutu
ally dependent |
| 15961 * libraries within a single context. | 16010 * libraries within a single context. |
| 15962 */ | 16011 */ |
| 15963 class LibraryResolver2 { | 16012 class LibraryResolver2 { |
| 15964 /** | 16013 /** |
| 16014 * Report that the core library could not be resolved in the given analysis co
ntext and throw an |
| 16015 * exception. |
| 16016 * |
| 16017 * @param analysisContext the analysis context in which the failure occurred |
| 16018 * @param coreLibrarySource the source representing the core library |
| 16019 * @throws AnalysisException always |
| 16020 */ |
| 16021 static void missingCoreLibrary(AnalysisContext analysisContext, Source coreLib
rarySource) { |
| 16022 throw new AnalysisException("Could not resolve dart:core"); |
| 16023 } |
| 16024 |
| 16025 /** |
| 15965 * The analysis context in which the libraries are being analyzed. | 16026 * The analysis context in which the libraries are being analyzed. |
| 15966 */ | 16027 */ |
| 15967 final InternalAnalysisContext analysisContext; | 16028 final InternalAnalysisContext analysisContext; |
| 15968 | 16029 |
| 15969 /** | 16030 /** |
| 15970 * The listener to which analysis errors will be reported, this error listener
is either | 16031 * The listener to which analysis errors will be reported, this error listener
is either |
| 15971 * references [recordingErrorListener], or it unions the passed | 16032 * references [recordingErrorListener], or it unions the passed |
| 15972 * [AnalysisErrorListener] with the [recordingErrorListener]. | 16033 * [AnalysisErrorListener] with the [recordingErrorListener]. |
| 15973 */ | 16034 */ |
| 15974 RecordingErrorListener _errorListener; | 16035 RecordingErrorListener _errorListener; |
| 15975 | 16036 |
| 15976 /** | 16037 /** |
| 15977 * A source object representing the core library (dart:core). | 16038 * A source object representing the core library (dart:core). |
| 15978 */ | 16039 */ |
| 15979 Source _coreLibrarySource; | 16040 Source _coreLibrarySource; |
| 15980 | 16041 |
| 15981 /** | 16042 /** |
| 15982 * The object representing the core library. | 16043 * The object representing the core library. |
| 15983 */ | 16044 */ |
| 15984 ResolvableLibrary _coreLibrary; | 16045 ResolvableLibrary _coreLibrary; |
| 15985 | 16046 |
| 15986 /** | 16047 /** |
| 15987 * The object used to access the types from the core library. | 16048 * The object used to access the types from the core library. |
| 15988 */ | 16049 */ |
| 15989 TypeProvider _typeProvider; | 16050 TypeProvider _typeProvider; |
| 15990 | 16051 |
| 15991 /** | 16052 /** |
| 15992 * A table mapping library sources to the information being maintained for tho
se libraries. | 16053 * A table mapping library sources to the information being maintained for tho
se libraries. |
| 15993 */ | 16054 */ |
| 15994 Map<Source, ResolvableLibrary> _libraryMap = new Map<Source, ResolvableLibrary
>(); | 16055 HashMap<Source, ResolvableLibrary> _libraryMap = new HashMap<Source, Resolvabl
eLibrary>(); |
| 15995 | 16056 |
| 15996 /** | 16057 /** |
| 15997 * A collection containing the libraries that are being resolved together. | 16058 * A collection containing the libraries that are being resolved together. |
| 15998 */ | 16059 */ |
| 15999 List<ResolvableLibrary> _librariesInCycle; | 16060 List<ResolvableLibrary> _librariesInCycle; |
| 16000 | 16061 |
| 16001 /** | 16062 /** |
| 16002 * Initialize a newly created library resolver to resolve libraries within the
given context. | 16063 * Initialize a newly created library resolver to resolve libraries within the
given context. |
| 16003 * | 16064 * |
| 16004 * @param analysisContext the analysis context in which the library is being a
nalyzed | 16065 * @param analysisContext the analysis context in which the library is being a
nalyzed |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16058 // elements built for the referenced libraries, but because of the poss
ibility of circular | 16119 // elements built for the referenced libraries, but because of the poss
ibility of circular |
| 16059 // references needs to happen after all of the library elements have be
en created. | 16120 // references needs to happen after all of the library elements have be
en created. |
| 16060 // 3. Build the rest of the type model by connecting superclasses, mixins,
and interfaces. This | 16121 // 3. Build the rest of the type model by connecting superclasses, mixins,
and interfaces. This |
| 16061 // requires that we be able to compute the names visible in the librari
es being resolved, | 16122 // requires that we be able to compute the names visible in the librari
es being resolved, |
| 16062 // which in turn requires that we have resolved the import directives. | 16123 // which in turn requires that we have resolved the import directives. |
| 16063 // | 16124 // |
| 16064 _buildElementModels(); | 16125 _buildElementModels(); |
| 16065 instrumentation.metric3("buildElementModels", "complete"); | 16126 instrumentation.metric3("buildElementModels", "complete"); |
| 16066 LibraryElement coreElement = _coreLibrary.libraryElement; | 16127 LibraryElement coreElement = _coreLibrary.libraryElement; |
| 16067 if (coreElement == null) { | 16128 if (coreElement == null) { |
| 16068 throw new AnalysisException("Could not resolve dart:core"); | 16129 missingCoreLibrary(analysisContext, _coreLibrarySource); |
| 16069 } | 16130 } |
| 16070 _buildDirectiveModels(); | 16131 _buildDirectiveModels(); |
| 16071 instrumentation.metric3("buildDirectiveModels", "complete"); | 16132 instrumentation.metric3("buildDirectiveModels", "complete"); |
| 16072 _typeProvider = new TypeProviderImpl(coreElement); | 16133 _typeProvider = new TypeProviderImpl(coreElement); |
| 16073 _buildTypeHierarchies(); | 16134 _buildTypeHierarchies(); |
| 16074 instrumentation.metric3("buildTypeHierarchies", "complete"); | 16135 instrumentation.metric3("buildTypeHierarchies", "complete"); |
| 16075 // | 16136 // |
| 16076 // Perform resolution and type analysis. | 16137 // Perform resolution and type analysis. |
| 16077 // | 16138 // |
| 16078 // TODO(brianwilkerson) Decide whether we want to resolve all of the libra
ries or whether we | 16139 // TODO(brianwilkerson) Decide whether we want to resolve all of the libra
ries or whether we |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16125 | 16186 |
| 16126 /** | 16187 /** |
| 16127 * Every library now has a corresponding [LibraryElement], so it is now possib
le to resolve | 16188 * Every library now has a corresponding [LibraryElement], so it is now possib
le to resolve |
| 16128 * the import and export directives. | 16189 * the import and export directives. |
| 16129 * | 16190 * |
| 16130 * @throws AnalysisException if the defining compilation unit for any of the l
ibraries could not | 16191 * @throws AnalysisException if the defining compilation unit for any of the l
ibraries could not |
| 16131 * be accessed | 16192 * be accessed |
| 16132 */ | 16193 */ |
| 16133 void _buildDirectiveModels() { | 16194 void _buildDirectiveModels() { |
| 16134 for (ResolvableLibrary library in _librariesInCycle) { | 16195 for (ResolvableLibrary library in _librariesInCycle) { |
| 16135 Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixEle
mentImpl>(); | 16196 HashMap<String, PrefixElementImpl> nameToPrefixMap = new HashMap<String, P
refixElementImpl>(); |
| 16136 List<ImportElement> imports = new List<ImportElement>(); | 16197 List<ImportElement> imports = new List<ImportElement>(); |
| 16137 List<ExportElement> exports = new List<ExportElement>(); | 16198 List<ExportElement> exports = new List<ExportElement>(); |
| 16138 for (Directive directive in library.definingCompilationUnit.directives) { | 16199 for (Directive directive in library.definingCompilationUnit.directives) { |
| 16139 if (directive is ImportDirective) { | 16200 if (directive is ImportDirective) { |
| 16140 ImportDirective importDirective = directive; | 16201 ImportDirective importDirective = directive; |
| 16141 String uriContent = importDirective.uriContent; | 16202 String uriContent = importDirective.uriContent; |
| 16142 if (DartUriResolver.isDartExtUri(uriContent)) { | 16203 if (DartUriResolver.isDartExtUri(uriContent)) { |
| 16143 library.libraryElement.hasExtUri = true; | 16204 library.libraryElement.hasExtUri = true; |
| 16144 } | 16205 } |
| 16145 Source importedSource = importDirective.source; | 16206 Source importedSource = importDirective.source; |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16234 * @throws AnalysisException if any of the element models cannot be built | 16295 * @throws AnalysisException if any of the element models cannot be built |
| 16235 */ | 16296 */ |
| 16236 void _buildElementModels() { | 16297 void _buildElementModels() { |
| 16237 for (ResolvableLibrary library in _librariesInCycle) { | 16298 for (ResolvableLibrary library in _librariesInCycle) { |
| 16238 LibraryElementBuilder builder = new LibraryElementBuilder(analysisContext,
errorListener); | 16299 LibraryElementBuilder builder = new LibraryElementBuilder(analysisContext,
errorListener); |
| 16239 LibraryElementImpl libraryElement = builder.buildLibrary2(library); | 16300 LibraryElementImpl libraryElement = builder.buildLibrary2(library); |
| 16240 library.libraryElement = libraryElement; | 16301 library.libraryElement = libraryElement; |
| 16241 } | 16302 } |
| 16242 } | 16303 } |
| 16243 | 16304 |
| 16244 Map<Source, ResolvableLibrary> _buildLibraryMap() { | 16305 HashMap<Source, ResolvableLibrary> _buildLibraryMap() { |
| 16245 Map<Source, ResolvableLibrary> libraryMap = new Map<Source, ResolvableLibrar
y>(); | 16306 HashMap<Source, ResolvableLibrary> libraryMap = new HashMap<Source, Resolvab
leLibrary>(); |
| 16246 int libraryCount = _librariesInCycle.length; | 16307 int libraryCount = _librariesInCycle.length; |
| 16247 for (int i = 0; i < libraryCount; i++) { | 16308 for (int i = 0; i < libraryCount; i++) { |
| 16248 ResolvableLibrary library = _librariesInCycle[i]; | 16309 ResolvableLibrary library = _librariesInCycle[i]; |
| 16249 library.errorListener = _errorListener; | 16310 library.errorListener = _errorListener; |
| 16250 libraryMap[library.librarySource] = library; | 16311 libraryMap[library.librarySource] = library; |
| 16251 List<ResolvableLibrary> dependencies = library.importsAndExports; | 16312 List<ResolvableLibrary> dependencies = library.importsAndExports; |
| 16252 int dependencyCount = dependencies.length; | 16313 int dependencyCount = dependencies.length; |
| 16253 for (int j = 0; j < dependencyCount; j++) { | 16314 for (int j = 0; j < dependencyCount; j++) { |
| 16254 ResolvableLibrary dependency = dependencies[j]; | 16315 ResolvableLibrary dependency = dependencies[j]; |
| 16255 //dependency.setErrorListener(errorListener); | 16316 //dependency.setErrorListener(errorListener); |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16608 | 16669 |
| 16609 /** | 16670 /** |
| 16610 * Instances of the class `Namespace` implement a mapping of identifiers to the
elements | 16671 * Instances of the class `Namespace` implement a mapping of identifiers to the
elements |
| 16611 * represented by those identifiers. Namespaces are the building blocks for scop
es. | 16672 * represented by those identifiers. Namespaces are the building blocks for scop
es. |
| 16612 */ | 16673 */ |
| 16613 class Namespace { | 16674 class Namespace { |
| 16614 /** | 16675 /** |
| 16615 * A table mapping names that are defined in this namespace to the element rep
resenting the thing | 16676 * A table mapping names that are defined in this namespace to the element rep
resenting the thing |
| 16616 * declared with that name. | 16677 * declared with that name. |
| 16617 */ | 16678 */ |
| 16618 final Map<String, Element> _definedNames; | 16679 final HashMap<String, Element> _definedNames; |
| 16619 | 16680 |
| 16620 /** | 16681 /** |
| 16621 * An empty namespace. | 16682 * An empty namespace. |
| 16622 */ | 16683 */ |
| 16623 static Namespace EMPTY = new Namespace(new Map<String, Element>()); | 16684 static Namespace EMPTY = new Namespace(new HashMap<String, Element>()); |
| 16624 | 16685 |
| 16625 /** | 16686 /** |
| 16626 * Initialize a newly created namespace to have the given defined names. | 16687 * Initialize a newly created namespace to have the given defined names. |
| 16627 * | 16688 * |
| 16628 * @param definedNames the mapping from names that are defined in this namespa
ce to the | 16689 * @param definedNames the mapping from names that are defined in this namespa
ce to the |
| 16629 * corresponding elements | 16690 * corresponding elements |
| 16630 */ | 16691 */ |
| 16631 Namespace(this._definedNames); | 16692 Namespace(this._definedNames); |
| 16632 | 16693 |
| 16633 /** | 16694 /** |
| 16634 * Return the element in this namespace that is available to the containing sc
ope using the given | 16695 * Return the element in this namespace that is available to the containing sc
ope using the given |
| 16635 * name. | 16696 * name. |
| 16636 * | 16697 * |
| 16637 * @param name the name used to reference the | 16698 * @param name the name used to reference the |
| 16638 * @return the element represented by the given identifier | 16699 * @return the element represented by the given identifier |
| 16639 */ | 16700 */ |
| 16640 Element get(String name) => _definedNames[name]; | 16701 Element get(String name) => _definedNames[name]; |
| 16641 | 16702 |
| 16642 /** | 16703 /** |
| 16643 * Return a table containing the same mappings as those defined by this namesp
ace. | 16704 * Return a table containing the same mappings as those defined by this namesp
ace. |
| 16644 * | 16705 * |
| 16645 * @return a table containing the same mappings as those defined by this names
pace | 16706 * @return a table containing the same mappings as those defined by this names
pace |
| 16646 */ | 16707 */ |
| 16647 Map<String, Element> get definedNames => new Map<String, Element>.from(_define
dNames); | 16708 Map<String, Element> get definedNames => new HashMap<String, Element>.from(_de
finedNames); |
| 16648 } | 16709 } |
| 16649 | 16710 |
| 16650 /** | 16711 /** |
| 16651 * Instances of the class `NamespaceBuilder` are used to build a `Namespace`. Na
mespace | 16712 * Instances of the class `NamespaceBuilder` are used to build a `Namespace`. Na
mespace |
| 16652 * builders are thread-safe and re-usable. | 16713 * builders are thread-safe and re-usable. |
| 16653 */ | 16714 */ |
| 16654 class NamespaceBuilder { | 16715 class NamespaceBuilder { |
| 16655 /** | 16716 /** |
| 16656 * Create a namespace representing the export namespace of the given [ExportEl
ement]. | 16717 * Create a namespace representing the export namespace of the given [ExportEl
ement]. |
| 16657 * | 16718 * |
| 16658 * @param element the export element whose export namespace is to be created | 16719 * @param element the export element whose export namespace is to be created |
| 16659 * @return the export namespace that was created | 16720 * @return the export namespace that was created |
| 16660 */ | 16721 */ |
| 16661 Namespace createExportNamespaceForDirective(ExportElement element) { | 16722 Namespace createExportNamespaceForDirective(ExportElement element) { |
| 16662 LibraryElement exportedLibrary = element.exportedLibrary; | 16723 LibraryElement exportedLibrary = element.exportedLibrary; |
| 16663 if (exportedLibrary == null) { | 16724 if (exportedLibrary == null) { |
| 16664 // | 16725 // |
| 16665 // The exported library will be null if the URI does not reference a valid
library. | 16726 // The exported library will be null if the URI does not reference a valid
library. |
| 16666 // | 16727 // |
| 16667 return Namespace.EMPTY; | 16728 return Namespace.EMPTY; |
| 16668 } | 16729 } |
| 16669 Map<String, Element> definedNames = _createExportMapping(exportedLibrary, ne
w Set<LibraryElement>()); | 16730 HashMap<String, Element> definedNames = _createExportMapping(exportedLibrary
, new Set<LibraryElement>()); |
| 16670 definedNames = _applyCombinators(definedNames, element.combinators); | 16731 definedNames = _applyCombinators(definedNames, element.combinators); |
| 16671 return new Namespace(definedNames); | 16732 return new Namespace(definedNames); |
| 16672 } | 16733 } |
| 16673 | 16734 |
| 16674 /** | 16735 /** |
| 16675 * Create a namespace representing the export namespace of the given library. | 16736 * Create a namespace representing the export namespace of the given library. |
| 16676 * | 16737 * |
| 16677 * @param library the library whose export namespace is to be created | 16738 * @param library the library whose export namespace is to be created |
| 16678 * @return the export namespace that was created | 16739 * @return the export namespace that was created |
| 16679 */ | 16740 */ |
| 16680 Namespace createExportNamespaceForLibrary(LibraryElement library) => new Names
pace(_createExportMapping(library, new Set<LibraryElement>())); | 16741 Namespace createExportNamespaceForLibrary(LibraryElement library) => new Names
pace(_createExportMapping(library, new Set<LibraryElement>())); |
| 16681 | 16742 |
| 16682 /** | 16743 /** |
| 16683 * Create a namespace representing the import namespace of the given library. | 16744 * Create a namespace representing the import namespace of the given library. |
| 16684 * | 16745 * |
| 16685 * @param library the library whose import namespace is to be created | 16746 * @param library the library whose import namespace is to be created |
| 16686 * @return the import namespace that was created | 16747 * @return the import namespace that was created |
| 16687 */ | 16748 */ |
| 16688 Namespace createImportNamespaceForDirective(ImportElement element) { | 16749 Namespace createImportNamespaceForDirective(ImportElement element) { |
| 16689 LibraryElement importedLibrary = element.importedLibrary; | 16750 LibraryElement importedLibrary = element.importedLibrary; |
| 16690 if (importedLibrary == null) { | 16751 if (importedLibrary == null) { |
| 16691 // | 16752 // |
| 16692 // The imported library will be null if the URI does not reference a valid
library. | 16753 // The imported library will be null if the URI does not reference a valid
library. |
| 16693 // | 16754 // |
| 16694 return Namespace.EMPTY; | 16755 return Namespace.EMPTY; |
| 16695 } | 16756 } |
| 16696 Map<String, Element> definedNames = _createExportMapping(importedLibrary, ne
w Set<LibraryElement>()); | 16757 HashMap<String, Element> definedNames = _createExportMapping(importedLibrary
, new Set<LibraryElement>()); |
| 16697 definedNames = _applyCombinators(definedNames, element.combinators); | 16758 definedNames = _applyCombinators(definedNames, element.combinators); |
| 16698 definedNames = _applyPrefix(definedNames, element.prefix); | 16759 definedNames = _applyPrefix(definedNames, element.prefix); |
| 16699 return new Namespace(definedNames); | 16760 return new Namespace(definedNames); |
| 16700 } | 16761 } |
| 16701 | 16762 |
| 16702 /** | 16763 /** |
| 16703 * Create a namespace representing the public namespace of the given library. | 16764 * Create a namespace representing the public namespace of the given library. |
| 16704 * | 16765 * |
| 16705 * @param library the library whose public namespace is to be created | 16766 * @param library the library whose public namespace is to be created |
| 16706 * @return the public namespace that was created | 16767 * @return the public namespace that was created |
| 16707 */ | 16768 */ |
| 16708 Namespace createPublicNamespaceForLibrary(LibraryElement library) { | 16769 Namespace createPublicNamespaceForLibrary(LibraryElement library) { |
| 16709 Map<String, Element> definedNames = new Map<String, Element>(); | 16770 HashMap<String, Element> definedNames = new HashMap<String, Element>(); |
| 16710 _addPublicNames(definedNames, library.definingCompilationUnit); | 16771 _addPublicNames(definedNames, library.definingCompilationUnit); |
| 16711 for (CompilationUnitElement compilationUnit in library.parts) { | 16772 for (CompilationUnitElement compilationUnit in library.parts) { |
| 16712 _addPublicNames(definedNames, compilationUnit); | 16773 _addPublicNames(definedNames, compilationUnit); |
| 16713 } | 16774 } |
| 16714 return new Namespace(definedNames); | 16775 return new Namespace(definedNames); |
| 16715 } | 16776 } |
| 16716 | 16777 |
| 16717 /** | 16778 /** |
| 16718 * Add all of the names in the given namespace to the given mapping table. | 16779 * Add all of the names in the given namespace to the given mapping table. |
| 16719 * | 16780 * |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16773 _addIfPublic(definedNames, element); | 16834 _addIfPublic(definedNames, element); |
| 16774 } | 16835 } |
| 16775 } | 16836 } |
| 16776 | 16837 |
| 16777 /** | 16838 /** |
| 16778 * Apply the given combinators to all of the names in the given mapping table. | 16839 * Apply the given combinators to all of the names in the given mapping table. |
| 16779 * | 16840 * |
| 16780 * @param definedNames the mapping table to which the namespace operations are
to be applied | 16841 * @param definedNames the mapping table to which the namespace operations are
to be applied |
| 16781 * @param combinators the combinators to be applied | 16842 * @param combinators the combinators to be applied |
| 16782 */ | 16843 */ |
| 16783 Map<String, Element> _applyCombinators(Map<String, Element> definedNames, List
<NamespaceCombinator> combinators) { | 16844 HashMap<String, Element> _applyCombinators(HashMap<String, Element> definedNam
es, List<NamespaceCombinator> combinators) { |
| 16784 for (NamespaceCombinator combinator in combinators) { | 16845 for (NamespaceCombinator combinator in combinators) { |
| 16785 if (combinator is HideElementCombinator) { | 16846 if (combinator is HideElementCombinator) { |
| 16786 _hide(definedNames, combinator.hiddenNames); | 16847 _hide(definedNames, combinator.hiddenNames); |
| 16787 } else if (combinator is ShowElementCombinator) { | 16848 } else if (combinator is ShowElementCombinator) { |
| 16788 definedNames = _show(definedNames, combinator.shownNames); | 16849 definedNames = _show(definedNames, combinator.shownNames); |
| 16789 } else { | 16850 } else { |
| 16790 // Internal error. | 16851 // Internal error. |
| 16791 AnalysisEngine.instance.logger.logError("Unknown type of combinator: ${c
ombinator.runtimeType.toString()}"); | 16852 AnalysisEngine.instance.logger.logError("Unknown type of combinator: ${c
ombinator.runtimeType.toString()}"); |
| 16792 } | 16853 } |
| 16793 } | 16854 } |
| 16794 return definedNames; | 16855 return definedNames; |
| 16795 } | 16856 } |
| 16796 | 16857 |
| 16797 /** | 16858 /** |
| 16798 * Apply the given prefix to all of the names in the table of defined names. | 16859 * Apply the given prefix to all of the names in the table of defined names. |
| 16799 * | 16860 * |
| 16800 * @param definedNames the names that were defined before this operation | 16861 * @param definedNames the names that were defined before this operation |
| 16801 * @param prefixElement the element defining the prefix to be added to the nam
es | 16862 * @param prefixElement the element defining the prefix to be added to the nam
es |
| 16802 */ | 16863 */ |
| 16803 Map<String, Element> _applyPrefix(Map<String, Element> definedNames, PrefixEle
ment prefixElement) { | 16864 HashMap<String, Element> _applyPrefix(HashMap<String, Element> definedNames, P
refixElement prefixElement) { |
| 16804 if (prefixElement != null) { | 16865 if (prefixElement != null) { |
| 16805 String prefix = prefixElement.name; | 16866 String prefix = prefixElement.name; |
| 16806 Map<String, Element> newNames = new Map<String, Element>(); | 16867 HashMap<String, Element> newNames = new HashMap<String, Element>(); |
| 16807 for (MapEntry<String, Element> entry in getMapEntrySet(definedNames)) { | 16868 for (MapEntry<String, Element> entry in getMapEntrySet(definedNames)) { |
| 16808 newNames["${prefix}.${entry.getKey()}"] = entry.getValue(); | 16869 newNames["${prefix}.${entry.getKey()}"] = entry.getValue(); |
| 16809 } | 16870 } |
| 16810 return newNames; | 16871 return newNames; |
| 16811 } else { | 16872 } else { |
| 16812 return definedNames; | 16873 return definedNames; |
| 16813 } | 16874 } |
| 16814 } | 16875 } |
| 16815 | 16876 |
| 16816 /** | 16877 /** |
| 16817 * Create a mapping table representing the export namespace of the given libra
ry. | 16878 * Create a mapping table representing the export namespace of the given libra
ry. |
| 16818 * | 16879 * |
| 16819 * @param library the library whose public namespace is to be created | 16880 * @param library the library whose public namespace is to be created |
| 16820 * @param visitedElements a set of libraries that do not need to be visited wh
en processing the | 16881 * @param visitedElements a set of libraries that do not need to be visited wh
en processing the |
| 16821 * export directives of the given library because all of the names de
fined by them will | 16882 * export directives of the given library because all of the names de
fined by them will |
| 16822 * be added by another library | 16883 * be added by another library |
| 16823 * @return the mapping table that was created | 16884 * @return the mapping table that was created |
| 16824 */ | 16885 */ |
| 16825 Map<String, Element> _createExportMapping(LibraryElement library, Set<LibraryE
lement> visitedElements) { | 16886 HashMap<String, Element> _createExportMapping(LibraryElement library, Set<Libr
aryElement> visitedElements) { |
| 16826 visitedElements.add(library); | 16887 visitedElements.add(library); |
| 16827 try { | 16888 try { |
| 16828 Map<String, Element> definedNames = new Map<String, Element>(); | 16889 HashMap<String, Element> definedNames = new HashMap<String, Element>(); |
| 16829 for (ExportElement element in library.exports) { | 16890 for (ExportElement element in library.exports) { |
| 16830 LibraryElement exportedLibrary = element.exportedLibrary; | 16891 LibraryElement exportedLibrary = element.exportedLibrary; |
| 16831 if (exportedLibrary != null && !visitedElements.contains(exportedLibrary
)) { | 16892 if (exportedLibrary != null && !visitedElements.contains(exportedLibrary
)) { |
| 16832 // | 16893 // |
| 16833 // The exported library will be null if the URI does not reference a v
alid library. | 16894 // The exported library will be null if the URI does not reference a v
alid library. |
| 16834 // | 16895 // |
| 16835 Map<String, Element> exportedNames = _createExportMapping(exportedLibr
ary, visitedElements); | 16896 HashMap<String, Element> exportedNames = _createExportMapping(exported
Library, visitedElements); |
| 16836 exportedNames = _applyCombinators(exportedNames, element.combinators); | 16897 exportedNames = _applyCombinators(exportedNames, element.combinators); |
| 16837 _addAllFromMap(definedNames, exportedNames); | 16898 _addAllFromMap(definedNames, exportedNames); |
| 16838 } | 16899 } |
| 16839 } | 16900 } |
| 16840 _addAllFromNamespace(definedNames, (library.context as InternalAnalysisCon
text).getPublicNamespace(library)); | 16901 _addAllFromNamespace(definedNames, (library.context as InternalAnalysisCon
text).getPublicNamespace(library)); |
| 16841 return definedNames; | 16902 return definedNames; |
| 16842 } finally { | 16903 } finally { |
| 16843 visitedElements.remove(library); | 16904 visitedElements.remove(library); |
| 16844 } | 16905 } |
| 16845 } | 16906 } |
| 16846 | 16907 |
| 16847 /** | 16908 /** |
| 16848 * Hide all of the given names by removing them from the given collection of d
efined names. | 16909 * Hide all of the given names by removing them from the given collection of d
efined names. |
| 16849 * | 16910 * |
| 16850 * @param definedNames the names that were defined before this operation | 16911 * @param definedNames the names that were defined before this operation |
| 16851 * @param hiddenNames the names to be hidden | 16912 * @param hiddenNames the names to be hidden |
| 16852 */ | 16913 */ |
| 16853 void _hide(Map<String, Element> definedNames, List<String> hiddenNames) { | 16914 void _hide(HashMap<String, Element> definedNames, List<String> hiddenNames) { |
| 16854 for (String name in hiddenNames) { | 16915 for (String name in hiddenNames) { |
| 16855 definedNames.remove(name); | 16916 definedNames.remove(name); |
| 16856 definedNames.remove("${name}="); | 16917 definedNames.remove("${name}="); |
| 16857 } | 16918 } |
| 16858 } | 16919 } |
| 16859 | 16920 |
| 16860 /** | 16921 /** |
| 16861 * Show only the given names by removing all other names from the given collec
tion of defined | 16922 * Show only the given names by removing all other names from the given collec
tion of defined |
| 16862 * names. | 16923 * names. |
| 16863 * | 16924 * |
| 16864 * @param definedNames the names that were defined before this operation | 16925 * @param definedNames the names that were defined before this operation |
| 16865 * @param shownNames the names to be shown | 16926 * @param shownNames the names to be shown |
| 16866 */ | 16927 */ |
| 16867 Map<String, Element> _show(Map<String, Element> definedNames, List<String> sho
wnNames) { | 16928 HashMap<String, Element> _show(HashMap<String, Element> definedNames, List<Str
ing> shownNames) { |
| 16868 Map<String, Element> newNames = new Map<String, Element>(); | 16929 HashMap<String, Element> newNames = new HashMap<String, Element>(); |
| 16869 for (String name in shownNames) { | 16930 for (String name in shownNames) { |
| 16870 Element element = definedNames[name]; | 16931 Element element = definedNames[name]; |
| 16871 if (element != null) { | 16932 if (element != null) { |
| 16872 newNames[name] = element; | 16933 newNames[name] = element; |
| 16873 } | 16934 } |
| 16874 String setterName = "${name}="; | 16935 String setterName = "${name}="; |
| 16875 element = definedNames[setterName]; | 16936 element = definedNames[setterName]; |
| 16876 if (element != null) { | 16937 if (element != null) { |
| 16877 newNames[setterName] = element; | 16938 newNames[setterName] = element; |
| 16878 } | 16939 } |
| (...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17717 * Initialize a newly created error code to have the given type, message and c
orrection. | 17778 * Initialize a newly created error code to have the given type, message and c
orrection. |
| 17718 * | 17779 * |
| 17719 * @param type the type of this error | 17780 * @param type the type of this error |
| 17720 * @param message the template used to create the message to be displayed for
the error | 17781 * @param message the template used to create the message to be displayed for
the error |
| 17721 * @param correction the template used to create the correction to be displaye
d for the error | 17782 * @param correction the template used to create the correction to be displaye
d for the error |
| 17722 */ | 17783 */ |
| 17723 const ResolverErrorCode.con2(String name, int ordinal, this.type, this.message
, this.correction) : super(name, ordinal); | 17784 const ResolverErrorCode.con2(String name, int ordinal, this.type, this.message
, this.correction) : super(name, ordinal); |
| 17724 | 17785 |
| 17725 @override | 17786 @override |
| 17726 ErrorSeverity get errorSeverity => type.severity; | 17787 ErrorSeverity get errorSeverity => type.severity; |
| 17788 |
| 17789 @override |
| 17790 String get uniqueName => "${runtimeType.toString()}.${name}"; |
| 17727 } | 17791 } |
| 17728 | 17792 |
| 17729 /** | 17793 /** |
| 17730 * Instances of the class `ResolverVisitor` are used to resolve the nodes within
a single | 17794 * Instances of the class `ResolverVisitor` are used to resolve the nodes within
a single |
| 17731 * compilation unit. | 17795 * compilation unit. |
| 17732 */ | 17796 */ |
| 17733 class ResolverVisitor extends ScopedVisitor { | 17797 class ResolverVisitor extends ScopedVisitor { |
| 17734 /** | 17798 /** |
| 17735 * The manager for the inheritance mappings. | 17799 * The manager for the inheritance mappings. |
| 17736 */ | 17800 */ |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18156 } | 18220 } |
| 18157 return null; | 18221 return null; |
| 18158 } | 18222 } |
| 18159 | 18223 |
| 18160 @override | 18224 @override |
| 18161 Object visitFieldDeclaration(FieldDeclaration node) { | 18225 Object visitFieldDeclaration(FieldDeclaration node) { |
| 18162 _overrideManager.enterScope(); | 18226 _overrideManager.enterScope(); |
| 18163 try { | 18227 try { |
| 18164 super.visitFieldDeclaration(node); | 18228 super.visitFieldDeclaration(node); |
| 18165 } finally { | 18229 } finally { |
| 18166 Map<Element, DartType> overrides = _overrideManager.captureOverrides(node.
fields); | 18230 HashMap<Element, DartType> overrides = _overrideManager.captureOverrides(n
ode.fields); |
| 18167 _overrideManager.exitScope(); | 18231 _overrideManager.exitScope(); |
| 18168 _overrideManager.applyOverrides(overrides); | 18232 _overrideManager.applyOverrides(overrides); |
| 18169 } | 18233 } |
| 18170 return null; | 18234 return null; |
| 18171 } | 18235 } |
| 18172 | 18236 |
| 18173 @override | 18237 @override |
| 18174 Object visitForEachStatement(ForEachStatement node) { | 18238 Object visitForEachStatement(ForEachStatement node) { |
| 18175 _overrideManager.enterScope(); | 18239 _overrideManager.enterScope(); |
| 18176 try { | 18240 try { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18248 return null; | 18312 return null; |
| 18249 } | 18313 } |
| 18250 | 18314 |
| 18251 @override | 18315 @override |
| 18252 Object visitHideCombinator(HideCombinator node) => null; | 18316 Object visitHideCombinator(HideCombinator node) => null; |
| 18253 | 18317 |
| 18254 @override | 18318 @override |
| 18255 Object visitIfStatement(IfStatement node) { | 18319 Object visitIfStatement(IfStatement node) { |
| 18256 Expression condition = node.condition; | 18320 Expression condition = node.condition; |
| 18257 safelyVisit(condition); | 18321 safelyVisit(condition); |
| 18258 Map<Element, DartType> thenOverrides = null; | 18322 HashMap<Element, DartType> thenOverrides = null; |
| 18259 Statement thenStatement = node.thenStatement; | 18323 Statement thenStatement = node.thenStatement; |
| 18260 if (thenStatement != null) { | 18324 if (thenStatement != null) { |
| 18261 _overrideManager.enterScope(); | 18325 _overrideManager.enterScope(); |
| 18262 try { | 18326 try { |
| 18263 _promoteManager.enterScope(); | 18327 _promoteManager.enterScope(); |
| 18264 try { | 18328 try { |
| 18265 _propagateTrueState(condition); | 18329 _propagateTrueState(condition); |
| 18266 // Type promotion. | 18330 // Type promotion. |
| 18267 _promoteTypes(condition); | 18331 _promoteTypes(condition); |
| 18268 _clearTypePromotionsIfPotentiallyMutatedIn(thenStatement); | 18332 _clearTypePromotionsIfPotentiallyMutatedIn(thenStatement); |
| 18269 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenStat
ement); | 18333 _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(thenStat
ement); |
| 18270 // Visit "then". | 18334 // Visit "then". |
| 18271 visitStatementInScope(thenStatement); | 18335 visitStatementInScope(thenStatement); |
| 18272 } finally { | 18336 } finally { |
| 18273 _promoteManager.exitScope(); | 18337 _promoteManager.exitScope(); |
| 18274 } | 18338 } |
| 18275 } finally { | 18339 } finally { |
| 18276 thenOverrides = _overrideManager.captureLocalOverrides(); | 18340 thenOverrides = _overrideManager.captureLocalOverrides(); |
| 18277 _overrideManager.exitScope(); | 18341 _overrideManager.exitScope(); |
| 18278 } | 18342 } |
| 18279 } | 18343 } |
| 18280 Map<Element, DartType> elseOverrides = null; | 18344 HashMap<Element, DartType> elseOverrides = null; |
| 18281 Statement elseStatement = node.elseStatement; | 18345 Statement elseStatement = node.elseStatement; |
| 18282 if (elseStatement != null) { | 18346 if (elseStatement != null) { |
| 18283 _overrideManager.enterScope(); | 18347 _overrideManager.enterScope(); |
| 18284 try { | 18348 try { |
| 18285 _propagateFalseState(condition); | 18349 _propagateFalseState(condition); |
| 18286 visitStatementInScope(elseStatement); | 18350 visitStatementInScope(elseStatement); |
| 18287 } finally { | 18351 } finally { |
| 18288 elseOverrides = _overrideManager.captureLocalOverrides(); | 18352 elseOverrides = _overrideManager.captureLocalOverrides(); |
| 18289 _overrideManager.exitScope(); | 18353 _overrideManager.exitScope(); |
| 18290 } | 18354 } |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18419 } | 18483 } |
| 18420 return null; | 18484 return null; |
| 18421 } | 18485 } |
| 18422 | 18486 |
| 18423 @override | 18487 @override |
| 18424 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { | 18488 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { |
| 18425 _overrideManager.enterScope(); | 18489 _overrideManager.enterScope(); |
| 18426 try { | 18490 try { |
| 18427 super.visitTopLevelVariableDeclaration(node); | 18491 super.visitTopLevelVariableDeclaration(node); |
| 18428 } finally { | 18492 } finally { |
| 18429 Map<Element, DartType> overrides = _overrideManager.captureOverrides(node.
variables); | 18493 HashMap<Element, DartType> overrides = _overrideManager.captureOverrides(n
ode.variables); |
| 18430 _overrideManager.exitScope(); | 18494 _overrideManager.exitScope(); |
| 18431 _overrideManager.applyOverrides(overrides); | 18495 _overrideManager.applyOverrides(overrides); |
| 18432 } | 18496 } |
| 18433 return null; | 18497 return null; |
| 18434 } | 18498 } |
| 18435 | 18499 |
| 18436 @override | 18500 @override |
| 18437 Object visitTypeName(TypeName node) => null; | 18501 Object visitTypeName(TypeName node) => null; |
| 18438 | 18502 |
| 18439 @override | 18503 @override |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 18571 * type. Generally speaking, it is appropriate if the given type is more speci
fic than the current | 18635 * type. Generally speaking, it is appropriate if the given type is more speci
fic than the current |
| 18572 * type. | 18636 * type. |
| 18573 * | 18637 * |
| 18574 * @param element the element whose type might be overridden | 18638 * @param element the element whose type might be overridden |
| 18575 * @param potentialType the potential type of the element | 18639 * @param potentialType the potential type of the element |
| 18576 */ | 18640 */ |
| 18577 void overrideVariable(VariableElement element, DartType potentialType) { | 18641 void overrideVariable(VariableElement element, DartType potentialType) { |
| 18578 if (potentialType == null || potentialType.isBottom) { | 18642 if (potentialType == null || potentialType.isBottom) { |
| 18579 return; | 18643 return; |
| 18580 } | 18644 } |
| 18581 if (element is PropertyInducingElement) { | |
| 18582 PropertyInducingElement variable = element; | |
| 18583 if (!variable.isConst && !variable.isFinal) { | |
| 18584 return; | |
| 18585 } | |
| 18586 } | |
| 18587 DartType currentType = _getBestType(element); | 18645 DartType currentType = _getBestType(element); |
| 18588 if (currentType == null || !currentType.isMoreSpecificThan(potentialType)) { | 18646 if (currentType == null || !currentType.isMoreSpecificThan(potentialType)) { |
| 18647 if (element is PropertyInducingElement) { |
| 18648 PropertyInducingElement variable = element; |
| 18649 if (!variable.isConst && !variable.isFinal) { |
| 18650 return; |
| 18651 } |
| 18652 (variable as PropertyInducingElementImpl).propagatedType = potentialType
; |
| 18653 } |
| 18589 _overrideManager.setType(element, potentialType); | 18654 _overrideManager.setType(element, potentialType); |
| 18590 } | 18655 } |
| 18591 } | 18656 } |
| 18592 | 18657 |
| 18593 @override | 18658 @override |
| 18594 void visitForEachStatementInScope(ForEachStatement node) { | 18659 void visitForEachStatementInScope(ForEachStatement node) { |
| 18595 // | 18660 // |
| 18596 // We visit the iterator before the loop variable because the loop variable
cannot be in scope | 18661 // We visit the iterator before the loop variable because the loop variable
cannot be in scope |
| 18597 // while visiting the iterator. | 18662 // while visiting the iterator. |
| 18598 // | 18663 // |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19036 * | 19101 * |
| 19037 * @param name the name being tested | 19102 * @param name the name being tested |
| 19038 * @return `true` if the given name is a library-private name | 19103 * @return `true` if the given name is a library-private name |
| 19039 */ | 19104 */ |
| 19040 static bool isPrivateName(String name) => name != null && StringUtilities.star
tsWithChar(name, PRIVATE_NAME_PREFIX); | 19105 static bool isPrivateName(String name) => name != null && StringUtilities.star
tsWithChar(name, PRIVATE_NAME_PREFIX); |
| 19041 | 19106 |
| 19042 /** | 19107 /** |
| 19043 * A table mapping names that are defined in this scope to the element represe
nting the thing | 19108 * A table mapping names that are defined in this scope to the element represe
nting the thing |
| 19044 * declared with that name. | 19109 * declared with that name. |
| 19045 */ | 19110 */ |
| 19046 Map<String, Element> _definedNames = new Map<String, Element>(); | 19111 HashMap<String, Element> _definedNames = new HashMap<String, Element>(); |
| 19047 | 19112 |
| 19048 /** | 19113 /** |
| 19049 * A flag indicating whether there are any names defined in this scope. | 19114 * A flag indicating whether there are any names defined in this scope. |
| 19050 */ | 19115 */ |
| 19051 bool _hasName = false; | 19116 bool _hasName = false; |
| 19052 | 19117 |
| 19053 /** | 19118 /** |
| 19054 * Add the given element to this scope. If there is already an element with th
e given name defined | 19119 * Add the given element to this scope. If there is already an element with th
e given name defined |
| 19055 * in this scope, then an error will be generated and the original element wil
l continue to be | 19120 * in this scope, then an error will be generated and the original element wil
l continue to be |
| 19056 * mapped to the name. If there is an element with the given name in an enclos
ing scope, then a | 19121 * mapped to the name. If there is an element with the given name in an enclos
ing scope, then a |
| (...skipping 878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19935 * * Every node representing an expression should be resolved to the Type of the
expression. | 20000 * * Every node representing an expression should be resolved to the Type of the
expression. |
| 19936 * </ol> | 20001 * </ol> |
| 19937 */ | 20002 */ |
| 19938 class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { | 20003 class StaticTypeAnalyzer extends SimpleAstVisitor<Object> { |
| 19939 /** | 20004 /** |
| 19940 * Create a table mapping HTML tag names to the names of the classes (in 'dart
:html') that | 20005 * Create a table mapping HTML tag names to the names of the classes (in 'dart
:html') that |
| 19941 * implement those tags. | 20006 * implement those tags. |
| 19942 * | 20007 * |
| 19943 * @return the table that was created | 20008 * @return the table that was created |
| 19944 */ | 20009 */ |
| 19945 static Map<String, String> _createHtmlTagToClassMap() { | 20010 static HashMap<String, String> _createHtmlTagToClassMap() { |
| 19946 Map<String, String> map = new Map<String, String>(); | 20011 HashMap<String, String> map = new HashMap<String, String>(); |
| 19947 map["a"] = "AnchorElement"; | 20012 map["a"] = "AnchorElement"; |
| 19948 map["area"] = "AreaElement"; | 20013 map["area"] = "AreaElement"; |
| 19949 map["br"] = "BRElement"; | 20014 map["br"] = "BRElement"; |
| 19950 map["base"] = "BaseElement"; | 20015 map["base"] = "BaseElement"; |
| 19951 map["body"] = "BodyElement"; | 20016 map["body"] = "BodyElement"; |
| 19952 map["button"] = "ButtonElement"; | 20017 map["button"] = "ButtonElement"; |
| 19953 map["canvas"] = "CanvasElement"; | 20018 map["canvas"] = "CanvasElement"; |
| 19954 map["content"] = "ContentElement"; | 20019 map["content"] = "ContentElement"; |
| 19955 map["dl"] = "DListElement"; | 20020 map["dl"] = "DListElement"; |
| 19956 map["datalist"] = "DataListElement"; | 20021 map["datalist"] = "DataListElement"; |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20032 TypeOverrideManager _overrideManager; | 20097 TypeOverrideManager _overrideManager; |
| 20033 | 20098 |
| 20034 /** | 20099 /** |
| 20035 * The object keeping track of which elements have had their types promoted. | 20100 * The object keeping track of which elements have had their types promoted. |
| 20036 */ | 20101 */ |
| 20037 TypePromotionManager _promoteManager; | 20102 TypePromotionManager _promoteManager; |
| 20038 | 20103 |
| 20039 /** | 20104 /** |
| 20040 * A table mapping [ExecutableElement]s to their propagated return types. | 20105 * A table mapping [ExecutableElement]s to their propagated return types. |
| 20041 */ | 20106 */ |
| 20042 Map<ExecutableElement, DartType> _propagatedReturnTypes = new Map<ExecutableEl
ement, DartType>(); | 20107 HashMap<ExecutableElement, DartType> _propagatedReturnTypes = new HashMap<Exec
utableElement, DartType>(); |
| 20043 | 20108 |
| 20044 /** | 20109 /** |
| 20045 * A table mapping HTML tag names to the names of the classes (in 'dart:html')
that implement | 20110 * A table mapping HTML tag names to the names of the classes (in 'dart:html')
that implement |
| 20046 * those tags. | 20111 * those tags. |
| 20047 */ | 20112 */ |
| 20048 static Map<String, String> _HTML_ELEMENT_TO_CLASS_MAP = _createHtmlTagToClassM
ap(); | 20113 static HashMap<String, String> _HTML_ELEMENT_TO_CLASS_MAP = _createHtmlTagToCl
assMap(); |
| 20049 | 20114 |
| 20050 /** | 20115 /** |
| 20051 * Initialize a newly created type analyzer. | 20116 * Initialize a newly created type analyzer. |
| 20052 * | 20117 * |
| 20053 * @param resolver the resolver driving this participant | 20118 * @param resolver the resolver driving this participant |
| 20054 */ | 20119 */ |
| 20055 StaticTypeAnalyzer(this._resolver) { | 20120 StaticTypeAnalyzer(this._resolver) { |
| 20056 _typeProvider = _resolver.typeProvider; | 20121 _typeProvider = _resolver.typeProvider; |
| 20057 _dynamicType = _typeProvider.dynamicType; | 20122 _dynamicType = _typeProvider.dynamicType; |
| 20058 _overrideManager = _resolver.overrideManager; | 20123 _overrideManager = _resolver.overrideManager; |
| (...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20801 } | 20866 } |
| 20802 | 20867 |
| 20803 /** | 20868 /** |
| 20804 * See [visitSimpleIdentifier]. | 20869 * See [visitSimpleIdentifier]. |
| 20805 */ | 20870 */ |
| 20806 @override | 20871 @override |
| 20807 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 20872 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 20808 SimpleIdentifier prefixedIdentifier = node.identifier; | 20873 SimpleIdentifier prefixedIdentifier = node.identifier; |
| 20809 Element staticElement = prefixedIdentifier.staticElement; | 20874 Element staticElement = prefixedIdentifier.staticElement; |
| 20810 DartType staticType = _dynamicType; | 20875 DartType staticType = _dynamicType; |
| 20876 DartType propagatedType = null; |
| 20811 if (staticElement is ClassElement) { | 20877 if (staticElement is ClassElement) { |
| 20812 if (_isNotTypeLiteral(node)) { | 20878 if (_isNotTypeLiteral(node)) { |
| 20813 staticType = staticElement.type; | 20879 staticType = staticElement.type; |
| 20814 } else { | 20880 } else { |
| 20815 staticType = _typeProvider.typeType; | 20881 staticType = _typeProvider.typeType; |
| 20816 } | 20882 } |
| 20817 } else if (staticElement is FunctionTypeAliasElement) { | 20883 } else if (staticElement is FunctionTypeAliasElement) { |
| 20818 if (_isNotTypeLiteral(node)) { | 20884 if (_isNotTypeLiteral(node)) { |
| 20819 staticType = staticElement.type; | 20885 staticType = staticElement.type; |
| 20820 } else { | 20886 } else { |
| 20821 staticType = _typeProvider.typeType; | 20887 staticType = _typeProvider.typeType; |
| 20822 } | 20888 } |
| 20823 } else if (staticElement is MethodElement) { | 20889 } else if (staticElement is MethodElement) { |
| 20824 staticType = staticElement.type; | 20890 staticType = staticElement.type; |
| 20825 } else if (staticElement is PropertyAccessorElement) { | 20891 } else if (staticElement is PropertyAccessorElement) { |
| 20826 staticType = _getTypeOfProperty(staticElement, node.prefix.staticType); | 20892 staticType = _getTypeOfProperty(staticElement, node.prefix.staticType); |
| 20893 propagatedType = _getPropertyPropagatedType(staticElement, propagatedType)
; |
| 20827 } else if (staticElement is ExecutableElement) { | 20894 } else if (staticElement is ExecutableElement) { |
| 20828 staticType = staticElement.type; | 20895 staticType = staticElement.type; |
| 20829 } else if (staticElement is TypeParameterElement) { | 20896 } else if (staticElement is TypeParameterElement) { |
| 20830 staticType = staticElement.type; | 20897 staticType = staticElement.type; |
| 20831 } else if (staticElement is VariableElement) { | 20898 } else if (staticElement is VariableElement) { |
| 20832 staticType = staticElement.type; | 20899 staticType = staticElement.type; |
| 20833 } | 20900 } |
| 20834 _recordStaticType(prefixedIdentifier, staticType); | 20901 _recordStaticType(prefixedIdentifier, staticType); |
| 20835 _recordStaticType(node, staticType); | 20902 _recordStaticType(node, staticType); |
| 20836 Element propagatedElement = prefixedIdentifier.propagatedElement; | 20903 Element propagatedElement = prefixedIdentifier.propagatedElement; |
| 20837 DartType propagatedType = null; | |
| 20838 if (propagatedElement is ClassElement) { | 20904 if (propagatedElement is ClassElement) { |
| 20839 if (_isNotTypeLiteral(node)) { | 20905 if (_isNotTypeLiteral(node)) { |
| 20840 propagatedType = propagatedElement.type; | 20906 propagatedType = propagatedElement.type; |
| 20841 } else { | 20907 } else { |
| 20842 propagatedType = _typeProvider.typeType; | 20908 propagatedType = _typeProvider.typeType; |
| 20843 } | 20909 } |
| 20844 } else if (propagatedElement is FunctionTypeAliasElement) { | 20910 } else if (propagatedElement is FunctionTypeAliasElement) { |
| 20845 propagatedType = propagatedElement.type; | 20911 propagatedType = propagatedElement.type; |
| 20846 } else if (propagatedElement is MethodElement) { | 20912 } else if (propagatedElement is MethodElement) { |
| 20847 propagatedType = propagatedElement.type; | 20913 propagatedType = propagatedElement.type; |
| 20848 } else if (propagatedElement is PropertyAccessorElement) { | 20914 } else if (propagatedElement is PropertyAccessorElement) { |
| 20849 propagatedType = _getTypeOfProperty(propagatedElement, node.prefix.staticT
ype); | 20915 propagatedType = _getTypeOfProperty(propagatedElement, node.prefix.staticT
ype); |
| 20916 propagatedType = _getPropertyPropagatedType(propagatedElement, propagatedT
ype); |
| 20850 } else if (propagatedElement is ExecutableElement) { | 20917 } else if (propagatedElement is ExecutableElement) { |
| 20851 propagatedType = propagatedElement.type; | 20918 propagatedType = propagatedElement.type; |
| 20852 } else if (propagatedElement is TypeParameterElement) { | 20919 } else if (propagatedElement is TypeParameterElement) { |
| 20853 propagatedType = propagatedElement.type; | 20920 propagatedType = propagatedElement.type; |
| 20854 } else if (propagatedElement is VariableElement) { | 20921 } else if (propagatedElement is VariableElement) { |
| 20855 propagatedType = propagatedElement.type; | 20922 propagatedType = propagatedElement.type; |
| 20856 } | 20923 } |
| 20857 DartType overriddenType = _overrideManager.getType(propagatedElement); | 20924 DartType overriddenType = _overrideManager.getType(propagatedElement); |
| 20858 if (propagatedType == null || (overriddenType != null && overriddenType.isMo
reSpecificThan(propagatedType))) { | 20925 if (propagatedType == null || (overriddenType != null && overriddenType.isMo
reSpecificThan(propagatedType))) { |
| 20859 propagatedType = overriddenType; | 20926 propagatedType = overriddenType; |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21045 VariableElement variable = element; | 21112 VariableElement variable = element; |
| 21046 staticType = _promoteManager.getStaticType(variable); | 21113 staticType = _promoteManager.getStaticType(variable); |
| 21047 } else if (element is PrefixElement) { | 21114 } else if (element is PrefixElement) { |
| 21048 return null; | 21115 return null; |
| 21049 } else { | 21116 } else { |
| 21050 staticType = _dynamicType; | 21117 staticType = _dynamicType; |
| 21051 } | 21118 } |
| 21052 _recordStaticType(node, staticType); | 21119 _recordStaticType(node, staticType); |
| 21053 // TODO(brianwilkerson) I think we want to repeat the logic above using the
propagated element | 21120 // TODO(brianwilkerson) I think we want to repeat the logic above using the
propagated element |
| 21054 // to get another candidate for the propagated type. | 21121 // to get another candidate for the propagated type. |
| 21055 DartType propagatedType = _overrideManager.getType(element); | 21122 DartType propagatedType = _getPropertyPropagatedType(element, null); |
| 21123 if (propagatedType == null) { |
| 21124 DartType overriddenType = _overrideManager.getType(element); |
| 21125 if (propagatedType == null || overriddenType != null && overriddenType.isM
oreSpecificThan(propagatedType)) { |
| 21126 propagatedType = overriddenType; |
| 21127 } |
| 21128 } |
| 21056 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType))
{ | 21129 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType))
{ |
| 21057 _recordPropagatedType(node, propagatedType); | 21130 _recordPropagatedType(node, propagatedType); |
| 21058 } | 21131 } |
| 21059 return null; | 21132 return null; |
| 21060 } | 21133 } |
| 21061 | 21134 |
| 21062 /** | 21135 /** |
| 21063 * The Dart Language Specification, 12.5: <blockquote>The static type of a str
ing literal is | 21136 * The Dart Language Specification, 12.5: <blockquote>The static type of a str
ing literal is |
| 21064 * `String`.</blockquote> | 21137 * `String`.</blockquote> |
| 21065 */ | 21138 */ |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21268 | 21341 |
| 21269 /** | 21342 /** |
| 21270 * If the given element name can be mapped to the name of a class defined with
in the given | 21343 * If the given element name can be mapped to the name of a class defined with
in the given |
| 21271 * library, return the type specified by the argument. | 21344 * library, return the type specified by the argument. |
| 21272 * | 21345 * |
| 21273 * @param library the library in which the specified type would be defined | 21346 * @param library the library in which the specified type would be defined |
| 21274 * @param elementName the name of the element for which a type is being sought | 21347 * @param elementName the name of the element for which a type is being sought |
| 21275 * @param nameMap an optional map used to map the element name to a type name | 21348 * @param nameMap an optional map used to map the element name to a type name |
| 21276 * @return the type specified by the first argument in the argument list | 21349 * @return the type specified by the first argument in the argument list |
| 21277 */ | 21350 */ |
| 21278 DartType _getElementNameAsType(LibraryElement library, String elementName, Map
<String, String> nameMap) { | 21351 DartType _getElementNameAsType(LibraryElement library, String elementName, Has
hMap<String, String> nameMap) { |
| 21279 if (elementName != null) { | 21352 if (elementName != null) { |
| 21280 if (nameMap != null) { | 21353 if (nameMap != null) { |
| 21281 elementName = nameMap[elementName.toLowerCase()]; | 21354 elementName = nameMap[elementName.toLowerCase()]; |
| 21282 } | 21355 } |
| 21283 ClassElement returnType = library.getType(elementName); | 21356 ClassElement returnType = library.getType(elementName); |
| 21284 if (returnType != null) { | 21357 if (returnType != null) { |
| 21285 return returnType.type; | 21358 return returnType.type; |
| 21286 } | 21359 } |
| 21287 } | 21360 } |
| 21288 return null; | 21361 return null; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21356 /** | 21429 /** |
| 21357 * If the given argument list contains at least one argument, and if the argum
ent is a simple | 21430 * If the given argument list contains at least one argument, and if the argum
ent is a simple |
| 21358 * string literal, and if the value of the argument is the name of a class def
ined within the | 21431 * string literal, and if the value of the argument is the name of a class def
ined within the |
| 21359 * given library, return the type specified by the argument. | 21432 * given library, return the type specified by the argument. |
| 21360 * | 21433 * |
| 21361 * @param library the library in which the specified type would be defined | 21434 * @param library the library in which the specified type would be defined |
| 21362 * @param argumentList the list of arguments from which a type is to be extrac
ted | 21435 * @param argumentList the list of arguments from which a type is to be extrac
ted |
| 21363 * @param nameMap an optional map used to map the element name to a type name | 21436 * @param nameMap an optional map used to map the element name to a type name |
| 21364 * @return the type specified by the first argument in the argument list | 21437 * @return the type specified by the first argument in the argument list |
| 21365 */ | 21438 */ |
| 21366 DartType _getFirstArgumentAsTypeWithMap(LibraryElement library, ArgumentList a
rgumentList, Map<String, String> nameMap) => _getElementNameAsType(library, _get
FirstArgumentAsString(argumentList), nameMap); | 21439 DartType _getFirstArgumentAsTypeWithMap(LibraryElement library, ArgumentList a
rgumentList, HashMap<String, String> nameMap) => _getElementNameAsType(library,
_getFirstArgumentAsString(argumentList), nameMap); |
| 21440 |
| 21441 /** |
| 21442 * Return the propagated type of the given [Element], or `null`. |
| 21443 */ |
| 21444 DartType _getPropertyPropagatedType(Element element, DartType currentType) { |
| 21445 if (element is PropertyAccessorElement) { |
| 21446 PropertyAccessorElement accessor = element; |
| 21447 if (accessor.isGetter) { |
| 21448 PropertyInducingElement variable = accessor.variable; |
| 21449 DartType propagatedType = variable.propagatedType; |
| 21450 if (currentType == null || propagatedType != null && propagatedType.isMo
reSpecificThan(currentType)) { |
| 21451 return propagatedType; |
| 21452 } |
| 21453 } |
| 21454 } |
| 21455 return currentType; |
| 21456 } |
| 21367 | 21457 |
| 21368 /** | 21458 /** |
| 21369 * Return the static type of the given expression. | 21459 * Return the static type of the given expression. |
| 21370 * | 21460 * |
| 21371 * @param expression the expression whose type is to be returned | 21461 * @param expression the expression whose type is to be returned |
| 21372 * @return the static type of the given expression | 21462 * @return the static type of the given expression |
| 21373 */ | 21463 */ |
| 21374 DartType _getStaticType(Expression expression) { | 21464 DartType _getStaticType(Expression expression) { |
| 21375 DartType type = expression.staticType; | 21465 DartType type = expression.staticType; |
| 21376 if (type == null) { | 21466 if (type == null) { |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21571 } | 21661 } |
| 21572 | 21662 |
| 21573 /** | 21663 /** |
| 21574 * Instances of this class manage the knowledge of what the set of subtypes are
for a given type. | 21664 * Instances of this class manage the knowledge of what the set of subtypes are
for a given type. |
| 21575 */ | 21665 */ |
| 21576 class SubtypeManager { | 21666 class SubtypeManager { |
| 21577 /** | 21667 /** |
| 21578 * A map between [ClassElement]s and a set of [ClassElement]s that are subtype
s of the | 21668 * A map between [ClassElement]s and a set of [ClassElement]s that are subtype
s of the |
| 21579 * key. | 21669 * key. |
| 21580 */ | 21670 */ |
| 21581 Map<ClassElement, Set<ClassElement>> _subtypeMap = new Map<ClassElement, Set<C
lassElement>>(); | 21671 HashMap<ClassElement, Set<ClassElement>> _subtypeMap = new HashMap<ClassElemen
t, Set<ClassElement>>(); |
| 21582 | 21672 |
| 21583 /** | 21673 /** |
| 21584 * The set of all [LibraryElement]s that have been visited by the manager. Thi
s is used both | 21674 * The set of all [LibraryElement]s that have been visited by the manager. Thi
s is used both |
| 21585 * to prevent infinite loops in the recursive methods, and also as a marker fo
r the scope of the | 21675 * to prevent infinite loops in the recursive methods, and also as a marker fo
r the scope of the |
| 21586 * libraries visited by this manager. | 21676 * libraries visited by this manager. |
| 21587 */ | 21677 */ |
| 21588 Set<LibraryElement> _visitedLibraries = new Set<LibraryElement>(); | 21678 Set<LibraryElement> _visitedLibraries = new Set<LibraryElement>(); |
| 21589 | 21679 |
| 21590 /** | 21680 /** |
| 21591 * Given some [ClassElement], return the set of all subtypes, and subtypes of
subtypes. | 21681 * Given some [ClassElement], return the set of all subtypes, and subtypes of
subtypes. |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21790 /** | 21880 /** |
| 21791 * The current override scope, or `null` if no scope has been entered. | 21881 * The current override scope, or `null` if no scope has been entered. |
| 21792 */ | 21882 */ |
| 21793 TypeOverrideManager_TypeOverrideScope _currentScope; | 21883 TypeOverrideManager_TypeOverrideScope _currentScope; |
| 21794 | 21884 |
| 21795 /** | 21885 /** |
| 21796 * Apply a set of overrides that were previously captured. | 21886 * Apply a set of overrides that were previously captured. |
| 21797 * | 21887 * |
| 21798 * @param overrides the overrides to be applied | 21888 * @param overrides the overrides to be applied |
| 21799 */ | 21889 */ |
| 21800 void applyOverrides(Map<Element, DartType> overrides) { | 21890 void applyOverrides(HashMap<Element, DartType> overrides) { |
| 21801 if (_currentScope == null) { | 21891 if (_currentScope == null) { |
| 21802 throw new IllegalStateException("Cannot apply overrides without a scope"); | 21892 throw new IllegalStateException("Cannot apply overrides without a scope"); |
| 21803 } | 21893 } |
| 21804 _currentScope.applyOverrides(overrides); | 21894 _currentScope.applyOverrides(overrides); |
| 21805 } | 21895 } |
| 21806 | 21896 |
| 21807 /** | 21897 /** |
| 21808 * Return a table mapping the elements whose type is overridden in the current
scope to the | 21898 * Return a table mapping the elements whose type is overridden in the current
scope to the |
| 21809 * overriding type. | 21899 * overriding type. |
| 21810 * | 21900 * |
| 21811 * @return the overrides in the current scope | 21901 * @return the overrides in the current scope |
| 21812 */ | 21902 */ |
| 21813 Map<Element, DartType> captureLocalOverrides() { | 21903 HashMap<Element, DartType> captureLocalOverrides() { |
| 21814 if (_currentScope == null) { | 21904 if (_currentScope == null) { |
| 21815 throw new IllegalStateException("Cannot capture local overrides without a
scope"); | 21905 throw new IllegalStateException("Cannot capture local overrides without a
scope"); |
| 21816 } | 21906 } |
| 21817 return _currentScope.captureLocalOverrides(); | 21907 return _currentScope.captureLocalOverrides(); |
| 21818 } | 21908 } |
| 21819 | 21909 |
| 21820 /** | 21910 /** |
| 21821 * Return a map from the elements for the variables in the given list that hav
e their types | 21911 * Return a map from the elements for the variables in the given list that hav
e their types |
| 21822 * overridden to the overriding type. | 21912 * overridden to the overriding type. |
| 21823 * | 21913 * |
| 21824 * @param variableList the list of variables whose overriding types are to be
captured | 21914 * @param variableList the list of variables whose overriding types are to be
captured |
| 21825 * @return a table mapping elements to their overriding types | 21915 * @return a table mapping elements to their overriding types |
| 21826 */ | 21916 */ |
| 21827 Map<Element, DartType> captureOverrides(VariableDeclarationList variableList)
{ | 21917 HashMap<Element, DartType> captureOverrides(VariableDeclarationList variableLi
st) { |
| 21828 if (_currentScope == null) { | 21918 if (_currentScope == null) { |
| 21829 throw new IllegalStateException("Cannot capture overrides without a scope"
); | 21919 throw new IllegalStateException("Cannot capture overrides without a scope"
); |
| 21830 } | 21920 } |
| 21831 return _currentScope.captureOverrides(variableList); | 21921 return _currentScope.captureOverrides(variableList); |
| 21832 } | 21922 } |
| 21833 | 21923 |
| 21834 /** | 21924 /** |
| 21835 * Enter a new override scope. | 21925 * Enter a new override scope. |
| 21836 */ | 21926 */ |
| 21837 void enterScope() { | 21927 void enterScope() { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 21882 */ | 21972 */ |
| 21883 class TypeOverrideManager_TypeOverrideScope { | 21973 class TypeOverrideManager_TypeOverrideScope { |
| 21884 /** | 21974 /** |
| 21885 * The outer scope in which types might be overridden. | 21975 * The outer scope in which types might be overridden. |
| 21886 */ | 21976 */ |
| 21887 final TypeOverrideManager_TypeOverrideScope _outerScope; | 21977 final TypeOverrideManager_TypeOverrideScope _outerScope; |
| 21888 | 21978 |
| 21889 /** | 21979 /** |
| 21890 * A table mapping elements to the overridden type of that element. | 21980 * A table mapping elements to the overridden type of that element. |
| 21891 */ | 21981 */ |
| 21892 Map<Element, DartType> _overridenTypes = new Map<Element, DartType>(); | 21982 HashMap<Element, DartType> _overridenTypes = new HashMap<Element, DartType>(); |
| 21893 | 21983 |
| 21894 /** | 21984 /** |
| 21895 * Initialize a newly created scope to be an empty child of the given scope. | 21985 * Initialize a newly created scope to be an empty child of the given scope. |
| 21896 * | 21986 * |
| 21897 * @param outerScope the outer scope in which types might be overridden | 21987 * @param outerScope the outer scope in which types might be overridden |
| 21898 */ | 21988 */ |
| 21899 TypeOverrideManager_TypeOverrideScope(this._outerScope); | 21989 TypeOverrideManager_TypeOverrideScope(this._outerScope); |
| 21900 | 21990 |
| 21901 /** | 21991 /** |
| 21902 * Apply a set of overrides that were previously captured. | 21992 * Apply a set of overrides that were previously captured. |
| 21903 * | 21993 * |
| 21904 * @param overrides the overrides to be applied | 21994 * @param overrides the overrides to be applied |
| 21905 */ | 21995 */ |
| 21906 void applyOverrides(Map<Element, DartType> overrides) { | 21996 void applyOverrides(HashMap<Element, DartType> overrides) { |
| 21907 for (MapEntry<Element, DartType> entry in getMapEntrySet(overrides)) { | 21997 for (MapEntry<Element, DartType> entry in getMapEntrySet(overrides)) { |
| 21908 _overridenTypes[entry.getKey()] = entry.getValue(); | 21998 _overridenTypes[entry.getKey()] = entry.getValue(); |
| 21909 } | 21999 } |
| 21910 } | 22000 } |
| 21911 | 22001 |
| 21912 /** | 22002 /** |
| 21913 * Return a table mapping the elements whose type is overridden in the current
scope to the | 22003 * Return a table mapping the elements whose type is overridden in the current
scope to the |
| 21914 * overriding type. | 22004 * overriding type. |
| 21915 * | 22005 * |
| 21916 * @return the overrides in the current scope | 22006 * @return the overrides in the current scope |
| 21917 */ | 22007 */ |
| 21918 Map<Element, DartType> captureLocalOverrides() => _overridenTypes; | 22008 HashMap<Element, DartType> captureLocalOverrides() => _overridenTypes; |
| 21919 | 22009 |
| 21920 /** | 22010 /** |
| 21921 * Return a map from the elements for the variables in the given list that hav
e their types | 22011 * Return a map from the elements for the variables in the given list that hav
e their types |
| 21922 * overridden to the overriding type. | 22012 * overridden to the overriding type. |
| 21923 * | 22013 * |
| 21924 * @param variableList the list of variables whose overriding types are to be
captured | 22014 * @param variableList the list of variables whose overriding types are to be
captured |
| 21925 * @return a table mapping elements to their overriding types | 22015 * @return a table mapping elements to their overriding types |
| 21926 */ | 22016 */ |
| 21927 Map<Element, DartType> captureOverrides(VariableDeclarationList variableList)
{ | 22017 HashMap<Element, DartType> captureOverrides(VariableDeclarationList variableLi
st) { |
| 21928 Map<Element, DartType> overrides = new Map<Element, DartType>(); | 22018 HashMap<Element, DartType> overrides = new HashMap<Element, DartType>(); |
| 21929 if (variableList.isConst || variableList.isFinal) { | 22019 if (variableList.isConst || variableList.isFinal) { |
| 21930 for (VariableDeclaration variable in variableList.variables) { | 22020 for (VariableDeclaration variable in variableList.variables) { |
| 21931 Element element = variable.element; | 22021 Element element = variable.element; |
| 21932 if (element != null) { | 22022 if (element != null) { |
| 21933 DartType type = _overridenTypes[element]; | 22023 DartType type = _overridenTypes[element]; |
| 21934 if (type != null) { | 22024 if (type != null) { |
| 21935 overrides[element] = type; | 22025 overrides[element] = type; |
| 21936 } | 22026 } |
| 21937 } | 22027 } |
| 21938 } | 22028 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 22050 */ | 22140 */ |
| 22051 class TypePromotionManager_TypePromoteScope { | 22141 class TypePromotionManager_TypePromoteScope { |
| 22052 /** | 22142 /** |
| 22053 * The outer scope in which types might be promoter. | 22143 * The outer scope in which types might be promoter. |
| 22054 */ | 22144 */ |
| 22055 final TypePromotionManager_TypePromoteScope _outerScope; | 22145 final TypePromotionManager_TypePromoteScope _outerScope; |
| 22056 | 22146 |
| 22057 /** | 22147 /** |
| 22058 * A table mapping elements to the promoted type of that element. | 22148 * A table mapping elements to the promoted type of that element. |
| 22059 */ | 22149 */ |
| 22060 Map<Element, DartType> _promotedTypes = new Map<Element, DartType>(); | 22150 HashMap<Element, DartType> _promotedTypes = new HashMap<Element, DartType>(); |
| 22061 | 22151 |
| 22062 /** | 22152 /** |
| 22063 * Initialize a newly created scope to be an empty child of the given scope. | 22153 * Initialize a newly created scope to be an empty child of the given scope. |
| 22064 * | 22154 * |
| 22065 * @param outerScope the outer scope in which types might be promoted | 22155 * @param outerScope the outer scope in which types might be promoted |
| 22066 */ | 22156 */ |
| 22067 TypePromotionManager_TypePromoteScope(this._outerScope); | 22157 TypePromotionManager_TypePromoteScope(this._outerScope); |
| 22068 | 22158 |
| 22069 /** | 22159 /** |
| 22070 * Returns the elements with promoted types. | 22160 * Returns the elements with promoted types. |
| (...skipping 1592 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 23663 parameterImpl.markPotentiallyMutatedInScope(); | 23753 parameterImpl.markPotentiallyMutatedInScope(); |
| 23664 // If we are in some closure, check if it is not the same as where varia
ble is declared. | 23754 // If we are in some closure, check if it is not the same as where varia
ble is declared. |
| 23665 if (_enclosingFunction != null && (element.enclosingElement != _enclosin
gFunction)) { | 23755 if (_enclosingFunction != null && (element.enclosingElement != _enclosin
gFunction)) { |
| 23666 parameterImpl.markPotentiallyMutatedInClosure(); | 23756 parameterImpl.markPotentiallyMutatedInClosure(); |
| 23667 } | 23757 } |
| 23668 } | 23758 } |
| 23669 } | 23759 } |
| 23670 return null; | 23760 return null; |
| 23671 } | 23761 } |
| 23672 } | 23762 } |
| OLD | NEW |