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

Side by Side Diff: pkg/analyzer-experimental/lib/src/generated/resolver.dart

Issue 12253009: Fresh drop of analyzer-experimental. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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.
3
4 library engine.resolver;
5
6 import 'dart:collection';
7 import 'java_core.dart';
8 import 'java_engine.dart';
9 import 'source.dart';
10 import 'error.dart';
11 import 'scanner.dart' show Keyword, TokenType, Token, KeywordToken, StringToken;
12 import 'utilities_dart.dart';
13 import 'ast.dart';
14 import 'element.dart' hide HideCombinator, ShowCombinator;
15 import 'engine.dart';
16 import 'element.dart' as __imp_combi show HideCombinator, ShowCombinator;
17
18 /**
19 * Instances of the class {@code CompilationUnitBuilder} build an element model for a single
20 * compilation unit.
21 */
22 class CompilationUnitBuilder {
23 /**
24 * The analysis context in which the element model will be built.
25 */
26 AnalysisContextImpl _analysisContext;
27 /**
28 * The listener to which errors will be reported.
29 */
30 AnalysisErrorListener _errorListener;
31 /**
32 * Initialize a newly created compilation unit element builder.
33 * @param analysisContext the analysis context in which the element model will be built
34 * @param errorListener the listener to which errors will be reported
35 */
36 CompilationUnitBuilder(AnalysisContextImpl analysisContext, AnalysisErrorListe ner errorListener) {
37 this._analysisContext = analysisContext;
38 this._errorListener = errorListener;
39 }
40 /**
41 * Build the compilation unit element for the given source.
42 * @param source the source describing the compilation unit
43 * @return the compilation unit element that was built
44 * @throws AnalysisException if the analysis could not be performed
45 */
46 CompilationUnitElementImpl buildCompilationUnit(Source source) => buildCompila tionUnit2(source, _analysisContext.parse2(source, _errorListener));
47 /**
48 * Build the compilation unit element for the given source.
49 * @param source the source describing the compilation unit
50 * @param unit the AST structure representing the compilation unit
51 * @return the compilation unit element that was built
52 * @throws AnalysisException if the analysis could not be performed
53 */
54 CompilationUnitElementImpl buildCompilationUnit2(Source source11, CompilationU nit unit) {
55 ElementHolder holder = new ElementHolder();
56 ElementBuilder builder = new ElementBuilder(holder);
57 unit.accept(builder);
58 CompilationUnitElementImpl element = new CompilationUnitElementImpl(source11 .shortName);
59 element.accessors = holder.accessors;
60 element.functions = holder.functions;
61 element.source = source11;
62 element.typeAliases = holder.typeAliases;
63 element.types = holder.types;
64 element.variables = holder.variables;
65 unit.element = element;
66 return element;
67 }
68 }
69 /**
70 * Instances of the class {@code ElementBuilder} traverse an AST structure and b uild the element
71 * model representing the AST structure.
72 */
73 class ElementBuilder extends RecursiveASTVisitor<Object> {
74 /**
75 * The element holder associated with the element that is currently being buil t.
76 */
77 ElementHolder _currentHolder;
78 /**
79 * A flag indicating whether a variable declaration is in the context of a fie ld declaration.
80 */
81 bool _inFieldContext = false;
82 /**
83 * 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
85 */
86 ElementBuilder(ElementHolder initialHolder) {
87 _currentHolder = initialHolder;
88 }
89 Object visitCatchClause(CatchClause node) {
90 SimpleIdentifier exceptionParameter2 = node.exceptionParameter;
91 if (exceptionParameter2 != null) {
92 VariableElementImpl exception = new VariableElementImpl.con1(exceptionPara meter2);
93 _currentHolder.addVariable(exception);
94 exceptionParameter2.element = exception;
95 SimpleIdentifier stackTraceParameter2 = node.stackTraceParameter;
96 if (stackTraceParameter2 != null) {
97 VariableElementImpl stackTrace = new VariableElementImpl.con1(stackTrace Parameter2);
98 _currentHolder.addVariable(stackTrace);
99 stackTraceParameter2.element = stackTrace;
100 }
101 }
102 node.visitChildren(this);
103 return null;
104 }
105 Object visitClassDeclaration(ClassDeclaration node) {
106 ElementHolder holder = new ElementHolder();
107 visitChildren(holder, node);
108 SimpleIdentifier className = node.name;
109 ClassElementImpl element = new ClassElementImpl(className);
110 List<ConstructorElement> constructors3 = holder.constructors;
111 if (constructors3.length == 0) {
112 ConstructorElementImpl constructor = new ConstructorElementImpl(null);
113 constructor.synthetic = true;
114 FunctionTypeImpl type = new FunctionTypeImpl.con1(constructor);
115 type.returnType = element.type;
116 constructor.type = type;
117 constructors3 = <ConstructorElement> [constructor];
118 }
119 element.abstract = node.abstractKeyword != null;
120 element.accessors = holder.accessors;
121 element.constructors = constructors3;
122 element.fields = holder.fields;
123 element.methods = holder.methods;
124 List<TypeVariableElement> typeVariables4 = holder.typeVariables;
125 element.typeVariables = typeVariables4;
126 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
127 int typeVariableCount = typeVariables4.length;
128 List<Type2> typeArguments = new List<Type2>.fixedLength(typeVariableCount);
129 for (int i = 0; i < typeVariableCount; i++) {
130 TypeVariableElementImpl typeVariable = (typeVariables4[i] as TypeVariableE lementImpl);
131 TypeVariableTypeImpl typeArgument = new TypeVariableTypeImpl(typeVariable) ;
132 typeVariable.type = typeArgument;
133 typeArguments[i] = typeArgument;
134 }
135 interfaceType.typeArguments = typeArguments;
136 element.type = interfaceType;
137 _currentHolder.addType(element);
138 className.element = element;
139 return null;
140 }
141 Object visitClassTypeAlias(ClassTypeAlias node) {
142 ElementHolder holder = new ElementHolder();
143 visitChildren(holder, node);
144 SimpleIdentifier className = node.name;
145 ClassElementImpl element = new ClassElementImpl(className);
146 element.abstract = node.abstractKeyword != null;
147 List<TypeVariableElement> typeVariables5 = holder.typeVariables;
148 element.typeVariables = typeVariables5;
149 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
150 int typeVariableCount = typeVariables5.length;
151 List<Type2> typeArguments = new List<Type2>.fixedLength(typeVariableCount);
152 for (int i = 0; i < typeVariableCount; i++) {
153 TypeVariableElementImpl typeVariable = (typeVariables5[i] as TypeVariableE lementImpl);
154 TypeVariableTypeImpl typeArgument = new TypeVariableTypeImpl(typeVariable) ;
155 typeVariable.type = typeArgument;
156 typeArguments[i] = typeArgument;
157 }
158 interfaceType.typeArguments = typeArguments;
159 element.type = interfaceType;
160 _currentHolder.addType(element);
161 className.element = element;
162 return null;
163 }
164 Object visitConstructorDeclaration(ConstructorDeclaration node) {
165 ElementHolder holder = new ElementHolder();
166 visitChildren(holder, node);
167 SimpleIdentifier constructorName = node.name;
168 ConstructorElementImpl element = new ConstructorElementImpl(constructorName) ;
169 if (node.factoryKeyword != null) {
170 element.factory = true;
171 }
172 element.functions = holder.functions;
173 element.labels = holder.labels;
174 element.localVariables = holder.variables;
175 element.parameters = holder.parameters;
176 _currentHolder.addConstructor(element);
177 node.element = element;
178 if (constructorName != null) {
179 constructorName.element = element;
180 }
181 return null;
182 }
183 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
184 ElementHolder holder = new ElementHolder();
185 visitChildren(holder, node.defaultValue);
186 FunctionElementImpl initializer = new FunctionElementImpl();
187 initializer.functions = holder.functions;
188 initializer.labels = holder.labels;
189 initializer.localVariables = holder.variables;
190 initializer.parameters = holder.parameters;
191 SimpleIdentifier parameterName = node.parameter.identifier;
192 ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
193 parameter.const2 = node.isConst();
194 parameter.final2 = node.isFinal();
195 parameter.initializer = initializer;
196 parameter.parameterKind = node.kind;
197 _currentHolder.addParameter(parameter);
198 parameterName.element = parameter;
199 node.parameter.accept(this);
200 return null;
201 }
202 Object visitFieldDeclaration(FieldDeclaration node) {
203 bool wasInField = _inFieldContext;
204 _inFieldContext = true;
205 try {
206 node.visitChildren(this);
207 } finally {
208 _inFieldContext = wasInField;
209 }
210 return null;
211 }
212 Object visitFieldFormalParameter(FieldFormalParameter node) {
213 if (node.parent is! DefaultFormalParameter) {
214 SimpleIdentifier parameterName = node.identifier;
215 ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
216 parameter.const2 = node.isConst();
217 parameter.initializingFormal = true;
218 parameter.final2 = node.isFinal();
219 parameter.parameterKind = node.kind;
220 _currentHolder.addParameter(parameter);
221 parameterName.element = parameter;
222 }
223 node.visitChildren(this);
224 return null;
225 }
226 Object visitFunctionDeclaration(FunctionDeclaration node) {
227 ElementHolder holder = new ElementHolder();
228 visitChildren(holder, node);
229 SimpleIdentifier functionName = node.name;
230 FunctionElementImpl element = new FunctionElementImpl.con1(functionName);
231 element.functions = holder.functions;
232 element.labels = holder.labels;
233 element.localVariables = holder.variables;
234 element.parameters = holder.parameters;
235 _currentHolder.addFunction(element);
236 functionName.element = element;
237 return null;
238 }
239 Object visitFunctionExpression(FunctionExpression node) {
240 ElementHolder holder = new ElementHolder();
241 visitChildren(holder, node);
242 SimpleIdentifier functionName = null;
243 FunctionElementImpl element = new FunctionElementImpl.con1(functionName);
244 element.functions = holder.functions;
245 element.labels = holder.labels;
246 element.localVariables = holder.variables;
247 element.parameters = holder.parameters;
248 FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
249 element.type = type;
250 _currentHolder.addFunction(element);
251 node.element = element;
252 return null;
253 }
254 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
255 ElementHolder holder = new ElementHolder();
256 visitChildren(holder, node);
257 SimpleIdentifier aliasName = node.name;
258 List<ParameterElement> parameters10 = holder.parameters;
259 TypeAliasElementImpl element = new TypeAliasElementImpl(aliasName);
260 element.parameters = parameters10;
261 element.typeVariables = holder.typeVariables;
262 FunctionTypeImpl type = new FunctionTypeImpl.con2(element);
263 element.type = type;
264 _currentHolder.addTypeAlias(element);
265 aliasName.element = element;
266 return null;
267 }
268 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
269 if (node.parent is! DefaultFormalParameter) {
270 SimpleIdentifier parameterName = node.identifier;
271 ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
272 parameter.parameterKind = node.kind;
273 _currentHolder.addParameter(parameter);
274 parameterName.element = parameter;
275 }
276 visitChildren(new ElementHolder(), node);
277 return null;
278 }
279 Object visitLabeledStatement(LabeledStatement node) {
280 bool onSwitchStatement = node.statement is SwitchStatement;
281 for (Label label in node.labels) {
282 SimpleIdentifier labelName = label.label;
283 LabelElementImpl element = new LabelElementImpl(labelName, onSwitchStateme nt, false);
284 _currentHolder.addLabel(element);
285 labelName.element = element;
286 }
287 node.visitChildren(this);
288 return null;
289 }
290 Object visitMethodDeclaration(MethodDeclaration node) {
291 ElementHolder holder = new ElementHolder();
292 visitChildren(holder, node);
293 Token property = node.propertyKeyword;
294 if (property == null) {
295 Identifier methodName = node.name;
296 String nameOfMethod = methodName.name;
297 if (nameOfMethod == TokenType.MINUS.lexeme && node.parameters.parameters.l ength == 0) {
298 nameOfMethod = "unary-";
299 }
300 MethodElementImpl element = new MethodElementImpl.con2(nameOfMethod, metho dName.offset);
301 Token keyword = node.modifierKeyword;
302 element.abstract = matches(keyword, Keyword.ABSTRACT);
303 element.functions = holder.functions;
304 element.labels = holder.labels;
305 element.localVariables = holder.variables;
306 element.parameters = holder.parameters;
307 element.static = matches(keyword, Keyword.STATIC);
308 _currentHolder.addMethod(element);
309 methodName.element = element;
310 } else {
311 Identifier propertyNameNode = node.name;
312 String propertyName = propertyNameNode.name;
313 FieldElementImpl field = (_currentHolder.getField(propertyName) as FieldEl ementImpl);
314 if (field == null) {
315 field = new FieldElementImpl.con2(node.name.name);
316 field.final2 = true;
317 field.static = matches(node.modifierKeyword, Keyword.STATIC);
318 _currentHolder.addField(field);
319 }
320 if (matches(property, Keyword.GET)) {
321 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con 2(propertyNameNode);
322 getter.functions = holder.functions;
323 getter.labels = holder.labels;
324 getter.localVariables = holder.variables;
325 getter.field = field;
326 getter.getter = true;
327 field.getter = getter;
328 _currentHolder.addAccessor(getter);
329 propertyNameNode.element = getter;
330 } else {
331 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con 2(propertyNameNode);
332 setter.functions = holder.functions;
333 setter.labels = holder.labels;
334 setter.localVariables = holder.variables;
335 setter.parameters = holder.parameters;
336 setter.field = field;
337 setter.setter = true;
338 field.setter = setter;
339 field.final2 = false;
340 _currentHolder.addAccessor(setter);
341 propertyNameNode.element = setter;
342 }
343 }
344 return null;
345 }
346 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
347 if (node.parent is! DefaultFormalParameter) {
348 SimpleIdentifier parameterName = node.identifier;
349 ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
350 parameter.const2 = node.isConst();
351 parameter.final2 = node.isFinal();
352 parameter.parameterKind = node.kind;
353 _currentHolder.addParameter(parameter);
354 parameterName.element = parameter;
355 }
356 node.visitChildren(this);
357 return null;
358 }
359 Object visitSwitchCase(SwitchCase node) {
360 for (Label label in node.labels) {
361 SimpleIdentifier labelName = label.label;
362 LabelElementImpl element = new LabelElementImpl(labelName, false, true);
363 _currentHolder.addLabel(element);
364 labelName.element = element;
365 }
366 node.visitChildren(this);
367 return null;
368 }
369 Object visitSwitchDefault(SwitchDefault node) {
370 for (Label label in node.labels) {
371 SimpleIdentifier labelName = label.label;
372 LabelElementImpl element = new LabelElementImpl(labelName, false, true);
373 _currentHolder.addLabel(element);
374 labelName.element = element;
375 }
376 node.visitChildren(this);
377 return null;
378 }
379 Object visitTypeParameter(TypeParameter node) {
380 SimpleIdentifier parameterName = node.name;
381 TypeVariableElementImpl element = new TypeVariableElementImpl(parameterName) ;
382 TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
383 element.type = type;
384 _currentHolder.addTypeVariable(element);
385 parameterName.element = element;
386 node.visitChildren(this);
387 return null;
388 }
389 Object visitVariableDeclaration(VariableDeclaration node) {
390 VariableElementImpl element;
391 if (_inFieldContext) {
392 SimpleIdentifier fieldName = node.name;
393 FieldElementImpl field = new FieldElementImpl.con1(fieldName);
394 element = field;
395 _currentHolder.addField(field);
396 fieldName.element = field;
397 } else {
398 SimpleIdentifier variableName = node.name;
399 element = new VariableElementImpl.con1(variableName);
400 _currentHolder.addVariable(element);
401 variableName.element = element;
402 }
403 Token keyword26 = ((node.parent as VariableDeclarationList)).keyword;
404 bool isFinal = matches(keyword26, Keyword.FINAL);
405 element.const2 = matches(keyword26, Keyword.CONST);
406 element.final2 = isFinal;
407 if (node.initializer != null) {
408 ElementHolder holder = new ElementHolder();
409 bool wasInFieldContext = _inFieldContext;
410 _inFieldContext = false;
411 try {
412 visitChildren(holder, node.initializer);
413 } finally {
414 _inFieldContext = wasInFieldContext;
415 }
416 FunctionElementImpl initializer = new FunctionElementImpl();
417 initializer.functions = holder.functions;
418 initializer.labels = holder.labels;
419 initializer.localVariables = holder.variables;
420 initializer.synthetic = true;
421 element.initializer = initializer;
422 }
423 if (_inFieldContext) {
424 FieldElementImpl field = (element as FieldElementImpl);
425 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con1( field);
426 getter.getter = true;
427 _currentHolder.addAccessor(getter);
428 field.getter = getter;
429 if (!isFinal) {
430 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con 1(field);
431 setter.setter = true;
432 _currentHolder.addAccessor(setter);
433 field.setter = setter;
434 }
435 field.static = matches(((node.parent.parent as FieldDeclaration)).keyword, Keyword.STATIC);
436 }
437 node.visitChildren(this);
438 return null;
439 }
440 /**
441 * Return {@code true} if the given token is a token for the given keyword.
442 * @param token the token being tested
443 * @param keyword the keyword being tested for
444 * @return {@code true} if the given token is a token for the given keyword
445 */
446 bool matches(Token token, Keyword keyword34) => token != null && identical(tok en.type, TokenType.KEYWORD) && identical(((token as KeywordToken)).keyword, keyw ord34);
447 /**
448 * Make the given holder be the current holder while visiting the children of the given node.
449 * @param holder the holder that will gather elements that are built while vis iting the children
450 * @param node the node whose children are to be visited
451 */
452 void visitChildren(ElementHolder holder, ASTNode node) {
453 if (node != null) {
454 ElementHolder previousHolder = _currentHolder;
455 _currentHolder = holder;
456 try {
457 node.visitChildren(this);
458 } finally {
459 _currentHolder = previousHolder;
460 }
461 }
462 }
463 }
464 /**
465 * Instances of the class {@code ElementHolder} hold on to elements created whil e traversing an AST
466 * structure so that they can be accessed when creating their enclosing element.
467 */
468 class ElementHolder {
469 List<PropertyAccessorElement> _accessors = new List<PropertyAccessorElement>() ;
470 List<ConstructorElement> _constructors = new List<ConstructorElement>();
471 List<FieldElement> _fields = new List<FieldElement>();
472 List<FunctionElement> _functions = new List<FunctionElement>();
473 List<LabelElement> _labels = new List<LabelElement>();
474 List<MethodElement> _methods = new List<MethodElement>();
475 List<TypeAliasElement> _typeAliases = new List<TypeAliasElement>();
476 List<ParameterElement> _parameters = new List<ParameterElement>();
477 List<ClassElement> _types = new List<ClassElement>();
478 List<TypeVariableElement> _typeVariables = new List<TypeVariableElement>();
479 List<VariableElement> _variables = new List<VariableElement>();
480 /**
481 * Initialize a newly created element holder.
482 */
483 ElementHolder() : super() {
484 }
485 void addAccessor(PropertyAccessorElement element) {
486 _accessors.add(element);
487 }
488 void addConstructor(ConstructorElement element) {
489 _constructors.add(element);
490 }
491 void addField(FieldElement element) {
492 _fields.add(element);
493 }
494 void addFunction(FunctionElement element) {
495 _functions.add(element);
496 }
497 void addLabel(LabelElement element) {
498 _labels.add(element);
499 }
500 void addMethod(MethodElement element) {
501 _methods.add(element);
502 }
503 void addParameter(ParameterElement element) {
504 _parameters.add(element);
505 }
506 void addType(ClassElement element) {
507 _types.add(element);
508 }
509 void addTypeAlias(TypeAliasElement element) {
510 _typeAliases.add(element);
511 }
512 void addTypeVariable(TypeVariableElement element) {
513 _typeVariables.add(element);
514 }
515 void addVariable(VariableElement element) {
516 _variables.add(element);
517 }
518 List<PropertyAccessorElement> get accessors => new List.from(_accessors);
519 List<ConstructorElement> get constructors => new List.from(_constructors);
520 FieldElement getField(String fieldName) {
521 for (FieldElement field in _fields) {
522 if (field.name == fieldName) {
523 return field;
524 }
525 }
526 return null;
527 }
528 List<FieldElement> get fields => new List.from(_fields);
529 List<FunctionElement> get functions => new List.from(_functions);
530 List<LabelElement> get labels => new List.from(_labels);
531 List<MethodElement> get methods => new List.from(_methods);
532 List<ParameterElement> get parameters => new List.from(_parameters);
533 List<TypeAliasElement> get typeAliases => new List.from(_typeAliases);
534 List<ClassElement> get types => new List.from(_types);
535 List<TypeVariableElement> get typeVariables => new List.from(_typeVariables);
536 List<VariableElement> get variables => new List.from(_variables);
537 }
538 /**
539 * 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
540 * for the element resolver are:
541 * <ol>
542 * <li>Every {@link SimpleIdentifier} should be resolved to the element to which it refers.
543 * Specifically:
544 * <ul>
545 * <li>An identifier within the declaration of that name should resolve to the e lement being
546 * declared.</li>
547 * <li>An identifier denoting a prefix should resolve to the element representin g the import that
548 * defines the prefix (an {@link ImportElement}).</li>
549 * <li>An identifier denoting a variable should resolve to the element represent ing the variable (a{@link VariableElement}).</li>
550 * <li>An identifier denoting a parameter should resolve to the element represen ting the parameter
551 * (a {@link ParameterElement}).</li>
552 * <li>An identifier denoting a field should resolve to the element representing the getter or
553 * setter being invoked (a {@link PropertyAccessorElement}).</li>
554 * <li>An identifier denoting the name of a method or function being invoked sho uld resolve to the
555 * element representing the method or function (a {@link ExecutableElement}).</l i>
556 * <li>An identifier denoting a label should resolve to the element representing the label (a{@link LabelElement}).</li>
557 * </ul>
558 * The identifiers within directives are exceptions to this rule and are covered below.</li>
559 * <li>Every node containing a token representing an operator that can be overri dden ({@link BinaryExpression}, {@link PrefixExpression}, {@link PostfixExpressi on}) should resolve to
560 * the element representing the method invoked by that operator (a {@link Method Element}).</li>
561 * <li>Every {@link FunctionExpressionInvocation} should resolve to the element representing the
562 * function being invoked (a {@link FunctionElement}). This will be the same ele ment as that to
563 * which the name is resolved if the function has a name, but is provided for th ose cases where an
564 * unnamed function is being invoked.</li>
565 * <li>Every {@link LibraryDirective} and {@link PartOfDirective} should resolve to the element
566 * representing the library being specified by the directive (a {@link LibraryEl ement}) unless, in
567 * the case of a part-of directive, the specified library does not exist.</li>
568 * <li>Every {@link ImportDirective} and {@link ExportDirective} should resolve to the element
569 * representing the library being specified by the directive unless the specifie d library does not
570 * exist (a {@link LibraryElement}).</li>
571 * <li>The identifier representing the prefix in an {@link ImportDirective} shou ld resolve to the
572 * element representing the prefix (a {@link PrefixElement}).</li>
573 * <li>The identifiers in the hide and show combinators in {@link ImportDirectiv e}s and{@link ExportDirective}s should resolve to the elements that are being hi dden or shown,
574 * respectively, unless those names are not defined in the specified library (or the specified
575 * library does not exist).</li>
576 * <li>Every {@link PartDirective} should resolve to the element representing th e compilation unit
577 * being specified by the string unless the specified compilation unit does not exist (a{@link CompilationUnitElement}).</li>
578 * </ol>
579 * Note that AST nodes that would represent elements that are not defined are no t resolved to
580 * anything. This includes such things as references to undeclared variables (wh ich is an error) and
581 * names in hide and show combinators that are not defined in the imported libra ry (which is not an
582 * error).
583 */
584 class ElementResolver extends SimpleASTVisitor<Object> {
585 /**
586 * The resolver driving this participant.
587 */
588 ResolverVisitor _resolver;
589 /**
590 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
591 * @param resolver the resolver driving this participant
592 */
593 ElementResolver(ResolverVisitor resolver) {
594 this._resolver = resolver;
595 }
596 Object visitAssignmentExpression(AssignmentExpression node) {
597 TokenType operator7 = node.operator.type;
598 if (operator7 != TokenType.EQ) {
599 operator7 = operatorFromCompoundAssignment(operator7);
600 Expression leftNode = node.leftHandSide;
601 if (leftNode != null) {
602 Type2 leftType = leftNode.staticType;
603 if (leftType != null) {
604 Element leftElement = leftType.element;
605 if (leftElement != null) {
606 MethodElement method = lookUpMethod(leftElement, operator7.lexeme, 1 , []);
607 if (method != null) {
608 node.element = method;
609 } else {
610 }
611 }
612 }
613 }
614 }
615 return null;
616 }
617 Object visitBinaryExpression(BinaryExpression node) {
618 Token operator8 = node.operator;
619 if (operator8.isUserDefinableOperator()) {
620 Type2 leftType = getType(node.leftOperand);
621 Element leftTypeElement;
622 if (leftType == null) {
623 return null;
624 } else if (leftType is FunctionType) {
625 leftTypeElement = _resolver.typeProvider.functionType.element;
626 } else {
627 leftTypeElement = leftType.element;
628 }
629 String methodName = operator8.lexeme;
630 MethodElement member = lookUpMethod(leftTypeElement, methodName, 1, []);
631 if (member == null) {
632 _resolver.reportError2(ResolverErrorCode.CANNOT_BE_RESOLVED, operator8, [methodName]);
633 } else {
634 node.element = member;
635 }
636 }
637 return null;
638 }
639 Object visitBreakStatement(BreakStatement node) {
640 SimpleIdentifier labelNode = node.label;
641 LabelElementImpl labelElement = lookupLabel(node, labelNode);
642 if (labelElement != null && labelElement.isOnSwitchMember()) {
643 _resolver.reportError(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labe lNode, []);
644 }
645 return null;
646 }
647 Object visitConstructorName(ConstructorName node) {
648 Type2 type10 = node.type.type;
649 if (type10 is! InterfaceType) {
650 return null;
651 }
652 ClassElement classElement = ((type10 as InterfaceType)).element;
653 ConstructorElement constructor;
654 SimpleIdentifier name14 = node.name;
655 if (name14 == null) {
656 constructor = classElement.unnamedConstructor;
657 } else {
658 constructor = classElement.getNamedConstructor(name14.name);
659 name14.element = constructor;
660 }
661 node.element = constructor;
662 return null;
663 }
664 Object visitContinueStatement(ContinueStatement node) {
665 SimpleIdentifier labelNode = node.label;
666 LabelElementImpl labelElement = lookupLabel(node, labelNode);
667 if (labelElement != null && labelElement.isOnSwitchStatement()) {
668 _resolver.reportError(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNod e, []);
669 }
670 return null;
671 }
672 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => null;
673 Object visitImportDirective(ImportDirective node) {
674 SimpleIdentifier prefixNode = node.prefix;
675 if (prefixNode != null) {
676 String prefixName = prefixNode.name;
677 for (PrefixElement prefixElement in _resolver.definingLibrary.prefixes) {
678 if (prefixElement.name == prefixName) {
679 recordResolution(prefixNode, prefixElement);
680 }
681 return null;
682 }
683 }
684 return null;
685 }
686 Object visitIndexExpression(IndexExpression node) {
687 Type2 arrayType = getType(node.array);
688 if (arrayType == null) {
689 return null;
690 }
691 Element arrayTypeElement = arrayType.element;
692 String operator;
693 if (node.inSetterContext()) {
694 operator = TokenType.INDEX_EQ.lexeme;
695 } else {
696 operator = TokenType.INDEX.lexeme;
697 }
698 MethodElement member = lookUpMethod(arrayTypeElement, operator, 1, []);
699 if (member == null) {
700 _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, node, [operato r]);
701 } else {
702 node.element = member;
703 }
704 return null;
705 }
706 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
707 node.element = node.constructorName.element;
708 return null;
709 }
710 Object visitLibraryIdentifier(LibraryIdentifier node) => null;
711 Object visitMethodInvocation(MethodInvocation node) {
712 SimpleIdentifier methodName2 = node.methodName;
713 Expression target4 = node.target;
714 Element element;
715 if (target4 == null) {
716 element = _resolver.nameScope.lookup(methodName2, _resolver.definingLibrar y);
717 if (element == null) {
718 element = lookUpMethod(_resolver.enclosingClass, methodName2.name, -1, [ ]);
719 }
720 } else {
721 Type2 targetType = getType(target4);
722 if (targetType is InterfaceType) {
723 int parameterCount = 0;
724 List<String> parameterNames = new List<String>();
725 ArgumentList argumentList10 = node.argumentList;
726 for (Expression argument in argumentList10.arguments) {
727 if (argument is NamedExpression) {
728 parameterNames.add(((argument as NamedExpression)).name.label.name);
729 } else {
730 parameterCount++;
731 }
732 }
733 element = lookUpMethod(targetType.element, methodName2.name, parameterCo unt, new List.from(parameterNames));
734 } else if (target4 is SimpleIdentifier) {
735 Element targetElement = ((target4 as SimpleIdentifier)).element;
736 if (targetElement is PrefixElement) {
737 String name9 = "${((target4 as SimpleIdentifier)).name}.${methodName2} ";
738 Identifier functionName = new Identifier_2(name9);
739 element = _resolver.nameScope.lookup(functionName, _resolver.definingL ibrary);
740 } else {
741 return null;
742 }
743 } else {
744 return null;
745 }
746 }
747 ExecutableElement invokedMethod = null;
748 if (element is ExecutableElement) {
749 invokedMethod = (element as ExecutableElement);
750 } else if (element is FieldElement) {
751 } else {
752 return null;
753 }
754 if (invokedMethod == null) {
755 return null;
756 }
757 recordResolution(methodName2, invokedMethod);
758 return null;
759 }
760 Object visitPostfixExpression(PostfixExpression node) {
761 Token operator9 = node.operator;
762 if (operator9.isUserDefinableOperator()) {
763 Type2 operandType = getType(node.operand);
764 if (operandType == null) {
765 return null;
766 }
767 Element operandTypeElement = operandType.element;
768 String methodName;
769 if (identical(operator9.type, TokenType.PLUS_PLUS)) {
770 methodName = TokenType.PLUS.lexeme;
771 } else {
772 methodName = TokenType.MINUS.lexeme;
773 }
774 MethodElement member = lookUpMethod(operandTypeElement, methodName, 1, []) ;
775 if (member == null) {
776 _resolver.reportError2(ResolverErrorCode.CANNOT_BE_RESOLVED, operator9, [methodName]);
777 } else {
778 node.element = member;
779 }
780 }
781 return null;
782 }
783 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
784 SimpleIdentifier prefix5 = node.prefix;
785 SimpleIdentifier identifier10 = node.identifier;
786 Element prefixElement = prefix5.element;
787 if (prefixElement is PrefixElement) {
788 Element element = _resolver.nameScope.lookup(node, _resolver.definingLibra ry);
789 if (element == null) {
790 return null;
791 }
792 recordResolution(identifier10, element);
793 recordResolution(node, element);
794 return null;
795 }
796 if (prefixElement is ClassElement) {
797 Element memberElement;
798 if (node.identifier.inSetterContext()) {
799 memberElement = lookUpSetterInType((prefixElement as ClassElement), iden tifier10.name);
800 } else {
801 memberElement = lookUpGetterInType((prefixElement as ClassElement), iden tifier10.name);
802 }
803 if (memberElement == null) {
804 MethodElement methodElement = lookUpMethod(prefixElement, identifier10.n ame, -1, []);
805 if (methodElement != null) {
806 recordResolution(identifier10, methodElement);
807 recordResolution(node, methodElement);
808 return null;
809 }
810 }
811 if (memberElement == null) {
812 _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, identifier10 , [identifier10.name]);
813 } else {
814 recordResolution(identifier10, memberElement);
815 recordResolution(node, memberElement);
816 }
817 return null;
818 }
819 Element variableType;
820 if (prefixElement is PropertyAccessorElement) {
821 PropertyAccessorElement accessor = (prefixElement as PropertyAccessorEleme nt);
822 if (accessor.isGetter()) {
823 variableType = accessor.type.returnType.element;
824 } else {
825 variableType = accessor.type.normalParameterTypes[0].element;
826 }
827 } else if (prefixElement is VariableElement) {
828 variableType = ((prefixElement as VariableElement)).type.element;
829 } else {
830 return null;
831 }
832 PropertyAccessorElement memberElement;
833 if (node.identifier.inGetterContext()) {
834 memberElement = lookUpGetter(variableType, identifier10.name);
835 } else {
836 memberElement = lookUpSetter(variableType, identifier10.name);
837 }
838 if (memberElement == null) {
839 MethodElement methodElement = lookUpMethod(variableType, identifier10.name , -1, []);
840 if (methodElement != null) {
841 recordResolution(identifier10, methodElement);
842 recordResolution(node, methodElement);
843 return null;
844 }
845 }
846 if (memberElement == null) {
847 _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, identifier10, [identifier10.name]);
848 } else {
849 recordResolution(identifier10, memberElement);
850 recordResolution(node, memberElement);
851 }
852 return null;
853 }
854 Object visitPrefixExpression(PrefixExpression node) {
855 Token operator10 = node.operator;
856 TokenType operatorType = operator10.type;
857 if (operatorType.isUserDefinableOperator() || identical(operatorType, TokenT ype.PLUS_PLUS) || identical(operatorType, TokenType.MINUS_MINUS)) {
858 Type2 operandType = getType(node.operand);
859 if (operandType == null) {
860 return null;
861 }
862 Element operandTypeElement = operandType.element;
863 String methodName;
864 if (identical(operatorType, TokenType.PLUS_PLUS)) {
865 methodName = TokenType.PLUS.lexeme;
866 } else if (identical(operatorType, TokenType.MINUS_MINUS)) {
867 methodName = TokenType.MINUS.lexeme;
868 } else if (identical(operatorType, TokenType.MINUS)) {
869 methodName = "unary-";
870 } else {
871 methodName = operator10.lexeme;
872 }
873 MethodElement member = lookUpMethod(operandTypeElement, methodName, 1, []) ;
874 if (member == null) {
875 _resolver.reportError2(ResolverErrorCode.CANNOT_BE_RESOLVED, operator10, [methodName]);
876 } else {
877 node.element = member;
878 }
879 }
880 return null;
881 }
882 Object visitPropertyAccess(PropertyAccess node) {
883 Type2 targetType = getType(node.realTarget);
884 if (targetType is! InterfaceType) {
885 return null;
886 }
887 ClassElement targetElement = ((targetType as InterfaceType)).element;
888 SimpleIdentifier identifier = node.propertyName;
889 PropertyAccessorElement memberElement;
890 if (identifier.inSetterContext()) {
891 memberElement = lookUpSetter(targetElement, identifier.name);
892 } else {
893 memberElement = lookUpGetter(targetElement, identifier.name);
894 }
895 if (memberElement == null) {
896 MethodElement methodElement = lookUpMethod(targetElement, identifier.name, -1, []);
897 if (methodElement != null) {
898 recordResolution(identifier, methodElement);
899 return null;
900 }
901 }
902 if (memberElement == null) {
903 _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, identifier, [i dentifier.name]);
904 } else {
905 recordResolution(identifier, memberElement);
906 }
907 return null;
908 }
909 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
910 ClassElement enclosingClass2 = _resolver.enclosingClass;
911 if (enclosingClass2 == null) {
912 return null;
913 }
914 SimpleIdentifier name = node.constructorName;
915 ConstructorElement element;
916 if (name == null) {
917 element = enclosingClass2.unnamedConstructor;
918 } else {
919 element = enclosingClass2.getNamedConstructor(name.name);
920 }
921 if (element == null) {
922 return null;
923 }
924 if (name != null) {
925 recordResolution(name, element);
926 }
927 node.element = element;
928 return null;
929 }
930 Object visitSimpleIdentifier(SimpleIdentifier node) {
931 if (node.element != null) {
932 return null;
933 }
934 Element element = _resolver.nameScope.lookup(node, _resolver.definingLibrary );
935 if (element == null) {
936 if (node.inGetterContext()) {
937 element = lookUpGetter(_resolver.enclosingClass, node.name);
938 } else {
939 element = lookUpSetter(_resolver.enclosingClass, node.name);
940 }
941 }
942 if (element == null) {
943 element = lookUpMethod(_resolver.enclosingClass, node.name, -1, []);
944 }
945 if (element == null) {
946 }
947 recordResolution(node, element);
948 return null;
949 }
950 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
951 ClassElement enclosingClass3 = _resolver.enclosingClass;
952 if (enclosingClass3 == null) {
953 return null;
954 }
955 ClassElement superclass = getSuperclass(enclosingClass3);
956 if (superclass == null) {
957 return null;
958 }
959 SimpleIdentifier name = node.constructorName;
960 ConstructorElement element;
961 if (name == null) {
962 element = superclass.unnamedConstructor;
963 } else {
964 element = superclass.getNamedConstructor(name.name);
965 }
966 if (element == null) {
967 return null;
968 }
969 if (name != null) {
970 recordResolution(name, element);
971 }
972 node.element = element;
973 return null;
974 }
975 /**
976 * Return the element representing the superclass of the given class.
977 * @param targetClass the class whose superclass is to be returned
978 * @return the element representing the superclass of the given class
979 */
980 ClassElement getSuperclass(ClassElement targetClass) {
981 InterfaceType superType = targetClass.supertype;
982 if (superType == null) {
983 return null;
984 }
985 return superType.element;
986 }
987 /**
988 * Return the type of the given expression that is to be used for type analysi s.
989 * @param expression the expression whose type is to be returned
990 * @return the type of the given expression
991 */
992 Type2 getType(Expression expression) => expression.staticType;
993 /**
994 * Look up the getter with the given name in the given type. Return the elemen t representing the
995 * getter that was found, or {@code null} if there is no getter with the given name.
996 * @param element the element representing the type in which the getter is def ined
997 * @param getterName the name of the getter being looked up
998 * @return the element representing the getter that was found
999 */
1000 PropertyAccessorElement lookUpGetter(Element element, String getterName) {
1001 if (identical(element, DynamicTypeImpl.instance)) {
1002 return null;
1003 }
1004 element = resolveTypeVariable(element);
1005 if (element is ClassElement) {
1006 ClassElement classElement = (element as ClassElement);
1007 PropertyAccessorElement member = classElement.lookUpGetter(getterName, _re solver.definingLibrary);
1008 if (member != null) {
1009 return member;
1010 }
1011 return lookUpGetterInInterfaces((element as ClassElement), getterName, new Set<ClassElement>());
1012 }
1013 return null;
1014 }
1015 /**
1016 * Look up the name of a getter in the interfaces implemented by the given typ e, either directly
1017 * or indirectly. Return the element representing the getter that was found, o r {@code null} if
1018 * there is no getter with the given name.
1019 * @param element the element representing the type in which the getter is def ined
1020 * @param memberName the name of the getter being looked up
1021 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used
1022 * to prevent infinite recursion and to optimize the search
1023 * @return the element representing the getter that was found
1024 */
1025 PropertyAccessorElement lookUpGetterInInterfaces(ClassElement targetClass, Str ing memberName, Set<ClassElement> visitedInterfaces) {
1026 if (visitedInterfaces.contains(targetClass)) {
1027 return null;
1028 }
1029 javaSetAdd(visitedInterfaces, targetClass);
1030 PropertyAccessorElement member = lookUpGetterInType(targetClass, memberName) ;
1031 if (member != null) {
1032 return member;
1033 }
1034 for (InterfaceType interfaceType in targetClass.interfaces) {
1035 member = lookUpGetterInInterfaces(interfaceType.element, memberName, visit edInterfaces);
1036 if (member != null) {
1037 return member;
1038 }
1039 }
1040 ClassElement superclass = getSuperclass(targetClass);
1041 if (superclass == null) {
1042 return null;
1043 }
1044 return lookUpGetterInInterfaces(superclass, memberName, visitedInterfaces);
1045 }
1046 /**
1047 * Look up the name of a getter in the given type. Return the element represen ting the getter that
1048 * was found, or {@code null} if there is no getter with the given name.
1049 * @param element the element representing the type in which the getter is def ined
1050 * @param memberName the name of the getter being looked up
1051 * @return the element representing the getter that was found
1052 */
1053 PropertyAccessorElement lookUpGetterInType(ClassElement element, String member Name) {
1054 for (PropertyAccessorElement accessor in element.accessors) {
1055 if (accessor.isGetter() && accessor.name == memberName) {
1056 return accessor;
1057 }
1058 }
1059 return null;
1060 }
1061 /**
1062 * Find the element corresponding to the given label node in the current label scope.
1063 * @param parentNode the node containing the given label
1064 * @param labelNode the node representing the label being looked up
1065 * @return the element corresponding to the given label node in the current sc ope
1066 */
1067 LabelElementImpl lookupLabel(ASTNode parentNode, SimpleIdentifier labelNode) {
1068 LabelScope labelScope2 = _resolver.labelScope;
1069 LabelElementImpl labelElement = null;
1070 if (labelNode == null) {
1071 if (labelScope2 == null) {
1072 } else {
1073 labelElement = (labelScope2.lookup2(LabelScope.EMPTY_LABEL) as LabelElem entImpl);
1074 if (labelElement == null) {
1075 }
1076 }
1077 } else {
1078 if (labelScope2 == null) {
1079 _resolver.reportError(ResolverErrorCode.UNDEFINED_LABEL, labelNode, [lab elNode.name]);
1080 } else {
1081 labelElement = (labelScope2.lookup(labelNode) as LabelElementImpl);
1082 if (labelElement == null) {
1083 _resolver.reportError(ResolverErrorCode.UNDEFINED_LABEL, labelNode, [l abelNode.name]);
1084 } else {
1085 recordResolution(labelNode, labelElement);
1086 }
1087 }
1088 }
1089 if (labelElement != null) {
1090 ExecutableElement labelContainer = labelElement.getAncestor(ExecutableElem ent);
1091 if (labelContainer != _resolver.enclosingFunction) {
1092 if (labelNode == null) {
1093 _resolver.reportError(ResolverErrorCode.LABEL_IN_OUTER_SCOPE, parentNo de, [""]);
1094 } else {
1095 _resolver.reportError(ResolverErrorCode.LABEL_IN_OUTER_SCOPE, labelNod e, [labelNode.name]);
1096 }
1097 labelElement = null;
1098 }
1099 }
1100 return labelElement;
1101 }
1102 /**
1103 * Look up the method with the given name in the given type. Return the elemen t representing the
1104 * method that was found, or {@code null} if there is no method with the given name.
1105 * @param element the element representing the type in which the method is def ined
1106 * @param methodName the name of the method being looked up
1107 * @return the element representing the method that was found
1108 */
1109 MethodElement lookUpMethod(Element element, String methodName, int parameterCo unt, List<String> parameterNames) {
1110 if (identical(element, DynamicTypeImpl.instance)) {
1111 return null;
1112 }
1113 element = resolveTypeVariable(element);
1114 if (element is ClassElement) {
1115 ClassElement classElement = (element as ClassElement);
1116 MethodElement member = classElement.lookUpMethod(methodName, _resolver.def iningLibrary);
1117 if (member != null) {
1118 return member;
1119 }
1120 return lookUpMethodInInterfaces((element as ClassElement), methodName, new Set<ClassElement>());
1121 }
1122 return null;
1123 }
1124 /**
1125 * Look up the name of a member in the interfaces implemented by the given typ e, either directly
1126 * or indirectly. Return the element representing the member that was found, o r {@code null} if
1127 * there is no member with the given name.
1128 * @param element the element representing the type in which the member is def ined
1129 * @param memberName the name of the member being looked up
1130 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used
1131 * to prevent infinite recursion and to optimize the search
1132 * @return the element representing the member that was found
1133 */
1134 MethodElement lookUpMethodInInterfaces(ClassElement targetClass, String member Name, Set<ClassElement> visitedInterfaces) {
1135 if (visitedInterfaces.contains(targetClass)) {
1136 return null;
1137 }
1138 javaSetAdd(visitedInterfaces, targetClass);
1139 MethodElement member = lookUpMethodInType(targetClass, memberName);
1140 if (member != null) {
1141 return member;
1142 }
1143 for (InterfaceType interfaceType in targetClass.interfaces) {
1144 member = lookUpMethodInInterfaces(interfaceType.element, memberName, visit edInterfaces);
1145 if (member != null) {
1146 return member;
1147 }
1148 }
1149 ClassElement superclass = getSuperclass(targetClass);
1150 if (superclass == null) {
1151 return null;
1152 }
1153 return lookUpMethodInInterfaces(superclass, memberName, visitedInterfaces);
1154 }
1155 /**
1156 * Look up the name of a method in the given type. Return the element represen ting the method that
1157 * was found, or {@code null} if there is no method with the given name.
1158 * @param element the element representing the type in which the method is def ined
1159 * @param memberName the name of the method being looked up
1160 * @return the element representing the method that was found
1161 */
1162 MethodElement lookUpMethodInType(ClassElement element, String memberName) {
1163 for (MethodElement method in element.methods) {
1164 if (method.name == memberName) {
1165 return method;
1166 }
1167 }
1168 return null;
1169 }
1170 /**
1171 * Look up the setter with the given name in the given type. Return the elemen t representing the
1172 * setter that was found, or {@code null} if there is no setter with the given name.
1173 * @param element the element representing the type in which the setter is def ined
1174 * @param setterName the name of the setter being looked up
1175 * @return the element representing the setter that was found
1176 */
1177 PropertyAccessorElement lookUpSetter(Element element, String setterName) {
1178 if (identical(element, DynamicTypeImpl.instance)) {
1179 return null;
1180 }
1181 element = resolveTypeVariable(element);
1182 if (element is ClassElement) {
1183 ClassElement classElement = (element as ClassElement);
1184 PropertyAccessorElement member = classElement.lookUpSetter(setterName, _re solver.definingLibrary);
1185 if (member != null) {
1186 return member;
1187 }
1188 return lookUpSetterInInterfaces((element as ClassElement), setterName, new Set<ClassElement>());
1189 }
1190 return null;
1191 }
1192 /**
1193 * Look up the name of a setter in the interfaces implemented by the given typ e, either directly
1194 * or indirectly. Return the element representing the setter that was found, o r {@code null} if
1195 * there is no setter with the given name.
1196 * @param element the element representing the type in which the setter is def ined
1197 * @param memberName the name of the setter being looked up
1198 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used
1199 * to prevent infinite recursion and to optimize the search
1200 * @return the element representing the setter that was found
1201 */
1202 PropertyAccessorElement lookUpSetterInInterfaces(ClassElement targetClass, Str ing memberName, Set<ClassElement> visitedInterfaces) {
1203 if (visitedInterfaces.contains(targetClass)) {
1204 return null;
1205 }
1206 javaSetAdd(visitedInterfaces, targetClass);
1207 PropertyAccessorElement member = lookUpSetterInType(targetClass, memberName) ;
1208 if (member != null) {
1209 return member;
1210 }
1211 for (InterfaceType interfaceType in targetClass.interfaces) {
1212 member = lookUpSetterInInterfaces(interfaceType.element, memberName, visit edInterfaces);
1213 if (member != null) {
1214 return member;
1215 }
1216 }
1217 ClassElement superclass = getSuperclass(targetClass);
1218 if (superclass == null) {
1219 return null;
1220 }
1221 return lookUpSetterInInterfaces(superclass, memberName, visitedInterfaces);
1222 }
1223 /**
1224 * Look up the name of a setter in the given type. Return the element represen ting the setter that
1225 * was found, or {@code null} if there is no setter with the given name.
1226 * @param element the element representing the type in which the setter is def ined
1227 * @param memberName the name of the setter being looked up
1228 * @return the element representing the setter that was found
1229 */
1230 PropertyAccessorElement lookUpSetterInType(ClassElement element, String member Name) {
1231 for (PropertyAccessorElement accessor in element.accessors) {
1232 if (accessor.isSetter() && accessor.name == memberName) {
1233 return accessor;
1234 }
1235 }
1236 return null;
1237 }
1238 /**
1239 * Return the binary operator that is invoked by the given compound assignment operator.
1240 * @param operator the assignment operator being mapped
1241 * @return the binary operator that invoked by the given assignment operator
1242 */
1243 TokenType operatorFromCompoundAssignment(TokenType operator) {
1244 if (operator == TokenType.AMPERSAND_EQ) {
1245 return TokenType.AMPERSAND;
1246 } else if (operator == TokenType.BAR_EQ) {
1247 return TokenType.BAR;
1248 } else if (operator == TokenType.CARET_EQ) {
1249 return TokenType.CARET;
1250 } else if (operator == TokenType.GT_GT_EQ) {
1251 return TokenType.GT_GT;
1252 } else if (operator == TokenType.LT_LT_EQ) {
1253 return TokenType.LT_LT;
1254 } else if (operator == TokenType.MINUS_EQ) {
1255 return TokenType.MINUS;
1256 } else if (operator == TokenType.PERCENT_EQ) {
1257 return TokenType.PERCENT;
1258 } else if (operator == TokenType.PLUS_EQ) {
1259 return TokenType.PLUS;
1260 } else if (operator == TokenType.SLASH_EQ) {
1261 return TokenType.SLASH;
1262 } else if (operator == TokenType.STAR_EQ) {
1263 return TokenType.STAR;
1264 } else if (operator == TokenType.TILDE_SLASH_EQ) {
1265 return TokenType.TILDE_SLASH;
1266 }
1267 AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to it's corresponding operator");
1268 return operator;
1269 }
1270 /**
1271 * Record the fact that the given AST node was resolved to the given element.
1272 * @param node the AST node that was resolved
1273 * @param element the element to which the AST node was resolved
1274 */
1275 void recordResolution(Identifier node, Element element39) {
1276 if (element39 != null) {
1277 node.element = element39;
1278 }
1279 }
1280 /**
1281 * If the given element is a type variable, resolve it to the class that shoul d be used when
1282 * looking up members. Otherwise, return the original element.
1283 * @param element the element that is to be resolved if it is a type variable
1284 * @return the class that should be used in place of the argument if it is a t ype variable, or the
1285 * original argument if it isn't a type variable
1286 */
1287 Element resolveTypeVariable(Element element40) {
1288 if (element40 is TypeVariableElement) {
1289 Type2 bound3 = ((element40 as TypeVariableElement)).bound;
1290 if (bound3 == null) {
1291 return _resolver.typeProvider.objectType.element;
1292 }
1293 return bound3.element;
1294 }
1295 return element40;
1296 }
1297 }
1298 class Identifier_2 extends Identifier {
1299 String name9;
1300 Identifier_2(this.name9) : super();
1301 accept(ASTVisitor visitor) => null;
1302 Token get beginToken => null;
1303 Token get endToken => null;
1304 String get name => name9;
1305 void visitChildren(ASTVisitor<Object> visitor) {
1306 }
1307 }
1308 /**
1309 * Instances of the class {@code Library} represent the data about a single libr ary during the
1310 * resolution of some (possibly different) library. They are not intended to be used except during
1311 * the resolution process.
1312 */
1313 class Library {
1314 /**
1315 * The analysis context in which this library is being analyzed.
1316 */
1317 AnalysisContextImpl _analysisContext;
1318 /**
1319 * The listener to which analysis errors will be reported.
1320 */
1321 AnalysisErrorListener _errorListener;
1322 /**
1323 * The source specifying the defining compilation unit of this library.
1324 */
1325 Source _librarySource;
1326 /**
1327 * The library element representing this library.
1328 */
1329 LibraryElementImpl _libraryElement;
1330 /**
1331 * A list containing all of the libraries that are imported into this library.
1332 */
1333 Map<ImportDirective, Library> _importedLibraries = new Map<ImportDirective, Li brary>();
1334 /**
1335 * A flag indicating whether this library explicitly imports core.
1336 */
1337 bool _explicitlyImportsCore = false;
1338 /**
1339 * A list containing all of the libraries that are exported from this library.
1340 */
1341 Map<ExportDirective, Library> _exportedLibraries = new Map<ExportDirective, Li brary>();
1342 /**
1343 * A table mapping the sources for the compilation units in this library to th eir corresponding
1344 * AST structures.
1345 */
1346 Map<Source, CompilationUnit> _astMap = new Map<Source, CompilationUnit>();
1347 /**
1348 * The library scope used when resolving elements within this library's compil ation units.
1349 */
1350 LibraryScope _libraryScope;
1351 /**
1352 * Initialize a newly created data holder that can maintain the data associate d with a library.
1353 * @param analysisContext the analysis context in which this library is being analyzed
1354 * @param errorListener the listener to which analysis errors will be reported
1355 * @param librarySource the source specifying the defining compilation unit of this library
1356 */
1357 Library(AnalysisContextImpl analysisContext, AnalysisErrorListener errorListen er, Source librarySource) {
1358 this._analysisContext = analysisContext;
1359 this._errorListener = errorListener;
1360 this._librarySource = librarySource;
1361 this._libraryElement = (analysisContext.getLibraryElementOrNull(librarySourc e) as LibraryElementImpl);
1362 }
1363 /**
1364 * Record that the given library is exported from this library.
1365 * @param importLibrary the library that is exported from this library
1366 */
1367 void addExport(ExportDirective directive, Library exportLibrary) {
1368 _exportedLibraries[directive] = exportLibrary;
1369 }
1370 /**
1371 * Record that the given library is imported into this library.
1372 * @param importLibrary the library that is imported into this library
1373 */
1374 void addImport(ImportDirective directive, Library importLibrary) {
1375 _importedLibraries[directive] = importLibrary;
1376 }
1377 /**
1378 * Return the AST structure associated with the given source.
1379 * @param source the source representing the compilation unit whose AST is to be returned
1380 * @return the AST structure associated with the given source
1381 * @throws AnalysisException if an AST structure could not be created for the compilation unit
1382 */
1383 CompilationUnit getAST(Source source) {
1384 CompilationUnit unit = _astMap[source];
1385 if (unit == null) {
1386 unit = _analysisContext.parse2(source, _errorListener);
1387 _astMap[source] = unit;
1388 }
1389 return unit;
1390 }
1391 /**
1392 * Return a collection containing the sources for the compilation units in thi s library.
1393 * @return the sources for the compilation units in this library
1394 */
1395 Set<Source> get compilationUnitSources => _astMap.keys.toSet();
1396 /**
1397 * Return the AST structure associated with the defining compilation unit for this library.
1398 * @return the AST structure associated with the defining compilation unit for this library
1399 * @throws AnalysisException if an AST structure could not be created for the defining compilation
1400 * unit
1401 */
1402 CompilationUnit get definingCompilationUnit => getAST(librarySource);
1403 /**
1404 * Return {@code true} if this library explicitly imports core.
1405 * @return {@code true} if this library explicitly imports core
1406 */
1407 bool get explicitlyImportsCore => _explicitlyImportsCore;
1408 /**
1409 * Return the library exported by the given directive.
1410 * @param directive the directive that exports the library to be returned
1411 * @return the library exported by the given directive
1412 */
1413 Library getExport(ExportDirective directive) => _exportedLibraries[directive];
1414 /**
1415 * Return an array containing the libraries that are exported from this librar y.
1416 * @return an array containing the libraries that are exported from this libra ry
1417 */
1418 List<Library> get exports {
1419 Set<Library> libraries = new Set<Library>();
1420 libraries.addAll(_exportedLibraries.values);
1421 return new List.from(libraries);
1422 }
1423 /**
1424 * Return the library imported by the given directive.
1425 * @param directive the directive that imports the library to be returned
1426 * @return the library imported by the given directive
1427 */
1428 Library getImport(ImportDirective directive) => _importedLibraries[directive];
1429 /**
1430 * Return an array containing the libraries that are imported into this librar y.
1431 * @return an array containing the libraries that are imported into this libra ry
1432 */
1433 List<Library> get imports {
1434 Set<Library> libraries = new Set<Library>();
1435 libraries.addAll(_importedLibraries.values);
1436 return new List.from(libraries);
1437 }
1438 /**
1439 * Return an array containing the libraries that are either imported or export ed from this
1440 * library.
1441 * @return the libraries that are either imported or exported from this librar y
1442 */
1443 List<Library> get importsAndExports {
1444 Set<Library> libraries = new Set<Library>();
1445 libraries.addAll(_importedLibraries.values);
1446 libraries.addAll(_exportedLibraries.values);
1447 return new List.from(libraries);
1448 }
1449 /**
1450 * Return the library element representing this library, creating it if necess ary.
1451 * @return the library element representing this library
1452 */
1453 LibraryElementImpl get libraryElement {
1454 if (_libraryElement == null) {
1455 _libraryElement = (_analysisContext.getLibraryElement(_librarySource) as L ibraryElementImpl);
1456 }
1457 return _libraryElement;
1458 }
1459 /**
1460 * Return the library scope used when resolving elements within this library's compilation units.
1461 * @return the library scope used when resolving elements within this library' s compilation units
1462 */
1463 LibraryScope get libraryScope {
1464 if (_libraryScope == null) {
1465 _libraryScope = new LibraryScope(_libraryElement, _errorListener);
1466 }
1467 return _libraryScope;
1468 }
1469 /**
1470 * Return the source specifying the defining compilation unit of this library.
1471 * @return the source specifying the defining compilation unit of this library
1472 */
1473 Source get librarySource => _librarySource;
1474 /**
1475 * Return the result of resolving the given URI against the URI of the library , or {@code null} if
1476 * the URI is not valid. If the URI is not valid, report the error.
1477 * @param uriLiteral the string literal specifying the URI to be resolved
1478 * @return the result of resolving the given URI against the URI of the librar y
1479 */
1480 Source getSource(StringLiteral uriLiteral) => getSource2(getStringValue(uriLit eral), uriLiteral.offset, uriLiteral.length);
1481 /**
1482 * Set whether this library explicitly imports core to match the given value.
1483 * @param explicitlyImportsCore {@code true} if this library explicitly import s core
1484 */
1485 void set explicitlyImportsCore(bool explicitlyImportsCore2) {
1486 this._explicitlyImportsCore = explicitlyImportsCore2;
1487 }
1488 /**
1489 * Set the library element representing this library to the given library elem ent.
1490 * @param libraryElement the library element representing this library
1491 */
1492 void set libraryElement(LibraryElementImpl libraryElement2) {
1493 this._libraryElement = libraryElement2;
1494 }
1495 String toString() => _librarySource.shortName;
1496 /**
1497 * Append the value of the given string literal to the given string builder.
1498 * @param builder the builder to which the string's value is to be appended
1499 * @param literal the string literal whose value is to be appended to the buil der
1500 * @throws IllegalArgumentException if the string is not a constant string wit hout any string
1501 * interpolation
1502 */
1503 void appendStringValue(StringBuffer builder, StringLiteral literal) {
1504 if (literal is SimpleStringLiteral) {
1505 builder.add(((literal as SimpleStringLiteral)).value);
1506 } else if (literal is AdjacentStrings) {
1507 for (StringLiteral stringLiteral in ((literal as AdjacentStrings)).strings ) {
1508 appendStringValue(builder, stringLiteral);
1509 }
1510 } else {
1511 throw new IllegalArgumentException();
1512 }
1513 }
1514 /**
1515 * Return the result of resolving the given URI against the URI of the library , or {@code null} if
1516 * the URI is not valid. If the URI is not valid, report the error.
1517 * @param uri the URI to be resolved
1518 * @param uriOffset the offset of the string literal representing the URI
1519 * @param uriLength the length of the string literal representing the URI
1520 * @return the result of resolving the given URI against the URI of the librar y
1521 */
1522 Source getSource2(String uri, int uriOffset, int uriLength) {
1523 if (uri == null) {
1524 _errorListener.onError(new AnalysisError.con2(_librarySource, uriOffset, u riLength, ResolverErrorCode.INVALID_URI, []));
1525 return null;
1526 }
1527 return _librarySource.resolve(uri);
1528 }
1529 /**
1530 * Return the value of the given string literal, or {@code null} if the string is not a constant
1531 * string without any string interpolation.
1532 * @param literal the string literal whose value is to be returned
1533 * @return the value of the given string literal
1534 */
1535 String getStringValue(StringLiteral literal) {
1536 StringBuffer builder = new StringBuffer();
1537 try {
1538 appendStringValue(builder, literal);
1539 } on IllegalArgumentException catch (exception) {
1540 return null;
1541 }
1542 return builder.toString();
1543 }
1544 }
1545 /**
1546 * Instances of the class {@code LibraryElementBuilder} build an element model f or a single library.
1547 */
1548 class LibraryElementBuilder {
1549 /**
1550 * The analysis context in which the element model will be built.
1551 */
1552 AnalysisContextImpl _analysisContext;
1553 /**
1554 * The listener to which errors will be reported.
1555 */
1556 AnalysisErrorListener _errorListener;
1557 /**
1558 * The name of the core library.
1559 */
1560 static String CORE_LIBRARY_URI = "dart:core";
1561 /**
1562 * The name of the function used as an entry point.
1563 */
1564 static String _ENTRY_POINT_NAME = "main";
1565 /**
1566 * Initialize a newly created library element builder.
1567 * @param resolver the resolver for which the element model is being built
1568 */
1569 LibraryElementBuilder(LibraryResolver resolver) {
1570 this._analysisContext = resolver.analysisContext;
1571 this._errorListener = resolver.errorListener;
1572 }
1573 /**
1574 * Build the library element for the given library.
1575 * @param library the library for which an element model is to be built
1576 * @return the library element that was built
1577 * @throws AnalysisException if the analysis could not be performed
1578 */
1579 LibraryElementImpl buildLibrary(Library library) {
1580 CompilationUnitBuilder builder = new CompilationUnitBuilder(_analysisContext , _errorListener);
1581 Source librarySource2 = library.librarySource;
1582 CompilationUnit definingCompilationUnit3 = library.definingCompilationUnit;
1583 CompilationUnitElementImpl definingCompilationUnitElement = builder.buildCom pilationUnit2(librarySource2, definingCompilationUnit3);
1584 NodeList<Directive> directives3 = definingCompilationUnit3.directives;
1585 LibraryIdentifier libraryNameNode = null;
1586 bool hasPartDirective = false;
1587 FunctionElement entryPoint = findEntryPoint(definingCompilationUnitElement);
1588 List<ImportElement> imports = new List<ImportElement>();
1589 List<ExportElement> exports = new List<ExportElement>();
1590 List<Directive> directivesToResolve = new List<Directive>();
1591 List<CompilationUnitElementImpl> sourcedCompilationUnits = new List<Compilat ionUnitElementImpl>();
1592 for (Directive directive in directives3) {
1593 if (directive is LibraryDirective) {
1594 if (libraryNameNode == null) {
1595 libraryNameNode = ((directive as LibraryDirective)).name;
1596 directivesToResolve.add(directive);
1597 }
1598 } else if (directive is PartDirective) {
1599 hasPartDirective = true;
1600 StringLiteral partUri = ((directive as PartDirective)).uri;
1601 Source partSource = library.getSource(partUri);
1602 if (partSource != null) {
1603 CompilationUnitElementImpl part = builder.buildCompilationUnit(partSou rce);
1604 String partLibraryName = getPartLibraryName(library, partSource, direc tivesToResolve);
1605 if (partLibraryName == null) {
1606 _errorListener.onError(new AnalysisError.con2(librarySource2, partUr i.offset, partUri.length, ResolverErrorCode.MISSING_PART_OF_DIRECTIVE, []));
1607 } else if (libraryNameNode == null) {
1608 } else if (libraryNameNode.name != partLibraryName) {
1609 _errorListener.onError(new AnalysisError.con2(librarySource2, partUr i.offset, partUri.length, ResolverErrorCode.PART_WITH_WRONG_LIBRARY_NAME, [partL ibraryName]));
1610 }
1611 if (entryPoint == null) {
1612 entryPoint = findEntryPoint(part);
1613 }
1614 directive.element = part;
1615 sourcedCompilationUnits.add(part);
1616 }
1617 }
1618 }
1619 if (hasPartDirective && libraryNameNode == null) {
1620 _errorListener.onError(new AnalysisError.con1(librarySource2, ResolverErro rCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART, []));
1621 }
1622 LibraryElementImpl libraryElement = new LibraryElementImpl(_analysisContext, libraryNameNode);
1623 libraryElement.definingCompilationUnit = definingCompilationUnitElement;
1624 if (entryPoint != null) {
1625 libraryElement.entryPoint = entryPoint;
1626 }
1627 libraryElement.imports = new List.from(imports);
1628 libraryElement.exports = new List.from(exports);
1629 libraryElement.parts = new List.from(sourcedCompilationUnits);
1630 for (Directive directive in directivesToResolve) {
1631 directive.element = libraryElement;
1632 }
1633 library.libraryElement = libraryElement;
1634 return libraryElement;
1635 }
1636 /**
1637 * Search the top-level functions defined in the given compilation unit for th e entry point.
1638 * @param element the compilation unit to be searched
1639 * @return the entry point that was found, or {@code null} if the compilation unit does not define
1640 * an entry point
1641 */
1642 FunctionElement findEntryPoint(CompilationUnitElementImpl element) {
1643 for (FunctionElement function in element.functions) {
1644 if (function.name == _ENTRY_POINT_NAME) {
1645 return function;
1646 }
1647 }
1648 return null;
1649 }
1650 /**
1651 * 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.
1652 * @param library the library containing the part
1653 * @param partSource the source representing the part
1654 * @param directivesToResolve a list of directives that should be resolved to the library being
1655 * built
1656 * @return the name of the library that the given part is declared to be a par t of
1657 */
1658 String getPartLibraryName(Library library, Source partSource, List<Directive> directivesToResolve) {
1659 try {
1660 CompilationUnit partUnit = library.getAST(partSource);
1661 for (Directive directive in partUnit.directives) {
1662 if (directive is PartOfDirective) {
1663 directivesToResolve.add(directive);
1664 LibraryIdentifier libraryName3 = ((directive as PartOfDirective)).libr aryName;
1665 if (libraryName3 != null) {
1666 return libraryName3.name;
1667 }
1668 }
1669 }
1670 } on AnalysisException catch (exception) {
1671 }
1672 return null;
1673 }
1674 }
1675 /**
1676 * Instances of the class {@code LibraryResolver} are used to resolve one or mor e mutually dependent
1677 * libraries within a single context.
1678 */
1679 class LibraryResolver {
1680 /**
1681 * The analysis context in which the libraries are being analyzed.
1682 */
1683 AnalysisContextImpl _analysisContext;
1684 /**
1685 * The listener to which analysis errors will be reported.
1686 */
1687 AnalysisErrorListener _errorListener;
1688 /**
1689 * A source object representing the core library (dart:core).
1690 */
1691 Source _coreLibrarySource;
1692 /**
1693 * The object representing the core library.
1694 */
1695 Library _coreLibrary;
1696 /**
1697 * The object used to access the types from the core library.
1698 */
1699 TypeProvider _typeProvider;
1700 /**
1701 * A table mapping library sources to the information being maintained for tho se libraries.
1702 */
1703 Map<Source, Library> _libraryMap = new Map<Source, Library>();
1704 /**
1705 * A collection containing the libraries that are being resolved together.
1706 */
1707 Set<Library> _librariesInCycles;
1708 /**
1709 * Initialize a newly created library resolver to resolve libraries within the given context.
1710 * @param analysisContext the analysis context in which the library is being a nalyzed
1711 * @param errorListener the listener to which analysis errors will be reported
1712 */
1713 LibraryResolver(AnalysisContextImpl analysisContext, AnalysisErrorListener err orListener) {
1714 this._analysisContext = analysisContext;
1715 this._errorListener = errorListener;
1716 _coreLibrarySource = analysisContext.sourceFactory.forUri(LibraryElementBuil der.CORE_LIBRARY_URI);
1717 }
1718 /**
1719 * Return the analysis context in which the libraries are being analyzed.
1720 * @return the analysis context in which the libraries are being analyzed
1721 */
1722 AnalysisContextImpl get analysisContext => _analysisContext;
1723 /**
1724 * Return the listener to which analysis errors will be reported.
1725 * @return the listener to which analysis errors will be reported
1726 */
1727 AnalysisErrorListener get errorListener => _errorListener;
1728 /**
1729 * Resolve the library specified by the given source in the given context.
1730 * <p>
1731 * Note that because Dart allows circular imports between libraries, it is pos sible that more than
1732 * one library will need to be resolved. In such cases the error listener can receive errors from
1733 * multiple libraries.
1734 * @param librarySource the source specifying the defining compilation unit of the library to be
1735 * resolved
1736 * @param fullAnalysis {@code true} if a full analysis should be performed
1737 * @return the element representing the resolved library
1738 * @throws AnalysisException if the library could not be resolved for some rea son
1739 */
1740 LibraryElement resolveLibrary(Source librarySource, bool fullAnalysis) {
1741 Library targetLibrary = createLibrary(librarySource);
1742 _coreLibrary = _libraryMap[_coreLibrarySource];
1743 if (_coreLibrary == null) {
1744 _coreLibrary = createLibrary(_coreLibrarySource);
1745 }
1746 computeLibraryDependencies(targetLibrary);
1747 _librariesInCycles = computeLibrariesInCycles(targetLibrary);
1748 buildElementModels();
1749 buildDirectiveModels();
1750 _typeProvider = new TypeProviderImpl(_coreLibrary.libraryElement);
1751 buildTypeHierarchies();
1752 resolveReferencesAndTypes();
1753 if (fullAnalysis) {
1754 }
1755 recordLibraryElements();
1756 return targetLibrary.libraryElement;
1757 }
1758 /**
1759 * Add a dependency to the given map from the referencing library to the refer enced library.
1760 * @param dependencyMap the map to which the dependency is to be added
1761 * @param referencingLibrary the library that references the referenced librar y
1762 * @param referencedLibrary the library referenced by the referencing library
1763 */
1764 void addDependencyToMap(Map<Library, List<Library>> dependencyMap, Library ref erencingLibrary, Library referencedLibrary) {
1765 List<Library> dependentLibraries = dependencyMap[referencedLibrary];
1766 if (dependentLibraries == null) {
1767 dependentLibraries = new List<Library>();
1768 dependencyMap[referencedLibrary] = dependentLibraries;
1769 }
1770 dependentLibraries.add(referencingLibrary);
1771 }
1772 /**
1773 * Given a library that is part of a cycle that includes the root library, add to the given set of
1774 * libraries all of the libraries reachable from the root library that are als o included in the
1775 * cycle.
1776 * @param library the library to be added to the collection of libraries in cy cles
1777 * @param librariesInCycle a collection of the libraries that are in the cycle
1778 * @param dependencyMap a table mapping libraries to the collection of librari es from which those
1779 * libraries are referenced
1780 */
1781 void addLibrariesInCycle(Library library, Set<Library> librariesInCycle, Map<L ibrary, List<Library>> dependencyMap) {
1782 if (javaSetAdd(librariesInCycle, library)) {
1783 List<Library> dependentLibraries = dependencyMap[library];
1784 if (dependentLibraries != null) {
1785 for (Library dependentLibrary in dependentLibraries) {
1786 addLibrariesInCycle(dependentLibrary, librariesInCycle, dependencyMap) ;
1787 }
1788 }
1789 }
1790 }
1791 /**
1792 * Add the given library, and all libraries reachable from it that have not al ready been visited,
1793 * to the given dependency map.
1794 * @param library the library currently being added to the dependency map
1795 * @param dependencyMap the dependency map being computed
1796 * @param visitedLibraries the libraries that have already been visited, used to prevent infinite
1797 * recursion
1798 */
1799 void addToDependencyMap(Library library, Map<Library, List<Library>> dependenc yMap, Set<Library> visitedLibraries) {
1800 if (javaSetAdd(visitedLibraries, library)) {
1801 for (Library referencedLibrary in library.importsAndExports) {
1802 addDependencyToMap(dependencyMap, library, referencedLibrary);
1803 addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries);
1804 }
1805 if (!library.explicitlyImportsCore && library != _coreLibrary) {
1806 addDependencyToMap(dependencyMap, library, _coreLibrary);
1807 }
1808 }
1809 }
1810 /**
1811 * Build the element model representing the combinators declared by the given directive.
1812 * @param directive the directive that declares the combinators
1813 * @return an array containing the import combinators that were built
1814 */
1815 List<NamespaceCombinator> buildCombinators(NamespaceDirective directive) {
1816 List<NamespaceCombinator> combinators = new List<NamespaceCombinator>();
1817 for (Combinator combinator in directive.combinators) {
1818 if (combinator is HideCombinator) {
1819 HideCombinatorImpl hide = new HideCombinatorImpl();
1820 hide.hiddenNames = getIdentifiers(((combinator as HideCombinator)).hidde nNames);
1821 combinators.add(hide);
1822 } else {
1823 ShowCombinatorImpl show = new ShowCombinatorImpl();
1824 show.shownNames = getIdentifiers(((combinator as ShowCombinator)).shownN ames);
1825 combinators.add(show);
1826 }
1827 }
1828 return new List.from(combinators);
1829 }
1830 /**
1831 * Every library now has a corresponding {@link LibraryElement}, so it is now possible to resolve
1832 * the import and export directives.
1833 * @throws AnalysisException if the defining compilation unit for any of the l ibraries could not
1834 * be accessed
1835 */
1836 void buildDirectiveModels() {
1837 for (Library library in _librariesInCycles) {
1838 Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixEle mentImpl>();
1839 List<ImportElement> imports = new List<ImportElement>();
1840 List<ExportElement> exports = new List<ExportElement>();
1841 for (Directive directive in library.definingCompilationUnit.directives) {
1842 if (directive is ImportDirective) {
1843 ImportDirective importDirective = (directive as ImportDirective);
1844 Library importedLibrary = library.getImport(importDirective);
1845 ImportElementImpl importElement = new ImportElementImpl();
1846 importElement.combinators = buildCombinators(importDirective);
1847 LibraryElement importedLibraryElement = importedLibrary.libraryElement ;
1848 if (importedLibraryElement != null) {
1849 importElement.importedLibrary = importedLibraryElement;
1850 directive.element = importedLibraryElement;
1851 }
1852 SimpleIdentifier prefixNode = ((directive as ImportDirective)).prefix;
1853 if (prefixNode != null) {
1854 String prefixName = prefixNode.name;
1855 PrefixElementImpl prefix = nameToPrefixMap[prefixName];
1856 if (prefix == null) {
1857 prefix = new PrefixElementImpl(prefixNode);
1858 nameToPrefixMap[prefixName] = prefix;
1859 }
1860 importElement.prefix = prefix;
1861 }
1862 imports.add(importElement);
1863 } else if (directive is ExportDirective) {
1864 ExportDirective exportDirective = (directive as ExportDirective);
1865 ExportElementImpl exportElement = new ExportElementImpl();
1866 exportElement.combinators = buildCombinators(exportDirective);
1867 LibraryElement exportedLibrary = library.getExport(exportDirective).li braryElement;
1868 if (exportedLibrary != null) {
1869 exportElement.exportedLibrary = exportedLibrary;
1870 directive.element = exportedLibrary;
1871 }
1872 exports.add(exportElement);
1873 }
1874 }
1875 Source librarySource3 = library.librarySource;
1876 if (!library.explicitlyImportsCore && _coreLibrarySource != librarySource3 ) {
1877 ImportElementImpl importElement = new ImportElementImpl();
1878 importElement.importedLibrary = _coreLibrary.libraryElement;
1879 importElement.synthetic = true;
1880 imports.add(importElement);
1881 }
1882 LibraryElementImpl libraryElement3 = library.libraryElement;
1883 libraryElement3.imports = new List.from(imports);
1884 libraryElement3.exports = new List.from(exports);
1885 }
1886 }
1887 /**
1888 * Build element models for all of the libraries in the current cycle.
1889 * @throws AnalysisException if any of the element models cannot be built
1890 */
1891 void buildElementModels() {
1892 for (Library library in _librariesInCycles) {
1893 LibraryElementBuilder builder = new LibraryElementBuilder(this);
1894 LibraryElementImpl libraryElement = builder.buildLibrary(library);
1895 library.libraryElement = libraryElement;
1896 }
1897 }
1898 /**
1899 * Resolve the type hierarchy across all of the types declared in the librarie s in the current
1900 * cycle.
1901 * @throws AnalysisException if any of the type hierarchies could not be resol ved
1902 */
1903 void buildTypeHierarchies() {
1904 for (Library library in _librariesInCycles) {
1905 for (Source source in library.compilationUnitSources) {
1906 TypeResolverVisitor visitor = new TypeResolverVisitor(library, source, _ typeProvider);
1907 library.getAST(source).accept(visitor);
1908 }
1909 }
1910 }
1911 /**
1912 * Compute a dependency map of libraries reachable from the given library. A d ependency map is a
1913 * table that maps individual libraries to a list of the libraries that either import or export
1914 * those libraries.
1915 * <p>
1916 * This map is used to compute all of the libraries involved in a cycle that i nclude the root
1917 * library. Given that we only add libraries that are reachable from the root library, when we
1918 * work backward we are guaranteed to only get libraries in the cycle.
1919 * @param library the library currently being added to the dependency map
1920 */
1921 Map<Library, List<Library>> computeDependencyMap(Library library) {
1922 Map<Library, List<Library>> dependencyMap = new Map<Library, List<Library>>( );
1923 addToDependencyMap(library, dependencyMap, new Set<Library>());
1924 return dependencyMap;
1925 }
1926 /**
1927 * Return a collection containing all of the libraries reachable from the give n library that are
1928 * contained in a cycle that includes the given library.
1929 * @param library the library that must be included in any cycles whose member s are to be returned
1930 * @return all of the libraries referenced by the given library that have a ci rcular reference
1931 * back to the given library
1932 */
1933 Set<Library> computeLibrariesInCycles(Library library) {
1934 Map<Library, List<Library>> dependencyMap = computeDependencyMap(library);
1935 Set<Library> librariesInCycle = new Set<Library>();
1936 addLibrariesInCycle(library, librariesInCycle, dependencyMap);
1937 return librariesInCycle;
1938 }
1939 /**
1940 * Recursively traverse the libraries reachable from the given library, creati ng instances of the
1941 * class {@link Library} to represent them, and record the references in the l ibrary objects.
1942 * @param library the library to be processed to find libaries that have not y et been traversed
1943 * @throws AnalysisException if some portion of the library graph could not be traversed
1944 */
1945 void computeLibraryDependencies(Library library) {
1946 bool explicitlyImportsCore = false;
1947 CompilationUnit unit = library.definingCompilationUnit;
1948 for (Directive directive in unit.directives) {
1949 if (directive is ImportDirective) {
1950 ImportDirective importDirective = (directive as ImportDirective);
1951 Source importedSource = library.getSource(importDirective.uri);
1952 if (importedSource == _coreLibrarySource) {
1953 explicitlyImportsCore = true;
1954 }
1955 Library importedLibrary = _libraryMap[importedSource];
1956 if (importedLibrary == null) {
1957 importedLibrary = createLibrary(importedSource);
1958 computeLibraryDependencies(importedLibrary);
1959 }
1960 library.addImport(importDirective, importedLibrary);
1961 } else if (directive is ExportDirective) {
1962 ExportDirective exportDirective = (directive as ExportDirective);
1963 Source exportedSource = library.getSource(exportDirective.uri);
1964 Library exportedLibrary = _libraryMap[exportedSource];
1965 if (exportedLibrary == null) {
1966 exportedLibrary = createLibrary(exportedSource);
1967 computeLibraryDependencies(exportedLibrary);
1968 }
1969 library.addExport(exportDirective, exportedLibrary);
1970 }
1971 }
1972 library.explicitlyImportsCore = explicitlyImportsCore;
1973 if (!explicitlyImportsCore && _coreLibrarySource != library.librarySource) {
1974 Library importedLibrary = _libraryMap[_coreLibrarySource];
1975 if (importedLibrary == null) {
1976 importedLibrary = createLibrary(_coreLibrarySource);
1977 computeLibraryDependencies(importedLibrary);
1978 }
1979 }
1980 }
1981 /**
1982 * Create an object to represent the information about the library defined by the compilation unit
1983 * with the given source.
1984 * @param librarySource the source of the library's defining compilation unit
1985 * @return the library object that was created
1986 */
1987 Library createLibrary(Source librarySource) {
1988 Library library = new Library(_analysisContext, _errorListener, librarySourc e);
1989 _libraryMap[librarySource] = library;
1990 return library;
1991 }
1992 /**
1993 * Return an array containing the lexical identifiers associated with the node s in the given list.
1994 * @param names the AST nodes representing the identifiers
1995 * @return the lexical identifiers associated with the nodes in the list
1996 */
1997 List<String> getIdentifiers(NodeList<SimpleIdentifier> names) {
1998 int count = names.length;
1999 List<String> identifiers = new List<String>.fixedLength(count);
2000 for (int i = 0; i < count; i++) {
2001 identifiers[i] = names[i].name;
2002 }
2003 return identifiers;
2004 }
2005 /**
2006 * As the final step in the process, record the resolved element models with t he analysis context.
2007 */
2008 void recordLibraryElements() {
2009 Map<Source, LibraryElement> elementMap = new Map<Source, LibraryElement>();
2010 for (Library library in _librariesInCycles) {
2011 elementMap[library.librarySource] = library.libraryElement;
2012 }
2013 _analysisContext.recordLibraryElements(elementMap);
2014 }
2015 /**
2016 * Resolve the identifiers and perform type analysis in the libraries in the c urrent cycle.
2017 * @throws AnalysisException if any of the identifiers could not be resolved o r if any of the
2018 * libraries could not have their types analyzed
2019 */
2020 void resolveReferencesAndTypes() {
2021 for (Library library in _librariesInCycles) {
2022 resolveReferencesAndTypes2(library);
2023 }
2024 }
2025 /**
2026 * Resolve the identifiers and perform type analysis in the given library.
2027 * @param library the library to be resolved
2028 * @throws AnalysisException if any of the identifiers could not be resolved o r if the types in
2029 * the library cannot be analyzed
2030 */
2031 void resolveReferencesAndTypes2(Library library) {
2032 for (Source source in library.compilationUnitSources) {
2033 ResolverVisitor visitor = new ResolverVisitor(library, source, _typeProvid er);
2034 library.getAST(source).accept(visitor);
2035 }
2036 }
2037 }
2038 /**
2039 * Instances of the class {@code ResolverVisitor} are used to resolve the nodes within a single
2040 * compilation unit.
2041 */
2042 class ResolverVisitor extends ScopedVisitor {
2043 /**
2044 * The object used to resolve the element associated with the current node.
2045 */
2046 ElementResolver _elementResolver;
2047 /**
2048 * The object used to compute the type associated with the current node.
2049 */
2050 StaticTypeAnalyzer _typeAnalyzer;
2051 /**
2052 * The class element representing the class containing the current node, or {@ code null} if the
2053 * current node is not contained in a class.
2054 */
2055 ClassElement _enclosingClass = null;
2056 /**
2057 * The element representing the function containing the current node, or {@cod e null} if the
2058 * current node is not contained in a function.
2059 */
2060 ExecutableElement _enclosingFunction = null;
2061 /**
2062 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
2063 * @param library the library containing the compilation unit being resolved
2064 * @param source the source representing the compilation unit being visited
2065 * @param typeProvider the object used to access the types from the core libra ry
2066 */
2067 ResolverVisitor(Library library, Source source, TypeProvider typeProvider) : s uper(library, source, typeProvider) {
2068 this._elementResolver = new ElementResolver(this);
2069 this._typeAnalyzer = new StaticTypeAnalyzer(this);
2070 }
2071 Object visitClassDeclaration(ClassDeclaration node) {
2072 ClassElement outerType = _enclosingClass;
2073 try {
2074 _enclosingClass = node.element;
2075 _typeAnalyzer.thisType = _enclosingClass == null ? null : _enclosingClass. type;
2076 super.visitClassDeclaration(node);
2077 } finally {
2078 _typeAnalyzer.thisType = outerType == null ? null : outerType.type;
2079 _enclosingClass = outerType;
2080 }
2081 return null;
2082 }
2083 Object visitFunctionDeclaration(FunctionDeclaration node) {
2084 ExecutableElement outerFunction = _enclosingFunction;
2085 try {
2086 SimpleIdentifier functionName = node.name;
2087 _enclosingFunction = (functionName.element as ExecutableElement);
2088 super.visitFunctionDeclaration(node);
2089 } finally {
2090 _enclosingFunction = outerFunction;
2091 }
2092 return null;
2093 }
2094 Object visitFunctionExpression(FunctionExpression node) {
2095 ExecutableElement outerFunction = _enclosingFunction;
2096 try {
2097 _enclosingFunction = node.element;
2098 super.visitFunctionExpression(node);
2099 } finally {
2100 _enclosingFunction = outerFunction;
2101 }
2102 return null;
2103 }
2104 Object visitLibraryIdentifier(LibraryIdentifier node) => null;
2105 Object visitMethodDeclaration(MethodDeclaration node) {
2106 ExecutableElement outerFunction = _enclosingFunction;
2107 try {
2108 _enclosingFunction = node.element;
2109 super.visitMethodDeclaration(node);
2110 } finally {
2111 _enclosingFunction = outerFunction;
2112 }
2113 return null;
2114 }
2115 Object visitNode(ASTNode node) {
2116 node.visitChildren(this);
2117 node.accept(_elementResolver);
2118 node.accept(_typeAnalyzer);
2119 return null;
2120 }
2121 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
2122 SimpleIdentifier prefix6 = node.prefix;
2123 if (prefix6 != null) {
2124 prefix6.accept(this);
2125 }
2126 node.accept(_elementResolver);
2127 node.accept(_typeAnalyzer);
2128 return null;
2129 }
2130 Object visitPropertyAccess(PropertyAccess node) {
2131 Expression target5 = node.target;
2132 if (target5 != null) {
2133 target5.accept(this);
2134 }
2135 node.accept(_elementResolver);
2136 node.accept(_typeAnalyzer);
2137 return null;
2138 }
2139 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
2140 ArgumentList argumentList11 = node.argumentList;
2141 if (argumentList11 != null) {
2142 argumentList11.accept(this);
2143 }
2144 node.accept(_elementResolver);
2145 node.accept(_typeAnalyzer);
2146 return null;
2147 }
2148 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
2149 ArgumentList argumentList12 = node.argumentList;
2150 if (argumentList12 != null) {
2151 argumentList12.accept(this);
2152 }
2153 node.accept(_elementResolver);
2154 node.accept(_typeAnalyzer);
2155 return null;
2156 }
2157 Object visitTypeName(TypeName node) => null;
2158 /**
2159 * Return the class element representing the class containing the current node , or {@code null} if
2160 * the current node is not contained in a class.
2161 * @return the class element representing the class containing the current nod e
2162 */
2163 ClassElement get enclosingClass => _enclosingClass;
2164 /**
2165 * Return the element representing the function containing the current node, o r {@code null} if
2166 * the current node is not contained in a function.
2167 * @return the element representing the function containing the current node
2168 */
2169 ExecutableElement get enclosingFunction => _enclosingFunction;
2170 }
2171 /**
2172 * The abstract class {@code ScopedVisitor} maintains name and label scopes as a n AST structure is
2173 * being visited.
2174 */
2175 abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
2176 /**
2177 * The element for the library containing the compilation unit being visited.
2178 */
2179 LibraryElement _definingLibrary;
2180 /**
2181 * The source representing the compilation unit being visited.
2182 */
2183 Source _source;
2184 /**
2185 * The error listener that will be informed of any errors that are found durin g resolution.
2186 */
2187 AnalysisErrorListener _errorListener;
2188 /**
2189 * The scope used to resolve identifiers.
2190 */
2191 Scope _nameScope;
2192 /**
2193 * The object used to access the types from the core library.
2194 */
2195 TypeProvider _typeProvider;
2196 /**
2197 * 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.
2198 */
2199 LabelScope _labelScope;
2200 /**
2201 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
2202 * @param library the library containing the compilation unit being resolved
2203 * @param source the source representing the compilation unit being visited
2204 * @param typeProvider the object used to access the types from the core libra ry
2205 */
2206 ScopedVisitor(Library library, Source source, TypeProvider typeProvider) {
2207 this._definingLibrary = library.libraryElement;
2208 this._source = source;
2209 LibraryScope libraryScope2 = library.libraryScope;
2210 this._errorListener = libraryScope2.errorListener;
2211 this._nameScope = libraryScope2;
2212 this._typeProvider = typeProvider;
2213 }
2214 /**
2215 * Return the library element for the library containing the compilation unit being resolved.
2216 * @return the library element for the library containing the compilation unit being resolved
2217 */
2218 LibraryElement get definingLibrary => _definingLibrary;
2219 /**
2220 * Return the object used to access the types from the core library.
2221 * @return the object used to access the types from the core library
2222 */
2223 TypeProvider get typeProvider => _typeProvider;
2224 Object visitBlock(Block node) {
2225 Scope outerScope = _nameScope;
2226 _nameScope = new EnclosedScope(_nameScope);
2227 try {
2228 super.visitBlock(node);
2229 } finally {
2230 _nameScope = outerScope;
2231 }
2232 return null;
2233 }
2234 Object visitClassDeclaration(ClassDeclaration node) {
2235 Scope outerScope = _nameScope;
2236 try {
2237 _nameScope = new ClassScope(_nameScope, node.element);
2238 super.visitClassDeclaration(node);
2239 } finally {
2240 _nameScope = outerScope;
2241 }
2242 return null;
2243 }
2244 Object visitClassTypeAlias(ClassTypeAlias node) {
2245 Scope outerScope = _nameScope;
2246 try {
2247 _nameScope = new ClassScope(_nameScope, node.element);
2248 super.visitClassTypeAlias(node);
2249 } finally {
2250 _nameScope = outerScope;
2251 }
2252 return null;
2253 }
2254 Object visitConstructorDeclaration(ConstructorDeclaration node) {
2255 Scope outerScope = _nameScope;
2256 try {
2257 _nameScope = new FunctionScope(_nameScope, node.element);
2258 super.visitConstructorDeclaration(node);
2259 } finally {
2260 _nameScope = outerScope;
2261 }
2262 return null;
2263 }
2264 Object visitDoStatement(DoStatement node) {
2265 LabelScope outerScope = _labelScope;
2266 _labelScope = new LabelScope.con1(outerScope, false, false);
2267 try {
2268 super.visitDoStatement(node);
2269 } finally {
2270 _labelScope = outerScope;
2271 }
2272 return null;
2273 }
2274 Object visitForEachStatement(ForEachStatement node) {
2275 LabelScope outerScope = _labelScope;
2276 _labelScope = new LabelScope.con1(outerScope, false, false);
2277 try {
2278 super.visitForEachStatement(node);
2279 } finally {
2280 _labelScope = outerScope;
2281 }
2282 return null;
2283 }
2284 Object visitForStatement(ForStatement node) {
2285 LabelScope outerScope = _labelScope;
2286 _labelScope = new LabelScope.con1(outerScope, false, false);
2287 try {
2288 super.visitForStatement(node);
2289 } finally {
2290 _labelScope = outerScope;
2291 }
2292 return null;
2293 }
2294 Object visitFunctionDeclaration(FunctionDeclaration node) {
2295 FunctionElement function = node.element;
2296 Scope outerScope = _nameScope;
2297 try {
2298 _nameScope = new FunctionScope(_nameScope, function);
2299 super.visitFunctionDeclaration(node);
2300 } finally {
2301 _nameScope = outerScope;
2302 }
2303 _nameScope.define(function);
2304 return null;
2305 }
2306 Object visitFunctionExpression(FunctionExpression node) {
2307 Scope outerScope = _nameScope;
2308 try {
2309 _nameScope = new FunctionScope(_nameScope, node.element);
2310 super.visitFunctionExpression(node);
2311 } finally {
2312 _nameScope = outerScope;
2313 }
2314 return null;
2315 }
2316 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
2317 Scope outerScope = _nameScope;
2318 try {
2319 _nameScope = new FunctionTypeScope(_nameScope, node.element);
2320 super.visitFunctionTypeAlias(node);
2321 } finally {
2322 _nameScope = outerScope;
2323 }
2324 return null;
2325 }
2326 Object visitLabeledStatement(LabeledStatement node) {
2327 LabelScope outerScope = addScopesFor(node.labels);
2328 try {
2329 super.visitLabeledStatement(node);
2330 } finally {
2331 _labelScope = outerScope;
2332 }
2333 return null;
2334 }
2335 Object visitMethodDeclaration(MethodDeclaration node) {
2336 Scope outerScope = _nameScope;
2337 try {
2338 _nameScope = new FunctionScope(_nameScope, node.element);
2339 super.visitMethodDeclaration(node);
2340 } finally {
2341 _nameScope = outerScope;
2342 }
2343 return null;
2344 }
2345 Object visitSwitchCase(SwitchCase node) {
2346 node.expression.accept(this);
2347 LabelScope outerLabelScope = addScopesFor(node.labels);
2348 Scope outerNameScope = _nameScope;
2349 _nameScope = new EnclosedScope(_nameScope);
2350 try {
2351 node.statements.accept(this);
2352 } finally {
2353 _nameScope = outerNameScope;
2354 _labelScope = outerLabelScope;
2355 }
2356 return null;
2357 }
2358 Object visitSwitchDefault(SwitchDefault node) {
2359 LabelScope outerLabelScope = addScopesFor(node.labels);
2360 Scope outerNameScope = _nameScope;
2361 _nameScope = new EnclosedScope(_nameScope);
2362 try {
2363 node.statements.accept(this);
2364 } finally {
2365 _nameScope = outerNameScope;
2366 _labelScope = outerLabelScope;
2367 }
2368 return null;
2369 }
2370 Object visitSwitchStatement(SwitchStatement node) {
2371 LabelScope outerScope = _labelScope;
2372 _labelScope = new LabelScope.con1(outerScope, true, false);
2373 for (SwitchMember member in node.members) {
2374 for (Label label in member.labels) {
2375 SimpleIdentifier labelName = label.label;
2376 LabelElement labelElement = (labelName.element as LabelElement);
2377 _labelScope = new LabelScope.con2(outerScope, labelName.name, labelEleme nt);
2378 }
2379 }
2380 try {
2381 super.visitSwitchStatement(node);
2382 } finally {
2383 _labelScope = outerScope;
2384 }
2385 return null;
2386 }
2387 Object visitVariableDeclaration(VariableDeclaration node) {
2388 if (node.parent.parent is! TopLevelVariableDeclaration) {
2389 VariableElement element19 = node.element;
2390 if (element19 != null) {
2391 _nameScope.define(element19);
2392 }
2393 }
2394 super.visitVariableDeclaration(node);
2395 return null;
2396 }
2397 Object visitWhileStatement(WhileStatement node) {
2398 LabelScope outerScope = _labelScope;
2399 _labelScope = new LabelScope.con1(outerScope, false, false);
2400 try {
2401 super.visitWhileStatement(node);
2402 } finally {
2403 _labelScope = outerScope;
2404 }
2405 return null;
2406 }
2407 /**
2408 * Return the label scope in which the current node is being resolved.
2409 * @return the label scope in which the current node is being resolved
2410 */
2411 LabelScope get labelScope => _labelScope;
2412 /**
2413 * Return the name scope in which the current node is being resolved.
2414 * @return the name scope in which the current node is being resolved
2415 */
2416 Scope get nameScope => _nameScope;
2417 /**
2418 * Report an error with the given error code and arguments.
2419 * @param errorCode the error code of the error to be reported
2420 * @param node the node specifying the location of the error
2421 * @param arguments the arguments to the error, used to compose the error mess age
2422 */
2423 void reportError(ResolverErrorCode errorCode, ASTNode node, List<Object> argum ents) {
2424 _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.len gth, errorCode, [arguments]));
2425 }
2426 /**
2427 * Report an error with the given error code and arguments.
2428 * @param errorCode the error code of the error to be reported
2429 * @param token the token specifying the location of the error
2430 * @param arguments the arguments to the error, used to compose the error mess age
2431 */
2432 void reportError2(ResolverErrorCode errorCode, Token token, List<Object> argum ents) {
2433 _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.l ength, errorCode, [arguments]));
2434 }
2435 /**
2436 * Add scopes for each of the given labels.
2437 * @param labels the labels for which new scopes are to be added
2438 * @return the scope that was in effect before the new scopes were added
2439 */
2440 LabelScope addScopesFor(NodeList<Label> labels) {
2441 LabelScope outerScope = _labelScope;
2442 for (Label label in labels) {
2443 SimpleIdentifier labelNameNode = label.label;
2444 String labelName = labelNameNode.name;
2445 LabelElement labelElement = (labelNameNode.element as LabelElement);
2446 _labelScope = new LabelScope.con2(_labelScope, labelName, labelElement);
2447 }
2448 return outerScope;
2449 }
2450 }
2451 /**
2452 * Instances of the class {@code StaticTypeAnalyzer} perform two type-related ta sks. First, they
2453 * compute the static type of every expression. Second, they look for any static type errors or
2454 * warnings that might need to be generated. The requirements for the type analy zer are:
2455 * <ol>
2456 * <li>Every element that refers to types should be fully populated.
2457 * <li>Every node representing an expression should be resolved to the Type of t he expression.</li>
2458 * </ol>
2459 */
2460 class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
2461 /**
2462 * The resolver driving this participant.
2463 */
2464 ResolverVisitor _resolver;
2465 /**
2466 * The object providing access to the types defined by the language.
2467 */
2468 TypeProvider _typeProvider;
2469 /**
2470 * The type representing the class containing the nodes being analyzed, or {@c ode null} if the
2471 * nodes are not within a class.
2472 */
2473 InterfaceType _thisType;
2474 /**
2475 * Initialize a newly created type analyzer.
2476 * @param resolver the resolver driving this participant
2477 */
2478 StaticTypeAnalyzer(ResolverVisitor resolver) {
2479 this._resolver = resolver;
2480 _typeProvider = resolver.typeProvider;
2481 }
2482 /**
2483 * Set the type of the class being analyzed to the given type.
2484 * @param thisType the type representing the class containing the nodes being analyzed
2485 */
2486 void set thisType(InterfaceType thisType2) {
2487 this._thisType = thisType2;
2488 }
2489 /**
2490 * The Dart Language Specification, 12.5: <blockquote>The static type of a str ing literal is{@code String}.</blockquote>
2491 */
2492 Object visitAdjacentStrings(AdjacentStrings node) => recordType(node, _typePro vider.stringType);
2493 /**
2494 * The Dart Language Specification, 12.33: <blockquote>The static type of an a rgument definition
2495 * test is {@code bool}.</blockquote>
2496 */
2497 Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) => recordType( node, _typeProvider.boolType);
2498 /**
2499 * The Dart Language Specification, 12.32: <blockquote>... the cast expression <i>e as T</i> ...
2500 * <p>
2501 * It is a static warning if <i>T</i> does not denote a type available in the current lexical
2502 * scope.
2503 * <p>
2504 * The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote >
2505 */
2506 Object visitAsExpression(AsExpression node) => recordType(node, getType2(node. type));
2507 /**
2508 * The Dart Language Specification, 12.18: <blockquote> ... an assignment <i>a </i> of the form
2509 * <i>v = e</i> ...
2510 * <p>
2511 * It is a static type warning if the static type of <i>e</i> may not be assig ned to the static
2512 * type of <i>v</i>.
2513 * <p>
2514 * The static type of the expression <i>v = e</i> is the static type of <i>e</ i>.
2515 * <p>
2516 * ... an assignment of the form <i>C.v = e</i> ...
2517 * <p>
2518 * It is a static type warning if the static type of <i>e</i> may not be assig ned to the static
2519 * type of <i>C.v</i>.
2520 * <p>
2521 * The static type of the expression <i>C.v = e</i> is the static type of <i>e </i>.
2522 * <p>
2523 * ... an assignment of the form <i>e<sub>1</sub>.v = e<sub>2</sub></i> ...
2524 * <p>
2525 * Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static typ e warning if
2526 * <i>T</i> does not have an accessible instance setter named <i>v=</i>. It is a static type
2527 * warning if the static type of <i>e<sub>2</sub></i> may not be assigned to < i>T</i>.
2528 * <p>
2529 * The static type of the expression <i>e<sub>1</sub>.v = e<sub>2</sub></i> is the static type of
2530 * <i>e<sub>2</sub></i>.
2531 * <p>
2532 * ... an assignment of the form <i>e<sub>1</sub>[e<sub>2</sub>] = e<sub>3</su b></i> ...
2533 * <p>
2534 * The static type of the expression <i>e<sub>1</sub>[e<sub>2</sub>] = e<sub>3 </sub></i> is the
2535 * static type of <i>e<sub>3</sub></i>.
2536 * <p>
2537 * A compound assignment of the form <i>v op= e</i> is equivalent to <i>v = v op e</i>. A compound
2538 * assignment of the form <i>C.v op= e</i> is equivalent to <i>C.v = C.v op e< /i>. A compound
2539 * assignment of the form <i>e<sub>1</sub>.v op= e<sub>2</sub></i> is equivale nt to <i>((x) => x.v
2540 * = 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
2541 * <i>e<sub>2</sub></i>. A compound assignment of the form <i>e<sub>1</sub>[e< sub>2</sub>] op=
2542 * e<sub>3</sub></i> is equivalent to <i>((a, i) => a[i] = a[i] op e<sub>3</su b>)(e<sub>1</sub>,
2543 * e<sub>2</sub>)</i> where <i>a</i> and <i>i</i> are a variables that are not used in
2544 * <i>e<sub>3</sub></i>. </blockquote>
2545 */
2546 Object visitAssignmentExpression(AssignmentExpression node) {
2547 TokenType operator11 = node.operator.type;
2548 if (operator11 != TokenType.EQ) {
2549 return recordReturnType(node, node.element);
2550 }
2551 Type2 leftType = getType(node.leftHandSide);
2552 Type2 rightType = getType(node.rightHandSide);
2553 if (!rightType.isAssignableTo(leftType)) {
2554 }
2555 return recordType(node, rightType);
2556 }
2557 /**
2558 * The Dart Language Specification, 12.20: <blockquote>The static type of a lo gical boolean
2559 * expression is {@code bool}.</blockquote>
2560 * <p>
2561 * The Dart Language Specification, 12.21:<blockquote>A bitwise expression of the form
2562 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n
2563 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A bitwise expression of the form <i >super op
2564 * e<sub>2</sub></i> is equivalent to the method invocation
2565 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
2566 * <p>
2567 * The Dart Language Specification, 12.22: <blockquote>The static type of an e quality expression
2568 * is {@code bool}.</blockquote>
2569 * <p>
2570 * The Dart Language Specification, 12.23: <blockquote>A relational expression of the form
2571 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n
2572 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A relational expression of the form <i>super op
2573 * e<sub>2</sub></i> is equivalent to the method invocation
2574 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
2575 * <p>
2576 * The Dart Language Specification, 12.24: <blockquote>A shift expression of t he form
2577 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n
2578 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A shift expression of the form <i>s uper op
2579 * e<sub>2</sub></i> is equivalent to the method invocation
2580 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
2581 * <p>
2582 * The Dart Language Specification, 12.25: <blockquote>An additive expression of the form
2583 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n
2584 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. An additive expression of the form <i>super op
2585 * e<sub>2</sub></i> is equivalent to the method invocation
2586 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
2587 * <p>
2588 * The Dart Language Specification, 12.26: <blockquote>A multiplicative expres sion of the form
2589 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n
2590 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A multiplicative expression of the form <i>super op
2591 * e<sub>2</sub></i> is equivalent to the method invocation
2592 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
2593 */
2594 Object visitBinaryExpression(BinaryExpression node) {
2595 TokenType operator12 = node.operator.type;
2596 if (operator12 == TokenType.AMPERSAND_AMPERSAND || operator12 == TokenType.B AR_BAR || operator12 == TokenType.EQ_EQ || operator12 == TokenType.BANG_EQ) {
2597 return recordType(node, _typeProvider.boolType);
2598 }
2599 return recordReturnType(node, node.element);
2600 }
2601 /**
2602 * The Dart Language Specification, 12.4: <blockquote>The static type of a boo lean literal is{@code bool}.</blockquote>
2603 */
2604 Object visitBooleanLiteral(BooleanLiteral node) => recordType(node, _typeProvi der.boolType);
2605 /**
2606 * The Dart Language Specification, 12.15.2: <blockquote>A cascaded method inv ocation expression
2607 * of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suff ix; return
2608 * t;}(e)</i>.</blockquote>
2609 */
2610 Object visitCascadeExpression(CascadeExpression node) => recordType(node, getT ype(node.target));
2611 /**
2612 * The Dart Language Specification, 12.19: <blockquote> ... a conditional expr ession <i>c</i> of
2613 * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ...
2614 * <p>
2615 * It is a static type warning if the type of e<sub>1</sub> may not be assigne d to {@code bool}.
2616 * <p>
2617 * The static type of <i>c</i> is the least upper bound of the static type of <i>e<sub>2</sub></i>
2618 * and the static type of <i>e<sub>3</sub></i>.</blockquote>
2619 */
2620 Object visitConditionalExpression(ConditionalExpression node) {
2621 Type2 conditionType = getType(node.condition);
2622 if (conditionType != null && !conditionType.isAssignableTo(_typeProvider.boo lType)) {
2623 _resolver.reportError(ResolverErrorCode.NON_BOOLEAN_CONDITION, node.condit ion, []);
2624 }
2625 Type2 thenType = getType(node.thenExpression);
2626 Type2 elseType = getType(node.elseExpression);
2627 if (thenType == null) {
2628 return recordType(node, _typeProvider.dynamicType);
2629 }
2630 Type2 resultType = thenType.getLeastUpperBound(elseType);
2631 return recordType(node, resultType);
2632 }
2633 /**
2634 * The Dart Language Specification, 12.3: <blockquote>The static type of a lit eral double is{@code double}.</blockquote>
2635 */
2636 Object visitDoubleLiteral(DoubleLiteral node) => recordType(node, _typeProvide r.doubleType);
2637 /**
2638 * The Dart Language Specification, 12.9: <blockquote>The static type of a fun ction literal of the
2639 * form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;, T<sub>n</sub> a<sub>n</sub> , [T<sub>n+1</sub>
2640 * x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub> = dk]) => e </i> is
2641 * <i>(T<sub>1</sub>, &hellip;, Tn, [T<sub>n+1</sub> x<sub>n+1</sub>, &hellip; , T<sub>n+k</sub>
2642 * x<sub>n+k</sub>]) &rarr; T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is t he static type of
2643 * <i>e</i>. In any case where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is
2644 * considered to have been specified as dynamic.
2645 * <p>
2646 * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1 </sub>, &hellip;,
2647 * T<sub>n</sub> a<sub>n</sub>, {T<sub>n+1</sub> x<sub>n+1</sub> : d1, &hellip ;, T<sub>n+k</sub>
2648 * x<sub>n+k</sub> : dk}) => e</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</su b>, {T<sub>n+1</sub>
2649 * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; T<sub>0 </sub></i>, where
2650 * <i>T<sub>0</sub></i> is the static type of <i>e</i>. In any case where <i>T <sub>i</sub>, 1
2651 * &lt;= i &lt;= n</i>, is not specified, it is considered to have been specif ied as dynamic.
2652 * <p>
2653 * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1 </sub>, &hellip;,
2654 * T<sub>n</sub> a<sub>n</sub>, [T<sub>n+1</sub> x<sub>n+1</sub> = d1, &hellip ;, T<sub>n+k</sub>
2655 * x<sub>n+k</sub> = dk]) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub >, [T<sub>n+1</sub>
2656 * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>]) &rarr; dynamic </i>. In any case
2657 * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is cons idered to have been
2658 * specified as dynamic.
2659 * <p>
2660 * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1 </sub>, &hellip;,
2661 * T<sub>n</sub> a<sub>n</sub>, {T<sub>n+1</sub> x<sub>n+1</sub> : d1, &hellip ;, T<sub>n+k</sub>
2662 * x<sub>n+k</sub> : dk}) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub >, {T<sub>n+1</sub>
2663 * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; dynamic </i>. In any case
2664 * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is cons idered to have been
2665 * specified as dynamic.</blockquote>
2666 */
2667 Object visitFunctionExpression(FunctionExpression node) {
2668 FunctionTypeImpl functionType = (node.element.type as FunctionTypeImpl);
2669 setTypeInformation(functionType, computeReturnType(node), node.parameters);
2670 return recordType(node, functionType);
2671 }
2672 /**
2673 * The Dart Language Specification, 12.14.4: <blockquote>A function expression invocation <i>i</i>
2674 * has the form <i>e<sub>f</sub>(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub >n+1</sub>:
2675 * a<sub>n+1</sub>, &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>, where <i> e<sub>f</sub></i> is
2676 * an expression.
2677 * <p>
2678 * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub> </i> may not be
2679 * assigned to a function type.
2680 * <p>
2681 * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic. Otherwise the
2682 * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquot e>
2683 */
2684 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => recordReturnType(node, node.element);
2685 /**
2686 * The Dart Language Specification, 12.29: <blockquote>An assignable expressio n of the form
2687 * <i>e<sub>1</sub>[e<sub>2</sub>]</i> is evaluated as a method invocation of the operator method
2688 * <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</bloc kquote>
2689 */
2690 Object visitIndexExpression(IndexExpression node) => recordReturnType(node, no de.element);
2691 /**
2692 * The Dart Language Specification, 12.11.1: <blockquote>The static type of a new expression of
2693 * either the form <i>new T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the form <i>new
2694 * T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>.</blockquote>
2695 * <p>
2696 * The Dart Language Specification, 12.11.2: <blockquote>The static type of a constant object
2697 * expression of either the form <i>const T.id(a<sub>1</sub>, &hellip;, a<sub> n</sub>)</i> or the
2698 * form <i>const T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>. </ blockquote>
2699 */
2700 Object visitInstanceCreationExpression(InstanceCreationExpression node) => rec ordReturnType(node, node.element);
2701 /**
2702 * The Dart Language Specification, 12.3: <blockquote>The static type of an in teger literal is{@code int}.</blockquote>
2703 */
2704 Object visitIntegerLiteral(IntegerLiteral node) => recordType(node, _typeProvi der.intType);
2705 /**
2706 * The Dart Language Specification, 12.31: <blockquote>It is a static warning if <i>T</i> does not
2707 * denote a type available in the current lexical scope.
2708 * <p>
2709 * The static type of an is-expression is {@code bool}.</blockquote>
2710 */
2711 Object visitIsExpression(IsExpression node) => recordType(node, _typeProvider. boolType);
2712 /**
2713 * The Dart Language Specification, 12.6: <blockquote>The static type of a lis t literal of the
2714 * form <i><b>const</b> &lt;E&gt;[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> or the form
2715 * <i>&lt;E&gt;[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> is {@code List&lt; E&gt;}. The static
2716 * type a list literal of the form <i><b>const</b> [e<sub>1</sub>, &hellip;, e <sub>n</sub>]</i> or
2717 * the form <i>[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> is {@code List&lt; dynamic&gt;}.</blockquote>
2718 */
2719 Object visitListLiteral(ListLiteral node) {
2720 TypeArgumentList typeArguments8 = node.typeArguments;
2721 if (typeArguments8 != null) {
2722 NodeList<TypeName> arguments3 = typeArguments8.arguments;
2723 if (arguments3 != null && arguments3.length == 1) {
2724 TypeName argumentType = arguments3[0];
2725 return recordType(node, _typeProvider.listType.substitute5(<Type2> [getT ype2(argumentType)]));
2726 }
2727 }
2728 return recordType(node, _typeProvider.listType.substitute5(<Type2> [_typePro vider.dynamicType]));
2729 }
2730 /**
2731 * The Dart Language Specification, 12.7: <blockquote>The static type of a map literal of the form
2732 * <i><b>const</b> &lt;String, V&gt; {k<sub>1</sub>:e<sub>1</sub>, &hellip;,
2733 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>&lt;String, V&gt; {k<sub>1< /sub>:e<sub>1</sub>,
2734 * &hellip;, k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map&lt;String, V&gt;}. The static type a
2735 * map literal of the form <i><b>const</b> {k<sub>1</sub>:e<sub>1</sub>, &hell ip;,
2736 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>{k<sub>1</sub>:e<sub>1</sub >, &hellip;,
2737 * k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map&lt;String, dynamic&gt;}.
2738 * <p>
2739 * It is a compile-time error if the first type argument to a map literal is n ot
2740 * <i>String</i>.</blockquote>
2741 */
2742 Object visitMapLiteral(MapLiteral node) {
2743 TypeArgumentList typeArguments9 = node.typeArguments;
2744 if (typeArguments9 != null) {
2745 NodeList<TypeName> arguments4 = typeArguments9.arguments;
2746 if (arguments4 != null && arguments4.length == 2) {
2747 TypeName keyType = arguments4[0];
2748 if (keyType != _typeProvider.stringType) {
2749 }
2750 TypeName valueType = arguments4[1];
2751 return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_type Provider.stringType, getType2(valueType)]));
2752 }
2753 }
2754 return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_typeProv ider.stringType, _typeProvider.dynamicType]));
2755 }
2756 /**
2757 * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method in vocation <i>i</i>
2758 * has the form <i>o.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub> : a<sub>n+1</sub>,
2759 * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
2760 * <p>
2761 * Let <i>T</i> be the static type of <i>o</i>. It is a static type warning if <i>T</i> does not
2762 * have an accessible instance member named <i>m</i>. If <i>T.m</i> exists, it is a static warning
2763 * if the type <i>F</i> of <i>T.m</i> may not be assigned to a function type.
2764 * <p>
2765 * If <i>T.m</i> does not exist, or if <i>F</i> is not a function type, the st atic type of
2766 * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
2767 * <i>F</i>.</blockquote>
2768 * <p>
2769 * The Dart Language Specification, 11.15.3: <blockquote>A static method invoc ation <i>i</i> has
2770 * the form <i>C.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a< sub>n+1</sub>,
2771 * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
2772 * <p>
2773 * It is a static type warning if the type <i>F</i> of <i>C.m</i> may not be a ssigned to a
2774 * function type.
2775 * <p>
2776 * If <i>F</i> is not a function type, or if <i>C.m</i> does not exist, the st atic type of i is
2777 * dynamic. Otherwise the static type of <i>i</i> is the declared return type of
2778 * <i>F</i>.</blockquote>
2779 * <p>
2780 * The Dart Language Specification, 11.15.4: <blockquote>A super method invoca tion <i>i</i> has
2781 * the form <i>super.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub> : a<sub>n+1</sub>,
2782 * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
2783 * <p>
2784 * It is a static type warning if <i>S</i> does not have an accessible instanc e member named m. If
2785 * <i>S.m</i> exists, it is a static warning if the type <i>F</i> of <i>S.m</i > may not be
2786 * assigned to a function type.
2787 * <p>
2788 * If <i>S.m</i> does not exist, or if <i>F</i> is not a function type, the st atic type of
2789 * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
2790 * <i>F</i>.</blockquote>
2791 */
2792 Object visitMethodInvocation(MethodInvocation node) => recordReturnType(node, node.methodName.element);
2793 Object visitNamedExpression(NamedExpression node) => recordType(node, getType( node.expression));
2794 /**
2795 * The Dart Language Specification, 12.2: <blockquote>The static type of {@cod e null} is bottom.
2796 * </blockquote>
2797 */
2798 Object visitNullLiteral(NullLiteral node) => recordType(node, _typeProvider.bo ttomType);
2799 Object visitParenthesizedExpression(ParenthesizedExpression node) => recordTyp e(node, getType(node.expression));
2800 /**
2801 * The Dart Language Specification, 12.28: <blockquote>A postfix expression of the form
2802 * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r = v; v = r + 1;
2803 * return r}()</i>.
2804 * <p>
2805 * A postfix expression of the form <i>C.v++</i> is equivalent to <i>(){var r = C.v; C.v = r + 1;
2806 * return r}()</i>.
2807 * <p>
2808 * A postfix expression of the form <i>e1.v++</i> is equivalent to <i>(x){var r = x.v; x.v = r +
2809 * 1; return r}(e1)</i>.
2810 * <p>
2811 * A postfix expression of the form <i>e1[e2]++</i> is equivalent to <i>(a, i) {var r = a[i]; a[i]
2812 * = r + 1; return r}(e1, e2)</i>
2813 * <p>
2814 * A postfix expression of the form <i>v--</i>, where <i>v</i> is an identifie r, is equivalent to
2815 * <i>(){var r = v; v = r - 1; return r}()</i>.
2816 * <p>
2817 * A postfix expression of the form <i>C.v--</i> is equivalent to <i>(){var r = C.v; C.v = r - 1;
2818 * return r}()</i>.
2819 * <p>
2820 * A postfix expression of the form <i>e1.v--</i> is equivalent to <i>(x){var r = x.v; x.v = r -
2821 * 1; return r}(e1)</i>.
2822 * <p>
2823 * A postfix expression of the form <i>e1[e2]--</i> is equivalent to <i>(a, i) {var r = a[i]; a[i]
2824 * = r - 1; return r}(e1, e2)</i></blockquote>
2825 */
2826 Object visitPostfixExpression(PostfixExpression node) => recordType(node, getT ype(node.operand));
2827 /**
2828 * See {@link #visitSimpleIdentifier(SimpleIdentifier)}.
2829 */
2830 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
2831 SimpleIdentifier prefixedIdentifier = node.identifier;
2832 Element element20 = prefixedIdentifier.element;
2833 if (element20 is VariableElement) {
2834 Type2 variableType = ((element20 as VariableElement)).type;
2835 recordType(prefixedIdentifier, variableType);
2836 return recordType(node, variableType);
2837 } else if (element20 is PropertyAccessorElement) {
2838 Type2 propertyType = ((element20 as PropertyAccessorElement)).type.returnT ype;
2839 recordType(prefixedIdentifier, propertyType);
2840 return recordType(node, propertyType);
2841 } else if (element20 is MethodElement) {
2842 Type2 returnType = ((element20 as MethodElement)).type;
2843 recordType(prefixedIdentifier, returnType);
2844 return recordType(node, returnType);
2845 } else {
2846 }
2847 recordType(prefixedIdentifier, _typeProvider.dynamicType);
2848 return recordType(node, _typeProvider.dynamicType);
2849 }
2850 /**
2851 * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u </i> of the form
2852 * <i>op e</i> is equivalent to a method invocation <i>expression e.op()</i>. An expression of the
2853 * form <i>op super</i> is equivalent to the method invocation <i>super.op()<i >.</blockquote>
2854 */
2855 Object visitPrefixExpression(PrefixExpression node) {
2856 TokenType operator13 = node.operator.type;
2857 if (identical(operator13, TokenType.BANG)) {
2858 return recordType(node, _typeProvider.boolType);
2859 }
2860 return recordReturnType(node, node.element);
2861 }
2862 /**
2863 * The Dart Language Specification, 12.13: <blockquote> Property extraction al lows for a member of
2864 * an object to be concisely extracted from the object. If <i>o</i> is an obje ct, and if <i>m</i>
2865 * is the name of a method member of <i>o</i>, then
2866 * <ul>
2867 * <li><i>o.m</i> is defined to be equivalent to: <i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
2868 * {p<sub>1</sub> : d<sub>1</sub>, &hellip;, p<sub>k</sub> : d<sub>k</sub>}){r eturn
2869 * o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>, p<sub>1</sub>: p<sub>1</sub>, & hellip;,
2870 * p<sub>k</sub>: p<sub>k</sub>);}</i> if <i>m</i> has required parameters <i> r<sub>1</sub>,
2871 * &hellip;, r<sub>n</sub></i>, and named parameters <i>p<sub>1</sub> &hellip; p<sub>k</sub></i>
2872 * with defaults <i>d<sub>1</sub>, &hellip;, d<sub>k</sub></i>.</li>
2873 * <li><i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>, [p<sub>1</sub> = d<sub>1</s ub>, &hellip;,
2874 * p<sub>k</sub> = d<sub>k</sub>]){return o.m(r<sub>1</sub>, &hellip;, r<sub>n </sub>,
2875 * p<sub>1</sub>, &hellip;, p<sub>k</sub>);}</i> if <i>m</i> has required para meters
2876 * <i>r<sub>1</sub>, &hellip;, r<sub>n</sub></i>, and optional positional para meters
2877 * <i>p<sub>1</sub> &hellip; p<sub>k</sub></i> with defaults <i>d<sub>1</sub>, &hellip;,
2878 * d<sub>k</sub></i>.</li>
2879 * </ul>
2880 * Otherwise, if <i>m</i> is the name of a getter member of <i>o</i> (declared implicitly or
2881 * explicitly) then <i>o.m</i> evaluates to the result of invoking the getter. </blockquote>
2882 * <p>
2883 * The Dart Language Specification, 12.17: <blockquote> ... a getter invocatio n <i>i</i> of the
2884 * form <i>e.m</i> ...
2885 * <p>
2886 * Let <i>T</i> be the static type of <i>e</i>. It is a static type warning if <i>T</i> does not
2887 * have a getter named <i>m</i>.
2888 * <p>
2889 * The static type of <i>i</i> is the declared return type of <i>T.m</i>, if < i>T.m</i> exists;
2890 * otherwise the static type of <i>i</i> is dynamic.
2891 * <p>
2892 * ... a getter invocation <i>i</i> of the form <i>C.m</i> ...
2893 * <p>
2894 * It is a static warning if there is no class <i>C</i> in the enclosing lexic al scope of
2895 * <i>i</i>, or if <i>C</i> does not declare, implicitly or explicitly, a gett er named <i>m</i>.
2896 * <p>
2897 * The static type of <i>i</i> is the declared return type of <i>C.m</i> if it exists or dynamic
2898 * otherwise.
2899 * <p>
2900 * ... a top-level getter invocation <i>i</i> of the form <i>m</i>, where <i>m </i> is an
2901 * identifier ...
2902 * <p>
2903 * The static type of <i>i</i> is the declared return type of <i>m</i>.</block quote>
2904 */
2905 Object visitPropertyAccess(PropertyAccess node) {
2906 SimpleIdentifier propertyName2 = node.propertyName;
2907 Element element21 = propertyName2.element;
2908 if (element21 is MethodElement) {
2909 FunctionType type11 = ((element21 as MethodElement)).type;
2910 recordType(propertyName2, type11);
2911 return recordType(node, type11);
2912 } else if (element21 is PropertyAccessorElement) {
2913 PropertyAccessorElement accessor = (element21 as PropertyAccessorElement);
2914 if (accessor.isGetter()) {
2915 if (accessor.type == null) {
2916 recordType(propertyName2, _typeProvider.dynamicType);
2917 return recordType(node, _typeProvider.dynamicType);
2918 }
2919 Type2 returnType4 = accessor.type.returnType;
2920 recordType(propertyName2, returnType4);
2921 return recordType(node, returnType4);
2922 } else {
2923 recordType(propertyName2, VoidTypeImpl.instance);
2924 return recordType(node, VoidTypeImpl.instance);
2925 }
2926 } else {
2927 }
2928 recordType(propertyName2, _typeProvider.dynamicType);
2929 return recordType(node, _typeProvider.dynamicType);
2930 }
2931 /**
2932 * The Dart Language Specification, 12.30: <blockquote>Evaluation of an identi fier expression
2933 * <i>e</i> of the form <i>id</i> proceeds as follows:
2934 * <p>
2935 * Let <i>d</i> be the innermost declaration in the enclosing lexical scope wh ose name is
2936 * <i>id</i>. If no such declaration exists in the lexical scope, let <i>d</i> be the declaration
2937 * of the inherited member named <i>id</i> if it exists.
2938 * <ul>
2939 * <li>If <i>d</i> is a class or type alias <i>T</i>, the value of <i>e</i> is the unique instance
2940 * of class {@code Type} reifying <i>T</i>.
2941 * <li>If <i>d</i> is a type parameter <i>T</i>, then the value of <i>e</i> is the value of the
2942 * actual type argument corresponding to <i>T</i> that was passed to the gener ative constructor
2943 * that created the current binding of this. We are assured that this is well defined, because if
2944 * we were in a static member the reference to <i>T</i> would be a compile-tim e error.
2945 * <li>If <i>d</i> is a library variable then:
2946 * <ul>
2947 * <li>If <i>d</i> is of one of the forms <i>var v = e<sub>i</sub>;</i>, <i>T v =
2948 * e<sub>i</sub>;</i>, <i>final v = e<sub>i</sub>;</i>, <i>final T v = e<sub>i </sub>;</i>, and no
2949 * value has yet been stored into <i>v</i> then the initializer expression <i> e<sub>i</sub></i> is
2950 * evaluated. If, during the evaluation of <i>e<sub>i</sub></i>, the getter fo r <i>v</i> is
2951 * referenced, a CyclicInitializationError is thrown. If the evaluation succee ded yielding an
2952 * object <i>o</i>, let <i>r = o</i>, otherwise let <i>r = null</i>. In any ca se, <i>r</i> is
2953 * stored into <i>v</i>. The value of <i>e</i> is <i>r</i>.
2954 * <li>If <i>d</i> is of one of the forms <i>const v = e;</i> or <i>const T v = e;</i> the result
2955 * of the getter is the value of the compile time constant <i>e</i>. Otherwise
2956 * <li><i>e</i> evaluates to the current binding of <i>id</i>.
2957 * </ul>
2958 * <li>If <i>d</i> is a local variable or formal parameter then <i>e</i> evalu ates to the current
2959 * binding of <i>id</i>.
2960 * <li>If <i>d</i> is a static method, top level function or local function th en <i>e</i>
2961 * evaluates to the function defined by <i>d</i>.
2962 * <li>If <i>d</i> is the declaration of a static variable or static getter de clared in class
2963 * <i>C</i>, then <i>e</i> is equivalent to the getter invocation <i>C.id</i>.
2964 * <li>If <i>d</i> is the declaration of a top level getter, then <i>e</i> is equivalent to the
2965 * getter invocation <i>id</i>.
2966 * <li>Otherwise, if <i>e</i> occurs inside a top level or static function (be it function,
2967 * method, getter, or setter) or variable initializer, evaluation of e causes a NoSuchMethodError
2968 * to be thrown.
2969 * <li>Otherwise <i>e</i> is equivalent to the property extraction <i>this.id< /i>.
2970 * </ul>
2971 * </blockquote>
2972 */
2973 Object visitSimpleIdentifier(SimpleIdentifier node) {
2974 Element element22 = node.element;
2975 if (element22 == null) {
2976 return recordType(node, _typeProvider.dynamicType);
2977 } else if (element22 is ClassElement) {
2978 if (isTypeName(node)) {
2979 return recordType(node, ((element22 as ClassElement)).type);
2980 }
2981 return recordType(node, _typeProvider.typeType);
2982 } else if (element22 is TypeVariableElement) {
2983 return recordType(node, ((element22 as TypeVariableElement)).type);
2984 } else if (element22 is TypeAliasElement) {
2985 return recordType(node, ((element22 as TypeAliasElement)).type);
2986 } else if (element22 is VariableElement) {
2987 return recordType(node, ((element22 as VariableElement)).type);
2988 } else if (element22 is MethodElement) {
2989 return recordType(node, ((element22 as MethodElement)).type);
2990 } else if (element22 is PropertyAccessorElement) {
2991 PropertyAccessorElement accessor = (element22 as PropertyAccessorElement);
2992 if (accessor.isGetter()) {
2993 return recordType(node, accessor.type.returnType);
2994 } else {
2995 return recordType(node, accessor.type.normalParameterTypes[0]);
2996 }
2997 } else if (element22 is ExecutableElement) {
2998 return recordType(node, ((element22 as ExecutableElement)).type);
2999 } else if (element22 is PrefixElement) {
3000 return null;
3001 } else {
3002 return recordType(node, _typeProvider.dynamicType);
3003 }
3004 }
3005 /**
3006 * The Dart Language Specification, 12.5: <blockquote>The static type of a str ing literal is{@code String}.</blockquote>
3007 */
3008 Object visitSimpleStringLiteral(SimpleStringLiteral node) => recordType(node, _typeProvider.stringType);
3009 /**
3010 * The Dart Language Specification, 12.5: <blockquote>The static type of a str ing literal is{@code String}.</blockquote>
3011 */
3012 Object visitStringInterpolation(StringInterpolation node) => recordType(node, _typeProvider.stringType);
3013 Object visitSuperExpression(SuperExpression node) => recordType(node, _thisTyp e == null ? _typeProvider.dynamicType : _thisType.superclass);
3014 /**
3015 * The Dart Language Specification, 12.10: <blockquote>The static type of {@co de this} is the
3016 * interface of the immediately enclosing class.</blockquote>
3017 */
3018 Object visitThisExpression(ThisExpression node) => recordType(node, _thisType) ;
3019 /**
3020 * The Dart Language Specification, 12.8: <blockquote>The static type of a thr ow expression is
3021 * bottom.</blockquote>
3022 */
3023 Object visitThrowExpression(ThrowExpression node) => recordType(node, _typePro vider.bottomType);
3024 /**
3025 * Given a function expression, compute the return type of the function. The r eturn type of
3026 * functions with a block body is {@code dynamicType}, with an expression body it is the type of
3027 * the expression.
3028 * @param node the function expression whose return type is to be computed
3029 * @return the return type that was computed
3030 */
3031 Type2 computeReturnType(FunctionExpression node) {
3032 FunctionBody body4 = node.body;
3033 if (body4 is ExpressionFunctionBody) {
3034 return getType(((body4 as ExpressionFunctionBody)).expression);
3035 }
3036 return _typeProvider.dynamicType;
3037 }
3038 /**
3039 * Return the type of the given expression that is to be used for type analysi s.
3040 * @param expression the expression whose type is to be returned
3041 * @return the type of the given expression
3042 */
3043 Type2 getType(Expression expression) {
3044 Type2 type = expression.staticType;
3045 if (type == null) {
3046 return _typeProvider.dynamicType;
3047 }
3048 return type;
3049 }
3050 /**
3051 * Return the type represented by the given type name.
3052 * @param typeName the type name representing the type to be returned
3053 * @return the type represented by the type name
3054 */
3055 Type2 getType2(TypeName typeName) {
3056 Type2 type12 = typeName.type;
3057 if (type12 == null) {
3058 return _typeProvider.dynamicType;
3059 }
3060 return type12;
3061 }
3062 /**
3063 * Return {@code true} if the given node is being used as the name of a type.
3064 * @param node the node being tested
3065 * @return {@code true} if the given node is being used as the name of a type
3066 */
3067 bool isTypeName(SimpleIdentifier node) {
3068 ASTNode parent8 = node.parent;
3069 return parent8 is TypeName || (parent8 is PrefixedIdentifier && parent8.pare nt is TypeName) || (parent8 is MethodInvocation && identical(node, ((parent8 as MethodInvocation)).target));
3070 }
3071 /**
3072 * Record that the static type of the given node is the return type of the met hod or function
3073 * represented by the given element.
3074 * @param expression the node whose type is to be recorded
3075 * @param element the element representing the method or function invoked by t he given node
3076 */
3077 Object recordReturnType(Expression expression, Element element) {
3078 if (element is ExecutableElement) {
3079 FunctionType type13 = ((element as ExecutableElement)).type;
3080 if (type13 != null) {
3081 return recordType(expression, type13.returnType);
3082 }
3083 } else if (element is VariableElement) {
3084 Type2 variableType = ((element as VariableElement)).type;
3085 if (variableType is FunctionType) {
3086 return recordType(expression, ((variableType as FunctionType)).returnTyp e);
3087 }
3088 }
3089 return recordType(expression, _typeProvider.dynamicType);
3090 }
3091 /**
3092 * Record that the static type of the given node is the given type.
3093 * @param expression the node whose type is to be recorded
3094 * @param type the static type of the node
3095 */
3096 Object recordType(Expression expression, Type2 type) {
3097 if (type == null) {
3098 expression.staticType = _typeProvider.dynamicType;
3099 } else {
3100 expression.staticType = type;
3101 }
3102 return null;
3103 }
3104 /**
3105 * Set the return type and parameter type information for the given function t ype based on the
3106 * given return type and parameter elements.
3107 * @param functionType the function type to be filled in
3108 * @param returnType the return type of the function, or {@code null} if no ty pe was declared
3109 * @param parameters the elements representing the parameters to the function
3110 */
3111 void setTypeInformation(FunctionTypeImpl functionType, Type2 returnType7, Form alParameterList parameterList) {
3112 List<Type2> normalParameterTypes = new List<Type2>();
3113 List<Type2> optionalParameterTypes = new List<Type2>();
3114 LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
3115 if (parameterList != null) {
3116 for (ParameterElement parameter in parameterList.elements) {
3117 if (parameter.parameterKind == ParameterKind.REQUIRED) {
3118 normalParameterTypes.add(parameter.type);
3119 } else if (parameter.parameterKind == ParameterKind.POSITIONAL) {
3120 optionalParameterTypes.add(parameter.type);
3121 } else if (parameter.parameterKind == ParameterKind.NAMED) {
3122 namedParameterTypes[parameter.name] = parameter.type;
3123 }
3124 }
3125 }
3126 functionType.normalParameterTypes = new List.from(normalParameterTypes);
3127 functionType.optionalParameterTypes = new List.from(optionalParameterTypes);
3128 functionType.namedParameterTypes = namedParameterTypes;
3129 functionType.returnType = returnType7;
3130 }
3131 }
3132 /**
3133 * The interface {@code TypeProvider} defines the behavior of objects that provi de access to types
3134 * defined by the language.
3135 */
3136 abstract class TypeProvider {
3137 /**
3138 * Return the type representing the built-in type 'bool'.
3139 * @return the type representing the built-in type 'bool'
3140 */
3141 InterfaceType get boolType;
3142 /**
3143 * Return the type representing the type 'bottom'.
3144 * @return the type representing the type 'bottom'
3145 */
3146 Type2 get bottomType;
3147 /**
3148 * Return the type representing the built-in type 'double'.
3149 * @return the type representing the built-in type 'double'
3150 */
3151 InterfaceType get doubleType;
3152 /**
3153 * Return the type representing the built-in type 'dynamic'.
3154 * @return the type representing the built-in type 'dynamic'
3155 */
3156 Type2 get dynamicType;
3157 /**
3158 * Return the type representing the built-in type 'Function'.
3159 * @return the type representing the built-in type 'Function'
3160 */
3161 InterfaceType get functionType;
3162 /**
3163 * Return the type representing the built-in type 'int'.
3164 * @return the type representing the built-in type 'int'
3165 */
3166 InterfaceType get intType;
3167 /**
3168 * Return the type representing the built-in type 'List'.
3169 * @return the type representing the built-in type 'List'
3170 */
3171 InterfaceType get listType;
3172 /**
3173 * Return the type representing the built-in type 'Map'.
3174 * @return the type representing the built-in type 'Map'
3175 */
3176 InterfaceType get mapType;
3177 /**
3178 * Return the type representing the built-in type 'Object'.
3179 * @return the type representing the built-in type 'Object'
3180 */
3181 InterfaceType get objectType;
3182 /**
3183 * Return the type representing the built-in type 'StackTrace'.
3184 * @return the type representing the built-in type 'StackTrace'
3185 */
3186 InterfaceType get stackTraceType;
3187 /**
3188 * Return the type representing the built-in type 'String'.
3189 * @return the type representing the built-in type 'String'
3190 */
3191 InterfaceType get stringType;
3192 /**
3193 * Return the type representing the built-in type 'Type'.
3194 * @return the type representing the built-in type 'Type'
3195 */
3196 InterfaceType get typeType;
3197 }
3198 /**
3199 * Instances of the class {@code TypeProviderImpl} provide access to types defin ed by the language
3200 * by looking for those types in the element model for the core library.
3201 */
3202 class TypeProviderImpl implements TypeProvider {
3203 /**
3204 * The type representing the built-in type 'bool'.
3205 */
3206 InterfaceType _boolType;
3207 /**
3208 * The type representing the type 'bottom'.
3209 */
3210 Type2 _bottomType;
3211 /**
3212 * The type representing the built-in type 'double'.
3213 */
3214 InterfaceType _doubleType;
3215 /**
3216 * The type representing the built-in type 'dynamic'.
3217 */
3218 Type2 _dynamicType;
3219 /**
3220 * The type representing the built-in type 'Function'.
3221 */
3222 InterfaceType _functionType;
3223 /**
3224 * The type representing the built-in type 'int'.
3225 */
3226 InterfaceType _intType;
3227 /**
3228 * The type representing the built-in type 'List'.
3229 */
3230 InterfaceType _listType;
3231 /**
3232 * The type representing the built-in type 'Map'.
3233 */
3234 InterfaceType _mapType;
3235 /**
3236 * The type representing the built-in type 'Object'.
3237 */
3238 InterfaceType _objectType;
3239 /**
3240 * The type representing the built-in type 'StackTrace'.
3241 */
3242 InterfaceType _stackTraceType;
3243 /**
3244 * The type representing the built-in type 'String'.
3245 */
3246 InterfaceType _stringType;
3247 /**
3248 * The type representing the built-in type 'Type'.
3249 */
3250 InterfaceType _typeType;
3251 /**
3252 * Initialize a newly created type provider to provide the types defined in th e given library.
3253 * @param coreLibrary the element representing the core library (dart:core).
3254 */
3255 TypeProviderImpl(LibraryElement coreLibrary) {
3256 initializeFrom(coreLibrary);
3257 }
3258 InterfaceType get boolType => _boolType;
3259 Type2 get bottomType => _bottomType;
3260 InterfaceType get doubleType => _doubleType;
3261 Type2 get dynamicType => _dynamicType;
3262 InterfaceType get functionType => _functionType;
3263 InterfaceType get intType => _intType;
3264 InterfaceType get listType => _listType;
3265 InterfaceType get mapType => _mapType;
3266 InterfaceType get objectType => _objectType;
3267 InterfaceType get stackTraceType => _stackTraceType;
3268 InterfaceType get stringType => _stringType;
3269 InterfaceType get typeType => _typeType;
3270 /**
3271 * Return the type with the given name from the given namespace, or {@code nul l} if there is no
3272 * class with the given name.
3273 * @param namespace the namespace in which to search for the given name
3274 * @param typeName the name of the type being searched for
3275 * @return the type that was found
3276 */
3277 InterfaceType getType(Namespace namespace, String typeName) {
3278 Element element = namespace.get(typeName);
3279 if (element == null) {
3280 AnalysisEngine.instance.logger.logInformation("No definition of type ${typ eName}");
3281 return null;
3282 }
3283 return ((element as ClassElement)).type;
3284 }
3285 /**
3286 * Initialize the types provided by this type provider from the given library.
3287 * @param library the library containing the definitions of the core types
3288 */
3289 void initializeFrom(LibraryElement library) {
3290 Namespace namespace = new NamespaceBuilder().createPublicNamespace(library);
3291 _boolType = getType(namespace, "bool");
3292 _bottomType = BottomTypeImpl.instance;
3293 _doubleType = getType(namespace, "double");
3294 _dynamicType = DynamicTypeImpl.instance;
3295 _functionType = getType(namespace, "Function");
3296 _intType = getType(namespace, "int");
3297 _listType = getType(namespace, "List");
3298 _mapType = getType(namespace, "Map");
3299 _objectType = getType(namespace, "Object");
3300 _stackTraceType = getType(namespace, "StackTrace");
3301 _stringType = getType(namespace, "String");
3302 _typeType = getType(namespace, "Type");
3303 }
3304 }
3305 /**
3306 * Instances of the class {@code TypeResolverVisitor} are used to resolve the ty pes associated with
3307 * the elements in the element model. This includes the types of superclasses, m ixins, interfaces,
3308 * fields, methods, parameters, and local variables. As a side-effect, this also finishes building
3309 * the type hierarchy.
3310 */
3311 class TypeResolverVisitor extends ScopedVisitor {
3312 /**
3313 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
3314 * @param library the library containing the compilation unit being resolved
3315 * @param source the source representing the compilation unit being visited
3316 * @param typeProvider the object used to access the types from the core libra ry
3317 */
3318 TypeResolverVisitor(Library library, Source source, TypeProvider typeProvider) : super(library, source, typeProvider) {
3319 }
3320 Object visitCatchClause(CatchClause node) {
3321 super.visitCatchClause(node);
3322 SimpleIdentifier exception = node.exceptionParameter;
3323 if (exception != null) {
3324 TypeName exceptionTypeName = node.exceptionType;
3325 Type2 exceptionType;
3326 if (exceptionTypeName == null) {
3327 exceptionType = typeProvider.objectType;
3328 } else {
3329 exceptionType = getType(exceptionTypeName);
3330 }
3331 recordType(exception, exceptionType);
3332 Element element23 = exception.element;
3333 if (element23 is VariableElementImpl) {
3334 ((element23 as VariableElementImpl)).type = exceptionType;
3335 } else {
3336 }
3337 }
3338 SimpleIdentifier stackTrace = node.stackTraceParameter;
3339 if (stackTrace != null) {
3340 recordType(stackTrace, typeProvider.stackTraceType);
3341 }
3342 return null;
3343 }
3344 Object visitClassDeclaration(ClassDeclaration node) {
3345 super.visitClassDeclaration(node);
3346 ClassElementImpl classElement = getClassElement(node.name);
3347 InterfaceType superclassType = null;
3348 ExtendsClause extendsClause4 = node.extendsClause;
3349 if (extendsClause4 != null) {
3350 superclassType = resolveType(extendsClause4.superclass, null, null, null);
3351 }
3352 if (classElement != null) {
3353 if (superclassType == null) {
3354 InterfaceType objectType2 = typeProvider.objectType;
3355 if (classElement.type != objectType2) {
3356 superclassType = objectType2;
3357 }
3358 }
3359 classElement.supertype = superclassType;
3360 }
3361 resolve(classElement, node.withClause, node.implementsClause);
3362 return null;
3363 }
3364 Object visitClassTypeAlias(ClassTypeAlias node) {
3365 super.visitClassTypeAlias(node);
3366 ClassElementImpl classElement = getClassElement(node.name);
3367 InterfaceType superclassType = resolveType(node.superclass, null, null, null );
3368 if (superclassType == null) {
3369 superclassType = typeProvider.objectType;
3370 }
3371 if (classElement != null && superclassType != null) {
3372 classElement.supertype = superclassType;
3373 }
3374 resolve(classElement, node.withClause, node.implementsClause);
3375 return null;
3376 }
3377 Object visitConstructorDeclaration(ConstructorDeclaration node) {
3378 super.visitConstructorDeclaration(node);
3379 ExecutableElementImpl element24 = (node.element as ExecutableElementImpl);
3380 FunctionTypeImpl type = new FunctionTypeImpl.con1(element24);
3381 setTypeInformation(type, null, element24.parameters);
3382 type.returnType = ((element24.enclosingElement as ClassElement)).type;
3383 element24.type = type;
3384 return null;
3385 }
3386 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
3387 super.visitDefaultFormalParameter(node);
3388 return null;
3389 }
3390 Object visitFieldFormalParameter(FieldFormalParameter node) {
3391 super.visitFieldFormalParameter(node);
3392 Element element25 = node.identifier.element;
3393 if (element25 is ParameterElementImpl) {
3394 ParameterElementImpl parameter = (element25 as ParameterElementImpl);
3395 Type2 type;
3396 TypeName typeName = node.type;
3397 if (typeName == null) {
3398 type = typeProvider.dynamicType;
3399 } else {
3400 type = getType(typeName);
3401 }
3402 parameter.type = type;
3403 } else {
3404 }
3405 return null;
3406 }
3407 Object visitFunctionDeclaration(FunctionDeclaration node) {
3408 super.visitFunctionDeclaration(node);
3409 ExecutableElementImpl element26 = (node.element as ExecutableElementImpl);
3410 FunctionTypeImpl type = new FunctionTypeImpl.con1(element26);
3411 setTypeInformation(type, node.returnType, element26.parameters);
3412 element26.type = type;
3413 return null;
3414 }
3415 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
3416 super.visitFunctionTypeAlias(node);
3417 TypeAliasElementImpl element27 = (node.element as TypeAliasElementImpl);
3418 FunctionTypeImpl type14 = (element27.type as FunctionTypeImpl);
3419 setTypeInformation(type14, node.returnType, element27.parameters);
3420 return null;
3421 }
3422 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
3423 super.visitFunctionTypedFormalParameter(node);
3424 ParameterElementImpl element28 = (node.identifier.element as ParameterElemen tImpl);
3425 FunctionTypeImpl type = new FunctionTypeImpl.con1((null as ExecutableElement ));
3426 setTypeInformation(type, node.returnType, getElements(node.parameters));
3427 element28.type = type;
3428 return null;
3429 }
3430 Object visitMethodDeclaration(MethodDeclaration node) {
3431 super.visitMethodDeclaration(node);
3432 ExecutableElementImpl element29 = (node.element as ExecutableElementImpl);
3433 FunctionTypeImpl type = new FunctionTypeImpl.con1(element29);
3434 setTypeInformation(type, node.returnType, element29.parameters);
3435 element29.type = type;
3436 return null;
3437 }
3438 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
3439 super.visitSimpleFormalParameter(node);
3440 Type2 declaredType;
3441 TypeName typeName = node.type;
3442 if (typeName == null) {
3443 declaredType = typeProvider.dynamicType;
3444 } else {
3445 declaredType = getType(typeName);
3446 }
3447 Element element30 = node.identifier.element;
3448 if (element30 is ParameterElement) {
3449 ((element30 as ParameterElementImpl)).type = declaredType;
3450 } else {
3451 }
3452 return null;
3453 }
3454 Object visitTypeName(TypeName node) {
3455 super.visitTypeName(node);
3456 Identifier typeName = node.name;
3457 Element element = nameScope.lookup(typeName, definingLibrary);
3458 Type2 type = null;
3459 if (element == null) {
3460 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
3461 VoidTypeImpl voidType = VoidTypeImpl.instance;
3462 if (typeName.name == dynamicType.name) {
3463 element = dynamicType.element;
3464 type = dynamicType;
3465 setElement(typeName, element);
3466 } else if (typeName.name == voidType.name) {
3467 type = voidType;
3468 } else {
3469 ASTNode parent9 = node.parent;
3470 if (typeName is PrefixedIdentifier && parent9 is ConstructorName) {
3471 ConstructorName name = (parent9 as ConstructorName);
3472 if (name.name == null) {
3473 SimpleIdentifier prefix7 = ((typeName as PrefixedIdentifier)).prefix ;
3474 element = nameScope.lookup(prefix7, definingLibrary);
3475 if (element is PrefixElement) {
3476 return null;
3477 } else if (element != null) {
3478 name.name = ((typeName as PrefixedIdentifier)).identifier;
3479 node.name = prefix7;
3480 typeName = prefix7;
3481 }
3482 }
3483 }
3484 }
3485 }
3486 if (element == null && type == null) {
3487 return null;
3488 } else if (element is ClassElement) {
3489 setElement(typeName, element);
3490 type = ((element as ClassElement)).type;
3491 } else if (element is TypeAliasElement) {
3492 setElement(typeName, element);
3493 type = ((element as TypeAliasElement)).type;
3494 } else if (element is TypeVariableElement) {
3495 setElement(typeName, element);
3496 type = ((element as TypeVariableElement)).type;
3497 } else if (type == null) {
3498 return null;
3499 }
3500 if (type == null) {
3501 return null;
3502 }
3503 TypeArgumentList argumentList = node.typeArguments;
3504 if (argumentList != null) {
3505 NodeList<TypeName> arguments5 = argumentList.arguments;
3506 int argumentCount = arguments5.length;
3507 List<Type2> parameters = getTypeArguments(type);
3508 int parameterCount = parameters.length;
3509 if (argumentCount != parameterCount) {
3510 }
3511 List<Type2> typeArguments = new List<Type2>(argumentCount);
3512 for (int i = 0; i < argumentCount; i++) {
3513 Type2 argumentType = getType(arguments5[i]);
3514 if (argumentType != null) {
3515 typeArguments.add(argumentType);
3516 }
3517 }
3518 if (type is InterfaceTypeImpl) {
3519 InterfaceTypeImpl interfaceType = (type as InterfaceTypeImpl);
3520 argumentCount = typeArguments.length;
3521 if (interfaceType.typeArguments.length == argumentCount) {
3522 type = interfaceType.substitute5(new List.from(typeArguments));
3523 } else {
3524 }
3525 } else if (type is FunctionTypeImpl) {
3526 FunctionTypeImpl functionType = (type as FunctionTypeImpl);
3527 argumentCount = typeArguments.length;
3528 if (functionType.typeArguments.length == argumentCount) {
3529 type = functionType.substitute4(new List.from(typeArguments));
3530 } else {
3531 }
3532 } else {
3533 }
3534 } else {
3535 List<Type2> parameters = getTypeArguments(type);
3536 int parameterCount = parameters.length;
3537 if (parameterCount > 0) {
3538 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
3539 List<Type2> arguments = new List<Type2>.fixedLength(parameterCount);
3540 for (int i = 0; i < parameterCount; i++) {
3541 arguments[i] = dynamicType;
3542 }
3543 type = type.substitute2(arguments, parameters);
3544 }
3545 }
3546 typeName.staticType = type;
3547 node.type = type;
3548 return null;
3549 }
3550 Object visitVariableDeclaration(VariableDeclaration node) {
3551 super.visitVariableDeclaration(node);
3552 Type2 declaredType;
3553 TypeName typeName = ((node.parent as VariableDeclarationList)).type;
3554 if (typeName == null) {
3555 declaredType = typeProvider.dynamicType;
3556 } else {
3557 declaredType = getType(typeName);
3558 }
3559 Element element31 = node.name.element;
3560 if (element31 is VariableElement) {
3561 ((element31 as VariableElementImpl)).type = declaredType;
3562 if (element31 is FieldElement) {
3563 FieldElement field = (element31 as FieldElement);
3564 PropertyAccessorElementImpl getter3 = (field.getter as PropertyAccessorE lementImpl);
3565 FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter3);
3566 getterType.returnType = declaredType;
3567 getter3.type = getterType;
3568 PropertyAccessorElementImpl setter3 = (field.setter as PropertyAccessorE lementImpl);
3569 if (setter3 != null) {
3570 FunctionTypeImpl setterType = new FunctionTypeImpl.con1(setter3);
3571 setterType.returnType = VoidTypeImpl.instance;
3572 setterType.normalParameterTypes = <Type2> [declaredType];
3573 setter3.type = setterType;
3574 }
3575 }
3576 } else {
3577 }
3578 return null;
3579 }
3580 /**
3581 * Return the class element that represents the class whose name was provided.
3582 * @param identifier the name from the declaration of a class
3583 * @return the class element that represents the class
3584 */
3585 ClassElementImpl getClassElement(SimpleIdentifier identifier) {
3586 if (identifier == null) {
3587 return null;
3588 }
3589 Element element32 = identifier.element;
3590 if (element32 is! ClassElementImpl) {
3591 return null;
3592 }
3593 return (element32 as ClassElementImpl);
3594 }
3595 /**
3596 * Return an array containing all of the elements associated with the paramete rs in the given
3597 * list.
3598 * @param parameterList the list of parameters whose elements are to be return ed
3599 * @return the elements associated with the parameters
3600 */
3601 List<ParameterElement> getElements(FormalParameterList parameterList) {
3602 List<ParameterElement> elements = new List<ParameterElement>();
3603 for (FormalParameter parameter in parameterList.parameters) {
3604 ParameterElement element33 = (parameter.identifier.element as ParameterEle ment);
3605 if (element33 != null) {
3606 elements.add(element33);
3607 }
3608 }
3609 return new List.from(elements);
3610 }
3611 /**
3612 * Return the type represented by the given type name.
3613 * @param typeName the type name representing the type to be returned
3614 * @return the type represented by the type name
3615 */
3616 Type2 getType(TypeName typeName) => typeName.type;
3617 /**
3618 * Return the type arguments associated with the given type.
3619 * @param type the type whole type arguments are to be returned
3620 * @return the type arguments associated with the given type
3621 */
3622 List<Type2> getTypeArguments(Type2 type) {
3623 if (type is InterfaceType) {
3624 return ((type as InterfaceType)).typeArguments;
3625 } else if (type is FunctionType) {
3626 return ((type as FunctionType)).typeArguments;
3627 }
3628 return TypeImpl.EMPTY_ARRAY;
3629 }
3630 /**
3631 * Record that the static type of the given node is the given type.
3632 * @param expression the node whose type is to be recorded
3633 * @param type the static type of the node
3634 */
3635 Object recordType(Expression expression, Type2 type) {
3636 if (type == null) {
3637 expression.staticType = typeProvider.dynamicType;
3638 } else {
3639 expression.staticType = type;
3640 }
3641 return null;
3642 }
3643 /**
3644 * Resolve the types in the given with and implements clauses and associate th ose types with the
3645 * given class element.
3646 * @param classElement the class element with which the mixin and interface ty pes are to be
3647 * associated
3648 * @param withClause the with clause to be resolved
3649 * @param implementsClause the implements clause to be resolved
3650 */
3651 void resolve(ClassElementImpl classElement, WithClause withClause, ImplementsC lause implementsClause) {
3652 if (withClause != null) {
3653 List<InterfaceType> mixinTypes2 = resolveTypes(withClause.mixinTypes, null , null, null);
3654 if (classElement != null) {
3655 classElement.mixins = mixinTypes2;
3656 }
3657 }
3658 if (implementsClause != null) {
3659 List<InterfaceType> interfaceTypes = resolveTypes(implementsClause.interfa ces, null, null, null);
3660 if (classElement != null) {
3661 classElement.interfaces = interfaceTypes;
3662 }
3663 }
3664 }
3665 /**
3666 * Return the type specified by the given name.
3667 * @param typeName the type name specifying the type to be returned
3668 * @param undefinedError the error to produce if the type name is not defined
3669 * @param nonTypeError the error to produce if the type name is defined to be something other than
3670 * a type
3671 * @param nonInterfaceType the error to produce if the type is not an interfac e type
3672 * @return the type specified by the type name
3673 */
3674 InterfaceType resolveType(TypeName typeName, ResolverErrorCode undefinedError, ResolverErrorCode nonTypeError, ResolverErrorCode nonInterfaceType) {
3675 Identifier name15 = typeName.name;
3676 Element element = nameScope.lookup(name15, definingLibrary);
3677 if (element == null) {
3678 reportError(undefinedError, name15, []);
3679 } else if (element is ClassElement) {
3680 Type2 classType = ((element as ClassElement)).type;
3681 typeName.type = classType;
3682 if (classType is InterfaceType) {
3683 return (classType as InterfaceType);
3684 }
3685 reportError(nonInterfaceType, name15, []);
3686 } else {
3687 reportError(nonTypeError, name15, []);
3688 }
3689 return null;
3690 }
3691 /**
3692 * Resolve the types in the given list of type names.
3693 * @param typeNames the type names to be resolved
3694 * @param undefinedError the error to produce if the type name is not defined
3695 * @param nonTypeError the error to produce if the type name is defined to be something other than
3696 * a type
3697 * @param nonInterfaceType the error to produce if the type is not an interfac e type
3698 * @return an array containing all of the types that were resolved.
3699 */
3700 List<InterfaceType> resolveTypes(NodeList<TypeName> typeNames, ResolverErrorCo de undefinedError, ResolverErrorCode nonTypeError, ResolverErrorCode nonInterfac eType) {
3701 List<InterfaceType> types = new List<InterfaceType>();
3702 for (TypeName typeName in typeNames) {
3703 InterfaceType type = resolveType(typeName, undefinedError, nonTypeError, n onInterfaceType);
3704 if (type != null) {
3705 types.add(type);
3706 }
3707 }
3708 return new List.from(types);
3709 }
3710 void setElement(Identifier typeName, Element element41) {
3711 if (element41 != null) {
3712 typeName.element = element41;
3713 if (typeName is PrefixedIdentifier) {
3714 PrefixedIdentifier identifier = (typeName as PrefixedIdentifier);
3715 identifier.identifier.element = element41;
3716 SimpleIdentifier prefix8 = identifier.prefix;
3717 Element prefixElement = nameScope.lookup(prefix8, definingLibrary);
3718 if (prefixElement != null) {
3719 prefix8.element = prefixElement;
3720 }
3721 }
3722 }
3723 }
3724 /**
3725 * Set the return type and parameter type information for the given function t ype based on the
3726 * given return type and parameter elements.
3727 * @param functionType the function type to be filled in
3728 * @param returnType the return type of the function, or {@code null} if no ty pe was declared
3729 * @param parameters the elements representing the parameters to the function
3730 */
3731 void setTypeInformation(FunctionTypeImpl functionType, TypeName returnType8, L ist<ParameterElement> parameters) {
3732 List<Type2> normalParameterTypes = new List<Type2>();
3733 List<Type2> optionalParameterTypes = new List<Type2>();
3734 LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
3735 for (ParameterElement parameter in parameters) {
3736 if (parameter.parameterKind == ParameterKind.REQUIRED) {
3737 normalParameterTypes.add(parameter.type);
3738 } else if (parameter.parameterKind == ParameterKind.POSITIONAL) {
3739 optionalParameterTypes.add(parameter.type);
3740 } else if (parameter.parameterKind == ParameterKind.NAMED) {
3741 namedParameterTypes[parameter.name] = parameter.type;
3742 }
3743 }
3744 functionType.normalParameterTypes = new List.from(normalParameterTypes);
3745 functionType.optionalParameterTypes = new List.from(optionalParameterTypes);
3746 functionType.namedParameterTypes = namedParameterTypes;
3747 if (returnType8 == null) {
3748 functionType.returnType = typeProvider.dynamicType;
3749 } else {
3750 functionType.returnType = returnType8.type;
3751 }
3752 }
3753 }
3754 /**
3755 * Instances of the class {@code ClassScope} implement the scope defined by a cl ass.
3756 */
3757 class ClassScope extends EnclosedScope {
3758 /**
3759 * Initialize a newly created scope enclosed within another scope.
3760 * @param enclosingScope the scope in which this scope is lexically enclosed
3761 * @param typeElement the element representing the type represented by this sc ope
3762 */
3763 ClassScope(Scope enclosingScope, ClassElement typeElement) : super(new Enclose dScope(enclosingScope)) {
3764 defineTypeParameters(typeElement);
3765 defineMembers(typeElement);
3766 }
3767 /**
3768 * Define the instance members defined by the class.
3769 * @param typeElement the element representing the type represented by this sc ope
3770 */
3771 void defineMembers(ClassElement typeElement) {
3772 for (PropertyAccessorElement accessor in typeElement.accessors) {
3773 define(accessor);
3774 }
3775 for (FieldElement field in typeElement.fields) {
3776 define(field);
3777 }
3778 for (MethodElement method in typeElement.methods) {
3779 define(method);
3780 }
3781 }
3782 /**
3783 * Define the type parameters for the class.
3784 * @param typeElement the element representing the type represented by this sc ope
3785 */
3786 void defineTypeParameters(ClassElement typeElement) {
3787 Scope parameterScope = enclosingScope;
3788 for (TypeVariableElement parameter in typeElement.typeVariables) {
3789 parameterScope.define(parameter);
3790 }
3791 }
3792 }
3793 /**
3794 * Instances of the class {@code EnclosedScope} implement a scope that is lexica lly enclosed in
3795 * another scope.
3796 */
3797 class EnclosedScope extends Scope {
3798 /**
3799 * The scope in which this scope is lexically enclosed.
3800 */
3801 Scope _enclosingScope;
3802 /**
3803 * Initialize a newly created scope enclosed within another scope.
3804 * @param enclosingScope the scope in which this scope is lexically enclosed
3805 */
3806 EnclosedScope(Scope enclosingScope) {
3807 this._enclosingScope = enclosingScope;
3808 }
3809 LibraryElement get definingLibrary => _enclosingScope.definingLibrary;
3810 AnalysisErrorListener get errorListener => _enclosingScope.errorListener;
3811 /**
3812 * Return the scope in which this scope is lexically enclosed.
3813 * @return the scope in which this scope is lexically enclosed
3814 */
3815 Scope get enclosingScope => _enclosingScope;
3816 Element lookup3(String name, LibraryElement referencingLibrary) {
3817 Element element = localLookup(name, referencingLibrary);
3818 if (element != null) {
3819 return element;
3820 }
3821 return _enclosingScope.lookup3(name, referencingLibrary);
3822 }
3823 }
3824 /**
3825 * Instances of the class {@code FunctionScope} implement the scope defined by a function.
3826 */
3827 class FunctionScope extends EnclosedScope {
3828 /**
3829 * Initialize a newly created scope enclosed within another scope.
3830 * @param enclosingScope the scope in which this scope is lexically enclosed
3831 * @param functionElement the element representing the type represented by thi s scope
3832 */
3833 FunctionScope(Scope enclosingScope, ExecutableElement functionElement) : super (new EnclosedScope(enclosingScope)) {
3834 defineParameters(functionElement);
3835 }
3836 /**
3837 * Define the parameters for the given function in the scope that encloses thi s function.
3838 * @param functionElement the element representing the function represented by this scope
3839 */
3840 void defineParameters(ExecutableElement functionElement) {
3841 Scope parameterScope = enclosingScope;
3842 if (functionElement.enclosingElement is ExecutableElement) {
3843 String name16 = functionElement.name;
3844 if (name16 != null && !name16.isEmpty) {
3845 parameterScope.define(functionElement);
3846 }
3847 }
3848 for (ParameterElement parameter in functionElement.parameters) {
3849 if (!parameter.isInitializingFormal()) {
3850 parameterScope.define(parameter);
3851 }
3852 }
3853 }
3854 }
3855 /**
3856 * Instances of the class {@code FunctionTypeScope} implement the scope defined by a function type
3857 * alias.
3858 */
3859 class FunctionTypeScope extends EnclosedScope {
3860 /**
3861 * Initialize a newly created scope enclosed within another scope.
3862 * @param enclosingScope the scope in which this scope is lexically enclosed
3863 * @param typeElement the element representing the type alias represented by t his scope
3864 */
3865 FunctionTypeScope(Scope enclosingScope, TypeAliasElement typeElement) : super( new EnclosedScope(enclosingScope)) {
3866 defineTypeParameters(typeElement);
3867 }
3868 /**
3869 * Define the type parameters for the function type alias.
3870 * @param typeElement the element representing the type represented by this sc ope
3871 */
3872 void defineTypeParameters(TypeAliasElement typeElement) {
3873 Scope parameterScope = enclosingScope;
3874 for (TypeVariableElement parameter in typeElement.typeVariables) {
3875 parameterScope.define(parameter);
3876 }
3877 }
3878 }
3879 /**
3880 * Instances of the class {@code LabelScope} represent a scope in which a single label is defined.
3881 */
3882 class LabelScope {
3883 /**
3884 * The label scope enclosing this label scope.
3885 */
3886 LabelScope _outerScope;
3887 /**
3888 * The label defined in this scope.
3889 */
3890 String _label;
3891 /**
3892 * The element to which the label resolves.
3893 */
3894 LabelElement _element;
3895 /**
3896 * The marker used to look up a label element for an unlabeled {@code break} o r {@code continue}.
3897 */
3898 static String EMPTY_LABEL = "";
3899 /**
3900 * The label element returned for scopes that can be the target of an unlabele d {@code break} or{@code continue}.
3901 */
3902 static SimpleIdentifier _EMPTY_LABEL_IDENTIFIER = new SimpleIdentifier.full(ne w StringToken(TokenType.IDENTIFIER, "", 0));
3903 /**
3904 * Initialize a newly created scope to represent the potential target of an un labeled{@code break} or {@code continue}.
3905 * @param outerScope the label scope enclosing the new label scope
3906 * @param onSwitchStatement {@code true} if this label is associated with a {@ code switch}statement
3907 * @param onSwitchMember {@code true} if this label is associated with a {@cod e switch} member
3908 */
3909 LabelScope.con1(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMe mber) {
3910 _jtd_constructor_198_impl(outerScope, onSwitchStatement, onSwitchMember);
3911 }
3912 _jtd_constructor_198_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
3913 _jtd_constructor_199_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMP TY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember));
3914 }
3915 /**
3916 * Initialize a newly created scope to represent the given label.
3917 * @param outerScope the label scope enclosing the new label scope
3918 * @param label the label defined in this scope
3919 * @param element the element to which the label resolves
3920 */
3921 LabelScope.con2(LabelScope outerScope2, String label3, LabelElement element18) {
3922 _jtd_constructor_199_impl(outerScope2, label3, element18);
3923 }
3924 _jtd_constructor_199_impl(LabelScope outerScope2, String label3, LabelElement element18) {
3925 this._outerScope = outerScope2;
3926 this._label = label3;
3927 this._element = element18;
3928 }
3929 /**
3930 * Return the label element corresponding to the given label, or {@code null} if the given label
3931 * is not defined in this scope.
3932 * @param targetLabel the label being looked up
3933 * @return the label element corresponding to the given label
3934 */
3935 LabelElement lookup(SimpleIdentifier targetLabel) => lookup2(targetLabel.name) ;
3936 /**
3937 * Return the label element corresponding to the given label, or {@code null} if the given label
3938 * is not defined in this scope.
3939 * @param targetLabel the label being looked up
3940 * @return the label element corresponding to the given label
3941 */
3942 LabelElement lookup2(String targetLabel) {
3943 if (_label == targetLabel) {
3944 return _element;
3945 } else if (_outerScope != null) {
3946 return _outerScope.lookup2(targetLabel);
3947 } else {
3948 return null;
3949 }
3950 }
3951 }
3952 /**
3953 * Instances of the class {@code LibraryImportScope} represent the scope contain ing all of the names
3954 * available from imported libraries.
3955 */
3956 class LibraryImportScope extends Scope {
3957 /**
3958 * The element representing the library in which this scope is enclosed.
3959 */
3960 LibraryElement _definingLibrary;
3961 /**
3962 * The listener that is to be informed when an error is encountered.
3963 */
3964 AnalysisErrorListener _errorListener;
3965 /**
3966 * A list of the namespaces representing the names that are available in this scope from imported
3967 * libraries.
3968 */
3969 List<Namespace> _importedNamespaces = new List<Namespace>();
3970 /**
3971 * Initialize a newly created scope representing the names imported into the g iven library.
3972 * @param definingLibrary the element representing the library that imports th e names defined in
3973 * this scope
3974 * @param errorListener the listener that is to be informed when an error is e ncountered
3975 */
3976 LibraryImportScope(LibraryElement definingLibrary, AnalysisErrorListener error Listener) {
3977 this._definingLibrary = definingLibrary;
3978 this._errorListener = errorListener;
3979 createImportedNamespaces(definingLibrary);
3980 }
3981 void define(Element element) {
3982 if (!Scope.isPrivateName(element.name)) {
3983 super.define(element);
3984 }
3985 }
3986 LibraryElement get definingLibrary => _definingLibrary;
3987 AnalysisErrorListener get errorListener => _errorListener;
3988 Element lookup3(String name, LibraryElement referencingLibrary) {
3989 if (Scope.isPrivateName(name)) {
3990 return null;
3991 }
3992 Element foundElement = localLookup(name, referencingLibrary);
3993 if (foundElement != null) {
3994 return foundElement;
3995 }
3996 for (Namespace nameSpace in _importedNamespaces) {
3997 Element element = nameSpace.get(name);
3998 if (element != null) {
3999 if (foundElement == null) {
4000 foundElement = element;
4001 } else {
4002 foundElement = new MultiplyDefinedElementImpl(_definingLibrary.context , foundElement, element);
4003 }
4004 }
4005 }
4006 if (foundElement != null) {
4007 defineWithoutChecking(foundElement);
4008 }
4009 return foundElement;
4010 }
4011 /**
4012 * Create all of the namespaces associated with the libraries imported into th is library. The
4013 * names are not added to this scope, but are stored for later reference.
4014 * @param definingLibrary the element representing the library that imports th e libraries for
4015 * which namespaces will be created
4016 */
4017 void createImportedNamespaces(LibraryElement definingLibrary) {
4018 NamespaceBuilder builder = new NamespaceBuilder();
4019 for (ImportElement element in definingLibrary.imports) {
4020 _importedNamespaces.add(builder.createImportNamespace(element));
4021 }
4022 }
4023 }
4024 /**
4025 * Instances of the class {@code LibraryScope} implement a scope containing all of the names defined
4026 * in a given library.
4027 */
4028 class LibraryScope extends EnclosedScope {
4029 /**
4030 * Initialize a newly created scope representing the names defined in the give n library.
4031 * @param definingLibrary the element representing the library represented by this scope
4032 * @param errorListener the listener that is to be informed when an error is e ncountered
4033 */
4034 LibraryScope(LibraryElement definingLibrary, AnalysisErrorListener errorListen er) : super(new LibraryImportScope(definingLibrary, errorListener)) {
4035 defineTopLevelNames(definingLibrary);
4036 }
4037 /**
4038 * Add to this scope all of the public top-level names that are defined in the given compilation
4039 * unit.
4040 * @param compilationUnit the compilation unit defining the top-level names to be added to this
4041 * scope
4042 */
4043 void defineLocalNames(CompilationUnitElement compilationUnit) {
4044 for (PropertyAccessorElement element in compilationUnit.accessors) {
4045 define(element);
4046 }
4047 for (FunctionElement element in compilationUnit.functions) {
4048 define(element);
4049 }
4050 for (TypeAliasElement element in compilationUnit.typeAliases) {
4051 define(element);
4052 }
4053 for (ClassElement element in compilationUnit.types) {
4054 define(element);
4055 }
4056 for (VariableElement element in compilationUnit.variables) {
4057 define(element);
4058 }
4059 }
4060 /**
4061 * Add to this scope all of the names that are explicitly defined in the given library.
4062 * @param definingLibrary the element representing the library that defines th e names in this
4063 * scope
4064 */
4065 void defineTopLevelNames(LibraryElement definingLibrary) {
4066 for (PrefixElement prefix in definingLibrary.prefixes) {
4067 define(prefix);
4068 }
4069 defineLocalNames(definingLibrary.definingCompilationUnit);
4070 for (CompilationUnitElement compilationUnit in definingLibrary.parts) {
4071 defineLocalNames(compilationUnit);
4072 }
4073 }
4074 }
4075 /**
4076 * Instances of the class {@code Namespace} implement a mapping of identifiers t o the elements
4077 * represented by those identifiers. Namespaces are the building blocks for scop es.
4078 */
4079 class Namespace {
4080 /**
4081 * A table mapping names that are defined in this namespace to the element rep resenting the thing
4082 * declared with that name.
4083 */
4084 Map<String, Element> _definedNames = new Map<String, Element>();
4085 /**
4086 * Initialize a newly created namespace to have the given defined names.
4087 * @param definedNames the mapping from names that are defined in this namespa ce to the
4088 * corresponding elements
4089 */
4090 Namespace(Map<String, Element> definedNames) {
4091 this._definedNames = definedNames;
4092 }
4093 /**
4094 * Return the element in this namespace that is available to the containing sc ope using the given
4095 * name.
4096 * @param name the name used to reference the
4097 * @return the element represented by the given identifier
4098 */
4099 Element get(String name) => _definedNames[name];
4100 /**
4101 * Return a table containing the same mappings as those defined by this namesp ace.
4102 * @return a table containing the same mappings as those defined by this names pace
4103 */
4104 Map<String, Element> get definedNames => new Map<String, Element>();
4105 }
4106 /**
4107 * Instances of the class {@code NamespaceBuilder} are used to build a {@code Na mespace}. Namespace
4108 * builders are thread-safe and re-usable.
4109 */
4110 class NamespaceBuilder {
4111 /**
4112 * Initialize a newly created namespace builder.
4113 */
4114 NamespaceBuilder() : super() {
4115 }
4116 /**
4117 * Create a namespace representing the export namespace of the given library.
4118 * @param library the library whose export namespace is to be created
4119 * @return the export namespace that was created
4120 */
4121 Namespace createExportNamespace(LibraryElement library) => new Namespace(creat eExportMapping(library, new Set<LibraryElement>()));
4122 /**
4123 * Create a namespace representing the import namespace of the given library.
4124 * @param library the library whose import namespace is to be created
4125 * @return the import namespace that was created
4126 */
4127 Namespace createImportNamespace(ImportElement element) {
4128 Map<String, Element> definedNames = createExportMapping(element.importedLibr ary, new Set<LibraryElement>());
4129 definedNames = apply(definedNames, element.combinators);
4130 definedNames = apply2(definedNames, element.prefix);
4131 return new Namespace(definedNames);
4132 }
4133 /**
4134 * Create a namespace representing the public namespace of the given library.
4135 * @param library the library whose public namespace is to be created
4136 * @return the public namespace that was created
4137 */
4138 Namespace createPublicNamespace(LibraryElement library) {
4139 Map<String, Element> definedNames = new Map<String, Element>();
4140 addPublicNames(definedNames, library.definingCompilationUnit);
4141 for (CompilationUnitElement compilationUnit in library.parts) {
4142 addPublicNames(definedNames, compilationUnit);
4143 }
4144 return new Namespace(definedNames);
4145 }
4146 /**
4147 * Add all of the names in the given namespace to the given mapping table.
4148 * @param definedNames the mapping table to which the names in the given names pace are to be added
4149 * @param namespace the namespace containing the names to be added to this nam espace
4150 */
4151 void addAll(Map<String, Element> definedNames, Map<String, Element> newNames) {
4152 for (MapEntry<String, Element> entry in getMapEntrySet(newNames)) {
4153 definedNames[entry.getKey()] = entry.getValue();
4154 }
4155 }
4156 /**
4157 * Add all of the names in the given namespace to the given mapping table.
4158 * @param definedNames the mapping table to which the names in the given names pace are to be added
4159 * @param namespace the namespace containing the names to be added to this nam espace
4160 */
4161 void addAll2(Map<String, Element> definedNames2, Namespace namespace) {
4162 addAll(definedNames2, namespace.definedNames);
4163 }
4164 /**
4165 * Add the given element to the given mapping table if it has a publicly visib le name.
4166 * @param definedNames the mapping table to which the public name is to be add ed
4167 * @param element the element to be added
4168 */
4169 void addIfPublic(Map<String, Element> definedNames, Element element) {
4170 String name17 = element.name;
4171 if (name17 != null && !Scope.isPrivateName(name17)) {
4172 definedNames[name17] = element;
4173 }
4174 }
4175 /**
4176 * Add to the given mapping table all of the public top-level names that are d efined in the given
4177 * compilation unit.
4178 * @param definedNames the mapping table to which the public names are to be a dded
4179 * @param compilationUnit the compilation unit defining the top-level names to be added to this
4180 * namespace
4181 */
4182 void addPublicNames(Map<String, Element> definedNames, CompilationUnitElement compilationUnit) {
4183 for (PropertyAccessorElement element in compilationUnit.accessors) {
4184 addIfPublic(definedNames, element);
4185 }
4186 for (FunctionElement element in compilationUnit.functions) {
4187 addIfPublic(definedNames, element);
4188 }
4189 for (TypeAliasElement element in compilationUnit.typeAliases) {
4190 addIfPublic(definedNames, element);
4191 }
4192 for (ClassElement element in compilationUnit.types) {
4193 addIfPublic(definedNames, element);
4194 }
4195 for (VariableElement element in compilationUnit.variables) {
4196 addIfPublic(definedNames, element);
4197 }
4198 }
4199 /**
4200 * Apply the given combinators to all of the names in the given mapping table.
4201 * @param definedNames the mapping table to which the namespace operations are to be applied
4202 * @param combinators the combinators to be applied
4203 */
4204 Map<String, Element> apply(Map<String, Element> definedNames, List<NamespaceCo mbinator> combinators) {
4205 for (NamespaceCombinator combinator in combinators) {
4206 if (combinator is __imp_combi.HideCombinator) {
4207 hide(definedNames, ((combinator as __imp_combi.HideCombinator)).hiddenNa mes);
4208 } else if (combinator is __imp_combi.ShowCombinator) {
4209 definedNames = show(definedNames, ((combinator as __imp_combi.ShowCombin ator)).shownNames);
4210 } else {
4211 AnalysisEngine.instance.logger.logError("Unknown type of combinator: ${c ombinator.runtimeType.toString()}");
4212 }
4213 }
4214 return definedNames;
4215 }
4216 /**
4217 * Apply the given prefix to all of the names in the table of defined names.
4218 * @param definedNames the names that were defined before this operation
4219 * @param prefixElement the element defining the prefix to be added to the nam es
4220 */
4221 Map<String, Element> apply2(Map<String, Element> definedNames, PrefixElement p refixElement) {
4222 if (prefixElement != null) {
4223 String prefix = prefixElement.name;
4224 Map<String, Element> newNames = new Map<String, Element>();
4225 for (MapEntry<String, Element> entry in getMapEntrySet(definedNames)) {
4226 newNames["${prefix}.${entry.getKey()}"] = entry.getValue();
4227 }
4228 return newNames;
4229 } else {
4230 return definedNames;
4231 }
4232 }
4233 /**
4234 * Create a mapping table representing the export namespace of the given libra ry.
4235 * @param library the library whose public namespace is to be created
4236 * @param visitedElements a set of libraries that do not need to be visited wh en processing the
4237 * export directives of the given library because all of the names defined by them will
4238 * be added by another library
4239 * @return the mapping table that was created
4240 */
4241 Map<String, Element> createExportMapping(LibraryElement library, Set<LibraryEl ement> visitedElements) {
4242 javaSetAdd(visitedElements, library);
4243 try {
4244 Map<String, Element> definedNames = new Map<String, Element>();
4245 for (ExportElement element in library.exports) {
4246 LibraryElement exportedLibrary3 = element.exportedLibrary;
4247 if (!visitedElements.contains(exportedLibrary3)) {
4248 Map<String, Element> exportedNames = createExportMapping(exportedLibra ry3, visitedElements);
4249 exportedNames = apply(exportedNames, element.combinators);
4250 addAll(definedNames, exportedNames);
4251 }
4252 }
4253 addAll2(definedNames, ((library.context as AnalysisContextImpl)).getPublic Namespace(library));
4254 return definedNames;
4255 } finally {
4256 visitedElements.remove(library);
4257 }
4258 }
4259 /**
4260 * Hide all of the given names by removing them from the given collection of d efined names.
4261 * @param definedNames the names that were defined before this operation
4262 * @param hiddenNames the names to be hidden
4263 */
4264 void hide(Map<String, Element> definedNames, List<String> hiddenNames) {
4265 for (String name in hiddenNames) {
4266 definedNames.remove(name);
4267 }
4268 }
4269 /**
4270 * Show only the given names by removing all other names from the given collec tion of defined
4271 * names.
4272 * @param definedNames the names that were defined before this operation
4273 * @param shownNames the names to be shown
4274 */
4275 Map<String, Element> show(Map<String, Element> definedNames, List<String> show nNames) {
4276 Map<String, Element> newNames = new Map<String, Element>();
4277 for (String name in shownNames) {
4278 Element element = definedNames[name];
4279 if (element != null) {
4280 newNames[name] = element;
4281 }
4282 }
4283 return newNames;
4284 }
4285 }
4286 /**
4287 * The abstract class {@code Scope} defines the behavior common to name scopes u sed by the resolver
4288 * to determine which names are visible at any given point in the code.
4289 */
4290 abstract class Scope {
4291 /**
4292 * The prefix used to mark an identifier as being private to its library.
4293 */
4294 static String PRIVATE_NAME_PREFIX = "_";
4295 /**
4296 * The suffix added to the declared name of a setter when looking up the sette r. Used to
4297 * disambiguate between a getter and a setter that have the same name.
4298 */
4299 static String SETTER_SUFFIX = "=";
4300 /**
4301 * The name used to look up the method used to implement the unary minus opera tor. Used to
4302 * disambiguate between the unary and binary operators.
4303 */
4304 static String UNARY_MINUS = "unary-";
4305 /**
4306 * Return {@code true} if the given name is a library-private name.
4307 * @param name the name being tested
4308 * @return {@code true} if the given name is a library-private name
4309 */
4310 static bool isPrivateName(String name) => name != null && name.startsWith(PRIV ATE_NAME_PREFIX);
4311 /**
4312 * A table mapping names that are defined in this scope to the element represe nting the thing
4313 * declared with that name.
4314 */
4315 Map<String, Element> _definedNames = new Map<String, Element>();
4316 /**
4317 * Initialize a newly created scope to be empty.
4318 */
4319 Scope() : super() {
4320 }
4321 /**
4322 * Add the given element to this scope. If there is already an element with th e given name defined
4323 * in this scope, then an error will be generated and the original element wil l continue to be
4324 * mapped to the name. If there is an element with the given name in an enclos ing scope, then a
4325 * warning will be generated but the given element will hide the inherited ele ment.
4326 * @param element the element to be added to this scope
4327 */
4328 void define(Element element) {
4329 String name = getName(element);
4330 if (_definedNames.containsKey(name)) {
4331 errorListener.onError(getErrorForDuplicate(_definedNames[name], element));
4332 } else {
4333 Element overriddenElement = lookup3(name, definingLibrary);
4334 if (overriddenElement != null) {
4335 AnalysisError error = getErrorForHiding(overriddenElement, element);
4336 if (error != null) {
4337 errorListener.onError(error);
4338 }
4339 }
4340 _definedNames[name] = element;
4341 }
4342 }
4343 /**
4344 * Return the element with which the given identifier is associated, or {@code null} if the name
4345 * is not defined within this scope.
4346 * @param identifier the identifier associated with the element to be returned
4347 * @param referencingLibrary the library that contains the reference to the na me, used to
4348 * implement library-level privacy
4349 * @return the element with which the given identifier is associated
4350 */
4351 Element lookup(Identifier identifier, LibraryElement referencingLibrary) => lo okup3(identifier.name, referencingLibrary);
4352 /**
4353 * Add the given element to this scope without checking for duplication or hid ing.
4354 * @param element the element to be added to this scope
4355 */
4356 void defineWithoutChecking(Element element) {
4357 _definedNames[getName(element)] = element;
4358 }
4359 /**
4360 * Return the element representing the library in which this scope is enclosed .
4361 * @return the element representing the library in which this scope is enclose d
4362 */
4363 LibraryElement get definingLibrary;
4364 /**
4365 * Return the error code to be used when reporting that a name being defined l ocally conflicts
4366 * with another element of the same name in the local scope.
4367 * @param existing the first element to be declared with the conflicting name
4368 * @param duplicate another element declared with the conflicting name
4369 * @return the error code used to report duplicate names within a scope
4370 */
4371 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) => new AnalysisError.con1(source, ResolverErrorCode.DUPLICATE_MEMBER_ERROR, [existing. name]);
4372 /**
4373 * Return the error code to be used when reporting that a name being defined l ocally hides a name
4374 * defined in an outer scope.
4375 * @param hidden the element whose visibility is being hidden
4376 * @param hiding the element that is hiding the visibility of another declarat ion
4377 * @return the error code used to report name hiding
4378 */
4379 AnalysisError getErrorForHiding(Element hidden, Element hiding) => new Analysi sError.con1(source, ResolverErrorCode.DUPLICATE_MEMBER_WARNING, [hidden.name]);
4380 /**
4381 * Return the listener that is to be informed when an error is encountered.
4382 * @return the listener that is to be informed when an error is encountered
4383 */
4384 AnalysisErrorListener get errorListener;
4385 /**
4386 * Return the source object representing the compilation unit with which error s related to this
4387 * scope should be associated.
4388 * @return the source object with which errors should be associated
4389 */
4390 Source get source => definingLibrary.definingCompilationUnit.source;
4391 /**
4392 * Return the element with which the given name is associated, or {@code null} if the name is not
4393 * defined within this scope. This method only returns elements that are direc tly defined within
4394 * this scope, not elements that are defined in an enclosing scope.
4395 * @param name the name associated with the element to be returned
4396 * @param referencingLibrary the library that contains the reference to the na me, used to
4397 * implement library-level privacy
4398 * @return the element with which the given name is associated
4399 */
4400 Element localLookup(String name, LibraryElement referencingLibrary) => _define dNames[name];
4401 /**
4402 * Return the element with which the given name is associated, or {@code null} if the name is not
4403 * defined within this scope.
4404 * @param name the name associated with the element to be returned
4405 * @param referencingLibrary the library that contains the reference to the na me, used to
4406 * implement library-level privacy
4407 * @return the element with which the given name is associated
4408 */
4409 Element lookup3(String name, LibraryElement referencingLibrary);
4410 /**
4411 * Return the name that will be used to look up the given element.
4412 * @param element the element whose look-up name is to be returned
4413 * @return the name that will be used to look up the given element
4414 */
4415 String getName(Element element) {
4416 if (element is MethodElement) {
4417 MethodElement method = (element as MethodElement);
4418 if (method.name == "-" && method.parameters.length == 0) {
4419 return UNARY_MINUS;
4420 }
4421 } else if (element is PropertyAccessorElement) {
4422 PropertyAccessorElement accessor = (element as PropertyAccessorElement);
4423 if (accessor.isSetter()) {
4424 return "${accessor.name}${SETTER_SUFFIX}";
4425 }
4426 }
4427 return element.name;
4428 }
4429 }
4430 /**
4431 * The enumeration {@code ResolverErrorCode} defines the error codes used for er rors detected by the
4432 * resolver. The convention for this class is for the name of the error code to indicate the problem
4433 * that caused the error to be generated and for the error message to explain wh at is wrong and,
4434 * when appropriate, how the problem can be corrected.
4435 */
4436 class ResolverErrorCode implements ErrorCode {
4437 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");
4438 static final ResolverErrorCode CANNOT_BE_RESOLVED = new ResolverErrorCode('CAN NOT_BE_RESOLVED', 1, ErrorType.STATIC_WARNING, "Cannot resolve the name '%s'");
4439 static final ResolverErrorCode CONTINUE_LABEL_ON_SWITCH = new ResolverErrorCod e('CONTINUE_LABEL_ON_SWITCH', 2, ErrorType.COMPILE_TIME_ERROR, "A continue label resolves to switch, must be loop or switch member");
4440 /**
4441 * It is a compile-time error if [the URI] is not a compile-time constant, or if [the URI]
4442 * involves string interpolation.
4443 */
4444 static final ResolverErrorCode INVALID_URI = new ResolverErrorCode('INVALID_UR I', 3, ErrorType.COMPILE_TIME_ERROR, "URI's used in directives must be compile t ime constants without interpolation expressions");
4445 static final ResolverErrorCode LABEL_IN_OUTER_SCOPE = new ResolverErrorCode('L ABEL_IN_OUTER_SCOPE', 4, ErrorType.COMPILE_TIME_ERROR, "Cannot reference label ' %s' declared in an outer method or function");
4446 static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_IMPORTED = new Resolv erErrorCode('MISSING_LIBRARY_DIRECTIVE_IMPORTED', 5, ErrorType.COMPILE_TIME_ERRO R, "Libraries that are imported by other libraries must have a library directive ");
4447 static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_WITH_PART = new Resol verErrorCode('MISSING_LIBRARY_DIRECTIVE_WITH_PART', 6, ErrorType.COMPILE_TIME_ER ROR, "Libraries that have parts must have a library directive");
4448 static final ResolverErrorCode MISSING_PART_OF_DIRECTIVE = new ResolverErrorCo de('MISSING_PART_OF_DIRECTIVE', 7, ErrorType.COMPILE_TIME_ERROR, "The included p art must have a part-of directive");
4449 static final ResolverErrorCode NON_BOOLEAN_CONDITION = new ResolverErrorCode(' NON_BOOLEAN_CONDITION', 8, ErrorType.STATIC_TYPE_WARNING, "Conditions must have a static type of 'bool'");
4450 static final ResolverErrorCode PART_WITH_WRONG_LIBRARY_NAME = new ResolverErro rCode('PART_WITH_WRONG_LIBRARY_NAME', 9, ErrorType.STATIC_WARNING, "The included part appears to be part of the library '%s'");
4451 static final ResolverErrorCode UNDEFINED_LABEL = new ResolverErrorCode('UNDEFI NED_LABEL', 10, ErrorType.COMPILE_TIME_ERROR, "The label '%s' is not defined");
4452 static final ResolverErrorCode DUPLICATE_MEMBER_ERROR = new ResolverErrorCode( 'DUPLICATE_MEMBER_ERROR', 11, ErrorType.COMPILE_TIME_ERROR, "Duplicate member '% s'");
4453 static final ResolverErrorCode DUPLICATE_MEMBER_WARNING = new ResolverErrorCod e('DUPLICATE_MEMBER_WARNING', 12, ErrorType.STATIC_WARNING, "Duplicate member '% s'");
4454 static final List<ResolverErrorCode> values = [BREAK_LABEL_ON_SWITCH_MEMBER, C ANNOT_BE_RESOLVED, CONTINUE_LABEL_ON_SWITCH, INVALID_URI, LABEL_IN_OUTER_SCOPE, MISSING_LIBRARY_DIRECTIVE_IMPORTED, MISSING_LIBRARY_DIRECTIVE_WITH_PART, MISSING _PART_OF_DIRECTIVE, NON_BOOLEAN_CONDITION, PART_WITH_WRONG_LIBRARY_NAME, UNDEFIN ED_LABEL, DUPLICATE_MEMBER_ERROR, DUPLICATE_MEMBER_WARNING];
4455 final String __name;
4456 final int __ordinal;
4457 /**
4458 * The type of this error.
4459 */
4460 ErrorType _type;
4461 /**
4462 * The message template used to create the message to be displayed for this er ror.
4463 */
4464 String _message;
4465 /**
4466 * Initialize a newly created error code to have the given type and message.
4467 * @param type the type of this error
4468 * @param message the message template used to create the message to be displa yed for the error
4469 */
4470 ResolverErrorCode(this.__name, this.__ordinal, ErrorType type, String message) {
4471 this._type = type;
4472 this._message = message;
4473 }
4474 ErrorSeverity get errorSeverity => _type.severity;
4475 String get message => _message;
4476 ErrorType get type => _type;
4477 bool needsRecompilation() => true;
4478 String toString() => __name;
4479 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698