OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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>, …, T<sub>n</sub> a<sub>n</sub>
, \[T<sub>n+1</sub> | 6180 * form <i>(T<sub>1</sub> a<sub>1</sub>, …, T<sub>n</sub> a<sub>n</sub>
, \[T<sub>n+1</sub> |
4839 * x<sub>n+1</sub> = d1, …, T<sub>n+k</sub> x<sub>n+k</sub> = dk\]) =>
e</i> is | 6181 * x<sub>n+1</sub> = d1, …, T<sub>n+k</sub> x<sub>n+k</sub> = dk\]) =>
e</i> is |
4840 * <i>(T<sub>1</sub>, …, Tn, \[T<sub>n+1</sub> x<sub>n+1</sub>, &hellip
;, T<sub>n+k</sub> | 6182 * <i>(T<sub>1</sub>, …, Tn, \[T<sub>n+1</sub> x<sub>n+1</sub>, &hellip
;, T<sub>n+k</sub> |
4841 * x<sub>n+k</sub>\]) → T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is
the static type of | 6183 * x<sub>n+k</sub>\]) → 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 <= i <= n</i>, is not
specified, it is | 6184 * <i>e</i>. In any case where <i>T<sub>i</sub>, 1 <= i <= 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>, …, | 6187 * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1
</sub>, …, |
(...skipping 15 matching lines...) Expand all Loading... |
4861 * x<sub>n+k</sub> : dk}) {s}</i> is <i>(T<sub>1</sub>, …, T<sub>n</sub
>, {T<sub>n+1</sub> | 6203 * x<sub>n+k</sub> : dk}) {s}</i> is <i>(T<sub>1</sub>, …, T<sub>n</sub
>, {T<sub>n+1</sub> |
4862 * x<sub>n+1</sub>, …, T<sub>n+k</sub> x<sub>n+k</sub>}) → dynamic
</i>. In any case | 6204 * x<sub>n+1</sub>, …, T<sub>n+k</sub> x<sub>n+k</sub>}) → dynamic
</i>. In any case |
4863 * where <i>T<sub>i</sub>, 1 <= i <= n</i>, is not specified, it is cons
idered to have been | 6205 * where <i>T<sub>i</sub>, 1 <= i <= 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>, …, a<sub>n</sub>, x<sub
>n+1</sub>: | 6220 * has the form <i>e<sub>f</sub>(a<sub>1</sub>, …, a<sub>n</sub>, x<sub
>n+1</sub>: |
4877 * a<sub>n+1</sub>, …, 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>, …, 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>, …, a<sub>n</sub>)</i> or
the form <i>new | 6278 * either the form <i>new T.id(a<sub>1</sub>, …, a<sub>n</sub>)</i> or
the form <i>new |
4901 * T(a<sub>1</sub>, …, a<sub>n</sub>)</i> is <i>T</i>.</blockquote> | 6279 * T(a<sub>1</sub>, …, 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>, …, a<sub>
n</sub>)</i> or the | 6282 * expression of either the form <i>const T.id(a<sub>1</sub>, …, a<sub>
n</sub>)</i> or the |
4905 * form <i>const T(a<sub>1</sub>, …, a<sub>n</sub>)</i> is <i>T</i>. </
blockquote> | 6283 * form <i>const T(a<sub>1</sub>, …, 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> <E>\[e<sub>1</sub>, …, e<sub>n</sub>\]</i
> or the form | 6321 * form <i><b>const</b> <E>\[e<sub>1</sub>, …, e<sub>n</sub>\]</i
> or the form |
4936 * <i><E>\[e<sub>1</sub>, …, e<sub>n</sub>\]</i> is {@code List&l
t;E>}. The static | 6322 * <i><E>\[e<sub>1</sub>, …, e<sub>n</sub>\]</i> is {@code List&l
t;E>}. The static |
4937 * type a list literal of the form <i><b>const</b> \[e<sub>1</sub>, …,
e<sub>n</sub>\]</i> or | 6323 * type a list literal of the form <i><b>const</b> \[e<sub>1</sub>, …,
e<sub>n</sub>\]</i> or |
4938 * the form <i>\[e<sub>1</sub>, …, e<sub>n</sub>\]</i> is {@code List&l
t;dynamic>}.</blockquote> | 6324 * the form <i>\[e<sub>1</sub>, …, e<sub>n</sub>\]</i> is {@code List&l
t;dynamic>}.</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> <String, V> {k<sub>1</sub>:e<sub>1</sub>, …, | 6364 * <i><b>const</b> <String, V> {k<sub>1</sub>:e<sub>1</sub>, …, |
4954 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i><String, V> {k<sub>1<
/sub>:e<sub>1</sub>, | 6365 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i><String, V> {k<sub>1<
/sub>:e<sub>1</sub>, |
4955 * …, k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map<String, V>}.
The static type a | 6366 * …, k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map<String, V>}.
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
>, …, | 6368 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>{k<sub>1</sub>:e<sub>1</sub
>, …, |
4958 * k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map<String, dynamic>}. | 6369 * k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map<String, dynamic>}. |
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>, …, 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>, …, a<sub>n</sub>, x<sub>n+1</sub>
: a<sub>n+1</sub>, |
4980 * …, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>. | 6439 * …, 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 Loading... |
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>, …,
r<sub>n</sub>, | 6682 * <li><i>o.m</i> is defined to be equivalent to: <i>(r<sub>1</sub>, …,
r<sub>n</sub>, |
5156 * {p<sub>1</sub> : d<sub>1</sub>, …, p<sub>k</sub> : d<sub>k</sub>}){r
eturn | 6683 * {p<sub>1</sub> : d<sub>1</sub>, …, p<sub>k</sub> : d<sub>k</sub>}){r
eturn |
5157 * o.m(r<sub>1</sub>, …, r<sub>n</sub>, p<sub>1</sub>: p<sub>1</sub>, &
hellip;, | 6684 * o.m(r<sub>1</sub>, …, 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 * …, r<sub>n</sub></i>, and named parameters <i>p<sub>1</sub> …
p<sub>k</sub></i> | 6686 * …, r<sub>n</sub></i>, and named parameters <i>p<sub>1</sub> …
p<sub>k</sub></i> |
(...skipping 26 matching lines...) Expand all Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } | |
OLD | NEW |