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

Side by Side Diff: pkg/analyzer_experimental/lib/src/generated/resolver.dart

Issue 16337007: Version 0.5.13.1 . (Closed) Base URL: http://dart.googlecode.com/svn/trunk/dart/
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // This code was auto-generated, is not intended to be edited, and is subject to 1 // This code was auto-generated, is not intended to be edited, and is subject to
2 // significant change. Please see the README file for more information. 2 // significant change. Please see the README file for more information.
3 3
4 library engine.resolver; 4 library engine.resolver;
5 5
6 import 'dart:collection'; 6 import 'dart:collection';
7 import 'java_core.dart'; 7 import 'java_core.dart';
8 import 'java_engine.dart'; 8 import 'java_engine.dart';
9 import 'instrumentation.dart'; 9 import 'instrumentation.dart';
10 import 'source.dart'; 10 import 'source.dart';
11 import 'error.dart'; 11 import 'error.dart';
12 import 'scanner.dart' as sc; 12 import 'scanner.dart' as sc;
13 import 'utilities_dart.dart'; 13 import 'utilities_dart.dart';
14 import 'ast.dart'; 14 import 'ast.dart';
15 import 'parser.dart' show Parser, ParserErrorCode; 15 import 'parser.dart' show Parser, ParserErrorCode;
16 import 'sdk.dart' show DartSdk; 16 import 'sdk.dart' show DartSdk, SdkLibrary;
17 import 'element.dart' hide HideCombinator, ShowCombinator; 17 import 'element.dart' hide Annotation, HideCombinator, ShowCombinator;
18 import 'html.dart' as ht; 18 import 'html.dart' as ht;
19 import 'engine.dart'; 19 import 'engine.dart';
20 import 'constant.dart'; 20 import 'constant.dart';
21 import 'element.dart' as __imp_combi show HideCombinator, ShowCombinator; 21 import 'element.dart' as __imp_combi show HideCombinator, ShowCombinator;
22 22
23
23 /** 24 /**
24 * Instances of the class {@code CompilationUnitBuilder} build an element model for a single 25 * Instances of the class {@code CompilationUnitBuilder} build an element model for a single
25 * compilation unit. 26 * compilation unit.
26 * @coverage dart.engine.resolver 27 * @coverage dart.engine.resolver
27 */ 28 */
28 class CompilationUnitBuilder { 29 class CompilationUnitBuilder {
29 /** 30
30 * Initialize a newly created compilation unit element builder.
31 * @param analysisContext the analysis context in which the element model will be built
32 */
33 CompilationUnitBuilder() : super() {
34 }
35 /** 31 /**
36 * Build the compilation unit element for the given source. 32 * Build the compilation unit element for the given source.
37 * @param source the source describing the compilation unit 33 * @param source the source describing the compilation unit
38 * @param unit the AST structure representing the compilation unit 34 * @param unit the AST structure representing the compilation unit
39 * @return the compilation unit element that was built 35 * @return the compilation unit element that was built
40 * @throws AnalysisException if the analysis could not be performed 36 * @throws AnalysisException if the analysis could not be performed
41 */ 37 */
42 CompilationUnitElementImpl buildCompilationUnit(Source source2, CompilationUni t unit) { 38 CompilationUnitElementImpl buildCompilationUnit(Source source2, CompilationUni t unit) {
43 if (unit == null) { 39 if (unit == null) {
44 return null; 40 return null;
45 } 41 }
46 ElementHolder holder = new ElementHolder(); 42 ElementHolder holder = new ElementHolder();
47 ElementBuilder builder = new ElementBuilder(holder); 43 ElementBuilder builder = new ElementBuilder(holder);
48 unit.accept(builder); 44 unit.accept(builder);
49 CompilationUnitElementImpl element = new CompilationUnitElementImpl(source2. shortName); 45 CompilationUnitElementImpl element = new CompilationUnitElementImpl(source2. shortName);
50 element.accessors = holder.accessors; 46 element.accessors = holder.accessors;
51 element.functions = holder.functions; 47 element.functions = holder.functions;
52 element.source = source2; 48 element.source = source2;
53 element.typeAliases = holder.typeAliases; 49 element.typeAliases = holder.typeAliases;
54 element.types = holder.types; 50 element.types = holder.types;
55 element.topLevelVariables = holder.topLevelVariables; 51 element.topLevelVariables = holder.topLevelVariables;
56 unit.element = element; 52 unit.element = element;
57 return element; 53 return element;
58 } 54 }
59 } 55 }
56
60 /** 57 /**
61 * Instances of the class {@code ElementBuilder} traverse an AST structure and b uild the element 58 * Instances of the class {@code ElementBuilder} traverse an AST structure and b uild the element
62 * model representing the AST structure. 59 * model representing the AST structure.
63 * @coverage dart.engine.resolver 60 * @coverage dart.engine.resolver
64 */ 61 */
65 class ElementBuilder extends RecursiveASTVisitor<Object> { 62 class ElementBuilder extends RecursiveASTVisitor<Object> {
63
66 /** 64 /**
67 * The element holder associated with the element that is currently being buil t. 65 * The element holder associated with the element that is currently being buil t.
68 */ 66 */
69 ElementHolder _currentHolder; 67 ElementHolder _currentHolder;
68
70 /** 69 /**
71 * A flag indicating whether a variable declaration is in the context of a fie ld declaration. 70 * A flag indicating whether a variable declaration is in the context of a fie ld declaration.
72 */ 71 */
73 bool _inFieldContext = false; 72 bool _inFieldContext = false;
73
74 /** 74 /**
75 * A flag indicating whether a variable declaration is within the body of a me thod or function. 75 * A flag indicating whether a variable declaration is within the body of a me thod or function.
76 */ 76 */
77 bool _inFunction = false; 77 bool _inFunction = false;
78
78 /** 79 /**
79 * A flag indicating whether the class currently being visited can be used as a mixin. 80 * A flag indicating whether the class currently being visited can be used as a mixin.
80 */ 81 */
81 bool _isValidMixin = false; 82 bool _isValidMixin = false;
83
82 /** 84 /**
83 * Initialize a newly created element builder to build the elements for a comp ilation unit. 85 * Initialize a newly created element builder to build the elements for a comp ilation unit.
84 * @param initialHolder the element holder associated with the compilation uni t being built 86 * @param initialHolder the element holder associated with the compilation uni t being built
85 */ 87 */
86 ElementBuilder(ElementHolder initialHolder) { 88 ElementBuilder(ElementHolder initialHolder) {
87 _currentHolder = initialHolder; 89 _currentHolder = initialHolder;
88 } 90 }
89 Object visitBlock(Block node) { 91 Object visitBlock(Block node) {
90 bool wasInField = _inFieldContext; 92 bool wasInField = _inFieldContext;
91 _inFieldContext = false; 93 _inFieldContext = false;
(...skipping 24 matching lines...) Expand all
116 _isValidMixin = true; 118 _isValidMixin = true;
117 visitChildren(holder, node); 119 visitChildren(holder, node);
118 SimpleIdentifier className = node.name; 120 SimpleIdentifier className = node.name;
119 ClassElementImpl element = new ClassElementImpl(className); 121 ClassElementImpl element = new ClassElementImpl(className);
120 List<TypeVariableElement> typeVariables2 = holder.typeVariables; 122 List<TypeVariableElement> typeVariables2 = holder.typeVariables;
121 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element); 123 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
122 interfaceType.typeArguments = createTypeVariableTypes(typeVariables2); 124 interfaceType.typeArguments = createTypeVariableTypes(typeVariables2);
123 element.type = interfaceType; 125 element.type = interfaceType;
124 List<ConstructorElement> constructors2 = holder.constructors; 126 List<ConstructorElement> constructors2 = holder.constructors;
125 if (constructors2.length == 0) { 127 if (constructors2.length == 0) {
126 ConstructorElementImpl constructor = new ConstructorElementImpl(null); 128 constructors2 = createDefaultConstructors(interfaceType);
127 constructor.synthetic = true;
128 FunctionTypeImpl type = new FunctionTypeImpl.con1(constructor);
129 type.returnType = interfaceType;
130 constructor.type = type;
131 constructors2 = <ConstructorElement> [constructor];
132 } 129 }
133 element.abstract = node.abstractKeyword != null; 130 element.abstract = node.abstractKeyword != null;
134 element.accessors = holder.accessors; 131 element.accessors = holder.accessors;
135 element.constructors = constructors2; 132 element.constructors = constructors2;
136 element.fields = holder.fields; 133 element.fields = holder.fields;
137 element.methods = holder.methods; 134 element.methods = holder.methods;
138 element.typeVariables = typeVariables2; 135 element.typeVariables = typeVariables2;
139 element.validMixin = _isValidMixin; 136 element.validMixin = _isValidMixin;
140 _currentHolder.addType(element); 137 _currentHolder.addType(element);
141 className.element = element; 138 className.element = element;
142 return null; 139 return null;
143 } 140 }
144 Object visitClassTypeAlias(ClassTypeAlias node) { 141 Object visitClassTypeAlias(ClassTypeAlias node) {
145 ElementHolder holder = new ElementHolder(); 142 ElementHolder holder = new ElementHolder();
146 visitChildren(holder, node); 143 visitChildren(holder, node);
147 SimpleIdentifier className = node.name; 144 SimpleIdentifier className = node.name;
148 ClassElementImpl element = new ClassElementImpl(className); 145 ClassElementImpl element = new ClassElementImpl(className);
149 element.abstract = node.abstractKeyword != null; 146 element.abstract = node.abstractKeyword != null;
150 element.typedef = true; 147 element.typedef = true;
151 List<TypeVariableElement> typeVariables2 = holder.typeVariables; 148 List<TypeVariableElement> typeVariables2 = holder.typeVariables;
152 element.typeVariables = typeVariables2; 149 element.typeVariables = typeVariables2;
153 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element); 150 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
154 interfaceType.typeArguments = createTypeVariableTypes(typeVariables2); 151 interfaceType.typeArguments = createTypeVariableTypes(typeVariables2);
155 element.type = interfaceType; 152 element.type = interfaceType;
153 element.constructors = createDefaultConstructors(interfaceType);
156 _currentHolder.addType(element); 154 _currentHolder.addType(element);
157 className.element = element; 155 className.element = element;
158 return null; 156 return null;
159 } 157 }
160 Object visitConstructorDeclaration(ConstructorDeclaration node) { 158 Object visitConstructorDeclaration(ConstructorDeclaration node) {
161 _isValidMixin = false; 159 _isValidMixin = false;
162 ElementHolder holder = new ElementHolder(); 160 ElementHolder holder = new ElementHolder();
163 bool wasInFunction = _inFunction; 161 bool wasInFunction = _inFunction;
164 _inFunction = true; 162 _inFunction = true;
165 try { 163 try {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 } finally { 239 } finally {
242 _inFieldContext = wasInField; 240 _inFieldContext = wasInField;
243 } 241 }
244 return null; 242 return null;
245 } 243 }
246 Object visitFieldFormalParameter(FieldFormalParameter node) { 244 Object visitFieldFormalParameter(FieldFormalParameter node) {
247 if (node.parent is! DefaultFormalParameter) { 245 if (node.parent is! DefaultFormalParameter) {
248 SimpleIdentifier parameterName = node.identifier; 246 SimpleIdentifier parameterName = node.identifier;
249 FieldFormalParameterElementImpl parameter = new FieldFormalParameterElemen tImpl(parameterName); 247 FieldFormalParameterElementImpl parameter = new FieldFormalParameterElemen tImpl(parameterName);
250 parameter.const3 = node.isConst(); 248 parameter.const3 = node.isConst();
251 parameter.initializingFormal = true;
252 parameter.final2 = node.isFinal(); 249 parameter.final2 = node.isFinal();
253 parameter.parameterKind = node.kind; 250 parameter.parameterKind = node.kind;
254 _currentHolder.addParameter(parameter); 251 _currentHolder.addParameter(parameter);
255 parameterName.element = parameter; 252 parameterName.element = parameter;
256 } 253 }
257 return super.visitFieldFormalParameter(node); 254 return super.visitFieldFormalParameter(node);
258 } 255 }
259 Object visitFunctionDeclaration(FunctionDeclaration node) { 256 Object visitFunctionDeclaration(FunctionDeclaration node) {
260 FunctionExpression expression = node.functionExpression; 257 FunctionExpression expression = node.functionExpression;
261 if (expression != null) { 258 if (expression != null) {
(...skipping 21 matching lines...) Expand all
283 } else { 280 } else {
284 SimpleIdentifier propertyNameNode = node.name; 281 SimpleIdentifier propertyNameNode = node.name;
285 if (propertyNameNode == null) { 282 if (propertyNameNode == null) {
286 return null; 283 return null;
287 } 284 }
288 String propertyName = propertyNameNode.name; 285 String propertyName = propertyNameNode.name;
289 FieldElementImpl field = _currentHolder.getField(propertyName) as FieldE lementImpl; 286 FieldElementImpl field = _currentHolder.getField(propertyName) as FieldE lementImpl;
290 if (field == null) { 287 if (field == null) {
291 field = new FieldElementImpl.con2(node.name.name); 288 field = new FieldElementImpl.con2(node.name.name);
292 field.final2 = true; 289 field.final2 = true;
290 field.static = true;
293 _currentHolder.addField(field); 291 _currentHolder.addField(field);
294 } 292 }
295 if (matches(property, sc.Keyword.GET)) { 293 if (matches(property, sc.Keyword.GET)) {
296 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.c on1(propertyNameNode); 294 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.c on1(propertyNameNode);
297 getter.functions = holder.functions; 295 getter.functions = holder.functions;
298 getter.labels = holder.labels; 296 getter.labels = holder.labels;
299 getter.localVariables = holder.localVariables; 297 getter.localVariables = holder.localVariables;
300 getter.variable = field; 298 getter.variable = field;
301 getter.getter = true; 299 getter.getter = true;
300 getter.static = true;
302 field.getter = getter; 301 field.getter = getter;
303 _currentHolder.addAccessor(getter); 302 _currentHolder.addAccessor(getter);
304 propertyNameNode.element = getter; 303 propertyNameNode.element = getter;
305 } else { 304 } else {
306 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.c on1(propertyNameNode); 305 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.c on1(propertyNameNode);
307 setter.functions = holder.functions; 306 setter.functions = holder.functions;
308 setter.labels = holder.labels; 307 setter.labels = holder.labels;
309 setter.localVariables = holder.localVariables; 308 setter.localVariables = holder.localVariables;
310 setter.parameters = holder.parameters; 309 setter.parameters = holder.parameters;
311 setter.variable = field; 310 setter.variable = field;
312 setter.setter = true; 311 setter.setter = true;
312 setter.static = true;
313 field.setter = setter; 313 field.setter = setter;
314 field.final2 = false; 314 field.final2 = false;
315 _currentHolder.addAccessor(setter); 315 _currentHolder.addAccessor(setter);
316 propertyNameNode.element = setter; 316 propertyNameNode.element = setter;
317 } 317 }
318 } 318 }
319 } 319 }
320 return null; 320 return null;
321 } 321 }
322 Object visitFunctionExpression(FunctionExpression node) { 322 Object visitFunctionExpression(FunctionExpression node) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 } 388 }
389 Object visitMethodDeclaration(MethodDeclaration node) { 389 Object visitMethodDeclaration(MethodDeclaration node) {
390 ElementHolder holder = new ElementHolder(); 390 ElementHolder holder = new ElementHolder();
391 bool wasInFunction = _inFunction; 391 bool wasInFunction = _inFunction;
392 _inFunction = true; 392 _inFunction = true;
393 try { 393 try {
394 visitChildren(holder, node); 394 visitChildren(holder, node);
395 } finally { 395 } finally {
396 _inFunction = wasInFunction; 396 _inFunction = wasInFunction;
397 } 397 }
398 bool isStatic2 = node.isStatic();
398 sc.Token property = node.propertyKeyword; 399 sc.Token property = node.propertyKeyword;
399 if (property == null) { 400 if (property == null) {
400 SimpleIdentifier methodName = node.name; 401 SimpleIdentifier methodName = node.name;
401 String nameOfMethod = methodName.name; 402 String nameOfMethod = methodName.name;
402 if (nameOfMethod == sc.TokenType.MINUS.lexeme && node.parameters.parameter s.length == 0) { 403 if (nameOfMethod == sc.TokenType.MINUS.lexeme && node.parameters.parameter s.length == 0) {
403 nameOfMethod = "unary-"; 404 nameOfMethod = "unary-";
404 } 405 }
405 MethodElementImpl element = new MethodElementImpl.con2(nameOfMethod, metho dName.offset); 406 MethodElementImpl element = new MethodElementImpl.con2(nameOfMethod, metho dName.offset);
406 element.abstract = node.isAbstract(); 407 element.abstract = node.isAbstract();
407 element.functions = holder.functions; 408 element.functions = holder.functions;
408 element.labels = holder.labels; 409 element.labels = holder.labels;
409 element.localVariables = holder.localVariables; 410 element.localVariables = holder.localVariables;
410 element.parameters = holder.parameters; 411 element.parameters = holder.parameters;
411 element.static = node.isStatic(); 412 element.static = isStatic2;
412 _currentHolder.addMethod(element); 413 _currentHolder.addMethod(element);
413 methodName.element = element; 414 methodName.element = element;
414 } else { 415 } else {
415 SimpleIdentifier propertyNameNode = node.name; 416 SimpleIdentifier propertyNameNode = node.name;
416 String propertyName = propertyNameNode.name; 417 String propertyName = propertyNameNode.name;
417 FieldElementImpl field = _currentHolder.getField(propertyName) as FieldEle mentImpl; 418 FieldElementImpl field = _currentHolder.getField(propertyName) as FieldEle mentImpl;
418 if (field == null) { 419 if (field == null) {
419 field = new FieldElementImpl.con2(node.name.name); 420 field = new FieldElementImpl.con2(node.name.name);
420 field.final2 = true; 421 field.final2 = true;
421 field.static = matches(node.modifierKeyword, sc.Keyword.STATIC); 422 field.static = isStatic2;
422 _currentHolder.addField(field); 423 _currentHolder.addField(field);
423 } 424 }
424 if (matches(property, sc.Keyword.GET)) { 425 if (matches(property, sc.Keyword.GET)) {
425 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con 1(propertyNameNode); 426 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con 1(propertyNameNode);
426 getter.functions = holder.functions; 427 getter.functions = holder.functions;
427 getter.labels = holder.labels; 428 getter.labels = holder.labels;
428 getter.localVariables = holder.localVariables; 429 getter.localVariables = holder.localVariables;
429 getter.variable = field; 430 getter.variable = field;
431 getter.abstract = node.body is EmptyFunctionBody && node.externalKeyword == null;
430 getter.getter = true; 432 getter.getter = true;
433 getter.static = isStatic2;
431 field.getter = getter; 434 field.getter = getter;
432 _currentHolder.addAccessor(getter); 435 _currentHolder.addAccessor(getter);
433 propertyNameNode.element = getter; 436 propertyNameNode.element = getter;
434 } else { 437 } else {
435 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con 1(propertyNameNode); 438 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con 1(propertyNameNode);
436 setter.functions = holder.functions; 439 setter.functions = holder.functions;
437 setter.labels = holder.labels; 440 setter.labels = holder.labels;
438 setter.localVariables = holder.localVariables; 441 setter.localVariables = holder.localVariables;
439 setter.parameters = holder.parameters; 442 setter.parameters = holder.parameters;
440 setter.variable = field; 443 setter.variable = field;
444 setter.abstract = node.body is EmptyFunctionBody && !matches(node.extern alKeyword, sc.Keyword.EXTERNAL);
441 setter.setter = true; 445 setter.setter = true;
446 setter.static = isStatic2;
442 field.setter = setter; 447 field.setter = setter;
443 field.final2 = false; 448 field.final2 = false;
444 _currentHolder.addAccessor(setter); 449 _currentHolder.addAccessor(setter);
445 propertyNameNode.element = setter; 450 propertyNameNode.element = setter;
446 } 451 }
447 } 452 }
448 return null; 453 return null;
449 } 454 }
450 Object visitSimpleFormalParameter(SimpleFormalParameter node) { 455 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
451 if (node.parent is! DefaultFormalParameter) { 456 if (node.parent is! DefaultFormalParameter) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 } 552 }
548 FunctionElementImpl initializer = new FunctionElementImpl(); 553 FunctionElementImpl initializer = new FunctionElementImpl();
549 initializer.functions = holder.functions; 554 initializer.functions = holder.functions;
550 initializer.labels = holder.labels; 555 initializer.labels = holder.labels;
551 initializer.localVariables = holder.localVariables; 556 initializer.localVariables = holder.localVariables;
552 initializer.synthetic = true; 557 initializer.synthetic = true;
553 element.initializer = initializer; 558 element.initializer = initializer;
554 } 559 }
555 if (element is PropertyInducingElementImpl) { 560 if (element is PropertyInducingElementImpl) {
556 PropertyInducingElementImpl variable = element as PropertyInducingElementI mpl; 561 PropertyInducingElementImpl variable = element as PropertyInducingElementI mpl;
562 if (_inFieldContext) {
563 ((variable as FieldElementImpl)).static = matches(((node.parent.parent a s FieldDeclaration)).keyword, sc.Keyword.STATIC);
564 }
557 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2( variable); 565 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2( variable);
558 getter.getter = true; 566 getter.getter = true;
567 getter.static = variable.isStatic();
559 _currentHolder.addAccessor(getter); 568 _currentHolder.addAccessor(getter);
560 variable.getter = getter; 569 variable.getter = getter;
561 if (!isFinal) { 570 if (!isFinal) {
562 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con 2(variable); 571 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con 2(variable);
563 setter.setter = true; 572 setter.setter = true;
573 setter.static = variable.isStatic();
564 _currentHolder.addAccessor(setter); 574 _currentHolder.addAccessor(setter);
565 variable.setter = setter; 575 variable.setter = setter;
566 } 576 }
567 if (_inFieldContext) {
568 ((variable as FieldElementImpl)).static = matches(((node.parent.parent a s FieldDeclaration)).keyword, sc.Keyword.STATIC);
569 }
570 } 577 }
571 return null; 578 return null;
572 } 579 }
580
581 /**
582 * Creates the {@link ConstructorElement}s array with the single default const ructor element.
583 * @param interfaceType the interface type for which to create a default const ructor
584 * @return the {@link ConstructorElement}s array with the single default const ructor element
585 */
586 List<ConstructorElement> createDefaultConstructors(InterfaceTypeImpl interface Type) {
587 ConstructorElementImpl constructor = new ConstructorElementImpl(null);
588 constructor.synthetic = true;
589 FunctionTypeImpl type = new FunctionTypeImpl.con1(constructor);
590 type.returnType = interfaceType;
591 constructor.type = type;
592 return <ConstructorElement> [constructor];
593 }
573 List<Type2> createTypeVariableTypes(List<TypeVariableElement> typeVariables) { 594 List<Type2> createTypeVariableTypes(List<TypeVariableElement> typeVariables) {
574 int typeVariableCount = typeVariables.length; 595 int typeVariableCount = typeVariables.length;
575 List<Type2> typeArguments = new List<Type2>(typeVariableCount); 596 List<Type2> typeArguments = new List<Type2>(typeVariableCount);
576 for (int i = 0; i < typeVariableCount; i++) { 597 for (int i = 0; i < typeVariableCount; i++) {
577 TypeVariableElementImpl typeVariable = typeVariables[i] as TypeVariableEle mentImpl; 598 TypeVariableElementImpl typeVariable = typeVariables[i] as TypeVariableEle mentImpl;
578 TypeVariableTypeImpl typeArgument = new TypeVariableTypeImpl(typeVariable) ; 599 TypeVariableTypeImpl typeArgument = new TypeVariableTypeImpl(typeVariable) ;
579 typeVariable.type = typeArgument; 600 typeVariable.type = typeArgument;
580 typeArguments[i] = typeArgument; 601 typeArguments[i] = typeArgument;
581 } 602 }
582 return typeArguments; 603 return typeArguments;
583 } 604 }
605
584 /** 606 /**
585 * Return the body of the function that contains the given parameter, or {@cod e null} if no 607 * Return the body of the function that contains the given parameter, or {@cod e null} if no
586 * function body could be found. 608 * function body could be found.
587 * @param node the parameter contained in the function whose body is to be ret urned 609 * @param node the parameter contained in the function whose body is to be ret urned
588 * @return the body of the function that contains the given parameter 610 * @return the body of the function that contains the given parameter
589 */ 611 */
590 FunctionBody getFunctionBody(FormalParameter node) { 612 FunctionBody getFunctionBody(FormalParameter node) {
591 ASTNode parent2 = node.parent; 613 ASTNode parent2 = node.parent;
592 while (parent2 != null) { 614 while (parent2 != null) {
593 if (parent2 is FunctionExpression) { 615 if (parent2 is FunctionExpression) {
594 return ((parent2 as FunctionExpression)).body; 616 return ((parent2 as FunctionExpression)).body;
595 } else if (parent2 is MethodDeclaration) { 617 } else if (parent2 is MethodDeclaration) {
596 return ((parent2 as MethodDeclaration)).body; 618 return ((parent2 as MethodDeclaration)).body;
597 } 619 }
598 parent2 = parent2.parent; 620 parent2 = parent2.parent;
599 } 621 }
600 return null; 622 return null;
601 } 623 }
624
602 /** 625 /**
603 * Return {@code true} if the given token is a token for the given keyword. 626 * Return {@code true} if the given token is a token for the given keyword.
604 * @param token the token being tested 627 * @param token the token being tested
605 * @param keyword the keyword being tested for 628 * @param keyword the keyword being tested for
606 * @return {@code true} if the given token is a token for the given keyword 629 * @return {@code true} if the given token is a token for the given keyword
607 */ 630 */
608 bool matches(sc.Token token, sc.Keyword keyword2) => token != null && identica l(token.type, sc.TokenType.KEYWORD) && identical(((token as sc.KeywordToken)).ke yword, keyword2); 631 bool matches(sc.Token token, sc.Keyword keyword2) => token != null && identica l(token.type, sc.TokenType.KEYWORD) && identical(((token as sc.KeywordToken)).ke yword, keyword2);
632
609 /** 633 /**
610 * Make the given holder be the current holder while visiting the given node. 634 * Make the given holder be the current holder while visiting the given node.
611 * @param holder the holder that will gather elements that are built while vis iting the children 635 * @param holder the holder that will gather elements that are built while vis iting the children
612 * @param node the node to be visited 636 * @param node the node to be visited
613 */ 637 */
614 void visit(ElementHolder holder, ASTNode node) { 638 void visit(ElementHolder holder, ASTNode node) {
615 if (node != null) { 639 if (node != null) {
616 ElementHolder previousHolder = _currentHolder; 640 ElementHolder previousHolder = _currentHolder;
617 _currentHolder = holder; 641 _currentHolder = holder;
618 try { 642 try {
619 node.accept(this); 643 node.accept(this);
620 } finally { 644 } finally {
621 _currentHolder = previousHolder; 645 _currentHolder = previousHolder;
622 } 646 }
623 } 647 }
624 } 648 }
649
625 /** 650 /**
626 * Make the given holder be the current holder while visiting the children of the given node. 651 * Make the given holder be the current holder while visiting the children of the given node.
627 * @param holder the holder that will gather elements that are built while vis iting the children 652 * @param holder the holder that will gather elements that are built while vis iting the children
628 * @param node the node whose children are to be visited 653 * @param node the node whose children are to be visited
629 */ 654 */
630 void visitChildren(ElementHolder holder, ASTNode node) { 655 void visitChildren(ElementHolder holder, ASTNode node) {
631 if (node != null) { 656 if (node != null) {
632 ElementHolder previousHolder = _currentHolder; 657 ElementHolder previousHolder = _currentHolder;
633 _currentHolder = holder; 658 _currentHolder = holder;
634 try { 659 try {
635 node.visitChildren(this); 660 node.visitChildren(this);
636 } finally { 661 } finally {
637 _currentHolder = previousHolder; 662 _currentHolder = previousHolder;
638 } 663 }
639 } 664 }
640 } 665 }
641 } 666 }
667
642 /** 668 /**
643 * Instances of the class {@code ElementHolder} hold on to elements created whil e traversing an AST 669 * Instances of the class {@code ElementHolder} hold on to elements created whil e traversing an AST
644 * structure so that they can be accessed when creating their enclosing element. 670 * structure so that they can be accessed when creating their enclosing element.
645 * @coverage dart.engine.resolver 671 * @coverage dart.engine.resolver
646 */ 672 */
647 class ElementHolder { 673 class ElementHolder {
648 List<PropertyAccessorElement> _accessors = new List<PropertyAccessorElement>() ; 674 List<PropertyAccessorElement> _accessors = new List<PropertyAccessorElement>() ;
649 List<ConstructorElement> _constructors = new List<ConstructorElement>(); 675 List<ConstructorElement> _constructors = new List<ConstructorElement>();
650 List<FieldElement> _fields = new List<FieldElement>(); 676 List<FieldElement> _fields = new List<FieldElement>();
651 List<FunctionElement> _functions = new List<FunctionElement>(); 677 List<FunctionElement> _functions = new List<FunctionElement>();
652 List<LabelElement> _labels = new List<LabelElement>(); 678 List<LabelElement> _labels = new List<LabelElement>();
653 List<VariableElement> _localVariables = new List<VariableElement>(); 679 List<VariableElement> _localVariables = new List<VariableElement>();
654 List<MethodElement> _methods = new List<MethodElement>(); 680 List<MethodElement> _methods = new List<MethodElement>();
655 List<FunctionTypeAliasElement> _typeAliases = new List<FunctionTypeAliasElemen t>(); 681 List<FunctionTypeAliasElement> _typeAliases = new List<FunctionTypeAliasElemen t>();
656 List<ParameterElement> _parameters = new List<ParameterElement>(); 682 List<ParameterElement> _parameters = new List<ParameterElement>();
657 List<VariableElement> _topLevelVariables = new List<VariableElement>(); 683 List<VariableElement> _topLevelVariables = new List<VariableElement>();
658 List<ClassElement> _types = new List<ClassElement>(); 684 List<ClassElement> _types = new List<ClassElement>();
659 List<TypeVariableElement> _typeVariables = new List<TypeVariableElement>(); 685 List<TypeVariableElement> _typeVariables = new List<TypeVariableElement>();
660 /**
661 * Initialize a newly created element holder.
662 */
663 ElementHolder() : super() {
664 }
665 void addAccessor(PropertyAccessorElement element) { 686 void addAccessor(PropertyAccessorElement element) {
666 _accessors.add(element); 687 _accessors.add(element);
667 } 688 }
668 void addConstructor(ConstructorElement element) { 689 void addConstructor(ConstructorElement element) {
669 _constructors.add(element); 690 _constructors.add(element);
670 } 691 }
671 void addField(FieldElement element) { 692 void addField(FieldElement element) {
672 _fields.add(element); 693 _fields.add(element);
673 } 694 }
674 void addFunction(FunctionElement element) { 695 void addFunction(FunctionElement element) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 } 793 }
773 return new List.from(_types); 794 return new List.from(_types);
774 } 795 }
775 List<TypeVariableElement> get typeVariables { 796 List<TypeVariableElement> get typeVariables {
776 if (_typeVariables.isEmpty) { 797 if (_typeVariables.isEmpty) {
777 return TypeVariableElementImpl.EMPTY_ARRAY; 798 return TypeVariableElementImpl.EMPTY_ARRAY;
778 } 799 }
779 return new List.from(_typeVariables); 800 return new List.from(_typeVariables);
780 } 801 }
781 } 802 }
803
782 /** 804 /**
783 * Instances of the class {@code HtmlUnitBuilder} build an element model for a s ingle HTML unit. 805 * Instances of the class {@code HtmlUnitBuilder} build an element model for a s ingle HTML unit.
784 */ 806 */
785 class HtmlUnitBuilder implements ht.XmlVisitor<Object> { 807 class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
786 static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\""; 808 static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\"";
787 static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'"; 809 static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'";
788 static String _SCRIPT = "script"; 810 static String _SCRIPT = "script";
789 static String _SRC = "src"; 811 static String _SRC = "src";
790 static String _TYPE = "type"; 812 static String _TYPE = "type";
813
791 /** 814 /**
792 * The analysis context in which the element model will be built. 815 * The analysis context in which the element model will be built.
793 */ 816 */
794 InternalAnalysisContext _context; 817 InternalAnalysisContext _context;
818
795 /** 819 /**
796 * The error listener to which errors will be reported. 820 * The error listener to which errors will be reported.
797 */ 821 */
798 AnalysisErrorListener _errorListener; 822 RecordingErrorListener _errorListener;
823
799 /** 824 /**
800 * The line information associated with the source for which an element is bei ng built, or{@code null} if we are not building an element. 825 * The line information associated with the source for which an element is bei ng built, or{@code null} if we are not building an element.
801 */ 826 */
802 LineInfo _lineInfo; 827 LineInfo _lineInfo;
828
803 /** 829 /**
804 * The HTML element being built. 830 * The HTML element being built.
805 */ 831 */
806 HtmlElementImpl _htmlElement; 832 HtmlElementImpl _htmlElement;
833
834 /**
835 * The elements in the path from the HTML unit to the current tag node.
836 */
837 List<ht.XmlTagNode> _parentNodes;
838
807 /** 839 /**
808 * The script elements being built. 840 * The script elements being built.
809 */ 841 */
810 List<HtmlScriptElement> _scripts; 842 List<HtmlScriptElement> _scripts;
843
844 /**
845 * A set of the libraries that were resolved while resolving the HTML unit.
846 */
847 Set<Library> _resolvedLibraries = new Set<Library>();
848
811 /** 849 /**
812 * Initialize a newly created HTML unit builder. 850 * Initialize a newly created HTML unit builder.
813 * @param context the analysis context in which the element model will be buil t 851 * @param context the analysis context in which the element model will be buil t
814 * @param errorListener the error listener to which errors will be reported
815 */ 852 */
816 HtmlUnitBuilder(InternalAnalysisContext context, AnalysisErrorListener errorLi stener) { 853 HtmlUnitBuilder(InternalAnalysisContext context) {
817 this._context = context; 854 this._context = context;
818 this._errorListener = errorListener; 855 this._errorListener = new RecordingErrorListener();
819 } 856 }
857
820 /** 858 /**
821 * Build the HTML element for the given source. 859 * Build the HTML element for the given source.
822 * @param source the source describing the compilation unit 860 * @param source the source describing the compilation unit
823 * @return the HTML element that was built 861 * @return the HTML element that was built
824 * @throws AnalysisException if the analysis could not be performed 862 * @throws AnalysisException if the analysis could not be performed
825 */ 863 */
826 HtmlElementImpl buildHtmlElement(Source source) => buildHtmlElement2(source, _ context.parseHtmlUnit(source)); 864 HtmlElementImpl buildHtmlElement(Source source) => buildHtmlElement2(source, _ context.parseHtmlUnit(source));
865
827 /** 866 /**
828 * Build the HTML element for the given source. 867 * Build the HTML element for the given source.
829 * @param source the source describing the compilation unit 868 * @param source the source describing the compilation unit
830 * @param unit the AST structure representing the HTML 869 * @param unit the AST structure representing the HTML
831 * @throws AnalysisException if the analysis could not be performed 870 * @throws AnalysisException if the analysis could not be performed
832 */ 871 */
833 HtmlElementImpl buildHtmlElement2(Source source2, ht.HtmlUnit unit) { 872 HtmlElementImpl buildHtmlElement2(Source source2, ht.HtmlUnit unit) {
834 _lineInfo = _context.computeLineInfo(source2); 873 _lineInfo = _context.computeLineInfo(source2);
835 HtmlElementImpl result = new HtmlElementImpl(_context, source2.shortName); 874 HtmlElementImpl result = new HtmlElementImpl(_context, source2.shortName);
836 result.source = source2; 875 result.source = source2;
837 _htmlElement = result; 876 _htmlElement = result;
838 unit.accept(this); 877 unit.accept(this);
839 _htmlElement = null; 878 _htmlElement = null;
840 unit.element = result; 879 unit.element = result;
841 return result; 880 return result;
842 } 881 }
882
883 /**
884 * Return the listener to which analysis errors will be reported.
885 * @return the listener to which analysis errors will be reported
886 */
887 RecordingErrorListener get errorListener => _errorListener;
888
889 /**
890 * Return an array containing information about all of the libraries that were resolved.
891 * @return an array containing the libraries that were resolved
892 */
893 Set<Library> get resolvedLibraries => _resolvedLibraries;
843 Object visitHtmlUnit(ht.HtmlUnit node) { 894 Object visitHtmlUnit(ht.HtmlUnit node) {
895 _parentNodes = new List<ht.XmlTagNode>();
844 _scripts = new List<HtmlScriptElement>(); 896 _scripts = new List<HtmlScriptElement>();
845 node.visitChildren(this); 897 try {
846 _htmlElement.scripts = new List.from(_scripts); 898 node.visitChildren(this);
847 _scripts = null; 899 _htmlElement.scripts = new List.from(_scripts);
900 } finally {
901 _scripts = null;
902 _parentNodes = null;
903 }
848 return null; 904 return null;
849 } 905 }
850 Object visitXmlAttributeNode(ht.XmlAttributeNode node) => null; 906 Object visitXmlAttributeNode(ht.XmlAttributeNode node) => null;
851 Object visitXmlTagNode(ht.XmlTagNode node) { 907 Object visitXmlTagNode(ht.XmlTagNode node) {
852 if (isScriptNode(node)) { 908 if (_parentNodes.contains(node)) {
853 Source htmlSource = _htmlElement.source; 909 JavaStringBuilder builder = new JavaStringBuilder();
854 ht.XmlAttributeNode scriptAttribute = getScriptSourcePath(node); 910 builder.append("Found circularity in XML nodes: ");
855 String scriptSourcePath = scriptAttribute == null ? null : scriptAttribute .text; 911 bool first = true;
856 if (identical(node.attributeEnd.type, ht.TokenType.GT) && scriptSourcePath == null) { 912 for (ht.XmlTagNode pathNode in _parentNodes) {
857 EmbeddedHtmlScriptElementImpl script = new EmbeddedHtmlScriptElementImpl (node); 913 if (first) {
858 String contents = node.content; 914 first = false;
859 int attributeEnd2 = node.attributeEnd.end; 915 } else {
860 LineInfo_Location location = _lineInfo.getLocation(attributeEnd2); 916 builder.append(", ");
861 sc.StringScanner scanner = new sc.StringScanner(htmlSource, contents, _e rrorListener);
862 scanner.setSourceStart(location.lineNumber, location.columnNumber, attri buteEnd2);
863 sc.Token firstToken = scanner.tokenize();
864 List<int> lineStarts2 = scanner.lineStarts;
865 Parser parser = new Parser(null, _errorListener);
866 CompilationUnit unit = parser.parseCompilationUnit(firstToken);
867 unit.lineInfo = new LineInfo(lineStarts2);
868 try {
869 CompilationUnitBuilder builder = new CompilationUnitBuilder();
870 CompilationUnitElementImpl elem = builder.buildCompilationUnit(htmlSou rce, unit);
871 LibraryElementImpl library = new LibraryElementImpl(_context, null);
872 library.definingCompilationUnit = elem;
873 script.scriptLibrary = library;
874 } on AnalysisException catch (exception) {
875 print(exception);
876 } 917 }
877 _scripts.add(script); 918 String tagName = pathNode.tag.lexeme;
919 if (identical(pathNode, node)) {
920 builder.append("*");
921 builder.append(tagName);
922 builder.append("*");
923 } else {
924 builder.append(tagName);
925 }
926 }
927 AnalysisEngine.instance.logger.logError(builder.toString());
928 return null;
929 }
930 _parentNodes.add(node);
931 try {
932 if (isScriptNode(node)) {
933 Source htmlSource = _htmlElement.source;
934 ht.XmlAttributeNode scriptAttribute = getScriptSourcePath(node);
935 String scriptSourcePath = scriptAttribute == null ? null : scriptAttribu te.text;
936 if (identical(node.attributeEnd.type, ht.TokenType.GT) && scriptSourcePa th == null) {
937 EmbeddedHtmlScriptElementImpl script = new EmbeddedHtmlScriptElementIm pl(node);
938 String contents = node.content;
939 int attributeEnd2 = node.attributeEnd.end;
940 LineInfo_Location location = _lineInfo.getLocation(attributeEnd2);
941 sc.StringScanner scanner = new sc.StringScanner(htmlSource, contents, _errorListener);
942 scanner.setSourceStart(location.lineNumber, location.columnNumber, att ributeEnd2);
943 sc.Token firstToken = scanner.tokenize();
944 List<int> lineStarts2 = scanner.lineStarts;
945 Parser parser = new Parser(htmlSource, _errorListener);
946 CompilationUnit unit = parser.parseCompilationUnit(firstToken);
947 unit.lineInfo = new LineInfo(lineStarts2);
948 try {
949 LibraryResolver resolver = new LibraryResolver(_context);
950 LibraryElementImpl library = resolver.resolveEmbeddedLibrary(htmlSou rce, unit, true) as LibraryElementImpl;
951 script.scriptLibrary = library;
952 _resolvedLibraries.addAll(resolver.resolvedLibraries);
953 _errorListener.addAll(resolver.errorListener);
954 } on AnalysisException catch (exception) {
955 AnalysisEngine.instance.logger.logError3(exception);
956 }
957 _scripts.add(script);
958 } else {
959 ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementIm pl(node);
960 if (scriptSourcePath != null) {
961 try {
962 parseUriWithException(scriptSourcePath);
963 Source scriptSource = _context.sourceFactory.resolveUri(htmlSource , scriptSourcePath);
964 script.scriptSource = scriptSource;
965 if (!scriptSource.exists()) {
966 reportError(HtmlWarningCode.URI_DOES_NOT_EXIST, scriptAttribute. offset + 1, scriptSourcePath.length, [scriptSourcePath]);
967 }
968 } on URISyntaxException catch (exception) {
969 reportError(HtmlWarningCode.INVALID_URI, scriptAttribute.offset + 1, scriptSourcePath.length, [scriptSourcePath]);
970 }
971 }
972 _scripts.add(script);
973 }
878 } else { 974 } else {
879 ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl (node); 975 node.visitChildren(this);
880 if (scriptSourcePath != null) {
881 try {
882 Uri.parse(scriptSourcePath);
883 Source scriptSource = _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath);
884 script.scriptSource = scriptSource;
885 if (!scriptSource.exists()) {
886 reportError(HtmlWarningCode.URI_DOES_NOT_EXIST, scriptAttribute.of fset + 1, scriptSourcePath.length, []);
887 }
888 } on URISyntaxException catch (exception) {
889 reportError(HtmlWarningCode.INVALID_URI, scriptAttribute.offset + 1, scriptSourcePath.length, []);
890 }
891 }
892 _scripts.add(script);
893 } 976 }
894 } else { 977 } finally {
895 node.visitChildren(this); 978 _parentNodes.remove(node);
896 } 979 }
897 return null; 980 return null;
898 } 981 }
982
899 /** 983 /**
900 * Return the first source attribute for the given tag node, or {@code null} i f it does not exist. 984 * Return the first source attribute for the given tag node, or {@code null} i f it does not exist.
901 * @param node the node containing attributes 985 * @param node the node containing attributes
902 * @return the source attribute contained in the given tag 986 * @return the source attribute contained in the given tag
903 */ 987 */
904 ht.XmlAttributeNode getScriptSourcePath(ht.XmlTagNode node) { 988 ht.XmlAttributeNode getScriptSourcePath(ht.XmlTagNode node) {
905 for (ht.XmlAttributeNode attribute in node.attributes) { 989 for (ht.XmlAttributeNode attribute in node.attributes) {
906 if (attribute.name.lexeme == _SRC) { 990 if (attribute.name.lexeme == _SRC) {
907 return attribute; 991 return attribute;
908 } 992 }
909 } 993 }
910 return null; 994 return null;
911 } 995 }
996
912 /** 997 /**
913 * Determine if the specified node is a Dart script. 998 * Determine if the specified node is a Dart script.
914 * @param node the node to be tested (not {@code null}) 999 * @param node the node to be tested (not {@code null})
915 * @return {@code true} if the node is a Dart script 1000 * @return {@code true} if the node is a Dart script
916 */ 1001 */
917 bool isScriptNode(ht.XmlTagNode node) { 1002 bool isScriptNode(ht.XmlTagNode node) {
918 if (node.tagNodes.length != 0 || node.tag.lexeme != _SCRIPT) { 1003 if (node.tagNodes.length != 0 || node.tag.lexeme != _SCRIPT) {
919 return false; 1004 return false;
920 } 1005 }
921 for (ht.XmlAttributeNode attribute in node.attributes) { 1006 for (ht.XmlAttributeNode attribute in node.attributes) {
922 if (attribute.name.lexeme == _TYPE) { 1007 if (attribute.name.lexeme == _TYPE) {
923 ht.Token valueToken = attribute.value; 1008 ht.Token valueToken = attribute.value;
924 if (valueToken != null) { 1009 if (valueToken != null) {
925 String value = valueToken.lexeme; 1010 String value = valueToken.lexeme;
926 if (value == _APPLICATION_DART_IN_DOUBLE_QUOTES || value == _APPLICATI ON_DART_IN_SINGLE_QUOTES) { 1011 if (value == _APPLICATION_DART_IN_DOUBLE_QUOTES || value == _APPLICATI ON_DART_IN_SINGLE_QUOTES) {
927 return true; 1012 return true;
928 } 1013 }
929 } 1014 }
930 } 1015 }
931 } 1016 }
932 return false; 1017 return false;
933 } 1018 }
1019
934 /** 1020 /**
935 * Report an error with the given error code at the given location. Use the gi ven arguments to 1021 * Report an error with the given error code at the given location. Use the gi ven arguments to
936 * compose the error message. 1022 * compose the error message.
937 * @param errorCode the error code of the error to be reported 1023 * @param errorCode the error code of the error to be reported
938 * @param offset the offset of the first character to be highlighted 1024 * @param offset the offset of the first character to be highlighted
939 * @param length the number of characters to be highlighted 1025 * @param length the number of characters to be highlighted
940 * @param arguments the arguments used to compose the error message 1026 * @param arguments the arguments used to compose the error message
941 */ 1027 */
942 void reportError(ErrorCode errorCode, int offset, int length, List<Object> arg uments) { 1028 void reportError(ErrorCode errorCode, int offset, int length, List<Object> arg uments) {
943 _errorListener.onError(new AnalysisError.con2(_htmlElement.source, offset, l ength, errorCode, arguments)); 1029 _errorListener.onError(new AnalysisError.con2(_htmlElement.source, offset, l ength, errorCode, arguments));
944 } 1030 }
945 } 1031 }
1032
946 /** 1033 /**
947 * Instances of the class {@code DeclarationResolver} are used to resolve declar ations in an AST 1034 * Instances of the class {@code DeclarationResolver} are used to resolve declar ations in an AST
948 * structure to already built elements. 1035 * structure to already built elements.
949 */ 1036 */
950 class DeclarationResolver extends RecursiveASTVisitor<Object> { 1037 class DeclarationResolver extends RecursiveASTVisitor<Object> {
1038
951 /** 1039 /**
952 * The compilation unit containing the AST nodes being visited. 1040 * The compilation unit containing the AST nodes being visited.
953 */ 1041 */
954 CompilationUnitElement _enclosingUnit; 1042 CompilationUnitElement _enclosingUnit;
1043
955 /** 1044 /**
956 * The function type alias containing the AST nodes being visited, or {@code n ull} if we are not 1045 * The function type alias containing the AST nodes being visited, or {@code n ull} if we are not
957 * in the scope of a function type alias. 1046 * in the scope of a function type alias.
958 */ 1047 */
959 FunctionTypeAliasElement _enclosingAlias; 1048 FunctionTypeAliasElement _enclosingAlias;
1049
960 /** 1050 /**
961 * The class containing the AST nodes being visited, or {@code null} if we are not in the scope of 1051 * The class containing the AST nodes being visited, or {@code null} if we are not in the scope of
962 * a class. 1052 * a class.
963 */ 1053 */
964 ClassElement _enclosingClass; 1054 ClassElement _enclosingClass;
1055
965 /** 1056 /**
966 * The method or function containing the AST nodes being visited, or {@code nu ll} if we are not in 1057 * The method or function containing the AST nodes being visited, or {@code nu ll} if we are not in
967 * the scope of a method or function. 1058 * the scope of a method or function.
968 */ 1059 */
969 ExecutableElement _enclosingExecutable; 1060 ExecutableElement _enclosingExecutable;
1061
970 /** 1062 /**
971 * The parameter containing the AST nodes being visited, or {@code null} if we are not in the 1063 * The parameter containing the AST nodes being visited, or {@code null} if we are not in the
972 * scope of a parameter. 1064 * scope of a parameter.
973 */ 1065 */
974 ParameterElement _enclosingParameter; 1066 ParameterElement _enclosingParameter;
975 /** 1067
976 * Initialize a newly created resolver.
977 */
978 DeclarationResolver() : super() {
979 }
980 /** 1068 /**
981 * Resolve the declarations within the given compilation unit to the elements rooted at the given 1069 * Resolve the declarations within the given compilation unit to the elements rooted at the given
982 * element. 1070 * element.
983 * @param unit the compilation unit to be resolved 1071 * @param unit the compilation unit to be resolved
984 * @param element the root of the element model used to resolve the AST nodes 1072 * @param element the root of the element model used to resolve the AST nodes
985 */ 1073 */
986 void resolve(CompilationUnit unit, CompilationUnitElement element2) { 1074 void resolve(CompilationUnit unit, CompilationUnitElement element2) {
987 _enclosingUnit = element2; 1075 _enclosingUnit = element2;
988 unit.element = element2; 1076 unit.element = element2;
989 unit.accept(this); 1077 unit.accept(this);
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1290 } else { 1378 } else {
1291 _enclosingExecutable = element.initializer; 1379 _enclosingExecutable = element.initializer;
1292 } 1380 }
1293 return super.visitVariableDeclaration(node); 1381 return super.visitVariableDeclaration(node);
1294 } finally { 1382 } finally {
1295 _enclosingExecutable = outerExecutable; 1383 _enclosingExecutable = outerExecutable;
1296 } 1384 }
1297 } 1385 }
1298 return super.visitVariableDeclaration(node); 1386 return super.visitVariableDeclaration(node);
1299 } 1387 }
1388
1300 /** 1389 /**
1301 * Append the value of the given string literal to the given string builder. 1390 * Append the value of the given string literal to the given string builder.
1302 * @param builder the builder to which the string's value is to be appended 1391 * @param builder the builder to which the string's value is to be appended
1303 * @param literal the string literal whose value is to be appended to the buil der 1392 * @param literal the string literal whose value is to be appended to the buil der
1304 * @throws IllegalArgumentException if the string is not a constant string wit hout any string 1393 * @throws IllegalArgumentException if the string is not a constant string wit hout any string
1305 * interpolation 1394 * interpolation
1306 */ 1395 */
1307 void appendStringValue(JavaStringBuilder builder, StringLiteral literal) { 1396 void appendStringValue(JavaStringBuilder builder, StringLiteral literal) {
1308 if (literal is SimpleStringLiteral) { 1397 if (literal is SimpleStringLiteral) {
1309 builder.append(((literal as SimpleStringLiteral)).value); 1398 builder.append(((literal as SimpleStringLiteral)).value);
1310 } else if (literal is AdjacentStrings) { 1399 } else if (literal is AdjacentStrings) {
1311 for (StringLiteral stringLiteral in ((literal as AdjacentStrings)).strings ) { 1400 for (StringLiteral stringLiteral in ((literal as AdjacentStrings)).strings ) {
1312 appendStringValue(builder, stringLiteral); 1401 appendStringValue(builder, stringLiteral);
1313 } 1402 }
1314 } else { 1403 } else {
1315 throw new IllegalArgumentException(); 1404 throw new IllegalArgumentException();
1316 } 1405 }
1317 } 1406 }
1407
1318 /** 1408 /**
1319 * Return the element for the part with the given source, or {@code null} if t here is no element 1409 * Return the element for the part with the given source, or {@code null} if t here is no element
1320 * for the given source. 1410 * for the given source.
1321 * @param parts the elements for the parts 1411 * @param parts the elements for the parts
1322 * @param partSource the source for the part whose element is to be returned 1412 * @param partSource the source for the part whose element is to be returned
1323 * @return the element for the part with the given source 1413 * @return the element for the part with the given source
1324 */ 1414 */
1325 CompilationUnitElement find(List<CompilationUnitElement> parts, Source partSou rce) { 1415 CompilationUnitElement find(List<CompilationUnitElement> parts, Source partSou rce) {
1326 for (CompilationUnitElement part in parts) { 1416 for (CompilationUnitElement part in parts) {
1327 if (part.source == partSource) { 1417 if (part.source == partSource) {
1328 return part; 1418 return part;
1329 } 1419 }
1330 } 1420 }
1331 return null; 1421 return null;
1332 } 1422 }
1423
1333 /** 1424 /**
1334 * Return the element in the given array of elements that was created for the declaration at the 1425 * Return the element in the given array of elements that was created for the declaration at the
1335 * given offset. This method should only be used when there is no name 1426 * given offset. This method should only be used when there is no name
1336 * @param elements the elements of the appropriate kind that exist in the curr ent context 1427 * @param elements the elements of the appropriate kind that exist in the curr ent context
1337 * @param offset the offset of the name of the element to be returned 1428 * @param offset the offset of the name of the element to be returned
1338 * @return the element at the given offset 1429 * @return the element at the given offset
1339 */ 1430 */
1340 Element find2(List<Element> elements, int offset) => find4(elements, "", offse t); 1431 Element find2(List<Element> elements, int offset) => find4(elements, "", offse t);
1432
1341 /** 1433 /**
1342 * Return the element in the given array of elements that was created for the declaration with the 1434 * Return the element in the given array of elements that was created for the declaration with the
1343 * given name. 1435 * given name.
1344 * @param elements the elements of the appropriate kind that exist in the curr ent context 1436 * @param elements the elements of the appropriate kind that exist in the curr ent context
1345 * @param identifier the name node in the declaration of the element to be ret urned 1437 * @param identifier the name node in the declaration of the element to be ret urned
1346 * @return the element created for the declaration with the given name 1438 * @return the element created for the declaration with the given name
1347 */ 1439 */
1348 Element find3(List<Element> elements, SimpleIdentifier identifier) { 1440 Element find3(List<Element> elements, SimpleIdentifier identifier) {
1349 Element element = find4(elements, identifier.name, identifier.offset); 1441 Element element = find4(elements, identifier.name, identifier.offset);
1350 identifier.element = element; 1442 identifier.element = element;
1351 return element; 1443 return element;
1352 } 1444 }
1445
1353 /** 1446 /**
1354 * Return the element in the given array of elements that was created for the declaration with the 1447 * Return the element in the given array of elements that was created for the declaration with the
1355 * given name at the given offset. 1448 * given name at the given offset.
1356 * @param elements the elements of the appropriate kind that exist in the curr ent context 1449 * @param elements the elements of the appropriate kind that exist in the curr ent context
1357 * @param name the name of the element to be returned 1450 * @param name the name of the element to be returned
1358 * @param offset the offset of the name of the element to be returned 1451 * @param offset the offset of the name of the element to be returned
1359 * @return the element with the given name and offset 1452 * @return the element with the given name and offset
1360 */ 1453 */
1361 Element find4(List<Element> elements, String name2, int offset) { 1454 Element find4(List<Element> elements, String name, int offset) {
1362 for (Element element in elements) { 1455 for (Element element in elements) {
1363 if (element.name == name2 && element.nameOffset == offset) { 1456 if (element.displayName == name && element.nameOffset == offset) {
1364 return element; 1457 return element;
1365 } 1458 }
1366 } 1459 }
1367 return null; 1460 return null;
1368 } 1461 }
1462
1369 /** 1463 /**
1370 * Return the export element from the given array whose library has the given source, or{@code null} if there is no such export. 1464 * Return the export element from the given array whose library has the given source, or{@code null} if there is no such export.
1371 * @param exports the export elements being searched 1465 * @param exports the export elements being searched
1372 * @param source the source of the library associated with the export element to being searched 1466 * @param source the source of the library associated with the export element to being searched
1373 * for 1467 * for
1374 * @return the export element whose library has the given source 1468 * @return the export element whose library has the given source
1375 */ 1469 */
1376 ExportElement find5(List<ExportElement> exports, Source source2) { 1470 ExportElement find5(List<ExportElement> exports, Source source2) {
1377 for (ExportElement export in exports) { 1471 for (ExportElement export in exports) {
1378 if (export.exportedLibrary.source == source2) { 1472 if (export.exportedLibrary.source == source2) {
1379 return export; 1473 return export;
1380 } 1474 }
1381 } 1475 }
1382 return null; 1476 return null;
1383 } 1477 }
1478
1384 /** 1479 /**
1385 * Return the import element from the given array whose library has the given source and that has 1480 * Return the import element from the given array whose library has the given source and that has
1386 * the given prefix, or {@code null} if there is no such import. 1481 * the given prefix, or {@code null} if there is no such import.
1387 * @param imports the import elements being searched 1482 * @param imports the import elements being searched
1388 * @param source the source of the library associated with the import element to being searched 1483 * @param source the source of the library associated with the import element to being searched
1389 * for 1484 * for
1390 * @param prefix the prefix with which the library was imported 1485 * @param prefix the prefix with which the library was imported
1391 * @return the import element whose library has the given source and prefix 1486 * @return the import element whose library has the given source and prefix
1392 */ 1487 */
1393 ImportElement find6(List<ImportElement> imports, Source source2, SimpleIdentif ier prefix2) { 1488 ImportElement find6(List<ImportElement> imports, Source source2, SimpleIdentif ier prefix2) {
1394 for (ImportElement element in imports) { 1489 for (ImportElement element in imports) {
1395 if (element.importedLibrary.source == source2) { 1490 if (element.importedLibrary.source == source2) {
1396 PrefixElement prefixElement = element.prefix; 1491 PrefixElement prefixElement = element.prefix;
1397 if (prefix2 == null) { 1492 if (prefix2 == null) {
1398 if (prefixElement == null) { 1493 if (prefixElement == null) {
1399 return element; 1494 return element;
1400 } 1495 }
1401 } else { 1496 } else {
1402 if (prefixElement != null && prefix2.name == prefixElement.name) { 1497 if (prefixElement != null && prefix2.name == prefixElement.displayName ) {
1403 return element; 1498 return element;
1404 } 1499 }
1405 } 1500 }
1406 } 1501 }
1407 } 1502 }
1408 return null; 1503 return null;
1409 } 1504 }
1505
1410 /** 1506 /**
1411 * Return the value of the given string literal, or {@code null} if the string is not a constant 1507 * Return the value of the given string literal, or {@code null} if the string is not a constant
1412 * string without any string interpolation. 1508 * string without any string interpolation.
1413 * @param literal the string literal whose value is to be returned 1509 * @param literal the string literal whose value is to be returned
1414 * @return the value of the given string literal 1510 * @return the value of the given string literal
1415 */ 1511 */
1416 String getStringValue(StringLiteral literal) { 1512 String getStringValue(StringLiteral literal) {
1417 if (literal is StringInterpolation) { 1513 if (literal is StringInterpolation) {
1418 return null; 1514 return null;
1419 } 1515 }
1420 JavaStringBuilder builder = new JavaStringBuilder(); 1516 JavaStringBuilder builder = new JavaStringBuilder();
1421 try { 1517 try {
1422 appendStringValue(builder, literal); 1518 appendStringValue(builder, literal);
1423 } on IllegalArgumentException catch (exception) { 1519 } on IllegalArgumentException catch (exception) {
1424 return null; 1520 return null;
1425 } 1521 }
1426 return builder.toString().trim(); 1522 return builder.toString().trim();
1427 } 1523 }
1428 } 1524 }
1525
1429 /** 1526 /**
1430 * Instances of the class {@code ElementResolver} are used by instances of {@lin k ResolverVisitor}to resolve references within the AST structure to the elements being referenced. The requirements 1527 * Instances of the class {@code ElementResolver} are used by instances of {@lin k ResolverVisitor}to resolve references within the AST structure to the elements being referenced. The requirements
1431 * for the element resolver are: 1528 * for the element resolver are:
1432 * <ol> 1529 * <ol>
1433 * <li>Every {@link SimpleIdentifier} should be resolved to the element to which it refers. 1530 * <li>Every {@link SimpleIdentifier} should be resolved to the element to which it refers.
1434 * Specifically: 1531 * Specifically:
1435 * <ul> 1532 * <ul>
1436 * <li>An identifier within the declaration of that name should resolve to the e lement being 1533 * <li>An identifier within the declaration of that name should resolve to the e lement being
1437 * declared.</li> 1534 * declared.</li>
1438 * <li>An identifier denoting a prefix should resolve to the element representin g the import that 1535 * <li>An identifier denoting a prefix should resolve to the element representin g the import that
(...skipping 28 matching lines...) Expand all
1467 * <li>Every {@link PartDirective} should resolve to the element representing th e compilation unit 1564 * <li>Every {@link PartDirective} should resolve to the element representing th e compilation unit
1468 * being specified by the string unless the specified compilation unit does not exist (a{@link CompilationUnitElement}).</li> 1565 * being specified by the string unless the specified compilation unit does not exist (a{@link CompilationUnitElement}).</li>
1469 * </ol> 1566 * </ol>
1470 * Note that AST nodes that would represent elements that are not defined are no t resolved to 1567 * Note that AST nodes that would represent elements that are not defined are no t resolved to
1471 * anything. This includes such things as references to undeclared variables (wh ich is an error) and 1568 * anything. This includes such things as references to undeclared variables (wh ich is an error) and
1472 * names in hide and show combinators that are not defined in the imported libra ry (which is not an 1569 * names in hide and show combinators that are not defined in the imported libra ry (which is not an
1473 * error). 1570 * error).
1474 * @coverage dart.engine.resolver 1571 * @coverage dart.engine.resolver
1475 */ 1572 */
1476 class ElementResolver extends SimpleASTVisitor<Object> { 1573 class ElementResolver extends SimpleASTVisitor<Object> {
1574
1575 /**
1576 * @return {@code true} if the given identifier is the return type of a constr uctor declaration.
1577 */
1578 static bool isConstructorReturnType(SimpleIdentifier node) {
1579 ASTNode parent2 = node.parent;
1580 if (parent2 is ConstructorDeclaration) {
1581 ConstructorDeclaration constructor = parent2 as ConstructorDeclaration;
1582 return identical(constructor.returnType, node);
1583 }
1584 return false;
1585 }
1586
1587 /**
1588 * @return {@code true} if the given identifier is the return type of a factor y constructor
1589 * declaration.
1590 */
1591 static bool isFactoryConstructorReturnType(SimpleIdentifier node) {
1592 ASTNode parent2 = node.parent;
1593 if (parent2 is ConstructorDeclaration) {
1594 ConstructorDeclaration constructor = parent2 as ConstructorDeclaration;
1595 return identical(constructor.returnType, node) && constructor.factoryKeywo rd != null;
1596 }
1597 return false;
1598 }
1599
1600 /**
1601 * Checks if the given 'super' expression is used in the valid context.
1602 * @param node the 'super' expression to analyze
1603 * @return {@code true} if the given 'super' expression is in the valid contex t
1604 */
1605 static bool isSuperInValidContext(SuperExpression node) {
1606 for (ASTNode n = node; n != null; n = n.parent) {
1607 if (n is CompilationUnit) {
1608 return false;
1609 }
1610 if (n is ConstructorDeclaration) {
1611 ConstructorDeclaration constructor = n as ConstructorDeclaration;
1612 return constructor.factoryKeyword == null;
1613 }
1614 if (n is ConstructorFieldInitializer) {
1615 return false;
1616 }
1617 if (n is MethodDeclaration) {
1618 MethodDeclaration method = n as MethodDeclaration;
1619 return !method.isStatic();
1620 }
1621 }
1622 return false;
1623 }
1624
1477 /** 1625 /**
1478 * The resolver driving this participant. 1626 * The resolver driving this participant.
1479 */ 1627 */
1480 ResolverVisitor _resolver; 1628 ResolverVisitor _resolver;
1629
1630 /**
1631 * The name of the method that can be implemented by a class to allow its inst ances to be invoked
1632 * as if they were a function.
1633 */
1634 static String CALL_METHOD_NAME = "call";
1635
1636 /**
1637 * The name of the method that will be invoked if an attempt is made to invoke an undefined method
1638 * on an object.
1639 */
1640 static String _NO_SUCH_METHOD_METHOD_NAME = "noSuchMethod";
1641
1481 /** 1642 /**
1482 * Initialize a newly created visitor to resolve the nodes in a compilation un it. 1643 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
1483 * @param resolver the resolver driving this participant 1644 * @param resolver the resolver driving this participant
1484 */ 1645 */
1485 ElementResolver(ResolverVisitor resolver) { 1646 ElementResolver(ResolverVisitor resolver) {
1486 this._resolver = resolver; 1647 this._resolver = resolver;
1487 } 1648 }
1488 Object visitAssignmentExpression(AssignmentExpression node) { 1649 Object visitAssignmentExpression(AssignmentExpression node) {
1489 sc.TokenType operator2 = node.operator.type; 1650 sc.Token operator2 = node.operator;
1490 if (operator2 != sc.TokenType.EQ) { 1651 sc.TokenType operatorType = operator2.type;
1491 operator2 = operatorFromCompoundAssignment(operator2); 1652 if (operatorType != sc.TokenType.EQ) {
1492 Expression leftNode = node.leftHandSide; 1653 operatorType = operatorFromCompoundAssignment(operatorType);
1493 if (leftNode != null) { 1654 Expression leftHandSide2 = node.leftHandSide;
1494 Type2 leftType = getType(leftNode); 1655 if (leftHandSide2 != null) {
1495 if (leftType != null) { 1656 String methodName = operatorType.lexeme;
1496 MethodElement method = lookUpMethod(leftType, operator2.lexeme); 1657 Type2 staticType = getStaticType(leftHandSide2);
1497 if (method != null) { 1658 MethodElement staticMethod = lookUpMethod(leftHandSide2, staticType, met hodName);
1498 node.element = method; 1659 node.staticElement = staticMethod;
1499 } else { 1660 Type2 propagatedType = getPropagatedType(leftHandSide2);
1500 } 1661 MethodElement propagatedMethod = lookUpMethod(leftHandSide2, propagatedT ype, methodName);
1662 node.element = select3(staticMethod, propagatedMethod);
1663 if (shouldReportMissingMember(staticType, staticMethod) && (propagatedTy pe == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
1664 _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_METHOD, operato r2, [methodName, staticType.displayName]);
1501 } 1665 }
1502 } 1666 }
1503 } 1667 }
1504 return null; 1668 return null;
1505 } 1669 }
1506 Object visitBinaryExpression(BinaryExpression node) { 1670 Object visitBinaryExpression(BinaryExpression node) {
1507 sc.Token operator2 = node.operator; 1671 sc.Token operator2 = node.operator;
1508 if (operator2.isUserDefinableOperator()) { 1672 if (operator2.isUserDefinableOperator()) {
1509 Type2 leftType = getType(node.leftOperand); 1673 Expression leftOperand2 = node.leftOperand;
1510 if (leftType == null || leftType.isDynamic()) { 1674 if (leftOperand2 != null) {
1511 return null; 1675 String methodName = operator2.lexeme;
1512 } else if (leftType is FunctionType) { 1676 Type2 staticType = getStaticType(leftOperand2);
1513 leftType = _resolver.typeProvider.functionType; 1677 MethodElement staticMethod = lookUpMethod(leftOperand2, staticType, meth odName);
1514 } 1678 node.staticElement = staticMethod;
1515 String methodName = operator2.lexeme; 1679 Type2 propagatedType = getPropagatedType(leftOperand2);
1516 MethodElement member = lookUpMethod(leftType, methodName); 1680 MethodElement propagatedMethod = lookUpMethod(leftOperand2, propagatedTy pe, methodName);
1517 if (member == null) { 1681 node.element = select3(staticMethod, propagatedMethod);
1518 _resolver.reportError3(StaticWarningCode.UNDEFINED_OPERATOR, operator2, [methodName, leftType.name]); 1682 if (shouldReportMissingMember(staticType, staticMethod) && (propagatedTy pe == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
1519 } else { 1683 _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_OPERATOR, opera tor2, [methodName, staticType.displayName]);
1520 node.element = member; 1684 }
1521 } 1685 }
1522 } 1686 }
1523 return null; 1687 return null;
1524 } 1688 }
1525 Object visitBreakStatement(BreakStatement node) { 1689 Object visitBreakStatement(BreakStatement node) {
1526 SimpleIdentifier labelNode = node.label; 1690 SimpleIdentifier labelNode = node.label;
1527 LabelElementImpl labelElement = lookupLabel(node, labelNode); 1691 LabelElementImpl labelElement = lookupLabel(node, labelNode);
1528 if (labelElement != null && labelElement.isOnSwitchMember()) { 1692 if (labelElement != null && labelElement.isOnSwitchMember()) {
1529 _resolver.reportError(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labe lNode, []); 1693 _resolver.reportError(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labe lNode, []);
1530 } 1694 }
1531 return null; 1695 return null;
1532 } 1696 }
1697 Object visitClassDeclaration(ClassDeclaration node) {
1698 setMetadata(node.element, node);
1699 return null;
1700 }
1701 Object visitClassTypeAlias(ClassTypeAlias node) {
1702 setMetadata(node.element, node);
1703 return null;
1704 }
1533 Object visitCommentReference(CommentReference node) { 1705 Object visitCommentReference(CommentReference node) {
1534 Identifier identifier2 = node.identifier; 1706 Identifier identifier2 = node.identifier;
1535 if (identifier2 is SimpleIdentifier) { 1707 if (identifier2 is SimpleIdentifier) {
1536 SimpleIdentifier simpleIdentifier = identifier2 as SimpleIdentifier; 1708 SimpleIdentifier simpleIdentifier = identifier2 as SimpleIdentifier;
1537 visitSimpleIdentifier(simpleIdentifier); 1709 Element element = resolveSimpleIdentifier(simpleIdentifier);
1538 Element element2 = simpleIdentifier.element; 1710 if (element == null) {
1539 if (element2 != null) { 1711 element = findImportWithoutPrefix(simpleIdentifier);
1540 if (element2.library != _resolver.definingLibrary) { 1712 if (element is MultiplyDefinedElement) {
1713 element = null;
1541 } 1714 }
1715 }
1716 if (element == null) {
1717 } else {
1718 if (element.library != _resolver.definingLibrary) {
1719 }
1720 recordResolution(simpleIdentifier, element);
1542 if (node.newKeyword != null) { 1721 if (node.newKeyword != null) {
1543 if (element2 is ClassElement) { 1722 if (element is ClassElement) {
1544 ConstructorElement constructor = ((element2 as ClassElement)).unname dConstructor; 1723 ConstructorElement constructor = ((element as ClassElement)).unnamed Constructor;
1545 recordResolution(simpleIdentifier, constructor); 1724 if (constructor == null) {
1725 } else {
1726 recordResolution(simpleIdentifier, constructor);
1727 }
1546 } else { 1728 } else {
1547 } 1729 }
1548 } 1730 }
1549 } 1731 }
1550 } else if (identifier2 is PrefixedIdentifier) { 1732 } else if (identifier2 is PrefixedIdentifier) {
1551 PrefixedIdentifier prefixedIdentifier = identifier2 as PrefixedIdentifier; 1733 PrefixedIdentifier prefixedIdentifier = identifier2 as PrefixedIdentifier;
1552 SimpleIdentifier prefix2 = prefixedIdentifier.prefix; 1734 SimpleIdentifier prefix2 = prefixedIdentifier.prefix;
1553 SimpleIdentifier name = prefixedIdentifier.identifier; 1735 SimpleIdentifier name = prefixedIdentifier.identifier;
1554 visitSimpleIdentifier(prefix2); 1736 Element element = resolveSimpleIdentifier(prefix2);
1555 Element element3 = prefix2.element; 1737 if (element == null) {
1556 if (element3 != null) { 1738 } else {
1557 if (element3 is PrefixElement) { 1739 if (element is PrefixElement) {
1558 element3 = _resolver.nameScope.lookup(identifier2, _resolver.definingL ibrary); 1740 recordResolution(prefix2, element);
1559 recordResolution(name, element3); 1741 element = _resolver.nameScope.lookup(identifier2, _resolver.definingLi brary);
1742 recordResolution(name, element);
1560 return null; 1743 return null;
1561 } 1744 }
1562 if (element3.library != _resolver.definingLibrary) { 1745 LibraryElement library2 = element.library;
1746 if (library2 == null) {
1747 AnalysisEngine.instance.logger.logError("Found element with null libra ry: ${element.name}");
1748 } else if (library2 != _resolver.definingLibrary) {
1563 } 1749 }
1750 recordResolution(name, element);
1564 if (node.newKeyword == null) { 1751 if (node.newKeyword == null) {
1565 if (element3 is ClassElement) { 1752 if (element is ClassElement) {
1566 Element memberElement = lookupGetterOrMethod(((element3 as ClassElem ent)).type, name.name); 1753 Element memberElement = lookupGetterOrMethod(((element as ClassEleme nt)).type, name.name);
1567 if (memberElement == null) { 1754 if (memberElement == null) {
1568 memberElement = ((element3 as ClassElement)).getNamedConstructor(n ame.name); 1755 memberElement = ((element as ClassElement)).getNamedConstructor(na me.name);
1756 if (memberElement == null) {
1757 memberElement = lookUpSetter(prefix2, ((element as ClassElement) ).type, name.name);
1758 }
1569 } 1759 }
1570 if (memberElement == null) { 1760 if (memberElement == null) {
1571 reportGetterOrSetterNotFound(prefixedIdentifier, name, element3.na me);
1572 } else { 1761 } else {
1573 recordResolution(name, memberElement); 1762 recordResolution(name, memberElement);
1574 } 1763 }
1575 } else { 1764 } else {
1576 } 1765 }
1577 } else { 1766 } else {
1578 if (element3 is ClassElement) { 1767 if (element is ClassElement) {
1579 ConstructorElement constructor = ((element3 as ClassElement)).getNam edConstructor(name.name); 1768 ConstructorElement constructor = ((element as ClassElement)).getName dConstructor(name.name);
1580 if (constructor != null) { 1769 if (constructor == null) {
1770 } else {
1581 recordResolution(name, constructor); 1771 recordResolution(name, constructor);
1582 } 1772 }
1583 } else { 1773 } else {
1584 } 1774 }
1585 } 1775 }
1586 } 1776 }
1587 } 1777 }
1588 return null; 1778 return null;
1589 } 1779 }
1780 Object visitConstructorDeclaration(ConstructorDeclaration node) {
1781 super.visitConstructorDeclaration(node);
1782 ConstructorElement element2 = node.element;
1783 if (element2 is ConstructorElementImpl) {
1784 ConstructorElementImpl constructorElement = element2 as ConstructorElement Impl;
1785 ConstructorName redirectedNode = node.redirectedConstructor;
1786 if (redirectedNode != null) {
1787 ConstructorElement redirectedElement = redirectedNode.element;
1788 constructorElement.redirectedConstructor = redirectedElement;
1789 }
1790 for (ConstructorInitializer initializer in node.initializers) {
1791 if (initializer is RedirectingConstructorInvocation) {
1792 ConstructorElement redirectedElement = ((initializer as RedirectingCon structorInvocation)).element;
1793 constructorElement.redirectedConstructor = redirectedElement;
1794 }
1795 }
1796 setMetadata(constructorElement, node);
1797 }
1798 return null;
1799 }
1590 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { 1800 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
1591 FieldElement fieldElement = null;
1592 SimpleIdentifier fieldName2 = node.fieldName; 1801 SimpleIdentifier fieldName2 = node.fieldName;
1593 ClassElement enclosingClass2 = _resolver.enclosingClass; 1802 ClassElement enclosingClass2 = _resolver.enclosingClass;
1594 fieldElement = ((enclosingClass2 as ClassElementImpl)).getField(fieldName2.n ame); 1803 FieldElement fieldElement = ((enclosingClass2 as ClassElementImpl)).getField (fieldName2.name);
1595 if (fieldElement == null) { 1804 recordResolution(fieldName2, fieldElement);
1805 if (fieldElement == null || fieldElement.isSynthetic()) {
1596 _resolver.reportError(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FI ELD, node, [fieldName2]); 1806 _resolver.reportError(CompileTimeErrorCode.INITIALIZER_FOR_NON_EXISTANT_FI ELD, node, [fieldName2]);
1597 } else if (!fieldElement.isSynthetic()) { 1807 } else if (fieldElement.isStatic()) {
1598 recordResolution(fieldName2, fieldElement); 1808 _resolver.reportError(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, n ode, [fieldName2]);
1599 if (fieldElement.isStatic()) {
1600 _resolver.reportError(CompileTimeErrorCode.INITIALIZER_FOR_STATIC_FIELD, node, [fieldName2]);
1601 }
1602 } 1809 }
1603 return null; 1810 return null;
1604 } 1811 }
1605 Object visitConstructorName(ConstructorName node) { 1812 Object visitConstructorName(ConstructorName node) {
1606 Type2 type2 = node.type.type; 1813 Type2 type2 = node.type.type;
1607 if (type2 is DynamicTypeImpl) { 1814 if (type2 != null && type2.isDynamic()) {
1608 return null; 1815 return null;
1609 } else if (type2 is! InterfaceType) { 1816 } else if (type2 is! InterfaceType) {
1610 ASTNode parent2 = node.parent; 1817 ASTNode parent2 = node.parent;
1611 if (parent2 is InstanceCreationExpression) { 1818 if (parent2 is InstanceCreationExpression) {
1612 if (((parent2 as InstanceCreationExpression)).isConst()) { 1819 if (((parent2 as InstanceCreationExpression)).isConst()) {
1613 } else { 1820 } else {
1614 } 1821 }
1615 } else { 1822 } else {
1616 } 1823 }
1617 return null; 1824 return null;
1618 } 1825 }
1619 ClassElement classElement = ((type2 as InterfaceType)).element;
1620 ConstructorElement constructor; 1826 ConstructorElement constructor;
1621 SimpleIdentifier name2 = node.name; 1827 SimpleIdentifier name2 = node.name;
1828 InterfaceType interfaceType = type2 as InterfaceType;
1829 LibraryElement definingLibrary2 = _resolver.definingLibrary;
1622 if (name2 == null) { 1830 if (name2 == null) {
1623 constructor = classElement.unnamedConstructor; 1831 constructor = interfaceType.lookUpConstructor(null, definingLibrary2);
1624 } else { 1832 } else {
1625 constructor = classElement.getNamedConstructor(name2.name); 1833 constructor = interfaceType.lookUpConstructor(name2.name, definingLibrary2 );
1834 name2.staticElement = constructor;
1626 name2.element = constructor; 1835 name2.element = constructor;
1627 } 1836 }
1837 node.staticElement = constructor;
1628 node.element = constructor; 1838 node.element = constructor;
1629 return null; 1839 return null;
1630 } 1840 }
1631 Object visitContinueStatement(ContinueStatement node) { 1841 Object visitContinueStatement(ContinueStatement node) {
1632 SimpleIdentifier labelNode = node.label; 1842 SimpleIdentifier labelNode = node.label;
1633 LabelElementImpl labelElement = lookupLabel(node, labelNode); 1843 LabelElementImpl labelElement = lookupLabel(node, labelNode);
1634 if (labelElement != null && labelElement.isOnSwitchStatement()) { 1844 if (labelElement != null && labelElement.isOnSwitchStatement()) {
1635 _resolver.reportError(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNod e, []); 1845 _resolver.reportError(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNod e, []);
1636 } 1846 }
1637 return null; 1847 return null;
1638 } 1848 }
1849 Object visitDeclaredIdentifier(DeclaredIdentifier node) {
1850 setMetadata(node.element, node);
1851 return null;
1852 }
1639 Object visitExportDirective(ExportDirective node) { 1853 Object visitExportDirective(ExportDirective node) {
1640 Element element2 = node.element; 1854 Element element2 = node.element;
1641 if (element2 is ExportElement) { 1855 if (element2 is ExportElement) {
1642 resolveCombinators(((element2 as ExportElement)).exportedLibrary, node.com binators); 1856 resolveCombinators(((element2 as ExportElement)).exportedLibrary, node.com binators);
1857 setMetadata(element2, node);
1643 } 1858 }
1644 return null; 1859 return null;
1645 } 1860 }
1646 Object visitFieldFormalParameter(FieldFormalParameter node) { 1861 Object visitFieldFormalParameter(FieldFormalParameter node) {
1647 String fieldName = node.identifier.name; 1862 String fieldName = node.identifier.name;
1648 ClassElement classElement = _resolver.enclosingClass; 1863 ClassElement classElement = _resolver.enclosingClass;
1649 if (classElement != null) { 1864 if (classElement != null) {
1650 FieldElement fieldElement = ((classElement as ClassElementImpl)).getField( fieldName); 1865 FieldElement fieldElement = ((classElement as ClassElementImpl)).getField( fieldName);
1651 if (fieldElement != null) { 1866 if (fieldElement == null) {
1652 if (!fieldElement.isSynthetic()) { 1867 _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_E XISTANT_FIELD, node, [fieldName]);
1653 ParameterElement parameterElement = node.element; 1868 } else {
1654 if (parameterElement is FieldFormalParameterElementImpl) { 1869 ParameterElement parameterElement = node.element;
1655 FieldFormalParameterElementImpl fieldFormal = parameterElement as Fi eldFormalParameterElementImpl; 1870 if (parameterElement is FieldFormalParameterElementImpl) {
1656 fieldFormal.field = fieldElement; 1871 FieldFormalParameterElementImpl fieldFormal = parameterElement as Fiel dFormalParameterElementImpl;
1657 Type2 declaredType = fieldFormal.type; 1872 fieldFormal.field = fieldElement;
1658 Type2 fieldType = fieldElement.type; 1873 Type2 declaredType = fieldFormal.type;
1659 if (node.type == null) { 1874 Type2 fieldType = fieldElement.type;
1660 fieldFormal.type = fieldType; 1875 if (node.type == null) {
1661 } 1876 fieldFormal.type = fieldType;
1662 if (fieldElement.isStatic()) { 1877 }
1663 _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR _STATIC_FIELD, node, [fieldName]); 1878 if (fieldElement.isSynthetic()) {
1664 } else if (declaredType != null && fieldType != null && !declaredTyp e.isAssignableTo(fieldType)) { 1879 _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_N ON_EXISTANT_FIELD, node, [fieldName]);
1665 _resolver.reportError(StaticWarningCode.FIELD_INITIALIZER_WITH_INV ALID_TYPE, node, [declaredType.name, fieldType.name]); 1880 } else if (fieldElement.isStatic()) {
1666 } 1881 _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_S TATIC_FIELD, node, [fieldName]);
1882 } else if (declaredType != null && fieldType != null && !declaredType. isAssignableTo(fieldType)) {
1883 _resolver.reportError(StaticWarningCode.FIELD_INITIALIZING_FORMAL_NO T_ASSIGNABLE, node, [declaredType.displayName, fieldType.displayName]);
1884 }
1885 } else {
1886 if (fieldElement.isSynthetic()) {
1887 _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_N ON_EXISTANT_FIELD, node, [fieldName]);
1888 } else if (fieldElement.isStatic()) {
1889 _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_S TATIC_FIELD, node, [fieldName]);
1667 } 1890 }
1668 } 1891 }
1669 } else {
1670 _resolver.reportError(CompileTimeErrorCode.INITIALIZING_FORMAL_FOR_NON_E XISTANT_FIELD, node, [fieldName]);
1671 } 1892 }
1672 } 1893 }
1673 return super.visitFieldFormalParameter(node); 1894 return super.visitFieldFormalParameter(node);
1674 } 1895 }
1896 Object visitFunctionDeclaration(FunctionDeclaration node) {
1897 setMetadata(node.element, node);
1898 return null;
1899 }
1675 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => null; 1900 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => null;
1901 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
1902 setMetadata(node.element, node);
1903 return null;
1904 }
1676 Object visitImportDirective(ImportDirective node) { 1905 Object visitImportDirective(ImportDirective node) {
1677 SimpleIdentifier prefixNode = node.prefix; 1906 SimpleIdentifier prefixNode = node.prefix;
1678 if (prefixNode != null) { 1907 if (prefixNode != null) {
1679 String prefixName = prefixNode.name; 1908 String prefixName = prefixNode.name;
1680 for (PrefixElement prefixElement in _resolver.definingLibrary.prefixes) { 1909 for (PrefixElement prefixElement in _resolver.definingLibrary.prefixes) {
1681 if (prefixElement.name == prefixName) { 1910 if (prefixElement.displayName == prefixName) {
1682 recordResolution(prefixNode, prefixElement); 1911 recordResolution(prefixNode, prefixElement);
1683 break; 1912 break;
1684 } 1913 }
1685 } 1914 }
1686 } 1915 }
1687 Element element2 = node.element; 1916 Element element2 = node.element;
1688 if (element2 is ImportElement) { 1917 if (element2 is ImportElement) {
1689 resolveCombinators(((element2 as ImportElement)).importedLibrary, node.com binators); 1918 ImportElement importElement = element2 as ImportElement;
1919 LibraryElement library = importElement.importedLibrary;
1920 if (library != null) {
1921 resolveCombinators(library, node.combinators);
1922 }
1923 setMetadata(element2, node);
1690 } 1924 }
1691 return null; 1925 return null;
1692 } 1926 }
1693 Object visitIndexExpression(IndexExpression node) { 1927 Object visitIndexExpression(IndexExpression node) {
1694 Type2 arrayType = getType(node.realTarget); 1928 Expression target = node.realTarget;
1695 if (arrayType == null || arrayType.isDynamic()) { 1929 Type2 staticType = getStaticType(target);
1696 return null; 1930 Type2 propagatedType = getPropagatedType(target);
1931 if (node.inGetterContext()) {
1932 String methodName = sc.TokenType.INDEX.lexeme;
1933 bool error = lookUpCheckIndexOperator(node, target, methodName, staticType , propagatedType);
1934 if (error) {
1935 return null;
1936 }
1697 } 1937 }
1698 String operator;
1699 if (node.inSetterContext()) { 1938 if (node.inSetterContext()) {
1700 operator = sc.TokenType.INDEX_EQ.lexeme; 1939 String methodName = sc.TokenType.INDEX_EQ.lexeme;
1701 } else { 1940 lookUpCheckIndexOperator(node, target, methodName, staticType, propagatedT ype);
1702 operator = sc.TokenType.INDEX.lexeme;
1703 }
1704 MethodElement member = lookUpMethod(arrayType, operator);
1705 if (member == null) {
1706 _resolver.reportError(StaticWarningCode.UNDEFINED_OPERATOR, node, [operato r, arrayType.name]);
1707 } else {
1708 node.element = member;
1709 } 1941 }
1710 return null; 1942 return null;
1711 } 1943 }
1712 Object visitInstanceCreationExpression(InstanceCreationExpression node) { 1944 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
1713 ConstructorElement invokedConstructor = node.constructorName.element; 1945 ConstructorElement invokedConstructor = node.constructorName.element;
1946 node.staticElement = invokedConstructor;
1714 node.element = invokedConstructor; 1947 node.element = invokedConstructor;
1715 resolveNamedArguments(node.argumentList, invokedConstructor); 1948 resolveArgumentsToParameters(node.isConst(), node.argumentList, invokedConst ructor);
1949 return null;
1950 }
1951 Object visitLibraryDirective(LibraryDirective node) {
1952 setMetadata(node.element, node);
1953 return null;
1954 }
1955 Object visitMethodDeclaration(MethodDeclaration node) {
1956 setMetadata(node.element, node);
1716 return null; 1957 return null;
1717 } 1958 }
1718 Object visitMethodInvocation(MethodInvocation node) { 1959 Object visitMethodInvocation(MethodInvocation node) {
1719 SimpleIdentifier methodName2 = node.methodName; 1960 SimpleIdentifier methodName2 = node.methodName;
1720 Expression target = node.realTarget; 1961 Expression target = node.realTarget;
1721 Element element; 1962 Element staticElement;
1963 Element propagatedElement;
1964 if (target is SuperExpression && !isSuperInValidContext((target as SuperExpr ession))) {
1965 return null;
1966 }
1722 if (target == null) { 1967 if (target == null) {
1723 element = _resolver.nameScope.lookup(methodName2, _resolver.definingLibrar y); 1968 staticElement = resolveInvokedElement2(methodName2);
1724 if (element == null) { 1969 propagatedElement = null;
1725 ClassElement enclosingClass2 = _resolver.enclosingClass; 1970 } else {
1726 if (enclosingClass2 != null) { 1971 Type2 targetType = getStaticType(target);
1727 InterfaceType enclosingType = enclosingClass2.type; 1972 staticElement = resolveInvokedElement(target, targetType, methodName2);
1728 element = lookUpMethod(enclosingType, methodName2.name); 1973 propagatedElement = resolveInvokedElement(target, getPropagatedType(target ), methodName2);
1729 if (element == null) { 1974 }
1730 PropertyAccessorElement getter = lookUpGetter(enclosingType, methodN ame2.name); 1975 staticElement = convertSetterToGetter(staticElement);
1731 if (getter != null) { 1976 propagatedElement = convertSetterToGetter(propagatedElement);
1732 FunctionType getterType = getter.type; 1977 Element recordedElement = recordResolution2(methodName2, staticElement, prop agatedElement);
1733 if (getterType != null) { 1978 if (recordedElement is PropertyAccessorElement) {
1734 Type2 returnType2 = getterType.returnType; 1979 FunctionType getterType = ((recordedElement as PropertyAccessorElement)).t ype;
1735 if (!isExecutableType(returnType2)) { 1980 if (getterType != null) {
1736 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_ FUNCTION, methodName2, [methodName2.name]); 1981 Type2 getterReturnType = getterType.returnType;
1737 } 1982 if (getterReturnType is InterfaceType) {
1738 } 1983 MethodElement callMethod = ((getterReturnType as InterfaceType)).lookU pMethod(CALL_METHOD_NAME, _resolver.definingLibrary);
1739 recordResolution(methodName2, getter); 1984 if (callMethod != null) {
1740 return null; 1985 resolveArgumentsToParameters(false, node.argumentList, callMethod);
1741 } 1986 }
1987 } else if (getterReturnType is FunctionType) {
1988 Element functionElement = ((getterReturnType as FunctionType)).element ;
1989 if (functionElement is ExecutableElement) {
1990 resolveArgumentsToParameters(false, node.argumentList, (functionElem ent as ExecutableElement));
1742 } 1991 }
1743 } 1992 }
1744 } 1993 }
1745 } else { 1994 } else if (recordedElement is ExecutableElement) {
1746 Type2 targetType = getType(target); 1995 resolveArgumentsToParameters(false, node.argumentList, (recordedElement as ExecutableElement));
1747 if (targetType is InterfaceType) { 1996 } else if (recordedElement is VariableElement) {
1748 InterfaceType classType = targetType as InterfaceType; 1997 VariableElement variable = recordedElement as VariableElement;
1749 element = lookUpMethod(classType, methodName2.name); 1998 Type2 type2 = variable.type;
1750 if (element == null) { 1999 if (type2 is FunctionType) {
1751 PropertyAccessorElement accessor = classType.getGetter(methodName2.nam e); 2000 FunctionType functionType = type2 as FunctionType;
1752 if (accessor != null) { 2001 List<ParameterElement> parameters2 = functionType.parameters;
1753 Type2 returnType3 = accessor.type.returnType; 2002 resolveArgumentsToParameters2(false, node.argumentList, parameters2);
1754 if (!isExecutableType(returnType3)) { 2003 } else if (type2 is InterfaceType) {
1755 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNC TION, methodName2, [methodName2.name]); 2004 MethodElement callMethod = ((type2 as InterfaceType)).lookUpMethod(CALL_ METHOD_NAME, _resolver.definingLibrary);
1756 return null; 2005 if (callMethod != null) {
1757 } 2006 List<ParameterElement> parameters3 = callMethod.parameters;
1758 element = accessor; 2007 resolveArgumentsToParameters2(false, node.argumentList, parameters3);
1759 }
1760 } 2008 }
1761 if (element == null && target is SuperExpression) {
1762 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, me thodName2, [methodName2.name, targetType.element.name]);
1763 return null;
1764 }
1765 } else if (target is SimpleIdentifier) {
1766 Element targetElement = ((target as SimpleIdentifier)).element;
1767 if (targetElement is PrefixElement) {
1768 String name3 = "${((target as SimpleIdentifier)).name}.${methodName2}" ;
1769 Identifier functionName = new Identifier_8(name3);
1770 element = _resolver.nameScope.lookup(functionName, _resolver.definingL ibrary);
1771 } else {
1772 return null;
1773 }
1774 } else {
1775 return null;
1776 } 2009 }
1777 } 2010 }
1778 ExecutableElement invokedMethod = null; 2011 ErrorCode errorCode;
1779 if (element is PropertyAccessorElement) { 2012 if (staticElement == null) {
1780 PropertyAccessorElement getter = element as PropertyAccessorElement; 2013 if (propagatedElement == null) {
1781 FunctionType getterType = getter.type; 2014 errorCode = checkForInvocationError(target, staticElement);
1782 if (getterType != null) { 2015 } else {
1783 Type2 returnType4 = getterType.returnType; 2016 errorCode = checkForInvocationError(target, propagatedElement);
1784 if (!isExecutableType(returnType4)) {
1785 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION , methodName2, [methodName2.name]);
1786 }
1787 } 2017 }
1788 recordResolution(methodName2, element);
1789 return null;
1790 } else if (element is ExecutableElement) {
1791 invokedMethod = element as ExecutableElement;
1792 } else { 2018 } else {
1793 if (element is PropertyInducingElement) { 2019 errorCode = checkForInvocationError(target, staticElement);
1794 PropertyAccessorElement getter2 = ((element as PropertyInducingElement)) .getter; 2020 if (propagatedElement != null) {
1795 FunctionType getterType = getter2.type; 2021 ErrorCode propagatedError = checkForInvocationError(target, propagatedEl ement);
1796 if (getterType != null) { 2022 errorCode = select(errorCode, propagatedError);
1797 Type2 returnType5 = getterType.returnType;
1798 if (!isExecutableType(returnType5)) {
1799 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTI ON, methodName2, [methodName2.name]);
1800 }
1801 }
1802 recordResolution(methodName2, element);
1803 return null;
1804 } else if (element is VariableElement) {
1805 Type2 variableType = _resolver.overrideManager.getType(element);
1806 if (variableType == null) {
1807 variableType = ((element as VariableElement)).type;
1808 }
1809 if (!isExecutableType(variableType)) {
1810 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION , methodName2, [methodName2.name]);
1811 }
1812 recordResolution(methodName2, element);
1813 return null;
1814 } else {
1815 if (target == null) {
1816 ClassElement enclosingClass3 = _resolver.enclosingClass;
1817 if (enclosingClass3 == null) {
1818 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_FUNCTION, meth odName2, [methodName2.name]);
1819 } else if (element == null) {
1820 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_METHOD, method Name2, [methodName2.name, enclosingClass3.name]);
1821 } else {
1822 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTI ON, methodName2, [methodName2.name]);
1823 }
1824 } else {
1825 Type2 targetType = getType(target);
1826 String targetTypeName = targetType == null ? null : targetType.name;
1827 if (targetTypeName == null) {
1828 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_FUNCTION, meth odName2, [methodName2.name]);
1829 } else {
1830 if (!doesClassDeclareNoSuchMethod(targetType.element)) {
1831 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_METHOD, meth odName2, [methodName2.name, targetTypeName]);
1832 }
1833 }
1834 }
1835 return null;
1836 } 2023 }
1837 } 2024 }
1838 recordResolution(methodName2, invokedMethod); 2025 if (identical(errorCode, StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION)) {
1839 resolveNamedArguments(node.argumentList, invokedMethod); 2026 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, me thodName2, [methodName2.name]);
2027 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_FUNCTION)) {
2028 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_FUNCTION, methodName 2, [methodName2.name]);
2029 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_METHOD)) {
2030 String targetTypeName;
2031 if (target == null) {
2032 ClassElement enclosingClass2 = _resolver.enclosingClass;
2033 targetTypeName = enclosingClass2.displayName;
2034 } else {
2035 Type2 targetType = getPropagatedType(target);
2036 if (targetType == null) {
2037 targetType = getStaticType(target);
2038 }
2039 targetTypeName = targetType == null ? null : targetType.displayName;
2040 }
2041 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_METHOD, methodName2, [methodName2.name, targetTypeName]);
2042 } else if (identical(errorCode, StaticTypeWarningCode.UNDEFINED_SUPER_METHOD )) {
2043 Type2 targetType = getPropagatedType(target);
2044 if (targetType == null) {
2045 targetType = getStaticType(target);
2046 }
2047 String targetTypeName = targetType == null ? null : targetType.name;
2048 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, method Name2, [methodName2.name, targetTypeName]);
2049 }
2050 return null;
2051 }
2052 Object visitPartDirective(PartDirective node) {
2053 setMetadata(node.element, node);
2054 return null;
2055 }
2056 Object visitPartOfDirective(PartOfDirective node) {
2057 setMetadata(node.element, node);
1840 return null; 2058 return null;
1841 } 2059 }
1842 Object visitPostfixExpression(PostfixExpression node) { 2060 Object visitPostfixExpression(PostfixExpression node) {
1843 sc.Token operator2 = node.operator; 2061 Expression operand2 = node.operand;
1844 Type2 operandType = getType(node.operand); 2062 String methodName = getPostfixOperator(node);
1845 if (operandType == null || operandType.isDynamic()) { 2063 Type2 staticType = getStaticType(operand2);
1846 return null; 2064 MethodElement staticMethod = lookUpMethod(operand2, staticType, methodName);
1847 } 2065 node.staticElement = staticMethod;
1848 String methodName; 2066 Type2 propagatedType = getPropagatedType(operand2);
1849 if (identical(operator2.type, sc.TokenType.PLUS_PLUS)) { 2067 MethodElement propagatedMethod = lookUpMethod(operand2, propagatedType, meth odName);
1850 methodName = sc.TokenType.PLUS.lexeme; 2068 node.element = select3(staticMethod, propagatedMethod);
1851 } else { 2069 if (shouldReportMissingMember(staticType, staticMethod) && (propagatedType = = null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
1852 methodName = sc.TokenType.MINUS.lexeme; 2070 _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_OPERATOR, node.oper ator, [methodName, staticType.displayName]);
1853 }
1854 MethodElement member = lookUpMethod(operandType, methodName);
1855 if (member == null) {
1856 _resolver.reportError3(StaticWarningCode.UNDEFINED_OPERATOR, operator2, [m ethodName, operandType.name]);
1857 } else {
1858 node.element = member;
1859 } 2071 }
1860 return null; 2072 return null;
1861 } 2073 }
1862 Object visitPrefixedIdentifier(PrefixedIdentifier node) { 2074 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
1863 SimpleIdentifier prefix2 = node.prefix; 2075 SimpleIdentifier prefix2 = node.prefix;
1864 SimpleIdentifier identifier2 = node.identifier; 2076 SimpleIdentifier identifier2 = node.identifier;
1865 Element prefixElement = prefix2.element; 2077 Element prefixElement = prefix2.element;
1866 if (prefixElement is PrefixElement) { 2078 if (prefixElement is PrefixElement) {
1867 Element element = _resolver.nameScope.lookup(node, _resolver.definingLibra ry); 2079 Element element = _resolver.nameScope.lookup(node, _resolver.definingLibra ry);
1868 if (element == null) { 2080 if (element == null) {
1869 return null; 2081 return null;
1870 } 2082 }
2083 if (element is PropertyAccessorElement && identifier2.inSetterContext()) {
2084 PropertyInducingElement variable2 = ((element as PropertyAccessorElement )).variable;
2085 if (variable2 != null) {
2086 PropertyAccessorElement setter2 = variable2.setter;
2087 if (setter2 != null) {
2088 element = setter2;
2089 }
2090 }
2091 }
1871 recordResolution(identifier2, element); 2092 recordResolution(identifier2, element);
1872 return null; 2093 return null;
1873 } 2094 }
1874 if (prefixElement is ClassElement) { 2095 resolvePropertyAccess(prefix2, identifier2);
1875 Element memberElement;
1876 if (node.identifier.inSetterContext()) {
1877 memberElement = ((prefixElement as ClassElementImpl)).getSetter(identifi er2.name);
1878 } else {
1879 memberElement = ((prefixElement as ClassElementImpl)).getGetter(identifi er2.name);
1880 }
1881 if (memberElement == null) {
1882 MethodElement methodElement = lookUpMethod(((prefixElement as ClassEleme nt)).type, identifier2.name);
1883 if (methodElement != null) {
1884 recordResolution(identifier2, methodElement);
1885 return null;
1886 }
1887 }
1888 if (memberElement == null) {
1889 reportGetterOrSetterNotFound(node, identifier2, prefixElement.name);
1890 } else {
1891 recordResolution(identifier2, memberElement);
1892 }
1893 return null;
1894 }
1895 Type2 variableType;
1896 if (prefixElement is PropertyAccessorElement) {
1897 PropertyAccessorElement accessor = prefixElement as PropertyAccessorElemen t;
1898 FunctionType type2 = accessor.type;
1899 if (type2 == null) {
1900 return null;
1901 }
1902 if (accessor.isGetter()) {
1903 variableType = type2.returnType;
1904 } else {
1905 variableType = type2.normalParameterTypes[0];
1906 }
1907 if (variableType == null || variableType.isDynamic()) {
1908 return null;
1909 }
1910 } else if (prefixElement is VariableElement) {
1911 variableType = _resolver.overrideManager.getType(prefixElement);
1912 if (variableType == null) {
1913 variableType = ((prefixElement as VariableElement)).type;
1914 }
1915 if (variableType == null || variableType.isDynamic()) {
1916 return null;
1917 }
1918 } else {
1919 return null;
1920 }
1921 PropertyAccessorElement memberElement = null;
1922 if (node.identifier.inSetterContext()) {
1923 memberElement = lookUpSetter(variableType, identifier2.name);
1924 }
1925 if (memberElement == null && node.identifier.inGetterContext()) {
1926 memberElement = lookUpGetter(variableType, identifier2.name);
1927 }
1928 if (memberElement == null) {
1929 MethodElement methodElement = lookUpMethod(variableType, identifier2.name) ;
1930 if (methodElement != null) {
1931 recordResolution(identifier2, methodElement);
1932 return null;
1933 }
1934 }
1935 if (memberElement == null) {
1936 reportGetterOrSetterNotFound(node, identifier2, variableType.element.name) ;
1937 } else {
1938 recordResolution(identifier2, memberElement);
1939 }
1940 return null; 2096 return null;
1941 } 2097 }
1942 Object visitPrefixExpression(PrefixExpression node) { 2098 Object visitPrefixExpression(PrefixExpression node) {
1943 sc.Token operator2 = node.operator; 2099 sc.Token operator2 = node.operator;
1944 sc.TokenType operatorType = operator2.type; 2100 sc.TokenType operatorType = operator2.type;
1945 if (operatorType.isUserDefinableOperator() || identical(operatorType, sc.Tok enType.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) { 2101 if (operatorType.isUserDefinableOperator() || identical(operatorType, sc.Tok enType.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) {
1946 Type2 operandType = getType(node.operand); 2102 Expression operand2 = node.operand;
1947 if (operandType == null || operandType.isDynamic()) { 2103 String methodName = getPrefixOperator(node);
1948 return null; 2104 Type2 staticType = getStaticType(operand2);
1949 } 2105 MethodElement staticMethod = lookUpMethod(operand2, staticType, methodName );
1950 String methodName; 2106 node.staticElement = staticMethod;
1951 if (identical(operatorType, sc.TokenType.PLUS_PLUS)) { 2107 Type2 propagatedType = getPropagatedType(operand2);
1952 methodName = sc.TokenType.PLUS.lexeme; 2108 MethodElement propagatedMethod = lookUpMethod(operand2, propagatedType, me thodName);
1953 } else if (identical(operatorType, sc.TokenType.MINUS_MINUS)) { 2109 node.element = select3(staticMethod, propagatedMethod);
1954 methodName = sc.TokenType.MINUS.lexeme; 2110 if (shouldReportMissingMember(staticType, staticMethod) && (propagatedType == null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
1955 } else if (identical(operatorType, sc.TokenType.MINUS)) { 2111 _resolver.reportError6(StaticTypeWarningCode.UNDEFINED_OPERATOR, operato r2, [methodName, staticType.displayName]);
1956 methodName = "unary-";
1957 } else {
1958 methodName = operator2.lexeme;
1959 }
1960 MethodElement member = lookUpMethod(operandType, methodName);
1961 if (member == null) {
1962 _resolver.reportError3(StaticWarningCode.UNDEFINED_OPERATOR, operator2, [methodName, operandType.name]);
1963 } else {
1964 node.element = member;
1965 } 2112 }
1966 } 2113 }
1967 return null; 2114 return null;
1968 } 2115 }
1969 Object visitPropertyAccess(PropertyAccess node) { 2116 Object visitPropertyAccess(PropertyAccess node) {
1970 Type2 targetType = getType(node.realTarget); 2117 Expression target = node.realTarget;
1971 if (targetType is! InterfaceType) { 2118 if (target is SuperExpression && !isSuperInValidContext((target as SuperExpr ession))) {
1972 return null; 2119 return null;
1973 } 2120 }
1974 SimpleIdentifier identifier = node.propertyName; 2121 SimpleIdentifier propertyName2 = node.propertyName;
1975 PropertyAccessorElement memberElement = null; 2122 resolvePropertyAccess(target, propertyName2);
1976 if (identifier.inSetterContext()) {
1977 memberElement = lookUpSetter(targetType, identifier.name);
1978 }
1979 if (memberElement == null && identifier.inGetterContext()) {
1980 memberElement = lookUpGetter(targetType, identifier.name);
1981 }
1982 if (memberElement == null) {
1983 MethodElement methodElement = lookUpMethod(targetType, identifier.name);
1984 if (methodElement != null) {
1985 recordResolution(identifier, methodElement);
1986 return null;
1987 }
1988 }
1989 if (memberElement == null) {
1990 if (!doesClassDeclareNoSuchMethod(targetType.element)) {
1991 if (identifier.inSetterContext()) {
1992 _resolver.reportError(StaticWarningCode.UNDEFINED_SETTER, identifier, [identifier.name, targetType.name]);
1993 } else if (identifier.inGetterContext()) {
1994 _resolver.reportError(StaticWarningCode.UNDEFINED_GETTER, identifier, [identifier.name, targetType.name]);
1995 } else {
1996 print("two ${identifier.name}");
1997 _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, identifi er, [identifier.name]);
1998 }
1999 }
2000 } else {
2001 recordResolution(identifier, memberElement);
2002 }
2003 return null; 2123 return null;
2004 } 2124 }
2005 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) { 2125 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
2006 ClassElement enclosingClass2 = _resolver.enclosingClass; 2126 ClassElement enclosingClass2 = _resolver.enclosingClass;
2007 if (enclosingClass2 == null) { 2127 if (enclosingClass2 == null) {
2008 return null; 2128 return null;
2009 } 2129 }
2010 SimpleIdentifier name = node.constructorName; 2130 SimpleIdentifier name = node.constructorName;
2011 ConstructorElement element; 2131 ConstructorElement element;
2012 if (name == null) { 2132 if (name == null) {
2013 element = enclosingClass2.unnamedConstructor; 2133 element = enclosingClass2.unnamedConstructor;
2014 } else { 2134 } else {
2015 element = enclosingClass2.getNamedConstructor(name.name); 2135 element = enclosingClass2.getNamedConstructor(name.name);
2016 } 2136 }
2017 if (element == null) { 2137 if (element == null) {
2018 return null; 2138 return null;
2019 } 2139 }
2020 if (name != null) { 2140 if (name != null) {
2021 recordResolution(name, element); 2141 recordResolution(name, element);
2022 } 2142 }
2143 node.staticElement = element;
2023 node.element = element; 2144 node.element = element;
2024 resolveNamedArguments(node.argumentList, element); 2145 resolveArgumentsToParameters(false, node.argumentList, element);
2025 return null; 2146 return null;
2026 } 2147 }
2027 Object visitSimpleIdentifier(SimpleIdentifier node) { 2148 Object visitSimpleIdentifier(SimpleIdentifier node) {
2028 if (node.element != null) { 2149 if (node.element != null) {
2029 return null; 2150 return null;
2030 } 2151 }
2031 Element element = _resolver.nameScope.lookup(node, _resolver.definingLibrary ); 2152 Element element = resolveSimpleIdentifier(node);
2032 if (element is PropertyAccessorElement && node.inSetterContext()) { 2153 if (isFactoryConstructorReturnType(node) && element != _resolver.enclosingCl ass) {
2033 PropertyInducingElement variable2 = ((element as PropertyAccessorElement)) .variable; 2154 _resolver.reportError(CompileTimeErrorCode.INVALID_FACTORY_NAME_NOT_A_CLAS S, node, []);
2034 if (variable2 != null) { 2155 } else if (element == null) {
2035 PropertyAccessorElement setter2 = variable2.setter; 2156 if (isConstructorReturnType(node)) {
2036 if (setter2 != null) { 2157 _resolver.reportError(CompileTimeErrorCode.INVALID_CONSTRUCTOR_NAME, nod e, []);
2037 element = setter2; 2158 } else if (!classDeclaresNoSuchMethod(_resolver.enclosingClass)) {
2038 }
2039 }
2040 }
2041 ClassElement enclosingClass2 = _resolver.enclosingClass;
2042 if (element == null && enclosingClass2 != null) {
2043 InterfaceType enclosingType = enclosingClass2.type;
2044 if (element == null && node.inSetterContext()) {
2045 element = lookUpSetter(enclosingType, node.name);
2046 }
2047 if (element == null && node.inGetterContext()) {
2048 element = lookUpGetter(enclosingType, node.name);
2049 }
2050 if (element == null) {
2051 element = lookUpMethod(enclosingType, node.name);
2052 }
2053 }
2054 if (element == null) {
2055 if (!doesClassDeclareNoSuchMethod(enclosingClass2)) {
2056 _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, node, [nod e.name]); 2159 _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, node, [nod e.name]);
2057 } 2160 }
2058 } 2161 }
2059 recordResolution(node, element); 2162 recordResolution(node, element);
2060 return null; 2163 return null;
2061 } 2164 }
2062 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { 2165 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
2063 ClassElement enclosingClass2 = _resolver.enclosingClass; 2166 ClassElement enclosingClass2 = _resolver.enclosingClass;
2064 if (enclosingClass2 == null) { 2167 if (enclosingClass2 == null) {
2065 return null; 2168 return null;
2066 } 2169 }
2067 ClassElement superclass = getSuperclass(enclosingClass2); 2170 ClassElement superclass = getSuperclass(enclosingClass2);
2068 if (superclass == null) { 2171 if (superclass == null) {
2069 return null; 2172 return null;
2070 } 2173 }
2071 SimpleIdentifier name = node.constructorName; 2174 SimpleIdentifier name = node.constructorName;
2072 ConstructorElement element; 2175 ConstructorElement element;
2073 if (name == null) { 2176 if (name == null) {
2074 element = superclass.unnamedConstructor; 2177 element = superclass.unnamedConstructor;
2075 } else { 2178 } else {
2076 element = superclass.getNamedConstructor(name.name); 2179 element = superclass.getNamedConstructor(name.name);
2077 } 2180 }
2078 if (element == null) { 2181 if (element == null) {
2182 if (name != null) {
2183 _resolver.reportError(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INIT IALIZER, node, [superclass.name, name]);
2184 } else {
2185 _resolver.reportError(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_INIT IALIZER_DEFAULT, node, [superclass.name]);
2186 }
2079 return null; 2187 return null;
2188 } else {
2189 if (element.isFactory()) {
2190 _resolver.reportError(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUCTOR, n ode, [element]);
2191 }
2080 } 2192 }
2081 if (name != null) { 2193 if (name != null) {
2082 recordResolution(name, element); 2194 recordResolution(name, element);
2083 } 2195 }
2196 node.staticElement = element;
2084 node.element = element; 2197 node.element = element;
2085 resolveNamedArguments(node.argumentList, element); 2198 resolveArgumentsToParameters(false, node.argumentList, element);
2086 return null; 2199 return null;
2087 } 2200 }
2201 Object visitSuperExpression(SuperExpression node) {
2202 if (!isSuperInValidContext(node)) {
2203 _resolver.reportError(CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, node, []);
2204 }
2205 return super.visitSuperExpression(node);
2206 }
2088 Object visitTypeParameter(TypeParameter node) { 2207 Object visitTypeParameter(TypeParameter node) {
2089 TypeName bound2 = node.bound; 2208 TypeName bound2 = node.bound;
2090 if (bound2 != null) { 2209 if (bound2 != null) {
2091 TypeVariableElementImpl variable = node.name.element as TypeVariableElemen tImpl; 2210 TypeVariableElementImpl variable = node.name.element as TypeVariableElemen tImpl;
2092 if (variable != null) { 2211 if (variable != null) {
2093 variable.bound = bound2.type; 2212 variable.bound = bound2.type;
2094 } 2213 }
2095 } 2214 }
2215 setMetadata(node.element, node);
2096 return null; 2216 return null;
2097 } 2217 }
2098 /** 2218 Object visitVariableDeclaration(VariableDeclaration node) {
2099 * Return {@code true} if the passed {@link Element} is a {@link ClassElement} that declares a 2219 setMetadata(node.element, node);
2100 * method "noSuchMethod". 2220 return null;
2101 * @param element the {@link Element} to evaluate 2221 }
2102 * @return {@code true} if the passed {@link Element} is a {@link ClassElement } that declares a 2222
2103 * method "noSuchMethod" 2223 /**
2104 */ 2224 * Generate annotation elements for each of the annotations in the given node list and add them to
2105 bool doesClassDeclareNoSuchMethod(Element element) { 2225 * the given list of elements.
2106 if (element == null) { 2226 * @param annotationList the list of elements to which new elements are to be added
2227 * @param annotations the AST nodes used to generate new elements
2228 */
2229 void addAnnotations(List<AnnotationImpl> annotationList, NodeList<Annotation> annotations) {
2230 for (Annotation annotationNode in annotations) {
2231 Element resolvedElement = annotationNode.element;
2232 if (resolvedElement != null) {
2233 annotationList.add(new AnnotationImpl(resolvedElement));
2234 }
2235 }
2236 }
2237
2238 /**
2239 * Given that we have found code to invoke the given element, return the error code that should be
2240 * reported, or {@code null} if no error should be reported.
2241 * @param target the target of the invocation, or {@code null} if there was no target
2242 * @param element the element to be invoked
2243 * @return the error code that should be reported
2244 */
2245 ErrorCode checkForInvocationError(Expression target, Element element2) {
2246 if (element2 is PropertyAccessorElement) {
2247 FunctionType getterType = ((element2 as PropertyAccessorElement)).type;
2248 if (getterType != null) {
2249 Type2 returnType2 = getterType.returnType;
2250 if (!isExecutableType(returnType2)) {
2251 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
2252 }
2253 }
2254 } else if (element2 is ExecutableElement) {
2255 return null;
2256 } else if (element2 == null && target is SuperExpression) {
2257 return StaticTypeWarningCode.UNDEFINED_SUPER_METHOD;
2258 } else {
2259 if (element2 is PropertyInducingElement) {
2260 PropertyAccessorElement getter2 = ((element2 as PropertyInducingElement) ).getter;
2261 FunctionType getterType = getter2.type;
2262 if (getterType != null) {
2263 Type2 returnType3 = getterType.returnType;
2264 if (!isExecutableType(returnType3)) {
2265 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
2266 }
2267 }
2268 } else if (element2 is VariableElement) {
2269 Type2 variableType = _resolver.overrideManager.getType(element2);
2270 if (variableType == null) {
2271 variableType = ((element2 as VariableElement)).type;
2272 }
2273 if (!isExecutableType(variableType)) {
2274 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
2275 }
2276 } else {
2277 if (target == null) {
2278 ClassElement enclosingClass2 = _resolver.enclosingClass;
2279 if (enclosingClass2 == null) {
2280 return StaticTypeWarningCode.UNDEFINED_FUNCTION;
2281 } else if (element2 == null) {
2282 if (!classDeclaresNoSuchMethod(enclosingClass2)) {
2283 return StaticTypeWarningCode.UNDEFINED_METHOD;
2284 }
2285 } else {
2286 return StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION;
2287 }
2288 } else {
2289 Type2 targetType = getStaticType(target);
2290 if (targetType == null) {
2291 return StaticTypeWarningCode.UNDEFINED_FUNCTION;
2292 } else if (!targetType.isDynamic() && !classDeclaresNoSuchMethod2(targ etType.element)) {
2293 return StaticTypeWarningCode.UNDEFINED_METHOD;
2294 }
2295 }
2296 }
2297 }
2298 return null;
2299 }
2300
2301 /**
2302 * Return {@code true} if the given class declares a method named "noSuchMetho d" and is not the
2303 * class 'Object'.
2304 * @param element the class being tested
2305 * @return {@code true} if the given class declares a method named "noSuchMeth od"
2306 */
2307 bool classDeclaresNoSuchMethod(ClassElement classElement) {
2308 if (classElement == null) {
2107 return false; 2309 return false;
2108 } 2310 }
2109 if (element is! ClassElementImpl) { 2311 MethodElement methodElement = classElement.lookUpMethod(_NO_SUCH_METHOD_METH OD_NAME, _resolver.definingLibrary);
2110 return false; 2312 return methodElement != null && methodElement.enclosingElement.supertype != null;
2111 } 2313 }
2112 ClassElementImpl classElement = element as ClassElementImpl; 2314
2113 MethodElement method = classElement.lookUpMethod("noSuchMethod", _resolver.d efiningLibrary); 2315 /**
2114 if (method == null) { 2316 * Return {@code true} if the given element represents a class that declares a method named
2115 return false; 2317 * "noSuchMethod" and is not the class 'Object'.
2116 } 2318 * @param element the element being tested
2117 return true; 2319 * @return {@code true} if the given element represents a class that declares a method named
2118 } 2320 * "noSuchMethod"
2119 /** 2321 */
2120 * Search through the array of parameters for a parameter whose name matches t he given name. 2322 bool classDeclaresNoSuchMethod2(Element element) {
2121 * Return the parameter with the given name, or {@code null} if there is no su ch parameter. 2323 if (element is ClassElement) {
2122 * @param parameters the parameters being searched 2324 return classDeclaresNoSuchMethod((element as ClassElement));
2123 * @param name the name being searched for 2325 }
2124 * @return the parameter with the given name 2326 return false;
2125 */ 2327 }
2126 ParameterElement findNamedParameter(List<ParameterElement> parameters, String name2) { 2328
2127 for (ParameterElement parameter in parameters) { 2329 /**
2128 if (identical(parameter.parameterKind, ParameterKind.NAMED)) { 2330 * If the given element is a setter, return the getter associated with it. Oth erwise, return the
2129 String parameteName = parameter.name; 2331 * element unchanged.
2130 if (parameteName != null && parameteName == name2) { 2332 * @param element the element to be normalized
2131 return parameter; 2333 * @return a non-setter element derived from the given element
2132 } 2334 */
2133 } 2335 Element convertSetterToGetter(Element element) {
2134 } 2336 if (element is PropertyAccessorElement) {
2135 return null; 2337 return ((element as PropertyAccessorElement)).variable.getter;
2136 } 2338 }
2339 return element;
2340 }
2341
2342 /**
2343 * Look for any declarations of the given identifier that are imported using a prefix. Return the
2344 * element that was found, or {@code null} if the name is not imported using a prefix.
2345 * @param identifier the identifier that might have been imported using a pref ix
2346 * @return the element that was found
2347 */
2348 Element findImportWithoutPrefix(SimpleIdentifier identifier) {
2349 Element element = null;
2350 Scope nameScope2 = _resolver.nameScope;
2351 LibraryElement definingLibrary2 = _resolver.definingLibrary;
2352 for (ImportElement importElement in definingLibrary2.imports) {
2353 PrefixElement prefixElement = importElement.prefix;
2354 if (prefixElement != null) {
2355 Identifier prefixedIdentifier = new ElementResolver_SyntheticIdentifier( "${prefixElement.name}.${identifier.name}");
2356 Element importedElement = nameScope2.lookup(prefixedIdentifier, defining Library2);
2357 if (importedElement != null) {
2358 if (element == null) {
2359 element = importedElement;
2360 } else {
2361 element = new MultiplyDefinedElementImpl(definingLibrary2.context, e lement, importedElement);
2362 }
2363 }
2364 }
2365 }
2366 return element;
2367 }
2368
2369 /**
2370 * Return the name of the method invoked by the given postfix expression.
2371 * @param node the postfix expression being invoked
2372 * @return the name of the method invoked by the expression
2373 */
2374 String getPostfixOperator(PostfixExpression node) => (identical(node.operator. type, sc.TokenType.PLUS_PLUS)) ? sc.TokenType.PLUS.lexeme : sc.TokenType.MINUS.l exeme;
2375
2376 /**
2377 * Return the name of the method invoked by the given postfix expression.
2378 * @param node the postfix expression being invoked
2379 * @return the name of the method invoked by the expression
2380 */
2381 String getPrefixOperator(PrefixExpression node) {
2382 sc.Token operator2 = node.operator;
2383 sc.TokenType operatorType = operator2.type;
2384 if (identical(operatorType, sc.TokenType.PLUS_PLUS)) {
2385 return sc.TokenType.PLUS.lexeme;
2386 } else if (identical(operatorType, sc.TokenType.MINUS_MINUS)) {
2387 return sc.TokenType.MINUS.lexeme;
2388 } else if (identical(operatorType, sc.TokenType.MINUS)) {
2389 return "unary-";
2390 } else {
2391 return operator2.lexeme;
2392 }
2393 }
2394
2395 /**
2396 * Return the propagated type of the given expression that is to be used for t ype analysis.
2397 * @param expression the expression whose type is to be returned
2398 * @return the type of the given expression
2399 */
2400 Type2 getPropagatedType(Expression expression) {
2401 Type2 propagatedType2 = resolveTypeVariable(expression.propagatedType);
2402 if (propagatedType2 is FunctionType) {
2403 propagatedType2 = _resolver.typeProvider.functionType;
2404 }
2405 return propagatedType2;
2406 }
2407
2408 /**
2409 * Return the static type of the given expression that is to be used for type analysis.
2410 * @param expression the expression whose type is to be returned
2411 * @return the type of the given expression
2412 */
2413 Type2 getStaticType(Expression expression) {
2414 if (expression is NullLiteral) {
2415 return _resolver.typeProvider.objectType;
2416 }
2417 Type2 staticType2 = resolveTypeVariable(expression.staticType);
2418 if (staticType2 is FunctionType) {
2419 staticType2 = _resolver.typeProvider.functionType;
2420 }
2421 return staticType2;
2422 }
2423
2137 /** 2424 /**
2138 * Return the element representing the superclass of the given class. 2425 * Return the element representing the superclass of the given class.
2139 * @param targetClass the class whose superclass is to be returned 2426 * @param targetClass the class whose superclass is to be returned
2140 * @return the element representing the superclass of the given class 2427 * @return the element representing the superclass of the given class
2141 */ 2428 */
2142 ClassElement getSuperclass(ClassElement targetClass) { 2429 ClassElement getSuperclass(ClassElement targetClass) {
2143 InterfaceType superType = targetClass.supertype; 2430 InterfaceType superType = targetClass.supertype;
2144 if (superType == null) { 2431 if (superType == null) {
2145 return null; 2432 return null;
2146 } 2433 }
2147 return superType.element; 2434 return superType.element;
2148 } 2435 }
2149 /** 2436
2150 * Return the type of the given expression that is to be used for type analysi s.
2151 * @param expression the expression whose type is to be returned
2152 * @return the type of the given expression
2153 */
2154 Type2 getType(Expression expression) {
2155 if (expression is NullLiteral) {
2156 return _resolver.typeProvider.objectType;
2157 }
2158 return expression.staticType;
2159 }
2160 /** 2437 /**
2161 * Return {@code true} if the given type represents an object that could be in voked using the call 2438 * Return {@code true} if the given type represents an object that could be in voked using the call
2162 * operator '()'. 2439 * operator '()'.
2163 * @param type the type being tested 2440 * @param type the type being tested
2164 * @return {@code true} if the given type represents an object that could be i nvoked 2441 * @return {@code true} if the given type represents an object that could be i nvoked
2165 */ 2442 */
2166 bool isExecutableType(Type2 type) { 2443 bool isExecutableType(Type2 type) {
2167 if (type.isDynamic() || (type is FunctionType) || type.isDartCoreFunction()) { 2444 if (type.isDynamic() || (type is FunctionType) || type.isDartCoreFunction()) {
2168 return true; 2445 return true;
2169 } else if (type is InterfaceType) { 2446 } else if (type is InterfaceType) {
2170 ClassElement classElement = ((type as InterfaceType)).element; 2447 ClassElement classElement = ((type as InterfaceType)).element;
2171 MethodElement methodElement = classElement.lookUpMethod("call", _resolver. definingLibrary); 2448 MethodElement methodElement = classElement.lookUpMethod(CALL_METHOD_NAME, _resolver.definingLibrary);
2172 return methodElement != null; 2449 return methodElement != null;
2173 } 2450 }
2174 return false; 2451 return false;
2175 } 2452 }
2453
2454 /**
2455 * Return {@code true} if the given element is a static element.
2456 * @param element the element being tested
2457 * @return {@code true} if the given element is a static element
2458 */
2459 bool isStatic(Element element) {
2460 if (element is ExecutableElement) {
2461 return ((element as ExecutableElement)).isStatic();
2462 } else if (element is PropertyInducingElement) {
2463 return ((element as PropertyInducingElement)).isStatic();
2464 }
2465 return false;
2466 }
2467
2468 /**
2469 * Looks up the method element with the given name for index expression, repor ts{@link StaticWarningCode#UNDEFINED_OPERATOR} if not found.
2470 * @param node the index expression to resolve
2471 * @param target the target of the expression
2472 * @param methodName the name of the operator associated with the context of u sing of the given
2473 * index expression
2474 * @return {@code true} if and only if an error code is generated on the passe d node
2475 */
2476 bool lookUpCheckIndexOperator(IndexExpression node, Expression target, String methodName, Type2 staticType, Type2 propagatedType) {
2477 MethodElement staticMethod = lookUpMethod(target, staticType, methodName);
2478 MethodElement propagatedMethod = lookUpMethod(target, propagatedType, method Name);
2479 node.staticElement = staticMethod;
2480 node.element = select3(staticMethod, propagatedMethod);
2481 if (shouldReportMissingMember(staticType, staticMethod) && (propagatedType = = null || shouldReportMissingMember(propagatedType, propagatedMethod))) {
2482 sc.Token leftBracket2 = node.leftBracket;
2483 sc.Token rightBracket2 = node.rightBracket;
2484 if (leftBracket2 == null || rightBracket2 == null) {
2485 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_OPERATOR, node, [m ethodName, staticType.displayName]);
2486 return true;
2487 } else {
2488 int offset2 = leftBracket2.offset;
2489 int length = rightBracket2.offset - offset2 + 1;
2490 _resolver.reportError5(StaticTypeWarningCode.UNDEFINED_OPERATOR, offset2 , length, [methodName, staticType.displayName]);
2491 return true;
2492 }
2493 }
2494 return false;
2495 }
2496
2176 /** 2497 /**
2177 * Look up the getter with the given name in the given type. Return the elemen t representing the 2498 * Look up the getter with the given name in the given type. Return the elemen t representing the
2178 * getter that was found, or {@code null} if there is no getter with the given name. 2499 * getter that was found, or {@code null} if there is no getter with the given name.
2500 * @param target the target of the invocation, or {@code null} if there is no target
2179 * @param type the type in which the getter is defined 2501 * @param type the type in which the getter is defined
2180 * @param getterName the name of the getter being looked up 2502 * @param getterName the name of the getter being looked up
2181 * @return the element representing the getter that was found 2503 * @return the element representing the getter that was found
2182 */ 2504 */
2183 PropertyAccessorElement lookUpGetter(Type2 type, String getterName) { 2505 PropertyAccessorElement lookUpGetter(Expression target, Type2 type, String get terName) {
2184 type = resolveTypeVariable(type); 2506 type = resolveTypeVariable(type);
2185 if (type is InterfaceType) { 2507 if (type is InterfaceType) {
2186 InterfaceType interfaceType = type as InterfaceType; 2508 InterfaceType interfaceType = type as InterfaceType;
2187 PropertyAccessorElement accessor = interfaceType.lookUpGetter(getterName, _resolver.definingLibrary); 2509 PropertyAccessorElement accessor;
2510 if (target is SuperExpression) {
2511 accessor = interfaceType.lookUpGetterInSuperclass(getterName, _resolver. definingLibrary);
2512 } else {
2513 accessor = interfaceType.lookUpGetter(getterName, _resolver.definingLibr ary);
2514 }
2188 if (accessor != null) { 2515 if (accessor != null) {
2189 return accessor; 2516 return accessor;
2190 } 2517 }
2191 return lookUpGetterInInterfaces(interfaceType, getterName, new Set<ClassEl ement>()); 2518 return lookUpGetterInInterfaces(interfaceType, false, getterName, new Set< ClassElement>());
2192 } 2519 }
2193 return null; 2520 return null;
2194 } 2521 }
2522
2195 /** 2523 /**
2196 * Look up the getter with the given name in the interfaces implemented by the given type, either 2524 * Look up the getter with the given name in the interfaces implemented by the given type, either
2197 * directly or indirectly. Return the element representing the getter that was found, or{@code null} if there is no getter with the given name. 2525 * directly or indirectly. Return the element representing the getter that was found, or{@code null} if there is no getter with the given name.
2198 * @param targetType the type in which the getter might be defined 2526 * @param targetType the type in which the getter might be defined
2527 * @param includeTargetType {@code true} if the search should include the targ et type
2199 * @param getterName the name of the getter being looked up 2528 * @param getterName the name of the getter being looked up
2200 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used 2529 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used
2201 * to prevent infinite recursion and to optimize the search 2530 * to prevent infinite recursion and to optimize the search
2202 * @return the element representing the getter that was found 2531 * @return the element representing the getter that was found
2203 */ 2532 */
2204 PropertyAccessorElement lookUpGetterInInterfaces(InterfaceType targetType, Str ing getterName, Set<ClassElement> visitedInterfaces) { 2533 PropertyAccessorElement lookUpGetterInInterfaces(InterfaceType targetType, boo l includeTargetType, String getterName, Set<ClassElement> visitedInterfaces) {
2205 ClassElement targetClass = targetType.element; 2534 ClassElement targetClass = targetType.element;
2206 if (visitedInterfaces.contains(targetClass)) { 2535 if (visitedInterfaces.contains(targetClass)) {
2207 return null; 2536 return null;
2208 } 2537 }
2209 javaSetAdd(visitedInterfaces, targetClass); 2538 javaSetAdd(visitedInterfaces, targetClass);
2210 PropertyAccessorElement getter = targetType.getGetter(getterName); 2539 if (includeTargetType) {
2211 if (getter != null) { 2540 PropertyAccessorElement getter = targetType.getGetter(getterName);
2212 return getter;
2213 }
2214 for (InterfaceType interfaceType in targetType.interfaces) {
2215 getter = lookUpGetterInInterfaces(interfaceType, getterName, visitedInterf aces);
2216 if (getter != null) { 2541 if (getter != null) {
2217 return getter; 2542 return getter;
2218 } 2543 }
2544 }
2545 for (InterfaceType interfaceType in targetType.interfaces) {
2546 PropertyAccessorElement getter = lookUpGetterInInterfaces(interfaceType, t rue, getterName, visitedInterfaces);
2547 if (getter != null) {
2548 return getter;
2549 }
2219 } 2550 }
2220 InterfaceType superclass2 = targetType.superclass; 2551 InterfaceType superclass2 = targetType.superclass;
2221 if (superclass2 == null) { 2552 if (superclass2 == null) {
2222 return null; 2553 return null;
2223 } 2554 }
2224 return lookUpGetterInInterfaces(superclass2, getterName, visitedInterfaces); 2555 return lookUpGetterInInterfaces(superclass2, true, getterName, visitedInterf aces);
2225 } 2556 }
2557
2226 /** 2558 /**
2227 * Look up the method or getter with the given name in the given type. Return the element 2559 * Look up the method or getter with the given name in the given type. Return the element
2228 * representing the method or getter that was found, or {@code null} if there is no method or 2560 * representing the method or getter that was found, or {@code null} if there is no method or
2229 * getter with the given name. 2561 * getter with the given name.
2230 * @param type the type in which the method or getter is defined 2562 * @param type the type in which the method or getter is defined
2231 * @param memberName the name of the method or getter being looked up 2563 * @param memberName the name of the method or getter being looked up
2232 * @return the element representing the method or getter that was found 2564 * @return the element representing the method or getter that was found
2233 */ 2565 */
2234 ExecutableElement lookupGetterOrMethod(Type2 type, String memberName) { 2566 ExecutableElement lookupGetterOrMethod(Type2 type, String memberName) {
2235 type = resolveTypeVariable(type); 2567 type = resolveTypeVariable(type);
2236 if (type is InterfaceType) { 2568 if (type is InterfaceType) {
2237 InterfaceType interfaceType = type as InterfaceType; 2569 InterfaceType interfaceType = type as InterfaceType;
2238 ExecutableElement member = interfaceType.lookUpMethod(memberName, _resolve r.definingLibrary); 2570 ExecutableElement member = interfaceType.lookUpMethod(memberName, _resolve r.definingLibrary);
2239 if (member != null) { 2571 if (member != null) {
2240 return member; 2572 return member;
2241 } 2573 }
2242 member = interfaceType.lookUpGetter(memberName, _resolver.definingLibrary) ; 2574 member = interfaceType.lookUpGetter(memberName, _resolver.definingLibrary) ;
2243 if (member != null) { 2575 if (member != null) {
2244 return member; 2576 return member;
2245 } 2577 }
2246 return lookUpGetterOrMethodInInterfaces(interfaceType, memberName, new Set <ClassElement>()); 2578 return lookUpGetterOrMethodInInterfaces(interfaceType, false, memberName, new Set<ClassElement>());
2247 } 2579 }
2248 return null; 2580 return null;
2249 } 2581 }
2582
2250 /** 2583 /**
2251 * Look up the method or getter with the given name in the interfaces implemen ted by the given 2584 * Look up the method or getter with the given name in the interfaces implemen ted by the given
2252 * type, either directly or indirectly. Return the element representing the me thod or getter that 2585 * type, either directly or indirectly. Return the element representing the me thod or getter that
2253 * was found, or {@code null} if there is no method or getter with the given n ame. 2586 * was found, or {@code null} if there is no method or getter with the given n ame.
2254 * @param targetType the type in which the method or getter might be defined 2587 * @param targetType the type in which the method or getter might be defined
2588 * @param includeTargetType {@code true} if the search should include the targ et type
2255 * @param memberName the name of the method or getter being looked up 2589 * @param memberName the name of the method or getter being looked up
2256 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used 2590 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used
2257 * to prevent infinite recursion and to optimize the search 2591 * to prevent infinite recursion and to optimize the search
2258 * @return the element representing the method or getter that was found 2592 * @return the element representing the method or getter that was found
2259 */ 2593 */
2260 ExecutableElement lookUpGetterOrMethodInInterfaces(InterfaceType targetType, S tring memberName, Set<ClassElement> visitedInterfaces) { 2594 ExecutableElement lookUpGetterOrMethodInInterfaces(InterfaceType targetType, b ool includeTargetType, String memberName, Set<ClassElement> visitedInterfaces) {
2261 ClassElement targetClass = targetType.element; 2595 ClassElement targetClass = targetType.element;
2262 if (visitedInterfaces.contains(targetClass)) { 2596 if (visitedInterfaces.contains(targetClass)) {
2263 return null; 2597 return null;
2264 } 2598 }
2265 javaSetAdd(visitedInterfaces, targetClass); 2599 javaSetAdd(visitedInterfaces, targetClass);
2266 ExecutableElement member = targetType.getMethod(memberName); 2600 if (includeTargetType) {
2267 if (member != null) { 2601 ExecutableElement member = targetType.getMethod(memberName);
2268 return member;
2269 }
2270 member = targetType.getGetter(memberName);
2271 if (member != null) {
2272 return member;
2273 }
2274 for (InterfaceType interfaceType in targetType.interfaces) {
2275 member = lookUpGetterOrMethodInInterfaces(interfaceType, memberName, visit edInterfaces);
2276 if (member != null) { 2602 if (member != null) {
2277 return member; 2603 return member;
2278 } 2604 }
2605 member = targetType.getGetter(memberName);
2606 if (member != null) {
2607 return member;
2608 }
2609 }
2610 for (InterfaceType interfaceType in targetType.interfaces) {
2611 ExecutableElement member = lookUpGetterOrMethodInInterfaces(interfaceType, true, memberName, visitedInterfaces);
2612 if (member != null) {
2613 return member;
2614 }
2279 } 2615 }
2280 InterfaceType superclass2 = targetType.superclass; 2616 InterfaceType superclass2 = targetType.superclass;
2281 if (superclass2 == null) { 2617 if (superclass2 == null) {
2282 return null; 2618 return null;
2283 } 2619 }
2284 return lookUpGetterInInterfaces(superclass2, memberName, visitedInterfaces); 2620 return lookUpGetterOrMethodInInterfaces(superclass2, true, memberName, visit edInterfaces);
2285 } 2621 }
2622
2286 /** 2623 /**
2287 * Find the element corresponding to the given label node in the current label scope. 2624 * Find the element corresponding to the given label node in the current label scope.
2288 * @param parentNode the node containing the given label 2625 * @param parentNode the node containing the given label
2289 * @param labelNode the node representing the label being looked up 2626 * @param labelNode the node representing the label being looked up
2290 * @return the element corresponding to the given label node in the current sc ope 2627 * @return the element corresponding to the given label node in the current sc ope
2291 */ 2628 */
2292 LabelElementImpl lookupLabel(ASTNode parentNode, SimpleIdentifier labelNode) { 2629 LabelElementImpl lookupLabel(ASTNode parentNode, SimpleIdentifier labelNode) {
2293 LabelScope labelScope2 = _resolver.labelScope; 2630 LabelScope labelScope2 = _resolver.labelScope;
2294 LabelElementImpl labelElement = null; 2631 LabelElementImpl labelElement = null;
2295 if (labelNode == null) { 2632 if (labelNode == null) {
(...skipping 18 matching lines...) Expand all
2314 } 2651 }
2315 if (labelElement != null) { 2652 if (labelElement != null) {
2316 ExecutableElement labelContainer = labelElement.getAncestor(ExecutableElem ent); 2653 ExecutableElement labelContainer = labelElement.getAncestor(ExecutableElem ent);
2317 if (labelContainer != _resolver.enclosingFunction) { 2654 if (labelContainer != _resolver.enclosingFunction) {
2318 _resolver.reportError(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, labelNo de, [labelNode.name]); 2655 _resolver.reportError(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, labelNo de, [labelNode.name]);
2319 labelElement = null; 2656 labelElement = null;
2320 } 2657 }
2321 } 2658 }
2322 return labelElement; 2659 return labelElement;
2323 } 2660 }
2661
2324 /** 2662 /**
2325 * Look up the method with the given name in the given type. Return the elemen t representing the 2663 * Look up the method with the given name in the given type. Return the elemen t representing the
2326 * method that was found, or {@code null} if there is no method with the given name. 2664 * method that was found, or {@code null} if there is no method with the given name.
2665 * @param target the target of the invocation, or {@code null} if there is no target
2327 * @param type the type in which the method is defined 2666 * @param type the type in which the method is defined
2328 * @param methodName the name of the method being looked up 2667 * @param methodName the name of the method being looked up
2329 * @return the element representing the method that was found 2668 * @return the element representing the method that was found
2330 */ 2669 */
2331 MethodElement lookUpMethod(Type2 type, String methodName) { 2670 MethodElement lookUpMethod(Expression target, Type2 type, String methodName) {
2332 type = resolveTypeVariable(type); 2671 type = resolveTypeVariable(type);
2333 if (type is InterfaceType) { 2672 if (type is InterfaceType) {
2334 InterfaceType interfaceType = type as InterfaceType; 2673 InterfaceType interfaceType = type as InterfaceType;
2335 MethodElement method = interfaceType.lookUpMethod(methodName, _resolver.de finingLibrary); 2674 MethodElement method;
2675 if (target is SuperExpression) {
2676 method = interfaceType.lookUpMethodInSuperclass(methodName, _resolver.de finingLibrary);
2677 } else {
2678 method = interfaceType.lookUpMethod(methodName, _resolver.definingLibrar y);
2679 }
2336 if (method != null) { 2680 if (method != null) {
2337 return method; 2681 return method;
2338 } 2682 }
2339 return lookUpMethodInInterfaces(interfaceType, methodName, new Set<ClassEl ement>()); 2683 return lookUpMethodInInterfaces(interfaceType, false, methodName, new Set< ClassElement>());
2340 } 2684 }
2341 return null; 2685 return null;
2342 } 2686 }
2687
2343 /** 2688 /**
2344 * Look up the method with the given name in the interfaces implemented by the given type, either 2689 * Look up the method with the given name in the interfaces implemented by the given type, either
2345 * directly or indirectly. Return the element representing the method that was found, or{@code null} if there is no method with the given name. 2690 * directly or indirectly. Return the element representing the method that was found, or{@code null} if there is no method with the given name.
2346 * @param targetType the type in which the member might be defined 2691 * @param targetType the type in which the member might be defined
2692 * @param includeTargetType {@code true} if the search should include the targ et type
2347 * @param methodName the name of the method being looked up 2693 * @param methodName the name of the method being looked up
2348 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used 2694 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used
2349 * to prevent infinite recursion and to optimize the search 2695 * to prevent infinite recursion and to optimize the search
2350 * @return the element representing the method that was found 2696 * @return the element representing the method that was found
2351 */ 2697 */
2352 MethodElement lookUpMethodInInterfaces(InterfaceType targetType, String method Name, Set<ClassElement> visitedInterfaces) { 2698 MethodElement lookUpMethodInInterfaces(InterfaceType targetType, bool includeT argetType, String methodName, Set<ClassElement> visitedInterfaces) {
2353 ClassElement targetClass = targetType.element; 2699 ClassElement targetClass = targetType.element;
2354 if (visitedInterfaces.contains(targetClass)) { 2700 if (visitedInterfaces.contains(targetClass)) {
2355 return null; 2701 return null;
2356 } 2702 }
2357 javaSetAdd(visitedInterfaces, targetClass); 2703 javaSetAdd(visitedInterfaces, targetClass);
2358 MethodElement method = targetType.getMethod(methodName); 2704 if (includeTargetType) {
2359 if (method != null) { 2705 MethodElement method = targetType.getMethod(methodName);
2360 return method;
2361 }
2362 for (InterfaceType interfaceType in targetType.interfaces) {
2363 method = lookUpMethodInInterfaces(interfaceType, methodName, visitedInterf aces);
2364 if (method != null) { 2706 if (method != null) {
2365 return method; 2707 return method;
2366 } 2708 }
2709 }
2710 for (InterfaceType interfaceType in targetType.interfaces) {
2711 MethodElement method = lookUpMethodInInterfaces(interfaceType, true, metho dName, visitedInterfaces);
2712 if (method != null) {
2713 return method;
2714 }
2367 } 2715 }
2368 InterfaceType superclass2 = targetType.superclass; 2716 InterfaceType superclass2 = targetType.superclass;
2369 if (superclass2 == null) { 2717 if (superclass2 == null) {
2370 return null; 2718 return null;
2371 } 2719 }
2372 return lookUpMethodInInterfaces(superclass2, methodName, visitedInterfaces); 2720 return lookUpMethodInInterfaces(superclass2, true, methodName, visitedInterf aces);
2373 } 2721 }
2722
2374 /** 2723 /**
2375 * Look up the setter with the given name in the given type. Return the elemen t representing the 2724 * Look up the setter with the given name in the given type. Return the elemen t representing the
2376 * setter that was found, or {@code null} if there is no setter with the given name. 2725 * setter that was found, or {@code null} if there is no setter with the given name.
2726 * @param target the target of the invocation, or {@code null} if there is no target
2377 * @param type the type in which the setter is defined 2727 * @param type the type in which the setter is defined
2378 * @param setterName the name of the setter being looked up 2728 * @param setterName the name of the setter being looked up
2379 * @return the element representing the setter that was found 2729 * @return the element representing the setter that was found
2380 */ 2730 */
2381 PropertyAccessorElement lookUpSetter(Type2 type, String setterName) { 2731 PropertyAccessorElement lookUpSetter(Expression target, Type2 type, String set terName) {
2382 type = resolveTypeVariable(type); 2732 type = resolveTypeVariable(type);
2383 if (type is InterfaceType) { 2733 if (type is InterfaceType) {
2384 InterfaceType interfaceType = type as InterfaceType; 2734 InterfaceType interfaceType = type as InterfaceType;
2385 PropertyAccessorElement accessor = interfaceType.lookUpSetter(setterName, _resolver.definingLibrary); 2735 PropertyAccessorElement accessor;
2736 if (target is SuperExpression) {
2737 accessor = interfaceType.lookUpSetterInSuperclass(setterName, _resolver. definingLibrary);
2738 } else {
2739 accessor = interfaceType.lookUpSetter(setterName, _resolver.definingLibr ary);
2740 }
2386 if (accessor != null) { 2741 if (accessor != null) {
2387 return accessor; 2742 return accessor;
2388 } 2743 }
2389 return lookUpSetterInInterfaces(interfaceType, setterName, new Set<ClassEl ement>()); 2744 return lookUpSetterInInterfaces(interfaceType, false, setterName, new Set< ClassElement>());
2390 } 2745 }
2391 return null; 2746 return null;
2392 } 2747 }
2748
2393 /** 2749 /**
2394 * Look up the setter with the given name in the interfaces implemented by the given type, either 2750 * Look up the setter with the given name in the interfaces implemented by the given type, either
2395 * directly or indirectly. Return the element representing the setter that was found, or{@code null} if there is no setter with the given name. 2751 * directly or indirectly. Return the element representing the setter that was found, or{@code null} if there is no setter with the given name.
2396 * @param targetType the type in which the setter might be defined 2752 * @param targetType the type in which the setter might be defined
2753 * @param includeTargetType {@code true} if the search should include the targ et type
2397 * @param setterName the name of the setter being looked up 2754 * @param setterName the name of the setter being looked up
2398 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used 2755 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used
2399 * to prevent infinite recursion and to optimize the search 2756 * to prevent infinite recursion and to optimize the search
2400 * @return the element representing the setter that was found 2757 * @return the element representing the setter that was found
2401 */ 2758 */
2402 PropertyAccessorElement lookUpSetterInInterfaces(InterfaceType targetType, Str ing setterName, Set<ClassElement> visitedInterfaces) { 2759 PropertyAccessorElement lookUpSetterInInterfaces(InterfaceType targetType, boo l includeTargetType, String setterName, Set<ClassElement> visitedInterfaces) {
2403 ClassElement targetClass = targetType.element; 2760 ClassElement targetClass = targetType.element;
2404 if (visitedInterfaces.contains(targetClass)) { 2761 if (visitedInterfaces.contains(targetClass)) {
2405 return null; 2762 return null;
2406 } 2763 }
2407 javaSetAdd(visitedInterfaces, targetClass); 2764 javaSetAdd(visitedInterfaces, targetClass);
2408 PropertyAccessorElement setter = targetType.getGetter(setterName); 2765 if (includeTargetType) {
2409 if (setter != null) { 2766 PropertyAccessorElement setter = targetType.getSetter(setterName);
2410 return setter;
2411 }
2412 for (InterfaceType interfaceType in targetType.interfaces) {
2413 setter = lookUpSetterInInterfaces(interfaceType, setterName, visitedInterf aces);
2414 if (setter != null) { 2767 if (setter != null) {
2415 return setter; 2768 return setter;
2416 } 2769 }
2770 }
2771 for (InterfaceType interfaceType in targetType.interfaces) {
2772 PropertyAccessorElement setter = lookUpSetterInInterfaces(interfaceType, t rue, setterName, visitedInterfaces);
2773 if (setter != null) {
2774 return setter;
2775 }
2417 } 2776 }
2418 InterfaceType superclass2 = targetType.superclass; 2777 InterfaceType superclass2 = targetType.superclass;
2419 if (superclass2 == null) { 2778 if (superclass2 == null) {
2420 return null; 2779 return null;
2421 } 2780 }
2422 return lookUpSetterInInterfaces(superclass2, setterName, visitedInterfaces); 2781 return lookUpSetterInInterfaces(superclass2, true, setterName, visitedInterf aces);
2423 } 2782 }
2783
2424 /** 2784 /**
2425 * Return the binary operator that is invoked by the given compound assignment operator. 2785 * Return the binary operator that is invoked by the given compound assignment operator.
2426 * @param operator the assignment operator being mapped 2786 * @param operator the assignment operator being mapped
2427 * @return the binary operator that invoked by the given assignment operator 2787 * @return the binary operator that invoked by the given assignment operator
2428 */ 2788 */
2429 sc.TokenType operatorFromCompoundAssignment(sc.TokenType operator) { 2789 sc.TokenType operatorFromCompoundAssignment(sc.TokenType operator) {
2430 while (true) { 2790 while (true) {
2431 if (operator == sc.TokenType.AMPERSAND_EQ) { 2791 if (operator == sc.TokenType.AMPERSAND_EQ) {
2432 return sc.TokenType.AMPERSAND; 2792 return sc.TokenType.AMPERSAND;
2433 } else if (operator == sc.TokenType.BAR_EQ) { 2793 } else if (operator == sc.TokenType.BAR_EQ) {
(...skipping 15 matching lines...) Expand all
2449 } else if (operator == sc.TokenType.STAR_EQ) { 2809 } else if (operator == sc.TokenType.STAR_EQ) {
2450 return sc.TokenType.STAR; 2810 return sc.TokenType.STAR;
2451 } else if (operator == sc.TokenType.TILDE_SLASH_EQ) { 2811 } else if (operator == sc.TokenType.TILDE_SLASH_EQ) {
2452 return sc.TokenType.TILDE_SLASH; 2812 return sc.TokenType.TILDE_SLASH;
2453 } 2813 }
2454 break; 2814 break;
2455 } 2815 }
2456 AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to it's corresponding operator"); 2816 AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to it's corresponding operator");
2457 return operator; 2817 return operator;
2458 } 2818 }
2819
2459 /** 2820 /**
2460 * Record the fact that the given AST node was resolved to the given element. 2821 * Record the fact that the given AST node was resolved to the given element.
2461 * @param node the AST node that was resolved 2822 * @param node the AST node that was resolved
2462 * @param element the element to which the AST node was resolved 2823 * @param element the element to which the AST node was resolved
2463 */ 2824 */
2464 void recordResolution(SimpleIdentifier node, Element element2) { 2825 void recordResolution(SimpleIdentifier node, Element element2) {
2465 if (element2 != null) { 2826 node.staticElement = element2;
2466 node.element = element2; 2827 node.element = element2;
2467 }
2468 } 2828 }
2829
2469 /** 2830 /**
2470 * Report the {@link StaticTypeWarningCode}s <code>UNDEFINED_SETTER</code> and <code>UNDEFINED_GETTER</code>. 2831 * Record the fact that the given AST node was resolved to the given elements.
2471 * @param node the prefixed identifier that gives the context to determine if the error on the 2832 * @param node the AST node that was resolved
2472 * undefined identifier is a getter or a setter 2833 * @param staticElement the element to which the AST node was resolved using s tatic type
2473 * @param identifier the identifier in the passed prefix identifier 2834 * information
2474 * @param typeName the name of the type of the left hand side of the passed pr efixed identifier 2835 * @param propagatedElement the element to which the AST node was resolved usi ng propagated type
2836 * information
2837 * @return the element that was associated with the node
2475 */ 2838 */
2476 void reportGetterOrSetterNotFound(PrefixedIdentifier node, SimpleIdentifier id entifier2, String typeName) { 2839 Element recordResolution2(SimpleIdentifier node, Element staticElement2, Eleme nt propagatedElement) {
2477 Type2 targetType = getType(node); 2840 node.staticElement = staticElement2;
2478 if (targetType != null && doesClassDeclareNoSuchMethod(targetType.element)) { 2841 Element element = propagatedElement == null ? staticElement2 : propagatedEle ment;
2842 node.element = element;
2843 return element;
2844 }
2845
2846 /**
2847 * Given a list of arguments and the element that will be invoked using those argument, compute
2848 * the list of parameters that correspond to the list of arguments.
2849 * @param reportError if {@code true} then compile-time error should be report ed; if {@code false}then compile-time warning
2850 * @param argumentList the list of arguments being passed to the element
2851 * @param executableElement the element that will be invoked with the argument s
2852 */
2853 void resolveArgumentsToParameters(bool reportError, ArgumentList argumentList, ExecutableElement executableElement) {
2854 if (executableElement == null) {
2479 return; 2855 return;
2480 } 2856 }
2481 bool isSetterContext = node.identifier.inSetterContext(); 2857 List<ParameterElement> parameters2 = executableElement.parameters;
2482 ErrorCode errorCode = isSetterContext ? StaticTypeWarningCode.UNDEFINED_SETT ER : StaticTypeWarningCode.UNDEFINED_GETTER; 2858 resolveArgumentsToParameters2(reportError, argumentList, parameters2);
2483 _resolver.reportError(errorCode, identifier2, [identifier2.name, typeName]);
2484 } 2859 }
2860
2861 /**
2862 * Given a list of arguments and the element that will be invoked using those argument, compute
2863 * the list of parameters that correspond to the list of arguments.
2864 * @param reportError if {@code true} then compile-time error should be report ed; if {@code false}then compile-time warning
2865 * @param argumentList the list of arguments being passed to the element
2866 * @param parameters the of the function that will be invoked with the argumen ts
2867 */
2868 void resolveArgumentsToParameters2(bool reportError2, ArgumentList argumentLis t, List<ParameterElement> parameters) {
2869 List<ParameterElement> requiredParameters = new List<ParameterElement>();
2870 List<ParameterElement> positionalParameters = new List<ParameterElement>();
2871 Map<String, ParameterElement> namedParameters = new Map<String, ParameterEle ment>();
2872 for (ParameterElement parameter in parameters) {
2873 ParameterKind kind = parameter.parameterKind;
2874 if (identical(kind, ParameterKind.REQUIRED)) {
2875 requiredParameters.add(parameter);
2876 } else if (identical(kind, ParameterKind.POSITIONAL)) {
2877 positionalParameters.add(parameter);
2878 } else {
2879 namedParameters[parameter.name] = parameter;
2880 }
2881 }
2882 List<ParameterElement> unnamedParameters = new List<ParameterElement>.from(r equiredParameters);
2883 unnamedParameters.addAll(positionalParameters);
2884 int unnamedParameterCount = unnamedParameters.length;
2885 int unnamedIndex = 0;
2886 NodeList<Expression> arguments2 = argumentList.arguments;
2887 int argumentCount = arguments2.length;
2888 List<ParameterElement> resolvedParameters = new List<ParameterElement>(argum entCount);
2889 int positionalArgumentCount = 0;
2890 Set<String> usedNames = new Set<String>();
2891 for (int i = 0; i < argumentCount; i++) {
2892 Expression argument = arguments2[i];
2893 if (argument is NamedExpression) {
2894 SimpleIdentifier nameNode = ((argument as NamedExpression)).name.label;
2895 String name2 = nameNode.name;
2896 ParameterElement element = namedParameters[name2];
2897 if (element == null) {
2898 ErrorCode errorCode = reportError2 ? CompileTimeErrorCode.UNDEFINED_NA MED_PARAMETER : StaticWarningCode.UNDEFINED_NAMED_PARAMETER;
2899 _resolver.reportError(errorCode, nameNode, [name2]);
2900 } else {
2901 resolvedParameters[i] = element;
2902 recordResolution(nameNode, element);
2903 }
2904 if (!javaSetAdd(usedNames, name2)) {
2905 _resolver.reportError(CompileTimeErrorCode.DUPLICATE_NAMED_ARGUMENT, n ameNode, [name2]);
2906 }
2907 } else {
2908 positionalArgumentCount++;
2909 if (unnamedIndex < unnamedParameterCount) {
2910 resolvedParameters[i] = unnamedParameters[unnamedIndex++];
2911 }
2912 }
2913 }
2914 if (positionalArgumentCount < requiredParameters.length) {
2915 ErrorCode errorCode = reportError2 ? CompileTimeErrorCode.NOT_ENOUGH_REQUI RED_ARGUMENTS : StaticWarningCode.NOT_ENOUGH_REQUIRED_ARGUMENTS;
2916 _resolver.reportError(errorCode, argumentList, [requiredParameters.length, positionalArgumentCount]);
2917 } else if (positionalArgumentCount > unnamedParameterCount) {
2918 ErrorCode errorCode = reportError2 ? CompileTimeErrorCode.EXTRA_POSITIONAL _ARGUMENTS : StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS;
2919 _resolver.reportError(errorCode, argumentList, [unnamedParameterCount, pos itionalArgumentCount]);
2920 }
2921 argumentList.correspondingParameters = resolvedParameters;
2922 }
2923
2485 /** 2924 /**
2486 * Resolve the names in the given combinators in the scope of the given librar y. 2925 * Resolve the names in the given combinators in the scope of the given librar y.
2487 * @param library the library that defines the names 2926 * @param library the library that defines the names
2488 * @param combinators the combinators containing the names to be resolved 2927 * @param combinators the combinators containing the names to be resolved
2489 */ 2928 */
2490 void resolveCombinators(LibraryElement library, NodeList<Combinator> combinato rs) { 2929 void resolveCombinators(LibraryElement library, NodeList<Combinator> combinato rs) {
2491 if (library == null) { 2930 if (library == null) {
2492 return; 2931 return;
2493 } 2932 }
2494 Namespace namespace = new NamespaceBuilder().createExportNamespace(library); 2933 Namespace namespace = new NamespaceBuilder().createExportNamespace2(library) ;
2495 for (Combinator combinator in combinators) { 2934 for (Combinator combinator in combinators) {
2496 NodeList<SimpleIdentifier> names; 2935 NodeList<SimpleIdentifier> names;
2497 if (combinator is HideCombinator) { 2936 if (combinator is HideCombinator) {
2498 names = ((combinator as HideCombinator)).hiddenNames; 2937 names = ((combinator as HideCombinator)).hiddenNames;
2499 } else { 2938 } else {
2500 names = ((combinator as ShowCombinator)).shownNames; 2939 names = ((combinator as ShowCombinator)).shownNames;
2501 } 2940 }
2502 for (SimpleIdentifier name in names) { 2941 for (SimpleIdentifier name in names) {
2503 Element element = namespace.get(name.name); 2942 Element element = namespace.get(name.name);
2504 if (element != null) { 2943 if (element != null) {
2505 name.element = element; 2944 name.element = element;
2506 } 2945 }
2507 } 2946 }
2508 } 2947 }
2509 } 2948 }
2949
2510 /** 2950 /**
2511 * Resolve the names associated with any named arguments to the parameter elem ents named by the 2951 * Given an invocation of the form 'e.m(a1, ..., an)', resolve 'e.m' to the el ement being invoked.
2512 * argument. 2952 * If the returned element is a method, then the method will be invoked. If th e returned element
2513 * @param argumentList the arguments to be resolved 2953 * is a getter, the getter will be invoked without arguments and the result of that invocation
2514 * @param invokedMethod the method or function defining the parameters to whic h the named 2954 * will then be invoked with the arguments.
2515 * arguments are to be resolved 2955 * @param target the target of the invocation ('e')
2956 * @param targetType the type of the target
2957 * @param methodName the name of the method being invoked ('m')
2958 * @return the element being invoked
2516 */ 2959 */
2517 void resolveNamedArguments(ArgumentList argumentList, ExecutableElement invoke dMethod) { 2960 Element resolveInvokedElement(Expression target, Type2 targetType, SimpleIdent ifier methodName) {
2518 if (invokedMethod == null) { 2961 if (targetType is InterfaceType) {
2519 return; 2962 InterfaceType classType = targetType as InterfaceType;
2963 Element element = lookUpMethod(target, classType, methodName.name);
2964 if (element == null) {
2965 element = classType.getGetter(methodName.name);
2966 }
2967 return element;
2968 } else if (target is SimpleIdentifier) {
2969 Element targetElement = ((target as SimpleIdentifier)).element;
2970 if (targetElement is PrefixElement) {
2971 String name2 = "${((target as SimpleIdentifier)).name}.${methodName}";
2972 Identifier functionName = new ElementResolver_SyntheticIdentifier(name2) ;
2973 Element element = _resolver.nameScope.lookup(functionName, _resolver.def iningLibrary);
2974 if (element != null) {
2975 return element;
2976 }
2977 }
2520 } 2978 }
2521 List<ParameterElement> parameters2 = invokedMethod.parameters; 2979 return null;
2522 for (Expression argument in argumentList.arguments) { 2980 }
2523 if (argument is NamedExpression) { 2981
2524 SimpleIdentifier name2 = ((argument as NamedExpression)).name.label; 2982 /**
2525 ParameterElement parameter = findNamedParameter(parameters2, name2.name) ; 2983 * Given an invocation of the form 'm(a1, ..., an)', resolve 'm' to the elemen t being invoked. If
2526 if (parameter != null) { 2984 * the returned element is a method, then the method will be invoked. If the r eturned element is a
2527 recordResolution(name2, parameter); 2985 * getter, the getter will be invoked without arguments and the result of that invocation will
2986 * then be invoked with the arguments.
2987 * @param methodName the name of the method being invoked ('m')
2988 * @return the element being invoked
2989 */
2990 Element resolveInvokedElement2(SimpleIdentifier methodName) {
2991 Element element = _resolver.nameScope.lookup(methodName, _resolver.definingL ibrary);
2992 if (element == null) {
2993 ClassElement enclosingClass2 = _resolver.enclosingClass;
2994 if (enclosingClass2 != null) {
2995 InterfaceType enclosingType = enclosingClass2.type;
2996 element = lookUpMethod(null, enclosingType, methodName.name);
2997 if (element == null) {
2998 element = lookUpGetter(null, enclosingType, methodName.name);
2999 }
3000 }
3001 }
3002 return element;
3003 }
3004
3005 /**
3006 * Given that we are accessing a property of the given type with the given nam e, return the
3007 * element that represents the property.
3008 * @param target the target of the invocation ('e')
3009 * @param targetType the type in which the search for the property should begi n
3010 * @param propertyName the name of the property being accessed
3011 * @return the element that represents the property
3012 */
3013 ExecutableElement resolveProperty(Expression target, Type2 targetType, SimpleI dentifier propertyName) {
3014 ExecutableElement memberElement = null;
3015 if (propertyName.inSetterContext()) {
3016 memberElement = lookUpSetter(target, targetType, propertyName.name);
3017 }
3018 if (memberElement == null) {
3019 memberElement = lookUpGetter(target, targetType, propertyName.name);
3020 }
3021 if (memberElement == null) {
3022 memberElement = lookUpMethod(target, targetType, propertyName.name);
3023 }
3024 return memberElement;
3025 }
3026 void resolvePropertyAccess(Expression target, SimpleIdentifier propertyName) {
3027 Type2 staticType = getStaticType(target);
3028 ExecutableElement staticElement = resolveProperty(target, staticType, proper tyName);
3029 propertyName.staticElement = staticElement;
3030 Type2 propagatedType = getPropagatedType(target);
3031 ExecutableElement propagatedElement = resolveProperty(target, propagatedType , propertyName);
3032 Element selectedElement = select2(staticElement, propagatedElement);
3033 propertyName.element = selectedElement;
3034 if (shouldReportMissingMember(staticType, staticElement) && (propagatedType == null || shouldReportMissingMember(propagatedType, propagatedElement))) {
3035 bool staticNoSuchMethod = staticType != null && classDeclaresNoSuchMethod2 (staticType.element);
3036 bool propagatedNoSuchMethod = propagatedType != null && classDeclaresNoSuc hMethod2(propagatedType.element);
3037 if (!staticNoSuchMethod && !propagatedNoSuchMethod) {
3038 bool isStaticProperty = isStatic(selectedElement);
3039 if (propertyName.inSetterContext()) {
3040 if (isStaticProperty) {
3041 _resolver.reportError(StaticWarningCode.UNDEFINED_SETTER, propertyNa me, [propertyName.name, staticType.displayName]);
3042 } else {
3043 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_SETTER, proper tyName, [propertyName.name, staticType.displayName]);
3044 }
3045 } else if (propertyName.inGetterContext()) {
3046 if (isStaticProperty) {
3047 _resolver.reportError(StaticWarningCode.UNDEFINED_GETTER, propertyNa me, [propertyName.name, staticType.displayName]);
3048 } else {
3049 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_GETTER, proper tyName, [propertyName.name, staticType.displayName]);
3050 }
3051 } else {
3052 _resolver.reportError(StaticWarningCode.UNDEFINED_IDENTIFIER, property Name, [propertyName.name]);
2528 } 3053 }
2529 } 3054 }
2530 } 3055 }
2531 } 3056 }
3057
3058 /**
3059 * Resolve the given simple identifier if possible. Return the element to whic h it could be
3060 * resolved, or {@code null} if it could not be resolved. This does not record the results of the
3061 * resolution.
3062 * @param node the identifier to be resolved
3063 * @return the element to which the identifier could be resolved
3064 */
3065 Element resolveSimpleIdentifier(SimpleIdentifier node) {
3066 Element element = _resolver.nameScope.lookup(node, _resolver.definingLibrary );
3067 if (element is PropertyAccessorElement && node.inSetterContext()) {
3068 PropertyInducingElement variable2 = ((element as PropertyAccessorElement)) .variable;
3069 if (variable2 != null) {
3070 PropertyAccessorElement setter2 = variable2.setter;
3071 if (setter2 == null) {
3072 ClassElement enclosingClass2 = _resolver.enclosingClass;
3073 if (enclosingClass2 != null) {
3074 setter2 = lookUpSetter(null, enclosingClass2.type, node.name);
3075 }
3076 }
3077 if (setter2 != null) {
3078 element = setter2;
3079 }
3080 }
3081 } else if (element == null && node.inSetterContext()) {
3082 element = _resolver.nameScope.lookup(new ElementResolver_SyntheticIdentifi er("${node.name}="), _resolver.definingLibrary);
3083 }
3084 ClassElement enclosingClass3 = _resolver.enclosingClass;
3085 if (element == null && enclosingClass3 != null) {
3086 InterfaceType enclosingType = enclosingClass3.type;
3087 if (element == null && node.inSetterContext()) {
3088 element = lookUpSetter(null, enclosingType, node.name);
3089 }
3090 if (element == null && node.inGetterContext()) {
3091 element = lookUpGetter(null, enclosingType, node.name);
3092 }
3093 if (element == null) {
3094 element = lookUpMethod(null, enclosingType, node.name);
3095 }
3096 }
3097 return element;
3098 }
3099
2532 /** 3100 /**
2533 * If the given type is a type variable, resolve it to the type that should be used when looking 3101 * If the given type is a type variable, resolve it to the type that should be used when looking
2534 * up members. Otherwise, return the original type. 3102 * up members. Otherwise, return the original type.
2535 * @param type the type that is to be resolved if it is a type variable 3103 * @param type the type that is to be resolved if it is a type variable
2536 * @return the type that should be used in place of the argument if it is a ty pe variable, or the 3104 * @return the type that should be used in place of the argument if it is a ty pe variable, or the
2537 * original argument if it isn't a type variable 3105 * original argument if it isn't a type variable
2538 */ 3106 */
2539 Type2 resolveTypeVariable(Type2 type) { 3107 Type2 resolveTypeVariable(Type2 type) {
2540 if (type is TypeVariableType) { 3108 if (type is TypeVariableType) {
2541 Type2 bound2 = ((type as TypeVariableType)).element.bound; 3109 Type2 bound2 = ((type as TypeVariableType)).element.bound;
2542 if (bound2 == null) { 3110 if (bound2 == null) {
2543 return _resolver.typeProvider.objectType; 3111 return _resolver.typeProvider.objectType;
2544 } 3112 }
2545 return bound2; 3113 return bound2;
2546 } 3114 }
2547 return type; 3115 return type;
2548 } 3116 }
3117
3118 /**
3119 * Given two possible error codes for the same piece of code, one computed usi ng static type
3120 * information and the other using propagated type information, return the err or code that should
3121 * be reported, or {@code null} if no error should be reported.
3122 * @param staticError the error code computed using static type information
3123 * @param propagatedError the error code computed using propagated type inform ation
3124 * @return the error code that should be reported
3125 */
3126 ErrorCode select(ErrorCode staticError, ErrorCode propagatedError) {
3127 if (staticError == null || propagatedError == null) {
3128 return null;
3129 }
3130 return propagatedError;
3131 }
3132
3133 /**
3134 * Return the propagated element if it is not {@code null}, or the static elem ent if it is.
3135 * @param staticElement the element computed using static type information
3136 * @param propagatedElement the element computed using propagated type informa tion
3137 * @return the more specific of the two elements
3138 */
3139 ExecutableElement select2(ExecutableElement staticElement, ExecutableElement p ropagatedElement) => propagatedElement != null ? propagatedElement : staticEleme nt;
3140
3141 /**
3142 * Return the propagated method if it is not {@code null}, or the static metho d if it is.
3143 * @param staticMethod the method computed using static type information
3144 * @param propagatedMethod the method computed using propagated type informati on
3145 * @return the more specific of the two methods
3146 */
3147 MethodElement select3(MethodElement staticMethod, MethodElement propagatedMeth od) => propagatedMethod != null ? propagatedMethod : staticMethod;
3148
3149 /**
3150 * Given a node that can have annotations associated with it and the element t o which that node
3151 * has been resolved, create the annotations in the element model representing the annotations on
3152 * the node.
3153 * @param element the element to which the node has been resolved
3154 * @param node the node that can have annotations associated with it
3155 */
3156 void setMetadata(Element element, AnnotatedNode node) {
3157 if (element is! ElementImpl) {
3158 return;
3159 }
3160 List<AnnotationImpl> annotationList = new List<AnnotationImpl>();
3161 addAnnotations(annotationList, node.metadata);
3162 if (node is VariableDeclaration && node.parent is VariableDeclarationList) {
3163 VariableDeclarationList list = node.parent as VariableDeclarationList;
3164 addAnnotations(annotationList, list.metadata);
3165 if (list.parent is FieldDeclaration) {
3166 FieldDeclaration fieldDeclaration = list.parent as FieldDeclaration;
3167 addAnnotations(annotationList, fieldDeclaration.metadata);
3168 } else if (list.parent is TopLevelVariableDeclaration) {
3169 TopLevelVariableDeclaration variableDeclaration = list.parent as TopLeve lVariableDeclaration;
3170 addAnnotations(annotationList, variableDeclaration.metadata);
3171 }
3172 }
3173 if (!annotationList.isEmpty) {
3174 ((element as ElementImpl)).metadata = new List.from(annotationList);
3175 }
3176 }
3177
3178 /**
3179 * Return {@code true} if we should report an error as a result of looking up a member in the
3180 * given type and not finding any member.
3181 * @param type the type in which we attempted to perform the look-up
3182 * @param member the result of the look-up
3183 * @return {@code true} if we should report an error
3184 */
3185 bool shouldReportMissingMember(Type2 type, ExecutableElement member) {
3186 if (member != null || type == null || type.isDynamic()) {
3187 return false;
3188 }
3189 if (type is InterfaceType) {
3190 return !classDeclaresNoSuchMethod(((type as InterfaceType)).element);
3191 }
3192 return true;
3193 }
2549 } 3194 }
2550 class Identifier_8 extends Identifier { 3195
2551 String name3; 3196 /**
2552 Identifier_8(this.name3) : super(); 3197 * Instances of the class {@code SyntheticIdentifier} implement an identifier th at can be used to
3198 * look up names in the lexical scope when there is no identifier in the AST str ucture. There is
3199 * no identifier in the AST when the parser could not distinguish between a meth od invocation and
3200 * an invocation of a top-level function imported with a prefix.
3201 */
3202 class ElementResolver_SyntheticIdentifier extends Identifier {
3203
3204 /**
3205 * The name of the synthetic identifier.
3206 */
3207 String _name;
3208
3209 /**
3210 * Initialize a newly created synthetic identifier to have the given name.
3211 * @param name the name of the synthetic identifier
3212 */
3213 ElementResolver_SyntheticIdentifier(String name) {
3214 this._name = name;
3215 }
2553 accept(ASTVisitor visitor) => null; 3216 accept(ASTVisitor visitor) => null;
2554 sc.Token get beginToken => null; 3217 sc.Token get beginToken => null;
2555 Element get element => null; 3218 Element get element => null;
2556 sc.Token get endToken => null; 3219 sc.Token get endToken => null;
2557 String get name => name3; 3220 String get name => _name;
3221 Element get staticElement => null;
2558 void visitChildren(ASTVisitor<Object> visitor) { 3222 void visitChildren(ASTVisitor<Object> visitor) {
2559 } 3223 }
2560 } 3224 }
3225
3226 /**
3227 * Instances of the class {@code InheritanceManager} manage the knowledge of whe re class members
3228 * (methods, getters & setters) are inherited from.
3229 * @coverage dart.engine.resolver
3230 */
3231 class InheritanceManager {
3232
3233 /**
3234 * The {@link LibraryElement} that is managed by this manager.
3235 */
3236 LibraryElement _library;
3237
3238 /**
3239 * This is a mapping between each {@link ClassElement} and a map between the { @link String} member
3240 * names and the associated {@link ExecutableElement} in the mixin and supercl ass chain.
3241 */
3242 Map<ClassElement, Map<String, ExecutableElement>> _classLookup;
3243
3244 /**
3245 * This is a mapping between each {@link ClassElement} and a map between the { @link String} member
3246 * names and the associated {@link ExecutableElement} in the interface set.
3247 */
3248 Map<ClassElement, Map<String, ExecutableElement>> _interfaceLookup;
3249
3250 /**
3251 * A map between each visited {@link ClassElement} and the set of {@link Analy sisError}s found on
3252 * the class element.
3253 */
3254 Map<ClassElement, Set<AnalysisError>> _errorsInClassElement = new Map<ClassEle ment, Set<AnalysisError>>();
3255
3256 /**
3257 * Initialize a newly created inheritance manager.
3258 * @param library the library element context that the inheritance mappings ar e being generated
3259 */
3260 InheritanceManager(LibraryElement library) {
3261 this._library = library;
3262 _classLookup = new Map<ClassElement, Map<String, ExecutableElement>>();
3263 _interfaceLookup = new Map<ClassElement, Map<String, ExecutableElement>>();
3264 }
3265
3266 /**
3267 * Return the set of {@link AnalysisError}s found on the passed {@link ClassEl ement}, or{@code null} if there are none.
3268 * @param classElt the class element to query
3269 * @return the set of {@link AnalysisError}s found on the passed {@link ClassE lement}, or{@code null} if there are none
3270 */
3271 Set<AnalysisError> getErrors(ClassElement classElt) => _errorsInClassElement[c lassElt];
3272
3273 /**
3274 * Get and return a mapping between the set of all string names of the members inherited from the
3275 * passed {@link ClassElement} superclass hierarchy, and the associated {@link ExecutableElement}.
3276 * @param classElt the class element to query
3277 * @return a mapping between the set of all members inherited from the passed {@link ClassElement}superclass hierarchy, and the associated {@link ExecutableEl ement}
3278 */
3279 Map<String, ExecutableElement> getMapOfMembersInheritedFromClasses(ClassElemen t classElt) => computeClassChainLookupMap(classElt, new Set<ClassElement>());
3280
3281 /**
3282 * Get and return a mapping between the set of all string names of the members inherited from the
3283 * passed {@link ClassElement} interface hierarchy, and the associated {@link ExecutableElement}.
3284 * @param classElt the class element to query
3285 * @return a mapping between the set of all string names of the members inheri ted from the passed{@link ClassElement} interface hierarchy, and the associated {@link ExecutableElement}.
3286 */
3287 Map<String, ExecutableElement> getMapOfMembersInheritedFromInterfaces(ClassEle ment classElt) => computeInterfaceLookupMap(classElt, new Set<ClassElement>());
3288
3289 /**
3290 * Given some {@link ClassElement class element} and some member name, this re turns the{@link ExecutableElement executable element} that the class inherits fr om the mixins,
3291 * superclasses or interfaces, that has the member name, if no member is inher ited {@code null} is
3292 * returned.
3293 * @param classElt the class element to query
3294 * @param memberName the name of the executable element to find and return
3295 * @return the inherited executable element with the member name, or {@code nu ll} if no such
3296 * member exists
3297 */
3298 ExecutableElement lookupInheritance(ClassElement classElt, String memberName) {
3299 if (memberName == null || memberName.isEmpty) {
3300 return null;
3301 }
3302 ExecutableElement executable = computeClassChainLookupMap(classElt, new Set< ClassElement>())[memberName];
3303 if (executable == null) {
3304 return computeInterfaceLookupMap(classElt, new Set<ClassElement>())[member Name];
3305 }
3306 return executable;
3307 }
3308
3309 /**
3310 * Given some {@link ClassElement class element} and some member name, this re turns the{@link ExecutableElement executable element} that the class either decl ares itself, or
3311 * inherits, that has the member name, if no member is inherited {@code null} is returned.
3312 * @param classElt the class element to query
3313 * @param memberName the name of the executable element to find and return
3314 * @return the inherited executable element with the member name, or {@code nu ll} if no such
3315 * member exists
3316 */
3317 ExecutableElement lookupMember(ClassElement classElt, String memberName) {
3318 ExecutableElement element = lookupMemberInClass(classElt, memberName);
3319 if (element != null) {
3320 return element;
3321 }
3322 return lookupInheritance(classElt, memberName);
3323 }
3324
3325 /**
3326 * Set the new library element context.
3327 * @param library the new library element
3328 */
3329 void set libraryElement(LibraryElement library2) {
3330 this._library = library2;
3331 }
3332
3333 /**
3334 * This method takes some inherited {@link FunctionType}, and resolves all the parameterized types
3335 * in the function type, dependent on the class in which it is being overridde n.
3336 * @param baseFunctionType the function type that is being overridden
3337 * @param memberName the name of the member, this is used to lookup the inheri tance path of the
3338 * override
3339 * @param definingType the type that is overriding the member
3340 * @return the passed function type with any parameterized types substituted
3341 */
3342 FunctionType substituteTypeArgumentsInMemberFromInheritance(FunctionType baseF unctionType, String memberName, InterfaceType definingType) {
3343 if (baseFunctionType == null) {
3344 return baseFunctionType;
3345 }
3346 Queue<InterfaceType> inheritancePath = new Queue<InterfaceType>();
3347 computeInheritancePath(inheritancePath, definingType, memberName);
3348 if (inheritancePath == null || inheritancePath.length < 2) {
3349 return baseFunctionType;
3350 }
3351 FunctionType functionTypeToReturn = baseFunctionType;
3352 InterfaceType lastType = inheritancePath.removeLast();
3353 while (inheritancePath.length > 0) {
3354 List<Type2> paramTypes = TypeVariableTypeImpl.getTypes(lastType.element.ty peVariables);
3355 List<Type2> argTypes = lastType.typeArguments;
3356 functionTypeToReturn = functionTypeToReturn.substitute2(argTypes, paramTyp es);
3357 lastType = inheritancePath.removeLast();
3358 }
3359 return functionTypeToReturn;
3360 }
3361
3362 /**
3363 * Compute and return a mapping between the set of all string names of the mem bers inherited from
3364 * the passed {@link ClassElement} superclass hierarchy, and the associated{@l ink ExecutableElement}.
3365 * @param classElt the class element to query
3366 * @param visitedClasses a set of visited classes passed back into this method when it calls
3367 * itself recursively
3368 * @return a mapping between the set of all string names of the members inheri ted from the passed{@link ClassElement} superclass hierarchy, and the associated {@link ExecutableElement}
3369 */
3370 Map<String, ExecutableElement> computeClassChainLookupMap(ClassElement classEl t, Set<ClassElement> visitedClasses) {
3371 Map<String, ExecutableElement> resultMap = _classLookup[classElt];
3372 if (resultMap != null) {
3373 return resultMap;
3374 } else {
3375 resultMap = new Map<String, ExecutableElement>();
3376 }
3377 ClassElement superclassElt = null;
3378 InterfaceType supertype2 = classElt.supertype;
3379 if (supertype2 != null) {
3380 superclassElt = supertype2.element;
3381 } else {
3382 _classLookup[classElt] = resultMap;
3383 return resultMap;
3384 }
3385 if (superclassElt != null) {
3386 if (!visitedClasses.contains(superclassElt)) {
3387 javaSetAdd(visitedClasses, classElt);
3388 resultMap = new Map<String, ExecutableElement>.from(computeClassChainLoo kupMap(superclassElt, visitedClasses));
3389 } else {
3390 _classLookup[superclassElt] = resultMap;
3391 return resultMap;
3392 }
3393 recordMapWithClassMembers(resultMap, superclassElt);
3394 }
3395 List<InterfaceType> mixins2 = classElt.mixins;
3396 for (int i = mixins2.length - 1; i >= 0; i--) {
3397 ClassElement mixinElement = mixins2[i].element;
3398 if (mixinElement != null) {
3399 recordMapWithClassMembers(resultMap, mixinElement);
3400 }
3401 }
3402 _classLookup[classElt] = resultMap;
3403 return resultMap;
3404 }
3405
3406 /**
3407 * Compute and return the inheritance path given the context of a type and a m ember that is
3408 * overridden in the inheritance path (for which the type is in the path).
3409 * @param chain the inheritance path that is built up as this method calls its elf recursively,
3410 * when this method is called an empty {@link LinkedList} should be provided
3411 * @param currentType the current type in the inheritance path
3412 * @param memberName the name of the member that is being looked up the inheri tance path
3413 */
3414 void computeInheritancePath(Queue<InterfaceType> chain, InterfaceType currentT ype, String memberName) {
3415 chain.add(currentType);
3416 ClassElement classElt = currentType.element;
3417 InterfaceType supertype2 = classElt.supertype;
3418 if (supertype2 == null) {
3419 return;
3420 }
3421 if (chain.length != 1) {
3422 if (lookupMemberInClass(classElt, memberName) != null) {
3423 return;
3424 }
3425 }
3426 List<InterfaceType> mixins2 = classElt.mixins;
3427 for (int i = mixins2.length - 1; i >= 0; i--) {
3428 ClassElement mixinElement = mixins2[i].element;
3429 if (mixinElement != null) {
3430 ExecutableElement elt = lookupMemberInClass(mixinElement, memberName);
3431 if (elt != null) {
3432 chain.add(mixins2[i]);
3433 return;
3434 }
3435 }
3436 }
3437 ClassElement superclassElt = supertype2.element;
3438 if (lookupMember(superclassElt, memberName) != null) {
3439 computeInheritancePath(chain, supertype2, memberName);
3440 return;
3441 }
3442 List<InterfaceType> interfaces2 = classElt.interfaces;
3443 for (InterfaceType interfaceType in interfaces2) {
3444 ClassElement interfaceElement = interfaceType.element;
3445 if (interfaceElement != null && lookupMember(interfaceElement, memberName) != null) {
3446 computeInheritancePath(chain, interfaceType, memberName);
3447 return;
3448 }
3449 }
3450 }
3451
3452 /**
3453 * Compute and return a mapping between the set of all string names of the mem bers inherited from
3454 * the passed {@link ClassElement} interface hierarchy, and the associated{@li nk ExecutableElement}.
3455 * @param classElt the class element to query
3456 * @param visitedInterfaces a set of visited classes passed back into this met hod when it calls
3457 * itself recursively
3458 * @return a mapping between the set of all string names of the members inheri ted from the passed{@link ClassElement} interface hierarchy, and the associated {@link ExecutableElement}
3459 */
3460 Map<String, ExecutableElement> computeInterfaceLookupMap(ClassElement classElt , Set<ClassElement> visitedInterfaces) {
3461 Map<String, ExecutableElement> resultMap = _interfaceLookup[classElt];
3462 if (resultMap != null) {
3463 return resultMap;
3464 } else {
3465 resultMap = new Map<String, ExecutableElement>();
3466 }
3467 List<InterfaceType> interfaces2 = classElt.interfaces;
3468 if (interfaces2.length == 0) {
3469 _interfaceLookup[classElt] = resultMap;
3470 return resultMap;
3471 }
3472 List<Map<String, ExecutableElement>> lookupMaps = new List<Map<String, Execu tableElement>>();
3473 for (InterfaceType interfaceType in interfaces2) {
3474 ClassElement interfaceElement = interfaceType.element;
3475 if (interfaceElement != null) {
3476 if (!visitedInterfaces.contains(interfaceElement)) {
3477 javaSetAdd(visitedInterfaces, interfaceElement);
3478 lookupMaps.add(computeInterfaceLookupMap(interfaceElement, visitedInte rfaces));
3479 } else {
3480 Map<String, ExecutableElement> map = _interfaceLookup[classElt];
3481 if (map != null) {
3482 lookupMaps.add(map);
3483 } else {
3484 _interfaceLookup[interfaceElement] = resultMap;
3485 return resultMap;
3486 }
3487 }
3488 }
3489 }
3490 if (lookupMaps.length == 0) {
3491 _interfaceLookup[classElt] = resultMap;
3492 return resultMap;
3493 }
3494 Map<String, Set<ExecutableElement>> unionMap = new Map<String, Set<Executabl eElement>>();
3495 for (Map<String, ExecutableElement> lookupMap in lookupMaps) {
3496 for (MapEntry<String, ExecutableElement> entry in getMapEntrySet(lookupMap )) {
3497 String key = entry.getKey();
3498 if (!unionMap.containsKey(key)) {
3499 Set<ExecutableElement> set = new Set<ExecutableElement>();
3500 javaSetAdd(set, entry.getValue());
3501 unionMap[key] = set;
3502 } else {
3503 javaSetAdd(unionMap[key], entry.getValue());
3504 }
3505 }
3506 }
3507 for (InterfaceType interfaceType in interfaces2) {
3508 ClassElement interfaceElement = interfaceType.element;
3509 if (interfaceElement != null) {
3510 List<MethodElement> methods2 = interfaceElement.methods;
3511 for (MethodElement method in methods2) {
3512 if (method.isAccessibleIn(_library) && !method.isStatic()) {
3513 String key = method.name;
3514 if (!unionMap.containsKey(key)) {
3515 Set<ExecutableElement> set = new Set<ExecutableElement>();
3516 javaSetAdd(set, method);
3517 unionMap[key] = set;
3518 } else {
3519 javaSetAdd(unionMap[key], method);
3520 }
3521 }
3522 }
3523 List<PropertyAccessorElement> accessors2 = interfaceElement.accessors;
3524 for (PropertyAccessorElement accessor in accessors2) {
3525 if (accessor.isAccessibleIn(_library) && !accessor.isStatic()) {
3526 String key = accessor.name;
3527 if (!unionMap.containsKey(key)) {
3528 Set<ExecutableElement> set = new Set<ExecutableElement>();
3529 javaSetAdd(set, accessor);
3530 unionMap[key] = set;
3531 } else {
3532 javaSetAdd(unionMap[key], accessor);
3533 }
3534 }
3535 }
3536 }
3537 }
3538 for (MapEntry<String, Set<ExecutableElement>> entry in getMapEntrySet(unionM ap)) {
3539 String key = entry.getKey();
3540 Set<ExecutableElement> set = entry.getValue();
3541 int numOfEltsWithMatchingNames = set.length;
3542 if (numOfEltsWithMatchingNames == 1) {
3543 resultMap[key] = new JavaIterator(set).next();
3544 } else {
3545 bool allMethods = true;
3546 bool allSetters = true;
3547 bool allGetters = true;
3548 for (ExecutableElement executableElement in set) {
3549 if (executableElement is PropertyAccessorElement) {
3550 allMethods = false;
3551 if (((executableElement as PropertyAccessorElement)).isSetter()) {
3552 allGetters = false;
3553 } else {
3554 allSetters = false;
3555 }
3556 } else {
3557 allGetters = false;
3558 allSetters = false;
3559 }
3560 }
3561 if (allMethods || allGetters || allSetters) {
3562 List<ExecutableElement> elements = new List.from(set);
3563 List<FunctionType> executableElementTypes = new List<FunctionType>(num OfEltsWithMatchingNames);
3564 for (int i = 0; i < numOfEltsWithMatchingNames; i++) {
3565 executableElementTypes[i] = elements[i].type;
3566 }
3567 bool foundSubtypeOfAllTypes = true;
3568 for (int i = 0; i < numOfEltsWithMatchingNames; i++) {
3569 FunctionType subtype = executableElementTypes[i];
3570 if (subtype == null) {
3571 continue;
3572 }
3573 bool subtypeOfAllTypes = true;
3574 for (int j = 0; j < numOfEltsWithMatchingNames && subtypeOfAllTypes; j++) {
3575 if (i != j) {
3576 if (!subtype.isSubtypeOf(executableElementTypes[j])) {
3577 subtypeOfAllTypes = false;
3578 foundSubtypeOfAllTypes = false;
3579 break;
3580 }
3581 }
3582 }
3583 if (subtypeOfAllTypes) {
3584 resultMap[key] = elements[i];
3585 break;
3586 }
3587 }
3588 if (!foundSubtypeOfAllTypes) {
3589 reportError(classElt, classElt.nameOffset, classElt.displayName.leng th, StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [key]);
3590 }
3591 } else {
3592 if (!allMethods && !allGetters) {
3593 reportError(classElt, classElt.nameOffset, classElt.displayName.leng th, StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD, [key]);
3594 }
3595 resultMap.remove(entry.getKey());
3596 }
3597 }
3598 }
3599 _interfaceLookup[classElt] = resultMap;
3600 return resultMap;
3601 }
3602
3603 /**
3604 * Given some {@link ClassElement}, this method finds and returns the {@link E xecutableElement} of
3605 * the passed name in the class element. Static members, members in super type s and members not
3606 * accessible from the current library are not considered.
3607 * @param classElt the class element to query
3608 * @param memberName the name of the member to lookup in the class
3609 * @return the found {@link ExecutableElement}, or {@code null} if no such mem ber was found
3610 */
3611 ExecutableElement lookupMemberInClass(ClassElement classElt, String memberName ) {
3612 List<MethodElement> methods2 = classElt.methods;
3613 for (MethodElement method in methods2) {
3614 if (memberName == method.name && method.isAccessibleIn(_library) && !metho d.isStatic()) {
3615 return method;
3616 }
3617 }
3618 List<PropertyAccessorElement> accessors2 = classElt.accessors;
3619 for (PropertyAccessorElement accessor in accessors2) {
3620 if (memberName == accessor.name && accessor.isAccessibleIn(_library) && !a ccessor.isStatic()) {
3621 return accessor;
3622 }
3623 }
3624 return null;
3625 }
3626
3627 /**
3628 * Record the passed map with the set of all members (methods, getters and set ters) in the class
3629 * into the passed map.
3630 * @param map some non-{@code null}
3631 * @param classElt the class element that will be recorded into the passed map
3632 */
3633 void recordMapWithClassMembers(Map<String, ExecutableElement> map, ClassElemen t classElt) {
3634 List<MethodElement> methods2 = classElt.methods;
3635 for (MethodElement method in methods2) {
3636 if (method.isAccessibleIn(_library) && !method.isStatic()) {
3637 map[method.name] = method;
3638 }
3639 }
3640 List<PropertyAccessorElement> accessors2 = classElt.accessors;
3641 for (PropertyAccessorElement accessor in accessors2) {
3642 if (accessor.isAccessibleIn(_library) && !accessor.isStatic()) {
3643 map[accessor.name] = accessor;
3644 }
3645 }
3646 }
3647
3648 /**
3649 * This method is used to report errors on when they are found computing inher itance information.
3650 * See {@link ErrorVerifier#checkForInconsistentMethodInheritance()} to see wh ere these generated
3651 * error codes are reported back into the analysis engine.
3652 * @param classElt the location of the source for which the exception occurred
3653 * @param offset the offset of the location of the error
3654 * @param length the length of the location of the error
3655 * @param errorCode the error code to be associated with this error
3656 * @param arguments the arguments used to build the error message
3657 */
3658 void reportError(ClassElement classElt, int offset, int length, ErrorCode erro rCode, List<Object> arguments) {
3659 Set<AnalysisError> errorSet = _errorsInClassElement[classElt];
3660 if (errorSet == null) {
3661 errorSet = new Set<AnalysisError>();
3662 _errorsInClassElement[classElt] = errorSet;
3663 }
3664 javaSetAdd(errorSet, new AnalysisError.con2(classElt.source, offset, length, errorCode, arguments));
3665 }
3666 }
3667
2561 /** 3668 /**
2562 * Instances of the class {@code Library} represent the data about a single libr ary during the 3669 * Instances of the class {@code Library} represent the data about a single libr ary during the
2563 * resolution of some (possibly different) library. They are not intended to be used except during 3670 * resolution of some (possibly different) library. They are not intended to be used except during
2564 * the resolution process. 3671 * the resolution process.
2565 * @coverage dart.engine.resolver 3672 * @coverage dart.engine.resolver
2566 */ 3673 */
2567 class Library { 3674 class Library {
3675
2568 /** 3676 /**
2569 * The analysis context in which this library is being analyzed. 3677 * The analysis context in which this library is being analyzed.
2570 */ 3678 */
2571 InternalAnalysisContext _analysisContext; 3679 InternalAnalysisContext _analysisContext;
3680
3681 /**
3682 * The inheritance manager which is used for this member lookups in this libra ry.
3683 */
3684 InheritanceManager _inheritanceManager;
3685
2572 /** 3686 /**
2573 * The listener to which analysis errors will be reported. 3687 * The listener to which analysis errors will be reported.
2574 */ 3688 */
2575 AnalysisErrorListener _errorListener; 3689 AnalysisErrorListener _errorListener;
3690
2576 /** 3691 /**
2577 * The source specifying the defining compilation unit of this library. 3692 * The source specifying the defining compilation unit of this library.
2578 */ 3693 */
2579 Source _librarySource; 3694 Source _librarySource;
3695
2580 /** 3696 /**
2581 * The library element representing this library. 3697 * The library element representing this library.
2582 */ 3698 */
2583 LibraryElementImpl _libraryElement; 3699 LibraryElementImpl _libraryElement;
3700
2584 /** 3701 /**
2585 * A list containing all of the libraries that are imported into this library. 3702 * A list containing all of the libraries that are imported into this library.
2586 */ 3703 */
2587 Map<ImportDirective, Library> _importedLibraries = new Map<ImportDirective, Li brary>(); 3704 Map<ImportDirective, Library> _importedLibraries = new Map<ImportDirective, Li brary>();
3705
3706 /**
3707 * A table mapping URI-based directive to the actual URI value.
3708 */
3709 Map<UriBasedDirective, String> _directiveUris = new Map<UriBasedDirective, Str ing>();
3710
2588 /** 3711 /**
2589 * A flag indicating whether this library explicitly imports core. 3712 * A flag indicating whether this library explicitly imports core.
2590 */ 3713 */
2591 bool _explicitlyImportsCore = false; 3714 bool _explicitlyImportsCore = false;
3715
2592 /** 3716 /**
2593 * A list containing all of the libraries that are exported from this library. 3717 * A list containing all of the libraries that are exported from this library.
2594 */ 3718 */
2595 Map<ExportDirective, Library> _exportedLibraries = new Map<ExportDirective, Li brary>(); 3719 Map<ExportDirective, Library> _exportedLibraries = new Map<ExportDirective, Li brary>();
3720
2596 /** 3721 /**
2597 * A table mapping the sources for the compilation units in this library to th eir corresponding 3722 * A table mapping the sources for the compilation units in this library to th eir corresponding
2598 * AST structures. 3723 * AST structures.
2599 */ 3724 */
2600 Map<Source, CompilationUnit> _astMap = new Map<Source, CompilationUnit>(); 3725 Map<Source, CompilationUnit> _astMap = new Map<Source, CompilationUnit>();
3726
2601 /** 3727 /**
2602 * The library scope used when resolving elements within this library's compil ation units. 3728 * The library scope used when resolving elements within this library's compil ation units.
2603 */ 3729 */
2604 LibraryScope _libraryScope; 3730 LibraryScope _libraryScope;
3731
2605 /** 3732 /**
2606 * Initialize a newly created data holder that can maintain the data associate d with a library. 3733 * Initialize a newly created data holder that can maintain the data associate d with a library.
2607 * @param analysisContext the analysis context in which this library is being analyzed 3734 * @param analysisContext the analysis context in which this library is being analyzed
2608 * @param errorListener the listener to which analysis errors will be reported 3735 * @param errorListener the listener to which analysis errors will be reported
2609 * @param librarySource the source specifying the defining compilation unit of this library 3736 * @param librarySource the source specifying the defining compilation unit of this library
2610 */ 3737 */
2611 Library(InternalAnalysisContext analysisContext, AnalysisErrorListener errorLi stener, Source librarySource) { 3738 Library(InternalAnalysisContext analysisContext, AnalysisErrorListener errorLi stener, Source librarySource) {
2612 this._analysisContext = analysisContext; 3739 this._analysisContext = analysisContext;
2613 this._errorListener = errorListener; 3740 this._errorListener = errorListener;
2614 this._librarySource = librarySource; 3741 this._librarySource = librarySource;
2615 this._libraryElement = analysisContext.getLibraryElement(librarySource) as L ibraryElementImpl; 3742 this._libraryElement = analysisContext.getLibraryElement(librarySource) as L ibraryElementImpl;
2616 } 3743 }
3744
2617 /** 3745 /**
2618 * Record that the given library is exported from this library. 3746 * Record that the given library is exported from this library.
2619 * @param importLibrary the library that is exported from this library 3747 * @param importLibrary the library that is exported from this library
2620 */ 3748 */
2621 void addExport(ExportDirective directive, Library exportLibrary) { 3749 void addExport(ExportDirective directive, Library exportLibrary) {
2622 _exportedLibraries[directive] = exportLibrary; 3750 _exportedLibraries[directive] = exportLibrary;
2623 } 3751 }
3752
2624 /** 3753 /**
2625 * Record that the given library is imported into this library. 3754 * Record that the given library is imported into this library.
2626 * @param importLibrary the library that is imported into this library 3755 * @param importLibrary the library that is imported into this library
2627 */ 3756 */
2628 void addImport(ImportDirective directive, Library importLibrary) { 3757 void addImport(ImportDirective directive, Library importLibrary) {
2629 _importedLibraries[directive] = importLibrary; 3758 _importedLibraries[directive] = importLibrary;
2630 } 3759 }
3760
2631 /** 3761 /**
2632 * Return the AST structure associated with the given source. 3762 * Return the AST structure associated with the given source.
2633 * @param source the source representing the compilation unit whose AST is to be returned 3763 * @param source the source representing the compilation unit whose AST is to be returned
2634 * @return the AST structure associated with the given source 3764 * @return the AST structure associated with the given source
2635 * @throws AnalysisException if an AST structure could not be created for the compilation unit 3765 * @throws AnalysisException if an AST structure could not be created for the compilation unit
2636 */ 3766 */
2637 CompilationUnit getAST(Source source) { 3767 CompilationUnit getAST(Source source) {
2638 CompilationUnit unit = _astMap[source]; 3768 CompilationUnit unit = _astMap[source];
2639 if (unit == null) { 3769 if (unit == null) {
2640 unit = _analysisContext.computeResolvableCompilationUnit(source); 3770 unit = _analysisContext.computeResolvableCompilationUnit(source);
2641 _astMap[source] = unit; 3771 _astMap[source] = unit;
2642 } 3772 }
2643 return unit; 3773 return unit;
2644 } 3774 }
3775
2645 /** 3776 /**
2646 * Return a collection containing the sources for the compilation units in thi s library, including 3777 * Return a collection containing the sources for the compilation units in thi s library, including
2647 * the defining compilation unit. 3778 * the defining compilation unit.
2648 * @return the sources for the compilation units in this library 3779 * @return the sources for the compilation units in this library
2649 */ 3780 */
2650 Set<Source> get compilationUnitSources => _astMap.keys.toSet(); 3781 Set<Source> get compilationUnitSources => _astMap.keys.toSet();
3782
2651 /** 3783 /**
2652 * Return the AST structure associated with the defining compilation unit for this library. 3784 * Return the AST structure associated with the defining compilation unit for this library.
2653 * @return the AST structure associated with the defining compilation unit for this library 3785 * @return the AST structure associated with the defining compilation unit for this library
2654 * @throws AnalysisException if an AST structure could not be created for the defining compilation 3786 * @throws AnalysisException if an AST structure could not be created for the defining compilation
2655 * unit 3787 * unit
2656 */ 3788 */
2657 CompilationUnit get definingCompilationUnit => getAST(librarySource); 3789 CompilationUnit get definingCompilationUnit => getAST(librarySource);
3790
2658 /** 3791 /**
2659 * Return {@code true} if this library explicitly imports core. 3792 * Return {@code true} if this library explicitly imports core.
2660 * @return {@code true} if this library explicitly imports core 3793 * @return {@code true} if this library explicitly imports core
2661 */ 3794 */
2662 bool get explicitlyImportsCore => _explicitlyImportsCore; 3795 bool get explicitlyImportsCore => _explicitlyImportsCore;
3796
2663 /** 3797 /**
2664 * Return the library exported by the given directive. 3798 * Return the library exported by the given directive.
2665 * @param directive the directive that exports the library to be returned 3799 * @param directive the directive that exports the library to be returned
2666 * @return the library exported by the given directive 3800 * @return the library exported by the given directive
2667 */ 3801 */
2668 Library getExport(ExportDirective directive) => _exportedLibraries[directive]; 3802 Library getExport(ExportDirective directive) => _exportedLibraries[directive];
3803
2669 /** 3804 /**
2670 * Return an array containing the libraries that are exported from this librar y. 3805 * Return an array containing the libraries that are exported from this librar y.
2671 * @return an array containing the libraries that are exported from this libra ry 3806 * @return an array containing the libraries that are exported from this libra ry
2672 */ 3807 */
2673 List<Library> get exports { 3808 List<Library> get exports {
2674 Set<Library> libraries = new Set<Library>(); 3809 Set<Library> libraries = new Set<Library>();
2675 libraries.addAll(_exportedLibraries.values); 3810 libraries.addAll(_exportedLibraries.values);
2676 return new List.from(libraries); 3811 return new List.from(libraries);
2677 } 3812 }
3813
2678 /** 3814 /**
2679 * Return the library imported by the given directive. 3815 * Return the library imported by the given directive.
2680 * @param directive the directive that imports the library to be returned 3816 * @param directive the directive that imports the library to be returned
2681 * @return the library imported by the given directive 3817 * @return the library imported by the given directive
2682 */ 3818 */
2683 Library getImport(ImportDirective directive) => _importedLibraries[directive]; 3819 Library getImport(ImportDirective directive) => _importedLibraries[directive];
3820
2684 /** 3821 /**
2685 * Return an array containing the libraries that are imported into this librar y. 3822 * Return an array containing the libraries that are imported into this librar y.
2686 * @return an array containing the libraries that are imported into this libra ry 3823 * @return an array containing the libraries that are imported into this libra ry
2687 */ 3824 */
2688 List<Library> get imports { 3825 List<Library> get imports {
2689 Set<Library> libraries = new Set<Library>(); 3826 Set<Library> libraries = new Set<Library>();
2690 libraries.addAll(_importedLibraries.values); 3827 libraries.addAll(_importedLibraries.values);
2691 return new List.from(libraries); 3828 return new List.from(libraries);
2692 } 3829 }
3830
2693 /** 3831 /**
2694 * Return an array containing the libraries that are either imported or export ed from this 3832 * Return an array containing the libraries that are either imported or export ed from this
2695 * library. 3833 * library.
2696 * @return the libraries that are either imported or exported from this librar y 3834 * @return the libraries that are either imported or exported from this librar y
2697 */ 3835 */
2698 List<Library> get importsAndExports { 3836 List<Library> get importsAndExports {
2699 Set<Library> libraries = new Set<Library>(); 3837 Set<Library> libraries = new Set<Library>();
2700 libraries.addAll(_importedLibraries.values); 3838 libraries.addAll(_importedLibraries.values);
2701 libraries.addAll(_exportedLibraries.values); 3839 libraries.addAll(_exportedLibraries.values);
2702 return new List.from(libraries); 3840 return new List.from(libraries);
2703 } 3841 }
3842
3843 /**
3844 * Return the inheritance manager for this library.
3845 * @return the inheritance manager for this library
3846 */
3847 InheritanceManager get inheritanceManager {
3848 if (_inheritanceManager == null) {
3849 return _inheritanceManager = new InheritanceManager(_libraryElement);
3850 }
3851 return _inheritanceManager;
3852 }
3853
2704 /** 3854 /**
2705 * Return the library element representing this library, creating it if necess ary. 3855 * Return the library element representing this library, creating it if necess ary.
2706 * @return the library element representing this library 3856 * @return the library element representing this library
2707 */ 3857 */
2708 LibraryElementImpl get libraryElement { 3858 LibraryElementImpl get libraryElement {
2709 if (_libraryElement == null) { 3859 if (_libraryElement == null) {
2710 try { 3860 try {
2711 _libraryElement = _analysisContext.computeLibraryElement(_librarySource) as LibraryElementImpl; 3861 _libraryElement = _analysisContext.computeLibraryElement(_librarySource) as LibraryElementImpl;
2712 } on AnalysisException catch (exception) { 3862 } on AnalysisException catch (exception) {
2713 AnalysisEngine.instance.logger.logError2("Could not compute ilbrary elem ent for ${_librarySource.fullName}", exception); 3863 AnalysisEngine.instance.logger.logError2("Could not compute ilbrary elem ent for ${_librarySource.fullName}", exception);
2714 } 3864 }
2715 } 3865 }
2716 return _libraryElement; 3866 return _libraryElement;
2717 } 3867 }
3868
2718 /** 3869 /**
2719 * Return the library scope used when resolving elements within this library's compilation units. 3870 * Return the library scope used when resolving elements within this library's compilation units.
2720 * @return the library scope used when resolving elements within this library' s compilation units 3871 * @return the library scope used when resolving elements within this library' s compilation units
2721 */ 3872 */
2722 LibraryScope get libraryScope { 3873 LibraryScope get libraryScope {
2723 if (_libraryScope == null) { 3874 if (_libraryScope == null) {
2724 _libraryScope = new LibraryScope(_libraryElement, _errorListener); 3875 _libraryScope = new LibraryScope(_libraryElement, _errorListener);
2725 } 3876 }
2726 return _libraryScope; 3877 return _libraryScope;
2727 } 3878 }
3879
2728 /** 3880 /**
2729 * Return the source specifying the defining compilation unit of this library. 3881 * Return the source specifying the defining compilation unit of this library.
2730 * @return the source specifying the defining compilation unit of this library 3882 * @return the source specifying the defining compilation unit of this library
2731 */ 3883 */
2732 Source get librarySource => _librarySource; 3884 Source get librarySource => _librarySource;
3885
2733 /** 3886 /**
2734 * Return the result of resolving the given URI against the URI of the library , or {@code null} if 3887 * Return the result of resolving the URI of the given URI-based directive aga inst the URI of the
2735 * the URI is not valid. If the URI is not valid, report the error. 3888 * library, or {@code null} if the URI is not valid. If the URI is not valid, report the error.
2736 * @param uriLiteral the string literal specifying the URI to be resolved 3889 * @param directive the directive which URI should be resolved
2737 * @return the result of resolving the given URI against the URI of the librar y 3890 * @return the result of resolving the URI against the URI of the library
2738 */ 3891 */
2739 Source getSource(StringLiteral uriLiteral) { 3892 Source getSource(UriBasedDirective directive) {
3893 StringLiteral uriLiteral = directive.uri;
2740 if (uriLiteral is StringInterpolation) { 3894 if (uriLiteral is StringInterpolation) {
2741 _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.o ffset, uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION, [])); 3895 _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.o ffset, uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION, []));
2742 return null; 3896 return null;
2743 } 3897 }
2744 Source source = getSource2(getStringValue(uriLiteral)); 3898 String uriContent = uriLiteral.stringValue.trim();
2745 if (source == null || !source.exists()) { 3899 _directiveUris[directive] = uriContent;
2746 _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.o ffset, uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriLiteral.toSource ()])); 3900 try {
3901 parseUriWithException(uriContent);
3902 Source source = getSource2(uriContent);
3903 if (source == null || !source.exists()) {
3904 _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral .offset, uriLiteral.length, CompileTimeErrorCode.URI_DOES_NOT_EXIST, [uriContent ]));
3905 }
3906 return source;
3907 } on URISyntaxException catch (exception) {
3908 _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.o ffset, uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent]));
2747 } 3909 }
2748 return source; 3910 return null;
2749 } 3911 }
3912
3913 /**
3914 * Returns the URI value of the given directive.
3915 */
3916 String getUri(UriBasedDirective directive) => _directiveUris[directive];
3917
3918 /**
3919 * Set the AST structure associated with the defining compilation unit for thi s library to the
3920 * given AST structure.
3921 * @param unit the AST structure associated with the defining compilation unit for this library
3922 */
3923 void set definingCompilationUnit(CompilationUnit unit) {
3924 _astMap[librarySource] = unit;
3925 }
3926
2750 /** 3927 /**
2751 * Set whether this library explicitly imports core to match the given value. 3928 * Set whether this library explicitly imports core to match the given value.
2752 * @param explicitlyImportsCore {@code true} if this library explicitly import s core 3929 * @param explicitlyImportsCore {@code true} if this library explicitly import s core
2753 */ 3930 */
2754 void set explicitlyImportsCore(bool explicitlyImportsCore2) { 3931 void set explicitlyImportsCore(bool explicitlyImportsCore2) {
2755 this._explicitlyImportsCore = explicitlyImportsCore2; 3932 this._explicitlyImportsCore = explicitlyImportsCore2;
2756 } 3933 }
3934
2757 /** 3935 /**
2758 * Set the library element representing this library to the given library elem ent. 3936 * Set the library element representing this library to the given library elem ent.
2759 * @param libraryElement the library element representing this library 3937 * @param libraryElement the library element representing this library
2760 */ 3938 */
2761 void set libraryElement(LibraryElementImpl libraryElement2) { 3939 void set libraryElement(LibraryElementImpl libraryElement2) {
2762 this._libraryElement = libraryElement2; 3940 this._libraryElement = libraryElement2;
3941 if (_inheritanceManager != null) {
3942 _inheritanceManager.libraryElement = libraryElement2;
3943 }
2763 } 3944 }
2764 String toString() => _librarySource.shortName; 3945 String toString() => _librarySource.shortName;
2765 /** 3946
2766 * Append the value of the given string literal to the given string builder.
2767 * @param builder the builder to which the string's value is to be appended
2768 * @param literal the string literal whose value is to be appended to the buil der
2769 * @throws IllegalArgumentException if the string is not a constant string wit hout any string
2770 * interpolation
2771 */
2772 void appendStringValue(JavaStringBuilder builder, StringLiteral literal) {
2773 if (literal is SimpleStringLiteral) {
2774 builder.append(((literal as SimpleStringLiteral)).value);
2775 } else if (literal is AdjacentStrings) {
2776 for (StringLiteral stringLiteral in ((literal as AdjacentStrings)).strings ) {
2777 appendStringValue(builder, stringLiteral);
2778 }
2779 } else {
2780 throw new IllegalArgumentException();
2781 }
2782 }
2783 /** 3947 /**
2784 * Return the result of resolving the given URI against the URI of the library , or {@code null} if 3948 * Return the result of resolving the given URI against the URI of the library , or {@code null} if
2785 * the URI is not valid. 3949 * the URI is not valid.
2786 * @param uri the URI to be resolved 3950 * @param uri the URI to be resolved
2787 * @return the result of resolving the given URI against the URI of the librar y 3951 * @return the result of resolving the given URI against the URI of the librar y
2788 */ 3952 */
2789 Source getSource2(String uri) { 3953 Source getSource2(String uri) {
2790 if (uri == null) { 3954 if (uri == null) {
2791 return null; 3955 return null;
2792 } 3956 }
2793 return _analysisContext.sourceFactory.resolveUri(_librarySource, uri); 3957 return _analysisContext.sourceFactory.resolveUri(_librarySource, uri);
2794 } 3958 }
2795 /**
2796 * Return the value of the given string literal, or {@code null} if the string is not a constant
2797 * string without any string interpolation.
2798 * @param literal the string literal whose value is to be returned
2799 * @return the value of the given string literal
2800 */
2801 String getStringValue(StringLiteral literal) {
2802 JavaStringBuilder builder = new JavaStringBuilder();
2803 try {
2804 appendStringValue(builder, literal);
2805 } on IllegalArgumentException catch (exception) {
2806 return null;
2807 }
2808 return builder.toString().trim();
2809 }
2810 } 3959 }
3960
2811 /** 3961 /**
2812 * Instances of the class {@code LibraryElementBuilder} build an element model f or a single library. 3962 * Instances of the class {@code LibraryElementBuilder} build an element model f or a single library.
2813 * @coverage dart.engine.resolver 3963 * @coverage dart.engine.resolver
2814 */ 3964 */
2815 class LibraryElementBuilder { 3965 class LibraryElementBuilder {
3966
2816 /** 3967 /**
2817 * The analysis context in which the element model will be built. 3968 * The analysis context in which the element model will be built.
2818 */ 3969 */
2819 InternalAnalysisContext _analysisContext; 3970 InternalAnalysisContext _analysisContext;
3971
2820 /** 3972 /**
2821 * The listener to which errors will be reported. 3973 * The listener to which errors will be reported.
2822 */ 3974 */
2823 AnalysisErrorListener _errorListener; 3975 AnalysisErrorListener _errorListener;
3976
2824 /** 3977 /**
2825 * The name of the function used as an entry point. 3978 * The name of the function used as an entry point.
2826 */ 3979 */
2827 static String _ENTRY_POINT_NAME = "main"; 3980 static String _ENTRY_POINT_NAME = "main";
3981
2828 /** 3982 /**
2829 * Initialize a newly created library element builder. 3983 * Initialize a newly created library element builder.
2830 * @param resolver the resolver for which the element model is being built 3984 * @param resolver the resolver for which the element model is being built
2831 */ 3985 */
2832 LibraryElementBuilder(LibraryResolver resolver) { 3986 LibraryElementBuilder(LibraryResolver resolver) {
2833 this._analysisContext = resolver.analysisContext; 3987 this._analysisContext = resolver.analysisContext;
2834 this._errorListener = resolver.errorListener; 3988 this._errorListener = resolver.errorListener;
2835 } 3989 }
3990
2836 /** 3991 /**
2837 * Build the library element for the given library. 3992 * Build the library element for the given library.
2838 * @param library the library for which an element model is to be built 3993 * @param library the library for which an element model is to be built
2839 * @return the library element that was built 3994 * @return the library element that was built
2840 * @throws AnalysisException if the analysis could not be performed 3995 * @throws AnalysisException if the analysis could not be performed
2841 */ 3996 */
2842 LibraryElementImpl buildLibrary(Library library) { 3997 LibraryElementImpl buildLibrary(Library library) {
2843 CompilationUnitBuilder builder = new CompilationUnitBuilder(); 3998 CompilationUnitBuilder builder = new CompilationUnitBuilder();
2844 Source librarySource2 = library.librarySource; 3999 Source librarySource2 = library.librarySource;
2845 CompilationUnit definingCompilationUnit2 = library.definingCompilationUnit; 4000 CompilationUnit definingCompilationUnit2 = library.definingCompilationUnit;
2846 CompilationUnitElementImpl definingCompilationUnitElement = builder.buildCom pilationUnit(librarySource2, definingCompilationUnit2); 4001 CompilationUnitElementImpl definingCompilationUnitElement = builder.buildCom pilationUnit(librarySource2, definingCompilationUnit2);
2847 NodeList<Directive> directives2 = definingCompilationUnit2.directives; 4002 NodeList<Directive> directives2 = definingCompilationUnit2.directives;
2848 LibraryIdentifier libraryNameNode = null; 4003 LibraryIdentifier libraryNameNode = null;
2849 bool hasPartDirective = false; 4004 bool hasPartDirective = false;
2850 FunctionElement entryPoint = findEntryPoint(definingCompilationUnitElement); 4005 FunctionElement entryPoint = findEntryPoint(definingCompilationUnitElement);
2851 List<Directive> directivesToResolve = new List<Directive>(); 4006 List<Directive> directivesToResolve = new List<Directive>();
2852 List<CompilationUnitElementImpl> sourcedCompilationUnits = new List<Compilat ionUnitElementImpl>(); 4007 List<CompilationUnitElementImpl> sourcedCompilationUnits = new List<Compilat ionUnitElementImpl>();
2853 for (Directive directive in directives2) { 4008 for (Directive directive in directives2) {
2854 if (directive is LibraryDirective) { 4009 if (directive is LibraryDirective) {
2855 if (libraryNameNode == null) { 4010 if (libraryNameNode == null) {
2856 libraryNameNode = ((directive as LibraryDirective)).name; 4011 libraryNameNode = ((directive as LibraryDirective)).name;
2857 directivesToResolve.add(directive); 4012 directivesToResolve.add(directive);
2858 } 4013 }
2859 } else if (directive is PartDirective) { 4014 } else if (directive is PartDirective) {
2860 hasPartDirective = true; 4015 PartDirective partDirective = directive as PartDirective;
2861 StringLiteral partUri = ((directive as PartDirective)).uri; 4016 StringLiteral partUri = partDirective.uri;
2862 Source partSource = library.getSource(partUri); 4017 Source partSource = library.getSource(partDirective);
2863 if (partSource != null && partSource.exists()) { 4018 if (partSource != null && partSource.exists()) {
4019 hasPartDirective = true;
2864 CompilationUnitElementImpl part = builder.buildCompilationUnit(partSou rce, library.getAST(partSource)); 4020 CompilationUnitElementImpl part = builder.buildCompilationUnit(partSou rce, library.getAST(partSource));
4021 part.uri = library.getUri(partDirective);
2865 String partLibraryName = getPartLibraryName(library, partSource, direc tivesToResolve); 4022 String partLibraryName = getPartLibraryName(library, partSource, direc tivesToResolve);
2866 if (partLibraryName == null) { 4023 if (partLibraryName == null) {
2867 _errorListener.onError(new AnalysisError.con2(librarySource2, partUr i.offset, partUri.length, CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSour ce()])); 4024 _errorListener.onError(new AnalysisError.con2(librarySource2, partUr i.offset, partUri.length, CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSour ce()]));
2868 } else if (libraryNameNode == null) { 4025 } else if (libraryNameNode == null) {
2869 } else if (libraryNameNode.name != partLibraryName) { 4026 } else if (libraryNameNode.name != partLibraryName) {
2870 _errorListener.onError(new AnalysisError.con2(librarySource2, partUr i.offset, partUri.length, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [libraryN ameNode.name, partLibraryName])); 4027 _errorListener.onError(new AnalysisError.con2(librarySource2, partUr i.offset, partUri.length, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [libraryN ameNode.name, partLibraryName]));
2871 } 4028 }
2872 if (entryPoint == null) { 4029 if (entryPoint == null) {
2873 entryPoint = findEntryPoint(part); 4030 entryPoint = findEntryPoint(part);
2874 } 4031 }
2875 directive.element = part; 4032 directive.element = part;
2876 sourcedCompilationUnits.add(part); 4033 sourcedCompilationUnits.add(part);
2877 } 4034 }
2878 } 4035 }
2879 } 4036 }
2880 if (hasPartDirective && libraryNameNode == null) { 4037 if (hasPartDirective && libraryNameNode == null) {
2881 _errorListener.onError(new AnalysisError.con1(librarySource2, ResolverErro rCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART, [])); 4038 _errorListener.onError(new AnalysisError.con1(librarySource2, ResolverErro rCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART, []));
2882 } 4039 }
2883 LibraryElementImpl libraryElement = new LibraryElementImpl(_analysisContext, libraryNameNode); 4040 LibraryElementImpl libraryElement = new LibraryElementImpl(_analysisContext, libraryNameNode);
2884 libraryElement.definingCompilationUnit = definingCompilationUnitElement; 4041 libraryElement.definingCompilationUnit = definingCompilationUnitElement;
2885 if (entryPoint != null) { 4042 if (entryPoint != null) {
2886 libraryElement.entryPoint = entryPoint; 4043 libraryElement.entryPoint = entryPoint;
2887 } 4044 }
4045 int sourcedUnitCount = sourcedCompilationUnits.length;
2888 libraryElement.parts = new List.from(sourcedCompilationUnits); 4046 libraryElement.parts = new List.from(sourcedCompilationUnits);
2889 for (Directive directive in directivesToResolve) { 4047 for (Directive directive in directivesToResolve) {
2890 directive.element = libraryElement; 4048 directive.element = libraryElement;
2891 } 4049 }
2892 library.libraryElement = libraryElement; 4050 library.libraryElement = libraryElement;
4051 if (sourcedUnitCount > 0) {
4052 patchTopLevelAccessors(libraryElement);
4053 }
2893 return libraryElement; 4054 return libraryElement;
2894 } 4055 }
4056
4057 /**
4058 * Add all of the non-synthetic getters and setters defined in the given compi lation unit that
4059 * have no corresponding accessor to one of the given collections.
4060 * @param getters the map to which getters are to be added
4061 * @param setters the list to which setters are to be added
4062 * @param unit the compilation unit defining the accessors that are potentiall y being added
4063 */
4064 void collectAccessors(Map<String, PropertyAccessorElement> getters, List<Prope rtyAccessorElement> setters, CompilationUnitElement unit) {
4065 for (PropertyAccessorElement accessor in unit.accessors) {
4066 if (accessor.isGetter()) {
4067 if (!accessor.isSynthetic() && accessor.correspondingSetter == null) {
4068 getters[accessor.displayName] = accessor;
4069 }
4070 } else {
4071 if (!accessor.isSynthetic() && accessor.correspondingGetter == null) {
4072 setters.add(accessor);
4073 }
4074 }
4075 }
4076 }
4077
2895 /** 4078 /**
2896 * Search the top-level functions defined in the given compilation unit for th e entry point. 4079 * Search the top-level functions defined in the given compilation unit for th e entry point.
2897 * @param element the compilation unit to be searched 4080 * @param element the compilation unit to be searched
2898 * @return the entry point that was found, or {@code null} if the compilation unit does not define 4081 * @return the entry point that was found, or {@code null} if the compilation unit does not define
2899 * an entry point 4082 * an entry point
2900 */ 4083 */
2901 FunctionElement findEntryPoint(CompilationUnitElementImpl element) { 4084 FunctionElement findEntryPoint(CompilationUnitElementImpl element) {
2902 for (FunctionElement function in element.functions) { 4085 for (FunctionElement function in element.functions) {
2903 if (function.name == _ENTRY_POINT_NAME) { 4086 if (function.name == _ENTRY_POINT_NAME) {
2904 return function; 4087 return function;
2905 } 4088 }
2906 } 4089 }
2907 return null; 4090 return null;
2908 } 4091 }
4092
2909 /** 4093 /**
2910 * Return the name of the library that the given part is declared to be a part of, or {@code null}if the part does not contain a part-of directive. 4094 * Return the name of the library that the given part is declared to be a part of, or {@code null}if the part does not contain a part-of directive.
2911 * @param library the library containing the part 4095 * @param library the library containing the part
2912 * @param partSource the source representing the part 4096 * @param partSource the source representing the part
2913 * @param directivesToResolve a list of directives that should be resolved to the library being 4097 * @param directivesToResolve a list of directives that should be resolved to the library being
2914 * built 4098 * built
2915 * @return the name of the library that the given part is declared to be a par t of 4099 * @return the name of the library that the given part is declared to be a par t of
2916 */ 4100 */
2917 String getPartLibraryName(Library library, Source partSource, List<Directive> directivesToResolve) { 4101 String getPartLibraryName(Library library, Source partSource, List<Directive> directivesToResolve) {
2918 try { 4102 try {
2919 CompilationUnit partUnit = library.getAST(partSource); 4103 CompilationUnit partUnit = library.getAST(partSource);
2920 for (Directive directive in partUnit.directives) { 4104 for (Directive directive in partUnit.directives) {
2921 if (directive is PartOfDirective) { 4105 if (directive is PartOfDirective) {
2922 directivesToResolve.add(directive); 4106 directivesToResolve.add(directive);
2923 LibraryIdentifier libraryName2 = ((directive as PartOfDirective)).libr aryName; 4107 LibraryIdentifier libraryName2 = ((directive as PartOfDirective)).libr aryName;
2924 if (libraryName2 != null) { 4108 if (libraryName2 != null) {
2925 return libraryName2.name; 4109 return libraryName2.name;
2926 } 4110 }
2927 } 4111 }
2928 } 4112 }
2929 } on AnalysisException catch (exception) { 4113 } on AnalysisException catch (exception) {
2930 } 4114 }
2931 return null; 4115 return null;
2932 } 4116 }
4117
4118 /**
4119 * Look through all of the compilation units defined for the given library, lo oking for getters
4120 * and setters that are defined in different compilation units but that have t he same names. If
4121 * any are found, make sure that they have the same variable element.
4122 * @param libraryElement the library defining the compilation units to be proc essed
4123 */
4124 void patchTopLevelAccessors(LibraryElementImpl libraryElement) {
4125 Map<String, PropertyAccessorElement> getters = new Map<String, PropertyAcces sorElement>();
4126 List<PropertyAccessorElement> setters = new List<PropertyAccessorElement>();
4127 collectAccessors(getters, setters, libraryElement.definingCompilationUnit);
4128 for (CompilationUnitElement unit in libraryElement.parts) {
4129 collectAccessors(getters, setters, unit);
4130 }
4131 for (PropertyAccessorElement setter in setters) {
4132 PropertyAccessorElement getter = getters[setter.displayName];
4133 if (getter != null) {
4134 PropertyInducingElementImpl variable2 = getter.variable as PropertyInduc ingElementImpl;
4135 variable2.setter = setter;
4136 ((setter as PropertyAccessorElementImpl)).variable = variable2;
4137 }
4138 }
4139 }
2933 } 4140 }
4141
2934 /** 4142 /**
2935 * Instances of the class {@code LibraryResolver} are used to resolve one or mor e mutually dependent 4143 * Instances of the class {@code LibraryResolver} are used to resolve one or mor e mutually dependent
2936 * libraries within a single context. 4144 * libraries within a single context.
2937 * @coverage dart.engine.resolver 4145 * @coverage dart.engine.resolver
2938 */ 4146 */
2939 class LibraryResolver { 4147 class LibraryResolver {
4148
2940 /** 4149 /**
2941 * The analysis context in which the libraries are being analyzed. 4150 * The analysis context in which the libraries are being analyzed.
2942 */ 4151 */
2943 InternalAnalysisContext _analysisContext; 4152 InternalAnalysisContext _analysisContext;
4153
2944 /** 4154 /**
2945 * The listener to which analysis errors will be reported, this error listener is either 4155 * The listener to which analysis errors will be reported, this error listener is either
2946 * references {@link #recordingErrorListener}, or it unions the passed{@link A nalysisErrorListener} with the {@link #recordingErrorListener}. 4156 * references {@link #recordingErrorListener}, or it unions the passed{@link A nalysisErrorListener} with the {@link #recordingErrorListener}.
2947 */ 4157 */
2948 AnalysisErrorListener _errorListener; 4158 RecordingErrorListener _errorListener;
2949 /** 4159
2950 * This error listener is used by the resolver to be able to call the listener and get back the
2951 * set of errors for each {@link Source}.
2952 * @see #recordResults()
2953 */
2954 RecordingErrorListener _recordingErrorListener;
2955 /** 4160 /**
2956 * A source object representing the core library (dart:core). 4161 * A source object representing the core library (dart:core).
2957 */ 4162 */
2958 Source _coreLibrarySource; 4163 Source _coreLibrarySource;
4164
2959 /** 4165 /**
2960 * The object representing the core library. 4166 * The object representing the core library.
2961 */ 4167 */
2962 Library _coreLibrary; 4168 Library _coreLibrary;
4169
2963 /** 4170 /**
2964 * The object used to access the types from the core library. 4171 * The object used to access the types from the core library.
2965 */ 4172 */
2966 TypeProvider _typeProvider; 4173 TypeProvider _typeProvider;
4174
2967 /** 4175 /**
2968 * A table mapping library sources to the information being maintained for tho se libraries. 4176 * A table mapping library sources to the information being maintained for tho se libraries.
2969 */ 4177 */
2970 Map<Source, Library> _libraryMap = new Map<Source, Library>(); 4178 Map<Source, Library> _libraryMap = new Map<Source, Library>();
4179
2971 /** 4180 /**
2972 * A collection containing the libraries that are being resolved together. 4181 * A collection containing the libraries that are being resolved together.
2973 */ 4182 */
2974 Set<Library> _librariesInCycles; 4183 Set<Library> _librariesInCycles;
4184
2975 /** 4185 /**
2976 * Initialize a newly created library resolver to resolve libraries within the given context. 4186 * Initialize a newly created library resolver to resolve libraries within the given context.
2977 * @param analysisContext the analysis context in which the library is being a nalyzed 4187 * @param analysisContext the analysis context in which the library is being a nalyzed
2978 */ 4188 */
2979 LibraryResolver.con1(InternalAnalysisContext analysisContext) { 4189 LibraryResolver(InternalAnalysisContext analysisContext) {
2980 _jtd_constructor_264_impl(analysisContext); 4190 this._analysisContext = analysisContext;
4191 this._errorListener = new RecordingErrorListener();
4192 _coreLibrarySource = analysisContext.sourceFactory.forUri(DartSdk.DART_CORE) ;
2981 } 4193 }
2982 _jtd_constructor_264_impl(InternalAnalysisContext analysisContext) { 4194
2983 _jtd_constructor_265_impl(analysisContext, null);
2984 }
2985 /**
2986 * Initialize a newly created library resolver to resolve libraries within the given context.
2987 * @param analysisContext the analysis context in which the library is being a nalyzed
2988 * @param errorListener the listener to which analysis errors will be reported
2989 */
2990 LibraryResolver.con2(InternalAnalysisContext analysisContext2, AnalysisErrorLi stener additionalAnalysisErrorListener) {
2991 _jtd_constructor_265_impl(analysisContext2, additionalAnalysisErrorListener) ;
2992 }
2993 _jtd_constructor_265_impl(InternalAnalysisContext analysisContext2, AnalysisEr rorListener additionalAnalysisErrorListener) {
2994 this._analysisContext = analysisContext2;
2995 this._recordingErrorListener = new RecordingErrorListener();
2996 if (additionalAnalysisErrorListener == null) {
2997 this._errorListener = _recordingErrorListener;
2998 } else {
2999 this._errorListener = new AnalysisErrorListener_9(this, additionalAnalysis ErrorListener);
3000 }
3001 _coreLibrarySource = analysisContext2.sourceFactory.forUri(DartSdk.DART_CORE );
3002 }
3003 /** 4195 /**
3004 * Return the analysis context in which the libraries are being analyzed. 4196 * Return the analysis context in which the libraries are being analyzed.
3005 * @return the analysis context in which the libraries are being analyzed 4197 * @return the analysis context in which the libraries are being analyzed
3006 */ 4198 */
3007 InternalAnalysisContext get analysisContext => _analysisContext; 4199 InternalAnalysisContext get analysisContext => _analysisContext;
4200
3008 /** 4201 /**
3009 * Return the listener to which analysis errors will be reported. 4202 * Return the listener to which analysis errors will be reported.
3010 * @return the listener to which analysis errors will be reported 4203 * @return the listener to which analysis errors will be reported
3011 */ 4204 */
3012 AnalysisErrorListener get errorListener => _errorListener; 4205 RecordingErrorListener get errorListener => _errorListener;
4206
4207 /**
4208 * Return an array containing information about all of the libraries that were resolved.
4209 * @return an array containing the libraries that were resolved
4210 */
4211 Set<Library> get resolvedLibraries => _librariesInCycles;
4212
4213 /**
4214 * Resolve the library specified by the given source in the given context. The library is assumed
4215 * to be embedded in the given source.
4216 * @param librarySource the source specifying the defining compilation unit of the library to be
4217 * resolved
4218 * @param unit the compilation unit representing the embedded library
4219 * @param fullAnalysis {@code true} if a full analysis should be performed
4220 * @return the element representing the resolved library
4221 * @throws AnalysisException if the library could not be resolved for some rea son
4222 */
4223 LibraryElement resolveEmbeddedLibrary(Source librarySource, CompilationUnit un it, bool fullAnalysis) {
4224 InstrumentationBuilder instrumentation = Instrumentation.builder2("dart.engi ne.LibraryResolver.resolveEmbeddedLibrary");
4225 try {
4226 instrumentation.metric("fullAnalysis", fullAnalysis);
4227 instrumentation.data3("fullName", librarySource.fullName);
4228 Library targetLibrary = createLibrary2(librarySource, unit);
4229 _coreLibrary = _libraryMap[_coreLibrarySource];
4230 if (_coreLibrary == null) {
4231 _coreLibrary = createLibrary(_coreLibrarySource);
4232 }
4233 instrumentation.metric3("createLibrary", "complete");
4234 computeLibraryDependencies(targetLibrary);
4235 _librariesInCycles = computeLibrariesInCycles(targetLibrary);
4236 buildElementModels();
4237 instrumentation.metric3("buildElementModels", "complete");
4238 LibraryElement coreElement = _coreLibrary.libraryElement;
4239 if (coreElement == null) {
4240 throw new AnalysisException.con1("Could not resolve dart:core");
4241 }
4242 buildDirectiveModels();
4243 instrumentation.metric3("buildDirectiveModels", "complete");
4244 _typeProvider = new TypeProviderImpl(coreElement);
4245 buildTypeHierarchies();
4246 instrumentation.metric3("buildTypeHierarchies", "complete");
4247 resolveReferencesAndTypes();
4248 instrumentation.metric3("resolveReferencesAndTypes", "complete");
4249 performConstantEvaluation();
4250 instrumentation.metric3("performConstantEvaluation", "complete");
4251 if (fullAnalysis) {
4252 runAdditionalAnalyses();
4253 instrumentation.metric3("runAdditionalAnalyses", "complete");
4254 }
4255 return targetLibrary.libraryElement;
4256 } finally {
4257 instrumentation.log();
4258 }
4259 }
4260
3013 /** 4261 /**
3014 * Resolve the library specified by the given source in the given context. 4262 * Resolve the library specified by the given source in the given context.
3015 * <p> 4263 * <p>
3016 * Note that because Dart allows circular imports between libraries, it is pos sible that more than 4264 * Note that because Dart allows circular imports between libraries, it is pos sible that more than
3017 * one library will need to be resolved. In such cases the error listener can receive errors from 4265 * one library will need to be resolved. In such cases the error listener can receive errors from
3018 * multiple libraries. 4266 * multiple libraries.
3019 * @param librarySource the source specifying the defining compilation unit of the library to be 4267 * @param librarySource the source specifying the defining compilation unit of the library to be
3020 * resolved 4268 * resolved
3021 * @param fullAnalysis {@code true} if a full analysis should be performed 4269 * @param fullAnalysis {@code true} if a full analysis should be performed
3022 * @return the element representing the resolved library 4270 * @return the element representing the resolved library
(...skipping 24 matching lines...) Expand all
3047 buildTypeHierarchies(); 4295 buildTypeHierarchies();
3048 instrumentation.metric3("buildTypeHierarchies", "complete"); 4296 instrumentation.metric3("buildTypeHierarchies", "complete");
3049 resolveReferencesAndTypes(); 4297 resolveReferencesAndTypes();
3050 instrumentation.metric3("resolveReferencesAndTypes", "complete"); 4298 instrumentation.metric3("resolveReferencesAndTypes", "complete");
3051 performConstantEvaluation(); 4299 performConstantEvaluation();
3052 instrumentation.metric3("performConstantEvaluation", "complete"); 4300 instrumentation.metric3("performConstantEvaluation", "complete");
3053 if (fullAnalysis) { 4301 if (fullAnalysis) {
3054 runAdditionalAnalyses(); 4302 runAdditionalAnalyses();
3055 instrumentation.metric3("runAdditionalAnalyses", "complete"); 4303 instrumentation.metric3("runAdditionalAnalyses", "complete");
3056 } 4304 }
3057 recordResults();
3058 instrumentation.metric3("recordResults", "complete");
3059 instrumentation.metric2("librariesInCycles", _librariesInCycles.length); 4305 instrumentation.metric2("librariesInCycles", _librariesInCycles.length);
3060 for (Library lib in _librariesInCycles) { 4306 for (Library lib in _librariesInCycles) {
3061 instrumentation.metric2("librariesInCycles-CompilationUnitSources-Size", lib.compilationUnitSources.length); 4307 instrumentation.metric2("librariesInCycles-CompilationUnitSources-Size", lib.compilationUnitSources.length);
3062 } 4308 }
3063 return targetLibrary.libraryElement; 4309 return targetLibrary.libraryElement;
3064 } finally { 4310 } finally {
3065 instrumentation.log(); 4311 instrumentation.log();
3066 } 4312 }
3067 } 4313 }
4314
3068 /** 4315 /**
3069 * Add a dependency to the given map from the referencing library to the refer enced library. 4316 * Add a dependency to the given map from the referencing library to the refer enced library.
3070 * @param dependencyMap the map to which the dependency is to be added 4317 * @param dependencyMap the map to which the dependency is to be added
3071 * @param referencingLibrary the library that references the referenced librar y 4318 * @param referencingLibrary the library that references the referenced librar y
3072 * @param referencedLibrary the library referenced by the referencing library 4319 * @param referencedLibrary the library referenced by the referencing library
3073 */ 4320 */
3074 void addDependencyToMap(Map<Library, List<Library>> dependencyMap, Library ref erencingLibrary, Library referencedLibrary) { 4321 void addDependencyToMap(Map<Library, List<Library>> dependencyMap, Library ref erencingLibrary, Library referencedLibrary) {
3075 List<Library> dependentLibraries = dependencyMap[referencedLibrary]; 4322 List<Library> dependentLibraries = dependencyMap[referencedLibrary];
3076 if (dependentLibraries == null) { 4323 if (dependentLibraries == null) {
3077 dependentLibraries = new List<Library>(); 4324 dependentLibraries = new List<Library>();
3078 dependencyMap[referencedLibrary] = dependentLibraries; 4325 dependencyMap[referencedLibrary] = dependentLibraries;
3079 } 4326 }
3080 dependentLibraries.add(referencingLibrary); 4327 dependentLibraries.add(referencingLibrary);
3081 } 4328 }
4329
3082 /** 4330 /**
3083 * Given a library that is part of a cycle that includes the root library, add to the given set of 4331 * Given a library that is part of a cycle that includes the root library, add to the given set of
3084 * libraries all of the libraries reachable from the root library that are als o included in the 4332 * libraries all of the libraries reachable from the root library that are als o included in the
3085 * cycle. 4333 * cycle.
3086 * @param library the library to be added to the collection of libraries in cy cles 4334 * @param library the library to be added to the collection of libraries in cy cles
3087 * @param librariesInCycle a collection of the libraries that are in the cycle 4335 * @param librariesInCycle a collection of the libraries that are in the cycle
3088 * @param dependencyMap a table mapping libraries to the collection of librari es from which those 4336 * @param dependencyMap a table mapping libraries to the collection of librari es from which those
3089 * libraries are referenced 4337 * libraries are referenced
3090 */ 4338 */
3091 void addLibrariesInCycle(Library library, Set<Library> librariesInCycle, Map<L ibrary, List<Library>> dependencyMap) { 4339 void addLibrariesInCycle(Library library, Set<Library> librariesInCycle, Map<L ibrary, List<Library>> dependencyMap) {
3092 if (javaSetAdd(librariesInCycle, library)) { 4340 if (javaSetAdd(librariesInCycle, library)) {
3093 List<Library> dependentLibraries = dependencyMap[library]; 4341 List<Library> dependentLibraries = dependencyMap[library];
3094 if (dependentLibraries != null) { 4342 if (dependentLibraries != null) {
3095 for (Library dependentLibrary in dependentLibraries) { 4343 for (Library dependentLibrary in dependentLibraries) {
3096 addLibrariesInCycle(dependentLibrary, librariesInCycle, dependencyMap) ; 4344 addLibrariesInCycle(dependentLibrary, librariesInCycle, dependencyMap) ;
3097 } 4345 }
3098 } 4346 }
3099 } 4347 }
3100 } 4348 }
4349
3101 /** 4350 /**
3102 * Add the given library, and all libraries reachable from it that have not al ready been visited, 4351 * Add the given library, and all libraries reachable from it that have not al ready been visited,
3103 * to the given dependency map. 4352 * to the given dependency map.
3104 * @param library the library currently being added to the dependency map 4353 * @param library the library currently being added to the dependency map
3105 * @param dependencyMap the dependency map being computed 4354 * @param dependencyMap the dependency map being computed
3106 * @param visitedLibraries the libraries that have already been visited, used to prevent infinite 4355 * @param visitedLibraries the libraries that have already been visited, used to prevent infinite
3107 * recursion 4356 * recursion
3108 */ 4357 */
3109 void addToDependencyMap(Library library, Map<Library, List<Library>> dependenc yMap, Set<Library> visitedLibraries) { 4358 void addToDependencyMap(Library library, Map<Library, List<Library>> dependenc yMap, Set<Library> visitedLibraries) {
3110 if (javaSetAdd(visitedLibraries, library)) { 4359 if (javaSetAdd(visitedLibraries, library)) {
3111 for (Library referencedLibrary in library.importsAndExports) { 4360 for (Library referencedLibrary in library.importsAndExports) {
3112 addDependencyToMap(dependencyMap, library, referencedLibrary); 4361 addDependencyToMap(dependencyMap, library, referencedLibrary);
3113 addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries); 4362 addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries);
3114 } 4363 }
3115 if (!library.explicitlyImportsCore && library != _coreLibrary) { 4364 if (!library.explicitlyImportsCore && library != _coreLibrary) {
3116 addDependencyToMap(dependencyMap, library, _coreLibrary); 4365 addDependencyToMap(dependencyMap, library, _coreLibrary);
3117 } 4366 }
3118 } 4367 }
3119 } 4368 }
4369
3120 /** 4370 /**
3121 * Build the element model representing the combinators declared by the given directive. 4371 * Build the element model representing the combinators declared by the given directive.
3122 * @param directive the directive that declares the combinators 4372 * @param directive the directive that declares the combinators
3123 * @return an array containing the import combinators that were built 4373 * @return an array containing the import combinators that were built
3124 */ 4374 */
3125 List<NamespaceCombinator> buildCombinators(NamespaceDirective directive) { 4375 List<NamespaceCombinator> buildCombinators(NamespaceDirective directive) {
3126 List<NamespaceCombinator> combinators = new List<NamespaceCombinator>(); 4376 List<NamespaceCombinator> combinators = new List<NamespaceCombinator>();
3127 for (Combinator combinator in directive.combinators) { 4377 for (Combinator combinator in directive.combinators) {
3128 if (combinator is HideCombinator) { 4378 if (combinator is HideCombinator) {
3129 HideCombinatorImpl hide = new HideCombinatorImpl(); 4379 HideCombinatorImpl hide = new HideCombinatorImpl();
3130 hide.hiddenNames = getIdentifiers(((combinator as HideCombinator)).hidde nNames); 4380 hide.hiddenNames = getIdentifiers(((combinator as HideCombinator)).hidde nNames);
3131 combinators.add(hide); 4381 combinators.add(hide);
3132 } else { 4382 } else {
3133 ShowCombinatorImpl show = new ShowCombinatorImpl(); 4383 ShowCombinatorImpl show = new ShowCombinatorImpl();
3134 show.shownNames = getIdentifiers(((combinator as ShowCombinator)).shownN ames); 4384 show.shownNames = getIdentifiers(((combinator as ShowCombinator)).shownN ames);
3135 combinators.add(show); 4385 combinators.add(show);
3136 } 4386 }
3137 } 4387 }
3138 return new List.from(combinators); 4388 return new List.from(combinators);
3139 } 4389 }
4390
3140 /** 4391 /**
3141 * Every library now has a corresponding {@link LibraryElement}, so it is now possible to resolve 4392 * Every library now has a corresponding {@link LibraryElement}, so it is now possible to resolve
3142 * the import and export directives. 4393 * the import and export directives.
3143 * @throws AnalysisException if the defining compilation unit for any of the l ibraries could not 4394 * @throws AnalysisException if the defining compilation unit for any of the l ibraries could not
3144 * be accessed 4395 * be accessed
3145 */ 4396 */
3146 void buildDirectiveModels() { 4397 void buildDirectiveModels() {
3147 for (Library library in _librariesInCycles) { 4398 for (Library library in _librariesInCycles) {
3148 Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixEle mentImpl>(); 4399 Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixEle mentImpl>();
3149 List<ImportElement> imports = new List<ImportElement>(); 4400 List<ImportElement> imports = new List<ImportElement>();
3150 List<ExportElement> exports = new List<ExportElement>(); 4401 List<ExportElement> exports = new List<ExportElement>();
3151 for (Directive directive in library.definingCompilationUnit.directives) { 4402 for (Directive directive in library.definingCompilationUnit.directives) {
3152 if (directive is ImportDirective) { 4403 if (directive is ImportDirective) {
3153 ImportDirective importDirective = directive as ImportDirective; 4404 ImportDirective importDirective = directive as ImportDirective;
3154 Library importedLibrary = library.getImport(importDirective); 4405 Library importedLibrary = library.getImport(importDirective);
3155 if (importedLibrary != null) { 4406 if (importedLibrary != null) {
3156 ImportElementImpl importElement = new ImportElementImpl(); 4407 ImportElementImpl importElement = new ImportElementImpl();
4408 importElement.uri = library.getUri(importDirective);
3157 importElement.combinators = buildCombinators(importDirective); 4409 importElement.combinators = buildCombinators(importDirective);
3158 LibraryElement importedLibraryElement = importedLibrary.libraryEleme nt; 4410 LibraryElement importedLibraryElement = importedLibrary.libraryEleme nt;
3159 if (importedLibraryElement != null) { 4411 if (importedLibraryElement != null) {
3160 importElement.importedLibrary = importedLibraryElement; 4412 importElement.importedLibrary = importedLibraryElement;
3161 } 4413 }
3162 SimpleIdentifier prefixNode = ((directive as ImportDirective)).prefi x; 4414 SimpleIdentifier prefixNode = ((directive as ImportDirective)).prefi x;
3163 if (prefixNode != null) { 4415 if (prefixNode != null) {
3164 String prefixName = prefixNode.name; 4416 String prefixName = prefixNode.name;
3165 PrefixElementImpl prefix = nameToPrefixMap[prefixName]; 4417 PrefixElementImpl prefix = nameToPrefixMap[prefixName];
3166 if (prefix == null) { 4418 if (prefix == null) {
3167 prefix = new PrefixElementImpl(prefixNode); 4419 prefix = new PrefixElementImpl(prefixNode);
3168 nameToPrefixMap[prefixName] = prefix; 4420 nameToPrefixMap[prefixName] = prefix;
3169 } 4421 }
3170 importElement.prefix = prefix; 4422 importElement.prefix = prefix;
3171 } 4423 }
3172 directive.element = importElement; 4424 directive.element = importElement;
3173 imports.add(importElement); 4425 imports.add(importElement);
3174 } 4426 }
3175 } else if (directive is ExportDirective) { 4427 } else if (directive is ExportDirective) {
3176 ExportDirective exportDirective = directive as ExportDirective; 4428 ExportDirective exportDirective = directive as ExportDirective;
3177 ExportElementImpl exportElement = new ExportElementImpl(); 4429 ExportElementImpl exportElement = new ExportElementImpl();
4430 exportElement.uri = library.getUri(exportDirective);
3178 exportElement.combinators = buildCombinators(exportDirective); 4431 exportElement.combinators = buildCombinators(exportDirective);
3179 Library exportedLibrary = library.getExport(exportDirective); 4432 Library exportedLibrary = library.getExport(exportDirective);
3180 if (exportedLibrary != null) { 4433 if (exportedLibrary != null) {
3181 LibraryElement exportedLibraryElement = exportedLibrary.libraryEleme nt; 4434 LibraryElement exportedLibraryElement = exportedLibrary.libraryEleme nt;
3182 if (exportedLibraryElement != null) { 4435 if (exportedLibraryElement != null) {
3183 exportElement.exportedLibrary = exportedLibraryElement; 4436 exportElement.exportedLibrary = exportedLibraryElement;
3184 } 4437 }
3185 directive.element = exportElement; 4438 directive.element = exportElement;
3186 exports.add(exportElement); 4439 exports.add(exportElement);
3187 } 4440 }
3188 } 4441 }
3189 } 4442 }
3190 Source librarySource2 = library.librarySource; 4443 Source librarySource2 = library.librarySource;
3191 if (!library.explicitlyImportsCore && _coreLibrarySource != librarySource2 ) { 4444 if (!library.explicitlyImportsCore && _coreLibrarySource != librarySource2 ) {
3192 ImportElementImpl importElement = new ImportElementImpl(); 4445 ImportElementImpl importElement = new ImportElementImpl();
3193 importElement.importedLibrary = _coreLibrary.libraryElement; 4446 importElement.importedLibrary = _coreLibrary.libraryElement;
3194 importElement.synthetic = true; 4447 importElement.synthetic = true;
3195 imports.add(importElement); 4448 imports.add(importElement);
3196 } 4449 }
3197 LibraryElementImpl libraryElement2 = library.libraryElement; 4450 LibraryElementImpl libraryElement2 = library.libraryElement;
3198 libraryElement2.imports = new List.from(imports); 4451 libraryElement2.imports = new List.from(imports);
3199 libraryElement2.exports = new List.from(exports); 4452 libraryElement2.exports = new List.from(exports);
3200 } 4453 }
3201 } 4454 }
4455
3202 /** 4456 /**
3203 * Build element models for all of the libraries in the current cycle. 4457 * Build element models for all of the libraries in the current cycle.
3204 * @throws AnalysisException if any of the element models cannot be built 4458 * @throws AnalysisException if any of the element models cannot be built
3205 */ 4459 */
3206 void buildElementModels() { 4460 void buildElementModels() {
3207 for (Library library in _librariesInCycles) { 4461 for (Library library in _librariesInCycles) {
3208 LibraryElementBuilder builder = new LibraryElementBuilder(this); 4462 LibraryElementBuilder builder = new LibraryElementBuilder(this);
3209 LibraryElementImpl libraryElement = builder.buildLibrary(library); 4463 LibraryElementImpl libraryElement = builder.buildLibrary(library);
3210 library.libraryElement = libraryElement; 4464 library.libraryElement = libraryElement;
3211 } 4465 }
3212 } 4466 }
4467
3213 /** 4468 /**
3214 * Resolve the type hierarchy across all of the types declared in the librarie s in the current 4469 * Resolve the type hierarchy across all of the types declared in the librarie s in the current
3215 * cycle. 4470 * cycle.
3216 * @throws AnalysisException if any of the type hierarchies could not be resol ved 4471 * @throws AnalysisException if any of the type hierarchies could not be resol ved
3217 */ 4472 */
3218 void buildTypeHierarchies() { 4473 void buildTypeHierarchies() {
3219 for (Library library in _librariesInCycles) { 4474 for (Library library in _librariesInCycles) {
3220 for (Source source in library.compilationUnitSources) { 4475 for (Source source in library.compilationUnitSources) {
3221 TypeResolverVisitor visitor = new TypeResolverVisitor.con1(library, sour ce, _typeProvider); 4476 TypeResolverVisitor visitor = new TypeResolverVisitor.con1(library, sour ce, _typeProvider);
3222 library.getAST(source).accept(visitor); 4477 library.getAST(source).accept(visitor);
3223 } 4478 }
3224 } 4479 }
3225 } 4480 }
4481
3226 /** 4482 /**
3227 * Compute a dependency map of libraries reachable from the given library. A d ependency map is a 4483 * Compute a dependency map of libraries reachable from the given library. A d ependency map is a
3228 * table that maps individual libraries to a list of the libraries that either import or export 4484 * table that maps individual libraries to a list of the libraries that either import or export
3229 * those libraries. 4485 * those libraries.
3230 * <p> 4486 * <p>
3231 * This map is used to compute all of the libraries involved in a cycle that i nclude the root 4487 * This map is used to compute all of the libraries involved in a cycle that i nclude the root
3232 * library. Given that we only add libraries that are reachable from the root library, when we 4488 * library. Given that we only add libraries that are reachable from the root library, when we
3233 * work backward we are guaranteed to only get libraries in the cycle. 4489 * work backward we are guaranteed to only get libraries in the cycle.
3234 * @param library the library currently being added to the dependency map 4490 * @param library the library currently being added to the dependency map
3235 */ 4491 */
3236 Map<Library, List<Library>> computeDependencyMap(Library library) { 4492 Map<Library, List<Library>> computeDependencyMap(Library library) {
3237 Map<Library, List<Library>> dependencyMap = new Map<Library, List<Library>>( ); 4493 Map<Library, List<Library>> dependencyMap = new Map<Library, List<Library>>( );
3238 addToDependencyMap(library, dependencyMap, new Set<Library>()); 4494 addToDependencyMap(library, dependencyMap, new Set<Library>());
3239 return dependencyMap; 4495 return dependencyMap;
3240 } 4496 }
4497
3241 /** 4498 /**
3242 * Return a collection containing all of the libraries reachable from the give n library that are 4499 * Return a collection containing all of the libraries reachable from the give n library that are
3243 * contained in a cycle that includes the given library. 4500 * contained in a cycle that includes the given library.
3244 * @param library the library that must be included in any cycles whose member s are to be returned 4501 * @param library the library that must be included in any cycles whose member s are to be returned
3245 * @return all of the libraries referenced by the given library that have a ci rcular reference 4502 * @return all of the libraries referenced by the given library that have a ci rcular reference
3246 * back to the given library 4503 * back to the given library
3247 */ 4504 */
3248 Set<Library> computeLibrariesInCycles(Library library) { 4505 Set<Library> computeLibrariesInCycles(Library library) {
3249 Map<Library, List<Library>> dependencyMap = computeDependencyMap(library); 4506 Map<Library, List<Library>> dependencyMap = computeDependencyMap(library);
3250 Set<Library> librariesInCycle = new Set<Library>(); 4507 Set<Library> librariesInCycle = new Set<Library>();
3251 addLibrariesInCycle(library, librariesInCycle, dependencyMap); 4508 addLibrariesInCycle(library, librariesInCycle, dependencyMap);
3252 return librariesInCycle; 4509 return librariesInCycle;
3253 } 4510 }
4511
3254 /** 4512 /**
3255 * Recursively traverse the libraries reachable from the given library, creati ng instances of the 4513 * Recursively traverse the libraries reachable from the given library, creati ng instances of the
3256 * class {@link Library} to represent them, and record the references in the l ibrary objects. 4514 * class {@link Library} to represent them, and record the references in the l ibrary objects.
3257 * @param library the library to be processed to find libraries that have not yet been traversed 4515 * @param library the library to be processed to find libraries that have not yet been traversed
3258 * @throws AnalysisException if some portion of the library graph could not be traversed 4516 * @throws AnalysisException if some portion of the library graph could not be traversed
3259 */ 4517 */
3260 void computeLibraryDependencies(Library library) { 4518 void computeLibraryDependencies(Library library) {
3261 bool explicitlyImportsCore = false; 4519 bool explicitlyImportsCore = false;
3262 CompilationUnit unit = library.definingCompilationUnit; 4520 CompilationUnit unit = library.definingCompilationUnit;
3263 for (Directive directive in unit.directives) { 4521 for (Directive directive in unit.directives) {
3264 if (directive is ImportDirective) { 4522 if (directive is ImportDirective) {
3265 ImportDirective importDirective = directive as ImportDirective; 4523 ImportDirective importDirective = directive as ImportDirective;
3266 Source importedSource = library.getSource(importDirective.uri); 4524 Source importedSource = library.getSource(importDirective);
3267 if (importedSource != null) { 4525 if (importedSource != null) {
3268 if (importedSource == _coreLibrarySource) { 4526 if (importedSource == _coreLibrarySource) {
3269 explicitlyImportsCore = true; 4527 explicitlyImportsCore = true;
3270 } 4528 }
3271 Library importedLibrary = _libraryMap[importedSource]; 4529 Library importedLibrary = _libraryMap[importedSource];
3272 if (importedLibrary == null) { 4530 if (importedLibrary == null) {
3273 importedLibrary = createLibraryOrNull(importedSource); 4531 importedLibrary = createLibraryOrNull(importedSource);
3274 if (importedLibrary != null) { 4532 if (importedLibrary != null) {
3275 computeLibraryDependencies(importedLibrary); 4533 computeLibraryDependencies(importedLibrary);
3276 } 4534 }
3277 } 4535 }
3278 if (importedLibrary != null) { 4536 if (importedLibrary != null) {
3279 library.addImport(importDirective, importedLibrary); 4537 library.addImport(importDirective, importedLibrary);
3280 if (doesCompilationUnitHavePartOfDirective(importedLibrary.getAST(im portedSource))) { 4538 if (doesCompilationUnitHavePartOfDirective(importedLibrary.getAST(im portedSource))) {
3281 StringLiteral uriLiteral = importDirective.uri; 4539 StringLiteral uriLiteral = importDirective.uri;
3282 _errorListener.onError(new AnalysisError.con2(library.librarySourc e, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.IMPORT_OF_NON_LIBR ARY, [uriLiteral.toSource()])); 4540 _errorListener.onError(new AnalysisError.con2(library.librarySourc e, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.IMPORT_OF_NON_LIBR ARY, [uriLiteral.toSource()]));
3283 } 4541 }
3284 } 4542 }
3285 } 4543 }
3286 } else if (directive is ExportDirective) { 4544 } else if (directive is ExportDirective) {
3287 ExportDirective exportDirective = directive as ExportDirective; 4545 ExportDirective exportDirective = directive as ExportDirective;
3288 Source exportedSource = library.getSource(exportDirective.uri); 4546 Source exportedSource = library.getSource(exportDirective);
3289 if (exportedSource != null) { 4547 if (exportedSource != null) {
3290 Library exportedLibrary = _libraryMap[exportedSource]; 4548 Library exportedLibrary = _libraryMap[exportedSource];
3291 if (exportedLibrary == null) { 4549 if (exportedLibrary == null) {
3292 exportedLibrary = createLibraryOrNull(exportedSource); 4550 exportedLibrary = createLibraryOrNull(exportedSource);
3293 if (exportedLibrary != null) { 4551 if (exportedLibrary != null) {
3294 computeLibraryDependencies(exportedLibrary); 4552 computeLibraryDependencies(exportedLibrary);
3295 } 4553 }
3296 } 4554 }
3297 if (exportedLibrary != null) { 4555 if (exportedLibrary != null) {
3298 library.addExport(exportDirective, exportedLibrary); 4556 library.addExport(exportDirective, exportedLibrary);
3299 if (doesCompilationUnitHavePartOfDirective(exportedLibrary.getAST(ex portedSource))) { 4557 if (doesCompilationUnitHavePartOfDirective(exportedLibrary.getAST(ex portedSource))) {
3300 StringLiteral uriLiteral = exportDirective.uri; 4558 StringLiteral uriLiteral = exportDirective.uri;
3301 _errorListener.onError(new AnalysisError.con2(library.librarySourc e, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.EXPORT_OF_NON_LIBR ARY, [uriLiteral.toSource()])); 4559 _errorListener.onError(new AnalysisError.con2(library.librarySourc e, uriLiteral.offset, uriLiteral.length, CompileTimeErrorCode.EXPORT_OF_NON_LIBR ARY, [uriLiteral.toSource()]));
3302 } 4560 }
3303 } 4561 }
3304 } 4562 }
3305 } 4563 }
3306 } 4564 }
3307 library.explicitlyImportsCore = explicitlyImportsCore; 4565 library.explicitlyImportsCore = explicitlyImportsCore;
3308 if (!explicitlyImportsCore && _coreLibrarySource != library.librarySource) { 4566 if (!explicitlyImportsCore && _coreLibrarySource != library.librarySource) {
3309 Library importedLibrary = _libraryMap[_coreLibrarySource]; 4567 Library importedLibrary = _libraryMap[_coreLibrarySource];
3310 if (importedLibrary == null) { 4568 if (importedLibrary == null) {
3311 importedLibrary = createLibraryOrNull(_coreLibrarySource); 4569 importedLibrary = createLibraryOrNull(_coreLibrarySource);
3312 if (importedLibrary != null) { 4570 if (importedLibrary != null) {
3313 computeLibraryDependencies(importedLibrary); 4571 computeLibraryDependencies(importedLibrary);
3314 } 4572 }
3315 } 4573 }
3316 } 4574 }
3317 } 4575 }
4576
3318 /** 4577 /**
3319 * Create an object to represent the information about the library defined by the compilation unit 4578 * Create an object to represent the information about the library defined by the compilation unit
3320 * with the given source. 4579 * with the given source.
3321 * @param librarySource the source of the library's defining compilation unit 4580 * @param librarySource the source of the library's defining compilation unit
3322 * @return the library object that was created 4581 * @return the library object that was created
3323 * @throws AnalysisException if the library source is not valid 4582 * @throws AnalysisException if the library source is not valid
3324 */ 4583 */
3325 Library createLibrary(Source librarySource) { 4584 Library createLibrary(Source librarySource) {
3326 Library library = new Library(_analysisContext, _errorListener, librarySourc e); 4585 Library library = new Library(_analysisContext, _errorListener, librarySourc e);
3327 library.definingCompilationUnit; 4586 library.definingCompilationUnit;
3328 _libraryMap[librarySource] = library; 4587 _libraryMap[librarySource] = library;
3329 return library; 4588 return library;
3330 } 4589 }
4590
4591 /**
4592 * Create an object to represent the information about the library defined by the compilation unit
4593 * with the given source.
4594 * @param librarySource the source of the library's defining compilation unit
4595 * @return the library object that was created
4596 * @throws AnalysisException if the library source is not valid
4597 */
4598 Library createLibrary2(Source librarySource, CompilationUnit unit) {
4599 Library library = new Library(_analysisContext, _errorListener, librarySourc e);
4600 library.definingCompilationUnit = unit;
4601 _libraryMap[librarySource] = library;
4602 return library;
4603 }
4604
3331 /** 4605 /**
3332 * Create an object to represent the information about the library defined by the compilation unit 4606 * Create an object to represent the information about the library defined by the compilation unit
3333 * with the given source. Return the library object that was created, or {@cod e null} if the 4607 * with the given source. Return the library object that was created, or {@cod e null} if the
3334 * source is not valid. 4608 * source is not valid.
3335 * @param librarySource the source of the library's defining compilation unit 4609 * @param librarySource the source of the library's defining compilation unit
3336 * @return the library object that was created 4610 * @return the library object that was created
3337 */ 4611 */
3338 Library createLibraryOrNull(Source librarySource) { 4612 Library createLibraryOrNull(Source librarySource) {
3339 if (!librarySource.exists()) { 4613 if (!librarySource.exists()) {
3340 return null; 4614 return null;
3341 } 4615 }
3342 Library library = new Library(_analysisContext, _errorListener, librarySourc e); 4616 Library library = new Library(_analysisContext, _errorListener, librarySourc e);
3343 try { 4617 try {
3344 library.definingCompilationUnit; 4618 library.definingCompilationUnit;
3345 } on AnalysisException catch (exception) { 4619 } on AnalysisException catch (exception) {
3346 return null; 4620 return null;
3347 } 4621 }
3348 _libraryMap[librarySource] = library; 4622 _libraryMap[librarySource] = library;
3349 return library; 4623 return library;
3350 } 4624 }
4625
3351 /** 4626 /**
3352 * Return {@code true} if and only if the passed {@link CompilationUnit} has a part-of directive. 4627 * Return {@code true} if and only if the passed {@link CompilationUnit} has a part-of directive.
3353 * @param node the {@link CompilationUnit} to test 4628 * @param node the {@link CompilationUnit} to test
3354 * @return {@code true} if and only if the passed {@link CompilationUnit} has a part-of directive 4629 * @return {@code true} if and only if the passed {@link CompilationUnit} has a part-of directive
3355 */ 4630 */
3356 bool doesCompilationUnitHavePartOfDirective(CompilationUnit node) { 4631 bool doesCompilationUnitHavePartOfDirective(CompilationUnit node) {
3357 NodeList<Directive> directives2 = node.directives; 4632 NodeList<Directive> directives2 = node.directives;
3358 for (Directive directive in directives2) { 4633 for (Directive directive in directives2) {
3359 if (directive is PartOfDirective) { 4634 if (directive is PartOfDirective) {
3360 return true; 4635 return true;
3361 } 4636 }
3362 } 4637 }
3363 return false; 4638 return false;
3364 } 4639 }
4640
3365 /** 4641 /**
3366 * Return an array containing the lexical identifiers associated with the node s in the given list. 4642 * Return an array containing the lexical identifiers associated with the node s in the given list.
3367 * @param names the AST nodes representing the identifiers 4643 * @param names the AST nodes representing the identifiers
3368 * @return the lexical identifiers associated with the nodes in the list 4644 * @return the lexical identifiers associated with the nodes in the list
3369 */ 4645 */
3370 List<String> getIdentifiers(NodeList<SimpleIdentifier> names) { 4646 List<String> getIdentifiers(NodeList<SimpleIdentifier> names) {
3371 int count = names.length; 4647 int count = names.length;
3372 List<String> identifiers = new List<String>(count); 4648 List<String> identifiers = new List<String>(count);
3373 for (int i = 0; i < count; i++) { 4649 for (int i = 0; i < count; i++) {
3374 identifiers[i] = names[i].name; 4650 identifiers[i] = names[i].name;
3375 } 4651 }
3376 return identifiers; 4652 return identifiers;
3377 } 4653 }
4654
3378 /** 4655 /**
3379 * Compute a value for all of the constants in the libraries being analyzed. 4656 * Compute a value for all of the constants in the libraries being analyzed.
3380 */ 4657 */
3381 void performConstantEvaluation() { 4658 void performConstantEvaluation() {
3382 ConstantValueComputer computer = new ConstantValueComputer(); 4659 ConstantValueComputer computer = new ConstantValueComputer();
3383 for (Library library in _librariesInCycles) { 4660 for (Library library in _librariesInCycles) {
3384 for (Source source in library.compilationUnitSources) { 4661 for (Source source in library.compilationUnitSources) {
3385 try { 4662 try {
3386 CompilationUnit unit = library.getAST(source); 4663 CompilationUnit unit = library.getAST(source);
3387 if (unit != null) { 4664 if (unit != null) {
3388 computer.add(unit); 4665 computer.add(unit);
3389 } 4666 }
3390 } on AnalysisException catch (exception) { 4667 } on AnalysisException catch (exception) {
3391 AnalysisEngine.instance.logger.logError2("Internal Error: Could not ac cess AST for ${source.fullName} during constant evaluation", exception); 4668 AnalysisEngine.instance.logger.logError2("Internal Error: Could not ac cess AST for ${source.fullName} during constant evaluation", exception);
3392 } 4669 }
3393 } 4670 }
3394 } 4671 }
3395 computer.computeValues(); 4672 computer.computeValues();
3396 } 4673 }
3397 /** 4674
3398 * Record the results of resolution with the analysis context. This includes r ecording
3399 * <ul>
3400 * <li>the resolved AST associated with each compilation unit,</li>
3401 * <li>the set of resolution errors produced for each compilation unit, and</l i>
3402 * <li>the element models produced for each library.</li>
3403 * </ul>
3404 */
3405 void recordResults() {
3406 Map<Source, LibraryElement> elementMap = new Map<Source, LibraryElement>();
3407 for (Library library in _librariesInCycles) {
3408 Source librarySource2 = library.librarySource;
3409 recordResults2(librarySource2, librarySource2, library.definingCompilation Unit);
3410 for (Source source in library.compilationUnitSources) {
3411 recordResults2(source, librarySource2, library.getAST(source));
3412 }
3413 elementMap[library.librarySource] = library.libraryElement;
3414 }
3415 _analysisContext.recordLibraryElements(elementMap);
3416 }
3417 void recordResults2(Source source, Source librarySource, CompilationUnit unit) {
3418 List<AnalysisError> errors = _recordingErrorListener.getErrors2(source);
3419 unit.resolutionErrors = errors;
3420 _analysisContext.recordResolvedCompilationUnit(source, librarySource, unit);
3421 _analysisContext.recordResolutionErrors(source, librarySource, errors, unit. lineInfo);
3422 }
3423 /** 4675 /**
3424 * Resolve the identifiers and perform type analysis in the libraries in the c urrent cycle. 4676 * Resolve the identifiers and perform type analysis in the libraries in the c urrent cycle.
3425 * @throws AnalysisException if any of the identifiers could not be resolved o r if any of the 4677 * @throws AnalysisException if any of the identifiers could not be resolved o r if any of the
3426 * libraries could not have their types analyzed 4678 * libraries could not have their types analyzed
3427 */ 4679 */
3428 void resolveReferencesAndTypes() { 4680 void resolveReferencesAndTypes() {
3429 for (Library library in _librariesInCycles) { 4681 for (Library library in _librariesInCycles) {
3430 resolveReferencesAndTypes2(library); 4682 resolveReferencesAndTypes2(library);
3431 } 4683 }
3432 } 4684 }
4685
3433 /** 4686 /**
3434 * Resolve the identifiers and perform type analysis in the given library. 4687 * Resolve the identifiers and perform type analysis in the given library.
3435 * @param library the library to be resolved 4688 * @param library the library to be resolved
3436 * @throws AnalysisException if any of the identifiers could not be resolved o r if the types in 4689 * @throws AnalysisException if any of the identifiers could not be resolved o r if the types in
3437 * the library cannot be analyzed 4690 * the library cannot be analyzed
3438 */ 4691 */
3439 void resolveReferencesAndTypes2(Library library) { 4692 void resolveReferencesAndTypes2(Library library) {
3440 for (Source source in library.compilationUnitSources) { 4693 for (Source source in library.compilationUnitSources) {
3441 ResolverVisitor visitor = new ResolverVisitor.con1(library, source, _typeP rovider); 4694 ResolverVisitor visitor = new ResolverVisitor.con1(library, source, _typeP rovider);
3442 library.getAST(source).accept(visitor); 4695 library.getAST(source).accept(visitor);
3443 } 4696 }
3444 } 4697 }
4698
3445 /** 4699 /**
3446 * Run additional analyses, such as the {@link ConstantVerifier} and {@link Er rorVerifier}analysis in the current cycle. 4700 * Run additional analyses, such as the {@link ConstantVerifier} and {@link Er rorVerifier}analysis in the current cycle.
3447 * @throws AnalysisException if any of the identifiers could not be resolved o r if the types in 4701 * @throws AnalysisException if any of the identifiers could not be resolved o r if the types in
3448 * the library cannot be analyzed 4702 * the library cannot be analyzed
3449 */ 4703 */
3450 void runAdditionalAnalyses() { 4704 void runAdditionalAnalyses() {
3451 for (Library library in _librariesInCycles) { 4705 for (Library library in _librariesInCycles) {
3452 runAdditionalAnalyses2(library); 4706 runAdditionalAnalyses2(library);
3453 } 4707 }
3454 } 4708 }
4709
3455 /** 4710 /**
3456 * Run additional analyses, such as the {@link ConstantVerifier} and {@link Er rorVerifier}analysis in the given library. 4711 * Run additional analyses, such as the {@link ConstantVerifier} and {@link Er rorVerifier}analysis in the given library.
3457 * @param library the library to have the extra analyses processes run 4712 * @param library the library to have the extra analyses processes run
3458 * @throws AnalysisException if any of the identifiers could not be resolved o r if the types in 4713 * @throws AnalysisException if any of the identifiers could not be resolved o r if the types in
3459 * the library cannot be analyzed 4714 * the library cannot be analyzed
3460 */ 4715 */
3461 void runAdditionalAnalyses2(Library library) { 4716 void runAdditionalAnalyses2(Library library) {
3462 for (Source source in library.compilationUnitSources) { 4717 for (Source source in library.compilationUnitSources) {
3463 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source); 4718 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source);
3464 CompilationUnit unit = library.getAST(source); 4719 CompilationUnit unit = library.getAST(source);
3465 ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, library.lib raryElement, _typeProvider); 4720 ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, library.lib raryElement, _typeProvider, library.inheritanceManager);
3466 unit.accept(errorVerifier); 4721 unit.accept(errorVerifier);
3467 ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter); 4722 ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, _t ypeProvider);
3468 unit.accept(constantVerifier); 4723 unit.accept(constantVerifier);
3469 } 4724 }
3470 } 4725 }
3471 } 4726 }
3472 class AnalysisErrorListener_9 implements AnalysisErrorListener { 4727
3473 final LibraryResolver LibraryResolver_this;
3474 AnalysisErrorListener additionalAnalysisErrorListener;
3475 AnalysisErrorListener_9(this.LibraryResolver_this, this.additionalAnalysisErro rListener);
3476 void onError(AnalysisError error) {
3477 additionalAnalysisErrorListener.onError(error);
3478 LibraryResolver_this._recordingErrorListener.onError(error);
3479 }
3480 }
3481 /** 4728 /**
3482 * Instances of the class {@code ResolverVisitor} are used to resolve the nodes within a single 4729 * Instances of the class {@code ResolverVisitor} are used to resolve the nodes within a single
3483 * compilation unit. 4730 * compilation unit.
3484 * @coverage dart.engine.resolver 4731 * @coverage dart.engine.resolver
3485 */ 4732 */
3486 class ResolverVisitor extends ScopedVisitor { 4733 class ResolverVisitor extends ScopedVisitor {
4734
3487 /** 4735 /**
3488 * The object used to resolve the element associated with the current node. 4736 * The object used to resolve the element associated with the current node.
3489 */ 4737 */
3490 ElementResolver _elementResolver; 4738 ElementResolver _elementResolver;
4739
3491 /** 4740 /**
3492 * The object used to compute the type associated with the current node. 4741 * The object used to compute the type associated with the current node.
3493 */ 4742 */
3494 StaticTypeAnalyzer _typeAnalyzer; 4743 StaticTypeAnalyzer _typeAnalyzer;
4744
3495 /** 4745 /**
3496 * The class element representing the class containing the current node, or {@ code null} if the 4746 * The class element representing the class containing the current node, or {@ code null} if the
3497 * current node is not contained in a class. 4747 * current node is not contained in a class.
3498 */ 4748 */
3499 ClassElement _enclosingClass = null; 4749 ClassElement _enclosingClass = null;
4750
3500 /** 4751 /**
3501 * The element representing the function containing the current node, or {@cod e null} if the 4752 * The element representing the function containing the current node, or {@cod e null} if the
3502 * current node is not contained in a function. 4753 * current node is not contained in a function.
3503 */ 4754 */
3504 ExecutableElement _enclosingFunction = null; 4755 ExecutableElement _enclosingFunction = null;
4756
3505 /** 4757 /**
3506 * The object keeping track of which elements have had their types overridden. 4758 * The object keeping track of which elements have had their types overridden.
3507 */ 4759 */
3508 TypeOverrideManager _overrideManager = new TypeOverrideManager(); 4760 TypeOverrideManager _overrideManager = new TypeOverrideManager();
4761
3509 /** 4762 /**
3510 * Initialize a newly created visitor to resolve the nodes in a compilation un it. 4763 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
3511 * @param library the library containing the compilation unit being resolved 4764 * @param library the library containing the compilation unit being resolved
3512 * @param source the source representing the compilation unit being visited 4765 * @param source the source representing the compilation unit being visited
3513 * @param typeProvider the object used to access the types from the core libra ry 4766 * @param typeProvider the object used to access the types from the core libra ry
3514 */ 4767 */
3515 ResolverVisitor.con1(Library library, Source source, TypeProvider typeProvider ) : super.con1(library, source, typeProvider) { 4768 ResolverVisitor.con1(Library library, Source source, TypeProvider typeProvider ) : super.con1(library, source, typeProvider) {
3516 _jtd_constructor_266_impl(library, source, typeProvider); 4769 _jtd_constructor_272_impl(library, source, typeProvider);
3517 } 4770 }
3518 _jtd_constructor_266_impl(Library library, Source source, TypeProvider typePro vider) { 4771 _jtd_constructor_272_impl(Library library, Source source, TypeProvider typePro vider) {
3519 this._elementResolver = new ElementResolver(this); 4772 this._elementResolver = new ElementResolver(this);
3520 this._typeAnalyzer = new StaticTypeAnalyzer(this); 4773 this._typeAnalyzer = new StaticTypeAnalyzer(this);
3521 } 4774 }
4775
3522 /** 4776 /**
3523 * Initialize a newly created visitor to resolve the nodes in a compilation un it. 4777 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
3524 * @param definingLibrary the element for the library containing the compilati on unit being 4778 * @param definingLibrary the element for the library containing the compilati on unit being
3525 * visited 4779 * visited
3526 * @param source the source representing the compilation unit being visited 4780 * @param source the source representing the compilation unit being visited
3527 * @param typeProvider the object used to access the types from the core libra ry 4781 * @param typeProvider the object used to access the types from the core libra ry
3528 * @param errorListener the error listener that will be informed of any errors that are found 4782 * @param errorListener the error listener that will be informed of any errors that are found
3529 * during resolution 4783 * during resolution
3530 */ 4784 */
3531 ResolverVisitor.con2(LibraryElement definingLibrary, Source source, TypeProvid er typeProvider, AnalysisErrorListener errorListener) : super.con2(definingLibra ry, source, typeProvider, errorListener) { 4785 ResolverVisitor.con2(LibraryElement definingLibrary, Source source, TypeProvid er typeProvider, AnalysisErrorListener errorListener) : super.con2(definingLibra ry, source, typeProvider, errorListener) {
3532 _jtd_constructor_267_impl(definingLibrary, source, typeProvider, errorListen er); 4786 _jtd_constructor_273_impl(definingLibrary, source, typeProvider, errorListen er);
3533 } 4787 }
3534 _jtd_constructor_267_impl(LibraryElement definingLibrary, Source source, TypeP rovider typeProvider, AnalysisErrorListener errorListener) { 4788 _jtd_constructor_273_impl(LibraryElement definingLibrary, Source source, TypeP rovider typeProvider, AnalysisErrorListener errorListener) {
3535 this._elementResolver = new ElementResolver(this); 4789 this._elementResolver = new ElementResolver(this);
3536 this._typeAnalyzer = new StaticTypeAnalyzer(this); 4790 this._typeAnalyzer = new StaticTypeAnalyzer(this);
3537 } 4791 }
4792
3538 /** 4793 /**
3539 * Return the object keeping track of which elements have had their types over ridden. 4794 * Return the object keeping track of which elements have had their types over ridden.
3540 * @return the object keeping track of which elements have had their types ove rridden 4795 * @return the object keeping track of which elements have had their types ove rridden
3541 */ 4796 */
3542 TypeOverrideManager get overrideManager => _overrideManager; 4797 TypeOverrideManager get overrideManager => _overrideManager;
3543 Object visitAsExpression(AsExpression node) { 4798 Object visitAsExpression(AsExpression node) {
3544 super.visitAsExpression(node); 4799 super.visitAsExpression(node);
3545 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 4800 VariableElement element = getOverridableElement(node.expression);
3546 VariableElement element = getOverridableElement(node.expression); 4801 if (element != null) {
3547 if (element != null) { 4802 override(element, node.type.type);
3548 Type2 type2 = node.type.type;
3549 if (type2 != null) {
3550 override(element, getType(element), type2);
3551 }
3552 }
3553 } 4803 }
3554 return null; 4804 return null;
3555 } 4805 }
3556 Object visitAssertStatement(AssertStatement node) { 4806 Object visitAssertStatement(AssertStatement node) {
3557 super.visitAssertStatement(node); 4807 super.visitAssertStatement(node);
3558 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 4808 propagateTrueState(node.condition);
3559 propagateTrueState(node.condition);
3560 }
3561 return null; 4809 return null;
3562 } 4810 }
3563 Object visitBinaryExpression(BinaryExpression node) { 4811 Object visitBinaryExpression(BinaryExpression node) {
3564 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 4812 sc.TokenType operatorType = node.operator.type;
3565 sc.TokenType operatorType = node.operator.type; 4813 Expression leftOperand2 = node.leftOperand;
3566 if (identical(operatorType, sc.TokenType.AMPERSAND_AMPERSAND)) { 4814 Expression rightOperand2 = node.rightOperand;
3567 Expression leftOperand2 = node.leftOperand; 4815 if (identical(operatorType, sc.TokenType.AMPERSAND_AMPERSAND)) {
3568 leftOperand2.accept(this); 4816 safelyVisit(leftOperand2);
3569 Expression rightOperand2 = node.rightOperand; 4817 if (rightOperand2 != null) {
3570 if (rightOperand2 != null) { 4818 try {
3571 try { 4819 _overrideManager.enterScope();
3572 _overrideManager.enterScope(); 4820 propagateTrueState(leftOperand2);
3573 propagateTrueState(leftOperand2); 4821 rightOperand2.accept(this);
3574 rightOperand2.accept(this); 4822 } finally {
3575 } finally { 4823 _overrideManager.exitScope();
3576 _overrideManager.exitScope();
3577 }
3578 } 4824 }
3579 } else if (identical(operatorType, sc.TokenType.BAR_BAR)) { 4825 }
3580 Expression leftOperand3 = node.leftOperand; 4826 } else if (identical(operatorType, sc.TokenType.BAR_BAR)) {
3581 leftOperand3.accept(this); 4827 safelyVisit(leftOperand2);
3582 Expression rightOperand3 = node.rightOperand; 4828 if (rightOperand2 != null) {
3583 if (rightOperand3 != null) { 4829 try {
3584 try { 4830 _overrideManager.enterScope();
3585 _overrideManager.enterScope(); 4831 propagateFalseState(leftOperand2);
3586 propagateFalseState(leftOperand3); 4832 rightOperand2.accept(this);
3587 rightOperand3.accept(this); 4833 } finally {
3588 } finally { 4834 _overrideManager.exitScope();
3589 _overrideManager.exitScope();
3590 }
3591 } 4835 }
3592 } else {
3593 node.leftOperand.accept(this);
3594 node.rightOperand.accept(this);
3595 } 4836 }
3596 node.accept(_elementResolver);
3597 node.accept(_typeAnalyzer);
3598 } else { 4837 } else {
3599 super.visitBinaryExpression(node); 4838 safelyVisit(leftOperand2);
4839 safelyVisit(rightOperand2);
3600 } 4840 }
4841 node.accept(_elementResolver);
4842 node.accept(_typeAnalyzer);
3601 return null; 4843 return null;
3602 } 4844 }
3603 Object visitBreakStatement(BreakStatement node) { 4845 Object visitBreakStatement(BreakStatement node) {
3604 node.accept(_elementResolver); 4846 node.accept(_elementResolver);
3605 node.accept(_typeAnalyzer); 4847 node.accept(_typeAnalyzer);
3606 return null; 4848 return null;
3607 } 4849 }
3608 Object visitClassDeclaration(ClassDeclaration node) { 4850 Object visitClassDeclaration(ClassDeclaration node) {
3609 ClassElement outerType = _enclosingClass; 4851 ClassElement outerType = _enclosingClass;
3610 try { 4852 try {
3611 _enclosingClass = node.element; 4853 _enclosingClass = node.element;
3612 _typeAnalyzer.thisType = _enclosingClass == null ? null : _enclosingClass. type; 4854 _typeAnalyzer.thisType = _enclosingClass == null ? null : _enclosingClass. type;
3613 super.visitClassDeclaration(node); 4855 super.visitClassDeclaration(node);
3614 } finally { 4856 } finally {
3615 _typeAnalyzer.thisType = outerType == null ? null : outerType.type; 4857 _typeAnalyzer.thisType = outerType == null ? null : outerType.type;
3616 _enclosingClass = outerType; 4858 _enclosingClass = outerType;
3617 } 4859 }
3618 return null; 4860 return null;
3619 } 4861 }
3620 Object visitCommentReference(CommentReference node) { 4862 Object visitCommentReference(CommentReference node) {
3621 node.accept(_elementResolver); 4863 node.accept(_elementResolver);
3622 node.accept(_typeAnalyzer); 4864 node.accept(_typeAnalyzer);
3623 return null; 4865 return null;
3624 } 4866 }
3625 Object visitCompilationUnit(CompilationUnit node) { 4867 Object visitCompilationUnit(CompilationUnit node) {
3626 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 4868 try {
4869 _overrideManager.enterScope();
4870 for (Directive directive in node.directives) {
4871 directive.accept(this);
4872 }
4873 List<CompilationUnitMember> classes = new List<CompilationUnitMember>();
4874 for (CompilationUnitMember declaration in node.declarations) {
4875 if (declaration is ClassDeclaration) {
4876 classes.add(declaration);
4877 } else {
4878 declaration.accept(this);
4879 }
4880 }
4881 for (CompilationUnitMember declaration in classes) {
4882 declaration.accept(this);
4883 }
4884 } finally {
4885 _overrideManager.exitScope();
4886 }
4887 node.accept(_elementResolver);
4888 node.accept(_typeAnalyzer);
4889 return null;
4890 }
4891 Object visitConditionalExpression(ConditionalExpression node) {
4892 Expression condition2 = node.condition;
4893 safelyVisit(condition2);
4894 Expression thenExpression2 = node.thenExpression;
4895 if (thenExpression2 != null) {
3627 try { 4896 try {
3628 _overrideManager.enterScope(); 4897 _overrideManager.enterScope();
3629 for (Directive directive in node.directives) { 4898 propagateTrueState(condition2);
3630 directive.accept(this); 4899 thenExpression2.accept(this);
3631 }
3632 List<CompilationUnitMember> classes = new List<CompilationUnitMember>();
3633 for (CompilationUnitMember declaration in node.declarations) {
3634 if (declaration is ClassDeclaration) {
3635 classes.add(declaration);
3636 } else {
3637 declaration.accept(this);
3638 }
3639 }
3640 for (CompilationUnitMember declaration in classes) {
3641 declaration.accept(this);
3642 }
3643 } finally { 4900 } finally {
3644 _overrideManager.exitScope(); 4901 _overrideManager.exitScope();
3645 } 4902 }
3646 node.accept(_elementResolver);
3647 node.accept(_typeAnalyzer);
3648 } else {
3649 super.visitCompilationUnit(node);
3650 } 4903 }
3651 return null; 4904 Expression elseExpression2 = node.elseExpression;
3652 } 4905 if (elseExpression2 != null) {
3653 Object visitConditionalExpression(ConditionalExpression node) { 4906 try {
3654 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 4907 _overrideManager.enterScope();
3655 Expression condition2 = node.condition; 4908 propagateFalseState(condition2);
3656 condition2.accept(this); 4909 elseExpression2.accept(this);
3657 Expression thenExpression2 = node.thenExpression; 4910 } finally {
3658 if (thenExpression2 != null) { 4911 _overrideManager.exitScope();
3659 try {
3660 _overrideManager.enterScope();
3661 propagateTrueState(condition2);
3662 thenExpression2.accept(this);
3663 } finally {
3664 _overrideManager.exitScope();
3665 }
3666 } 4912 }
3667 Expression elseExpression2 = node.elseExpression; 4913 }
3668 if (elseExpression2 != null) { 4914 node.accept(_elementResolver);
3669 try { 4915 node.accept(_typeAnalyzer);
3670 _overrideManager.enterScope(); 4916 bool thenIsAbrupt = isAbruptTermination(thenExpression2);
3671 propagateFalseState(condition2); 4917 bool elseIsAbrupt = isAbruptTermination(elseExpression2);
3672 elseExpression2.accept(this); 4918 if (elseIsAbrupt && !thenIsAbrupt) {
3673 } finally { 4919 propagateTrueState(condition2);
3674 _overrideManager.exitScope(); 4920 propagateState(thenExpression2);
3675 } 4921 } else if (thenIsAbrupt && !elseIsAbrupt) {
3676 } 4922 propagateFalseState(condition2);
3677 node.accept(_elementResolver); 4923 propagateState(elseExpression2);
3678 node.accept(_typeAnalyzer);
3679 bool thenIsAbrupt = thenExpression2 != null && isAbruptTermination(thenExp ression2);
3680 bool elseIsAbrupt = elseExpression2 != null && isAbruptTermination(elseExp ression2);
3681 if (elseIsAbrupt && !thenIsAbrupt) {
3682 propagateTrueState(condition2);
3683 } else if (thenIsAbrupt && !elseIsAbrupt) {
3684 propagateFalseState(condition2);
3685 }
3686 } else {
3687 super.visitConditionalExpression(node);
3688 } 4924 }
3689 return null; 4925 return null;
3690 } 4926 }
3691 Object visitConstructorDeclaration(ConstructorDeclaration node) { 4927 Object visitConstructorDeclaration(ConstructorDeclaration node) {
3692 ExecutableElement outerFunction = _enclosingFunction; 4928 ExecutableElement outerFunction = _enclosingFunction;
3693 try { 4929 try {
3694 _enclosingFunction = node.element; 4930 _enclosingFunction = node.element;
3695 super.visitConstructorDeclaration(node); 4931 super.visitConstructorDeclaration(node);
3696 } finally { 4932 } finally {
3697 _enclosingFunction = outerFunction; 4933 _enclosingFunction = outerFunction;
3698 } 4934 }
3699 return null; 4935 return null;
3700 } 4936 }
3701 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) { 4937 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
3702 safelyVisit(node.expression); 4938 safelyVisit(node.expression);
3703 node.accept(_elementResolver); 4939 node.accept(_elementResolver);
3704 node.accept(_typeAnalyzer); 4940 node.accept(_typeAnalyzer);
3705 return null; 4941 return null;
3706 } 4942 }
3707 Object visitConstructorName(ConstructorName node) { 4943 Object visitConstructorName(ConstructorName node) {
3708 node.accept(_elementResolver); 4944 node.accept(_elementResolver);
3709 node.accept(_typeAnalyzer); 4945 node.accept(_typeAnalyzer);
3710 return null; 4946 return null;
3711 } 4947 }
3712 Object visitContinueStatement(ContinueStatement node) { 4948 Object visitContinueStatement(ContinueStatement node) {
3713 node.accept(_elementResolver); 4949 node.accept(_elementResolver);
3714 node.accept(_typeAnalyzer); 4950 node.accept(_typeAnalyzer);
3715 return null; 4951 return null;
3716 } 4952 }
4953 Object visitDoStatement(DoStatement node) {
4954 try {
4955 _overrideManager.enterScope();
4956 super.visitDoStatement(node);
4957 } finally {
4958 _overrideManager.exitScope();
4959 }
4960 return null;
4961 }
3717 Object visitFieldDeclaration(FieldDeclaration node) { 4962 Object visitFieldDeclaration(FieldDeclaration node) {
3718 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 4963 try {
3719 try { 4964 _overrideManager.enterScope();
3720 _overrideManager.enterScope();
3721 super.visitFieldDeclaration(node);
3722 } finally {
3723 Map<Element, Type2> overrides = captureOverrides(node.fields);
3724 _overrideManager.exitScope();
3725 applyOverrides(overrides);
3726 }
3727 } else {
3728 super.visitFieldDeclaration(node); 4965 super.visitFieldDeclaration(node);
4966 } finally {
4967 Map<Element, Type2> overrides = _overrideManager.captureOverrides(node.fie lds);
4968 _overrideManager.exitScope();
4969 _overrideManager.applyOverrides(overrides);
3729 } 4970 }
3730 return null; 4971 return null;
3731 } 4972 }
3732 Object visitForEachStatement(ForEachStatement node) { 4973 Object visitForEachStatement(ForEachStatement node) {
3733 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 4974 try {
3734 try { 4975 _overrideManager.enterScope();
3735 _overrideManager.enterScope();
3736 super.visitForEachStatement(node);
3737 } finally {
3738 _overrideManager.exitScope();
3739 }
3740 } else {
3741 super.visitForEachStatement(node); 4976 super.visitForEachStatement(node);
4977 } finally {
4978 _overrideManager.exitScope();
3742 } 4979 }
3743 return null; 4980 return null;
3744 } 4981 }
3745 Object visitForStatement(ForStatement node) { 4982 Object visitForStatement(ForStatement node) {
3746 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 4983 try {
3747 try { 4984 _overrideManager.enterScope();
3748 _overrideManager.enterScope();
3749 super.visitForStatement(node);
3750 } finally {
3751 _overrideManager.exitScope();
3752 }
3753 } else {
3754 super.visitForStatement(node); 4985 super.visitForStatement(node);
4986 } finally {
4987 _overrideManager.exitScope();
3755 } 4988 }
3756 return null; 4989 return null;
3757 } 4990 }
3758 Object visitFunctionBody(FunctionBody node) { 4991 Object visitFunctionBody(FunctionBody node) {
3759 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 4992 try {
3760 try { 4993 _overrideManager.enterScope();
3761 _overrideManager.enterScope();
3762 super.visitFunctionBody(node);
3763 } finally {
3764 _overrideManager.exitScope();
3765 }
3766 } else {
3767 super.visitFunctionBody(node); 4994 super.visitFunctionBody(node);
4995 } finally {
4996 _overrideManager.exitScope();
3768 } 4997 }
3769 return null; 4998 return null;
3770 } 4999 }
3771 Object visitFunctionDeclaration(FunctionDeclaration node) { 5000 Object visitFunctionDeclaration(FunctionDeclaration node) {
3772 ExecutableElement outerFunction = _enclosingFunction; 5001 ExecutableElement outerFunction = _enclosingFunction;
3773 try { 5002 try {
3774 SimpleIdentifier functionName = node.name; 5003 SimpleIdentifier functionName = node.name;
3775 _enclosingFunction = functionName.element as ExecutableElement; 5004 _enclosingFunction = functionName.element as ExecutableElement;
3776 super.visitFunctionDeclaration(node); 5005 super.visitFunctionDeclaration(node);
3777 } finally { 5006 } finally {
3778 _enclosingFunction = outerFunction; 5007 _enclosingFunction = outerFunction;
3779 } 5008 }
3780 return null; 5009 return null;
3781 } 5010 }
3782 Object visitFunctionExpression(FunctionExpression node) { 5011 Object visitFunctionExpression(FunctionExpression node) {
3783 ExecutableElement outerFunction = _enclosingFunction; 5012 ExecutableElement outerFunction = _enclosingFunction;
3784 try { 5013 try {
3785 _enclosingFunction = node.element; 5014 _enclosingFunction = node.element;
3786 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 5015 _overrideManager.enterScope();
3787 _overrideManager.enterScope();
3788 }
3789 super.visitFunctionExpression(node); 5016 super.visitFunctionExpression(node);
3790 } finally { 5017 } finally {
3791 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 5018 _overrideManager.exitScope();
3792 _overrideManager.exitScope();
3793 }
3794 _enclosingFunction = outerFunction; 5019 _enclosingFunction = outerFunction;
3795 } 5020 }
3796 return null; 5021 return null;
3797 } 5022 }
3798 Object visitHideCombinator(HideCombinator node) => null; 5023 Object visitHideCombinator(HideCombinator node) => null;
3799 Object visitIfStatement(IfStatement node) { 5024 Object visitIfStatement(IfStatement node) {
3800 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 5025 Expression condition2 = node.condition;
3801 Expression condition2 = node.condition; 5026 safelyVisit(condition2);
3802 condition2.accept(this); 5027 Map<Element, Type2> thenOverrides = null;
3803 Statement thenStatement2 = node.thenStatement; 5028 Statement thenStatement2 = node.thenStatement;
3804 if (thenStatement2 != null) { 5029 if (thenStatement2 != null) {
3805 try { 5030 try {
3806 _overrideManager.enterScope(); 5031 _overrideManager.enterScope();
3807 propagateTrueState(condition2); 5032 propagateTrueState(condition2);
3808 thenStatement2.accept(this); 5033 thenStatement2.accept(this);
3809 } finally { 5034 } finally {
3810 _overrideManager.exitScope(); 5035 thenOverrides = _overrideManager.captureLocalOverrides();
3811 } 5036 _overrideManager.exitScope();
3812 } 5037 }
3813 Statement elseStatement2 = node.elseStatement; 5038 }
3814 if (elseStatement2 != null) { 5039 Map<Element, Type2> elseOverrides = null;
3815 try { 5040 Statement elseStatement2 = node.elseStatement;
3816 _overrideManager.enterScope(); 5041 if (elseStatement2 != null) {
3817 propagateFalseState(condition2); 5042 try {
3818 elseStatement2.accept(this); 5043 _overrideManager.enterScope();
3819 } finally { 5044 propagateFalseState(condition2);
3820 _overrideManager.exitScope(); 5045 elseStatement2.accept(this);
3821 } 5046 } finally {
5047 elseOverrides = _overrideManager.captureLocalOverrides();
5048 _overrideManager.exitScope();
3822 } 5049 }
3823 node.accept(_elementResolver); 5050 }
3824 node.accept(_typeAnalyzer); 5051 node.accept(_elementResolver);
3825 bool thenIsAbrupt = thenStatement2 != null && isAbruptTermination2(thenSta tement2); 5052 node.accept(_typeAnalyzer);
3826 bool elseIsAbrupt = elseStatement2 != null && isAbruptTermination2(elseSta tement2); 5053 bool thenIsAbrupt = isAbruptTermination2(thenStatement2);
3827 if (elseIsAbrupt && !thenIsAbrupt) { 5054 bool elseIsAbrupt = isAbruptTermination2(elseStatement2);
3828 propagateTrueState(condition2); 5055 if (elseIsAbrupt && !thenIsAbrupt) {
3829 } else if (thenIsAbrupt && !elseIsAbrupt) { 5056 propagateTrueState(condition2);
3830 propagateFalseState(condition2); 5057 if (thenOverrides != null) {
5058 _overrideManager.applyOverrides(thenOverrides);
3831 } 5059 }
3832 } else { 5060 } else if (thenIsAbrupt && !elseIsAbrupt) {
3833 super.visitIfStatement(node); 5061 propagateFalseState(condition2);
5062 if (elseOverrides != null) {
5063 _overrideManager.applyOverrides(elseOverrides);
5064 }
3834 } 5065 }
3835 return null; 5066 return null;
3836 } 5067 }
3837 Object visitLabel(Label node) => null; 5068 Object visitLabel(Label node) => null;
3838 Object visitLibraryIdentifier(LibraryIdentifier node) => null; 5069 Object visitLibraryIdentifier(LibraryIdentifier node) => null;
3839 Object visitMethodDeclaration(MethodDeclaration node) { 5070 Object visitMethodDeclaration(MethodDeclaration node) {
3840 ExecutableElement outerFunction = _enclosingFunction; 5071 ExecutableElement outerFunction = _enclosingFunction;
3841 try { 5072 try {
3842 _enclosingFunction = node.element; 5073 _enclosingFunction = node.element;
3843 super.visitMethodDeclaration(node); 5074 super.visitMethodDeclaration(node);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3878 return null; 5109 return null;
3879 } 5110 }
3880 Object visitShowCombinator(ShowCombinator node) => null; 5111 Object visitShowCombinator(ShowCombinator node) => null;
3881 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) { 5112 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
3882 safelyVisit(node.argumentList); 5113 safelyVisit(node.argumentList);
3883 node.accept(_elementResolver); 5114 node.accept(_elementResolver);
3884 node.accept(_typeAnalyzer); 5115 node.accept(_typeAnalyzer);
3885 return null; 5116 return null;
3886 } 5117 }
3887 Object visitSwitchCase(SwitchCase node) { 5118 Object visitSwitchCase(SwitchCase node) {
3888 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 5119 try {
3889 try { 5120 _overrideManager.enterScope();
3890 _overrideManager.enterScope();
3891 super.visitSwitchCase(node);
3892 } finally {
3893 _overrideManager.exitScope();
3894 }
3895 } else {
3896 super.visitSwitchCase(node); 5121 super.visitSwitchCase(node);
5122 } finally {
5123 _overrideManager.exitScope();
3897 } 5124 }
3898 return null; 5125 return null;
3899 } 5126 }
3900 Object visitSwitchDefault(SwitchDefault node) { 5127 Object visitSwitchDefault(SwitchDefault node) {
3901 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 5128 try {
3902 try { 5129 _overrideManager.enterScope();
3903 _overrideManager.enterScope();
3904 super.visitSwitchDefault(node);
3905 } finally {
3906 _overrideManager.exitScope();
3907 }
3908 } else {
3909 super.visitSwitchDefault(node); 5130 super.visitSwitchDefault(node);
5131 } finally {
5132 _overrideManager.exitScope();
3910 } 5133 }
3911 return null; 5134 return null;
3912 } 5135 }
3913 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { 5136 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
3914 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 5137 try {
3915 try { 5138 _overrideManager.enterScope();
3916 _overrideManager.enterScope();
3917 super.visitTopLevelVariableDeclaration(node);
3918 } finally {
3919 Map<Element, Type2> overrides = captureOverrides(node.variables);
3920 _overrideManager.exitScope();
3921 applyOverrides(overrides);
3922 }
3923 } else {
3924 super.visitTopLevelVariableDeclaration(node); 5139 super.visitTopLevelVariableDeclaration(node);
5140 } finally {
5141 Map<Element, Type2> overrides = _overrideManager.captureOverrides(node.var iables);
5142 _overrideManager.exitScope();
5143 _overrideManager.applyOverrides(overrides);
3925 } 5144 }
3926 return null; 5145 return null;
3927 } 5146 }
3928 Object visitTypeName(TypeName node) => null; 5147 Object visitTypeName(TypeName node) => null;
3929 Object visitWhileStatement(WhileStatement node) { 5148 Object visitWhileStatement(WhileStatement node) {
3930 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 5149 Expression condition2 = node.condition;
3931 Expression condition2 = node.condition; 5150 safelyVisit(condition2);
3932 condition2.accept(this); 5151 Statement body2 = node.body;
3933 Statement body2 = node.body; 5152 if (body2 != null) {
3934 if (body2 != null) { 5153 try {
3935 try { 5154 _overrideManager.enterScope();
3936 _overrideManager.enterScope(); 5155 propagateTrueState(condition2);
3937 propagateTrueState(condition2); 5156 body2.accept(this);
3938 body2.accept(this); 5157 } finally {
3939 } finally { 5158 _overrideManager.exitScope();
3940 _overrideManager.exitScope();
3941 }
3942 } 5159 }
3943 node.accept(_elementResolver);
3944 node.accept(_typeAnalyzer);
3945 } else {
3946 super.visitWhileStatement(node);
3947 } 5160 }
5161 node.accept(_elementResolver);
5162 node.accept(_typeAnalyzer);
3948 return null; 5163 return null;
3949 } 5164 }
5165
3950 /** 5166 /**
3951 * Return the class element representing the class containing the current node , or {@code null} if 5167 * Return the class element representing the class containing the current node , or {@code null} if
3952 * the current node is not contained in a class. 5168 * the current node is not contained in a class.
3953 * @return the class element representing the class containing the current nod e 5169 * @return the class element representing the class containing the current nod e
3954 */ 5170 */
3955 ClassElement get enclosingClass => _enclosingClass; 5171 ClassElement get enclosingClass => _enclosingClass;
5172
3956 /** 5173 /**
3957 * Return the element representing the function containing the current node, o r {@code null} if 5174 * Return the element representing the function containing the current node, o r {@code null} if
3958 * the current node is not contained in a function. 5175 * the current node is not contained in a function.
3959 * @return the element representing the function containing the current node 5176 * @return the element representing the function containing the current node
3960 */ 5177 */
3961 ExecutableElement get enclosingFunction => _enclosingFunction; 5178 ExecutableElement get enclosingFunction => _enclosingFunction;
5179
3962 /** 5180 /**
3963 * Return the element associated with the given expression whose type can be o verridden, or{@code null} if there is no element whose type can be overridden. 5181 * Return the element associated with the given expression whose type can be o verridden, or{@code null} if there is no element whose type can be overridden.
3964 * @param expression the expression with which the element is associated 5182 * @param expression the expression with which the element is associated
3965 * @return the element associated with the given expression 5183 * @return the element associated with the given expression
3966 */ 5184 */
3967 VariableElement getOverridableElement(Expression expression) { 5185 VariableElement getOverridableElement(Expression expression) {
5186 Element element = null;
3968 if (expression is SimpleIdentifier) { 5187 if (expression is SimpleIdentifier) {
3969 Element element2 = ((expression as SimpleIdentifier)).element; 5188 element = ((expression as SimpleIdentifier)).element;
3970 if (element2 is VariableElement) { 5189 } else if (expression is PrefixedIdentifier) {
3971 return element2 as VariableElement; 5190 element = ((expression as PrefixedIdentifier)).element;
3972 } 5191 } else if (expression is PropertyAccess) {
5192 element = ((expression as PropertyAccess)).propertyName.element;
5193 }
5194 if (element is VariableElement) {
5195 return element as VariableElement;
3973 } 5196 }
3974 return null; 5197 return null;
3975 } 5198 }
3976 void visitForEachStatementInScope(ForEachStatement node) { 5199
3977 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 5200 /**
3978 DeclaredIdentifier loopVariable2 = node.loopVariable; 5201 * If it is appropriate to do so, override the current type of the given eleme nt with the given
3979 safelyVisit(loopVariable2); 5202 * type. Generally speaking, it is appropriate if the given type is more speci fic than the current
3980 Expression iterator2 = node.iterator; 5203 * type.
3981 if (iterator2 != null) { 5204 * @param element the element whose type might be overridden
3982 iterator2.accept(this); 5205 * @param potentialType the potential type of the element
3983 if (loopVariable2 != null) { 5206 */
3984 LocalVariableElement loopElement = loopVariable2.element; 5207 void override(VariableElement element, Type2 potentialType) {
3985 override(loopElement, loopElement.type, getIteratorElementType(iterato r2)); 5208 if (potentialType == null || identical(potentialType, BottomTypeImpl.instanc e)) {
3986 } 5209 return;
5210 }
5211 if (element is PropertyInducingElement) {
5212 PropertyInducingElement variable = element as PropertyInducingElement;
5213 if (!variable.isConst() && !variable.isFinal()) {
5214 return;
3987 } 5215 }
3988 safelyVisit(node.body); 5216 }
3989 node.accept(_elementResolver); 5217 Type2 currentType = getBestType(element);
3990 node.accept(_typeAnalyzer); 5218 if (currentType == null || !currentType.isMoreSpecificThan(potentialType)) {
3991 } else { 5219 _overrideManager.setType(element, potentialType);
3992 super.visitForEachStatementInScope(node);
3993 } 5220 }
3994 } 5221 }
3995 /** 5222 void visitForEachStatementInScope(ForEachStatement node) {
3996 * Apply a set of overrides that were previously captured. 5223 Expression iterator2 = node.iterator;
3997 * @param overrides the overrides to be applied 5224 safelyVisit(iterator2);
3998 */ 5225 DeclaredIdentifier loopVariable2 = node.loopVariable;
3999 void applyOverrides(Map<Element, Type2> overrides) { 5226 safelyVisit(loopVariable2);
4000 for (MapEntry<Element, Type2> entry in getMapEntrySet(overrides)) { 5227 Statement body2 = node.body;
4001 _overrideManager.setType(entry.getKey(), entry.getValue()); 5228 if (body2 != null) {
5229 try {
5230 _overrideManager.enterScope();
5231 if (loopVariable2 != null && iterator2 != null) {
5232 LocalVariableElement loopElement = loopVariable2.element;
5233 if (loopElement != null) {
5234 override(loopElement, getIteratorElementType(iterator2));
5235 }
5236 }
5237 body2.accept(this);
5238 } finally {
5239 _overrideManager.exitScope();
5240 }
5241 }
5242 node.accept(_elementResolver);
5243 node.accept(_typeAnalyzer);
5244 }
5245 void visitForStatementInScope(ForStatement node) {
5246 safelyVisit(node.variables);
5247 safelyVisit(node.initialization);
5248 safelyVisit(node.condition);
5249 _overrideManager.enterScope();
5250 try {
5251 propagateTrueState(node.condition);
5252 safelyVisit(node.body);
5253 node.updaters.accept(this);
5254 } finally {
5255 _overrideManager.exitScope();
4002 } 5256 }
4003 } 5257 }
5258
4004 /** 5259 /**
4005 * Return a map from the elements for the variables in the given list that hav e their types 5260 * Return the best type information available for the given element. If the ty pe of the element
4006 * overridden to the overriding type. 5261 * has been overridden, then return the overriding type. Otherwise, return the static type.
4007 * @param variableList the list of variables whose overriding types are to be captured 5262 * @param element the element for which type information is to be returned
4008 * @return a table mapping elements to their overriding types 5263 * @return the best type information available for the given element
4009 */ 5264 */
4010 Map<Element, Type2> captureOverrides(VariableDeclarationList variableList) { 5265 Type2 getBestType(Element element) {
4011 Map<Element, Type2> overrides = new Map<Element, Type2>(); 5266 Type2 bestType = _overrideManager.getType(element);
4012 if (StaticTypeAnalyzer.USE_TYPE_PROPAGATION) { 5267 if (bestType == null) {
4013 if (variableList.isConst() || variableList.isFinal()) { 5268 if (element is LocalVariableElement) {
4014 for (VariableDeclaration variable in variableList.variables) { 5269 bestType = ((element as LocalVariableElement)).type;
4015 Element element2 = variable.element; 5270 } else if (element is ParameterElement) {
4016 if (element2 != null) { 5271 bestType = ((element as ParameterElement)).type;
4017 Type2 type = _overrideManager.getType(element2);
4018 if (type != null) {
4019 overrides[element2] = type;
4020 }
4021 }
4022 }
4023 } 5272 }
4024 } 5273 }
4025 return overrides; 5274 return bestType;
4026 } 5275 }
5276
4027 /** 5277 /**
4028 * The given expression is the expression used to compute the iterator for a f or-each statement. 5278 * The given expression is the expression used to compute the iterator for a f or-each statement.
4029 * Attempt to compute the type of objects that will be assigned to the loop va riable and return 5279 * Attempt to compute the type of objects that will be assigned to the loop va riable and return
4030 * that type. Return {@code null} if the type could not be determined. 5280 * that type. Return {@code null} if the type could not be determined.
4031 * @param iterator the iterator for a for-each statement 5281 * @param iterator the iterator for a for-each statement
4032 * @return the type of objects that will be assigned to the loop variable 5282 * @return the type of objects that will be assigned to the loop variable
4033 */ 5283 */
4034 Type2 getIteratorElementType(Expression iteratorExpression) { 5284 Type2 getIteratorElementType(Expression iteratorExpression) {
4035 Type2 expressionType = iteratorExpression.staticType; 5285 Type2 expressionType = iteratorExpression.staticType;
4036 if (expressionType is InterfaceType) { 5286 if (expressionType is InterfaceType) {
4037 PropertyAccessorElement iterator = ((expressionType as InterfaceType)).loo kUpGetter("iterator", definingLibrary); 5287 PropertyAccessorElement iterator = ((expressionType as InterfaceType)).loo kUpGetter("iterator", definingLibrary);
4038 if (iterator == null) { 5288 if (iterator == null) {
4039 return null; 5289 return null;
4040 } 5290 }
4041 Type2 iteratorType = iterator.type.returnType; 5291 Type2 iteratorType = iterator.type.returnType;
4042 if (iteratorType is InterfaceType) { 5292 if (iteratorType is InterfaceType) {
4043 PropertyAccessorElement current = ((iteratorType as InterfaceType)).look UpGetter("current", definingLibrary); 5293 PropertyAccessorElement current = ((iteratorType as InterfaceType)).look UpGetter("current", definingLibrary);
4044 if (current == null) { 5294 if (current == null) {
4045 return null; 5295 return null;
4046 } 5296 }
4047 return current.type.returnType; 5297 return current.type.returnType;
4048 } 5298 }
4049 } 5299 }
4050 return null; 5300 return null;
4051 } 5301 }
4052 /** 5302
4053 * Return the type of the given (overridable) element.
4054 * @param element the element whose type is to be returned
4055 * @return the type of the given element
4056 */
4057 Type2 getType(Element element) {
4058 if (element is LocalVariableElement) {
4059 return ((element as LocalVariableElement)).type;
4060 } else if (element is ParameterElement) {
4061 return ((element as ParameterElement)).type;
4062 }
4063 return null;
4064 }
4065 /** 5303 /**
4066 * Return {@code true} if the given expression terminates abruptly (that is, i f any expression 5304 * Return {@code true} if the given expression terminates abruptly (that is, i f any expression
4067 * following the given expression will not be reached). 5305 * following the given expression will not be reached).
4068 * @param expression the expression being tested 5306 * @param expression the expression being tested
4069 * @return {@code true} if the given expression terminates abruptly 5307 * @return {@code true} if the given expression terminates abruptly
4070 */ 5308 */
4071 bool isAbruptTermination(Expression expression2) { 5309 bool isAbruptTermination(Expression expression2) {
4072 while (expression2 is ParenthesizedExpression) { 5310 while (expression2 is ParenthesizedExpression) {
4073 expression2 = ((expression2 as ParenthesizedExpression)).expression; 5311 expression2 = ((expression2 as ParenthesizedExpression)).expression;
4074 } 5312 }
4075 return expression2 is ThrowExpression || expression2 is RethrowExpression; 5313 return expression2 is ThrowExpression || expression2 is RethrowExpression;
4076 } 5314 }
5315
4077 /** 5316 /**
4078 * Return {@code true} if the given statement terminates abruptly (that is, if any statement 5317 * Return {@code true} if the given statement terminates abruptly (that is, if any statement
4079 * following the given statement will not be reached). 5318 * following the given statement will not be reached).
4080 * @param statement the statement being tested 5319 * @param statement the statement being tested
4081 * @return {@code true} if the given statement terminates abruptly 5320 * @return {@code true} if the given statement terminates abruptly
4082 */ 5321 */
4083 bool isAbruptTermination2(Statement statement) { 5322 bool isAbruptTermination2(Statement statement) {
4084 if (statement is ReturnStatement) { 5323 if (statement is ReturnStatement || statement is BreakStatement || statement is ContinueStatement) {
4085 return true; 5324 return true;
4086 } else if (statement is ExpressionStatement) { 5325 } else if (statement is ExpressionStatement) {
4087 return isAbruptTermination(((statement as ExpressionStatement)).expression ); 5326 return isAbruptTermination(((statement as ExpressionStatement)).expression );
4088 } else if (statement is Block) { 5327 } else if (statement is Block) {
4089 NodeList<Statement> statements2 = ((statement as Block)).statements; 5328 NodeList<Statement> statements2 = ((statement as Block)).statements;
4090 int size2 = statements2.length; 5329 int size2 = statements2.length;
4091 if (size2 == 0) { 5330 if (size2 == 0) {
4092 return false; 5331 return false;
4093 } 5332 }
4094 return isAbruptTermination2(statements2[size2 - 1]); 5333 return isAbruptTermination2(statements2[size2 - 1]);
4095 } 5334 }
4096 return false; 5335 return false;
4097 } 5336 }
4098 /** 5337
4099 * If it is appropriate to do so, override the type of the given element. Use the static type and
4100 * inferred type of the element to determine whether or not it is appropriate.
4101 * @param element the element whose type might be overridden
4102 * @param staticType the static type of the element
4103 * @param inferredType the inferred type of the element
4104 */
4105 void override(VariableElement element, Type2 staticType, Type2 inferredType) {
4106 if (identical(inferredType, BottomTypeImpl.instance)) {
4107 return;
4108 }
4109 if (element is PropertyInducingElement) {
4110 PropertyInducingElement variable = element as PropertyInducingElement;
4111 if (!variable.isConst() && !variable.isFinal()) {
4112 return;
4113 }
4114 }
4115 if (staticType == null || (inferredType != null && inferredType.isMoreSpecif icThan(staticType))) {
4116 _overrideManager.setType(element, inferredType);
4117 }
4118 }
4119 /** 5338 /**
4120 * Propagate any type information that results from knowing that the given con dition will have 5339 * Propagate any type information that results from knowing that the given con dition will have
4121 * evaluated to 'false'. 5340 * been evaluated to 'false'.
4122 * @param condition the condition that will have evaluated to 'false' 5341 * @param condition the condition that will have evaluated to 'false'
4123 */ 5342 */
4124 void propagateFalseState(Expression condition) { 5343 void propagateFalseState(Expression condition) {
4125 while (condition is ParenthesizedExpression) { 5344 if (condition is BinaryExpression) {
4126 condition = ((condition as ParenthesizedExpression)).expression;
4127 }
4128 if (condition is IsExpression) {
4129 IsExpression is2 = condition as IsExpression;
4130 if (is2.notOperator != null) {
4131 VariableElement element = getOverridableElement(is2.expression);
4132 if (element != null) {
4133 Type2 type2 = is2.type.type;
4134 if (type2 != null) {
4135 override(element, getType(element), type2);
4136 }
4137 }
4138 }
4139 } else if (condition is BinaryExpression) {
4140 BinaryExpression binary = condition as BinaryExpression; 5345 BinaryExpression binary = condition as BinaryExpression;
4141 if (identical(binary.operator.type, sc.TokenType.BAR_BAR)) { 5346 if (identical(binary.operator.type, sc.TokenType.BAR_BAR)) {
4142 propagateFalseState(binary.leftOperand); 5347 propagateFalseState(binary.leftOperand);
4143 propagateFalseState(binary.rightOperand); 5348 propagateFalseState(binary.rightOperand);
4144 } 5349 }
5350 } else if (condition is IsExpression) {
5351 IsExpression is2 = condition as IsExpression;
5352 if (is2.notOperator != null) {
5353 VariableElement element = getOverridableElement(is2.expression);
5354 if (element != null) {
5355 override(element, is2.type.type);
5356 }
5357 }
5358 } else if (condition is PrefixExpression) {
5359 PrefixExpression prefix = condition as PrefixExpression;
5360 if (identical(prefix.operator.type, sc.TokenType.BANG)) {
5361 propagateTrueState(prefix.operand);
5362 }
5363 } else if (condition is ParenthesizedExpression) {
5364 propagateFalseState(((condition as ParenthesizedExpression)).expression);
4145 } 5365 }
4146 } 5366 }
5367
5368 /**
5369 * Propagate any type information that results from knowing that the given exp ression will have
5370 * been evaluated without altering the flow of execution.
5371 * @param expression the expression that will have been evaluated
5372 */
5373 void propagateState(Expression expression) {
5374 }
5375
4147 /** 5376 /**
4148 * Propagate any type information that results from knowing that the given con dition will have 5377 * Propagate any type information that results from knowing that the given con dition will have
4149 * evaluated to 'true'. 5378 * been evaluated to 'true'.
4150 * @param condition the condition that will have evaluated to 'true' 5379 * @param condition the condition that will have evaluated to 'true'
4151 */ 5380 */
4152 void propagateTrueState(Expression condition) { 5381 void propagateTrueState(Expression condition) {
4153 while (condition is ParenthesizedExpression) { 5382 if (condition is BinaryExpression) {
4154 condition = ((condition as ParenthesizedExpression)).expression;
4155 }
4156 if (condition is IsExpression) {
4157 IsExpression is2 = condition as IsExpression;
4158 if (is2.notOperator == null) {
4159 VariableElement element = getOverridableElement(is2.expression);
4160 if (element != null) {
4161 Type2 type2 = is2.type.type;
4162 if (type2 != null) {
4163 override(element, getType(element), type2);
4164 }
4165 }
4166 }
4167 } else if (condition is BinaryExpression) {
4168 BinaryExpression binary = condition as BinaryExpression; 5383 BinaryExpression binary = condition as BinaryExpression;
4169 if (identical(binary.operator.type, sc.TokenType.AMPERSAND_AMPERSAND)) { 5384 if (identical(binary.operator.type, sc.TokenType.AMPERSAND_AMPERSAND)) {
4170 propagateTrueState(binary.leftOperand); 5385 propagateTrueState(binary.leftOperand);
4171 propagateTrueState(binary.rightOperand); 5386 propagateTrueState(binary.rightOperand);
4172 } 5387 }
4173 } 5388 } else if (condition is IsExpression) {
4174 } 5389 IsExpression is2 = condition as IsExpression;
4175 /** 5390 if (is2.notOperator == null) {
4176 * Visit the given AST node if it is not null. 5391 VariableElement element = getOverridableElement(is2.expression);
4177 * @param node the node to be visited 5392 if (element != null) {
4178 */ 5393 override(element, is2.type.type);
4179 void safelyVisit(ASTNode node) { 5394 }
4180 if (node != null) { 5395 }
4181 node.accept(this); 5396 } else if (condition is PrefixExpression) {
5397 PrefixExpression prefix = condition as PrefixExpression;
5398 if (identical(prefix.operator.type, sc.TokenType.BANG)) {
5399 propagateFalseState(prefix.operand);
5400 }
5401 } else if (condition is ParenthesizedExpression) {
5402 propagateTrueState(((condition as ParenthesizedExpression)).expression);
4182 } 5403 }
4183 } 5404 }
4184 get elementResolver_J2DAccessor => _elementResolver; 5405 get elementResolver_J2DAccessor => _elementResolver;
4185 set elementResolver_J2DAccessor(__v) => _elementResolver = __v; 5406 set elementResolver_J2DAccessor(__v) => _elementResolver = __v;
4186 get labelScope_J2DAccessor => _labelScope; 5407 get labelScope_J2DAccessor => _labelScope;
4187 set labelScope_J2DAccessor(__v) => _labelScope = __v; 5408 set labelScope_J2DAccessor(__v) => _labelScope = __v;
4188 get nameScope_J2DAccessor => _nameScope; 5409 get nameScope_J2DAccessor => _nameScope;
4189 set nameScope_J2DAccessor(__v) => _nameScope = __v; 5410 set nameScope_J2DAccessor(__v) => _nameScope = __v;
4190 get typeAnalyzer_J2DAccessor => _typeAnalyzer; 5411 get typeAnalyzer_J2DAccessor => _typeAnalyzer;
4191 set typeAnalyzer_J2DAccessor(__v) => _typeAnalyzer = __v; 5412 set typeAnalyzer_J2DAccessor(__v) => _typeAnalyzer = __v;
4192 get enclosingClass_J2DAccessor => _enclosingClass; 5413 get enclosingClass_J2DAccessor => _enclosingClass;
4193 set enclosingClass_J2DAccessor(__v) => _enclosingClass = __v; 5414 set enclosingClass_J2DAccessor(__v) => _enclosingClass = __v;
4194 } 5415 }
5416
4195 /** 5417 /**
4196 * The abstract class {@code ScopedVisitor} maintains name and label scopes as a n AST structure is 5418 * The abstract class {@code ScopedVisitor} maintains name and label scopes as a n AST structure is
4197 * being visited. 5419 * being visited.
4198 * @coverage dart.engine.resolver 5420 * @coverage dart.engine.resolver
4199 */ 5421 */
4200 abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> { 5422 abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
5423
4201 /** 5424 /**
4202 * The element for the library containing the compilation unit being visited. 5425 * The element for the library containing the compilation unit being visited.
4203 */ 5426 */
4204 LibraryElement _definingLibrary; 5427 LibraryElement _definingLibrary;
5428
4205 /** 5429 /**
4206 * The source representing the compilation unit being visited. 5430 * The source representing the compilation unit being visited.
4207 */ 5431 */
4208 Source _source; 5432 Source _source;
5433
4209 /** 5434 /**
4210 * The error listener that will be informed of any errors that are found durin g resolution. 5435 * The error listener that will be informed of any errors that are found durin g resolution.
4211 */ 5436 */
4212 AnalysisErrorListener _errorListener; 5437 AnalysisErrorListener _errorListener;
5438
4213 /** 5439 /**
4214 * The scope used to resolve identifiers. 5440 * The scope used to resolve identifiers.
4215 */ 5441 */
4216 Scope _nameScope; 5442 Scope _nameScope;
5443
4217 /** 5444 /**
4218 * The object used to access the types from the core library. 5445 * The object used to access the types from the core library.
4219 */ 5446 */
4220 TypeProvider _typeProvider; 5447 TypeProvider _typeProvider;
5448
4221 /** 5449 /**
4222 * The scope used to resolve labels for {@code break} and {@code continue} sta tements, or{@code null} if no labels have been defined in the current context. 5450 * The scope used to resolve labels for {@code break} and {@code continue} sta tements, or{@code null} if no labels have been defined in the current context.
4223 */ 5451 */
4224 LabelScope _labelScope; 5452 LabelScope _labelScope;
5453
4225 /** 5454 /**
4226 * Initialize a newly created visitor to resolve the nodes in a compilation un it. 5455 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
4227 * @param library the library containing the compilation unit being resolved 5456 * @param library the library containing the compilation unit being resolved
4228 * @param source the source representing the compilation unit being visited 5457 * @param source the source representing the compilation unit being visited
4229 * @param typeProvider the object used to access the types from the core libra ry 5458 * @param typeProvider the object used to access the types from the core libra ry
4230 */ 5459 */
4231 ScopedVisitor.con1(Library library, Source source2, TypeProvider typeProvider2 ) { 5460 ScopedVisitor.con1(Library library, Source source2, TypeProvider typeProvider2 ) {
4232 _jtd_constructor_268_impl(library, source2, typeProvider2); 5461 _jtd_constructor_274_impl(library, source2, typeProvider2);
4233 } 5462 }
4234 _jtd_constructor_268_impl(Library library, Source source2, TypeProvider typePr ovider2) { 5463 _jtd_constructor_274_impl(Library library, Source source2, TypeProvider typePr ovider2) {
4235 this._definingLibrary = library.libraryElement; 5464 this._definingLibrary = library.libraryElement;
4236 this._source = source2; 5465 this._source = source2;
4237 LibraryScope libraryScope2 = library.libraryScope; 5466 LibraryScope libraryScope2 = library.libraryScope;
4238 this._errorListener = libraryScope2.errorListener; 5467 this._errorListener = libraryScope2.errorListener;
4239 this._nameScope = libraryScope2; 5468 this._nameScope = libraryScope2;
4240 this._typeProvider = typeProvider2; 5469 this._typeProvider = typeProvider2;
4241 } 5470 }
5471
4242 /** 5472 /**
4243 * Initialize a newly created visitor to resolve the nodes in a compilation un it. 5473 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
4244 * @param definingLibrary the element for the library containing the compilati on unit being 5474 * @param definingLibrary the element for the library containing the compilati on unit being
4245 * visited 5475 * visited
4246 * @param source the source representing the compilation unit being visited 5476 * @param source the source representing the compilation unit being visited
4247 * @param typeProvider the object used to access the types from the core libra ry 5477 * @param typeProvider the object used to access the types from the core libra ry
4248 * @param errorListener the error listener that will be informed of any errors that are found 5478 * @param errorListener the error listener that will be informed of any errors that are found
4249 * during resolution 5479 * during resolution
4250 */ 5480 */
4251 ScopedVisitor.con2(LibraryElement definingLibrary2, Source source2, TypeProvid er typeProvider2, AnalysisErrorListener errorListener2) { 5481 ScopedVisitor.con2(LibraryElement definingLibrary2, Source source2, TypeProvid er typeProvider2, AnalysisErrorListener errorListener2) {
4252 _jtd_constructor_269_impl(definingLibrary2, source2, typeProvider2, errorLis tener2); 5482 _jtd_constructor_275_impl(definingLibrary2, source2, typeProvider2, errorLis tener2);
4253 } 5483 }
4254 _jtd_constructor_269_impl(LibraryElement definingLibrary2, Source source2, Typ eProvider typeProvider2, AnalysisErrorListener errorListener2) { 5484 _jtd_constructor_275_impl(LibraryElement definingLibrary2, Source source2, Typ eProvider typeProvider2, AnalysisErrorListener errorListener2) {
4255 this._definingLibrary = definingLibrary2; 5485 this._definingLibrary = definingLibrary2;
4256 this._source = source2; 5486 this._source = source2;
4257 this._errorListener = errorListener2; 5487 this._errorListener = errorListener2;
4258 this._nameScope = new LibraryScope(definingLibrary2, errorListener2); 5488 this._nameScope = new LibraryScope(definingLibrary2, errorListener2);
4259 this._typeProvider = typeProvider2; 5489 this._typeProvider = typeProvider2;
4260 } 5490 }
5491
4261 /** 5492 /**
4262 * Return the library element for the library containing the compilation unit being resolved. 5493 * Return the library element for the library containing the compilation unit being resolved.
4263 * @return the library element for the library containing the compilation unit being resolved 5494 * @return the library element for the library containing the compilation unit being resolved
4264 */ 5495 */
4265 LibraryElement get definingLibrary => _definingLibrary; 5496 LibraryElement get definingLibrary => _definingLibrary;
5497
4266 /** 5498 /**
4267 * Return the object used to access the types from the core library. 5499 * Return the object used to access the types from the core library.
4268 * @return the object used to access the types from the core library 5500 * @return the object used to access the types from the core library
4269 */ 5501 */
4270 TypeProvider get typeProvider => _typeProvider; 5502 TypeProvider get typeProvider => _typeProvider;
4271 Object visitBlock(Block node) { 5503 Object visitBlock(Block node) {
4272 Scope outerScope = _nameScope; 5504 Scope outerScope = _nameScope;
4273 _nameScope = new EnclosedScope(_nameScope); 5505 _nameScope = new EnclosedScope(_nameScope);
4274 try { 5506 try {
4275 super.visitBlock(node); 5507 super.visitBlock(node);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
4356 _labelScope = outerLabelScope; 5588 _labelScope = outerLabelScope;
4357 } 5589 }
4358 return null; 5590 return null;
4359 } 5591 }
4360 Object visitForStatement(ForStatement node) { 5592 Object visitForStatement(ForStatement node) {
4361 LabelScope outerLabelScope = _labelScope; 5593 LabelScope outerLabelScope = _labelScope;
4362 _labelScope = new LabelScope.con1(outerLabelScope, false, false); 5594 _labelScope = new LabelScope.con1(outerLabelScope, false, false);
4363 Scope outerNameScope = _nameScope; 5595 Scope outerNameScope = _nameScope;
4364 _nameScope = new EnclosedScope(_nameScope); 5596 _nameScope = new EnclosedScope(_nameScope);
4365 try { 5597 try {
4366 super.visitForStatement(node); 5598 visitForStatementInScope(node);
4367 } finally { 5599 } finally {
4368 _nameScope = outerNameScope; 5600 _nameScope = outerNameScope;
4369 _labelScope = outerLabelScope; 5601 _labelScope = outerLabelScope;
4370 } 5602 }
4371 return null; 5603 return null;
4372 } 5604 }
4373 Object visitFunctionDeclaration(FunctionDeclaration node) { 5605 Object visitFunctionDeclaration(FunctionDeclaration node) {
4374 ExecutableElement function = node.element; 5606 ExecutableElement function = node.element;
4375 Scope outerScope = _nameScope; 5607 Scope outerScope = _nameScope;
4376 try { 5608 try {
4377 _nameScope = new FunctionScope(_nameScope, function); 5609 _nameScope = new FunctionScope(_nameScope, function);
4378 super.visitFunctionDeclaration(node); 5610 super.visitFunctionDeclaration(node);
4379 } finally { 5611 } finally {
4380 _nameScope = outerScope; 5612 _nameScope = outerScope;
4381 } 5613 }
4382 if (function.enclosingElement is! CompilationUnitElement) { 5614 if (function.enclosingElement is! CompilationUnitElement) {
4383 _nameScope.define(function); 5615 _nameScope.define(function);
4384 } 5616 }
4385 return null; 5617 return null;
4386 } 5618 }
4387 Object visitFunctionExpression(FunctionExpression node) { 5619 Object visitFunctionExpression(FunctionExpression node) {
4388 Scope outerScope = _nameScope; 5620 if (node.parent is FunctionDeclaration) {
4389 try { 5621 super.visitFunctionExpression(node);
4390 ExecutableElement functionElement = node.element; 5622 } else {
4391 if (functionElement == null) { 5623 Scope outerScope = _nameScope;
4392 } else { 5624 try {
4393 _nameScope = new FunctionScope(_nameScope, functionElement); 5625 ExecutableElement functionElement = node.element;
5626 if (functionElement == null) {
5627 } else {
5628 _nameScope = new FunctionScope(_nameScope, functionElement);
5629 }
5630 super.visitFunctionExpression(node);
5631 } finally {
5632 _nameScope = outerScope;
4394 } 5633 }
4395 super.visitFunctionExpression(node);
4396 } finally {
4397 _nameScope = outerScope;
4398 } 5634 }
4399 return null; 5635 return null;
4400 } 5636 }
4401 Object visitFunctionTypeAlias(FunctionTypeAlias node) { 5637 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
4402 Scope outerScope = _nameScope; 5638 Scope outerScope = _nameScope;
4403 try { 5639 try {
4404 _nameScope = new FunctionTypeScope(_nameScope, node.element); 5640 _nameScope = new FunctionTypeScope(_nameScope, node.element);
4405 super.visitFunctionTypeAlias(node); 5641 super.visitFunctionTypeAlias(node);
4406 } finally { 5642 } finally {
4407 _nameScope = outerScope; 5643 _nameScope = outerScope;
(...skipping 14 matching lines...) Expand all
4422 try { 5658 try {
4423 _nameScope = new FunctionScope(_nameScope, node.element); 5659 _nameScope = new FunctionScope(_nameScope, node.element);
4424 super.visitMethodDeclaration(node); 5660 super.visitMethodDeclaration(node);
4425 } finally { 5661 } finally {
4426 _nameScope = outerScope; 5662 _nameScope = outerScope;
4427 } 5663 }
4428 return null; 5664 return null;
4429 } 5665 }
4430 Object visitSwitchCase(SwitchCase node) { 5666 Object visitSwitchCase(SwitchCase node) {
4431 node.expression.accept(this); 5667 node.expression.accept(this);
4432 LabelScope outerLabelScope = addScopesFor(node.labels);
4433 Scope outerNameScope = _nameScope; 5668 Scope outerNameScope = _nameScope;
4434 _nameScope = new EnclosedScope(_nameScope); 5669 _nameScope = new EnclosedScope(_nameScope);
4435 try { 5670 try {
4436 node.statements.accept(this); 5671 node.statements.accept(this);
4437 } finally { 5672 } finally {
4438 _nameScope = outerNameScope; 5673 _nameScope = outerNameScope;
4439 _labelScope = outerLabelScope;
4440 } 5674 }
4441 return null; 5675 return null;
4442 } 5676 }
4443 Object visitSwitchDefault(SwitchDefault node) { 5677 Object visitSwitchDefault(SwitchDefault node) {
4444 LabelScope outerLabelScope = addScopesFor(node.labels);
4445 Scope outerNameScope = _nameScope; 5678 Scope outerNameScope = _nameScope;
4446 _nameScope = new EnclosedScope(_nameScope); 5679 _nameScope = new EnclosedScope(_nameScope);
4447 try { 5680 try {
4448 node.statements.accept(this); 5681 node.statements.accept(this);
4449 } finally { 5682 } finally {
4450 _nameScope = outerNameScope; 5683 _nameScope = outerNameScope;
4451 _labelScope = outerLabelScope;
4452 } 5684 }
4453 return null; 5685 return null;
4454 } 5686 }
4455 Object visitSwitchStatement(SwitchStatement node) { 5687 Object visitSwitchStatement(SwitchStatement node) {
4456 LabelScope outerScope = _labelScope; 5688 LabelScope outerScope = _labelScope;
4457 _labelScope = new LabelScope.con1(outerScope, true, false); 5689 _labelScope = new LabelScope.con1(outerScope, true, false);
4458 for (SwitchMember member in node.members) { 5690 for (SwitchMember member in node.members) {
4459 for (Label label in member.labels) { 5691 for (Label label in member.labels) {
4460 SimpleIdentifier labelName = label.label; 5692 SimpleIdentifier labelName = label.label;
4461 LabelElement labelElement = labelName.element as LabelElement; 5693 LabelElement labelElement = labelName.element as LabelElement;
4462 _labelScope = new LabelScope.con2(outerScope, labelName.name, labelEleme nt); 5694 _labelScope = new LabelScope.con2(_labelScope, labelName.name, labelElem ent);
4463 } 5695 }
4464 } 5696 }
4465 try { 5697 try {
4466 super.visitSwitchStatement(node); 5698 super.visitSwitchStatement(node);
4467 } finally { 5699 } finally {
4468 _labelScope = outerScope; 5700 _labelScope = outerScope;
4469 } 5701 }
4470 return null; 5702 return null;
4471 } 5703 }
4472 Object visitVariableDeclaration(VariableDeclaration node) { 5704 Object visitVariableDeclaration(VariableDeclaration node) {
4473 if (node.parent.parent is! TopLevelVariableDeclaration && node.parent.parent is! FieldDeclaration) { 5705 if (node.parent.parent is! TopLevelVariableDeclaration && node.parent.parent is! FieldDeclaration) {
4474 VariableElement element2 = node.element; 5706 VariableElement element2 = node.element;
4475 if (element2 != null) { 5707 if (element2 != null) {
4476 _nameScope.define(element2); 5708 _nameScope.define(element2);
4477 } 5709 }
4478 } 5710 }
4479 super.visitVariableDeclaration(node); 5711 super.visitVariableDeclaration(node);
4480 return null; 5712 return null;
4481 } 5713 }
4482 Object visitWhileStatement(WhileStatement node) { 5714 Object visitWhileStatement(WhileStatement node) {
4483 LabelScope outerScope = _labelScope; 5715 LabelScope outerScope = _labelScope;
4484 _labelScope = new LabelScope.con1(outerScope, false, false); 5716 _labelScope = new LabelScope.con1(outerScope, false, false);
4485 try { 5717 try {
4486 super.visitWhileStatement(node); 5718 super.visitWhileStatement(node);
4487 } finally { 5719 } finally {
4488 _labelScope = outerScope; 5720 _labelScope = outerScope;
4489 } 5721 }
4490 return null; 5722 return null;
4491 } 5723 }
5724
4492 /** 5725 /**
4493 * Return the label scope in which the current node is being resolved. 5726 * Return the label scope in which the current node is being resolved.
4494 * @return the label scope in which the current node is being resolved 5727 * @return the label scope in which the current node is being resolved
4495 */ 5728 */
4496 LabelScope get labelScope => _labelScope; 5729 LabelScope get labelScope => _labelScope;
5730
4497 /** 5731 /**
4498 * Return the name scope in which the current node is being resolved. 5732 * Return the name scope in which the current node is being resolved.
4499 * @return the name scope in which the current node is being resolved 5733 * @return the name scope in which the current node is being resolved
4500 */ 5734 */
4501 Scope get nameScope => _nameScope; 5735 Scope get nameScope => _nameScope;
5736
4502 /** 5737 /**
4503 * Report an error with the given error code and arguments. 5738 * Report an error with the given error code and arguments.
4504 * @param errorCode the error code of the error to be reported 5739 * @param errorCode the error code of the error to be reported
4505 * @param node the node specifying the location of the error 5740 * @param node the node specifying the location of the error
4506 * @param arguments the arguments to the error, used to compose the error mess age 5741 * @param arguments the arguments to the error, used to compose the error mess age
4507 */ 5742 */
4508 void reportError(ErrorCode errorCode, ASTNode node, List<Object> arguments) { 5743 void reportError(ErrorCode errorCode, ASTNode node, List<Object> arguments) {
4509 _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.len gth, errorCode, arguments)); 5744 _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.len gth, errorCode, arguments));
4510 } 5745 }
5746
5747 /**
5748 * Report an error with the given error code and arguments.
5749 * @param errorCode the error code of the error to be reported
5750 * @param offset the offset of the location of the error
5751 * @param length the length of the location of the error
5752 * @param arguments the arguments to the error, used to compose the error mess age
5753 */
5754 void reportError5(ErrorCode errorCode, int offset, int length, List<Object> ar guments) {
5755 _errorListener.onError(new AnalysisError.con2(_source, offset, length, error Code, arguments));
5756 }
5757
4511 /** 5758 /**
4512 * Report an error with the given error code and arguments. 5759 * Report an error with the given error code and arguments.
4513 * @param errorCode the error code of the error to be reported 5760 * @param errorCode the error code of the error to be reported
4514 * @param token the token specifying the location of the error 5761 * @param token the token specifying the location of the error
4515 * @param arguments the arguments to the error, used to compose the error mess age 5762 * @param arguments the arguments to the error, used to compose the error mess age
4516 */ 5763 */
4517 void reportError3(ErrorCode errorCode, sc.Token token, List<Object> arguments) { 5764 void reportError6(ErrorCode errorCode, sc.Token token, List<Object> arguments) {
4518 _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.l ength, errorCode, arguments)); 5765 _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.l ength, errorCode, arguments));
4519 } 5766 }
5767
5768 /**
5769 * Visit the given AST node if it is not null.
5770 * @param node the node to be visited
5771 */
5772 void safelyVisit(ASTNode node) {
5773 if (node != null) {
5774 node.accept(this);
5775 }
5776 }
5777
4520 /** 5778 /**
4521 * Visit the given statement after it's scope has been created. This replaces the normal call to 5779 * Visit the given statement after it's scope has been created. This replaces the normal call to
4522 * the inherited visit method so that ResolverVisitor can intervene when type propagation is 5780 * the inherited visit method so that ResolverVisitor can intervene when type propagation is
4523 * enabled. 5781 * enabled.
4524 * @param node the statement to be visited 5782 * @param node the statement to be visited
4525 */ 5783 */
4526 void visitForEachStatementInScope(ForEachStatement node) { 5784 void visitForEachStatementInScope(ForEachStatement node) {
4527 super.visitForEachStatement(node); 5785 safelyVisit(node.iterator);
5786 safelyVisit(node.loopVariable);
5787 safelyVisit(node.body);
4528 } 5788 }
5789
5790 /**
5791 * Visit the given statement after it's scope has been created. This replaces the normal call to
5792 * the inherited visit method so that ResolverVisitor can intervene when type propagation is
5793 * enabled.
5794 * @param node the statement to be visited
5795 */
5796 void visitForStatementInScope(ForStatement node) {
5797 super.visitForStatement(node);
5798 }
5799
4529 /** 5800 /**
4530 * Add scopes for each of the given labels. 5801 * Add scopes for each of the given labels.
4531 * @param labels the labels for which new scopes are to be added 5802 * @param labels the labels for which new scopes are to be added
4532 * @return the scope that was in effect before the new scopes were added 5803 * @return the scope that was in effect before the new scopes were added
4533 */ 5804 */
4534 LabelScope addScopesFor(NodeList<Label> labels) { 5805 LabelScope addScopesFor(NodeList<Label> labels) {
4535 LabelScope outerScope = _labelScope; 5806 LabelScope outerScope = _labelScope;
4536 for (Label label in labels) { 5807 for (Label label in labels) {
4537 SimpleIdentifier labelNameNode = label.label; 5808 SimpleIdentifier labelNameNode = label.label;
4538 String labelName = labelNameNode.name; 5809 String labelName = labelNameNode.name;
4539 LabelElement labelElement = labelNameNode.element as LabelElement; 5810 LabelElement labelElement = labelNameNode.element as LabelElement;
4540 _labelScope = new LabelScope.con2(_labelScope, labelName, labelElement); 5811 _labelScope = new LabelScope.con2(_labelScope, labelName, labelElement);
4541 } 5812 }
4542 return outerScope; 5813 return outerScope;
4543 } 5814 }
4544 } 5815 }
5816
4545 /** 5817 /**
4546 * Instances of the class {@code StaticTypeAnalyzer} perform two type-related ta sks. First, they 5818 * Instances of the class {@code StaticTypeAnalyzer} perform two type-related ta sks. First, they
4547 * compute the static type of every expression. Second, they look for any static type errors or 5819 * compute the static type of every expression. Second, they look for any static type errors or
4548 * warnings that might need to be generated. The requirements for the type analy zer are: 5820 * warnings that might need to be generated. The requirements for the type analy zer are:
4549 * <ol> 5821 * <ol>
4550 * <li>Every element that refers to types should be fully populated. 5822 * <li>Every element that refers to types should be fully populated.
4551 * <li>Every node representing an expression should be resolved to the Type of t he expression.</li> 5823 * <li>Every node representing an expression should be resolved to the Type of t he expression.</li>
4552 * </ol> 5824 * </ol>
4553 * @coverage dart.engine.resolver 5825 * @coverage dart.engine.resolver
4554 */ 5826 */
4555 class StaticTypeAnalyzer extends SimpleASTVisitor<Object> { 5827 class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
5828
4556 /** 5829 /**
4557 * Create a table mapping HTML tag names to the names of the classes (in 'dart :html') that 5830 * Create a table mapping HTML tag names to the names of the classes (in 'dart :html') that
4558 * implement those tags. 5831 * implement those tags.
4559 * @return the table that was created 5832 * @return the table that was created
4560 */ 5833 */
4561 static Map<String, String> createHtmlTagToClassMap() { 5834 static Map<String, String> createHtmlTagToClassMap() {
4562 Map<String, String> map = new Map<String, String>(); 5835 Map<String, String> map = new Map<String, String>();
4563 map["a"] = "AnchorElement"; 5836 map["a"] = "AnchorElement";
4564 map["area"] = "AreaElement"; 5837 map["area"] = "AreaElement";
4565 map["br"] = "BRElement"; 5838 map["br"] = "BRElement";
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
4613 map["col"] = "TableColElement"; 5886 map["col"] = "TableColElement";
4614 map["table"] = "TableElement"; 5887 map["table"] = "TableElement";
4615 map["tr"] = "TableRowElement"; 5888 map["tr"] = "TableRowElement";
4616 map["textarea"] = "TextAreaElement"; 5889 map["textarea"] = "TextAreaElement";
4617 map["title"] = "TitleElement"; 5890 map["title"] = "TitleElement";
4618 map["track"] = "TrackElement"; 5891 map["track"] = "TrackElement";
4619 map["ul"] = "UListElement"; 5892 map["ul"] = "UListElement";
4620 map["video"] = "VideoElement"; 5893 map["video"] = "VideoElement";
4621 return map; 5894 return map;
4622 } 5895 }
5896
4623 /** 5897 /**
4624 * The resolver driving the resolution and type analysis. 5898 * The resolver driving the resolution and type analysis.
4625 */ 5899 */
4626 ResolverVisitor _resolver; 5900 ResolverVisitor _resolver;
5901
4627 /** 5902 /**
4628 * The object providing access to the types defined by the language. 5903 * The object providing access to the types defined by the language.
4629 */ 5904 */
4630 TypeProvider _typeProvider; 5905 TypeProvider _typeProvider;
5906
4631 /** 5907 /**
4632 * The type representing the type 'dynamic'. 5908 * The type representing the type 'dynamic'.
4633 */ 5909 */
4634 Type2 _dynamicType; 5910 Type2 _dynamicType;
5911
4635 /** 5912 /**
4636 * The type representing the class containing the nodes being analyzed, or {@c ode null} if the 5913 * The type representing the class containing the nodes being analyzed, or {@c ode null} if the
4637 * nodes are not within a class. 5914 * nodes are not within a class.
4638 */ 5915 */
4639 InterfaceType _thisType; 5916 InterfaceType _thisType;
5917
4640 /** 5918 /**
4641 * The object keeping track of which elements have had their types overridden. 5919 * The object keeping track of which elements have had their types overridden.
4642 */ 5920 */
4643 TypeOverrideManager _overrideManager; 5921 TypeOverrideManager _overrideManager;
4644 /** 5922
4645 * A flag indicating whether type propagation should be enabled.
4646 */
4647 static bool USE_TYPE_PROPAGATION = true;
4648 /** 5923 /**
4649 * A table mapping HTML tag names to the names of the classes (in 'dart:html') that implement 5924 * A table mapping HTML tag names to the names of the classes (in 'dart:html') that implement
4650 * those tags. 5925 * those tags.
4651 */ 5926 */
4652 static Map<String, String> _HTML_ELEMENT_TO_CLASS_MAP = createHtmlTagToClassMa p(); 5927 static Map<String, String> _HTML_ELEMENT_TO_CLASS_MAP = createHtmlTagToClassMa p();
5928
4653 /** 5929 /**
4654 * Initialize a newly created type analyzer. 5930 * Initialize a newly created type analyzer.
4655 * @param resolver the resolver driving this participant 5931 * @param resolver the resolver driving this participant
4656 */ 5932 */
4657 StaticTypeAnalyzer(ResolverVisitor resolver) { 5933 StaticTypeAnalyzer(ResolverVisitor resolver) {
4658 this._resolver = resolver; 5934 this._resolver = resolver;
4659 _typeProvider = resolver.typeProvider; 5935 _typeProvider = resolver.typeProvider;
4660 _dynamicType = _typeProvider.dynamicType; 5936 _dynamicType = _typeProvider.dynamicType;
4661 _overrideManager = resolver.overrideManager; 5937 _overrideManager = resolver.overrideManager;
4662 } 5938 }
5939
4663 /** 5940 /**
4664 * Set the type of the class being analyzed to the given type. 5941 * Set the type of the class being analyzed to the given type.
4665 * @param thisType the type representing the class containing the nodes being analyzed 5942 * @param thisType the type representing the class containing the nodes being analyzed
4666 */ 5943 */
4667 void set thisType(InterfaceType thisType2) { 5944 void set thisType(InterfaceType thisType2) {
4668 this._thisType = thisType2; 5945 this._thisType = thisType2;
4669 } 5946 }
5947
4670 /** 5948 /**
4671 * The Dart Language Specification, 12.5: <blockquote>The static type of a str ing literal is{@code String}.</blockquote> 5949 * The Dart Language Specification, 12.5: <blockquote>The static type of a str ing literal is{@code String}.</blockquote>
4672 */ 5950 */
4673 Object visitAdjacentStrings(AdjacentStrings node) => recordType(node, _typePro vider.stringType); 5951 Object visitAdjacentStrings(AdjacentStrings node) {
5952 recordStaticType(node, _typeProvider.stringType);
5953 return null;
5954 }
5955
4674 /** 5956 /**
4675 * The Dart Language Specification, 12.33: <blockquote>The static type of an a rgument definition 5957 * The Dart Language Specification, 12.33: <blockquote>The static type of an a rgument definition
4676 * test is {@code bool}.</blockquote> 5958 * test is {@code bool}.</blockquote>
4677 */ 5959 */
4678 Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) => recordType( node, _typeProvider.boolType); 5960 Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) {
5961 recordStaticType(node, _typeProvider.boolType);
5962 return null;
5963 }
5964
4679 /** 5965 /**
4680 * The Dart Language Specification, 12.32: <blockquote>... the cast expression <i>e as T</i> ... 5966 * The Dart Language Specification, 12.32: <blockquote>... the cast expression <i>e as T</i> ...
4681 * <p> 5967 * <p>
4682 * It is a static warning if <i>T</i> does not denote a type available in the current lexical 5968 * It is a static warning if <i>T</i> does not denote a type available in the current lexical
4683 * scope. 5969 * scope.
4684 * <p> 5970 * <p>
4685 * The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote > 5971 * The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote >
4686 */ 5972 */
4687 Object visitAsExpression(AsExpression node) => recordType(node, getType4(node. type)); 5973 Object visitAsExpression(AsExpression node) {
5974 recordStaticType(node, getType2(node.type));
5975 return null;
5976 }
5977
4688 /** 5978 /**
4689 * The Dart Language Specification, 12.18: <blockquote> ... an assignment <i>a </i> of the form 5979 * The Dart Language Specification, 12.18: <blockquote>... an assignment <i>a< /i> of the form <i>v
4690 * <i>v = e</i> ... 5980 * = e</i> ...
4691 * <p> 5981 * <p>
4692 * It is a static type warning if the static type of <i>e</i> may not be assig ned to the static 5982 * It is a static type warning if the static type of <i>e</i> may not be assig ned to the static
4693 * type of <i>v</i>. 5983 * type of <i>v</i>.
4694 * <p> 5984 * <p>
4695 * The static type of the expression <i>v = e</i> is the static type of <i>e</ i>. 5985 * The static type of the expression <i>v = e</i> is the static type of <i>e</ i>.
4696 * <p> 5986 * <p>
4697 * ... an assignment of the form <i>C.v = e</i> ... 5987 * ... an assignment of the form <i>C.v = e</i> ...
4698 * <p> 5988 * <p>
4699 * It is a static type warning if the static type of <i>e</i> may not be assig ned to the static 5989 * It is a static type warning if the static type of <i>e</i> may not be assig ned to the static
4700 * type of <i>C.v</i>. 5990 * type of <i>C.v</i>.
(...skipping 14 matching lines...) Expand all
4715 * The static type of the expression <i>e<sub>1</sub>\[e<sub>2</sub>\] = e<sub >3</sub></i> is the 6005 * The static type of the expression <i>e<sub>1</sub>\[e<sub>2</sub>\] = e<sub >3</sub></i> is the
4716 * static type of <i>e<sub>3</sub></i>. 6006 * static type of <i>e<sub>3</sub></i>.
4717 * <p> 6007 * <p>
4718 * A compound assignment of the form <i>v op= e</i> is equivalent to <i>v = v op e</i>. A compound 6008 * A compound assignment of the form <i>v op= e</i> is equivalent to <i>v = v op e</i>. A compound
4719 * assignment of the form <i>C.v op= e</i> is equivalent to <i>C.v = C.v op e< /i>. A compound 6009 * assignment of the form <i>C.v op= e</i> is equivalent to <i>C.v = C.v op e< /i>. A compound
4720 * assignment of the form <i>e<sub>1</sub>.v op= e<sub>2</sub></i> is equivale nt to <i>((x) => x.v 6010 * assignment of the form <i>e<sub>1</sub>.v op= e<sub>2</sub></i> is equivale nt to <i>((x) => x.v
4721 * = x.v op e<sub>2</sub>)(e<sub>1</sub>)</i> where <i>x</i> is a variable tha t is not used in 6011 * = x.v op e<sub>2</sub>)(e<sub>1</sub>)</i> where <i>x</i> is a variable tha t is not used in
4722 * <i>e<sub>2</sub></i>. A compound assignment of the form <i>e<sub>1</sub>\[e <sub>2</sub>\] op= 6012 * <i>e<sub>2</sub></i>. A compound assignment of the form <i>e<sub>1</sub>\[e <sub>2</sub>\] op=
4723 * e<sub>3</sub></i> is equivalent to <i>((a, i) => a\[i\] = a\[i\] op e<sub>3 </sub>)(e<sub>1</sub>, 6013 * e<sub>3</sub></i> is equivalent to <i>((a, i) => a\[i\] = a\[i\] op e<sub>3 </sub>)(e<sub>1</sub>,
4724 * e<sub>2</sub>)</i> where <i>a</i> and <i>i</i> are a variables that are not used in 6014 * e<sub>2</sub>)</i> where <i>a</i> and <i>i</i> are a variables that are not used in
4725 * <i>e<sub>3</sub></i>. </blockquote> 6015 * <i>e<sub>3</sub></i>.</blockquote>
4726 */ 6016 */
4727 Object visitAssignmentExpression(AssignmentExpression node) { 6017 Object visitAssignmentExpression(AssignmentExpression node) {
4728 sc.TokenType operator2 = node.operator.type; 6018 sc.TokenType operator2 = node.operator.type;
4729 if (operator2 != sc.TokenType.EQ) { 6019 if (identical(operator2, sc.TokenType.EQ)) {
4730 return recordReturnType(node, node.element); 6020 Expression rightHandSide2 = node.rightHandSide;
4731 } 6021 Type2 staticType = getStaticType(rightHandSide2);
4732 Type2 rightType = getType2(node.rightHandSide); 6022 recordStaticType(node, staticType);
4733 if (USE_TYPE_PROPAGATION) { 6023 Type2 overrideType = staticType;
6024 Type2 propagatedType = getPropagatedType(rightHandSide2);
6025 if (propagatedType != null) {
6026 if (propagatedType.isMoreSpecificThan(staticType)) {
6027 recordPropagatedType(node, propagatedType);
6028 }
6029 overrideType = propagatedType;
6030 }
4734 VariableElement element = _resolver.getOverridableElement(node.leftHandSid e); 6031 VariableElement element = _resolver.getOverridableElement(node.leftHandSid e);
4735 if (element != null) { 6032 if (element != null) {
4736 override(element, getType(element), rightType); 6033 _resolver.override(element, overrideType);
6034 }
6035 } else {
6036 ExecutableElement staticMethodElement = node.staticElement;
6037 Type2 staticType = computeReturnType(staticMethodElement);
6038 recordStaticType(node, staticType);
6039 MethodElement propagatedMethodElement = node.element;
6040 if (propagatedMethodElement != staticMethodElement) {
6041 Type2 propagatedType = computeReturnType(propagatedMethodElement);
6042 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy pe)) {
6043 recordPropagatedType(node, propagatedType);
6044 }
4737 } 6045 }
4738 } 6046 }
4739 return recordType(node, rightType); 6047 return null;
4740 } 6048 }
6049
4741 /** 6050 /**
4742 * The Dart Language Specification, 12.20: <blockquote>The static type of a lo gical boolean 6051 * The Dart Language Specification, 12.20: <blockquote>The static type of a lo gical boolean
4743 * expression is {@code bool}.</blockquote> 6052 * expression is {@code bool}.</blockquote>
4744 * <p> 6053 * <p>
4745 * The Dart Language Specification, 12.21:<blockquote>A bitwise expression of the form 6054 * The Dart Language Specification, 12.21:<blockquote>A bitwise expression of the form
4746 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n 6055 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n
4747 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A bitwise expression of the form <i >super op 6056 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A bitwise expression of the form <i >super op
4748 * e<sub>2</sub></i> is equivalent to the method invocation 6057 * e<sub>2</sub></i> is equivalent to the method invocation
4749 * <i>super.op(e<sub>2</sub>)</i>.</blockquote> 6058 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
4750 * <p> 6059 * <p>
(...skipping 18 matching lines...) Expand all
4769 * e<sub>2</sub></i> is equivalent to the method invocation 6078 * e<sub>2</sub></i> is equivalent to the method invocation
4770 * <i>super.op(e<sub>2</sub>)</i>.</blockquote> 6079 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
4771 * <p> 6080 * <p>
4772 * The Dart Language Specification, 12.26: <blockquote>A multiplicative expres sion of the form 6081 * The Dart Language Specification, 12.26: <blockquote>A multiplicative expres sion of the form
4773 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n 6082 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n
4774 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A multiplicative expression of the form <i>super op 6083 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A multiplicative expression of the form <i>super op
4775 * e<sub>2</sub></i> is equivalent to the method invocation 6084 * e<sub>2</sub></i> is equivalent to the method invocation
4776 * <i>super.op(e<sub>2</sub>)</i>.</blockquote> 6085 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
4777 */ 6086 */
4778 Object visitBinaryExpression(BinaryExpression node) { 6087 Object visitBinaryExpression(BinaryExpression node) {
4779 sc.TokenType operator2 = node.operator.type; 6088 ExecutableElement staticMethodElement = node.staticElement;
4780 while (true) { 6089 Type2 staticType = computeReturnType(staticMethodElement);
4781 if (operator2 == sc.TokenType.AMPERSAND_AMPERSAND || operator2 == sc.Token Type.BAR_BAR || operator2 == sc.TokenType.EQ_EQ || operator2 == sc.TokenType.BAN G_EQ) { 6090 staticType = refineBinaryExpressionType(node, staticType);
4782 return recordType(node, _typeProvider.boolType); 6091 recordStaticType(node, staticType);
4783 } else if (operator2 == sc.TokenType.MINUS || operator2 == sc.TokenType.PE RCENT || operator2 == sc.TokenType.PLUS || operator2 == sc.TokenType.STAR || ope rator2 == sc.TokenType.TILDE_SLASH) { 6092 MethodElement propagatedMethodElement = node.element;
4784 Type2 intType2 = _typeProvider.intType; 6093 if (propagatedMethodElement != staticMethodElement) {
4785 if (identical(getType2(node.leftOperand), intType2) && identical(getType 2(node.rightOperand), intType2)) { 6094 Type2 propagatedType = computeReturnType(propagatedMethodElement);
4786 return recordType(node, intType2); 6095 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType )) {
4787 } 6096 recordPropagatedType(node, propagatedType);
4788 } else if (operator2 == sc.TokenType.SLASH) {
4789 Type2 doubleType2 = _typeProvider.doubleType;
4790 if (identical(getType2(node.leftOperand), doubleType2) || identical(getT ype2(node.rightOperand), doubleType2)) {
4791 return recordType(node, doubleType2);
4792 }
4793 } 6097 }
4794 break;
4795 } 6098 }
4796 return recordReturnType(node, node.element); 6099 return null;
4797 } 6100 }
6101
4798 /** 6102 /**
4799 * The Dart Language Specification, 12.4: <blockquote>The static type of a boo lean literal is{@code bool}.</blockquote> 6103 * The Dart Language Specification, 12.4: <blockquote>The static type of a boo lean literal is
6104 * bool.</blockquote>
4800 */ 6105 */
4801 Object visitBooleanLiteral(BooleanLiteral node) => recordType(node, _typeProvi der.boolType); 6106 Object visitBooleanLiteral(BooleanLiteral node) {
6107 recordStaticType(node, _typeProvider.boolType);
6108 return null;
6109 }
6110
4802 /** 6111 /**
4803 * The Dart Language Specification, 12.15.2: <blockquote>A cascaded method inv ocation expression 6112 * The Dart Language Specification, 12.15.2: <blockquote>A cascaded method inv ocation expression
4804 * of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suff ix; return 6113 * of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suff ix; return
4805 * t;}(e)</i>.</blockquote> 6114 * t;}(e)</i>.</blockquote>
4806 */ 6115 */
4807 Object visitCascadeExpression(CascadeExpression node) => recordType(node, getT ype2(node.target)); 6116 Object visitCascadeExpression(CascadeExpression node) {
6117 recordStaticType(node, getStaticType(node.target));
6118 recordPropagatedType(node, getPropagatedType(node.target));
6119 return null;
6120 }
6121
4808 /** 6122 /**
4809 * The Dart Language Specification, 12.19: <blockquote> ... a conditional expr ession <i>c</i> of 6123 * The Dart Language Specification, 12.19: <blockquote> ... a conditional expr ession <i>c</i> of
4810 * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ... 6124 * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ...
4811 * <p> 6125 * <p>
4812 * It is a static type warning if the type of e<sub>1</sub> may not be assigne d to {@code bool}. 6126 * It is a static type warning if the type of e<sub>1</sub> may not be assigne d to {@code bool}.
4813 * <p> 6127 * <p>
4814 * The static type of <i>c</i> is the least upper bound of the static type of <i>e<sub>2</sub></i> 6128 * The static type of <i>c</i> is the least upper bound of the static type of <i>e<sub>2</sub></i>
4815 * and the static type of <i>e<sub>3</sub></i>.</blockquote> 6129 * and the static type of <i>e<sub>3</sub></i>.</blockquote>
4816 */ 6130 */
4817 Object visitConditionalExpression(ConditionalExpression node) { 6131 Object visitConditionalExpression(ConditionalExpression node) {
4818 Type2 thenType = getType2(node.thenExpression); 6132 Type2 staticThenType = getStaticType(node.thenExpression);
4819 Type2 elseType = getType2(node.elseExpression); 6133 Type2 staticElseType = getStaticType(node.elseExpression);
4820 if (thenType == null) { 6134 if (staticThenType == null) {
4821 return recordType(node, _dynamicType); 6135 staticThenType = _dynamicType;
4822 } 6136 }
4823 Type2 resultType = thenType.getLeastUpperBound(elseType); 6137 if (staticElseType == null) {
4824 return recordType(node, resultType); 6138 staticElseType = _dynamicType;
6139 }
6140 Type2 staticType = staticThenType.getLeastUpperBound(staticElseType);
6141 if (staticType == null) {
6142 staticType = _dynamicType;
6143 }
6144 recordStaticType(node, staticType);
6145 Type2 propagatedThenType = getPropagatedType(node.thenExpression);
6146 Type2 propagatedElseType = getPropagatedType(node.elseExpression);
6147 if (propagatedThenType != null || propagatedElseType != null) {
6148 if (propagatedThenType == null) {
6149 propagatedThenType = staticThenType;
6150 }
6151 if (propagatedElseType == null) {
6152 propagatedElseType = staticElseType;
6153 }
6154 Type2 propagatedType = propagatedThenType.getLeastUpperBound(propagatedEls eType);
6155 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType )) {
6156 recordPropagatedType(node, propagatedType);
6157 }
6158 }
6159 return null;
4825 } 6160 }
6161
4826 /** 6162 /**
4827 * The Dart Language Specification, 12.3: <blockquote>The static type of a lit eral double is{@code double}.</blockquote> 6163 * The Dart Language Specification, 12.3: <blockquote>The static type of a lit eral double is
6164 * double.</blockquote>
4828 */ 6165 */
4829 Object visitDoubleLiteral(DoubleLiteral node) => recordType(node, _typeProvide r.doubleType); 6166 Object visitDoubleLiteral(DoubleLiteral node) {
6167 recordStaticType(node, _typeProvider.doubleType);
6168 return null;
6169 }
4830 Object visitFunctionDeclaration(FunctionDeclaration node) { 6170 Object visitFunctionDeclaration(FunctionDeclaration node) {
4831 FunctionExpression function = node.functionExpression; 6171 FunctionExpression function = node.functionExpression;
4832 FunctionTypeImpl functionType = node.element.type as FunctionTypeImpl; 6172 FunctionTypeImpl functionType = node.element.type as FunctionTypeImpl;
4833 setTypeInformation(functionType, computeReturnType(node), function.parameter s); 6173 setTypeInformation(functionType, computeReturnType2(node), function.paramete rs);
4834 return recordType(function, functionType); 6174 recordStaticType(function, functionType);
6175 return null;
4835 } 6176 }
6177
4836 /** 6178 /**
4837 * The Dart Language Specification, 12.9: <blockquote>The static type of a fun ction literal of the 6179 * The Dart Language Specification, 12.9: <blockquote>The static type of a fun ction literal of the
4838 * form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;, T<sub>n</sub> a<sub>n</sub> , \[T<sub>n+1</sub> 6180 * form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;, T<sub>n</sub> a<sub>n</sub> , \[T<sub>n+1</sub>
4839 * x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub> = dk\]) => e</i> is 6181 * x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub> = dk\]) => e</i> is
4840 * <i>(T<sub>1</sub>, &hellip;, Tn, \[T<sub>n+1</sub> x<sub>n+1</sub>, &hellip ;, T<sub>n+k</sub> 6182 * <i>(T<sub>1</sub>, &hellip;, Tn, \[T<sub>n+1</sub> x<sub>n+1</sub>, &hellip ;, T<sub>n+k</sub>
4841 * x<sub>n+k</sub>\]) &rarr; T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is the static type of 6183 * x<sub>n+k</sub>\]) &rarr; T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is the static type of
4842 * <i>e</i>. In any case where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is 6184 * <i>e</i>. In any case where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is
4843 * considered to have been specified as dynamic. 6185 * considered to have been specified as dynamic.
4844 * <p> 6186 * <p>
4845 * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1 </sub>, &hellip;, 6187 * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1 </sub>, &hellip;,
(...skipping 15 matching lines...) Expand all
4861 * x<sub>n+k</sub> : dk}) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub >, {T<sub>n+1</sub> 6203 * x<sub>n+k</sub> : dk}) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub >, {T<sub>n+1</sub>
4862 * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; dynamic </i>. In any case 6204 * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; dynamic </i>. In any case
4863 * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is cons idered to have been 6205 * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is cons idered to have been
4864 * specified as dynamic.</blockquote> 6206 * specified as dynamic.</blockquote>
4865 */ 6207 */
4866 Object visitFunctionExpression(FunctionExpression node) { 6208 Object visitFunctionExpression(FunctionExpression node) {
4867 if (node.parent is FunctionDeclaration) { 6209 if (node.parent is FunctionDeclaration) {
4868 return null; 6210 return null;
4869 } 6211 }
4870 FunctionTypeImpl functionType = node.element.type as FunctionTypeImpl; 6212 FunctionTypeImpl functionType = node.element.type as FunctionTypeImpl;
4871 setTypeInformation(functionType, computeReturnType2(node), node.parameters); 6213 setTypeInformation(functionType, computeReturnType3(node), node.parameters);
4872 return recordType(node, functionType); 6214 recordStaticType(node, functionType);
6215 return null;
4873 } 6216 }
6217
4874 /** 6218 /**
4875 * The Dart Language Specification, 12.14.4: <blockquote>A function expression invocation <i>i</i> 6219 * The Dart Language Specification, 12.14.4: <blockquote>A function expression invocation <i>i</i>
4876 * has the form <i>e<sub>f</sub>(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub >n+1</sub>: 6220 * has the form <i>e<sub>f</sub>(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub >n+1</sub>:
4877 * a<sub>n+1</sub>, &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i> e<sub>f</sub></i> is 6221 * a<sub>n+1</sub>, &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i> e<sub>f</sub></i> is
4878 * an expression. 6222 * an expression.
4879 * <p> 6223 * <p>
4880 * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub> </i> may not be 6224 * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub> </i> may not be
4881 * assigned to a function type. 6225 * assigned to a function type.
4882 * <p> 6226 * <p>
4883 * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic. Otherwise the 6227 * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic. Otherwise the
4884 * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquot e> 6228 * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquot e>
4885 */ 6229 */
4886 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => recordReturnType(node, node.element); 6230 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
6231 ExecutableElement staticMethodElement = node.staticElement;
6232 Type2 staticType = computeReturnType(staticMethodElement);
6233 recordStaticType(node, staticType);
6234 ExecutableElement propagatedMethodElement = node.element;
6235 Type2 propagatedType = computeReturnType(propagatedMethodElement);
6236 if (staticType == null) {
6237 recordStaticType(node, propagatedType);
6238 } else if (propagatedType != null && propagatedType.isMoreSpecificThan(stati cType)) {
6239 recordPropagatedType(node, propagatedType);
6240 }
6241 return null;
6242 }
6243
4887 /** 6244 /**
4888 * The Dart Language Specification, 12.29: <blockquote>An assignable expressio n of the form 6245 * The Dart Language Specification, 12.29: <blockquote>An assignable expressio n of the form
4889 * <i>e<sub>1</sub>\[e<sub>2</sub>\]</i> is evaluated as a method invocation o f the operator method 6246 * <i>e<sub>1</sub>\[e<sub>2</sub>\]</i> is evaluated as a method invocation o f the operator method
4890 * <i>\[\]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</bl ockquote> 6247 * <i>\[\]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</bl ockquote>
4891 */ 6248 */
4892 Object visitIndexExpression(IndexExpression node) { 6249 Object visitIndexExpression(IndexExpression node) {
4893 if (node.inSetterContext()) { 6250 if (node.inSetterContext()) {
4894 return recordArgumentType(node, node.element); 6251 ExecutableElement staticMethodElement = node.staticElement;
6252 Type2 staticType = computeArgumentType(staticMethodElement);
6253 recordStaticType(node, staticType);
6254 MethodElement propagatedMethodElement = node.element;
6255 if (propagatedMethodElement != staticMethodElement) {
6256 Type2 propagatedType = computeArgumentType(propagatedMethodElement);
6257 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy pe)) {
6258 recordPropagatedType(node, propagatedType);
6259 }
6260 }
6261 } else {
6262 ExecutableElement staticMethodElement = node.staticElement;
6263 Type2 staticType = computeReturnType(staticMethodElement);
6264 recordStaticType(node, staticType);
6265 MethodElement propagatedMethodElement = node.element;
6266 if (propagatedMethodElement != staticMethodElement) {
6267 Type2 propagatedType = computeReturnType(propagatedMethodElement);
6268 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy pe)) {
6269 recordPropagatedType(node, propagatedType);
6270 }
6271 }
4895 } 6272 }
4896 return recordReturnType(node, node.element); 6273 return null;
4897 } 6274 }
6275
4898 /** 6276 /**
4899 * The Dart Language Specification, 12.11.1: <blockquote>The static type of a new expression of 6277 * The Dart Language Specification, 12.11.1: <blockquote>The static type of a new expression of
4900 * either the form <i>new T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the form <i>new 6278 * either the form <i>new T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the form <i>new
4901 * T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>.</blockquote> 6279 * T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>.</blockquote>
4902 * <p> 6280 * <p>
4903 * The Dart Language Specification, 12.11.2: <blockquote>The static type of a constant object 6281 * The Dart Language Specification, 12.11.2: <blockquote>The static type of a constant object
4904 * expression of either the form <i>const T.id(a<sub>1</sub>, &hellip;, a<sub> n</sub>)</i> or the 6282 * expression of either the form <i>const T.id(a<sub>1</sub>, &hellip;, a<sub> n</sub>)</i> or the
4905 * form <i>const T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>. </ blockquote> 6283 * form <i>const T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>. </ blockquote>
4906 */ 6284 */
4907 Object visitInstanceCreationExpression(InstanceCreationExpression node) { 6285 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
4908 if (USE_TYPE_PROPAGATION) { 6286 recordStaticType(node, node.constructorName.type.type);
4909 ConstructorElement element2 = node.element; 6287 ConstructorElement element2 = node.element;
4910 if (element2 != null && "Element" == element2.enclosingElement.name && "ta g" == element2.name) { 6288 if (element2 != null && "Element" == element2.enclosingElement.name && "tag" == element2.name) {
4911 LibraryElement library2 = element2.library; 6289 LibraryElement library2 = element2.library;
4912 if (isHtmlLibrary(library2)) { 6290 if (isHtmlLibrary(library2)) {
4913 Type2 returnType = getFirstArgumentAsType2(library2, node.argumentList , _HTML_ELEMENT_TO_CLASS_MAP); 6291 Type2 returnType = getFirstArgumentAsType2(library2, node.argumentList, _HTML_ELEMENT_TO_CLASS_MAP);
4914 if (returnType != null) { 6292 if (returnType != null) {
4915 return recordType(node, returnType); 6293 recordPropagatedType(node, returnType);
4916 }
4917 } 6294 }
4918 } 6295 }
4919 } 6296 }
4920 return recordType(node, node.constructorName.type.type); 6297 return null;
4921 } 6298 }
6299
4922 /** 6300 /**
4923 * The Dart Language Specification, 12.3: <blockquote>The static type of an in teger literal is{@code int}.</blockquote> 6301 * The Dart Language Specification, 12.3: <blockquote>The static type of an in teger literal is{@code int}.</blockquote>
4924 */ 6302 */
4925 Object visitIntegerLiteral(IntegerLiteral node) => recordType(node, _typeProvi der.intType); 6303 Object visitIntegerLiteral(IntegerLiteral node) {
6304 recordStaticType(node, _typeProvider.intType);
6305 return null;
6306 }
6307
4926 /** 6308 /**
4927 * The Dart Language Specification, 12.31: <blockquote>It is a static warning if <i>T</i> does not 6309 * The Dart Language Specification, 12.31: <blockquote>It is a static warning if <i>T</i> does not
4928 * denote a type available in the current lexical scope. 6310 * denote a type available in the current lexical scope.
4929 * <p> 6311 * <p>
4930 * The static type of an is-expression is {@code bool}.</blockquote> 6312 * The static type of an is-expression is {@code bool}.</blockquote>
4931 */ 6313 */
4932 Object visitIsExpression(IsExpression node) => recordType(node, _typeProvider. boolType); 6314 Object visitIsExpression(IsExpression node) {
6315 recordStaticType(node, _typeProvider.boolType);
6316 return null;
6317 }
6318
4933 /** 6319 /**
4934 * The Dart Language Specification, 12.6: <blockquote>The static type of a lis t literal of the 6320 * The Dart Language Specification, 12.6: <blockquote>The static type of a lis t literal of the
4935 * form <i><b>const</b> &lt;E&gt;\[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i > or the form 6321 * form <i><b>const</b> &lt;E&gt;\[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i > or the form
4936 * <i>&lt;E&gt;\[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i> is {@code List&l t;E&gt;}. The static 6322 * <i>&lt;E&gt;\[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i> is {@code List&l t;E&gt;}. The static
4937 * type a list literal of the form <i><b>const</b> \[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i> or 6323 * type a list literal of the form <i><b>const</b> \[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i> or
4938 * the form <i>\[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i> is {@code List&l t;dynamic&gt;}.</blockquote> 6324 * the form <i>\[e<sub>1</sub>, &hellip;, e<sub>n</sub>\]</i> is {@code List&l t;dynamic&gt;}.</blockquote>
4939 */ 6325 */
4940 Object visitListLiteral(ListLiteral node) { 6326 Object visitListLiteral(ListLiteral node) {
6327 Type2 staticType = _dynamicType;
4941 TypeArgumentList typeArguments2 = node.typeArguments; 6328 TypeArgumentList typeArguments2 = node.typeArguments;
4942 if (typeArguments2 != null) { 6329 if (typeArguments2 != null) {
4943 NodeList<TypeName> arguments2 = typeArguments2.arguments; 6330 NodeList<TypeName> arguments2 = typeArguments2.arguments;
4944 if (arguments2 != null && arguments2.length == 1) { 6331 if (arguments2 != null && arguments2.length == 1) {
4945 TypeName argumentType = arguments2[0]; 6332 TypeName argumentTypeName = arguments2[0];
4946 return recordType(node, _typeProvider.listType.substitute5(<Type2> [getT ype4(argumentType)])); 6333 Type2 argumentType = getType2(argumentTypeName);
6334 if (argumentType != null) {
6335 staticType = argumentType;
6336 }
4947 } 6337 }
4948 } 6338 }
4949 return recordType(node, _typeProvider.listType.substitute5(<Type2> [_dynamic Type])); 6339 recordStaticType(node, _typeProvider.listType.substitute5(<Type2> [staticTyp e]));
6340 NodeList<Expression> elements2 = node.elements;
6341 int count = elements2.length;
6342 if (count > 0) {
6343 Type2 propagatedType = getBestType(elements2[0]);
6344 for (int i = 1; i < count; i++) {
6345 Type2 elementType = getBestType(elements2[i]);
6346 if (propagatedType != elementType) {
6347 propagatedType = _dynamicType;
6348 } else {
6349 propagatedType = propagatedType.getLeastUpperBound(elementType);
6350 if (propagatedType == null) {
6351 propagatedType = _dynamicType;
6352 }
6353 }
6354 }
6355 if (propagatedType.isMoreSpecificThan(staticType)) {
6356 recordPropagatedType(node, _typeProvider.listType.substitute5(<Type2> [p ropagatedType]));
6357 }
6358 }
6359 return null;
4950 } 6360 }
6361
4951 /** 6362 /**
4952 * The Dart Language Specification, 12.7: <blockquote>The static type of a map literal of the form 6363 * The Dart Language Specification, 12.7: <blockquote>The static type of a map literal of the form
4953 * <i><b>const</b> &lt;String, V&gt; {k<sub>1</sub>:e<sub>1</sub>, &hellip;, 6364 * <i><b>const</b> &lt;String, V&gt; {k<sub>1</sub>:e<sub>1</sub>, &hellip;,
4954 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>&lt;String, V&gt; {k<sub>1< /sub>:e<sub>1</sub>, 6365 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>&lt;String, V&gt; {k<sub>1< /sub>:e<sub>1</sub>,
4955 * &hellip;, k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map&lt;String, V&gt;}. The static type a 6366 * &hellip;, k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map&lt;String, V&gt;}. The static type a
4956 * map literal of the form <i><b>const</b> {k<sub>1</sub>:e<sub>1</sub>, &hell ip;, 6367 * map literal of the form <i><b>const</b> {k<sub>1</sub>:e<sub>1</sub>, &hell ip;,
4957 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>{k<sub>1</sub>:e<sub>1</sub >, &hellip;, 6368 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>{k<sub>1</sub>:e<sub>1</sub >, &hellip;,
4958 * k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map&lt;String, dynamic&gt;}. 6369 * k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map&lt;String, dynamic&gt;}.
4959 * <p> 6370 * <p>
4960 * It is a compile-time error if the first type argument to a map literal is n ot 6371 * It is a compile-time error if the first type argument to a map literal is n ot
4961 * <i>String</i>.</blockquote> 6372 * <i>String</i>.</blockquote>
4962 */ 6373 */
4963 Object visitMapLiteral(MapLiteral node) { 6374 Object visitMapLiteral(MapLiteral node) {
6375 Type2 staticKeyType = _dynamicType;
6376 Type2 staticValueType = _dynamicType;
4964 TypeArgumentList typeArguments2 = node.typeArguments; 6377 TypeArgumentList typeArguments2 = node.typeArguments;
4965 if (typeArguments2 != null) { 6378 if (typeArguments2 != null) {
4966 NodeList<TypeName> arguments2 = typeArguments2.arguments; 6379 NodeList<TypeName> arguments2 = typeArguments2.arguments;
4967 if (arguments2 != null && arguments2.length == 2) { 6380 if (arguments2 != null && arguments2.length == 2) {
4968 TypeName keyType = arguments2[0]; 6381 TypeName entryKeyTypeName = arguments2[0];
4969 if (keyType != _typeProvider.stringType) { 6382 Type2 entryKeyType = getType2(entryKeyTypeName);
6383 if (entryKeyType != null) {
6384 staticKeyType = entryKeyType;
4970 } 6385 }
4971 TypeName valueType = arguments2[1]; 6386 TypeName entryValueTypeName = arguments2[1];
4972 return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_type Provider.stringType, getType4(valueType)])); 6387 Type2 entryValueType = getType2(entryValueTypeName);
6388 if (entryValueType != null) {
6389 staticValueType = entryValueType;
6390 }
4973 } 6391 }
4974 } 6392 }
4975 return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_typeProv ider.stringType, _dynamicType])); 6393 recordStaticType(node, _typeProvider.mapType.substitute5(<Type2> [staticKeyT ype, staticValueType]));
6394 NodeList<MapLiteralEntry> entries2 = node.entries;
6395 int count = entries2.length;
6396 if (count > 0) {
6397 MapLiteralEntry entry = entries2[0];
6398 Type2 propagatedKeyType = getBestType(entry.key);
6399 Type2 propagatedValueType = getBestType(entry.value);
6400 for (int i = 1; i < count; i++) {
6401 entry = entries2[i];
6402 Type2 elementKeyType = getBestType(entry.key);
6403 if (propagatedKeyType != elementKeyType) {
6404 propagatedKeyType = _dynamicType;
6405 } else {
6406 propagatedKeyType = propagatedKeyType.getLeastUpperBound(elementKeyTyp e);
6407 if (propagatedKeyType == null) {
6408 propagatedKeyType = _dynamicType;
6409 }
6410 }
6411 Type2 elementValueType = getBestType(entry.value);
6412 if (propagatedValueType != elementValueType) {
6413 propagatedValueType = _dynamicType;
6414 } else {
6415 propagatedValueType = propagatedValueType.getLeastUpperBound(elementVa lueType);
6416 if (propagatedValueType == null) {
6417 propagatedValueType = _dynamicType;
6418 }
6419 }
6420 }
6421 bool betterKey = propagatedKeyType != null && propagatedKeyType.isMoreSpec ificThan(staticKeyType);
6422 bool betterValue = propagatedValueType != null && propagatedValueType.isMo reSpecificThan(staticValueType);
6423 if (betterKey || betterValue) {
6424 if (!betterKey) {
6425 propagatedKeyType = staticKeyType;
6426 }
6427 if (!betterValue) {
6428 propagatedValueType = staticValueType;
6429 }
6430 recordPropagatedType(node, _typeProvider.mapType.substitute5(<Type2> [pr opagatedKeyType, propagatedValueType]));
6431 }
6432 }
6433 return null;
4976 } 6434 }
6435
4977 /** 6436 /**
4978 * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method in vocation <i>i</i> 6437 * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method in vocation <i>i</i>
4979 * has the form <i>o.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub> : a<sub>n+1</sub>, 6438 * has the form <i>o.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub> : a<sub>n+1</sub>,
4980 * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. 6439 * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
4981 * <p> 6440 * <p>
4982 * Let <i>T</i> be the static type of <i>o</i>. It is a static type warning if <i>T</i> does not 6441 * Let <i>T</i> be the static type of <i>o</i>. It is a static type warning if <i>T</i> does not
4983 * have an accessible instance member named <i>m</i>. If <i>T.m</i> exists, it is a static warning 6442 * have an accessible instance member named <i>m</i>. If <i>T.m</i> exists, it is a static warning
4984 * if the type <i>F</i> of <i>T.m</i> may not be assigned to a function type. 6443 * if the type <i>F</i> of <i>T.m</i> may not be assigned to a function type.
4985 * <p> 6444 * <p>
4986 * If <i>T.m</i> does not exist, or if <i>F</i> is not a function type, the st atic type of 6445 * If <i>T.m</i> does not exist, or if <i>F</i> is not a function type, the st atic type of
(...skipping 17 matching lines...) Expand all
5004 * <p> 6463 * <p>
5005 * It is a static type warning if <i>S</i> does not have an accessible instanc e member named m. If 6464 * It is a static type warning if <i>S</i> does not have an accessible instanc e member named m. If
5006 * <i>S.m</i> exists, it is a static warning if the type <i>F</i> of <i>S.m</i > may not be 6465 * <i>S.m</i> exists, it is a static warning if the type <i>F</i> of <i>S.m</i > may not be
5007 * assigned to a function type. 6466 * assigned to a function type.
5008 * <p> 6467 * <p>
5009 * If <i>S.m</i> does not exist, or if <i>F</i> is not a function type, the st atic type of 6468 * If <i>S.m</i> does not exist, or if <i>F</i> is not a function type, the st atic type of
5010 * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of 6469 * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
5011 * <i>F</i>.</blockquote> 6470 * <i>F</i>.</blockquote>
5012 */ 6471 */
5013 Object visitMethodInvocation(MethodInvocation node) { 6472 Object visitMethodInvocation(MethodInvocation node) {
5014 if (USE_TYPE_PROPAGATION) { 6473 SimpleIdentifier methodNameNode = node.methodName;
5015 String methodName2 = node.methodName.name; 6474 Element staticMethodElement = methodNameNode.staticElement;
5016 if (methodName2 == "\$dom_createEvent") { 6475 if (staticMethodElement == null) {
5017 Expression target = node.realTarget; 6476 staticMethodElement = methodNameNode.element;
5018 if (target != null) { 6477 }
5019 Type2 targetType = getType2(target); 6478 Type2 staticType = computeReturnType(staticMethodElement);
5020 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || targetType.name == "Document")) { 6479 recordStaticType(node, staticType);
5021 LibraryElement library2 = targetType.element.library; 6480 String methodName = methodNameNode.name;
5022 if (isHtmlLibrary(library2)) { 6481 if (methodName == "\$dom_createEvent") {
5023 Type2 returnType = getFirstArgumentAsType(library2, node.argumentL ist); 6482 Expression target = node.realTarget;
5024 if (returnType != null) { 6483 if (target != null) {
5025 return recordType(node, returnType); 6484 Type2 targetType = getBestType(target);
5026 } 6485 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || targetType.name == "Document")) {
6486 LibraryElement library2 = targetType.element.library;
6487 if (isHtmlLibrary(library2)) {
6488 Type2 returnType = getFirstArgumentAsType(library2, node.argumentLis t);
6489 if (returnType != null) {
6490 recordPropagatedType(node, returnType);
5027 } 6491 }
5028 } 6492 }
5029 } 6493 }
5030 } else if (methodName2 == "query") { 6494 }
5031 Expression target = node.realTarget; 6495 } else if (methodName == "query") {
5032 if (target == null) { 6496 Expression target = node.realTarget;
5033 Element methodElement = node.methodName.element; 6497 if (target == null) {
5034 if (methodElement != null) { 6498 Element methodElement = methodNameNode.element;
5035 LibraryElement library3 = methodElement.library; 6499 if (methodElement != null) {
5036 if (isHtmlLibrary(library3)) { 6500 LibraryElement library3 = methodElement.library;
5037 Type2 returnType = getFirstArgumentAsQuery(library3, node.argument List); 6501 if (isHtmlLibrary(library3)) {
5038 if (returnType != null) { 6502 Type2 returnType = getFirstArgumentAsQuery(library3, node.argumentLi st);
5039 return recordType(node, returnType); 6503 if (returnType != null) {
5040 } 6504 recordPropagatedType(node, returnType);
5041 }
5042 }
5043 } else {
5044 Type2 targetType = getType2(target);
5045 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || targetType.name == "Document")) {
5046 LibraryElement library4 = targetType.element.library;
5047 if (isHtmlLibrary(library4)) {
5048 Type2 returnType = getFirstArgumentAsQuery(library4, node.argument List);
5049 if (returnType != null) {
5050 return recordType(node, returnType);
5051 }
5052 } 6505 }
5053 } 6506 }
5054 } 6507 }
5055 } else if (methodName2 == "JS") { 6508 } else {
5056 Type2 returnType = getFirstArgumentAsType(_typeProvider.objectType.eleme nt.library, node.argumentList); 6509 Type2 targetType = getBestType(target);
5057 if (returnType != null) { 6510 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || targetType.name == "Document")) {
5058 return recordType(node, returnType); 6511 LibraryElement library4 = targetType.element.library;
6512 if (isHtmlLibrary(library4)) {
6513 Type2 returnType = getFirstArgumentAsQuery(library4, node.argumentLi st);
6514 if (returnType != null) {
6515 recordPropagatedType(node, returnType);
6516 }
6517 }
6518 }
6519 }
6520 } else if (methodName == "\$dom_createElement") {
6521 Expression target = node.realTarget;
6522 Type2 targetType = getBestType(target);
6523 if (targetType is InterfaceType && (targetType.name == "HtmlDocument" || t argetType.name == "Document")) {
6524 LibraryElement library5 = targetType.element.library;
6525 if (isHtmlLibrary(library5)) {
6526 Type2 returnType = getFirstArgumentAsQuery(library5, node.argumentList );
6527 if (returnType != null) {
6528 recordPropagatedType(node, returnType);
6529 }
6530 }
6531 }
6532 } else if (methodName == "JS") {
6533 Type2 returnType = getFirstArgumentAsType(_typeProvider.objectType.element .library, node.argumentList);
6534 if (returnType != null) {
6535 recordPropagatedType(node, returnType);
6536 }
6537 } else {
6538 Element propagatedElement = methodNameNode.element;
6539 if (propagatedElement != staticMethodElement) {
6540 Type2 propagatedType = computeReturnType(propagatedElement);
6541 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy pe)) {
6542 recordPropagatedType(node, propagatedType);
5059 } 6543 }
5060 } 6544 }
5061 } 6545 }
5062 return recordReturnType(node, node.methodName.element); 6546 return null;
5063 } 6547 }
5064 Object visitNamedExpression(NamedExpression node) => recordType(node, getType2 (node.expression)); 6548 Object visitNamedExpression(NamedExpression node) {
6549 Expression expression2 = node.expression;
6550 recordStaticType(node, getStaticType(expression2));
6551 recordPropagatedType(node, getPropagatedType(expression2));
6552 return null;
6553 }
6554
5065 /** 6555 /**
5066 * The Dart Language Specification, 12.2: <blockquote>The static type of {@cod e null} is bottom. 6556 * The Dart Language Specification, 12.2: <blockquote>The static type of {@cod e null} is bottom.
5067 * </blockquote> 6557 * </blockquote>
5068 */ 6558 */
5069 Object visitNullLiteral(NullLiteral node) => recordType(node, _typeProvider.bo ttomType); 6559 Object visitNullLiteral(NullLiteral node) {
5070 Object visitParenthesizedExpression(ParenthesizedExpression node) => recordTyp e(node, getType2(node.expression)); 6560 recordStaticType(node, _typeProvider.bottomType);
6561 return null;
6562 }
6563 Object visitParenthesizedExpression(ParenthesizedExpression node) {
6564 Expression expression2 = node.expression;
6565 recordStaticType(node, getStaticType(expression2));
6566 recordPropagatedType(node, getPropagatedType(expression2));
6567 return null;
6568 }
6569
5071 /** 6570 /**
5072 * The Dart Language Specification, 12.28: <blockquote>A postfix expression of the form 6571 * The Dart Language Specification, 12.28: <blockquote>A postfix expression of the form
5073 * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r = v; v = r + 1; 6572 * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r = v; v = r + 1;
5074 * return r}()</i>. 6573 * return r}()</i>.
5075 * <p> 6574 * <p>
5076 * A postfix expression of the form <i>C.v++</i> is equivalent to <i>(){var r = C.v; C.v = r + 1; 6575 * A postfix expression of the form <i>C.v++</i> is equivalent to <i>(){var r = C.v; C.v = r + 1;
5077 * return r}()</i>. 6576 * return r}()</i>.
5078 * <p> 6577 * <p>
5079 * A postfix expression of the form <i>e1.v++</i> is equivalent to <i>(x){var r = x.v; x.v = r + 6578 * A postfix expression of the form <i>e1.v++</i> is equivalent to <i>(x){var r = x.v; x.v = r +
5080 * 1; return r}(e1)</i>. 6579 * 1; return r}(e1)</i>.
5081 * <p> 6580 * <p>
5082 * A postfix expression of the form <i>e1\[e2\]++</i> is equivalent to <i>(a, i){var r = a\[i\]; a\[i\] 6581 * A postfix expression of the form <i>e1\[e2\]++</i> is equivalent to <i>(a, i){var r = a\[i\]; a\[i\]
5083 * = r + 1; return r}(e1, e2)</i> 6582 * = r + 1; return r}(e1, e2)</i>
5084 * <p> 6583 * <p>
5085 * A postfix expression of the form <i>v--</i>, where <i>v</i> is an identifie r, is equivalent to 6584 * A postfix expression of the form <i>v--</i>, where <i>v</i> is an identifie r, is equivalent to
5086 * <i>(){var r = v; v = r - 1; return r}()</i>. 6585 * <i>(){var r = v; v = r - 1; return r}()</i>.
5087 * <p> 6586 * <p>
5088 * A postfix expression of the form <i>C.v--</i> is equivalent to <i>(){var r = C.v; C.v = r - 1; 6587 * A postfix expression of the form <i>C.v--</i> is equivalent to <i>(){var r = C.v; C.v = r - 1;
5089 * return r}()</i>. 6588 * return r}()</i>.
5090 * <p> 6589 * <p>
5091 * A postfix expression of the form <i>e1.v--</i> is equivalent to <i>(x){var r = x.v; x.v = r - 6590 * A postfix expression of the form <i>e1.v--</i> is equivalent to <i>(x){var r = x.v; x.v = r -
5092 * 1; return r}(e1)</i>. 6591 * 1; return r}(e1)</i>.
5093 * <p> 6592 * <p>
5094 * A postfix expression of the form <i>e1\[e2\]--</i> is equivalent to <i>(a, i){var r = a\[i\]; a\[i\] 6593 * A postfix expression of the form <i>e1\[e2\]--</i> is equivalent to <i>(a, i){var r = a\[i\]; a\[i\]
5095 * = r - 1; return r}(e1, e2)</i></blockquote> 6594 * = r - 1; return r}(e1, e2)</i></blockquote>
5096 */ 6595 */
5097 Object visitPostfixExpression(PostfixExpression node) => recordType(node, getT ype2(node.operand)); 6596 Object visitPostfixExpression(PostfixExpression node) {
6597 Expression operand2 = node.operand;
6598 Type2 staticType = getStaticType(operand2);
6599 sc.TokenType operator2 = node.operator.type;
6600 if (identical(operator2, sc.TokenType.MINUS_MINUS) || identical(operator2, s c.TokenType.PLUS_PLUS)) {
6601 Type2 intType2 = _typeProvider.intType;
6602 if (identical(getStaticType(node.operand), intType2)) {
6603 staticType = intType2;
6604 }
6605 }
6606 recordStaticType(node, staticType);
6607 recordPropagatedType(node, getPropagatedType(operand2));
6608 return null;
6609 }
6610
5098 /** 6611 /**
5099 * See {@link #visitSimpleIdentifier(SimpleIdentifier)}. 6612 * See {@link #visitSimpleIdentifier(SimpleIdentifier)}.
5100 */ 6613 */
5101 Object visitPrefixedIdentifier(PrefixedIdentifier node) { 6614 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
5102 SimpleIdentifier prefixedIdentifier = node.identifier; 6615 SimpleIdentifier prefixedIdentifier = node.identifier;
5103 Element element2 = prefixedIdentifier.element; 6616 Element element2 = prefixedIdentifier.element;
5104 if (element2 == null) { 6617 Type2 staticType = _dynamicType;
5105 return recordType(node, _dynamicType);
5106 }
5107 if (USE_TYPE_PROPAGATION) {
5108 Type2 type = _overrideManager.getType(element2);
5109 if (type != null) {
5110 return recordType(node, type);
5111 }
5112 }
5113 Type2 type;
5114 if (element2 is ClassElement) { 6618 if (element2 is ClassElement) {
5115 if (isNotTypeLiteral(node)) { 6619 if (isNotTypeLiteral(node)) {
5116 type = ((element2 as ClassElement)).type; 6620 staticType = ((element2 as ClassElement)).type;
5117 } else { 6621 } else {
5118 type = _typeProvider.typeType; 6622 staticType = _typeProvider.typeType;
5119 } 6623 }
5120 } else if (element2 is FunctionTypeAliasElement) { 6624 } else if (element2 is FunctionTypeAliasElement) {
5121 type = ((element2 as FunctionTypeAliasElement)).type; 6625 staticType = ((element2 as FunctionTypeAliasElement)).type;
5122 } else if (element2 is MethodElement) { 6626 } else if (element2 is MethodElement) {
5123 type = ((element2 as MethodElement)).type; 6627 staticType = ((element2 as MethodElement)).type;
5124 } else if (element2 is PropertyAccessorElement) { 6628 } else if (element2 is PropertyAccessorElement) {
5125 type = getType3((element2 as PropertyAccessorElement), node.prefix.staticT ype); 6629 staticType = getType((element2 as PropertyAccessorElement), node.prefix.st aticType);
5126 } else if (element2 is ExecutableElement) { 6630 } else if (element2 is ExecutableElement) {
5127 type = ((element2 as ExecutableElement)).type; 6631 staticType = ((element2 as ExecutableElement)).type;
5128 } else if (element2 is TypeVariableElement) { 6632 } else if (element2 is TypeVariableElement) {
5129 type = ((element2 as TypeVariableElement)).type; 6633 staticType = ((element2 as TypeVariableElement)).type;
5130 } else if (element2 is VariableElement) { 6634 } else if (element2 is VariableElement) {
5131 type = ((element2 as VariableElement)).type; 6635 staticType = ((element2 as VariableElement)).type;
5132 } else {
5133 type = _dynamicType;
5134 } 6636 }
5135 recordType(prefixedIdentifier, type); 6637 recordStaticType(prefixedIdentifier, staticType);
5136 return recordType(node, type); 6638 recordStaticType(node, staticType);
6639 Type2 propagatedType = _overrideManager.getType(element2);
6640 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
6641 recordPropagatedType(prefixedIdentifier, propagatedType);
6642 recordPropagatedType(node, propagatedType);
6643 }
6644 return null;
5137 } 6645 }
6646
5138 /** 6647 /**
5139 * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u </i> of the form 6648 * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u </i> of the form
5140 * <i>op e</i> is equivalent to a method invocation <i>expression e.op()</i>. An expression of the 6649 * <i>op e</i> is equivalent to a method invocation <i>expression e.op()</i>. An expression of the
5141 * form <i>op super</i> is equivalent to the method invocation <i>super.op()<i >.</blockquote> 6650 * form <i>op super</i> is equivalent to the method invocation <i>super.op()<i >.</blockquote>
5142 */ 6651 */
5143 Object visitPrefixExpression(PrefixExpression node) { 6652 Object visitPrefixExpression(PrefixExpression node) {
5144 sc.TokenType operator2 = node.operator.type; 6653 sc.TokenType operator2 = node.operator.type;
5145 if (identical(operator2, sc.TokenType.BANG)) { 6654 if (identical(operator2, sc.TokenType.BANG)) {
5146 return recordType(node, _typeProvider.boolType); 6655 recordStaticType(node, _typeProvider.boolType);
6656 } else {
6657 ExecutableElement staticMethodElement = node.staticElement;
6658 Type2 staticType = computeReturnType(staticMethodElement);
6659 if (identical(operator2, sc.TokenType.MINUS_MINUS) || identical(operator2, sc.TokenType.PLUS_PLUS)) {
6660 Type2 intType2 = _typeProvider.intType;
6661 if (identical(getStaticType(node.operand), intType2)) {
6662 staticType = intType2;
6663 }
6664 }
6665 recordStaticType(node, staticType);
6666 MethodElement propagatedMethodElement = node.element;
6667 if (propagatedMethodElement != staticMethodElement) {
6668 Type2 propagatedType = computeReturnType(propagatedMethodElement);
6669 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticTy pe)) {
6670 recordPropagatedType(node, propagatedType);
6671 }
6672 }
5147 } 6673 }
5148 return recordReturnType(node, node.element); 6674 return null;
5149 } 6675 }
6676
5150 /** 6677 /**
5151 * The Dart Language Specification, 12.13: <blockquote> Property extraction al lows for a member of 6678 * The Dart Language Specification, 12.13: <blockquote> Property extraction al lows for a member of
5152 * an object to be concisely extracted from the object. If <i>o</i> is an obje ct, and if <i>m</i> 6679 * an object to be concisely extracted from the object. If <i>o</i> is an obje ct, and if <i>m</i>
5153 * is the name of a method member of <i>o</i>, then 6680 * is the name of a method member of <i>o</i>, then
5154 * <ul> 6681 * <ul>
5155 * <li><i>o.m</i> is defined to be equivalent to: <i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>, 6682 * <li><i>o.m</i> is defined to be equivalent to: <i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
5156 * {p<sub>1</sub> : d<sub>1</sub>, &hellip;, p<sub>k</sub> : d<sub>k</sub>}){r eturn 6683 * {p<sub>1</sub> : d<sub>1</sub>, &hellip;, p<sub>k</sub> : d<sub>k</sub>}){r eturn
5157 * o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>, p<sub>1</sub>: p<sub>1</sub>, & hellip;, 6684 * o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>, p<sub>1</sub>: p<sub>1</sub>, & hellip;,
5158 * p<sub>k</sub>: p<sub>k</sub>);}</i> if <i>m</i> has required parameters <i> r<sub>1</sub>, 6685 * p<sub>k</sub>: p<sub>k</sub>);}</i> if <i>m</i> has required parameters <i> r<sub>1</sub>,
5159 * &hellip;, r<sub>n</sub></i>, and named parameters <i>p<sub>1</sub> &hellip; p<sub>k</sub></i> 6686 * &hellip;, r<sub>n</sub></i>, and named parameters <i>p<sub>1</sub> &hellip; p<sub>k</sub></i>
(...skipping 26 matching lines...) Expand all
5186 * otherwise. 6713 * otherwise.
5187 * <p> 6714 * <p>
5188 * ... a top-level getter invocation <i>i</i> of the form <i>m</i>, where <i>m </i> is an 6715 * ... a top-level getter invocation <i>i</i> of the form <i>m</i>, where <i>m </i> is an
5189 * identifier ... 6716 * identifier ...
5190 * <p> 6717 * <p>
5191 * The static type of <i>i</i> is the declared return type of <i>m</i>.</block quote> 6718 * The static type of <i>i</i> is the declared return type of <i>m</i>.</block quote>
5192 */ 6719 */
5193 Object visitPropertyAccess(PropertyAccess node) { 6720 Object visitPropertyAccess(PropertyAccess node) {
5194 SimpleIdentifier propertyName2 = node.propertyName; 6721 SimpleIdentifier propertyName2 = node.propertyName;
5195 Element element2 = propertyName2.element; 6722 Element element2 = propertyName2.element;
5196 if (USE_TYPE_PROPAGATION) { 6723 Type2 staticType = _dynamicType;
5197 Type2 type = _overrideManager.getType(element2);
5198 if (type != null) {
5199 return recordType(node, type);
5200 }
5201 }
5202 if (element2 is MethodElement) { 6724 if (element2 is MethodElement) {
5203 FunctionType type2 = ((element2 as MethodElement)).type; 6725 staticType = ((element2 as MethodElement)).type;
5204 recordType(propertyName2, type2);
5205 return recordType(node, type2);
5206 } else if (element2 is PropertyAccessorElement) { 6726 } else if (element2 is PropertyAccessorElement) {
5207 Type2 propertyType = getType3((element2 as PropertyAccessorElement), node. target != null ? node.target.staticType : null); 6727 staticType = getType((element2 as PropertyAccessorElement), node.target != null ? getStaticType(node.target) : null);
5208 recordType(propertyName2, propertyType);
5209 return recordType(node, propertyType);
5210 } else { 6728 } else {
5211 } 6729 }
5212 recordType(propertyName2, _dynamicType); 6730 recordStaticType(propertyName2, staticType);
5213 return recordType(node, _dynamicType); 6731 recordStaticType(node, staticType);
6732 Type2 propagatedType = _overrideManager.getType(element2);
6733 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
6734 recordPropagatedType(node, propagatedType);
6735 }
6736 return null;
5214 } 6737 }
6738
5215 /** 6739 /**
5216 * The Dart Language Specification, 12.9: <blockquote>The static type of a ret hrow expression is 6740 * The Dart Language Specification, 12.9: <blockquote>The static type of a ret hrow expression is
5217 * bottom.</blockquote> 6741 * bottom.</blockquote>
5218 */ 6742 */
5219 Object visitRethrowExpression(RethrowExpression node) => recordType(node, _typ eProvider.bottomType); 6743 Object visitRethrowExpression(RethrowExpression node) {
6744 recordStaticType(node, _typeProvider.bottomType);
6745 return null;
6746 }
6747
5220 /** 6748 /**
5221 * The Dart Language Specification, 12.30: <blockquote>Evaluation of an identi fier expression 6749 * The Dart Language Specification, 12.30: <blockquote>Evaluation of an identi fier expression
5222 * <i>e</i> of the form <i>id</i> proceeds as follows: 6750 * <i>e</i> of the form <i>id</i> proceeds as follows:
5223 * <p> 6751 * <p>
5224 * Let <i>d</i> be the innermost declaration in the enclosing lexical scope wh ose name is 6752 * Let <i>d</i> be the innermost declaration in the enclosing lexical scope wh ose name is
5225 * <i>id</i>. If no such declaration exists in the lexical scope, let <i>d</i> be the declaration 6753 * <i>id</i>. If no such declaration exists in the lexical scope, let <i>d</i> be the declaration
5226 * of the inherited member named <i>id</i> if it exists. 6754 * of the inherited member named <i>id</i> if it exists.
5227 * <ul> 6755 * <ul>
5228 * <li>If <i>d</i> is a class or type alias <i>T</i>, the value of <i>e</i> is the unique instance 6756 * <li>If <i>d</i> is a class or type alias <i>T</i>, the value of <i>e</i> is the unique instance
5229 * of class {@code Type} reifying <i>T</i>. 6757 * of class {@code Type} reifying <i>T</i>.
(...skipping 24 matching lines...) Expand all
5254 * getter invocation <i>id</i>. 6782 * getter invocation <i>id</i>.
5255 * <li>Otherwise, if <i>e</i> occurs inside a top level or static function (be it function, 6783 * <li>Otherwise, if <i>e</i> occurs inside a top level or static function (be it function,
5256 * method, getter, or setter) or variable initializer, evaluation of e causes a NoSuchMethodError 6784 * method, getter, or setter) or variable initializer, evaluation of e causes a NoSuchMethodError
5257 * to be thrown. 6785 * to be thrown.
5258 * <li>Otherwise <i>e</i> is equivalent to the property extraction <i>this.id< /i>. 6786 * <li>Otherwise <i>e</i> is equivalent to the property extraction <i>this.id< /i>.
5259 * </ul> 6787 * </ul>
5260 * </blockquote> 6788 * </blockquote>
5261 */ 6789 */
5262 Object visitSimpleIdentifier(SimpleIdentifier node) { 6790 Object visitSimpleIdentifier(SimpleIdentifier node) {
5263 Element element2 = node.element; 6791 Element element2 = node.element;
5264 if (element2 == null) { 6792 Type2 staticType = _dynamicType;
5265 return recordType(node, _dynamicType);
5266 }
5267 if (USE_TYPE_PROPAGATION) {
5268 Type2 type = _overrideManager.getType(element2);
5269 if (type != null) {
5270 return recordType(node, type);
5271 }
5272 }
5273 Type2 type;
5274 if (element2 is ClassElement) { 6793 if (element2 is ClassElement) {
5275 if (isNotTypeLiteral(node)) { 6794 if (isNotTypeLiteral(node)) {
5276 type = ((element2 as ClassElement)).type; 6795 staticType = ((element2 as ClassElement)).type;
5277 } else { 6796 } else {
5278 type = _typeProvider.typeType; 6797 staticType = _typeProvider.typeType;
5279 } 6798 }
5280 } else if (element2 is FunctionTypeAliasElement) { 6799 } else if (element2 is FunctionTypeAliasElement) {
5281 type = ((element2 as FunctionTypeAliasElement)).type; 6800 staticType = ((element2 as FunctionTypeAliasElement)).type;
5282 } else if (element2 is MethodElement) { 6801 } else if (element2 is MethodElement) {
5283 type = ((element2 as MethodElement)).type; 6802 staticType = ((element2 as MethodElement)).type;
5284 } else if (element2 is PropertyAccessorElement) { 6803 } else if (element2 is PropertyAccessorElement) {
5285 type = getType3((element2 as PropertyAccessorElement), null); 6804 staticType = getType((element2 as PropertyAccessorElement), null);
5286 } else if (element2 is ExecutableElement) { 6805 } else if (element2 is ExecutableElement) {
5287 type = ((element2 as ExecutableElement)).type; 6806 staticType = ((element2 as ExecutableElement)).type;
5288 } else if (element2 is TypeVariableElement) { 6807 } else if (element2 is TypeVariableElement) {
5289 type = ((element2 as TypeVariableElement)).type; 6808 staticType = ((element2 as TypeVariableElement)).type;
5290 } else if (element2 is VariableElement) { 6809 } else if (element2 is VariableElement) {
5291 type = ((element2 as VariableElement)).type; 6810 staticType = ((element2 as VariableElement)).type;
5292 } else if (element2 is PrefixElement) { 6811 } else if (element2 is PrefixElement) {
5293 return null; 6812 return null;
5294 } else { 6813 } else {
5295 type = _dynamicType; 6814 staticType = _dynamicType;
5296 } 6815 }
5297 return recordType(node, type); 6816 recordStaticType(node, staticType);
6817 Type2 propagatedType = _overrideManager.getType(element2);
6818 if (propagatedType != null && propagatedType.isMoreSpecificThan(staticType)) {
6819 recordPropagatedType(node, propagatedType);
6820 }
6821 return null;
5298 } 6822 }
6823
5299 /** 6824 /**
5300 * The Dart Language Specification, 12.5: <blockquote>The static type of a str ing literal is{@code String}.</blockquote> 6825 * The Dart Language Specification, 12.5: <blockquote>The static type of a str ing literal is{@code String}.</blockquote>
5301 */ 6826 */
5302 Object visitSimpleStringLiteral(SimpleStringLiteral node) => recordType(node, _typeProvider.stringType); 6827 Object visitSimpleStringLiteral(SimpleStringLiteral node) {
6828 recordStaticType(node, _typeProvider.stringType);
6829 return null;
6830 }
6831
5303 /** 6832 /**
5304 * The Dart Language Specification, 12.5: <blockquote>The static type of a str ing literal is{@code String}.</blockquote> 6833 * The Dart Language Specification, 12.5: <blockquote>The static type of a str ing literal is{@code String}.</blockquote>
5305 */ 6834 */
5306 Object visitStringInterpolation(StringInterpolation node) => recordType(node, _typeProvider.stringType); 6835 Object visitStringInterpolation(StringInterpolation node) {
6836 recordStaticType(node, _typeProvider.stringType);
6837 return null;
6838 }
5307 Object visitSuperExpression(SuperExpression node) { 6839 Object visitSuperExpression(SuperExpression node) {
5308 if (_thisType == null) { 6840 if (_thisType == null) {
5309 return recordType(node, _dynamicType); 6841 recordStaticType(node, _dynamicType);
5310 } else { 6842 } else {
5311 return recordType(node, _thisType.superclass); 6843 recordStaticType(node, _thisType);
5312 } 6844 }
6845 return null;
5313 } 6846 }
6847
5314 /** 6848 /**
5315 * The Dart Language Specification, 12.10: <blockquote>The static type of {@co de this} is the 6849 * The Dart Language Specification, 12.10: <blockquote>The static type of {@co de this} is the
5316 * interface of the immediately enclosing class.</blockquote> 6850 * interface of the immediately enclosing class.</blockquote>
5317 */ 6851 */
5318 Object visitThisExpression(ThisExpression node) { 6852 Object visitThisExpression(ThisExpression node) {
5319 if (_thisType == null) { 6853 if (_thisType == null) {
5320 return recordType(node, _dynamicType); 6854 recordStaticType(node, _dynamicType);
5321 } else { 6855 } else {
5322 return recordType(node, _thisType); 6856 recordStaticType(node, _thisType);
5323 } 6857 }
6858 return null;
5324 } 6859 }
6860
5325 /** 6861 /**
5326 * The Dart Language Specification, 12.8: <blockquote>The static type of a thr ow expression is 6862 * The Dart Language Specification, 12.8: <blockquote>The static type of a thr ow expression is
5327 * bottom.</blockquote> 6863 * bottom.</blockquote>
5328 */ 6864 */
5329 Object visitThrowExpression(ThrowExpression node) => recordType(node, _typePro vider.bottomType); 6865 Object visitThrowExpression(ThrowExpression node) {
6866 recordStaticType(node, _typeProvider.bottomType);
6867 return null;
6868 }
5330 Object visitVariableDeclaration(VariableDeclaration node) { 6869 Object visitVariableDeclaration(VariableDeclaration node) {
5331 if (USE_TYPE_PROPAGATION) { 6870 Expression initializer2 = node.initializer;
5332 Expression initializer2 = node.initializer; 6871 if (initializer2 != null) {
5333 if (initializer2 != null) { 6872 Type2 rightType = getBestType(initializer2);
5334 Type2 rightType = getType2(initializer2); 6873 VariableElement element2 = node.name.element as VariableElement;
5335 VariableElement element2 = node.name.element as VariableElement; 6874 if (element2 != null) {
5336 if (element2 != null) { 6875 _resolver.override(element2, rightType);
5337 override(element2, getType(element2), rightType);
5338 }
5339 } 6876 }
5340 } 6877 }
5341 return null; 6878 return null;
5342 } 6879 }
6880
6881 /**
6882 * Record that the static type of the given node is the type of the second arg ument to the method
6883 * represented by the given element.
6884 * @param element the element representing the method invoked by the given nod e
6885 */
6886 Type2 computeArgumentType(ExecutableElement element) {
6887 if (element != null) {
6888 List<ParameterElement> parameters2 = element.parameters;
6889 if (parameters2 != null && parameters2.length == 2) {
6890 return parameters2[1].type;
6891 }
6892 }
6893 return _dynamicType;
6894 }
6895
6896 /**
6897 * Compute the return type of the method or function represented by the given element.
6898 * @param element the element representing the method or function invoked by t he given node
6899 * @return the return type that was computed
6900 */
6901 Type2 computeReturnType(Element element) {
6902 if (element is PropertyAccessorElement) {
6903 FunctionType propertyType = ((element as PropertyAccessorElement)).type;
6904 if (propertyType != null) {
6905 Type2 returnType2 = propertyType.returnType;
6906 if (returnType2 is InterfaceType) {
6907 if (identical(returnType2, _typeProvider.functionType)) {
6908 return _dynamicType;
6909 }
6910 MethodElement callMethod = ((returnType2 as InterfaceType)).lookUpMeth od(ElementResolver.CALL_METHOD_NAME, _resolver.definingLibrary);
6911 if (callMethod != null) {
6912 return callMethod.type.returnType;
6913 }
6914 } else if (returnType2 is FunctionType) {
6915 Type2 innerReturnType = ((returnType2 as FunctionType)).returnType;
6916 if (innerReturnType != null) {
6917 return innerReturnType;
6918 }
6919 } else if (returnType2.isDartCoreFunction()) {
6920 return _dynamicType;
6921 }
6922 if (returnType2 != null) {
6923 return returnType2;
6924 }
6925 }
6926 } else if (element is ExecutableElement) {
6927 FunctionType type2 = ((element as ExecutableElement)).type;
6928 if (type2 != null) {
6929 return type2.returnType;
6930 }
6931 } else if (element is VariableElement) {
6932 Type2 variableType = ((element as VariableElement)).type;
6933 if (variableType is FunctionType) {
6934 return ((variableType as FunctionType)).returnType;
6935 }
6936 }
6937 return _dynamicType;
6938 }
6939
5343 /** 6940 /**
5344 * Given a function declaration, compute the return type of the function. The return type of 6941 * Given a function declaration, compute the return type of the function. The return type of
5345 * functions with a block body is {@code dynamicType}, with an expression body it is the type of 6942 * functions with a block body is {@code dynamicType}, with an expression body it is the type of
5346 * the expression. 6943 * the expression.
5347 * @param node the function expression whose return type is to be computed 6944 * @param node the function expression whose return type is to be computed
5348 * @return the return type that was computed 6945 * @return the return type that was computed
5349 */ 6946 */
5350 Type2 computeReturnType(FunctionDeclaration node) { 6947 Type2 computeReturnType2(FunctionDeclaration node) {
5351 TypeName returnType2 = node.returnType; 6948 TypeName returnType2 = node.returnType;
5352 if (returnType2 == null) { 6949 if (returnType2 == null) {
5353 return computeReturnType2(node.functionExpression); 6950 return _dynamicType;
5354 } 6951 }
5355 return returnType2.type; 6952 return returnType2.type;
5356 } 6953 }
6954
5357 /** 6955 /**
5358 * Given a function expression, compute the return type of the function. The r eturn type of 6956 * Given a function expression, compute the return type of the function. The r eturn type of
5359 * functions with a block body is {@code dynamicType}, with an expression body it is the type of 6957 * functions with a block body is {@code dynamicType}, with an expression body it is the type of
5360 * the expression. 6958 * the expression.
5361 * @param node the function expression whose return type is to be computed 6959 * @param node the function expression whose return type is to be computed
5362 * @return the return type that was computed 6960 * @return the return type that was computed
5363 */ 6961 */
5364 Type2 computeReturnType2(FunctionExpression node) { 6962 Type2 computeReturnType3(FunctionExpression node) {
5365 FunctionBody body2 = node.body; 6963 FunctionBody body2 = node.body;
5366 if (body2 is ExpressionFunctionBody) { 6964 if (body2 is ExpressionFunctionBody) {
5367 return getType2(((body2 as ExpressionFunctionBody)).expression); 6965 return getStaticType(((body2 as ExpressionFunctionBody)).expression);
5368 } 6966 }
5369 return _dynamicType; 6967 return _dynamicType;
5370 } 6968 }
6969
6970 /**
6971 * Return the propagated type of the given expression if it is available, or t he static type if
6972 * there is no propagated type.
6973 * @param expression the expression whose type is to be returned
6974 * @return the propagated or static type of the given expression
6975 */
6976 Type2 getBestType(Expression expression) {
6977 Type2 type = expression.propagatedType;
6978 if (type == null) {
6979 type = expression.staticType;
6980 if (type == null) {
6981 return _dynamicType;
6982 }
6983 }
6984 return type;
6985 }
6986
5371 /** 6987 /**
5372 * If the given argument list contains at least one argument, and if the argum ent is a simple 6988 * If the given argument list contains at least one argument, and if the argum ent is a simple
5373 * string literal, then parse that argument as a query string and return the t ype specified by the 6989 * string literal, then parse that argument as a query string and return the t ype specified by the
5374 * argument. 6990 * argument.
5375 * @param library the library in which the specified type would be defined 6991 * @param library the library in which the specified type would be defined
5376 * @param argumentList the list of arguments from which a type is to be extrac ted 6992 * @param argumentList the list of arguments from which a type is to be extrac ted
5377 * @return the type specified by the first argument in the argument list 6993 * @return the type specified by the first argument in the argument list
5378 */ 6994 */
5379 Type2 getFirstArgumentAsQuery(LibraryElement library, ArgumentList argumentLis t) { 6995 Type2 getFirstArgumentAsQuery(LibraryElement library, ArgumentList argumentLis t) {
5380 String argumentValue = getFirstArgumentAsString(argumentList); 6996 String argumentValue = getFirstArgumentAsString(argumentList);
5381 if (argumentValue != null) { 6997 if (argumentValue != null) {
5382 if (argumentValue.contains(" ")) { 6998 if (argumentValue.contains(" ")) {
5383 return null; 6999 return null;
5384 } 7000 }
5385 String tag = argumentValue; 7001 String tag = argumentValue;
5386 tag = StringUtilities.substringBefore(tag, ":"); 7002 tag = StringUtilities.substringBefore(tag, ":");
5387 tag = StringUtilities.substringBefore(tag, "["); 7003 tag = StringUtilities.substringBefore(tag, "[");
5388 tag = StringUtilities.substringBefore(tag, "."); 7004 tag = StringUtilities.substringBefore(tag, ".");
5389 tag = StringUtilities.substringBefore(tag, "#"); 7005 tag = StringUtilities.substringBefore(tag, "#");
5390 tag = _HTML_ELEMENT_TO_CLASS_MAP[tag.toLowerCase()]; 7006 tag = _HTML_ELEMENT_TO_CLASS_MAP[tag.toLowerCase()];
5391 ClassElement returnType = library.getType(tag); 7007 ClassElement returnType = library.getType(tag);
5392 if (returnType != null) { 7008 if (returnType != null) {
5393 return returnType.type; 7009 return returnType.type;
5394 } 7010 }
5395 } 7011 }
5396 return null; 7012 return null;
5397 } 7013 }
7014
5398 /** 7015 /**
5399 * If the given argument list contains at least one argument, and if the argum ent is a simple 7016 * If the given argument list contains at least one argument, and if the argum ent is a simple
5400 * string literal, return the String value of the argument. 7017 * string literal, return the String value of the argument.
5401 * @param argumentList the list of arguments from which a string value is to b e extracted 7018 * @param argumentList the list of arguments from which a string value is to b e extracted
5402 * @return the string specified by the first argument in the argument list 7019 * @return the string specified by the first argument in the argument list
5403 */ 7020 */
5404 String getFirstArgumentAsString(ArgumentList argumentList) { 7021 String getFirstArgumentAsString(ArgumentList argumentList) {
5405 NodeList<Expression> arguments2 = argumentList.arguments; 7022 NodeList<Expression> arguments2 = argumentList.arguments;
5406 if (arguments2.length > 0) { 7023 if (arguments2.length > 0) {
5407 Expression argument = arguments2[0]; 7024 Expression argument = arguments2[0];
5408 if (argument is SimpleStringLiteral) { 7025 if (argument is SimpleStringLiteral) {
5409 return ((argument as SimpleStringLiteral)).value; 7026 return ((argument as SimpleStringLiteral)).value;
5410 } 7027 }
5411 } 7028 }
5412 return null; 7029 return null;
5413 } 7030 }
7031
5414 /** 7032 /**
5415 * If the given argument list contains at least one argument, and if the argum ent is a simple 7033 * If the given argument list contains at least one argument, and if the argum ent is a simple
5416 * string literal, and if the value of the argument is the name of a class def ined within the 7034 * string literal, and if the value of the argument is the name of a class def ined within the
5417 * given library, return the type specified by the argument. 7035 * given library, return the type specified by the argument.
5418 * @param library the library in which the specified type would be defined 7036 * @param library the library in which the specified type would be defined
5419 * @param argumentList the list of arguments from which a type is to be extrac ted 7037 * @param argumentList the list of arguments from which a type is to be extrac ted
5420 * @return the type specified by the first argument in the argument list 7038 * @return the type specified by the first argument in the argument list
5421 */ 7039 */
5422 Type2 getFirstArgumentAsType(LibraryElement library, ArgumentList argumentList ) => getFirstArgumentAsType2(library, argumentList, null); 7040 Type2 getFirstArgumentAsType(LibraryElement library, ArgumentList argumentList ) => getFirstArgumentAsType2(library, argumentList, null);
7041
5423 /** 7042 /**
5424 * If the given argument list contains at least one argument, and if the argum ent is a simple 7043 * If the given argument list contains at least one argument, and if the argum ent is a simple
5425 * string literal, and if the value of the argument is the name of a class def ined within the 7044 * string literal, and if the value of the argument is the name of a class def ined within the
5426 * given library, return the type specified by the argument. 7045 * given library, return the type specified by the argument.
5427 * @param library the library in which the specified type would be defined 7046 * @param library the library in which the specified type would be defined
5428 * @param argumentList the list of arguments from which a type is to be extrac ted 7047 * @param argumentList the list of arguments from which a type is to be extrac ted
5429 * @return the type specified by the first argument in the argument list 7048 * @return the type specified by the first argument in the argument list
5430 */ 7049 */
5431 Type2 getFirstArgumentAsType2(LibraryElement library, ArgumentList argumentLis t, Map<String, String> nameMap) { 7050 Type2 getFirstArgumentAsType2(LibraryElement library, ArgumentList argumentLis t, Map<String, String> nameMap) {
5432 String argumentValue = getFirstArgumentAsString(argumentList); 7051 String argumentValue = getFirstArgumentAsString(argumentList);
5433 if (argumentValue != null) { 7052 if (argumentValue != null) {
5434 if (nameMap != null) { 7053 if (nameMap != null) {
5435 argumentValue = nameMap[argumentValue.toLowerCase()]; 7054 argumentValue = nameMap[argumentValue.toLowerCase()];
5436 } 7055 }
5437 ClassElement returnType = library.getType(argumentValue); 7056 ClassElement returnType = library.getType(argumentValue);
5438 if (returnType != null) { 7057 if (returnType != null) {
5439 return returnType.type; 7058 return returnType.type;
5440 } 7059 }
5441 } 7060 }
5442 return null; 7061 return null;
5443 } 7062 }
7063
5444 /** 7064 /**
5445 * Return the type of the given (overridable) element. 7065 * Return the propagated type of the given expression.
5446 * @param element the element whose type is to be returned 7066 * @param expression the expression whose type is to be returned
5447 * @return the type of the given element 7067 * @return the propagated type of the given expression
5448 */ 7068 */
5449 Type2 getType(Element element) { 7069 Type2 getPropagatedType(Expression expression) {
5450 if (element is LocalVariableElement) { 7070 Type2 type = expression.propagatedType;
5451 return ((element as LocalVariableElement)).type; 7071 return type;
5452 } else if (element is ParameterElement) {
5453 return ((element as ParameterElement)).type;
5454 }
5455 return null;
5456 } 7072 }
7073
5457 /** 7074 /**
5458 * Return the type of the given expression that is to be used for type analysi s. 7075 * Return the static type of the given expression.
5459 * @param expression the expression whose type is to be returned 7076 * @param expression the expression whose type is to be returned
5460 * @return the type of the given expression 7077 * @return the static type of the given expression
5461 */ 7078 */
5462 Type2 getType2(Expression expression) { 7079 Type2 getStaticType(Expression expression) {
5463 Type2 type = expression.staticType; 7080 Type2 type = expression.staticType;
5464 if (type == null) { 7081 if (type == null) {
5465 return _dynamicType; 7082 return _dynamicType;
5466 } 7083 }
5467 return type; 7084 return type;
5468 } 7085 }
7086
5469 /** 7087 /**
5470 * Return the type that should be recorded for a node that resolved to the giv en accessor. 7088 * Return the type that should be recorded for a node that resolved to the giv en accessor.
5471 * @param accessor the accessor that the node resolved to 7089 * @param accessor the accessor that the node resolved to
5472 * @param context if the accessor element has context \[by being the RHS of a{ @link PrefixedIdentifier} or {@link PropertyAccess}\], and the return type of th e 7090 * @param context if the accessor element has context \[by being the RHS of a{ @link PrefixedIdentifier} or {@link PropertyAccess}\], and the return type of th e
5473 * accessor is a parameter type, then the type of the LHS can be used to get m ore 7091 * accessor is a parameter type, then the type of the LHS can be used to get m ore
5474 * specific type information 7092 * specific type information
5475 * @return the type that should be recorded for a node that resolved to the gi ven accessor 7093 * @return the type that should be recorded for a node that resolved to the gi ven accessor
5476 */ 7094 */
5477 Type2 getType3(PropertyAccessorElement accessor, Type2 context) { 7095 Type2 getType(PropertyAccessorElement accessor, Type2 context) {
5478 FunctionType functionType = accessor.type; 7096 FunctionType functionType = accessor.type;
5479 if (functionType == null) { 7097 if (functionType == null) {
5480 return _dynamicType; 7098 return _dynamicType;
5481 } 7099 }
5482 if (accessor.isSetter()) { 7100 if (accessor.isSetter()) {
5483 List<Type2> parameterTypes = functionType.normalParameterTypes; 7101 List<Type2> parameterTypes = functionType.normalParameterTypes;
5484 if (parameterTypes != null && parameterTypes.length > 0) { 7102 if (parameterTypes != null && parameterTypes.length > 0) {
5485 return parameterTypes[0]; 7103 return parameterTypes[0];
5486 } 7104 }
5487 PropertyAccessorElement getter2 = accessor.variable.getter; 7105 PropertyAccessorElement getter2 = accessor.variable.getter;
(...skipping 13 matching lines...) Expand all
5501 for (int i = 0; i < parameterElements.length; i++) { 7119 for (int i = 0; i < parameterElements.length; i++) {
5502 TypeVariableElement varElt = parameterElements[i]; 7120 TypeVariableElement varElt = parameterElements[i];
5503 if (returnType2.name == varElt.name) { 7121 if (returnType2.name == varElt.name) {
5504 return interfaceTypeContext.typeArguments[i]; 7122 return interfaceTypeContext.typeArguments[i];
5505 } 7123 }
5506 } 7124 }
5507 } 7125 }
5508 } 7126 }
5509 return returnType2; 7127 return returnType2;
5510 } 7128 }
7129
5511 /** 7130 /**
5512 * Return the type represented by the given type name. 7131 * Return the type represented by the given type name.
5513 * @param typeName the type name representing the type to be returned 7132 * @param typeName the type name representing the type to be returned
5514 * @return the type represented by the type name 7133 * @return the type represented by the type name
5515 */ 7134 */
5516 Type2 getType4(TypeName typeName) { 7135 Type2 getType2(TypeName typeName) {
5517 Type2 type2 = typeName.type; 7136 Type2 type2 = typeName.type;
5518 if (type2 == null) { 7137 if (type2 == null) {
5519 return _dynamicType; 7138 return _dynamicType;
5520 } 7139 }
5521 return type2; 7140 return type2;
5522 } 7141 }
7142
5523 /** 7143 /**
5524 * Return {@code true} if the given library is the 'dart:html' library. 7144 * Return {@code true} if the given library is the 'dart:html' library.
5525 * @param library the library being tested 7145 * @param library the library being tested
5526 * @return {@code true} if the library is 'dart:html' 7146 * @return {@code true} if the library is 'dart:html'
5527 */ 7147 */
5528 bool isHtmlLibrary(LibraryElement library) => library.name == "dart.dom.html"; 7148 bool isHtmlLibrary(LibraryElement library) => library.name == "dart.dom.html";
7149
5529 /** 7150 /**
5530 * Return {@code true} if the given node is not a type literal. 7151 * Return {@code true} if the given node is not a type literal.
5531 * @param node the node being tested 7152 * @param node the node being tested
5532 * @return {@code true} if the given node is not a type literal 7153 * @return {@code true} if the given node is not a type literal
5533 */ 7154 */
5534 bool isNotTypeLiteral(Identifier node) { 7155 bool isNotTypeLiteral(Identifier node) {
5535 ASTNode parent2 = node.parent; 7156 ASTNode parent2 = node.parent;
5536 return parent2 is TypeName || (parent2 is PrefixedIdentifier && (parent2.par ent is TypeName || identical(((parent2 as PrefixedIdentifier)).prefix, node))) | | (parent2 is PropertyAccess && identical(((parent2 as PropertyAccess)).target, node)) || (parent2 is MethodInvocation && identical(node, ((parent2 as MethodInv ocation)).target)); 7157 return parent2 is TypeName || (parent2 is PrefixedIdentifier && (parent2.par ent is TypeName || identical(((parent2 as PrefixedIdentifier)).prefix, node))) | | (parent2 is PropertyAccess && identical(((parent2 as PropertyAccess)).target, node)) || (parent2 is MethodInvocation && identical(node, ((parent2 as MethodInv ocation)).target));
5537 } 7158 }
7159
5538 /** 7160 /**
5539 * If it is appropriate to do so, override the type of the given element. Use the static type and 7161 * Record that the propagated type of the given node is the given type.
5540 * inferred type of the element to determine whether or not it is appropriate. 7162 * @param expression the node whose type is to be recorded
5541 * @param element the element whose type might be overridden 7163 * @param type the propagated type of the node
5542 * @param staticType the static type of the element
5543 * @param inferredType the inferred type of the element
5544 */ 7164 */
5545 void override(VariableElement element, Type2 staticType, Type2 inferredType) { 7165 void recordPropagatedType(Expression expression, Type2 type) {
5546 if (identical(inferredType, BottomTypeImpl.instance)) { 7166 if (type != null && !type.isDynamic()) {
5547 return; 7167 expression.propagatedType = type;
5548 }
5549 if (element is PropertyInducingElement) {
5550 PropertyInducingElement variable = element as PropertyInducingElement;
5551 if (!variable.isConst() && !variable.isFinal()) {
5552 return;
5553 }
5554 }
5555 if (staticType == null || (inferredType != null && inferredType.isMoreSpecif icThan(staticType))) {
5556 _overrideManager.setType(element, inferredType);
5557 } 7168 }
5558 } 7169 }
5559 /** 7170
5560 * Record that the static type of the given node is the type of the second arg ument to the method
5561 * represented by the given element.
5562 * @param expression the node whose type is to be recorded
5563 * @param element the element representing the method invoked by the given nod e
5564 */
5565 Object recordArgumentType(IndexExpression expression, MethodElement element) {
5566 if (element != null) {
5567 List<ParameterElement> parameters2 = element.parameters;
5568 if (parameters2 != null && parameters2.length == 2) {
5569 return recordType(expression, parameters2[1].type);
5570 }
5571 }
5572 return recordType(expression, _dynamicType);
5573 }
5574 /**
5575 * Record that the static type of the given node is the return type of the met hod or function
5576 * represented by the given element.
5577 * @param expression the node whose type is to be recorded
5578 * @param element the element representing the method or function invoked by t he given node
5579 */
5580 Object recordReturnType(Expression expression, Element element) {
5581 if (element is PropertyAccessorElement) {
5582 FunctionType propertyType = ((element as PropertyAccessorElement)).type;
5583 if (propertyType != null) {
5584 Type2 returnType2 = propertyType.returnType;
5585 if (returnType2 is FunctionType) {
5586 Type2 innerReturnType = ((returnType2 as FunctionType)).returnType;
5587 if (innerReturnType != null) {
5588 return recordType(expression, innerReturnType);
5589 }
5590 } else if (returnType2.isDartCoreFunction()) {
5591 return recordType(expression, _dynamicType);
5592 }
5593 if (returnType2 != null) {
5594 return recordType(expression, returnType2);
5595 }
5596 }
5597 } else if (element is ExecutableElement) {
5598 FunctionType type2 = ((element as ExecutableElement)).type;
5599 if (type2 != null) {
5600 return recordType(expression, type2.returnType);
5601 }
5602 } else if (element is VariableElement) {
5603 Type2 variableType = ((element as VariableElement)).type;
5604 if (variableType is FunctionType) {
5605 return recordType(expression, ((variableType as FunctionType)).returnTyp e);
5606 }
5607 }
5608 return recordType(expression, _dynamicType);
5609 }
5610 /** 7171 /**
5611 * Record that the static type of the given node is the given type. 7172 * Record that the static type of the given node is the given type.
5612 * @param expression the node whose type is to be recorded 7173 * @param expression the node whose type is to be recorded
5613 * @param type the static type of the node 7174 * @param type the static type of the node
5614 */ 7175 */
5615 Object recordType(Expression expression, Type2 type) { 7176 void recordStaticType(Expression expression, Type2 type) {
5616 if (type == null) { 7177 if (type == null) {
5617 expression.staticType = _dynamicType; 7178 expression.staticType = _dynamicType;
5618 } else { 7179 } else {
5619 expression.staticType = type; 7180 expression.staticType = type;
5620 } 7181 }
5621 return null;
5622 } 7182 }
7183
7184 /**
7185 * Attempts to make a better guess for the static type of the given binary exp ression.
7186 * @param node the binary expression to analyze
7187 * @param staticType the static type of the expression as resolved
7188 * @return the better type guess, or the same static type as given
7189 */
7190 Type2 refineBinaryExpressionType(BinaryExpression node, Type2 staticType) {
7191 sc.TokenType operator2 = node.operator.type;
7192 if (identical(operator2, sc.TokenType.AMPERSAND_AMPERSAND) || identical(oper ator2, sc.TokenType.BAR_BAR) || identical(operator2, sc.TokenType.EQ_EQ) || iden tical(operator2, sc.TokenType.BANG_EQ)) {
7193 return _typeProvider.boolType;
7194 }
7195 if (identical(operator2, sc.TokenType.MINUS) || identical(operator2, sc.Toke nType.PERCENT) || identical(operator2, sc.TokenType.PLUS) || identical(operator2 , sc.TokenType.STAR)) {
7196 Type2 doubleType2 = _typeProvider.doubleType;
7197 if (identical(getStaticType(node.leftOperand), doubleType2) || identical(g etStaticType(node.rightOperand), doubleType2)) {
7198 return doubleType2;
7199 }
7200 }
7201 if (identical(operator2, sc.TokenType.MINUS) || identical(operator2, sc.Toke nType.PERCENT) || identical(operator2, sc.TokenType.PLUS) || identical(operator2 , sc.TokenType.STAR) || identical(operator2, sc.TokenType.TILDE_SLASH)) {
7202 Type2 intType2 = _typeProvider.intType;
7203 if (identical(getStaticType(node.leftOperand), intType2) && identical(getS taticType(node.rightOperand), intType2)) {
7204 staticType = intType2;
7205 }
7206 }
7207 return staticType;
7208 }
7209
5623 /** 7210 /**
5624 * Set the return type and parameter type information for the given function t ype based on the 7211 * Set the return type and parameter type information for the given function t ype based on the
5625 * given return type and parameter elements. 7212 * given return type and parameter elements.
5626 * @param functionType the function type to be filled in 7213 * @param functionType the function type to be filled in
5627 * @param returnType the return type of the function, or {@code null} if no ty pe was declared 7214 * @param returnType the return type of the function, or {@code null} if no ty pe was declared
5628 * @param parameters the elements representing the parameters to the function 7215 * @param parameters the elements representing the parameters to the function
5629 */ 7216 */
5630 void setTypeInformation(FunctionTypeImpl functionType, Type2 returnType2, Form alParameterList parameterList) { 7217 void setTypeInformation(FunctionTypeImpl functionType, Type2 returnType2, Form alParameterList parameterList) {
5631 List<Type2> normalParameterTypes = new List<Type2>(); 7218 List<Type2> normalParameterTypes = new List<Type2>();
5632 List<Type2> optionalParameterTypes = new List<Type2>(); 7219 List<Type2> optionalParameterTypes = new List<Type2>();
(...skipping 13 matching lines...) Expand all
5646 } 7233 }
5647 } 7234 }
5648 functionType.normalParameterTypes = new List.from(normalParameterTypes); 7235 functionType.normalParameterTypes = new List.from(normalParameterTypes);
5649 functionType.optionalParameterTypes = new List.from(optionalParameterTypes); 7236 functionType.optionalParameterTypes = new List.from(optionalParameterTypes);
5650 functionType.namedParameterTypes = namedParameterTypes; 7237 functionType.namedParameterTypes = namedParameterTypes;
5651 functionType.returnType = returnType2; 7238 functionType.returnType = returnType2;
5652 } 7239 }
5653 get thisType_J2DAccessor => _thisType; 7240 get thisType_J2DAccessor => _thisType;
5654 set thisType_J2DAccessor(__v) => _thisType = __v; 7241 set thisType_J2DAccessor(__v) => _thisType = __v;
5655 } 7242 }
7243
5656 /** 7244 /**
5657 * Instances of the class {@code TypeOverrideManager} manage the ability to over ride the type of an 7245 * Instances of the class {@code TypeOverrideManager} manage the ability to over ride the type of an
5658 * element within a given context. 7246 * element within a given context.
5659 */ 7247 */
5660 class TypeOverrideManager { 7248 class TypeOverrideManager {
7249
5661 /** 7250 /**
5662 * The current override scope, or {@code null} if no scope has been entered. 7251 * The current override scope, or {@code null} if no scope has been entered.
5663 */ 7252 */
5664 TypeOverrideManager_TypeOverrideScope _currentScope; 7253 TypeOverrideManager_TypeOverrideScope _currentScope;
7254
5665 /** 7255 /**
5666 * Initialize a newly created override manager to not be in any scope. 7256 * Apply a set of overrides that were previously captured.
7257 * @param overrides the overrides to be applied
5667 */ 7258 */
5668 TypeOverrideManager() : super() { 7259 void applyOverrides(Map<Element, Type2> overrides) {
7260 if (_currentScope == null) {
7261 throw new IllegalStateException("Cannot apply overrides without a scope");
7262 }
7263 _currentScope.applyOverrides(overrides);
5669 } 7264 }
7265
7266 /**
7267 * Return a table mapping the elements whose type is overridden in the current scope to the
7268 * overriding type.
7269 * @return the overrides in the current scope
7270 */
7271 Map<Element, Type2> captureLocalOverrides() {
7272 if (_currentScope == null) {
7273 throw new IllegalStateException("Cannot capture local overrides without a scope");
7274 }
7275 return _currentScope.captureLocalOverrides();
7276 }
7277
7278 /**
7279 * Return a map from the elements for the variables in the given list that hav e their types
7280 * overridden to the overriding type.
7281 * @param variableList the list of variables whose overriding types are to be captured
7282 * @return a table mapping elements to their overriding types
7283 */
7284 Map<Element, Type2> captureOverrides(VariableDeclarationList variableList) {
7285 if (_currentScope == null) {
7286 throw new IllegalStateException("Cannot capture overrides without a scope" );
7287 }
7288 return _currentScope.captureOverrides(variableList);
7289 }
7290
5670 /** 7291 /**
5671 * Enter a new override scope. 7292 * Enter a new override scope.
5672 */ 7293 */
5673 void enterScope() { 7294 void enterScope() {
5674 _currentScope = new TypeOverrideManager_TypeOverrideScope(_currentScope); 7295 _currentScope = new TypeOverrideManager_TypeOverrideScope(_currentScope);
5675 } 7296 }
7297
5676 /** 7298 /**
5677 * Exit the current override scope. 7299 * Exit the current override scope.
5678 */ 7300 */
5679 void exitScope() { 7301 void exitScope() {
5680 if (_currentScope == null) { 7302 if (_currentScope == null) {
5681 throw new IllegalStateException("No scope to exit"); 7303 throw new IllegalStateException("No scope to exit");
5682 } 7304 }
5683 _currentScope = _currentScope._outerScope; 7305 _currentScope = _currentScope._outerScope;
5684 } 7306 }
7307
5685 /** 7308 /**
5686 * Return the overridden type of the given element, or {@code null} if the typ e of the element has 7309 * Return the overridden type of the given element, or {@code null} if the typ e of the element has
5687 * not been overridden. 7310 * not been overridden.
5688 * @param element the element whose type might have been overridden 7311 * @param element the element whose type might have been overridden
5689 * @return the overridden type of the given element 7312 * @return the overridden type of the given element
5690 */ 7313 */
5691 Type2 getType(Element element) { 7314 Type2 getType(Element element) {
5692 if (_currentScope == null) { 7315 if (_currentScope == null) {
5693 return null; 7316 return null;
5694 } 7317 }
5695 return _currentScope.getType(element); 7318 return _currentScope.getType(element);
5696 } 7319 }
7320
5697 /** 7321 /**
5698 * Set the overridden type of the given element to the given type 7322 * Set the overridden type of the given element to the given type
5699 * @param element the element whose type might have been overridden 7323 * @param element the element whose type might have been overridden
5700 * @param type the overridden type of the given element 7324 * @param type the overridden type of the given element
5701 */ 7325 */
5702 void setType(Element element, Type2 type) { 7326 void setType(Element element, Type2 type) {
5703 if (_currentScope == null) { 7327 if (_currentScope == null) {
5704 throw new IllegalStateException("Cannot override without a scope"); 7328 throw new IllegalStateException("Cannot override without a scope");
5705 } 7329 }
5706 _currentScope.setType(element, type); 7330 _currentScope.setType(element, type);
5707 } 7331 }
5708 } 7332 }
7333
5709 /** 7334 /**
5710 * Instances of the class {@code TypeOverrideScope} represent a scope in which t he types of 7335 * Instances of the class {@code TypeOverrideScope} represent a scope in which t he types of
5711 * elements can be overridden. 7336 * elements can be overridden.
5712 */ 7337 */
5713 class TypeOverrideManager_TypeOverrideScope { 7338 class TypeOverrideManager_TypeOverrideScope {
7339
5714 /** 7340 /**
5715 * The outer scope in which types might be overridden. 7341 * The outer scope in which types might be overridden.
5716 */ 7342 */
5717 TypeOverrideManager_TypeOverrideScope _outerScope; 7343 TypeOverrideManager_TypeOverrideScope _outerScope;
7344
5718 /** 7345 /**
5719 * A table mapping elements to the overridden type of that element. 7346 * A table mapping elements to the overridden type of that element.
5720 */ 7347 */
5721 Map<Element, Type2> _overridenTypes = new Map<Element, Type2>(); 7348 Map<Element, Type2> _overridenTypes = new Map<Element, Type2>();
7349
5722 /** 7350 /**
5723 * Initialize a newly created scope to be an empty child of the given scope. 7351 * Initialize a newly created scope to be an empty child of the given scope.
5724 * @param outerScope the outer scope in which types might be overridden 7352 * @param outerScope the outer scope in which types might be overridden
5725 */ 7353 */
5726 TypeOverrideManager_TypeOverrideScope(TypeOverrideManager_TypeOverrideScope ou terScope) { 7354 TypeOverrideManager_TypeOverrideScope(TypeOverrideManager_TypeOverrideScope ou terScope) {
5727 this._outerScope = outerScope; 7355 this._outerScope = outerScope;
5728 } 7356 }
7357
7358 /**
7359 * Apply a set of overrides that were previously captured.
7360 * @param overrides the overrides to be applied
7361 */
7362 void applyOverrides(Map<Element, Type2> overrides) {
7363 for (MapEntry<Element, Type2> entry in getMapEntrySet(overrides)) {
7364 _overridenTypes[entry.getKey()] = entry.getValue();
7365 }
7366 }
7367
7368 /**
7369 * Return a table mapping the elements whose type is overridden in the current scope to the
7370 * overriding type.
7371 * @return the overrides in the current scope
7372 */
7373 Map<Element, Type2> captureLocalOverrides() => _overridenTypes;
7374
7375 /**
7376 * Return a map from the elements for the variables in the given list that hav e their types
7377 * overridden to the overriding type.
7378 * @param variableList the list of variables whose overriding types are to be captured
7379 * @return a table mapping elements to their overriding types
7380 */
7381 Map<Element, Type2> captureOverrides(VariableDeclarationList variableList) {
7382 Map<Element, Type2> overrides = new Map<Element, Type2>();
7383 if (variableList.isConst() || variableList.isFinal()) {
7384 for (VariableDeclaration variable in variableList.variables) {
7385 Element element2 = variable.element;
7386 if (element2 != null) {
7387 Type2 type = _overridenTypes[element2];
7388 if (type != null) {
7389 overrides[element2] = type;
7390 }
7391 }
7392 }
7393 }
7394 return overrides;
7395 }
7396
5729 /** 7397 /**
5730 * Return the overridden type of the given element, or {@code null} if the typ e of the element 7398 * Return the overridden type of the given element, or {@code null} if the typ e of the element
5731 * has not been overridden. 7399 * has not been overridden.
5732 * @param element the element whose type might have been overridden 7400 * @param element the element whose type might have been overridden
5733 * @return the overridden type of the given element 7401 * @return the overridden type of the given element
5734 */ 7402 */
5735 Type2 getType(Element element) { 7403 Type2 getType(Element element) {
5736 Type2 type = _overridenTypes[element]; 7404 Type2 type = _overridenTypes[element];
5737 if (type == null && element is PropertyAccessorElement) { 7405 if (type == null && element is PropertyAccessorElement) {
5738 type = _overridenTypes[((element as PropertyAccessorElement)).variable]; 7406 type = _overridenTypes[((element as PropertyAccessorElement)).variable];
5739 } 7407 }
5740 if (type != null) { 7408 if (type != null) {
5741 return type; 7409 return type;
5742 } else if (_outerScope != null) { 7410 } else if (_outerScope != null) {
5743 return _outerScope.getType(element); 7411 return _outerScope.getType(element);
5744 } 7412 }
5745 return null; 7413 return null;
5746 } 7414 }
7415
5747 /** 7416 /**
5748 * Set the overridden type of the given element to the given type 7417 * Set the overridden type of the given element to the given type
5749 * @param element the element whose type might have been overridden 7418 * @param element the element whose type might have been overridden
5750 * @param type the overridden type of the given element 7419 * @param type the overridden type of the given element
5751 */ 7420 */
5752 void setType(Element element, Type2 type) { 7421 void setType(Element element, Type2 type) {
5753 _overridenTypes[element] = type; 7422 _overridenTypes[element] = type;
5754 } 7423 }
5755 } 7424 }
7425
5756 /** 7426 /**
5757 * The interface {@code TypeProvider} defines the behavior of objects that provi de access to types 7427 * The interface {@code TypeProvider} defines the behavior of objects that provi de access to types
5758 * defined by the language. 7428 * defined by the language.
5759 * @coverage dart.engine.resolver 7429 * @coverage dart.engine.resolver
5760 */ 7430 */
5761 abstract class TypeProvider { 7431 abstract class TypeProvider {
7432
5762 /** 7433 /**
5763 * Return the type representing the built-in type 'bool'. 7434 * Return the type representing the built-in type 'bool'.
5764 * @return the type representing the built-in type 'bool' 7435 * @return the type representing the built-in type 'bool'
5765 */ 7436 */
5766 InterfaceType get boolType; 7437 InterfaceType get boolType;
7438
5767 /** 7439 /**
5768 * Return the type representing the type 'bottom'. 7440 * Return the type representing the type 'bottom'.
5769 * @return the type representing the type 'bottom' 7441 * @return the type representing the type 'bottom'
5770 */ 7442 */
5771 Type2 get bottomType; 7443 Type2 get bottomType;
7444
5772 /** 7445 /**
5773 * Return the type representing the built-in type 'double'. 7446 * Return the type representing the built-in type 'double'.
5774 * @return the type representing the built-in type 'double' 7447 * @return the type representing the built-in type 'double'
5775 */ 7448 */
5776 InterfaceType get doubleType; 7449 InterfaceType get doubleType;
7450
5777 /** 7451 /**
5778 * Return the type representing the built-in type 'dynamic'. 7452 * Return the type representing the built-in type 'dynamic'.
5779 * @return the type representing the built-in type 'dynamic' 7453 * @return the type representing the built-in type 'dynamic'
5780 */ 7454 */
5781 Type2 get dynamicType; 7455 Type2 get dynamicType;
7456
5782 /** 7457 /**
5783 * Return the type representing the built-in type 'Function'. 7458 * Return the type representing the built-in type 'Function'.
5784 * @return the type representing the built-in type 'Function' 7459 * @return the type representing the built-in type 'Function'
5785 */ 7460 */
5786 InterfaceType get functionType; 7461 InterfaceType get functionType;
7462
5787 /** 7463 /**
5788 * Return the type representing the built-in type 'int'. 7464 * Return the type representing the built-in type 'int'.
5789 * @return the type representing the built-in type 'int' 7465 * @return the type representing the built-in type 'int'
5790 */ 7466 */
5791 InterfaceType get intType; 7467 InterfaceType get intType;
7468
5792 /** 7469 /**
5793 * Return the type representing the built-in type 'List'. 7470 * Return the type representing the built-in type 'List'.
5794 * @return the type representing the built-in type 'List' 7471 * @return the type representing the built-in type 'List'
5795 */ 7472 */
5796 InterfaceType get listType; 7473 InterfaceType get listType;
7474
5797 /** 7475 /**
5798 * Return the type representing the built-in type 'Map'. 7476 * Return the type representing the built-in type 'Map'.
5799 * @return the type representing the built-in type 'Map' 7477 * @return the type representing the built-in type 'Map'
5800 */ 7478 */
5801 InterfaceType get mapType; 7479 InterfaceType get mapType;
7480
5802 /** 7481 /**
5803 * Return the type representing the built-in type 'num'. 7482 * Return the type representing the built-in type 'num'.
5804 * @return the type representing the built-in type 'num' 7483 * @return the type representing the built-in type 'num'
5805 */ 7484 */
5806 InterfaceType get numType; 7485 InterfaceType get numType;
7486
5807 /** 7487 /**
5808 * Return the type representing the built-in type 'Object'. 7488 * Return the type representing the built-in type 'Object'.
5809 * @return the type representing the built-in type 'Object' 7489 * @return the type representing the built-in type 'Object'
5810 */ 7490 */
5811 InterfaceType get objectType; 7491 InterfaceType get objectType;
7492
5812 /** 7493 /**
5813 * Return the type representing the built-in type 'StackTrace'. 7494 * Return the type representing the built-in type 'StackTrace'.
5814 * @return the type representing the built-in type 'StackTrace' 7495 * @return the type representing the built-in type 'StackTrace'
5815 */ 7496 */
5816 InterfaceType get stackTraceType; 7497 InterfaceType get stackTraceType;
7498
5817 /** 7499 /**
5818 * Return the type representing the built-in type 'String'. 7500 * Return the type representing the built-in type 'String'.
5819 * @return the type representing the built-in type 'String' 7501 * @return the type representing the built-in type 'String'
5820 */ 7502 */
5821 InterfaceType get stringType; 7503 InterfaceType get stringType;
7504
5822 /** 7505 /**
5823 * Return the type representing the built-in type 'Type'. 7506 * Return the type representing the built-in type 'Type'.
5824 * @return the type representing the built-in type 'Type' 7507 * @return the type representing the built-in type 'Type'
5825 */ 7508 */
5826 InterfaceType get typeType; 7509 InterfaceType get typeType;
5827 } 7510 }
7511
5828 /** 7512 /**
5829 * Instances of the class {@code TypeProviderImpl} provide access to types defin ed by the language 7513 * Instances of the class {@code TypeProviderImpl} provide access to types defin ed by the language
5830 * by looking for those types in the element model for the core library. 7514 * by looking for those types in the element model for the core library.
5831 * @coverage dart.engine.resolver 7515 * @coverage dart.engine.resolver
5832 */ 7516 */
5833 class TypeProviderImpl implements TypeProvider { 7517 class TypeProviderImpl implements TypeProvider {
7518
5834 /** 7519 /**
5835 * The type representing the built-in type 'bool'. 7520 * The type representing the built-in type 'bool'.
5836 */ 7521 */
5837 InterfaceType _boolType; 7522 InterfaceType _boolType;
7523
5838 /** 7524 /**
5839 * The type representing the type 'bottom'. 7525 * The type representing the type 'bottom'.
5840 */ 7526 */
5841 Type2 _bottomType; 7527 Type2 _bottomType;
7528
5842 /** 7529 /**
5843 * The type representing the built-in type 'double'. 7530 * The type representing the built-in type 'double'.
5844 */ 7531 */
5845 InterfaceType _doubleType; 7532 InterfaceType _doubleType;
7533
5846 /** 7534 /**
5847 * The type representing the built-in type 'dynamic'. 7535 * The type representing the built-in type 'dynamic'.
5848 */ 7536 */
5849 Type2 _dynamicType; 7537 Type2 _dynamicType;
7538
5850 /** 7539 /**
5851 * The type representing the built-in type 'Function'. 7540 * The type representing the built-in type 'Function'.
5852 */ 7541 */
5853 InterfaceType _functionType; 7542 InterfaceType _functionType;
7543
5854 /** 7544 /**
5855 * The type representing the built-in type 'int'. 7545 * The type representing the built-in type 'int'.
5856 */ 7546 */
5857 InterfaceType _intType; 7547 InterfaceType _intType;
7548
5858 /** 7549 /**
5859 * The type representing the built-in type 'List'. 7550 * The type representing the built-in type 'List'.
5860 */ 7551 */
5861 InterfaceType _listType; 7552 InterfaceType _listType;
7553
5862 /** 7554 /**
5863 * The type representing the built-in type 'Map'. 7555 * The type representing the built-in type 'Map'.
5864 */ 7556 */
5865 InterfaceType _mapType; 7557 InterfaceType _mapType;
7558
5866 /** 7559 /**
5867 * The type representing the built-in type 'num'. 7560 * The type representing the built-in type 'num'.
5868 */ 7561 */
5869 InterfaceType _numType; 7562 InterfaceType _numType;
7563
5870 /** 7564 /**
5871 * The type representing the built-in type 'Object'. 7565 * The type representing the built-in type 'Object'.
5872 */ 7566 */
5873 InterfaceType _objectType; 7567 InterfaceType _objectType;
7568
5874 /** 7569 /**
5875 * The type representing the built-in type 'StackTrace'. 7570 * The type representing the built-in type 'StackTrace'.
5876 */ 7571 */
5877 InterfaceType _stackTraceType; 7572 InterfaceType _stackTraceType;
7573
5878 /** 7574 /**
5879 * The type representing the built-in type 'String'. 7575 * The type representing the built-in type 'String'.
5880 */ 7576 */
5881 InterfaceType _stringType; 7577 InterfaceType _stringType;
7578
5882 /** 7579 /**
5883 * The type representing the built-in type 'Type'. 7580 * The type representing the built-in type 'Type'.
5884 */ 7581 */
5885 InterfaceType _typeType; 7582 InterfaceType _typeType;
7583
5886 /** 7584 /**
5887 * Initialize a newly created type provider to provide the types defined in th e given library. 7585 * Initialize a newly created type provider to provide the types defined in th e given library.
5888 * @param coreLibrary the element representing the core library (dart:core). 7586 * @param coreLibrary the element representing the core library (dart:core).
5889 */ 7587 */
5890 TypeProviderImpl(LibraryElement coreLibrary) { 7588 TypeProviderImpl(LibraryElement coreLibrary) {
5891 initializeFrom(coreLibrary); 7589 initializeFrom(coreLibrary);
5892 } 7590 }
5893 InterfaceType get boolType => _boolType; 7591 InterfaceType get boolType => _boolType;
5894 Type2 get bottomType => _bottomType; 7592 Type2 get bottomType => _bottomType;
5895 InterfaceType get doubleType => _doubleType; 7593 InterfaceType get doubleType => _doubleType;
5896 Type2 get dynamicType => _dynamicType; 7594 Type2 get dynamicType => _dynamicType;
5897 InterfaceType get functionType => _functionType; 7595 InterfaceType get functionType => _functionType;
5898 InterfaceType get intType => _intType; 7596 InterfaceType get intType => _intType;
5899 InterfaceType get listType => _listType; 7597 InterfaceType get listType => _listType;
5900 InterfaceType get mapType => _mapType; 7598 InterfaceType get mapType => _mapType;
5901 InterfaceType get numType => _numType; 7599 InterfaceType get numType => _numType;
5902 InterfaceType get objectType => _objectType; 7600 InterfaceType get objectType => _objectType;
5903 InterfaceType get stackTraceType => _stackTraceType; 7601 InterfaceType get stackTraceType => _stackTraceType;
5904 InterfaceType get stringType => _stringType; 7602 InterfaceType get stringType => _stringType;
5905 InterfaceType get typeType => _typeType; 7603 InterfaceType get typeType => _typeType;
7604
5906 /** 7605 /**
5907 * Return the type with the given name from the given namespace, or {@code nul l} if there is no 7606 * Return the type with the given name from the given namespace, or {@code nul l} if there is no
5908 * class with the given name. 7607 * class with the given name.
5909 * @param namespace the namespace in which to search for the given name 7608 * @param namespace the namespace in which to search for the given name
5910 * @param typeName the name of the type being searched for 7609 * @param typeName the name of the type being searched for
5911 * @return the type that was found 7610 * @return the type that was found
5912 */ 7611 */
5913 InterfaceType getType(Namespace namespace, String typeName) { 7612 InterfaceType getType(Namespace namespace, String typeName) {
5914 Element element = namespace.get(typeName); 7613 Element element = namespace.get(typeName);
5915 if (element == null) { 7614 if (element == null) {
5916 AnalysisEngine.instance.logger.logInformation("No definition of type ${typ eName}"); 7615 AnalysisEngine.instance.logger.logInformation("No definition of type ${typ eName}");
5917 return null; 7616 return null;
5918 } 7617 }
5919 return ((element as ClassElement)).type; 7618 return ((element as ClassElement)).type;
5920 } 7619 }
7620
5921 /** 7621 /**
5922 * Initialize the types provided by this type provider from the given library. 7622 * Initialize the types provided by this type provider from the given library.
5923 * @param library the library containing the definitions of the core types 7623 * @param library the library containing the definitions of the core types
5924 */ 7624 */
5925 void initializeFrom(LibraryElement library) { 7625 void initializeFrom(LibraryElement library) {
5926 Namespace namespace = new NamespaceBuilder().createPublicNamespace(library); 7626 Namespace namespace = new NamespaceBuilder().createPublicNamespace(library);
5927 _boolType = getType(namespace, "bool"); 7627 _boolType = getType(namespace, "bool");
5928 _bottomType = BottomTypeImpl.instance; 7628 _bottomType = BottomTypeImpl.instance;
5929 _doubleType = getType(namespace, "double"); 7629 _doubleType = getType(namespace, "double");
5930 _dynamicType = DynamicTypeImpl.instance; 7630 _dynamicType = DynamicTypeImpl.instance;
5931 _functionType = getType(namespace, "Function"); 7631 _functionType = getType(namespace, "Function");
5932 _intType = getType(namespace, "int"); 7632 _intType = getType(namespace, "int");
5933 _listType = getType(namespace, "List"); 7633 _listType = getType(namespace, "List");
5934 _mapType = getType(namespace, "Map"); 7634 _mapType = getType(namespace, "Map");
5935 _numType = getType(namespace, "num"); 7635 _numType = getType(namespace, "num");
5936 _objectType = getType(namespace, "Object"); 7636 _objectType = getType(namespace, "Object");
5937 _stackTraceType = getType(namespace, "StackTrace"); 7637 _stackTraceType = getType(namespace, "StackTrace");
5938 _stringType = getType(namespace, "String"); 7638 _stringType = getType(namespace, "String");
5939 _typeType = getType(namespace, "Type"); 7639 _typeType = getType(namespace, "Type");
5940 } 7640 }
5941 } 7641 }
7642
5942 /** 7643 /**
5943 * Instances of the class {@code TypeResolverVisitor} are used to resolve the ty pes associated with 7644 * Instances of the class {@code TypeResolverVisitor} are used to resolve the ty pes associated with
5944 * the elements in the element model. This includes the types of superclasses, m ixins, interfaces, 7645 * the elements in the element model. This includes the types of superclasses, m ixins, interfaces,
5945 * fields, methods, parameters, and local variables. As a side-effect, this also finishes building 7646 * fields, methods, parameters, and local variables. As a side-effect, this also finishes building
5946 * the type hierarchy. 7647 * the type hierarchy.
5947 * @coverage dart.engine.resolver 7648 * @coverage dart.engine.resolver
5948 */ 7649 */
5949 class TypeResolverVisitor extends ScopedVisitor { 7650 class TypeResolverVisitor extends ScopedVisitor {
7651
5950 /** 7652 /**
5951 * The type representing the type 'dynamic'. 7653 * The type representing the type 'dynamic'.
5952 */ 7654 */
5953 Type2 _dynamicType; 7655 Type2 _dynamicType;
7656
7657 /**
7658 * The flag specifying if currently visited class references 'super' expressio n.
7659 */
7660 bool _hasReferenceToSuper = false;
7661
5954 /** 7662 /**
5955 * Initialize a newly created visitor to resolve the nodes in a compilation un it. 7663 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
5956 * @param library the library containing the compilation unit being resolved 7664 * @param library the library containing the compilation unit being resolved
5957 * @param source the source representing the compilation unit being visited 7665 * @param source the source representing the compilation unit being visited
5958 * @param typeProvider the object used to access the types from the core libra ry 7666 * @param typeProvider the object used to access the types from the core libra ry
5959 */ 7667 */
5960 TypeResolverVisitor.con1(Library library, Source source, TypeProvider typeProv ider) : super.con1(library, source, typeProvider) { 7668 TypeResolverVisitor.con1(Library library, Source source, TypeProvider typeProv ider) : super.con1(library, source, typeProvider) {
5961 _jtd_constructor_274_impl(library, source, typeProvider); 7669 _jtd_constructor_280_impl(library, source, typeProvider);
5962 } 7670 }
5963 _jtd_constructor_274_impl(Library library, Source source, TypeProvider typePro vider) { 7671 _jtd_constructor_280_impl(Library library, Source source, TypeProvider typePro vider) {
5964 _dynamicType = typeProvider.dynamicType; 7672 _dynamicType = typeProvider.dynamicType;
5965 } 7673 }
7674
5966 /** 7675 /**
5967 * Initialize a newly created visitor to resolve the nodes in a compilation un it. 7676 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
5968 * @param definingLibrary the element for the library containing the compilati on unit being 7677 * @param definingLibrary the element for the library containing the compilati on unit being
5969 * visited 7678 * visited
5970 * @param source the source representing the compilation unit being visited 7679 * @param source the source representing the compilation unit being visited
5971 * @param typeProvider the object used to access the types from the core libra ry 7680 * @param typeProvider the object used to access the types from the core libra ry
5972 * @param errorListener the error listener that will be informed of any errors that are found 7681 * @param errorListener the error listener that will be informed of any errors that are found
5973 * during resolution 7682 * during resolution
5974 */ 7683 */
5975 TypeResolverVisitor.con2(LibraryElement definingLibrary, Source source, TypePr ovider typeProvider, AnalysisErrorListener errorListener) : super.con2(definingL ibrary, source, typeProvider, errorListener) { 7684 TypeResolverVisitor.con2(LibraryElement definingLibrary, Source source, TypePr ovider typeProvider, AnalysisErrorListener errorListener) : super.con2(definingL ibrary, source, typeProvider, errorListener) {
5976 _jtd_constructor_275_impl(definingLibrary, source, typeProvider, errorListen er); 7685 _jtd_constructor_281_impl(definingLibrary, source, typeProvider, errorListen er);
5977 } 7686 }
5978 _jtd_constructor_275_impl(LibraryElement definingLibrary, Source source, TypeP rovider typeProvider, AnalysisErrorListener errorListener) { 7687 _jtd_constructor_281_impl(LibraryElement definingLibrary, Source source, TypeP rovider typeProvider, AnalysisErrorListener errorListener) {
5979 _dynamicType = typeProvider.dynamicType; 7688 _dynamicType = typeProvider.dynamicType;
5980 } 7689 }
5981 Object visitCatchClause(CatchClause node) { 7690 Object visitCatchClause(CatchClause node) {
5982 super.visitCatchClause(node); 7691 super.visitCatchClause(node);
5983 SimpleIdentifier exception = node.exceptionParameter; 7692 SimpleIdentifier exception = node.exceptionParameter;
5984 if (exception != null) { 7693 if (exception != null) {
5985 TypeName exceptionTypeName = node.exceptionType; 7694 TypeName exceptionTypeName = node.exceptionType;
5986 Type2 exceptionType; 7695 Type2 exceptionType;
5987 if (exceptionTypeName == null) { 7696 if (exceptionTypeName == null) {
5988 exceptionType = typeProvider.objectType; 7697 exceptionType = typeProvider.objectType;
5989 } else { 7698 } else {
5990 exceptionType = getType5(exceptionTypeName); 7699 exceptionType = getType3(exceptionTypeName);
5991 } 7700 }
5992 recordType(exception, exceptionType); 7701 recordType(exception, exceptionType);
5993 Element element2 = exception.element; 7702 Element element2 = exception.element;
5994 if (element2 is VariableElementImpl) { 7703 if (element2 is VariableElementImpl) {
5995 ((element2 as VariableElementImpl)).type = exceptionType; 7704 ((element2 as VariableElementImpl)).type = exceptionType;
5996 } else { 7705 } else {
5997 } 7706 }
5998 } 7707 }
5999 SimpleIdentifier stackTrace = node.stackTraceParameter; 7708 SimpleIdentifier stackTrace = node.stackTraceParameter;
6000 if (stackTrace != null) { 7709 if (stackTrace != null) {
6001 recordType(stackTrace, typeProvider.stackTraceType); 7710 recordType(stackTrace, typeProvider.stackTraceType);
6002 } 7711 }
6003 return null; 7712 return null;
6004 } 7713 }
6005 Object visitClassDeclaration(ClassDeclaration node) { 7714 Object visitClassDeclaration(ClassDeclaration node) {
7715 _hasReferenceToSuper = false;
6006 super.visitClassDeclaration(node); 7716 super.visitClassDeclaration(node);
6007 ClassElementImpl classElement = getClassElement(node.name); 7717 ClassElementImpl classElement = getClassElement(node.name);
6008 InterfaceType superclassType = null; 7718 InterfaceType superclassType = null;
6009 ExtendsClause extendsClause2 = node.extendsClause; 7719 ExtendsClause extendsClause2 = node.extendsClause;
6010 if (extendsClause2 != null) { 7720 if (extendsClause2 != null) {
6011 superclassType = resolveType(extendsClause2.superclass, CompileTimeErrorCo de.EXTENDS_NON_CLASS); 7721 ErrorCode errorCode = node.withClause == null ? CompileTimeErrorCode.EXTEN DS_NON_CLASS : CompileTimeErrorCode.MIXIN_WITH_NON_CLASS_SUPERCLASS;
7722 superclassType = resolveType(extendsClause2.superclass, errorCode);
6012 if (superclassType != typeProvider.objectType) { 7723 if (superclassType != typeProvider.objectType) {
6013 classElement.validMixin = false; 7724 classElement.validMixin = false;
6014 } 7725 }
6015 } 7726 }
6016 if (classElement != null) { 7727 if (classElement != null) {
6017 if (superclassType == null) { 7728 if (superclassType == null) {
6018 InterfaceType objectType2 = typeProvider.objectType; 7729 InterfaceType objectType2 = typeProvider.objectType;
6019 if (classElement.type != objectType2) { 7730 if (classElement.type != objectType2) {
6020 superclassType = objectType2; 7731 superclassType = objectType2;
6021 } 7732 }
6022 } 7733 }
6023 classElement.supertype = superclassType; 7734 classElement.supertype = superclassType;
7735 classElement.hasReferenceToSuper2 = _hasReferenceToSuper;
6024 } 7736 }
6025 resolve(classElement, node.withClause, node.implementsClause); 7737 resolve(classElement, node.withClause, node.implementsClause);
6026 return null; 7738 return null;
6027 } 7739 }
6028 Object visitClassTypeAlias(ClassTypeAlias node) { 7740 Object visitClassTypeAlias(ClassTypeAlias node) {
6029 super.visitClassTypeAlias(node); 7741 super.visitClassTypeAlias(node);
6030 ClassElementImpl classElement = getClassElement(node.name); 7742 ClassElementImpl classElement = getClassElement(node.name);
6031 InterfaceType superclassType = resolveType(node.superclass, CompileTimeError Code.EXTENDS_NON_CLASS); 7743 InterfaceType superclassType = resolveType(node.superclass, CompileTimeError Code.MIXIN_WITH_NON_CLASS_SUPERCLASS);
6032 if (superclassType == null) { 7744 if (superclassType == null) {
6033 superclassType = typeProvider.objectType; 7745 superclassType = typeProvider.objectType;
6034 } 7746 }
6035 if (classElement != null && superclassType != null) { 7747 if (classElement != null && superclassType != null) {
6036 classElement.supertype = superclassType; 7748 classElement.supertype = superclassType;
6037 } 7749 }
6038 resolve(classElement, node.withClause, node.implementsClause); 7750 resolve(classElement, node.withClause, node.implementsClause);
6039 return null; 7751 return null;
6040 } 7752 }
6041 Object visitConstructorDeclaration(ConstructorDeclaration node) { 7753 Object visitConstructorDeclaration(ConstructorDeclaration node) {
6042 super.visitConstructorDeclaration(node); 7754 super.visitConstructorDeclaration(node);
6043 ExecutableElementImpl element2 = node.element as ExecutableElementImpl; 7755 ExecutableElementImpl element2 = node.element as ExecutableElementImpl;
6044 FunctionTypeImpl type = new FunctionTypeImpl.con1(element2); 7756 FunctionTypeImpl type = new FunctionTypeImpl.con1(element2);
6045 setTypeInformation(type, null, element2.parameters); 7757 setTypeInformation(type, null, element2.parameters);
6046 type.returnType = ((element2.enclosingElement as ClassElement)).type; 7758 type.returnType = ((element2.enclosingElement as ClassElement)).type;
6047 element2.type = type; 7759 element2.type = type;
6048 return null; 7760 return null;
6049 } 7761 }
6050 Object visitDeclaredIdentifier(DeclaredIdentifier node) { 7762 Object visitDeclaredIdentifier(DeclaredIdentifier node) {
6051 super.visitDeclaredIdentifier(node); 7763 super.visitDeclaredIdentifier(node);
6052 Type2 declaredType; 7764 Type2 declaredType;
6053 TypeName typeName = node.type; 7765 TypeName typeName = node.type;
6054 if (typeName == null) { 7766 if (typeName == null) {
6055 declaredType = _dynamicType; 7767 declaredType = _dynamicType;
6056 } else { 7768 } else {
6057 declaredType = getType5(typeName); 7769 declaredType = getType3(typeName);
6058 } 7770 }
6059 LocalVariableElementImpl element2 = node.element as LocalVariableElementImpl ; 7771 LocalVariableElementImpl element2 = node.element as LocalVariableElementImpl ;
6060 element2.type = declaredType; 7772 element2.type = declaredType;
6061 return null; 7773 return null;
6062 } 7774 }
6063 Object visitDefaultFormalParameter(DefaultFormalParameter node) { 7775 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
6064 super.visitDefaultFormalParameter(node); 7776 super.visitDefaultFormalParameter(node);
6065 return null; 7777 return null;
6066 } 7778 }
6067 Object visitFieldFormalParameter(FieldFormalParameter node) { 7779 Object visitFieldFormalParameter(FieldFormalParameter node) {
6068 super.visitFieldFormalParameter(node); 7780 super.visitFieldFormalParameter(node);
6069 Element element2 = node.identifier.element; 7781 Element element2 = node.identifier.element;
6070 if (element2 is ParameterElementImpl) { 7782 if (element2 is ParameterElementImpl) {
6071 ParameterElementImpl parameter = element2 as ParameterElementImpl; 7783 ParameterElementImpl parameter = element2 as ParameterElementImpl;
6072 Type2 type; 7784 Type2 type;
6073 TypeName typeName = node.type; 7785 TypeName typeName = node.type;
6074 if (typeName == null) { 7786 if (typeName == null) {
6075 type = _dynamicType; 7787 type = _dynamicType;
6076 } else { 7788 } else {
6077 type = getType5(typeName); 7789 type = getType3(typeName);
6078 } 7790 }
6079 parameter.type = type; 7791 parameter.type = type;
6080 } else { 7792 } else {
6081 } 7793 }
6082 return null; 7794 return null;
6083 } 7795 }
6084 Object visitFunctionDeclaration(FunctionDeclaration node) { 7796 Object visitFunctionDeclaration(FunctionDeclaration node) {
6085 super.visitFunctionDeclaration(node); 7797 super.visitFunctionDeclaration(node);
6086 ExecutableElementImpl element2 = node.element as ExecutableElementImpl; 7798 ExecutableElementImpl element2 = node.element as ExecutableElementImpl;
6087 FunctionTypeImpl type = new FunctionTypeImpl.con1(element2); 7799 FunctionTypeImpl type = new FunctionTypeImpl.con1(element2);
6088 setTypeInformation(type, node.returnType, element2.parameters); 7800 setTypeInformation(type, node.returnType, element2.parameters);
6089 element2.type = type; 7801 element2.type = type;
6090 return null; 7802 return null;
6091 } 7803 }
6092 Object visitFunctionTypeAlias(FunctionTypeAlias node) { 7804 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
6093 super.visitFunctionTypeAlias(node); 7805 super.visitFunctionTypeAlias(node);
6094 FunctionTypeAliasElementImpl element2 = node.element as FunctionTypeAliasEle mentImpl; 7806 FunctionTypeAliasElementImpl element2 = node.element as FunctionTypeAliasEle mentImpl;
6095 FunctionTypeImpl type2 = element2.type as FunctionTypeImpl; 7807 FunctionTypeImpl type2 = element2.type as FunctionTypeImpl;
6096 setTypeInformation(type2, node.returnType, element2.parameters); 7808 setTypeInformation(type2, node.returnType, element2.parameters);
6097 return null; 7809 return null;
6098 } 7810 }
6099 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { 7811 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
6100 super.visitFunctionTypedFormalParameter(node); 7812 super.visitFunctionTypedFormalParameter(node);
6101 ParameterElementImpl element2 = node.identifier.element as ParameterElementI mpl; 7813 ParameterElementImpl element2 = node.identifier.element as ParameterElementI mpl;
6102 FunctionTypeImpl type = new FunctionTypeImpl.con1((null as ExecutableElement )); 7814 AnonymousFunctionTypeImpl type = new AnonymousFunctionTypeImpl();
6103 setTypeInformation(type, node.returnType, getElements(node.parameters)); 7815 List<ParameterElement> parameters2 = getElements(node.parameters);
7816 setTypeInformation(type, node.returnType, parameters2);
7817 type.baseParameters = parameters2;
6104 element2.type = type; 7818 element2.type = type;
6105 return null; 7819 return null;
6106 } 7820 }
6107 Object visitMethodDeclaration(MethodDeclaration node) { 7821 Object visitMethodDeclaration(MethodDeclaration node) {
6108 super.visitMethodDeclaration(node); 7822 super.visitMethodDeclaration(node);
6109 ExecutableElementImpl element2 = node.element as ExecutableElementImpl; 7823 ExecutableElementImpl element2 = node.element as ExecutableElementImpl;
6110 FunctionTypeImpl type = new FunctionTypeImpl.con1(element2); 7824 FunctionTypeImpl type = new FunctionTypeImpl.con1(element2);
6111 setTypeInformation(type, node.returnType, element2.parameters); 7825 setTypeInformation(type, node.returnType, element2.parameters);
6112 element2.type = type; 7826 element2.type = type;
6113 if (element2 is PropertyAccessorElement) { 7827 if (element2 is PropertyAccessorElement) {
(...skipping 10 matching lines...) Expand all
6124 } 7838 }
6125 return null; 7839 return null;
6126 } 7840 }
6127 Object visitSimpleFormalParameter(SimpleFormalParameter node) { 7841 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
6128 super.visitSimpleFormalParameter(node); 7842 super.visitSimpleFormalParameter(node);
6129 Type2 declaredType; 7843 Type2 declaredType;
6130 TypeName typeName = node.type; 7844 TypeName typeName = node.type;
6131 if (typeName == null) { 7845 if (typeName == null) {
6132 declaredType = _dynamicType; 7846 declaredType = _dynamicType;
6133 } else { 7847 } else {
6134 declaredType = getType5(typeName); 7848 declaredType = getType3(typeName);
6135 } 7849 }
6136 Element element2 = node.identifier.element; 7850 Element element2 = node.identifier.element;
6137 if (element2 is ParameterElement) { 7851 if (element2 is ParameterElement) {
6138 ((element2 as ParameterElementImpl)).type = declaredType; 7852 ((element2 as ParameterElementImpl)).type = declaredType;
6139 } else { 7853 } else {
6140 } 7854 }
6141 return null; 7855 return null;
6142 } 7856 }
7857 Object visitSuperExpression(SuperExpression node) {
7858 _hasReferenceToSuper = true;
7859 return super.visitSuperExpression(node);
7860 }
6143 Object visitTypeName(TypeName node) { 7861 Object visitTypeName(TypeName node) {
6144 super.visitTypeName(node); 7862 super.visitTypeName(node);
6145 Identifier typeName = node.name; 7863 Identifier typeName = node.name;
6146 TypeArgumentList argumentList = node.typeArguments; 7864 TypeArgumentList argumentList = node.typeArguments;
6147 Element element = nameScope.lookup(typeName, definingLibrary); 7865 Element element = nameScope.lookup(typeName, definingLibrary);
6148 if (element == null) { 7866 if (element == null) {
6149 if (typeName.name == _dynamicType.name) { 7867 if (typeName.name == _dynamicType.name) {
6150 setElement(typeName, _dynamicType.element); 7868 setElement(typeName, _dynamicType.element);
6151 if (argumentList != null) { 7869 if (argumentList != null) {
6152 } 7870 }
(...skipping 19 matching lines...) Expand all
6172 return null; 7890 return null;
6173 } else if (element != null) { 7891 } else if (element != null) {
6174 name.name = ((typeName as PrefixedIdentifier)).identifier; 7892 name.name = ((typeName as PrefixedIdentifier)).identifier;
6175 name.period = ((typeName as PrefixedIdentifier)).period; 7893 name.period = ((typeName as PrefixedIdentifier)).period;
6176 node.name = prefix2; 7894 node.name = prefix2;
6177 typeName = prefix2; 7895 typeName = prefix2;
6178 } 7896 }
6179 } 7897 }
6180 } 7898 }
6181 } 7899 }
6182 if (element == null) { 7900 bool elementValid = element is! MultiplyDefinedElement;
6183 Identifier simpleIdentifier; 7901 if (elementValid && element is! ClassElement && isTypeNameInInstanceCreation Expression(node)) {
6184 if (typeName is SimpleIdentifier) { 7902 SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName);
6185 simpleIdentifier = typeName; 7903 InstanceCreationExpression creation = node.parent.parent as InstanceCreati onExpression;
7904 if (creation.isConst()) {
7905 if (element == null) {
7906 reportError(CompileTimeErrorCode.UNDEFINED_CLASS, typeNameSimple, [typ eName]);
7907 } else {
7908 reportError(CompileTimeErrorCode.CONST_WITH_NON_TYPE, typeNameSimple, [typeName]);
7909 }
7910 elementValid = false;
6186 } else { 7911 } else {
6187 simpleIdentifier = ((typeName as PrefixedIdentifier)).prefix; 7912 if (element != null) {
7913 reportError(StaticWarningCode.NEW_WITH_NON_TYPE, typeNameSimple, [type Name]);
7914 elementValid = false;
7915 }
6188 } 7916 }
6189 if (simpleIdentifier.name == "boolean") { 7917 }
6190 reportError(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, simpleIdentifier, []); 7918 if (elementValid && element == null) {
7919 SimpleIdentifier typeNameSimple = getTypeSimpleIdentifier(typeName);
7920 if (typeNameSimple.name == "boolean") {
7921 reportError(StaticWarningCode.UNDEFINED_CLASS_BOOLEAN, typeNameSimple, [ ]);
7922 } else if (isTypeNameInCatchClause(node)) {
7923 reportError(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, node, [node]);
6191 } else { 7924 } else {
6192 reportError(StaticWarningCode.UNDEFINED_CLASS, simpleIdentifier, [simple Identifier.name]); 7925 reportError(StaticWarningCode.UNDEFINED_CLASS, typeNameSimple, [typeName Simple.name]);
6193 } 7926 }
7927 elementValid = false;
7928 }
7929 if (!elementValid) {
6194 setElement(typeName, _dynamicType.element); 7930 setElement(typeName, _dynamicType.element);
6195 typeName.staticType = _dynamicType; 7931 typeName.staticType = _dynamicType;
6196 node.type = _dynamicType; 7932 node.type = _dynamicType;
6197 return null; 7933 return null;
6198 } 7934 }
6199 Type2 type = null; 7935 Type2 type = null;
6200 if (element is ClassElement) { 7936 if (element is ClassElement) {
6201 setElement(typeName, element); 7937 setElement(typeName, element);
6202 type = ((element as ClassElement)).type; 7938 type = ((element as ClassElement)).type;
6203 } else if (element is FunctionTypeAliasElement) { 7939 } else if (element is FunctionTypeAliasElement) {
6204 setElement(typeName, element); 7940 setElement(typeName, element);
6205 type = ((element as FunctionTypeAliasElement)).type; 7941 type = ((element as FunctionTypeAliasElement)).type;
6206 } else if (element is TypeVariableElement) { 7942 } else if (element is TypeVariableElement) {
6207 setElement(typeName, element); 7943 setElement(typeName, element);
6208 type = ((element as TypeVariableElement)).type; 7944 type = ((element as TypeVariableElement)).type;
6209 if (argumentList != null) { 7945 if (argumentList != null) {
6210 } 7946 }
6211 } else if (element is MultiplyDefinedElement) { 7947 } else if (element is MultiplyDefinedElement) {
6212 List<Element> elements = ((element as MultiplyDefinedElement)).conflicting Elements; 7948 List<Element> elements = ((element as MultiplyDefinedElement)).conflicting Elements;
6213 type = getType(elements); 7949 type = getType(elements);
6214 if (type != null) { 7950 if (type != null) {
6215 node.type = type; 7951 node.type = type;
6216 } 7952 }
6217 } else { 7953 } else {
7954 if (isTypeNameInCatchClause(node)) {
7955 reportError(StaticWarningCode.NON_TYPE_IN_CATCH_CLAUSE, node, [node]);
7956 }
6218 setElement(typeName, _dynamicType.element); 7957 setElement(typeName, _dynamicType.element);
6219 typeName.staticType = _dynamicType; 7958 typeName.staticType = _dynamicType;
6220 node.type = _dynamicType; 7959 node.type = _dynamicType;
6221 return null; 7960 return null;
6222 } 7961 }
6223 if (argumentList != null) { 7962 if (argumentList != null) {
6224 NodeList<TypeName> arguments2 = argumentList.arguments; 7963 NodeList<TypeName> arguments2 = argumentList.arguments;
6225 int argumentCount = arguments2.length; 7964 int argumentCount = arguments2.length;
6226 List<Type2> parameters = getTypeArguments(type); 7965 List<Type2> parameters = getTypeArguments(type);
6227 int parameterCount = parameters.length; 7966 int parameterCount = parameters.length;
6228 int count = Math.min(argumentCount, parameterCount); 7967 int count = Math.min(argumentCount, parameterCount);
6229 List<Type2> typeArguments = new List<Type2>(); 7968 List<Type2> typeArguments = new List<Type2>();
6230 for (int i = 0; i < count; i++) { 7969 for (int i = 0; i < count; i++) {
6231 Type2 argumentType = getType5(arguments2[i]); 7970 Type2 argumentType = getType3(arguments2[i]);
6232 if (argumentType != null) { 7971 if (argumentType != null) {
6233 typeArguments.add(argumentType); 7972 typeArguments.add(argumentType);
6234 } 7973 }
6235 } 7974 }
6236 if (argumentCount != parameterCount) { 7975 if (argumentCount != parameterCount) {
6237 reportError(getInvalidTypeParametersErrorCode(node), node, [typeName.nam e, parameterCount, argumentCount]); 7976 reportError(getInvalidTypeParametersErrorCode(node), node, [typeName.nam e, parameterCount, argumentCount]);
6238 } 7977 }
6239 argumentCount = typeArguments.length; 7978 argumentCount = typeArguments.length;
6240 if (argumentCount < parameterCount) { 7979 if (argumentCount < parameterCount) {
6241 for (int i = argumentCount; i < parameterCount; i++) { 7980 for (int i = argumentCount; i < parameterCount; i++) {
(...skipping 24 matching lines...) Expand all
6266 node.type = type; 8005 node.type = type;
6267 return null; 8006 return null;
6268 } 8007 }
6269 Object visitVariableDeclaration(VariableDeclaration node) { 8008 Object visitVariableDeclaration(VariableDeclaration node) {
6270 super.visitVariableDeclaration(node); 8009 super.visitVariableDeclaration(node);
6271 Type2 declaredType; 8010 Type2 declaredType;
6272 TypeName typeName = ((node.parent as VariableDeclarationList)).type; 8011 TypeName typeName = ((node.parent as VariableDeclarationList)).type;
6273 if (typeName == null) { 8012 if (typeName == null) {
6274 declaredType = _dynamicType; 8013 declaredType = _dynamicType;
6275 } else { 8014 } else {
6276 declaredType = getType5(typeName); 8015 declaredType = getType3(typeName);
6277 } 8016 }
6278 Element element2 = node.name.element; 8017 Element element2 = node.name.element;
6279 if (element2 is VariableElement) { 8018 if (element2 is VariableElement) {
6280 ((element2 as VariableElementImpl)).type = declaredType; 8019 ((element2 as VariableElementImpl)).type = declaredType;
6281 if (element2 is PropertyInducingElement) { 8020 if (element2 is PropertyInducingElement) {
6282 PropertyInducingElement variableElement = element2 as PropertyInducingEl ement; 8021 PropertyInducingElement variableElement = element2 as PropertyInducingEl ement;
6283 PropertyAccessorElementImpl getter2 = variableElement.getter as Property AccessorElementImpl; 8022 PropertyAccessorElementImpl getter2 = variableElement.getter as Property AccessorElementImpl;
6284 FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter2); 8023 FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter2);
6285 getterType.returnType = declaredType; 8024 getterType.returnType = declaredType;
6286 getter2.type = getterType; 8025 getter2.type = getterType;
6287 PropertyAccessorElementImpl setter2 = variableElement.setter as Property AccessorElementImpl; 8026 PropertyAccessorElementImpl setter2 = variableElement.setter as Property AccessorElementImpl;
6288 if (setter2 != null) { 8027 if (setter2 != null) {
6289 FunctionTypeImpl setterType = new FunctionTypeImpl.con1(setter2); 8028 FunctionTypeImpl setterType = new FunctionTypeImpl.con1(setter2);
6290 setterType.returnType = VoidTypeImpl.instance; 8029 setterType.returnType = VoidTypeImpl.instance;
6291 setterType.normalParameterTypes = <Type2> [declaredType]; 8030 setterType.normalParameterTypes = <Type2> [declaredType];
6292 setter2.type = setterType; 8031 setter2.type = setterType;
6293 } 8032 }
6294 } 8033 }
6295 } else { 8034 } else {
6296 } 8035 }
6297 return null; 8036 return null;
6298 } 8037 }
8038
6299 /** 8039 /**
6300 * Return the class element that represents the class whose name was provided. 8040 * Return the class element that represents the class whose name was provided.
6301 * @param identifier the name from the declaration of a class 8041 * @param identifier the name from the declaration of a class
6302 * @return the class element that represents the class 8042 * @return the class element that represents the class
6303 */ 8043 */
6304 ClassElementImpl getClassElement(SimpleIdentifier identifier) { 8044 ClassElementImpl getClassElement(SimpleIdentifier identifier) {
6305 if (identifier == null) { 8045 if (identifier == null) {
6306 return null; 8046 return null;
6307 } 8047 }
6308 Element element2 = identifier.element; 8048 Element element2 = identifier.element;
6309 if (element2 is! ClassElementImpl) { 8049 if (element2 is! ClassElementImpl) {
6310 return null; 8050 return null;
6311 } 8051 }
6312 return element2 as ClassElementImpl; 8052 return element2 as ClassElementImpl;
6313 } 8053 }
8054
6314 /** 8055 /**
6315 * Return an array containing all of the elements associated with the paramete rs in the given 8056 * Return an array containing all of the elements associated with the paramete rs in the given
6316 * list. 8057 * list.
6317 * @param parameterList the list of parameters whose elements are to be return ed 8058 * @param parameterList the list of parameters whose elements are to be return ed
6318 * @return the elements associated with the parameters 8059 * @return the elements associated with the parameters
6319 */ 8060 */
6320 List<ParameterElement> getElements(FormalParameterList parameterList) { 8061 List<ParameterElement> getElements(FormalParameterList parameterList) {
6321 List<ParameterElement> elements = new List<ParameterElement>(); 8062 List<ParameterElement> elements = new List<ParameterElement>();
6322 for (FormalParameter parameter in parameterList.parameters) { 8063 for (FormalParameter parameter in parameterList.parameters) {
6323 ParameterElement element2 = parameter.identifier.element as ParameterEleme nt; 8064 ParameterElement element2 = parameter.identifier.element as ParameterEleme nt;
6324 if (element2 != null) { 8065 if (element2 != null) {
6325 elements.add(element2); 8066 elements.add(element2);
6326 } 8067 }
6327 } 8068 }
6328 return new List.from(elements); 8069 return new List.from(elements);
6329 } 8070 }
8071
6330 /** 8072 /**
6331 * The number of type arguments in the given type name does not match the numb er of parameters in 8073 * The number of type arguments in the given type name does not match the numb er of parameters in
6332 * the corresponding class element. Return the error code that should be used to report this 8074 * the corresponding class element. Return the error code that should be used to report this
6333 * error. 8075 * error.
6334 * @param node the type name with the wrong number of type arguments 8076 * @param node the type name with the wrong number of type arguments
6335 * @return the error code that should be used to report that the wrong number of type arguments 8077 * @return the error code that should be used to report that the wrong number of type arguments
6336 * were provided 8078 * were provided
6337 */ 8079 */
6338 ErrorCode getInvalidTypeParametersErrorCode(TypeName node) { 8080 ErrorCode getInvalidTypeParametersErrorCode(TypeName node) {
6339 ASTNode parent2 = node.parent; 8081 ASTNode parent2 = node.parent;
6340 if (parent2 is ConstructorName) { 8082 if (parent2 is ConstructorName) {
6341 parent2 = parent2.parent; 8083 parent2 = parent2.parent;
6342 if (parent2 is InstanceCreationExpression) { 8084 if (parent2 is InstanceCreationExpression) {
6343 if (((parent2 as InstanceCreationExpression)).isConst()) { 8085 if (((parent2 as InstanceCreationExpression)).isConst()) {
6344 return CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS; 8086 return CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS;
6345 } else { 8087 } else {
6346 return CompileTimeErrorCode.NEW_WITH_INVALID_TYPE_PARAMETERS; 8088 return CompileTimeErrorCode.NEW_WITH_INVALID_TYPE_PARAMETERS;
6347 } 8089 }
6348 } 8090 }
6349 } 8091 }
6350 return StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS; 8092 return StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS;
6351 } 8093 }
8094
6352 /** 8095 /**
6353 * Given the multiple elements to which a single name could potentially be res olved, return the 8096 * Given the multiple elements to which a single name could potentially be res olved, return the
6354 * single interface type that should be used, or {@code null} if there is no c lear choice. 8097 * single interface type that should be used, or {@code null} if there is no c lear choice.
6355 * @param elements the elements to which a single name could potentially be re solved 8098 * @param elements the elements to which a single name could potentially be re solved
6356 * @return the single interface type that should be used for the type name 8099 * @return the single interface type that should be used for the type name
6357 */ 8100 */
6358 InterfaceType getType(List<Element> elements) { 8101 InterfaceType getType(List<Element> elements) {
6359 InterfaceType type = null; 8102 InterfaceType type = null;
6360 for (Element element in elements) { 8103 for (Element element in elements) {
6361 if (element is ClassElement) { 8104 if (element is ClassElement) {
6362 if (type != null) { 8105 if (type != null) {
6363 return null; 8106 return null;
6364 } 8107 }
6365 type = ((element as ClassElement)).type; 8108 type = ((element as ClassElement)).type;
6366 } 8109 }
6367 } 8110 }
6368 return type; 8111 return type;
6369 } 8112 }
8113
6370 /** 8114 /**
6371 * Return the type represented by the given type name. 8115 * Return the type represented by the given type name.
6372 * @param typeName the type name representing the type to be returned 8116 * @param typeName the type name representing the type to be returned
6373 * @return the type represented by the type name 8117 * @return the type represented by the type name
6374 */ 8118 */
6375 Type2 getType5(TypeName typeName) { 8119 Type2 getType3(TypeName typeName) {
6376 Type2 type2 = typeName.type; 8120 Type2 type2 = typeName.type;
6377 if (type2 == null) { 8121 if (type2 == null) {
6378 return _dynamicType; 8122 return _dynamicType;
6379 } 8123 }
6380 return type2; 8124 return type2;
6381 } 8125 }
8126
6382 /** 8127 /**
6383 * Return the type arguments associated with the given type. 8128 * Return the type arguments associated with the given type.
6384 * @param type the type whole type arguments are to be returned 8129 * @param type the type whole type arguments are to be returned
6385 * @return the type arguments associated with the given type 8130 * @return the type arguments associated with the given type
6386 */ 8131 */
6387 List<Type2> getTypeArguments(Type2 type) { 8132 List<Type2> getTypeArguments(Type2 type) {
6388 if (type is InterfaceType) { 8133 if (type is InterfaceType) {
6389 return ((type as InterfaceType)).typeArguments; 8134 return ((type as InterfaceType)).typeArguments;
6390 } else if (type is FunctionType) { 8135 } else if (type is FunctionType) {
6391 return ((type as FunctionType)).typeArguments; 8136 return ((type as FunctionType)).typeArguments;
6392 } 8137 }
6393 return TypeImpl.EMPTY_ARRAY; 8138 return TypeImpl.EMPTY_ARRAY;
6394 } 8139 }
8140
8141 /**
8142 * Returns the simple identifier of the given (may be qualified) type name.
8143 * @param typeName the (may be qualified) qualified type name
8144 * @return the simple identifier of the given (may be qualified) type name.
8145 */
8146 SimpleIdentifier getTypeSimpleIdentifier(Identifier typeName) {
8147 if (typeName is SimpleIdentifier) {
8148 return typeName as SimpleIdentifier;
8149 } else {
8150 return ((typeName as PrefixedIdentifier)).identifier;
8151 }
8152 }
8153
8154 /**
8155 * Checks if the given type name is used as the exception type in the catch cl ause.
8156 * @param typeName the type name to analyzer
8157 * @return {@code true} if the given type name is used as the exception type i n the catch clause.
8158 */
8159 bool isTypeNameInCatchClause(TypeName typeName) {
8160 ASTNode parent2 = typeName.parent;
8161 if (parent2 is CatchClause) {
8162 CatchClause catchClause = parent2 as CatchClause;
8163 return identical(catchClause.exceptionType, typeName);
8164 }
8165 return false;
8166 }
8167
8168 /**
8169 * Checks if the given type name is used as the type in the instance creation expression.
8170 * @param typeName the type name to analyzer
8171 * @return {@code true} if the given type name is used as the type in the inst ance creation
8172 * expression
8173 */
8174 bool isTypeNameInInstanceCreationExpression(TypeName typeName) {
8175 ASTNode parent2 = typeName.parent;
8176 if (parent2 is ConstructorName && parent2.parent is InstanceCreationExpressi on) {
8177 ConstructorName constructorName = parent2 as ConstructorName;
8178 return constructorName != null && identical(constructorName.type, typeName );
8179 }
8180 return false;
8181 }
8182
6395 /** 8183 /**
6396 * Record that the static type of the given node is the given type. 8184 * Record that the static type of the given node is the given type.
6397 * @param expression the node whose type is to be recorded 8185 * @param expression the node whose type is to be recorded
6398 * @param type the static type of the node 8186 * @param type the static type of the node
6399 */ 8187 */
6400 Object recordType(Expression expression, Type2 type) { 8188 Object recordType(Expression expression, Type2 type) {
6401 if (type == null) { 8189 if (type == null) {
6402 expression.staticType = _dynamicType; 8190 expression.staticType = _dynamicType;
6403 } else { 8191 } else {
6404 expression.staticType = type; 8192 expression.staticType = type;
6405 } 8193 }
6406 return null; 8194 return null;
6407 } 8195 }
8196
6408 /** 8197 /**
6409 * Resolve the types in the given with and implements clauses and associate th ose types with the 8198 * Resolve the types in the given with and implements clauses and associate th ose types with the
6410 * given class element. 8199 * given class element.
6411 * @param classElement the class element with which the mixin and interface ty pes are to be 8200 * @param classElement the class element with which the mixin and interface ty pes are to be
6412 * associated 8201 * associated
6413 * @param withClause the with clause to be resolved 8202 * @param withClause the with clause to be resolved
6414 * @param implementsClause the implements clause to be resolved 8203 * @param implementsClause the implements clause to be resolved
6415 */ 8204 */
6416 void resolve(ClassElementImpl classElement, WithClause withClause, ImplementsC lause implementsClause) { 8205 void resolve(ClassElementImpl classElement, WithClause withClause, ImplementsC lause implementsClause) {
6417 if (withClause != null) { 8206 if (withClause != null) {
6418 List<InterfaceType> mixinTypes2 = resolveTypes(withClause.mixinTypes, Comp ileTimeErrorCode.MIXIN_OF_NON_CLASS); 8207 List<InterfaceType> mixinTypes2 = resolveTypes(withClause.mixinTypes, Comp ileTimeErrorCode.MIXIN_OF_NON_CLASS);
6419 if (classElement != null) { 8208 if (classElement != null) {
6420 classElement.mixins = mixinTypes2; 8209 classElement.mixins = mixinTypes2;
6421 } 8210 }
6422 } 8211 }
6423 if (implementsClause != null) { 8212 if (implementsClause != null) {
6424 NodeList<TypeName> interfaces2 = implementsClause.interfaces; 8213 NodeList<TypeName> interfaces2 = implementsClause.interfaces;
6425 List<InterfaceType> interfaceTypes = resolveTypes(interfaces2, CompileTime ErrorCode.IMPLEMENTS_NON_CLASS); 8214 List<InterfaceType> interfaceTypes = resolveTypes(interfaces2, CompileTime ErrorCode.IMPLEMENTS_NON_CLASS);
6426 List<TypeName> typeNames = new List.from(interfaces2); 8215 List<TypeName> typeNames = new List.from(interfaces2);
6427 String dynamicKeyword = sc.Keyword.DYNAMIC.syntax; 8216 String dynamicKeyword = sc.Keyword.DYNAMIC.syntax;
6428 List<bool> detectedRepeatOnIndex = new List<bool>.filled(typeNames.length, false); 8217 List<bool> detectedRepeatOnIndex = new List<bool>.filled(typeNames.length, false);
6429 for (int i = 0; i < detectedRepeatOnIndex.length; i++) { 8218 for (int i = 0; i < detectedRepeatOnIndex.length; i++) {
6430 detectedRepeatOnIndex[i] = false; 8219 detectedRepeatOnIndex[i] = false;
6431 } 8220 }
6432 for (int i = 0; i < typeNames.length; i++) { 8221 for (int i = 0; i < typeNames.length; i++) {
6433 TypeName typeName = typeNames[i]; 8222 TypeName typeName = typeNames[i];
6434 String name3 = typeName.name.name; 8223 String name3 = typeName.name.name;
6435 if (name3 == dynamicKeyword) { 8224 if (name3 == dynamicKeyword) {
6436 reportError(CompileTimeErrorCode.IMPLEMENTS_DYNAMIC, typeName, []); 8225 reportError(CompileTimeErrorCode.IMPLEMENTS_DYNAMIC, typeName, []);
6437 } else {
6438 Element element3 = typeName.name.element;
6439 if (element3 != null && element3 == classElement) {
6440 reportError(CompileTimeErrorCode.IMPLEMENTS_SELF, typeName, [name3]) ;
6441 }
6442 } 8226 }
6443 if (!detectedRepeatOnIndex[i]) { 8227 if (!detectedRepeatOnIndex[i]) {
6444 for (int j = i + 1; j < typeNames.length; j++) { 8228 for (int j = i + 1; j < typeNames.length; j++) {
6445 Element element4 = typeName.name.element; 8229 Element element3 = typeName.name.element;
6446 TypeName typeName2 = typeNames[j]; 8230 TypeName typeName2 = typeNames[j];
6447 Identifier identifier2 = typeName2.name; 8231 Identifier identifier2 = typeName2.name;
6448 String name2 = identifier2.name; 8232 String name2 = identifier2.name;
6449 Element element2 = identifier2.element; 8233 Element element2 = identifier2.element;
6450 if (element4 != null && element4 == element2) { 8234 if (element3 != null && element3 == element2) {
6451 detectedRepeatOnIndex[j] = true; 8235 detectedRepeatOnIndex[j] = true;
6452 reportError(CompileTimeErrorCode.IMPLEMENTS_REPEATED, typeName2, [ name2]); 8236 reportError(CompileTimeErrorCode.IMPLEMENTS_REPEATED, typeName2, [ name2]);
6453 } 8237 }
6454 } 8238 }
6455 } 8239 }
6456 } 8240 }
6457 if (classElement != null) { 8241 if (classElement != null) {
6458 classElement.interfaces = interfaceTypes; 8242 classElement.interfaces = interfaceTypes;
6459 } 8243 }
6460 } 8244 }
6461 } 8245 }
8246
6462 /** 8247 /**
6463 * Return the type specified by the given name. 8248 * Return the type specified by the given name.
6464 * @param typeName the type name specifying the type to be returned 8249 * @param typeName the type name specifying the type to be returned
6465 * @param nonTypeError the error to produce if the type name is defined to be something other than 8250 * @param nonTypeError the error to produce if the type name is defined to be something other than
6466 * a type 8251 * a type
6467 * @return the type specified by the type name 8252 * @return the type specified by the type name
6468 */ 8253 */
6469 InterfaceType resolveType(TypeName typeName, ErrorCode nonTypeError) { 8254 InterfaceType resolveType(TypeName typeName, ErrorCode nonTypeError) {
6470 Type2 type2 = typeName.type; 8255 Type2 type2 = typeName.type;
6471 if (type2 is InterfaceType) { 8256 if (type2 is InterfaceType) {
6472 return type2 as InterfaceType; 8257 return type2 as InterfaceType;
6473 } 8258 }
6474 Identifier name2 = typeName.name; 8259 Identifier name2 = typeName.name;
6475 if (name2.name != sc.Keyword.DYNAMIC.syntax) { 8260 if (name2.name != sc.Keyword.DYNAMIC.syntax) {
6476 reportError(nonTypeError, name2, [name2.name]); 8261 reportError(nonTypeError, name2, [name2.name]);
6477 } 8262 }
6478 return null; 8263 return null;
6479 } 8264 }
8265
6480 /** 8266 /**
6481 * Resolve the types in the given list of type names. 8267 * Resolve the types in the given list of type names.
6482 * @param typeNames the type names to be resolved 8268 * @param typeNames the type names to be resolved
6483 * @param nonTypeError the error to produce if the type name is defined to be something other than 8269 * @param nonTypeError the error to produce if the type name is defined to be something other than
6484 * a type 8270 * a type
6485 * @return an array containing all of the types that were resolved. 8271 * @return an array containing all of the types that were resolved.
6486 */ 8272 */
6487 List<InterfaceType> resolveTypes(NodeList<TypeName> typeNames, ErrorCode nonTy peError) { 8273 List<InterfaceType> resolveTypes(NodeList<TypeName> typeNames, ErrorCode nonTy peError) {
6488 List<InterfaceType> types = new List<InterfaceType>(); 8274 List<InterfaceType> types = new List<InterfaceType>();
6489 for (TypeName typeName in typeNames) { 8275 for (TypeName typeName in typeNames) {
(...skipping 12 matching lines...) Expand all
6502 PrefixedIdentifier identifier = typeName as PrefixedIdentifier; 8288 PrefixedIdentifier identifier = typeName as PrefixedIdentifier;
6503 identifier.identifier.element = element2; 8289 identifier.identifier.element = element2;
6504 SimpleIdentifier prefix2 = identifier.prefix; 8290 SimpleIdentifier prefix2 = identifier.prefix;
6505 Element prefixElement = nameScope.lookup(prefix2, definingLibrary); 8291 Element prefixElement = nameScope.lookup(prefix2, definingLibrary);
6506 if (prefixElement != null) { 8292 if (prefixElement != null) {
6507 prefix2.element = prefixElement; 8293 prefix2.element = prefixElement;
6508 } 8294 }
6509 } 8295 }
6510 } 8296 }
6511 } 8297 }
8298
6512 /** 8299 /**
6513 * Set the return type and parameter type information for the given function t ype based on the 8300 * Set the return type and parameter type information for the given function t ype based on the
6514 * given return type and parameter elements. 8301 * given return type and parameter elements.
6515 * @param functionType the function type to be filled in 8302 * @param functionType the function type to be filled in
6516 * @param returnType the return type of the function, or {@code null} if no ty pe was declared 8303 * @param returnType the return type of the function, or {@code null} if no ty pe was declared
6517 * @param parameters the elements representing the parameters to the function 8304 * @param parameters the elements representing the parameters to the function
6518 */ 8305 */
6519 void setTypeInformation(FunctionTypeImpl functionType, TypeName returnType2, L ist<ParameterElement> parameters) { 8306 void setTypeInformation(FunctionTypeImpl functionType, TypeName returnType2, L ist<ParameterElement> parameters) {
6520 List<Type2> normalParameterTypes = new List<Type2>(); 8307 List<Type2> normalParameterTypes = new List<Type2>();
6521 List<Type2> optionalParameterTypes = new List<Type2>(); 8308 List<Type2> optionalParameterTypes = new List<Type2>();
(...skipping 19 matching lines...) Expand all
6541 if (!namedParameterTypes.isEmpty) { 8328 if (!namedParameterTypes.isEmpty) {
6542 functionType.namedParameterTypes = namedParameterTypes; 8329 functionType.namedParameterTypes = namedParameterTypes;
6543 } 8330 }
6544 if (returnType2 == null) { 8331 if (returnType2 == null) {
6545 functionType.returnType = _dynamicType; 8332 functionType.returnType = _dynamicType;
6546 } else { 8333 } else {
6547 functionType.returnType = returnType2.type; 8334 functionType.returnType = returnType2.type;
6548 } 8335 }
6549 } 8336 }
6550 } 8337 }
8338
6551 /** 8339 /**
6552 * Instances of the class {@code ClassScope} implement the scope defined by a cl ass. 8340 * Instances of the class {@code ClassScope} implement the scope defined by a cl ass.
6553 * @coverage dart.engine.resolver 8341 * @coverage dart.engine.resolver
6554 */ 8342 */
6555 class ClassScope extends EnclosedScope { 8343 class ClassScope extends EnclosedScope {
8344
6556 /** 8345 /**
6557 * Initialize a newly created scope enclosed within another scope. 8346 * Initialize a newly created scope enclosed within another scope.
6558 * @param enclosingScope the scope in which this scope is lexically enclosed 8347 * @param enclosingScope the scope in which this scope is lexically enclosed
6559 * @param typeElement the element representing the type represented by this sc ope 8348 * @param typeElement the element representing the type represented by this sc ope
6560 */ 8349 */
6561 ClassScope(Scope enclosingScope, ClassElement typeElement) : super(new Enclose dScope(enclosingScope)) { 8350 ClassScope(Scope enclosingScope, ClassElement typeElement) : super(new Enclose dScope(enclosingScope)) {
6562 defineTypeParameters(typeElement); 8351 defineTypeParameters(typeElement);
6563 defineMembers(typeElement); 8352 defineMembers(typeElement);
6564 } 8353 }
8354 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
8355 if (existing is PropertyAccessorElement && duplicate is MethodElement) {
8356 if (existing.nameOffset < duplicate.nameOffset) {
8357 return new AnalysisError.con2(duplicate.source, duplicate.nameOffset, du plicate.displayName.length, CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAM E, [existing.displayName]);
8358 } else {
8359 return new AnalysisError.con2(existing.source, existing.nameOffset, exis ting.displayName.length, CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME, [existing.displayName]);
8360 }
8361 }
8362 return super.getErrorForDuplicate(existing, duplicate);
8363 }
8364
6565 /** 8365 /**
6566 * Define the instance members defined by the class. 8366 * Define the instance members defined by the class.
6567 * @param typeElement the element representing the type represented by this sc ope 8367 * @param typeElement the element representing the type represented by this sc ope
6568 */ 8368 */
6569 void defineMembers(ClassElement typeElement) { 8369 void defineMembers(ClassElement typeElement) {
6570 for (PropertyAccessorElement accessor in typeElement.accessors) { 8370 for (PropertyAccessorElement accessor in typeElement.accessors) {
6571 define(accessor); 8371 define(accessor);
6572 } 8372 }
6573 for (MethodElement method in typeElement.methods) { 8373 for (MethodElement method in typeElement.methods) {
6574 define(method); 8374 define(method);
6575 } 8375 }
6576 } 8376 }
8377
6577 /** 8378 /**
6578 * Define the type parameters for the class. 8379 * Define the type parameters for the class.
6579 * @param typeElement the element representing the type represented by this sc ope 8380 * @param typeElement the element representing the type represented by this sc ope
6580 */ 8381 */
6581 void defineTypeParameters(ClassElement typeElement) { 8382 void defineTypeParameters(ClassElement typeElement) {
6582 Scope parameterScope = enclosingScope; 8383 Scope parameterScope = enclosingScope;
6583 for (TypeVariableElement parameter in typeElement.typeVariables) { 8384 for (TypeVariableElement parameter in typeElement.typeVariables) {
6584 parameterScope.define(parameter); 8385 parameterScope.define(parameter);
6585 } 8386 }
6586 } 8387 }
6587 } 8388 }
8389
6588 /** 8390 /**
6589 * Instances of the class {@code EnclosedScope} implement a scope that is lexica lly enclosed in 8391 * Instances of the class {@code EnclosedScope} implement a scope that is lexica lly enclosed in
6590 * another scope. 8392 * another scope.
6591 * @coverage dart.engine.resolver 8393 * @coverage dart.engine.resolver
6592 */ 8394 */
6593 class EnclosedScope extends Scope { 8395 class EnclosedScope extends Scope {
8396
6594 /** 8397 /**
6595 * The scope in which this scope is lexically enclosed. 8398 * The scope in which this scope is lexically enclosed.
6596 */ 8399 */
6597 Scope _enclosingScope; 8400 Scope _enclosingScope;
8401
6598 /** 8402 /**
6599 * Initialize a newly created scope enclosed within another scope. 8403 * Initialize a newly created scope enclosed within another scope.
6600 * @param enclosingScope the scope in which this scope is lexically enclosed 8404 * @param enclosingScope the scope in which this scope is lexically enclosed
6601 */ 8405 */
6602 EnclosedScope(Scope enclosingScope) { 8406 EnclosedScope(Scope enclosingScope) {
6603 this._enclosingScope = enclosingScope; 8407 this._enclosingScope = enclosingScope;
6604 } 8408 }
6605 LibraryElement get definingLibrary => _enclosingScope.definingLibrary; 8409 LibraryElement get definingLibrary => _enclosingScope.definingLibrary;
6606 AnalysisErrorListener get errorListener => _enclosingScope.errorListener; 8410 AnalysisErrorListener get errorListener => _enclosingScope.errorListener;
8411
6607 /** 8412 /**
6608 * Return the scope in which this scope is lexically enclosed. 8413 * Return the scope in which this scope is lexically enclosed.
6609 * @return the scope in which this scope is lexically enclosed 8414 * @return the scope in which this scope is lexically enclosed
6610 */ 8415 */
6611 Scope get enclosingScope => _enclosingScope; 8416 Scope get enclosingScope => _enclosingScope;
6612 Element lookup3(String name, LibraryElement referencingLibrary) { 8417 Element lookup3(Identifier identifier, String name, LibraryElement referencing Library) {
6613 Element element = localLookup(name, referencingLibrary); 8418 Element element = localLookup(name, referencingLibrary);
6614 if (element != null) { 8419 if (element != null) {
6615 return element; 8420 return element;
6616 } 8421 }
6617 return _enclosingScope.lookup3(name, referencingLibrary); 8422 return _enclosingScope.lookup3(identifier, name, referencingLibrary);
6618 } 8423 }
6619 } 8424 }
8425
6620 /** 8426 /**
6621 * Instances of the class {@code FunctionScope} implement the scope defined by a function. 8427 * Instances of the class {@code FunctionScope} implement the scope defined by a function.
6622 * @coverage dart.engine.resolver 8428 * @coverage dart.engine.resolver
6623 */ 8429 */
6624 class FunctionScope extends EnclosedScope { 8430 class FunctionScope extends EnclosedScope {
8431
6625 /** 8432 /**
6626 * Initialize a newly created scope enclosed within another scope. 8433 * Initialize a newly created scope enclosed within another scope.
6627 * @param enclosingScope the scope in which this scope is lexically enclosed 8434 * @param enclosingScope the scope in which this scope is lexically enclosed
6628 * @param functionElement the element representing the type represented by thi s scope 8435 * @param functionElement the element representing the type represented by thi s scope
6629 */ 8436 */
6630 FunctionScope(Scope enclosingScope, ExecutableElement functionElement) : super (new EnclosedScope(enclosingScope)) { 8437 FunctionScope(Scope enclosingScope, ExecutableElement functionElement) : super (new EnclosedScope(enclosingScope)) {
6631 defineParameters(functionElement); 8438 defineParameters(functionElement);
6632 } 8439 }
8440
6633 /** 8441 /**
6634 * Define the parameters for the given function in the scope that encloses thi s function. 8442 * Define the parameters for the given function in the scope that encloses thi s function.
6635 * @param functionElement the element representing the function represented by this scope 8443 * @param functionElement the element representing the function represented by this scope
6636 */ 8444 */
6637 void defineParameters(ExecutableElement functionElement) { 8445 void defineParameters(ExecutableElement functionElement) {
6638 Scope parameterScope = enclosingScope; 8446 Scope parameterScope = enclosingScope;
6639 if (functionElement.enclosingElement is ExecutableElement) { 8447 if (functionElement.enclosingElement is ExecutableElement) {
6640 String name2 = functionElement.name; 8448 String name2 = functionElement.name;
6641 if (name2 != null && !name2.isEmpty) { 8449 if (name2 != null && !name2.isEmpty) {
6642 parameterScope.define(functionElement); 8450 parameterScope.define(functionElement);
6643 } 8451 }
6644 } 8452 }
6645 for (ParameterElement parameter in functionElement.parameters) { 8453 for (ParameterElement parameter in functionElement.parameters) {
6646 if (!parameter.isInitializingFormal()) { 8454 if (!parameter.isInitializingFormal()) {
6647 parameterScope.define(parameter); 8455 parameterScope.define(parameter);
6648 } 8456 }
6649 } 8457 }
6650 } 8458 }
6651 } 8459 }
8460
6652 /** 8461 /**
6653 * Instances of the class {@code FunctionTypeScope} implement the scope defined by a function type 8462 * Instances of the class {@code FunctionTypeScope} implement the scope defined by a function type
6654 * alias. 8463 * alias.
6655 * @coverage dart.engine.resolver 8464 * @coverage dart.engine.resolver
6656 */ 8465 */
6657 class FunctionTypeScope extends EnclosedScope { 8466 class FunctionTypeScope extends EnclosedScope {
8467
6658 /** 8468 /**
6659 * Initialize a newly created scope enclosed within another scope. 8469 * Initialize a newly created scope enclosed within another scope.
6660 * @param enclosingScope the scope in which this scope is lexically enclosed 8470 * @param enclosingScope the scope in which this scope is lexically enclosed
6661 * @param typeElement the element representing the type alias represented by t his scope 8471 * @param typeElement the element representing the type alias represented by t his scope
6662 */ 8472 */
6663 FunctionTypeScope(Scope enclosingScope, FunctionTypeAliasElement typeElement) : super(new EnclosedScope(enclosingScope)) { 8473 FunctionTypeScope(Scope enclosingScope, FunctionTypeAliasElement typeElement) : super(new EnclosedScope(enclosingScope)) {
6664 defineTypeVariables(typeElement); 8474 defineTypeVariables(typeElement);
6665 defineParameters(typeElement); 8475 defineParameters(typeElement);
6666 } 8476 }
8477
6667 /** 8478 /**
6668 * Define the parameters for the function type alias. 8479 * Define the parameters for the function type alias.
6669 * @param typeElement the element representing the type represented by this sc ope 8480 * @param typeElement the element representing the type represented by this sc ope
6670 */ 8481 */
6671 void defineParameters(FunctionTypeAliasElement typeElement) { 8482 void defineParameters(FunctionTypeAliasElement typeElement) {
6672 for (ParameterElement parameter in typeElement.parameters) { 8483 for (ParameterElement parameter in typeElement.parameters) {
6673 define(parameter); 8484 define(parameter);
6674 } 8485 }
6675 } 8486 }
8487
6676 /** 8488 /**
6677 * Define the type variables for the function type alias. 8489 * Define the type variables for the function type alias.
6678 * @param typeElement the element representing the type represented by this sc ope 8490 * @param typeElement the element representing the type represented by this sc ope
6679 */ 8491 */
6680 void defineTypeVariables(FunctionTypeAliasElement typeElement) { 8492 void defineTypeVariables(FunctionTypeAliasElement typeElement) {
6681 Scope typeVariableScope = enclosingScope; 8493 Scope typeVariableScope = enclosingScope;
6682 for (TypeVariableElement typeVariable in typeElement.typeVariables) { 8494 for (TypeVariableElement typeVariable in typeElement.typeVariables) {
6683 typeVariableScope.define(typeVariable); 8495 typeVariableScope.define(typeVariable);
6684 } 8496 }
6685 } 8497 }
6686 } 8498 }
8499
6687 /** 8500 /**
6688 * Instances of the class {@code LabelScope} represent a scope in which a single label is defined. 8501 * Instances of the class {@code LabelScope} represent a scope in which a single label is defined.
6689 * @coverage dart.engine.resolver 8502 * @coverage dart.engine.resolver
6690 */ 8503 */
6691 class LabelScope { 8504 class LabelScope {
8505
6692 /** 8506 /**
6693 * The label scope enclosing this label scope. 8507 * The label scope enclosing this label scope.
6694 */ 8508 */
6695 LabelScope _outerScope; 8509 LabelScope _outerScope;
8510
6696 /** 8511 /**
6697 * The label defined in this scope. 8512 * The label defined in this scope.
6698 */ 8513 */
6699 String _label; 8514 String _label;
8515
6700 /** 8516 /**
6701 * The element to which the label resolves. 8517 * The element to which the label resolves.
6702 */ 8518 */
6703 LabelElement _element; 8519 LabelElement _element;
8520
6704 /** 8521 /**
6705 * The marker used to look up a label element for an unlabeled {@code break} o r {@code continue}. 8522 * The marker used to look up a label element for an unlabeled {@code break} o r {@code continue}.
6706 */ 8523 */
6707 static String EMPTY_LABEL = ""; 8524 static String EMPTY_LABEL = "";
8525
6708 /** 8526 /**
6709 * The label element returned for scopes that can be the target of an unlabele d {@code break} or{@code continue}. 8527 * The label element returned for scopes that can be the target of an unlabele d {@code break} or{@code continue}.
6710 */ 8528 */
6711 static SimpleIdentifier _EMPTY_LABEL_IDENTIFIER = new SimpleIdentifier.full(ne w sc.StringToken(sc.TokenType.IDENTIFIER, "", 0)); 8529 static SimpleIdentifier _EMPTY_LABEL_IDENTIFIER = new SimpleIdentifier.full(ne w sc.StringToken(sc.TokenType.IDENTIFIER, "", 0));
8530
6712 /** 8531 /**
6713 * Initialize a newly created scope to represent the potential target of an un labeled{@code break} or {@code continue}. 8532 * Initialize a newly created scope to represent the potential target of an un labeled{@code break} or {@code continue}.
6714 * @param outerScope the label scope enclosing the new label scope 8533 * @param outerScope the label scope enclosing the new label scope
6715 * @param onSwitchStatement {@code true} if this label is associated with a {@ code switch}statement 8534 * @param onSwitchStatement {@code true} if this label is associated with a {@ code switch}statement
6716 * @param onSwitchMember {@code true} if this label is associated with a {@cod e switch} member 8535 * @param onSwitchMember {@code true} if this label is associated with a {@cod e switch} member
6717 */ 8536 */
6718 LabelScope.con1(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMe mber) { 8537 LabelScope.con1(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMe mber) {
6719 _jtd_constructor_280_impl(outerScope, onSwitchStatement, onSwitchMember); 8538 _jtd_constructor_286_impl(outerScope, onSwitchStatement, onSwitchMember);
6720 } 8539 }
6721 _jtd_constructor_280_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) { 8540 _jtd_constructor_286_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
6722 _jtd_constructor_281_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMP TY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember)); 8541 _jtd_constructor_287_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMP TY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember));
6723 } 8542 }
8543
6724 /** 8544 /**
6725 * Initialize a newly created scope to represent the given label. 8545 * Initialize a newly created scope to represent the given label.
6726 * @param outerScope the label scope enclosing the new label scope 8546 * @param outerScope the label scope enclosing the new label scope
6727 * @param label the label defined in this scope 8547 * @param label the label defined in this scope
6728 * @param element the element to which the label resolves 8548 * @param element the element to which the label resolves
6729 */ 8549 */
6730 LabelScope.con2(LabelScope outerScope2, String label2, LabelElement element2) { 8550 LabelScope.con2(LabelScope outerScope2, String label2, LabelElement element2) {
6731 _jtd_constructor_281_impl(outerScope2, label2, element2); 8551 _jtd_constructor_287_impl(outerScope2, label2, element2);
6732 } 8552 }
6733 _jtd_constructor_281_impl(LabelScope outerScope2, String label2, LabelElement element2) { 8553 _jtd_constructor_287_impl(LabelScope outerScope2, String label2, LabelElement element2) {
6734 this._outerScope = outerScope2; 8554 this._outerScope = outerScope2;
6735 this._label = label2; 8555 this._label = label2;
6736 this._element = element2; 8556 this._element = element2;
6737 } 8557 }
8558
6738 /** 8559 /**
6739 * Return the label element corresponding to the given label, or {@code null} if the given label 8560 * Return the label element corresponding to the given label, or {@code null} if the given label
6740 * is not defined in this scope. 8561 * is not defined in this scope.
6741 * @param targetLabel the label being looked up 8562 * @param targetLabel the label being looked up
6742 * @return the label element corresponding to the given label 8563 * @return the label element corresponding to the given label
6743 */ 8564 */
6744 LabelElement lookup(SimpleIdentifier targetLabel) => lookup2(targetLabel.name) ; 8565 LabelElement lookup(SimpleIdentifier targetLabel) => lookup2(targetLabel.name) ;
8566
6745 /** 8567 /**
6746 * Return the label element corresponding to the given label, or {@code null} if the given label 8568 * Return the label element corresponding to the given label, or {@code null} if the given label
6747 * is not defined in this scope. 8569 * is not defined in this scope.
6748 * @param targetLabel the label being looked up 8570 * @param targetLabel the label being looked up
6749 * @return the label element corresponding to the given label 8571 * @return the label element corresponding to the given label
6750 */ 8572 */
6751 LabelElement lookup2(String targetLabel) { 8573 LabelElement lookup2(String targetLabel) {
6752 if (_label == targetLabel) { 8574 if (_label == targetLabel) {
6753 return _element; 8575 return _element;
6754 } else if (_outerScope != null) { 8576 } else if (_outerScope != null) {
6755 return _outerScope.lookup2(targetLabel); 8577 return _outerScope.lookup2(targetLabel);
6756 } else { 8578 } else {
6757 return null; 8579 return null;
6758 } 8580 }
6759 } 8581 }
6760 } 8582 }
8583
6761 /** 8584 /**
6762 * Instances of the class {@code LibraryImportScope} represent the scope contain ing all of the names 8585 * Instances of the class {@code LibraryImportScope} represent the scope contain ing all of the names
6763 * available from imported libraries. 8586 * available from imported libraries.
6764 * @coverage dart.engine.resolver 8587 * @coverage dart.engine.resolver
6765 */ 8588 */
6766 class LibraryImportScope extends Scope { 8589 class LibraryImportScope extends Scope {
8590
8591 /**
8592 * @return {@code true} if the given {@link Identifier} is the part of type an notation.
8593 */
8594 static bool isTypeAnnotation(Identifier identifier) {
8595 ASTNode parent4 = identifier.parent;
8596 if (parent4 is TypeName) {
8597 ASTNode parent2 = parent4.parent;
8598 if (parent2 is FunctionDeclaration) {
8599 FunctionDeclaration decl = parent2 as FunctionDeclaration;
8600 return identical(decl.returnType, parent4);
8601 }
8602 if (parent2 is FunctionTypeAlias) {
8603 FunctionTypeAlias decl = parent2 as FunctionTypeAlias;
8604 return identical(decl.returnType, parent4);
8605 }
8606 if (parent2 is MethodDeclaration) {
8607 MethodDeclaration decl = parent2 as MethodDeclaration;
8608 return identical(decl.returnType, parent4);
8609 }
8610 if (parent2 is VariableDeclarationList) {
8611 VariableDeclarationList decl = parent2 as VariableDeclarationList;
8612 return identical(decl.type, parent4);
8613 }
8614 if (parent2 is SimpleFormalParameter) {
8615 SimpleFormalParameter decl = parent2 as SimpleFormalParameter;
8616 return identical(decl.type, parent4);
8617 }
8618 if (parent2 is TypeParameter) {
8619 TypeParameter decl = parent2 as TypeParameter;
8620 return identical(decl.bound, parent4);
8621 }
8622 if (parent2 is TypeArgumentList) {
8623 ASTNode parent3 = parent2.parent;
8624 if (parent3 is TypeName) {
8625 TypeName typeName = parent3 as TypeName;
8626 if (identical((typeName).typeArguments, parent2)) {
8627 return isTypeAnnotation(typeName.name);
8628 }
8629 }
8630 }
8631 return false;
8632 }
8633 return false;
8634 }
8635
6767 /** 8636 /**
6768 * The element representing the library in which this scope is enclosed. 8637 * The element representing the library in which this scope is enclosed.
6769 */ 8638 */
6770 LibraryElement _definingLibrary; 8639 LibraryElement _definingLibrary;
8640
6771 /** 8641 /**
6772 * The listener that is to be informed when an error is encountered. 8642 * The listener that is to be informed when an error is encountered.
6773 */ 8643 */
6774 AnalysisErrorListener _errorListener; 8644 AnalysisErrorListener _errorListener;
8645
6775 /** 8646 /**
6776 * A list of the namespaces representing the names that are available in this scope from imported 8647 * A list of the namespaces representing the names that are available in this scope from imported
6777 * libraries. 8648 * libraries.
6778 */ 8649 */
6779 List<Namespace> _importedNamespaces = new List<Namespace>(); 8650 List<Namespace> _importedNamespaces = new List<Namespace>();
8651
6780 /** 8652 /**
6781 * Initialize a newly created scope representing the names imported into the g iven library. 8653 * Initialize a newly created scope representing the names imported into the g iven library.
6782 * @param definingLibrary the element representing the library that imports th e names defined in 8654 * @param definingLibrary the element representing the library that imports th e names defined in
6783 * this scope 8655 * this scope
6784 * @param errorListener the listener that is to be informed when an error is e ncountered 8656 * @param errorListener the listener that is to be informed when an error is e ncountered
6785 */ 8657 */
6786 LibraryImportScope(LibraryElement definingLibrary, AnalysisErrorListener error Listener) { 8658 LibraryImportScope(LibraryElement definingLibrary, AnalysisErrorListener error Listener) {
6787 this._definingLibrary = definingLibrary; 8659 this._definingLibrary = definingLibrary;
6788 this._errorListener = errorListener; 8660 this._errorListener = errorListener;
6789 createImportedNamespaces(definingLibrary); 8661 createImportedNamespaces(definingLibrary);
6790 } 8662 }
6791 void define(Element element) { 8663 void define(Element element) {
6792 if (!Scope.isPrivateName(element.name)) { 8664 if (!Scope.isPrivateName(element.displayName)) {
6793 super.define(element); 8665 super.define(element);
6794 } 8666 }
6795 } 8667 }
6796 LibraryElement get definingLibrary => _definingLibrary; 8668 LibraryElement get definingLibrary => _definingLibrary;
6797 AnalysisErrorListener get errorListener => _errorListener; 8669 AnalysisErrorListener get errorListener => _errorListener;
6798 Element lookup3(String name, LibraryElement referencingLibrary) { 8670 Element lookup3(Identifier identifier, String name, LibraryElement referencing Library) {
6799 Element foundElement = localLookup(name, referencingLibrary); 8671 Element foundElement = localLookup(name, referencingLibrary);
6800 if (foundElement != null) { 8672 if (foundElement != null) {
6801 return foundElement; 8673 return foundElement;
6802 } 8674 }
6803 for (Namespace nameSpace in _importedNamespaces) { 8675 for (Namespace nameSpace in _importedNamespaces) {
6804 Element element = nameSpace.get(name); 8676 Element element = nameSpace.get(name);
6805 if (element != null) { 8677 if (element != null) {
6806 if (foundElement == null) { 8678 if (foundElement == null) {
6807 foundElement = element; 8679 foundElement = element;
6808 } else { 8680 } else {
6809 foundElement = new MultiplyDefinedElementImpl(_definingLibrary.context , foundElement, element); 8681 foundElement = new MultiplyDefinedElementImpl(_definingLibrary.context , foundElement, element);
6810 } 8682 }
6811 } 8683 }
6812 } 8684 }
6813 if (foundElement is MultiplyDefinedElementImpl) { 8685 if (foundElement is MultiplyDefinedElementImpl) {
8686 String foundEltName = foundElement.displayName;
8687 String libName1 = "", libName2 = "";
8688 List<Element> conflictingMembers = ((foundElement as MultiplyDefinedElemen tImpl)).conflictingElements;
8689 LibraryElement enclosingLibrary = conflictingMembers[0].getAncestor(Librar yElement);
8690 if (enclosingLibrary != null) {
8691 libName1 = enclosingLibrary.definingCompilationUnit.displayName;
8692 }
8693 enclosingLibrary = conflictingMembers[1].getAncestor(LibraryElement);
8694 if (enclosingLibrary != null) {
8695 libName2 = enclosingLibrary.definingCompilationUnit.displayName;
8696 }
8697 ErrorCode errorCode = isTypeAnnotation(identifier) ? StaticWarningCode.AMB IGUOUS_IMPORT : CompileTimeErrorCode.AMBIGUOUS_IMPORT;
8698 _errorListener.onError(new AnalysisError.con2(source, identifier.offset, i dentifier.length, errorCode, [foundEltName, libName1, libName2]));
8699 return foundElement;
6814 } 8700 }
6815 if (foundElement != null) { 8701 if (foundElement != null) {
6816 defineWithoutChecking(foundElement); 8702 defineWithoutChecking2(name, foundElement);
6817 } 8703 }
6818 return foundElement; 8704 return foundElement;
6819 } 8705 }
8706
6820 /** 8707 /**
6821 * Create all of the namespaces associated with the libraries imported into th is library. The 8708 * Create all of the namespaces associated with the libraries imported into th is library. The
6822 * names are not added to this scope, but are stored for later reference. 8709 * names are not added to this scope, but are stored for later reference.
6823 * @param definingLibrary the element representing the library that imports th e libraries for 8710 * @param definingLibrary the element representing the library that imports th e libraries for
6824 * which namespaces will be created 8711 * which namespaces will be created
6825 */ 8712 */
6826 void createImportedNamespaces(LibraryElement definingLibrary) { 8713 void createImportedNamespaces(LibraryElement definingLibrary) {
6827 NamespaceBuilder builder = new NamespaceBuilder(); 8714 NamespaceBuilder builder = new NamespaceBuilder();
6828 for (ImportElement element in definingLibrary.imports) { 8715 for (ImportElement element in definingLibrary.imports) {
6829 _importedNamespaces.add(builder.createImportNamespace(element)); 8716 _importedNamespaces.add(builder.createImportNamespace(element));
6830 } 8717 }
6831 } 8718 }
6832 } 8719 }
8720
6833 /** 8721 /**
6834 * Instances of the class {@code LibraryScope} implement a scope containing all of the names defined 8722 * Instances of the class {@code LibraryScope} implement a scope containing all of the names defined
6835 * in a given library. 8723 * in a given library.
6836 * @coverage dart.engine.resolver 8724 * @coverage dart.engine.resolver
6837 */ 8725 */
6838 class LibraryScope extends EnclosedScope { 8726 class LibraryScope extends EnclosedScope {
8727
6839 /** 8728 /**
6840 * Initialize a newly created scope representing the names defined in the give n library. 8729 * Initialize a newly created scope representing the names defined in the give n library.
6841 * @param definingLibrary the element representing the library represented by this scope 8730 * @param definingLibrary the element representing the library represented by this scope
6842 * @param errorListener the listener that is to be informed when an error is e ncountered 8731 * @param errorListener the listener that is to be informed when an error is e ncountered
6843 */ 8732 */
6844 LibraryScope(LibraryElement definingLibrary, AnalysisErrorListener errorListen er) : super(new LibraryImportScope(definingLibrary, errorListener)) { 8733 LibraryScope(LibraryElement definingLibrary, AnalysisErrorListener errorListen er) : super(new LibraryImportScope(definingLibrary, errorListener)) {
6845 defineTopLevelNames(definingLibrary); 8734 defineTopLevelNames(definingLibrary);
6846 } 8735 }
8736 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
8737 if (existing is PrefixElement) {
8738 int offset = duplicate.nameOffset;
8739 if (duplicate is PropertyAccessorElement) {
8740 PropertyAccessorElement accessor = duplicate as PropertyAccessorElement;
8741 if (accessor.isSynthetic()) {
8742 offset = accessor.variable.nameOffset;
8743 }
8744 }
8745 return new AnalysisError.con2(source, offset, duplicate.displayName.length , CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, [existing.displayN ame]);
8746 }
8747 return super.getErrorForDuplicate(existing, duplicate);
8748 }
8749
6847 /** 8750 /**
6848 * Add to this scope all of the public top-level names that are defined in the given compilation 8751 * Add to this scope all of the public top-level names that are defined in the given compilation
6849 * unit. 8752 * unit.
6850 * @param compilationUnit the compilation unit defining the top-level names to be added to this 8753 * @param compilationUnit the compilation unit defining the top-level names to be added to this
6851 * scope 8754 * scope
6852 */ 8755 */
6853 void defineLocalNames(CompilationUnitElement compilationUnit) { 8756 void defineLocalNames(CompilationUnitElement compilationUnit) {
6854 for (PropertyAccessorElement element in compilationUnit.accessors) { 8757 for (PropertyAccessorElement element in compilationUnit.accessors) {
6855 define(element); 8758 define(element);
6856 } 8759 }
6857 for (FunctionElement element in compilationUnit.functions) { 8760 for (FunctionElement element in compilationUnit.functions) {
6858 define(element); 8761 define(element);
6859 } 8762 }
6860 for (FunctionTypeAliasElement element in compilationUnit.functionTypeAliases ) { 8763 for (FunctionTypeAliasElement element in compilationUnit.functionTypeAliases ) {
6861 define(element); 8764 define(element);
6862 } 8765 }
6863 for (ClassElement element in compilationUnit.types) { 8766 for (ClassElement element in compilationUnit.types) {
6864 define(element); 8767 define(element);
6865 } 8768 }
6866 } 8769 }
8770
6867 /** 8771 /**
6868 * Add to this scope all of the names that are explicitly defined in the given library. 8772 * Add to this scope all of the names that are explicitly defined in the given library.
6869 * @param definingLibrary the element representing the library that defines th e names in this 8773 * @param definingLibrary the element representing the library that defines th e names in this
6870 * scope 8774 * scope
6871 */ 8775 */
6872 void defineTopLevelNames(LibraryElement definingLibrary) { 8776 void defineTopLevelNames(LibraryElement definingLibrary) {
6873 for (PrefixElement prefix in definingLibrary.prefixes) { 8777 for (PrefixElement prefix in definingLibrary.prefixes) {
6874 define(prefix); 8778 define(prefix);
6875 } 8779 }
6876 defineLocalNames(definingLibrary.definingCompilationUnit); 8780 defineLocalNames(definingLibrary.definingCompilationUnit);
6877 for (CompilationUnitElement compilationUnit in definingLibrary.parts) { 8781 for (CompilationUnitElement compilationUnit in definingLibrary.parts) {
6878 defineLocalNames(compilationUnit); 8782 defineLocalNames(compilationUnit);
6879 } 8783 }
6880 } 8784 }
6881 } 8785 }
8786
6882 /** 8787 /**
6883 * Instances of the class {@code Namespace} implement a mapping of identifiers t o the elements 8788 * Instances of the class {@code Namespace} implement a mapping of identifiers t o the elements
6884 * represented by those identifiers. Namespaces are the building blocks for scop es. 8789 * represented by those identifiers. Namespaces are the building blocks for scop es.
6885 * @coverage dart.engine.resolver 8790 * @coverage dart.engine.resolver
6886 */ 8791 */
6887 class Namespace { 8792 class Namespace {
8793
6888 /** 8794 /**
6889 * A table mapping names that are defined in this namespace to the element rep resenting the thing 8795 * A table mapping names that are defined in this namespace to the element rep resenting the thing
6890 * declared with that name. 8796 * declared with that name.
6891 */ 8797 */
6892 Map<String, Element> _definedNames; 8798 Map<String, Element> _definedNames;
8799
6893 /** 8800 /**
6894 * An empty namespace. 8801 * An empty namespace.
6895 */ 8802 */
6896 static Namespace EMPTY = new Namespace(new Map<String, Element>()); 8803 static Namespace EMPTY = new Namespace(new Map<String, Element>());
8804
6897 /** 8805 /**
6898 * Initialize a newly created namespace to have the given defined names. 8806 * Initialize a newly created namespace to have the given defined names.
6899 * @param definedNames the mapping from names that are defined in this namespa ce to the 8807 * @param definedNames the mapping from names that are defined in this namespa ce to the
6900 * corresponding elements 8808 * corresponding elements
6901 */ 8809 */
6902 Namespace(Map<String, Element> definedNames) { 8810 Namespace(Map<String, Element> definedNames) {
6903 this._definedNames = definedNames; 8811 this._definedNames = definedNames;
6904 } 8812 }
8813
6905 /** 8814 /**
6906 * Return the element in this namespace that is available to the containing sc ope using the given 8815 * Return the element in this namespace that is available to the containing sc ope using the given
6907 * name. 8816 * name.
6908 * @param name the name used to reference the 8817 * @param name the name used to reference the
6909 * @return the element represented by the given identifier 8818 * @return the element represented by the given identifier
6910 */ 8819 */
6911 Element get(String name) => _definedNames[name]; 8820 Element get(String name) => _definedNames[name];
8821
6912 /** 8822 /**
6913 * Return a table containing the same mappings as those defined by this namesp ace. 8823 * Return a table containing the same mappings as those defined by this namesp ace.
6914 * @return a table containing the same mappings as those defined by this names pace 8824 * @return a table containing the same mappings as those defined by this names pace
6915 */ 8825 */
6916 Map<String, Element> get definedNames => new Map<String, Element>.from(_define dNames); 8826 Map<String, Element> get definedNames => new Map<String, Element>.from(_define dNames);
6917 } 8827 }
8828
6918 /** 8829 /**
6919 * Instances of the class {@code NamespaceBuilder} are used to build a {@code Na mespace}. Namespace 8830 * Instances of the class {@code NamespaceBuilder} are used to build a {@code Na mespace}. Namespace
6920 * builders are thread-safe and re-usable. 8831 * builders are thread-safe and re-usable.
6921 * @coverage dart.engine.resolver 8832 * @coverage dart.engine.resolver
6922 */ 8833 */
6923 class NamespaceBuilder { 8834 class NamespaceBuilder {
8835
6924 /** 8836 /**
6925 * Initialize a newly created namespace builder. 8837 * Create a namespace representing the export namespace of the given {@link Ex portElement}.
8838 * @param element the export element whose export namespace is to be created
8839 * @return the export namespace that was created
6926 */ 8840 */
6927 NamespaceBuilder() : super() { 8841 Namespace createExportNamespace(ExportElement element) {
8842 LibraryElement exportedLibrary2 = element.exportedLibrary;
8843 if (exportedLibrary2 == null) {
8844 return Namespace.EMPTY;
8845 }
8846 Map<String, Element> definedNames = createExportMapping(exportedLibrary2, ne w Set<LibraryElement>());
8847 definedNames = apply(definedNames, element.combinators);
8848 return new Namespace(definedNames);
6928 } 8849 }
8850
6929 /** 8851 /**
6930 * Create a namespace representing the export namespace of the given library. 8852 * Create a namespace representing the export namespace of the given library.
6931 * @param library the library whose export namespace is to be created 8853 * @param library the library whose export namespace is to be created
6932 * @return the export namespace that was created 8854 * @return the export namespace that was created
6933 */ 8855 */
6934 Namespace createExportNamespace(LibraryElement library) => new Namespace(creat eExportMapping(library, new Set<LibraryElement>())); 8856 Namespace createExportNamespace2(LibraryElement library) => new Namespace(crea teExportMapping(library, new Set<LibraryElement>()));
8857
6935 /** 8858 /**
6936 * Create a namespace representing the import namespace of the given library. 8859 * Create a namespace representing the import namespace of the given library.
6937 * @param library the library whose import namespace is to be created 8860 * @param library the library whose import namespace is to be created
6938 * @return the import namespace that was created 8861 * @return the import namespace that was created
6939 */ 8862 */
6940 Namespace createImportNamespace(ImportElement element) { 8863 Namespace createImportNamespace(ImportElement element) {
6941 LibraryElement importedLibrary2 = element.importedLibrary; 8864 LibraryElement importedLibrary2 = element.importedLibrary;
6942 if (importedLibrary2 == null) { 8865 if (importedLibrary2 == null) {
6943 return Namespace.EMPTY; 8866 return Namespace.EMPTY;
6944 } 8867 }
6945 Map<String, Element> definedNames = createExportMapping(importedLibrary2, ne w Set<LibraryElement>()); 8868 Map<String, Element> definedNames = createExportMapping(importedLibrary2, ne w Set<LibraryElement>());
6946 definedNames = apply(definedNames, element.combinators); 8869 definedNames = apply(definedNames, element.combinators);
6947 definedNames = apply2(definedNames, element.prefix); 8870 definedNames = apply2(definedNames, element.prefix);
6948 return new Namespace(definedNames); 8871 return new Namespace(definedNames);
6949 } 8872 }
8873
6950 /** 8874 /**
6951 * Create a namespace representing the public namespace of the given library. 8875 * Create a namespace representing the public namespace of the given library.
6952 * @param library the library whose public namespace is to be created 8876 * @param library the library whose public namespace is to be created
6953 * @return the public namespace that was created 8877 * @return the public namespace that was created
6954 */ 8878 */
6955 Namespace createPublicNamespace(LibraryElement library) { 8879 Namespace createPublicNamespace(LibraryElement library) {
6956 Map<String, Element> definedNames = new Map<String, Element>(); 8880 Map<String, Element> definedNames = new Map<String, Element>();
6957 addPublicNames(definedNames, library.definingCompilationUnit); 8881 addPublicNames(definedNames, library.definingCompilationUnit);
6958 for (CompilationUnitElement compilationUnit in library.parts) { 8882 for (CompilationUnitElement compilationUnit in library.parts) {
6959 addPublicNames(definedNames, compilationUnit); 8883 addPublicNames(definedNames, compilationUnit);
6960 } 8884 }
6961 return new Namespace(definedNames); 8885 return new Namespace(definedNames);
6962 } 8886 }
8887
6963 /** 8888 /**
6964 * Add all of the names in the given namespace to the given mapping table. 8889 * Add all of the names in the given namespace to the given mapping table.
6965 * @param definedNames the mapping table to which the names in the given names pace are to be added 8890 * @param definedNames the mapping table to which the names in the given names pace are to be added
6966 * @param namespace the namespace containing the names to be added to this nam espace 8891 * @param namespace the namespace containing the names to be added to this nam espace
6967 */ 8892 */
6968 void addAll(Map<String, Element> definedNames, Map<String, Element> newNames) { 8893 void addAll(Map<String, Element> definedNames, Map<String, Element> newNames) {
6969 for (MapEntry<String, Element> entry in getMapEntrySet(newNames)) { 8894 for (MapEntry<String, Element> entry in getMapEntrySet(newNames)) {
6970 definedNames[entry.getKey()] = entry.getValue(); 8895 definedNames[entry.getKey()] = entry.getValue();
6971 } 8896 }
6972 } 8897 }
8898
6973 /** 8899 /**
6974 * Add all of the names in the given namespace to the given mapping table. 8900 * Add all of the names in the given namespace to the given mapping table.
6975 * @param definedNames the mapping table to which the names in the given names pace are to be added 8901 * @param definedNames the mapping table to which the names in the given names pace are to be added
6976 * @param namespace the namespace containing the names to be added to this nam espace 8902 * @param namespace the namespace containing the names to be added to this nam espace
6977 */ 8903 */
6978 void addAll2(Map<String, Element> definedNames2, Namespace namespace) { 8904 void addAll2(Map<String, Element> definedNames2, Namespace namespace) {
6979 if (namespace != null) { 8905 if (namespace != null) {
6980 addAll(definedNames2, namespace.definedNames); 8906 addAll(definedNames2, namespace.definedNames);
6981 } 8907 }
6982 } 8908 }
8909
6983 /** 8910 /**
6984 * Add the given element to the given mapping table if it has a publicly visib le name. 8911 * Add the given element to the given mapping table if it has a publicly visib le name.
6985 * @param definedNames the mapping table to which the public name is to be add ed 8912 * @param definedNames the mapping table to which the public name is to be add ed
6986 * @param element the element to be added 8913 * @param element the element to be added
6987 */ 8914 */
6988 void addIfPublic(Map<String, Element> definedNames, Element element) { 8915 void addIfPublic(Map<String, Element> definedNames, Element element) {
6989 String name2 = element.name; 8916 String name2 = element.name;
6990 if (name2 != null && !Scope.isPrivateName(name2)) { 8917 if (name2 != null && !Scope.isPrivateName(name2)) {
6991 definedNames[name2] = element; 8918 definedNames[name2] = element;
6992 } 8919 }
6993 } 8920 }
8921
6994 /** 8922 /**
6995 * Add to the given mapping table all of the public top-level names that are d efined in the given 8923 * Add to the given mapping table all of the public top-level names that are d efined in the given
6996 * compilation unit. 8924 * compilation unit.
6997 * @param definedNames the mapping table to which the public names are to be a dded 8925 * @param definedNames the mapping table to which the public names are to be a dded
6998 * @param compilationUnit the compilation unit defining the top-level names to be added to this 8926 * @param compilationUnit the compilation unit defining the top-level names to be added to this
6999 * namespace 8927 * namespace
7000 */ 8928 */
7001 void addPublicNames(Map<String, Element> definedNames, CompilationUnitElement compilationUnit) { 8929 void addPublicNames(Map<String, Element> definedNames, CompilationUnitElement compilationUnit) {
7002 for (PropertyAccessorElement element in compilationUnit.accessors) { 8930 for (PropertyAccessorElement element in compilationUnit.accessors) {
7003 addIfPublic(definedNames, element); 8931 addIfPublic(definedNames, element);
7004 } 8932 }
7005 for (FunctionElement element in compilationUnit.functions) { 8933 for (FunctionElement element in compilationUnit.functions) {
7006 addIfPublic(definedNames, element); 8934 addIfPublic(definedNames, element);
7007 } 8935 }
7008 for (FunctionTypeAliasElement element in compilationUnit.functionTypeAliases ) { 8936 for (FunctionTypeAliasElement element in compilationUnit.functionTypeAliases ) {
7009 addIfPublic(definedNames, element); 8937 addIfPublic(definedNames, element);
7010 } 8938 }
7011 for (ClassElement element in compilationUnit.types) { 8939 for (ClassElement element in compilationUnit.types) {
7012 addIfPublic(definedNames, element); 8940 addIfPublic(definedNames, element);
7013 } 8941 }
7014 for (VariableElement element in compilationUnit.topLevelVariables) {
7015 addIfPublic(definedNames, element);
7016 }
7017 } 8942 }
8943
7018 /** 8944 /**
7019 * Apply the given combinators to all of the names in the given mapping table. 8945 * Apply the given combinators to all of the names in the given mapping table.
7020 * @param definedNames the mapping table to which the namespace operations are to be applied 8946 * @param definedNames the mapping table to which the namespace operations are to be applied
7021 * @param combinators the combinators to be applied 8947 * @param combinators the combinators to be applied
7022 */ 8948 */
7023 Map<String, Element> apply(Map<String, Element> definedNames, List<NamespaceCo mbinator> combinators) { 8949 Map<String, Element> apply(Map<String, Element> definedNames, List<NamespaceCo mbinator> combinators) {
7024 for (NamespaceCombinator combinator in combinators) { 8950 for (NamespaceCombinator combinator in combinators) {
7025 if (combinator is __imp_combi.HideCombinator) { 8951 if (combinator is __imp_combi.HideCombinator) {
7026 hide(definedNames, ((combinator as __imp_combi.HideCombinator)).hiddenNa mes); 8952 hide(definedNames, ((combinator as __imp_combi.HideCombinator)).hiddenNa mes);
7027 } else if (combinator is __imp_combi.ShowCombinator) { 8953 } else if (combinator is __imp_combi.ShowCombinator) {
7028 definedNames = show(definedNames, ((combinator as __imp_combi.ShowCombin ator)).shownNames); 8954 definedNames = show(definedNames, ((combinator as __imp_combi.ShowCombin ator)).shownNames);
7029 } else { 8955 } else {
7030 AnalysisEngine.instance.logger.logError("Unknown type of combinator: ${c ombinator.runtimeType.toString()}"); 8956 AnalysisEngine.instance.logger.logError("Unknown type of combinator: ${c ombinator.runtimeType.toString()}");
7031 } 8957 }
7032 } 8958 }
7033 return definedNames; 8959 return definedNames;
7034 } 8960 }
8961
7035 /** 8962 /**
7036 * Apply the given prefix to all of the names in the table of defined names. 8963 * Apply the given prefix to all of the names in the table of defined names.
7037 * @param definedNames the names that were defined before this operation 8964 * @param definedNames the names that were defined before this operation
7038 * @param prefixElement the element defining the prefix to be added to the nam es 8965 * @param prefixElement the element defining the prefix to be added to the nam es
7039 */ 8966 */
7040 Map<String, Element> apply2(Map<String, Element> definedNames, PrefixElement p refixElement) { 8967 Map<String, Element> apply2(Map<String, Element> definedNames, PrefixElement p refixElement) {
7041 if (prefixElement != null) { 8968 if (prefixElement != null) {
7042 String prefix = prefixElement.name; 8969 String prefix = prefixElement.name;
7043 Map<String, Element> newNames = new Map<String, Element>(); 8970 Map<String, Element> newNames = new Map<String, Element>();
7044 for (MapEntry<String, Element> entry in getMapEntrySet(definedNames)) { 8971 for (MapEntry<String, Element> entry in getMapEntrySet(definedNames)) {
7045 newNames["${prefix}.${entry.getKey()}"] = entry.getValue(); 8972 newNames["${prefix}.${entry.getKey()}"] = entry.getValue();
7046 } 8973 }
7047 return newNames; 8974 return newNames;
7048 } else { 8975 } else {
7049 return definedNames; 8976 return definedNames;
7050 } 8977 }
7051 } 8978 }
8979
7052 /** 8980 /**
7053 * Create a mapping table representing the export namespace of the given libra ry. 8981 * Create a mapping table representing the export namespace of the given libra ry.
7054 * @param library the library whose public namespace is to be created 8982 * @param library the library whose public namespace is to be created
7055 * @param visitedElements a set of libraries that do not need to be visited wh en processing the 8983 * @param visitedElements a set of libraries that do not need to be visited wh en processing the
7056 * export directives of the given library because all of the names defined by them will 8984 * export directives of the given library because all of the names defined by them will
7057 * be added by another library 8985 * be added by another library
7058 * @return the mapping table that was created 8986 * @return the mapping table that was created
7059 */ 8987 */
7060 Map<String, Element> createExportMapping(LibraryElement library, Set<LibraryEl ement> visitedElements) { 8988 Map<String, Element> createExportMapping(LibraryElement library, Set<LibraryEl ement> visitedElements) {
7061 javaSetAdd(visitedElements, library); 8989 javaSetAdd(visitedElements, library);
7062 try { 8990 try {
7063 Map<String, Element> definedNames = new Map<String, Element>(); 8991 Map<String, Element> definedNames = new Map<String, Element>();
7064 for (ExportElement element in library.exports) { 8992 for (ExportElement element in library.exports) {
7065 LibraryElement exportedLibrary2 = element.exportedLibrary; 8993 LibraryElement exportedLibrary2 = element.exportedLibrary;
7066 if (exportedLibrary2 != null && !visitedElements.contains(exportedLibrar y2)) { 8994 if (exportedLibrary2 != null && !visitedElements.contains(exportedLibrar y2)) {
7067 Map<String, Element> exportedNames = createExportMapping(exportedLibra ry2, visitedElements); 8995 Map<String, Element> exportedNames = createExportMapping(exportedLibra ry2, visitedElements);
7068 exportedNames = apply(exportedNames, element.combinators); 8996 exportedNames = apply(exportedNames, element.combinators);
7069 addAll(definedNames, exportedNames); 8997 addAll(definedNames, exportedNames);
7070 } 8998 }
7071 } 8999 }
7072 addAll2(definedNames, ((library.context as InternalAnalysisContext)).getPu blicNamespace(library)); 9000 addAll2(definedNames, ((library.context as InternalAnalysisContext)).getPu blicNamespace(library));
7073 return definedNames; 9001 return definedNames;
7074 } finally { 9002 } finally {
7075 visitedElements.remove(library); 9003 visitedElements.remove(library);
7076 } 9004 }
7077 } 9005 }
9006
7078 /** 9007 /**
7079 * Hide all of the given names by removing them from the given collection of d efined names. 9008 * Hide all of the given names by removing them from the given collection of d efined names.
7080 * @param definedNames the names that were defined before this operation 9009 * @param definedNames the names that were defined before this operation
7081 * @param hiddenNames the names to be hidden 9010 * @param hiddenNames the names to be hidden
7082 */ 9011 */
7083 void hide(Map<String, Element> definedNames, List<String> hiddenNames) { 9012 void hide(Map<String, Element> definedNames, List<String> hiddenNames) {
7084 for (String name in hiddenNames) { 9013 for (String name in hiddenNames) {
7085 definedNames.remove(name); 9014 definedNames.remove(name);
7086 } 9015 }
7087 } 9016 }
9017
7088 /** 9018 /**
7089 * Show only the given names by removing all other names from the given collec tion of defined 9019 * Show only the given names by removing all other names from the given collec tion of defined
7090 * names. 9020 * names.
7091 * @param definedNames the names that were defined before this operation 9021 * @param definedNames the names that were defined before this operation
7092 * @param shownNames the names to be shown 9022 * @param shownNames the names to be shown
7093 */ 9023 */
7094 Map<String, Element> show(Map<String, Element> definedNames, List<String> show nNames) { 9024 Map<String, Element> show(Map<String, Element> definedNames, List<String> show nNames) {
7095 Map<String, Element> newNames = new Map<String, Element>(); 9025 Map<String, Element> newNames = new Map<String, Element>();
7096 for (String name in shownNames) { 9026 for (String name in shownNames) {
7097 Element element = definedNames[name]; 9027 Element element = definedNames[name];
7098 if (element != null) { 9028 if (element != null) {
7099 newNames[name] = element; 9029 newNames[name] = element;
7100 } 9030 }
7101 } 9031 }
7102 return newNames; 9032 return newNames;
7103 } 9033 }
7104 } 9034 }
9035
7105 /** 9036 /**
7106 * The abstract class {@code Scope} defines the behavior common to name scopes u sed by the resolver 9037 * The abstract class {@code Scope} defines the behavior common to name scopes u sed by the resolver
7107 * to determine which names are visible at any given point in the code. 9038 * to determine which names are visible at any given point in the code.
7108 * @coverage dart.engine.resolver 9039 * @coverage dart.engine.resolver
7109 */ 9040 */
7110 abstract class Scope { 9041 abstract class Scope {
9042
7111 /** 9043 /**
7112 * The prefix used to mark an identifier as being private to its library. 9044 * The prefix used to mark an identifier as being private to its library.
7113 */ 9045 */
7114 static String PRIVATE_NAME_PREFIX = "_"; 9046 static String PRIVATE_NAME_PREFIX = "_";
9047
7115 /** 9048 /**
7116 * The suffix added to the declared name of a setter when looking up the sette r. Used to 9049 * The suffix added to the declared name of a setter when looking up the sette r. Used to
7117 * disambiguate between a getter and a setter that have the same name. 9050 * disambiguate between a getter and a setter that have the same name.
7118 */ 9051 */
7119 static String SETTER_SUFFIX = "="; 9052 static String SETTER_SUFFIX = "=";
9053
7120 /** 9054 /**
7121 * The name used to look up the method used to implement the unary minus opera tor. Used to 9055 * The name used to look up the method used to implement the unary minus opera tor. Used to
7122 * disambiguate between the unary and binary operators. 9056 * disambiguate between the unary and binary operators.
7123 */ 9057 */
7124 static String UNARY_MINUS = "unary-"; 9058 static String UNARY_MINUS = "unary-";
9059
7125 /** 9060 /**
7126 * Return {@code true} if the given name is a library-private name. 9061 * Return {@code true} if the given name is a library-private name.
7127 * @param name the name being tested 9062 * @param name the name being tested
7128 * @return {@code true} if the given name is a library-private name 9063 * @return {@code true} if the given name is a library-private name
7129 */ 9064 */
7130 static bool isPrivateName(String name) => name != null && name.startsWith(PRIV ATE_NAME_PREFIX); 9065 static bool isPrivateName(String name) => name != null && name.startsWith(PRIV ATE_NAME_PREFIX);
9066
7131 /** 9067 /**
7132 * A table mapping names that are defined in this scope to the element represe nting the thing 9068 * A table mapping names that are defined in this scope to the element represe nting the thing
7133 * declared with that name. 9069 * declared with that name.
7134 */ 9070 */
7135 Map<String, Element> _definedNames = new Map<String, Element>(); 9071 Map<String, Element> _definedNames = new Map<String, Element>();
7136 /** 9072
7137 * Initialize a newly created scope to be empty.
7138 */
7139 Scope() : super() {
7140 }
7141 /** 9073 /**
7142 * Add the given element to this scope. If there is already an element with th e given name defined 9074 * Add the given element to this scope. If there is already an element with th e given name defined
7143 * in this scope, then an error will be generated and the original element wil l continue to be 9075 * in this scope, then an error will be generated and the original element wil l continue to be
7144 * mapped to the name. If there is an element with the given name in an enclos ing scope, then a 9076 * mapped to the name. If there is an element with the given name in an enclos ing scope, then a
7145 * warning will be generated but the given element will hide the inherited ele ment. 9077 * warning will be generated but the given element will hide the inherited ele ment.
7146 * @param element the element to be added to this scope 9078 * @param element the element to be added to this scope
7147 */ 9079 */
7148 void define(Element element) { 9080 void define(Element element) {
7149 String name = getName(element); 9081 String name = getName(element);
7150 if (name != null && !name.isEmpty) { 9082 if (name != null && !name.isEmpty) {
7151 if (_definedNames.containsKey(name)) { 9083 if (_definedNames.containsKey(name)) {
7152 errorListener.onError(getErrorForDuplicate(_definedNames[name], element) ); 9084 errorListener.onError(getErrorForDuplicate(_definedNames[name], element) );
7153 } else { 9085 } else {
7154 _definedNames[name] = element; 9086 _definedNames[name] = element;
7155 } 9087 }
7156 } 9088 }
7157 } 9089 }
9090
7158 /** 9091 /**
7159 * Return the element with which the given identifier is associated, or {@code null} if the name 9092 * Return the element with which the given identifier is associated, or {@code null} if the name
7160 * is not defined within this scope. 9093 * is not defined within this scope.
7161 * @param identifier the identifier associated with the element to be returned 9094 * @param identifier the identifier associated with the element to be returned
7162 * @param referencingLibrary the library that contains the reference to the na me, used to 9095 * @param referencingLibrary the library that contains the reference to the na me, used to
7163 * implement library-level privacy 9096 * implement library-level privacy
7164 * @return the element with which the given identifier is associated 9097 * @return the element with which the given identifier is associated
7165 */ 9098 */
7166 Element lookup(Identifier identifier, LibraryElement referencingLibrary) => lo okup3(identifier.name, referencingLibrary); 9099 Element lookup(Identifier identifier, LibraryElement referencingLibrary) => lo okup3(identifier, identifier.name, referencingLibrary);
9100
7167 /** 9101 /**
7168 * Add the given element to this scope without checking for duplication or hid ing. 9102 * Add the given element to this scope without checking for duplication or hid ing.
7169 * @param element the element to be added to this scope 9103 * @param element the element to be added to this scope
7170 */ 9104 */
7171 void defineWithoutChecking(Element element) { 9105 void defineWithoutChecking(Element element) {
7172 _definedNames[getName(element)] = element; 9106 _definedNames[getName(element)] = element;
7173 } 9107 }
9108
9109 /**
9110 * Add the given element to this scope without checking for duplication or hid ing.
9111 * @param name the name of the element to be added
9112 * @param element the element to be added to this scope
9113 */
9114 void defineWithoutChecking2(String name, Element element) {
9115 _definedNames[name] = element;
9116 }
9117
7174 /** 9118 /**
7175 * Return the element representing the library in which this scope is enclosed . 9119 * Return the element representing the library in which this scope is enclosed .
7176 * @return the element representing the library in which this scope is enclose d 9120 * @return the element representing the library in which this scope is enclose d
7177 */ 9121 */
7178 LibraryElement get definingLibrary; 9122 LibraryElement get definingLibrary;
9123
7179 /** 9124 /**
7180 * Return the error code to be used when reporting that a name being defined l ocally conflicts 9125 * Return the error code to be used when reporting that a name being defined l ocally conflicts
7181 * with another element of the same name in the local scope. 9126 * with another element of the same name in the local scope.
7182 * @param existing the first element to be declared with the conflicting name 9127 * @param existing the first element to be declared with the conflicting name
7183 * @param duplicate another element declared with the conflicting name 9128 * @param duplicate another element declared with the conflicting name
7184 * @return the error code used to report duplicate names within a scope 9129 * @return the error code used to report duplicate names within a scope
7185 */ 9130 */
7186 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) { 9131 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
7187 Source source2 = duplicate.source; 9132 Source source2 = duplicate.source;
7188 if (source2 == null) { 9133 if (source2 == null) {
7189 source2 = source; 9134 source2 = source;
7190 } 9135 }
7191 return new AnalysisError.con2(source2, duplicate.nameOffset, duplicate.name. length, CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.name]); 9136 return new AnalysisError.con2(source2, duplicate.nameOffset, duplicate.displ ayName.length, CompileTimeErrorCode.DUPLICATE_DEFINITION, [existing.displayName] );
7192 } 9137 }
9138
7193 /** 9139 /**
7194 * Return the listener that is to be informed when an error is encountered. 9140 * Return the listener that is to be informed when an error is encountered.
7195 * @return the listener that is to be informed when an error is encountered 9141 * @return the listener that is to be informed when an error is encountered
7196 */ 9142 */
7197 AnalysisErrorListener get errorListener; 9143 AnalysisErrorListener get errorListener;
9144
7198 /** 9145 /**
7199 * Return the source object representing the compilation unit with which error s related to this 9146 * Return the source object representing the compilation unit with which error s related to this
7200 * scope should be associated. 9147 * scope should be associated.
7201 * @return the source object with which errors should be associated 9148 * @return the source object with which errors should be associated
7202 */ 9149 */
7203 Source get source => definingLibrary.definingCompilationUnit.source; 9150 Source get source => definingLibrary.definingCompilationUnit.source;
9151
7204 /** 9152 /**
7205 * Return the element with which the given name is associated, or {@code null} if the name is not 9153 * Return the element with which the given name is associated, or {@code null} if the name is not
7206 * defined within this scope. This method only returns elements that are direc tly defined within 9154 * defined within this scope. This method only returns elements that are direc tly defined within
7207 * this scope, not elements that are defined in an enclosing scope. 9155 * this scope, not elements that are defined in an enclosing scope.
7208 * @param name the name associated with the element to be returned 9156 * @param name the name associated with the element to be returned
7209 * @param referencingLibrary the library that contains the reference to the na me, used to 9157 * @param referencingLibrary the library that contains the reference to the na me, used to
7210 * implement library-level privacy 9158 * implement library-level privacy
7211 * @return the element with which the given name is associated 9159 * @return the element with which the given name is associated
7212 */ 9160 */
7213 Element localLookup(String name, LibraryElement referencingLibrary) => _define dNames[name]; 9161 Element localLookup(String name, LibraryElement referencingLibrary) => _define dNames[name];
9162
7214 /** 9163 /**
7215 * Return the element with which the given name is associated, or {@code null} if the name is not 9164 * Return the element with which the given name is associated, or {@code null} if the name is not
7216 * defined within this scope. 9165 * defined within this scope.
9166 * @param identifier the identifier node to lookup element for, used to report correct kind of a
9167 * problem and associate problem with
7217 * @param name the name associated with the element to be returned 9168 * @param name the name associated with the element to be returned
7218 * @param referencingLibrary the library that contains the reference to the na me, used to 9169 * @param referencingLibrary the library that contains the reference to the na me, used to
7219 * implement library-level privacy 9170 * implement library-level privacy
7220 * @return the element with which the given name is associated 9171 * @return the element with which the given name is associated
7221 */ 9172 */
7222 Element lookup3(String name, LibraryElement referencingLibrary); 9173 Element lookup3(Identifier identifier, String name, LibraryElement referencing Library);
9174
7223 /** 9175 /**
7224 * Return the name that will be used to look up the given element. 9176 * Return the name that will be used to look up the given element.
7225 * @param element the element whose look-up name is to be returned 9177 * @param element the element whose look-up name is to be returned
7226 * @return the name that will be used to look up the given element 9178 * @return the name that will be used to look up the given element
7227 */ 9179 */
7228 String getName(Element element) { 9180 String getName(Element element) {
7229 if (element is MethodElement) { 9181 if (element is MethodElement) {
7230 MethodElement method = element as MethodElement; 9182 MethodElement method = element as MethodElement;
7231 if (method.name == "-" && method.parameters.length == 0) { 9183 if (method.name == "-" && method.parameters.length == 0) {
7232 return UNARY_MINUS; 9184 return UNARY_MINUS;
7233 } 9185 }
7234 } else if (element is PropertyAccessorElement) {
7235 PropertyAccessorElement accessor = element as PropertyAccessorElement;
7236 if (accessor.isSetter()) {
7237 return "${accessor.name}${SETTER_SUFFIX}";
7238 }
7239 } 9186 }
7240 return element.name; 9187 return element.name;
7241 } 9188 }
7242 } 9189 }
9190
7243 /** 9191 /**
7244 * Instances of the class {@code ConstantVerifier} traverse an AST structure loo king for additional 9192 * Instances of the class {@code ConstantVerifier} traverse an AST structure loo king for additional
7245 * errors and warnings not covered by the parser and resolver. In particular, it looks for errors 9193 * errors and warnings not covered by the parser and resolver. In particular, it looks for errors
7246 * and warnings related to constant expressions. 9194 * and warnings related to constant expressions.
7247 * @coverage dart.engine.resolver 9195 * @coverage dart.engine.resolver
7248 */ 9196 */
7249 class ConstantVerifier extends RecursiveASTVisitor<Object> { 9197 class ConstantVerifier extends RecursiveASTVisitor<Object> {
9198
7250 /** 9199 /**
7251 * The error reporter by which errors will be reported. 9200 * The error reporter by which errors will be reported.
7252 */ 9201 */
7253 ErrorReporter _errorReporter; 9202 ErrorReporter _errorReporter;
9203
9204 /**
9205 * The type representing the type 'bool'.
9206 */
9207 InterfaceType _boolType;
9208
9209 /**
9210 * The type representing the type 'int'.
9211 */
9212 InterfaceType _intType;
9213
9214 /**
9215 * The type representing the type 'num'.
9216 */
9217 InterfaceType _numType;
9218
9219 /**
9220 * The type representing the type 'string'.
9221 */
9222 InterfaceType _stringType;
9223
7254 /** 9224 /**
7255 * Initialize a newly created constant verifier. 9225 * Initialize a newly created constant verifier.
7256 * @param errorReporter the error reporter by which errors will be reported 9226 * @param errorReporter the error reporter by which errors will be reported
7257 */ 9227 */
7258 ConstantVerifier(ErrorReporter errorReporter) { 9228 ConstantVerifier(ErrorReporter errorReporter, TypeProvider typeProvider) {
7259 this._errorReporter = errorReporter; 9229 this._errorReporter = errorReporter;
9230 this._boolType = typeProvider.boolType;
9231 this._intType = typeProvider.intType;
9232 this._numType = typeProvider.numType;
9233 this._stringType = typeProvider.stringType;
9234 }
9235 Object visitConstructorDeclaration(ConstructorDeclaration node) {
9236 if (node.constKeyword != null) {
9237 validateInitializers(node);
9238 }
9239 return super.visitConstructorDeclaration(node);
7260 } 9240 }
7261 Object visitFunctionExpression(FunctionExpression node) { 9241 Object visitFunctionExpression(FunctionExpression node) {
7262 super.visitFunctionExpression(node); 9242 super.visitFunctionExpression(node);
7263 validateDefaultValues(node.parameters); 9243 validateDefaultValues(node.parameters);
7264 return null; 9244 return null;
7265 } 9245 }
9246 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
9247 validateConstantArguments(node);
9248 return super.visitInstanceCreationExpression(node);
9249 }
7266 Object visitListLiteral(ListLiteral node) { 9250 Object visitListLiteral(ListLiteral node) {
7267 super.visitListLiteral(node); 9251 super.visitListLiteral(node);
7268 if (node.modifier != null) { 9252 if (node.modifier != null) {
7269 for (Expression element in node.elements) { 9253 for (Expression element in node.elements) {
7270 validate(element, CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT); 9254 validate(element, CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT);
7271 } 9255 }
7272 } 9256 }
7273 return null; 9257 return null;
7274 } 9258 }
7275 Object visitMapLiteral(MapLiteral node) { 9259 Object visitMapLiteral(MapLiteral node) {
7276 super.visitMapLiteral(node); 9260 super.visitMapLiteral(node);
7277 bool isConst = node.modifier != null; 9261 bool isConst = node.modifier != null;
7278 Set<String> keys = new Set<String>(); 9262 bool reportEqualKeys = true;
9263 Set<Object> keys = new Set<Object>();
9264 List<Expression> invalidKeys = new List<Expression>();
7279 for (MapLiteralEntry entry in node.entries) { 9265 for (MapLiteralEntry entry in node.entries) {
7280 StringLiteral key2 = entry.key; 9266 Expression key2 = entry.key;
7281 EvaluationResultImpl result = validate(key2, CompileTimeErrorCode.NON_CONS TANT_MAP_KEY); 9267 if (isConst) {
7282 if (result is ValidResult && ((result as ValidResult)).value is String) { 9268 EvaluationResultImpl result = validate(key2, CompileTimeErrorCode.NON_CO NSTANT_MAP_KEY);
7283 String value2 = ((result as ValidResult)).value as String; 9269 validate(entry.value, CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE);
7284 if (keys.contains(value2)) { 9270 if (result is ValidResult) {
7285 _errorReporter.reportError(StaticWarningCode.EQUAL_KEYS_IN_MAP, key2, []); 9271 Object value2 = ((result as ValidResult)).value;
9272 if (keys.contains(value2)) {
9273 invalidKeys.add(key2);
9274 } else {
9275 javaSetAdd(keys, value2);
9276 }
9277 }
9278 } else {
9279 EvaluationResultImpl result = key2.accept(new ConstantVisitor());
9280 if (result is ValidResult) {
9281 Object value3 = ((result as ValidResult)).value;
9282 if (keys.contains(value3)) {
9283 invalidKeys.add(key2);
9284 } else {
9285 javaSetAdd(keys, value3);
9286 }
7286 } else { 9287 } else {
7287 javaSetAdd(keys, value2); 9288 reportEqualKeys = false;
7288 } 9289 }
7289 } 9290 }
7290 if (isConst) { 9291 }
7291 validate(entry.value, CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE); 9292 if (reportEqualKeys) {
9293 for (Expression key in invalidKeys) {
9294 _errorReporter.reportError2(StaticWarningCode.EQUAL_KEYS_IN_MAP, key, [] );
7292 } 9295 }
7293 } 9296 }
7294 return null; 9297 return null;
7295 } 9298 }
7296 Object visitMethodDeclaration(MethodDeclaration node) { 9299 Object visitMethodDeclaration(MethodDeclaration node) {
7297 super.visitMethodDeclaration(node); 9300 super.visitMethodDeclaration(node);
7298 validateDefaultValues(node.parameters); 9301 validateDefaultValues(node.parameters);
7299 return null; 9302 return null;
7300 } 9303 }
7301 Object visitSwitchCase(SwitchCase node) { 9304 Object visitSwitchCase(SwitchCase node) {
7302 super.visitSwitchCase(node); 9305 super.visitSwitchCase(node);
7303 validate(node.expression, CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION) ; 9306 validate(node.expression, CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION) ;
7304 return null; 9307 return null;
7305 } 9308 }
7306 Object visitVariableDeclaration(VariableDeclaration node) { 9309 Object visitVariableDeclaration(VariableDeclaration node) {
7307 super.visitVariableDeclaration(node); 9310 super.visitVariableDeclaration(node);
7308 Expression initializer2 = node.initializer; 9311 Expression initializer2 = node.initializer;
7309 if (initializer2 != null && node.isConst()) { 9312 if (initializer2 != null && node.isConst()) {
7310 VariableElementImpl element2 = node.element as VariableElementImpl; 9313 VariableElementImpl element2 = node.element as VariableElementImpl;
7311 EvaluationResultImpl result = element2.evaluationResult; 9314 EvaluationResultImpl result = element2.evaluationResult;
7312 if (result == null) { 9315 if (result == null) {
7313 result = validate(initializer2, CompileTimeErrorCode.CONST_INITIALIZED_W ITH_NON_CONSTANT_VALUE); 9316 result = validate(initializer2, CompileTimeErrorCode.CONST_INITIALIZED_W ITH_NON_CONSTANT_VALUE);
7314 element2.evaluationResult = result; 9317 element2.evaluationResult = result;
7315 } else if (result is ErrorResult) { 9318 } else if (result is ErrorResult) {
7316 reportErrors(result, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CON STANT_VALUE); 9319 reportErrors(result, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CON STANT_VALUE);
7317 } 9320 }
7318 } 9321 }
7319 return null; 9322 return null;
7320 } 9323 }
9324
9325 /**
9326 * Return {@code true} if the given value is the result of evaluating an expre ssion whose value is
9327 * a valid key in a const map literal. Keys in const map literals must be eith er a string, number,
9328 * boolean, list, map, or null.
9329 * @param value
9330 * @return {@code true} if the given value is a valid key in a const map liter al
9331 */
9332 bool isValidConstMapKey(Object value) => true;
9333
7321 /** 9334 /**
7322 * If the given result represents one or more errors, report those errors. Exc ept for special 9335 * If the given result represents one or more errors, report those errors. Exc ept for special
7323 * cases, use the given error code rather than the one reported in the error. 9336 * cases, use the given error code rather than the one reported in the error.
7324 * @param result the result containing any errors that need to be reported 9337 * @param result the result containing any errors that need to be reported
7325 * @param errorCode the error code to be used if the result represents an erro r 9338 * @param errorCode the error code to be used if the result represents an erro r
7326 */ 9339 */
7327 void reportErrors(EvaluationResultImpl result, ErrorCode errorCode) { 9340 void reportErrors(EvaluationResultImpl result, ErrorCode errorCode2) {
7328 if (result is ErrorResult) { 9341 if (result is ErrorResult) {
7329 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) { 9342 for (ErrorResult_ErrorData data in ((result as ErrorResult)).errorData) {
7330 _errorReporter.reportError(errorCode, data.node, []); 9343 ErrorCode dataErrorCode = data.errorCode;
9344 if (identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCE PTION) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM _STRING) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL) || identical(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_INT) || identic al(dataErrorCode, CompileTimeErrorCode.CONST_EVAL_TYPE_NUM)) {
9345 _errorReporter.reportError2(dataErrorCode, data.node, []);
9346 } else {
9347 _errorReporter.reportError2(errorCode2, data.node, []);
9348 }
7331 } 9349 }
7332 } 9350 }
7333 } 9351 }
9352
7334 /** 9353 /**
7335 * Validate that the given expression is a compile time constant. Return the v alue of the compile 9354 * Validate that the given expression is a compile time constant. Return the v alue of the compile
7336 * time constant, or {@code null} if the expression is not a compile time cons tant. 9355 * time constant, or {@code null} if the expression is not a compile time cons tant.
7337 * @param expression the expression to be validated 9356 * @param expression the expression to be validated
7338 * @param errorCode the error code to be used if the expression is not a compi le time constant 9357 * @param errorCode the error code to be used if the expression is not a compi le time constant
7339 * @return the value of the compile time constant 9358 * @return the value of the compile time constant
7340 */ 9359 */
7341 EvaluationResultImpl validate(Expression expression, ErrorCode errorCode) { 9360 EvaluationResultImpl validate(Expression expression, ErrorCode errorCode) {
7342 EvaluationResultImpl result = expression.accept(new ConstantVisitor()); 9361 EvaluationResultImpl result = expression.accept(new ConstantVisitor());
7343 reportErrors(result, errorCode); 9362 reportErrors(result, errorCode);
7344 return result; 9363 return result;
7345 } 9364 }
9365
9366 /**
9367 * Validate that if the passed instance creation is 'const' then all its argum ents are constant
9368 * expressions.
9369 * @param node the instance creation evaluate
9370 */
9371 void validateConstantArguments(InstanceCreationExpression node) {
9372 if (!node.isConst()) {
9373 return;
9374 }
9375 ArgumentList argumentList2 = node.argumentList;
9376 if (argumentList2 == null) {
9377 return;
9378 }
9379 for (Expression argument in argumentList2.arguments) {
9380 if (argument is NamedExpression) {
9381 argument = ((argument as NamedExpression)).expression;
9382 }
9383 validate(argument, CompileTimeErrorCode.CONST_WITH_NON_CONSTANT_ARGUMENT);
9384 }
9385 }
9386
7346 /** 9387 /**
7347 * Validate that the default value associated with each of the parameters in t he given list is a 9388 * Validate that the default value associated with each of the parameters in t he given list is a
7348 * compile time constant. 9389 * compile time constant.
7349 * @param parameters the list of parameters to be validated 9390 * @param parameters the list of parameters to be validated
7350 */ 9391 */
7351 void validateDefaultValues(FormalParameterList parameters2) { 9392 void validateDefaultValues(FormalParameterList parameters2) {
7352 if (parameters2 == null) { 9393 if (parameters2 == null) {
7353 return; 9394 return;
7354 } 9395 }
7355 for (FormalParameter parameter in parameters2.parameters) { 9396 for (FormalParameter parameter in parameters2.parameters) {
7356 if (parameter is DefaultFormalParameter) { 9397 if (parameter is DefaultFormalParameter) {
7357 DefaultFormalParameter defaultParameter = parameter as DefaultFormalPara meter; 9398 DefaultFormalParameter defaultParameter = parameter as DefaultFormalPara meter;
7358 Expression defaultValue2 = defaultParameter.defaultValue; 9399 Expression defaultValue2 = defaultParameter.defaultValue;
7359 if (defaultValue2 != null) { 9400 if (defaultValue2 != null) {
7360 EvaluationResultImpl result = validate(defaultValue2, CompileTimeError Code.NON_CONSTANT_DEFAULT_VALUE); 9401 EvaluationResultImpl result = validate(defaultValue2, CompileTimeError Code.NON_CONSTANT_DEFAULT_VALUE);
7361 if (defaultParameter.isConst()) { 9402 if (defaultParameter.isConst()) {
7362 VariableElementImpl element2 = parameter.element as VariableElementI mpl; 9403 VariableElementImpl element2 = parameter.element as VariableElementI mpl;
7363 element2.evaluationResult = result; 9404 element2.evaluationResult = result;
7364 } 9405 }
7365 } 9406 }
7366 } 9407 }
7367 } 9408 }
7368 } 9409 }
9410
9411 /**
9412 * Validates that the given expression is a compile time constant.
9413 * @param parameterElements the elements of parameters of constant constructor , they are
9414 * considered as a valid potentially constant expressions
9415 * @param expression the expression to validate
9416 */
9417 void validateInitializerExpression(List<ParameterElement> parameterElements, E xpression expression) {
9418 EvaluationResultImpl result = expression.accept(new ConstantVisitor_10(this, parameterElements));
9419 reportErrors(result, CompileTimeErrorCode.NON_CONSTANT_VALUE_IN_INITIALIZER) ;
9420 }
9421
9422 /**
9423 * Validates that all of the arguments of a constructor initializer are compil e time constants.
9424 * @param parameterElements the elements of parameters of constant constructor , they are
9425 * considered as a valid potentially constant expressions
9426 * @param argumentList the argument list to validate
9427 */
9428 void validateInitializerInvocationArguments(List<ParameterElement> parameterEl ements, ArgumentList argumentList) {
9429 if (argumentList == null) {
9430 return;
9431 }
9432 for (Expression argument in argumentList.arguments) {
9433 validateInitializerExpression(parameterElements, argument);
9434 }
9435 }
9436
9437 /**
9438 * Validates that the expressions of the given initializers (of a constant con structor) are all
9439 * compile time constants.
9440 * @param constructor the constant constructor declaration to validate
9441 */
9442 void validateInitializers(ConstructorDeclaration constructor) {
9443 List<ParameterElement> parameterElements = constructor.parameters.elements;
9444 NodeList<ConstructorInitializer> initializers2 = constructor.initializers;
9445 for (ConstructorInitializer initializer in initializers2) {
9446 if (initializer is ConstructorFieldInitializer) {
9447 ConstructorFieldInitializer fieldInitializer = initializer as Constructo rFieldInitializer;
9448 validateInitializerExpression(parameterElements, fieldInitializer.expres sion);
9449 }
9450 if (initializer is RedirectingConstructorInvocation) {
9451 RedirectingConstructorInvocation invocation = initializer as Redirecting ConstructorInvocation;
9452 validateInitializerInvocationArguments(parameterElements, invocation.arg umentList);
9453 }
9454 if (initializer is SuperConstructorInvocation) {
9455 SuperConstructorInvocation invocation = initializer as SuperConstructorI nvocation;
9456 validateInitializerInvocationArguments(parameterElements, invocation.arg umentList);
9457 }
9458 }
9459 }
7369 } 9460 }
9461 class ConstantVisitor_10 extends ConstantVisitor {
9462 final ConstantVerifier ConstantVerifier_this;
9463 List<ParameterElement> parameterElements;
9464 ConstantVisitor_10(this.ConstantVerifier_this, this.parameterElements) : super ();
9465 EvaluationResultImpl visitSimpleIdentifier(SimpleIdentifier node) {
9466 Element element2 = node.element;
9467 for (ParameterElement parameterElement in parameterElements) {
9468 if (identical(parameterElement, element2) && parameterElement != null) {
9469 Type2 type2 = parameterElement.type;
9470 if (type2 != null) {
9471 if (type2.isDynamic()) {
9472 return ValidResult.RESULT_DYNAMIC;
9473 }
9474 if (type2.isSubtypeOf(ConstantVerifier_this._boolType)) {
9475 return ValidResult.RESULT_BOOL;
9476 }
9477 if (type2.isSubtypeOf(ConstantVerifier_this._intType)) {
9478 return ValidResult.RESULT_INT;
9479 }
9480 if (type2.isSubtypeOf(ConstantVerifier_this._numType)) {
9481 return ValidResult.RESULT_NUM;
9482 }
9483 if (type2.isSubtypeOf(ConstantVerifier_this._stringType)) {
9484 return ValidResult.RESULT_STRING;
9485 }
9486 }
9487 return ValidResult.RESULT_OBJECT;
9488 }
9489 }
9490 return super.visitSimpleIdentifier(node);
9491 }
9492 }
9493
7370 /** 9494 /**
7371 * Instances of the class {@code ErrorVerifier} traverse an AST structure lookin g for additional 9495 * Instances of the class {@code ErrorVerifier} traverse an AST structure lookin g for additional
7372 * errors and warnings not covered by the parser and resolver. 9496 * errors and warnings not covered by the parser and resolver.
7373 * @coverage dart.engine.resolver 9497 * @coverage dart.engine.resolver
7374 */ 9498 */
7375 class ErrorVerifier extends RecursiveASTVisitor<Object> { 9499 class ErrorVerifier extends RecursiveASTVisitor<Object> {
9500
9501 /**
9502 * Checks if the given expression is the reference to the type.
9503 * @param expr the expression to evaluate
9504 * @return {@code true} if the given expression is the reference to the type
9505 */
9506 static bool isTypeReference(Expression expr) {
9507 if (expr is Identifier) {
9508 Identifier identifier = expr as Identifier;
9509 return identifier.element is ClassElement;
9510 }
9511 return false;
9512 }
9513
7376 /** 9514 /**
7377 * The error reporter by which errors will be reported. 9515 * The error reporter by which errors will be reported.
7378 */ 9516 */
7379 ErrorReporter _errorReporter; 9517 ErrorReporter _errorReporter;
9518
7380 /** 9519 /**
7381 * The current library that is being analyzed. 9520 * The current library that is being analyzed.
7382 */ 9521 */
7383 LibraryElement _currentLibrary; 9522 LibraryElement _currentLibrary;
9523
7384 /** 9524 /**
7385 * The type representing the type 'dynamic'. 9525 * The type representing the type 'dynamic'.
7386 */ 9526 */
7387 Type2 _dynamicType; 9527 Type2 _dynamicType;
9528
7388 /** 9529 /**
7389 * The object providing access to the types defined by the language. 9530 * The object providing access to the types defined by the language.
7390 */ 9531 */
7391 TypeProvider _typeProvider; 9532 TypeProvider _typeProvider;
9533
9534 /**
9535 * The manager for the inheritance mappings.
9536 */
9537 InheritanceManager _inheritanceManager;
9538
7392 /** 9539 /**
7393 * This is set to {@code true} iff the visitor is currently visiting children nodes of a{@link ConstructorDeclaration} and the constructor is 'const'. 9540 * This is set to {@code true} iff the visitor is currently visiting children nodes of a{@link ConstructorDeclaration} and the constructor is 'const'.
7394 * @see #visitConstructorDeclaration(ConstructorDeclaration) 9541 * @see #visitConstructorDeclaration(ConstructorDeclaration)
7395 */ 9542 */
7396 bool _isEnclosingConstructorConst = false; 9543 bool _isEnclosingConstructorConst = false;
9544
7397 /** 9545 /**
7398 * This is set to {@code true} iff the visitor is currently visiting children nodes of a{@link CatchClause}. 9546 * This is set to {@code true} iff the visitor is currently visiting children nodes of a{@link CatchClause}.
7399 * @see #visitCatchClause(CatchClause) 9547 * @see #visitCatchClause(CatchClause)
7400 */ 9548 */
7401 bool _isInCatchClause = false; 9549 bool _isInCatchClause = false;
9550
9551 /**
9552 * This is set to {@code true} iff the visitor is currently visiting a{@link C onstructorInitializer}.
9553 */
9554 bool _isInConstructorInitializer = false;
9555
7402 /** 9556 /**
7403 * This is set to {@code true} iff the visitor is currently visiting code in t he SDK. 9557 * This is set to {@code true} iff the visitor is currently visiting code in t he SDK.
7404 */ 9558 */
7405 bool _isInSystemLibrary = false; 9559 bool _isInSystemLibrary = false;
9560
7406 /** 9561 /**
7407 * The class containing the AST nodes being visited, or {@code null} if we are not in the scope of 9562 * The class containing the AST nodes being visited, or {@code null} if we are not in the scope of
7408 * a class. 9563 * a class.
7409 */ 9564 */
7410 ClassElement _enclosingClass; 9565 ClassElement _enclosingClass;
9566
7411 /** 9567 /**
7412 * The method or function that we are currently visiting, or {@code null} if w e are not inside a 9568 * The method or function that we are currently visiting, or {@code null} if w e are not inside a
7413 * method or function. 9569 * method or function.
7414 */ 9570 */
7415 ExecutableElement _enclosingFunction; 9571 ExecutableElement _enclosingFunction;
9572
7416 /** 9573 /**
7417 * This map is initialized when visiting the contents of a class declaration. If the visitor is 9574 * This map is initialized when visiting the contents of a class declaration. If the visitor is
7418 * not in an enclosing class declaration, then the map is set to {@code null}. 9575 * not in an enclosing class declaration, then the map is set to {@code null}.
7419 * <p> 9576 * <p>
7420 * When set the map maps the set of {@link FieldElement}s in the class to an{@ link INIT_STATE#NOT_INIT} or {@link INIT_STATE#INIT_IN_DECLARATION}. <code>check For*</code> 9577 * When set the map maps the set of {@link FieldElement}s in the class to an{@ link INIT_STATE#NOT_INIT} or {@link INIT_STATE#INIT_IN_DECLARATION}. <code>check For*</code>
7421 * methods, specifically {@link #checkForAllFinalInitializedErrorCodes(Constru ctorDeclaration)}, 9578 * methods, specifically {@link #checkForAllFinalInitializedErrorCodes(Constru ctorDeclaration)},
7422 * can make a copy of the map to compute error code states. <code>checkFor*</c ode> methods should 9579 * can make a copy of the map to compute error code states. <code>checkFor*</c ode> methods should
7423 * only ever make a copy, or read from this map after it has been set in{@link #visitClassDeclaration(ClassDeclaration)}. 9580 * only ever make a copy, or read from this map after it has been set in{@link #visitClassDeclaration(ClassDeclaration)}.
7424 * @see #visitClassDeclaration(ClassDeclaration) 9581 * @see #visitClassDeclaration(ClassDeclaration)
7425 * @see #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration) 9582 * @see #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration)
7426 */ 9583 */
7427 Map<FieldElement, INIT_STATE> _initialFieldElementsMap; 9584 Map<FieldElement, INIT_STATE> _initialFieldElementsMap;
9585
9586 /**
9587 * A table mapping name of the library to the export directive which export th is library.
9588 */
9589 Map<String, LibraryElement> _nameToExportElement = new Map<String, LibraryElem ent>();
9590
9591 /**
9592 * A table mapping name of the library to the import directive which import th is library.
9593 */
9594 Map<String, LibraryElement> _nameToImportElement = new Map<String, LibraryElem ent>();
9595
9596 /**
9597 * A table mapping names to the export elements exported them.
9598 */
9599 Map<String, ExportElement> _exportedNames = new Map<String, ExportElement>();
9600
9601 /**
9602 * A set of the names of the variable initializers we are visiting now.
9603 */
9604 Set<String> _namesForReferenceToDeclaredVariableInInitializer = new Set<String >();
9605
7428 /** 9606 /**
7429 * A list of types used by the {@link CompileTimeErrorCode#EXTENDS_DISALLOWED_ CLASS} and{@link CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS} error codes. 9607 * A list of types used by the {@link CompileTimeErrorCode#EXTENDS_DISALLOWED_ CLASS} and{@link CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS} error codes.
7430 */ 9608 */
7431 List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT; 9609 List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT;
7432 ErrorVerifier(ErrorReporter errorReporter, LibraryElement currentLibrary, Type Provider typeProvider) { 9610 ErrorVerifier(ErrorReporter errorReporter, LibraryElement currentLibrary, Type Provider typeProvider, InheritanceManager inheritanceManager) {
7433 this._errorReporter = errorReporter; 9611 this._errorReporter = errorReporter;
7434 this._currentLibrary = currentLibrary; 9612 this._currentLibrary = currentLibrary;
7435 this._isInSystemLibrary = currentLibrary.source.isInSystemLibrary(); 9613 this._isInSystemLibrary = currentLibrary.source.isInSystemLibrary();
7436 this._typeProvider = typeProvider; 9614 this._typeProvider = typeProvider;
9615 this._inheritanceManager = inheritanceManager;
7437 _isEnclosingConstructorConst = false; 9616 _isEnclosingConstructorConst = false;
7438 _isInCatchClause = false; 9617 _isInCatchClause = false;
7439 _dynamicType = typeProvider.dynamicType; 9618 _dynamicType = typeProvider.dynamicType;
7440 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = <InterfaceType> [typeProvider.num Type, typeProvider.intType, typeProvider.doubleType, typeProvider.boolType, type Provider.stringType]; 9619 _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT = <InterfaceType> [typeProvider.num Type, typeProvider.intType, typeProvider.doubleType, typeProvider.boolType, type Provider.stringType];
7441 } 9620 }
7442 Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) { 9621 Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) {
7443 checkForArgumentDefinitionTestNonParameter(node); 9622 checkForArgumentDefinitionTestNonParameter(node);
7444 return super.visitArgumentDefinitionTest(node); 9623 return super.visitArgumentDefinitionTest(node);
7445 } 9624 }
9625 Object visitArgumentList(ArgumentList node) {
9626 checkForArgumentTypeNotAssignable(node);
9627 return super.visitArgumentList(node);
9628 }
7446 Object visitAssertStatement(AssertStatement node) { 9629 Object visitAssertStatement(AssertStatement node) {
7447 checkForNonBoolExpression(node); 9630 checkForNonBoolExpression(node);
7448 return super.visitAssertStatement(node); 9631 return super.visitAssertStatement(node);
7449 } 9632 }
7450 Object visitAssignmentExpression(AssignmentExpression node) { 9633 Object visitAssignmentExpression(AssignmentExpression node) {
7451 checkForInvalidAssignment(node); 9634 sc.Token operator2 = node.operator;
9635 sc.TokenType operatorType = operator2.type;
9636 if (identical(operatorType, sc.TokenType.EQ)) {
9637 checkForInvalidAssignment2(node.leftHandSide, node.rightHandSide);
9638 } else {
9639 checkForInvalidAssignment(node);
9640 }
9641 checkForAssignmentToFinal(node);
7452 return super.visitAssignmentExpression(node); 9642 return super.visitAssignmentExpression(node);
7453 } 9643 }
9644 Object visitBinaryExpression(BinaryExpression node) {
9645 checkForArgumentTypeNotAssignable2(node.rightOperand);
9646 return super.visitBinaryExpression(node);
9647 }
7454 Object visitCatchClause(CatchClause node) { 9648 Object visitCatchClause(CatchClause node) {
7455 bool previousIsInCatchClause = _isInCatchClause; 9649 bool previousIsInCatchClause = _isInCatchClause;
7456 try { 9650 try {
7457 _isInCatchClause = true; 9651 _isInCatchClause = true;
7458 return super.visitCatchClause(node); 9652 return super.visitCatchClause(node);
7459 } finally { 9653 } finally {
7460 _isInCatchClause = previousIsInCatchClause; 9654 _isInCatchClause = previousIsInCatchClause;
7461 } 9655 }
7462 } 9656 }
7463 Object visitClassDeclaration(ClassDeclaration node) { 9657 Object visitClassDeclaration(ClassDeclaration node) {
7464 ClassElement outerClass = _enclosingClass; 9658 ClassElement outerClass = _enclosingClass;
7465 try { 9659 try {
7466 _enclosingClass = node.element; 9660 _enclosingClass = node.element;
9661 WithClause withClause2 = node.withClause;
9662 ImplementsClause implementsClause2 = node.implementsClause;
9663 ExtendsClause extendsClause2 = node.extendsClause;
7467 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_I DENTIFIER_AS_TYPE_NAME); 9664 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_I DENTIFIER_AS_TYPE_NAME);
9665 checkForMemberWithClassName();
9666 checkForAllMixinErrorCodes(withClause2);
9667 if (implementsClause2 != null || extendsClause2 != null) {
9668 if (!checkForImplementsDisallowedClass(implementsClause2) && !checkForEx tendsDisallowedClass(extendsClause2)) {
9669 checkForNonAbstractClassInheritsAbstractMember(node);
9670 checkForInconsistentMethodInheritance();
9671 checkForRecursiveInterfaceInheritance(_enclosingClass, new List<ClassE lement>());
9672 }
9673 }
7468 ClassElement classElement = node.element; 9674 ClassElement classElement = node.element;
7469 if (classElement != null) { 9675 if (classElement != null) {
7470 List<FieldElement> fieldElements = classElement.fields; 9676 List<FieldElement> fieldElements = classElement.fields;
7471 _initialFieldElementsMap = new Map<FieldElement, INIT_STATE>(); 9677 _initialFieldElementsMap = new Map<FieldElement, INIT_STATE>();
7472 for (FieldElement fieldElement in fieldElements) { 9678 for (FieldElement fieldElement in fieldElements) {
7473 if (!fieldElement.isSynthetic()) { 9679 if (!fieldElement.isSynthetic()) {
7474 _initialFieldElementsMap[fieldElement] = fieldElement.initializer == null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION; 9680 _initialFieldElementsMap[fieldElement] = fieldElement.initializer == null ? INIT_STATE.NOT_INIT : INIT_STATE.INIT_IN_DECLARATION;
7475 } 9681 }
7476 } 9682 }
7477 } 9683 }
7478 checkForFinalNotInitialized(node); 9684 checkForFinalNotInitialized(node);
7479 return super.visitClassDeclaration(node); 9685 return super.visitClassDeclaration(node);
7480 } finally { 9686 } finally {
7481 _initialFieldElementsMap = null; 9687 _initialFieldElementsMap = null;
7482 _enclosingClass = outerClass; 9688 _enclosingClass = outerClass;
7483 } 9689 }
7484 } 9690 }
7485 Object visitClassTypeAlias(ClassTypeAlias node) { 9691 Object visitClassTypeAlias(ClassTypeAlias node) {
7486 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE NTIFIER_AS_TYPEDEF_NAME); 9692 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE NTIFIER_AS_TYPEDEF_NAME);
9693 checkForAllMixinErrorCodes(node.withClause);
9694 ClassElement outerClassElement = _enclosingClass;
9695 try {
9696 _enclosingClass = node.element;
9697 checkForRecursiveInterfaceInheritance(node.element, new List<ClassElement> ());
9698 } finally {
9699 _enclosingClass = outerClassElement;
9700 }
7487 return super.visitClassTypeAlias(node); 9701 return super.visitClassTypeAlias(node);
7488 } 9702 }
7489 Object visitConditionalExpression(ConditionalExpression node) { 9703 Object visitConditionalExpression(ConditionalExpression node) {
7490 checkForNonBoolCondition(node.condition); 9704 checkForNonBoolCondition(node.condition);
7491 return super.visitConditionalExpression(node); 9705 return super.visitConditionalExpression(node);
7492 } 9706 }
7493 Object visitConstructorDeclaration(ConstructorDeclaration node) { 9707 Object visitConstructorDeclaration(ConstructorDeclaration node) {
7494 ExecutableElement outerFunction = _enclosingFunction; 9708 ExecutableElement outerFunction = _enclosingFunction;
7495 try { 9709 try {
7496 _enclosingFunction = node.element; 9710 _enclosingFunction = node.element;
7497 _isEnclosingConstructorConst = node.constKeyword != null; 9711 _isEnclosingConstructorConst = node.constKeyword != null;
7498 checkForConstConstructorWithNonFinalField(node); 9712 checkForConstConstructorWithNonFinalField(node);
7499 checkForConflictingConstructorNameAndMember(node); 9713 checkForConflictingConstructorNameAndMember(node);
7500 checkForAllFinalInitializedErrorCodes(node); 9714 checkForAllFinalInitializedErrorCodes(node);
9715 checkForRedirectingConstructorErrorCodes(node);
9716 checkForMultipleSuperInitializers(node);
9717 checkForRecursiveConstructorRedirect(node);
9718 checkForRecursiveFactoryRedirect(node);
9719 checkForRedirectToInvalidFunction(node);
9720 checkForUndefinedConstructorInInitializerImplicit(node);
9721 checkForRedirectToNonConstConstructor(node);
7501 return super.visitConstructorDeclaration(node); 9722 return super.visitConstructorDeclaration(node);
7502 } finally { 9723 } finally {
7503 _isEnclosingConstructorConst = false; 9724 _isEnclosingConstructorConst = false;
7504 _enclosingFunction = outerFunction; 9725 _enclosingFunction = outerFunction;
7505 } 9726 }
7506 } 9727 }
9728 Object visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
9729 _isInConstructorInitializer = true;
9730 try {
9731 checkForFieldInitializerNotAssignable(node);
9732 return super.visitConstructorFieldInitializer(node);
9733 } finally {
9734 _isInConstructorInitializer = false;
9735 }
9736 }
7507 Object visitDefaultFormalParameter(DefaultFormalParameter node) { 9737 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
7508 checkForPrivateOptionalParameter(node); 9738 checkForPrivateOptionalParameter(node);
7509 return super.visitDefaultFormalParameter(node); 9739 return super.visitDefaultFormalParameter(node);
7510 } 9740 }
7511 Object visitDoStatement(DoStatement node) { 9741 Object visitDoStatement(DoStatement node) {
7512 checkForNonBoolCondition(node.condition); 9742 checkForNonBoolCondition(node.condition);
7513 return super.visitDoStatement(node); 9743 return super.visitDoStatement(node);
7514 } 9744 }
7515 Object visitExtendsClause(ExtendsClause node) { 9745 Object visitExportDirective(ExportDirective node) {
7516 checkForExtendsDisallowedClass(node); 9746 checkForAmbiguousExport(node);
7517 return super.visitExtendsClause(node); 9747 checkForExportDuplicateLibraryName(node);
9748 checkForExportInternalLibrary(node);
9749 return super.visitExportDirective(node);
7518 } 9750 }
7519 Object visitFieldFormalParameter(FieldFormalParameter node) { 9751 Object visitFieldFormalParameter(FieldFormalParameter node) {
7520 checkForConstFormalParameter(node); 9752 checkForConstFormalParameter(node);
7521 checkForFieldInitializerOutsideConstructor(node); 9753 checkForFieldInitializingFormalRedirectingConstructor(node);
7522 return super.visitFieldFormalParameter(node); 9754 return super.visitFieldFormalParameter(node);
7523 } 9755 }
7524 Object visitFunctionDeclaration(FunctionDeclaration node) { 9756 Object visitFunctionDeclaration(FunctionDeclaration node) {
7525 ExecutableElement outerFunction = _enclosingFunction; 9757 ExecutableElement outerFunction = _enclosingFunction;
7526 try { 9758 try {
9759 SimpleIdentifier identifier = node.name;
9760 String methoName = "";
9761 if (identifier != null) {
9762 methoName = identifier.name;
9763 }
7527 _enclosingFunction = node.element; 9764 _enclosingFunction = node.element;
9765 if (node.isSetter() || node.isGetter()) {
9766 checkForMismatchedAccessorTypes(node, methoName);
9767 if (node.isSetter()) {
9768 FunctionExpression functionExpression2 = node.functionExpression;
9769 if (functionExpression2 != null) {
9770 checkForWrongNumberOfParametersForSetter(node.name, functionExpressi on2.parameters);
9771 }
9772 TypeName returnType2 = node.returnType;
9773 checkForNonVoidReturnTypeForSetter(returnType2);
9774 }
9775 }
7528 return super.visitFunctionDeclaration(node); 9776 return super.visitFunctionDeclaration(node);
7529 } finally { 9777 } finally {
7530 _enclosingFunction = outerFunction; 9778 _enclosingFunction = outerFunction;
7531 } 9779 }
7532 } 9780 }
7533 Object visitFunctionExpression(FunctionExpression node) { 9781 Object visitFunctionExpression(FunctionExpression node) {
7534 ExecutableElement outerFunction = _enclosingFunction; 9782 ExecutableElement outerFunction = _enclosingFunction;
7535 try { 9783 try {
7536 _enclosingFunction = node.element; 9784 _enclosingFunction = node.element;
7537 return super.visitFunctionExpression(node); 9785 return super.visitFunctionExpression(node);
7538 } finally { 9786 } finally {
7539 _enclosingFunction = outerFunction; 9787 _enclosingFunction = outerFunction;
7540 } 9788 }
7541 } 9789 }
7542 Object visitFunctionTypeAlias(FunctionTypeAlias node) { 9790 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
7543 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE NTIFIER_AS_TYPEDEF_NAME); 9791 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE NTIFIER_AS_TYPEDEF_NAME);
7544 checkForDefaultValueInFunctionTypeAlias(node); 9792 checkForDefaultValueInFunctionTypeAlias(node);
7545 return super.visitFunctionTypeAlias(node); 9793 return super.visitFunctionTypeAlias(node);
7546 } 9794 }
7547 Object visitIfStatement(IfStatement node) { 9795 Object visitIfStatement(IfStatement node) {
7548 checkForNonBoolCondition(node.condition); 9796 checkForNonBoolCondition(node.condition);
7549 return super.visitIfStatement(node); 9797 return super.visitIfStatement(node);
7550 } 9798 }
7551 Object visitImplementsClause(ImplementsClause node) { 9799 Object visitImportDirective(ImportDirective node) {
7552 checkForImplementsDisallowedClass(node); 9800 checkForImportDuplicateLibraryName(node);
7553 return super.visitImplementsClause(node); 9801 checkForImportInternalLibrary(node);
9802 return super.visitImportDirective(node);
9803 }
9804 Object visitIndexExpression(IndexExpression node) {
9805 checkForArgumentTypeNotAssignable2(node.index);
9806 return super.visitIndexExpression(node);
7554 } 9807 }
7555 Object visitInstanceCreationExpression(InstanceCreationExpression node) { 9808 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
7556 ConstructorName constructorName2 = node.constructorName; 9809 ConstructorName constructorName2 = node.constructorName;
7557 TypeName typeName = constructorName2.type; 9810 TypeName typeName = constructorName2.type;
7558 Type2 type2 = typeName.type; 9811 Type2 type2 = typeName.type;
7559 if (type2 is InterfaceType) { 9812 if (type2 is InterfaceType) {
7560 InterfaceType interfaceType = type2 as InterfaceType; 9813 InterfaceType interfaceType = type2 as InterfaceType;
7561 checkForConstWithNonConst(node);
7562 checkForConstOrNewWithAbstractClass(node, typeName, interfaceType); 9814 checkForConstOrNewWithAbstractClass(node, typeName, interfaceType);
9815 if (node.isConst()) {
9816 checkForConstWithNonConst(node);
9817 checkForConstWithUndefinedConstructor(node);
9818 checkForConstWithTypeParameters(node);
9819 } else {
9820 checkForNewWithUndefinedConstructor(node);
9821 }
7563 checkForTypeArgumentNotMatchingBounds(node, constructorName2.element, type Name); 9822 checkForTypeArgumentNotMatchingBounds(node, constructorName2.element, type Name);
7564 } 9823 }
7565 return super.visitInstanceCreationExpression(node); 9824 return super.visitInstanceCreationExpression(node);
7566 } 9825 }
7567 Object visitListLiteral(ListLiteral node) { 9826 Object visitListLiteral(ListLiteral node) {
7568 if (node.modifier != null) { 9827 if (node.modifier != null) {
7569 TypeArgumentList typeArguments2 = node.typeArguments; 9828 TypeArgumentList typeArguments2 = node.typeArguments;
7570 if (typeArguments2 != null) { 9829 if (typeArguments2 != null) {
7571 NodeList<TypeName> arguments2 = typeArguments2.arguments; 9830 NodeList<TypeName> arguments2 = typeArguments2.arguments;
7572 if (arguments2.length != 0) { 9831 if (arguments2.length != 0) {
7573 checkForInvalidTypeArgumentInConstTypedLiteral(arguments2, CompileTime ErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST); 9832 checkForInvalidTypeArgumentInConstTypedLiteral(arguments2, CompileTime ErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_LIST);
7574 } 9833 }
7575 } 9834 }
7576 } 9835 }
7577 return super.visitListLiteral(node); 9836 return super.visitListLiteral(node);
7578 } 9837 }
7579 Object visitMapLiteral(MapLiteral node) { 9838 Object visitMapLiteral(MapLiteral node) {
7580 TypeArgumentList typeArguments2 = node.typeArguments; 9839 TypeArgumentList typeArguments2 = node.typeArguments;
7581 if (typeArguments2 != null) { 9840 if (typeArguments2 != null) {
7582 NodeList<TypeName> arguments2 = typeArguments2.arguments; 9841 NodeList<TypeName> arguments2 = typeArguments2.arguments;
7583 if (arguments2.length != 0) { 9842 if (arguments2.length != 0) {
7584 checkForInvalidTypeArgumentForKey(arguments2); 9843 checkForInvalidTypeArgumentForKey(arguments2);
7585 if (node.modifier != null) { 9844 if (node.modifier != null) {
7586 checkForInvalidTypeArgumentInConstTypedLiteral(arguments2, CompileTime ErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP); 9845 checkForInvalidTypeArgumentInConstTypedLiteral(arguments2, CompileTime ErrorCode.INVALID_TYPE_ARGUMENT_IN_CONST_MAP);
7587 } 9846 }
7588 } 9847 }
7589 } 9848 }
9849 checkForNonConstMapAsExpressionStatement(node);
7590 return super.visitMapLiteral(node); 9850 return super.visitMapLiteral(node);
7591 } 9851 }
7592 Object visitMethodDeclaration(MethodDeclaration node) { 9852 Object visitMethodDeclaration(MethodDeclaration node) {
7593 ExecutableElement previousFunction = _enclosingFunction; 9853 ExecutableElement previousFunction = _enclosingFunction;
7594 try { 9854 try {
7595 _enclosingFunction = node.element; 9855 _enclosingFunction = node.element;
7596 if (node.isSetter()) { 9856 SimpleIdentifier identifier = node.name;
7597 checkForWrongNumberOfParametersForSetter(node); 9857 String methoName = "";
9858 if (identifier != null) {
9859 methoName = identifier.name;
9860 }
9861 if (node.isSetter() || node.isGetter()) {
9862 checkForMismatchedAccessorTypes(node, methoName);
9863 checkForConflictingInstanceGetterAndSuperclassMember(node);
9864 }
9865 if (node.isGetter()) {
9866 checkForConflictingStaticGetterAndInstanceSetter(node);
9867 } else if (node.isSetter()) {
9868 checkForWrongNumberOfParametersForSetter(node.name, node.parameters);
9869 checkForNonVoidReturnTypeForSetter(node.returnType);
9870 checkForConflictingStaticSetterAndInstanceMember(node);
7598 } else if (node.isOperator()) { 9871 } else if (node.isOperator()) {
7599 checkForOptionalParameterInOperator(node); 9872 checkForOptionalParameterInOperator(node);
9873 checkForWrongNumberOfParametersForOperator(node);
9874 checkForNonVoidReturnTypeForOperator(node);
7600 } 9875 }
7601 checkForConcreteClassWithAbstractMember(node); 9876 checkForConcreteClassWithAbstractMember(node);
9877 checkForAllInvalidOverrideErrorCodes(node);
7602 return super.visitMethodDeclaration(node); 9878 return super.visitMethodDeclaration(node);
7603 } finally { 9879 } finally {
7604 _enclosingFunction = previousFunction; 9880 _enclosingFunction = previousFunction;
7605 } 9881 }
7606 } 9882 }
9883 Object visitMethodInvocation(MethodInvocation node) {
9884 checkForStaticAccessToInstanceMember(node.target, node.methodName);
9885 return super.visitMethodInvocation(node);
9886 }
7607 Object visitNativeFunctionBody(NativeFunctionBody node) { 9887 Object visitNativeFunctionBody(NativeFunctionBody node) {
7608 checkForNativeFunctionBodyInNonSDKCode(node); 9888 checkForNativeFunctionBodyInNonSDKCode(node);
7609 return super.visitNativeFunctionBody(node); 9889 return super.visitNativeFunctionBody(node);
7610 } 9890 }
9891 Object visitPostfixExpression(PostfixExpression node) {
9892 checkForAssignmentToFinal2(node.operand);
9893 return super.visitPostfixExpression(node);
9894 }
9895 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
9896 checkForStaticAccessToInstanceMember(node.prefix, node.identifier);
9897 return super.visitPrefixedIdentifier(node);
9898 }
9899 Object visitPrefixExpression(PrefixExpression node) {
9900 if (node.operator.type.isIncrementOperator()) {
9901 checkForAssignmentToFinal2(node.operand);
9902 }
9903 return super.visitPrefixExpression(node);
9904 }
9905 Object visitPropertyAccess(PropertyAccess node) {
9906 checkForStaticAccessToInstanceMember(node.target, node.propertyName);
9907 return super.visitPropertyAccess(node);
9908 }
9909 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
9910 _isInConstructorInitializer = true;
9911 try {
9912 return super.visitRedirectingConstructorInvocation(node);
9913 } finally {
9914 _isInConstructorInitializer = false;
9915 }
9916 }
7611 Object visitRethrowExpression(RethrowExpression node) { 9917 Object visitRethrowExpression(RethrowExpression node) {
7612 checkForRethrowOutsideCatch(node); 9918 checkForRethrowOutsideCatch(node);
7613 return super.visitRethrowExpression(node); 9919 return super.visitRethrowExpression(node);
7614 } 9920 }
7615 Object visitReturnStatement(ReturnStatement node) { 9921 Object visitReturnStatement(ReturnStatement node) {
7616 checkForAllReturnStatementErrorCodes(node); 9922 checkForAllReturnStatementErrorCodes(node);
7617 return super.visitReturnStatement(node); 9923 return super.visitReturnStatement(node);
7618 } 9924 }
7619 Object visitSimpleFormalParameter(SimpleFormalParameter node) { 9925 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
7620 checkForConstFormalParameter(node); 9926 checkForConstFormalParameter(node);
7621 return super.visitSimpleFormalParameter(node); 9927 return super.visitSimpleFormalParameter(node);
7622 } 9928 }
9929 Object visitSimpleIdentifier(SimpleIdentifier node) {
9930 checkForReferenceToDeclaredVariableInInitializer(node);
9931 checkForImplicitThisReferenceInInitializer(node);
9932 return super.visitSimpleIdentifier(node);
9933 }
9934 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
9935 _isInConstructorInitializer = true;
9936 try {
9937 return super.visitSuperConstructorInvocation(node);
9938 } finally {
9939 _isInConstructorInitializer = false;
9940 }
9941 }
7623 Object visitSwitchStatement(SwitchStatement node) { 9942 Object visitSwitchStatement(SwitchStatement node) {
7624 checkForCaseExpressionTypeImplementsEquals(node); 9943 checkForCaseExpressionTypeImplementsEquals(node);
7625 checkForInconsistentCaseExpressionTypes(node); 9944 checkForInconsistentCaseExpressionTypes(node);
9945 checkForSwitchExpressionNotAssignable(node);
9946 checkForCaseBlocksNotTerminated(node);
7626 return super.visitSwitchStatement(node); 9947 return super.visitSwitchStatement(node);
7627 } 9948 }
9949 Object visitThisExpression(ThisExpression node) {
9950 checkForInvalidReferenceToThis(node);
9951 return super.visitThisExpression(node);
9952 }
7628 Object visitThrowExpression(ThrowExpression node) { 9953 Object visitThrowExpression(ThrowExpression node) {
7629 checkForConstEvalThrowsException(node); 9954 checkForConstEvalThrowsException(node);
7630 return super.visitThrowExpression(node); 9955 return super.visitThrowExpression(node);
7631 } 9956 }
7632 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) { 9957 Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
7633 checkForFinalNotInitialized2(node.variables); 9958 checkForFinalNotInitialized2(node.variables);
7634 return super.visitTopLevelVariableDeclaration(node); 9959 return super.visitTopLevelVariableDeclaration(node);
7635 } 9960 }
7636 Object visitTypeParameter(TypeParameter node) { 9961 Object visitTypeParameter(TypeParameter node) {
7637 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE NTIFIER_AS_TYPE_VARIABLE_NAME); 9962 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE NTIFIER_AS_TYPE_VARIABLE_NAME);
7638 return super.visitTypeParameter(node); 9963 return super.visitTypeParameter(node);
7639 } 9964 }
9965 Object visitVariableDeclaration(VariableDeclaration node) {
9966 SimpleIdentifier nameNode = node.name;
9967 Expression initializerNode = node.initializer;
9968 checkForInvalidAssignment2(nameNode, initializerNode);
9969 nameNode.accept(this);
9970 String name2 = nameNode.name;
9971 javaSetAdd(_namesForReferenceToDeclaredVariableInInitializer, name2);
9972 try {
9973 if (initializerNode != null) {
9974 initializerNode.accept(this);
9975 }
9976 } finally {
9977 _namesForReferenceToDeclaredVariableInInitializer.remove(name2);
9978 }
9979 return null;
9980 }
7640 Object visitVariableDeclarationList(VariableDeclarationList node) { 9981 Object visitVariableDeclarationList(VariableDeclarationList node) {
7641 checkForBuiltInIdentifierAsName2(node); 9982 checkForBuiltInIdentifierAsName2(node);
7642 return super.visitVariableDeclarationList(node); 9983 return super.visitVariableDeclarationList(node);
7643 } 9984 }
7644 Object visitVariableDeclarationStatement(VariableDeclarationStatement node) { 9985 Object visitVariableDeclarationStatement(VariableDeclarationStatement node) {
7645 checkForFinalNotInitialized2(node.variables); 9986 checkForFinalNotInitialized2(node.variables);
7646 return super.visitVariableDeclarationStatement(node); 9987 return super.visitVariableDeclarationStatement(node);
7647 } 9988 }
7648 Object visitWhileStatement(WhileStatement node) { 9989 Object visitWhileStatement(WhileStatement node) {
7649 checkForNonBoolCondition(node.condition); 9990 checkForNonBoolCondition(node.condition);
7650 return super.visitWhileStatement(node); 9991 return super.visitWhileStatement(node);
7651 } 9992 }
9993
7652 /** 9994 /**
7653 * This verifies that the passed constructor declaration does not violate any of the error codes 9995 * This verifies that the passed constructor declaration does not violate any of the error codes
7654 * relating to the initialization of fields in the enclosing class. 9996 * relating to the initialization of fields in the enclosing class.
7655 * @param node the {@link ConstructorDeclaration} to evaluate 9997 * @param node the {@link ConstructorDeclaration} to evaluate
7656 * @return return {@code true} if and only if an error code is generated on th e passed node 9998 * @return {@code true} if and only if an error code is generated on the passe d node
7657 * @see #initialFieldElementsMap 9999 * @see #initialFieldElementsMap
7658 * @see CompileTimeErrorCode#FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR 10000 * @see CompileTimeErrorCode#FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR
7659 * @see CompileTimeErrorCode#FINAL_INITIALIZED_MULTIPLE_TIMES 10001 * @see CompileTimeErrorCode#FINAL_INITIALIZED_MULTIPLE_TIMES
7660 */ 10002 */
7661 bool checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) { 10003 bool checkForAllFinalInitializedErrorCodes(ConstructorDeclaration node) {
7662 if (node.factoryKeyword != null || node.redirectedConstructor != null || nod e.externalKeyword != null) { 10004 if (node.factoryKeyword != null || node.redirectedConstructor != null || nod e.externalKeyword != null) {
7663 return false; 10005 return false;
7664 } 10006 }
7665 bool foundError = false; 10007 bool foundError = false;
7666 Map<FieldElement, INIT_STATE> fieldElementsMap = new Map<FieldElement, INIT_ STATE>.from(_initialFieldElementsMap); 10008 Map<FieldElement, INIT_STATE> fieldElementsMap = new Map<FieldElement, INIT_ STATE>.from(_initialFieldElementsMap);
7667 NodeList<FormalParameter> formalParameters = node.parameters.parameters; 10009 NodeList<FormalParameter> formalParameters = node.parameters.parameters;
7668 for (FormalParameter formalParameter in formalParameters) { 10010 for (FormalParameter formalParameter in formalParameters) {
7669 FormalParameter parameter = formalParameter; 10011 FormalParameter parameter = formalParameter;
7670 if (parameter is DefaultFormalParameter) { 10012 if (parameter is DefaultFormalParameter) {
7671 parameter = ((parameter as DefaultFormalParameter)).parameter; 10013 parameter = ((parameter as DefaultFormalParameter)).parameter;
7672 } 10014 }
7673 if (parameter is FieldFormalParameter) { 10015 if (parameter is FieldFormalParameter) {
7674 FieldElement fieldElement = ((parameter.element as FieldFormalParameterE lementImpl)).field; 10016 FieldElement fieldElement = ((parameter.element as FieldFormalParameterE lementImpl)).field;
7675 INIT_STATE state = fieldElementsMap[fieldElement]; 10017 INIT_STATE state = fieldElementsMap[fieldElement];
7676 if (identical(state, INIT_STATE.NOT_INIT)) { 10018 if (identical(state, INIT_STATE.NOT_INIT)) {
7677 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL; 10019 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_FIELD_FORMAL;
7678 } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) { 10020 } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) {
7679 if (fieldElement.isFinal() || fieldElement.isConst()) { 10021 if (fieldElement.isFinal() || fieldElement.isConst()) {
7680 _errorReporter.reportError(CompileTimeErrorCode.FINAL_INITIALIZED_IN _DECLARATION_AND_CONSTRUCTOR, formalParameter.identifier, [fieldElement.name]); 10022 _errorReporter.reportError2(CompileTimeErrorCode.FINAL_INITIALIZED_I N_DECLARATION_AND_CONSTRUCTOR, formalParameter.identifier, [fieldElement.display Name]);
7681 foundError = true; 10023 foundError = true;
7682 } 10024 }
7683 } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) { 10025 } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) {
7684 if (fieldElement.isFinal() || fieldElement.isConst()) { 10026 if (fieldElement.isFinal() || fieldElement.isConst()) {
7685 _errorReporter.reportError(CompileTimeErrorCode.FINAL_INITIALIZED_MU LTIPLE_TIMES, formalParameter.identifier, [fieldElement.name]); 10027 _errorReporter.reportError2(CompileTimeErrorCode.FINAL_INITIALIZED_M ULTIPLE_TIMES, formalParameter.identifier, [fieldElement.displayName]);
7686 foundError = true; 10028 foundError = true;
7687 } 10029 }
7688 } 10030 }
7689 } 10031 }
7690 } 10032 }
7691 NodeList<ConstructorInitializer> initializers2 = node.initializers; 10033 NodeList<ConstructorInitializer> initializers2 = node.initializers;
7692 for (ConstructorInitializer constructorInitializer in initializers2) { 10034 for (ConstructorInitializer constructorInitializer in initializers2) {
7693 if (constructorInitializer is ConstructorFieldInitializer) { 10035 if (constructorInitializer is ConstructorFieldInitializer) {
7694 ConstructorFieldInitializer constructorFieldInitializer = constructorIni tializer as ConstructorFieldInitializer; 10036 ConstructorFieldInitializer constructorFieldInitializer = constructorIni tializer as ConstructorFieldInitializer;
7695 SimpleIdentifier fieldName2 = constructorFieldInitializer.fieldName; 10037 SimpleIdentifier fieldName2 = constructorFieldInitializer.fieldName;
7696 Element element2 = fieldName2.element; 10038 Element element2 = fieldName2.element;
7697 if (element2 is FieldElement) { 10039 if (element2 is FieldElement) {
7698 FieldElement fieldElement = element2 as FieldElement; 10040 FieldElement fieldElement = element2 as FieldElement;
7699 INIT_STATE state = fieldElementsMap[fieldElement]; 10041 INIT_STATE state = fieldElementsMap[fieldElement];
7700 if (identical(state, INIT_STATE.NOT_INIT)) { 10042 if (identical(state, INIT_STATE.NOT_INIT)) {
7701 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_INITIALIZERS; 10043 fieldElementsMap[fieldElement] = INIT_STATE.INIT_IN_INITIALIZERS;
7702 } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) { 10044 } else if (identical(state, INIT_STATE.INIT_IN_DECLARATION)) {
7703 if (fieldElement.isFinal() || fieldElement.isConst()) { 10045 if (fieldElement.isFinal() || fieldElement.isConst()) {
7704 _errorReporter.reportError(CompileTimeErrorCode.FIELD_INITIALIZED_ IN_INITIALIZER_AND_DECLARATION, fieldName2, []); 10046 _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZED _IN_INITIALIZER_AND_DECLARATION, fieldName2, []);
7705 foundError = true; 10047 foundError = true;
7706 } 10048 }
7707 } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) { 10049 } else if (identical(state, INIT_STATE.INIT_IN_FIELD_FORMAL)) {
7708 _errorReporter.reportError(CompileTimeErrorCode.FIELD_INITIALIZED_IN _PARAMETER_AND_INITIALIZER, fieldName2, []); 10050 _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZED_I N_PARAMETER_AND_INITIALIZER, fieldName2, []);
7709 foundError = true; 10051 foundError = true;
7710 } else if (identical(state, INIT_STATE.INIT_IN_INITIALIZERS)) { 10052 } else if (identical(state, INIT_STATE.INIT_IN_INITIALIZERS)) {
7711 _errorReporter.reportError(CompileTimeErrorCode.FIELD_INITIALIZED_BY _MULTIPLE_INITIALIZERS, fieldName2, [fieldElement.name]); 10053 _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZED_B Y_MULTIPLE_INITIALIZERS, fieldName2, [fieldElement.displayName]);
7712 foundError = true; 10054 foundError = true;
7713 } 10055 }
7714 } 10056 }
7715 } 10057 }
7716 } 10058 }
7717 return foundError; 10059 return foundError;
7718 } 10060 }
10061
10062 /**
10063 * This checks the passed method declaration against override-error codes.
10064 * @param node the {@link MethodDeclaration} to evaluate
10065 * @return {@code true} if and only if an error code is generated on the passe d node
10066 * @see StaticWarningCode#INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
10067 * @see CompileTimeErrorCode#INVALID_OVERRIDE_REQUIRED
10068 * @see CompileTimeErrorCode#INVALID_OVERRIDE_POSITIONAL
10069 * @see CompileTimeErrorCode#INVALID_OVERRIDE_NAMED
10070 * @see StaticWarningCode#INVALID_GETTER_OVERRIDE_RETURN_TYPE
10071 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_RETURN_TYPE
10072 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE
10073 * @see StaticWarningCode#INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE
10074 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE
10075 * @see StaticWarningCode#INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE
10076 */
10077 bool checkForAllInvalidOverrideErrorCodes(MethodDeclaration node) {
10078 if (_enclosingClass == null || node.isStatic() || node.body is NativeFunctio nBody) {
10079 return false;
10080 }
10081 ExecutableElement executableElement = node.element;
10082 if (executableElement == null) {
10083 return false;
10084 }
10085 SimpleIdentifier methodName = node.name;
10086 if (methodName.isSynthetic()) {
10087 return false;
10088 }
10089 String methodNameStr = methodName.name;
10090 ExecutableElement overriddenExecutable = _inheritanceManager.lookupInheritan ce(_enclosingClass, executableElement.name);
10091 if (overriddenExecutable == null) {
10092 if (!node.isGetter() && !node.isSetter() && !node.isOperator()) {
10093 Set<ClassElement> visitedClasses = new Set<ClassElement>();
10094 InterfaceType superclassType = _enclosingClass.supertype;
10095 ClassElement superclassElement = superclassType == null ? null : supercl assType.element;
10096 while (superclassElement != null && !visitedClasses.contains(superclassE lement)) {
10097 javaSetAdd(visitedClasses, superclassElement);
10098 List<FieldElement> fieldElts = superclassElement.fields;
10099 for (FieldElement fieldElt in fieldElts) {
10100 if (fieldElt.name == methodNameStr && fieldElt.isStatic()) {
10101 _errorReporter.reportError2(StaticWarningCode.INSTANCE_METHOD_NAME _COLLIDES_WITH_SUPERCLASS_STATIC, methodName, [methodNameStr, fieldElt.enclosing Element.displayName]);
10102 return true;
10103 }
10104 }
10105 List<PropertyAccessorElement> propertyAccessorElts = superclassElement .accessors;
10106 for (PropertyAccessorElement accessorElt in propertyAccessorElts) {
10107 if (accessorElt.name == methodNameStr && accessorElt.isStatic()) {
10108 _errorReporter.reportError2(StaticWarningCode.INSTANCE_METHOD_NAME _COLLIDES_WITH_SUPERCLASS_STATIC, methodName, [methodNameStr, accessorElt.enclos ingElement.displayName]);
10109 return true;
10110 }
10111 }
10112 List<MethodElement> methodElements = superclassElement.methods;
10113 for (MethodElement methodElement in methodElements) {
10114 if (methodElement.name == methodNameStr && methodElement.isStatic()) {
10115 _errorReporter.reportError2(StaticWarningCode.INSTANCE_METHOD_NAME _COLLIDES_WITH_SUPERCLASS_STATIC, methodName, [methodNameStr, methodElement.encl osingElement.displayName]);
10116 return true;
10117 }
10118 }
10119 superclassType = superclassElement.supertype;
10120 superclassElement = superclassType == null ? null : superclassType.ele ment;
10121 }
10122 }
10123 return false;
10124 }
10125 FunctionType overridingFT = executableElement.type;
10126 FunctionType overriddenFT = overriddenExecutable.type;
10127 InterfaceType enclosingType = _enclosingClass.type;
10128 overriddenFT = _inheritanceManager.substituteTypeArgumentsInMemberFromInheri tance(overriddenFT, methodNameStr, enclosingType);
10129 if (overridingFT == null || overriddenFT == null) {
10130 return false;
10131 }
10132 Type2 overridingFTReturnType = overridingFT.returnType;
10133 Type2 overriddenFTReturnType = overriddenFT.returnType;
10134 List<Type2> overridingNormalPT = overridingFT.normalParameterTypes;
10135 List<Type2> overriddenNormalPT = overriddenFT.normalParameterTypes;
10136 List<Type2> overridingPositionalPT = overridingFT.optionalParameterTypes;
10137 List<Type2> overriddenPositionalPT = overriddenFT.optionalParameterTypes;
10138 Map<String, Type2> overridingNamedPT = overridingFT.namedParameterTypes;
10139 Map<String, Type2> overriddenNamedPT = overriddenFT.namedParameterTypes;
10140 if (overridingNormalPT.length != overriddenNormalPT.length) {
10141 _errorReporter.reportError2(CompileTimeErrorCode.INVALID_OVERRIDE_REQUIRED , methodName, [overriddenNormalPT.length, overriddenExecutable.enclosingElement. displayName]);
10142 return true;
10143 }
10144 if (overridingPositionalPT.length < overriddenPositionalPT.length) {
10145 _errorReporter.reportError2(CompileTimeErrorCode.INVALID_OVERRIDE_POSITION AL, methodName, [overriddenPositionalPT.length, overriddenExecutable.enclosingEl ement.displayName]);
10146 return true;
10147 }
10148 Set<String> overridingParameterNameSet = overridingNamedPT.keys.toSet();
10149 JavaIterator<String> overriddenParameterNameIterator = new JavaIterator(over riddenNamedPT.keys.toSet());
10150 while (overriddenParameterNameIterator.hasNext) {
10151 String overriddenParamName = overriddenParameterNameIterator.next();
10152 if (!overridingParameterNameSet.contains(overriddenParamName)) {
10153 _errorReporter.reportError2(CompileTimeErrorCode.INVALID_OVERRIDE_NAMED, methodName, [overriddenParamName, overriddenExecutable.enclosingElement.display Name]);
10154 return true;
10155 }
10156 }
10157 if (overriddenFTReturnType != VoidTypeImpl.instance && !overridingFTReturnTy pe.isAssignableTo(overriddenFTReturnType)) {
10158 _errorReporter.reportError2(!node.isGetter() ? StaticWarningCode.INVALID_M ETHOD_OVERRIDE_RETURN_TYPE : StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TY PE, methodName, [overridingFTReturnType.displayName, overriddenFTReturnType.disp layName, overriddenExecutable.enclosingElement.displayName]);
10159 return true;
10160 }
10161 FormalParameterList formalParameterList = node.parameters;
10162 if (formalParameterList == null) {
10163 return false;
10164 }
10165 NodeList<FormalParameter> parameterNodeList = formalParameterList.parameters ;
10166 int parameterIndex = 0;
10167 for (int i = 0; i < overridingNormalPT.length; i++) {
10168 if (!overridingNormalPT[i].isAssignableTo(overriddenNormalPT[i])) {
10169 _errorReporter.reportError2(!node.isSetter() ? StaticWarningCode.INVALID _METHOD_OVERRIDE_NORMAL_PARAM_TYPE : StaticWarningCode.INVALID_SETTER_OVERRIDE_N ORMAL_PARAM_TYPE, parameterNodeList[parameterIndex], [overridingNormalPT[i].disp layName, overriddenNormalPT[i].displayName, overriddenExecutable.enclosingElemen t.displayName]);
10170 return true;
10171 }
10172 parameterIndex++;
10173 }
10174 for (int i = 0; i < overriddenPositionalPT.length; i++) {
10175 if (!overridingPositionalPT[i].isAssignableTo(overriddenPositionalPT[i])) {
10176 _errorReporter.reportError2(StaticWarningCode.INVALID_METHOD_OVERRIDE_OP TIONAL_PARAM_TYPE, parameterNodeList[parameterIndex], [overridingPositionalPT[i] .displayName, overriddenPositionalPT[i].displayName, overriddenExecutable.enclos ingElement.displayName]);
10177 return true;
10178 }
10179 parameterIndex++;
10180 }
10181 JavaIterator<MapEntry<String, Type2>> overriddenNamedPTIterator = new JavaIt erator(getMapEntrySet(overriddenNamedPT));
10182 while (overriddenNamedPTIterator.hasNext) {
10183 MapEntry<String, Type2> overriddenNamedPTEntry = overriddenNamedPTIterator .next();
10184 Type2 overridingType = overridingNamedPT[overriddenNamedPTEntry.getKey()];
10185 if (overridingType == null) {
10186 continue;
10187 }
10188 if (!overriddenNamedPTEntry.getValue().isAssignableTo(overridingType)) {
10189 NormalFormalParameter parameterToSelect = null;
10190 for (FormalParameter formalParameter in parameterNodeList) {
10191 if (formalParameter is DefaultFormalParameter && identical(formalParam eter.kind, ParameterKind.NAMED)) {
10192 DefaultFormalParameter defaultFormalParameter = formalParameter as D efaultFormalParameter;
10193 NormalFormalParameter normalFormalParameter = defaultFormalParameter .parameter;
10194 if (overriddenNamedPTEntry.getKey() == normalFormalParameter.identif ier.name) {
10195 parameterToSelect = normalFormalParameter;
10196 break;
10197 }
10198 }
10199 }
10200 if (parameterToSelect != null) {
10201 _errorReporter.reportError2(StaticWarningCode.INVALID_METHOD_OVERRIDE_ NAMED_PARAM_TYPE, parameterToSelect, [overridingType.displayName, overriddenName dPTEntry.getValue().displayName, overriddenExecutable.enclosingElement.displayNa me]);
10202 return true;
10203 }
10204 }
10205 }
10206 return false;
10207 }
10208
10209 /**
10210 * This verifies that all classes of the passed 'with' clause are valid.
10211 * @param node the 'with' clause to evaluate
10212 * @return {@code true} if and only if an error code is generated on the passe d node
10213 * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR
10214 * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT
10215 * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER
10216 */
10217 bool checkForAllMixinErrorCodes(WithClause withClause) {
10218 if (withClause == null) {
10219 return false;
10220 }
10221 bool problemReported = false;
10222 for (TypeName mixinName in withClause.mixinTypes) {
10223 Type2 mixinType = mixinName.type;
10224 if (mixinType is! InterfaceType) {
10225 continue;
10226 }
10227 ClassElement mixinElement = ((mixinType as InterfaceType)).element;
10228 problemReported = javaBooleanOr(problemReported, checkForMixinDeclaresCons tructor(mixinName, mixinElement));
10229 problemReported = javaBooleanOr(problemReported, checkForMixinInheritsNotF romObject(mixinName, mixinElement));
10230 problemReported = javaBooleanOr(problemReported, checkForMixinReferencesSu per(mixinName, mixinElement));
10231 }
10232 return problemReported;
10233 }
10234
7719 /** 10235 /**
7720 * This checks that the return statement of the form <i>return e;</i> is not i n a generative 10236 * This checks that the return statement of the form <i>return e;</i> is not i n a generative
7721 * constructor. 10237 * constructor.
7722 * <p> 10238 * <p>
7723 * This checks that return statements without expressions are not in a generat ive constructor and 10239 * This checks that return statements without expressions are not in a generat ive constructor and
7724 * the return type is not assignable to {@code null}; that is, we don't have { @code return;} if 10240 * the return type is not assignable to {@code null}; that is, we don't have { @code return;} if
7725 * the enclosing method has a return type. 10241 * the enclosing method has a return type.
7726 * <p> 10242 * <p>
7727 * This checks that the return type matches the type of the declared return ty pe in the enclosing 10243 * This checks that the return type matches the type of the declared return ty pe in the enclosing
7728 * method or function. 10244 * method or function.
7729 * @param node the return statement to evaluate 10245 * @param node the return statement to evaluate
7730 * @return {@code true} if and only if an error code is generated on the passe d node 10246 * @return {@code true} if and only if an error code is generated on the passe d node
7731 * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR 10247 * @see CompileTimeErrorCode#RETURN_IN_GENERATIVE_CONSTRUCTOR
7732 * @see StaticWarningCode#RETURN_WITHOUT_VALUE 10248 * @see StaticWarningCode#RETURN_WITHOUT_VALUE
7733 * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE 10249 * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
7734 */ 10250 */
7735 bool checkForAllReturnStatementErrorCodes(ReturnStatement node) { 10251 bool checkForAllReturnStatementErrorCodes(ReturnStatement node) {
7736 FunctionType functionType = _enclosingFunction == null ? null : _enclosingFu nction.type; 10252 FunctionType functionType = _enclosingFunction == null ? null : _enclosingFu nction.type;
7737 Type2 expectedReturnType = functionType == null ? DynamicTypeImpl.instance : functionType.returnType; 10253 Type2 expectedReturnType = functionType == null ? DynamicTypeImpl.instance : functionType.returnType;
7738 Expression returnExpression = node.expression; 10254 Expression returnExpression = node.expression;
7739 bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && ! ((_enclosingFunction as ConstructorElement)).isFactory(); 10255 bool isGenerativeConstructor = _enclosingFunction is ConstructorElement && ! ((_enclosingFunction as ConstructorElement)).isFactory();
7740 if (returnExpression != null) { 10256 if (isGenerativeConstructor) {
7741 if (isGenerativeConstructor) { 10257 if (returnExpression == null) {
7742 _errorReporter.reportError(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CON STRUCTOR, returnExpression, []); 10258 return false;
10259 }
10260 _errorReporter.reportError2(CompileTimeErrorCode.RETURN_IN_GENERATIVE_CONS TRUCTOR, returnExpression, []);
10261 return true;
10262 }
10263 if (returnExpression == null) {
10264 if (VoidTypeImpl.instance.isAssignableTo(expectedReturnType)) {
10265 return false;
10266 }
10267 _errorReporter.reportError2(StaticWarningCode.RETURN_WITHOUT_VALUE, node, []);
10268 return true;
10269 }
10270 Type2 staticReturnType = getStaticType(returnExpression);
10271 if (expectedReturnType.isVoid()) {
10272 if (staticReturnType.isVoid() || staticReturnType.isDynamic() || identical (staticReturnType, BottomTypeImpl.instance)) {
10273 return false;
10274 }
10275 _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [staticReturnType.displayName, expectedReturnType.displayName, _enclosingFunction.displayName]);
10276 return true;
10277 }
10278 bool isStaticAssignable = staticReturnType.isAssignableTo(expectedReturnType );
10279 Type2 propagatedReturnType = getPropagatedType(returnExpression);
10280 if (propagatedReturnType == null) {
10281 if (isStaticAssignable) {
10282 return false;
10283 }
10284 _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [staticReturnType.displayName, expectedReturnType.displayName, _enclosingFunction.displayName]);
10285 return true;
10286 } else {
10287 bool isPropagatedAssignable = propagatedReturnType.isAssignableTo(expected ReturnType);
10288 if (isStaticAssignable || isPropagatedAssignable) {
10289 return false;
10290 }
10291 _errorReporter.reportError2(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [staticReturnType.displayName, expectedReturnType.displayName, _enclosingFunction.displayName]);
10292 return true;
10293 }
10294 }
10295
10296 /**
10297 * This verifies that the export namespace of the passed export directive does not export any name
10298 * already exported by other export directive.
10299 * @param node the export directive node to report problem on
10300 * @return {@code true} if and only if an error code is generated on the passe d node
10301 * @see CompileTimeErrorCode#AMBIGUOUS_EXPORT
10302 */
10303 bool checkForAmbiguousExport(ExportDirective node) {
10304 if (node.element is! ExportElement) {
10305 return false;
10306 }
10307 ExportElement exportElement = node.element as ExportElement;
10308 LibraryElement exportedLibrary2 = exportElement.exportedLibrary;
10309 if (exportedLibrary2 == null) {
10310 return false;
10311 }
10312 Namespace namespace = new NamespaceBuilder().createExportNamespace(exportEle ment);
10313 Set<String> newNames = namespace.definedNames.keys.toSet();
10314 for (String name in newNames) {
10315 ExportElement prevElement = _exportedNames[name];
10316 if (prevElement != null && prevElement != exportElement) {
10317 _errorReporter.reportError2(CompileTimeErrorCode.AMBIGUOUS_EXPORT, node, [name, prevElement.exportedLibrary.definingCompilationUnit.displayName, exporte dLibrary2.definingCompilationUnit.displayName]);
7743 return true; 10318 return true;
7744 } 10319 } else {
7745 if (!expectedReturnType.isVoid()) { 10320 _exportedNames[name] = exportElement;
7746 Type2 actualReturnType = getType(returnExpression);
7747 if (!actualReturnType.isAssignableTo(expectedReturnType)) {
7748 _errorReporter.reportError(StaticTypeWarningCode.RETURN_OF_INVALID_TYP E, returnExpression, [actualReturnType.name, expectedReturnType.name, _enclosing Function.name]);
7749 return true;
7750 }
7751 }
7752 } else {
7753 if (!isGenerativeConstructor && !VoidTypeImpl.instance.isAssignableTo(expe ctedReturnType)) {
7754 _errorReporter.reportError(StaticWarningCode.RETURN_WITHOUT_VALUE, node, []);
7755 } 10321 }
7756 } 10322 }
7757 return false; 10323 return false;
7758 } 10324 }
10325
7759 /** 10326 /**
7760 * This verifies that the passed argument definition test identifier is a para meter. 10327 * This verifies that the passed argument definition test identifier is a para meter.
7761 * @param node the {@link ArgumentDefinitionTest} to evaluate 10328 * @param node the {@link ArgumentDefinitionTest} to evaluate
7762 * @return return {@code true} if and only if an error code is generated on th e passed node 10329 * @return {@code true} if and only if an error code is generated on the passe d node
7763 * @see CompileTimeErrorCode#ARGUMENT_DEFINITION_TEST_NON_PARAMETER 10330 * @see CompileTimeErrorCode#ARGUMENT_DEFINITION_TEST_NON_PARAMETER
7764 */ 10331 */
7765 bool checkForArgumentDefinitionTestNonParameter(ArgumentDefinitionTest node) { 10332 bool checkForArgumentDefinitionTestNonParameter(ArgumentDefinitionTest node) {
7766 SimpleIdentifier identifier2 = node.identifier; 10333 SimpleIdentifier identifier2 = node.identifier;
7767 Element element2 = identifier2.element; 10334 Element element2 = identifier2.element;
7768 if (element2 != null && element2 is! ParameterElement) { 10335 if (element2 != null && element2 is! ParameterElement) {
7769 _errorReporter.reportError(CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_N ON_PARAMETER, identifier2, [identifier2.name]); 10336 _errorReporter.reportError2(CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_ NON_PARAMETER, identifier2, [identifier2.name]);
7770 return true; 10337 return true;
7771 } 10338 }
7772 return false; 10339 return false;
7773 } 10340 }
10341
10342 /**
10343 * This verifies that the passed arguments can be assigned to their correspond ing parameters.
10344 * @param node the arguments to evaluate
10345 * @return {@code true} if and only if an error code is generated on the passe d node
10346 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
10347 */
10348 bool checkForArgumentTypeNotAssignable(ArgumentList argumentList) {
10349 if (argumentList == null) {
10350 return false;
10351 }
10352 bool problemReported = false;
10353 for (Expression argument in argumentList.arguments) {
10354 problemReported = javaBooleanOr(problemReported, checkForArgumentTypeNotAs signable2(argument));
10355 }
10356 return problemReported;
10357 }
10358
10359 /**
10360 * This verifies that the passed argument can be assigned to their correspondi ng parameters.
10361 * @param node the argument to evaluate
10362 * @return {@code true} if and only if an error code is generated on the passe d node
10363 * @see StaticWarningCode#ARGUMENT_TYPE_NOT_ASSIGNABLE
10364 */
10365 bool checkForArgumentTypeNotAssignable2(Expression argument) {
10366 if (argument == null) {
10367 return false;
10368 }
10369 ParameterElement parameterElement2 = argument.parameterElement;
10370 if (parameterElement2 == null) {
10371 return false;
10372 }
10373 Type2 parameterType = parameterElement2.type;
10374 if (parameterType == null) {
10375 return false;
10376 }
10377 Type2 staticType = getStaticType(argument);
10378 if (staticType == null) {
10379 return false;
10380 }
10381 if (staticType.isAssignableTo(parameterType)) {
10382 return false;
10383 }
10384 Type2 propagatedType = getPropagatedType(argument);
10385 if (propagatedType != null && propagatedType.isAssignableTo(parameterType)) {
10386 return false;
10387 }
10388 _errorReporter.reportError2(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, argument, [(propagatedType == null ? staticType : propagatedType).displayName, p arameterType.displayName]);
10389 return true;
10390 }
10391
10392 /**
10393 * This verifies that left hand side of the passed assignment expression is no t final.
10394 * @param node the assignment expression to evaluate
10395 * @return {@code true} if and only if an error code is generated on the passe d node
10396 * @see StaticWarningCode#ASSIGNMENT_TO_FINAL
10397 */
10398 bool checkForAssignmentToFinal(AssignmentExpression node) {
10399 Expression leftExpression = node.leftHandSide;
10400 return checkForAssignmentToFinal2(leftExpression);
10401 }
10402
10403 /**
10404 * This verifies that the passed expression is not final.
10405 * @param node the expression to evaluate
10406 * @return {@code true} if and only if an error code is generated on the passe d node
10407 * @see StaticWarningCode#ASSIGNMENT_TO_FINAL
10408 */
10409 bool checkForAssignmentToFinal2(Expression expression) {
10410 Element element = null;
10411 if (expression is Identifier) {
10412 element = ((expression as Identifier)).element;
10413 }
10414 if (expression is PropertyAccess) {
10415 element = ((expression as PropertyAccess)).propertyName.element;
10416 }
10417 if (element is VariableElement) {
10418 VariableElement leftVar = element as VariableElement;
10419 if (leftVar.isFinal()) {
10420 _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_FINAL, expre ssion, []);
10421 return true;
10422 }
10423 return false;
10424 }
10425 if (element is PropertyAccessorElement) {
10426 PropertyAccessorElement leftAccessor = element as PropertyAccessorElement;
10427 if (!leftAccessor.isSetter()) {
10428 _errorReporter.reportError2(StaticWarningCode.ASSIGNMENT_TO_FINAL, expre ssion, []);
10429 return true;
10430 }
10431 return false;
10432 }
10433 return false;
10434 }
10435
7774 /** 10436 /**
7775 * This verifies that the passed identifier is not a keyword, and generates th e passed error code 10437 * This verifies that the passed identifier is not a keyword, and generates th e passed error code
7776 * on the identifier if it is a keyword. 10438 * on the identifier if it is a keyword.
7777 * @param identifier the identifier to check to ensure that it is not a keywor d 10439 * @param identifier the identifier to check to ensure that it is not a keywor d
7778 * @param errorCode if the passed identifier is a keyword then this error code is created on the 10440 * @param errorCode if the passed identifier is a keyword then this error code is created on the
7779 * identifier, the error code will be one of{@link CompileTimeErrorCode#BUILT_ IN_IDENTIFIER_AS_TYPE_NAME},{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_T YPE_VARIABLE_NAME} or{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_ NAME} 10441 * identifier, the error code will be one of{@link CompileTimeErrorCode#BUILT_ IN_IDENTIFIER_AS_TYPE_NAME},{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_T YPE_VARIABLE_NAME} or{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_ NAME}
7780 * @return return {@code true} if and only if an error code is generated on th e passed node 10442 * @return {@code true} if and only if an error code is generated on the passe d node
7781 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME 10443 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME
7782 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME 10444 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME
7783 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME 10445 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME
7784 */ 10446 */
7785 bool checkForBuiltInIdentifierAsName(SimpleIdentifier identifier, ErrorCode er rorCode) { 10447 bool checkForBuiltInIdentifierAsName(SimpleIdentifier identifier, ErrorCode er rorCode) {
7786 sc.Token token2 = identifier.token; 10448 sc.Token token2 = identifier.token;
7787 if (identical(token2.type, sc.TokenType.KEYWORD)) { 10449 if (identical(token2.type, sc.TokenType.KEYWORD)) {
7788 _errorReporter.reportError(errorCode, identifier, [identifier.name]); 10450 _errorReporter.reportError2(errorCode, identifier, [identifier.name]);
7789 return true; 10451 return true;
7790 } 10452 }
7791 return false; 10453 return false;
7792 } 10454 }
10455
7793 /** 10456 /**
7794 * This verifies that the passed variable declaration list does not have a bui lt-in identifier. 10457 * This verifies that the passed variable declaration list does not have a bui lt-in identifier.
7795 * @param node the variable declaration list to check 10458 * @param node the variable declaration list to check
7796 * @return return {@code true} if and only if an error code is generated on th e passed node 10459 * @return {@code true} if and only if an error code is generated on the passe d node
7797 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE 10460 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE
7798 */ 10461 */
7799 bool checkForBuiltInIdentifierAsName2(VariableDeclarationList node) { 10462 bool checkForBuiltInIdentifierAsName2(VariableDeclarationList node) {
7800 TypeName typeName = node.type; 10463 TypeName typeName = node.type;
7801 if (typeName != null) { 10464 if (typeName != null) {
7802 Identifier identifier = typeName.name; 10465 Identifier identifier = typeName.name;
7803 if (identifier is SimpleIdentifier) { 10466 if (identifier is SimpleIdentifier) {
7804 SimpleIdentifier simpleIdentifier = identifier as SimpleIdentifier; 10467 SimpleIdentifier simpleIdentifier = identifier as SimpleIdentifier;
7805 sc.Token token2 = simpleIdentifier.token; 10468 sc.Token token2 = simpleIdentifier.token;
7806 if (identical(token2.type, sc.TokenType.KEYWORD)) { 10469 if (identical(token2.type, sc.TokenType.KEYWORD)) {
7807 if (((token2 as sc.KeywordToken)).keyword != sc.Keyword.DYNAMIC) { 10470 if (((token2 as sc.KeywordToken)).keyword != sc.Keyword.DYNAMIC) {
7808 _errorReporter.reportError(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_ AS_TYPE, identifier, [identifier.name]); 10471 _errorReporter.reportError2(CompileTimeErrorCode.BUILT_IN_IDENTIFIER _AS_TYPE, identifier, [identifier.name]);
7809 return true; 10472 return true;
7810 } 10473 }
7811 } 10474 }
7812 } 10475 }
7813 } 10476 }
7814 return false; 10477 return false;
7815 } 10478 }
10479
10480 /**
10481 * This verifies that the given switch case is terminated with 'break', 'conti nue', 'return' or
10482 * 'throw'.
10483 * @param node the switch case to evaluate
10484 * @return {@code true} if and only if an error code is generated on the passe d node
10485 * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED
10486 */
10487 bool checkForCaseBlockNotTerminated(SwitchCase node) {
10488 NodeList<Statement> statements2 = node.statements;
10489 if (statements2.isEmpty) {
10490 ASTNode parent2 = node.parent;
10491 if (parent2 is SwitchStatement) {
10492 SwitchStatement switchStatement = parent2 as SwitchStatement;
10493 NodeList<SwitchMember> members2 = switchStatement.members;
10494 int index = members2.indexOf(node);
10495 if (index != -1 && index < members2.length - 1) {
10496 return false;
10497 }
10498 }
10499 } else {
10500 Statement statement = statements2[statements2.length - 1];
10501 if (statement is BreakStatement || statement is ContinueStatement || state ment is ReturnStatement) {
10502 return false;
10503 }
10504 if (statement is ExpressionStatement) {
10505 Expression expression2 = ((statement as ExpressionStatement)).expression ;
10506 if (expression2 is ThrowExpression) {
10507 return false;
10508 }
10509 }
10510 }
10511 _errorReporter.reportError4(StaticWarningCode.CASE_BLOCK_NOT_TERMINATED, nod e.keyword, []);
10512 return true;
10513 }
10514
10515 /**
10516 * This verifies that the switch cases in the given switch statement is termin ated with 'break',
10517 * 'continue', 'return' or 'throw'.
10518 * @param node the switch statement containing the cases to be checked
10519 * @return {@code true} if and only if an error code is generated on the passe d node
10520 * @see StaticWarningCode#CASE_BLOCK_NOT_TERMINATED
10521 */
10522 bool checkForCaseBlocksNotTerminated(SwitchStatement node) {
10523 bool foundError = false;
10524 NodeList<SwitchMember> members2 = node.members;
10525 int lastMember = members2.length - 1;
10526 for (int i = 0; i < lastMember; i++) {
10527 SwitchMember member = members2[i];
10528 if (member is SwitchCase) {
10529 foundError = javaBooleanOr(foundError, checkForCaseBlockNotTerminated((m ember as SwitchCase)));
10530 }
10531 }
10532 return foundError;
10533 }
10534
7816 /** 10535 /**
7817 * This verifies that the passed switch statement does not have a case express ion with the 10536 * This verifies that the passed switch statement does not have a case express ion with the
7818 * operator '==' overridden. 10537 * operator '==' overridden.
7819 * @param node the switch statement to evaluate 10538 * @param node the switch statement to evaluate
7820 * @return return {@code true} if and only if an error code is generated on th e passed node 10539 * @return {@code true} if and only if an error code is generated on the passe d node
7821 * @see CompileTimeErrorCode#CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS 10540 * @see CompileTimeErrorCode#CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
7822 */ 10541 */
7823 bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node) { 10542 bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node) {
7824 Expression expression2 = node.expression; 10543 Expression expression2 = node.expression;
7825 Type2 type = expression2.staticType; 10544 Type2 type = getStaticType(expression2);
7826 if (type != null && type != _typeProvider.intType && type != _typeProvider.s tringType) { 10545 if (type != null && type != _typeProvider.intType && type != _typeProvider.s tringType) {
7827 Element element2 = type.element; 10546 Element element2 = type.element;
7828 if (element2 is ClassElement) { 10547 if (element2 is ClassElement) {
7829 ClassElement classElement = element2 as ClassElement; 10548 ClassElement classElement = element2 as ClassElement;
7830 MethodElement method = classElement.lookUpMethod("==", _currentLibrary); 10549 MethodElement method = classElement.lookUpMethod("==", _currentLibrary);
7831 if (method != null && method.enclosingElement.type != _typeProvider.obje ctType) { 10550 if (method != null && method.enclosingElement.type != _typeProvider.obje ctType) {
7832 _errorReporter.reportError(CompileTimeErrorCode.CASE_EXPRESSION_TYPE_I MPLEMENTS_EQUALS, expression2, [element2.name]); 10551 _errorReporter.reportError2(CompileTimeErrorCode.CASE_EXPRESSION_TYPE_ IMPLEMENTS_EQUALS, expression2, [element2.displayName]);
7833 return true; 10552 return true;
7834 } 10553 }
7835 } 10554 }
7836 } 10555 }
7837 return false; 10556 return false;
7838 } 10557 }
10558
7839 /** 10559 /**
7840 * This verifies that the passed method declaration is abstract only if the en closing class is 10560 * This verifies that the passed method declaration is abstract only if the en closing class is
7841 * also abstract. 10561 * also abstract.
7842 * @param node the method declaration to evaluate 10562 * @param node the method declaration to evaluate
7843 * @return {@code true} if and only if an error code is generated on the passe d node 10563 * @return {@code true} if and only if an error code is generated on the passe d node
7844 * @see StaticWarningCode#CONCRETE_CLASS_WITH_ABSTRACT_MEMBER 10564 * @see StaticWarningCode#CONCRETE_CLASS_WITH_ABSTRACT_MEMBER
7845 */ 10565 */
7846 bool checkForConcreteClassWithAbstractMember(MethodDeclaration node) { 10566 bool checkForConcreteClassWithAbstractMember(MethodDeclaration node) {
7847 if (node.isAbstract() && _enclosingClass != null && !_enclosingClass.isAbstr act()) { 10567 if (node.isAbstract() && _enclosingClass != null && !_enclosingClass.isAbstr act()) {
7848 SimpleIdentifier methodName = node.name; 10568 SimpleIdentifier methodName = node.name;
7849 _errorReporter.reportError(StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_ MEMBER, methodName, [methodName.name, _enclosingClass.name]); 10569 _errorReporter.reportError2(StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT _MEMBER, methodName, [methodName.name, _enclosingClass.displayName]);
7850 return true; 10570 return true;
7851 } 10571 }
7852 return false; 10572 return false;
7853 } 10573 }
10574
10575 /**
10576 * This verifies all possible conflicts of the constructor name with other con structors and
10577 * members of the same class.
10578 * @param node the constructor declaration to evaluate
10579 * @return {@code true} if and only if an error code is generated on the passe d node
10580 * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_DEFAULT
10581 * @see CompileTimeErrorCode#DUPLICATE_CONSTRUCTOR_NAME
10582 * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD
10583 * @see CompileTimeErrorCode#CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD
10584 */
7854 bool checkForConflictingConstructorNameAndMember(ConstructorDeclaration node) { 10585 bool checkForConflictingConstructorNameAndMember(ConstructorDeclaration node) {
7855 ConstructorElement constructorElement = node.element; 10586 ConstructorElement constructorElement = node.element;
7856 SimpleIdentifier constructorName = node.name; 10587 SimpleIdentifier constructorName = node.name;
10588 String name2 = constructorElement.name;
10589 ClassElement classElement = constructorElement.enclosingElement;
10590 List<ConstructorElement> constructors2 = classElement.constructors;
10591 for (ConstructorElement otherConstructor in constructors2) {
10592 if (identical(otherConstructor, constructorElement)) {
10593 continue;
10594 }
10595 if (name2 == otherConstructor.name) {
10596 if (name2 == null || name2.length == 0) {
10597 _errorReporter.reportError2(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR _DEFAULT, node, []);
10598 } else {
10599 _errorReporter.reportError2(CompileTimeErrorCode.DUPLICATE_CONSTRUCTOR _NAME, node, [name2]);
10600 }
10601 return true;
10602 }
10603 }
7857 if (constructorName != null && constructorElement != null && !constructorNam e.isSynthetic()) { 10604 if (constructorName != null && constructorElement != null && !constructorNam e.isSynthetic()) {
7858 String name2 = constructorName.name;
7859 ClassElement classElement = constructorElement.enclosingElement;
7860 List<FieldElement> fields2 = classElement.fields; 10605 List<FieldElement> fields2 = classElement.fields;
7861 for (FieldElement field in fields2) { 10606 for (FieldElement field in fields2) {
7862 if (field.name == name2) { 10607 if (field.name == name2) {
7863 _errorReporter.reportError(CompileTimeErrorCode.CONFLICTING_CONSTRUCTO R_NAME_AND_FIELD, node, [name2]); 10608 _errorReporter.reportError2(CompileTimeErrorCode.CONFLICTING_CONSTRUCT OR_NAME_AND_FIELD, node, [name2]);
7864 return true; 10609 return true;
7865 } 10610 }
7866 } 10611 }
7867 List<MethodElement> methods2 = classElement.methods; 10612 List<MethodElement> methods2 = classElement.methods;
7868 for (MethodElement method in methods2) { 10613 for (MethodElement method in methods2) {
7869 if (method.name == name2) { 10614 if (method.name == name2) {
7870 _errorReporter.reportError(CompileTimeErrorCode.CONFLICTING_CONSTRUCTO R_NAME_AND_METHOD, node, [name2]); 10615 _errorReporter.reportError2(CompileTimeErrorCode.CONFLICTING_CONSTRUCT OR_NAME_AND_METHOD, node, [name2]);
7871 return true; 10616 return true;
7872 } 10617 }
7873 } 10618 }
7874 } 10619 }
7875 return false; 10620 return false;
7876 } 10621 }
10622
7877 /** 10623 /**
7878 * This verifies that the passed constructor declaration is not 'const' if it has a non-final 10624 * This verifies that the superclass of the enclosing class does not declare a ccessible static
10625 * member with the same name as the passed instance getter/setter method decla ration.
10626 * @param node the method declaration to evaluate
10627 * @return {@code true} if and only if an error code is generated on the passe d node
10628 * @see StaticWarningCode#CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER
10629 * @see StaticWarningCode#CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER
10630 */
10631 bool checkForConflictingInstanceGetterAndSuperclassMember(MethodDeclaration no de) {
10632 if (node.isStatic()) {
10633 return false;
10634 }
10635 SimpleIdentifier nameNode = node.name;
10636 if (nameNode == null) {
10637 return false;
10638 }
10639 String name2 = nameNode.name;
10640 if (_enclosingClass == null) {
10641 return false;
10642 }
10643 InterfaceType enclosingType = _enclosingClass.type;
10644 ExecutableElement superElement;
10645 superElement = enclosingType.lookUpGetterInSuperclass(name2, _currentLibrary );
10646 if (superElement == null) {
10647 superElement = enclosingType.lookUpSetterInSuperclass(name2, _currentLibra ry);
10648 }
10649 if (superElement == null) {
10650 superElement = enclosingType.lookUpMethodInSuperclass(name2, _currentLibra ry);
10651 }
10652 if (superElement == null) {
10653 return false;
10654 }
10655 if (!superElement.isStatic()) {
10656 return false;
10657 }
10658 ClassElement superElementClass = superElement.enclosingElement as ClassEleme nt;
10659 InterfaceType superElementType = superElementClass.type;
10660 if (node.isGetter()) {
10661 _errorReporter.reportError2(StaticWarningCode.CONFLICTING_INSTANCE_GETTER_ AND_SUPERCLASS_MEMBER, nameNode, [superElementType.displayName]);
10662 } else {
10663 _errorReporter.reportError2(StaticWarningCode.CONFLICTING_INSTANCE_SETTER_ AND_SUPERCLASS_MEMBER, nameNode, [superElementType.displayName]);
10664 }
10665 return true;
10666 }
10667
10668 /**
10669 * This verifies that the enclosing class does not have an instance member wit h the same name as
10670 * the passed static getter method declaration.
10671 * @param node the method declaration to evaluate
10672 * @return {@code true} if and only if an error code is generated on the passe d node
10673 * @see StaticWarningCode#CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER
10674 */
10675 bool checkForConflictingStaticGetterAndInstanceSetter(MethodDeclaration node) {
10676 if (!node.isStatic()) {
10677 return false;
10678 }
10679 SimpleIdentifier nameNode = node.name;
10680 if (nameNode == null) {
10681 return false;
10682 }
10683 String name2 = nameNode.name;
10684 if (_enclosingClass == null) {
10685 return false;
10686 }
10687 InterfaceType enclosingType = _enclosingClass.type;
10688 ExecutableElement setter = enclosingType.lookUpSetter(name2, _currentLibrary );
10689 if (setter == null) {
10690 return false;
10691 }
10692 if (setter.isStatic()) {
10693 return false;
10694 }
10695 ClassElement setterClass = setter.enclosingElement as ClassElement;
10696 InterfaceType setterType = setterClass.type;
10697 _errorReporter.reportError2(StaticWarningCode.CONFLICTING_STATIC_GETTER_AND_ INSTANCE_SETTER, nameNode, [setterType.displayName]);
10698 return true;
10699 }
10700
10701 /**
10702 * This verifies that the enclosing class does not have an instance member wit h the same name as
10703 * the passed static getter method declaration.
10704 * @param node the method declaration to evaluate
10705 * @return {@code true} if and only if an error code is generated on the passe d node
10706 * @see StaticWarningCode#CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER
10707 */
10708 bool checkForConflictingStaticSetterAndInstanceMember(MethodDeclaration node) {
10709 if (!node.isStatic()) {
10710 return false;
10711 }
10712 SimpleIdentifier nameNode = node.name;
10713 if (nameNode == null) {
10714 return false;
10715 }
10716 String name2 = nameNode.name;
10717 if (_enclosingClass == null) {
10718 return false;
10719 }
10720 InterfaceType enclosingType = _enclosingClass.type;
10721 ExecutableElement member;
10722 member = enclosingType.lookUpMethod(name2, _currentLibrary);
10723 if (member == null) {
10724 member = enclosingType.lookUpGetter(name2, _currentLibrary);
10725 }
10726 if (member == null) {
10727 member = enclosingType.lookUpSetter(name2, _currentLibrary);
10728 }
10729 if (member == null) {
10730 return false;
10731 }
10732 if (member.isStatic()) {
10733 return false;
10734 }
10735 ClassElement memberClass = member.enclosingElement as ClassElement;
10736 InterfaceType memberType = memberClass.type;
10737 _errorReporter.reportError2(StaticWarningCode.CONFLICTING_STATIC_SETTER_AND_ INSTANCE_MEMBER, nameNode, [memberType.displayName]);
10738 return true;
10739 }
10740
10741 /**
10742 * This verifies that the passed constructor declaration is 'const' then there are no non-final
7879 * instance variable. 10743 * instance variable.
7880 * @param node the instance creation expression to evaluate 10744 * @param node the constructor declaration to evaluate
7881 * @return return {@code true} if and only if an error code is generated on th e passed node 10745 * @return {@code true} if and only if an error code is generated on the passe d node
7882 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD 10746 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
7883 */ 10747 */
7884 bool checkForConstConstructorWithNonFinalField(ConstructorDeclaration node) { 10748 bool checkForConstConstructorWithNonFinalField(ConstructorDeclaration node) {
7885 if (!_isEnclosingConstructorConst) { 10749 if (!_isEnclosingConstructorConst) {
7886 return false; 10750 return false;
7887 } 10751 }
7888 ConstructorElement constructorElement = node.element; 10752 ConstructorElement constructorElement = node.element;
7889 if (constructorElement != null) { 10753 ClassElement classElement = constructorElement.enclosingElement;
7890 ClassElement classElement = constructorElement.enclosingElement; 10754 if (!classElement.hasNonFinalField()) {
7891 List<FieldElement> elements = classElement.fields; 10755 return false;
7892 for (FieldElement field in elements) {
7893 if (!field.isFinal() && !field.isConst() && !field.isStatic() && !field. isSynthetic()) {
7894 _errorReporter.reportError(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH _NON_FINAL_FIELD, node, []);
7895 return true;
7896 }
7897 }
7898 } 10756 }
7899 return false; 10757 _errorReporter.reportError2(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_ FINAL_FIELD, node, []);
10758 return true;
7900 } 10759 }
10760
7901 /** 10761 /**
7902 * This verifies that the passed throw expression is not enclosed in a 'const' constructor 10762 * This verifies that the passed throw expression is not enclosed in a 'const' constructor
7903 * declaration. 10763 * declaration.
7904 * @param node the throw expression expression to evaluate 10764 * @param node the throw expression expression to evaluate
7905 * @return return {@code true} if and only if an error code is generated on th e passed node 10765 * @return {@code true} if and only if an error code is generated on the passe d node
7906 * @see CompileTimeErrorCode#CONST_EVAL_THROWS_EXCEPTION 10766 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_THROWS_EXCEPTION
7907 */ 10767 */
7908 bool checkForConstEvalThrowsException(ThrowExpression node) { 10768 bool checkForConstEvalThrowsException(ThrowExpression node) {
7909 if (_isEnclosingConstructorConst) { 10769 if (_isEnclosingConstructorConst) {
7910 _errorReporter.reportError(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTIO N, node, []); 10770 _errorReporter.reportError2(CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_ EXCEPTION, node, []);
7911 return true; 10771 return true;
7912 } 10772 }
7913 return false; 10773 return false;
7914 } 10774 }
10775
7915 /** 10776 /**
7916 * This verifies that the passed normal formal parameter is not 'const'. 10777 * This verifies that the passed normal formal parameter is not 'const'.
7917 * @param node the normal formal parameter to evaluate 10778 * @param node the normal formal parameter to evaluate
7918 * @return return {@code true} if and only if an error code is generated on th e passed node 10779 * @return {@code true} if and only if an error code is generated on the passe d node
7919 * @see CompileTimeErrorCode#CONST_FORMAL_PARAMETER 10780 * @see CompileTimeErrorCode#CONST_FORMAL_PARAMETER
7920 */ 10781 */
7921 bool checkForConstFormalParameter(NormalFormalParameter node) { 10782 bool checkForConstFormalParameter(NormalFormalParameter node) {
7922 if (node.isConst()) { 10783 if (node.isConst()) {
7923 _errorReporter.reportError(CompileTimeErrorCode.CONST_FORMAL_PARAMETER, no de, []); 10784 _errorReporter.reportError2(CompileTimeErrorCode.CONST_FORMAL_PARAMETER, n ode, []);
7924 return true; 10785 return true;
7925 } 10786 }
7926 return false; 10787 return false;
7927 } 10788 }
10789
7928 /** 10790 /**
7929 * This verifies that the passed instance creation expression is not being inv oked on an abstract 10791 * This verifies that the passed instance creation expression is not being inv oked on an abstract
7930 * class. 10792 * class.
7931 * @param node the instance creation expression to evaluate 10793 * @param node the instance creation expression to evaluate
7932 * @param typeName the {@link TypeName} of the {@link ConstructorName} from th e{@link InstanceCreationExpression}, this is the AST node that the error is atta ched to 10794 * @param typeName the {@link TypeName} of the {@link ConstructorName} from th e{@link InstanceCreationExpression}, this is the AST node that the error is atta ched to
7933 * @param type the type being constructed with this {@link InstanceCreationExp ression} 10795 * @param type the type being constructed with this {@link InstanceCreationExp ression}
7934 * @return return {@code true} if and only if an error code is generated on th e passed node 10796 * @return {@code true} if and only if an error code is generated on the passe d node
7935 * @see StaticWarningCode#CONST_WITH_ABSTRACT_CLASS 10797 * @see StaticWarningCode#CONST_WITH_ABSTRACT_CLASS
7936 * @see StaticWarningCode#NEW_WITH_ABSTRACT_CLASS 10798 * @see StaticWarningCode#NEW_WITH_ABSTRACT_CLASS
7937 */ 10799 */
7938 bool checkForConstOrNewWithAbstractClass(InstanceCreationExpression node, Type Name typeName, InterfaceType type) { 10800 bool checkForConstOrNewWithAbstractClass(InstanceCreationExpression node, Type Name typeName, InterfaceType type) {
7939 if (type.element.isAbstract()) { 10801 if (type.element.isAbstract()) {
7940 ConstructorElement element2 = node.element; 10802 ConstructorElement element2 = node.element;
7941 if (element2 != null && !element2.isFactory()) { 10803 if (element2 != null && !element2.isFactory()) {
7942 if (identical(((node.keyword as sc.KeywordToken)).keyword, sc.Keyword.CO NST)) { 10804 if (identical(((node.keyword as sc.KeywordToken)).keyword, sc.Keyword.CO NST)) {
7943 _errorReporter.reportError(StaticWarningCode.CONST_WITH_ABSTRACT_CLASS , typeName, []); 10805 _errorReporter.reportError2(StaticWarningCode.CONST_WITH_ABSTRACT_CLAS S, typeName, []);
7944 } else { 10806 } else {
7945 _errorReporter.reportError(StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName, []); 10807 _errorReporter.reportError2(StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName, []);
7946 } 10808 }
7947 return true; 10809 return true;
7948 } 10810 }
7949 } 10811 }
7950 return false; 10812 return false;
7951 } 10813 }
10814
7952 /** 10815 /**
7953 * This verifies that if the passed instance creation expression is 'const', t hen it is not being 10816 * This verifies that the passed 'const' instance creation expression is not b eing invoked on a
7954 * invoked on a constructor that is not 'const'. 10817 * constructor that is not 'const'.
10818 * <p>
10819 * This method assumes that the instance creation was tested to be 'const' bef ore being called.
7955 * @param node the instance creation expression to evaluate 10820 * @param node the instance creation expression to evaluate
7956 * @return return {@code true} if and only if an error code is generated on th e passed node 10821 * @return {@code true} if and only if an error code is generated on the passe d node
7957 * @see CompileTimeErrorCode#CONST_WITH_NON_CONST 10822 * @see CompileTimeErrorCode#CONST_WITH_NON_CONST
7958 */ 10823 */
7959 bool checkForConstWithNonConst(InstanceCreationExpression node) { 10824 bool checkForConstWithNonConst(InstanceCreationExpression node) {
7960 ConstructorElement constructorElement = node.element; 10825 ConstructorElement constructorElement = node.element;
7961 if (node.isConst() && constructorElement != null && !constructorElement.isCo nst()) { 10826 if (constructorElement != null && !constructorElement.isConst()) {
7962 _errorReporter.reportError(CompileTimeErrorCode.CONST_WITH_NON_CONST, node , []); 10827 _errorReporter.reportError2(CompileTimeErrorCode.CONST_WITH_NON_CONST, nod e, []);
7963 return true; 10828 return true;
7964 } 10829 }
7965 return false; 10830 return false;
7966 } 10831 }
10832
10833 /**
10834 * This verifies that the passed 'const' instance creation expression does not reference any type
10835 * parameters.
10836 * <p>
10837 * This method assumes that the instance creation was tested to be 'const' bef ore being called.
10838 * @param node the instance creation expression to evaluate
10839 * @return {@code true} if and only if an error code is generated on the passe d node
10840 * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS
10841 */
10842 bool checkForConstWithTypeParameters(InstanceCreationExpression node) {
10843 ConstructorName constructorName2 = node.constructorName;
10844 if (constructorName2 == null) {
10845 return false;
10846 }
10847 TypeName typeName = constructorName2.type;
10848 return checkForConstWithTypeParameters2(typeName);
10849 }
10850
10851 /**
10852 * This verifies that the passed type name does not reference any type paramet ers.
10853 * @param typeName the type name to evaluate
10854 * @return {@code true} if and only if an error code is generated on the passe d node
10855 * @see CompileTimeErrorCode#CONST_WITH_TYPE_PARAMETERS
10856 */
10857 bool checkForConstWithTypeParameters2(TypeName typeName) {
10858 if (typeName == null) {
10859 return false;
10860 }
10861 Identifier name2 = typeName.name;
10862 if (name2 == null) {
10863 return false;
10864 }
10865 if (name2.element is TypeVariableElement) {
10866 _errorReporter.reportError2(CompileTimeErrorCode.CONST_WITH_TYPE_PARAMETER S, name2, []);
10867 }
10868 TypeArgumentList typeArguments2 = typeName.typeArguments;
10869 if (typeArguments2 != null) {
10870 bool hasError = false;
10871 for (TypeName argument in typeArguments2.arguments) {
10872 hasError = javaBooleanOr(hasError, checkForConstWithTypeParameters2(argu ment));
10873 }
10874 return hasError;
10875 }
10876 return false;
10877 }
10878
10879 /**
10880 * This verifies that if the passed 'const' instance creation expression is be ing invoked on the
10881 * resolved constructor.
10882 * <p>
10883 * This method assumes that the instance creation was tested to be 'const' bef ore being called.
10884 * @param node the instance creation expression to evaluate
10885 * @return {@code true} if and only if an error code is generated on the passe d node
10886 * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR
10887 * @see CompileTimeErrorCode#CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT
10888 */
10889 bool checkForConstWithUndefinedConstructor(InstanceCreationExpression node) {
10890 if (node.element != null) {
10891 return false;
10892 }
10893 ConstructorName constructorName2 = node.constructorName;
10894 if (constructorName2 == null) {
10895 return false;
10896 }
10897 TypeName type2 = constructorName2.type;
10898 if (type2 == null) {
10899 return false;
10900 }
10901 Identifier className = type2.name;
10902 SimpleIdentifier name2 = constructorName2.name;
10903 if (name2 != null) {
10904 _errorReporter.reportError2(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONS TRUCTOR, name2, [className, name2]);
10905 } else {
10906 _errorReporter.reportError2(CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONS TRUCTOR_DEFAULT, constructorName2, [className]);
10907 }
10908 return true;
10909 }
10910
7967 /** 10911 /**
7968 * This verifies that there are no default parameters in the passed function t ype alias. 10912 * This verifies that there are no default parameters in the passed function t ype alias.
7969 * @param node the function type alias to evaluate 10913 * @param node the function type alias to evaluate
7970 * @return return {@code true} if and only if an error code is generated on th e passed node 10914 * @return {@code true} if and only if an error code is generated on the passe d node
7971 * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS 10915 * @see CompileTimeErrorCode#DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS
7972 */ 10916 */
7973 bool checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) { 10917 bool checkForDefaultValueInFunctionTypeAlias(FunctionTypeAlias node) {
7974 bool result = false; 10918 bool result = false;
7975 FormalParameterList formalParameterList = node.parameters; 10919 FormalParameterList formalParameterList = node.parameters;
7976 NodeList<FormalParameter> parameters2 = formalParameterList.parameters; 10920 NodeList<FormalParameter> parameters2 = formalParameterList.parameters;
7977 for (FormalParameter formalParameter in parameters2) { 10921 for (FormalParameter formalParameter in parameters2) {
7978 if (formalParameter is DefaultFormalParameter) { 10922 if (formalParameter is DefaultFormalParameter) {
7979 DefaultFormalParameter defaultFormalParameter = formalParameter as Defau ltFormalParameter; 10923 DefaultFormalParameter defaultFormalParameter = formalParameter as Defau ltFormalParameter;
7980 if (defaultFormalParameter.defaultValue != null) { 10924 if (defaultFormalParameter.defaultValue != null) {
7981 _errorReporter.reportError(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNCT ION_TYPE_ALIAS, node, []); 10925 _errorReporter.reportError2(CompileTimeErrorCode.DEFAULT_VALUE_IN_FUNC TION_TYPE_ALIAS, node, []);
7982 result = true; 10926 result = true;
7983 } 10927 }
7984 } 10928 }
7985 } 10929 }
7986 return result; 10930 return result;
7987 } 10931 }
10932
10933 /**
10934 * This verifies the passed import has unique name among other exported librar ies.
10935 * @param node the export directive to evaluate
10936 * @return {@code true} if and only if an error code is generated on the passe d node
10937 * @see CompileTimeErrorCode#EXPORT_DUPLICATED_LIBRARY_NAME
10938 */
10939 bool checkForExportDuplicateLibraryName(ExportDirective node) {
10940 Element nodeElement = node.element;
10941 if (nodeElement is! ExportElement) {
10942 return false;
10943 }
10944 ExportElement nodeExportElement = nodeElement as ExportElement;
10945 LibraryElement nodeLibrary = nodeExportElement.exportedLibrary;
10946 if (nodeLibrary == null) {
10947 return false;
10948 }
10949 String name2 = nodeLibrary.name;
10950 LibraryElement prevLibrary = _nameToExportElement[name2];
10951 if (prevLibrary != null) {
10952 if (prevLibrary != nodeLibrary) {
10953 _errorReporter.reportError2(StaticWarningCode.EXPORT_DUPLICATED_LIBRARY_ NAME, node, [prevLibrary.definingCompilationUnit.displayName, nodeLibrary.defini ngCompilationUnit.displayName, name2]);
10954 return true;
10955 }
10956 } else {
10957 _nameToExportElement[name2] = nodeLibrary;
10958 }
10959 return false;
10960 }
10961
10962 /**
10963 * Check that if the visiting library is not system, then any passed library s hould not be SDK
10964 * internal library.
10965 * @param node the export directive to evaluate
10966 * @return {@code true} if and only if an error code is generated on the passe d node
10967 * @see CompileTimeErrorCode#EXPORT_INTERNAL_LIBRARY
10968 */
10969 bool checkForExportInternalLibrary(ExportDirective node) {
10970 if (_isInSystemLibrary) {
10971 return false;
10972 }
10973 Element element2 = node.element;
10974 if (element2 is! ExportElement) {
10975 return false;
10976 }
10977 ExportElement exportElement = element2 as ExportElement;
10978 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk;
10979 String uri2 = exportElement.uri;
10980 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri2);
10981 if (sdkLibrary == null) {
10982 return false;
10983 }
10984 if (!sdkLibrary.isInternal()) {
10985 return false;
10986 }
10987 _errorReporter.reportError2(CompileTimeErrorCode.EXPORT_INTERNAL_LIBRARY, no de, [node.uri]);
10988 return true;
10989 }
10990
7988 /** 10991 /**
7989 * This verifies that the passed extends clause does not extend classes such a s num or String. 10992 * This verifies that the passed extends clause does not extend classes such a s num or String.
7990 * @param node the extends clause to test 10993 * @param node the extends clause to test
7991 * @return return {@code true} if and only if an error code is generated on th e passed node 10994 * @return {@code true} if and only if an error code is generated on the passe d node
7992 * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS 10995 * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
7993 */ 10996 */
7994 bool checkForExtendsDisallowedClass(ExtendsClause extendsClause) => checkForEx tendsOrImplementsDisallowedClass(extendsClause.superclass, CompileTimeErrorCode. EXTENDS_DISALLOWED_CLASS); 10997 bool checkForExtendsDisallowedClass(ExtendsClause extendsClause) {
10998 if (extendsClause == null) {
10999 return false;
11000 }
11001 return checkForExtendsOrImplementsDisallowedClass(extendsClause.superclass, CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS);
11002 }
11003
7995 /** 11004 /**
7996 * This verifies that the passed type name does not extend or implement classe s such as 'num' or 11005 * This verifies that the passed type name does not extend or implement classe s such as 'num' or
7997 * 'String'. 11006 * 'String'.
7998 * @param node the type name to test 11007 * @param node the type name to test
7999 * @return return {@code true} if and only if an error code is generated on th e passed node 11008 * @return {@code true} if and only if an error code is generated on the passe d node
8000 * @see #checkForExtendsDisallowedClass(ExtendsClause) 11009 * @see #checkForExtendsDisallowedClass(ExtendsClause)
8001 * @see #checkForImplementsDisallowedClass(ImplementsClause) 11010 * @see #checkForImplementsDisallowedClass(ImplementsClause)
8002 * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS 11011 * @see CompileTimeErrorCode#EXTENDS_DISALLOWED_CLASS
8003 * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS 11012 * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS
8004 */ 11013 */
8005 bool checkForExtendsOrImplementsDisallowedClass(TypeName typeName, ErrorCode e rrorCode) { 11014 bool checkForExtendsOrImplementsDisallowedClass(TypeName typeName, ErrorCode e rrorCode) {
8006 if (typeName.isSynthetic()) { 11015 if (typeName.isSynthetic()) {
8007 return false; 11016 return false;
8008 } 11017 }
8009 Type2 superType = typeName.type; 11018 Type2 superType = typeName.type;
8010 for (InterfaceType disallowedType in _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMEN T) { 11019 for (InterfaceType disallowedType in _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMEN T) {
8011 if (superType != null && superType == disallowedType) { 11020 if (superType != null && superType == disallowedType) {
8012 if (superType == _typeProvider.numType) { 11021 if (superType == _typeProvider.numType) {
8013 ASTNode grandParent = typeName.parent.parent; 11022 ASTNode grandParent = typeName.parent.parent;
8014 if (grandParent is ClassDeclaration) { 11023 if (grandParent is ClassDeclaration) {
8015 ClassElement classElement = ((grandParent as ClassDeclaration)).elem ent; 11024 ClassElement classElement = ((grandParent as ClassDeclaration)).elem ent;
8016 Type2 classType = classElement.type; 11025 Type2 classType = classElement.type;
8017 if (classType != null && (classType == _typeProvider.intType || clas sType == _typeProvider.doubleType)) { 11026 if (classType != null && (classType == _typeProvider.intType || clas sType == _typeProvider.doubleType)) {
8018 return false; 11027 return false;
8019 } 11028 }
8020 } 11029 }
8021 } 11030 }
8022 _errorReporter.reportError(errorCode, typeName, [disallowedType.name]); 11031 _errorReporter.reportError2(errorCode, typeName, [disallowedType.display Name]);
8023 return true; 11032 return true;
8024 } 11033 }
8025 } 11034 }
8026 return false; 11035 return false;
8027 } 11036 }
11037
11038 /**
11039 * This verifies that the passed constructor field initializer has compatible field and
11040 * initializer expression types.
11041 * @param node the constructor field initializer to test
11042 * @return {@code true} if and only if an error code is generated on the passe d node
11043 * @see CompileTimeErrorCode#CONST_FIELD_INITIALIZER_NOT_ASSIGNABLE
11044 * @see StaticWarningCode#FIELD_INITIALIZER_NOT_ASSIGNABLE
11045 */
11046 bool checkForFieldInitializerNotAssignable(ConstructorFieldInitializer node) {
11047 Element fieldNameElement = node.fieldName.element;
11048 if (fieldNameElement is! FieldElement) {
11049 return false;
11050 }
11051 FieldElement fieldElement = fieldNameElement as FieldElement;
11052 Type2 fieldType = fieldElement.type;
11053 Expression expression2 = node.expression;
11054 if (expression2 == null) {
11055 return false;
11056 }
11057 Type2 staticType = getStaticType(expression2);
11058 if (staticType == null) {
11059 return false;
11060 }
11061 if (staticType.isAssignableTo(fieldType)) {
11062 return false;
11063 }
11064 Type2 propagatedType = getPropagatedType(expression2);
11065 if (propagatedType != null && propagatedType.isAssignableTo(fieldType)) {
11066 return false;
11067 }
11068 if (_isEnclosingConstructorConst) {
11069 _errorReporter.reportError2(CompileTimeErrorCode.CONST_FIELD_INITIALIZER_N OT_ASSIGNABLE, expression2, [(propagatedType == null ? staticType : propagatedTy pe).displayName, fieldType.displayName]);
11070 } else {
11071 _errorReporter.reportError2(StaticWarningCode.FIELD_INITIALIZER_NOT_ASSIGN ABLE, expression2, [(propagatedType == null ? staticType : propagatedType).displ ayName, fieldType.displayName]);
11072 }
11073 return true;
11074 }
11075
8028 /** 11076 /**
8029 * This verifies that the passed field formal parameter is in a constructor de claration. 11077 * This verifies that the passed field formal parameter is in a constructor de claration.
8030 * @param node the field formal parameter to test 11078 * @param node the field formal parameter to test
8031 * @return return {@code true} if and only if an error code is generated on th e passed node 11079 * @return {@code true} if and only if an error code is generated on the passe d node
8032 * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR 11080 * @see CompileTimeErrorCode#FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
8033 */ 11081 */
8034 bool checkForFieldInitializerOutsideConstructor(FieldFormalParameter node) { 11082 bool checkForFieldInitializingFormalRedirectingConstructor(FieldFormalParamete r node) {
8035 ASTNode parent2 = node.parent; 11083 ConstructorDeclaration constructor = node.getAncestor(ConstructorDeclaration );
8036 if (parent2 != null) { 11084 if (constructor == null) {
8037 ASTNode grandparent = parent2.parent; 11085 _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE _CONSTRUCTOR, node, []);
8038 if (grandparent != null && grandparent is! ConstructorDeclaration && grand parent.parent is! ConstructorDeclaration) { 11086 return true;
8039 _errorReporter.reportError(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSID E_CONSTRUCTOR, node, []); 11087 }
11088 if (constructor.factoryKeyword != null) {
11089 _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY _CONSTRUCTOR, node, []);
11090 return true;
11091 }
11092 for (ConstructorInitializer initializer in constructor.initializers) {
11093 if (initializer is RedirectingConstructorInvocation) {
11094 _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZER_REDIR ECTING_CONSTRUCTOR, node, []);
8040 return true; 11095 return true;
8041 } 11096 }
8042 } 11097 }
8043 return false; 11098 return false;
8044 } 11099 }
11100
8045 /** 11101 /**
8046 * This verifies that final fields that are declared, without any constructors in the enclosing 11102 * This verifies that final fields that are declared, without any constructors in the enclosing
8047 * class, are initialized. Cases in which there is at least one constructor ar e handled at the end 11103 * class, are initialized. Cases in which there is at least one constructor ar e handled at the end
8048 * of {@link #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration)}. 11104 * of {@link #checkForAllFinalInitializedErrorCodes(ConstructorDeclaration)}.
8049 * @param node the class declaration to test 11105 * @param node the class declaration to test
8050 * @return {@code true} if and only if an error code is generated on the passe d node 11106 * @return {@code true} if and only if an error code is generated on the passe d node
8051 * @see CompileTimeErrorCode#FINAL_NOT_INITIALIZED 11107 * @see CompileTimeErrorCode#FINAL_NOT_INITIALIZED
8052 */ 11108 */
8053 bool checkForFinalNotInitialized(ClassDeclaration node) { 11109 bool checkForFinalNotInitialized(ClassDeclaration node) {
8054 NodeList<ClassMember> classMembers = node.members; 11110 NodeList<ClassMember> classMembers = node.members;
8055 for (ClassMember classMember in classMembers) { 11111 for (ClassMember classMember in classMembers) {
8056 if (classMember is ConstructorDeclaration) { 11112 if (classMember is ConstructorDeclaration) {
8057 return false; 11113 return false;
8058 } 11114 }
8059 } 11115 }
8060 bool foundError = false; 11116 bool foundError = false;
8061 for (ClassMember classMember in classMembers) { 11117 for (ClassMember classMember in classMembers) {
8062 if (classMember is FieldDeclaration) { 11118 if (classMember is FieldDeclaration) {
8063 FieldDeclaration field = classMember as FieldDeclaration; 11119 FieldDeclaration field = classMember as FieldDeclaration;
8064 foundError = javaBooleanOr(foundError, checkForFinalNotInitialized2(fiel d.fields)); 11120 foundError = javaBooleanOr(foundError, checkForFinalNotInitialized2(fiel d.fields));
8065 } 11121 }
8066 } 11122 }
8067 return foundError; 11123 return foundError;
8068 } 11124 }
11125
8069 /** 11126 /**
8070 * This verifies that the passed variable declaration list has only initialize d variables if the 11127 * This verifies that the passed variable declaration list has only initialize d variables if the
8071 * list is final or const. This method is called by{@link #checkForFinalNotIni tialized(ClassDeclaration)},{@link #visitTopLevelVariableDeclaration(TopLevelVar iableDeclaration)} and{@link #visitVariableDeclarationStatement(VariableDeclarat ionStatement)}. 11128 * list is final or const. This method is called by{@link #checkForFinalNotIni tialized(ClassDeclaration)},{@link #visitTopLevelVariableDeclaration(TopLevelVar iableDeclaration)} and{@link #visitVariableDeclarationStatement(VariableDeclarat ionStatement)}.
8072 * @param node the class declaration to test 11129 * @param node the class declaration to test
8073 * @return {@code true} if and only if an error code is generated on the passe d node 11130 * @return {@code true} if and only if an error code is generated on the passe d node
8074 * @see CompileTimeErrorCode#FINAL_NOT_INITIALIZED 11131 * @see CompileTimeErrorCode#FINAL_NOT_INITIALIZED
8075 */ 11132 */
8076 bool checkForFinalNotInitialized2(VariableDeclarationList node) { 11133 bool checkForFinalNotInitialized2(VariableDeclarationList node) {
8077 bool foundError = false; 11134 bool foundError = false;
8078 if (!node.isSynthetic() && (node.isConst() || node.isFinal())) { 11135 if (!node.isSynthetic() && (node.isConst() || node.isFinal())) {
8079 NodeList<VariableDeclaration> variables2 = node.variables; 11136 NodeList<VariableDeclaration> variables2 = node.variables;
8080 for (VariableDeclaration variable in variables2) { 11137 for (VariableDeclaration variable in variables2) {
8081 if (variable.initializer == null) { 11138 if (variable.initializer == null) {
8082 _errorReporter.reportError(CompileTimeErrorCode.FINAL_NOT_INITIALIZED, variable, [variable.name.name]); 11139 _errorReporter.reportError2(CompileTimeErrorCode.FINAL_NOT_INITIALIZED , variable, [variable.name.name]);
8083 foundError = true; 11140 foundError = true;
8084 } 11141 }
8085 } 11142 }
8086 } 11143 }
8087 return foundError; 11144 return foundError;
8088 } 11145 }
11146
8089 /** 11147 /**
8090 * This verifies that the passed implements clause does not implement classes such as 'num' or 11148 * This verifies that the passed implements clause does not implement classes such as 'num' or
8091 * 'String'. 11149 * 'String'.
8092 * @param node the implements clause to test 11150 * @param node the implements clause to test
8093 * @return return {@code true} if and only if an error code is generated on th e passed node 11151 * @return {@code true} if and only if an error code is generated on the passe d node
8094 * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS 11152 * @see CompileTimeErrorCode#IMPLEMENTS_DISALLOWED_CLASS
8095 */ 11153 */
8096 bool checkForImplementsDisallowedClass(ImplementsClause implementsClause) { 11154 bool checkForImplementsDisallowedClass(ImplementsClause implementsClause) {
11155 if (implementsClause == null) {
11156 return false;
11157 }
8097 bool foundError = false; 11158 bool foundError = false;
8098 for (TypeName type in implementsClause.interfaces) { 11159 for (TypeName type in implementsClause.interfaces) {
8099 foundError = javaBooleanOr(foundError, checkForExtendsOrImplementsDisallow edClass(type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS)); 11160 foundError = javaBooleanOr(foundError, checkForExtendsOrImplementsDisallow edClass(type, CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS));
8100 } 11161 }
8101 return foundError; 11162 return foundError;
8102 } 11163 }
11164
11165 /**
11166 * This verifies that if the passed identifier is part of constructor initiali zer, then it does
11167 * not reference implicitly 'this' expression.
11168 * @param node the simple identifier to test
11169 * @return {@code true} if and only if an error code is generated on the passe d node
11170 * @see CompileTimeErrorCode#IMPLICIT_THIS_REFERENCE_IN_INITIALIZER
11171 */
11172 bool checkForImplicitThisReferenceInInitializer(SimpleIdentifier node) {
11173 if (!_isInConstructorInitializer) {
11174 return false;
11175 }
11176 Element element2 = node.element;
11177 if (!(element2 is MethodElement || element2 is PropertyAccessorElement)) {
11178 return false;
11179 }
11180 ExecutableElement executableElement = element2 as ExecutableElement;
11181 if (executableElement.isStatic()) {
11182 return false;
11183 }
11184 Element enclosingElement2 = element2.enclosingElement;
11185 if (enclosingElement2 is! ClassElement) {
11186 return false;
11187 }
11188 ASTNode parent2 = node.parent;
11189 if (parent2 is MethodInvocation) {
11190 MethodInvocation invocation = parent2 as MethodInvocation;
11191 if (identical(invocation.methodName, node) && invocation.realTarget != nul l) {
11192 return false;
11193 }
11194 }
11195 {
11196 if (parent2 is PropertyAccess) {
11197 PropertyAccess access = parent2 as PropertyAccess;
11198 if (identical(access.propertyName, node) && access.realTarget != null) {
11199 return false;
11200 }
11201 }
11202 if (parent2 is PrefixedIdentifier) {
11203 PrefixedIdentifier prefixed = parent2 as PrefixedIdentifier;
11204 if (identical(prefixed.identifier, node)) {
11205 return false;
11206 }
11207 }
11208 }
11209 _errorReporter.reportError2(CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_ INITIALIZER, node, []);
11210 return true;
11211 }
11212
11213 /**
11214 * This verifies the passed import has unique name among other imported librar ies.
11215 * @param node the import directive to evaluate
11216 * @return {@code true} if and only if an error code is generated on the passe d node
11217 * @see CompileTimeErrorCode#IMPORT_DUPLICATED_LIBRARY_NAME
11218 */
11219 bool checkForImportDuplicateLibraryName(ImportDirective node) {
11220 Element nodeElement = node.element;
11221 if (nodeElement is! ImportElement) {
11222 return false;
11223 }
11224 ImportElement nodeImportElement = nodeElement as ImportElement;
11225 LibraryElement nodeLibrary = nodeImportElement.importedLibrary;
11226 if (nodeLibrary == null) {
11227 return false;
11228 }
11229 String name2 = nodeLibrary.name;
11230 LibraryElement prevLibrary = _nameToImportElement[name2];
11231 if (prevLibrary != null) {
11232 if (prevLibrary != nodeLibrary) {
11233 _errorReporter.reportError2(StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_ NAME, node, [prevLibrary.definingCompilationUnit.displayName, nodeLibrary.defini ngCompilationUnit.displayName, name2]);
11234 return true;
11235 }
11236 } else {
11237 _nameToImportElement[name2] = nodeLibrary;
11238 }
11239 return false;
11240 }
11241
11242 /**
11243 * Check that if the visiting library is not system, then any passed library s hould not be SDK
11244 * internal library.
11245 * @param node the import directive to evaluate
11246 * @return {@code true} if and only if an error code is generated on the passe d node
11247 * @see CompileTimeErrorCode#IMPORT_INTERNAL_LIBRARY
11248 */
11249 bool checkForImportInternalLibrary(ImportDirective node) {
11250 if (_isInSystemLibrary) {
11251 return false;
11252 }
11253 Element element2 = node.element;
11254 if (element2 is! ImportElement) {
11255 return false;
11256 }
11257 ImportElement importElement = element2 as ImportElement;
11258 DartSdk sdk = _currentLibrary.context.sourceFactory.dartSdk;
11259 String uri2 = importElement.uri;
11260 SdkLibrary sdkLibrary = sdk.getSdkLibrary(uri2);
11261 if (sdkLibrary == null) {
11262 return false;
11263 }
11264 if (!sdkLibrary.isInternal()) {
11265 return false;
11266 }
11267 _errorReporter.reportError2(CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY, no de, [node.uri]);
11268 return true;
11269 }
11270
8103 /** 11271 /**
8104 * This verifies that the passed switch statement case expressions all have th e same type. 11272 * This verifies that the passed switch statement case expressions all have th e same type.
8105 * @param node the switch statement to evaluate 11273 * @param node the switch statement to evaluate
8106 * @return return {@code true} if and only if an error code is generated on th e passed node 11274 * @return {@code true} if and only if an error code is generated on the passe d node
8107 * @see CompileTimeErrorCode#INCONSISTENT_CASE_EXPRESSION_TYPES 11275 * @see CompileTimeErrorCode#INCONSISTENT_CASE_EXPRESSION_TYPES
8108 */ 11276 */
8109 bool checkForInconsistentCaseExpressionTypes(SwitchStatement node) { 11277 bool checkForInconsistentCaseExpressionTypes(SwitchStatement node) {
8110 NodeList<SwitchMember> switchMembers = node.members; 11278 NodeList<SwitchMember> switchMembers = node.members;
8111 bool foundError = false; 11279 bool foundError = false;
8112 Type2 firstType = null; 11280 Type2 firstType = null;
8113 for (SwitchMember switchMember in switchMembers) { 11281 for (SwitchMember switchMember in switchMembers) {
8114 if (switchMember is SwitchCase) { 11282 if (switchMember is SwitchCase) {
8115 SwitchCase switchCase = switchMember as SwitchCase; 11283 SwitchCase switchCase = switchMember as SwitchCase;
8116 Expression expression2 = switchCase.expression; 11284 Expression expression2 = switchCase.expression;
8117 if (firstType == null) { 11285 if (firstType == null) {
8118 firstType = expression2.staticType; 11286 firstType = getBestType(expression2);
8119 } else { 11287 } else {
8120 Type2 nType = expression2.staticType; 11288 Type2 nType = getBestType(expression2);
8121 if (firstType != nType) { 11289 if (firstType != nType) {
8122 _errorReporter.reportError(CompileTimeErrorCode.INCONSISTENT_CASE_EX PRESSION_TYPES, expression2, [expression2.toSource(), firstType.name]); 11290 _errorReporter.reportError2(CompileTimeErrorCode.INCONSISTENT_CASE_E XPRESSION_TYPES, expression2, [expression2.toSource(), firstType.displayName]);
8123 foundError = true; 11291 foundError = true;
8124 } 11292 }
8125 } 11293 }
8126 } 11294 }
8127 } 11295 }
8128 return foundError; 11296 return foundError;
8129 } 11297 }
11298
8130 /** 11299 /**
8131 * This verifies that the passed assignment expression represents a valid assi gnment. 11300 * For each class declaration, this method is called which verifies that all i nherited members are
8132 * @param node the assignment expression to evaluate 11301 * inherited consistently.
8133 * @return return {@code true} if and only if an error code is generated on th e passed node 11302 * @return {@code true} if and only if an error code is generated on the passe d node
11303 * @see StaticTypeWarningCode#INCONSISTENT_METHOD_INHERITANCE
11304 */
11305 bool checkForInconsistentMethodInheritance() {
11306 _inheritanceManager.getMapOfMembersInheritedFromInterfaces(_enclosingClass);
11307 Set<AnalysisError> errors = _inheritanceManager.getErrors(_enclosingClass);
11308 if (errors == null || errors.isEmpty) {
11309 return false;
11310 }
11311 for (AnalysisError error in errors) {
11312 _errorReporter.reportError(error);
11313 }
11314 return true;
11315 }
11316
11317 /**
11318 * Given an assignment using a compound assignment operator, this verifies tha t the given
11319 * assignment is valid.
11320 * @param node the assignment expression being tested
11321 * @return {@code true} if and only if an error code is generated on the passe d node
8134 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT 11322 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
8135 */ 11323 */
8136 bool checkForInvalidAssignment(AssignmentExpression node) { 11324 bool checkForInvalidAssignment(AssignmentExpression node) {
8137 Expression lhs = node.leftHandSide; 11325 Expression lhs = node.leftHandSide;
8138 Expression rhs = node.rightHandSide; 11326 if (lhs == null) {
11327 return false;
11328 }
8139 VariableElement leftElement = getVariableElement(lhs); 11329 VariableElement leftElement = getVariableElement(lhs);
8140 Type2 leftType = (leftElement == null) ? getType(lhs) : leftElement.type; 11330 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty pe;
8141 Type2 rightType = getType(rhs); 11331 MethodElement invokedMethod = node.element;
11332 if (invokedMethod == null) {
11333 return false;
11334 }
11335 Type2 rightType = invokedMethod.type.returnType;
11336 if (leftType == null || rightType == null) {
11337 return false;
11338 }
8142 if (!rightType.isAssignableTo(leftType)) { 11339 if (!rightType.isAssignableTo(leftType)) {
8143 _errorReporter.reportError(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [rightType.name, leftType.name]); 11340 _errorReporter.reportError2(StaticTypeWarningCode.INVALID_ASSIGNMENT, node .rightHandSide, [rightType.displayName, leftType.displayName]);
8144 return true; 11341 return true;
8145 } 11342 }
8146 return false; 11343 return false;
8147 } 11344 }
11345
11346 /**
11347 * This verifies that the passed left hand side and right hand side represent a valid assignment.
11348 * @param lhs the left hand side expression
11349 * @param rhs the right hand side expression
11350 * @return {@code true} if and only if an error code is generated on the passe d node
11351 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
11352 */
11353 bool checkForInvalidAssignment2(Expression lhs, Expression rhs) {
11354 if (lhs == null || rhs == null) {
11355 return false;
11356 }
11357 VariableElement leftElement = getVariableElement(lhs);
11358 Type2 leftType = (leftElement == null) ? getStaticType(lhs) : leftElement.ty pe;
11359 Type2 staticRightType = getStaticType(rhs);
11360 bool isStaticAssignable = staticRightType.isAssignableTo(leftType);
11361 Type2 propagatedRightType = getPropagatedType(rhs);
11362 if (propagatedRightType == null) {
11363 if (!isStaticAssignable) {
11364 _errorReporter.reportError2(StaticTypeWarningCode.INVALID_ASSIGNMENT, rh s, [staticRightType.displayName, leftType.displayName]);
11365 return true;
11366 }
11367 } else {
11368 bool isPropagatedAssignable = propagatedRightType.isAssignableTo(leftType) ;
11369 if (!isStaticAssignable && !isPropagatedAssignable) {
11370 _errorReporter.reportError2(StaticTypeWarningCode.INVALID_ASSIGNMENT, rh s, [staticRightType.displayName, leftType.displayName]);
11371 return true;
11372 }
11373 }
11374 return false;
11375 }
11376
11377 /**
11378 * This verifies that the usage of the passed 'this' is valid.
11379 * @param node the 'this' expression to evaluate
11380 * @return {@code true} if and only if an error code is generated on the passe d node
11381 * @see CompileTimeErrorCode#INVALID_REFERENCE_TO_THIS
11382 */
11383 bool checkForInvalidReferenceToThis(ThisExpression node) {
11384 if (!isThisInValidContext(node)) {
11385 _errorReporter.reportError2(CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS , node, []);
11386 return true;
11387 }
11388 return false;
11389 }
11390
8148 /** 11391 /**
8149 * Checks to ensure that first type argument to a map literal must be the 'Str ing' type. 11392 * Checks to ensure that first type argument to a map literal must be the 'Str ing' type.
8150 * @param arguments a non-{@code null}, non-empty {@link TypeName} node list f rom the respective{@link MapLiteral} 11393 * @param arguments a non-{@code null}, non-empty {@link TypeName} node list f rom the respective{@link MapLiteral}
8151 * @return return {@code true} if and only if an error code is generated on th e passed node 11394 * @return {@code true} if and only if an error code is generated on the passe d node
8152 * @see CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_FOR_KEY 11395 * @see CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_FOR_KEY
8153 */ 11396 */
8154 bool checkForInvalidTypeArgumentForKey(NodeList<TypeName> arguments) { 11397 bool checkForInvalidTypeArgumentForKey(NodeList<TypeName> arguments) {
8155 TypeName firstArgument = arguments[0]; 11398 TypeName firstArgument = arguments[0];
8156 Type2 firstArgumentType = firstArgument.type; 11399 Type2 firstArgumentType = firstArgument.type;
8157 if (firstArgumentType != null && firstArgumentType != _typeProvider.stringTy pe) { 11400 if (firstArgumentType != null && firstArgumentType != _typeProvider.stringTy pe) {
8158 _errorReporter.reportError(CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_FOR_ KEY, firstArgument, []); 11401 _errorReporter.reportError2(CompileTimeErrorCode.INVALID_TYPE_ARGUMENT_FOR _KEY, firstArgument, []);
8159 return true; 11402 return true;
8160 } 11403 }
8161 return false; 11404 return false;
8162 } 11405 }
11406
8163 /** 11407 /**
8164 * Checks to ensure that the passed {@link ListLiteral} or {@link MapLiteral} does not have a type 11408 * Checks to ensure that the passed {@link ListLiteral} or {@link MapLiteral} does not have a type
8165 * parameter as a type argument. 11409 * parameter as a type argument.
8166 * @param arguments a non-{@code null}, non-empty {@link TypeName} node list f rom the respective{@link ListLiteral} or {@link MapLiteral} 11410 * @param arguments a non-{@code null}, non-empty {@link TypeName} node list f rom the respective{@link ListLiteral} or {@link MapLiteral}
8167 * @param errorCode either {@link CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_I N_CONST_LIST} or{@link CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_MAP} 11411 * @param errorCode either {@link CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_I N_CONST_LIST} or{@link CompileTimeErrorCode#INVALID_TYPE_ARGUMENT_IN_CONST_MAP}
8168 * @return {@code true} if and only if an error code is generated on the passe d node 11412 * @return {@code true} if and only if an error code is generated on the passe d node
8169 */ 11413 */
8170 bool checkForInvalidTypeArgumentInConstTypedLiteral(NodeList<TypeName> argumen ts, ErrorCode errorCode) { 11414 bool checkForInvalidTypeArgumentInConstTypedLiteral(NodeList<TypeName> argumen ts, ErrorCode errorCode) {
8171 bool foundError = false; 11415 bool foundError = false;
8172 for (TypeName typeName in arguments) { 11416 for (TypeName typeName in arguments) {
8173 if (typeName.type is TypeVariableType) { 11417 if (typeName.type is TypeVariableType) {
8174 _errorReporter.reportError(errorCode, typeName, [typeName.name]); 11418 _errorReporter.reportError2(errorCode, typeName, [typeName.name]);
8175 foundError = true; 11419 foundError = true;
8176 } 11420 }
8177 } 11421 }
8178 return foundError; 11422 return foundError;
8179 } 11423 }
11424
11425 /**
11426 * This verifies that the {@link #enclosingClass} does not define members with the same name as
11427 * the enclosing class.
11428 * @return {@code true} if and only if an error code is generated on the passe d node
11429 * @see CompileTimeErrorCode#MEMBER_WITH_CLASS_NAME
11430 */
11431 bool checkForMemberWithClassName() {
11432 if (_enclosingClass == null) {
11433 return false;
11434 }
11435 String className = _enclosingClass.name;
11436 if (className == null) {
11437 return false;
11438 }
11439 bool problemReported = false;
11440 for (PropertyAccessorElement accessor in _enclosingClass.accessors) {
11441 if (className == accessor.name) {
11442 _errorReporter.reportError3(CompileTimeErrorCode.MEMBER_WITH_CLASS_NAME, accessor.nameOffset, className.length, []);
11443 problemReported = true;
11444 }
11445 }
11446 return problemReported;
11447 }
11448
11449 /**
11450 * Check to make sure that all similarly typed accessors are of the same type (including inherited
11451 * accessors).
11452 * @param node The accessor currently being visited.
11453 */
11454 void checkForMismatchedAccessorTypes(Declaration accessorDeclaration, String a ccessorTextName) {
11455 PropertyAccessorElement counterpartAccessor = null;
11456 ExecutableElement accessorElement = accessorDeclaration.element as Executabl eElement;
11457 if (accessorElement is! PropertyAccessorElement) {
11458 return;
11459 }
11460 PropertyAccessorElement propertyAccessorElement = accessorElement as Propert yAccessorElement;
11461 counterpartAccessor = propertyAccessorElement.correspondingSetter;
11462 if (counterpartAccessor == null) {
11463 return;
11464 }
11465 Type2 getterType = null;
11466 Type2 setterType = null;
11467 if (propertyAccessorElement.isGetter()) {
11468 getterType = getGetterType(propertyAccessorElement);
11469 setterType = getSetterType(counterpartAccessor);
11470 } else if (propertyAccessorElement.isSetter()) {
11471 setterType = getSetterType(propertyAccessorElement);
11472 counterpartAccessor = propertyAccessorElement.correspondingGetter;
11473 getterType = getGetterType(counterpartAccessor);
11474 }
11475 if (setterType != null && getterType != null && !getterType.isAssignableTo(s etterType)) {
11476 _errorReporter.reportError2(StaticWarningCode.MISMATCHED_GETTER_AND_SETTER _TYPES, accessorDeclaration, [accessorTextName, setterType.displayName, getterTy pe.displayName]);
11477 }
11478 }
11479
11480 /**
11481 * This verifies that the passed mixin does not have an explicitly declared co nstructor.
11482 * @param mixinName the node to report problem on
11483 * @param mixinElement the mixing to evaluate
11484 * @return {@code true} if and only if an error code is generated on the passe d node
11485 * @see CompileTimeErrorCode#MIXIN_DECLARES_CONSTRUCTOR
11486 */
11487 bool checkForMixinDeclaresConstructor(TypeName mixinName, ClassElement mixinEl ement) {
11488 for (ConstructorElement constructor in mixinElement.constructors) {
11489 if (!constructor.isSynthetic() && !constructor.isFactory()) {
11490 _errorReporter.reportError2(CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUC TOR, mixinName, [mixinElement.name]);
11491 return true;
11492 }
11493 }
11494 return false;
11495 }
11496
11497 /**
11498 * This verifies that the passed mixin has the 'Object' superclass.
11499 * @param mixinName the node to report problem on
11500 * @param mixinElement the mixing to evaluate
11501 * @return {@code true} if and only if an error code is generated on the passe d node
11502 * @see CompileTimeErrorCode#MIXIN_INHERITS_FROM_NOT_OBJECT
11503 */
11504 bool checkForMixinInheritsNotFromObject(TypeName mixinName, ClassElement mixin Element) {
11505 InterfaceType mixinSupertype = mixinElement.supertype;
11506 if (mixinSupertype != null) {
11507 if (!mixinSupertype.isObject() || !mixinElement.isTypedef() && mixinElemen t.mixins.length != 0) {
11508 _errorReporter.reportError2(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT _OBJECT, mixinName, [mixinElement.name]);
11509 return true;
11510 }
11511 }
11512 return false;
11513 }
11514
11515 /**
11516 * This verifies that the passed mixin does not reference 'super'.
11517 * @param mixinName the node to report problem on
11518 * @param mixinElement the mixing to evaluate
11519 * @return {@code true} if and only if an error code is generated on the passe d node
11520 * @see CompileTimeErrorCode#MIXIN_REFERENCES_SUPER
11521 */
11522 bool checkForMixinReferencesSuper(TypeName mixinName, ClassElement mixinElemen t) {
11523 if (mixinElement.hasReferenceToSuper()) {
11524 _errorReporter.reportError2(CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, m ixinName, [mixinElement.name]);
11525 }
11526 return false;
11527 }
11528
11529 /**
11530 * This verifies that the passed constructor has at most one 'super' initializ er.
11531 * @param node the constructor declaration to evaluate
11532 * @return {@code true} if and only if an error code is generated on the passe d node
11533 * @see CompileTimeErrorCode#MULTIPLE_SUPER_INITIALIZERS
11534 */
11535 bool checkForMultipleSuperInitializers(ConstructorDeclaration node) {
11536 int numSuperInitializers = 0;
11537 for (ConstructorInitializer initializer in node.initializers) {
11538 if (initializer is SuperConstructorInvocation) {
11539 numSuperInitializers++;
11540 if (numSuperInitializers > 1) {
11541 _errorReporter.reportError2(CompileTimeErrorCode.MULTIPLE_SUPER_INITIA LIZERS, initializer, []);
11542 }
11543 }
11544 }
11545 return numSuperInitializers > 0;
11546 }
11547
8180 /** 11548 /**
8181 * Checks to ensure that native function bodies can only in SDK code. 11549 * Checks to ensure that native function bodies can only in SDK code.
8182 * @param node the native function body to test 11550 * @param node the native function body to test
8183 * @return return {@code true} if and only if an error code is generated on th e passed node 11551 * @return {@code true} if and only if an error code is generated on the passe d node
8184 * @see ParserErrorCode#NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE 11552 * @see ParserErrorCode#NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE
8185 */ 11553 */
8186 bool checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) { 11554 bool checkForNativeFunctionBodyInNonSDKCode(NativeFunctionBody node) {
8187 if (!_isInSystemLibrary) { 11555 if (!_isInSystemLibrary) {
8188 _errorReporter.reportError(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SDK _CODE, node, []); 11556 _errorReporter.reportError2(ParserErrorCode.NATIVE_FUNCTION_BODY_IN_NON_SD K_CODE, node, []);
8189 return true; 11557 return true;
8190 } 11558 }
8191 return false; 11559 return false;
8192 } 11560 }
11561
11562 /**
11563 * This verifies that the passed 'new' instance creation expression invokes ex isting constructor.
11564 * <p>
11565 * This method assumes that the instance creation was tested to be 'new' befor e being called.
11566 * @param node the instance creation expression to evaluate
11567 * @return {@code true} if and only if an error code is generated on the passe d node
11568 * @see StaticWarningCode#NEW_WITH_UNDEFINED_CONSTRUCTOR
11569 */
11570 bool checkForNewWithUndefinedConstructor(InstanceCreationExpression node) {
11571 if (node.element != null) {
11572 return false;
11573 }
11574 ConstructorName constructorName2 = node.constructorName;
11575 if (constructorName2 == null) {
11576 return false;
11577 }
11578 TypeName type2 = constructorName2.type;
11579 if (type2 == null) {
11580 return false;
11581 }
11582 Identifier className = type2.name;
11583 SimpleIdentifier name2 = constructorName2.name;
11584 if (name2 != null) {
11585 _errorReporter.reportError2(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCT OR, name2, [className, name2]);
11586 } else {
11587 _errorReporter.reportError2(StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCT OR_DEFAULT, constructorName2, [className]);
11588 }
11589 return true;
11590 }
11591
11592 /**
11593 * This checks that passed class declaration overrides all members required by its superclasses
11594 * and interfaces.
11595 * @param node the {@link ClassDeclaration} to evaluate
11596 * @return {@code true} if and only if an error code is generated on the passe d node
11597 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE
11598 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO
11599 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE
11600 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR
11601 * @see StaticWarningCode#NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLU S
11602 */
11603 bool checkForNonAbstractClassInheritsAbstractMember(ClassDeclaration node) {
11604 if (_enclosingClass.isAbstract()) {
11605 return false;
11606 }
11607 Set<ExecutableElement> missingOverrides = new Set<ExecutableElement>();
11608 Set<String> methodsInEnclosingClass = new Set<String>();
11609 Set<String> accessorsInEnclosingClass = new Set<String>();
11610 List<MethodElement> methods2 = _enclosingClass.methods;
11611 for (MethodElement method in methods2) {
11612 javaSetAdd(methodsInEnclosingClass, method.name);
11613 }
11614 List<PropertyAccessorElement> accessors2 = _enclosingClass.accessors;
11615 for (PropertyAccessorElement accessor in accessors2) {
11616 javaSetAdd(accessorsInEnclosingClass, accessor.name);
11617 }
11618 Map<String, ExecutableElement> membersInheritedFromSuperclasses = _inheritan ceManager.getMapOfMembersInheritedFromClasses(_enclosingClass);
11619 for (MapEntry<String, ExecutableElement> entry in getMapEntrySet(membersInhe ritedFromSuperclasses)) {
11620 ExecutableElement executableElt = entry.getValue();
11621 if (executableElt is MethodElement) {
11622 MethodElement methodElt = executableElt as MethodElement;
11623 if (methodElt.isAbstract()) {
11624 String methodName = entry.getKey();
11625 if (!methodsInEnclosingClass.contains(methodName)) {
11626 javaSetAdd(missingOverrides, executableElt);
11627 }
11628 }
11629 } else if (executableElt is PropertyAccessorElement) {
11630 PropertyAccessorElement propertyAccessorElt = executableElt as PropertyA ccessorElement;
11631 if (propertyAccessorElt.isAbstract()) {
11632 String accessorName = entry.getKey();
11633 if (!accessorsInEnclosingClass.contains(accessorName)) {
11634 javaSetAdd(missingOverrides, executableElt);
11635 }
11636 }
11637 }
11638 }
11639 Map<String, ExecutableElement> membersInheritedFromInterfaces = _inheritance Manager.getMapOfMembersInheritedFromInterfaces(_enclosingClass);
11640 for (MapEntry<String, ExecutableElement> entry in getMapEntrySet(membersInhe ritedFromInterfaces)) {
11641 ExecutableElement executableElt = entry.getValue();
11642 ExecutableElement elt = membersInheritedFromSuperclasses[executableElt.nam e];
11643 if (elt != null) {
11644 if (elt is MethodElement && !((elt as MethodElement)).isAbstract()) {
11645 continue;
11646 } else if (elt is PropertyAccessorElement && !((elt as PropertyAccessorE lement)).isAbstract()) {
11647 continue;
11648 }
11649 }
11650 if (executableElt is MethodElement) {
11651 String methodName = entry.getKey();
11652 if (!methodsInEnclosingClass.contains(methodName)) {
11653 javaSetAdd(missingOverrides, executableElt);
11654 }
11655 } else if (executableElt is PropertyAccessorElement) {
11656 String accessorName = entry.getKey();
11657 if (!accessorsInEnclosingClass.contains(accessorName)) {
11658 javaSetAdd(missingOverrides, executableElt);
11659 }
11660 }
11661 }
11662 int missingOverridesSize = missingOverrides.length;
11663 if (missingOverridesSize == 0) {
11664 return false;
11665 }
11666 List<ExecutableElement> missingOverridesArray = new List.from(missingOverrid es);
11667 if (missingOverridesSize == 1) {
11668 _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ ABSTRACT_MEMBER_ONE, node.name, [missingOverridesArray[0].enclosingElement.displ ayName, missingOverridesArray[0].displayName]);
11669 } else if (missingOverridesSize == 2) {
11670 _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ ABSTRACT_MEMBER_TWO, node.name, [missingOverridesArray[0].enclosingElement.displ ayName, missingOverridesArray[0].displayName, missingOverridesArray[1].enclosing Element.displayName, missingOverridesArray[1].displayName]);
11671 } else if (missingOverridesSize == 3) {
11672 _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ ABSTRACT_MEMBER_THREE, node.name, [missingOverridesArray[0].enclosingElement.dis playName, missingOverridesArray[0].displayName, missingOverridesArray[1].enclosi ngElement.displayName, missingOverridesArray[1].displayName, missingOverridesArr ay[2].enclosingElement.displayName, missingOverridesArray[2].displayName]);
11673 } else if (missingOverridesSize == 4) {
11674 _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ ABSTRACT_MEMBER_FOUR, node.name, [missingOverridesArray[0].enclosingElement.disp layName, missingOverridesArray[0].displayName, missingOverridesArray[1].enclosin gElement.displayName, missingOverridesArray[1].displayName, missingOverridesArra y[2].enclosingElement.displayName, missingOverridesArray[2].displayName, missing OverridesArray[3].enclosingElement.displayName, missingOverridesArray[3].display Name]);
11675 } else {
11676 _errorReporter.reportError2(StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ ABSTRACT_MEMBER_FIVE_PLUS, node.name, [missingOverridesArray[0].enclosingElement .displayName, missingOverridesArray[0].displayName, missingOverridesArray[1].enc losingElement.displayName, missingOverridesArray[1].displayName, missingOverride sArray[2].enclosingElement.displayName, missingOverridesArray[2].displayName, mi ssingOverridesArray[3].enclosingElement.displayName, missingOverridesArray[3].di splayName, missingOverridesArray.length - 4]);
11677 }
11678 return true;
11679 }
11680
8193 /** 11681 /**
8194 * Checks to ensure that the expressions that need to be of type bool, are. Ot herwise an error is 11682 * Checks to ensure that the expressions that need to be of type bool, are. Ot herwise an error is
8195 * reported on the expression. 11683 * reported on the expression.
8196 * @param condition the conditional expression to test 11684 * @param condition the conditional expression to test
8197 * @return return {@code true} if and only if an error code is generated on th e passed node 11685 * @return {@code true} if and only if an error code is generated on the passe d node
8198 * @see StaticTypeWarningCode#NON_BOOL_CONDITION 11686 * @see StaticTypeWarningCode#NON_BOOL_CONDITION
8199 */ 11687 */
8200 bool checkForNonBoolCondition(Expression condition) { 11688 bool checkForNonBoolCondition(Expression condition) {
8201 Type2 conditionType = getType(condition); 11689 Type2 conditionType = getStaticType(condition);
8202 if (conditionType != null && !conditionType.isAssignableTo(_typeProvider.boo lType)) { 11690 if (conditionType != null && !conditionType.isAssignableTo(_typeProvider.boo lType)) {
8203 _errorReporter.reportError(StaticTypeWarningCode.NON_BOOL_CONDITION, condi tion, []); 11691 _errorReporter.reportError2(StaticTypeWarningCode.NON_BOOL_CONDITION, cond ition, []);
8204 return true; 11692 return true;
8205 } 11693 }
8206 return false; 11694 return false;
8207 } 11695 }
11696
8208 /** 11697 /**
8209 * This verifies that the passed assert statement has either a 'bool' or '() - > bool' input. 11698 * This verifies that the passed assert statement has either a 'bool' or '() - > bool' input.
8210 * @param node the assert statement to evaluate 11699 * @param node the assert statement to evaluate
8211 * @return return {@code true} if and only if an error code is generated on th e passed node 11700 * @return {@code true} if and only if an error code is generated on the passe d node
8212 * @see StaticTypeWarningCode#NON_BOOL_EXPRESSION 11701 * @see StaticTypeWarningCode#NON_BOOL_EXPRESSION
8213 */ 11702 */
8214 bool checkForNonBoolExpression(AssertStatement node) { 11703 bool checkForNonBoolExpression(AssertStatement node) {
8215 Expression expression = node.condition; 11704 Expression expression = node.condition;
8216 Type2 type = getType(expression); 11705 Type2 type = getStaticType(expression);
8217 if (type is InterfaceType) { 11706 if (type is InterfaceType) {
8218 if (!type.isAssignableTo(_typeProvider.boolType)) { 11707 if (!type.isAssignableTo(_typeProvider.boolType)) {
8219 _errorReporter.reportError(StaticTypeWarningCode.NON_BOOL_EXPRESSION, ex pression, []); 11708 _errorReporter.reportError2(StaticTypeWarningCode.NON_BOOL_EXPRESSION, e xpression, []);
8220 return true; 11709 return true;
8221 } 11710 }
8222 } else if (type is FunctionType) { 11711 } else if (type is FunctionType) {
8223 FunctionType functionType = type as FunctionType; 11712 FunctionType functionType = type as FunctionType;
8224 if (functionType.typeArguments.length == 0 && !functionType.returnType.isA ssignableTo(_typeProvider.boolType)) { 11713 if (functionType.typeArguments.length == 0 && !functionType.returnType.isA ssignableTo(_typeProvider.boolType)) {
8225 _errorReporter.reportError(StaticTypeWarningCode.NON_BOOL_EXPRESSION, ex pression, []); 11714 _errorReporter.reportError2(StaticTypeWarningCode.NON_BOOL_EXPRESSION, e xpression, []);
8226 return true; 11715 return true;
8227 } 11716 }
8228 } 11717 }
8229 return false; 11718 return false;
8230 } 11719 }
11720
11721 /**
11722 * This verifies the passed map literal either:
11723 * <ul>
11724 * <li>has {@code const modifier}</li>
11725 * <li>has explicit type arguments</li>
11726 * <li>is not start of the statement</li>
11727 * <ul>
11728 * @param node the map literal to evaluate
11729 * @return {@code true} if and only if an error code is generated on the passe d node
11730 * @see CompileTimeErrorCode#NON_CONST_MAP_AS_EXPRESSION_STATEMENT
11731 */
11732 bool checkForNonConstMapAsExpressionStatement(MapLiteral node) {
11733 if (node.modifier != null) {
11734 return false;
11735 }
11736 if (node.typeArguments != null) {
11737 return false;
11738 }
11739 Statement statement = node.getAncestor(ExpressionStatement);
11740 if (statement == null) {
11741 return false;
11742 }
11743 if (statement.beginToken != node.beginToken) {
11744 return false;
11745 }
11746 _errorReporter.reportError2(CompileTimeErrorCode.NON_CONST_MAP_AS_EXPRESSION _STATEMENT, node, []);
11747 return true;
11748 }
11749
11750 /**
11751 * This verifies the passed method declaration of operator {@code \[\]=}, has {@code void} return
11752 * type.
11753 * @param node the method declaration to evaluate
11754 * @return {@code true} if and only if an error code is generated on the passe d node
11755 * @see StaticWarningCode#NON_VOID_RETURN_FOR_OPERATOR
11756 */
11757 bool checkForNonVoidReturnTypeForOperator(MethodDeclaration node) {
11758 SimpleIdentifier name2 = node.name;
11759 if (name2.name != "[]=") {
11760 return false;
11761 }
11762 TypeName typeName = node.returnType;
11763 if (typeName != null) {
11764 Type2 type2 = typeName.type;
11765 if (type2 != null && !type2.isVoid()) {
11766 _errorReporter.reportError2(StaticWarningCode.NON_VOID_RETURN_FOR_OPERAT OR, typeName, []);
11767 }
11768 }
11769 return false;
11770 }
11771
11772 /**
11773 * This verifies the passed setter has no return type or the {@code void} retu rn type.
11774 * @param typeName the type name to evaluate
11775 * @return {@code true} if and only if an error code is generated on the passe d node
11776 * @see StaticWarningCode#NON_VOID_RETURN_FOR_SETTER
11777 */
11778 bool checkForNonVoidReturnTypeForSetter(TypeName typeName) {
11779 if (typeName != null) {
11780 Type2 type2 = typeName.type;
11781 if (type2 != null && !type2.isVoid()) {
11782 _errorReporter.reportError2(StaticWarningCode.NON_VOID_RETURN_FOR_SETTER , typeName, []);
11783 }
11784 }
11785 return false;
11786 }
11787
8231 /** 11788 /**
8232 * This verifies the passed operator-method declaration, does not have an opti onal parameter. 11789 * This verifies the passed operator-method declaration, does not have an opti onal parameter.
8233 * <p> 11790 * <p>
8234 * This method assumes that the method declaration was tested to be an operato r declaration before 11791 * This method assumes that the method declaration was tested to be an operato r declaration before
8235 * being called. 11792 * being called.
8236 * @param node the method declaration to evaluate 11793 * @param node the method declaration to evaluate
8237 * @return {@code true} if and only if an error code is generated on the passe d node 11794 * @return {@code true} if and only if an error code is generated on the passe d node
8238 * @see CompileTimeErrorCode#OPTIONAL_PARAMETER_IN_OPERATOR 11795 * @see CompileTimeErrorCode#OPTIONAL_PARAMETER_IN_OPERATOR
8239 */ 11796 */
8240 bool checkForOptionalParameterInOperator(MethodDeclaration node) { 11797 bool checkForOptionalParameterInOperator(MethodDeclaration node) {
8241 FormalParameterList parameterList = node.parameters; 11798 FormalParameterList parameterList = node.parameters;
8242 if (parameterList == null) { 11799 if (parameterList == null) {
8243 return false; 11800 return false;
8244 } 11801 }
8245 bool foundError = false; 11802 bool foundError = false;
8246 NodeList<FormalParameter> formalParameters = parameterList.parameters; 11803 NodeList<FormalParameter> formalParameters = parameterList.parameters;
8247 for (FormalParameter formalParameter in formalParameters) { 11804 for (FormalParameter formalParameter in formalParameters) {
8248 if (formalParameter.kind.isOptional()) { 11805 if (formalParameter.kind.isOptional()) {
8249 _errorReporter.reportError(CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_OP ERATOR, formalParameter, []); 11806 _errorReporter.reportError2(CompileTimeErrorCode.OPTIONAL_PARAMETER_IN_O PERATOR, formalParameter, []);
8250 foundError = true; 11807 foundError = true;
8251 } 11808 }
8252 } 11809 }
8253 return foundError; 11810 return foundError;
8254 } 11811 }
11812
8255 /** 11813 /**
8256 * This checks for named optional parameters that begin with '_'. 11814 * This checks for named optional parameters that begin with '_'.
8257 * @param node the default formal parameter to evaluate 11815 * @param node the default formal parameter to evaluate
8258 * @return {@code true} if and only if an error code is generated on the passe d node 11816 * @return {@code true} if and only if an error code is generated on the passe d node
8259 * @see CompileTimeErrorCode#PRIVATE_OPTIONAL_PARAMETER 11817 * @see CompileTimeErrorCode#PRIVATE_OPTIONAL_PARAMETER
8260 */ 11818 */
8261 bool checkForPrivateOptionalParameter(DefaultFormalParameter node) { 11819 bool checkForPrivateOptionalParameter(DefaultFormalParameter node) {
8262 sc.Token separator2 = node.separator; 11820 sc.Token separator2 = node.separator;
8263 if (separator2 != null && separator2.lexeme == ":") { 11821 if (separator2 != null && separator2.lexeme == ":") {
8264 NormalFormalParameter parameter2 = node.parameter; 11822 NormalFormalParameter parameter2 = node.parameter;
8265 SimpleIdentifier name = parameter2.identifier; 11823 SimpleIdentifier name = parameter2.identifier;
8266 if (!name.isSynthetic() && name.name.startsWith("_")) { 11824 if (!name.isSynthetic() && name.name.startsWith("_")) {
8267 _errorReporter.reportError(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAMET ER, node, []); 11825 _errorReporter.reportError2(CompileTimeErrorCode.PRIVATE_OPTIONAL_PARAME TER, node, []);
8268 return true; 11826 return true;
8269 } 11827 }
8270 } 11828 }
8271 return false; 11829 return false;
8272 } 11830 }
11831
11832 /**
11833 * This checks if the passed constructor declaration is the redirecting genera tive constructor and
11834 * references itself directly or indirectly.
11835 * @param node the constructor declaration to evaluate
11836 * @return {@code true} if and only if an error code is generated on the passe d node
11837 * @see CompileTimeErrorCode#RECURSIVE_CONSTRUCTOR_REDIRECT
11838 */
11839 bool checkForRecursiveConstructorRedirect(ConstructorDeclaration node) {
11840 if (node.factoryKeyword != null) {
11841 return false;
11842 }
11843 for (ConstructorInitializer initializer in node.initializers) {
11844 if (initializer is RedirectingConstructorInvocation) {
11845 ConstructorElement element2 = node.element;
11846 if (!hasRedirectingFactoryConstructorCycle(element2)) {
11847 return false;
11848 }
11849 _errorReporter.reportError2(CompileTimeErrorCode.RECURSIVE_CONSTRUCTOR_R EDIRECT, initializer, []);
11850 return true;
11851 }
11852 }
11853 return false;
11854 }
11855
11856 /**
11857 * This checks if the passed constructor declaration has redirected constructo r and references
11858 * itself directly or indirectly.
11859 * @param node the constructor declaration to evaluate
11860 * @return {@code true} if and only if an error code is generated on the passe d node
11861 * @see CompileTimeErrorCode#RECURSIVE_FACTORY_REDIRECT
11862 */
11863 bool checkForRecursiveFactoryRedirect(ConstructorDeclaration node) {
11864 ConstructorName redirectedConstructorNode = node.redirectedConstructor;
11865 if (redirectedConstructorNode == null) {
11866 return false;
11867 }
11868 ConstructorElement element2 = node.element;
11869 if (!hasRedirectingFactoryConstructorCycle(element2)) {
11870 return false;
11871 }
11872 _errorReporter.reportError2(CompileTimeErrorCode.RECURSIVE_FACTORY_REDIRECT, redirectedConstructorNode, []);
11873 return true;
11874 }
11875
11876 /**
11877 * This checks the class declaration is not a superinterface to itself.
11878 * @param classElt the class element to test
11879 * @param list a list containing the potentially cyclic implements path
11880 * @return {@code true} if and only if an error code is generated on the passe d element
11881 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE
11882 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS
11883 * @see CompileTimeErrorCode#RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEME NTS
11884 */
11885 bool checkForRecursiveInterfaceInheritance(ClassElement classElt, List<ClassEl ement> list) {
11886 if (classElt == null) {
11887 return false;
11888 }
11889 InterfaceType supertype2 = classElt.supertype;
11890 list.add(classElt);
11891 if (list.length != 1 && _enclosingClass == classElt) {
11892 String enclosingClassName = _enclosingClass.displayName;
11893 if (list.length > 2) {
11894 String separator = ", ";
11895 int listLength = list.length;
11896 JavaStringBuilder builder = new JavaStringBuilder();
11897 for (int i = 0; i < listLength; i++) {
11898 builder.append(list[i].displayName);
11899 if (i != listLength - 1) {
11900 builder.append(separator);
11901 }
11902 }
11903 _errorReporter.reportError3(CompileTimeErrorCode.RECURSIVE_INTERFACE_INH ERITANCE, _enclosingClass.nameOffset, enclosingClassName.length, [enclosingClass Name, builder.toString()]);
11904 return true;
11905 } else if (list.length == 2) {
11906 ErrorCode errorCode = supertype2 != null && _enclosingClass == supertype 2.element ? CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTEN DS : CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS;
11907 _errorReporter.reportError3(errorCode, _enclosingClass.nameOffset, enclo singClassName.length, [enclosingClassName]);
11908 return true;
11909 }
11910 }
11911 for (int i = 1; i < list.length - 1; i++) {
11912 if (classElt == list[i]) {
11913 list.removeAt(list.length - 1);
11914 return false;
11915 }
11916 }
11917 List<ClassElement> interfaceElements;
11918 List<InterfaceType> interfaceTypes = classElt.interfaces;
11919 if (supertype2 != null && !supertype2.isObject()) {
11920 interfaceElements = new List<ClassElement>(interfaceTypes.length + 1);
11921 interfaceElements[0] = supertype2.element;
11922 for (int i = 0; i < interfaceTypes.length; i++) {
11923 interfaceElements[i + 1] = interfaceTypes[i].element;
11924 }
11925 } else {
11926 interfaceElements = new List<ClassElement>(interfaceTypes.length);
11927 for (int i = 0; i < interfaceTypes.length; i++) {
11928 interfaceElements[i] = interfaceTypes[i].element;
11929 }
11930 }
11931 for (ClassElement classElt2 in interfaceElements) {
11932 if (checkForRecursiveInterfaceInheritance(classElt2, list)) {
11933 return true;
11934 }
11935 }
11936 list.removeAt(list.length - 1);
11937 return false;
11938 }
11939
11940 /**
11941 * This checks the passed constructor declaration has a valid combination of r edirected
11942 * constructor invocation(s), super constructor invocations and field initiali zers.
11943 * @param node the constructor declaration to evaluate
11944 * @return {@code true} if and only if an error code is generated on the passe d node
11945 * @see CompileTimeErrorCode#MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS
11946 * @see CompileTimeErrorCode#SUPER_IN_REDIRECTING_CONSTRUCTOR
11947 * @see CompileTimeErrorCode#FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR
11948 */
11949 bool checkForRedirectingConstructorErrorCodes(ConstructorDeclaration node) {
11950 int numProblems = 0;
11951 int numRedirections = 0;
11952 for (ConstructorInitializer initializer in node.initializers) {
11953 if (initializer is RedirectingConstructorInvocation) {
11954 if (numRedirections > 0) {
11955 _errorReporter.reportError2(CompileTimeErrorCode.MULTIPLE_REDIRECTING_ CONSTRUCTOR_INVOCATIONS, initializer, []);
11956 numProblems++;
11957 }
11958 numRedirections++;
11959 }
11960 }
11961 if (numRedirections > 0) {
11962 for (ConstructorInitializer initializer in node.initializers) {
11963 if (initializer is SuperConstructorInvocation) {
11964 _errorReporter.reportError2(CompileTimeErrorCode.SUPER_IN_REDIRECTING_ CONSTRUCTOR, initializer, []);
11965 numProblems++;
11966 }
11967 if (initializer is ConstructorFieldInitializer) {
11968 _errorReporter.reportError2(CompileTimeErrorCode.FIELD_INITIALIZER_RED IRECTING_CONSTRUCTOR, initializer, []);
11969 numProblems++;
11970 }
11971 }
11972 }
11973 return numProblems != 0;
11974 }
11975
11976 /**
11977 * This checks if the passed constructor declaration has redirected constructo r with compatible
11978 * function type.
11979 * @param node the constructor declaration to evaluate
11980 * @return {@code true} if and only if an error code is generated on the passe d node
11981 * @see StaticWarningCode#REDIRECT_TO_INVALID_RETURN_TYPE
11982 * @see StaticWarningCode#REDIRECT_TO_INVALID_FUNCTION_TYPE
11983 */
11984 bool checkForRedirectToInvalidFunction(ConstructorDeclaration node) {
11985 ConstructorName redirectedNode = node.redirectedConstructor;
11986 if (redirectedNode == null) {
11987 return false;
11988 }
11989 ConstructorElement redirectedElement = redirectedNode.element;
11990 if (redirectedElement == null) {
11991 return false;
11992 }
11993 FunctionType redirectedType = redirectedElement.type;
11994 Type2 redirectedReturnType = redirectedType.returnType;
11995 FunctionType constructorType = node.element.type;
11996 Type2 constructorReturnType = constructorType.returnType;
11997 if (!redirectedReturnType.isSubtypeOf(constructorReturnType)) {
11998 _errorReporter.reportError2(StaticWarningCode.REDIRECT_TO_INVALID_RETURN_T YPE, redirectedNode, [redirectedReturnType, constructorReturnType]);
11999 return true;
12000 }
12001 if (!redirectedType.isSubtypeOf(constructorType)) {
12002 _errorReporter.reportError2(StaticWarningCode.REDIRECT_TO_INVALID_FUNCTION _TYPE, redirectedNode, [redirectedType, constructorType]);
12003 return true;
12004 }
12005 return false;
12006 }
12007
12008 /**
12009 * This checks if the passed constructor declaration has redirected constructo r and references
12010 * itself directly or indirectly. TODO(scheglov)
12011 * @param node the constructor declaration to evaluate
12012 * @return {@code true} if and only if an error code is generated on the passe d node
12013 * @see CompileTimeErrorCode#REDIRECT_TO_NON_CONST_CONSTRUCTOR
12014 */
12015 bool checkForRedirectToNonConstConstructor(ConstructorDeclaration node) {
12016 ConstructorName redirectedConstructorNode = node.redirectedConstructor;
12017 if (redirectedConstructorNode == null) {
12018 return false;
12019 }
12020 ConstructorElement element2 = node.element;
12021 if (element2 == null) {
12022 return false;
12023 }
12024 if (!element2.isConst()) {
12025 return false;
12026 }
12027 ConstructorElement redirectedConstructor2 = element2.redirectedConstructor;
12028 if (redirectedConstructor2 == null) {
12029 return false;
12030 }
12031 if (redirectedConstructor2.isConst()) {
12032 return false;
12033 }
12034 _errorReporter.reportError2(CompileTimeErrorCode.REDIRECT_TO_NON_CONST_CONST RUCTOR, redirectedConstructorNode, []);
12035 return true;
12036 }
12037
12038 /**
12039 * This checks if the passed identifier is banned because it is part of the va riable declaration
12040 * with the same name.
12041 * @param node the identifier to evaluate
12042 * @return {@code true} if and only if an error code is generated on the passe d node
12043 * @see CompileTimeErrorCode#REFERENCE_TO_DECLARED_VARIABLE_IN_INITIALIZER
12044 */
12045 bool checkForReferenceToDeclaredVariableInInitializer(SimpleIdentifier node) {
12046 ASTNode parent2 = node.parent;
12047 if (parent2 is PrefixedIdentifier) {
12048 PrefixedIdentifier prefixedIdentifier = parent2 as PrefixedIdentifier;
12049 if (identical(prefixedIdentifier.identifier, node)) {
12050 return false;
12051 }
12052 }
12053 if (parent2 is PropertyAccess) {
12054 PropertyAccess propertyAccess = parent2 as PropertyAccess;
12055 if (identical(propertyAccess.propertyName, node)) {
12056 return false;
12057 }
12058 }
12059 if (parent2 is MethodInvocation) {
12060 MethodInvocation methodInvocation = parent2 as MethodInvocation;
12061 if (methodInvocation.target != null && identical(methodInvocation.methodNa me, node)) {
12062 return false;
12063 }
12064 }
12065 if (parent2 is ConstructorName) {
12066 ConstructorName constructorName = parent2 as ConstructorName;
12067 if (identical(constructorName.name, node)) {
12068 return false;
12069 }
12070 }
12071 if (parent2 is Label) {
12072 Label label = parent2 as Label;
12073 if (identical(label.label, node)) {
12074 return false;
12075 }
12076 }
12077 String name2 = node.name;
12078 if (!_namesForReferenceToDeclaredVariableInInitializer.contains(name2)) {
12079 return false;
12080 }
12081 _errorReporter.reportError2(CompileTimeErrorCode.REFERENCE_TO_DECLARED_VARIA BLE_IN_INITIALIZER, node, [name2]);
12082 return true;
12083 }
12084
8273 /** 12085 /**
8274 * This checks that the rethrow is inside of a catch clause. 12086 * This checks that the rethrow is inside of a catch clause.
8275 * @param node the rethrow expression to evaluate 12087 * @param node the rethrow expression to evaluate
8276 * @return {@code true} if and only if an error code is generated on the passe d node 12088 * @return {@code true} if and only if an error code is generated on the passe d node
8277 * @see CompileTimeErrorCode#RETHROW_OUTSIDE_CATCH 12089 * @see CompileTimeErrorCode#RETHROW_OUTSIDE_CATCH
8278 */ 12090 */
8279 bool checkForRethrowOutsideCatch(RethrowExpression node) { 12091 bool checkForRethrowOutsideCatch(RethrowExpression node) {
8280 if (!_isInCatchClause) { 12092 if (!_isInCatchClause) {
8281 _errorReporter.reportError(CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, nod e, []); 12093 _errorReporter.reportError2(CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, no de, []);
8282 return true; 12094 return true;
8283 } 12095 }
8284 return false; 12096 return false;
8285 } 12097 }
12098
12099 /**
12100 * This checks that if the given "target" is the type reference then the "name " is not the
12101 * reference to a instance member.
12102 * @param target the target of the name access to evaluate
12103 * @param name the accessed name to evaluate
12104 * @return {@code true} if and only if an error code is generated on the passe d node
12105 * @see StaticWarningCode#STATIC_ACCESS_TO_INSTANCE_MEMBER
12106 */
12107 bool checkForStaticAccessToInstanceMember(Expression target, SimpleIdentifier name2) {
12108 Element element2 = name2.element;
12109 if (element2 is! ExecutableElement) {
12110 return false;
12111 }
12112 ExecutableElement memberElement = element2 as ExecutableElement;
12113 if (memberElement.isStatic()) {
12114 return false;
12115 }
12116 if (!isTypeReference(target)) {
12117 return false;
12118 }
12119 _errorReporter.reportError2(StaticWarningCode.STATIC_ACCESS_TO_INSTANCE_MEMB ER, name2, [name2.name]);
12120 return true;
12121 }
12122
12123 /**
12124 * This checks that the type of the passed 'switch' expression is assignable t o the type of the
12125 * 'case' members.
12126 * @param node the 'switch' statement to evaluate
12127 * @return {@code true} if and only if an error code is generated on the passe d node
12128 * @see StaticWarningCode#SWITCH_EXPRESSION_NOT_ASSIGNABLE
12129 */
12130 bool checkForSwitchExpressionNotAssignable(SwitchStatement node) {
12131 Expression expression2 = node.expression;
12132 Type2 expressionType = getStaticType(expression2);
12133 if (expressionType == null) {
12134 return false;
12135 }
12136 NodeList<SwitchMember> members2 = node.members;
12137 for (SwitchMember switchMember in members2) {
12138 if (switchMember is! SwitchCase) {
12139 continue;
12140 }
12141 SwitchCase switchCase = switchMember as SwitchCase;
12142 Expression caseExpression = switchCase.expression;
12143 Type2 caseType = getStaticType(caseExpression);
12144 if (expressionType.isAssignableTo(caseType)) {
12145 return false;
12146 }
12147 _errorReporter.reportError2(StaticWarningCode.SWITCH_EXPRESSION_NOT_ASSIGN ABLE, expression2, [expressionType, caseType]);
12148 return true;
12149 }
12150 return false;
12151 }
12152
8286 /** 12153 /**
8287 * This verifies that the type arguments in the passed instance creation expre ssion are all within 12154 * This verifies that the type arguments in the passed instance creation expre ssion are all within
8288 * their bounds as specified by the class element where the constructor \[that is being invoked\] is 12155 * their bounds as specified by the class element where the constructor \[that is being invoked\] is
8289 * declared. 12156 * declared.
8290 * @param node the instance creation expression to evaluate 12157 * @param node the instance creation expression to evaluate
8291 * @param typeName the {@link TypeName} of the {@link ConstructorName} from th e{@link InstanceCreationExpression}, this is the AST node that the error is atta ched to 12158 * @param typeName the {@link TypeName} of the {@link ConstructorName} from th e{@link InstanceCreationExpression}, this is the AST node that the error is atta ched to
8292 * @param constructorElement the {@link ConstructorElement} from the instance creation expression 12159 * @param constructorElement the {@link ConstructorElement} from the instance creation expression
8293 * @return return {@code true} if and only if an error code is generated on th e passed node 12160 * @return {@code true} if and only if an error code is generated on the passe d node
8294 * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS 12161 * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
8295 */ 12162 */
8296 bool checkForTypeArgumentNotMatchingBounds(InstanceCreationExpression node, Co nstructorElement constructorElement, TypeName typeName) { 12163 bool checkForTypeArgumentNotMatchingBounds(InstanceCreationExpression node, Co nstructorElement constructorElement, TypeName typeName) {
8297 if (typeName.typeArguments != null && constructorElement != null) { 12164 if (typeName.typeArguments != null && constructorElement != null) {
8298 NodeList<TypeName> typeNameArgList = typeName.typeArguments.arguments; 12165 NodeList<TypeName> typeNameArgList = typeName.typeArguments.arguments;
8299 List<TypeVariableElement> boundingElts = constructorElement.enclosingEleme nt.typeVariables; 12166 List<TypeVariableElement> boundingElts = constructorElement.enclosingEleme nt.typeVariables;
8300 int loopThroughIndex = Math.min(typeNameArgList.length, boundingElts.lengt h); 12167 int loopThroughIndex = Math.min(typeNameArgList.length, boundingElts.lengt h);
8301 for (int i = 0; i < loopThroughIndex; i++) { 12168 for (int i = 0; i < loopThroughIndex; i++) {
8302 TypeName argTypeName = typeNameArgList[i]; 12169 TypeName argTypeName = typeNameArgList[i];
8303 Type2 argType = argTypeName.type; 12170 Type2 argType = argTypeName.type;
8304 Type2 boundType = boundingElts[i].bound; 12171 Type2 boundType = boundingElts[i].bound;
8305 if (argType != null && boundType != null) { 12172 if (argType != null && boundType != null) {
8306 if (!argType.isSubtypeOf(boundType)) { 12173 if (!argType.isSubtypeOf(boundType)) {
8307 _errorReporter.reportError(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_M ATCHING_BOUNDS, argTypeName, [argTypeName.name, boundingElts[i].name]); 12174 _errorReporter.reportError2(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_ MATCHING_BOUNDS, argTypeName, [argTypeName.name, boundingElts[i].displayName]);
8308 return true; 12175 return true;
8309 } 12176 }
8310 } 12177 }
8311 } 12178 }
8312 } 12179 }
8313 return false; 12180 return false;
8314 } 12181 }
12182
8315 /** 12183 /**
8316 * This verifies if the passed setter method declaration, has only one paramet er. 12184 * This checks that if the passed generative constructor has no explicit super constructor
12185 * invocation, then super class has the default generative constructor.
12186 * @param node the constructor declaration to evaluate
12187 * @return {@code true} if and only if an error code is generated on the passe d node
12188 * @see CompileTimeErrorCode#UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT
12189 * @see CompileTimeErrorCode#NON_GENERATIVE_CONSTRUCTOR
12190 */
12191 bool checkForUndefinedConstructorInInitializerImplicit(ConstructorDeclaration node) {
12192 if (node.factoryKeyword != null) {
12193 return false;
12194 }
12195 if (_enclosingClass == null) {
12196 return false;
12197 }
12198 InterfaceType superType = _enclosingClass.supertype;
12199 if (superType == null) {
12200 return false;
12201 }
12202 ClassElement superElement = superType.element;
12203 for (ConstructorInitializer constructorInitializer in node.initializers) {
12204 if (constructorInitializer is SuperConstructorInvocation) {
12205 return false;
12206 }
12207 }
12208 ConstructorElement superDefaultConstructor = superElement.unnamedConstructor ;
12209 if (superDefaultConstructor != null) {
12210 if (superDefaultConstructor.isFactory()) {
12211 _errorReporter.reportError2(CompileTimeErrorCode.NON_GENERATIVE_CONSTRUC TOR, node.returnType, [superDefaultConstructor]);
12212 return true;
12213 }
12214 return false;
12215 }
12216 _errorReporter.reportError2(CompileTimeErrorCode.UNDEFINED_CONSTRUCTOR_IN_IN ITIALIZER_DEFAULT, node.returnType, [superElement.name]);
12217 return true;
12218 }
12219
12220 /**
12221 * This verifies the passed operator-method declaration, has correct number of parameters.
8317 * <p> 12222 * <p>
8318 * This method assumes that the method declaration was tested to be a setter b efore being called. 12223 * This method assumes that the method declaration was tested to be an operato r declaration before
12224 * being called.
8319 * @param node the method declaration to evaluate 12225 * @param node the method declaration to evaluate
8320 * @return return {@code true} if and only if an error code is generated on th e passed node 12226 * @return {@code true} if and only if an error code is generated on the passe d node
8321 * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER 12227 * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_OPERATOR
8322 */ 12228 */
8323 bool checkForWrongNumberOfParametersForSetter(MethodDeclaration node) { 12229 bool checkForWrongNumberOfParametersForOperator(MethodDeclaration node) {
8324 FormalParameterList parameterList = node.parameters; 12230 FormalParameterList parameterList = node.parameters;
8325 if (parameterList == null) { 12231 if (parameterList == null) {
8326 return false; 12232 return false;
8327 } 12233 }
8328 NodeList<FormalParameter> formalParameters = parameterList.parameters; 12234 int numParameters = parameterList.parameters.length;
8329 int numberOfParameters = formalParameters.length; 12235 SimpleIdentifier nameNode = node.name;
8330 if (numberOfParameters != 1) { 12236 if (nameNode == null) {
8331 _errorReporter.reportError(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETERS _FOR_SETTER, node.name, [numberOfParameters]); 12237 return false;
12238 }
12239 String name2 = nameNode.name;
12240 int expected = -1;
12241 if ("[]=" == name2) {
12242 expected = 2;
12243 } else if ("<" == name2 || ">" == name2 || "<=" == name2 || ">=" == name2 || "==" == name2 || "+" == name2 || "/" == name2 || "~/" == name2 || "*" == name2 || "%" == name2 || "|" == name2 || "^" == name2 || "&" == name2 || "<<" == name2 || ">>" == name2 || "[]" == name2) {
12244 expected = 1;
12245 } else if ("~" == name2) {
12246 expected = 0;
12247 }
12248 if (expected != -1 && numParameters != expected) {
12249 _errorReporter.reportError2(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETER S_FOR_OPERATOR, nameNode, [name2, expected, numParameters]);
12250 return true;
12251 }
12252 if ("-" == name2 && numParameters > 1) {
12253 _errorReporter.reportError2(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETER S_FOR_OPERATOR_MINUS, nameNode, [numParameters]);
8332 return true; 12254 return true;
8333 } 12255 }
8334 return false; 12256 return false;
8335 } 12257 }
12258
8336 /** 12259 /**
8337 * Return the type of the given expression that is to be used for type analysi s. 12260 * This verifies if the passed setter parameter list have only one parameter.
12261 * <p>
12262 * This method assumes that the method declaration was tested to be a setter b efore being called.
12263 * @param setterName the name of the setter to report problems on
12264 * @param parameterList the parameter list to evaluate
12265 * @return {@code true} if and only if an error code is generated on the passe d node
12266 * @see CompileTimeErrorCode#WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER
12267 */
12268 bool checkForWrongNumberOfParametersForSetter(SimpleIdentifier setterName, For malParameterList parameterList) {
12269 if (setterName == null) {
12270 return false;
12271 }
12272 if (parameterList == null) {
12273 return false;
12274 }
12275 int numberOfParameters = parameterList.parameters.length;
12276 if (numberOfParameters != 1) {
12277 _errorReporter.reportError2(CompileTimeErrorCode.WRONG_NUMBER_OF_PARAMETER S_FOR_SETTER, setterName, [numberOfParameters]);
12278 return true;
12279 }
12280 return false;
12281 }
12282
12283 /**
12284 * Return the propagated type of the given expression, or the static type if t here is no
12285 * propagated type information.
8338 * @param expression the expression whose type is to be returned 12286 * @param expression the expression whose type is to be returned
8339 * @return the type of the given expression 12287 * @return the propagated or static type of the given expression, whichever is best
8340 */ 12288 */
8341 Type2 getType(Expression expression) { 12289 Type2 getBestType(Expression expression) {
12290 Type2 type = getPropagatedType(expression);
12291 if (type == null) {
12292 type = getStaticType(expression);
12293 }
12294 return type;
12295 }
12296
12297 /**
12298 * Returns the Type (return type) for a given getter.
12299 * @param propertyAccessorElement
12300 * @return The type of the given getter.
12301 */
12302 Type2 getGetterType(PropertyAccessorElement propertyAccessorElement) {
12303 FunctionType functionType = propertyAccessorElement.type;
12304 if (functionType != null) {
12305 return functionType.returnType;
12306 } else {
12307 return null;
12308 }
12309 }
12310
12311 /**
12312 * Return the propagated type of the given expression that is to be used for t ype analysis.
12313 * @param expression the expression whose type is to be returned
12314 * @return the propagated type of the given expression
12315 */
12316 Type2 getPropagatedType(Expression expression) => expression.propagatedType;
12317
12318 /**
12319 * Returns the Type (first and only parameter) for a given setter.
12320 * @param propertyAccessorElement
12321 * @return The type of the given setter.
12322 */
12323 Type2 getSetterType(PropertyAccessorElement propertyAccessorElement) {
12324 List<ParameterElement> setterParameters = propertyAccessorElement.parameters ;
12325 if (setterParameters.length == 0) {
12326 return null;
12327 }
12328 return setterParameters[0].type;
12329 }
12330
12331 /**
12332 * Return the static type of the given expression that is to be used for type analysis.
12333 * @param expression the expression whose type is to be returned
12334 * @return the static type of the given expression
12335 */
12336 Type2 getStaticType(Expression expression) {
8342 Type2 type = expression.staticType; 12337 Type2 type = expression.staticType;
8343 return type == null ? _dynamicType : type; 12338 if (type == null) {
12339 return _dynamicType;
12340 }
12341 return type;
8344 } 12342 }
12343
8345 /** 12344 /**
8346 * Return the variable element represented by the given expression, or {@code null} if there is no 12345 * Return the variable element represented by the given expression, or {@code null} if there is no
8347 * such element. 12346 * such element.
8348 * @param expression the expression whose element is to be returned 12347 * @param expression the expression whose element is to be returned
8349 * @return the variable element represented by the expression 12348 * @return the variable element represented by the expression
8350 */ 12349 */
8351 VariableElement getVariableElement(Expression expression) { 12350 VariableElement getVariableElement(Expression expression) {
8352 if (expression is Identifier) { 12351 if (expression is Identifier) {
8353 Element element2 = ((expression as Identifier)).element; 12352 Element element2 = ((expression as Identifier)).element;
8354 if (element2 is VariableElement) { 12353 if (element2 is VariableElement) {
8355 return element2 as VariableElement; 12354 return element2 as VariableElement;
8356 } 12355 }
8357 } 12356 }
8358 return null; 12357 return null;
8359 } 12358 }
12359
12360 /**
12361 * @return {@code true} if the given constructor redirects to itself, directly or indirectly
12362 */
12363 bool hasRedirectingFactoryConstructorCycle(ConstructorElement element) {
12364 Set<ConstructorElement> constructors = new Set<ConstructorElement>();
12365 ConstructorElement current = element;
12366 while (current != null) {
12367 if (constructors.contains(current)) {
12368 return identical(current, element);
12369 }
12370 javaSetAdd(constructors, current);
12371 current = current.redirectedConstructor;
12372 if (current is ConstructorMember) {
12373 current = ((current as ConstructorMember)).baseElement;
12374 }
12375 }
12376 return false;
12377 }
12378
12379 /**
12380 * @param node the 'this' expression to analyze
12381 * @return {@code true} if the given 'this' expression is in the valid context
12382 */
12383 bool isThisInValidContext(ThisExpression node) {
12384 for (ASTNode n = node; n != null; n = n.parent) {
12385 if (n is CompilationUnit) {
12386 return false;
12387 }
12388 if (n is ConstructorDeclaration) {
12389 ConstructorDeclaration constructor = n as ConstructorDeclaration;
12390 return constructor.factoryKeyword == null;
12391 }
12392 if (n is ConstructorFieldInitializer) {
12393 return false;
12394 }
12395 if (n is MethodDeclaration) {
12396 MethodDeclaration method = n as MethodDeclaration;
12397 return !method.isStatic();
12398 }
12399 }
12400 return false;
12401 }
8360 } 12402 }
12403
8361 /** 12404 /**
8362 * This enum holds one of four states of a field initialization state through a constructor 12405 * This enum holds one of four states of a field initialization state through a constructor
8363 * signature, not initialized, initialized in the field declaration, initialized in the field 12406 * signature, not initialized, initialized in the field declaration, initialized in the field
8364 * formal, and finally, initialized in the initializers list. 12407 * formal, and finally, initialized in the initializers list.
8365 */ 12408 */
8366 class INIT_STATE implements Comparable<INIT_STATE> { 12409 class INIT_STATE implements Comparable<INIT_STATE> {
8367 static final INIT_STATE NOT_INIT = new INIT_STATE('NOT_INIT', 0); 12410 static final INIT_STATE NOT_INIT = new INIT_STATE('NOT_INIT', 0);
8368 static final INIT_STATE INIT_IN_DECLARATION = new INIT_STATE('INIT_IN_DECLARAT ION', 1); 12411 static final INIT_STATE INIT_IN_DECLARATION = new INIT_STATE('INIT_IN_DECLARAT ION', 1);
8369 static final INIT_STATE INIT_IN_FIELD_FORMAL = new INIT_STATE('INIT_IN_FIELD_F ORMAL', 2); 12412 static final INIT_STATE INIT_IN_FIELD_FORMAL = new INIT_STATE('INIT_IN_FIELD_F ORMAL', 2);
8370 static final INIT_STATE INIT_IN_DEFAULT_VALUE = new INIT_STATE('INIT_IN_DEFAUL T_VALUE', 3); 12413 static final INIT_STATE INIT_IN_DEFAULT_VALUE = new INIT_STATE('INIT_IN_DEFAUL T_VALUE', 3);
8371 static final INIT_STATE INIT_IN_INITIALIZERS = new INIT_STATE('INIT_IN_INITIAL IZERS', 4); 12414 static final INIT_STATE INIT_IN_INITIALIZERS = new INIT_STATE('INIT_IN_INITIAL IZERS', 4);
8372 static final List<INIT_STATE> values = [NOT_INIT, INIT_IN_DECLARATION, INIT_IN _FIELD_FORMAL, INIT_IN_DEFAULT_VALUE, INIT_IN_INITIALIZERS]; 12415 static final List<INIT_STATE> values = [NOT_INIT, INIT_IN_DECLARATION, INIT_IN _FIELD_FORMAL, INIT_IN_DEFAULT_VALUE, INIT_IN_INITIALIZERS];
8373 final String __name; 12416
8374 final int __ordinal; 12417 /// The name of this enum constant, as declared in the enum declaration.
8375 int get ordinal => __ordinal; 12418 final String name;
8376 INIT_STATE(this.__name, this.__ordinal) { 12419
12420 /// The position in the enum declaration.
12421 final int ordinal;
12422 INIT_STATE(this.name, this.ordinal) {
8377 } 12423 }
8378 int compareTo(INIT_STATE other) => __ordinal - other.__ordinal; 12424 int compareTo(INIT_STATE other) => ordinal - other.ordinal;
8379 String toString() => __name; 12425 String toString() => name;
8380 } 12426 }
12427
8381 /** 12428 /**
8382 * The enumeration {@code ResolverErrorCode} defines the error codes used for er rors detected by the 12429 * The enumeration {@code ResolverErrorCode} defines the error codes used for er rors detected by the
8383 * resolver. The convention for this class is for the name of the error code to indicate the problem 12430 * resolver. The convention for this class is for the name of the error code to indicate the problem
8384 * that caused the error to be generated and for the error message to explain wh at is wrong and, 12431 * that caused the error to be generated and for the error message to explain wh at is wrong and,
8385 * when appropriate, how the problem can be corrected. 12432 * when appropriate, how the problem can be corrected.
8386 * @coverage dart.engine.resolver 12433 * @coverage dart.engine.resolver
8387 */ 12434 */
8388 class ResolverErrorCode implements Comparable<ResolverErrorCode>, ErrorCode { 12435 class ResolverErrorCode implements Comparable<ResolverErrorCode>, ErrorCode {
8389 static final ResolverErrorCode BREAK_LABEL_ON_SWITCH_MEMBER = new ResolverErro rCode('BREAK_LABEL_ON_SWITCH_MEMBER', 0, ErrorType.COMPILE_TIME_ERROR, "Break la bel resolves to case or default statement"); 12436 static final ResolverErrorCode BREAK_LABEL_ON_SWITCH_MEMBER = new ResolverErro rCode('BREAK_LABEL_ON_SWITCH_MEMBER', 0, ErrorType.COMPILE_TIME_ERROR, "Break la bel resolves to case or default statement");
8390 static final ResolverErrorCode CONTINUE_LABEL_ON_SWITCH = new ResolverErrorCod e('CONTINUE_LABEL_ON_SWITCH', 1, ErrorType.COMPILE_TIME_ERROR, "A continue label resolves to switch, must be loop or switch member"); 12437 static final ResolverErrorCode CONTINUE_LABEL_ON_SWITCH = new ResolverErrorCod e('CONTINUE_LABEL_ON_SWITCH', 1, ErrorType.COMPILE_TIME_ERROR, "A continue label resolves to switch, must be loop or switch member");
8391 static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_WITH_PART = new Resol verErrorCode('MISSING_LIBRARY_DIRECTIVE_WITH_PART', 2, ErrorType.COMPILE_TIME_ER ROR, "Libraries that have parts must have a library directive"); 12438 static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_WITH_PART = new Resol verErrorCode('MISSING_LIBRARY_DIRECTIVE_WITH_PART', 2, ErrorType.COMPILE_TIME_ER ROR, "Libraries that have parts must have a library directive");
8392 static final List<ResolverErrorCode> values = [BREAK_LABEL_ON_SWITCH_MEMBER, C ONTINUE_LABEL_ON_SWITCH, MISSING_LIBRARY_DIRECTIVE_WITH_PART]; 12439 static final List<ResolverErrorCode> values = [BREAK_LABEL_ON_SWITCH_MEMBER, C ONTINUE_LABEL_ON_SWITCH, MISSING_LIBRARY_DIRECTIVE_WITH_PART];
8393 final String __name; 12440
8394 final int __ordinal; 12441 /// The name of this enum constant, as declared in the enum declaration.
8395 int get ordinal => __ordinal; 12442 final String name;
12443
12444 /// The position in the enum declaration.
12445 final int ordinal;
12446
8396 /** 12447 /**
8397 * The type of this error. 12448 * The type of this error.
8398 */ 12449 */
8399 ErrorType _type; 12450 ErrorType _type;
12451
8400 /** 12452 /**
8401 * The message template used to create the message to be displayed for this er ror. 12453 * The message template used to create the message to be displayed for this er ror.
8402 */ 12454 */
8403 String _message; 12455 String _message;
12456
8404 /** 12457 /**
8405 * Initialize a newly created error code to have the given type and message. 12458 * Initialize a newly created error code to have the given type and message.
8406 * @param type the type of this error 12459 * @param type the type of this error
8407 * @param message the message template used to create the message to be displa yed for the error 12460 * @param message the message template used to create the message to be displa yed for the error
8408 */ 12461 */
8409 ResolverErrorCode(this.__name, this.__ordinal, ErrorType type, String message) { 12462 ResolverErrorCode(this.name, this.ordinal, ErrorType type, String message) {
8410 this._type = type; 12463 this._type = type;
8411 this._message = message; 12464 this._message = message;
8412 } 12465 }
8413 ErrorSeverity get errorSeverity => _type.severity; 12466 ErrorSeverity get errorSeverity => _type.severity;
8414 String get message => _message; 12467 String get message => _message;
8415 ErrorType get type => _type; 12468 ErrorType get type => _type;
8416 bool needsRecompilation() => true; 12469 int compareTo(ResolverErrorCode other) => ordinal - other.ordinal;
8417 int compareTo(ResolverErrorCode other) => __ordinal - other.__ordinal; 12470 String toString() => name;
8418 String toString() => __name; 12471 }
8419 }
OLDNEW
« no previous file with comments | « pkg/analyzer_experimental/lib/src/generated/parser.dart ('k') | pkg/analyzer_experimental/lib/src/generated/scanner.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698