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

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

Issue 1019643004: Clean up comments in element_resolver (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library engine.resolver.element_resolver; 5 library engine.resolver.element_resolver;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'ast.dart'; 9 import 'ast.dart';
10 import 'element.dart'; 10 import 'element.dart';
11 import 'engine.dart'; 11 import 'engine.dart';
12 import 'error.dart'; 12 import 'error.dart';
13 import 'resolver.dart'; 13 import 'resolver.dart';
14 import 'scanner.dart' as sc; 14 import 'scanner.dart' as sc;
15 import 'utilities_dart.dart'; 15 import 'utilities_dart.dart';
16 16
17 /** 17 /**
18 * Instances of the class `ElementResolver` are used by instances of [ResolverVi sitor] 18 * An object used by instances of [ResolverVisitor] to resolve references within
19 * to resolve references within the AST structure to the elements being referenc ed. The requirements 19 * the AST structure to the elements being referenced. The requirements for the
20 * for the element resolver are: 20 * element resolver are:
21 * <ol> 21 *
22 * * Every [SimpleIdentifier] should be resolved to the element to which it refe rs. 22 * 1. Every [SimpleIdentifier] should be resolved to the element to which it
23 * Specifically: 23 * refers. Specifically:
24 * * An identifier within the declaration of that name should resolve to the ele ment being 24 * * An identifier within the declaration of that name should resolve to the
25 * declared. 25 * element being declared.
26 * * An identifier denoting a prefix should resolve to the element representing the import that 26 * * An identifier denoting a prefix should resolve to the element
27 * defines the prefix (an [ImportElement]). 27 * representing the import that defines the prefix (an [ImportElement]).
28 * * An identifier denoting a variable should resolve to the element representin g the variable (a 28 * * An identifier denoting a variable should resolve to the element
29 * [VariableElement]). 29 * representing the variable (a [VariableElement]).
30 * * An identifier denoting a parameter should resolve to the element representi ng the parameter 30 * * An identifier denoting a parameter should resolve to the element
31 * (a [ParameterElement]). 31 * representing the parameter (a [ParameterElement]).
32 * * An identifier denoting a field should resolve to the element representing t he getter or 32 * * An identifier denoting a field should resolve to the element
33 * setter being invoked (a [PropertyAccessorElement]). 33 * representing the getter or setter being invoked (a
34 * * An identifier denoting the name of a method or function being invoked shoul d resolve to the 34 * [PropertyAccessorElement]).
35 * element representing the method or function (a [ExecutableElement]). 35 * * An identifier denoting the name of a method or function being invoked
36 * * An identifier denoting a label should resolve to the element representing t he label (a 36 * should resolve to the element representing the method or function (an
37 * [LabelElement]). 37 * [ExecutableElement]).
38 * The identifiers within directives are exceptions to this rule and are covered below. 38 * * An identifier denoting a label should resolve to the element
39 * * Every node containing a token representing an operator that can be overridd en ( 39 * representing the label (a [LabelElement]).
40 * [BinaryExpression], [PrefixExpression], [PostfixExpression]) should resolve t o 40 * The identifiers within directives are exceptions to this rule and are
41 * the element representing the method invoked by that operator (a [MethodElemen t]). 41 * covered below.
42 * * Every [FunctionExpressionInvocation] should resolve to the element represen ting the 42 * 2. Every node containing a token representing an operator that can be
43 * function being invoked (a [FunctionElement]). This will be the same element a s that to 43 * overridden ( [BinaryExpression], [PrefixExpression], [PostfixExpression])
44 * which the name is resolved if the function has a name, but is provided for th ose cases where an 44 * should resolve to the element representing the method invoked by that
45 * unnamed function is being invoked. 45 * operator (a [MethodElement]).
46 * * Every [LibraryDirective] and [PartOfDirective] should resolve to the elemen t 46 * 3. Every [FunctionExpressionInvocation] should resolve to the element
47 * representing the library being specified by the directive (a [LibraryElement] ) unless, in 47 * representing the function being invoked (a [FunctionElement]). This will
48 * the case of a part-of directive, the specified library does not exist. 48 * be the same element as that to which the name is resolved if the function
49 * * Every [ImportDirective] and [ExportDirective] should resolve to the element 49 * has a name, but is provided for those cases where an unnamed function is
50 * representing the library being specified by the directive unless the specifie d library does not 50 * being invoked.
51 * exist (an [ImportElement] or [ExportElement]). 51 * 4. Every [LibraryDirective] and [PartOfDirective] should resolve to the
52 * * The identifier representing the prefix in an [ImportDirective] should resol ve to the 52 * element representing the library being specified by the directive (a
53 * element representing the prefix (a [PrefixElement]). 53 * [LibraryElement]) unless, in the case of a part-of directive, the
54 * * The identifiers in the hide and show combinators in [ImportDirective]s and 54 * specified library does not exist.
55 * [ExportDirective]s should resolve to the elements that are being hidden or sh own, 55 * 5. Every [ImportDirective] and [ExportDirective] should resolve to the
56 * respectively, unless those names are not defined in the specified library (or the specified 56 * element representing the library being specified by the directive unless
57 * library does not exist). 57 * the specified library does not exist (an [ImportElement] or
58 * * Every [PartDirective] should resolve to the element representing the compil ation unit 58 * [ExportElement]).
59 * being specified by the string unless the specified compilation unit does not exist (a 59 * 6. The identifier representing the prefix in an [ImportDirective] should
60 * [CompilationUnitElement]). 60 * resolve to the element representing the prefix (a [PrefixElement]).
61 * </ol> 61 * 7. The identifiers in the hide and show combinators in [ImportDirective]s
62 * Note that AST nodes that would represent elements that are not defined are no t resolved to 62 * and [ExportDirective]s should resolve to the elements that are being
63 * anything. This includes such things as references to undeclared variables (wh ich is an error) and 63 * hidden or shown, respectively, unless those names are not defined in the
64 * names in hide and show combinators that are not defined in the imported libra ry (which is not an 64 * specified library (or the specified library does not exist).
65 * 8. Every [PartDirective] should resolve to the element representing the
66 * compilation unit being specified by the string unless the specified
67 * compilation unit does not exist (a [CompilationUnitElement]).
68 *
69 * Note that AST nodes that would represent elements that are not defined are
70 * not resolved to anything. This includes such things as references to
71 * undeclared variables (which is an error) and names in hide and show
72 * combinators that are not defined in the imported library (which is not an
65 * error). 73 * error).
66 */ 74 */
67 class ElementResolver extends SimpleAstVisitor<Object> { 75 class ElementResolver extends SimpleAstVisitor<Object> {
68 /** 76 /**
69 * The resolver driving this participant. 77 * The resolver driving this participant.
70 */ 78 */
71 final ResolverVisitor _resolver; 79 final ResolverVisitor _resolver;
72 80
73 /** 81 /**
74 * The element for the library containing the compilation unit being visited. 82 * The element for the library containing the compilation unit being visited.
(...skipping 15 matching lines...) Expand all
90 * The type representing the type 'dynamic'. 98 * The type representing the type 'dynamic'.
91 */ 99 */
92 DartType _dynamicType; 100 DartType _dynamicType;
93 101
94 /** 102 /**
95 * The type representing the type 'type'. 103 * The type representing the type 'type'.
96 */ 104 */
97 DartType _typeType; 105 DartType _typeType;
98 106
99 /** 107 /**
100 * A utility class for the resolver to answer the question of "what are my sub types?". 108 * A utility class for the resolver to answer the question of "what are my
109 * subtypes?".
101 */ 110 */
102 SubtypeManager _subtypeManager; 111 SubtypeManager _subtypeManager;
103 112
104 /** 113 /**
105 * The object keeping track of which elements have had their types promoted. 114 * The object keeping track of which elements have had their types promoted.
106 */ 115 */
107 TypePromotionManager _promoteManager; 116 TypePromotionManager _promoteManager;
108 117
109 /** 118 /**
110 * Initialize a newly created visitor to resolve the nodes in a compilation un it. 119 * Initialize a newly created visitor to work for the given [_resolver] to
111 * 120 * resolve the nodes in a compilation unit.
112 * @param resolver the resolver driving this participant
113 */ 121 */
114 ElementResolver(this._resolver) { 122 ElementResolver(this._resolver) {
115 this._definingLibrary = _resolver.definingLibrary; 123 this._definingLibrary = _resolver.definingLibrary;
116 AnalysisOptions options = _definingLibrary.context.analysisOptions; 124 AnalysisOptions options = _definingLibrary.context.analysisOptions;
117 _enableHints = options.hint; 125 _enableHints = options.hint;
118 _enableStrictCallChecks = options.enableStrictCallChecks; 126 _enableStrictCallChecks = options.enableStrictCallChecks;
119 _dynamicType = _resolver.typeProvider.dynamicType; 127 _dynamicType = _resolver.typeProvider.dynamicType;
120 _typeType = _resolver.typeProvider.typeType; 128 _typeType = _resolver.typeProvider.typeType;
121 _subtypeManager = new SubtypeManager(); 129 _subtypeManager = new SubtypeManager();
122 _promoteManager = _resolver.promoteManager; 130 _promoteManager = _resolver.promoteManager;
123 } 131 }
124 132
125 /** 133 /**
126 * @return `true` iff current enclosing function is constant constructor decla ration. 134 * Return `true` iff the current enclosing function is a constant constructor
135 * declaration.
127 */ 136 */
128 bool get isInConstConstructor { 137 bool get isInConstConstructor {
129 ExecutableElement function = _resolver.enclosingFunction; 138 ExecutableElement function = _resolver.enclosingFunction;
130 if (function is ConstructorElement) { 139 if (function is ConstructorElement) {
131 return function.isConst; 140 return function.isConst;
132 } 141 }
133 return false; 142 return false;
134 } 143 }
135 144
136 @override 145 @override
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 return null; 1090 return null;
1082 } 1091 }
1083 1092
1084 @override 1093 @override
1085 Object visitVariableDeclaration(VariableDeclaration node) { 1094 Object visitVariableDeclaration(VariableDeclaration node) {
1086 _setMetadata(node.element, node); 1095 _setMetadata(node.element, node);
1087 return null; 1096 return null;
1088 } 1097 }
1089 1098
1090 /** 1099 /**
1091 * Generate annotation elements for each of the annotations in the given node list and add them to 1100 * Generate annotation elements for each of the annotations in the
1092 * the given list of elements. 1101 * [annotationList] and add them to the given list of [annotations].
1093 *
1094 * @param annotationList the list of elements to which new elements are to be added
1095 * @param annotations the AST nodes used to generate new elements
1096 */ 1102 */
1097 void _addAnnotations(List<ElementAnnotationImpl> annotationList, 1103 void _addAnnotations(List<ElementAnnotationImpl> annotationList,
1098 NodeList<Annotation> annotations) { 1104 NodeList<Annotation> annotations) {
1099 int annotationCount = annotations.length; 1105 int annotationCount = annotations.length;
1100 for (int i = 0; i < annotationCount; i++) { 1106 for (int i = 0; i < annotationCount; i++) {
1101 Annotation annotation = annotations[i]; 1107 Annotation annotation = annotations[i];
1102 Element resolvedElement = annotation.element; 1108 Element resolvedElement = annotation.element;
1103 if (resolvedElement != null) { 1109 if (resolvedElement != null) {
1104 ElementAnnotationImpl elementAnnotation = 1110 ElementAnnotationImpl elementAnnotation =
1105 new ElementAnnotationImpl(resolvedElement); 1111 new ElementAnnotationImpl(resolvedElement);
1106 annotation.elementAnnotation = elementAnnotation; 1112 annotation.elementAnnotation = elementAnnotation;
1107 annotationList.add(elementAnnotation); 1113 annotationList.add(elementAnnotation);
1108 } 1114 }
1109 } 1115 }
1110 } 1116 }
1111 1117
1112 /** 1118 /**
1113 * Given that we have found code to invoke the given element, return the error code that should be 1119 * Given that we have found code to invoke the given [element], return the
1114 * reported, or `null` if no error should be reported. 1120 * error code that should be reported, or `null` if no error should be
1115 * 1121 * reported. The [target] is the target of the invocation, or `null` if there
1116 * @param target the target of the invocation, or `null` if there was no targe t 1122 * was no target. The flag [useStaticContext] should be `true` if the
1117 * @param useStaticContext 1123 * invocation is in a static constant (does not have access to instance state.
1118 * @param element the element to be invoked
1119 * @return the error code that should be reported
1120 */ 1124 */
1121 ErrorCode _checkForInvocationError( 1125 ErrorCode _checkForInvocationError(
1122 Expression target, bool useStaticContext, Element element) { 1126 Expression target, bool useStaticContext, Element element) {
1123 // Prefix is not declared, instead "prefix.id" are declared. 1127 // Prefix is not declared, instead "prefix.id" are declared.
1124 if (element is PrefixElement) { 1128 if (element is PrefixElement) {
1125 element = null; 1129 element = null;
1126 } 1130 }
1127 if (element is PropertyAccessorElement) { 1131 if (element is PropertyAccessorElement) {
1128 // 1132 //
1129 // This is really a function expression invocation. 1133 // This is really a function expression invocation.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 // targetType.getElement() 1198 // targetType.getElement()
1195 return StaticTypeWarningCode.UNDEFINED_METHOD; 1199 return StaticTypeWarningCode.UNDEFINED_METHOD;
1196 } 1200 }
1197 } 1201 }
1198 } 1202 }
1199 } 1203 }
1200 return null; 1204 return null;
1201 } 1205 }
1202 1206
1203 /** 1207 /**
1204 * Check that the for some index expression that the method element was resolv ed, otherwise a 1208 * Check that the given index [expression] was resolved, otherwise a
1205 * [StaticTypeWarningCode.UNDEFINED_OPERATOR] is generated. 1209 * [StaticTypeWarningCode.UNDEFINED_OPERATOR] is generated. The [target] is
1206 * 1210 * the target of the expression. The [methodName] is the name of the operator
1207 * @param node the index expression to resolve 1211 * associated with the context of using of the given index expression.
1208 * @param target the target of the expression
1209 * @param methodName the name of the operator associated with the context of u sing of the given
1210 * index expression
1211 * @return `true` if and only if an error code is generated on the passed node
1212 */ 1212 */
1213 bool _checkForUndefinedIndexOperator(IndexExpression node, Expression target, 1213 bool _checkForUndefinedIndexOperator(IndexExpression expression,
1214 String methodName, MethodElement staticMethod, 1214 Expression target, String methodName, MethodElement staticMethod,
1215 MethodElement propagatedMethod, DartType staticType, 1215 MethodElement propagatedMethod, DartType staticType,
1216 DartType propagatedType) { 1216 DartType propagatedType) {
1217 bool shouldReportMissingMember_static = 1217 bool shouldReportMissingMember_static =
1218 _shouldReportMissingMember(staticType, staticMethod); 1218 _shouldReportMissingMember(staticType, staticMethod);
1219 bool shouldReportMissingMember_propagated = 1219 bool shouldReportMissingMember_propagated =
1220 !shouldReportMissingMember_static && 1220 !shouldReportMissingMember_static &&
1221 _enableHints && 1221 _enableHints &&
1222 _shouldReportMissingMember(propagatedType, propagatedMethod) && 1222 _shouldReportMissingMember(propagatedType, propagatedMethod) &&
1223 !_memberFoundInSubclass( 1223 !_memberFoundInSubclass(
1224 propagatedType.element, methodName, true, false); 1224 propagatedType.element, methodName, true, false);
1225 if (shouldReportMissingMember_static || 1225 if (shouldReportMissingMember_static ||
1226 shouldReportMissingMember_propagated) { 1226 shouldReportMissingMember_propagated) {
1227 sc.Token leftBracket = node.leftBracket; 1227 sc.Token leftBracket = expression.leftBracket;
1228 sc.Token rightBracket = node.rightBracket; 1228 sc.Token rightBracket = expression.rightBracket;
1229 ErrorCode errorCode; 1229 ErrorCode errorCode;
1230 if (shouldReportMissingMember_static) { 1230 if (shouldReportMissingMember_static) {
1231 if (target is SuperExpression) { 1231 if (target is SuperExpression) {
1232 errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR; 1232 errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR;
1233 } else { 1233 } else {
1234 errorCode = StaticTypeWarningCode.UNDEFINED_OPERATOR; 1234 errorCode = StaticTypeWarningCode.UNDEFINED_OPERATOR;
1235 } 1235 }
1236 } else { 1236 } else {
1237 errorCode = HintCode.UNDEFINED_OPERATOR; 1237 errorCode = HintCode.UNDEFINED_OPERATOR;
1238 } 1238 }
1239 DartType type = 1239 DartType type =
1240 shouldReportMissingMember_static ? staticType : propagatedType; 1240 shouldReportMissingMember_static ? staticType : propagatedType;
1241 if (leftBracket == null || rightBracket == null) { 1241 if (leftBracket == null || rightBracket == null) {
1242 _recordUndefinedNode( 1242 _recordUndefinedNode(type.element, errorCode, expression, [
1243 type.element, errorCode, node, [methodName, type.displayName]); 1243 methodName,
1244 type.displayName
1245 ]);
1244 } else { 1246 } else {
1245 int offset = leftBracket.offset; 1247 int offset = leftBracket.offset;
1246 int length = rightBracket.offset - offset + 1; 1248 int length = rightBracket.offset - offset + 1;
1247 _recordUndefinedOffset(type.element, errorCode, offset, length, [ 1249 _recordUndefinedOffset(type.element, errorCode, offset, length, [
1248 methodName, 1250 methodName,
1249 type.displayName 1251 type.displayName
1250 ]); 1252 ]);
1251 } 1253 }
1252 return true; 1254 return true;
1253 } 1255 }
1254 return false; 1256 return false;
1255 } 1257 }
1256 1258
1257 /** 1259 /**
1258 * Given a list of arguments and the element that will be invoked using those argument, compute 1260 * Given an [argumentList] and the executable [element] that will be invoked
1259 * the list of parameters that correspond to the list of arguments. Return the parameters that 1261 * using those arguments, compute the list of parameters that correspond to
1260 * correspond to the arguments, or `null` if no correspondence could be comput ed. 1262 * the list of arguments. Return the parameters that correspond to the
1261 * 1263 * arguments, or `null` if no correspondence could be computed.
1262 * @param argumentList the list of arguments being passed to the element
1263 * @param executableElement the element that will be invoked with the argument s
1264 * @return the parameters that correspond to the arguments
1265 */ 1264 */
1266 List<ParameterElement> _computeCorrespondingParameters( 1265 List<ParameterElement> _computeCorrespondingParameters(
1267 ArgumentList argumentList, Element element) { 1266 ArgumentList argumentList, Element element) {
1268 if (element is PropertyAccessorElement) { 1267 if (element is PropertyAccessorElement) {
1269 // 1268 //
1270 // This is an invocation of the call method defined on the value returned 1269 // This is an invocation of the call method defined on the value returned
1271 // by the getter. 1270 // by the getter.
1272 // 1271 //
1273 FunctionType getterType = element.type; 1272 FunctionType getterType = element.type;
1274 if (getterType != null) { 1273 if (getterType != null) {
(...skipping 25 matching lines...) Expand all
1300 if (callMethod != null) { 1299 if (callMethod != null) {
1301 List<ParameterElement> parameters = callMethod.parameters; 1300 List<ParameterElement> parameters = callMethod.parameters;
1302 return _resolveArgumentsToParameters(false, argumentList, parameters); 1301 return _resolveArgumentsToParameters(false, argumentList, parameters);
1303 } 1302 }
1304 } 1303 }
1305 } 1304 }
1306 return null; 1305 return null;
1307 } 1306 }
1308 1307
1309 /** 1308 /**
1310 * If the given element is a setter, return the getter associated with it. Oth erwise, return the 1309 * If the given [element] is a setter, return the getter associated with it.
1311 * element unchanged. 1310 * Otherwise, return the element unchanged.
1312 *
1313 * @param element the element to be normalized
1314 * @return a non-setter element derived from the given element
1315 */ 1311 */
1316 Element _convertSetterToGetter(Element element) { 1312 Element _convertSetterToGetter(Element element) {
1317 // TODO(brianwilkerson) Determine whether and why the element could ever be 1313 // TODO(brianwilkerson) Determine whether and why the element could ever be
1318 // a setter. 1314 // a setter.
1319 if (element is PropertyAccessorElement) { 1315 if (element is PropertyAccessorElement) {
1320 return element.variable.getter; 1316 return element.variable.getter;
1321 } 1317 }
1322 return element; 1318 return element;
1323 } 1319 }
1324 1320
1325 /** 1321 /**
1326 * Return `true` if the given element is not a proxy. 1322 * Return `true` if the given [element] is not a proxy. See
1327 * 1323 * [ClassElement.isOrInheritsProxy].
1328 * @param element the enclosing element. If null, `true` will be returned.
1329 * @return `false` iff the passed [Element] is a [ClassElement] that is a prox y
1330 * or inherits proxy
1331 * See [ClassElement.isOrInheritsProxy].
1332 */ 1324 */
1333 bool _doesntHaveProxy(Element element) => 1325 bool _doesntHaveProxy(Element element) =>
1334 !(element is ClassElement && element.isOrInheritsProxy); 1326 !(element is ClassElement && element.isOrInheritsProxy);
1335 1327
1336 /** 1328 /**
1337 * Look for any declarations of the given identifier that are imported using a prefix. Return the 1329 * Look for any declarations of the given [identifier] that are imported using
1338 * element that was found, or `null` if the name is not imported using a prefi x. 1330 * a prefix. Return the element that was found, or `null` if the name is not
1339 * 1331 * imported using a prefix.
1340 * @param identifier the identifier that might have been imported using a pref ix
1341 * @return the element that was found
1342 */ 1332 */
1343 Element _findImportWithoutPrefix(SimpleIdentifier identifier) { 1333 Element _findImportWithoutPrefix(SimpleIdentifier identifier) {
1344 Element element = null; 1334 Element element = null;
1345 Scope nameScope = _resolver.nameScope; 1335 Scope nameScope = _resolver.nameScope;
1346 for (ImportElement importElement in _definingLibrary.imports) { 1336 for (ImportElement importElement in _definingLibrary.imports) {
1347 PrefixElement prefixElement = importElement.prefix; 1337 PrefixElement prefixElement = importElement.prefix;
1348 if (prefixElement != null) { 1338 if (prefixElement != null) {
1349 Identifier prefixedIdentifier = new SyntheticIdentifier( 1339 Identifier prefixedIdentifier = new SyntheticIdentifier(
1350 "${prefixElement.name}.${identifier.name}", identifier); 1340 "${prefixElement.name}.${identifier.name}", identifier);
1351 Element importedElement = 1341 Element importedElement =
1352 nameScope.lookup(prefixedIdentifier, _definingLibrary); 1342 nameScope.lookup(prefixedIdentifier, _definingLibrary);
1353 if (importedElement != null) { 1343 if (importedElement != null) {
1354 if (element == null) { 1344 if (element == null) {
1355 element = importedElement; 1345 element = importedElement;
1356 } else { 1346 } else {
1357 element = MultiplyDefinedElementImpl.fromElements( 1347 element = MultiplyDefinedElementImpl.fromElements(
1358 _definingLibrary.context, element, importedElement); 1348 _definingLibrary.context, element, importedElement);
1359 } 1349 }
1360 } 1350 }
1361 } 1351 }
1362 } 1352 }
1363 return element; 1353 return element;
1364 } 1354 }
1365 1355
1366 /** 1356 /**
1367 * Assuming that the given expression is a prefix for a deferred import, retur n the library that 1357 * Assuming that the given [expression] is a prefix for a deferred import,
1368 * is being imported. 1358 * return the library that is being imported.
1369 *
1370 * @param expression the expression representing the deferred import's prefix
1371 * @return the library that is being imported by the import associated with th e prefix
1372 */ 1359 */
1373 LibraryElement _getImportedLibrary(Expression expression) { 1360 LibraryElement _getImportedLibrary(Expression expression) {
1374 PrefixElement prefixElement = 1361 PrefixElement prefixElement =
1375 (expression as SimpleIdentifier).staticElement as PrefixElement; 1362 (expression as SimpleIdentifier).staticElement as PrefixElement;
1376 List<ImportElement> imports = 1363 List<ImportElement> imports =
1377 prefixElement.enclosingElement.getImportsWithPrefix(prefixElement); 1364 prefixElement.enclosingElement.getImportsWithPrefix(prefixElement);
1378 return imports[0].importedLibrary; 1365 return imports[0].importedLibrary;
1379 } 1366 }
1380 1367
1381 /** 1368 /**
1382 * Return the name of the method invoked by the given postfix expression. 1369 * Return the name of the method invoked by the given postfix [expression].
1383 *
1384 * @param node the postfix expression being invoked
1385 * @return the name of the method invoked by the expression
1386 */ 1370 */
1387 String _getPostfixOperator(PostfixExpression node) => 1371 String _getPostfixOperator(PostfixExpression expression) =>
1388 (node.operator.type == sc.TokenType.PLUS_PLUS) 1372 (expression.operator.type == sc.TokenType.PLUS_PLUS)
1389 ? sc.TokenType.PLUS.lexeme 1373 ? sc.TokenType.PLUS.lexeme
1390 : sc.TokenType.MINUS.lexeme; 1374 : sc.TokenType.MINUS.lexeme;
1391 1375
1392 /** 1376 /**
1393 * Return the name of the method invoked by the given postfix expression. 1377 * Return the name of the method invoked by the given postfix [expression].
1394 *
1395 * @param node the postfix expression being invoked
1396 * @return the name of the method invoked by the expression
1397 */ 1378 */
1398 String _getPrefixOperator(PrefixExpression node) { 1379 String _getPrefixOperator(PrefixExpression expression) {
1399 sc.Token operator = node.operator; 1380 sc.Token operator = expression.operator;
1400 sc.TokenType operatorType = operator.type; 1381 sc.TokenType operatorType = operator.type;
1401 if (operatorType == sc.TokenType.PLUS_PLUS) { 1382 if (operatorType == sc.TokenType.PLUS_PLUS) {
1402 return sc.TokenType.PLUS.lexeme; 1383 return sc.TokenType.PLUS.lexeme;
1403 } else if (operatorType == sc.TokenType.MINUS_MINUS) { 1384 } else if (operatorType == sc.TokenType.MINUS_MINUS) {
1404 return sc.TokenType.MINUS.lexeme; 1385 return sc.TokenType.MINUS.lexeme;
1405 } else if (operatorType == sc.TokenType.MINUS) { 1386 } else if (operatorType == sc.TokenType.MINUS) {
1406 return "unary-"; 1387 return "unary-";
1407 } else { 1388 } else {
1408 return operator.lexeme; 1389 return operator.lexeme;
1409 } 1390 }
1410 } 1391 }
1411 1392
1412 /** 1393 /**
1413 * Return the propagated type of the given expression that is to be used for t ype analysis. 1394 * Return the propagated type of the given [expression] that is to be used for
1414 * 1395 * type analysis.
1415 * @param expression the expression whose type is to be returned
1416 * @return the type of the given expression
1417 */ 1396 */
1418 DartType _getPropagatedType(Expression expression) { 1397 DartType _getPropagatedType(Expression expression) {
1419 DartType propagatedType = _resolveTypeParameter(expression.propagatedType); 1398 DartType propagatedType = _resolveTypeParameter(expression.propagatedType);
1420 if (propagatedType is FunctionType) { 1399 if (propagatedType is FunctionType) {
1421 // 1400 //
1422 // All function types are subtypes of 'Function', which is itself a 1401 // All function types are subtypes of 'Function', which is itself a
1423 // subclass of 'Object'. 1402 // subclass of 'Object'.
1424 // 1403 //
1425 propagatedType = _resolver.typeProvider.functionType; 1404 propagatedType = _resolver.typeProvider.functionType;
1426 } 1405 }
1427 return propagatedType; 1406 return propagatedType;
1428 } 1407 }
1429 1408
1430 /** 1409 /**
1431 * Return the static type of the given expression that is to be used for type analysis. 1410 * Return the static type of the given [expression] that is to be used for
1432 * 1411 * type analysis.
1433 * @param expression the expression whose type is to be returned
1434 * @return the type of the given expression
1435 */ 1412 */
1436 DartType _getStaticType(Expression expression) { 1413 DartType _getStaticType(Expression expression) {
1437 if (expression is NullLiteral) { 1414 if (expression is NullLiteral) {
1438 return _resolver.typeProvider.bottomType; 1415 return _resolver.typeProvider.bottomType;
1439 } 1416 }
1440 DartType staticType = _resolveTypeParameter(expression.staticType); 1417 DartType staticType = _resolveTypeParameter(expression.staticType);
1441 if (staticType is FunctionType) { 1418 if (staticType is FunctionType) {
1442 // 1419 //
1443 // All function types are subtypes of 'Function', which is itself a 1420 // All function types are subtypes of 'Function', which is itself a
1444 // subclass of 'Object'. 1421 // subclass of 'Object'.
1445 // 1422 //
1446 staticType = _resolver.typeProvider.functionType; 1423 staticType = _resolver.typeProvider.functionType;
1447 } 1424 }
1448 return staticType; 1425 return staticType;
1449 } 1426 }
1450 1427
1451 /** 1428 /**
1452 * Return `true` if the given expression is a prefix for a deferred import. 1429 * Return `true` if the given [expression] is a prefix for a deferred import.
1453 *
1454 * @param expression the expression being tested
1455 * @return `true` if the given expression is a prefix for a deferred import
1456 */ 1430 */
1457 bool _isDeferredPrefix(Expression expression) { 1431 bool _isDeferredPrefix(Expression expression) {
1458 if (expression is! SimpleIdentifier) { 1432 if (expression is! SimpleIdentifier) {
1459 return false; 1433 return false;
1460 } 1434 }
1461 Element element = (expression as SimpleIdentifier).staticElement; 1435 Element element = (expression as SimpleIdentifier).staticElement;
1462 if (element is! PrefixElement) { 1436 if (element is! PrefixElement) {
1463 return false; 1437 return false;
1464 } 1438 }
1465 PrefixElement prefixElement = element as PrefixElement; 1439 PrefixElement prefixElement = element as PrefixElement;
1466 List<ImportElement> imports = 1440 List<ImportElement> imports =
1467 prefixElement.enclosingElement.getImportsWithPrefix(prefixElement); 1441 prefixElement.enclosingElement.getImportsWithPrefix(prefixElement);
1468 if (imports.length != 1) { 1442 if (imports.length != 1) {
1469 return false; 1443 return false;
1470 } 1444 }
1471 return imports[0].isDeferred; 1445 return imports[0].isDeferred;
1472 } 1446 }
1473 1447
1474 /** 1448 /**
1475 * Return `true` if the given type represents an object that could be invoked using the call 1449 * Return `true` if the given [type] represents an object that could be
1476 * operator '()'. 1450 * invoked using the call operator '()'.
1477 *
1478 * @param type the type being tested
1479 * @return `true` if the given type represents an object that could be invoked
1480 */ 1451 */
1481 bool _isExecutableType(DartType type) { 1452 bool _isExecutableType(DartType type) {
1482 if (type.isDynamic || type is FunctionType) { 1453 if (type.isDynamic || type is FunctionType) {
1483 return true; 1454 return true;
1484 } else if (!_enableStrictCallChecks && 1455 } else if (!_enableStrictCallChecks &&
1485 (type.isDartCoreFunction || type.isObject)) { 1456 (type.isDartCoreFunction || type.isObject)) {
1486 return true; 1457 return true;
1487 } else if (type is InterfaceType) { 1458 } else if (type is InterfaceType) {
1488 ClassElement classElement = type.element; 1459 ClassElement classElement = type.element;
1489 // 16078 from Gilad: If the type is a Functor with the @proxy annotation, 1460 // 16078 from Gilad: If the type is a Functor with the @proxy annotation,
1490 // treat it as an executable type. 1461 // treat it as an executable type.
1491 // example code: NonErrorResolverTest. 1462 // example code: NonErrorResolverTest.
1492 // test_invocationOfNonFunction_proxyOnFunctionClass() 1463 // test_invocationOfNonFunction_proxyOnFunctionClass()
1493 if (classElement.isProxy && 1464 if (classElement.isProxy &&
1494 type.isSubtypeOf(_resolver.typeProvider.functionType)) { 1465 type.isSubtypeOf(_resolver.typeProvider.functionType)) {
1495 return true; 1466 return true;
1496 } 1467 }
1497 MethodElement methodElement = classElement.lookUpMethod( 1468 MethodElement methodElement = classElement.lookUpMethod(
1498 FunctionElement.CALL_METHOD_NAME, _definingLibrary); 1469 FunctionElement.CALL_METHOD_NAME, _definingLibrary);
1499 return methodElement != null; 1470 return methodElement != null;
1500 } 1471 }
1501 return false; 1472 return false;
1502 } 1473 }
1503 1474
1504 /** 1475 /**
1505 * Return `true` if the given element is a static element. 1476 * Return `true` if the given [element] is a static element.
1506 *
1507 * @param element the element being tested
1508 * @return `true` if the given element is a static element
1509 */ 1477 */
1510 bool _isStatic(Element element) { 1478 bool _isStatic(Element element) {
1511 if (element is ExecutableElement) { 1479 if (element is ExecutableElement) {
1512 return element.isStatic; 1480 return element.isStatic;
1513 } else if (element is PropertyInducingElement) { 1481 } else if (element is PropertyInducingElement) {
1514 return element.isStatic; 1482 return element.isStatic;
1515 } 1483 }
1516 return false; 1484 return false;
1517 } 1485 }
1518 1486
1519 /** 1487 /**
1520 * Return `true` if the given node can validly be resolved to a prefix: 1488 * Return `true` if the given [node] can validly be resolved to a prefix:
1521 * * it is the prefix in an import directive, or 1489 * * it is the prefix in an import directive, or
1522 * * it is the prefix in a prefixed identifier. 1490 * * it is the prefix in a prefixed identifier.
1523 *
1524 * @param node the node being tested
1525 * @return `true` if the given node is the prefix in an import directive
1526 */ 1491 */
1527 bool _isValidAsPrefix(SimpleIdentifier node) { 1492 bool _isValidAsPrefix(SimpleIdentifier node) {
1528 AstNode parent = node.parent; 1493 AstNode parent = node.parent;
1529 if (parent is ImportDirective) { 1494 if (parent is ImportDirective) {
1530 return identical(parent.prefix, node); 1495 return identical(parent.prefix, node);
1531 } else if (parent is PrefixedIdentifier) { 1496 } else if (parent is PrefixedIdentifier) {
1532 return true; 1497 return true;
1533 } else if (parent is MethodInvocation) { 1498 } else if (parent is MethodInvocation) {
1534 return identical(parent.target, node); 1499 return identical(parent.target, node);
1535 } 1500 }
1536 return false; 1501 return false;
1537 } 1502 }
1538 1503
1539 /** 1504 /**
1540 * Return the target of a break or continue statement, and update the static 1505 * Return the target of a break or continue statement, and update the static
1541 * element of its label (if any). [parentNode] is the AST node of the break 1506 * element of its label (if any). The [parentNode] is the AST node of the
1542 * or continue statement, [labelNode] is the label contained in that 1507 * break or continue statement. The [labelNode] is the label contained in that
1543 * statement (if any), and [isContinue] is true if the node being visited is 1508 * statement (if any). The flag [isContinue] is `true` if the node being
1544 * a continue statement. 1509 * visited is a continue statement.
1545 */ 1510 */
1546 AstNode _lookupBreakOrContinueTarget( 1511 AstNode _lookupBreakOrContinueTarget(
1547 AstNode parentNode, SimpleIdentifier labelNode, bool isContinue) { 1512 AstNode parentNode, SimpleIdentifier labelNode, bool isContinue) {
1548 if (labelNode == null) { 1513 if (labelNode == null) {
1549 return _resolver.implicitLabelScope.getTarget(isContinue); 1514 return _resolver.implicitLabelScope.getTarget(isContinue);
1550 } else { 1515 } else {
1551 LabelScope labelScope = _resolver.labelScope; 1516 LabelScope labelScope = _resolver.labelScope;
1552 if (labelScope == null) { 1517 if (labelScope == null) {
1553 // There are no labels in scope, so by definition the label is 1518 // There are no labels in scope, so by definition the label is
1554 // undefined. 1519 // undefined.
(...skipping 15 matching lines...) Expand all
1570 .getAncestor((element) => element is ExecutableElement); 1535 .getAncestor((element) => element is ExecutableElement);
1571 if (!identical(labelContainer, _resolver.enclosingFunction)) { 1536 if (!identical(labelContainer, _resolver.enclosingFunction)) {
1572 _resolver.reportErrorForNode(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, 1537 _resolver.reportErrorForNode(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE,
1573 labelNode, [labelNode.name]); 1538 labelNode, [labelNode.name]);
1574 } 1539 }
1575 return definingScope.node; 1540 return definingScope.node;
1576 } 1541 }
1577 } 1542 }
1578 1543
1579 /** 1544 /**
1580 * Look up the getter with the given name in the given type. Return the elemen t representing the 1545 * Look up the getter with the given [getterName] in the given [type]. Return
1581 * getter that was found, or `null` if there is no getter with the given name. 1546 * the element representing the getter that was found, or `null` if there is
1582 * 1547 * no getter with the given name. The [target] is the target of the
1583 * @param target the target of the invocation, or `null` if there is no target 1548 * invocation, or `null` if there is no target.
1584 * @param type the type in which the getter is defined
1585 * @param getterName the name of the getter being looked up
1586 * @return the element representing the getter that was found
1587 */ 1549 */
1588 PropertyAccessorElement _lookUpGetter( 1550 PropertyAccessorElement _lookUpGetter(
1589 Expression target, DartType type, String getterName) { 1551 Expression target, DartType type, String getterName) {
1590 type = _resolveTypeParameter(type); 1552 type = _resolveTypeParameter(type);
1591 if (type is InterfaceType) { 1553 if (type is InterfaceType) {
1592 InterfaceType interfaceType = type; 1554 InterfaceType interfaceType = type;
1593 PropertyAccessorElement accessor; 1555 PropertyAccessorElement accessor;
1594 if (target is SuperExpression) { 1556 if (target is SuperExpression) {
1595 accessor = interfaceType.lookUpGetterInSuperclass( 1557 accessor = interfaceType.lookUpGetterInSuperclass(
1596 getterName, _definingLibrary); 1558 getterName, _definingLibrary);
1597 } else { 1559 } else {
1598 accessor = interfaceType.lookUpGetter(getterName, _definingLibrary); 1560 accessor = interfaceType.lookUpGetter(getterName, _definingLibrary);
1599 } 1561 }
1600 if (accessor != null) { 1562 if (accessor != null) {
1601 return accessor; 1563 return accessor;
1602 } 1564 }
1603 return _lookUpGetterInInterfaces( 1565 return _lookUpGetterInInterfaces(
1604 interfaceType, false, getterName, new HashSet<ClassElement>()); 1566 interfaceType, false, getterName, new HashSet<ClassElement>());
1605 } 1567 }
1606 return null; 1568 return null;
1607 } 1569 }
1608 1570
1609 /** 1571 /**
1610 * Look up the getter with the given name in the interfaces implemented by the given type, either 1572 * Look up the getter with the given [getterName] in the interfaces
1611 * directly or indirectly. Return the element representing the getter that was found, or 1573 * implemented by the given [targetType], either directly or indirectly.
1612 * `null` if there is no getter with the given name. 1574 * Return the element representing the getter that was found, or `null` if
1613 * 1575 * there is no getter with the given name. The flag [includeTargetType] should
1614 * @param targetType the type in which the getter might be defined 1576 * be `true` if the search should include the target type. The
1615 * @param includeTargetType `true` if the search should include the target typ e 1577 * [visitedInterfaces] is a set containing all of the interfaces that have
1616 * @param getterName the name of the getter being looked up 1578 * been examined, used to prevent infinite recursion and to optimize the
1617 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used 1579 * search.
1618 * to prevent infinite recursion and to optimize the search
1619 * @return the element representing the getter that was found
1620 */ 1580 */
1621 PropertyAccessorElement _lookUpGetterInInterfaces(InterfaceType targetType, 1581 PropertyAccessorElement _lookUpGetterInInterfaces(InterfaceType targetType,
1622 bool includeTargetType, String getterName, 1582 bool includeTargetType, String getterName,
1623 HashSet<ClassElement> visitedInterfaces) { 1583 HashSet<ClassElement> visitedInterfaces) {
1624 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the 1584 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
1625 // specification (titled "Inheritance and Overriding" under "Interfaces") 1585 // specification (titled "Inheritance and Overriding" under "Interfaces")
1626 // describes a much more complex scheme for finding the inherited member. 1586 // describes a much more complex scheme for finding the inherited member.
1627 // We need to follow that scheme. The code below should cover the 80% case. 1587 // We need to follow that scheme. The code below should cover the 80% case.
1628 ClassElement targetClass = targetType.element; 1588 ClassElement targetClass = targetType.element;
1629 if (visitedInterfaces.contains(targetClass)) { 1589 if (visitedInterfaces.contains(targetClass)) {
(...skipping 22 matching lines...) Expand all
1652 } 1612 }
1653 InterfaceType superclass = targetType.superclass; 1613 InterfaceType superclass = targetType.superclass;
1654 if (superclass == null) { 1614 if (superclass == null) {
1655 return null; 1615 return null;
1656 } 1616 }
1657 return _lookUpGetterInInterfaces( 1617 return _lookUpGetterInInterfaces(
1658 superclass, true, getterName, visitedInterfaces); 1618 superclass, true, getterName, visitedInterfaces);
1659 } 1619 }
1660 1620
1661 /** 1621 /**
1662 * Look up the method or getter with the given name in the given type. Return the element 1622 * Look up the method or getter with the given [memberName] in the given
1663 * representing the method or getter that was found, or `null` if there is no method or 1623 * [type]. Return the element representing the method or getter that was
1664 * getter with the given name. 1624 * found, or `null` if there is no method or getter with the given name.
1665 *
1666 * @param type the type in which the method or getter is defined
1667 * @param memberName the name of the method or getter being looked up
1668 * @return the element representing the method or getter that was found
1669 */ 1625 */
1670 ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) { 1626 ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) {
1671 type = _resolveTypeParameter(type); 1627 type = _resolveTypeParameter(type);
1672 if (type is InterfaceType) { 1628 if (type is InterfaceType) {
1673 InterfaceType interfaceType = type; 1629 InterfaceType interfaceType = type;
1674 ExecutableElement member = 1630 ExecutableElement member =
1675 interfaceType.lookUpMethod(memberName, _definingLibrary); 1631 interfaceType.lookUpMethod(memberName, _definingLibrary);
1676 if (member != null) { 1632 if (member != null) {
1677 return member; 1633 return member;
1678 } 1634 }
1679 member = interfaceType.lookUpGetter(memberName, _definingLibrary); 1635 member = interfaceType.lookUpGetter(memberName, _definingLibrary);
1680 if (member != null) { 1636 if (member != null) {
1681 return member; 1637 return member;
1682 } 1638 }
1683 return _lookUpGetterOrMethodInInterfaces( 1639 return _lookUpGetterOrMethodInInterfaces(
1684 interfaceType, false, memberName, new HashSet<ClassElement>()); 1640 interfaceType, false, memberName, new HashSet<ClassElement>());
1685 } 1641 }
1686 return null; 1642 return null;
1687 } 1643 }
1688 1644
1689 /** 1645 /**
1690 * Look up the method or getter with the given name in the interfaces implemen ted by the given 1646 * Look up the method or getter with the given [memberName] in the interfaces
1691 * type, either directly or indirectly. Return the element representing the me thod or getter that 1647 * implemented by the given [targetType], either directly or indirectly.
1692 * was found, or `null` if there is no method or getter with the given name. 1648 * Return the element representing the method or getter that was found, or
1693 * 1649 * `null` if there is no method or getter with the given name. The flag
1694 * @param targetType the type in which the method or getter might be defined 1650 * [includeTargetType] should be `true` if the search should include the
1695 * @param includeTargetType `true` if the search should include the target typ e 1651 * target type. The [visitedInterfaces] is a set containing all of the
1696 * @param memberName the name of the method or getter being looked up 1652 * interfaces that have been examined, used to prevent infinite recursion and
1697 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used 1653 * to optimize the search.
1698 * to prevent infinite recursion and to optimize the search
1699 * @return the element representing the method or getter that was found
1700 */ 1654 */
1701 ExecutableElement _lookUpGetterOrMethodInInterfaces(InterfaceType targetType, 1655 ExecutableElement _lookUpGetterOrMethodInInterfaces(InterfaceType targetType,
1702 bool includeTargetType, String memberName, 1656 bool includeTargetType, String memberName,
1703 HashSet<ClassElement> visitedInterfaces) { 1657 HashSet<ClassElement> visitedInterfaces) {
1704 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the 1658 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
1705 // specification (titled "Inheritance and Overriding" under "Interfaces") 1659 // specification (titled "Inheritance and Overriding" under "Interfaces")
1706 // describes a much more complex scheme for finding the inherited member. 1660 // describes a much more complex scheme for finding the inherited member.
1707 // We need to follow that scheme. The code below should cover the 80% case. 1661 // We need to follow that scheme. The code below should cover the 80% case.
1708 ClassElement targetClass = targetType.element; 1662 ClassElement targetClass = targetType.element;
1709 if (visitedInterfaces.contains(targetClass)) { 1663 if (visitedInterfaces.contains(targetClass)) {
(...skipping 26 matching lines...) Expand all
1736 } 1690 }
1737 InterfaceType superclass = targetType.superclass; 1691 InterfaceType superclass = targetType.superclass;
1738 if (superclass == null) { 1692 if (superclass == null) {
1739 return null; 1693 return null;
1740 } 1694 }
1741 return _lookUpGetterOrMethodInInterfaces( 1695 return _lookUpGetterOrMethodInInterfaces(
1742 superclass, true, memberName, visitedInterfaces); 1696 superclass, true, memberName, visitedInterfaces);
1743 } 1697 }
1744 1698
1745 /** 1699 /**
1746 * Look up the method with the given name in the given type. Return the elemen t representing the 1700 * Look up the method with the given [methodName] in the given [type]. Return
1747 * method that was found, or `null` if there is no method with the given name. 1701 * the element representing the method that was found, or `null` if there is
1748 * 1702 * no method with the given name. The [target] is the target of the
1749 * @param target the target of the invocation, or `null` if there is no target 1703 * invocation, or `null` if there is no target.
1750 * @param type the type in which the method is defined
1751 * @param methodName the name of the method being looked up
1752 * @return the element representing the method that was found
1753 */ 1704 */
1754 MethodElement _lookUpMethod( 1705 MethodElement _lookUpMethod(
1755 Expression target, DartType type, String methodName) { 1706 Expression target, DartType type, String methodName) {
1756 type = _resolveTypeParameter(type); 1707 type = _resolveTypeParameter(type);
1757 if (type is InterfaceType) { 1708 if (type is InterfaceType) {
1758 InterfaceType interfaceType = type; 1709 InterfaceType interfaceType = type;
1759 MethodElement method; 1710 MethodElement method;
1760 if (target is SuperExpression) { 1711 if (target is SuperExpression) {
1761 method = interfaceType.lookUpMethodInSuperclass( 1712 method = interfaceType.lookUpMethodInSuperclass(
1762 methodName, _definingLibrary); 1713 methodName, _definingLibrary);
(...skipping 10 matching lines...) Expand all
1773 // and work with functions, methods, constructors, and property accessors. 1724 // and work with functions, methods, constructors, and property accessors.
1774 // However, I won't be able to assume it returns [MethodElement] here 1725 // However, I won't be able to assume it returns [MethodElement] here
1775 // then. 1726 // then.
1776 return _maybeMergeExecutableElements( 1727 return _maybeMergeExecutableElements(
1777 _lookupMethods(target, type, methodName)) as MethodElement; 1728 _lookupMethods(target, type, methodName)) as MethodElement;
1778 } 1729 }
1779 return null; 1730 return null;
1780 } 1731 }
1781 1732
1782 /** 1733 /**
1783 * Look up the method with the given name in the interfaces implemented by the given type, either 1734 * Look up the method with the given [methodName] in the interfaces
1784 * directly or indirectly. Return the element representing the method that was found, or 1735 * implemented by the given [targetType], either directly or indirectly.
1785 * `null` if there is no method with the given name. 1736 * Return the element representing the method that was found, or `null` if
1786 * 1737 * there is no method with the given name. The flag [includeTargetType] should
1787 * @param targetType the type in which the member might be defined 1738 * be `true` if the search should include the target type. The
1788 * @param includeTargetType `true` if the search should include the target typ e 1739 * [visitedInterfaces] is a set containing all of the interfaces that have
1789 * @param methodName the name of the method being looked up 1740 * been examined, used to prevent infinite recursion and to optimize the
1790 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used 1741 * search.
1791 * to prevent infinite recursion and to optimize the search
1792 * @return the element representing the method that was found
1793 */ 1742 */
1794 MethodElement _lookUpMethodInInterfaces(InterfaceType targetType, 1743 MethodElement _lookUpMethodInInterfaces(InterfaceType targetType,
1795 bool includeTargetType, String methodName, 1744 bool includeTargetType, String methodName,
1796 HashSet<ClassElement> visitedInterfaces) { 1745 HashSet<ClassElement> visitedInterfaces) {
1797 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the 1746 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
1798 // specification (titled "Inheritance and Overriding" under "Interfaces") 1747 // specification (titled "Inheritance and Overriding" under "Interfaces")
1799 // describes a much more complex scheme for finding the inherited member. 1748 // describes a much more complex scheme for finding the inherited member.
1800 // We need to follow that scheme. The code below should cover the 80% case. 1749 // We need to follow that scheme. The code below should cover the 80% case.
1801 ClassElement targetClass = targetType.element; 1750 ClassElement targetClass = targetType.element;
1802 if (visitedInterfaces.contains(targetClass)) { 1751 if (visitedInterfaces.contains(targetClass)) {
(...skipping 22 matching lines...) Expand all
1825 } 1774 }
1826 InterfaceType superclass = targetType.superclass; 1775 InterfaceType superclass = targetType.superclass;
1827 if (superclass == null) { 1776 if (superclass == null) {
1828 return null; 1777 return null;
1829 } 1778 }
1830 return _lookUpMethodInInterfaces( 1779 return _lookUpMethodInInterfaces(
1831 superclass, true, methodName, visitedInterfaces); 1780 superclass, true, methodName, visitedInterfaces);
1832 } 1781 }
1833 1782
1834 /** 1783 /**
1835 * Look up all methods of a given name defined on a union type. 1784 * Look up all methods with the given [methodName] that are defined on the
1836 * 1785 * given union [type].
1837 * @param target
1838 * @param type
1839 * @param methodName
1840 * @return all methods named `methodName` defined on the union type `type`.
1841 */ 1786 */
1842 Set<ExecutableElement> _lookupMethods( 1787 Set<ExecutableElement> _lookupMethods(
1843 Expression target, UnionType type, String methodName) { 1788 Expression target, UnionType type, String methodName) {
1844 Set<ExecutableElement> methods = new HashSet<ExecutableElement>(); 1789 Set<ExecutableElement> methods = new HashSet<ExecutableElement>();
1845 bool allElementsHaveMethod = true; 1790 bool allElementsHaveMethod = true;
1846 for (DartType t in type.elements) { 1791 for (DartType t in type.elements) {
1847 MethodElement m = _lookUpMethod(target, t, methodName); 1792 MethodElement m = _lookUpMethod(target, t, methodName);
1848 if (m != null) { 1793 if (m != null) {
1849 methods.add(m); 1794 methods.add(m);
1850 } else { 1795 } else {
1851 allElementsHaveMethod = false; 1796 allElementsHaveMethod = false;
1852 } 1797 }
1853 } 1798 }
1854 // For strict union types we require that all types in the union define the 1799 // For strict union types we require that all types in the union define the
1855 // method. 1800 // method.
1856 if (AnalysisEngine.instance.strictUnionTypes) { 1801 if (AnalysisEngine.instance.strictUnionTypes) {
1857 if (allElementsHaveMethod) { 1802 if (allElementsHaveMethod) {
1858 return methods; 1803 return methods;
1859 } else { 1804 } else {
1860 return new Set<ExecutableElement>(); 1805 return new Set<ExecutableElement>();
1861 } 1806 }
1862 } else { 1807 } else {
1863 return methods; 1808 return methods;
1864 } 1809 }
1865 } 1810 }
1866 1811
1867 /** 1812 /**
1868 * Look up the setter with the given name in the given type. Return the elemen t representing the 1813 * Look up the setter with the given [setterName] in the given [type]. Return
1869 * setter that was found, or `null` if there is no setter with the given name. 1814 * the element representing the setter that was found, or `null` if there is
1870 * 1815 * no setter with the given name. The [target] is the target of the
1871 * @param target the target of the invocation, or `null` if there is no target 1816 * invocation, or `null` if there is no target.
1872 * @param type the type in which the setter is defined
1873 * @param setterName the name of the setter being looked up
1874 * @return the element representing the setter that was found
1875 */ 1817 */
1876 PropertyAccessorElement _lookUpSetter( 1818 PropertyAccessorElement _lookUpSetter(
1877 Expression target, DartType type, String setterName) { 1819 Expression target, DartType type, String setterName) {
1878 type = _resolveTypeParameter(type); 1820 type = _resolveTypeParameter(type);
1879 if (type is InterfaceType) { 1821 if (type is InterfaceType) {
1880 InterfaceType interfaceType = type; 1822 InterfaceType interfaceType = type;
1881 PropertyAccessorElement accessor; 1823 PropertyAccessorElement accessor;
1882 if (target is SuperExpression) { 1824 if (target is SuperExpression) {
1883 accessor = interfaceType.lookUpSetterInSuperclass( 1825 accessor = interfaceType.lookUpSetterInSuperclass(
1884 setterName, _definingLibrary); 1826 setterName, _definingLibrary);
1885 } else { 1827 } else {
1886 accessor = interfaceType.lookUpSetter(setterName, _definingLibrary); 1828 accessor = interfaceType.lookUpSetter(setterName, _definingLibrary);
1887 } 1829 }
1888 if (accessor != null) { 1830 if (accessor != null) {
1889 return accessor; 1831 return accessor;
1890 } 1832 }
1891 return _lookUpSetterInInterfaces( 1833 return _lookUpSetterInInterfaces(
1892 interfaceType, false, setterName, new HashSet<ClassElement>()); 1834 interfaceType, false, setterName, new HashSet<ClassElement>());
1893 } 1835 }
1894 return null; 1836 return null;
1895 } 1837 }
1896 1838
1897 /** 1839 /**
1898 * Look up the setter with the given name in the interfaces implemented by the given type, either 1840 * Look up the setter with the given [setterName] in the interfaces
1899 * directly or indirectly. Return the element representing the setter that was found, or 1841 * implemented by the given [targetType], either directly or indirectly.
1900 * `null` if there is no setter with the given name. 1842 * Return the element representing the setter that was found, or `null` if
1901 * 1843 * there is no setter with the given name. The [targetType] is the type in
1902 * @param targetType the type in which the setter might be defined 1844 * which the setter might be defined. The flag [includeTargetType] should be
1903 * @param includeTargetType `true` if the search should include the target typ e 1845 * `true` if the search should include the target type. The
1904 * @param setterName the name of the setter being looked up 1846 * [visitedInterfaces] is a set containing all of the interfaces that have
1905 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used 1847 * been examined, used to prevent infinite recursion and to optimize the
1906 * to prevent infinite recursion and to optimize the search 1848 * search.
1907 * @return the element representing the setter that was found
1908 */ 1849 */
1909 PropertyAccessorElement _lookUpSetterInInterfaces(InterfaceType targetType, 1850 PropertyAccessorElement _lookUpSetterInInterfaces(InterfaceType targetType,
1910 bool includeTargetType, String setterName, 1851 bool includeTargetType, String setterName,
1911 HashSet<ClassElement> visitedInterfaces) { 1852 HashSet<ClassElement> visitedInterfaces) {
1912 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the 1853 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
1913 // specification (titled "Inheritance and Overriding" under "Interfaces") 1854 // specification (titled "Inheritance and Overriding" under "Interfaces")
1914 // describes a much more complex scheme for finding the inherited member. 1855 // describes a much more complex scheme for finding the inherited member.
1915 // We need to follow that scheme. The code below should cover the 80% case. 1856 // We need to follow that scheme. The code below should cover the 80% case.
1916 ClassElement targetClass = targetType.element; 1857 ClassElement targetClass = targetType.element;
1917 if (visitedInterfaces.contains(targetClass)) { 1858 if (visitedInterfaces.contains(targetClass)) {
(...skipping 22 matching lines...) Expand all
1940 } 1881 }
1941 InterfaceType superclass = targetType.superclass; 1882 InterfaceType superclass = targetType.superclass;
1942 if (superclass == null) { 1883 if (superclass == null) {
1943 return null; 1884 return null;
1944 } 1885 }
1945 return _lookUpSetterInInterfaces( 1886 return _lookUpSetterInInterfaces(
1946 superclass, true, setterName, visitedInterfaces); 1887 superclass, true, setterName, visitedInterfaces);
1947 } 1888 }
1948 1889
1949 /** 1890 /**
1950 * Given some class element, this method uses [subtypeManager] to find the set of all 1891 * Given some class [element], this method uses [_subtypeManager] to find the
1951 * subtypes; the subtypes are then searched for a member (method, getter, or s etter), that matches 1892 * set of all subtypes; the subtypes are then searched for a member (method,
1952 * a passed 1893 * getter, or setter), that has the given [memberName]. The flag [asMethod]
1953 * 1894 * should be `true` if the methods should be searched for in the subtypes. The
1954 * @param element the class element to search the subtypes of, if a non-ClassE lement element is 1895 * flag [asAccessor] should be `true` if the accessors (getters and setters)
1955 * passed, then `false` is returned 1896 * should be searched for in the subtypes.
1956 * @param memberName the member name to search for
1957 * @param asMethod `true` if the methods should be searched for in the subtype s
1958 * @param asAccessor `true` if the accessors (getters and setters) should be s earched for in
1959 * the subtypes
1960 * @return `true` if and only if the passed memberName was found in a subtype
1961 */ 1897 */
1962 bool _memberFoundInSubclass( 1898 bool _memberFoundInSubclass(
1963 Element element, String memberName, bool asMethod, bool asAccessor) { 1899 Element element, String memberName, bool asMethod, bool asAccessor) {
1964 if (element is ClassElement) { 1900 if (element is ClassElement) {
1965 _subtypeManager.ensureLibraryVisited(_definingLibrary); 1901 _subtypeManager.ensureLibraryVisited(_definingLibrary);
1966 HashSet<ClassElement> subtypeElements = 1902 HashSet<ClassElement> subtypeElements =
1967 _subtypeManager.computeAllSubtypes(element); 1903 _subtypeManager.computeAllSubtypes(element);
1968 for (ClassElement subtypeElement in subtypeElements) { 1904 for (ClassElement subtypeElement in subtypeElements) {
1969 if (asMethod && subtypeElement.getMethod(memberName) != null) { 1905 if (asMethod && subtypeElement.getMethod(memberName) != null) {
1970 return true; 1906 return true;
1971 } else if (asAccessor && 1907 } else if (asAccessor &&
1972 (subtypeElement.getGetter(memberName) != null || 1908 (subtypeElement.getGetter(memberName) != null ||
1973 subtypeElement.getSetter(memberName) != null)) { 1909 subtypeElement.getSetter(memberName) != null)) {
1974 return true; 1910 return true;
1975 } 1911 }
1976 } 1912 }
1977 } 1913 }
1978 return false; 1914 return false;
1979 } 1915 }
1980 1916
1981 /** 1917 /**
1982 * Return the binary operator that is invoked by the given compound assignment operator. 1918 * Return the binary operator that is invoked by the given compound assignment
1983 * 1919 * [operator].
1984 * @param operator the assignment operator being mapped
1985 * @return the binary operator that invoked by the given assignment operator
1986 */ 1920 */
1987 sc.TokenType _operatorFromCompoundAssignment(sc.TokenType operator) { 1921 sc.TokenType _operatorFromCompoundAssignment(sc.TokenType operator) {
1988 while (true) { 1922 while (true) {
1989 if (operator == sc.TokenType.AMPERSAND_EQ) { 1923 if (operator == sc.TokenType.AMPERSAND_EQ) {
1990 return sc.TokenType.AMPERSAND; 1924 return sc.TokenType.AMPERSAND;
1991 } else if (operator == sc.TokenType.BAR_EQ) { 1925 } else if (operator == sc.TokenType.BAR_EQ) {
1992 return sc.TokenType.BAR; 1926 return sc.TokenType.BAR;
1993 } else if (operator == sc.TokenType.CARET_EQ) { 1927 } else if (operator == sc.TokenType.CARET_EQ) {
1994 return sc.TokenType.CARET; 1928 return sc.TokenType.CARET;
1995 } else if (operator == sc.TokenType.GT_GT_EQ) { 1929 } else if (operator == sc.TokenType.GT_GT_EQ) {
(...skipping 16 matching lines...) Expand all
2012 // Internal error: Unmapped assignment operator. 1946 // Internal error: Unmapped assignment operator.
2013 AnalysisEngine.instance.logger.logError( 1947 AnalysisEngine.instance.logger.logError(
2014 "Failed to map ${operator.lexeme} to it's corresponding operator"); 1948 "Failed to map ${operator.lexeme} to it's corresponding operator");
2015 return operator; 1949 return operator;
2016 } 1950 }
2017 break; 1951 break;
2018 } 1952 }
2019 } 1953 }
2020 1954
2021 /** 1955 /**
2022 * Record that the given node is undefined, causing an error to be reported if appropriate. 1956 * Record that the given [node] is undefined, causing an error to be reported
2023 * 1957 * if appropriate. The [declaringElement] is the element inside which no
2024 * @param declaringElement the element inside which no declaration was found. If this element is a 1958 * declaration was found. If this element is a proxy, no error will be
2025 * proxy, no error will be reported. If null, then an error will alwa ys be reported. 1959 * reported. If null, then an error will always be reported. The [errorCode]
2026 * @param errorCode the error code to report. 1960 * is the error code to report. The [arguments] are the arguments to the error
2027 * @param node the node which is undefined. 1961 * message.
2028 * @param arguments arguments to the error message.
2029 */ 1962 */
2030 void _recordUndefinedNode(Element declaringElement, ErrorCode errorCode, 1963 void _recordUndefinedNode(Element declaringElement, ErrorCode errorCode,
2031 AstNode node, List<Object> arguments) { 1964 AstNode node, List<Object> arguments) {
2032 if (_doesntHaveProxy(declaringElement)) { 1965 if (_doesntHaveProxy(declaringElement)) {
2033 _resolver.reportErrorForNode(errorCode, node, arguments); 1966 _resolver.reportErrorForNode(errorCode, node, arguments);
2034 } 1967 }
2035 } 1968 }
2036 1969
2037 /** 1970 /**
2038 * Record that the given offset/length is undefined, causing an error to be re ported if 1971 * Record that the given [offset]/[length] is undefined, causing an error to
2039 * appropriate. 1972 * be reported if appropriate. The [declaringElement] is the element inside
2040 * 1973 * which no declaration was found. If this element is a proxy, no error will
2041 * @param declaringElement the element inside which no declaration was found. If this element is a 1974 * be reported. If null, then an error will always be reported. The
2042 * proxy, no error will be reported. If null, then an error will alwa ys be reported. 1975 * [errorCode] is the error code to report. The [arguments] are arguments to
2043 * @param errorCode the error code to report. 1976 * the error message.
2044 * @param offset the offset to the text which is undefined.
2045 * @param length the length of the text which is undefined.
2046 * @param arguments arguments to the error message.
2047 */ 1977 */
2048 void _recordUndefinedOffset(Element declaringElement, ErrorCode errorCode, 1978 void _recordUndefinedOffset(Element declaringElement, ErrorCode errorCode,
2049 int offset, int length, List<Object> arguments) { 1979 int offset, int length, List<Object> arguments) {
2050 if (_doesntHaveProxy(declaringElement)) { 1980 if (_doesntHaveProxy(declaringElement)) {
2051 _resolver.reportErrorForOffset(errorCode, offset, length, arguments); 1981 _resolver.reportErrorForOffset(errorCode, offset, length, arguments);
2052 } 1982 }
2053 } 1983 }
2054 1984
2055 /** 1985 /**
2056 * Record that the given token is undefined, causing an error to be reported i f appropriate. 1986 * Record that the given [token] is undefined, causing an error to be reported
2057 * 1987 * if appropriate. The [declaringElement] is the element inside which no
2058 * @param declaringElement the element inside which no declaration was found. If this element is a 1988 * declaration was found. If this element is a proxy, no error will be
2059 * proxy, no error will be reported. If null, then an error will alwa ys be reported. 1989 * reported. If null, then an error will always be reported. The [errorCode]
2060 * @param errorCode the error code to report. 1990 * is the error code to report. The [arguments] are arguments to the error
2061 * @param token the token which is undefined. 1991 * message.
2062 * @param arguments arguments to the error message.
2063 */ 1992 */
2064 void _recordUndefinedToken(Element declaringElement, ErrorCode errorCode, 1993 void _recordUndefinedToken(Element declaringElement, ErrorCode errorCode,
2065 sc.Token token, List<Object> arguments) { 1994 sc.Token token, List<Object> arguments) {
2066 if (_doesntHaveProxy(declaringElement)) { 1995 if (_doesntHaveProxy(declaringElement)) {
2067 _resolver.reportErrorForToken(errorCode, token, arguments); 1996 _resolver.reportErrorForToken(errorCode, token, arguments);
2068 } 1997 }
2069 } 1998 }
2070 1999
2071 void _resolveAnnotationConstructorInvocationArguments( 2000 void _resolveAnnotationConstructorInvocationArguments(
2072 Annotation annotation, ConstructorElement constructor) { 2001 Annotation annotation, ConstructorElement constructor) {
2073 ArgumentList argumentList = annotation.arguments; 2002 ArgumentList argumentList = annotation.arguments;
2074 // error will be reported in ConstantVerifier 2003 // error will be reported in ConstantVerifier
2075 if (argumentList == null) { 2004 if (argumentList == null) {
2076 return; 2005 return;
2077 } 2006 }
2078 // resolve arguments to parameters 2007 // resolve arguments to parameters
2079 List<ParameterElement> parameters = 2008 List<ParameterElement> parameters =
2080 _resolveArgumentsToFunction(true, argumentList, constructor); 2009 _resolveArgumentsToFunction(true, argumentList, constructor);
2081 if (parameters != null) { 2010 if (parameters != null) {
2082 argumentList.correspondingStaticParameters = parameters; 2011 argumentList.correspondingStaticParameters = parameters;
2083 } 2012 }
2084 } 2013 }
2085 2014
2086 /** 2015 /**
2087 * Continues resolution of the given [Annotation]. 2016 * Continues resolution of the given [annotation].
2088 *
2089 * @param annotation the [Annotation] to resolve
2090 */ 2017 */
2091 void _resolveAnnotationElement(Annotation annotation) { 2018 void _resolveAnnotationElement(Annotation annotation) {
2092 SimpleIdentifier nameNode1; 2019 SimpleIdentifier nameNode1;
2093 SimpleIdentifier nameNode2; 2020 SimpleIdentifier nameNode2;
2094 { 2021 {
2095 Identifier annName = annotation.name; 2022 Identifier annName = annotation.name;
2096 if (annName is PrefixedIdentifier) { 2023 if (annName is PrefixedIdentifier) {
2097 PrefixedIdentifier prefixed = annName; 2024 PrefixedIdentifier prefixed = annName;
2098 nameNode1 = prefixed.prefix; 2025 nameNode1 = prefixed.prefix;
2099 nameNode2 = prefixed.identifier; 2026 nameNode2 = prefixed.identifier;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2199 VariableElement variableElement = accessorElement.variable; 2126 VariableElement variableElement = accessorElement.variable;
2200 if (!variableElement.isConst) { 2127 if (!variableElement.isConst) {
2201 _resolver.reportErrorForNode( 2128 _resolver.reportErrorForNode(
2202 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); 2129 CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
2203 } 2130 }
2204 // OK 2131 // OK
2205 return; 2132 return;
2206 } 2133 }
2207 2134
2208 /** 2135 /**
2209 * Given a list of arguments and the element that will be invoked using those argument, compute 2136 * Given an [argumentList] and the [executableElement] that will be invoked
2210 * the list of parameters that correspond to the list of arguments. Return the parameters that 2137 * using those argument, compute the list of parameters that correspond to the
2211 * correspond to the arguments, or `null` if no correspondence could be comput ed. 2138 * list of arguments. An error will be reported if any of the arguments cannot
2212 * 2139 * be matched to a parameter. The flag [reportError] should be `true` if a
2213 * @param reportError if `true` then compile-time error should be reported; if `false` 2140 * compile-time error should be reported; or `false` if a compile-time warning
2214 * then compile-time warning 2141 * should be reported. Return the parameters that correspond to the arguments,
2215 * @param argumentList the list of arguments being passed to the element 2142 * or `null` if no correspondence could be computed.
2216 * @param executableElement the element that will be invoked with the argument s
2217 * @return the parameters that correspond to the arguments
2218 */ 2143 */
2219 List<ParameterElement> _resolveArgumentsToFunction(bool reportError, 2144 List<ParameterElement> _resolveArgumentsToFunction(bool reportError,
2220 ArgumentList argumentList, ExecutableElement executableElement) { 2145 ArgumentList argumentList, ExecutableElement executableElement) {
2221 if (executableElement == null) { 2146 if (executableElement == null) {
2222 return null; 2147 return null;
2223 } 2148 }
2224 List<ParameterElement> parameters = executableElement.parameters; 2149 List<ParameterElement> parameters = executableElement.parameters;
2225 return _resolveArgumentsToParameters(reportError, argumentList, parameters); 2150 return _resolveArgumentsToParameters(reportError, argumentList, parameters);
2226 } 2151 }
2227 2152
2228 /** 2153 /**
2229 * Given a list of arguments and the parameters related to the element that wi ll be invoked using 2154 * Given an [argumentList] and the [parameters] related to the element that
2230 * those argument, compute the list of parameters that correspond to the list of arguments. Return 2155 * will be invoked using those arguments, compute the list of parameters that
2231 * the parameters that correspond to the arguments. 2156 * correspond to the list of arguments. An error will be reported if any of
2232 * 2157 * the arguments cannot be matched to a parameter. The flag [reportError]
2233 * @param reportError if `true` then compile-time error should be reported; if `false` 2158 * should be `true` if a compile-time error should be reported; or `false` if
2234 * then compile-time warning 2159 * a compile-time warning should be reported. Return the parameters that
2235 * @param argumentList the list of arguments being passed to the element 2160 * correspond to the arguments.
2236 * @param parameters the of the function that will be invoked with the argumen ts
2237 * @return the parameters that correspond to the arguments
2238 */ 2161 */
2239 List<ParameterElement> _resolveArgumentsToParameters(bool reportError, 2162 List<ParameterElement> _resolveArgumentsToParameters(bool reportError,
2240 ArgumentList argumentList, List<ParameterElement> parameters) { 2163 ArgumentList argumentList, List<ParameterElement> parameters) {
2241 List<ParameterElement> requiredParameters = new List<ParameterElement>(); 2164 List<ParameterElement> requiredParameters = new List<ParameterElement>();
2242 List<ParameterElement> positionalParameters = new List<ParameterElement>(); 2165 List<ParameterElement> positionalParameters = new List<ParameterElement>();
2243 HashMap<String, ParameterElement> namedParameters = 2166 HashMap<String, ParameterElement> namedParameters =
2244 new HashMap<String, ParameterElement>(); 2167 new HashMap<String, ParameterElement>();
2245 for (ParameterElement parameter in parameters) { 2168 for (ParameterElement parameter in parameters) {
2246 ParameterKind kind = parameter.parameterKind; 2169 ParameterKind kind = parameter.parameterKind;
2247 if (kind == ParameterKind.REQUIRED) { 2170 if (kind == ParameterKind.REQUIRED) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2347 _recordUndefinedToken(propagatedType.element, 2270 _recordUndefinedToken(propagatedType.element,
2348 HintCode.UNDEFINED_OPERATOR, node.operator, [ 2271 HintCode.UNDEFINED_OPERATOR, node.operator, [
2349 methodName, 2272 methodName,
2350 propagatedType.displayName 2273 propagatedType.displayName
2351 ]); 2274 ]);
2352 } 2275 }
2353 } 2276 }
2354 } 2277 }
2355 2278
2356 /** 2279 /**
2357 * Resolve the names in the given combinators in the scope of the given librar y. 2280 * Resolve the names in the given [combinators] in the scope of the given
2358 * 2281 * [library].
2359 * @param library the library that defines the names
2360 * @param combinators the combinators containing the names to be resolved
2361 */ 2282 */
2362 void _resolveCombinators( 2283 void _resolveCombinators(
2363 LibraryElement library, NodeList<Combinator> combinators) { 2284 LibraryElement library, NodeList<Combinator> combinators) {
2364 if (library == null) { 2285 if (library == null) {
2365 // 2286 //
2366 // The library will be null if the directive containing the combinators 2287 // The library will be null if the directive containing the combinators
2367 // has a URI that is not valid. 2288 // has a URI that is not valid.
2368 // 2289 //
2369 return; 2290 return;
2370 } 2291 }
(...skipping 18 matching lines...) Expand all
2389 if (element is PropertyAccessorElement) { 2310 if (element is PropertyAccessorElement) {
2390 element = (element as PropertyAccessorElement).variable; 2311 element = (element as PropertyAccessorElement).variable;
2391 } 2312 }
2392 name.staticElement = element; 2313 name.staticElement = element;
2393 } 2314 }
2394 } 2315 }
2395 } 2316 }
2396 } 2317 }
2397 2318
2398 /** 2319 /**
2399 * Given that we are accessing a property of the given [classElement] with 2320 * Given that we are accessing a property of the given [classElement] with the
2400 * the given [propertyName], return the element that represents the property. 2321 * given [propertyName], return the element that represents the property.
2401 */ 2322 */
2402 Element _resolveElement( 2323 Element _resolveElement(
2403 ClassElementImpl classElement, SimpleIdentifier propertyName) { 2324 ClassElementImpl classElement, SimpleIdentifier propertyName) {
2404 String name = propertyName.name; 2325 String name = propertyName.name;
2405 Element element = null; 2326 Element element = null;
2406 if (propertyName.inSetterContext()) { 2327 if (propertyName.inSetterContext()) {
2407 element = classElement.getSetter(name); 2328 element = classElement.getSetter(name);
2408 } 2329 }
2409 if (element == null) { 2330 if (element == null) {
2410 element = classElement.getGetter(name); 2331 element = classElement.getGetter(name);
2411 } 2332 }
2412 if (element == null) { 2333 if (element == null) {
2413 element = classElement.getMethod(name); 2334 element = classElement.getMethod(name);
2414 } 2335 }
2415 if (element != null && element.isAccessibleIn(_definingLibrary)) { 2336 if (element != null && element.isAccessibleIn(_definingLibrary)) {
2416 return element; 2337 return element;
2417 } 2338 }
2418 return null; 2339 return null;
2419 } 2340 }
2420 2341
2421 /** 2342 /**
2422 * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the elemen t being invoked. If 2343 * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the
2423 * the returned element is a method, then the method will be invoked. If the r eturned element is a 2344 * element being invoked. If the returned element is a method, then the method
2424 * getter, the getter will be invoked without arguments and the result of that invocation will 2345 * will be invoked. If the returned element is a getter, the getter will be
2425 * then be invoked with the arguments. 2346 * invoked without arguments and the result of that invocation will then be
2426 * 2347 * invoked with the arguments. The [methodName] is the name of the method
2427 * @param methodName the name of the method being invoked ('m') 2348 * being invoked ('m').
2428 * @return the element being invoked
2429 */ 2349 */
2430 Element _resolveInvokedElement(SimpleIdentifier methodName) { 2350 Element _resolveInvokedElement(SimpleIdentifier methodName) {
2431 // 2351 //
2432 // Look first in the lexical scope. 2352 // Look first in the lexical scope.
2433 // 2353 //
2434 Element element = _resolver.nameScope.lookup(methodName, _definingLibrary); 2354 Element element = _resolver.nameScope.lookup(methodName, _definingLibrary);
2435 if (element == null) { 2355 if (element == null) {
2436 // 2356 //
2437 // If it isn't defined in the lexical scope, and the invocation is within 2357 // If it isn't defined in the lexical scope, and the invocation is within
2438 // a class, then look in the inheritance scope. 2358 // a class, then look in the inheritance scope.
2439 // 2359 //
2440 ClassElement enclosingClass = _resolver.enclosingClass; 2360 ClassElement enclosingClass = _resolver.enclosingClass;
2441 if (enclosingClass != null) { 2361 if (enclosingClass != null) {
2442 InterfaceType enclosingType = enclosingClass.type; 2362 InterfaceType enclosingType = enclosingClass.type;
2443 element = _lookUpMethod(null, enclosingType, methodName.name); 2363 element = _lookUpMethod(null, enclosingType, methodName.name);
2444 if (element == null) { 2364 if (element == null) {
2445 // 2365 //
2446 // If there's no method, then it's possible that 'm' is a getter that 2366 // If there's no method, then it's possible that 'm' is a getter that
2447 // returns a function. 2367 // returns a function.
2448 // 2368 //
2449 element = _lookUpGetter(null, enclosingType, methodName.name); 2369 element = _lookUpGetter(null, enclosingType, methodName.name);
2450 } 2370 }
2451 } 2371 }
2452 } 2372 }
2453 // TODO(brianwilkerson) Report this error. 2373 // TODO(brianwilkerson) Report this error.
2454 return element; 2374 return element;
2455 } 2375 }
2456 2376
2457 /** 2377 /**
2458 * Given an invocation of the form 'e.m(a1, ..., an)', resolve 'e.m' to the el ement being invoked. 2378 * Given an invocation of the form 'e.m(a1, ..., an)', resolve 'e.m' to the
2459 * If the returned element is a method, then the method will be invoked. If th e returned element 2379 * element being invoked. If the returned element is a method, then the method
2460 * is a getter, the getter will be invoked without arguments and the result of that invocation 2380 * will be invoked. If the returned element is a getter, the getter will be
2461 * will then be invoked with the arguments. 2381 * invoked without arguments and the result of that invocation will then be
2462 * 2382 * invoked with the arguments. The [target] is the target of the invocation
2463 * @param target the target of the invocation ('e') 2383 * ('e'). The [targetType] is the type of the target. The [methodName] is th
2464 * @param targetType the type of the target 2384 * name of the method being invoked ('m').
2465 * @param methodName the name of the method being invoked ('m')
2466 * @return the element being invoked
2467 */ 2385 */
2468 Element _resolveInvokedElementWithTarget( 2386 Element _resolveInvokedElementWithTarget(
2469 Expression target, DartType targetType, SimpleIdentifier methodName) { 2387 Expression target, DartType targetType, SimpleIdentifier methodName) {
2470 if (targetType is InterfaceType || targetType is UnionType) { 2388 if (targetType is InterfaceType || targetType is UnionType) {
2471 Element element = _lookUpMethod(target, targetType, methodName.name); 2389 Element element = _lookUpMethod(target, targetType, methodName.name);
2472 if (element == null) { 2390 if (element == null) {
2473 // 2391 //
2474 // If there's no method, then it's possible that 'm' is a getter that 2392 // If there's no method, then it's possible that 'm' is a getter that
2475 // returns a function. 2393 // returns a function.
2476 // 2394 //
(...skipping 20 matching lines...) Expand all
2497 // identifier. Consider re-writing the AST. 2415 // identifier. Consider re-writing the AST.
2498 return element; 2416 return element;
2499 } 2417 }
2500 } 2418 }
2501 } 2419 }
2502 // TODO(brianwilkerson) Report this error. 2420 // TODO(brianwilkerson) Report this error.
2503 return null; 2421 return null;
2504 } 2422 }
2505 2423
2506 /** 2424 /**
2507 * Given that we are accessing a property of the given type with the given nam e, return the 2425 * Given that we are accessing a property of the given [targetType] with the
2508 * element that represents the property. 2426 * given [propertyName], return the element that represents the property. The
2509 * 2427 * [target] is the target of the invocation ('e').
2510 * @param target the target of the invocation ('e')
2511 * @param targetType the type in which the search for the property should begi n
2512 * @param propertyName the name of the property being accessed
2513 * @return the element that represents the property
2514 */ 2428 */
2515 ExecutableElement _resolveProperty( 2429 ExecutableElement _resolveProperty(
2516 Expression target, DartType targetType, SimpleIdentifier propertyName) { 2430 Expression target, DartType targetType, SimpleIdentifier propertyName) {
2517 ExecutableElement memberElement = null; 2431 ExecutableElement memberElement = null;
2518 if (propertyName.inSetterContext()) { 2432 if (propertyName.inSetterContext()) {
2519 memberElement = _lookUpSetter(target, targetType, propertyName.name); 2433 memberElement = _lookUpSetter(target, targetType, propertyName.name);
2520 } 2434 }
2521 if (memberElement == null) { 2435 if (memberElement == null) {
2522 memberElement = _lookUpGetter(target, targetType, propertyName.name); 2436 memberElement = _lookUpGetter(target, targetType, propertyName.name);
2523 } 2437 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
2654 ]); 2568 ]);
2655 } else { 2569 } else {
2656 _recordUndefinedNode(declaringElement, 2570 _recordUndefinedNode(declaringElement,
2657 StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName, 2571 StaticWarningCode.UNDEFINED_IDENTIFIER, propertyName,
2658 [propertyName.name]); 2572 [propertyName.name]);
2659 } 2573 }
2660 } 2574 }
2661 } 2575 }
2662 2576
2663 /** 2577 /**
2664 * Resolve the given simple identifier if possible. Return the element to whic h it could be 2578 * Resolve the given simple [identifier] if possible. Return the element to
2665 * resolved, or `null` if it could not be resolved. This does not record the r esults of the 2579 * which it could be resolved, or `null` if it could not be resolved. This
2666 * resolution. 2580 * does not record the results of the resolution.
2667 *
2668 * @param node the identifier to be resolved
2669 * @return the element to which the identifier could be resolved
2670 */ 2581 */
2671 Element _resolveSimpleIdentifier(SimpleIdentifier node) { 2582 Element _resolveSimpleIdentifier(SimpleIdentifier identifier) {
2672 Element element = _resolver.nameScope.lookup(node, _definingLibrary); 2583 Element element = _resolver.nameScope.lookup(identifier, _definingLibrary);
2673 if (element is PropertyAccessorElement && node.inSetterContext()) { 2584 if (element is PropertyAccessorElement && identifier.inSetterContext()) {
2674 PropertyInducingElement variable = 2585 PropertyInducingElement variable =
2675 (element as PropertyAccessorElement).variable; 2586 (element as PropertyAccessorElement).variable;
2676 if (variable != null) { 2587 if (variable != null) {
2677 PropertyAccessorElement setter = variable.setter; 2588 PropertyAccessorElement setter = variable.setter;
2678 if (setter == null) { 2589 if (setter == null) {
2679 // 2590 //
2680 // Check to see whether there might be a locally defined getter and 2591 // Check to see whether there might be a locally defined getter and
2681 // an inherited setter. 2592 // an inherited setter.
2682 // 2593 //
2683 ClassElement enclosingClass = _resolver.enclosingClass; 2594 ClassElement enclosingClass = _resolver.enclosingClass;
2684 if (enclosingClass != null) { 2595 if (enclosingClass != null) {
2685 setter = _lookUpSetter(null, enclosingClass.type, node.name); 2596 setter = _lookUpSetter(null, enclosingClass.type, identifier.name);
2686 } 2597 }
2687 } 2598 }
2688 if (setter != null) { 2599 if (setter != null) {
2689 element = setter; 2600 element = setter;
2690 } 2601 }
2691 } 2602 }
2692 } else if (element == null && 2603 } else if (element == null &&
2693 (node.inSetterContext() || node.parent is CommentReference)) { 2604 (identifier.inSetterContext() ||
2605 identifier.parent is CommentReference)) {
2694 element = _resolver.nameScope.lookup( 2606 element = _resolver.nameScope.lookup(
2695 new SyntheticIdentifier("${node.name}=", node), _definingLibrary); 2607 new SyntheticIdentifier("${identifier.name}=", identifier),
2608 _definingLibrary);
2696 } 2609 }
2697 ClassElement enclosingClass = _resolver.enclosingClass; 2610 ClassElement enclosingClass = _resolver.enclosingClass;
2698 if (element == null && enclosingClass != null) { 2611 if (element == null && enclosingClass != null) {
2699 InterfaceType enclosingType = enclosingClass.type; 2612 InterfaceType enclosingType = enclosingClass.type;
2700 if (element == null && 2613 if (element == null &&
2701 (node.inSetterContext() || node.parent is CommentReference)) { 2614 (identifier.inSetterContext() ||
2702 element = _lookUpSetter(null, enclosingType, node.name); 2615 identifier.parent is CommentReference)) {
2616 element = _lookUpSetter(null, enclosingType, identifier.name);
2703 } 2617 }
2704 if (element == null && node.inGetterContext()) { 2618 if (element == null && identifier.inGetterContext()) {
2705 element = _lookUpGetter(null, enclosingType, node.name); 2619 element = _lookUpGetter(null, enclosingType, identifier.name);
2706 } 2620 }
2707 if (element == null) { 2621 if (element == null) {
2708 element = _lookUpMethod(null, enclosingType, node.name); 2622 element = _lookUpMethod(null, enclosingType, identifier.name);
2709 } 2623 }
2710 } 2624 }
2711 return element; 2625 return element;
2712 } 2626 }
2713 2627
2714 /** 2628 /**
2715 * If the given type is a type parameter, resolve it to the type that should b e used when looking 2629 * If the given [type] is a type parameter, resolve it to the type that should
2716 * up members. Otherwise, return the original type. 2630 * be used when looking up members. Otherwise, return the original type.
2717 *
2718 * @param type the type that is to be resolved if it is a type parameter
2719 * @return the type that should be used in place of the argument if it is a ty pe parameter, or the
2720 * original argument if it isn't a type parameter
2721 */ 2631 */
2722 DartType _resolveTypeParameter(DartType type) { 2632 DartType _resolveTypeParameter(DartType type) {
2723 if (type is TypeParameterType) { 2633 if (type is TypeParameterType) {
2724 DartType bound = type.element.bound; 2634 DartType bound = type.element.bound;
2725 if (bound == null) { 2635 if (bound == null) {
2726 return _resolver.typeProvider.objectType; 2636 return _resolver.typeProvider.objectType;
2727 } 2637 }
2728 return bound; 2638 return bound;
2729 } 2639 }
2730 return type; 2640 return type;
2731 } 2641 }
2732 2642
2733 /** 2643 /**
2734 * Given a node that can have annotations associated with it and the element t o which that node 2644 * Given a [node] that can have annotations associated with it and the
2735 * has been resolved, create the annotations in the element model representing the annotations on 2645 * [element] to which that node has been resolved, create the annotations in
2736 * the node. 2646 * the element model representing the annotations on the node.
2737 *
2738 * @param element the element to which the node has been resolved
2739 * @param node the node that can have annotations associated with it
2740 */ 2647 */
2741 void _setMetadata(Element element, AnnotatedNode node) { 2648 void _setMetadata(Element element, AnnotatedNode node) {
2742 if (element is! ElementImpl) { 2649 if (element is! ElementImpl) {
2743 return; 2650 return;
2744 } 2651 }
2745 List<ElementAnnotationImpl> annotationList = 2652 List<ElementAnnotationImpl> annotationList =
2746 new List<ElementAnnotationImpl>(); 2653 new List<ElementAnnotationImpl>();
2747 _addAnnotations(annotationList, node.metadata); 2654 _addAnnotations(annotationList, node.metadata);
2748 if (node is VariableDeclaration && node.parent is VariableDeclarationList) { 2655 if (node is VariableDeclaration && node.parent is VariableDeclarationList) {
2749 VariableDeclarationList list = node.parent as VariableDeclarationList; 2656 VariableDeclarationList list = node.parent as VariableDeclarationList;
2750 _addAnnotations(annotationList, list.metadata); 2657 _addAnnotations(annotationList, list.metadata);
2751 if (list.parent is FieldDeclaration) { 2658 if (list.parent is FieldDeclaration) {
2752 FieldDeclaration fieldDeclaration = list.parent as FieldDeclaration; 2659 FieldDeclaration fieldDeclaration = list.parent as FieldDeclaration;
2753 _addAnnotations(annotationList, fieldDeclaration.metadata); 2660 _addAnnotations(annotationList, fieldDeclaration.metadata);
2754 } else if (list.parent is TopLevelVariableDeclaration) { 2661 } else if (list.parent is TopLevelVariableDeclaration) {
2755 TopLevelVariableDeclaration variableDeclaration = 2662 TopLevelVariableDeclaration variableDeclaration =
2756 list.parent as TopLevelVariableDeclaration; 2663 list.parent as TopLevelVariableDeclaration;
2757 _addAnnotations(annotationList, variableDeclaration.metadata); 2664 _addAnnotations(annotationList, variableDeclaration.metadata);
2758 } 2665 }
2759 } 2666 }
2760 if (!annotationList.isEmpty) { 2667 if (!annotationList.isEmpty) {
2761 (element as ElementImpl).metadata = annotationList; 2668 (element as ElementImpl).metadata = annotationList;
2762 } 2669 }
2763 } 2670 }
2764 2671
2765 /** 2672 /**
2766 * Given a node that can have annotations associated with it and the element t o which that node 2673 * Given a [node] that can have annotations associated with it and the
2767 * has been resolved, create the annotations in the element model representing the annotations on 2674 * [element] to which that node has been resolved, create the annotations in
2768 * the node. 2675 * the element model representing the annotations on the node.
2769 *
2770 * @param element the element to which the node has been resolved
2771 * @param node the node that can have annotations associated with it
2772 */ 2676 */
2773 void _setMetadataForParameter(Element element, NormalFormalParameter node) { 2677 void _setMetadataForParameter(Element element, NormalFormalParameter node) {
2774 if (element is! ElementImpl) { 2678 if (element is! ElementImpl) {
2775 return; 2679 return;
2776 } 2680 }
2777 List<ElementAnnotationImpl> annotationList = 2681 List<ElementAnnotationImpl> annotationList =
2778 new List<ElementAnnotationImpl>(); 2682 new List<ElementAnnotationImpl>();
2779 _addAnnotations(annotationList, node.metadata); 2683 _addAnnotations(annotationList, node.metadata);
2780 if (!annotationList.isEmpty) { 2684 if (!annotationList.isEmpty) {
2781 (element as ElementImpl).metadata = annotationList; 2685 (element as ElementImpl).metadata = annotationList;
2782 } 2686 }
2783 } 2687 }
2784 2688
2785 /** 2689 /**
2786 * Return `true` if we should report an error as a result of looking up a memb er in the 2690 * Return `true` if we should report an error as a result of looking up a
2787 * given type and not finding any member. 2691 * [member] in the given [type] and not finding any member.
2788 *
2789 * @param type the type in which we attempted to perform the look-up
2790 * @param member the result of the look-up
2791 * @return `true` if we should report an error
2792 */ 2692 */
2793 bool _shouldReportMissingMember(DartType type, Element member) { 2693 bool _shouldReportMissingMember(DartType type, Element member) {
2794 if (member != null || type == null || type.isDynamic || type.isBottom) { 2694 if (member != null || type == null || type.isDynamic || type.isBottom) {
2795 return false; 2695 return false;
2796 } 2696 }
2797 return true; 2697 return true;
2798 } 2698 }
2799 2699
2800 /** 2700 /**
2801 * Checks whether the given expression is a reference to a class. If it is the n the 2701 * Checks whether the given [expression] is a reference to a class. If it is
2802 * [ClassElement] is returned, otherwise `null` is returned. 2702 * then the element representing the class is returned, otherwise `null` is
2803 * 2703 * returned.
2804 * @param expression the expression to evaluate
2805 * @return the element representing the class
2806 */ 2704 */
2807 static ClassElementImpl getTypeReference(Expression expression) { 2705 static ClassElementImpl getTypeReference(Expression expression) {
2808 if (expression is Identifier) { 2706 if (expression is Identifier) {
2809 Element staticElement = expression.staticElement; 2707 Element staticElement = expression.staticElement;
2810 if (staticElement is ClassElementImpl) { 2708 if (staticElement is ClassElementImpl) {
2811 return staticElement; 2709 return staticElement;
2812 } 2710 }
2813 } 2711 }
2814 return null; 2712 return null;
2815 } 2713 }
2816 2714
2817 /** 2715 /**
2818 * Helper function for `maybeMergeExecutableElements` that does the actual mer ging. 2716 * Helper function for `maybeMergeExecutableElements` that does the actual
2819 * 2717 * merging. The [elementArrayToMerge] is the non-empty list of elements to
2820 * @param elementArrayToMerge non-empty array of elements to merge. 2718 * merge.
2821 * @return
2822 */ 2719 */
2823 static ExecutableElement _computeMergedExecutableElement( 2720 static ExecutableElement _computeMergedExecutableElement(
2824 List<ExecutableElement> elementArrayToMerge) { 2721 List<ExecutableElement> elementArrayToMerge) {
2825 // Flatten methods structurally. Based on 2722 // Flatten methods structurally. Based on
2826 // [InheritanceManager.computeMergedExecutableElement] and 2723 // [InheritanceManager.computeMergedExecutableElement] and
2827 // [InheritanceManager.createSyntheticExecutableElement]. 2724 // [InheritanceManager.createSyntheticExecutableElement].
2828 // 2725 //
2829 // However, the approach we take here is much simpler, but expected to work 2726 // However, the approach we take here is much simpler, but expected to work
2830 // well in the common case. It degrades gracefully in the uncommon case, 2727 // well in the common case. It degrades gracefully in the uncommon case,
2831 // by computing the type [dynamic] for the method, preventing any 2728 // by computing the type [dynamic] for the method, preventing any
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2883 e_out.synthetic = true; 2780 e_out.synthetic = true;
2884 e_out.returnType = r_out; 2781 e_out.returnType = r_out;
2885 e_out.parameters = ps_out; 2782 e_out.parameters = ps_out;
2886 e_out.type = new FunctionTypeImpl.con1(e_out); 2783 e_out.type = new FunctionTypeImpl.con1(e_out);
2887 // Get NPE in [toString()] w/o this. 2784 // Get NPE in [toString()] w/o this.
2888 e_out.enclosingElement = e_0.enclosingElement; 2785 e_out.enclosingElement = e_0.enclosingElement;
2889 return e_out; 2786 return e_out;
2890 } 2787 }
2891 2788
2892 /** 2789 /**
2893 * Return `true` if the given identifier is the return type of a constructor d eclaration. 2790 * Return `true` if the given [identifier] is the return type of a constructor
2894 * 2791 * declaration.
2895 * @return `true` if the given identifier is the return type of a constructor declaration.
2896 */ 2792 */
2897 static bool _isConstructorReturnType(SimpleIdentifier identifier) { 2793 static bool _isConstructorReturnType(SimpleIdentifier identifier) {
2898 AstNode parent = identifier.parent; 2794 AstNode parent = identifier.parent;
2899 if (parent is ConstructorDeclaration) { 2795 if (parent is ConstructorDeclaration) {
2900 return identical(parent.returnType, identifier); 2796 return identical(parent.returnType, identifier);
2901 } 2797 }
2902 return false; 2798 return false;
2903 } 2799 }
2904 2800
2905 /** 2801 /**
2906 * Return `true` if the given identifier is the return type of a factory const ructor. 2802 * Return `true` if the given [identifier] is the return type of a factory
2907 * 2803 * constructor.
2908 * @return `true` if the given identifier is the return type of a factory cons tructor
2909 * declaration.
2910 */ 2804 */
2911 static bool _isFactoryConstructorReturnType(SimpleIdentifier node) { 2805 static bool _isFactoryConstructorReturnType(SimpleIdentifier identifier) {
2912 AstNode parent = node.parent; 2806 AstNode parent = identifier.parent;
2913 if (parent is ConstructorDeclaration) { 2807 if (parent is ConstructorDeclaration) {
2914 ConstructorDeclaration constructor = parent; 2808 ConstructorDeclaration constructor = parent;
2915 return identical(constructor.returnType, node) && 2809 return identical(constructor.returnType, identifier) &&
2916 constructor.factoryKeyword != null; 2810 constructor.factoryKeyword != null;
2917 } 2811 }
2918 return false; 2812 return false;
2919 } 2813 }
2920 2814
2921 /** 2815 /**
2922 * Return `true` if the given 'super' expression is used in a valid context. 2816 * Return `true` if the given 'super' [expression] is used in a valid context.
2923 *
2924 * @param node the 'super' expression to analyze
2925 * @return `true` if the 'super' expression is in a valid context
2926 */ 2817 */
2927 static bool _isSuperInValidContext(SuperExpression node) { 2818 static bool _isSuperInValidContext(SuperExpression expression) {
2928 for (AstNode n = node; n != null; n = n.parent) { 2819 for (AstNode node = expression; node != null; node = node.parent) {
2929 if (n is CompilationUnit) { 2820 if (node is CompilationUnit) {
2930 return false; 2821 return false;
2931 } 2822 }
2932 if (n is ConstructorDeclaration) { 2823 if (node is ConstructorDeclaration) {
2933 return n.factoryKeyword == null; 2824 return node.factoryKeyword == null;
2934 } 2825 }
2935 if (n is ConstructorFieldInitializer) { 2826 if (node is ConstructorFieldInitializer) {
2936 return false; 2827 return false;
2937 } 2828 }
2938 if (n is MethodDeclaration) { 2829 if (node is MethodDeclaration) {
2939 return !n.isStatic; 2830 return !node.isStatic;
2940 } 2831 }
2941 } 2832 }
2942 return false; 2833 return false;
2943 } 2834 }
2944 2835
2945 /** 2836 /**
2946 * Return a method representing the merge of the given elements. The type of t he merged element is 2837 * Return a method representing the merge of the given [elements]. The type of
2947 * the component-wise union of the types of the given elements. If not all inp ut elements have the 2838 * the merged element is the component-wise union of the types of the given
2948 * same shape then [null] is returned. 2839 * elements. If not all input elements have the same shape then `null` is
2949 * 2840 * returned.
2950 * @param elements the `ExecutableElement`s to merge
2951 * @return an `ExecutableElement` representing the merge of `elements`
2952 */ 2841 */
2953 static ExecutableElement _maybeMergeExecutableElements( 2842 static ExecutableElement _maybeMergeExecutableElements(
2954 Set<ExecutableElement> elements) { 2843 Set<ExecutableElement> elements) {
2955 List<ExecutableElement> elementArrayToMerge = new List.from(elements); 2844 List<ExecutableElement> elementArrayToMerge = new List.from(elements);
2956 if (elementArrayToMerge.length == 0) { 2845 if (elementArrayToMerge.length == 0) {
2957 return null; 2846 return null;
2958 } else if (elementArrayToMerge.length == 1) { 2847 } else if (elementArrayToMerge.length == 1) {
2959 // If all methods are equal, don't bother building a new one. 2848 // If all methods are equal, don't bother building a new one.
2960 return elementArrayToMerge[0]; 2849 return elementArrayToMerge[0];
2961 } else { 2850 } else {
2962 return _computeMergedExecutableElement(elementArrayToMerge); 2851 return _computeMergedExecutableElement(elementArrayToMerge);
2963 } 2852 }
2964 } 2853 }
2965 } 2854 }
2966 2855
2967 /** 2856 /**
2968 * A `SyntheticIdentifier` is an identifier that can be used to look up names in 2857 * An identifier that can be used to look up names in the lexical scope when
2969 * the lexical scope when there is no identifier in the AST structure. There is 2858 * there is no identifier in the AST structure. There is no identifier in the
2970 * no identifier in the AST when the parser could not distinguish between a 2859 * AST when the parser could not distinguish between a method invocation and an
2971 * method invocation and an invocation of a top-level function imported with a 2860 * invocation of a top-level function imported with a prefix.
2972 * prefix.
2973 */ 2861 */
2974 class SyntheticIdentifier extends Identifier { 2862 class SyntheticIdentifier extends Identifier {
2975 /** 2863 /**
2976 * The name of the synthetic identifier. 2864 * The name of the synthetic identifier.
2977 */ 2865 */
2978 final String name; 2866 final String name;
2979 2867
2980 /** 2868 /**
2981 * The identifier to be highlighted in case of an error 2869 * The identifier to be highlighted in case of an error
2982 */ 2870 */
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3019 2907
3020 @override 2908 @override
3021 Element get staticElement => null; 2909 Element get staticElement => null;
3022 2910
3023 @override 2911 @override
3024 accept(AstVisitor visitor) => null; 2912 accept(AstVisitor visitor) => null;
3025 2913
3026 @override 2914 @override
3027 void visitChildren(AstVisitor visitor) {} 2915 void visitChildren(AstVisitor visitor) {}
3028 } 2916 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698