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

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

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 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
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 analyzer.src.generated.element_resolver;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'ast.dart'; 9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'element.dart'; 10 import 'package:analyzer/dart/ast/syntactic_entity.dart';
11 import 'engine.dart'; 11 import 'package:analyzer/dart/ast/token.dart';
12 import 'error.dart'; 12 import 'package:analyzer/dart/ast/visitor.dart';
13 import 'resolver.dart'; 13 import 'package:analyzer/dart/element/element.dart';
14 import 'scanner.dart' as sc; 14 import 'package:analyzer/dart/element/type.dart';
15 import 'utilities_dart.dart'; 15 import 'package:analyzer/error/error.dart';
16 import 'package:analyzer/src/dart/ast/ast.dart'
17 show
18 ChildEntities,
19 IdentifierImpl,
20 PrefixedIdentifierImpl,
21 SimpleIdentifierImpl;
22 import 'package:analyzer/src/dart/ast/token.dart';
23 import 'package:analyzer/src/dart/element/element.dart';
24 import 'package:analyzer/src/dart/element/type.dart';
25 import 'package:analyzer/src/error/codes.dart';
26 import 'package:analyzer/src/generated/engine.dart';
27 import 'package:analyzer/src/generated/resolver.dart';
16 28
17 /** 29 /**
18 * An object used by instances of [ResolverVisitor] to resolve references within 30 * An object used by instances of [ResolverVisitor] to resolve references within
19 * the AST structure to the elements being referenced. The requirements for the 31 * the AST structure to the elements being referenced. The requirements for the
20 * element resolver are: 32 * element resolver are:
21 * 33 *
22 * 1. Every [SimpleIdentifier] should be resolved to the element to which it 34 * 1. Every [SimpleIdentifier] should be resolved to the element to which it
23 * refers. Specifically: 35 * refers. Specifically:
24 * * An identifier within the declaration of that name should resolve to the 36 * * An identifier within the declaration of that name should resolve to the
25 * element being declared. 37 * element being declared.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 bool _enableStrictCallChecks = false; 107 bool _enableStrictCallChecks = false;
96 108
97 /** 109 /**
98 * The type representing the type 'dynamic'. 110 * The type representing the type 'dynamic'.
99 */ 111 */
100 DartType _dynamicType; 112 DartType _dynamicType;
101 113
102 /** 114 /**
103 * The type representing the type 'type'. 115 * The type representing the type 'type'.
104 */ 116 */
105 DartType _typeType; 117 InterfaceType _typeType;
106 118
107 /** 119 /**
108 * A utility class for the resolver to answer the question of "what are my 120 * A utility class for the resolver to answer the question of "what are my
109 * subtypes?". 121 * subtypes?".
110 */ 122 */
111 SubtypeManager _subtypeManager; 123 SubtypeManager _subtypeManager;
112 124
113 /** 125 /**
114 * The object keeping track of which elements have had their types promoted. 126 * The object keeping track of which elements have had their types promoted.
115 */ 127 */
(...skipping 21 matching lines...) Expand all
137 bool get isInConstConstructor { 149 bool get isInConstConstructor {
138 ExecutableElement function = _resolver.enclosingFunction; 150 ExecutableElement function = _resolver.enclosingFunction;
139 if (function is ConstructorElement) { 151 if (function is ConstructorElement) {
140 return function.isConst; 152 return function.isConst;
141 } 153 }
142 return false; 154 return false;
143 } 155 }
144 156
145 @override 157 @override
146 Object visitAssignmentExpression(AssignmentExpression node) { 158 Object visitAssignmentExpression(AssignmentExpression node) {
147 sc.Token operator = node.operator; 159 Token operator = node.operator;
148 sc.TokenType operatorType = operator.type; 160 TokenType operatorType = operator.type;
149 if (operatorType != sc.TokenType.EQ && 161 if (operatorType != TokenType.AMPERSAND_AMPERSAND_EQ &&
150 operatorType != sc.TokenType.QUESTION_QUESTION_EQ) { 162 operatorType != TokenType.BAR_BAR_EQ &&
163 operatorType != TokenType.EQ &&
164 operatorType != TokenType.QUESTION_QUESTION_EQ) {
151 operatorType = _operatorFromCompoundAssignment(operatorType); 165 operatorType = _operatorFromCompoundAssignment(operatorType);
152 Expression leftHandSide = node.leftHandSide; 166 Expression leftHandSide = node.leftHandSide;
153 if (leftHandSide != null) { 167 if (leftHandSide != null) {
154 String methodName = operatorType.lexeme; 168 String methodName = operatorType.lexeme;
155 DartType staticType = _getStaticType(leftHandSide); 169 DartType staticType = _getStaticType(leftHandSide);
156 MethodElement staticMethod = 170 MethodElement staticMethod =
157 _lookUpMethod(leftHandSide, staticType, methodName); 171 _lookUpMethod(leftHandSide, staticType, methodName);
158 node.staticElement = staticMethod; 172 node.staticElement = staticMethod;
159 DartType propagatedType = _getPropagatedType(leftHandSide); 173 DartType propagatedType = _getPropagatedType(leftHandSide);
160 MethodElement propagatedMethod = 174 MethodElement propagatedMethod =
(...skipping 15 matching lines...) Expand all
176 operator, 190 operator,
177 [methodName, propagatedType.displayName]); 191 [methodName, propagatedType.displayName]);
178 } 192 }
179 } 193 }
180 } 194 }
181 return null; 195 return null;
182 } 196 }
183 197
184 @override 198 @override
185 Object visitBinaryExpression(BinaryExpression node) { 199 Object visitBinaryExpression(BinaryExpression node) {
186 sc.Token operator = node.operator; 200 Token operator = node.operator;
187 if (operator.isUserDefinableOperator) { 201 if (operator.isUserDefinableOperator) {
188 _resolveBinaryExpression(node, operator.lexeme); 202 _resolveBinaryExpression(node, operator.lexeme);
189 } else if (operator.type == sc.TokenType.BANG_EQ) { 203 } else if (operator.type == TokenType.BANG_EQ) {
190 _resolveBinaryExpression(node, sc.TokenType.EQ_EQ.lexeme); 204 _resolveBinaryExpression(node, TokenType.EQ_EQ.lexeme);
191 } 205 }
192 return null; 206 return null;
193 } 207 }
194 208
195 @override 209 @override
196 Object visitBreakStatement(BreakStatement node) { 210 Object visitBreakStatement(BreakStatement node) {
197 node.target = _lookupBreakOrContinueTarget(node, node.label, false); 211 node.target = _lookupBreakOrContinueTarget(node, node.label, false);
198 return null; 212 return null;
199 } 213 }
200 214
201 @override 215 @override
202 Object visitClassDeclaration(ClassDeclaration node) { 216 Object visitClassDeclaration(ClassDeclaration node) {
203 setMetadata(node.element, node); 217 resolveMetadata(node);
204 return null; 218 return null;
205 } 219 }
206 220
207 @override 221 @override
208 Object visitClassTypeAlias(ClassTypeAlias node) { 222 Object visitClassTypeAlias(ClassTypeAlias node) {
209 setMetadata(node.element, node); 223 resolveMetadata(node);
210 return null; 224 return null;
211 } 225 }
212 226
213 @override 227 @override
214 Object visitCommentReference(CommentReference node) { 228 Object visitCommentReference(CommentReference node) {
215 Identifier identifier = node.identifier; 229 Identifier identifier = node.identifier;
216 if (identifier is SimpleIdentifier) { 230 if (identifier is SimpleIdentifier) {
217 SimpleIdentifier simpleIdentifier = identifier; 231 Element element = _resolveSimpleIdentifier(identifier);
218 Element element = _resolveSimpleIdentifier(simpleIdentifier);
219 if (element == null) { 232 if (element == null) {
220 // 233 //
221 // This might be a reference to an imported name that is missing the 234 // This might be a reference to an imported name that is missing the
222 // prefix. 235 // prefix.
223 // 236 //
224 element = _findImportWithoutPrefix(simpleIdentifier); 237 element = _findImportWithoutPrefix(identifier);
225 if (element is MultiplyDefinedElement) { 238 if (element is MultiplyDefinedElement) {
226 // TODO(brianwilkerson) Report this error? 239 // TODO(brianwilkerson) Report this error?
227 element = null; 240 element = null;
228 } 241 }
229 } 242 }
230 if (element == null) { 243 if (element == null) {
231 // TODO(brianwilkerson) Report this error? 244 // TODO(brianwilkerson) Report this error?
232 // resolver.reportError( 245 // resolver.reportError(
233 // StaticWarningCode.UNDEFINED_IDENTIFIER, 246 // StaticWarningCode.UNDEFINED_IDENTIFIER,
234 // simpleIdentifier, 247 // simpleIdentifier,
235 // simpleIdentifier.getName()); 248 // simpleIdentifier.getName());
236 } else { 249 } else {
237 if (element.library == null || element.library != _definingLibrary) { 250 if (element.library == null || element.library != _definingLibrary) {
238 // TODO(brianwilkerson) Report this error? 251 // TODO(brianwilkerson) Report this error?
239 } 252 }
240 simpleIdentifier.staticElement = element; 253 identifier.staticElement = element;
241 if (node.newKeyword != null) { 254 if (node.newKeyword != null) {
242 if (element is ClassElement) { 255 if (element is ClassElement) {
243 ConstructorElement constructor = element.unnamedConstructor; 256 ConstructorElement constructor = element.unnamedConstructor;
244 if (constructor == null) { 257 if (constructor == null) {
245 // TODO(brianwilkerson) Report this error. 258 // TODO(brianwilkerson) Report this error.
246 } else { 259 } else {
247 simpleIdentifier.staticElement = constructor; 260 identifier.staticElement = constructor;
248 } 261 }
249 } else { 262 } else {
250 // TODO(brianwilkerson) Report this error. 263 // TODO(brianwilkerson) Report this error.
251 } 264 }
252 } 265 }
253 } 266 }
254 } else if (identifier is PrefixedIdentifier) { 267 } else if (identifier is PrefixedIdentifier) {
255 PrefixedIdentifier prefixedIdentifier = identifier; 268 SimpleIdentifier prefix = identifier.prefix;
256 SimpleIdentifier prefix = prefixedIdentifier.prefix; 269 SimpleIdentifier name = identifier.identifier;
257 SimpleIdentifier name = prefixedIdentifier.identifier;
258 Element element = _resolveSimpleIdentifier(prefix); 270 Element element = _resolveSimpleIdentifier(prefix);
259 if (element == null) { 271 if (element == null) {
260 // resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, prefix, p refix.getName()); 272 // resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, prefix, p refix.getName());
261 } else { 273 } else {
274 prefix.staticElement = element;
262 if (element is PrefixElement) { 275 if (element is PrefixElement) {
263 prefix.staticElement = element;
264 // TODO(brianwilkerson) Report this error? 276 // TODO(brianwilkerson) Report this error?
265 element = _resolver.nameScope.lookup(identifier, _definingLibrary); 277 element = _resolver.nameScope.lookup(identifier, _definingLibrary);
266 name.staticElement = element; 278 name.staticElement = element;
267 return null; 279 return null;
268 } 280 }
269 LibraryElement library = element.library; 281 LibraryElement library = element.library;
270 if (library == null) { 282 if (library == null) {
271 // TODO(brianwilkerson) We need to understand how the library could 283 // TODO(brianwilkerson) We need to understand how the library could
272 // ever be null. 284 // ever be null.
273 AnalysisEngine.instance.logger 285 AnalysisEngine.instance.logger
274 .logError("Found element with null library: ${element.name}"); 286 .logError("Found element with null library: ${element.name}");
275 } else if (library != _definingLibrary) { 287 } else if (library != _definingLibrary) {
276 // TODO(brianwilkerson) Report this error. 288 // TODO(brianwilkerson) Report this error.
277 } 289 }
278 name.staticElement = element;
279 if (node.newKeyword == null) { 290 if (node.newKeyword == null) {
280 if (element is ClassElement) { 291 if (element is ClassElement) {
281 Element memberElement = 292 Element memberElement =
282 _lookupGetterOrMethod(element.type, name.name); 293 _lookupGetterOrMethod(element.type, name.name);
283 if (memberElement == null) { 294 if (memberElement == null) {
284 memberElement = element.getNamedConstructor(name.name); 295 memberElement = element.getNamedConstructor(name.name);
285 if (memberElement == null) { 296 if (memberElement == null) {
286 memberElement = _lookUpSetter(prefix, element.type, name.name); 297 memberElement = _lookUpSetter(prefix, element.type, name.name);
287 } 298 }
288 } 299 }
289 if (memberElement == null) { 300 if (memberElement == null) {
290 // reportGetterOrSetterNotFound(prefixedIdentifier, name, element.g etDisplayName()); 301 // reportGetterOrSetterNotFound(identifier, name, element.getDispla yName());
291 } else { 302 } else {
292 name.staticElement = memberElement; 303 name.staticElement = memberElement;
293 } 304 }
294 } else { 305 } else {
295 // TODO(brianwilkerson) Report this error. 306 // TODO(brianwilkerson) Report this error.
296 } 307 }
297 } else { 308 } else {
298 if (element is ClassElement) { 309 if (element is ClassElement) {
299 ConstructorElement constructor = 310 ConstructorElement constructor =
300 element.getNamedConstructor(name.name); 311 element.getNamedConstructor(name.name);
301 if (constructor == null) { 312 if (constructor == null) {
302 // TODO(brianwilkerson) Report this error. 313 // TODO(brianwilkerson) Report this error.
303 } else { 314 } else {
304 name.staticElement = constructor; 315 name.staticElement = constructor;
305 } 316 }
306 } else { 317 } else {
307 // TODO(brianwilkerson) Report this error. 318 // TODO(brianwilkerson) Report this error.
308 } 319 }
309 } 320 }
310 } 321 }
311 } 322 }
312 return null; 323 return null;
313 } 324 }
314 325
315 @override 326 @override
316 Object visitConstructorDeclaration(ConstructorDeclaration node) { 327 Object visitConstructorDeclaration(ConstructorDeclaration node) {
317 super.visitConstructorDeclaration(node); 328 super.visitConstructorDeclaration(node);
318 ConstructorElement element = node.element; 329 ConstructorElement element = node.element;
319 if (element is ConstructorElementImpl) { 330 if (element is ConstructorElementImpl) {
320 ConstructorElementImpl constructorElement = element;
321 ConstructorName redirectedNode = node.redirectedConstructor; 331 ConstructorName redirectedNode = node.redirectedConstructor;
322 if (redirectedNode != null) { 332 if (redirectedNode != null) {
323 // set redirected factory constructor 333 // set redirected factory constructor
324 ConstructorElement redirectedElement = redirectedNode.staticElement; 334 ConstructorElement redirectedElement = redirectedNode.staticElement;
325 constructorElement.redirectedConstructor = redirectedElement; 335 element.redirectedConstructor = redirectedElement;
326 } else { 336 } else {
327 // set redirected generative constructor 337 // set redirected generative constructor
328 for (ConstructorInitializer initializer in node.initializers) { 338 for (ConstructorInitializer initializer in node.initializers) {
329 if (initializer is RedirectingConstructorInvocation) { 339 if (initializer is RedirectingConstructorInvocation) {
330 ConstructorElement redirectedElement = initializer.staticElement; 340 ConstructorElement redirectedElement = initializer.staticElement;
331 constructorElement.redirectedConstructor = redirectedElement; 341 element.redirectedConstructor = redirectedElement;
332 } 342 }
333 } 343 }
334 } 344 }
335 setMetadata(constructorElement, node); 345 resolveMetadata(node);
336 } 346 }
337 return null; 347 return null;
338 } 348 }
339 349
340 @override 350 @override
341 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { 351 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
342 SimpleIdentifier fieldName = node.fieldName; 352 SimpleIdentifier fieldName = node.fieldName;
343 ClassElement enclosingClass = _resolver.enclosingClass; 353 ClassElement enclosingClass = _resolver.enclosingClass;
344 FieldElement fieldElement = enclosingClass.getField(fieldName.name); 354 FieldElement fieldElement = enclosingClass.getField(fieldName.name);
345 fieldName.staticElement = fieldElement; 355 fieldName.staticElement = fieldElement;
346 return null; 356 return null;
347 } 357 }
348 358
349 @override 359 @override
350 Object visitConstructorName(ConstructorName node) { 360 Object visitConstructorName(ConstructorName node) {
351 DartType type = node.type.type; 361 DartType type = node.type.type;
352 if (type != null && type.isDynamic) { 362 if (type != null && type.isDynamic) {
353 return null; 363 // Nothing to do.
354 } else if (type is! InterfaceType) { 364 } else if (type is InterfaceType) {
365 // look up ConstructorElement
366 ConstructorElement constructor;
367 SimpleIdentifier name = node.name;
368 if (name == null) {
369 constructor = type.lookUpConstructor(null, _definingLibrary);
370 } else {
371 constructor = type.lookUpConstructor(name.name, _definingLibrary);
372 name.staticElement = constructor;
373 }
374 node.staticElement = constructor;
375 } else {
355 // TODO(brianwilkerson) Report these errors. 376 // TODO(brianwilkerson) Report these errors.
356 // ASTNode parent = node.getParent(); 377 // ASTNode parent = node.getParent();
357 // if (parent instanceof InstanceCreationExpression) { 378 // if (parent instanceof InstanceCreationExpression) {
358 // if (((InstanceCreationExpression) parent).isConst()) { 379 // if (((InstanceCreationExpression) parent).isConst()) {
359 // // CompileTimeErrorCode.CONST_WITH_NON_TYPE 380 // // CompileTimeErrorCode.CONST_WITH_NON_TYPE
360 // } else { 381 // } else {
361 // // StaticWarningCode.NEW_WITH_NON_TYPE 382 // // StaticWarningCode.NEW_WITH_NON_TYPE
362 // } 383 // }
363 // } else { 384 // } else {
364 // // This is part of a redirecting factory constructor; not sure which e rror code to use 385 // // This is part of a redirecting factory constructor; not sure which e rror code to use
365 // } 386 // }
366 return null;
367 } 387 }
368 // look up ConstructorElement
369 ConstructorElement constructor;
370 SimpleIdentifier name = node.name;
371 InterfaceType interfaceType = type as InterfaceType;
372 if (name == null) {
373 constructor = interfaceType.lookUpConstructor(null, _definingLibrary);
374 } else {
375 constructor =
376 interfaceType.lookUpConstructor(name.name, _definingLibrary);
377 name.staticElement = constructor;
378 }
379 node.staticElement = constructor;
380 return null; 388 return null;
381 } 389 }
382 390
383 @override 391 @override
384 Object visitContinueStatement(ContinueStatement node) { 392 Object visitContinueStatement(ContinueStatement node) {
385 node.target = _lookupBreakOrContinueTarget(node, node.label, true); 393 node.target = _lookupBreakOrContinueTarget(node, node.label, true);
386 return null; 394 return null;
387 } 395 }
388 396
389 @override 397 @override
390 Object visitDeclaredIdentifier(DeclaredIdentifier node) { 398 Object visitDeclaredIdentifier(DeclaredIdentifier node) {
391 setMetadata(node.element, node); 399 resolveMetadata(node);
392 return null; 400 return null;
393 } 401 }
394 402
395 @override 403 @override
396 Object visitEnumDeclaration(EnumDeclaration node) { 404 Object visitEnumDeclaration(EnumDeclaration node) {
397 setMetadata(node.element, node); 405 resolveMetadata(node);
398 return null; 406 return null;
399 } 407 }
400 408
401 @override 409 @override
402 Object visitExportDirective(ExportDirective node) { 410 Object visitExportDirective(ExportDirective node) {
403 ExportElement exportElement = node.element; 411 ExportElement exportElement = node.element;
404 if (exportElement != null) { 412 if (exportElement != null) {
405 // The element is null when the URI is invalid 413 // The element is null when the URI is invalid
406 // TODO(brianwilkerson) Figure out whether the element can ever be 414 // TODO(brianwilkerson) Figure out whether the element can ever be
407 // something other than an ExportElement 415 // something other than an ExportElement
408 _resolveCombinators(exportElement.exportedLibrary, node.combinators); 416 _resolveCombinators(exportElement.exportedLibrary, node.combinators);
409 setMetadata(exportElement, node); 417 resolveMetadata(node);
410 } 418 }
411 return null; 419 return null;
412 } 420 }
413 421
414 @override 422 @override
415 Object visitFieldFormalParameter(FieldFormalParameter node) { 423 Object visitFieldFormalParameter(FieldFormalParameter node) {
416 _setMetadataForParameter(node.element, node); 424 _resolveMetadataForParameter(node);
417 return super.visitFieldFormalParameter(node); 425 return super.visitFieldFormalParameter(node);
418 } 426 }
419 427
420 @override 428 @override
421 Object visitFunctionDeclaration(FunctionDeclaration node) { 429 Object visitFunctionDeclaration(FunctionDeclaration node) {
422 setMetadata(node.element, node); 430 resolveMetadata(node);
423 return null; 431 return null;
424 } 432 }
425 433
426 @override 434 @override
427 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { 435 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
428 // TODO(brianwilkerson) Can we ever resolve the function being invoked? 436 Expression function = node.function;
429 Expression expression = node.function; 437 DartType staticInvokeType = _instantiateGenericMethod(
430 if (expression is FunctionExpression) { 438 function.staticType, node.typeArguments, node);
431 FunctionExpression functionExpression = expression; 439 DartType propagatedInvokeType = _instantiateGenericMethod(
432 ExecutableElement functionElement = functionExpression.element; 440 function.propagatedType, node.typeArguments, node);
433 ArgumentList argumentList = node.argumentList; 441
434 List<ParameterElement> parameters = 442 node.staticInvokeType = staticInvokeType;
435 _resolveArgumentsToFunction(false, argumentList, functionElement); 443 node.propagatedInvokeType =
436 if (parameters != null) { 444 _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType);
437 argumentList.correspondingStaticParameters = parameters; 445
438 } 446 List<ParameterElement> parameters =
447 _computeCorrespondingParameters(node.argumentList, staticInvokeType);
448 if (parameters != null) {
449 node.argumentList.correspondingStaticParameters = parameters;
450 }
451
452 parameters = _computeCorrespondingParameters(
453 node.argumentList, propagatedInvokeType);
454 if (parameters != null) {
455 node.argumentList.correspondingPropagatedParameters = parameters;
439 } 456 }
440 return null; 457 return null;
441 } 458 }
442 459
443 @override 460 @override
444 Object visitFunctionTypeAlias(FunctionTypeAlias node) { 461 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
445 setMetadata(node.element, node); 462 resolveMetadata(node);
446 return null; 463 return null;
447 } 464 }
448 465
449 @override 466 @override
450 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { 467 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
451 _setMetadataForParameter(node.element, node); 468 _resolveMetadataForParameter(node);
452 return null; 469 return null;
453 } 470 }
454 471
455 @override 472 @override
456 Object visitImportDirective(ImportDirective node) { 473 Object visitImportDirective(ImportDirective node) {
457 SimpleIdentifier prefixNode = node.prefix; 474 SimpleIdentifier prefixNode = node.prefix;
458 if (prefixNode != null) { 475 if (prefixNode != null) {
459 String prefixName = prefixNode.name; 476 String prefixName = prefixNode.name;
460 for (PrefixElement prefixElement in _definingLibrary.prefixes) { 477 List<PrefixElement> prefixes = _definingLibrary.prefixes;
478 int count = prefixes.length;
479 for (int i = 0; i < count; i++) {
480 PrefixElement prefixElement = prefixes[i];
461 if (prefixElement.displayName == prefixName) { 481 if (prefixElement.displayName == prefixName) {
462 prefixNode.staticElement = prefixElement; 482 prefixNode.staticElement = prefixElement;
463 break; 483 break;
464 } 484 }
465 } 485 }
466 } 486 }
467 ImportElement importElement = node.element; 487 ImportElement importElement = node.element;
468 if (importElement != null) { 488 if (importElement != null) {
469 // The element is null when the URI is invalid 489 // The element is null when the URI is invalid
470 LibraryElement library = importElement.importedLibrary; 490 LibraryElement library = importElement.importedLibrary;
471 if (library != null) { 491 if (library != null) {
472 _resolveCombinators(library, node.combinators); 492 _resolveCombinators(library, node.combinators);
473 } 493 }
474 setMetadata(importElement, node); 494 resolveMetadata(node);
475 } 495 }
476 return null; 496 return null;
477 } 497 }
478 498
479 @override 499 @override
480 Object visitIndexExpression(IndexExpression node) { 500 Object visitIndexExpression(IndexExpression node) {
481 Expression target = node.realTarget; 501 Expression target = node.realTarget;
482 DartType staticType = _getStaticType(target); 502 DartType staticType = _getStaticType(target);
483 DartType propagatedType = _getPropagatedType(target); 503 DartType propagatedType = _getPropagatedType(target);
484 String getterMethodName = sc.TokenType.INDEX.lexeme; 504 String getterMethodName = TokenType.INDEX.lexeme;
485 String setterMethodName = sc.TokenType.INDEX_EQ.lexeme; 505 String setterMethodName = TokenType.INDEX_EQ.lexeme;
486 bool isInGetterContext = node.inGetterContext(); 506 bool isInGetterContext = node.inGetterContext();
487 bool isInSetterContext = node.inSetterContext(); 507 bool isInSetterContext = node.inSetterContext();
488 if (isInGetterContext && isInSetterContext) { 508 if (isInGetterContext && isInSetterContext) {
489 // lookup setter 509 // lookup setter
490 MethodElement setterStaticMethod = 510 MethodElement setterStaticMethod =
491 _lookUpMethod(target, staticType, setterMethodName); 511 _lookUpMethod(target, staticType, setterMethodName);
492 MethodElement setterPropagatedMethod = 512 MethodElement setterPropagatedMethod =
493 _lookUpMethod(target, propagatedType, setterMethodName); 513 _lookUpMethod(target, propagatedType, setterMethodName);
494 // set setter element 514 // set setter element
495 node.staticElement = setterStaticMethod; 515 node.staticElement = setterStaticMethod;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 List<ParameterElement> parameters = _resolveArgumentsToFunction( 577 List<ParameterElement> parameters = _resolveArgumentsToFunction(
558 node.isConst, argumentList, invokedConstructor); 578 node.isConst, argumentList, invokedConstructor);
559 if (parameters != null) { 579 if (parameters != null) {
560 argumentList.correspondingStaticParameters = parameters; 580 argumentList.correspondingStaticParameters = parameters;
561 } 581 }
562 return null; 582 return null;
563 } 583 }
564 584
565 @override 585 @override
566 Object visitLibraryDirective(LibraryDirective node) { 586 Object visitLibraryDirective(LibraryDirective node) {
567 setMetadata(node.element, node); 587 resolveMetadata(node);
568 return null; 588 return null;
569 } 589 }
570 590
571 @override 591 @override
572 Object visitMethodDeclaration(MethodDeclaration node) { 592 Object visitMethodDeclaration(MethodDeclaration node) {
573 setMetadata(node.element, node); 593 resolveMetadata(node);
574 return null; 594 return null;
575 } 595 }
576 596
577 @override 597 @override
578 Object visitMethodInvocation(MethodInvocation node) { 598 Object visitMethodInvocation(MethodInvocation node) {
579 SimpleIdentifier methodName = node.methodName; 599 SimpleIdentifier methodName = node.methodName;
580 // 600 //
581 // Synthetic identifiers have been already reported during parsing. 601 // Synthetic identifiers have been already reported during parsing.
582 // 602 //
583 if (methodName.isSynthetic) { 603 if (methodName.isSynthetic) {
584 return null; 604 return null;
585 } 605 }
586 // 606 //
587 // We have a method invocation of one of two forms: 'e.m(a1, ..., an)' or 607 // We have a method invocation of one of two forms: 'e.m(a1, ..., an)' or
588 // 'm(a1, ..., an)'. The first step is to figure out which executable is 608 // 'm(a1, ..., an)'. The first step is to figure out which executable is
589 // being invoked, using both the static and the propagated type information. 609 // being invoked, using both the static and the propagated type information.
590 // 610 //
591 Expression target = node.realTarget; 611 Expression target = node.realTarget;
592 if (target is SuperExpression && !_isSuperInValidContext(target)) { 612 if (target is SuperExpression && !_isSuperInValidContext(target)) {
593 return null; 613 return null;
594 } 614 }
595 Element staticElement; 615 Element staticElement;
596 Element propagatedElement; 616 Element propagatedElement;
597 DartType staticType = null;
598 DartType propagatedType = null;
599 if (target == null) { 617 if (target == null) {
600 staticElement = _resolveInvokedElement(methodName); 618 staticElement = _resolveInvokedElement(methodName);
601 propagatedElement = null; 619 propagatedElement = null;
602 } else if (methodName.name == FunctionElement.LOAD_LIBRARY_NAME && 620 } else if (methodName.name == FunctionElement.LOAD_LIBRARY_NAME &&
603 _isDeferredPrefix(target)) { 621 _isDeferredPrefix(target)) {
604 if (node.operator.type == sc.TokenType.QUESTION_PERIOD) { 622 if (node.operator.type == TokenType.QUESTION_PERIOD) {
605 _resolver.reportErrorForNode( 623 _resolver.errorReporter.reportErrorForNode(
606 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 624 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
607 target, 625 target,
608 [(target as SimpleIdentifier).name]); 626 [(target as SimpleIdentifier).name]);
609 } 627 }
610 LibraryElement importedLibrary = _getImportedLibrary(target); 628 LibraryElement importedLibrary = _getImportedLibrary(target);
611 methodName.staticElement = importedLibrary.loadLibraryFunction; 629 FunctionElement loadLibraryFunction = importedLibrary.loadLibraryFunction;
630 methodName.staticElement = loadLibraryFunction;
631 node.staticInvokeType = loadLibraryFunction.type;
612 return null; 632 return null;
613 } else { 633 } else {
614 staticType = _getStaticType(target);
615 propagatedType = _getPropagatedType(target);
616 // 634 //
617 // If this method invocation is of the form 'C.m' where 'C' is a class, 635 // If this method invocation is of the form 'C.m' where 'C' is a class,
618 // then we don't call resolveInvokedElement(...) which walks up the class 636 // then we don't call resolveInvokedElement(...) which walks up the class
619 // hierarchy, instead we just look for the member in the type only. This 637 // hierarchy, instead we just look for the member in the type only. This
620 // does not apply to conditional method invocation (i.e. 'C?.m(...)'). 638 // does not apply to conditional method invocation (i.e. 'C?.m(...)').
621 // 639 //
622 bool isConditional = node.operator.type == sc.TokenType.QUESTION_PERIOD; 640 bool isConditional = node.operator.type == TokenType.QUESTION_PERIOD;
623 ClassElementImpl typeReference = getTypeReference(target); 641 ClassElement typeReference = getTypeReference(target);
624 if (typeReference != null) { 642 if (typeReference != null) {
625 staticElement = 643 if (node.isCascaded) {
626 propagatedElement = _resolveElement(typeReference, methodName); 644 typeReference = _typeType.element;
645 }
646 staticElement = _resolveElement(typeReference, methodName);
627 } else { 647 } else {
648 DartType staticType = _resolver.strongMode
649 ? _getStaticTypeOrFunctionType(target)
650 : _getStaticType(target);
651 DartType propagatedType = _getPropagatedType(target);
628 staticElement = _resolveInvokedElementWithTarget( 652 staticElement = _resolveInvokedElementWithTarget(
629 target, staticType, methodName, isConditional); 653 target, staticType, methodName, isConditional);
630 propagatedElement = _resolveInvokedElementWithTarget( 654 // If we have propagated type information use it (since it should
631 target, propagatedType, methodName, isConditional); 655 // not be redundant with the staticType). Otherwise, don't produce
656 // a propagatedElement which duplicates the staticElement.
657 if (propagatedType is InterfaceType) {
658 propagatedElement = _resolveInvokedElementWithTarget(
659 target, propagatedType, methodName, isConditional);
660 }
632 } 661 }
633 } 662 }
663
634 staticElement = _convertSetterToGetter(staticElement); 664 staticElement = _convertSetterToGetter(staticElement);
635 propagatedElement = _convertSetterToGetter(propagatedElement); 665 propagatedElement = _convertSetterToGetter(propagatedElement);
666
667 //
668 // Given the elements, determine the type of the function we are invoking
669 //
670 DartType staticInvokeType = _getInvokeType(staticElement);
671 methodName.staticType = staticInvokeType;
672
673 DartType propagatedInvokeType = _getInvokeType(propagatedElement);
674 methodName.propagatedType =
675 _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType);
676
677 //
678 // Instantiate generic function or method if needed.
679 //
680 staticInvokeType = _instantiateGenericMethod(
681 staticInvokeType, node.typeArguments, node.methodName);
682 propagatedInvokeType = _instantiateGenericMethod(
683 propagatedInvokeType, node.typeArguments, node.methodName);
684
636 // 685 //
637 // Record the results. 686 // Record the results.
638 // 687 //
639 methodName.staticElement = staticElement; 688 methodName.staticElement = staticElement;
640 methodName.propagatedElement = propagatedElement; 689 methodName.propagatedElement = propagatedElement;
690
691 node.staticInvokeType = staticInvokeType;
692 //
693 // Store the propagated invoke type if it's more specific than the static
694 // type.
695 //
696 // We still need to record the propagated parameter elements however,
697 // as they are used in propagatedType downwards inference of lambda
698 // parameters. So we don't want to clear the propagatedInvokeType variable.
699 //
700 node.propagatedInvokeType =
701 _propagatedInvokeTypeIfBetter(propagatedInvokeType, staticInvokeType);
702
641 ArgumentList argumentList = node.argumentList; 703 ArgumentList argumentList = node.argumentList;
642 if (staticElement != null) { 704 if (staticInvokeType != null) {
643 List<ParameterElement> parameters = 705 List<ParameterElement> parameters =
644 _computeCorrespondingParameters(argumentList, staticElement); 706 _computeCorrespondingParameters(argumentList, staticInvokeType);
645 if (parameters != null) { 707 argumentList.correspondingStaticParameters = parameters;
646 argumentList.correspondingStaticParameters = parameters;
647 }
648 } 708 }
649 if (propagatedElement != null) { 709 if (propagatedInvokeType != null) {
650 List<ParameterElement> parameters = 710 List<ParameterElement> parameters =
651 _computeCorrespondingParameters(argumentList, propagatedElement); 711 _computeCorrespondingParameters(argumentList, propagatedInvokeType);
652 if (parameters != null) { 712 argumentList.correspondingPropagatedParameters = parameters;
653 argumentList.correspondingPropagatedParameters = parameters;
654 }
655 } 713 }
656 // 714 //
657 // Then check for error conditions. 715 // Then check for error conditions.
658 // 716 //
659 ErrorCode errorCode = _checkForInvocationError(target, true, staticElement); 717 ErrorCode errorCode = _checkForInvocationError(target, true, staticElement);
718 if (errorCode != null &&
719 target is SimpleIdentifier &&
720 target.staticElement is PrefixElement) {
721 Identifier functionName =
722 new PrefixedIdentifierImpl.temp(target, methodName);
723 if (_resolver.nameScope.shouldIgnoreUndefined(functionName)) {
724 return null;
725 }
726 }
660 bool generatedWithTypePropagation = false; 727 bool generatedWithTypePropagation = false;
661 if (_enableHints && errorCode == null && staticElement == null) { 728 if (_enableHints && errorCode == null && staticElement == null) {
662 // The method lookup may have failed because there were multiple 729 // The method lookup may have failed because there were multiple
663 // incompatible choices. In this case we don't want to generate a hint. 730 // incompatible choices. In this case we don't want to generate a hint.
664 errorCode = _checkForInvocationError(target, false, propagatedElement); 731 errorCode = _checkForInvocationError(target, false, propagatedElement);
665 if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { 732 if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
666 ClassElement classElementContext = null; 733 ClassElement classElementContext = null;
667 if (target == null) { 734 if (target == null) {
668 classElementContext = _resolver.enclosingClass; 735 classElementContext = _resolver.enclosingClass;
669 } else { 736 } else {
670 DartType type = _getBestType(target); 737 DartType type = _getBestType(target);
671 if (type != null) { 738 if (type != null) {
672 if (type.element is ClassElement) { 739 Element element = type.element;
673 classElementContext = type.element as ClassElement; 740 if (element is ClassElement) {
741 classElementContext = element;
674 } 742 }
675 } 743 }
676 } 744 }
677 if (classElementContext != null) { 745 if (classElementContext != null) {
678 _subtypeManager.ensureLibraryVisited(_definingLibrary); 746 _subtypeManager.ensureLibraryVisited(_definingLibrary);
679 HashSet<ClassElement> subtypeElements = 747 HashSet<ClassElement> subtypeElements =
680 _subtypeManager.computeAllSubtypes(classElementContext); 748 _subtypeManager.computeAllSubtypes(classElementContext);
681 for (ClassElement subtypeElement in subtypeElements) { 749 for (ClassElement subtypeElement in subtypeElements) {
682 if (subtypeElement.getMethod(methodName.name) != null) { 750 if (subtypeElement.getMethod(methodName.name) != null) {
683 errorCode = null; 751 errorCode = null;
684 } 752 }
685 } 753 }
686 } 754 }
687 } 755 }
688 generatedWithTypePropagation = true; 756 generatedWithTypePropagation = true;
689 } 757 }
690 if (errorCode == null) { 758 if (errorCode == null) {
691 return null; 759 return null;
692 } 760 }
693 if (identical( 761 if (identical(
694 errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) || 762 errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION) ||
695 identical(errorCode, 763 identical(errorCode,
696 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT) || 764 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT) ||
697 identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) { 765 identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) {
698 _resolver.reportErrorForNode(errorCode, methodName, [methodName.name]); 766 if (!_resolver.nameScope.shouldIgnoreUndefined(methodName)) {
767 _resolver.errorReporter
768 .reportErrorForNode(errorCode, methodName, [methodName.name]);
769 }
699 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) { 770 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
700 String targetTypeName; 771 String targetTypeName;
701 if (target == null) { 772 if (target == null) {
702 ClassElement enclosingClass = _resolver.enclosingClass; 773 ClassElement enclosingClass = _resolver.enclosingClass;
703 targetTypeName = enclosingClass.displayName; 774 targetTypeName = enclosingClass.displayName;
704 ErrorCode proxyErrorCode = (generatedWithTypePropagation 775 ErrorCode proxyErrorCode = (generatedWithTypePropagation
705 ? HintCode.UNDEFINED_METHOD 776 ? HintCode.UNDEFINED_METHOD
706 : StaticTypeWarningCode.UNDEFINED_METHOD); 777 : StaticTypeWarningCode.UNDEFINED_METHOD);
707 _recordUndefinedNode(_resolver.enclosingClass, proxyErrorCode, 778 _recordUndefinedNode(_resolver.enclosingClass, proxyErrorCode,
708 methodName, [methodName.name, targetTypeName]); 779 methodName, [methodName.name, targetTypeName]);
(...skipping 13 matching lines...) Expand all
722 } 793 }
723 if (!_enableStrictCallChecks && 794 if (!_enableStrictCallChecks &&
724 targetType != null && 795 targetType != null &&
725 targetType.isDartCoreFunction && 796 targetType.isDartCoreFunction &&
726 methodName.name == FunctionElement.CALL_METHOD_NAME) { 797 methodName.name == FunctionElement.CALL_METHOD_NAME) {
727 // TODO(brianwilkerson) Can we ever resolve the function being 798 // TODO(brianwilkerson) Can we ever resolve the function being
728 // invoked? 799 // invoked?
729 // resolveArgumentsToParameters(node.getArgumentList(), invokedFunction ); 800 // resolveArgumentsToParameters(node.getArgumentList(), invokedFunction );
730 return null; 801 return null;
731 } 802 }
732 targetTypeName = targetType == null ? null : targetType.displayName; 803 if (!node.isCascaded) {
804 ClassElement typeReference = getTypeReference(target);
805 if (typeReference != null) {
806 ConstructorElement constructor =
807 typeReference.getNamedConstructor(methodName.name);
808 if (constructor != null) {
809 _recordUndefinedNode(
810 typeReference,
811 StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR,
812 methodName,
813 [methodName.name, typeReference.name]);
814 return null;
815 }
816 }
817 }
818 targetTypeName = targetType?.displayName;
733 ErrorCode proxyErrorCode = (generatedWithTypePropagation 819 ErrorCode proxyErrorCode = (generatedWithTypePropagation
734 ? HintCode.UNDEFINED_METHOD 820 ? HintCode.UNDEFINED_METHOD
735 : StaticTypeWarningCode.UNDEFINED_METHOD); 821 : StaticTypeWarningCode.UNDEFINED_METHOD);
736 _recordUndefinedNode(targetType.element, proxyErrorCode, methodName, 822 _recordUndefinedNode(targetType.element, proxyErrorCode, methodName,
737 [methodName.name, targetTypeName]); 823 [methodName.name, targetTypeName]);
738 } 824 }
739 } else if (identical( 825 } else if (identical(
740 errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) { 826 errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD)) {
741 // Generate the type name. 827 // Generate the type name.
742 // The error code will never be generated via type propagation 828 // The error code will never be generated via type propagation
743 DartType targetType = _getStaticType(target); 829 DartType getSuperType(DartType type) {
744 if (targetType is InterfaceType && !targetType.isObject) { 830 if (type is InterfaceType && !type.isObject) {
745 targetType = (targetType as InterfaceType).superclass; 831 return type.superclass;
832 }
833 return type;
746 } 834 }
747 String targetTypeName = targetType == null ? null : targetType.name; 835
748 _resolver.reportErrorForNode(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, 836 DartType targetType = getSuperType(_getStaticType(target));
749 methodName, [methodName.name, targetTypeName]); 837 String targetTypeName = targetType?.name;
838 _resolver.errorReporter.reportErrorForNode(
839 StaticTypeWarningCode.UNDEFINED_SUPER_METHOD,
840 methodName,
841 [methodName.name, targetTypeName]);
750 } 842 }
751 return null; 843 return null;
752 } 844 }
753 845
754 @override 846 @override
755 Object visitPartDirective(PartDirective node) { 847 Object visitPartDirective(PartDirective node) {
756 setMetadata(node.element, node); 848 resolveMetadata(node);
757 return null; 849 return null;
758 } 850 }
759 851
760 @override
761 Object visitPartOfDirective(PartOfDirective node) {
762 setMetadata(node.element, node);
763 return null;
764 }
765
766 @override 852 @override
767 Object visitPostfixExpression(PostfixExpression node) { 853 Object visitPostfixExpression(PostfixExpression node) {
768 Expression operand = node.operand; 854 Expression operand = node.operand;
769 String methodName = _getPostfixOperator(node); 855 String methodName = _getPostfixOperator(node);
770 DartType staticType = _getStaticType(operand); 856 DartType staticType = _getStaticType(operand);
771 MethodElement staticMethod = _lookUpMethod(operand, staticType, methodName); 857 MethodElement staticMethod = _lookUpMethod(operand, staticType, methodName);
772 node.staticElement = staticMethod; 858 node.staticElement = staticMethod;
773 DartType propagatedType = _getPropagatedType(operand); 859 DartType propagatedType = _getPropagatedType(operand);
774 MethodElement propagatedMethod = 860 MethodElement propagatedMethod =
775 _lookUpMethod(operand, propagatedType, methodName); 861 _lookUpMethod(operand, propagatedType, methodName);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 identifier.staticElement = importedLibrary.loadLibraryFunction; 897 identifier.staticElement = importedLibrary.loadLibraryFunction;
812 return null; 898 return null;
813 } 899 }
814 // 900 //
815 // Check to see whether the prefix is really a prefix. 901 // Check to see whether the prefix is really a prefix.
816 // 902 //
817 Element prefixElement = prefix.staticElement; 903 Element prefixElement = prefix.staticElement;
818 if (prefixElement is PrefixElement) { 904 if (prefixElement is PrefixElement) {
819 Element element = _resolver.nameScope.lookup(node, _definingLibrary); 905 Element element = _resolver.nameScope.lookup(node, _definingLibrary);
820 if (element == null && identifier.inSetterContext()) { 906 if (element == null && identifier.inSetterContext()) {
821 element = _resolver.nameScope.lookup( 907 Identifier setterName = new PrefixedIdentifierImpl.temp(
822 new SyntheticIdentifier("${node.name}=", node), _definingLibrary); 908 node.prefix,
909 new SimpleIdentifierImpl(new StringToken(TokenType.STRING,
910 "${node.identifier.name}=", node.identifier.offset - 1)));
911 element = _resolver.nameScope.lookup(setterName, _definingLibrary);
912 }
913 if (element == null && _resolver.nameScope.shouldIgnoreUndefined(node)) {
914 return null;
823 } 915 }
824 if (element == null) { 916 if (element == null) {
825 if (identifier.inSetterContext()) { 917 if (identifier.inSetterContext()) {
826 _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_SETTER, 918 _resolver.errorReporter.reportErrorForNode(
827 identifier, [identifier.name, prefixElement.name]); 919 StaticWarningCode.UNDEFINED_SETTER,
828 } else if (node.parent is Annotation) { 920 identifier,
829 Annotation annotation = node.parent as Annotation; 921 [identifier.name, prefixElement.name]);
830 _resolver.reportErrorForNode(
831 CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
832 return null; 922 return null;
923 }
924 AstNode parent = node.parent;
925 if (parent is Annotation) {
926 _resolver.errorReporter.reportErrorForNode(
927 CompileTimeErrorCode.INVALID_ANNOTATION, parent);
833 } else { 928 } else {
834 _resolver.reportErrorForNode(StaticWarningCode.UNDEFINED_GETTER, 929 _resolver.errorReporter.reportErrorForNode(
835 identifier, [identifier.name, prefixElement.name]); 930 StaticWarningCode.UNDEFINED_GETTER,
931 identifier,
932 [identifier.name, prefixElement.name]);
836 } 933 }
837 return null; 934 return null;
838 } 935 }
839 if (element is PropertyAccessorElement && identifier.inSetterContext()) { 936 Element accessor = element;
840 PropertyInducingElement variable = 937 if (accessor is PropertyAccessorElement && identifier.inSetterContext()) {
841 (element as PropertyAccessorElement).variable; 938 PropertyInducingElement variable = accessor.variable;
842 if (variable != null) { 939 if (variable != null) {
843 PropertyAccessorElement setter = variable.setter; 940 PropertyAccessorElement setter = variable.setter;
844 if (setter != null) { 941 if (setter != null) {
845 element = setter; 942 element = setter;
846 } 943 }
847 } 944 }
848 } 945 }
849 // TODO(brianwilkerson) The prefix needs to be resolved to the element for 946 // TODO(brianwilkerson) The prefix needs to be resolved to the element for
850 // the import that defines the prefix, not the prefix's element. 947 // the import that defines the prefix, not the prefix's element.
851 identifier.staticElement = element; 948 identifier.staticElement = element;
852 // Validate annotation element. 949 // Validate annotation element.
853 if (node.parent is Annotation) { 950 AstNode parent = node.parent;
854 Annotation annotation = node.parent as Annotation; 951 if (parent is Annotation) {
855 _resolveAnnotationElement(annotation); 952 _resolveAnnotationElement(parent);
856 return null;
857 } 953 }
858 return null; 954 return null;
859 } 955 }
860 // May be annotation, resolve invocation of "const" constructor. 956 // May be annotation, resolve invocation of "const" constructor.
861 if (node.parent is Annotation) { 957 AstNode parent = node.parent;
862 Annotation annotation = node.parent as Annotation; 958 if (parent is Annotation) {
863 _resolveAnnotationElement(annotation); 959 _resolveAnnotationElement(parent);
864 } 960 }
865 // 961 //
866 // Otherwise, the prefix is really an expression that happens to be a simple 962 // Otherwise, the prefix is really an expression that happens to be a simple
867 // identifier and this is really equivalent to a property access node. 963 // identifier and this is really equivalent to a property access node.
868 // 964 //
869 _resolvePropertyAccess(prefix, identifier); 965 _resolvePropertyAccess(prefix, identifier, false);
870 return null; 966 return null;
871 } 967 }
872 968
873 @override 969 @override
874 Object visitPrefixExpression(PrefixExpression node) { 970 Object visitPrefixExpression(PrefixExpression node) {
875 sc.Token operator = node.operator; 971 Token operator = node.operator;
876 sc.TokenType operatorType = operator.type; 972 TokenType operatorType = operator.type;
877 if (operatorType.isUserDefinableOperator || 973 if (operatorType.isUserDefinableOperator ||
878 operatorType == sc.TokenType.PLUS_PLUS || 974 operatorType == TokenType.PLUS_PLUS ||
879 operatorType == sc.TokenType.MINUS_MINUS) { 975 operatorType == TokenType.MINUS_MINUS) {
880 Expression operand = node.operand; 976 Expression operand = node.operand;
881 String methodName = _getPrefixOperator(node); 977 String methodName = _getPrefixOperator(node);
882 DartType staticType = _getStaticType(operand); 978 DartType staticType = _getStaticType(operand);
883 MethodElement staticMethod = 979 MethodElement staticMethod =
884 _lookUpMethod(operand, staticType, methodName); 980 _lookUpMethod(operand, staticType, methodName);
885 node.staticElement = staticMethod; 981 node.staticElement = staticMethod;
886 DartType propagatedType = _getPropagatedType(operand); 982 DartType propagatedType = _getPropagatedType(operand);
887 MethodElement propagatedMethod = 983 MethodElement propagatedMethod =
888 _lookUpMethod(operand, propagatedType, methodName); 984 _lookUpMethod(operand, propagatedType, methodName);
889 node.propagatedElement = propagatedMethod; 985 node.propagatedElement = propagatedMethod;
(...skipping 25 matching lines...) Expand all
915 return null; 1011 return null;
916 } 1012 }
917 1013
918 @override 1014 @override
919 Object visitPropertyAccess(PropertyAccess node) { 1015 Object visitPropertyAccess(PropertyAccess node) {
920 Expression target = node.realTarget; 1016 Expression target = node.realTarget;
921 if (target is SuperExpression && !_isSuperInValidContext(target)) { 1017 if (target is SuperExpression && !_isSuperInValidContext(target)) {
922 return null; 1018 return null;
923 } 1019 }
924 SimpleIdentifier propertyName = node.propertyName; 1020 SimpleIdentifier propertyName = node.propertyName;
925 _resolvePropertyAccess(target, propertyName); 1021 _resolvePropertyAccess(target, propertyName, node.isCascaded);
926 return null; 1022 return null;
927 } 1023 }
928 1024
929 @override 1025 @override
930 Object visitRedirectingConstructorInvocation( 1026 Object visitRedirectingConstructorInvocation(
931 RedirectingConstructorInvocation node) { 1027 RedirectingConstructorInvocation node) {
932 ClassElement enclosingClass = _resolver.enclosingClass; 1028 ClassElement enclosingClass = _resolver.enclosingClass;
933 if (enclosingClass == null) { 1029 if (enclosingClass == null) {
934 // TODO(brianwilkerson) Report this error. 1030 // TODO(brianwilkerson) Report this error.
935 return null; 1031 return null;
(...skipping 18 matching lines...) Expand all
954 List<ParameterElement> parameters = 1050 List<ParameterElement> parameters =
955 _resolveArgumentsToFunction(false, argumentList, element); 1051 _resolveArgumentsToFunction(false, argumentList, element);
956 if (parameters != null) { 1052 if (parameters != null) {
957 argumentList.correspondingStaticParameters = parameters; 1053 argumentList.correspondingStaticParameters = parameters;
958 } 1054 }
959 return null; 1055 return null;
960 } 1056 }
961 1057
962 @override 1058 @override
963 Object visitSimpleFormalParameter(SimpleFormalParameter node) { 1059 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
964 _setMetadataForParameter(node.element, node); 1060 _resolveMetadataForParameter(node);
965 return null; 1061 return null;
966 } 1062 }
967 1063
968 @override 1064 @override
969 Object visitSimpleIdentifier(SimpleIdentifier node) { 1065 Object visitSimpleIdentifier(SimpleIdentifier node) {
970 // 1066 //
971 // Synthetic identifiers have been already reported during parsing. 1067 // Synthetic identifiers have been already reported during parsing.
972 // 1068 //
973 if (node.isSynthetic) { 1069 if (node.isSynthetic) {
974 return null; 1070 return null;
975 } 1071 }
976 // 1072 //
977 // Ignore nodes that should have been resolved before getting here. 1073 // Ignore nodes that should have been resolved before getting here.
978 // 1074 //
979 if (node.inDeclarationContext()) { 1075 if (node.inDeclarationContext()) {
980 return null; 1076 return null;
981 } 1077 }
1078 if (node.staticElement is LocalVariableElement ||
1079 node.staticElement is ParameterElement) {
1080 return null;
1081 }
982 AstNode parent = node.parent; 1082 AstNode parent = node.parent;
983 if (parent is FieldFormalParameter) { 1083 if (parent is FieldFormalParameter) {
984 return null; 1084 return null;
985 } else if (parent is ConstructorFieldInitializer && 1085 } else if (parent is ConstructorFieldInitializer &&
986 parent.fieldName == node) { 1086 parent.fieldName == node) {
987 return null; 1087 return null;
988 } else if (parent is Annotation && parent.constructorName == node) { 1088 } else if (parent is Annotation && parent.constructorName == node) {
989 return null; 1089 return null;
990 } 1090 }
991 // 1091 //
992 // The name dynamic denotes a Type object even though dynamic is not a 1092 // The name dynamic denotes a Type object even though dynamic is not a
993 // class. 1093 // class.
994 // 1094 //
995 if (node.name == _dynamicType.name) { 1095 if (node.name == _dynamicType.name) {
996 node.staticElement = _dynamicType.element; 1096 node.staticElement = _dynamicType.element;
997 node.staticType = _typeType; 1097 node.staticType = _typeType;
998 return null; 1098 return null;
999 } 1099 }
1000 // 1100 //
1001 // Otherwise, the node should be resolved. 1101 // Otherwise, the node should be resolved.
1002 // 1102 //
1003 Element element = _resolveSimpleIdentifier(node); 1103 Element element = _resolveSimpleIdentifier(node);
1004 ClassElement enclosingClass = _resolver.enclosingClass; 1104 ClassElement enclosingClass = _resolver.enclosingClass;
1005 if (_isFactoryConstructorReturnType(node) && 1105 if (_isFactoryConstructorReturnType(node) &&
1006 !identical(element, enclosingClass)) { 1106 !identical(element, enclosingClass)) {
1007 _resolver.reportErrorForNode( 1107 _resolver.errorReporter.reportErrorForNode(
1008 CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node); 1108 CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLASS, node);
1009 } else if (_isConstructorReturnType(node) && 1109 } else if (_isConstructorReturnType(node) &&
1010 !identical(element, enclosingClass)) { 1110 !identical(element, enclosingClass)) {
1011 _resolver.reportErrorForNode( 1111 _resolver.errorReporter.reportErrorForNode(
1012 CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node); 1112 CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node);
1013 element = null; 1113 element = null;
1014 } else if (element == null || 1114 } else if (element == null ||
1015 (element is PrefixElement && !_isValidAsPrefix(node))) { 1115 (element is PrefixElement && !_isValidAsPrefix(node))) {
1016 // TODO(brianwilkerson) Recover from this error. 1116 // TODO(brianwilkerson) Recover from this error.
1017 if (_isConstructorReturnType(node)) { 1117 if (_isConstructorReturnType(node)) {
1018 _resolver.reportErrorForNode( 1118 _resolver.errorReporter.reportErrorForNode(
1019 CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node); 1119 CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, node);
1020 } else if (node.parent is Annotation) { 1120 } else if (parent is Annotation) {
1021 Annotation annotation = node.parent as Annotation; 1121 _resolver.errorReporter.reportErrorForNode(
1022 _resolver.reportErrorForNode( 1122 CompileTimeErrorCode.INVALID_ANNOTATION, parent);
1023 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); 1123 } else if (element != null) {
1024 } else if (element is PrefixElement) { 1124 _resolver.errorReporter.reportErrorForNode(
1025 _resolver.reportErrorForNode(
1026 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 1125 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
1027 node, 1126 node,
1028 [element.name]); 1127 [element.name]);
1029 } else { 1128 } else if (node.name == "await" && _resolver.enclosingFunction != null) {
1129 _recordUndefinedNode(
1130 _resolver.enclosingClass,
1131 StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT,
1132 node,
1133 [_resolver.enclosingFunction.displayName]);
1134 } else if (!_resolver.nameScope.shouldIgnoreUndefined(node)) {
1030 _recordUndefinedNode(_resolver.enclosingClass, 1135 _recordUndefinedNode(_resolver.enclosingClass,
1031 StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]); 1136 StaticWarningCode.UNDEFINED_IDENTIFIER, node, [node.name]);
1032 } 1137 }
1033 } 1138 }
1034 node.staticElement = element; 1139 node.staticElement = element;
1035 if (node.inSetterContext() && 1140 if (node.inSetterContext() &&
1036 node.inGetterContext() && 1141 node.inGetterContext() &&
1037 enclosingClass != null) { 1142 enclosingClass != null) {
1038 InterfaceType enclosingType = enclosingClass.type; 1143 InterfaceType enclosingType = enclosingClass.type;
1039 AuxiliaryElements auxiliaryElements = new AuxiliaryElements( 1144 AuxiliaryElements auxiliaryElements = new AuxiliaryElements(
1040 _lookUpGetter(null, enclosingType, node.name), null); 1145 _lookUpGetter(null, enclosingType, node.name), null);
1041 node.auxiliaryElements = auxiliaryElements; 1146 node.auxiliaryElements = auxiliaryElements;
1042 } 1147 }
1043 // 1148 //
1044 // Validate annotation element. 1149 // Validate annotation element.
1045 // 1150 //
1046 if (node.parent is Annotation) { 1151 if (parent is Annotation) {
1047 Annotation annotation = node.parent as Annotation; 1152 _resolveAnnotationElement(parent);
1048 _resolveAnnotationElement(annotation);
1049 } 1153 }
1050 return null; 1154 return null;
1051 } 1155 }
1052 1156
1053 @override 1157 @override
1054 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { 1158 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
1055 ClassElementImpl enclosingClass = _resolver.enclosingClass; 1159 ClassElementImpl enclosingClass =
1160 AbstractClassElementImpl.getImpl(_resolver.enclosingClass);
1056 if (enclosingClass == null) { 1161 if (enclosingClass == null) {
1057 // TODO(brianwilkerson) Report this error. 1162 // TODO(brianwilkerson) Report this error.
1058 return null; 1163 return null;
1059 } 1164 }
1060 InterfaceType superType = enclosingClass.supertype; 1165 InterfaceType superType = enclosingClass.supertype;
1061 if (superType == null) { 1166 if (superType == null) {
1062 // TODO(brianwilkerson) Report this error. 1167 // TODO(brianwilkerson) Report this error.
1063 return null; 1168 return null;
1064 } 1169 }
1065 SimpleIdentifier name = node.constructorName; 1170 SimpleIdentifier name = node.constructorName;
1066 String superName = name != null ? name.name : null; 1171 String superName = name?.name;
1067 ConstructorElement element = 1172 ConstructorElement element =
1068 superType.lookUpConstructor(superName, _definingLibrary); 1173 superType.lookUpConstructor(superName, _definingLibrary);
1069 if (element == null || 1174 if (element == null ||
1070 (!enclosingClass.doesMixinLackConstructors && 1175 (!enclosingClass.doesMixinLackConstructors &&
1071 !enclosingClass.isSuperConstructorAccessible(element))) { 1176 !enclosingClass.isSuperConstructorAccessible(element))) {
1072 if (name != null) { 1177 if (name != null) {
1073 _resolver.reportErrorForNode( 1178 _resolver.errorReporter.reportErrorForNode(
1074 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER, 1179 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER,
1075 node, 1180 node,
1076 [superType.displayName, name]); 1181 [superType.displayName, name]);
1077 } else { 1182 } else {
1078 _resolver.reportErrorForNode( 1183 _resolver.errorReporter.reportErrorForNode(
1079 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT, 1184 CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT,
1080 node, 1185 node,
1081 [superType.displayName]); 1186 [superType.displayName]);
1082 } 1187 }
1083 return null; 1188 return null;
1084 } else { 1189 } else {
1085 if (element.isFactory) { 1190 if (element.isFactory) {
1086 _resolver.reportErrorForNode( 1191 _resolver.errorReporter.reportErrorForNode(
1087 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]); 1192 CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, node, [element]);
1088 } 1193 }
1089 } 1194 }
1090 if (name != null) { 1195 if (name != null) {
1091 name.staticElement = element; 1196 name.staticElement = element;
1092 } 1197 }
1093 node.staticElement = element; 1198 node.staticElement = element;
1199 // TODO(brianwilkerson) Defer this check until we know there's an error (by
1200 // in-lining _resolveArgumentsToFunction below).
1201 ClassDeclaration declaration =
1202 node.getAncestor((AstNode node) => node is ClassDeclaration);
1203 Identifier superclassName = declaration.extendsClause?.superclass?.name;
1204 if (superclassName != null &&
1205 _resolver.nameScope.shouldIgnoreUndefined(superclassName)) {
1206 return null;
1207 }
1094 ArgumentList argumentList = node.argumentList; 1208 ArgumentList argumentList = node.argumentList;
1095 List<ParameterElement> parameters = _resolveArgumentsToFunction( 1209 List<ParameterElement> parameters = _resolveArgumentsToFunction(
1096 isInConstConstructor, argumentList, element); 1210 isInConstConstructor, argumentList, element);
1097 if (parameters != null) { 1211 if (parameters != null) {
1098 argumentList.correspondingStaticParameters = parameters; 1212 argumentList.correspondingStaticParameters = parameters;
1099 } 1213 }
1100 return null; 1214 return null;
1101 } 1215 }
1102 1216
1103 @override 1217 @override
1104 Object visitSuperExpression(SuperExpression node) { 1218 Object visitSuperExpression(SuperExpression node) {
1105 if (!_isSuperInValidContext(node)) { 1219 if (!_isSuperInValidContext(node)) {
1106 _resolver.reportErrorForNode( 1220 _resolver.errorReporter.reportErrorForNode(
1107 CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, node); 1221 CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, node);
1108 } 1222 }
1109 return super.visitSuperExpression(node); 1223 return super.visitSuperExpression(node);
1110 } 1224 }
1111 1225
1112 @override 1226 @override
1113 Object visitTypeParameter(TypeParameter node) { 1227 Object visitTypeParameter(TypeParameter node) {
1114 setMetadata(node.element, node); 1228 resolveMetadata(node);
1115 return null; 1229 return null;
1116 } 1230 }
1117 1231
1118 @override 1232 @override
1119 Object visitVariableDeclaration(VariableDeclaration node) { 1233 Object visitVariableDeclaration(VariableDeclaration node) {
1120 setMetadata(node.element, node); 1234 resolveMetadata(node);
1121 return null; 1235 return null;
1122 } 1236 }
1123 1237
1124 /** 1238 /**
1125 * Given that we have found code to invoke the given [element], return the 1239 * Given that we have found code to invoke the given [element], return the
1126 * error code that should be reported, or `null` if no error should be 1240 * error code that should be reported, or `null` if no error should be
1127 * reported. The [target] is the target of the invocation, or `null` if there 1241 * reported. The [target] is the target of the invocation, or `null` if there
1128 * was no target. The flag [useStaticContext] should be `true` if the 1242 * was no target. The flag [useStaticContext] should be `true` if the
1129 * invocation is in a static constant (does not have access to instance state. 1243 * invocation is in a static constant (does not have access to instance state) .
1130 */ 1244 */
1131 ErrorCode _checkForInvocationError( 1245 ErrorCode _checkForInvocationError(
1132 Expression target, bool useStaticContext, Element element) { 1246 Expression target, bool useStaticContext, Element element) {
1133 // Prefix is not declared, instead "prefix.id" are declared. 1247 // Prefix is not declared, instead "prefix.id" are declared.
1134 if (element is PrefixElement) { 1248 if (element is PrefixElement) {
1135 return CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT; 1249 return CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT;
1136 } 1250 } else if (element is PropertyAccessorElement) {
1137 if (element is PropertyAccessorElement) {
1138 // 1251 //
1139 // This is really a function expression invocation. 1252 // This is really a function expression invocation.
1140 // 1253 //
1141 // TODO(brianwilkerson) Consider the possibility of re-writing the AST. 1254 // TODO(brianwilkerson) Consider the possibility of re-writing the AST.
1142 FunctionType getterType = element.type; 1255 FunctionType getterType = element.type;
1143 if (getterType != null) { 1256 if (getterType != null) {
1144 DartType returnType = getterType.returnType; 1257 DartType returnType = getterType.returnType;
1145 if (!_isExecutableType(returnType)) { 1258 if (!_isExecutableType(returnType)) {
1146 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION; 1259 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
1147 } 1260 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 DartType targetType; 1304 DartType targetType;
1192 if (useStaticContext) { 1305 if (useStaticContext) {
1193 targetType = _getStaticType(target); 1306 targetType = _getStaticType(target);
1194 } else { 1307 } else {
1195 // Compute and use the propagated type, if it is null, then it may 1308 // Compute and use the propagated type, if it is null, then it may
1196 // be the case that static type is some type, in which the static 1309 // be the case that static type is some type, in which the static
1197 // type should be used. 1310 // type should be used.
1198 targetType = _getBestType(target); 1311 targetType = _getBestType(target);
1199 } 1312 }
1200 if (targetType == null) { 1313 if (targetType == null) {
1314 if (target is Identifier &&
1315 _resolver.nameScope.shouldIgnoreUndefined(target)) {
1316 return null;
1317 }
1201 return StaticTypeWarningCode.UNDEFINED_FUNCTION; 1318 return StaticTypeWarningCode.UNDEFINED_FUNCTION;
1202 } else if (!targetType.isDynamic && !targetType.isBottom) { 1319 } else if (!targetType.isDynamic && !targetType.isBottom) {
1203 // Proxy-conditional warning, based on state of 1320 // Proxy-conditional warning, based on state of
1204 // targetType.getElement() 1321 // targetType.getElement()
1205 return StaticTypeWarningCode.UNDEFINED_METHOD; 1322 return StaticTypeWarningCode.UNDEFINED_METHOD;
1206 } 1323 }
1207 } 1324 }
1208 } 1325 }
1209 } 1326 }
1210 return null; 1327 return null;
(...skipping 16 matching lines...) Expand all
1227 bool shouldReportMissingMember_static = 1344 bool shouldReportMissingMember_static =
1228 _shouldReportMissingMember(staticType, staticMethod); 1345 _shouldReportMissingMember(staticType, staticMethod);
1229 bool shouldReportMissingMember_propagated = 1346 bool shouldReportMissingMember_propagated =
1230 !shouldReportMissingMember_static && 1347 !shouldReportMissingMember_static &&
1231 _enableHints && 1348 _enableHints &&
1232 _shouldReportMissingMember(propagatedType, propagatedMethod) && 1349 _shouldReportMissingMember(propagatedType, propagatedMethod) &&
1233 !_memberFoundInSubclass( 1350 !_memberFoundInSubclass(
1234 propagatedType.element, methodName, true, false); 1351 propagatedType.element, methodName, true, false);
1235 if (shouldReportMissingMember_static || 1352 if (shouldReportMissingMember_static ||
1236 shouldReportMissingMember_propagated) { 1353 shouldReportMissingMember_propagated) {
1237 sc.Token leftBracket = expression.leftBracket; 1354 Token leftBracket = expression.leftBracket;
1238 sc.Token rightBracket = expression.rightBracket; 1355 Token rightBracket = expression.rightBracket;
1239 ErrorCode errorCode; 1356 ErrorCode errorCode;
1240 if (shouldReportMissingMember_static) { 1357 if (shouldReportMissingMember_static) {
1241 if (target is SuperExpression) { 1358 if (target is SuperExpression) {
1242 errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR; 1359 errorCode = StaticTypeWarningCode.UNDEFINED_SUPER_OPERATOR;
1243 } else { 1360 } else {
1244 errorCode = StaticTypeWarningCode.UNDEFINED_OPERATOR; 1361 errorCode = StaticTypeWarningCode.UNDEFINED_OPERATOR;
1245 } 1362 }
1246 } else { 1363 } else {
1247 errorCode = HintCode.UNDEFINED_OPERATOR; 1364 errorCode = HintCode.UNDEFINED_OPERATOR;
1248 } 1365 }
(...skipping 13 matching lines...) Expand all
1262 return false; 1379 return false;
1263 } 1380 }
1264 1381
1265 /** 1382 /**
1266 * Given an [argumentList] and the executable [element] that will be invoked 1383 * Given an [argumentList] and the executable [element] that will be invoked
1267 * using those arguments, compute the list of parameters that correspond to 1384 * using those arguments, compute the list of parameters that correspond to
1268 * the list of arguments. Return the parameters that correspond to the 1385 * the list of arguments. Return the parameters that correspond to the
1269 * arguments, or `null` if no correspondence could be computed. 1386 * arguments, or `null` if no correspondence could be computed.
1270 */ 1387 */
1271 List<ParameterElement> _computeCorrespondingParameters( 1388 List<ParameterElement> _computeCorrespondingParameters(
1272 ArgumentList argumentList, Element element) { 1389 ArgumentList argumentList, DartType type) {
1273 if (element is PropertyAccessorElement) { 1390 if (type is InterfaceType) {
1274 // 1391 MethodElement callMethod =
1275 // This is an invocation of the call method defined on the value returned 1392 type.lookUpMethod(FunctionElement.CALL_METHOD_NAME, _definingLibrary);
1276 // by the getter. 1393 if (callMethod != null) {
1277 // 1394 return _resolveArgumentsToFunction(false, argumentList, callMethod);
1278 FunctionType getterType = element.type;
1279 if (getterType != null) {
1280 DartType getterReturnType = getterType.returnType;
1281 if (getterReturnType is InterfaceType) {
1282 MethodElement callMethod = getterReturnType.lookUpMethod(
1283 FunctionElement.CALL_METHOD_NAME, _definingLibrary);
1284 if (callMethod != null) {
1285 return _resolveArgumentsToFunction(false, argumentList, callMethod);
1286 }
1287 } else if (getterReturnType is FunctionType) {
1288 List<ParameterElement> parameters = getterReturnType.parameters;
1289 return _resolveArgumentsToParameters(false, argumentList, parameters);
1290 }
1291 } 1395 }
1292 } else if (element is ExecutableElement) { 1396 } else if (type is FunctionType) {
1293 return _resolveArgumentsToFunction(false, argumentList, element); 1397 return _resolveArgumentsToParameters(
1294 } else if (element is VariableElement) { 1398 false, argumentList, type.parameters);
1295 VariableElement variable = element;
1296 DartType type = _promoteManager.getStaticType(variable);
1297 if (type is FunctionType) {
1298 FunctionType functionType = type;
1299 List<ParameterElement> parameters = functionType.parameters;
1300 return _resolveArgumentsToParameters(false, argumentList, parameters);
1301 } else if (type is InterfaceType) {
1302 // "call" invocation
1303 MethodElement callMethod = type.lookUpMethod(
1304 FunctionElement.CALL_METHOD_NAME, _definingLibrary);
1305 if (callMethod != null) {
1306 List<ParameterElement> parameters = callMethod.parameters;
1307 return _resolveArgumentsToParameters(false, argumentList, parameters);
1308 }
1309 }
1310 } 1399 }
1311 return null; 1400 return null;
1312 } 1401 }
1313 1402
1314 /** 1403 /**
1315 * If the given [element] is a setter, return the getter associated with it. 1404 * If the given [element] is a setter, return the getter associated with it.
1316 * Otherwise, return the element unchanged. 1405 * Otherwise, return the element unchanged.
1317 */ 1406 */
1318 Element _convertSetterToGetter(Element element) { 1407 Element _convertSetterToGetter(Element element) {
1319 // TODO(brianwilkerson) Determine whether and why the element could ever be 1408 // TODO(brianwilkerson) Determine whether and why the element could ever be
(...skipping 12 matching lines...) Expand all
1332 !(element is ClassElement && element.isOrInheritsProxy); 1421 !(element is ClassElement && element.isOrInheritsProxy);
1333 1422
1334 /** 1423 /**
1335 * Look for any declarations of the given [identifier] that are imported using 1424 * Look for any declarations of the given [identifier] that are imported using
1336 * a prefix. Return the element that was found, or `null` if the name is not 1425 * a prefix. Return the element that was found, or `null` if the name is not
1337 * imported using a prefix. 1426 * imported using a prefix.
1338 */ 1427 */
1339 Element _findImportWithoutPrefix(SimpleIdentifier identifier) { 1428 Element _findImportWithoutPrefix(SimpleIdentifier identifier) {
1340 Element element = null; 1429 Element element = null;
1341 Scope nameScope = _resolver.nameScope; 1430 Scope nameScope = _resolver.nameScope;
1342 for (ImportElement importElement in _definingLibrary.imports) { 1431 List<ImportElement> imports = _definingLibrary.imports;
1432 int length = imports.length;
1433 for (int i = 0; i < length; i++) {
1434 ImportElement importElement = imports[i];
1343 PrefixElement prefixElement = importElement.prefix; 1435 PrefixElement prefixElement = importElement.prefix;
1344 if (prefixElement != null) { 1436 if (prefixElement != null) {
1345 Identifier prefixedIdentifier = new SyntheticIdentifier( 1437 Identifier prefixedIdentifier = new PrefixedIdentifierImpl.temp(
1346 "${prefixElement.name}.${identifier.name}", identifier); 1438 new SimpleIdentifierImpl(new StringToken(TokenType.STRING,
1439 prefixElement.name, prefixElement.nameOffset)),
1440 identifier);
1347 Element importedElement = 1441 Element importedElement =
1348 nameScope.lookup(prefixedIdentifier, _definingLibrary); 1442 nameScope.lookup(prefixedIdentifier, _definingLibrary);
1349 if (importedElement != null) { 1443 if (importedElement != null) {
1350 if (element == null) { 1444 if (element == null) {
1351 element = importedElement; 1445 element = importedElement;
1352 } else { 1446 } else {
1353 element = MultiplyDefinedElementImpl.fromElements( 1447 element = MultiplyDefinedElementImpl.fromElements(
1354 _definingLibrary.context, element, importedElement); 1448 _definingLibrary.context, element, importedElement);
1355 } 1449 }
1356 } 1450 }
(...skipping 12 matching lines...) Expand all
1369 // 1463 //
1370 // All function types are subtypes of 'Function', which is itself a 1464 // All function types are subtypes of 'Function', which is itself a
1371 // subclass of 'Object'. 1465 // subclass of 'Object'.
1372 // 1466 //
1373 bestType = _resolver.typeProvider.functionType; 1467 bestType = _resolver.typeProvider.functionType;
1374 } 1468 }
1375 return bestType; 1469 return bestType;
1376 } 1470 }
1377 1471
1378 /** 1472 /**
1379 * Assuming that the given [expression] is a prefix for a deferred import, 1473 * Assuming that the given [identifier] is a prefix for a deferred import,
1380 * return the library that is being imported. 1474 * return the library that is being imported.
1381 */ 1475 */
1382 LibraryElement _getImportedLibrary(Expression expression) { 1476 LibraryElement _getImportedLibrary(SimpleIdentifier identifier) {
1383 PrefixElement prefixElement = 1477 PrefixElement prefixElement = identifier.staticElement as PrefixElement;
1384 (expression as SimpleIdentifier).staticElement as PrefixElement;
1385 List<ImportElement> imports = 1478 List<ImportElement> imports =
1386 prefixElement.enclosingElement.getImportsWithPrefix(prefixElement); 1479 prefixElement.enclosingElement.getImportsWithPrefix(prefixElement);
1387 return imports[0].importedLibrary; 1480 return imports[0].importedLibrary;
1388 } 1481 }
1389 1482
1390 /** 1483 /**
1484 * Given an element, computes the type of the invocation.
1485 *
1486 * For executable elements (like methods, functions) this is just their type.
1487 *
1488 * For variables it is their type taking into account any type promotion.
1489 *
1490 * For calls to getters in Dart, we invoke the function that is returned by
1491 * the getter, so the invoke type is the getter's returnType.
1492 */
1493 DartType _getInvokeType(Element element) {
1494 DartType invokeType;
1495 if (element is PropertyAccessorElement) {
1496 invokeType = element.returnType;
1497 } else if (element is ExecutableElement) {
1498 invokeType = element.type;
1499 } else if (element is VariableElement) {
1500 invokeType = _promoteManager.getStaticType(element);
1501 }
1502 return invokeType ?? DynamicTypeImpl.instance;
1503 }
1504
1505 /**
1391 * Return the name of the method invoked by the given postfix [expression]. 1506 * Return the name of the method invoked by the given postfix [expression].
1392 */ 1507 */
1393 String _getPostfixOperator(PostfixExpression expression) => 1508 String _getPostfixOperator(PostfixExpression expression) =>
1394 (expression.operator.type == sc.TokenType.PLUS_PLUS) 1509 (expression.operator.type == TokenType.PLUS_PLUS)
1395 ? sc.TokenType.PLUS.lexeme 1510 ? TokenType.PLUS.lexeme
1396 : sc.TokenType.MINUS.lexeme; 1511 : TokenType.MINUS.lexeme;
1397 1512
1398 /** 1513 /**
1399 * Return the name of the method invoked by the given postfix [expression]. 1514 * Return the name of the method invoked by the given postfix [expression].
1400 */ 1515 */
1401 String _getPrefixOperator(PrefixExpression expression) { 1516 String _getPrefixOperator(PrefixExpression expression) {
1402 sc.Token operator = expression.operator; 1517 Token operator = expression.operator;
1403 sc.TokenType operatorType = operator.type; 1518 TokenType operatorType = operator.type;
1404 if (operatorType == sc.TokenType.PLUS_PLUS) { 1519 if (operatorType == TokenType.PLUS_PLUS) {
1405 return sc.TokenType.PLUS.lexeme; 1520 return TokenType.PLUS.lexeme;
1406 } else if (operatorType == sc.TokenType.MINUS_MINUS) { 1521 } else if (operatorType == TokenType.MINUS_MINUS) {
1407 return sc.TokenType.MINUS.lexeme; 1522 return TokenType.MINUS.lexeme;
1408 } else if (operatorType == sc.TokenType.MINUS) { 1523 } else if (operatorType == TokenType.MINUS) {
1409 return "unary-"; 1524 return "unary-";
1410 } else { 1525 } else {
1411 return operator.lexeme; 1526 return operator.lexeme;
1412 } 1527 }
1413 } 1528 }
1414 1529
1415 /** 1530 /**
1416 * Return the propagated type of the given [expression] that is to be used for 1531 * Return the propagated type of the given [expression] that is to be used for
1417 * type analysis. 1532 * type analysis.
1418 */ 1533 */
1419 DartType _getPropagatedType(Expression expression) { 1534 DartType _getPropagatedType(Expression expression) {
1420 DartType propagatedType = _resolveTypeParameter(expression.propagatedType); 1535 DartType propagatedType = _resolveTypeParameter(expression.propagatedType);
1421 if (propagatedType is FunctionType) { 1536 if (propagatedType is FunctionType) {
1422 // 1537 //
1423 // All function types are subtypes of 'Function', which is itself a 1538 // All function types are subtypes of 'Function', which is itself a
1424 // subclass of 'Object'. 1539 // subclass of 'Object'.
1425 // 1540 //
1426 propagatedType = _resolver.typeProvider.functionType; 1541 propagatedType = _resolver.typeProvider.functionType;
1427 } 1542 }
1428 return propagatedType; 1543 return propagatedType;
1429 } 1544 }
1430 1545
1431 /** 1546 /**
1432 * Return the static type of the given [expression] that is to be used for 1547 * Return the static type of the given [expression] that is to be used for
1433 * type analysis. 1548 * type analysis.
1434 */ 1549 */
1435 DartType _getStaticType(Expression expression) { 1550 DartType _getStaticType(Expression expression) {
1436 if (expression is NullLiteral) { 1551 DartType staticType = _getStaticTypeOrFunctionType(expression);
1437 return _resolver.typeProvider.bottomType;
1438 }
1439 DartType staticType = _resolveTypeParameter(expression.staticType);
1440 if (staticType is FunctionType) { 1552 if (staticType is FunctionType) {
1441 // 1553 //
1442 // All function types are subtypes of 'Function', which is itself a 1554 // All function types are subtypes of 'Function', which is itself a
1443 // subclass of 'Object'. 1555 // subclass of 'Object'.
1444 // 1556 //
1445 staticType = _resolver.typeProvider.functionType; 1557 staticType = _resolver.typeProvider.functionType;
1446 } 1558 }
1447 return staticType; 1559 return staticType;
1448 } 1560 }
1449 1561
1562 DartType _getStaticTypeOrFunctionType(Expression expression) {
1563 if (expression is NullLiteral) {
1564 return _resolver.typeProvider.bottomType;
1565 }
1566 return _resolveTypeParameter(expression.staticType);
1567 }
1568
1569 /**
1570 * Check for a generic method & apply type arguments if any were passed.
1571 */
1572 DartType _instantiateGenericMethod(
1573 DartType invokeType, TypeArgumentList typeArguments, AstNode node) {
1574 // TODO(jmesserly): support generic "call" methods on InterfaceType.
1575 if (invokeType is FunctionType) {
1576 List<TypeParameterElement> parameters = invokeType.typeFormals;
1577
1578 NodeList<TypeName> arguments = typeArguments?.arguments;
1579 if (arguments != null && arguments.length != parameters.length) {
1580 _resolver.errorReporter.reportErrorForNode(
1581 StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
1582 node,
1583 [invokeType, parameters.length, arguments?.length ?? 0]);
1584
1585 // Wrong number of type arguments. Ignore them.
1586 arguments = null;
1587 }
1588 if (parameters.isNotEmpty) {
1589 if (arguments == null) {
1590 return _resolver.typeSystem.instantiateToBounds(invokeType);
1591 } else {
1592 return invokeType.instantiate(arguments.map((n) => n.type).toList());
1593 }
1594 }
1595 }
1596 return invokeType;
1597 }
1598
1450 /** 1599 /**
1451 * Return `true` if the given [expression] is a prefix for a deferred import. 1600 * Return `true` if the given [expression] is a prefix for a deferred import.
1452 */ 1601 */
1453 bool _isDeferredPrefix(Expression expression) { 1602 bool _isDeferredPrefix(Expression expression) {
1454 if (expression is! SimpleIdentifier) { 1603 if (expression is SimpleIdentifier) {
1455 return false; 1604 Element element = expression.staticElement;
1605 if (element is PrefixElement) {
1606 List<ImportElement> imports =
1607 element.enclosingElement.getImportsWithPrefix(element);
1608 if (imports.length != 1) {
1609 return false;
1610 }
1611 return imports[0].isDeferred;
1612 }
1456 } 1613 }
1457 Element element = (expression as SimpleIdentifier).staticElement; 1614 return false;
1458 if (element is! PrefixElement) {
1459 return false;
1460 }
1461 PrefixElement prefixElement = element as PrefixElement;
1462 List<ImportElement> imports =
1463 prefixElement.enclosingElement.getImportsWithPrefix(prefixElement);
1464 if (imports.length != 1) {
1465 return false;
1466 }
1467 return imports[0].isDeferred;
1468 } 1615 }
1469 1616
1470 /** 1617 /**
1471 * Return `true` if the given [type] represents an object that could be 1618 * Return `true` if the given [type] represents an object that could be
1472 * invoked using the call operator '()'. 1619 * invoked using the call operator '()'.
1473 */ 1620 */
1474 bool _isExecutableType(DartType type) { 1621 bool _isExecutableType(DartType type) {
1622 type = type?.resolveToBound(_resolver.typeProvider.objectType);
1475 if (type.isDynamic || type is FunctionType) { 1623 if (type.isDynamic || type is FunctionType) {
1476 return true; 1624 return true;
1477 } else if (!_enableStrictCallChecks && 1625 } else if (!_enableStrictCallChecks &&
1478 (type.isDartCoreFunction || type.isObject)) { 1626 (type.isDartCoreFunction || type.isObject)) {
1479 return true; 1627 return true;
1480 } else if (type is InterfaceType) { 1628 } else if (type is InterfaceType) {
1481 ClassElement classElement = type.element; 1629 ClassElement classElement = type.element;
1482 // 16078 from Gilad: If the type is a Functor with the @proxy annotation, 1630 // 16078 from Gilad: If the type is a Functor with the @proxy annotation,
1483 // treat it as an executable type. 1631 // treat it as an executable type.
1484 // example code: NonErrorResolverTest. 1632 // example code: NonErrorResolverTest.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1532 */ 1680 */
1533 AstNode _lookupBreakOrContinueTarget( 1681 AstNode _lookupBreakOrContinueTarget(
1534 AstNode parentNode, SimpleIdentifier labelNode, bool isContinue) { 1682 AstNode parentNode, SimpleIdentifier labelNode, bool isContinue) {
1535 if (labelNode == null) { 1683 if (labelNode == null) {
1536 return _resolver.implicitLabelScope.getTarget(isContinue); 1684 return _resolver.implicitLabelScope.getTarget(isContinue);
1537 } else { 1685 } else {
1538 LabelScope labelScope = _resolver.labelScope; 1686 LabelScope labelScope = _resolver.labelScope;
1539 if (labelScope == null) { 1687 if (labelScope == null) {
1540 // There are no labels in scope, so by definition the label is 1688 // There are no labels in scope, so by definition the label is
1541 // undefined. 1689 // undefined.
1542 _resolver.reportErrorForNode( 1690 _resolver.errorReporter.reportErrorForNode(
1543 CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]); 1691 CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
1544 return null; 1692 return null;
1545 } 1693 }
1546 LabelScope definingScope = labelScope.lookup(labelNode.name); 1694 LabelScope definingScope = labelScope.lookup(labelNode.name);
1547 if (definingScope == null) { 1695 if (definingScope == null) {
1548 // No definition of the given label name could be found in any 1696 // No definition of the given label name could be found in any
1549 // enclosing scope. 1697 // enclosing scope.
1550 _resolver.reportErrorForNode( 1698 _resolver.errorReporter.reportErrorForNode(
1551 CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]); 1699 CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
1552 return null; 1700 return null;
1553 } 1701 }
1554 // The target has been found. 1702 // The target has been found.
1555 labelNode.staticElement = definingScope.element; 1703 labelNode.staticElement = definingScope.element;
1556 ExecutableElement labelContainer = definingScope.element 1704 ExecutableElement labelContainer = definingScope.element
1557 .getAncestor((element) => element is ExecutableElement); 1705 .getAncestor((element) => element is ExecutableElement);
1558 if (!identical(labelContainer, _resolver.enclosingFunction)) { 1706 if (!identical(labelContainer, _resolver.enclosingFunction)) {
1559 _resolver.reportErrorForNode(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, 1707 _resolver.errorReporter.reportErrorForNode(
1560 labelNode, [labelNode.name]); 1708 CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE,
1709 labelNode,
1710 [labelNode.name]);
1561 } 1711 }
1562 return definingScope.node; 1712 return definingScope.node;
1563 } 1713 }
1564 } 1714 }
1565 1715
1566 /** 1716 /**
1567 * Look up the getter with the given [getterName] in the given [type]. Return 1717 * Look up the getter with the given [getterName] in the given [type]. Return
1568 * the element representing the getter that was found, or `null` if there is 1718 * the element representing the getter that was found, or `null` if there is
1569 * no getter with the given name. The [target] is the target of the 1719 * no getter with the given name. The [target] is the target of the
1570 * invocation, or `null` if there is no target. 1720 * invocation, or `null` if there is no target.
1571 */ 1721 */
1572 PropertyAccessorElement _lookUpGetter( 1722 PropertyAccessorElement _lookUpGetter(
1573 Expression target, DartType type, String getterName) { 1723 Expression target, DartType type, String getterName) {
1574 type = _resolveTypeParameter(type); 1724 type = _resolveTypeParameter(type);
1575 if (type is InterfaceType) { 1725 if (type is InterfaceType) {
1576 InterfaceType interfaceType = type; 1726 return type.lookUpInheritedGetter(getterName,
1577 PropertyAccessorElement accessor; 1727 library: _definingLibrary, thisType: target is! SuperExpression);
1578 if (target is SuperExpression) {
1579 accessor = interfaceType.lookUpGetterInSuperclass(
1580 getterName, _definingLibrary);
1581 } else {
1582 accessor = interfaceType.lookUpGetter(getterName, _definingLibrary);
1583 }
1584 if (accessor != null) {
1585 return accessor;
1586 }
1587 return _lookUpGetterInInterfaces(
1588 interfaceType, false, getterName, new HashSet<ClassElement>());
1589 } 1728 }
1590 return null; 1729 return null;
1591 } 1730 }
1592 1731
1593 /** 1732 /**
1594 * Look up the getter with the given [getterName] in the interfaces
1595 * implemented by the given [targetType], either directly or indirectly.
1596 * Return the element representing the getter that was found, or `null` if
1597 * there is no getter with the given name. The flag [includeTargetType] should
1598 * be `true` if the search should include the target type. The
1599 * [visitedInterfaces] is a set containing all of the interfaces that have
1600 * been examined, used to prevent infinite recursion and to optimize the
1601 * search.
1602 */
1603 PropertyAccessorElement _lookUpGetterInInterfaces(
1604 InterfaceType targetType,
1605 bool includeTargetType,
1606 String getterName,
1607 HashSet<ClassElement> visitedInterfaces) {
1608 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
1609 // specification (titled "Inheritance and Overriding" under "Interfaces")
1610 // describes a much more complex scheme for finding the inherited member.
1611 // We need to follow that scheme. The code below should cover the 80% case.
1612 ClassElement targetClass = targetType.element;
1613 if (visitedInterfaces.contains(targetClass)) {
1614 return null;
1615 }
1616 visitedInterfaces.add(targetClass);
1617 if (includeTargetType) {
1618 PropertyAccessorElement getter = targetType.getGetter(getterName);
1619 if (getter != null && getter.isAccessibleIn(_definingLibrary)) {
1620 return getter;
1621 }
1622 }
1623 for (InterfaceType interfaceType in targetType.interfaces) {
1624 PropertyAccessorElement getter = _lookUpGetterInInterfaces(
1625 interfaceType, true, getterName, visitedInterfaces);
1626 if (getter != null) {
1627 return getter;
1628 }
1629 }
1630 for (InterfaceType mixinType in targetType.mixins.reversed) {
1631 PropertyAccessorElement getter = _lookUpGetterInInterfaces(
1632 mixinType, true, getterName, visitedInterfaces);
1633 if (getter != null) {
1634 return getter;
1635 }
1636 }
1637 InterfaceType superclass = targetType.superclass;
1638 if (superclass == null) {
1639 return null;
1640 }
1641 return _lookUpGetterInInterfaces(
1642 superclass, true, getterName, visitedInterfaces);
1643 }
1644
1645 /**
1646 * Look up the method or getter with the given [memberName] in the given 1733 * Look up the method or getter with the given [memberName] in the given
1647 * [type]. Return the element representing the method or getter that was 1734 * [type]. Return the element representing the method or getter that was
1648 * found, or `null` if there is no method or getter with the given name. 1735 * found, or `null` if there is no method or getter with the given name.
1649 */ 1736 */
1650 ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) { 1737 ExecutableElement _lookupGetterOrMethod(DartType type, String memberName) {
1651 type = _resolveTypeParameter(type); 1738 type = _resolveTypeParameter(type);
1652 if (type is InterfaceType) { 1739 if (type is InterfaceType) {
1653 InterfaceType interfaceType = type; 1740 return type.lookUpInheritedGetterOrMethod(memberName,
1654 ExecutableElement member = 1741 library: _definingLibrary);
1655 interfaceType.lookUpMethod(memberName, _definingLibrary);
1656 if (member != null) {
1657 return member;
1658 }
1659 member = interfaceType.lookUpGetter(memberName, _definingLibrary);
1660 if (member != null) {
1661 return member;
1662 }
1663 return _lookUpGetterOrMethodInInterfaces(
1664 interfaceType, false, memberName, new HashSet<ClassElement>());
1665 } 1742 }
1666 return null; 1743 return null;
1667 } 1744 }
1668 1745
1669 /** 1746 /**
1670 * Look up the method or getter with the given [memberName] in the interfaces
1671 * implemented by the given [targetType], either directly or indirectly.
1672 * Return the element representing the method or getter that was found, or
1673 * `null` if there is no method or getter with the given name. The flag
1674 * [includeTargetType] should be `true` if the search should include the
1675 * target type. The [visitedInterfaces] is a set containing all of the
1676 * interfaces that have been examined, used to prevent infinite recursion and
1677 * to optimize the search.
1678 */
1679 ExecutableElement _lookUpGetterOrMethodInInterfaces(
1680 InterfaceType targetType,
1681 bool includeTargetType,
1682 String memberName,
1683 HashSet<ClassElement> visitedInterfaces) {
1684 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
1685 // specification (titled "Inheritance and Overriding" under "Interfaces")
1686 // describes a much more complex scheme for finding the inherited member.
1687 // We need to follow that scheme. The code below should cover the 80% case.
1688 ClassElement targetClass = targetType.element;
1689 if (visitedInterfaces.contains(targetClass)) {
1690 return null;
1691 }
1692 visitedInterfaces.add(targetClass);
1693 if (includeTargetType) {
1694 ExecutableElement member = targetType.getMethod(memberName);
1695 if (member != null) {
1696 return member;
1697 }
1698 member = targetType.getGetter(memberName);
1699 if (member != null) {
1700 return member;
1701 }
1702 }
1703 for (InterfaceType interfaceType in targetType.interfaces) {
1704 ExecutableElement member = _lookUpGetterOrMethodInInterfaces(
1705 interfaceType, true, memberName, visitedInterfaces);
1706 if (member != null) {
1707 return member;
1708 }
1709 }
1710 for (InterfaceType mixinType in targetType.mixins.reversed) {
1711 ExecutableElement member = _lookUpGetterOrMethodInInterfaces(
1712 mixinType, true, memberName, visitedInterfaces);
1713 if (member != null) {
1714 return member;
1715 }
1716 }
1717 InterfaceType superclass = targetType.superclass;
1718 if (superclass == null) {
1719 return null;
1720 }
1721 return _lookUpGetterOrMethodInInterfaces(
1722 superclass, true, memberName, visitedInterfaces);
1723 }
1724
1725 /**
1726 * Look up the method with the given [methodName] in the given [type]. Return 1747 * Look up the method with the given [methodName] in the given [type]. Return
1727 * the element representing the method that was found, or `null` if there is 1748 * the element representing the method that was found, or `null` if there is
1728 * no method with the given name. The [target] is the target of the 1749 * no method with the given name. The [target] is the target of the
1729 * invocation, or `null` if there is no target. 1750 * invocation, or `null` if there is no target.
1730 */ 1751 */
1731 MethodElement _lookUpMethod( 1752 MethodElement _lookUpMethod(
1732 Expression target, DartType type, String methodName) { 1753 Expression target, DartType type, String methodName) {
1733 type = _resolveTypeParameter(type); 1754 type = _resolveTypeParameter(type);
1734 if (type is InterfaceType) { 1755 if (type is InterfaceType) {
1735 InterfaceType interfaceType = type; 1756 return type.lookUpInheritedMethod(methodName,
1736 MethodElement method; 1757 library: _definingLibrary, thisType: target is! SuperExpression);
1737 if (target is SuperExpression) {
1738 method = interfaceType.lookUpMethodInSuperclass(
1739 methodName, _definingLibrary);
1740 } else {
1741 method = interfaceType.lookUpMethod(methodName, _definingLibrary);
1742 }
1743 if (method != null) {
1744 return method;
1745 }
1746 return _lookUpMethodInInterfaces(
1747 interfaceType, false, methodName, new HashSet<ClassElement>());
1748 } 1758 }
1749 return null; 1759 return null;
1750 } 1760 }
1751 1761
1752 /** 1762 /**
1753 * Look up the method with the given [methodName] in the interfaces
1754 * implemented by the given [targetType], either directly or indirectly.
1755 * Return the element representing the method that was found, or `null` if
1756 * there is no method with the given name. The flag [includeTargetType] should
1757 * be `true` if the search should include the target type. The
1758 * [visitedInterfaces] is a set containing all of the interfaces that have
1759 * been examined, used to prevent infinite recursion and to optimize the
1760 * search.
1761 */
1762 MethodElement _lookUpMethodInInterfaces(
1763 InterfaceType targetType,
1764 bool includeTargetType,
1765 String methodName,
1766 HashSet<ClassElement> visitedInterfaces) {
1767 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
1768 // specification (titled "Inheritance and Overriding" under "Interfaces")
1769 // describes a much more complex scheme for finding the inherited member.
1770 // We need to follow that scheme. The code below should cover the 80% case.
1771 ClassElement targetClass = targetType.element;
1772 if (visitedInterfaces.contains(targetClass)) {
1773 return null;
1774 }
1775 visitedInterfaces.add(targetClass);
1776 if (includeTargetType) {
1777 MethodElement method = targetType.getMethod(methodName);
1778 if (method != null && method.isAccessibleIn(_definingLibrary)) {
1779 return method;
1780 }
1781 }
1782 for (InterfaceType interfaceType in targetType.interfaces) {
1783 MethodElement method = _lookUpMethodInInterfaces(
1784 interfaceType, true, methodName, visitedInterfaces);
1785 if (method != null) {
1786 return method;
1787 }
1788 }
1789 for (InterfaceType mixinType in targetType.mixins.reversed) {
1790 MethodElement method = _lookUpMethodInInterfaces(
1791 mixinType, true, methodName, visitedInterfaces);
1792 if (method != null) {
1793 return method;
1794 }
1795 }
1796 InterfaceType superclass = targetType.superclass;
1797 if (superclass == null) {
1798 return null;
1799 }
1800 return _lookUpMethodInInterfaces(
1801 superclass, true, methodName, visitedInterfaces);
1802 }
1803
1804 /**
1805 * Look up the setter with the given [setterName] in the given [type]. Return 1763 * Look up the setter with the given [setterName] in the given [type]. Return
1806 * the element representing the setter that was found, or `null` if there is 1764 * the element representing the setter that was found, or `null` if there is
1807 * no setter with the given name. The [target] is the target of the 1765 * no setter with the given name. The [target] is the target of the
1808 * invocation, or `null` if there is no target. 1766 * invocation, or `null` if there is no target.
1809 */ 1767 */
1810 PropertyAccessorElement _lookUpSetter( 1768 PropertyAccessorElement _lookUpSetter(
1811 Expression target, DartType type, String setterName) { 1769 Expression target, DartType type, String setterName) {
1812 type = _resolveTypeParameter(type); 1770 type = _resolveTypeParameter(type);
1813 if (type is InterfaceType) { 1771 if (type is InterfaceType) {
1814 InterfaceType interfaceType = type; 1772 return type.lookUpInheritedSetter(setterName,
1815 PropertyAccessorElement accessor; 1773 library: _definingLibrary, thisType: target is! SuperExpression);
1816 if (target is SuperExpression) {
1817 accessor = interfaceType.lookUpSetterInSuperclass(
1818 setterName, _definingLibrary);
1819 } else {
1820 accessor = interfaceType.lookUpSetter(setterName, _definingLibrary);
1821 }
1822 if (accessor != null) {
1823 return accessor;
1824 }
1825 return _lookUpSetterInInterfaces(
1826 interfaceType, false, setterName, new HashSet<ClassElement>());
1827 } 1774 }
1828 return null; 1775 return null;
1829 } 1776 }
1830 1777
1831 /** 1778 /**
1832 * Look up the setter with the given [setterName] in the interfaces
1833 * implemented by the given [targetType], either directly or indirectly.
1834 * Return the element representing the setter that was found, or `null` if
1835 * there is no setter with the given name. The [targetType] is the type in
1836 * which the setter might be defined. The flag [includeTargetType] should be
1837 * `true` if the search should include the target type. The
1838 * [visitedInterfaces] is a set containing all of the interfaces that have
1839 * been examined, used to prevent infinite recursion and to optimize the
1840 * search.
1841 */
1842 PropertyAccessorElement _lookUpSetterInInterfaces(
1843 InterfaceType targetType,
1844 bool includeTargetType,
1845 String setterName,
1846 HashSet<ClassElement> visitedInterfaces) {
1847 // TODO(brianwilkerson) This isn't correct. Section 8.1.1 of the
1848 // specification (titled "Inheritance and Overriding" under "Interfaces")
1849 // describes a much more complex scheme for finding the inherited member.
1850 // We need to follow that scheme. The code below should cover the 80% case.
1851 ClassElement targetClass = targetType.element;
1852 if (visitedInterfaces.contains(targetClass)) {
1853 return null;
1854 }
1855 visitedInterfaces.add(targetClass);
1856 if (includeTargetType) {
1857 PropertyAccessorElement setter = targetType.getSetter(setterName);
1858 if (setter != null && setter.isAccessibleIn(_definingLibrary)) {
1859 return setter;
1860 }
1861 }
1862 for (InterfaceType interfaceType in targetType.interfaces) {
1863 PropertyAccessorElement setter = _lookUpSetterInInterfaces(
1864 interfaceType, true, setterName, visitedInterfaces);
1865 if (setter != null) {
1866 return setter;
1867 }
1868 }
1869 for (InterfaceType mixinType in targetType.mixins.reversed) {
1870 PropertyAccessorElement setter = _lookUpSetterInInterfaces(
1871 mixinType, true, setterName, visitedInterfaces);
1872 if (setter != null) {
1873 return setter;
1874 }
1875 }
1876 InterfaceType superclass = targetType.superclass;
1877 if (superclass == null) {
1878 return null;
1879 }
1880 return _lookUpSetterInInterfaces(
1881 superclass, true, setterName, visitedInterfaces);
1882 }
1883
1884 /**
1885 * Given some class [element], this method uses [_subtypeManager] to find the 1779 * Given some class [element], this method uses [_subtypeManager] to find the
1886 * set of all subtypes; the subtypes are then searched for a member (method, 1780 * set of all subtypes; the subtypes are then searched for a member (method,
1887 * getter, or setter), that has the given [memberName]. The flag [asMethod] 1781 * getter, or setter), that has the given [memberName]. The flag [asMethod]
1888 * should be `true` if the methods should be searched for in the subtypes. The 1782 * should be `true` if the methods should be searched for in the subtypes. The
1889 * flag [asAccessor] should be `true` if the accessors (getters and setters) 1783 * flag [asAccessor] should be `true` if the accessors (getters and setters)
1890 * should be searched for in the subtypes. 1784 * should be searched for in the subtypes.
1891 */ 1785 */
1892 bool _memberFoundInSubclass( 1786 bool _memberFoundInSubclass(
1893 Element element, String memberName, bool asMethod, bool asAccessor) { 1787 Element element, String memberName, bool asMethod, bool asAccessor) {
1894 if (element is ClassElement) { 1788 if (element is ClassElement) {
(...skipping 10 matching lines...) Expand all
1905 } 1799 }
1906 } 1800 }
1907 } 1801 }
1908 return false; 1802 return false;
1909 } 1803 }
1910 1804
1911 /** 1805 /**
1912 * Return the binary operator that is invoked by the given compound assignment 1806 * Return the binary operator that is invoked by the given compound assignment
1913 * [operator]. 1807 * [operator].
1914 */ 1808 */
1915 sc.TokenType _operatorFromCompoundAssignment(sc.TokenType operator) { 1809 TokenType _operatorFromCompoundAssignment(TokenType operator) {
1916 while (true) { 1810 if (operator == TokenType.AMPERSAND_EQ) {
1917 if (operator == sc.TokenType.AMPERSAND_EQ) { 1811 return TokenType.AMPERSAND;
1918 return sc.TokenType.AMPERSAND; 1812 } else if (operator == TokenType.BAR_EQ) {
1919 } else if (operator == sc.TokenType.BAR_EQ) { 1813 return TokenType.BAR;
1920 return sc.TokenType.BAR; 1814 } else if (operator == TokenType.CARET_EQ) {
1921 } else if (operator == sc.TokenType.CARET_EQ) { 1815 return TokenType.CARET;
1922 return sc.TokenType.CARET; 1816 } else if (operator == TokenType.GT_GT_EQ) {
1923 } else if (operator == sc.TokenType.GT_GT_EQ) { 1817 return TokenType.GT_GT;
1924 return sc.TokenType.GT_GT; 1818 } else if (operator == TokenType.LT_LT_EQ) {
1925 } else if (operator == sc.TokenType.LT_LT_EQ) { 1819 return TokenType.LT_LT;
1926 return sc.TokenType.LT_LT; 1820 } else if (operator == TokenType.MINUS_EQ) {
1927 } else if (operator == sc.TokenType.MINUS_EQ) { 1821 return TokenType.MINUS;
1928 return sc.TokenType.MINUS; 1822 } else if (operator == TokenType.PERCENT_EQ) {
1929 } else if (operator == sc.TokenType.PERCENT_EQ) { 1823 return TokenType.PERCENT;
1930 return sc.TokenType.PERCENT; 1824 } else if (operator == TokenType.PLUS_EQ) {
1931 } else if (operator == sc.TokenType.PLUS_EQ) { 1825 return TokenType.PLUS;
1932 return sc.TokenType.PLUS; 1826 } else if (operator == TokenType.SLASH_EQ) {
1933 } else if (operator == sc.TokenType.SLASH_EQ) { 1827 return TokenType.SLASH;
1934 return sc.TokenType.SLASH; 1828 } else if (operator == TokenType.STAR_EQ) {
1935 } else if (operator == sc.TokenType.STAR_EQ) { 1829 return TokenType.STAR;
1936 return sc.TokenType.STAR; 1830 } else if (operator == TokenType.TILDE_SLASH_EQ) {
1937 } else if (operator == sc.TokenType.TILDE_SLASH_EQ) { 1831 return TokenType.TILDE_SLASH;
1938 return sc.TokenType.TILDE_SLASH; 1832 } else {
1939 } else { 1833 // Internal error: Unmapped assignment operator.
1940 // Internal error: Unmapped assignment operator. 1834 AnalysisEngine.instance.logger.logError(
1941 AnalysisEngine.instance.logger.logError( 1835 "Failed to map ${operator.lexeme} to it's corresponding operator");
1942 "Failed to map ${operator.lexeme} to it's corresponding operator"); 1836 return operator;
1943 return operator;
1944 }
1945 break;
1946 } 1837 }
1947 } 1838 }
1948 1839
1949 /** 1840 /**
1841 * Determines if the [propagatedType] of the invoke is better (more specific)
1842 * than the [staticType]. If so it will be returned, otherwise returns null.
1843 */
1844 // TODO(jmesserly): can we refactor Resolver.recordPropagatedTypeIfBetter to
1845 // get some code sharing? Right now, this method is to support
1846 // `staticInvokeType` and `propagatedInvokeType`, and the one in Resolver is
1847 // for `staticType` and `propagatedType` on Expression.
1848 DartType _propagatedInvokeTypeIfBetter(
1849 DartType propagatedType, DartType staticType) {
1850 if (_resolver.strongMode || propagatedType == null) {
1851 return null;
1852 }
1853 if (staticType == null || propagatedType.isMoreSpecificThan(staticType)) {
1854 return propagatedType;
1855 }
1856 return null;
1857 }
1858
1859 /**
1950 * Record that the given [node] is undefined, causing an error to be reported 1860 * Record that the given [node] is undefined, causing an error to be reported
1951 * if appropriate. The [declaringElement] is the element inside which no 1861 * if appropriate. The [declaringElement] is the element inside which no
1952 * declaration was found. If this element is a proxy, no error will be 1862 * declaration was found. If this element is a proxy, no error will be
1953 * reported. If null, then an error will always be reported. The [errorCode] 1863 * reported. If null, then an error will always be reported. The [errorCode]
1954 * is the error code to report. The [arguments] are the arguments to the error 1864 * is the error code to report. The [arguments] are the arguments to the error
1955 * message. 1865 * message.
1956 */ 1866 */
1957 void _recordUndefinedNode(Element declaringElement, ErrorCode errorCode, 1867 void _recordUndefinedNode(Element declaringElement, ErrorCode errorCode,
1958 AstNode node, List<Object> arguments) { 1868 AstNode node, List<Object> arguments) {
1959 if (_doesntHaveProxy(declaringElement)) { 1869 if (_doesntHaveProxy(declaringElement)) {
1960 _resolver.reportErrorForNode(errorCode, node, arguments); 1870 _resolver.errorReporter.reportErrorForNode(errorCode, node, arguments);
1961 } 1871 }
1962 } 1872 }
1963 1873
1964 /** 1874 /**
1965 * Record that the given [offset]/[length] is undefined, causing an error to 1875 * Record that the given [offset]/[length] is undefined, causing an error to
1966 * be reported if appropriate. The [declaringElement] is the element inside 1876 * be reported if appropriate. The [declaringElement] is the element inside
1967 * which no declaration was found. If this element is a proxy, no error will 1877 * which no declaration was found. If this element is a proxy, no error will
1968 * be reported. If null, then an error will always be reported. The 1878 * be reported. If null, then an error will always be reported. The
1969 * [errorCode] is the error code to report. The [arguments] are arguments to 1879 * [errorCode] is the error code to report. The [arguments] are arguments to
1970 * the error message. 1880 * the error message.
1971 */ 1881 */
1972 void _recordUndefinedOffset(Element declaringElement, ErrorCode errorCode, 1882 void _recordUndefinedOffset(Element declaringElement, ErrorCode errorCode,
1973 int offset, int length, List<Object> arguments) { 1883 int offset, int length, List<Object> arguments) {
1974 if (_doesntHaveProxy(declaringElement)) { 1884 if (_doesntHaveProxy(declaringElement)) {
1975 _resolver.reportErrorForOffset(errorCode, offset, length, arguments); 1885 _resolver.errorReporter
1886 .reportErrorForOffset(errorCode, offset, length, arguments);
1976 } 1887 }
1977 } 1888 }
1978 1889
1979 /** 1890 /**
1980 * Record that the given [token] is undefined, causing an error to be reported 1891 * Record that the given [token] is undefined, causing an error to be reported
1981 * if appropriate. The [declaringElement] is the element inside which no 1892 * if appropriate. The [declaringElement] is the element inside which no
1982 * declaration was found. If this element is a proxy, no error will be 1893 * declaration was found. If this element is a proxy, no error will be
1983 * reported. If null, then an error will always be reported. The [errorCode] 1894 * reported. If null, then an error will always be reported. The [errorCode]
1984 * is the error code to report. The [arguments] are arguments to the error 1895 * is the error code to report. The [arguments] are arguments to the error
1985 * message. 1896 * message.
1986 */ 1897 */
1987 void _recordUndefinedToken(Element declaringElement, ErrorCode errorCode, 1898 void _recordUndefinedToken(Element declaringElement, ErrorCode errorCode,
1988 sc.Token token, List<Object> arguments) { 1899 Token token, List<Object> arguments) {
1989 if (_doesntHaveProxy(declaringElement)) { 1900 if (_doesntHaveProxy(declaringElement)) {
1990 _resolver.reportErrorForToken(errorCode, token, arguments); 1901 _resolver.errorReporter.reportErrorForToken(errorCode, token, arguments);
1991 } 1902 }
1992 } 1903 }
1993 1904
1994 void _resolveAnnotationConstructorInvocationArguments( 1905 void _resolveAnnotationConstructorInvocationArguments(
1995 Annotation annotation, ConstructorElement constructor) { 1906 Annotation annotation, ConstructorElement constructor) {
1996 ArgumentList argumentList = annotation.arguments; 1907 ArgumentList argumentList = annotation.arguments;
1997 // error will be reported in ConstantVerifier 1908 // error will be reported in ConstantVerifier
1998 if (argumentList == null) { 1909 if (argumentList == null) {
1999 return; 1910 return;
2000 } 1911 }
2001 // resolve arguments to parameters 1912 // resolve arguments to parameters
2002 List<ParameterElement> parameters = 1913 List<ParameterElement> parameters =
2003 _resolveArgumentsToFunction(true, argumentList, constructor); 1914 _resolveArgumentsToFunction(true, argumentList, constructor);
2004 if (parameters != null) { 1915 if (parameters != null) {
2005 argumentList.correspondingStaticParameters = parameters; 1916 argumentList.correspondingStaticParameters = parameters;
2006 } 1917 }
2007 } 1918 }
2008 1919
2009 /** 1920 /**
2010 * Continues resolution of the given [annotation]. 1921 * Continues resolution of the given [annotation].
2011 */ 1922 */
2012 void _resolveAnnotationElement(Annotation annotation) { 1923 void _resolveAnnotationElement(Annotation annotation) {
2013 SimpleIdentifier nameNode1; 1924 SimpleIdentifier nameNode1;
2014 SimpleIdentifier nameNode2; 1925 SimpleIdentifier nameNode2;
2015 { 1926 {
2016 Identifier annName = annotation.name; 1927 Identifier annName = annotation.name;
2017 if (annName is PrefixedIdentifier) { 1928 if (annName is PrefixedIdentifier) {
2018 PrefixedIdentifier prefixed = annName; 1929 nameNode1 = annName.prefix;
2019 nameNode1 = prefixed.prefix; 1930 nameNode2 = annName.identifier;
2020 nameNode2 = prefixed.identifier;
2021 } else { 1931 } else {
2022 nameNode1 = annName as SimpleIdentifier; 1932 nameNode1 = annName as SimpleIdentifier;
2023 nameNode2 = null; 1933 nameNode2 = null;
2024 } 1934 }
2025 } 1935 }
2026 SimpleIdentifier nameNode3 = annotation.constructorName; 1936 SimpleIdentifier nameNode3 = annotation.constructorName;
2027 ConstructorElement constructor = null; 1937 ConstructorElement constructor = null;
2028 // 1938 //
2029 // CONST or Class(args) 1939 // CONST or Class(args)
2030 // 1940 //
2031 if (nameNode1 != null && nameNode2 == null && nameNode3 == null) { 1941 if (nameNode1 != null && nameNode2 == null && nameNode3 == null) {
2032 Element element1 = nameNode1.staticElement; 1942 Element element1 = nameNode1.staticElement;
2033 // CONST 1943 // CONST
2034 if (element1 is PropertyAccessorElement) { 1944 if (element1 is PropertyAccessorElement) {
2035 _resolveAnnotationElementGetter(annotation, element1); 1945 _resolveAnnotationElementGetter(annotation, element1);
2036 return; 1946 return;
2037 } 1947 }
2038 // Class(args) 1948 // Class(args)
2039 if (element1 is ClassElement) { 1949 if (element1 is ClassElement) {
2040 ClassElement classElement = element1; 1950 constructor = new InterfaceTypeImpl(element1)
2041 constructor = new InterfaceTypeImpl(classElement)
2042 .lookUpConstructor(null, _definingLibrary); 1951 .lookUpConstructor(null, _definingLibrary);
2043 } 1952 }
2044 } 1953 }
2045 // 1954 //
2046 // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args) 1955 // prefix.CONST or prefix.Class() or Class.CONST or Class.constructor(args)
2047 // 1956 //
2048 if (nameNode1 != null && nameNode2 != null && nameNode3 == null) { 1957 if (nameNode1 != null && nameNode2 != null && nameNode3 == null) {
2049 Element element1 = nameNode1.staticElement; 1958 Element element1 = nameNode1.staticElement;
2050 Element element2 = nameNode2.staticElement; 1959 Element element2 = nameNode2.staticElement;
2051 // Class.CONST - not resolved yet 1960 // Class.CONST - not resolved yet
2052 if (element1 is ClassElement) { 1961 if (element1 is ClassElement) {
2053 ClassElement classElement = element1; 1962 element2 = element1.lookUpGetter(nameNode2.name, _definingLibrary);
2054 element2 = classElement.lookUpGetter(nameNode2.name, _definingLibrary);
2055 } 1963 }
2056 // prefix.CONST or Class.CONST 1964 // prefix.CONST or Class.CONST
2057 if (element2 is PropertyAccessorElement) { 1965 if (element2 is PropertyAccessorElement) {
2058 nameNode2.staticElement = element2; 1966 nameNode2.staticElement = element2;
2059 annotation.element = element2; 1967 annotation.element = element2;
2060 _resolveAnnotationElementGetter(annotation, element2); 1968 _resolveAnnotationElementGetter(annotation, element2);
2061 return; 1969 return;
2062 } 1970 }
2063 // prefix.Class() 1971 // prefix.Class()
2064 if (element2 is ClassElement) { 1972 if (element2 is ClassElement) {
2065 constructor = element2.unnamedConstructor; 1973 constructor = element2.unnamedConstructor;
2066 } 1974 }
2067 // Class.constructor(args) 1975 // Class.constructor(args)
2068 if (element1 is ClassElement) { 1976 if (element1 is ClassElement) {
2069 ClassElement classElement = element1; 1977 constructor = new InterfaceTypeImpl(element1)
2070 constructor = new InterfaceTypeImpl(classElement)
2071 .lookUpConstructor(nameNode2.name, _definingLibrary); 1978 .lookUpConstructor(nameNode2.name, _definingLibrary);
2072 nameNode2.staticElement = constructor; 1979 nameNode2.staticElement = constructor;
2073 } 1980 }
2074 } 1981 }
2075 // 1982 //
2076 // prefix.Class.CONST or prefix.Class.constructor(args) 1983 // prefix.Class.CONST or prefix.Class.constructor(args)
2077 // 1984 //
2078 if (nameNode1 != null && nameNode2 != null && nameNode3 != null) { 1985 if (nameNode1 != null && nameNode2 != null && nameNode3 != null) {
2079 Element element2 = nameNode2.staticElement; 1986 Element element2 = nameNode2.staticElement;
2080 // element2 should be ClassElement 1987 // element2 should be ClassElement
2081 if (element2 is ClassElement) { 1988 if (element2 is ClassElement) {
2082 ClassElement classElement = element2;
2083 String name3 = nameNode3.name; 1989 String name3 = nameNode3.name;
2084 // prefix.Class.CONST 1990 // prefix.Class.CONST
2085 PropertyAccessorElement getter = 1991 PropertyAccessorElement getter =
2086 classElement.lookUpGetter(name3, _definingLibrary); 1992 element2.lookUpGetter(name3, _definingLibrary);
2087 if (getter != null) { 1993 if (getter != null) {
2088 nameNode3.staticElement = getter; 1994 nameNode3.staticElement = getter;
2089 annotation.element = element2; 1995 annotation.element = getter;
2090 _resolveAnnotationElementGetter(annotation, getter); 1996 _resolveAnnotationElementGetter(annotation, getter);
2091 return; 1997 return;
2092 } 1998 }
2093 // prefix.Class.constructor(args) 1999 // prefix.Class.constructor(args)
2094 constructor = new InterfaceTypeImpl(classElement) 2000 constructor = new InterfaceTypeImpl(element2)
2095 .lookUpConstructor(name3, _definingLibrary); 2001 .lookUpConstructor(name3, _definingLibrary);
2096 nameNode3.staticElement = constructor; 2002 nameNode3.staticElement = constructor;
2097 } 2003 }
2098 } 2004 }
2099 // we need constructor 2005 // we need constructor
2100 if (constructor == null) { 2006 if (constructor == null) {
2101 _resolver.reportErrorForNode( 2007 _resolver.errorReporter.reportErrorForNode(
2102 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); 2008 CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
2103 return; 2009 return;
2104 } 2010 }
2105 // record element 2011 // record element
2106 annotation.element = constructor; 2012 annotation.element = constructor;
2107 // resolve arguments 2013 // resolve arguments
2108 _resolveAnnotationConstructorInvocationArguments(annotation, constructor); 2014 _resolveAnnotationConstructorInvocationArguments(annotation, constructor);
2109 } 2015 }
2110 2016
2111 void _resolveAnnotationElementGetter( 2017 void _resolveAnnotationElementGetter(
2112 Annotation annotation, PropertyAccessorElement accessorElement) { 2018 Annotation annotation, PropertyAccessorElement accessorElement) {
2113 // accessor should be synthetic 2019 // accessor should be synthetic
2114 if (!accessorElement.isSynthetic) { 2020 if (!accessorElement.isSynthetic) {
2115 _resolver.reportErrorForNode( 2021 _resolver.errorReporter.reportErrorForNode(
2116 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); 2022 CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
2117 return; 2023 return;
2118 } 2024 }
2119 // variable should be constant 2025 // variable should be constant
2120 VariableElement variableElement = accessorElement.variable; 2026 VariableElement variableElement = accessorElement.variable;
2121 if (!variableElement.isConst) { 2027 if (!variableElement.isConst) {
2122 _resolver.reportErrorForNode( 2028 _resolver.errorReporter.reportErrorForNode(
2123 CompileTimeErrorCode.INVALID_ANNOTATION, annotation); 2029 CompileTimeErrorCode.INVALID_ANNOTATION, annotation);
2124 } 2030 }
2031 // no arguments
2032 if (annotation.arguments != null) {
2033 _resolver.errorReporter.reportErrorForNode(
2034 CompileTimeErrorCode.ANNOTATION_WITH_NON_CLASS,
2035 annotation.name,
2036 [annotation.name]);
2037 }
2125 // OK 2038 // OK
2126 return; 2039 return;
2127 } 2040 }
2128 2041
2129 /** 2042 /**
2130 * Given an [argumentList] and the [executableElement] that will be invoked 2043 * Given an [argumentList] and the [executableElement] that will be invoked
2131 * using those argument, compute the list of parameters that correspond to the 2044 * using those argument, compute the list of parameters that correspond to the
2132 * list of arguments. An error will be reported if any of the arguments cannot 2045 * list of arguments. An error will be reported if any of the arguments cannot
2133 * be matched to a parameter. The flag [reportError] should be `true` if a 2046 * be matched to a parameter. The flag [reportAsError] should be `true` if a
2134 * compile-time error should be reported; or `false` if a compile-time warning 2047 * compile-time error should be reported; or `false` if a compile-time warning
2135 * should be reported. Return the parameters that correspond to the arguments, 2048 * should be reported. Return the parameters that correspond to the arguments,
2136 * or `null` if no correspondence could be computed. 2049 * or `null` if no correspondence could be computed.
2137 */ 2050 */
2138 List<ParameterElement> _resolveArgumentsToFunction(bool reportError, 2051 List<ParameterElement> _resolveArgumentsToFunction(bool reportAsError,
2139 ArgumentList argumentList, ExecutableElement executableElement) { 2052 ArgumentList argumentList, ExecutableElement executableElement) {
2140 if (executableElement == null) { 2053 if (executableElement == null) {
2141 return null; 2054 return null;
2142 } 2055 }
2143 List<ParameterElement> parameters = executableElement.parameters; 2056 List<ParameterElement> parameters = executableElement.parameters;
2144 return _resolveArgumentsToParameters(reportError, argumentList, parameters); 2057 return _resolveArgumentsToParameters(
2058 reportAsError, argumentList, parameters);
2145 } 2059 }
2146 2060
2147 /** 2061 /**
2148 * Given an [argumentList] and the [parameters] related to the element that 2062 * Given an [argumentList] and the [parameters] related to the element that
2149 * will be invoked using those arguments, compute the list of parameters that 2063 * will be invoked using those arguments, compute the list of parameters that
2150 * correspond to the list of arguments. An error will be reported if any of 2064 * correspond to the list of arguments. An error will be reported if any of
2151 * the arguments cannot be matched to a parameter. The flag [reportError] 2065 * the arguments cannot be matched to a parameter. The flag [reportAsError]
2152 * should be `true` if a compile-time error should be reported; or `false` if 2066 * should be `true` if a compile-time error should be reported; or `false` if
2153 * a compile-time warning should be reported. Return the parameters that 2067 * a compile-time warning should be reported. Return the parameters that
2154 * correspond to the arguments. 2068 * correspond to the arguments.
2155 */ 2069 */
2156 List<ParameterElement> _resolveArgumentsToParameters(bool reportError, 2070 List<ParameterElement> _resolveArgumentsToParameters(bool reportAsError,
2157 ArgumentList argumentList, List<ParameterElement> parameters) { 2071 ArgumentList argumentList, List<ParameterElement> parameters) {
2158 List<ParameterElement> requiredParameters = new List<ParameterElement>(); 2072 return ResolverVisitor.resolveArgumentsToParameters(
2159 List<ParameterElement> positionalParameters = new List<ParameterElement>(); 2073 argumentList, parameters, _resolver.errorReporter.reportErrorForNode,
2160 HashMap<String, ParameterElement> namedParameters = 2074 reportAsError: reportAsError);
2161 new HashMap<String, ParameterElement>();
2162 for (ParameterElement parameter in parameters) {
2163 ParameterKind kind = parameter.parameterKind;
2164 if (kind == ParameterKind.REQUIRED) {
2165 requiredParameters.add(parameter);
2166 } else if (kind == ParameterKind.POSITIONAL) {
2167 positionalParameters.add(parameter);
2168 } else {
2169 namedParameters[parameter.name] = parameter;
2170 }
2171 }
2172 List<ParameterElement> unnamedParameters =
2173 new List<ParameterElement>.from(requiredParameters);
2174 unnamedParameters.addAll(positionalParameters);
2175 int unnamedParameterCount = unnamedParameters.length;
2176 int unnamedIndex = 0;
2177 NodeList<Expression> arguments = argumentList.arguments;
2178 int argumentCount = arguments.length;
2179 List<ParameterElement> resolvedParameters =
2180 new List<ParameterElement>(argumentCount);
2181 int positionalArgumentCount = 0;
2182 HashSet<String> usedNames = new HashSet<String>();
2183 bool noBlankArguments = true;
2184 for (int i = 0; i < argumentCount; i++) {
2185 Expression argument = arguments[i];
2186 if (argument is NamedExpression) {
2187 SimpleIdentifier nameNode = argument.name.label;
2188 String name = nameNode.name;
2189 ParameterElement element = namedParameters[name];
2190 if (element == null) {
2191 ErrorCode errorCode = (reportError
2192 ? CompileTimeErrorCode.UNDEFINED_NAMED_PARAMETER
2193 : StaticWarningCode.UNDEFINED_NAMED_PARAMETER);
2194 _resolver.reportErrorForNode(errorCode, nameNode, [name]);
2195 } else {
2196 resolvedParameters[i] = element;
2197 nameNode.staticElement = element;
2198 }
2199 if (!usedNames.add(name)) {
2200 _resolver.reportErrorForNode(
2201 CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, nameNode, [name]);
2202 }
2203 } else {
2204 if (argument is SimpleIdentifier && argument.name.isEmpty) {
2205 noBlankArguments = false;
2206 }
2207 positionalArgumentCount++;
2208 if (unnamedIndex < unnamedParameterCount) {
2209 resolvedParameters[i] = unnamedParameters[unnamedIndex++];
2210 }
2211 }
2212 }
2213 if (positionalArgumentCount < requiredParameters.length &&
2214 noBlankArguments) {
2215 ErrorCode errorCode = (reportError
2216 ? CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS
2217 : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS);
2218 _resolver.reportErrorForNode(errorCode, argumentList,
2219 [requiredParameters.length, positionalArgumentCount]);
2220 } else if (positionalArgumentCount > unnamedParameterCount &&
2221 noBlankArguments) {
2222 ErrorCode errorCode = (reportError
2223 ? CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS
2224 : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS);
2225 _resolver.reportErrorForNode(errorCode, argumentList,
2226 [unnamedParameterCount, positionalArgumentCount]);
2227 }
2228 return resolvedParameters;
2229 } 2075 }
2230 2076
2231 void _resolveBinaryExpression(BinaryExpression node, String methodName) { 2077 void _resolveBinaryExpression(BinaryExpression node, String methodName) {
2232 Expression leftOperand = node.leftOperand; 2078 Expression leftOperand = node.leftOperand;
2233 if (leftOperand != null) { 2079 if (leftOperand != null) {
2234 DartType staticType = _getStaticType(leftOperand); 2080 DartType staticType = _getStaticType(leftOperand);
2235 MethodElement staticMethod = 2081 MethodElement staticMethod =
2236 _lookUpMethod(leftOperand, staticType, methodName); 2082 _lookUpMethod(leftOperand, staticType, methodName);
2237 node.staticElement = staticMethod; 2083 node.staticElement = staticMethod;
2238 DartType propagatedType = _getPropagatedType(leftOperand); 2084 DartType propagatedType = _getPropagatedType(leftOperand);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2283 new NamespaceBuilder().createExportNamespaceForLibrary(library); 2129 new NamespaceBuilder().createExportNamespaceForLibrary(library);
2284 for (Combinator combinator in combinators) { 2130 for (Combinator combinator in combinators) {
2285 NodeList<SimpleIdentifier> names; 2131 NodeList<SimpleIdentifier> names;
2286 if (combinator is HideCombinator) { 2132 if (combinator is HideCombinator) {
2287 names = combinator.hiddenNames; 2133 names = combinator.hiddenNames;
2288 } else { 2134 } else {
2289 names = (combinator as ShowCombinator).shownNames; 2135 names = (combinator as ShowCombinator).shownNames;
2290 } 2136 }
2291 for (SimpleIdentifier name in names) { 2137 for (SimpleIdentifier name in names) {
2292 String nameStr = name.name; 2138 String nameStr = name.name;
2293 Element element = namespace.get(nameStr); 2139 Element element = namespace.get(nameStr) ?? namespace.get("$nameStr=");
2294 if (element == null) {
2295 element = namespace.get("$nameStr=");
2296 }
2297 if (element != null) { 2140 if (element != null) {
2298 // Ensure that the name always resolves to a top-level variable 2141 // Ensure that the name always resolves to a top-level variable
2299 // rather than a getter or setter 2142 // rather than a getter or setter
2300 if (element is PropertyAccessorElement) { 2143 if (element is PropertyAccessorElement) {
2301 element = (element as PropertyAccessorElement).variable; 2144 name.staticElement = element.variable;
2145 } else {
2146 name.staticElement = element;
2302 } 2147 }
2303 name.staticElement = element;
2304 } 2148 }
2305 } 2149 }
2306 } 2150 }
2307 } 2151 }
2308 2152
2309 /** 2153 /**
2310 * Given that we are accessing a property of the given [classElement] with the 2154 * Given that we are accessing a property of the given [classElement] with the
2311 * given [propertyName], return the element that represents the property. 2155 * given [propertyName], return the element that represents the property.
2312 */ 2156 */
2313 Element _resolveElement( 2157 Element _resolveElement(
2314 ClassElementImpl classElement, SimpleIdentifier propertyName) { 2158 ClassElement classElement, SimpleIdentifier propertyName) {
2315 String name = propertyName.name; 2159 String name = propertyName.name;
2316 Element element = null; 2160 Element element = null;
2317 if (propertyName.inSetterContext()) { 2161 if (propertyName.inSetterContext()) {
2318 element = classElement.getSetter(name); 2162 element = classElement.getSetter(name);
2319 } 2163 }
2320 if (element == null) { 2164 if (element == null) {
2321 element = classElement.getGetter(name); 2165 element = classElement.getGetter(name);
2322 } 2166 }
2323 if (element == null) { 2167 if (element == null) {
2324 element = classElement.getMethod(name); 2168 element = classElement.getMethod(name);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2369 * element being invoked. If the returned element is a method, then the method 2213 * element being invoked. If the returned element is a method, then the method
2370 * will be invoked. If the returned element is a getter, the getter will be 2214 * will be invoked. If the returned element is a getter, the getter will be
2371 * invoked without arguments and the result of that invocation will then be 2215 * invoked without arguments and the result of that invocation will then be
2372 * invoked with the arguments. The [target] is the target of the invocation 2216 * invoked with the arguments. The [target] is the target of the invocation
2373 * ('e'). The [targetType] is the type of the target. The [methodName] is th 2217 * ('e'). The [targetType] is the type of the target. The [methodName] is th
2374 * name of the method being invoked ('m'). [isConditional] indicates 2218 * name of the method being invoked ('m'). [isConditional] indicates
2375 * whether the invocatoin uses a '?.' operator. 2219 * whether the invocatoin uses a '?.' operator.
2376 */ 2220 */
2377 Element _resolveInvokedElementWithTarget(Expression target, 2221 Element _resolveInvokedElementWithTarget(Expression target,
2378 DartType targetType, SimpleIdentifier methodName, bool isConditional) { 2222 DartType targetType, SimpleIdentifier methodName, bool isConditional) {
2223 String name = methodName.name;
2379 if (targetType is InterfaceType) { 2224 if (targetType is InterfaceType) {
2380 Element element = _lookUpMethod(target, targetType, methodName.name); 2225 Element element = _lookUpMethod(target, targetType, name);
2381 if (element == null) { 2226 if (element == null) {
2382 // 2227 //
2383 // If there's no method, then it's possible that 'm' is a getter that 2228 // If there's no method, then it's possible that 'm' is a getter that
2384 // returns a function. 2229 // returns a function.
2385 // 2230 //
2386 // TODO (collinsn): need to add union type support here too, in the 2231 // TODO (collinsn): need to add union type support here too, in the
2387 // style of [lookUpMethod]. 2232 // style of [lookUpMethod].
2388 element = _lookUpGetter(target, targetType, methodName.name); 2233 element = _lookUpGetter(target, targetType, name);
2389 } 2234 }
2390 return element; 2235 return element;
2236 } else if (targetType is FunctionType &&
2237 _resolver.typeProvider.isObjectMethod(name)) {
2238 return _resolver.typeProvider.objectType.element.getMethod(name);
2391 } else if (target is SimpleIdentifier) { 2239 } else if (target is SimpleIdentifier) {
2392 Element targetElement = target.staticElement; 2240 Element targetElement = target.staticElement;
2241 if (targetType is FunctionType &&
2242 name == FunctionElement.CALL_METHOD_NAME) {
2243 return targetElement;
2244 }
2393 if (targetElement is PrefixElement) { 2245 if (targetElement is PrefixElement) {
2394 if (isConditional) { 2246 if (isConditional) {
2395 _resolver.reportErrorForNode( 2247 _resolver.errorReporter.reportErrorForNode(
2396 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT, 2248 CompileTimeErrorCode.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT,
2397 target, 2249 target,
2398 [target.name]); 2250 [target.name]);
2399 } 2251 }
2400 // 2252 //
2401 // Look to see whether the name of the method is really part of a 2253 // Look to see whether the name of the method is really part of a
2402 // prefixed identifier for an imported top-level function or top-level 2254 // prefixed identifier for an imported top-level function or top-level
2403 // getter that returns a function. 2255 // getter that returns a function.
2404 // 2256 //
2405 String name = "${target.name}.$methodName"; 2257 Identifier functionName =
2406 Identifier functionName = new SyntheticIdentifier(name, methodName); 2258 new PrefixedIdentifierImpl.temp(target, methodName);
2407 Element element = 2259 Element element =
2408 _resolver.nameScope.lookup(functionName, _definingLibrary); 2260 _resolver.nameScope.lookup(functionName, _definingLibrary);
2409 if (element != null) { 2261 if (element != null) {
2410 // TODO(brianwilkerson) This isn't a method invocation, it's a 2262 // TODO(brianwilkerson) This isn't a method invocation, it's a
2411 // function invocation where the function name is a prefixed 2263 // function invocation where the function name is a prefixed
2412 // identifier. Consider re-writing the AST. 2264 // identifier. Consider re-writing the AST.
2413 return element; 2265 return element;
2414 } 2266 }
2415 } 2267 }
2416 } 2268 }
2417 // TODO(brianwilkerson) Report this error. 2269 // TODO(brianwilkerson) Report this error.
2418 return null; 2270 return null;
2419 } 2271 }
2420 2272
2421 /** 2273 /**
2274 * Given a [node] that can have annotations associated with it, resolve the
2275 * annotations in the element model representing annotations to the node.
2276 */
2277 void _resolveMetadataForParameter(NormalFormalParameter node) {
2278 _resolveAnnotations(node.metadata);
2279 }
2280
2281 /**
2422 * Given that we are accessing a property of the given [targetType] with the 2282 * Given that we are accessing a property of the given [targetType] with the
2423 * given [propertyName], return the element that represents the property. The 2283 * given [propertyName], return the element that represents the property. The
2424 * [target] is the target of the invocation ('e'). 2284 * [target] is the target of the invocation ('e').
2425 */ 2285 */
2426 ExecutableElement _resolveProperty( 2286 ExecutableElement _resolveProperty(
2427 Expression target, DartType targetType, SimpleIdentifier propertyName) { 2287 Expression target, DartType targetType, SimpleIdentifier propertyName) {
2428 ExecutableElement memberElement = null; 2288 ExecutableElement memberElement = null;
2429 if (propertyName.inSetterContext()) { 2289 if (propertyName.inSetterContext()) {
2430 memberElement = _lookUpSetter(target, targetType, propertyName.name); 2290 memberElement = _lookUpSetter(target, targetType, propertyName.name);
2431 } 2291 }
2432 if (memberElement == null) { 2292 if (memberElement == null) {
2433 memberElement = _lookUpGetter(target, targetType, propertyName.name); 2293 memberElement = _lookUpGetter(target, targetType, propertyName.name);
2434 } 2294 }
2435 if (memberElement == null) { 2295 if (memberElement == null) {
2436 memberElement = _lookUpMethod(target, targetType, propertyName.name); 2296 memberElement = _lookUpMethod(target, targetType, propertyName.name);
2437 } 2297 }
2438 return memberElement; 2298 return memberElement;
2439 } 2299 }
2440 2300
2441 void _resolvePropertyAccess( 2301 void _resolvePropertyAccess(
2442 Expression target, SimpleIdentifier propertyName) { 2302 Expression target, SimpleIdentifier propertyName, bool isCascaded) {
2443 DartType staticType = _getStaticType(target); 2303 DartType staticType = _getStaticType(target);
2444 DartType propagatedType = _getPropagatedType(target); 2304 DartType propagatedType = _getPropagatedType(target);
2445 Element staticElement = null; 2305 Element staticElement = null;
2446 Element propagatedElement = null; 2306 Element propagatedElement = null;
2447 // 2307 //
2448 // If this property access is of the form 'C.m' where 'C' is a class, 2308 // If this property access is of the form 'C.m' where 'C' is a class,
2449 // then we don't call resolveProperty(...) which walks up the class 2309 // then we don't call resolveProperty(...) which walks up the class
2450 // hierarchy, instead we just look for the member in the type only. This 2310 // hierarchy, instead we just look for the member in the type only. This
2451 // does not apply to conditional property accesses (i.e. 'C?.m'). 2311 // does not apply to conditional property accesses (i.e. 'C?.m').
2452 // 2312 //
2453 ClassElementImpl typeReference = getTypeReference(target); 2313 ClassElement typeReference = getTypeReference(target);
2454 if (typeReference != null) { 2314 if (typeReference != null) {
2315 if (isCascaded) {
2316 typeReference = _typeType.element;
2317 }
2455 // TODO(brianwilkerson) Why are we setting the propagated element here? 2318 // TODO(brianwilkerson) Why are we setting the propagated element here?
2456 // It looks wrong. 2319 // It looks wrong.
2457 staticElement = 2320 staticElement =
2458 propagatedElement = _resolveElement(typeReference, propertyName); 2321 propagatedElement = _resolveElement(typeReference, propertyName);
2459 } else { 2322 } else {
2460 staticElement = _resolveProperty(target, staticType, propertyName); 2323 staticElement = _resolveProperty(target, staticType, propertyName);
2461 propagatedElement = 2324 propagatedElement =
2462 _resolveProperty(target, propagatedType, propertyName); 2325 _resolveProperty(target, propagatedType, propertyName);
2463 } 2326 }
2464 // May be part of annotation, record property element only if exists. 2327 // May be part of annotation, record property element only if exists.
(...skipping 13 matching lines...) Expand all
2478 _enableHints && 2341 _enableHints &&
2479 _shouldReportMissingMember(propagatedType, propagatedElement) && 2342 _shouldReportMissingMember(propagatedType, propagatedElement) &&
2480 !_memberFoundInSubclass( 2343 !_memberFoundInSubclass(
2481 propagatedType.element, propertyName.name, false, true); 2344 propagatedType.element, propertyName.name, false, true);
2482 if (shouldReportMissingMember_static || 2345 if (shouldReportMissingMember_static ||
2483 shouldReportMissingMember_propagated) { 2346 shouldReportMissingMember_propagated) {
2484 DartType staticOrPropagatedType = 2347 DartType staticOrPropagatedType =
2485 shouldReportMissingMember_static ? staticType : propagatedType; 2348 shouldReportMissingMember_static ? staticType : propagatedType;
2486 Element staticOrPropagatedEnclosingElt = staticOrPropagatedType.element; 2349 Element staticOrPropagatedEnclosingElt = staticOrPropagatedType.element;
2487 bool isStaticProperty = _isStatic(staticOrPropagatedEnclosingElt); 2350 bool isStaticProperty = _isStatic(staticOrPropagatedEnclosingElt);
2488 DartType displayType = staticOrPropagatedType != null 2351 DartType displayType =
2489 ? staticOrPropagatedType 2352 staticOrPropagatedType ?? propagatedType ?? staticType;
2490 : propagatedType != null ? propagatedType : staticType;
2491 // Special getter cases. 2353 // Special getter cases.
2492 if (propertyName.inGetterContext()) { 2354 if (propertyName.inGetterContext()) {
2493 if (!isStaticProperty && 2355 if (!isStaticProperty &&
2494 staticOrPropagatedEnclosingElt is ClassElement) { 2356 staticOrPropagatedEnclosingElt is ClassElement) {
2495 ClassElement classElement = staticOrPropagatedEnclosingElt; 2357 InterfaceType targetType = staticOrPropagatedEnclosingElt.type;
2496 InterfaceType targetType = classElement.type;
2497 if (!_enableStrictCallChecks && 2358 if (!_enableStrictCallChecks &&
2498 targetType != null && 2359 targetType != null &&
2499 targetType.isDartCoreFunction && 2360 targetType.isDartCoreFunction &&
2500 propertyName.name == FunctionElement.CALL_METHOD_NAME) { 2361 propertyName.name == FunctionElement.CALL_METHOD_NAME) {
2501 // TODO(brianwilkerson) Can we ever resolve the function being 2362 // TODO(brianwilkerson) Can we ever resolve the function being
2502 // invoked? 2363 // invoked?
2503 // resolveArgumentsToParameters(node.getArgumentList(), invokedFuncti on); 2364 // resolveArgumentsToParameters(node.getArgumentList(), invokedFuncti on);
2504 return; 2365 return;
2505 } else if (classElement.isEnum && propertyName.name == "_name") { 2366 } else if (staticOrPropagatedEnclosingElt.isEnum &&
2506 _resolver.reportErrorForNode( 2367 propertyName.name == "_name") {
2368 _resolver.errorReporter.reportErrorForNode(
2507 CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD, 2369 CompileTimeErrorCode.ACCESS_PRIVATE_ENUM_FIELD,
2508 propertyName, 2370 propertyName,
2509 [propertyName.name]); 2371 [propertyName.name]);
2510 return; 2372 return;
2511 } 2373 }
2512 } 2374 }
2513 } 2375 }
2514 Element declaringElement = 2376 Element declaringElement =
2515 staticType.isVoid ? null : staticOrPropagatedEnclosingElt; 2377 staticType.isVoid ? null : staticOrPropagatedEnclosingElt;
2516 if (propertyName.inSetterContext()) { 2378 if (propertyName.inSetterContext()) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
2587 setter = _lookUpSetter(null, enclosingClass.type, identifier.name); 2449 setter = _lookUpSetter(null, enclosingClass.type, identifier.name);
2588 } 2450 }
2589 } 2451 }
2590 if (setter != null) { 2452 if (setter != null) {
2591 element = setter; 2453 element = setter;
2592 } 2454 }
2593 } 2455 }
2594 } else if (element == null && 2456 } else if (element == null &&
2595 (identifier.inSetterContext() || 2457 (identifier.inSetterContext() ||
2596 identifier.parent is CommentReference)) { 2458 identifier.parent is CommentReference)) {
2597 element = _resolver.nameScope.lookup( 2459 Identifier setterId =
2598 new SyntheticIdentifier("${identifier.name}=", identifier), 2460 new SyntheticIdentifier('${identifier.name}=', identifier);
2599 _definingLibrary); 2461 element = _resolver.nameScope.lookup(setterId, _definingLibrary);
2462 identifier.setProperty(LibraryImportScope.conflictingSdkElements,
2463 setterId.getProperty(LibraryImportScope.conflictingSdkElements));
2600 } 2464 }
2601 ClassElement enclosingClass = _resolver.enclosingClass; 2465 ClassElement enclosingClass = _resolver.enclosingClass;
2602 if (element == null && enclosingClass != null) { 2466 if (element == null && enclosingClass != null) {
2603 InterfaceType enclosingType = enclosingClass.type; 2467 InterfaceType enclosingType = enclosingClass.type;
2604 if (element == null && 2468 if (element == null &&
2605 (identifier.inSetterContext() || 2469 (identifier.inSetterContext() ||
2606 identifier.parent is CommentReference)) { 2470 identifier.parent is CommentReference)) {
2607 element = _lookUpSetter(null, enclosingType, identifier.name); 2471 element = _lookUpSetter(null, enclosingType, identifier.name);
2608 } 2472 }
2609 if (element == null && identifier.inGetterContext()) { 2473 if (element == null && identifier.inGetterContext()) {
2610 element = _lookUpGetter(null, enclosingType, identifier.name); 2474 element = _lookUpGetter(null, enclosingType, identifier.name);
2611 } 2475 }
2612 if (element == null) { 2476 if (element == null) {
2613 element = _lookUpMethod(null, enclosingType, identifier.name); 2477 element = _lookUpMethod(null, enclosingType, identifier.name);
2614 } 2478 }
2615 } 2479 }
2616 return element; 2480 return element;
2617 } 2481 }
2618 2482
2619 /** 2483 /**
2620 * If the given [type] is a type parameter, resolve it to the type that should 2484 * If the given [type] is a type parameter, resolve it to the type that should
2621 * be used when looking up members. Otherwise, return the original type. 2485 * be used when looking up members. Otherwise, return the original type.
2622 */ 2486 */
2623 DartType _resolveTypeParameter(DartType type) { 2487 DartType _resolveTypeParameter(DartType type) =>
2624 if (type is TypeParameterType) { 2488 type?.resolveToBound(_resolver.typeProvider.objectType);
2625 DartType bound = type.element.bound;
2626 if (bound == null) {
2627 return _resolver.typeProvider.objectType;
2628 }
2629 return bound;
2630 }
2631 return type;
2632 }
2633
2634 /**
2635 * Given a [node] that can have annotations associated with it and the
2636 * [element] to which that node has been resolved, create the annotations in
2637 * the element model representing the annotations on the node.
2638 */
2639 void _setMetadataForParameter(Element element, NormalFormalParameter node) {
2640 if (element is! ElementImpl) {
2641 return;
2642 }
2643 List<ElementAnnotationImpl> annotationList =
2644 new List<ElementAnnotationImpl>();
2645 _addAnnotations(annotationList, node.metadata);
2646 if (!annotationList.isEmpty) {
2647 (element as ElementImpl).metadata = annotationList;
2648 }
2649 }
2650 2489
2651 /** 2490 /**
2652 * Return `true` if we should report an error as a result of looking up a 2491 * Return `true` if we should report an error as a result of looking up a
2653 * [member] in the given [type] and not finding any member. 2492 * [member] in the given [type] and not finding any member.
2654 */ 2493 */
2655 bool _shouldReportMissingMember(DartType type, Element member) { 2494 bool _shouldReportMissingMember(DartType type, Element member) {
2656 if (member != null || type == null || type.isDynamic || type.isBottom) { 2495 return member == null && type != null && !type.isDynamic && !type.isBottom;
2657 return false;
2658 }
2659 return true;
2660 } 2496 }
2661 2497
2662 /** 2498 /**
2663 * Checks whether the given [expression] is a reference to a class. If it is 2499 * Checks whether the given [expression] is a reference to a class. If it is
2664 * then the element representing the class is returned, otherwise `null` is 2500 * then the element representing the class is returned, otherwise `null` is
2665 * returned. 2501 * returned.
2666 */ 2502 */
2667 static ClassElementImpl getTypeReference(Expression expression) { 2503 static ClassElement getTypeReference(Expression expression) {
2668 if (expression is Identifier) { 2504 if (expression is Identifier) {
2669 Element staticElement = expression.staticElement; 2505 Element staticElement = expression.staticElement;
2670 if (staticElement is ClassElementImpl) { 2506 if (staticElement is ClassElement) {
2671 return staticElement; 2507 return staticElement;
2672 } 2508 }
2673 } 2509 }
2674 return null; 2510 return null;
2675 } 2511 }
2676 2512
2677 /** 2513 /**
2678 * Given a [node] that can have annotations associated with it and the 2514 * Given a [node] that can have annotations associated with it, resolve the
2679 * [element] to which that node has been resolved, create the annotations in 2515 * annotations in the element model representing the annotations on the node.
2680 * the element model representing the annotations on the node.
2681 */ 2516 */
2682 static void setMetadata(Element element, AnnotatedNode node) { 2517 static void resolveMetadata(AnnotatedNode node) {
2683 if (element is! ElementImpl) { 2518 _resolveAnnotations(node.metadata);
2684 return; 2519 if (node is VariableDeclaration) {
2685 } 2520 AstNode parent = node.parent;
2686 List<ElementAnnotationImpl> annotationList = <ElementAnnotationImpl>[]; 2521 if (parent is VariableDeclarationList) {
2687 _addAnnotations(annotationList, node.metadata); 2522 _resolveAnnotations(parent.metadata);
2688 if (node is VariableDeclaration && node.parent is VariableDeclarationList) { 2523 AstNode grandParent = parent.parent;
2689 VariableDeclarationList list = node.parent as VariableDeclarationList; 2524 if (grandParent is FieldDeclaration) {
2690 _addAnnotations(annotationList, list.metadata); 2525 _resolveAnnotations(grandParent.metadata);
2691 if (list.parent is FieldDeclaration) { 2526 } else if (grandParent is TopLevelVariableDeclaration) {
2692 FieldDeclaration fieldDeclaration = list.parent as FieldDeclaration; 2527 _resolveAnnotations(grandParent.metadata);
2693 _addAnnotations(annotationList, fieldDeclaration.metadata); 2528 }
2694 } else if (list.parent is TopLevelVariableDeclaration) {
2695 TopLevelVariableDeclaration variableDeclaration =
2696 list.parent as TopLevelVariableDeclaration;
2697 _addAnnotations(annotationList, variableDeclaration.metadata);
2698 }
2699 }
2700 if (!annotationList.isEmpty) {
2701 (element as ElementImpl).metadata = annotationList;
2702 }
2703 }
2704
2705 /**
2706 * Generate annotation elements for each of the annotations in the
2707 * [annotationList] and add them to the given list of [annotations].
2708 */
2709 static void _addAnnotations(List<ElementAnnotationImpl> annotationList,
2710 NodeList<Annotation> annotations) {
2711 int annotationCount = annotations.length;
2712 for (int i = 0; i < annotationCount; i++) {
2713 Annotation annotation = annotations[i];
2714 Element resolvedElement = annotation.element;
2715 if (resolvedElement != null) {
2716 ElementAnnotationImpl elementAnnotation =
2717 new ElementAnnotationImpl(resolvedElement);
2718 annotation.elementAnnotation = elementAnnotation;
2719 annotationList.add(elementAnnotation);
2720 } 2529 }
2721 } 2530 }
2722 } 2531 }
2723 2532
2724 /** 2533 /**
2725 * Return `true` if the given [identifier] is the return type of a constructor 2534 * Return `true` if the given [identifier] is the return type of a constructor
2726 * declaration. 2535 * declaration.
2727 */ 2536 */
2728 static bool _isConstructorReturnType(SimpleIdentifier identifier) { 2537 static bool _isConstructorReturnType(SimpleIdentifier identifier) {
2729 AstNode parent = identifier.parent; 2538 AstNode parent = identifier.parent;
2730 if (parent is ConstructorDeclaration) { 2539 if (parent is ConstructorDeclaration) {
2731 return identical(parent.returnType, identifier); 2540 return identical(parent.returnType, identifier);
2732 } 2541 }
2733 return false; 2542 return false;
2734 } 2543 }
2735 2544
2736 /** 2545 /**
2737 * Return `true` if the given [identifier] is the return type of a factory 2546 * Return `true` if the given [identifier] is the return type of a factory
2738 * constructor. 2547 * constructor.
2739 */ 2548 */
2740 static bool _isFactoryConstructorReturnType(SimpleIdentifier identifier) { 2549 static bool _isFactoryConstructorReturnType(SimpleIdentifier identifier) {
2741 AstNode parent = identifier.parent; 2550 AstNode parent = identifier.parent;
2742 if (parent is ConstructorDeclaration) { 2551 if (parent is ConstructorDeclaration) {
2743 ConstructorDeclaration constructor = parent; 2552 return identical(parent.returnType, identifier) &&
2744 return identical(constructor.returnType, identifier) && 2553 parent.factoryKeyword != null;
2745 constructor.factoryKeyword != null;
2746 } 2554 }
2747 return false; 2555 return false;
2748 } 2556 }
2749 2557
2750 /** 2558 /**
2751 * Return `true` if the given 'super' [expression] is used in a valid context. 2559 * Return `true` if the given 'super' [expression] is used in a valid context.
2752 */ 2560 */
2753 static bool _isSuperInValidContext(SuperExpression expression) { 2561 static bool _isSuperInValidContext(SuperExpression expression) {
2754 for (AstNode node = expression; node != null; node = node.parent) { 2562 for (AstNode node = expression; node != null; node = node.parent) {
2755 if (node is CompilationUnit) { 2563 if (node is CompilationUnit) {
2756 return false; 2564 return false;
2757 } 2565 } else if (node is ConstructorDeclaration) {
2758 if (node is ConstructorDeclaration) {
2759 return node.factoryKeyword == null; 2566 return node.factoryKeyword == null;
2760 } 2567 } else if (node is ConstructorFieldInitializer) {
2761 if (node is ConstructorFieldInitializer) {
2762 return false; 2568 return false;
2763 } 2569 } else if (node is MethodDeclaration) {
2764 if (node is MethodDeclaration) {
2765 return !node.isStatic; 2570 return !node.isStatic;
2766 } 2571 }
2767 } 2572 }
2768 return false; 2573 return false;
2769 } 2574 }
2575
2576 /**
2577 * Resolve each of the annotations in the given list of [annotations].
2578 */
2579 static void _resolveAnnotations(NodeList<Annotation> annotations) {
2580 for (Annotation annotation in annotations) {
2581 ElementAnnotationImpl elementAnnotation = annotation.elementAnnotation;
2582 elementAnnotation.element = annotation.element;
2583 }
2584 }
2770 } 2585 }
2771 2586
2772 /** 2587 /**
2773 * An identifier that can be used to look up names in the lexical scope when 2588 * An identifier that can be used to look up names in the lexical scope when
2774 * there is no identifier in the AST structure. There is no identifier in the 2589 * there is no identifier in the AST structure. There is no identifier in the
2775 * AST when the parser could not distinguish between a method invocation and an 2590 * AST when the parser could not distinguish between a method invocation and an
2776 * invocation of a top-level function imported with a prefix. 2591 * invocation of a top-level function imported with a prefix.
2777 */ 2592 */
2778 class SyntheticIdentifier extends Identifier { 2593 class SyntheticIdentifier extends IdentifierImpl {
2779 /** 2594 /**
2780 * The name of the synthetic identifier. 2595 * The name of the synthetic identifier.
2781 */ 2596 */
2597 @override
2782 final String name; 2598 final String name;
2783 2599
2784 /** 2600 /**
2785 * The identifier to be highlighted in case of an error 2601 * The identifier to be highlighted in case of an error
2786 */ 2602 */
2787 final Identifier targetIdentifier; 2603 final Identifier targetIdentifier;
2788 2604
2789 /** 2605 /**
2790 * Initialize a newly created synthetic identifier to have the given [name] 2606 * Initialize a newly created synthetic identifier to have the given [name]
2791 * and [targetIdentifier]. 2607 * and [targetIdentifier].
2792 */ 2608 */
2793 SyntheticIdentifier(this.name, this.targetIdentifier); 2609 SyntheticIdentifier(this.name, this.targetIdentifier);
2794 2610
2795 @override 2611 @override
2796 sc.Token get beginToken => null; 2612 Token get beginToken => null;
2797 2613
2798 @override 2614 @override
2799 Element get bestElement => null; 2615 Element get bestElement => null;
2800 2616
2801 @override 2617 @override
2802 Iterable get childEntities { 2618 Iterable<SyntacticEntity> get childEntities {
2803 // Should never be called, since a SyntheticIdentifier never appears in the 2619 // Should never be called, since a SyntheticIdentifier never appears in the
2804 // AST--it is just used for lookup. 2620 // AST--it is just used for lookup.
2805 assert(false); 2621 assert(false);
2806 return new ChildEntities(); 2622 return new ChildEntities();
2807 } 2623 }
2808 2624
2809 @override 2625 @override
2810 sc.Token get endToken => null; 2626 Token get endToken => null;
2811 2627
2812 @override 2628 @override
2813 int get length => targetIdentifier.length; 2629 int get length => targetIdentifier.length;
2814 2630
2815 @override 2631 @override
2816 int get offset => targetIdentifier.offset; 2632 int get offset => targetIdentifier.offset;
2817 2633
2818 @override 2634 @override
2819 int get precedence => 16; 2635 int get precedence => 16;
2820 2636
2821 @override 2637 @override
2822 Element get propagatedElement => null; 2638 Element get propagatedElement => null;
2823 2639
2824 @override 2640 @override
2825 Element get staticElement => null; 2641 Element get staticElement => null;
2826 2642
2827 @override 2643 @override
2828 accept(AstVisitor visitor) => null; 2644 dynamic/*=E*/ accept/*<E>*/(AstVisitor/*<E>*/ visitor) => null;
2829 2645
2830 @override 2646 @override
2831 void visitChildren(AstVisitor visitor) {} 2647 void visitChildren(AstVisitor visitor) {}
2832 } 2648 }
OLDNEW
« no previous file with comments | « packages/analyzer/lib/src/generated/element_handle.dart ('k') | packages/analyzer/lib/src/generated/engine.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698