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

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

Issue 12838003: Rename analyzer-experimental to analyzer_experimental. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
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' as sc;
12 import 'utilities_dart.dart';
13 import 'ast.dart';
14 import 'parser.dart' show Parser;
15 import 'element.dart' hide HideCombinator, ShowCombinator;
16 import 'html.dart' as ht;
17 import 'engine.dart';
18 import 'element.dart' as __imp_combi show HideCombinator, ShowCombinator;
19
20 /**
21 * Instances of the class {@code CompilationUnitBuilder} build an element model for a single
22 * compilation unit.
23 * @coverage dart.engine.resolver
24 */
25 class CompilationUnitBuilder {
26 /**
27 * The analysis context in which the element model will be built.
28 */
29 AnalysisContextImpl _analysisContext;
30 /**
31 * The listener to which errors will be reported.
32 */
33 AnalysisErrorListener _errorListener;
34 /**
35 * Initialize a newly created compilation unit element builder.
36 * @param analysisContext the analysis context in which the element model will be built
37 * @param errorListener the listener to which errors will be reported
38 */
39 CompilationUnitBuilder(AnalysisContextImpl analysisContext, AnalysisErrorListe ner errorListener) {
40 this._analysisContext = analysisContext;
41 this._errorListener = errorListener;
42 }
43 /**
44 * Build the compilation unit element for the given source.
45 * @param source the source describing the compilation unit
46 * @return the compilation unit element that was built
47 * @throws AnalysisException if the analysis could not be performed
48 */
49 CompilationUnitElementImpl buildCompilationUnit(Source source) => buildCompila tionUnit2(source, _analysisContext.parse3(source, _errorListener));
50 /**
51 * Build the compilation unit element for the given source.
52 * @param source the source describing the compilation unit
53 * @param unit the AST structure representing the compilation unit
54 * @return the compilation unit element that was built
55 * @throws AnalysisException if the analysis could not be performed
56 */
57 CompilationUnitElementImpl buildCompilationUnit2(Source source13, CompilationU nit unit) {
58 ElementHolder holder = new ElementHolder();
59 ElementBuilder builder = new ElementBuilder(holder);
60 unit.accept(builder);
61 CompilationUnitElementImpl element = new CompilationUnitElementImpl(source13 .shortName);
62 element.accessors = holder.accessors;
63 element.functions = holder.functions;
64 element.source = source13;
65 element.typeAliases = holder.typeAliases;
66 element.types = holder.types;
67 element.topLevelVariables = holder.topLevelVariables;
68 unit.element = element;
69 return element;
70 }
71 }
72 /**
73 * Instances of the class {@code ElementBuilder} traverse an AST structure and b uild the element
74 * model representing the AST structure.
75 * @coverage dart.engine.resolver
76 */
77 class ElementBuilder extends RecursiveASTVisitor<Object> {
78 /**
79 * The element holder associated with the element that is currently being buil t.
80 */
81 ElementHolder _currentHolder;
82 /**
83 * A flag indicating whether a variable declaration is in the context of a fie ld declaration.
84 */
85 bool _inFieldContext = false;
86 /**
87 * A flag indicating whether a variable declaration is within the body of a me thod or function.
88 */
89 bool _inFunction = false;
90 /**
91 * A flag indicating whether the class currently being visited can be used as a mixin.
92 */
93 bool _isValidMixin = false;
94 /**
95 * Initialize a newly created element builder to build the elements for a comp ilation unit.
96 * @param initialHolder the element holder associated with the compilation uni t being built
97 */
98 ElementBuilder(ElementHolder initialHolder) {
99 _currentHolder = initialHolder;
100 }
101 Object visitCatchClause(CatchClause node) {
102 SimpleIdentifier exceptionParameter2 = node.exceptionParameter;
103 if (exceptionParameter2 != null) {
104 LocalVariableElementImpl exception = new LocalVariableElementImpl(exceptio nParameter2);
105 _currentHolder.addLocalVariable(exception);
106 exceptionParameter2.element = exception;
107 SimpleIdentifier stackTraceParameter2 = node.stackTraceParameter;
108 if (stackTraceParameter2 != null) {
109 LocalVariableElementImpl stackTrace = new LocalVariableElementImpl(stack TraceParameter2);
110 _currentHolder.addLocalVariable(stackTrace);
111 stackTraceParameter2.element = stackTrace;
112 }
113 }
114 return super.visitCatchClause(node);
115 }
116 Object visitClassDeclaration(ClassDeclaration node) {
117 ElementHolder holder = new ElementHolder();
118 _isValidMixin = true;
119 visitChildren(holder, node);
120 SimpleIdentifier className = node.name;
121 ClassElementImpl element = new ClassElementImpl(className);
122 List<TypeVariableElement> typeVariables4 = holder.typeVariables;
123 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
124 interfaceType.typeArguments = createTypeVariableTypes(typeVariables4);
125 element.type = interfaceType;
126 List<ConstructorElement> constructors3 = holder.constructors;
127 if (constructors3.length == 0) {
128 ConstructorElementImpl constructor = new ConstructorElementImpl(null);
129 constructor.synthetic = true;
130 FunctionTypeImpl type = new FunctionTypeImpl.con1(constructor);
131 type.returnType = interfaceType;
132 constructor.type = type;
133 constructors3 = <ConstructorElement> [constructor];
134 }
135 element.abstract = node.abstractKeyword != null;
136 element.accessors = holder.accessors;
137 element.constructors = constructors3;
138 element.fields = holder.fields;
139 element.methods = holder.methods;
140 element.typeVariables = typeVariables4;
141 element.validMixin = _isValidMixin;
142 _currentHolder.addType(element);
143 className.element = element;
144 return null;
145 }
146 Object visitClassTypeAlias(ClassTypeAlias node) {
147 ElementHolder holder = new ElementHolder();
148 visitChildren(holder, node);
149 SimpleIdentifier className = node.name;
150 ClassElementImpl element = new ClassElementImpl(className);
151 element.abstract = node.abstractKeyword != null;
152 element.typedef = true;
153 List<TypeVariableElement> typeVariables5 = holder.typeVariables;
154 element.typeVariables = typeVariables5;
155 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl.con1(element);
156 interfaceType.typeArguments = createTypeVariableTypes(typeVariables5);
157 element.type = interfaceType;
158 _currentHolder.addType(element);
159 className.element = element;
160 return null;
161 }
162 Object visitConstructorDeclaration(ConstructorDeclaration node) {
163 _isValidMixin = false;
164 ElementHolder holder = new ElementHolder();
165 visitChildren(holder, node);
166 SimpleIdentifier constructorName = node.name;
167 ConstructorElementImpl element = new ConstructorElementImpl(constructorName) ;
168 if (node.factoryKeyword != null) {
169 element.factory = true;
170 }
171 element.functions = holder.functions;
172 element.labels = holder.labels;
173 element.localVariables = holder.localVariables;
174 element.parameters = holder.parameters;
175 _currentHolder.addConstructor(element);
176 node.element = element;
177 if (constructorName != null) {
178 constructorName.element = element;
179 }
180 return null;
181 }
182 Object visitDeclaredIdentifier(DeclaredIdentifier node) {
183 SimpleIdentifier variableName = node.identifier;
184 sc.Token keyword27 = node.keyword;
185 LocalVariableElementImpl element = new LocalVariableElementImpl(variableName );
186 ForEachStatement statement = node.parent as ForEachStatement;
187 int declarationEnd = node.offset + node.length;
188 int statementEnd = statement.offset + statement.length;
189 element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1);
190 element.const2 = matches(keyword27, sc.Keyword.CONST);
191 element.final2 = matches(keyword27, sc.Keyword.FINAL);
192 _currentHolder.addLocalVariable(element);
193 variableName.element = element;
194 return super.visitDeclaredIdentifier(node);
195 }
196 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
197 ElementHolder holder = new ElementHolder();
198 visit(holder, node.defaultValue);
199 FunctionElementImpl initializer = new FunctionElementImpl();
200 initializer.functions = holder.functions;
201 initializer.labels = holder.labels;
202 initializer.localVariables = holder.localVariables;
203 initializer.parameters = holder.parameters;
204 SimpleIdentifier parameterName = node.parameter.identifier;
205 ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
206 parameter.const2 = node.isConst();
207 parameter.final2 = node.isFinal();
208 parameter.initializer = initializer;
209 parameter.parameterKind = node.kind;
210 FunctionBody body = getFunctionBody(node);
211 if (body != null) {
212 parameter.setVisibleRange(body.offset, body.length);
213 }
214 _currentHolder.addParameter(parameter);
215 parameterName.element = parameter;
216 node.parameter.accept(this);
217 return null;
218 }
219 Object visitFieldDeclaration(FieldDeclaration node) {
220 bool wasInField = _inFieldContext;
221 _inFieldContext = true;
222 try {
223 node.visitChildren(this);
224 } finally {
225 _inFieldContext = wasInField;
226 }
227 return null;
228 }
229 Object visitFieldFormalParameter(FieldFormalParameter node) {
230 if (node.parent is! DefaultFormalParameter) {
231 SimpleIdentifier parameterName = node.identifier;
232 ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
233 parameter.const2 = node.isConst();
234 parameter.initializingFormal = true;
235 parameter.final2 = node.isFinal();
236 parameter.parameterKind = node.kind;
237 _currentHolder.addParameter(parameter);
238 parameterName.element = parameter;
239 }
240 return super.visitFieldFormalParameter(node);
241 }
242 Object visitFunctionDeclaration(FunctionDeclaration node) {
243 FunctionExpression expression = node.functionExpression;
244 if (expression != null) {
245 ElementHolder holder = new ElementHolder();
246 bool wasInFunction = _inFunction;
247 _inFunction = true;
248 try {
249 visitChildren(holder, expression);
250 } finally {
251 _inFunction = wasInFunction;
252 }
253 sc.Token property = node.propertyKeyword;
254 if (property == null) {
255 SimpleIdentifier functionName = node.name;
256 FunctionElementImpl element = new FunctionElementImpl.con1(functionName) ;
257 element.functions = holder.functions;
258 element.labels = holder.labels;
259 element.localVariables = holder.localVariables;
260 element.parameters = holder.parameters;
261 FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
262 element.type = type;
263 _currentHolder.addFunction(element);
264 expression.element = element;
265 functionName.element = element;
266 } else {
267 SimpleIdentifier propertyNameNode = node.name;
268 if (propertyNameNode == null) {
269 return null;
270 }
271 String propertyName = propertyNameNode.name;
272 FieldElementImpl field = _currentHolder.getField(propertyName) as FieldE lementImpl;
273 if (field == null) {
274 field = new FieldElementImpl.con2(node.name.name);
275 field.final2 = true;
276 _currentHolder.addField(field);
277 }
278 if (matches(property, sc.Keyword.GET)) {
279 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.c on1(propertyNameNode);
280 getter.functions = holder.functions;
281 getter.labels = holder.labels;
282 getter.localVariables = holder.localVariables;
283 getter.variable = field;
284 getter.getter = true;
285 field.getter = getter;
286 _currentHolder.addAccessor(getter);
287 propertyNameNode.element = getter;
288 } else {
289 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.c on1(propertyNameNode);
290 setter.functions = holder.functions;
291 setter.labels = holder.labels;
292 setter.localVariables = holder.localVariables;
293 setter.parameters = holder.parameters;
294 setter.variable = field;
295 setter.setter = true;
296 field.setter = setter;
297 field.final2 = false;
298 _currentHolder.addAccessor(setter);
299 propertyNameNode.element = setter;
300 }
301 }
302 }
303 return null;
304 }
305 Object visitFunctionExpression(FunctionExpression node) {
306 ElementHolder holder = new ElementHolder();
307 bool wasInFunction = _inFunction;
308 _inFunction = true;
309 try {
310 visitChildren(holder, node);
311 } finally {
312 _inFunction = wasInFunction;
313 }
314 SimpleIdentifier functionName = null;
315 FunctionElementImpl element = new FunctionElementImpl.con1(functionName);
316 element.functions = holder.functions;
317 element.labels = holder.labels;
318 element.localVariables = holder.localVariables;
319 element.parameters = holder.parameters;
320 if (_inFunction) {
321 Block enclosingBlock = node.getAncestor(Block);
322 if (enclosingBlock != null) {
323 int functionEnd = node.offset + node.length;
324 int blockEnd = enclosingBlock.offset + enclosingBlock.length;
325 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
326 }
327 }
328 FunctionTypeImpl type = new FunctionTypeImpl.con1(element);
329 element.type = type;
330 _currentHolder.addFunction(element);
331 node.element = element;
332 return null;
333 }
334 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
335 ElementHolder holder = new ElementHolder();
336 visitChildren(holder, node);
337 SimpleIdentifier aliasName = node.name;
338 List<ParameterElement> parameters10 = holder.parameters;
339 List<TypeVariableElement> typeVariables6 = holder.typeVariables;
340 TypeAliasElementImpl element = new TypeAliasElementImpl(aliasName);
341 element.parameters = parameters10;
342 element.typeVariables = typeVariables6;
343 FunctionTypeImpl type = new FunctionTypeImpl.con2(element);
344 type.typeArguments = createTypeVariableTypes(typeVariables6);
345 element.type = type;
346 _currentHolder.addTypeAlias(element);
347 aliasName.element = element;
348 return null;
349 }
350 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
351 if (node.parent is! DefaultFormalParameter) {
352 SimpleIdentifier parameterName = node.identifier;
353 ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
354 parameter.parameterKind = node.kind;
355 _currentHolder.addParameter(parameter);
356 parameterName.element = parameter;
357 }
358 visitChildren(new ElementHolder(), node);
359 return null;
360 }
361 Object visitLabeledStatement(LabeledStatement node) {
362 bool onSwitchStatement = node.statement is SwitchStatement;
363 for (Label label in node.labels) {
364 SimpleIdentifier labelName = label.label;
365 LabelElementImpl element = new LabelElementImpl(labelName, onSwitchStateme nt, false);
366 _currentHolder.addLabel(element);
367 labelName.element = element;
368 }
369 return super.visitLabeledStatement(node);
370 }
371 Object visitMethodDeclaration(MethodDeclaration node) {
372 ElementHolder holder = new ElementHolder();
373 bool wasInFunction = _inFunction;
374 _inFunction = true;
375 try {
376 visitChildren(holder, node);
377 } finally {
378 _inFunction = wasInFunction;
379 }
380 sc.Token property = node.propertyKeyword;
381 if (property == null) {
382 SimpleIdentifier methodName = node.name;
383 String nameOfMethod = methodName.name;
384 if (nameOfMethod == sc.TokenType.MINUS.lexeme && node.parameters.parameter s.length == 0) {
385 nameOfMethod = "unary-";
386 }
387 MethodElementImpl element = new MethodElementImpl.con2(nameOfMethod, metho dName.offset);
388 sc.Token keyword = node.modifierKeyword;
389 element.abstract = matches(keyword, sc.Keyword.ABSTRACT);
390 element.functions = holder.functions;
391 element.labels = holder.labels;
392 element.localVariables = holder.localVariables;
393 element.parameters = holder.parameters;
394 element.static = matches(keyword, sc.Keyword.STATIC);
395 _currentHolder.addMethod(element);
396 methodName.element = element;
397 } else {
398 SimpleIdentifier propertyNameNode = node.name;
399 String propertyName = propertyNameNode.name;
400 FieldElementImpl field = _currentHolder.getField(propertyName) as FieldEle mentImpl;
401 if (field == null) {
402 field = new FieldElementImpl.con2(node.name.name);
403 field.final2 = true;
404 field.static = matches(node.modifierKeyword, sc.Keyword.STATIC);
405 _currentHolder.addField(field);
406 }
407 if (matches(property, sc.Keyword.GET)) {
408 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con 1(propertyNameNode);
409 getter.functions = holder.functions;
410 getter.labels = holder.labels;
411 getter.localVariables = holder.localVariables;
412 getter.variable = field;
413 getter.getter = true;
414 field.getter = getter;
415 _currentHolder.addAccessor(getter);
416 propertyNameNode.element = getter;
417 } else {
418 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con 1(propertyNameNode);
419 setter.functions = holder.functions;
420 setter.labels = holder.labels;
421 setter.localVariables = holder.localVariables;
422 setter.parameters = holder.parameters;
423 setter.variable = field;
424 setter.setter = true;
425 field.setter = setter;
426 field.final2 = false;
427 _currentHolder.addAccessor(setter);
428 propertyNameNode.element = setter;
429 }
430 }
431 return null;
432 }
433 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
434 if (node.parent is! DefaultFormalParameter) {
435 SimpleIdentifier parameterName = node.identifier;
436 ParameterElementImpl parameter = new ParameterElementImpl(parameterName);
437 parameter.const2 = node.isConst();
438 parameter.final2 = node.isFinal();
439 parameter.parameterKind = node.kind;
440 _currentHolder.addParameter(parameter);
441 parameterName.element = parameter;
442 }
443 return super.visitSimpleFormalParameter(node);
444 }
445 Object visitSuperExpression(SuperExpression node) {
446 _isValidMixin = false;
447 return super.visitSuperExpression(node);
448 }
449 Object visitSwitchCase(SwitchCase node) {
450 for (Label label in node.labels) {
451 SimpleIdentifier labelName = label.label;
452 LabelElementImpl element = new LabelElementImpl(labelName, false, true);
453 _currentHolder.addLabel(element);
454 labelName.element = element;
455 }
456 return super.visitSwitchCase(node);
457 }
458 Object visitSwitchDefault(SwitchDefault node) {
459 for (Label label in node.labels) {
460 SimpleIdentifier labelName = label.label;
461 LabelElementImpl element = new LabelElementImpl(labelName, false, true);
462 _currentHolder.addLabel(element);
463 labelName.element = element;
464 }
465 return super.visitSwitchDefault(node);
466 }
467 Object visitTypeParameter(TypeParameter node) {
468 SimpleIdentifier parameterName = node.name;
469 TypeVariableElementImpl element = new TypeVariableElementImpl(parameterName) ;
470 TypeVariableTypeImpl type = new TypeVariableTypeImpl(element);
471 element.type = type;
472 _currentHolder.addTypeVariable(element);
473 parameterName.element = element;
474 return super.visitTypeParameter(node);
475 }
476 Object visitVariableDeclaration(VariableDeclaration node) {
477 VariableElementImpl element;
478 if (_inFieldContext) {
479 SimpleIdentifier fieldName = node.name;
480 FieldElementImpl field = new FieldElementImpl.con1(fieldName);
481 element = field;
482 _currentHolder.addField(field);
483 fieldName.element = field;
484 } else if (_inFunction) {
485 SimpleIdentifier variableName = node.name;
486 element = new LocalVariableElementImpl(variableName);
487 Block enclosingBlock = node.getAncestor(Block);
488 int functionEnd = node.offset + node.length;
489 int blockEnd = enclosingBlock.offset + enclosingBlock.length;
490 ((element as LocalVariableElementImpl)).setVisibleRange(functionEnd, block End - functionEnd - 1);
491 _currentHolder.addLocalVariable((element as LocalVariableElementImpl));
492 variableName.element = element;
493 } else {
494 SimpleIdentifier variableName = node.name;
495 element = new TopLevelVariableElementImpl.con1(variableName);
496 _currentHolder.addTopLevelVariable((element as TopLevelVariableElementImpl ));
497 variableName.element = element;
498 }
499 sc.Token keyword28 = ((node.parent as VariableDeclarationList)).keyword;
500 bool isFinal = matches(keyword28, sc.Keyword.FINAL);
501 element.const2 = matches(keyword28, sc.Keyword.CONST);
502 element.final2 = isFinal;
503 if (node.initializer != null) {
504 ElementHolder holder = new ElementHolder();
505 bool wasInFieldContext = _inFieldContext;
506 _inFieldContext = false;
507 try {
508 visit(holder, node.initializer);
509 } finally {
510 _inFieldContext = wasInFieldContext;
511 }
512 FunctionElementImpl initializer = new FunctionElementImpl();
513 initializer.functions = holder.functions;
514 initializer.labels = holder.labels;
515 initializer.localVariables = holder.localVariables;
516 initializer.synthetic = true;
517 element.initializer = initializer;
518 }
519 if (element is PropertyInducingElementImpl) {
520 PropertyInducingElementImpl variable = element as PropertyInducingElementI mpl;
521 PropertyAccessorElementImpl getter = new PropertyAccessorElementImpl.con2( variable);
522 getter.getter = true;
523 _currentHolder.addAccessor(getter);
524 variable.getter = getter;
525 if (!isFinal) {
526 PropertyAccessorElementImpl setter = new PropertyAccessorElementImpl.con 2(variable);
527 setter.setter = true;
528 _currentHolder.addAccessor(setter);
529 variable.setter = setter;
530 }
531 if (_inFieldContext) {
532 ((variable as FieldElementImpl)).static = matches(((node.parent.parent a s FieldDeclaration)).keyword, sc.Keyword.STATIC);
533 }
534 }
535 return super.visitVariableDeclaration(node);
536 }
537 List<Type2> createTypeVariableTypes(List<TypeVariableElement> typeVariables) {
538 int typeVariableCount = typeVariables.length;
539 List<Type2> typeArguments = new List<Type2>(typeVariableCount);
540 for (int i = 0; i < typeVariableCount; i++) {
541 TypeVariableElementImpl typeVariable = typeVariables[i] as TypeVariableEle mentImpl;
542 TypeVariableTypeImpl typeArgument = new TypeVariableTypeImpl(typeVariable) ;
543 typeVariable.type = typeArgument;
544 typeArguments[i] = typeArgument;
545 }
546 return typeArguments;
547 }
548 /**
549 * Return the body of the function that contains the given parameter, or {@cod e null} if no
550 * function body could be found.
551 * @param node the parameter contained in the function whose body is to be ret urned
552 * @return the body of the function that contains the given parameter
553 */
554 FunctionBody getFunctionBody(FormalParameter node) {
555 ASTNode parent13 = node.parent;
556 while (parent13 != null) {
557 if (parent13 is FunctionExpression) {
558 return ((parent13 as FunctionExpression)).body;
559 } else if (parent13 is MethodDeclaration) {
560 return ((parent13 as MethodDeclaration)).body;
561 }
562 parent13 = parent13.parent;
563 }
564 return null;
565 }
566 /**
567 * Return {@code true} if the given token is a token for the given keyword.
568 * @param token the token being tested
569 * @param keyword the keyword being tested for
570 * @return {@code true} if the given token is a token for the given keyword
571 */
572 bool matches(sc.Token token, sc.Keyword keyword36) => token != null && identic al(token.type, sc.TokenType.KEYWORD) && identical(((token as sc.KeywordToken)).k eyword, keyword36);
573 /**
574 * Make the given holder be the current holder while visiting the given node.
575 * @param holder the holder that will gather elements that are built while vis iting the children
576 * @param node the node to be visited
577 */
578 void visit(ElementHolder holder, ASTNode node) {
579 if (node != null) {
580 ElementHolder previousHolder = _currentHolder;
581 _currentHolder = holder;
582 try {
583 node.accept(this);
584 } finally {
585 _currentHolder = previousHolder;
586 }
587 }
588 }
589 /**
590 * Make the given holder be the current holder while visiting the children of the given node.
591 * @param holder the holder that will gather elements that are built while vis iting the children
592 * @param node the node whose children are to be visited
593 */
594 void visitChildren(ElementHolder holder, ASTNode node) {
595 if (node != null) {
596 ElementHolder previousHolder = _currentHolder;
597 _currentHolder = holder;
598 try {
599 node.visitChildren(this);
600 } finally {
601 _currentHolder = previousHolder;
602 }
603 }
604 }
605 }
606 /**
607 * Instances of the class {@code ElementHolder} hold on to elements created whil e traversing an AST
608 * structure so that they can be accessed when creating their enclosing element.
609 * @coverage dart.engine.resolver
610 */
611 class ElementHolder {
612 List<PropertyAccessorElement> _accessors = new List<PropertyAccessorElement>() ;
613 List<ConstructorElement> _constructors = new List<ConstructorElement>();
614 List<FieldElement> _fields = new List<FieldElement>();
615 List<FunctionElement> _functions = new List<FunctionElement>();
616 List<LabelElement> _labels = new List<LabelElement>();
617 List<VariableElement> _localVariables = new List<VariableElement>();
618 List<MethodElement> _methods = new List<MethodElement>();
619 List<TypeAliasElement> _typeAliases = new List<TypeAliasElement>();
620 List<ParameterElement> _parameters = new List<ParameterElement>();
621 List<VariableElement> _topLevelVariables = new List<VariableElement>();
622 List<ClassElement> _types = new List<ClassElement>();
623 List<TypeVariableElement> _typeVariables = new List<TypeVariableElement>();
624 /**
625 * Initialize a newly created element holder.
626 */
627 ElementHolder() : super() {
628 }
629 void addAccessor(PropertyAccessorElement element) {
630 _accessors.add(element);
631 }
632 void addConstructor(ConstructorElement element) {
633 _constructors.add(element);
634 }
635 void addField(FieldElement element) {
636 _fields.add(element);
637 }
638 void addFunction(FunctionElement element) {
639 _functions.add(element);
640 }
641 void addLabel(LabelElement element) {
642 _labels.add(element);
643 }
644 void addLocalVariable(LocalVariableElement element) {
645 _localVariables.add(element);
646 }
647 void addMethod(MethodElement element) {
648 _methods.add(element);
649 }
650 void addParameter(ParameterElement element) {
651 _parameters.add(element);
652 }
653 void addTopLevelVariable(TopLevelVariableElement element) {
654 _topLevelVariables.add(element);
655 }
656 void addType(ClassElement element) {
657 _types.add(element);
658 }
659 void addTypeAlias(TypeAliasElement element) {
660 _typeAliases.add(element);
661 }
662 void addTypeVariable(TypeVariableElement element) {
663 _typeVariables.add(element);
664 }
665 List<PropertyAccessorElement> get accessors => new List.from(_accessors);
666 List<ConstructorElement> get constructors => new List.from(_constructors);
667 FieldElement getField(String fieldName) {
668 for (FieldElement field in _fields) {
669 if (field.name == fieldName) {
670 return field;
671 }
672 }
673 return null;
674 }
675 List<FieldElement> get fields => new List.from(_fields);
676 List<FunctionElement> get functions => new List.from(_functions);
677 List<LabelElement> get labels => new List.from(_labels);
678 List<LocalVariableElement> get localVariables => new List.from(_localVariables );
679 List<MethodElement> get methods => new List.from(_methods);
680 List<ParameterElement> get parameters => new List.from(_parameters);
681 List<TopLevelVariableElement> get topLevelVariables => new List.from(_topLevel Variables);
682 List<TypeAliasElement> get typeAliases => new List.from(_typeAliases);
683 List<ClassElement> get types => new List.from(_types);
684 List<TypeVariableElement> get typeVariables => new List.from(_typeVariables);
685 }
686 /**
687 * Instances of the class {@code HtmlUnitBuilder} build an element model for a s ingle HTML unit.
688 */
689 class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
690 static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\"";
691 static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'";
692 static String _SCRIPT = "script";
693 static String _SRC = "src";
694 static String _TYPE = "type";
695 /**
696 * The analysis context in which the element model will be built.
697 */
698 AnalysisContextImpl _context;
699 /**
700 * The HTML element being built.
701 */
702 HtmlElementImpl _htmlElement;
703 /**
704 * The script elements being built.
705 */
706 List<HtmlScriptElement> _scripts;
707 /**
708 * Initialize a newly created HTML unit builder.
709 * @param context the analysis context in which the element model will be buil t
710 */
711 HtmlUnitBuilder(AnalysisContextImpl context) {
712 this._context = context;
713 }
714 /**
715 * Build the HTML element for the given source.
716 * @param source the source describing the compilation unit
717 * @return the HTML element that was built
718 * @throws AnalysisException if the analysis could not be performed
719 */
720 HtmlElementImpl buildHtmlElement(Source source) => buildHtmlElement2(source, _ context.parseHtml(source).htmlUnit);
721 /**
722 * Build the HTML element for the given source.
723 * @param source the source describing the compilation unit
724 * @param unit the AST structure representing the HTML
725 * @throws AnalysisException if the analysis could not be performed
726 */
727 HtmlElementImpl buildHtmlElement2(Source source14, ht.HtmlUnit unit) {
728 HtmlElementImpl result = new HtmlElementImpl(_context, source14.shortName);
729 result.source = source14;
730 _htmlElement = result;
731 unit.accept(this);
732 _htmlElement = null;
733 unit.element = result;
734 return result;
735 }
736 Object visitHtmlUnit(ht.HtmlUnit node) {
737 _scripts = new List<HtmlScriptElement>();
738 node.visitChildren(this);
739 _htmlElement.scripts = new List.from(_scripts);
740 _scripts = null;
741 return null;
742 }
743 Object visitXmlAttributeNode(ht.XmlAttributeNode node) => null;
744 Object visitXmlTagNode(ht.XmlTagNode node) {
745 if (isScriptNode(node)) {
746 Source htmlSource = _htmlElement.source;
747 String scriptSourcePath = getScriptSourcePath(node);
748 if (identical(node.attributeEnd.type, ht.TokenType.GT) && scriptSourcePath == null) {
749 EmbeddedHtmlScriptElementImpl script = new EmbeddedHtmlScriptElementImpl (node);
750 String contents = node.content;
751 AnalysisErrorListener errorListener = new AnalysisErrorListener_2();
752 sc.StringScanner scanner = new sc.StringScanner(null, contents, errorLis tener);
753 sc.Token firstToken = scanner.tokenize();
754 List<int> lineStarts2 = scanner.lineStarts;
755 Parser parser = new Parser(null, errorListener);
756 CompilationUnit unit = parser.parseCompilationUnit(firstToken);
757 try {
758 CompilationUnitBuilder builder = new CompilationUnitBuilder(_context, errorListener);
759 CompilationUnitElementImpl elem = builder.buildCompilationUnit2(htmlSo urce, unit);
760 LibraryElementImpl library = new LibraryElementImpl(_context, null);
761 library.definingCompilationUnit = elem;
762 script.scriptLibrary = library;
763 } on AnalysisException catch (e) {
764 print(e);
765 }
766 _scripts.add(script);
767 } else {
768 ExternalHtmlScriptElementImpl script = new ExternalHtmlScriptElementImpl (node);
769 if (scriptSourcePath != null) {
770 script.scriptSource = htmlSource.resolve(scriptSourcePath);
771 }
772 _scripts.add(script);
773 }
774 } else {
775 node.visitChildren(this);
776 }
777 return null;
778 }
779 /**
780 * Return the value of the source attribute if it exists.
781 * @param node the node containing attributes
782 * @return the source path or {@code null} if not defined
783 */
784 String getScriptSourcePath(ht.XmlTagNode node) {
785 for (ht.XmlAttributeNode attribute in node.attributes) {
786 if (attribute.name.lexeme == _SRC) {
787 String text2 = attribute.text;
788 return text2 != null && text2.length > 0 ? text2 : null;
789 }
790 }
791 return null;
792 }
793 /**
794 * Determine if the specified node is a Dart script.
795 * @param node the node to be tested (not {@code null})
796 * @return {@code true} if the node is a Dart script
797 */
798 bool isScriptNode(ht.XmlTagNode node) {
799 if (node.tagNodes.length != 0 || node.tag.lexeme != _SCRIPT) {
800 return false;
801 }
802 for (ht.XmlAttributeNode attribute in node.attributes) {
803 if (attribute.name.lexeme == _TYPE) {
804 ht.Token valueToken = attribute.value;
805 if (valueToken != null) {
806 String value = valueToken.lexeme;
807 if (value == _APPLICATION_DART_IN_DOUBLE_QUOTES || value == _APPLICATI ON_DART_IN_SINGLE_QUOTES) {
808 return true;
809 }
810 }
811 }
812 }
813 return false;
814 }
815 }
816 class AnalysisErrorListener_2 implements AnalysisErrorListener {
817 void onError(AnalysisError error) {
818 }
819 }
820 /**
821 * 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
822 * for the element resolver are:
823 * <ol>
824 * <li>Every {@link SimpleIdentifier} should be resolved to the element to which it refers.
825 * Specifically:
826 * <ul>
827 * <li>An identifier within the declaration of that name should resolve to the e lement being
828 * declared.</li>
829 * <li>An identifier denoting a prefix should resolve to the element representin g the import that
830 * defines the prefix (an {@link ImportElement}).</li>
831 * <li>An identifier denoting a variable should resolve to the element represent ing the variable (a{@link VariableElement}).</li>
832 * <li>An identifier denoting a parameter should resolve to the element represen ting the parameter
833 * (a {@link ParameterElement}).</li>
834 * <li>An identifier denoting a field should resolve to the element representing the getter or
835 * setter being invoked (a {@link PropertyAccessorElement}).</li>
836 * <li>An identifier denoting the name of a method or function being invoked sho uld resolve to the
837 * element representing the method or function (a {@link ExecutableElement}).</l i>
838 * <li>An identifier denoting a label should resolve to the element representing the label (a{@link LabelElement}).</li>
839 * </ul>
840 * The identifiers within directives are exceptions to this rule and are covered below.</li>
841 * <li>Every node containing a token representing an operator that can be overri dden ({@link BinaryExpression}, {@link PrefixExpression}, {@link PostfixExpressi on}) should resolve to
842 * the element representing the method invoked by that operator (a {@link Method Element}).</li>
843 * <li>Every {@link FunctionExpressionInvocation} should resolve to the element representing the
844 * function being invoked (a {@link FunctionElement}). This will be the same ele ment as that to
845 * which the name is resolved if the function has a name, but is provided for th ose cases where an
846 * unnamed function is being invoked.</li>
847 * <li>Every {@link LibraryDirective} and {@link PartOfDirective} should resolve to the element
848 * representing the library being specified by the directive (a {@link LibraryEl ement}) unless, in
849 * the case of a part-of directive, the specified library does not exist.</li>
850 * <li>Every {@link ImportDirective} and {@link ExportDirective} should resolve to the element
851 * representing the library being specified by the directive unless the specifie d library does not
852 * exist (an {@link ImportElement} or {@link ExportElement}).</li>
853 * <li>The identifier representing the prefix in an {@link ImportDirective} shou ld resolve to the
854 * element representing the prefix (a {@link PrefixElement}).</li>
855 * <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,
856 * respectively, unless those names are not defined in the specified library (or the specified
857 * library does not exist).</li>
858 * <li>Every {@link PartDirective} should resolve to the element representing th e compilation unit
859 * being specified by the string unless the specified compilation unit does not exist (a{@link CompilationUnitElement}).</li>
860 * </ol>
861 * Note that AST nodes that would represent elements that are not defined are no t resolved to
862 * anything. This includes such things as references to undeclared variables (wh ich is an error) and
863 * names in hide and show combinators that are not defined in the imported libra ry (which is not an
864 * error).
865 * @coverage dart.engine.resolver
866 */
867 class ElementResolver extends SimpleASTVisitor<Object> {
868 /**
869 * The resolver driving this participant.
870 */
871 ResolverVisitor _resolver;
872 /**
873 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
874 * @param resolver the resolver driving this participant
875 */
876 ElementResolver(ResolverVisitor resolver) {
877 this._resolver = resolver;
878 }
879 Object visitAssignmentExpression(AssignmentExpression node) {
880 sc.TokenType operator7 = node.operator.type;
881 if (operator7 != sc.TokenType.EQ) {
882 operator7 = operatorFromCompoundAssignment(operator7);
883 Expression leftNode = node.leftHandSide;
884 if (leftNode != null) {
885 Type2 leftType = leftNode.staticType;
886 if (leftType != null) {
887 Element leftElement = leftType.element;
888 if (leftElement != null) {
889 MethodElement method = lookUpMethod(leftElement, operator7.lexeme);
890 if (method != null) {
891 node.element = method;
892 } else {
893 }
894 }
895 }
896 }
897 }
898 return null;
899 }
900 Object visitBinaryExpression(BinaryExpression node) {
901 sc.Token operator8 = node.operator;
902 if (operator8.isUserDefinableOperator()) {
903 Type2 leftType = getType(node.leftOperand);
904 Element leftTypeElement;
905 if (leftType == null || leftType.isDynamic()) {
906 return null;
907 } else if (leftType is FunctionType) {
908 leftTypeElement = _resolver.typeProvider.functionType.element;
909 } else {
910 leftTypeElement = leftType.element;
911 }
912 String methodName = operator8.lexeme;
913 MethodElement member = lookUpMethod(leftTypeElement, methodName);
914 if (member == null) {
915 _resolver.reportError3(ResolverErrorCode.CANNOT_BE_RESOLVED, operator8, [methodName]);
916 } else {
917 node.element = member;
918 }
919 }
920 return null;
921 }
922 Object visitBreakStatement(BreakStatement node) {
923 SimpleIdentifier labelNode = node.label;
924 LabelElementImpl labelElement = lookupLabel(node, labelNode);
925 if (labelElement != null && labelElement.isOnSwitchMember()) {
926 _resolver.reportError(ResolverErrorCode.BREAK_LABEL_ON_SWITCH_MEMBER, labe lNode, []);
927 }
928 return null;
929 }
930 Object visitConstructorName(ConstructorName node) {
931 Type2 type13 = node.type.type;
932 if (type13 is DynamicTypeImpl) {
933 return null;
934 } else if (type13 is! InterfaceType) {
935 ASTNode parent14 = node.parent;
936 if (parent14 is InstanceCreationExpression) {
937 if (((parent14 as InstanceCreationExpression)).isConst()) {
938 } else {
939 }
940 } else {
941 }
942 return null;
943 }
944 ClassElement classElement = ((type13 as InterfaceType)).element;
945 ConstructorElement constructor;
946 SimpleIdentifier name14 = node.name;
947 if (name14 == null) {
948 constructor = classElement.unnamedConstructor;
949 } else {
950 constructor = classElement.getNamedConstructor(name14.name);
951 name14.element = constructor;
952 }
953 node.element = constructor;
954 return null;
955 }
956 Object visitContinueStatement(ContinueStatement node) {
957 SimpleIdentifier labelNode = node.label;
958 LabelElementImpl labelElement = lookupLabel(node, labelNode);
959 if (labelElement != null && labelElement.isOnSwitchStatement()) {
960 _resolver.reportError(ResolverErrorCode.CONTINUE_LABEL_ON_SWITCH, labelNod e, []);
961 }
962 return null;
963 }
964 Object visitExportDirective(ExportDirective node) {
965 Element element21 = node.element;
966 if (element21 is ExportElement) {
967 resolveCombinators(((element21 as ExportElement)).exportedLibrary, node.co mbinators);
968 }
969 return null;
970 }
971 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => null;
972 Object visitImportDirective(ImportDirective node) {
973 SimpleIdentifier prefixNode = node.prefix;
974 if (prefixNode != null) {
975 String prefixName = prefixNode.name;
976 for (PrefixElement prefixElement in _resolver.definingLibrary.prefixes) {
977 if (prefixElement.name == prefixName) {
978 recordResolution(prefixNode, prefixElement);
979 break;
980 }
981 }
982 }
983 Element element22 = node.element;
984 if (element22 is ImportElement) {
985 resolveCombinators(((element22 as ImportElement)).importedLibrary, node.co mbinators);
986 }
987 return null;
988 }
989 Object visitIndexExpression(IndexExpression node) {
990 Type2 arrayType = getType(node.realTarget);
991 if (arrayType == null || arrayType.isDynamic()) {
992 return null;
993 }
994 Element arrayTypeElement = arrayType.element;
995 String operator;
996 if (node.inSetterContext()) {
997 operator = sc.TokenType.INDEX_EQ.lexeme;
998 } else {
999 operator = sc.TokenType.INDEX.lexeme;
1000 }
1001 MethodElement member = lookUpMethod(arrayTypeElement, operator);
1002 if (member == null) {
1003 _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, node, [operato r]);
1004 } else {
1005 node.element = member;
1006 }
1007 return null;
1008 }
1009 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
1010 ConstructorElement invokedConstructor = node.constructorName.element;
1011 node.element = invokedConstructor;
1012 resolveNamedArguments(node.argumentList, invokedConstructor);
1013 return null;
1014 }
1015 Object visitMethodInvocation(MethodInvocation node) {
1016 SimpleIdentifier methodName2 = node.methodName;
1017 Expression target = node.realTarget;
1018 Element element;
1019 if (target == null) {
1020 element = _resolver.nameScope.lookup(methodName2, _resolver.definingLibrar y);
1021 if (element == null) {
1022 element = lookUpMethod(_resolver.enclosingClass, methodName2.name);
1023 if (element == null) {
1024 PropertyAccessorElement getter = lookUpGetter(_resolver.enclosingClass , methodName2.name);
1025 if (getter != null) {
1026 FunctionType getterType = getter.type;
1027 if (getterType != null) {
1028 Type2 returnType4 = getterType.returnType;
1029 if (!returnType4.isDynamic() && returnType4 is! FunctionType && !r eturnType4.isDartCoreFunction()) {
1030 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FU NCTION, methodName2, [methodName2.name]);
1031 }
1032 }
1033 recordResolution(methodName2, getter);
1034 return null;
1035 }
1036 }
1037 }
1038 } else {
1039 Type2 targetType = getType(target);
1040 if (targetType is InterfaceType) {
1041 element = lookUpMethod(targetType.element, methodName2.name);
1042 if (element == null) {
1043 PropertyAccessorElement accessor = lookUpGetterInType((targetType.elem ent as ClassElement), methodName2.name);
1044 if (accessor != null) {
1045 Type2 returnType5 = accessor.type.returnType;
1046 if (!returnType5.isDynamic() && returnType5 is! FunctionType && !ret urnType5.isDartCoreFunction()) {
1047 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNC TION, methodName2, [methodName2.name]);
1048 return null;
1049 }
1050 element = accessor;
1051 }
1052 }
1053 if (element == null && target is SuperExpression) {
1054 _resolver.reportError(StaticTypeWarningCode.UNDEFINED_SUPER_METHOD, me thodName2, [methodName2.name, targetType.element.name]);
1055 return null;
1056 }
1057 } else if (target is SimpleIdentifier) {
1058 Element targetElement = ((target as SimpleIdentifier)).element;
1059 if (targetElement is PrefixElement) {
1060 String name9 = "${((target as SimpleIdentifier)).name}.${methodName2}" ;
1061 Identifier functionName = new Identifier_4(name9);
1062 element = _resolver.nameScope.lookup(functionName, _resolver.definingL ibrary);
1063 } else {
1064 return null;
1065 }
1066 } else {
1067 return null;
1068 }
1069 }
1070 ExecutableElement invokedMethod = null;
1071 if (element is ExecutableElement) {
1072 invokedMethod = element as ExecutableElement;
1073 } else {
1074 if (element is PropertyInducingElement) {
1075 PropertyAccessorElement getter3 = ((element as PropertyInducingElement)) .getter;
1076 FunctionType getterType = getter3.type;
1077 if (getterType != null) {
1078 Type2 returnType6 = getterType.returnType;
1079 if (!returnType6.isDynamic() && returnType6 is! FunctionType && !retur nType6.isDartCoreFunction()) {
1080 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTI ON, methodName2, [methodName2.name]);
1081 }
1082 }
1083 recordResolution(methodName2, element);
1084 return null;
1085 } else if (element is VariableElement) {
1086 Type2 variableType = ((element as VariableElement)).type;
1087 if (!variableType.isDynamic() && variableType is! FunctionType && !varia bleType.isDartCoreFunction()) {
1088 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION , methodName2, [methodName2.name]);
1089 }
1090 recordResolution(methodName2, element);
1091 return null;
1092 } else {
1093 _resolver.reportError(StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION, methodName2, [methodName2.name]);
1094 return null;
1095 }
1096 }
1097 recordResolution(methodName2, invokedMethod);
1098 resolveNamedArguments(node.argumentList, invokedMethod);
1099 return null;
1100 }
1101 Object visitPostfixExpression(PostfixExpression node) {
1102 sc.Token operator9 = node.operator;
1103 Type2 operandType = getType(node.operand);
1104 if (operandType == null || operandType.isDynamic()) {
1105 return null;
1106 }
1107 Element operandTypeElement = operandType.element;
1108 String methodName;
1109 if (identical(operator9.type, sc.TokenType.PLUS_PLUS)) {
1110 methodName = sc.TokenType.PLUS.lexeme;
1111 } else {
1112 methodName = sc.TokenType.MINUS.lexeme;
1113 }
1114 MethodElement member = lookUpMethod(operandTypeElement, methodName);
1115 if (member == null) {
1116 _resolver.reportError3(ResolverErrorCode.CANNOT_BE_RESOLVED, operator9, [m ethodName]);
1117 } else {
1118 node.element = member;
1119 }
1120 return null;
1121 }
1122 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
1123 SimpleIdentifier prefix6 = node.prefix;
1124 SimpleIdentifier identifier13 = node.identifier;
1125 Element prefixElement = prefix6.element;
1126 if (prefixElement is PrefixElement) {
1127 Element element = _resolver.nameScope.lookup(node, _resolver.definingLibra ry);
1128 if (element == null) {
1129 return null;
1130 }
1131 recordResolution(identifier13, element);
1132 return null;
1133 }
1134 if (prefixElement is ClassElement) {
1135 Element memberElement;
1136 if (node.identifier.inSetterContext()) {
1137 memberElement = lookUpSetterInType((prefixElement as ClassElement), iden tifier13.name);
1138 } else {
1139 memberElement = lookUpGetterInType((prefixElement as ClassElement), iden tifier13.name);
1140 }
1141 if (memberElement == null) {
1142 MethodElement methodElement = lookUpMethod(prefixElement, identifier13.n ame);
1143 if (methodElement != null) {
1144 recordResolution(identifier13, methodElement);
1145 return null;
1146 }
1147 }
1148 if (memberElement == null) {
1149 reportGetterOrSetterNotFound(node, identifier13, prefixElement.name);
1150 } else {
1151 recordResolution(identifier13, memberElement);
1152 }
1153 return null;
1154 }
1155 Element variableTypeElement;
1156 if (prefixElement is PropertyAccessorElement) {
1157 PropertyAccessorElement accessor = prefixElement as PropertyAccessorElemen t;
1158 FunctionType type14 = accessor.type;
1159 if (type14 == null) {
1160 return null;
1161 }
1162 Type2 variableType;
1163 if (accessor.isGetter()) {
1164 variableType = type14.returnType;
1165 } else {
1166 variableType = type14.normalParameterTypes[0];
1167 }
1168 if (variableType == null || variableType.isDynamic()) {
1169 return null;
1170 }
1171 variableTypeElement = variableType.element;
1172 } else if (prefixElement is VariableElement) {
1173 Type2 prefixType = ((prefixElement as VariableElement)).type;
1174 if (prefixType == null || prefixType.isDynamic()) {
1175 return null;
1176 }
1177 variableTypeElement = prefixType.element;
1178 } else {
1179 return null;
1180 }
1181 PropertyAccessorElement memberElement = null;
1182 if (node.identifier.inSetterContext()) {
1183 memberElement = lookUpSetter(variableTypeElement, identifier13.name);
1184 }
1185 if (memberElement == null && node.identifier.inGetterContext()) {
1186 memberElement = lookUpGetter(variableTypeElement, identifier13.name);
1187 }
1188 if (memberElement == null) {
1189 MethodElement methodElement = lookUpMethod(variableTypeElement, identifier 13.name);
1190 if (methodElement != null) {
1191 recordResolution(identifier13, methodElement);
1192 return null;
1193 }
1194 }
1195 if (memberElement == null) {
1196 reportGetterOrSetterNotFound(node, identifier13, variableTypeElement.name) ;
1197 } else {
1198 recordResolution(identifier13, memberElement);
1199 }
1200 return null;
1201 }
1202 Object visitPrefixExpression(PrefixExpression node) {
1203 sc.Token operator10 = node.operator;
1204 sc.TokenType operatorType = operator10.type;
1205 if (operatorType.isUserDefinableOperator() || identical(operatorType, sc.Tok enType.PLUS_PLUS) || identical(operatorType, sc.TokenType.MINUS_MINUS)) {
1206 Type2 operandType = getType(node.operand);
1207 if (operandType == null || operandType.isDynamic()) {
1208 return null;
1209 }
1210 Element operandTypeElement = operandType.element;
1211 String methodName;
1212 if (identical(operatorType, sc.TokenType.PLUS_PLUS)) {
1213 methodName = sc.TokenType.PLUS.lexeme;
1214 } else if (identical(operatorType, sc.TokenType.MINUS_MINUS)) {
1215 methodName = sc.TokenType.MINUS.lexeme;
1216 } else if (identical(operatorType, sc.TokenType.MINUS)) {
1217 methodName = "unary-";
1218 } else {
1219 methodName = operator10.lexeme;
1220 }
1221 MethodElement member = lookUpMethod(operandTypeElement, methodName);
1222 if (member == null) {
1223 _resolver.reportError3(ResolverErrorCode.CANNOT_BE_RESOLVED, operator10, [methodName]);
1224 } else {
1225 node.element = member;
1226 }
1227 }
1228 return null;
1229 }
1230 Object visitPropertyAccess(PropertyAccess node) {
1231 Type2 targetType = getType(node.realTarget);
1232 if (targetType is! InterfaceType) {
1233 return null;
1234 }
1235 ClassElement targetElement = ((targetType as InterfaceType)).element;
1236 SimpleIdentifier identifier = node.propertyName;
1237 PropertyAccessorElement memberElement = null;
1238 if (identifier.inSetterContext()) {
1239 memberElement = lookUpSetter(targetElement, identifier.name);
1240 }
1241 if (memberElement == null && identifier.inGetterContext()) {
1242 memberElement = lookUpGetter(targetElement, identifier.name);
1243 }
1244 if (memberElement == null) {
1245 MethodElement methodElement = lookUpMethod(targetElement, identifier.name) ;
1246 if (methodElement != null) {
1247 recordResolution(identifier, methodElement);
1248 return null;
1249 }
1250 }
1251 if (memberElement == null) {
1252 _resolver.reportError(ResolverErrorCode.CANNOT_BE_RESOLVED, identifier, [i dentifier.name]);
1253 } else {
1254 recordResolution(identifier, memberElement);
1255 }
1256 return null;
1257 }
1258 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
1259 ClassElement enclosingClass2 = _resolver.enclosingClass;
1260 if (enclosingClass2 == null) {
1261 return null;
1262 }
1263 SimpleIdentifier name = node.constructorName;
1264 ConstructorElement element;
1265 if (name == null) {
1266 element = enclosingClass2.unnamedConstructor;
1267 } else {
1268 element = enclosingClass2.getNamedConstructor(name.name);
1269 }
1270 if (element == null) {
1271 return null;
1272 }
1273 if (name != null) {
1274 recordResolution(name, element);
1275 }
1276 node.element = element;
1277 resolveNamedArguments(node.argumentList, element);
1278 return null;
1279 }
1280 Object visitSimpleIdentifier(SimpleIdentifier node) {
1281 if (node.element != null) {
1282 return null;
1283 }
1284 Element element = _resolver.nameScope.lookup(node, _resolver.definingLibrary );
1285 if (element is PropertyAccessorElement && node.inSetterContext()) {
1286 PropertyInducingElement variable4 = ((element as PropertyAccessorElement)) .variable;
1287 if (variable4 != null) {
1288 PropertyAccessorElement setter3 = variable4.setter;
1289 if (setter3 != null) {
1290 element = setter3;
1291 }
1292 }
1293 }
1294 if (element == null && node.inSetterContext()) {
1295 element = lookUpSetter(_resolver.enclosingClass, node.name);
1296 }
1297 if (element == null && node.inGetterContext()) {
1298 element = lookUpGetter(_resolver.enclosingClass, node.name);
1299 }
1300 if (element == null) {
1301 element = lookUpMethod(_resolver.enclosingClass, node.name);
1302 }
1303 if (element == null) {
1304 }
1305 recordResolution(node, element);
1306 return null;
1307 }
1308 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
1309 ClassElement enclosingClass3 = _resolver.enclosingClass;
1310 if (enclosingClass3 == null) {
1311 return null;
1312 }
1313 ClassElement superclass = getSuperclass(enclosingClass3);
1314 if (superclass == null) {
1315 return null;
1316 }
1317 SimpleIdentifier name = node.constructorName;
1318 ConstructorElement element;
1319 if (name == null) {
1320 element = superclass.unnamedConstructor;
1321 } else {
1322 element = superclass.getNamedConstructor(name.name);
1323 }
1324 if (element == null) {
1325 return null;
1326 }
1327 if (name != null) {
1328 recordResolution(name, element);
1329 }
1330 node.element = element;
1331 resolveNamedArguments(node.argumentList, element);
1332 return null;
1333 }
1334 Object visitTypeParameter(TypeParameter node) {
1335 TypeName bound3 = node.bound;
1336 if (bound3 != null) {
1337 TypeVariableElementImpl variable = node.name.element as TypeVariableElemen tImpl;
1338 if (variable != null) {
1339 variable.bound = bound3.type;
1340 }
1341 }
1342 return null;
1343 }
1344 /**
1345 * Search through the array of parameters for a parameter whose name matches t he given name.
1346 * Return the parameter with the given name, or {@code null} if there is no su ch parameter.
1347 * @param parameters the parameters being searched
1348 * @param name the name being searched for
1349 * @return the parameter with the given name
1350 */
1351 ParameterElement findNamedParameter(List<ParameterElement> parameters, String name25) {
1352 for (ParameterElement parameter in parameters) {
1353 if (identical(parameter.parameterKind, ParameterKind.NAMED)) {
1354 String parameteName = parameter.name;
1355 if (parameteName != null && parameteName == name25) {
1356 return parameter;
1357 }
1358 }
1359 }
1360 return null;
1361 }
1362 /**
1363 * Return the element representing the superclass of the given class.
1364 * @param targetClass the class whose superclass is to be returned
1365 * @return the element representing the superclass of the given class
1366 */
1367 ClassElement getSuperclass(ClassElement targetClass) {
1368 InterfaceType superType = targetClass.supertype;
1369 if (superType == null) {
1370 return null;
1371 }
1372 return superType.element;
1373 }
1374 /**
1375 * Return the type of the given expression that is to be used for type analysi s.
1376 * @param expression the expression whose type is to be returned
1377 * @return the type of the given expression
1378 */
1379 Type2 getType(Expression expression) {
1380 if (expression is NullLiteral) {
1381 return _resolver.typeProvider.objectType;
1382 }
1383 return expression.staticType;
1384 }
1385 /**
1386 * Look up the getter with the given name in the given type. Return the elemen t representing the
1387 * getter that was found, or {@code null} if there is no getter with the given name.
1388 * @param element the element representing the type in which the getter is def ined
1389 * @param getterName the name of the getter being looked up
1390 * @return the element representing the getter that was found
1391 */
1392 PropertyAccessorElement lookUpGetter(Element element, String getterName) {
1393 if (identical(element, DynamicTypeImpl.instance)) {
1394 return null;
1395 }
1396 element = resolveTypeVariable(element);
1397 if (element is ClassElement) {
1398 ClassElement classElement = element as ClassElement;
1399 PropertyAccessorElement member = classElement.lookUpGetter(getterName, _re solver.definingLibrary);
1400 if (member != null) {
1401 return member;
1402 }
1403 return lookUpGetterInInterfaces((element as ClassElement), getterName, new Set<ClassElement>());
1404 }
1405 return null;
1406 }
1407 /**
1408 * Look up the name of a getter in the interfaces implemented by the given typ e, either directly
1409 * or indirectly. Return the element representing the getter that was found, o r {@code null} if
1410 * there is no getter with the given name.
1411 * @param element the element representing the type in which the getter is def ined
1412 * @param memberName the name of the getter being looked up
1413 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used
1414 * to prevent infinite recursion and to optimize the search
1415 * @return the element representing the getter that was found
1416 */
1417 PropertyAccessorElement lookUpGetterInInterfaces(ClassElement targetClass, Str ing memberName, Set<ClassElement> visitedInterfaces) {
1418 if (visitedInterfaces.contains(targetClass)) {
1419 return null;
1420 }
1421 javaSetAdd(visitedInterfaces, targetClass);
1422 PropertyAccessorElement member = lookUpGetterInType(targetClass, memberName) ;
1423 if (member != null) {
1424 return member;
1425 }
1426 for (InterfaceType interfaceType in targetClass.interfaces) {
1427 member = lookUpGetterInInterfaces(interfaceType.element, memberName, visit edInterfaces);
1428 if (member != null) {
1429 return member;
1430 }
1431 }
1432 ClassElement superclass = getSuperclass(targetClass);
1433 if (superclass == null) {
1434 return null;
1435 }
1436 return lookUpGetterInInterfaces(superclass, memberName, visitedInterfaces);
1437 }
1438 /**
1439 * Look up the name of a getter in the given type. Return the element represen ting the getter that
1440 * was found, or {@code null} if there is no getter with the given name.
1441 * @param element the element representing the type in which the getter is def ined
1442 * @param memberName the name of the getter being looked up
1443 * @return the element representing the getter that was found
1444 */
1445 PropertyAccessorElement lookUpGetterInType(ClassElement element, String member Name) {
1446 for (PropertyAccessorElement accessor in element.accessors) {
1447 if (accessor.isGetter() && accessor.name == memberName) {
1448 return accessor;
1449 }
1450 }
1451 return null;
1452 }
1453 /**
1454 * Find the element corresponding to the given label node in the current label scope.
1455 * @param parentNode the node containing the given label
1456 * @param labelNode the node representing the label being looked up
1457 * @return the element corresponding to the given label node in the current sc ope
1458 */
1459 LabelElementImpl lookupLabel(ASTNode parentNode, SimpleIdentifier labelNode) {
1460 LabelScope labelScope2 = _resolver.labelScope;
1461 LabelElementImpl labelElement = null;
1462 if (labelNode == null) {
1463 if (labelScope2 == null) {
1464 } else {
1465 labelElement = labelScope2.lookup2(LabelScope.EMPTY_LABEL) as LabelEleme ntImpl;
1466 if (labelElement == null) {
1467 }
1468 labelElement = null;
1469 }
1470 } else {
1471 if (labelScope2 == null) {
1472 _resolver.reportError(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [ labelNode.name]);
1473 } else {
1474 labelElement = labelScope2.lookup(labelNode) as LabelElementImpl;
1475 if (labelElement == null) {
1476 _resolver.reportError(CompileTimeErrorCode.LABEL_UNDEFINED, labelNode, [labelNode.name]);
1477 } else {
1478 recordResolution(labelNode, labelElement);
1479 }
1480 }
1481 }
1482 if (labelElement != null) {
1483 ExecutableElement labelContainer = labelElement.getAncestor(ExecutableElem ent);
1484 if (labelContainer != _resolver.enclosingFunction) {
1485 _resolver.reportError(CompileTimeErrorCode.LABEL_IN_OUTER_SCOPE, labelNo de, [labelNode.name]);
1486 labelElement = null;
1487 }
1488 }
1489 return labelElement;
1490 }
1491 /**
1492 * Look up the method with the given name in the given type. Return the elemen t representing the
1493 * method that was found, or {@code null} if there is no method with the given name.
1494 * @param element the element representing the type in which the method is def ined
1495 * @param methodName the name of the method being looked up
1496 * @return the element representing the method that was found
1497 */
1498 MethodElement lookUpMethod(Element element, String methodName) {
1499 if (identical(element, DynamicTypeImpl.instance)) {
1500 return null;
1501 }
1502 element = resolveTypeVariable(element);
1503 if (element is ClassElement) {
1504 ClassElement classElement = element as ClassElement;
1505 MethodElement member = classElement.lookUpMethod(methodName, _resolver.def iningLibrary);
1506 if (member != null) {
1507 return member;
1508 }
1509 return lookUpMethodInInterfaces((element as ClassElement), methodName, new Set<ClassElement>());
1510 }
1511 return null;
1512 }
1513 /**
1514 * Look up the name of a member in the interfaces implemented by the given typ e, either directly
1515 * or indirectly. Return the element representing the member that was found, o r {@code null} if
1516 * there is no member with the given name.
1517 * @param element the element representing the type in which the member is def ined
1518 * @param memberName the name of the member being looked up
1519 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used
1520 * to prevent infinite recursion and to optimize the search
1521 * @return the element representing the member that was found
1522 */
1523 MethodElement lookUpMethodInInterfaces(ClassElement targetClass, String member Name, Set<ClassElement> visitedInterfaces) {
1524 if (visitedInterfaces.contains(targetClass)) {
1525 return null;
1526 }
1527 javaSetAdd(visitedInterfaces, targetClass);
1528 MethodElement member = lookUpMethodInType(targetClass, memberName);
1529 if (member != null) {
1530 return member;
1531 }
1532 for (InterfaceType interfaceType in targetClass.interfaces) {
1533 member = lookUpMethodInInterfaces(interfaceType.element, memberName, visit edInterfaces);
1534 if (member != null) {
1535 return member;
1536 }
1537 }
1538 ClassElement superclass = getSuperclass(targetClass);
1539 if (superclass == null) {
1540 return null;
1541 }
1542 return lookUpMethodInInterfaces(superclass, memberName, visitedInterfaces);
1543 }
1544 /**
1545 * Look up the name of a method in the given type. Return the element represen ting the method that
1546 * was found, or {@code null} if there is no method with the given name.
1547 * @param element the element representing the type in which the method is def ined
1548 * @param memberName the name of the method being looked up
1549 * @return the element representing the method that was found
1550 */
1551 MethodElement lookUpMethodInType(ClassElement element, String memberName) {
1552 for (MethodElement method in element.methods) {
1553 if (method.name == memberName) {
1554 return method;
1555 }
1556 }
1557 return null;
1558 }
1559 /**
1560 * Look up the setter with the given name in the given type. Return the elemen t representing the
1561 * setter that was found, or {@code null} if there is no setter with the given name.
1562 * @param element the element representing the type in which the setter is def ined
1563 * @param setterName the name of the setter being looked up
1564 * @return the element representing the setter that was found
1565 */
1566 PropertyAccessorElement lookUpSetter(Element element, String setterName) {
1567 if (identical(element, DynamicTypeImpl.instance)) {
1568 return null;
1569 }
1570 element = resolveTypeVariable(element);
1571 if (element is ClassElement) {
1572 ClassElement classElement = element as ClassElement;
1573 PropertyAccessorElement member = classElement.lookUpSetter(setterName, _re solver.definingLibrary);
1574 if (member != null) {
1575 return member;
1576 }
1577 return lookUpSetterInInterfaces((element as ClassElement), setterName, new Set<ClassElement>());
1578 }
1579 return null;
1580 }
1581 /**
1582 * Look up the name of a setter in the interfaces implemented by the given typ e, either directly
1583 * or indirectly. Return the element representing the setter that was found, o r {@code null} if
1584 * there is no setter with the given name.
1585 * @param element the element representing the type in which the setter is def ined
1586 * @param memberName the name of the setter being looked up
1587 * @param visitedInterfaces a set containing all of the interfaces that have b een examined, used
1588 * to prevent infinite recursion and to optimize the search
1589 * @return the element representing the setter that was found
1590 */
1591 PropertyAccessorElement lookUpSetterInInterfaces(ClassElement targetClass, Str ing memberName, Set<ClassElement> visitedInterfaces) {
1592 if (visitedInterfaces.contains(targetClass)) {
1593 return null;
1594 }
1595 javaSetAdd(visitedInterfaces, targetClass);
1596 PropertyAccessorElement member = lookUpSetterInType(targetClass, memberName) ;
1597 if (member != null) {
1598 return member;
1599 }
1600 for (InterfaceType interfaceType in targetClass.interfaces) {
1601 member = lookUpSetterInInterfaces(interfaceType.element, memberName, visit edInterfaces);
1602 if (member != null) {
1603 return member;
1604 }
1605 }
1606 ClassElement superclass = getSuperclass(targetClass);
1607 if (superclass == null) {
1608 return null;
1609 }
1610 return lookUpSetterInInterfaces(superclass, memberName, visitedInterfaces);
1611 }
1612 /**
1613 * Look up the name of a setter in the given type. Return the element represen ting the setter that
1614 * was found, or {@code null} if there is no setter with the given name.
1615 * @param element the element representing the type in which the setter is def ined
1616 * @param memberName the name of the setter being looked up
1617 * @return the element representing the setter that was found
1618 */
1619 PropertyAccessorElement lookUpSetterInType(ClassElement element, String member Name) {
1620 for (PropertyAccessorElement accessor in element.accessors) {
1621 if (accessor.isSetter() && accessor.name == memberName) {
1622 return accessor;
1623 }
1624 }
1625 return null;
1626 }
1627 /**
1628 * Return the binary operator that is invoked by the given compound assignment operator.
1629 * @param operator the assignment operator being mapped
1630 * @return the binary operator that invoked by the given assignment operator
1631 */
1632 sc.TokenType operatorFromCompoundAssignment(sc.TokenType operator) {
1633 while (true) {
1634 if (operator == sc.TokenType.AMPERSAND_EQ) {
1635 return sc.TokenType.AMPERSAND;
1636 } else if (operator == sc.TokenType.BAR_EQ) {
1637 return sc.TokenType.BAR;
1638 } else if (operator == sc.TokenType.CARET_EQ) {
1639 return sc.TokenType.CARET;
1640 } else if (operator == sc.TokenType.GT_GT_EQ) {
1641 return sc.TokenType.GT_GT;
1642 } else if (operator == sc.TokenType.LT_LT_EQ) {
1643 return sc.TokenType.LT_LT;
1644 } else if (operator == sc.TokenType.MINUS_EQ) {
1645 return sc.TokenType.MINUS;
1646 } else if (operator == sc.TokenType.PERCENT_EQ) {
1647 return sc.TokenType.PERCENT;
1648 } else if (operator == sc.TokenType.PLUS_EQ) {
1649 return sc.TokenType.PLUS;
1650 } else if (operator == sc.TokenType.SLASH_EQ) {
1651 return sc.TokenType.SLASH;
1652 } else if (operator == sc.TokenType.STAR_EQ) {
1653 return sc.TokenType.STAR;
1654 } else if (operator == sc.TokenType.TILDE_SLASH_EQ) {
1655 return sc.TokenType.TILDE_SLASH;
1656 }
1657 break;
1658 }
1659 AnalysisEngine.instance.logger.logError("Failed to map ${operator.lexeme} to it's corresponding operator");
1660 return operator;
1661 }
1662 /**
1663 * Record the fact that the given AST node was resolved to the given element.
1664 * @param node the AST node that was resolved
1665 * @param element the element to which the AST node was resolved
1666 */
1667 void recordResolution(SimpleIdentifier node, Element element49) {
1668 if (element49 != null) {
1669 node.element = element49;
1670 }
1671 }
1672 /**
1673 * Report the {@link StaticTypeWarningCode}s <code>UNDEFINED_SETTER</code> and
1674 * <code>UNDEFINED_GETTER</code>.
1675 * @param node the prefixed identifier that gives the context to determine if the error on the
1676 * undefined identifier is a getter or a setter
1677 * @param identifier the identifier in the passed prefix identifier
1678 * @param typeName the name of the type of the left hand side of the passed pr efixed identifier
1679 */
1680 void reportGetterOrSetterNotFound(PrefixedIdentifier node, SimpleIdentifier id entifier30, String typeName) {
1681 bool isSetterContext = node.identifier.inSetterContext();
1682 ErrorCode errorCode = isSetterContext ? StaticTypeWarningCode.UNDEFINED_SETT ER : StaticTypeWarningCode.UNDEFINED_GETTER;
1683 _resolver.reportError(errorCode, identifier30, [identifier30.name, typeName] );
1684 }
1685 /**
1686 * Resolve the names in the given combinators in the scope of the given librar y.
1687 * @param library the library that defines the names
1688 * @param combinators the combinators containing the names to be resolved
1689 */
1690 void resolveCombinators(LibraryElement library, NodeList<Combinator> combinato rs) {
1691 if (library == null) {
1692 return;
1693 }
1694 Namespace namespace = new NamespaceBuilder().createExportNamespace(library);
1695 for (Combinator combinator in combinators) {
1696 NodeList<SimpleIdentifier> names;
1697 if (combinator is HideCombinator) {
1698 names = ((combinator as HideCombinator)).hiddenNames;
1699 } else {
1700 names = ((combinator as ShowCombinator)).shownNames;
1701 }
1702 for (SimpleIdentifier name in names) {
1703 Element element = namespace.get(name.name);
1704 if (element != null) {
1705 name.element = element;
1706 }
1707 }
1708 }
1709 }
1710 /**
1711 * Resolve the names associated with any named arguments to the parameter elem ents named by the
1712 * argument.
1713 * @param argumentList the arguments to be resolved
1714 * @param invokedMethod the method or function defining the parameters to whic h the named
1715 * arguments are to be resolved
1716 */
1717 void resolveNamedArguments(ArgumentList argumentList, ExecutableElement invoke dMethod) {
1718 if (invokedMethod == null) {
1719 return;
1720 }
1721 List<ParameterElement> parameters11 = invokedMethod.parameters;
1722 for (Expression argument in argumentList.arguments) {
1723 if (argument is NamedExpression) {
1724 SimpleIdentifier name15 = ((argument as NamedExpression)).name.label;
1725 ParameterElement parameter = findNamedParameter(parameters11, name15.nam e);
1726 if (parameter != null) {
1727 recordResolution(name15, parameter);
1728 }
1729 }
1730 }
1731 }
1732 /**
1733 * If the given element is a type variable, resolve it to the class that shoul d be used when
1734 * looking up members. Otherwise, return the original element.
1735 * @param element the element that is to be resolved if it is a type variable
1736 * @return the class that should be used in place of the argument if it is a t ype variable, or the
1737 * original argument if it isn't a type variable
1738 */
1739 Element resolveTypeVariable(Element element50) {
1740 if (element50 is TypeVariableElement) {
1741 Type2 bound4 = ((element50 as TypeVariableElement)).bound;
1742 if (bound4 == null) {
1743 return _resolver.typeProvider.objectType.element;
1744 }
1745 return bound4.element;
1746 }
1747 return element50;
1748 }
1749 }
1750 class Identifier_4 extends Identifier {
1751 String name9;
1752 Identifier_4(this.name9) : super();
1753 accept(ASTVisitor visitor) => null;
1754 sc.Token get beginToken => null;
1755 Element get element => null;
1756 sc.Token get endToken => null;
1757 String get name => name9;
1758 void visitChildren(ASTVisitor<Object> visitor) {
1759 }
1760 }
1761 /**
1762 * Instances of the class {@code Library} represent the data about a single libr ary during the
1763 * resolution of some (possibly different) library. They are not intended to be used except during
1764 * the resolution process.
1765 * @coverage dart.engine.resolver
1766 */
1767 class Library {
1768 /**
1769 * The analysis context in which this library is being analyzed.
1770 */
1771 AnalysisContextImpl _analysisContext;
1772 /**
1773 * The listener to which analysis errors will be reported.
1774 */
1775 AnalysisErrorListener _errorListener;
1776 /**
1777 * The source specifying the defining compilation unit of this library.
1778 */
1779 Source _librarySource;
1780 /**
1781 * The library element representing this library.
1782 */
1783 LibraryElementImpl _libraryElement;
1784 /**
1785 * A list containing all of the libraries that are imported into this library.
1786 */
1787 Map<ImportDirective, Library> _importedLibraries = new Map<ImportDirective, Li brary>();
1788 /**
1789 * A flag indicating whether this library explicitly imports core.
1790 */
1791 bool _explicitlyImportsCore = false;
1792 /**
1793 * A list containing all of the libraries that are exported from this library.
1794 */
1795 Map<ExportDirective, Library> _exportedLibraries = new Map<ExportDirective, Li brary>();
1796 /**
1797 * A table mapping the sources for the compilation units in this library to th eir corresponding
1798 * AST structures.
1799 */
1800 Map<Source, CompilationUnit> _astMap = new Map<Source, CompilationUnit>();
1801 /**
1802 * The library scope used when resolving elements within this library's compil ation units.
1803 */
1804 LibraryScope _libraryScope;
1805 /**
1806 * Initialize a newly created data holder that can maintain the data associate d with a library.
1807 * @param analysisContext the analysis context in which this library is being analyzed
1808 * @param errorListener the listener to which analysis errors will be reported
1809 * @param librarySource the source specifying the defining compilation unit of this library
1810 */
1811 Library(AnalysisContextImpl analysisContext, AnalysisErrorListener errorListen er, Source librarySource) {
1812 this._analysisContext = analysisContext;
1813 this._errorListener = errorListener;
1814 this._librarySource = librarySource;
1815 this._libraryElement = analysisContext.getLibraryElementOrNull(librarySource ) as LibraryElementImpl;
1816 }
1817 /**
1818 * Record that the given library is exported from this library.
1819 * @param importLibrary the library that is exported from this library
1820 */
1821 void addExport(ExportDirective directive, Library exportLibrary) {
1822 _exportedLibraries[directive] = exportLibrary;
1823 }
1824 /**
1825 * Record that the given library is imported into this library.
1826 * @param importLibrary the library that is imported into this library
1827 */
1828 void addImport(ImportDirective directive, Library importLibrary) {
1829 _importedLibraries[directive] = importLibrary;
1830 }
1831 /**
1832 * Return the AST structure associated with the given source.
1833 * @param source the source representing the compilation unit whose AST is to be returned
1834 * @return the AST structure associated with the given source
1835 * @throws AnalysisException if an AST structure could not be created for the compilation unit
1836 */
1837 CompilationUnit getAST(Source source) {
1838 CompilationUnit unit = _astMap[source];
1839 if (unit == null) {
1840 unit = _analysisContext.parse3(source, _errorListener);
1841 _astMap[source] = unit;
1842 }
1843 return unit;
1844 }
1845 /**
1846 * Return a collection containing the sources for the compilation units in thi s library.
1847 * @return the sources for the compilation units in this library
1848 */
1849 Set<Source> get compilationUnitSources => _astMap.keys.toSet();
1850 /**
1851 * Return the AST structure associated with the defining compilation unit for this library.
1852 * @return the AST structure associated with the defining compilation unit for this library
1853 * @throws AnalysisException if an AST structure could not be created for the defining compilation
1854 * unit
1855 */
1856 CompilationUnit get definingCompilationUnit => getAST(librarySource);
1857 /**
1858 * Return {@code true} if this library explicitly imports core.
1859 * @return {@code true} if this library explicitly imports core
1860 */
1861 bool get explicitlyImportsCore => _explicitlyImportsCore;
1862 /**
1863 * Return the library exported by the given directive.
1864 * @param directive the directive that exports the library to be returned
1865 * @return the library exported by the given directive
1866 */
1867 Library getExport(ExportDirective directive) => _exportedLibraries[directive];
1868 /**
1869 * Return an array containing the libraries that are exported from this librar y.
1870 * @return an array containing the libraries that are exported from this libra ry
1871 */
1872 List<Library> get exports {
1873 Set<Library> libraries = new Set<Library>();
1874 libraries.addAll(_exportedLibraries.values);
1875 return new List.from(libraries);
1876 }
1877 /**
1878 * Return the library imported by the given directive.
1879 * @param directive the directive that imports the library to be returned
1880 * @return the library imported by the given directive
1881 */
1882 Library getImport(ImportDirective directive) => _importedLibraries[directive];
1883 /**
1884 * Return an array containing the libraries that are imported into this librar y.
1885 * @return an array containing the libraries that are imported into this libra ry
1886 */
1887 List<Library> get imports {
1888 Set<Library> libraries = new Set<Library>();
1889 libraries.addAll(_importedLibraries.values);
1890 return new List.from(libraries);
1891 }
1892 /**
1893 * Return an array containing the libraries that are either imported or export ed from this
1894 * library.
1895 * @return the libraries that are either imported or exported from this librar y
1896 */
1897 List<Library> get importsAndExports {
1898 Set<Library> libraries = new Set<Library>();
1899 libraries.addAll(_importedLibraries.values);
1900 libraries.addAll(_exportedLibraries.values);
1901 return new List.from(libraries);
1902 }
1903 /**
1904 * Return the library element representing this library, creating it if necess ary.
1905 * @return the library element representing this library
1906 */
1907 LibraryElementImpl get libraryElement {
1908 if (_libraryElement == null) {
1909 _libraryElement = _analysisContext.getLibraryElement(_librarySource) as Li braryElementImpl;
1910 }
1911 return _libraryElement;
1912 }
1913 /**
1914 * Return the library scope used when resolving elements within this library's compilation units.
1915 * @return the library scope used when resolving elements within this library' s compilation units
1916 */
1917 LibraryScope get libraryScope {
1918 if (_libraryScope == null) {
1919 _libraryScope = new LibraryScope(_libraryElement, _errorListener);
1920 }
1921 return _libraryScope;
1922 }
1923 /**
1924 * Return the source specifying the defining compilation unit of this library.
1925 * @return the source specifying the defining compilation unit of this library
1926 */
1927 Source get librarySource => _librarySource;
1928 /**
1929 * Return the result of resolving the given URI against the URI of the library , or {@code null} if
1930 * the URI is not valid. If the URI is not valid, report the error.
1931 * @param uriLiteral the string literal specifying the URI to be resolved
1932 * @return the result of resolving the given URI against the URI of the librar y
1933 */
1934 Source getSource(StringLiteral uriLiteral) {
1935 if (uriLiteral is StringInterpolation) {
1936 _errorListener.onError(new AnalysisError.con2(_librarySource, uriLiteral.o ffset, uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION, []));
1937 return null;
1938 }
1939 return getSource2(getStringValue(uriLiteral));
1940 }
1941 /**
1942 * Set whether this library explicitly imports core to match the given value.
1943 * @param explicitlyImportsCore {@code true} if this library explicitly import s core
1944 */
1945 void set explicitlyImportsCore(bool explicitlyImportsCore2) {
1946 this._explicitlyImportsCore = explicitlyImportsCore2;
1947 }
1948 /**
1949 * Set the library element representing this library to the given library elem ent.
1950 * @param libraryElement the library element representing this library
1951 */
1952 void set libraryElement(LibraryElementImpl libraryElement2) {
1953 this._libraryElement = libraryElement2;
1954 }
1955 String toString() => _librarySource.shortName;
1956 /**
1957 * Append the value of the given string literal to the given string builder.
1958 * @param builder the builder to which the string's value is to be appended
1959 * @param literal the string literal whose value is to be appended to the buil der
1960 * @throws IllegalArgumentException if the string is not a constant string wit hout any string
1961 * interpolation
1962 */
1963 void appendStringValue(JavaStringBuilder builder, StringLiteral literal) {
1964 if (literal is SimpleStringLiteral) {
1965 builder.append(((literal as SimpleStringLiteral)).value);
1966 } else if (literal is AdjacentStrings) {
1967 for (StringLiteral stringLiteral in ((literal as AdjacentStrings)).strings ) {
1968 appendStringValue(builder, stringLiteral);
1969 }
1970 } else {
1971 throw new IllegalArgumentException();
1972 }
1973 }
1974 /**
1975 * Return the result of resolving the given URI against the URI of the library , or {@code null} if
1976 * the URI is not valid.
1977 * @param uri the URI to be resolved
1978 * @return the result of resolving the given URI against the URI of the librar y
1979 */
1980 Source getSource2(String uri) {
1981 if (uri == null) {
1982 return null;
1983 }
1984 return _librarySource.resolve(uri);
1985 }
1986 /**
1987 * Return the value of the given string literal, or {@code null} if the string is not a constant
1988 * string without any string interpolation.
1989 * @param literal the string literal whose value is to be returned
1990 * @return the value of the given string literal
1991 */
1992 String getStringValue(StringLiteral literal) {
1993 JavaStringBuilder builder = new JavaStringBuilder();
1994 try {
1995 appendStringValue(builder, literal);
1996 } on IllegalArgumentException catch (exception) {
1997 return null;
1998 }
1999 return builder.toString().trim();
2000 }
2001 }
2002 /**
2003 * Instances of the class {@code LibraryElementBuilder} build an element model f or a single library.
2004 * @coverage dart.engine.resolver
2005 */
2006 class LibraryElementBuilder {
2007 /**
2008 * The analysis context in which the element model will be built.
2009 */
2010 AnalysisContextImpl _analysisContext;
2011 /**
2012 * The listener to which errors will be reported.
2013 */
2014 AnalysisErrorListener _errorListener;
2015 /**
2016 * The name of the core library.
2017 */
2018 static String CORE_LIBRARY_URI = "dart:core";
2019 /**
2020 * The name of the function used as an entry point.
2021 */
2022 static String _ENTRY_POINT_NAME = "main";
2023 /**
2024 * Initialize a newly created library element builder.
2025 * @param resolver the resolver for which the element model is being built
2026 */
2027 LibraryElementBuilder(LibraryResolver resolver) {
2028 this._analysisContext = resolver.analysisContext;
2029 this._errorListener = resolver.errorListener;
2030 }
2031 /**
2032 * Build the library element for the given library.
2033 * @param library the library for which an element model is to be built
2034 * @return the library element that was built
2035 * @throws AnalysisException if the analysis could not be performed
2036 */
2037 LibraryElementImpl buildLibrary(Library library) {
2038 CompilationUnitBuilder builder = new CompilationUnitBuilder(_analysisContext , _errorListener);
2039 Source librarySource2 = library.librarySource;
2040 CompilationUnit definingCompilationUnit3 = library.definingCompilationUnit;
2041 CompilationUnitElementImpl definingCompilationUnitElement = builder.buildCom pilationUnit2(librarySource2, definingCompilationUnit3);
2042 NodeList<Directive> directives3 = definingCompilationUnit3.directives;
2043 LibraryIdentifier libraryNameNode = null;
2044 bool hasPartDirective = false;
2045 FunctionElement entryPoint = findEntryPoint(definingCompilationUnitElement);
2046 List<Directive> directivesToResolve = new List<Directive>();
2047 List<CompilationUnitElementImpl> sourcedCompilationUnits = new List<Compilat ionUnitElementImpl>();
2048 for (Directive directive in directives3) {
2049 if (directive is LibraryDirective) {
2050 if (libraryNameNode == null) {
2051 libraryNameNode = ((directive as LibraryDirective)).name;
2052 directivesToResolve.add(directive);
2053 }
2054 } else if (directive is PartDirective) {
2055 hasPartDirective = true;
2056 StringLiteral partUri = ((directive as PartDirective)).uri;
2057 Source partSource = library.getSource(partUri);
2058 if (partSource != null) {
2059 CompilationUnitElementImpl part = builder.buildCompilationUnit(partSou rce);
2060 String partLibraryName = getPartLibraryName(library, partSource, direc tivesToResolve);
2061 if (partLibraryName == null) {
2062 _errorListener.onError(new AnalysisError.con2(librarySource2, partUr i.offset, partUri.length, ResolverErrorCode.MISSING_PART_OF_DIRECTIVE, []));
2063 } else if (libraryNameNode == null) {
2064 } else if (libraryNameNode.name != partLibraryName) {
2065 _errorListener.onError(new AnalysisError.con2(librarySource2, partUr i.offset, partUri.length, StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [libraryN ameNode.name, partLibraryName]));
2066 }
2067 if (entryPoint == null) {
2068 entryPoint = findEntryPoint(part);
2069 }
2070 directive.element = part;
2071 sourcedCompilationUnits.add(part);
2072 }
2073 }
2074 }
2075 if (hasPartDirective && libraryNameNode == null) {
2076 _errorListener.onError(new AnalysisError.con1(librarySource2, ResolverErro rCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART, []));
2077 }
2078 LibraryElementImpl libraryElement = new LibraryElementImpl(_analysisContext, libraryNameNode);
2079 libraryElement.definingCompilationUnit = definingCompilationUnitElement;
2080 if (entryPoint != null) {
2081 libraryElement.entryPoint = entryPoint;
2082 }
2083 libraryElement.parts = new List.from(sourcedCompilationUnits);
2084 for (Directive directive in directivesToResolve) {
2085 directive.element = libraryElement;
2086 }
2087 library.libraryElement = libraryElement;
2088 return libraryElement;
2089 }
2090 /**
2091 * Search the top-level functions defined in the given compilation unit for th e entry point.
2092 * @param element the compilation unit to be searched
2093 * @return the entry point that was found, or {@code null} if the compilation unit does not define
2094 * an entry point
2095 */
2096 FunctionElement findEntryPoint(CompilationUnitElementImpl element) {
2097 for (FunctionElement function in element.functions) {
2098 if (function.name == _ENTRY_POINT_NAME) {
2099 return function;
2100 }
2101 }
2102 return null;
2103 }
2104 /**
2105 * 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.
2106 * @param library the library containing the part
2107 * @param partSource the source representing the part
2108 * @param directivesToResolve a list of directives that should be resolved to the library being
2109 * built
2110 * @return the name of the library that the given part is declared to be a par t of
2111 */
2112 String getPartLibraryName(Library library, Source partSource, List<Directive> directivesToResolve) {
2113 try {
2114 CompilationUnit partUnit = library.getAST(partSource);
2115 for (Directive directive in partUnit.directives) {
2116 if (directive is PartOfDirective) {
2117 directivesToResolve.add(directive);
2118 LibraryIdentifier libraryName3 = ((directive as PartOfDirective)).libr aryName;
2119 if (libraryName3 != null) {
2120 return libraryName3.name;
2121 }
2122 }
2123 }
2124 } on AnalysisException catch (exception) {
2125 }
2126 return null;
2127 }
2128 }
2129 /**
2130 * Instances of the class {@code LibraryResolver} are used to resolve one or mor e mutually dependent
2131 * libraries within a single context.
2132 * @coverage dart.engine.resolver
2133 */
2134 class LibraryResolver {
2135 /**
2136 * The analysis context in which the libraries are being analyzed.
2137 */
2138 AnalysisContextImpl _analysisContext;
2139 /**
2140 * The listener to which analysis errors will be reported, this error listener is either
2141 * references {@link #recordingErrorListener}, or it unions the passed{@link A nalysisErrorListener} with the {@link #recordingErrorListener}.
2142 */
2143 AnalysisErrorListener _errorListener;
2144 /**
2145 * This error listener is used by the resolver to be able to call the listener and get back the
2146 * set of errors for each {@link Source}.
2147 * @see #recordErrors()
2148 */
2149 RecordingErrorListener _recordingErrorListener;
2150 /**
2151 * A source object representing the core library (dart:core).
2152 */
2153 Source _coreLibrarySource;
2154 /**
2155 * The object representing the core library.
2156 */
2157 Library _coreLibrary;
2158 /**
2159 * The object used to access the types from the core library.
2160 */
2161 TypeProvider _typeProvider;
2162 /**
2163 * A table mapping library sources to the information being maintained for tho se libraries.
2164 */
2165 Map<Source, Library> _libraryMap = new Map<Source, Library>();
2166 /**
2167 * A collection containing the libraries that are being resolved together.
2168 */
2169 Set<Library> _librariesInCycles;
2170 /**
2171 * Initialize a newly created library resolver to resolve libraries within the given context.
2172 * @param analysisContext the analysis context in which the library is being a nalyzed
2173 */
2174 LibraryResolver.con1(AnalysisContextImpl analysisContext) {
2175 _jtd_constructor_226_impl(analysisContext);
2176 }
2177 _jtd_constructor_226_impl(AnalysisContextImpl analysisContext) {
2178 _jtd_constructor_227_impl(analysisContext, null);
2179 }
2180 /**
2181 * Initialize a newly created library resolver to resolve libraries within the given context.
2182 * @param analysisContext the analysis context in which the library is being a nalyzed
2183 * @param errorListener the listener to which analysis errors will be reported
2184 */
2185 LibraryResolver.con2(AnalysisContextImpl analysisContext2, AnalysisErrorListen er additionalAnalysisErrorListener) {
2186 _jtd_constructor_227_impl(analysisContext2, additionalAnalysisErrorListener) ;
2187 }
2188 _jtd_constructor_227_impl(AnalysisContextImpl analysisContext2, AnalysisErrorL istener additionalAnalysisErrorListener) {
2189 this._analysisContext = analysisContext2;
2190 this._recordingErrorListener = new RecordingErrorListener();
2191 if (additionalAnalysisErrorListener == null) {
2192 this._errorListener = _recordingErrorListener;
2193 } else {
2194 this._errorListener = new AnalysisErrorListener_5(this, additionalAnalysis ErrorListener);
2195 }
2196 _coreLibrarySource = analysisContext2.sourceFactory.forUri(LibraryElementBui lder.CORE_LIBRARY_URI);
2197 }
2198 /**
2199 * Return the analysis context in which the libraries are being analyzed.
2200 * @return the analysis context in which the libraries are being analyzed
2201 */
2202 AnalysisContextImpl get analysisContext => _analysisContext;
2203 /**
2204 * Return the listener to which analysis errors will be reported.
2205 * @return the listener to which analysis errors will be reported
2206 */
2207 AnalysisErrorListener get errorListener => _errorListener;
2208 /**
2209 * Resolve the library specified by the given source in the given context.
2210 * <p>
2211 * Note that because Dart allows circular imports between libraries, it is pos sible that more than
2212 * one library will need to be resolved. In such cases the error listener can receive errors from
2213 * multiple libraries.
2214 * @param librarySource the source specifying the defining compilation unit of the library to be
2215 * resolved
2216 * @param fullAnalysis {@code true} if a full analysis should be performed
2217 * @return the element representing the resolved library
2218 * @throws AnalysisException if the library could not be resolved for some rea son
2219 */
2220 LibraryElement resolveLibrary(Source librarySource, bool fullAnalysis) {
2221 Library targetLibrary = createLibrary(librarySource);
2222 _coreLibrary = _libraryMap[_coreLibrarySource];
2223 if (_coreLibrary == null) {
2224 _coreLibrary = createLibrary(_coreLibrarySource);
2225 }
2226 computeLibraryDependencies(targetLibrary);
2227 _librariesInCycles = computeLibrariesInCycles(targetLibrary);
2228 buildElementModels();
2229 buildDirectiveModels();
2230 _typeProvider = new TypeProviderImpl(_coreLibrary.libraryElement);
2231 buildTypeHierarchies();
2232 resolveReferencesAndTypes();
2233 if (fullAnalysis) {
2234 runAdditionalAnalyses();
2235 }
2236 recordLibraryElements();
2237 recordErrors();
2238 return targetLibrary.libraryElement;
2239 }
2240 /**
2241 * Add a dependency to the given map from the referencing library to the refer enced library.
2242 * @param dependencyMap the map to which the dependency is to be added
2243 * @param referencingLibrary the library that references the referenced librar y
2244 * @param referencedLibrary the library referenced by the referencing library
2245 */
2246 void addDependencyToMap(Map<Library, List<Library>> dependencyMap, Library ref erencingLibrary, Library referencedLibrary) {
2247 List<Library> dependentLibraries = dependencyMap[referencedLibrary];
2248 if (dependentLibraries == null) {
2249 dependentLibraries = new List<Library>();
2250 dependencyMap[referencedLibrary] = dependentLibraries;
2251 }
2252 dependentLibraries.add(referencingLibrary);
2253 }
2254 /**
2255 * Given a library that is part of a cycle that includes the root library, add to the given set of
2256 * libraries all of the libraries reachable from the root library that are als o included in the
2257 * cycle.
2258 * @param library the library to be added to the collection of libraries in cy cles
2259 * @param librariesInCycle a collection of the libraries that are in the cycle
2260 * @param dependencyMap a table mapping libraries to the collection of librari es from which those
2261 * libraries are referenced
2262 */
2263 void addLibrariesInCycle(Library library, Set<Library> librariesInCycle, Map<L ibrary, List<Library>> dependencyMap) {
2264 if (javaSetAdd(librariesInCycle, library)) {
2265 List<Library> dependentLibraries = dependencyMap[library];
2266 if (dependentLibraries != null) {
2267 for (Library dependentLibrary in dependentLibraries) {
2268 addLibrariesInCycle(dependentLibrary, librariesInCycle, dependencyMap) ;
2269 }
2270 }
2271 }
2272 }
2273 /**
2274 * Add the given library, and all libraries reachable from it that have not al ready been visited,
2275 * to the given dependency map.
2276 * @param library the library currently being added to the dependency map
2277 * @param dependencyMap the dependency map being computed
2278 * @param visitedLibraries the libraries that have already been visited, used to prevent infinite
2279 * recursion
2280 */
2281 void addToDependencyMap(Library library, Map<Library, List<Library>> dependenc yMap, Set<Library> visitedLibraries) {
2282 if (javaSetAdd(visitedLibraries, library)) {
2283 for (Library referencedLibrary in library.importsAndExports) {
2284 addDependencyToMap(dependencyMap, library, referencedLibrary);
2285 addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries);
2286 }
2287 if (!library.explicitlyImportsCore && library != _coreLibrary) {
2288 addDependencyToMap(dependencyMap, library, _coreLibrary);
2289 }
2290 }
2291 }
2292 /**
2293 * Build the element model representing the combinators declared by the given directive.
2294 * @param directive the directive that declares the combinators
2295 * @return an array containing the import combinators that were built
2296 */
2297 List<NamespaceCombinator> buildCombinators(NamespaceDirective directive) {
2298 List<NamespaceCombinator> combinators = new List<NamespaceCombinator>();
2299 for (Combinator combinator in directive.combinators) {
2300 if (combinator is HideCombinator) {
2301 HideCombinatorImpl hide = new HideCombinatorImpl();
2302 hide.hiddenNames = getIdentifiers(((combinator as HideCombinator)).hidde nNames);
2303 combinators.add(hide);
2304 } else {
2305 ShowCombinatorImpl show = new ShowCombinatorImpl();
2306 show.shownNames = getIdentifiers(((combinator as ShowCombinator)).shownN ames);
2307 combinators.add(show);
2308 }
2309 }
2310 return new List.from(combinators);
2311 }
2312 /**
2313 * Every library now has a corresponding {@link LibraryElement}, so it is now possible to resolve
2314 * the import and export directives.
2315 * @throws AnalysisException if the defining compilation unit for any of the l ibraries could not
2316 * be accessed
2317 */
2318 void buildDirectiveModels() {
2319 for (Library library in _librariesInCycles) {
2320 Map<String, PrefixElementImpl> nameToPrefixMap = new Map<String, PrefixEle mentImpl>();
2321 List<ImportElement> imports = new List<ImportElement>();
2322 List<ExportElement> exports = new List<ExportElement>();
2323 for (Directive directive in library.definingCompilationUnit.directives) {
2324 if (directive is ImportDirective) {
2325 ImportDirective importDirective = directive as ImportDirective;
2326 Library importedLibrary = library.getImport(importDirective);
2327 if (importedLibrary != null) {
2328 ImportElementImpl importElement = new ImportElementImpl();
2329 importElement.combinators = buildCombinators(importDirective);
2330 LibraryElement importedLibraryElement = importedLibrary.libraryEleme nt;
2331 if (importedLibraryElement != null) {
2332 importElement.importedLibrary = importedLibraryElement;
2333 }
2334 SimpleIdentifier prefixNode = ((directive as ImportDirective)).prefi x;
2335 if (prefixNode != null) {
2336 String prefixName = prefixNode.name;
2337 PrefixElementImpl prefix = nameToPrefixMap[prefixName];
2338 if (prefix == null) {
2339 prefix = new PrefixElementImpl(prefixNode);
2340 nameToPrefixMap[prefixName] = prefix;
2341 }
2342 importElement.prefix = prefix;
2343 }
2344 directive.element = importElement;
2345 imports.add(importElement);
2346 }
2347 } else if (directive is ExportDirective) {
2348 ExportDirective exportDirective = directive as ExportDirective;
2349 ExportElementImpl exportElement = new ExportElementImpl();
2350 exportElement.combinators = buildCombinators(exportDirective);
2351 Library exportedLibrary = library.getExport(exportDirective);
2352 if (exportedLibrary != null) {
2353 LibraryElement exportedLibraryElement = exportedLibrary.libraryEleme nt;
2354 if (exportedLibraryElement != null) {
2355 exportElement.exportedLibrary = exportedLibraryElement;
2356 }
2357 directive.element = exportElement;
2358 exports.add(exportElement);
2359 }
2360 }
2361 }
2362 Source librarySource3 = library.librarySource;
2363 if (!library.explicitlyImportsCore && _coreLibrarySource != librarySource3 ) {
2364 ImportElementImpl importElement = new ImportElementImpl();
2365 importElement.importedLibrary = _coreLibrary.libraryElement;
2366 importElement.synthetic = true;
2367 imports.add(importElement);
2368 }
2369 LibraryElementImpl libraryElement3 = library.libraryElement;
2370 libraryElement3.imports = new List.from(imports);
2371 libraryElement3.exports = new List.from(exports);
2372 }
2373 }
2374 /**
2375 * Build element models for all of the libraries in the current cycle.
2376 * @throws AnalysisException if any of the element models cannot be built
2377 */
2378 void buildElementModels() {
2379 for (Library library in _librariesInCycles) {
2380 LibraryElementBuilder builder = new LibraryElementBuilder(this);
2381 LibraryElementImpl libraryElement = builder.buildLibrary(library);
2382 library.libraryElement = libraryElement;
2383 }
2384 }
2385 /**
2386 * Resolve the type hierarchy across all of the types declared in the librarie s in the current
2387 * cycle.
2388 * @throws AnalysisException if any of the type hierarchies could not be resol ved
2389 */
2390 void buildTypeHierarchies() {
2391 for (Library library in _librariesInCycles) {
2392 for (Source source in library.compilationUnitSources) {
2393 TypeResolverVisitor visitor = new TypeResolverVisitor(library, source, _ typeProvider);
2394 library.getAST(source).accept(visitor);
2395 }
2396 }
2397 }
2398 /**
2399 * Compute a dependency map of libraries reachable from the given library. A d ependency map is a
2400 * table that maps individual libraries to a list of the libraries that either import or export
2401 * those libraries.
2402 * <p>
2403 * This map is used to compute all of the libraries involved in a cycle that i nclude the root
2404 * library. Given that we only add libraries that are reachable from the root library, when we
2405 * work backward we are guaranteed to only get libraries in the cycle.
2406 * @param library the library currently being added to the dependency map
2407 */
2408 Map<Library, List<Library>> computeDependencyMap(Library library) {
2409 Map<Library, List<Library>> dependencyMap = new Map<Library, List<Library>>( );
2410 addToDependencyMap(library, dependencyMap, new Set<Library>());
2411 return dependencyMap;
2412 }
2413 /**
2414 * Return a collection containing all of the libraries reachable from the give n library that are
2415 * contained in a cycle that includes the given library.
2416 * @param library the library that must be included in any cycles whose member s are to be returned
2417 * @return all of the libraries referenced by the given library that have a ci rcular reference
2418 * back to the given library
2419 */
2420 Set<Library> computeLibrariesInCycles(Library library) {
2421 Map<Library, List<Library>> dependencyMap = computeDependencyMap(library);
2422 Set<Library> librariesInCycle = new Set<Library>();
2423 addLibrariesInCycle(library, librariesInCycle, dependencyMap);
2424 return librariesInCycle;
2425 }
2426 /**
2427 * Recursively traverse the libraries reachable from the given library, creati ng instances of the
2428 * class {@link Library} to represent them, and record the references in the l ibrary objects.
2429 * @param library the library to be processed to find libraries that have not yet been traversed
2430 * @throws AnalysisException if some portion of the library graph could not be traversed
2431 */
2432 void computeLibraryDependencies(Library library) {
2433 bool explicitlyImportsCore = false;
2434 CompilationUnit unit = library.definingCompilationUnit;
2435 for (Directive directive in unit.directives) {
2436 if (directive is ImportDirective) {
2437 ImportDirective importDirective = directive as ImportDirective;
2438 Source importedSource = library.getSource(importDirective.uri);
2439 if (importedSource != null) {
2440 if (importedSource == _coreLibrarySource) {
2441 explicitlyImportsCore = true;
2442 }
2443 Library importedLibrary = _libraryMap[importedSource];
2444 if (importedLibrary == null) {
2445 importedLibrary = createLibraryOrNull(importedSource);
2446 if (importedLibrary != null) {
2447 computeLibraryDependencies(importedLibrary);
2448 }
2449 }
2450 if (importedLibrary != null) {
2451 library.addImport(importDirective, importedLibrary);
2452 }
2453 }
2454 } else if (directive is ExportDirective) {
2455 ExportDirective exportDirective = directive as ExportDirective;
2456 Source exportedSource = library.getSource(exportDirective.uri);
2457 if (exportedSource != null) {
2458 Library exportedLibrary = _libraryMap[exportedSource];
2459 if (exportedLibrary == null) {
2460 exportedLibrary = createLibraryOrNull(exportedSource);
2461 if (exportedLibrary != null) {
2462 computeLibraryDependencies(exportedLibrary);
2463 }
2464 }
2465 if (exportedLibrary != null) {
2466 library.addExport(exportDirective, exportedLibrary);
2467 }
2468 }
2469 }
2470 }
2471 library.explicitlyImportsCore = explicitlyImportsCore;
2472 if (!explicitlyImportsCore && _coreLibrarySource != library.librarySource) {
2473 Library importedLibrary = _libraryMap[_coreLibrarySource];
2474 if (importedLibrary == null) {
2475 importedLibrary = createLibraryOrNull(_coreLibrarySource);
2476 if (importedLibrary != null) {
2477 computeLibraryDependencies(importedLibrary);
2478 }
2479 }
2480 }
2481 }
2482 /**
2483 * Create an object to represent the information about the library defined by the compilation unit
2484 * with the given source.
2485 * @param librarySource the source of the library's defining compilation unit
2486 * @return the library object that was created
2487 * @throws AnalysisException if the library source is not valid
2488 */
2489 Library createLibrary(Source librarySource) {
2490 Library library = new Library(_analysisContext, _errorListener, librarySourc e);
2491 library.definingCompilationUnit;
2492 _libraryMap[librarySource] = library;
2493 return library;
2494 }
2495 /**
2496 * Create an object to represent the information about the library defined by the compilation unit
2497 * with the given source. Return the library object that was created, or {@cod e null} if the
2498 * source is not valid.
2499 * @param librarySource the source of the library's defining compilation unit
2500 * @return the library object that was created
2501 */
2502 Library createLibraryOrNull(Source librarySource) {
2503 Library library = new Library(_analysisContext, _errorListener, librarySourc e);
2504 try {
2505 library.definingCompilationUnit;
2506 } on AnalysisException catch (exception) {
2507 return null;
2508 }
2509 _libraryMap[librarySource] = library;
2510 return library;
2511 }
2512 /**
2513 * Return an array containing the lexical identifiers associated with the node s in the given list.
2514 * @param names the AST nodes representing the identifiers
2515 * @return the lexical identifiers associated with the nodes in the list
2516 */
2517 List<String> getIdentifiers(NodeList<SimpleIdentifier> names) {
2518 int count = names.length;
2519 List<String> identifiers = new List<String>(count);
2520 for (int i = 0; i < count; i++) {
2521 identifiers[i] = names[i].name;
2522 }
2523 return identifiers;
2524 }
2525 /**
2526 * For each library, loop through the set of all {@link CompilationUnit}s reco rding the set of
2527 * resolution errors on each unit.
2528 */
2529 void recordErrors() {
2530 for (Library library in _librariesInCycles) {
2531 try {
2532 CompilationUnit definingUnit = library.definingCompilationUnit;
2533 definingUnit.resolutionErrors = _recordingErrorListener.getErrors2(libra ry.librarySource);
2534 } on AnalysisException catch (e) {
2535 throw new AnalysisException();
2536 }
2537 Set<Source> sources = library.compilationUnitSources;
2538 for (Source source in sources) {
2539 try {
2540 CompilationUnit unit = library.getAST(source);
2541 unit.resolutionErrors = _recordingErrorListener.getErrors2(source);
2542 } on JavaException catch (e) {
2543 throw new AnalysisException();
2544 }
2545 }
2546 }
2547 }
2548 /**
2549 * As the final step in the process, record the resolved element models with t he analysis context.
2550 */
2551 void recordLibraryElements() {
2552 Map<Source, LibraryElement> elementMap = new Map<Source, LibraryElement>();
2553 for (Library library in _librariesInCycles) {
2554 elementMap[library.librarySource] = library.libraryElement;
2555 }
2556 _analysisContext.recordLibraryElements(elementMap);
2557 }
2558 /**
2559 * Resolve the identifiers and perform type analysis in the libraries in the c urrent cycle.
2560 * @throws AnalysisException if any of the identifiers could not be resolved o r if any of the
2561 * libraries could not have their types analyzed
2562 */
2563 void resolveReferencesAndTypes() {
2564 for (Library library in _librariesInCycles) {
2565 resolveReferencesAndTypes2(library);
2566 }
2567 }
2568 /**
2569 * Resolve the identifiers and perform type analysis in the given library.
2570 * @param library the library to be resolved
2571 * @throws AnalysisException if any of the identifiers could not be resolved o r if the types in
2572 * the library cannot be analyzed
2573 */
2574 void resolveReferencesAndTypes2(Library library) {
2575 for (Source source in library.compilationUnitSources) {
2576 ResolverVisitor visitor = new ResolverVisitor(library, source, _typeProvid er);
2577 library.getAST(source).accept(visitor);
2578 }
2579 }
2580 /**
2581 * Run additional analyses, such as the {@link ConstantVerifier} and {@link Er rorVerifier}analysis in the current cycle.
2582 * @throws AnalysisException if any of the identifiers could not be resolved o r if the types in
2583 * the library cannot be analyzed
2584 */
2585 void runAdditionalAnalyses() {
2586 for (Library library in _librariesInCycles) {
2587 runAdditionalAnalyses2(library);
2588 }
2589 }
2590 /**
2591 * Run additional analyses, such as the {@link ConstantVerifier} and {@link Er rorVerifier}analysis in the given library.
2592 * @param library the library to have the extra analyses processes run
2593 * @throws AnalysisException if any of the identifiers could not be resolved o r if the types in
2594 * the library cannot be analyzed
2595 */
2596 void runAdditionalAnalyses2(Library library) {
2597 for (Source source in library.compilationUnitSources) {
2598 ErrorReporter errorReporter = new ErrorReporter(_errorListener, source);
2599 CompilationUnit unit = library.getAST(source);
2600 ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter, library.lib raryElement, _typeProvider);
2601 unit.accept(errorVerifier);
2602 ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter);
2603 unit.accept(constantVerifier);
2604 }
2605 }
2606 }
2607 class AnalysisErrorListener_5 implements AnalysisErrorListener {
2608 final LibraryResolver LibraryResolver_this;
2609 AnalysisErrorListener additionalAnalysisErrorListener;
2610 AnalysisErrorListener_5(this.LibraryResolver_this, this.additionalAnalysisErro rListener);
2611 void onError(AnalysisError error) {
2612 additionalAnalysisErrorListener.onError(error);
2613 LibraryResolver_this._recordingErrorListener.onError(error);
2614 }
2615 }
2616 /**
2617 * Instances of the class {@code ResolverVisitor} are used to resolve the nodes within a single
2618 * compilation unit.
2619 * @coverage dart.engine.resolver
2620 */
2621 class ResolverVisitor extends ScopedVisitor {
2622 /**
2623 * The object used to resolve the element associated with the current node.
2624 */
2625 ElementResolver _elementResolver;
2626 /**
2627 * The object used to compute the type associated with the current node.
2628 */
2629 StaticTypeAnalyzer _typeAnalyzer;
2630 /**
2631 * The class element representing the class containing the current node, or {@ code null} if the
2632 * current node is not contained in a class.
2633 */
2634 ClassElement _enclosingClass = null;
2635 /**
2636 * The element representing the function containing the current node, or {@cod e null} if the
2637 * current node is not contained in a function.
2638 */
2639 ExecutableElement _enclosingFunction = null;
2640 /**
2641 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
2642 * @param library the library containing the compilation unit being resolved
2643 * @param source the source representing the compilation unit being visited
2644 * @param typeProvider the object used to access the types from the core libra ry
2645 */
2646 ResolverVisitor(Library library, Source source, TypeProvider typeProvider) : s uper(library, source, typeProvider) {
2647 this._elementResolver = new ElementResolver(this);
2648 this._typeAnalyzer = new StaticTypeAnalyzer(this);
2649 }
2650 Object visitClassDeclaration(ClassDeclaration node) {
2651 ClassElement outerType = _enclosingClass;
2652 try {
2653 _enclosingClass = node.element;
2654 _typeAnalyzer.thisType = _enclosingClass == null ? null : _enclosingClass. type;
2655 super.visitClassDeclaration(node);
2656 } finally {
2657 _typeAnalyzer.thisType = outerType == null ? null : outerType.type;
2658 _enclosingClass = outerType;
2659 }
2660 return null;
2661 }
2662 Object visitFunctionDeclaration(FunctionDeclaration node) {
2663 ExecutableElement outerFunction = _enclosingFunction;
2664 try {
2665 SimpleIdentifier functionName = node.name;
2666 _enclosingFunction = functionName.element as ExecutableElement;
2667 super.visitFunctionDeclaration(node);
2668 } finally {
2669 _enclosingFunction = outerFunction;
2670 }
2671 return null;
2672 }
2673 Object visitFunctionExpression(FunctionExpression node) {
2674 ExecutableElement outerFunction = _enclosingFunction;
2675 try {
2676 _enclosingFunction = node.element;
2677 super.visitFunctionExpression(node);
2678 } finally {
2679 _enclosingFunction = outerFunction;
2680 }
2681 return null;
2682 }
2683 Object visitLabel(Label node) => null;
2684 Object visitLibraryIdentifier(LibraryIdentifier node) => null;
2685 Object visitMethodDeclaration(MethodDeclaration node) {
2686 ExecutableElement outerFunction = _enclosingFunction;
2687 try {
2688 _enclosingFunction = node.element;
2689 super.visitMethodDeclaration(node);
2690 } finally {
2691 _enclosingFunction = outerFunction;
2692 }
2693 return null;
2694 }
2695 Object visitNode(ASTNode node) {
2696 node.visitChildren(this);
2697 node.accept(_elementResolver);
2698 node.accept(_typeAnalyzer);
2699 return null;
2700 }
2701 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
2702 SimpleIdentifier prefix7 = node.prefix;
2703 if (prefix7 != null) {
2704 prefix7.accept(this);
2705 }
2706 node.accept(_elementResolver);
2707 node.accept(_typeAnalyzer);
2708 return null;
2709 }
2710 Object visitPropertyAccess(PropertyAccess node) {
2711 Expression target4 = node.target;
2712 if (target4 != null) {
2713 target4.accept(this);
2714 }
2715 node.accept(_elementResolver);
2716 node.accept(_typeAnalyzer);
2717 return null;
2718 }
2719 Object visitRedirectingConstructorInvocation(RedirectingConstructorInvocation node) {
2720 ArgumentList argumentList10 = node.argumentList;
2721 if (argumentList10 != null) {
2722 argumentList10.accept(this);
2723 }
2724 node.accept(_elementResolver);
2725 node.accept(_typeAnalyzer);
2726 return null;
2727 }
2728 Object visitSuperConstructorInvocation(SuperConstructorInvocation node) {
2729 ArgumentList argumentList11 = node.argumentList;
2730 if (argumentList11 != null) {
2731 argumentList11.accept(this);
2732 }
2733 node.accept(_elementResolver);
2734 node.accept(_typeAnalyzer);
2735 return null;
2736 }
2737 Object visitTypeName(TypeName node) => null;
2738 /**
2739 * Return the class element representing the class containing the current node , or {@code null} if
2740 * the current node is not contained in a class.
2741 * @return the class element representing the class containing the current nod e
2742 */
2743 ClassElement get enclosingClass => _enclosingClass;
2744 /**
2745 * Return the element representing the function containing the current node, o r {@code null} if
2746 * the current node is not contained in a function.
2747 * @return the element representing the function containing the current node
2748 */
2749 ExecutableElement get enclosingFunction => _enclosingFunction;
2750 get elementResolver_J2DAccessor => _elementResolver;
2751 set elementResolver_J2DAccessor(__v) => _elementResolver = __v;
2752 get labelScope_J2DAccessor => _labelScope;
2753 set labelScope_J2DAccessor(__v) => _labelScope = __v;
2754 get nameScope_J2DAccessor => _nameScope;
2755 set nameScope_J2DAccessor(__v) => _nameScope = __v;
2756 get typeAnalyzer_J2DAccessor => _typeAnalyzer;
2757 set typeAnalyzer_J2DAccessor(__v) => _typeAnalyzer = __v;
2758 get enclosingClass_J2DAccessor => _enclosingClass;
2759 set enclosingClass_J2DAccessor(__v) => _enclosingClass = __v;
2760 }
2761 /**
2762 * The abstract class {@code ScopedVisitor} maintains name and label scopes as a n AST structure is
2763 * being visited.
2764 * @coverage dart.engine.resolver
2765 */
2766 abstract class ScopedVisitor extends GeneralizingASTVisitor<Object> {
2767 /**
2768 * The element for the library containing the compilation unit being visited.
2769 */
2770 LibraryElement _definingLibrary;
2771 /**
2772 * The source representing the compilation unit being visited.
2773 */
2774 Source _source;
2775 /**
2776 * The error listener that will be informed of any errors that are found durin g resolution.
2777 */
2778 AnalysisErrorListener _errorListener;
2779 /**
2780 * The scope used to resolve identifiers.
2781 */
2782 Scope _nameScope;
2783 /**
2784 * The object used to access the types from the core library.
2785 */
2786 TypeProvider _typeProvider;
2787 /**
2788 * 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.
2789 */
2790 LabelScope _labelScope;
2791 /**
2792 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
2793 * @param library the library containing the compilation unit being resolved
2794 * @param source the source representing the compilation unit being visited
2795 * @param typeProvider the object used to access the types from the core libra ry
2796 */
2797 ScopedVisitor(Library library, Source source, TypeProvider typeProvider) {
2798 this._definingLibrary = library.libraryElement;
2799 this._source = source;
2800 LibraryScope libraryScope2 = library.libraryScope;
2801 this._errorListener = libraryScope2.errorListener;
2802 this._nameScope = libraryScope2;
2803 this._typeProvider = typeProvider;
2804 }
2805 /**
2806 * Return the library element for the library containing the compilation unit being resolved.
2807 * @return the library element for the library containing the compilation unit being resolved
2808 */
2809 LibraryElement get definingLibrary => _definingLibrary;
2810 /**
2811 * Return the object used to access the types from the core library.
2812 * @return the object used to access the types from the core library
2813 */
2814 TypeProvider get typeProvider => _typeProvider;
2815 Object visitBlock(Block node) {
2816 Scope outerScope = _nameScope;
2817 _nameScope = new EnclosedScope(_nameScope);
2818 try {
2819 super.visitBlock(node);
2820 } finally {
2821 _nameScope = outerScope;
2822 }
2823 return null;
2824 }
2825 Object visitClassDeclaration(ClassDeclaration node) {
2826 Scope outerScope = _nameScope;
2827 try {
2828 _nameScope = new ClassScope(_nameScope, node.element);
2829 super.visitClassDeclaration(node);
2830 } finally {
2831 _nameScope = outerScope;
2832 }
2833 return null;
2834 }
2835 Object visitClassTypeAlias(ClassTypeAlias node) {
2836 Scope outerScope = _nameScope;
2837 try {
2838 _nameScope = new ClassScope(_nameScope, node.element);
2839 super.visitClassTypeAlias(node);
2840 } finally {
2841 _nameScope = outerScope;
2842 }
2843 return null;
2844 }
2845 Object visitConstructorDeclaration(ConstructorDeclaration node) {
2846 Scope outerScope = _nameScope;
2847 try {
2848 _nameScope = new FunctionScope(_nameScope, node.element);
2849 super.visitConstructorDeclaration(node);
2850 } finally {
2851 _nameScope = outerScope;
2852 }
2853 return null;
2854 }
2855 Object visitDoStatement(DoStatement node) {
2856 LabelScope outerScope = _labelScope;
2857 _labelScope = new LabelScope.con1(outerScope, false, false);
2858 try {
2859 super.visitDoStatement(node);
2860 } finally {
2861 _labelScope = outerScope;
2862 }
2863 return null;
2864 }
2865 Object visitForEachStatement(ForEachStatement node) {
2866 LabelScope outerLabelScope = _labelScope;
2867 _labelScope = new LabelScope.con1(outerLabelScope, false, false);
2868 Scope outerNameScope = _nameScope;
2869 _nameScope = new EnclosedScope(_nameScope);
2870 try {
2871 super.visitForEachStatement(node);
2872 } finally {
2873 _nameScope = outerNameScope;
2874 _labelScope = outerLabelScope;
2875 }
2876 return null;
2877 }
2878 Object visitForStatement(ForStatement node) {
2879 LabelScope outerLabelScope = _labelScope;
2880 _labelScope = new LabelScope.con1(outerLabelScope, false, false);
2881 Scope outerNameScope = _nameScope;
2882 _nameScope = new EnclosedScope(_nameScope);
2883 try {
2884 super.visitForStatement(node);
2885 } finally {
2886 _nameScope = outerNameScope;
2887 _labelScope = outerLabelScope;
2888 }
2889 return null;
2890 }
2891 Object visitFunctionDeclaration(FunctionDeclaration node) {
2892 ExecutableElement function = node.element;
2893 Scope outerScope = _nameScope;
2894 try {
2895 _nameScope = new FunctionScope(_nameScope, function);
2896 super.visitFunctionDeclaration(node);
2897 } finally {
2898 _nameScope = outerScope;
2899 }
2900 if (function.enclosingElement is! CompilationUnitElement) {
2901 _nameScope.define(function);
2902 }
2903 return null;
2904 }
2905 Object visitFunctionExpression(FunctionExpression node) {
2906 Scope outerScope = _nameScope;
2907 try {
2908 ExecutableElement functionElement = node.element;
2909 if (functionElement == null) {
2910 } else {
2911 _nameScope = new FunctionScope(_nameScope, functionElement);
2912 }
2913 super.visitFunctionExpression(node);
2914 } finally {
2915 _nameScope = outerScope;
2916 }
2917 return null;
2918 }
2919 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
2920 Scope outerScope = _nameScope;
2921 try {
2922 _nameScope = new FunctionTypeScope(_nameScope, node.element);
2923 super.visitFunctionTypeAlias(node);
2924 } finally {
2925 _nameScope = outerScope;
2926 }
2927 return null;
2928 }
2929 Object visitLabeledStatement(LabeledStatement node) {
2930 LabelScope outerScope = addScopesFor(node.labels);
2931 try {
2932 super.visitLabeledStatement(node);
2933 } finally {
2934 _labelScope = outerScope;
2935 }
2936 return null;
2937 }
2938 Object visitMethodDeclaration(MethodDeclaration node) {
2939 Scope outerScope = _nameScope;
2940 try {
2941 _nameScope = new FunctionScope(_nameScope, node.element);
2942 super.visitMethodDeclaration(node);
2943 } finally {
2944 _nameScope = outerScope;
2945 }
2946 return null;
2947 }
2948 Object visitSwitchCase(SwitchCase node) {
2949 node.expression.accept(this);
2950 LabelScope outerLabelScope = addScopesFor(node.labels);
2951 Scope outerNameScope = _nameScope;
2952 _nameScope = new EnclosedScope(_nameScope);
2953 try {
2954 node.statements.accept(this);
2955 } finally {
2956 _nameScope = outerNameScope;
2957 _labelScope = outerLabelScope;
2958 }
2959 return null;
2960 }
2961 Object visitSwitchDefault(SwitchDefault node) {
2962 LabelScope outerLabelScope = addScopesFor(node.labels);
2963 Scope outerNameScope = _nameScope;
2964 _nameScope = new EnclosedScope(_nameScope);
2965 try {
2966 node.statements.accept(this);
2967 } finally {
2968 _nameScope = outerNameScope;
2969 _labelScope = outerLabelScope;
2970 }
2971 return null;
2972 }
2973 Object visitSwitchStatement(SwitchStatement node) {
2974 LabelScope outerScope = _labelScope;
2975 _labelScope = new LabelScope.con1(outerScope, true, false);
2976 for (SwitchMember member in node.members) {
2977 for (Label label in member.labels) {
2978 SimpleIdentifier labelName = label.label;
2979 LabelElement labelElement = labelName.element as LabelElement;
2980 _labelScope = new LabelScope.con2(outerScope, labelName.name, labelEleme nt);
2981 }
2982 }
2983 try {
2984 super.visitSwitchStatement(node);
2985 } finally {
2986 _labelScope = outerScope;
2987 }
2988 return null;
2989 }
2990 Object visitVariableDeclaration(VariableDeclaration node) {
2991 if (node.parent.parent is! TopLevelVariableDeclaration && node.parent.parent is! FieldDeclaration) {
2992 VariableElement element23 = node.element;
2993 if (element23 != null) {
2994 _nameScope.define(element23);
2995 }
2996 }
2997 super.visitVariableDeclaration(node);
2998 return null;
2999 }
3000 Object visitWhileStatement(WhileStatement node) {
3001 LabelScope outerScope = _labelScope;
3002 _labelScope = new LabelScope.con1(outerScope, false, false);
3003 try {
3004 super.visitWhileStatement(node);
3005 } finally {
3006 _labelScope = outerScope;
3007 }
3008 return null;
3009 }
3010 /**
3011 * Return the label scope in which the current node is being resolved.
3012 * @return the label scope in which the current node is being resolved
3013 */
3014 LabelScope get labelScope => _labelScope;
3015 /**
3016 * Return the name scope in which the current node is being resolved.
3017 * @return the name scope in which the current node is being resolved
3018 */
3019 Scope get nameScope => _nameScope;
3020 /**
3021 * Report an error with the given error code and arguments.
3022 * @param errorCode the error code of the error to be reported
3023 * @param node the node specifying the location of the error
3024 * @param arguments the arguments to the error, used to compose the error mess age
3025 */
3026 void reportError(ErrorCode errorCode, ASTNode node, List<Object> arguments) {
3027 _errorListener.onError(new AnalysisError.con2(_source, node.offset, node.len gth, errorCode, [arguments]));
3028 }
3029 /**
3030 * Report an error with the given error code and arguments.
3031 * @param errorCode the error code of the error to be reported
3032 * @param token the token specifying the location of the error
3033 * @param arguments the arguments to the error, used to compose the error mess age
3034 */
3035 void reportError3(ErrorCode errorCode, sc.Token token, List<Object> arguments) {
3036 _errorListener.onError(new AnalysisError.con2(_source, token.offset, token.l ength, errorCode, [arguments]));
3037 }
3038 /**
3039 * Add scopes for each of the given labels.
3040 * @param labels the labels for which new scopes are to be added
3041 * @return the scope that was in effect before the new scopes were added
3042 */
3043 LabelScope addScopesFor(NodeList<Label> labels) {
3044 LabelScope outerScope = _labelScope;
3045 for (Label label in labels) {
3046 SimpleIdentifier labelNameNode = label.label;
3047 String labelName = labelNameNode.name;
3048 LabelElement labelElement = labelNameNode.element as LabelElement;
3049 _labelScope = new LabelScope.con2(_labelScope, labelName, labelElement);
3050 }
3051 return outerScope;
3052 }
3053 }
3054 /**
3055 * Instances of the class {@code StaticTypeAnalyzer} perform two type-related ta sks. First, they
3056 * compute the static type of every expression. Second, they look for any static type errors or
3057 * warnings that might need to be generated. The requirements for the type analy zer are:
3058 * <ol>
3059 * <li>Every element that refers to types should be fully populated.
3060 * <li>Every node representing an expression should be resolved to the Type of t he expression.</li>
3061 * </ol>
3062 * @coverage dart.engine.resolver
3063 */
3064 class StaticTypeAnalyzer extends SimpleASTVisitor<Object> {
3065 /**
3066 * The object providing access to the types defined by the language.
3067 */
3068 TypeProvider _typeProvider;
3069 /**
3070 * The type representing the type 'dynamic'.
3071 */
3072 Type2 _dynamicType;
3073 /**
3074 * The type representing the class containing the nodes being analyzed, or {@c ode null} if the
3075 * nodes are not within a class.
3076 */
3077 InterfaceType _thisType;
3078 /**
3079 * Initialize a newly created type analyzer.
3080 * @param resolver the resolver driving this participant
3081 */
3082 StaticTypeAnalyzer(ResolverVisitor resolver) {
3083 _typeProvider = resolver.typeProvider;
3084 _dynamicType = _typeProvider.dynamicType;
3085 }
3086 /**
3087 * Set the type of the class being analyzed to the given type.
3088 * @param thisType the type representing the class containing the nodes being analyzed
3089 */
3090 void set thisType(InterfaceType thisType2) {
3091 this._thisType = thisType2;
3092 }
3093 /**
3094 * The Dart Language Specification, 12.5: <blockquote>The static type of a str ing literal is{@code String}.</blockquote>
3095 */
3096 Object visitAdjacentStrings(AdjacentStrings node) => recordType(node, _typePro vider.stringType);
3097 /**
3098 * The Dart Language Specification, 12.33: <blockquote>The static type of an a rgument definition
3099 * test is {@code bool}.</blockquote>
3100 */
3101 Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) => recordType( node, _typeProvider.boolType);
3102 /**
3103 * The Dart Language Specification, 12.32: <blockquote>... the cast expression <i>e as T</i> ...
3104 * <p>
3105 * It is a static warning if <i>T</i> does not denote a type available in the current lexical
3106 * scope.
3107 * <p>
3108 * The static type of a cast expression <i>e as T</i> is <i>T</i>.</blockquote >
3109 */
3110 Object visitAsExpression(AsExpression node) => recordType(node, getType3(node. type));
3111 /**
3112 * The Dart Language Specification, 12.18: <blockquote> ... an assignment <i>a </i> of the form
3113 * <i>v = e</i> ...
3114 * <p>
3115 * It is a static type warning if the static type of <i>e</i> may not be assig ned to the static
3116 * type of <i>v</i>.
3117 * <p>
3118 * The static type of the expression <i>v = e</i> is the static type of <i>e</ i>.
3119 * <p>
3120 * ... an assignment of the form <i>C.v = e</i> ...
3121 * <p>
3122 * It is a static type warning if the static type of <i>e</i> may not be assig ned to the static
3123 * type of <i>C.v</i>.
3124 * <p>
3125 * The static type of the expression <i>C.v = e</i> is the static type of <i>e </i>.
3126 * <p>
3127 * ... an assignment of the form <i>e<sub>1</sub>.v = e<sub>2</sub></i> ...
3128 * <p>
3129 * Let <i>T</i> be the static type of <i>e<sub>1</sub></i>. It is a static typ e warning if
3130 * <i>T</i> does not have an accessible instance setter named <i>v=</i>. It is a static type
3131 * warning if the static type of <i>e<sub>2</sub></i> may not be assigned to < i>T</i>.
3132 * <p>
3133 * The static type of the expression <i>e<sub>1</sub>.v = e<sub>2</sub></i> is the static type of
3134 * <i>e<sub>2</sub></i>.
3135 * <p>
3136 * ... an assignment of the form <i>e<sub>1</sub>[e<sub>2</sub>] = e<sub>3</su b></i> ...
3137 * <p>
3138 * The static type of the expression <i>e<sub>1</sub>[e<sub>2</sub>] = e<sub>3 </sub></i> is the
3139 * static type of <i>e<sub>3</sub></i>.
3140 * <p>
3141 * A compound assignment of the form <i>v op= e</i> is equivalent to <i>v = v op e</i>. A compound
3142 * assignment of the form <i>C.v op= e</i> is equivalent to <i>C.v = C.v op e< /i>. A compound
3143 * assignment of the form <i>e<sub>1</sub>.v op= e<sub>2</sub></i> is equivale nt to <i>((x) => x.v
3144 * = 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
3145 * <i>e<sub>2</sub></i>. A compound assignment of the form <i>e<sub>1</sub>[e< sub>2</sub>] op=
3146 * 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>,
3147 * e<sub>2</sub>)</i> where <i>a</i> and <i>i</i> are a variables that are not used in
3148 * <i>e<sub>3</sub></i>. </blockquote>
3149 */
3150 Object visitAssignmentExpression(AssignmentExpression node) {
3151 sc.TokenType operator11 = node.operator.type;
3152 if (operator11 != sc.TokenType.EQ) {
3153 return recordReturnType(node, node.element);
3154 }
3155 return recordType(node, getType(node.rightHandSide));
3156 }
3157 /**
3158 * The Dart Language Specification, 12.20: <blockquote>The static type of a lo gical boolean
3159 * expression is {@code bool}.</blockquote>
3160 * <p>
3161 * The Dart Language Specification, 12.21:<blockquote>A bitwise expression of the form
3162 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n
3163 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A bitwise expression of the form <i >super op
3164 * e<sub>2</sub></i> is equivalent to the method invocation
3165 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
3166 * <p>
3167 * The Dart Language Specification, 12.22: <blockquote>The static type of an e quality expression
3168 * is {@code bool}.</blockquote>
3169 * <p>
3170 * The Dart Language Specification, 12.23: <blockquote>A relational expression of the form
3171 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n
3172 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A relational expression of the form <i>super op
3173 * e<sub>2</sub></i> is equivalent to the method invocation
3174 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
3175 * <p>
3176 * The Dart Language Specification, 12.24: <blockquote>A shift expression of t he form
3177 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n
3178 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A shift expression of the form <i>s uper op
3179 * e<sub>2</sub></i> is equivalent to the method invocation
3180 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
3181 * <p>
3182 * The Dart Language Specification, 12.25: <blockquote>An additive expression of the form
3183 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n
3184 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. An additive expression of the form <i>super op
3185 * e<sub>2</sub></i> is equivalent to the method invocation
3186 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
3187 * <p>
3188 * The Dart Language Specification, 12.26: <blockquote>A multiplicative expres sion of the form
3189 * <i>e<sub>1</sub> op e<sub>2</sub></i> is equivalent to the method invocatio n
3190 * <i>e<sub>1</sub>.op(e<sub>2</sub>)</i>. A multiplicative expression of the form <i>super op
3191 * e<sub>2</sub></i> is equivalent to the method invocation
3192 * <i>super.op(e<sub>2</sub>)</i>.</blockquote>
3193 */
3194 Object visitBinaryExpression(BinaryExpression node) {
3195 sc.TokenType operator12 = node.operator.type;
3196 while (true) {
3197 if (operator12 == sc.TokenType.AMPERSAND_AMPERSAND || operator12 == sc.Tok enType.BAR_BAR || operator12 == sc.TokenType.EQ_EQ || operator12 == sc.TokenType .BANG_EQ) {
3198 return recordType(node, _typeProvider.boolType);
3199 }
3200 break;
3201 }
3202 return recordReturnType(node, node.element);
3203 }
3204 /**
3205 * The Dart Language Specification, 12.4: <blockquote>The static type of a boo lean literal is{@code bool}.</blockquote>
3206 */
3207 Object visitBooleanLiteral(BooleanLiteral node) => recordType(node, _typeProvi der.boolType);
3208 /**
3209 * The Dart Language Specification, 12.15.2: <blockquote>A cascaded method inv ocation expression
3210 * of the form <i>e..suffix</i> is equivalent to the expression <i>(t) {t.suff ix; return
3211 * t;}(e)</i>.</blockquote>
3212 */
3213 Object visitCascadeExpression(CascadeExpression node) => recordType(node, getT ype(node.target));
3214 /**
3215 * The Dart Language Specification, 12.19: <blockquote> ... a conditional expr ession <i>c</i> of
3216 * the form <i>e<sub>1</sub> ? e<sub>2</sub> : e<sub>3</sub></i> ...
3217 * <p>
3218 * It is a static type warning if the type of e<sub>1</sub> may not be assigne d to {@code bool}.
3219 * <p>
3220 * The static type of <i>c</i> is the least upper bound of the static type of <i>e<sub>2</sub></i>
3221 * and the static type of <i>e<sub>3</sub></i>.</blockquote>
3222 */
3223 Object visitConditionalExpression(ConditionalExpression node) {
3224 Type2 thenType = getType(node.thenExpression);
3225 Type2 elseType = getType(node.elseExpression);
3226 if (thenType == null) {
3227 return recordType(node, _dynamicType);
3228 }
3229 Type2 resultType = thenType.getLeastUpperBound(elseType);
3230 return recordType(node, resultType);
3231 }
3232 /**
3233 * The Dart Language Specification, 12.3: <blockquote>The static type of a lit eral double is{@code double}.</blockquote>
3234 */
3235 Object visitDoubleLiteral(DoubleLiteral node) => recordType(node, _typeProvide r.doubleType);
3236 Object visitFunctionDeclaration(FunctionDeclaration node) {
3237 FunctionExpression function = node.functionExpression;
3238 FunctionTypeImpl functionType = node.element.type as FunctionTypeImpl;
3239 setTypeInformation(functionType, computeReturnType(node), function.parameter s);
3240 return recordType(function, functionType);
3241 }
3242 /**
3243 * The Dart Language Specification, 12.9: <blockquote>The static type of a fun ction literal of the
3244 * form <i>(T<sub>1</sub> a<sub>1</sub>, &hellip;, T<sub>n</sub> a<sub>n</sub> , [T<sub>n+1</sub>
3245 * x<sub>n+1</sub> = d1, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub> = dk]) => e </i> is
3246 * <i>(T<sub>1</sub>, &hellip;, Tn, [T<sub>n+1</sub> x<sub>n+1</sub>, &hellip; , T<sub>n+k</sub>
3247 * x<sub>n+k</sub>]) &rarr; T<sub>0</sub></i>, where <i>T<sub>0</sub></i> is t he static type of
3248 * <i>e</i>. In any case where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is
3249 * considered to have been specified as dynamic.
3250 * <p>
3251 * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1 </sub>, &hellip;,
3252 * 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>
3253 * 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>
3254 * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; T<sub>0 </sub></i>, where
3255 * <i>T<sub>0</sub></i> is the static type of <i>e</i>. In any case where <i>T <sub>i</sub>, 1
3256 * &lt;= i &lt;= n</i>, is not specified, it is considered to have been specif ied as dynamic.
3257 * <p>
3258 * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1 </sub>, &hellip;,
3259 * 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>
3260 * x<sub>n+k</sub> = dk]) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub >, [T<sub>n+1</sub>
3261 * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>]) &rarr; dynamic </i>. In any case
3262 * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is cons idered to have been
3263 * specified as dynamic.
3264 * <p>
3265 * The static type of a function literal of the form <i>(T<sub>1</sub> a<sub>1 </sub>, &hellip;,
3266 * 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>
3267 * x<sub>n+k</sub> : dk}) {s}</i> is <i>(T<sub>1</sub>, &hellip;, T<sub>n</sub >, {T<sub>n+1</sub>
3268 * x<sub>n+1</sub>, &hellip;, T<sub>n+k</sub> x<sub>n+k</sub>}) &rarr; dynamic </i>. In any case
3269 * where <i>T<sub>i</sub>, 1 &lt;= i &lt;= n</i>, is not specified, it is cons idered to have been
3270 * specified as dynamic.</blockquote>
3271 */
3272 Object visitFunctionExpression(FunctionExpression node) {
3273 if (node.parent is FunctionDeclaration) {
3274 return null;
3275 }
3276 FunctionTypeImpl functionType = node.element.type as FunctionTypeImpl;
3277 setTypeInformation(functionType, computeReturnType2(node), node.parameters);
3278 return recordType(node, functionType);
3279 }
3280 /**
3281 * The Dart Language Specification, 12.14.4: <blockquote>A function expression invocation <i>i</i>
3282 * has the form <i>e<sub>f</sub>(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub >n+1</sub>:
3283 * 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
3284 * an expression.
3285 * <p>
3286 * It is a static type warning if the static type <i>F</i> of <i>e<sub>f</sub> </i> may not be
3287 * assigned to a function type.
3288 * <p>
3289 * If <i>F</i> is not a function type, the static type of <i>i</i> is dynamic. Otherwise the
3290 * static type of <i>i</i> is the declared return type of <i>F</i>.</blockquot e>
3291 */
3292 Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) => recordReturnType(node, node.element);
3293 /**
3294 * The Dart Language Specification, 12.29: <blockquote>An assignable expressio n of the form
3295 * <i>e<sub>1</sub>[e<sub>2</sub>]</i> is evaluated as a method invocation of the operator method
3296 * <i>[]</i> on <i>e<sub>1</sub></i> with argument <i>e<sub>2</sub></i>.</bloc kquote>
3297 */
3298 Object visitIndexExpression(IndexExpression node) {
3299 if (node.inSetterContext()) {
3300 return recordArgumentType(node, node.element);
3301 }
3302 return recordReturnType(node, node.element);
3303 }
3304 /**
3305 * The Dart Language Specification, 12.11.1: <blockquote>The static type of a new expression of
3306 * either the form <i>new T.id(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> or the form <i>new
3307 * T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>.</blockquote>
3308 * <p>
3309 * The Dart Language Specification, 12.11.2: <blockquote>The static type of a constant object
3310 * expression of either the form <i>const T.id(a<sub>1</sub>, &hellip;, a<sub> n</sub>)</i> or the
3311 * form <i>const T(a<sub>1</sub>, &hellip;, a<sub>n</sub>)</i> is <i>T</i>. </ blockquote>
3312 */
3313 Object visitInstanceCreationExpression(InstanceCreationExpression node) => rec ordType(node, node.constructorName.type.type);
3314 /**
3315 * The Dart Language Specification, 12.3: <blockquote>The static type of an in teger literal is{@code int}.</blockquote>
3316 */
3317 Object visitIntegerLiteral(IntegerLiteral node) => recordType(node, _typeProvi der.intType);
3318 /**
3319 * The Dart Language Specification, 12.31: <blockquote>It is a static warning if <i>T</i> does not
3320 * denote a type available in the current lexical scope.
3321 * <p>
3322 * The static type of an is-expression is {@code bool}.</blockquote>
3323 */
3324 Object visitIsExpression(IsExpression node) => recordType(node, _typeProvider. boolType);
3325 /**
3326 * The Dart Language Specification, 12.6: <blockquote>The static type of a lis t literal of the
3327 * form <i><b>const</b> &lt;E&gt;[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> or the form
3328 * <i>&lt;E&gt;[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> is {@code List&lt; E&gt;}. The static
3329 * type a list literal of the form <i><b>const</b> [e<sub>1</sub>, &hellip;, e <sub>n</sub>]</i> or
3330 * the form <i>[e<sub>1</sub>, &hellip;, e<sub>n</sub>]</i> is {@code List&lt; dynamic&gt;}.</blockquote>
3331 */
3332 Object visitListLiteral(ListLiteral node) {
3333 TypeArgumentList typeArguments8 = node.typeArguments;
3334 if (typeArguments8 != null) {
3335 NodeList<TypeName> arguments3 = typeArguments8.arguments;
3336 if (arguments3 != null && arguments3.length == 1) {
3337 TypeName argumentType = arguments3[0];
3338 return recordType(node, _typeProvider.listType.substitute5(<Type2> [getT ype3(argumentType)]));
3339 }
3340 }
3341 return recordType(node, _typeProvider.listType.substitute5(<Type2> [_dynamic Type]));
3342 }
3343 /**
3344 * The Dart Language Specification, 12.7: <blockquote>The static type of a map literal of the form
3345 * <i><b>const</b> &lt;String, V&gt; {k<sub>1</sub>:e<sub>1</sub>, &hellip;,
3346 * 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>,
3347 * &hellip;, k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map&lt;String, V&gt;}. The static type a
3348 * map literal of the form <i><b>const</b> {k<sub>1</sub>:e<sub>1</sub>, &hell ip;,
3349 * k<sub>n</sub>:e<sub>n</sub>}</i> or the form <i>{k<sub>1</sub>:e<sub>1</sub >, &hellip;,
3350 * k<sub>n</sub>:e<sub>n</sub>}</i> is {@code Map&lt;String, dynamic&gt;}.
3351 * <p>
3352 * It is a compile-time error if the first type argument to a map literal is n ot
3353 * <i>String</i>.</blockquote>
3354 */
3355 Object visitMapLiteral(MapLiteral node) {
3356 TypeArgumentList typeArguments9 = node.typeArguments;
3357 if (typeArguments9 != null) {
3358 NodeList<TypeName> arguments4 = typeArguments9.arguments;
3359 if (arguments4 != null && arguments4.length == 2) {
3360 TypeName keyType = arguments4[0];
3361 if (keyType != _typeProvider.stringType) {
3362 }
3363 TypeName valueType = arguments4[1];
3364 return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_type Provider.stringType, getType3(valueType)]));
3365 }
3366 }
3367 return recordType(node, _typeProvider.mapType.substitute5(<Type2> [_typeProv ider.stringType, _dynamicType]));
3368 }
3369 /**
3370 * The Dart Language Specification, 12.15.1: <blockquote>An ordinary method in vocation <i>i</i>
3371 * 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>,
3372 * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
3373 * <p>
3374 * Let <i>T</i> be the static type of <i>o</i>. It is a static type warning if <i>T</i> does not
3375 * have an accessible instance member named <i>m</i>. If <i>T.m</i> exists, it is a static warning
3376 * if the type <i>F</i> of <i>T.m</i> may not be assigned to a function type.
3377 * <p>
3378 * If <i>T.m</i> does not exist, or if <i>F</i> is not a function type, the st atic type of
3379 * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
3380 * <i>F</i>.</blockquote>
3381 * <p>
3382 * The Dart Language Specification, 11.15.3: <blockquote>A static method invoc ation <i>i</i> has
3383 * the form <i>C.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub>: a< sub>n+1</sub>,
3384 * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
3385 * <p>
3386 * It is a static type warning if the type <i>F</i> of <i>C.m</i> may not be a ssigned to a
3387 * function type.
3388 * <p>
3389 * 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
3390 * dynamic. Otherwise the static type of <i>i</i> is the declared return type of
3391 * <i>F</i>.</blockquote>
3392 * <p>
3393 * The Dart Language Specification, 11.15.4: <blockquote>A super method invoca tion <i>i</i> has
3394 * the form <i>super.m(a<sub>1</sub>, &hellip;, a<sub>n</sub>, x<sub>n+1</sub> : a<sub>n+1</sub>,
3395 * &hellip;, x<sub>n+k</sub>: a<sub>n+k</sub>)</i>.
3396 * <p>
3397 * It is a static type warning if <i>S</i> does not have an accessible instanc e member named m. If
3398 * <i>S.m</i> exists, it is a static warning if the type <i>F</i> of <i>S.m</i > may not be
3399 * assigned to a function type.
3400 * <p>
3401 * If <i>S.m</i> does not exist, or if <i>F</i> is not a function type, the st atic type of
3402 * <i>i</i> is dynamic. Otherwise the static type of <i>i</i> is the declared return type of
3403 * <i>F</i>.</blockquote>
3404 */
3405 Object visitMethodInvocation(MethodInvocation node) => recordReturnType(node, node.methodName.element);
3406 Object visitNamedExpression(NamedExpression node) => recordType(node, getType( node.expression));
3407 /**
3408 * The Dart Language Specification, 12.2: <blockquote>The static type of {@cod e null} is bottom.
3409 * </blockquote>
3410 */
3411 Object visitNullLiteral(NullLiteral node) => recordType(node, _typeProvider.bo ttomType);
3412 Object visitParenthesizedExpression(ParenthesizedExpression node) => recordTyp e(node, getType(node.expression));
3413 /**
3414 * The Dart Language Specification, 12.28: <blockquote>A postfix expression of the form
3415 * <i>v++</i>, where <i>v</i> is an identifier, is equivalent to <i>(){var r = v; v = r + 1;
3416 * return r}()</i>.
3417 * <p>
3418 * A postfix expression of the form <i>C.v++</i> is equivalent to <i>(){var r = C.v; C.v = r + 1;
3419 * return r}()</i>.
3420 * <p>
3421 * A postfix expression of the form <i>e1.v++</i> is equivalent to <i>(x){var r = x.v; x.v = r +
3422 * 1; return r}(e1)</i>.
3423 * <p>
3424 * A postfix expression of the form <i>e1[e2]++</i> is equivalent to <i>(a, i) {var r = a[i]; a[i]
3425 * = r + 1; return r}(e1, e2)</i>
3426 * <p>
3427 * A postfix expression of the form <i>v--</i>, where <i>v</i> is an identifie r, is equivalent to
3428 * <i>(){var r = v; v = r - 1; return r}()</i>.
3429 * <p>
3430 * A postfix expression of the form <i>C.v--</i> is equivalent to <i>(){var r = C.v; C.v = r - 1;
3431 * return r}()</i>.
3432 * <p>
3433 * A postfix expression of the form <i>e1.v--</i> is equivalent to <i>(x){var r = x.v; x.v = r -
3434 * 1; return r}(e1)</i>.
3435 * <p>
3436 * A postfix expression of the form <i>e1[e2]--</i> is equivalent to <i>(a, i) {var r = a[i]; a[i]
3437 * = r - 1; return r}(e1, e2)</i></blockquote>
3438 */
3439 Object visitPostfixExpression(PostfixExpression node) => recordType(node, getT ype(node.operand));
3440 /**
3441 * See {@link #visitSimpleIdentifier(SimpleIdentifier)}.
3442 */
3443 Object visitPrefixedIdentifier(PrefixedIdentifier node) {
3444 SimpleIdentifier prefixedIdentifier = node.identifier;
3445 Element element24 = prefixedIdentifier.element;
3446 if (element24 is VariableElement) {
3447 Type2 variableType = ((element24 as VariableElement)).type;
3448 recordType(prefixedIdentifier, variableType);
3449 return recordType(node, variableType);
3450 } else if (element24 is PropertyAccessorElement) {
3451 Type2 propertyType = getType2((element24 as PropertyAccessorElement));
3452 recordType(prefixedIdentifier, propertyType);
3453 return recordType(node, propertyType);
3454 } else if (element24 is MethodElement) {
3455 Type2 returnType = ((element24 as MethodElement)).type;
3456 recordType(prefixedIdentifier, returnType);
3457 return recordType(node, returnType);
3458 } else {
3459 }
3460 recordType(prefixedIdentifier, _dynamicType);
3461 return recordType(node, _dynamicType);
3462 }
3463 /**
3464 * The Dart Language Specification, 12.27: <blockquote>A unary expression <i>u </i> of the form
3465 * <i>op e</i> is equivalent to a method invocation <i>expression e.op()</i>. An expression of the
3466 * form <i>op super</i> is equivalent to the method invocation <i>super.op()<i >.</blockquote>
3467 */
3468 Object visitPrefixExpression(PrefixExpression node) {
3469 sc.TokenType operator13 = node.operator.type;
3470 if (identical(operator13, sc.TokenType.BANG)) {
3471 return recordType(node, _typeProvider.boolType);
3472 }
3473 return recordReturnType(node, node.element);
3474 }
3475 /**
3476 * The Dart Language Specification, 12.13: <blockquote> Property extraction al lows for a member of
3477 * an object to be concisely extracted from the object. If <i>o</i> is an obje ct, and if <i>m</i>
3478 * is the name of a method member of <i>o</i>, then
3479 * <ul>
3480 * <li><i>o.m</i> is defined to be equivalent to: <i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>,
3481 * {p<sub>1</sub> : d<sub>1</sub>, &hellip;, p<sub>k</sub> : d<sub>k</sub>}){r eturn
3482 * o.m(r<sub>1</sub>, &hellip;, r<sub>n</sub>, p<sub>1</sub>: p<sub>1</sub>, & hellip;,
3483 * p<sub>k</sub>: p<sub>k</sub>);}</i> if <i>m</i> has required parameters <i> r<sub>1</sub>,
3484 * &hellip;, r<sub>n</sub></i>, and named parameters <i>p<sub>1</sub> &hellip; p<sub>k</sub></i>
3485 * with defaults <i>d<sub>1</sub>, &hellip;, d<sub>k</sub></i>.</li>
3486 * <li><i>(r<sub>1</sub>, &hellip;, r<sub>n</sub>, [p<sub>1</sub> = d<sub>1</s ub>, &hellip;,
3487 * p<sub>k</sub> = d<sub>k</sub>]){return o.m(r<sub>1</sub>, &hellip;, r<sub>n </sub>,
3488 * p<sub>1</sub>, &hellip;, p<sub>k</sub>);}</i> if <i>m</i> has required para meters
3489 * <i>r<sub>1</sub>, &hellip;, r<sub>n</sub></i>, and optional positional para meters
3490 * <i>p<sub>1</sub> &hellip; p<sub>k</sub></i> with defaults <i>d<sub>1</sub>, &hellip;,
3491 * d<sub>k</sub></i>.</li>
3492 * </ul>
3493 * Otherwise, if <i>m</i> is the name of a getter member of <i>o</i> (declared implicitly or
3494 * explicitly) then <i>o.m</i> evaluates to the result of invoking the getter. </blockquote>
3495 * <p>
3496 * The Dart Language Specification, 12.17: <blockquote> ... a getter invocatio n <i>i</i> of the
3497 * form <i>e.m</i> ...
3498 * <p>
3499 * Let <i>T</i> be the static type of <i>e</i>. It is a static type warning if <i>T</i> does not
3500 * have a getter named <i>m</i>.
3501 * <p>
3502 * The static type of <i>i</i> is the declared return type of <i>T.m</i>, if < i>T.m</i> exists;
3503 * otherwise the static type of <i>i</i> is dynamic.
3504 * <p>
3505 * ... a getter invocation <i>i</i> of the form <i>C.m</i> ...
3506 * <p>
3507 * It is a static warning if there is no class <i>C</i> in the enclosing lexic al scope of
3508 * <i>i</i>, or if <i>C</i> does not declare, implicitly or explicitly, a gett er named <i>m</i>.
3509 * <p>
3510 * The static type of <i>i</i> is the declared return type of <i>C.m</i> if it exists or dynamic
3511 * otherwise.
3512 * <p>
3513 * ... a top-level getter invocation <i>i</i> of the form <i>m</i>, where <i>m </i> is an
3514 * identifier ...
3515 * <p>
3516 * The static type of <i>i</i> is the declared return type of <i>m</i>.</block quote>
3517 */
3518 Object visitPropertyAccess(PropertyAccess node) {
3519 SimpleIdentifier propertyName2 = node.propertyName;
3520 Element element25 = propertyName2.element;
3521 if (element25 is MethodElement) {
3522 FunctionType type15 = ((element25 as MethodElement)).type;
3523 recordType(propertyName2, type15);
3524 return recordType(node, type15);
3525 } else if (element25 is PropertyAccessorElement) {
3526 Type2 propertyType = getType2((element25 as PropertyAccessorElement));
3527 recordType(propertyName2, propertyType);
3528 return recordType(node, propertyType);
3529 } else {
3530 }
3531 recordType(propertyName2, _dynamicType);
3532 return recordType(node, _dynamicType);
3533 }
3534 /**
3535 * The Dart Language Specification, 12.30: <blockquote>Evaluation of an identi fier expression
3536 * <i>e</i> of the form <i>id</i> proceeds as follows:
3537 * <p>
3538 * Let <i>d</i> be the innermost declaration in the enclosing lexical scope wh ose name is
3539 * <i>id</i>. If no such declaration exists in the lexical scope, let <i>d</i> be the declaration
3540 * of the inherited member named <i>id</i> if it exists.
3541 * <ul>
3542 * <li>If <i>d</i> is a class or type alias <i>T</i>, the value of <i>e</i> is the unique instance
3543 * of class {@code Type} reifying <i>T</i>.
3544 * <li>If <i>d</i> is a type parameter <i>T</i>, then the value of <i>e</i> is the value of the
3545 * actual type argument corresponding to <i>T</i> that was passed to the gener ative constructor
3546 * that created the current binding of this. We are assured that this is well defined, because if
3547 * we were in a static member the reference to <i>T</i> would be a compile-tim e error.
3548 * <li>If <i>d</i> is a library variable then:
3549 * <ul>
3550 * <li>If <i>d</i> is of one of the forms <i>var v = e<sub>i</sub>;</i>, <i>T v =
3551 * e<sub>i</sub>;</i>, <i>final v = e<sub>i</sub>;</i>, <i>final T v = e<sub>i </sub>;</i>, and no
3552 * value has yet been stored into <i>v</i> then the initializer expression <i> e<sub>i</sub></i> is
3553 * evaluated. If, during the evaluation of <i>e<sub>i</sub></i>, the getter fo r <i>v</i> is
3554 * referenced, a CyclicInitializationError is thrown. If the evaluation succee ded yielding an
3555 * object <i>o</i>, let <i>r = o</i>, otherwise let <i>r = null</i>. In any ca se, <i>r</i> is
3556 * stored into <i>v</i>. The value of <i>e</i> is <i>r</i>.
3557 * <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
3558 * of the getter is the value of the compile time constant <i>e</i>. Otherwise
3559 * <li><i>e</i> evaluates to the current binding of <i>id</i>.
3560 * </ul>
3561 * <li>If <i>d</i> is a local variable or formal parameter then <i>e</i> evalu ates to the current
3562 * binding of <i>id</i>.
3563 * <li>If <i>d</i> is a static method, top level function or local function th en <i>e</i>
3564 * evaluates to the function defined by <i>d</i>.
3565 * <li>If <i>d</i> is the declaration of a static variable or static getter de clared in class
3566 * <i>C</i>, then <i>e</i> is equivalent to the getter invocation <i>C.id</i>.
3567 * <li>If <i>d</i> is the declaration of a top level getter, then <i>e</i> is equivalent to the
3568 * getter invocation <i>id</i>.
3569 * <li>Otherwise, if <i>e</i> occurs inside a top level or static function (be it function,
3570 * method, getter, or setter) or variable initializer, evaluation of e causes a NoSuchMethodError
3571 * to be thrown.
3572 * <li>Otherwise <i>e</i> is equivalent to the property extraction <i>this.id< /i>.
3573 * </ul>
3574 * </blockquote>
3575 */
3576 Object visitSimpleIdentifier(SimpleIdentifier node) {
3577 Element element26 = node.element;
3578 if (element26 == null) {
3579 return recordType(node, _dynamicType);
3580 } else if (element26 is ClassElement) {
3581 if (isTypeName(node)) {
3582 return recordType(node, ((element26 as ClassElement)).type);
3583 }
3584 return recordType(node, _typeProvider.typeType);
3585 } else if (element26 is TypeVariableElement) {
3586 return recordType(node, ((element26 as TypeVariableElement)).type);
3587 } else if (element26 is TypeAliasElement) {
3588 return recordType(node, ((element26 as TypeAliasElement)).type);
3589 } else if (element26 is VariableElement) {
3590 return recordType(node, ((element26 as VariableElement)).type);
3591 } else if (element26 is MethodElement) {
3592 return recordType(node, ((element26 as MethodElement)).type);
3593 } else if (element26 is PropertyAccessorElement) {
3594 return recordType(node, getType2((element26 as PropertyAccessorElement)));
3595 } else if (element26 is ExecutableElement) {
3596 return recordType(node, ((element26 as ExecutableElement)).type);
3597 } else if (element26 is PrefixElement) {
3598 return null;
3599 } else {
3600 return recordType(node, _dynamicType);
3601 }
3602 }
3603 /**
3604 * The Dart Language Specification, 12.5: <blockquote>The static type of a str ing literal is{@code String}.</blockquote>
3605 */
3606 Object visitSimpleStringLiteral(SimpleStringLiteral node) => recordType(node, _typeProvider.stringType);
3607 /**
3608 * The Dart Language Specification, 12.5: <blockquote>The static type of a str ing literal is{@code String}.</blockquote>
3609 */
3610 Object visitStringInterpolation(StringInterpolation node) => recordType(node, _typeProvider.stringType);
3611 Object visitSuperExpression(SuperExpression node) {
3612 if (_thisType == null) {
3613 return recordType(node, _dynamicType);
3614 } else {
3615 return recordType(node, _thisType.superclass);
3616 }
3617 }
3618 /**
3619 * The Dart Language Specification, 12.10: <blockquote>The static type of {@co de this} is the
3620 * interface of the immediately enclosing class.</blockquote>
3621 */
3622 Object visitThisExpression(ThisExpression node) {
3623 if (_thisType == null) {
3624 return recordType(node, _dynamicType);
3625 } else {
3626 return recordType(node, _thisType);
3627 }
3628 }
3629 /**
3630 * The Dart Language Specification, 12.8: <blockquote>The static type of a thr ow expression is
3631 * bottom.</blockquote>
3632 */
3633 Object visitThrowExpression(ThrowExpression node) => recordType(node, _typePro vider.bottomType);
3634 /**
3635 * Given a function declaration, compute the return type of the function. The return type of
3636 * functions with a block body is {@code dynamicType}, with an expression body it is the type of
3637 * the expression.
3638 * @param node the function expression whose return type is to be computed
3639 * @return the return type that was computed
3640 */
3641 Type2 computeReturnType(FunctionDeclaration node) {
3642 TypeName returnType7 = node.returnType;
3643 if (returnType7 == null) {
3644 return computeReturnType2(node.functionExpression);
3645 }
3646 return returnType7.type;
3647 }
3648 /**
3649 * Given a function expression, compute the return type of the function. The r eturn type of
3650 * functions with a block body is {@code dynamicType}, with an expression body it is the type of
3651 * the expression.
3652 * @param node the function expression whose return type is to be computed
3653 * @return the return type that was computed
3654 */
3655 Type2 computeReturnType2(FunctionExpression node) {
3656 FunctionBody body4 = node.body;
3657 if (body4 is ExpressionFunctionBody) {
3658 return getType(((body4 as ExpressionFunctionBody)).expression);
3659 }
3660 return _dynamicType;
3661 }
3662 /**
3663 * Return the type of the given expression that is to be used for type analysi s.
3664 * @param expression the expression whose type is to be returned
3665 * @return the type of the given expression
3666 */
3667 Type2 getType(Expression expression) {
3668 Type2 type = expression.staticType;
3669 if (type == null) {
3670 return _dynamicType;
3671 }
3672 return type;
3673 }
3674 /**
3675 * Return the type that should be recorded for a node that resolved to the giv en accessor.
3676 * @param accessor the accessor that the node resolved to
3677 * @return the type that should be recorded for a node that resolved to the gi ven accessor
3678 */
3679 Type2 getType2(PropertyAccessorElement accessor) {
3680 FunctionType functionType = accessor.type;
3681 if (functionType == null) {
3682 return _dynamicType;
3683 }
3684 if (accessor.isSetter()) {
3685 List<Type2> parameterTypes = functionType.normalParameterTypes;
3686 if (parameterTypes != null && parameterTypes.length > 0) {
3687 return parameterTypes[0];
3688 }
3689 PropertyAccessorElement getter4 = accessor.variable.getter;
3690 if (getter4 != null) {
3691 functionType = getter4.type;
3692 if (functionType != null) {
3693 return functionType.returnType;
3694 }
3695 }
3696 return _dynamicType;
3697 }
3698 return functionType.returnType;
3699 }
3700 /**
3701 * Return the type represented by the given type name.
3702 * @param typeName the type name representing the type to be returned
3703 * @return the type represented by the type name
3704 */
3705 Type2 getType3(TypeName typeName) {
3706 Type2 type16 = typeName.type;
3707 if (type16 == null) {
3708 return _dynamicType;
3709 }
3710 return type16;
3711 }
3712 /**
3713 * Return {@code true} if the given node is being used as the name of a type.
3714 * @param node the node being tested
3715 * @return {@code true} if the given node is being used as the name of a type
3716 */
3717 bool isTypeName(SimpleIdentifier node) {
3718 ASTNode parent15 = node.parent;
3719 return parent15 is TypeName || (parent15 is PrefixedIdentifier && parent15.p arent is TypeName) || (parent15 is MethodInvocation && identical(node, ((parent1 5 as MethodInvocation)).target));
3720 }
3721 /**
3722 * Record that the static type of the given node is the type of the second arg ument to the method
3723 * represented by the given element.
3724 * @param expression the node whose type is to be recorded
3725 * @param element the element representing the method invoked by the given nod e
3726 */
3727 Object recordArgumentType(IndexExpression expression, MethodElement element) {
3728 if (element != null) {
3729 List<ParameterElement> parameters12 = element.parameters;
3730 if (parameters12 != null && parameters12.length == 2) {
3731 return recordType(expression, parameters12[1].type);
3732 }
3733 }
3734 return recordType(expression, _dynamicType);
3735 }
3736 /**
3737 * Record that the static type of the given node is the return type of the met hod or function
3738 * represented by the given element.
3739 * @param expression the node whose type is to be recorded
3740 * @param element the element representing the method or function invoked by t he given node
3741 */
3742 Object recordReturnType(Expression expression, Element element) {
3743 if (element is PropertyAccessorElement) {
3744 FunctionType propertyType = ((element as PropertyAccessorElement)).type;
3745 if (propertyType != null) {
3746 Type2 returnType8 = propertyType.returnType;
3747 if (returnType8 is FunctionType) {
3748 Type2 innerReturnType = ((returnType8 as FunctionType)).returnType;
3749 if (innerReturnType != null) {
3750 return recordType(expression, innerReturnType);
3751 }
3752 }
3753 if (returnType8 != null) {
3754 return recordType(expression, returnType8);
3755 }
3756 }
3757 } else if (element is ExecutableElement) {
3758 FunctionType type17 = ((element as ExecutableElement)).type;
3759 if (type17 != null) {
3760 return recordType(expression, type17.returnType);
3761 }
3762 } else if (element is VariableElement) {
3763 Type2 variableType = ((element as VariableElement)).type;
3764 if (variableType is FunctionType) {
3765 return recordType(expression, ((variableType as FunctionType)).returnTyp e);
3766 }
3767 }
3768 return recordType(expression, _dynamicType);
3769 }
3770 /**
3771 * Record that the static type of the given node is the given type.
3772 * @param expression the node whose type is to be recorded
3773 * @param type the static type of the node
3774 */
3775 Object recordType(Expression expression, Type2 type) {
3776 if (type == null) {
3777 expression.staticType = _dynamicType;
3778 } else {
3779 expression.staticType = type;
3780 }
3781 return null;
3782 }
3783 /**
3784 * Set the return type and parameter type information for the given function t ype based on the
3785 * given return type and parameter elements.
3786 * @param functionType the function type to be filled in
3787 * @param returnType the return type of the function, or {@code null} if no ty pe was declared
3788 * @param parameters the elements representing the parameters to the function
3789 */
3790 void setTypeInformation(FunctionTypeImpl functionType, Type2 returnType11, For malParameterList parameterList) {
3791 List<Type2> normalParameterTypes = new List<Type2>();
3792 List<Type2> optionalParameterTypes = new List<Type2>();
3793 LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
3794 if (parameterList != null) {
3795 for (ParameterElement parameter in parameterList.elements) {
3796 while (true) {
3797 if (parameter.parameterKind == ParameterKind.REQUIRED) {
3798 normalParameterTypes.add(parameter.type);
3799 } else if (parameter.parameterKind == ParameterKind.POSITIONAL) {
3800 optionalParameterTypes.add(parameter.type);
3801 } else if (parameter.parameterKind == ParameterKind.NAMED) {
3802 namedParameterTypes[parameter.name] = parameter.type;
3803 }
3804 break;
3805 }
3806 }
3807 }
3808 functionType.normalParameterTypes = new List.from(normalParameterTypes);
3809 functionType.optionalParameterTypes = new List.from(optionalParameterTypes);
3810 functionType.namedParameterTypes = namedParameterTypes;
3811 functionType.returnType = returnType11;
3812 }
3813 get thisType_J2DAccessor => _thisType;
3814 set thisType_J2DAccessor(__v) => _thisType = __v;
3815 }
3816 /**
3817 * The interface {@code TypeProvider} defines the behavior of objects that provi de access to types
3818 * defined by the language.
3819 * @coverage dart.engine.resolver
3820 */
3821 abstract class TypeProvider {
3822 /**
3823 * Return the type representing the built-in type 'bool'.
3824 * @return the type representing the built-in type 'bool'
3825 */
3826 InterfaceType get boolType;
3827 /**
3828 * Return the type representing the type 'bottom'.
3829 * @return the type representing the type 'bottom'
3830 */
3831 Type2 get bottomType;
3832 /**
3833 * Return the type representing the built-in type 'double'.
3834 * @return the type representing the built-in type 'double'
3835 */
3836 InterfaceType get doubleType;
3837 /**
3838 * Return the type representing the built-in type 'dynamic'.
3839 * @return the type representing the built-in type 'dynamic'
3840 */
3841 Type2 get dynamicType;
3842 /**
3843 * Return the type representing the built-in type 'Function'.
3844 * @return the type representing the built-in type 'Function'
3845 */
3846 InterfaceType get functionType;
3847 /**
3848 * Return the type representing the built-in type 'int'.
3849 * @return the type representing the built-in type 'int'
3850 */
3851 InterfaceType get intType;
3852 /**
3853 * Return the type representing the built-in type 'List'.
3854 * @return the type representing the built-in type 'List'
3855 */
3856 InterfaceType get listType;
3857 /**
3858 * Return the type representing the built-in type 'Map'.
3859 * @return the type representing the built-in type 'Map'
3860 */
3861 InterfaceType get mapType;
3862 /**
3863 * Return the type representing the built-in type 'Object'.
3864 * @return the type representing the built-in type 'Object'
3865 */
3866 InterfaceType get objectType;
3867 /**
3868 * Return the type representing the built-in type 'StackTrace'.
3869 * @return the type representing the built-in type 'StackTrace'
3870 */
3871 InterfaceType get stackTraceType;
3872 /**
3873 * Return the type representing the built-in type 'String'.
3874 * @return the type representing the built-in type 'String'
3875 */
3876 InterfaceType get stringType;
3877 /**
3878 * Return the type representing the built-in type 'Type'.
3879 * @return the type representing the built-in type 'Type'
3880 */
3881 InterfaceType get typeType;
3882 }
3883 /**
3884 * Instances of the class {@code TypeProviderImpl} provide access to types defin ed by the language
3885 * by looking for those types in the element model for the core library.
3886 * @coverage dart.engine.resolver
3887 */
3888 class TypeProviderImpl implements TypeProvider {
3889 /**
3890 * The type representing the built-in type 'bool'.
3891 */
3892 InterfaceType _boolType;
3893 /**
3894 * The type representing the type 'bottom'.
3895 */
3896 Type2 _bottomType;
3897 /**
3898 * The type representing the built-in type 'double'.
3899 */
3900 InterfaceType _doubleType;
3901 /**
3902 * The type representing the built-in type 'dynamic'.
3903 */
3904 Type2 _dynamicType;
3905 /**
3906 * The type representing the built-in type 'Function'.
3907 */
3908 InterfaceType _functionType;
3909 /**
3910 * The type representing the built-in type 'int'.
3911 */
3912 InterfaceType _intType;
3913 /**
3914 * The type representing the built-in type 'List'.
3915 */
3916 InterfaceType _listType;
3917 /**
3918 * The type representing the built-in type 'Map'.
3919 */
3920 InterfaceType _mapType;
3921 /**
3922 * The type representing the built-in type 'Object'.
3923 */
3924 InterfaceType _objectType;
3925 /**
3926 * The type representing the built-in type 'StackTrace'.
3927 */
3928 InterfaceType _stackTraceType;
3929 /**
3930 * The type representing the built-in type 'String'.
3931 */
3932 InterfaceType _stringType;
3933 /**
3934 * The type representing the built-in type 'Type'.
3935 */
3936 InterfaceType _typeType;
3937 /**
3938 * Initialize a newly created type provider to provide the types defined in th e given library.
3939 * @param coreLibrary the element representing the core library (dart:core).
3940 */
3941 TypeProviderImpl(LibraryElement coreLibrary) {
3942 initializeFrom(coreLibrary);
3943 }
3944 InterfaceType get boolType => _boolType;
3945 Type2 get bottomType => _bottomType;
3946 InterfaceType get doubleType => _doubleType;
3947 Type2 get dynamicType => _dynamicType;
3948 InterfaceType get functionType => _functionType;
3949 InterfaceType get intType => _intType;
3950 InterfaceType get listType => _listType;
3951 InterfaceType get mapType => _mapType;
3952 InterfaceType get objectType => _objectType;
3953 InterfaceType get stackTraceType => _stackTraceType;
3954 InterfaceType get stringType => _stringType;
3955 InterfaceType get typeType => _typeType;
3956 /**
3957 * Return the type with the given name from the given namespace, or {@code nul l} if there is no
3958 * class with the given name.
3959 * @param namespace the namespace in which to search for the given name
3960 * @param typeName the name of the type being searched for
3961 * @return the type that was found
3962 */
3963 InterfaceType getType(Namespace namespace, String typeName) {
3964 Element element = namespace.get(typeName);
3965 if (element == null) {
3966 AnalysisEngine.instance.logger.logInformation("No definition of type ${typ eName}");
3967 return null;
3968 }
3969 return ((element as ClassElement)).type;
3970 }
3971 /**
3972 * Initialize the types provided by this type provider from the given library.
3973 * @param library the library containing the definitions of the core types
3974 */
3975 void initializeFrom(LibraryElement library) {
3976 Namespace namespace = new NamespaceBuilder().createPublicNamespace(library);
3977 _boolType = getType(namespace, "bool");
3978 _bottomType = BottomTypeImpl.instance;
3979 _doubleType = getType(namespace, "double");
3980 _dynamicType = DynamicTypeImpl.instance;
3981 _functionType = getType(namespace, "Function");
3982 _intType = getType(namespace, "int");
3983 _listType = getType(namespace, "List");
3984 _mapType = getType(namespace, "Map");
3985 _objectType = getType(namespace, "Object");
3986 _stackTraceType = getType(namespace, "StackTrace");
3987 _stringType = getType(namespace, "String");
3988 _typeType = getType(namespace, "Type");
3989 }
3990 }
3991 /**
3992 * Instances of the class {@code TypeResolverVisitor} are used to resolve the ty pes associated with
3993 * the elements in the element model. This includes the types of superclasses, m ixins, interfaces,
3994 * fields, methods, parameters, and local variables. As a side-effect, this also finishes building
3995 * the type hierarchy.
3996 * @coverage dart.engine.resolver
3997 */
3998 class TypeResolverVisitor extends ScopedVisitor {
3999 /**
4000 * The type representing the type 'dynamic'.
4001 */
4002 Type2 _dynamicType;
4003 /**
4004 * Initialize a newly created visitor to resolve the nodes in a compilation un it.
4005 * @param library the library containing the compilation unit being resolved
4006 * @param source the source representing the compilation unit being visited
4007 * @param typeProvider the object used to access the types from the core libra ry
4008 */
4009 TypeResolverVisitor(Library library, Source source, TypeProvider typeProvider) : super(library, source, typeProvider) {
4010 _dynamicType = typeProvider.dynamicType;
4011 }
4012 Object visitCatchClause(CatchClause node) {
4013 super.visitCatchClause(node);
4014 SimpleIdentifier exception = node.exceptionParameter;
4015 if (exception != null) {
4016 TypeName exceptionTypeName = node.exceptionType;
4017 Type2 exceptionType;
4018 if (exceptionTypeName == null) {
4019 exceptionType = typeProvider.objectType;
4020 } else {
4021 exceptionType = getType4(exceptionTypeName);
4022 }
4023 recordType(exception, exceptionType);
4024 Element element27 = exception.element;
4025 if (element27 is VariableElementImpl) {
4026 ((element27 as VariableElementImpl)).type = exceptionType;
4027 } else {
4028 }
4029 }
4030 SimpleIdentifier stackTrace = node.stackTraceParameter;
4031 if (stackTrace != null) {
4032 recordType(stackTrace, typeProvider.stackTraceType);
4033 }
4034 return null;
4035 }
4036 Object visitClassDeclaration(ClassDeclaration node) {
4037 super.visitClassDeclaration(node);
4038 ClassElementImpl classElement = getClassElement(node.name);
4039 InterfaceType superclassType = null;
4040 ExtendsClause extendsClause4 = node.extendsClause;
4041 if (extendsClause4 != null) {
4042 superclassType = resolveType(extendsClause4.superclass, CompileTimeErrorCo de.EXTENDS_NON_CLASS, CompileTimeErrorCode.EXTENDS_NON_CLASS, null);
4043 if (superclassType != typeProvider.objectType) {
4044 classElement.validMixin = false;
4045 }
4046 }
4047 if (classElement != null) {
4048 if (superclassType == null) {
4049 InterfaceType objectType2 = typeProvider.objectType;
4050 if (classElement.type != objectType2) {
4051 superclassType = objectType2;
4052 }
4053 }
4054 classElement.supertype = superclassType;
4055 }
4056 resolve(classElement, node.withClause, node.implementsClause);
4057 return null;
4058 }
4059 Object visitClassTypeAlias(ClassTypeAlias node) {
4060 super.visitClassTypeAlias(node);
4061 ClassElementImpl classElement = getClassElement(node.name);
4062 InterfaceType superclassType = resolveType(node.superclass, CompileTimeError Code.EXTENDS_NON_CLASS, CompileTimeErrorCode.EXTENDS_NON_CLASS, null);
4063 if (superclassType == null) {
4064 superclassType = typeProvider.objectType;
4065 }
4066 if (classElement != null && superclassType != null) {
4067 classElement.supertype = superclassType;
4068 }
4069 resolve(classElement, node.withClause, node.implementsClause);
4070 return null;
4071 }
4072 Object visitConstructorDeclaration(ConstructorDeclaration node) {
4073 super.visitConstructorDeclaration(node);
4074 ExecutableElementImpl element28 = node.element as ExecutableElementImpl;
4075 FunctionTypeImpl type = new FunctionTypeImpl.con1(element28);
4076 setTypeInformation(type, null, element28.parameters);
4077 type.returnType = ((element28.enclosingElement as ClassElement)).type;
4078 element28.type = type;
4079 return null;
4080 }
4081 Object visitDeclaredIdentifier(DeclaredIdentifier node) {
4082 super.visitDeclaredIdentifier(node);
4083 Type2 declaredType;
4084 TypeName typeName = node.type;
4085 if (typeName == null) {
4086 declaredType = _dynamicType;
4087 } else {
4088 declaredType = getType4(typeName);
4089 }
4090 LocalVariableElementImpl element29 = node.element as LocalVariableElementImp l;
4091 element29.type = declaredType;
4092 return null;
4093 }
4094 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
4095 super.visitDefaultFormalParameter(node);
4096 return null;
4097 }
4098 Object visitFieldFormalParameter(FieldFormalParameter node) {
4099 super.visitFieldFormalParameter(node);
4100 Element element30 = node.identifier.element;
4101 if (element30 is ParameterElementImpl) {
4102 ParameterElementImpl parameter = element30 as ParameterElementImpl;
4103 Type2 type;
4104 TypeName typeName = node.type;
4105 if (typeName == null) {
4106 type = _dynamicType;
4107 } else {
4108 type = getType4(typeName);
4109 }
4110 parameter.type = type;
4111 } else {
4112 }
4113 return null;
4114 }
4115 Object visitFunctionDeclaration(FunctionDeclaration node) {
4116 super.visitFunctionDeclaration(node);
4117 ExecutableElementImpl element31 = node.element as ExecutableElementImpl;
4118 FunctionTypeImpl type = new FunctionTypeImpl.con1(element31);
4119 setTypeInformation(type, node.returnType, element31.parameters);
4120 element31.type = type;
4121 return null;
4122 }
4123 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
4124 super.visitFunctionTypeAlias(node);
4125 TypeAliasElementImpl element32 = node.element as TypeAliasElementImpl;
4126 FunctionTypeImpl type18 = element32.type as FunctionTypeImpl;
4127 setTypeInformation(type18, node.returnType, element32.parameters);
4128 return null;
4129 }
4130 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
4131 super.visitFunctionTypedFormalParameter(node);
4132 ParameterElementImpl element33 = node.identifier.element as ParameterElement Impl;
4133 FunctionTypeImpl type = new FunctionTypeImpl.con1((null as ExecutableElement ));
4134 setTypeInformation(type, node.returnType, getElements(node.parameters));
4135 element33.type = type;
4136 return null;
4137 }
4138 Object visitMethodDeclaration(MethodDeclaration node) {
4139 super.visitMethodDeclaration(node);
4140 ExecutableElementImpl element34 = node.element as ExecutableElementImpl;
4141 FunctionTypeImpl type = new FunctionTypeImpl.con1(element34);
4142 setTypeInformation(type, node.returnType, element34.parameters);
4143 element34.type = type;
4144 if (element34 is PropertyAccessorElementImpl) {
4145 PropertyAccessorElementImpl accessor = element34 as PropertyAccessorElemen tImpl;
4146 PropertyInducingElementImpl variable5 = accessor.variable as PropertyInduc ingElementImpl;
4147 if (accessor.isGetter()) {
4148 variable5.type = type.returnType;
4149 } else if (variable5.type == null) {
4150 List<Type2> parameterTypes = type.normalParameterTypes;
4151 if (parameterTypes != null && parameterTypes.length > 0) {
4152 variable5.type = parameterTypes[0];
4153 }
4154 }
4155 }
4156 return null;
4157 }
4158 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
4159 super.visitSimpleFormalParameter(node);
4160 Type2 declaredType;
4161 TypeName typeName = node.type;
4162 if (typeName == null) {
4163 declaredType = _dynamicType;
4164 } else {
4165 declaredType = getType4(typeName);
4166 }
4167 Element element35 = node.identifier.element;
4168 if (element35 is ParameterElement) {
4169 ((element35 as ParameterElementImpl)).type = declaredType;
4170 } else {
4171 }
4172 return null;
4173 }
4174 Object visitTypeName(TypeName node) {
4175 super.visitTypeName(node);
4176 Identifier typeName = node.name;
4177 TypeArgumentList argumentList = node.typeArguments;
4178 Element element = nameScope.lookup(typeName, definingLibrary);
4179 if (element == null) {
4180 if (typeName.name == _dynamicType.name) {
4181 setElement(typeName, _dynamicType.element);
4182 if (argumentList != null) {
4183 }
4184 typeName.staticType = _dynamicType;
4185 node.type = _dynamicType;
4186 return null;
4187 }
4188 VoidTypeImpl voidType = VoidTypeImpl.instance;
4189 if (typeName.name == voidType.name) {
4190 if (argumentList != null) {
4191 }
4192 typeName.staticType = voidType;
4193 node.type = voidType;
4194 return null;
4195 }
4196 ASTNode parent16 = node.parent;
4197 if (typeName is PrefixedIdentifier && parent16 is ConstructorName && argum entList == null) {
4198 ConstructorName name = parent16 as ConstructorName;
4199 if (name.name == null) {
4200 SimpleIdentifier prefix8 = ((typeName as PrefixedIdentifier)).prefix;
4201 element = nameScope.lookup(prefix8, definingLibrary);
4202 if (element is PrefixElement) {
4203 return null;
4204 } else if (element != null) {
4205 name.name = ((typeName as PrefixedIdentifier)).identifier;
4206 name.period = ((typeName as PrefixedIdentifier)).period;
4207 node.name = prefix8;
4208 typeName = prefix8;
4209 }
4210 }
4211 }
4212 }
4213 if (element == null) {
4214 setElement(typeName, _dynamicType.element);
4215 typeName.staticType = _dynamicType;
4216 node.type = _dynamicType;
4217 return null;
4218 }
4219 Type2 type = null;
4220 if (element is ClassElement) {
4221 setElement(typeName, element);
4222 type = ((element as ClassElement)).type;
4223 } else if (element is TypeAliasElement) {
4224 setElement(typeName, element);
4225 type = ((element as TypeAliasElement)).type;
4226 } else if (element is TypeVariableElement) {
4227 setElement(typeName, element);
4228 type = ((element as TypeVariableElement)).type;
4229 if (argumentList != null) {
4230 }
4231 } else {
4232 setElement(typeName, _dynamicType.element);
4233 typeName.staticType = _dynamicType;
4234 node.type = _dynamicType;
4235 return null;
4236 }
4237 if (argumentList != null) {
4238 NodeList<TypeName> arguments5 = argumentList.arguments;
4239 int argumentCount = arguments5.length;
4240 List<Type2> parameters = getTypeArguments(type);
4241 int parameterCount = parameters.length;
4242 int count = Math.min(argumentCount, parameterCount);
4243 List<Type2> typeArguments = new List<Type2>();
4244 for (int i = 0; i < count; i++) {
4245 Type2 argumentType = getType4(arguments5[i]);
4246 if (argumentType != null) {
4247 typeArguments.add(argumentType);
4248 }
4249 }
4250 if (argumentCount != parameterCount) {
4251 reportError(getInvalidTypeParametersErrorCode(node), node, [typeName.nam e, argumentCount, parameterCount]);
4252 }
4253 argumentCount = typeArguments.length;
4254 if (argumentCount < parameterCount) {
4255 for (int i = argumentCount; i < parameterCount; i++) {
4256 typeArguments.add(_dynamicType);
4257 }
4258 }
4259 if (type is InterfaceTypeImpl) {
4260 InterfaceTypeImpl interfaceType = type as InterfaceTypeImpl;
4261 type = interfaceType.substitute5(new List.from(typeArguments));
4262 } else if (type is FunctionTypeImpl) {
4263 FunctionTypeImpl functionType = type as FunctionTypeImpl;
4264 type = functionType.substitute4(new List.from(typeArguments));
4265 } else {
4266 }
4267 } else {
4268 List<Type2> parameters = getTypeArguments(type);
4269 int parameterCount = parameters.length;
4270 if (parameterCount > 0) {
4271 DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
4272 List<Type2> arguments = new List<Type2>(parameterCount);
4273 for (int i = 0; i < parameterCount; i++) {
4274 arguments[i] = dynamicType;
4275 }
4276 type = type.substitute2(arguments, parameters);
4277 }
4278 }
4279 typeName.staticType = type;
4280 node.type = type;
4281 return null;
4282 }
4283 Object visitVariableDeclaration(VariableDeclaration node) {
4284 super.visitVariableDeclaration(node);
4285 Type2 declaredType;
4286 TypeName typeName = ((node.parent as VariableDeclarationList)).type;
4287 if (typeName == null) {
4288 declaredType = _dynamicType;
4289 } else {
4290 declaredType = getType4(typeName);
4291 }
4292 Element element36 = node.name.element;
4293 if (element36 is VariableElement) {
4294 ((element36 as VariableElementImpl)).type = declaredType;
4295 if (element36 is FieldElement) {
4296 FieldElement field = element36 as FieldElement;
4297 PropertyAccessorElementImpl getter5 = field.getter as PropertyAccessorEl ementImpl;
4298 FunctionTypeImpl getterType = new FunctionTypeImpl.con1(getter5);
4299 getterType.returnType = declaredType;
4300 getter5.type = getterType;
4301 PropertyAccessorElementImpl setter4 = field.setter as PropertyAccessorEl ementImpl;
4302 if (setter4 != null) {
4303 FunctionTypeImpl setterType = new FunctionTypeImpl.con1(setter4);
4304 setterType.returnType = VoidTypeImpl.instance;
4305 setterType.normalParameterTypes = <Type2> [declaredType];
4306 setter4.type = setterType;
4307 }
4308 }
4309 } else {
4310 }
4311 return null;
4312 }
4313 /**
4314 * Return the class element that represents the class whose name was provided.
4315 * @param identifier the name from the declaration of a class
4316 * @return the class element that represents the class
4317 */
4318 ClassElementImpl getClassElement(SimpleIdentifier identifier) {
4319 if (identifier == null) {
4320 return null;
4321 }
4322 Element element37 = identifier.element;
4323 if (element37 is! ClassElementImpl) {
4324 return null;
4325 }
4326 return element37 as ClassElementImpl;
4327 }
4328 /**
4329 * Return an array containing all of the elements associated with the paramete rs in the given
4330 * list.
4331 * @param parameterList the list of parameters whose elements are to be return ed
4332 * @return the elements associated with the parameters
4333 */
4334 List<ParameterElement> getElements(FormalParameterList parameterList) {
4335 List<ParameterElement> elements = new List<ParameterElement>();
4336 for (FormalParameter parameter in parameterList.parameters) {
4337 ParameterElement element38 = parameter.identifier.element as ParameterElem ent;
4338 if (element38 != null) {
4339 elements.add(element38);
4340 }
4341 }
4342 return new List.from(elements);
4343 }
4344 /**
4345 * The number of type arguments in the given type name does not match the numb er of parameters in
4346 * the corresponding class element. Return the error code that should be used to report this
4347 * error.
4348 * @param node the type name with the wrong number of type arguments
4349 * @return the error code that should be used to report that the wrong number of type arguments
4350 * were provided
4351 */
4352 ErrorCode getInvalidTypeParametersErrorCode(TypeName node) {
4353 ASTNode parent17 = node.parent;
4354 if (parent17 is ConstructorName) {
4355 parent17 = parent17.parent;
4356 if (parent17 is InstanceCreationExpression) {
4357 if (((parent17 as InstanceCreationExpression)).isConst()) {
4358 return CompileTimeErrorCode.CONST_WITH_INVALID_TYPE_PARAMETERS;
4359 } else {
4360 return CompileTimeErrorCode.NEW_WITH_INVALID_TYPE_PARAMETERS;
4361 }
4362 }
4363 }
4364 return StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS;
4365 }
4366 /**
4367 * Given the multiple elements to which a single name could potentially be res olved, return the
4368 * single interface type that should be used, or {@code null} if there is no c lear choice.
4369 * @param elements the elements to which a single name could potentially be re solved
4370 * @return the single interface type that should be used for the type name
4371 */
4372 InterfaceType getType(List<Element> elements) {
4373 InterfaceType type = null;
4374 for (Element element in elements) {
4375 if (element is ClassElement) {
4376 if (type != null) {
4377 return null;
4378 }
4379 type = ((element as ClassElement)).type;
4380 }
4381 }
4382 return type;
4383 }
4384 /**
4385 * Return the type represented by the given type name.
4386 * @param typeName the type name representing the type to be returned
4387 * @return the type represented by the type name
4388 */
4389 Type2 getType4(TypeName typeName) {
4390 Type2 type19 = typeName.type;
4391 if (type19 == null) {
4392 return _dynamicType;
4393 }
4394 return type19;
4395 }
4396 /**
4397 * Return the type arguments associated with the given type.
4398 * @param type the type whole type arguments are to be returned
4399 * @return the type arguments associated with the given type
4400 */
4401 List<Type2> getTypeArguments(Type2 type) {
4402 if (type is InterfaceType) {
4403 return ((type as InterfaceType)).typeArguments;
4404 } else if (type is FunctionType) {
4405 return ((type as FunctionType)).typeArguments;
4406 }
4407 return TypeImpl.EMPTY_ARRAY;
4408 }
4409 /**
4410 * Record that the static type of the given node is the given type.
4411 * @param expression the node whose type is to be recorded
4412 * @param type the static type of the node
4413 */
4414 Object recordType(Expression expression, Type2 type) {
4415 if (type == null) {
4416 expression.staticType = _dynamicType;
4417 } else {
4418 expression.staticType = type;
4419 }
4420 return null;
4421 }
4422 /**
4423 * Resolve the types in the given with and implements clauses and associate th ose types with the
4424 * given class element.
4425 * @param classElement the class element with which the mixin and interface ty pes are to be
4426 * associated
4427 * @param withClause the with clause to be resolved
4428 * @param implementsClause the implements clause to be resolved
4429 */
4430 void resolve(ClassElementImpl classElement, WithClause withClause, ImplementsC lause implementsClause) {
4431 if (withClause != null) {
4432 List<InterfaceType> mixinTypes2 = resolveTypes(withClause.mixinTypes, Comp ileTimeErrorCode.MIXIN_OF_NON_CLASS, CompileTimeErrorCode.MIXIN_OF_NON_CLASS, nu ll);
4433 if (classElement != null) {
4434 classElement.mixins = mixinTypes2;
4435 }
4436 }
4437 if (implementsClause != null) {
4438 List<InterfaceType> interfaceTypes = resolveTypes(implementsClause.interfa ces, CompileTimeErrorCode.IMPLEMENTS_NON_CLASS, CompileTimeErrorCode.IMPLEMENTS_ NON_CLASS, null);
4439 if (classElement != null) {
4440 classElement.interfaces = interfaceTypes;
4441 }
4442 }
4443 }
4444 /**
4445 * Return the type specified by the given name.
4446 * @param typeName the type name specifying the type to be returned
4447 * @param undefinedError the error to produce if the type name is not defined
4448 * @param nonTypeError the error to produce if the type name is defined to be something other than
4449 * a type
4450 * @param nonInterfaceType the error to produce if the type is not an interfac e type
4451 * @return the type specified by the type name
4452 */
4453 InterfaceType resolveType(TypeName typeName, ErrorCode undefinedError, ErrorCo de nonTypeError, ErrorCode nonInterfaceType) {
4454 Identifier name16 = typeName.name;
4455 Element element = nameScope.lookup(name16, definingLibrary);
4456 if (element == null) {
4457 reportError(undefinedError, name16, []);
4458 } else if (element is ClassElement) {
4459 Type2 classType = ((element as ClassElement)).type;
4460 typeName.type = classType;
4461 if (classType is InterfaceType) {
4462 return classType as InterfaceType;
4463 }
4464 reportError(nonInterfaceType, name16, []);
4465 } else if (element is MultiplyDefinedElement) {
4466 List<Element> elements = ((element as MultiplyDefinedElement)).conflicting Elements;
4467 InterfaceType type = getType(elements);
4468 if (type != null) {
4469 typeName.type = type;
4470 }
4471 } else {
4472 reportError(nonTypeError, name16, []);
4473 }
4474 return null;
4475 }
4476 /**
4477 * Resolve the types in the given list of type names.
4478 * @param typeNames the type names to be resolved
4479 * @param undefinedError the error to produce if the type name is not defined
4480 * @param nonTypeError the error to produce if the type name is defined to be something other than
4481 * a type
4482 * @param nonInterfaceType the error to produce if the type is not an interfac e type
4483 * @return an array containing all of the types that were resolved.
4484 */
4485 List<InterfaceType> resolveTypes(NodeList<TypeName> typeNames, ErrorCode undef inedError, ErrorCode nonTypeError, ErrorCode nonInterfaceType) {
4486 List<InterfaceType> types = new List<InterfaceType>();
4487 for (TypeName typeName in typeNames) {
4488 InterfaceType type = resolveType(typeName, undefinedError, nonTypeError, n onInterfaceType);
4489 if (type != null) {
4490 types.add(type);
4491 }
4492 }
4493 return new List.from(types);
4494 }
4495 void setElement(Identifier typeName, Element element51) {
4496 if (element51 != null) {
4497 if (typeName is SimpleIdentifier) {
4498 ((typeName as SimpleIdentifier)).element = element51;
4499 } else if (typeName is PrefixedIdentifier) {
4500 PrefixedIdentifier identifier = typeName as PrefixedIdentifier;
4501 identifier.identifier.element = element51;
4502 SimpleIdentifier prefix9 = identifier.prefix;
4503 Element prefixElement = nameScope.lookup(prefix9, definingLibrary);
4504 if (prefixElement != null) {
4505 prefix9.element = prefixElement;
4506 }
4507 }
4508 }
4509 }
4510 /**
4511 * Set the return type and parameter type information for the given function t ype based on the
4512 * given return type and parameter elements.
4513 * @param functionType the function type to be filled in
4514 * @param returnType the return type of the function, or {@code null} if no ty pe was declared
4515 * @param parameters the elements representing the parameters to the function
4516 */
4517 void setTypeInformation(FunctionTypeImpl functionType, TypeName returnType12, List<ParameterElement> parameters) {
4518 List<Type2> normalParameterTypes = new List<Type2>();
4519 List<Type2> optionalParameterTypes = new List<Type2>();
4520 LinkedHashMap<String, Type2> namedParameterTypes = new LinkedHashMap<String, Type2>();
4521 for (ParameterElement parameter in parameters) {
4522 while (true) {
4523 if (parameter.parameterKind == ParameterKind.REQUIRED) {
4524 normalParameterTypes.add(parameter.type);
4525 } else if (parameter.parameterKind == ParameterKind.POSITIONAL) {
4526 optionalParameterTypes.add(parameter.type);
4527 } else if (parameter.parameterKind == ParameterKind.NAMED) {
4528 namedParameterTypes[parameter.name] = parameter.type;
4529 }
4530 break;
4531 }
4532 }
4533 if (!normalParameterTypes.isEmpty) {
4534 functionType.normalParameterTypes = new List.from(normalParameterTypes);
4535 }
4536 if (!optionalParameterTypes.isEmpty) {
4537 functionType.optionalParameterTypes = new List.from(optionalParameterTypes );
4538 }
4539 if (!namedParameterTypes.isEmpty) {
4540 functionType.namedParameterTypes = namedParameterTypes;
4541 }
4542 if (returnType12 == null) {
4543 functionType.returnType = _dynamicType;
4544 } else {
4545 functionType.returnType = returnType12.type;
4546 }
4547 }
4548 }
4549 /**
4550 * Instances of the class {@code ClassScope} implement the scope defined by a cl ass.
4551 * @coverage dart.engine.resolver
4552 */
4553 class ClassScope extends EnclosedScope {
4554 /**
4555 * Initialize a newly created scope enclosed within another scope.
4556 * @param enclosingScope the scope in which this scope is lexically enclosed
4557 * @param typeElement the element representing the type represented by this sc ope
4558 */
4559 ClassScope(Scope enclosingScope, ClassElement typeElement) : super(new Enclose dScope(enclosingScope)) {
4560 defineTypeParameters(typeElement);
4561 defineMembers(typeElement);
4562 }
4563 /**
4564 * Define the instance members defined by the class.
4565 * @param typeElement the element representing the type represented by this sc ope
4566 */
4567 void defineMembers(ClassElement typeElement) {
4568 for (PropertyAccessorElement accessor in typeElement.accessors) {
4569 define(accessor);
4570 }
4571 for (MethodElement method in typeElement.methods) {
4572 define(method);
4573 }
4574 }
4575 /**
4576 * Define the type parameters for the class.
4577 * @param typeElement the element representing the type represented by this sc ope
4578 */
4579 void defineTypeParameters(ClassElement typeElement) {
4580 Scope parameterScope = enclosingScope;
4581 for (TypeVariableElement parameter in typeElement.typeVariables) {
4582 parameterScope.define(parameter);
4583 }
4584 }
4585 }
4586 /**
4587 * Instances of the class {@code EnclosedScope} implement a scope that is lexica lly enclosed in
4588 * another scope.
4589 * @coverage dart.engine.resolver
4590 */
4591 class EnclosedScope extends Scope {
4592 /**
4593 * The scope in which this scope is lexically enclosed.
4594 */
4595 Scope _enclosingScope;
4596 /**
4597 * Initialize a newly created scope enclosed within another scope.
4598 * @param enclosingScope the scope in which this scope is lexically enclosed
4599 */
4600 EnclosedScope(Scope enclosingScope) {
4601 this._enclosingScope = enclosingScope;
4602 }
4603 LibraryElement get definingLibrary => _enclosingScope.definingLibrary;
4604 AnalysisErrorListener get errorListener => _enclosingScope.errorListener;
4605 /**
4606 * Return the scope in which this scope is lexically enclosed.
4607 * @return the scope in which this scope is lexically enclosed
4608 */
4609 Scope get enclosingScope => _enclosingScope;
4610 Element lookup3(String name, LibraryElement referencingLibrary) {
4611 Element element = localLookup(name, referencingLibrary);
4612 if (element != null) {
4613 return element;
4614 }
4615 return _enclosingScope.lookup3(name, referencingLibrary);
4616 }
4617 }
4618 /**
4619 * Instances of the class {@code FunctionScope} implement the scope defined by a function.
4620 * @coverage dart.engine.resolver
4621 */
4622 class FunctionScope extends EnclosedScope {
4623 /**
4624 * Initialize a newly created scope enclosed within another scope.
4625 * @param enclosingScope the scope in which this scope is lexically enclosed
4626 * @param functionElement the element representing the type represented by thi s scope
4627 */
4628 FunctionScope(Scope enclosingScope, ExecutableElement functionElement) : super (new EnclosedScope(enclosingScope)) {
4629 defineParameters(functionElement);
4630 }
4631 /**
4632 * Define the parameters for the given function in the scope that encloses thi s function.
4633 * @param functionElement the element representing the function represented by this scope
4634 */
4635 void defineParameters(ExecutableElement functionElement) {
4636 Scope parameterScope = enclosingScope;
4637 if (functionElement.enclosingElement is ExecutableElement) {
4638 String name17 = functionElement.name;
4639 if (name17 != null && !name17.isEmpty) {
4640 parameterScope.define(functionElement);
4641 }
4642 }
4643 for (ParameterElement parameter in functionElement.parameters) {
4644 if (!parameter.isInitializingFormal()) {
4645 parameterScope.define(parameter);
4646 }
4647 }
4648 }
4649 }
4650 /**
4651 * Instances of the class {@code FunctionTypeScope} implement the scope defined by a function type
4652 * alias.
4653 * @coverage dart.engine.resolver
4654 */
4655 class FunctionTypeScope extends EnclosedScope {
4656 /**
4657 * Initialize a newly created scope enclosed within another scope.
4658 * @param enclosingScope the scope in which this scope is lexically enclosed
4659 * @param typeElement the element representing the type alias represented by t his scope
4660 */
4661 FunctionTypeScope(Scope enclosingScope, TypeAliasElement typeElement) : super( new EnclosedScope(enclosingScope)) {
4662 defineTypeParameters(typeElement);
4663 }
4664 /**
4665 * Define the type parameters for the function type alias.
4666 * @param typeElement the element representing the type represented by this sc ope
4667 */
4668 void defineTypeParameters(TypeAliasElement typeElement) {
4669 Scope parameterScope = enclosingScope;
4670 for (TypeVariableElement parameter in typeElement.typeVariables) {
4671 parameterScope.define(parameter);
4672 }
4673 }
4674 }
4675 /**
4676 * Instances of the class {@code LabelScope} represent a scope in which a single label is defined.
4677 * @coverage dart.engine.resolver
4678 */
4679 class LabelScope {
4680 /**
4681 * The label scope enclosing this label scope.
4682 */
4683 LabelScope _outerScope;
4684 /**
4685 * The label defined in this scope.
4686 */
4687 String _label;
4688 /**
4689 * The element to which the label resolves.
4690 */
4691 LabelElement _element;
4692 /**
4693 * The marker used to look up a label element for an unlabeled {@code break} o r {@code continue}.
4694 */
4695 static String EMPTY_LABEL = "";
4696 /**
4697 * The label element returned for scopes that can be the target of an unlabele d {@code break} or{@code continue}.
4698 */
4699 static SimpleIdentifier _EMPTY_LABEL_IDENTIFIER = new SimpleIdentifier.full(ne w sc.StringToken(sc.TokenType.IDENTIFIER, "", 0));
4700 /**
4701 * Initialize a newly created scope to represent the potential target of an un labeled{@code break} or {@code continue}.
4702 * @param outerScope the label scope enclosing the new label scope
4703 * @param onSwitchStatement {@code true} if this label is associated with a {@ code switch}statement
4704 * @param onSwitchMember {@code true} if this label is associated with a {@cod e switch} member
4705 */
4706 LabelScope.con1(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMe mber) {
4707 _jtd_constructor_237_impl(outerScope, onSwitchStatement, onSwitchMember);
4708 }
4709 _jtd_constructor_237_impl(LabelScope outerScope, bool onSwitchStatement, bool onSwitchMember) {
4710 _jtd_constructor_238_impl(outerScope, EMPTY_LABEL, new LabelElementImpl(_EMP TY_LABEL_IDENTIFIER, onSwitchStatement, onSwitchMember));
4711 }
4712 /**
4713 * Initialize a newly created scope to represent the given label.
4714 * @param outerScope the label scope enclosing the new label scope
4715 * @param label the label defined in this scope
4716 * @param element the element to which the label resolves
4717 */
4718 LabelScope.con2(LabelScope outerScope2, String label4, LabelElement element19) {
4719 _jtd_constructor_238_impl(outerScope2, label4, element19);
4720 }
4721 _jtd_constructor_238_impl(LabelScope outerScope2, String label4, LabelElement element19) {
4722 this._outerScope = outerScope2;
4723 this._label = label4;
4724 this._element = element19;
4725 }
4726 /**
4727 * Return the label element corresponding to the given label, or {@code null} if the given label
4728 * is not defined in this scope.
4729 * @param targetLabel the label being looked up
4730 * @return the label element corresponding to the given label
4731 */
4732 LabelElement lookup(SimpleIdentifier targetLabel) => lookup2(targetLabel.name) ;
4733 /**
4734 * Return the label element corresponding to the given label, or {@code null} if the given label
4735 * is not defined in this scope.
4736 * @param targetLabel the label being looked up
4737 * @return the label element corresponding to the given label
4738 */
4739 LabelElement lookup2(String targetLabel) {
4740 if (_label == targetLabel) {
4741 return _element;
4742 } else if (_outerScope != null) {
4743 return _outerScope.lookup2(targetLabel);
4744 } else {
4745 return null;
4746 }
4747 }
4748 }
4749 /**
4750 * Instances of the class {@code LibraryImportScope} represent the scope contain ing all of the names
4751 * available from imported libraries.
4752 * @coverage dart.engine.resolver
4753 */
4754 class LibraryImportScope extends Scope {
4755 /**
4756 * The element representing the library in which this scope is enclosed.
4757 */
4758 LibraryElement _definingLibrary;
4759 /**
4760 * The listener that is to be informed when an error is encountered.
4761 */
4762 AnalysisErrorListener _errorListener;
4763 /**
4764 * A list of the namespaces representing the names that are available in this scope from imported
4765 * libraries.
4766 */
4767 List<Namespace> _importedNamespaces = new List<Namespace>();
4768 /**
4769 * Initialize a newly created scope representing the names imported into the g iven library.
4770 * @param definingLibrary the element representing the library that imports th e names defined in
4771 * this scope
4772 * @param errorListener the listener that is to be informed when an error is e ncountered
4773 */
4774 LibraryImportScope(LibraryElement definingLibrary, AnalysisErrorListener error Listener) {
4775 this._definingLibrary = definingLibrary;
4776 this._errorListener = errorListener;
4777 createImportedNamespaces(definingLibrary);
4778 }
4779 void define(Element element) {
4780 if (!Scope.isPrivateName(element.name)) {
4781 super.define(element);
4782 }
4783 }
4784 LibraryElement get definingLibrary => _definingLibrary;
4785 AnalysisErrorListener get errorListener => _errorListener;
4786 Element lookup3(String name, LibraryElement referencingLibrary) {
4787 if (Scope.isPrivateName(name)) {
4788 return null;
4789 }
4790 Element foundElement = localLookup(name, referencingLibrary);
4791 if (foundElement != null) {
4792 return foundElement;
4793 }
4794 for (Namespace nameSpace in _importedNamespaces) {
4795 Element element = nameSpace.get(name);
4796 if (element != null) {
4797 if (foundElement == null) {
4798 foundElement = element;
4799 } else {
4800 foundElement = new MultiplyDefinedElementImpl(_definingLibrary.context , foundElement, element);
4801 }
4802 }
4803 }
4804 if (foundElement is MultiplyDefinedElementImpl) {
4805 }
4806 if (foundElement != null) {
4807 defineWithoutChecking(foundElement);
4808 }
4809 return foundElement;
4810 }
4811 /**
4812 * Create all of the namespaces associated with the libraries imported into th is library. The
4813 * names are not added to this scope, but are stored for later reference.
4814 * @param definingLibrary the element representing the library that imports th e libraries for
4815 * which namespaces will be created
4816 */
4817 void createImportedNamespaces(LibraryElement definingLibrary) {
4818 NamespaceBuilder builder = new NamespaceBuilder();
4819 for (ImportElement element in definingLibrary.imports) {
4820 _importedNamespaces.add(builder.createImportNamespace(element));
4821 }
4822 }
4823 }
4824 /**
4825 * Instances of the class {@code LibraryScope} implement a scope containing all of the names defined
4826 * in a given library.
4827 * @coverage dart.engine.resolver
4828 */
4829 class LibraryScope extends EnclosedScope {
4830 /**
4831 * Initialize a newly created scope representing the names defined in the give n library.
4832 * @param definingLibrary the element representing the library represented by this scope
4833 * @param errorListener the listener that is to be informed when an error is e ncountered
4834 */
4835 LibraryScope(LibraryElement definingLibrary, AnalysisErrorListener errorListen er) : super(new LibraryImportScope(definingLibrary, errorListener)) {
4836 defineTopLevelNames(definingLibrary);
4837 }
4838 /**
4839 * Add to this scope all of the public top-level names that are defined in the given compilation
4840 * unit.
4841 * @param compilationUnit the compilation unit defining the top-level names to be added to this
4842 * scope
4843 */
4844 void defineLocalNames(CompilationUnitElement compilationUnit) {
4845 for (PropertyAccessorElement element in compilationUnit.accessors) {
4846 define(element);
4847 }
4848 for (FunctionElement element in compilationUnit.functions) {
4849 define(element);
4850 }
4851 for (TypeAliasElement element in compilationUnit.typeAliases) {
4852 define(element);
4853 }
4854 for (ClassElement element in compilationUnit.types) {
4855 define(element);
4856 }
4857 }
4858 /**
4859 * Add to this scope all of the names that are explicitly defined in the given library.
4860 * @param definingLibrary the element representing the library that defines th e names in this
4861 * scope
4862 */
4863 void defineTopLevelNames(LibraryElement definingLibrary) {
4864 for (PrefixElement prefix in definingLibrary.prefixes) {
4865 define(prefix);
4866 }
4867 defineLocalNames(definingLibrary.definingCompilationUnit);
4868 for (CompilationUnitElement compilationUnit in definingLibrary.parts) {
4869 defineLocalNames(compilationUnit);
4870 }
4871 }
4872 }
4873 /**
4874 * Instances of the class {@code Namespace} implement a mapping of identifiers t o the elements
4875 * represented by those identifiers. Namespaces are the building blocks for scop es.
4876 * @coverage dart.engine.resolver
4877 */
4878 class Namespace {
4879 /**
4880 * A table mapping names that are defined in this namespace to the element rep resenting the thing
4881 * declared with that name.
4882 */
4883 Map<String, Element> _definedNames;
4884 /**
4885 * An empty namespace.
4886 */
4887 static Namespace EMPTY = new Namespace(new Map<String, Element>());
4888 /**
4889 * Initialize a newly created namespace to have the given defined names.
4890 * @param definedNames the mapping from names that are defined in this namespa ce to the
4891 * corresponding elements
4892 */
4893 Namespace(Map<String, Element> definedNames) {
4894 this._definedNames = definedNames;
4895 }
4896 /**
4897 * Return the element in this namespace that is available to the containing sc ope using the given
4898 * name.
4899 * @param name the name used to reference the
4900 * @return the element represented by the given identifier
4901 */
4902 Element get(String name) => _definedNames[name];
4903 /**
4904 * Return a table containing the same mappings as those defined by this namesp ace.
4905 * @return a table containing the same mappings as those defined by this names pace
4906 */
4907 Map<String, Element> get definedNames => new Map<String, Element>.from(_define dNames);
4908 }
4909 /**
4910 * Instances of the class {@code NamespaceBuilder} are used to build a {@code Na mespace}. Namespace
4911 * builders are thread-safe and re-usable.
4912 * @coverage dart.engine.resolver
4913 */
4914 class NamespaceBuilder {
4915 /**
4916 * Initialize a newly created namespace builder.
4917 */
4918 NamespaceBuilder() : super() {
4919 }
4920 /**
4921 * Create a namespace representing the export namespace of the given library.
4922 * @param library the library whose export namespace is to be created
4923 * @return the export namespace that was created
4924 */
4925 Namespace createExportNamespace(LibraryElement library) => new Namespace(creat eExportMapping(library, new Set<LibraryElement>()));
4926 /**
4927 * Create a namespace representing the import namespace of the given library.
4928 * @param library the library whose import namespace is to be created
4929 * @return the import namespace that was created
4930 */
4931 Namespace createImportNamespace(ImportElement element) {
4932 LibraryElement importedLibrary4 = element.importedLibrary;
4933 if (importedLibrary4 == null) {
4934 return Namespace.EMPTY;
4935 }
4936 Map<String, Element> definedNames = createExportMapping(importedLibrary4, ne w Set<LibraryElement>());
4937 definedNames = apply(definedNames, element.combinators);
4938 definedNames = apply2(definedNames, element.prefix);
4939 return new Namespace(definedNames);
4940 }
4941 /**
4942 * Create a namespace representing the public namespace of the given library.
4943 * @param library the library whose public namespace is to be created
4944 * @return the public namespace that was created
4945 */
4946 Namespace createPublicNamespace(LibraryElement library) {
4947 Map<String, Element> definedNames = new Map<String, Element>();
4948 addPublicNames(definedNames, library.definingCompilationUnit);
4949 for (CompilationUnitElement compilationUnit in library.parts) {
4950 addPublicNames(definedNames, compilationUnit);
4951 }
4952 return new Namespace(definedNames);
4953 }
4954 /**
4955 * Add all of the names in the given namespace to the given mapping table.
4956 * @param definedNames the mapping table to which the names in the given names pace are to be added
4957 * @param namespace the namespace containing the names to be added to this nam espace
4958 */
4959 void addAll(Map<String, Element> definedNames, Map<String, Element> newNames) {
4960 for (MapEntry<String, Element> entry in getMapEntrySet(newNames)) {
4961 definedNames[entry.getKey()] = entry.getValue();
4962 }
4963 }
4964 /**
4965 * Add all of the names in the given namespace to the given mapping table.
4966 * @param definedNames the mapping table to which the names in the given names pace are to be added
4967 * @param namespace the namespace containing the names to be added to this nam espace
4968 */
4969 void addAll2(Map<String, Element> definedNames2, Namespace namespace) {
4970 addAll(definedNames2, namespace.definedNames);
4971 }
4972 /**
4973 * Add the given element to the given mapping table if it has a publicly visib le name.
4974 * @param definedNames the mapping table to which the public name is to be add ed
4975 * @param element the element to be added
4976 */
4977 void addIfPublic(Map<String, Element> definedNames, Element element) {
4978 String name18 = element.name;
4979 if (name18 != null && !Scope.isPrivateName(name18)) {
4980 definedNames[name18] = element;
4981 }
4982 }
4983 /**
4984 * Add to the given mapping table all of the public top-level names that are d efined in the given
4985 * compilation unit.
4986 * @param definedNames the mapping table to which the public names are to be a dded
4987 * @param compilationUnit the compilation unit defining the top-level names to be added to this
4988 * namespace
4989 */
4990 void addPublicNames(Map<String, Element> definedNames, CompilationUnitElement compilationUnit) {
4991 for (PropertyAccessorElement element in compilationUnit.accessors) {
4992 addIfPublic(definedNames, element);
4993 }
4994 for (FunctionElement element in compilationUnit.functions) {
4995 addIfPublic(definedNames, element);
4996 }
4997 for (TypeAliasElement element in compilationUnit.typeAliases) {
4998 addIfPublic(definedNames, element);
4999 }
5000 for (ClassElement element in compilationUnit.types) {
5001 addIfPublic(definedNames, element);
5002 }
5003 for (VariableElement element in compilationUnit.topLevelVariables) {
5004 addIfPublic(definedNames, element);
5005 }
5006 }
5007 /**
5008 * Apply the given combinators to all of the names in the given mapping table.
5009 * @param definedNames the mapping table to which the namespace operations are to be applied
5010 * @param combinators the combinators to be applied
5011 */
5012 Map<String, Element> apply(Map<String, Element> definedNames, List<NamespaceCo mbinator> combinators) {
5013 for (NamespaceCombinator combinator in combinators) {
5014 if (combinator is __imp_combi.HideCombinator) {
5015 hide(definedNames, ((combinator as __imp_combi.HideCombinator)).hiddenNa mes);
5016 } else if (combinator is __imp_combi.ShowCombinator) {
5017 definedNames = show(definedNames, ((combinator as __imp_combi.ShowCombin ator)).shownNames);
5018 } else {
5019 AnalysisEngine.instance.logger.logError("Unknown type of combinator: ${c ombinator.runtimeType.toString()}");
5020 }
5021 }
5022 return definedNames;
5023 }
5024 /**
5025 * Apply the given prefix to all of the names in the table of defined names.
5026 * @param definedNames the names that were defined before this operation
5027 * @param prefixElement the element defining the prefix to be added to the nam es
5028 */
5029 Map<String, Element> apply2(Map<String, Element> definedNames, PrefixElement p refixElement) {
5030 if (prefixElement != null) {
5031 String prefix = prefixElement.name;
5032 Map<String, Element> newNames = new Map<String, Element>();
5033 for (MapEntry<String, Element> entry in getMapEntrySet(definedNames)) {
5034 newNames["${prefix}.${entry.getKey()}"] = entry.getValue();
5035 }
5036 return newNames;
5037 } else {
5038 return definedNames;
5039 }
5040 }
5041 /**
5042 * Create a mapping table representing the export namespace of the given libra ry.
5043 * @param library the library whose public namespace is to be created
5044 * @param visitedElements a set of libraries that do not need to be visited wh en processing the
5045 * export directives of the given library because all of the names defined by them will
5046 * be added by another library
5047 * @return the mapping table that was created
5048 */
5049 Map<String, Element> createExportMapping(LibraryElement library, Set<LibraryEl ement> visitedElements) {
5050 javaSetAdd(visitedElements, library);
5051 try {
5052 Map<String, Element> definedNames = new Map<String, Element>();
5053 for (ExportElement element in library.exports) {
5054 LibraryElement exportedLibrary3 = element.exportedLibrary;
5055 if (exportedLibrary3 != null && !visitedElements.contains(exportedLibrar y3)) {
5056 Map<String, Element> exportedNames = createExportMapping(exportedLibra ry3, visitedElements);
5057 exportedNames = apply(exportedNames, element.combinators);
5058 addAll(definedNames, exportedNames);
5059 }
5060 }
5061 addAll2(definedNames, ((library.context as AnalysisContextImpl)).getPublic Namespace(library));
5062 return definedNames;
5063 } finally {
5064 visitedElements.remove(library);
5065 }
5066 }
5067 /**
5068 * Hide all of the given names by removing them from the given collection of d efined names.
5069 * @param definedNames the names that were defined before this operation
5070 * @param hiddenNames the names to be hidden
5071 */
5072 void hide(Map<String, Element> definedNames, List<String> hiddenNames) {
5073 for (String name in hiddenNames) {
5074 definedNames.remove(name);
5075 }
5076 }
5077 /**
5078 * Show only the given names by removing all other names from the given collec tion of defined
5079 * names.
5080 * @param definedNames the names that were defined before this operation
5081 * @param shownNames the names to be shown
5082 */
5083 Map<String, Element> show(Map<String, Element> definedNames, List<String> show nNames) {
5084 Map<String, Element> newNames = new Map<String, Element>();
5085 for (String name in shownNames) {
5086 Element element = definedNames[name];
5087 if (element != null) {
5088 newNames[name] = element;
5089 }
5090 }
5091 return newNames;
5092 }
5093 }
5094 /**
5095 * The abstract class {@code Scope} defines the behavior common to name scopes u sed by the resolver
5096 * to determine which names are visible at any given point in the code.
5097 * @coverage dart.engine.resolver
5098 */
5099 abstract class Scope {
5100 /**
5101 * The prefix used to mark an identifier as being private to its library.
5102 */
5103 static String PRIVATE_NAME_PREFIX = "_";
5104 /**
5105 * The suffix added to the declared name of a setter when looking up the sette r. Used to
5106 * disambiguate between a getter and a setter that have the same name.
5107 */
5108 static String SETTER_SUFFIX = "=";
5109 /**
5110 * The name used to look up the method used to implement the unary minus opera tor. Used to
5111 * disambiguate between the unary and binary operators.
5112 */
5113 static String UNARY_MINUS = "unary-";
5114 /**
5115 * Return {@code true} if the given name is a library-private name.
5116 * @param name the name being tested
5117 * @return {@code true} if the given name is a library-private name
5118 */
5119 static bool isPrivateName(String name) => name != null && name.startsWith(PRIV ATE_NAME_PREFIX);
5120 /**
5121 * A table mapping names that are defined in this scope to the element represe nting the thing
5122 * declared with that name.
5123 */
5124 Map<String, Element> _definedNames = new Map<String, Element>();
5125 /**
5126 * Initialize a newly created scope to be empty.
5127 */
5128 Scope() : super() {
5129 }
5130 /**
5131 * Add the given element to this scope. If there is already an element with th e given name defined
5132 * in this scope, then an error will be generated and the original element wil l continue to be
5133 * mapped to the name. If there is an element with the given name in an enclos ing scope, then a
5134 * warning will be generated but the given element will hide the inherited ele ment.
5135 * @param element the element to be added to this scope
5136 */
5137 void define(Element element) {
5138 String name = getName(element);
5139 if (_definedNames.containsKey(name)) {
5140 errorListener.onError(getErrorForDuplicate(_definedNames[name], element));
5141 } else {
5142 _definedNames[name] = element;
5143 }
5144 }
5145 /**
5146 * Return the element with which the given identifier is associated, or {@code null} if the name
5147 * is not defined within this scope.
5148 * @param identifier the identifier associated with the element to be returned
5149 * @param referencingLibrary the library that contains the reference to the na me, used to
5150 * implement library-level privacy
5151 * @return the element with which the given identifier is associated
5152 */
5153 Element lookup(Identifier identifier, LibraryElement referencingLibrary) => lo okup3(identifier.name, referencingLibrary);
5154 /**
5155 * Add the given element to this scope without checking for duplication or hid ing.
5156 * @param element the element to be added to this scope
5157 */
5158 void defineWithoutChecking(Element element) {
5159 _definedNames[getName(element)] = element;
5160 }
5161 /**
5162 * Return the element representing the library in which this scope is enclosed .
5163 * @return the element representing the library in which this scope is enclose d
5164 */
5165 LibraryElement get definingLibrary;
5166 /**
5167 * Return the error code to be used when reporting that a name being defined l ocally conflicts
5168 * with another element of the same name in the local scope.
5169 * @param existing the first element to be declared with the conflicting name
5170 * @param duplicate another element declared with the conflicting name
5171 * @return the error code used to report duplicate names within a scope
5172 */
5173 AnalysisError getErrorForDuplicate(Element existing, Element duplicate) => new AnalysisError.con2(source, duplicate.nameOffset, duplicate.name.length, Compile TimeErrorCode.DUPLICATE_DEFINITION, [existing.name]);
5174 /**
5175 * Return the listener that is to be informed when an error is encountered.
5176 * @return the listener that is to be informed when an error is encountered
5177 */
5178 AnalysisErrorListener get errorListener;
5179 /**
5180 * Return the source object representing the compilation unit with which error s related to this
5181 * scope should be associated.
5182 * @return the source object with which errors should be associated
5183 */
5184 Source get source => definingLibrary.definingCompilationUnit.source;
5185 /**
5186 * Return the element with which the given name is associated, or {@code null} if the name is not
5187 * defined within this scope. This method only returns elements that are direc tly defined within
5188 * this scope, not elements that are defined in an enclosing scope.
5189 * @param name the name associated with the element to be returned
5190 * @param referencingLibrary the library that contains the reference to the na me, used to
5191 * implement library-level privacy
5192 * @return the element with which the given name is associated
5193 */
5194 Element localLookup(String name, LibraryElement referencingLibrary) => _define dNames[name];
5195 /**
5196 * Return the element with which the given name is associated, or {@code null} if the name is not
5197 * defined within this scope.
5198 * @param name the name associated with the element to be returned
5199 * @param referencingLibrary the library that contains the reference to the na me, used to
5200 * implement library-level privacy
5201 * @return the element with which the given name is associated
5202 */
5203 Element lookup3(String name, LibraryElement referencingLibrary);
5204 /**
5205 * Return the name that will be used to look up the given element.
5206 * @param element the element whose look-up name is to be returned
5207 * @return the name that will be used to look up the given element
5208 */
5209 String getName(Element element) {
5210 if (element is MethodElement) {
5211 MethodElement method = element as MethodElement;
5212 if (method.name == "-" && method.parameters.length == 0) {
5213 return UNARY_MINUS;
5214 }
5215 } else if (element is PropertyAccessorElement) {
5216 PropertyAccessorElement accessor = element as PropertyAccessorElement;
5217 if (accessor.isSetter()) {
5218 return "${accessor.name}${SETTER_SUFFIX}";
5219 }
5220 }
5221 return element.name;
5222 }
5223 }
5224 /**
5225 * Instances of the class {@code ConstantVerifier} traverse an AST structure loo king for additional
5226 * errors and warnings not covered by the parser and resolver. In particular, it looks for errors
5227 * and warnings related to constant expressions.
5228 * @coverage dart.engine.resolver
5229 */
5230 class ConstantVerifier extends RecursiveASTVisitor<Object> {
5231 /**
5232 * The error reporter by which errors will be reported.
5233 */
5234 ErrorReporter _errorReporter;
5235 /**
5236 * The constant evaluator used to evaluate constants.
5237 */
5238 ConstantEvaluator _evaluator;
5239 /**
5240 * Initialize a newly created constant verifier.
5241 * @param errorReporter the error reporter by which errors will be reported
5242 */
5243 ConstantVerifier(ErrorReporter errorReporter) {
5244 this._errorReporter = errorReporter;
5245 _evaluator = new ConstantEvaluator(errorReporter);
5246 }
5247 Object visitFunctionExpression(FunctionExpression node) {
5248 super.visitFunctionExpression(node);
5249 validateDefaultValues(node.parameters);
5250 return null;
5251 }
5252 Object visitListLiteral(ListLiteral node) {
5253 super.visitListLiteral(node);
5254 if (node.modifier != null) {
5255 for (Expression element in node.elements) {
5256 validate(element, CompileTimeErrorCode.NON_CONSTANT_LIST_ELEMENT);
5257 }
5258 }
5259 return null;
5260 }
5261 Object visitMapLiteral(MapLiteral node) {
5262 super.visitMapLiteral(node);
5263 bool isConst = node.modifier != null;
5264 Set<String> keys = new Set<String>();
5265 for (MapLiteralEntry entry in node.entries) {
5266 StringLiteral key4 = entry.key;
5267 Object value = validate(key4, CompileTimeErrorCode.NON_CONSTANT_MAP_KEY);
5268 if (value is String) {
5269 if (keys.contains(value)) {
5270 _errorReporter.reportError(StaticWarningCode.EQUAL_KEYS_IN_MAP, key4, []);
5271 } else {
5272 javaSetAdd(keys, (value as String));
5273 }
5274 } else if (value != null) {
5275 }
5276 if (isConst) {
5277 validate(entry.value, CompileTimeErrorCode.NON_CONSTANT_MAP_VALUE);
5278 }
5279 }
5280 return null;
5281 }
5282 Object visitMethodDeclaration(MethodDeclaration node) {
5283 super.visitMethodDeclaration(node);
5284 validateDefaultValues(node.parameters);
5285 return null;
5286 }
5287 Object visitSwitchCase(SwitchCase node) {
5288 super.visitSwitchCase(node);
5289 validate(node.expression, CompileTimeErrorCode.NON_CONSTANT_CASE_EXPRESSION) ;
5290 return null;
5291 }
5292 Object visitVariableDeclaration(VariableDeclaration node) {
5293 super.visitVariableDeclaration(node);
5294 Expression initializer4 = node.initializer;
5295 if (initializer4 != null && node.isConst()) {
5296 validate(initializer4, CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CON STANT_VALUE);
5297 }
5298 return null;
5299 }
5300 /**
5301 * Validate that the given expression is a compile time constant. Return the v alue of the compile
5302 * time constant, or {@code null} if the expression is not a compile time cons tant.
5303 * @param expression the expression to be validated
5304 * @param errorCode the error code to be used if the expression is not a compi le time constant
5305 * @return the value of the compile time constant
5306 */
5307 Object validate(Expression expression, ErrorCode errorCode) {
5308 Object value = expression.accept(_evaluator);
5309 if (identical(value, ConstantEvaluator.NOT_A_CONSTANT)) {
5310 _errorReporter.reportError(errorCode, expression, []);
5311 return null;
5312 }
5313 if (identical(value, errorCode)) {
5314 _errorReporter.reportError(CompileTimeErrorCode.COMPILE_TIME_CONSTANT_RAIS ES_EXCEPTION, expression, []);
5315 return null;
5316 }
5317 if (identical(value, errorCode)) {
5318 _errorReporter.reportError(CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CON STANT, expression, []);
5319 return null;
5320 }
5321 return value;
5322 }
5323 /**
5324 * Validate that the default value associated with each of the parameters in t he given list is a
5325 * compile time constant.
5326 * @param parameters the list of parameters to be validated
5327 */
5328 void validateDefaultValues(FormalParameterList parameters14) {
5329 if (parameters14 == null) {
5330 return;
5331 }
5332 for (FormalParameter parameter in parameters14.parameters) {
5333 if (parameter is DefaultFormalParameter) {
5334 Expression defaultValue2 = ((parameter as DefaultFormalParameter)).defau ltValue;
5335 if (defaultValue2 != null) {
5336 validate(defaultValue2, CompileTimeErrorCode.NON_CONSTANT_DEFAULT_VALU E);
5337 }
5338 }
5339 }
5340 }
5341 }
5342 /**
5343 * Instances of the class {@code ErrorVerifier} traverse an AST structure lookin g for additional
5344 * errors and warnings not covered by the parser and resolver.
5345 * @coverage dart.engine.resolver
5346 */
5347 class ErrorVerifier extends RecursiveASTVisitor<Object> {
5348 /**
5349 * The error reporter by which errors will be reported.
5350 */
5351 ErrorReporter _errorReporter;
5352 /**
5353 * The current library that is being analyzed.
5354 */
5355 LibraryElement _currentLibrary;
5356 /**
5357 * The type representing the type 'dynamic'.
5358 */
5359 Type2 _dynamicType;
5360 /**
5361 * The object providing access to the types defined by the language.
5362 */
5363 TypeProvider _typeProvider;
5364 /**
5365 * The method or function that we are currently visiting, or {@code null} if w e are not inside a
5366 * method or function.
5367 */
5368 ExecutableElement _currentFunction;
5369 ErrorVerifier(ErrorReporter errorReporter, LibraryElement currentLibrary, Type Provider typeProvider) {
5370 this._errorReporter = errorReporter;
5371 this._currentLibrary = currentLibrary;
5372 this._typeProvider = typeProvider;
5373 _dynamicType = typeProvider.dynamicType;
5374 }
5375 Object visitArgumentDefinitionTest(ArgumentDefinitionTest node) {
5376 checkForArgumentDefinitionTestNonParameter(node);
5377 return super.visitArgumentDefinitionTest(node);
5378 }
5379 Object visitAssertStatement(AssertStatement node) {
5380 checkForNonBoolExpression(node);
5381 return super.visitAssertStatement(node);
5382 }
5383 Object visitAssignmentExpression(AssignmentExpression node) {
5384 checkForInvalidAssignment(node);
5385 return super.visitAssignmentExpression(node);
5386 }
5387 Object visitClassDeclaration(ClassDeclaration node) {
5388 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE NTIFIER_AS_TYPE_NAME);
5389 return super.visitClassDeclaration(node);
5390 }
5391 Object visitClassTypeAlias(ClassTypeAlias node) {
5392 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE NTIFIER_AS_TYPEDEF_NAME);
5393 return super.visitClassTypeAlias(node);
5394 }
5395 Object visitConditionalExpression(ConditionalExpression node) {
5396 checkForNonBoolCondition(node.condition);
5397 return super.visitConditionalExpression(node);
5398 }
5399 Object visitConstructorDeclaration(ConstructorDeclaration node) {
5400 ExecutableElement previousFunction = _currentFunction;
5401 try {
5402 _currentFunction = node.element;
5403 checkForConstConstructorWithNonFinalField(node);
5404 checkForConflictingConstructorNameAndMember(node);
5405 return super.visitConstructorDeclaration(node);
5406 } finally {
5407 _currentFunction = previousFunction;
5408 }
5409 }
5410 Object visitDoStatement(DoStatement node) {
5411 checkForNonBoolCondition(node.condition);
5412 return super.visitDoStatement(node);
5413 }
5414 Object visitFieldFormalParameter(FieldFormalParameter node) {
5415 checkForConstFormalParameter(node);
5416 return super.visitFieldFormalParameter(node);
5417 }
5418 Object visitFunctionDeclaration(FunctionDeclaration node) {
5419 ExecutableElement previousFunction = _currentFunction;
5420 try {
5421 _currentFunction = node.element;
5422 return super.visitFunctionDeclaration(node);
5423 } finally {
5424 _currentFunction = previousFunction;
5425 }
5426 }
5427 Object visitFunctionExpression(FunctionExpression node) {
5428 ExecutableElement previousFunction = _currentFunction;
5429 try {
5430 _currentFunction = node.element;
5431 return super.visitFunctionExpression(node);
5432 } finally {
5433 _currentFunction = previousFunction;
5434 }
5435 }
5436 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
5437 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE NTIFIER_AS_TYPEDEF_NAME);
5438 return super.visitFunctionTypeAlias(node);
5439 }
5440 Object visitIfStatement(IfStatement node) {
5441 checkForNonBoolCondition(node.condition);
5442 return super.visitIfStatement(node);
5443 }
5444 Object visitInstanceCreationExpression(InstanceCreationExpression node) {
5445 ConstructorName constructorName4 = node.constructorName;
5446 TypeName typeName = constructorName4.type;
5447 Type2 type20 = typeName.type;
5448 if (type20 is InterfaceType) {
5449 InterfaceType interfaceType = type20 as InterfaceType;
5450 checkForConstOrNewWithAbstractClass(node, typeName, interfaceType);
5451 checkForTypeArgumentNotMatchingBounds(node, constructorName4.element, type Name);
5452 } else {
5453 _errorReporter.reportError(CompileTimeErrorCode.NON_CONSTANT_MAP_KEY, type Name, []);
5454 }
5455 return super.visitInstanceCreationExpression(node);
5456 }
5457 Object visitMethodDeclaration(MethodDeclaration node) {
5458 ExecutableElement previousFunction = _currentFunction;
5459 try {
5460 _currentFunction = node.element;
5461 return super.visitMethodDeclaration(node);
5462 } finally {
5463 _currentFunction = previousFunction;
5464 }
5465 }
5466 Object visitReturnStatement(ReturnStatement node) {
5467 checkForReturnOfInvalidType(node);
5468 return super.visitReturnStatement(node);
5469 }
5470 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
5471 checkForConstFormalParameter(node);
5472 return super.visitSimpleFormalParameter(node);
5473 }
5474 Object visitSwitchStatement(SwitchStatement node) {
5475 checkForCaseExpressionTypeImplementsEquals(node);
5476 return super.visitSwitchStatement(node);
5477 }
5478 Object visitTypeParameter(TypeParameter node) {
5479 checkForBuiltInIdentifierAsName(node.name, CompileTimeErrorCode.BUILT_IN_IDE NTIFIER_AS_TYPE_VARIABLE_NAME);
5480 return super.visitTypeParameter(node);
5481 }
5482 Object visitVariableDeclarationList(VariableDeclarationList node) {
5483 checkForBuiltInIdentifierAsName2(node);
5484 return super.visitVariableDeclarationList(node);
5485 }
5486 Object visitWhileStatement(WhileStatement node) {
5487 checkForNonBoolCondition(node.condition);
5488 return super.visitWhileStatement(node);
5489 }
5490 /**
5491 * This verifies that the passed argument definition test identifier is a para meter.
5492 * @param node the {@link ArgumentDefinitionTest} to evaluate
5493 * @return return <code>true</code> if and only if an error code is generated on the passed node
5494 * @see CompileTimeErrorCode#ARGUMENT_DEFINITION_TEST_NON_PARAMETER
5495 */
5496 bool checkForArgumentDefinitionTestNonParameter(ArgumentDefinitionTest node) {
5497 SimpleIdentifier identifier14 = node.identifier;
5498 Element element44 = identifier14.element;
5499 if (element44 != null && element44 is! ParameterElement) {
5500 _errorReporter.reportError(CompileTimeErrorCode.ARGUMENT_DEFINITION_TEST_N ON_PARAMETER, identifier14, [identifier14.name]);
5501 return true;
5502 }
5503 return false;
5504 }
5505 /**
5506 * This verifies that the passed identifier is not a keyword, and generates th e passed error code
5507 * on the identifier if it is a keyword.
5508 * @param identifier the identifier to check to ensure that it is not a keywor d
5509 * @param errorCode if the passed identifier is a keyword then this error code is created on the
5510 * identifier, the error code will be one of{@link CompileTimeErrorCode#BUILT_ IN_IDENTIFIER_AS_TYPE_NAME},{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_T YPE_VARIABLE_NAME} or{@link CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_ NAME}
5511 * @return return <code>true</code> if and only if an error code is generated on the passed node
5512 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_NAME
5513 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE_VARIABLE_NAME
5514 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME
5515 */
5516 bool checkForBuiltInIdentifierAsName(SimpleIdentifier identifier, ErrorCode er rorCode) {
5517 sc.Token token13 = identifier.token;
5518 if (identical(token13.type, sc.TokenType.KEYWORD)) {
5519 _errorReporter.reportError(errorCode, identifier, [identifier.name]);
5520 return true;
5521 }
5522 return false;
5523 }
5524 /**
5525 * This verifies that the passed variable declaration list does not have a bui lt-in identifier.
5526 * @param node the variable declaration list to check
5527 * @return return <code>true</code> if and only if an error code is generated on the passed node
5528 * @see CompileTimeErrorCode#BUILT_IN_IDENTIFIER_AS_TYPE
5529 */
5530 bool checkForBuiltInIdentifierAsName2(VariableDeclarationList node) {
5531 TypeName typeName = node.type;
5532 if (typeName != null) {
5533 Identifier identifier = typeName.name;
5534 if (identifier is SimpleIdentifier) {
5535 SimpleIdentifier simpleIdentifier = identifier as SimpleIdentifier;
5536 sc.Token token14 = simpleIdentifier.token;
5537 if (identical(token14.type, sc.TokenType.KEYWORD)) {
5538 if (((token14 as sc.KeywordToken)).keyword != sc.Keyword.DYNAMIC) {
5539 _errorReporter.reportError(CompileTimeErrorCode.BUILT_IN_IDENTIFIER_ AS_TYPE, identifier, [identifier.name]);
5540 return true;
5541 }
5542 }
5543 }
5544 }
5545 return false;
5546 }
5547 /**
5548 * This verifies that the passed switch statement does not have a case express ion with the
5549 * operator '==' overridden.
5550 * @param node the switch statement to evaluate
5551 * @return return <code>true</code> if and only if an error code is generated on the passed node
5552 * @see CompileTimeErrorCode#CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
5553 */
5554 bool checkForCaseExpressionTypeImplementsEquals(SwitchStatement node) {
5555 Expression expression16 = node.expression;
5556 Type2 type = expression16.staticType;
5557 if (type != null && type != _typeProvider.intType && type != _typeProvider.s tringType) {
5558 Element element45 = type.element;
5559 if (element45 is ClassElement) {
5560 ClassElement classElement = element45 as ClassElement;
5561 MethodElement method = classElement.lookUpMethod("==", _currentLibrary);
5562 if (method != null && method.enclosingElement.type != _typeProvider.obje ctType) {
5563 _errorReporter.reportError(CompileTimeErrorCode.CASE_EXPRESSION_TYPE_I MPLEMENTS_EQUALS, expression16, [element45.name]);
5564 return true;
5565 }
5566 }
5567 }
5568 return false;
5569 }
5570 bool checkForConflictingConstructorNameAndMember(ConstructorDeclaration node) {
5571 ConstructorElement constructorElement = node.element;
5572 SimpleIdentifier constructorName = node.name;
5573 if (constructorName != null && constructorElement != null && !constructorNam e.isSynthetic()) {
5574 String name20 = constructorName.name;
5575 ClassElement classElement = constructorElement.enclosingElement;
5576 List<FieldElement> fields3 = classElement.fields;
5577 for (FieldElement field in fields3) {
5578 if (field.name == name20) {
5579 _errorReporter.reportError(CompileTimeErrorCode.CONFLICTING_CONSTRUCTO R_NAME_AND_FIELD, node, [name20]);
5580 return true;
5581 }
5582 }
5583 List<MethodElement> methods3 = classElement.methods;
5584 for (MethodElement method in methods3) {
5585 if (method.name == name20) {
5586 _errorReporter.reportError(CompileTimeErrorCode.CONFLICTING_CONSTRUCTO R_NAME_AND_METHOD, node, [name20]);
5587 return true;
5588 }
5589 }
5590 }
5591 return false;
5592 }
5593 /**
5594 * This verifies that the passed constructor declaration is not 'const' if it has a non-final
5595 * instance variable.
5596 * @param node the instance creation expression to evaluate
5597 * @return return <code>true</code> if and only if an error code is generated on the passed node
5598 * @see CompileTimeErrorCode#CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD
5599 */
5600 bool checkForConstConstructorWithNonFinalField(ConstructorDeclaration node) {
5601 if (node.constKeyword == null) {
5602 return false;
5603 }
5604 ConstructorElement constructorElement = node.element;
5605 if (constructorElement != null) {
5606 ClassElement classElement = constructorElement.enclosingElement;
5607 List<FieldElement> elements = classElement.fields;
5608 for (FieldElement field in elements) {
5609 if (!field.isFinal() && !field.isConst()) {
5610 _errorReporter.reportError(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH _NON_FINAL_FIELD, node, []);
5611 return true;
5612 }
5613 }
5614 }
5615 return false;
5616 }
5617 /**
5618 * This verifies that the passed normal formal parameter is not 'const'.
5619 * @param node the normal formal parameter to evaluate
5620 * @return return <code>true</code> if and only if an error code is generated on the passed node
5621 * @see CompileTimeErrorCode#CONST_FORMAL_PARAMETER
5622 */
5623 bool checkForConstFormalParameter(NormalFormalParameter node) {
5624 if (node.isConst()) {
5625 _errorReporter.reportError(CompileTimeErrorCode.CONST_FORMAL_PARAMETER, no de, []);
5626 return true;
5627 }
5628 return false;
5629 }
5630 /**
5631 * This verifies that the passed instance creation expression is not being inv oked on an abstract
5632 * class.
5633 * @param node the instance creation expression to evaluate
5634 * @param typeName the {@link TypeName} of the {@link ConstructorName} from th e{@link InstanceCreationExpression}, this is the AST node that the error is atta ched to
5635 * @param type the type being constructed with this {@link InstanceCreationExp ression}
5636 * @return return <code>true</code> if and only if an error code is generated on the passed node
5637 * @see StaticWarningCode#CONST_WITH_ABSTRACT_CLASS
5638 * @see StaticWarningCode#NEW_WITH_ABSTRACT_CLASS
5639 */
5640 bool checkForConstOrNewWithAbstractClass(InstanceCreationExpression node, Type Name typeName, InterfaceType type) {
5641 if (type.element.isAbstract()) {
5642 ConstructorElement element46 = node.element;
5643 if (element46 != null && !element46.isFactory()) {
5644 if (identical(((node.keyword as sc.KeywordToken)).keyword, sc.Keyword.CO NST)) {
5645 _errorReporter.reportError(StaticWarningCode.CONST_WITH_ABSTRACT_CLASS , typeName, []);
5646 } else {
5647 _errorReporter.reportError(StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName, []);
5648 }
5649 return true;
5650 }
5651 }
5652 return false;
5653 }
5654 /**
5655 * This verifies that the passed assignment expression represents a valid assi gnment.
5656 * @param node the assignment expression to evaluate
5657 * @return return <code>true</code> if and only if an error code is generated on the passed node
5658 * @see StaticTypeWarningCode#INVALID_ASSIGNMENT
5659 */
5660 bool checkForInvalidAssignment(AssignmentExpression node) {
5661 Expression lhs = node.leftHandSide;
5662 Expression rhs = node.rightHandSide;
5663 Type2 leftType = getType(lhs);
5664 Type2 rightType = getType(rhs);
5665 if (!rightType.isAssignableTo(leftType)) {
5666 _errorReporter.reportError(StaticTypeWarningCode.INVALID_ASSIGNMENT, rhs, [leftType.name, rightType.name]);
5667 return true;
5668 }
5669 return false;
5670 }
5671 /**
5672 * Checks to ensure that the expressions that need to be of type bool, are. Ot herwise an error is
5673 * reported on the expression.
5674 * @param condition the conditional expression to test
5675 * @return return <code>true</code> if and only if an error code is generated on the passed node
5676 * @see StaticTypeWarningCode#NON_BOOL_CONDITION
5677 */
5678 bool checkForNonBoolCondition(Expression condition) {
5679 Type2 conditionType = getType(condition);
5680 if (conditionType != null && !conditionType.isAssignableTo(_typeProvider.boo lType)) {
5681 _errorReporter.reportError(StaticTypeWarningCode.NON_BOOL_CONDITION, condi tion, []);
5682 return true;
5683 }
5684 return false;
5685 }
5686 /**
5687 * This verifies that the passed assert statement has either a 'bool' or '() - > bool' input.
5688 * @param node the assert statement to evaluate
5689 * @return return <code>true</code> if and only if an error code is generated on the passed node
5690 * @see StaticTypeWarningCode#NON_BOOL_EXPRESSION
5691 */
5692 bool checkForNonBoolExpression(AssertStatement node) {
5693 Expression expression = node.condition;
5694 Type2 type = getType(expression);
5695 if (type is InterfaceType) {
5696 if (!type.isAssignableTo(_typeProvider.boolType)) {
5697 _errorReporter.reportError(StaticTypeWarningCode.NON_BOOL_EXPRESSION, ex pression, []);
5698 return true;
5699 }
5700 } else if (type is FunctionType) {
5701 FunctionType functionType = type as FunctionType;
5702 if (functionType.typeArguments.length == 0 && !functionType.returnType.isA ssignableTo(_typeProvider.boolType)) {
5703 _errorReporter.reportError(StaticTypeWarningCode.NON_BOOL_EXPRESSION, ex pression, []);
5704 return true;
5705 }
5706 }
5707 return false;
5708 }
5709 /**
5710 * This checks that the return type matches the type of the declared return ty pe in the enclosing
5711 * method or function.
5712 * @param node the return statement to evaluate
5713 * @return return <code>true</code> if and only if an error code is generated on the passed node
5714 * @see StaticTypeWarningCode#RETURN_OF_INVALID_TYPE
5715 */
5716 bool checkForReturnOfInvalidType(ReturnStatement node) {
5717 FunctionType functionType = _currentFunction == null ? null : _currentFuncti on.type;
5718 Type2 expectedReturnType = functionType == null ? null : functionType.return Type;
5719 Expression returnExpression = node.expression;
5720 if (expectedReturnType != null && !expectedReturnType.isVoid() && returnExpr ession != null) {
5721 Type2 actualReturnType = getType(returnExpression);
5722 if (!actualReturnType.isAssignableTo(expectedReturnType)) {
5723 _errorReporter.reportError(StaticTypeWarningCode.RETURN_OF_INVALID_TYPE, returnExpression, [actualReturnType.name, expectedReturnType.name]);
5724 return true;
5725 }
5726 }
5727 return false;
5728 }
5729 /**
5730 * This verifies that the type arguments in the passed instance creation expre ssion are all within
5731 * their bounds as specified by the class element where the constructor [that is being invoked] is
5732 * declared.
5733 * @param node the instance creation expression to evaluate
5734 * @param typeName the {@link TypeName} of the {@link ConstructorName} from th e{@link InstanceCreationExpression}, this is the AST node that the error is atta ched to
5735 * @param constructorElement the {@link ConstructorElement} from the instance creation expression
5736 * @return return <code>true</code> if and only if an error code is generated on the passed node
5737 * @see StaticTypeWarningCode#TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
5738 */
5739 bool checkForTypeArgumentNotMatchingBounds(InstanceCreationExpression node, Co nstructorElement constructorElement, TypeName typeName) {
5740 if (typeName.typeArguments != null && constructorElement != null) {
5741 NodeList<TypeName> typeNameArgList = typeName.typeArguments.arguments;
5742 List<TypeVariableElement> boundingElts = constructorElement.enclosingEleme nt.typeVariables;
5743 int loopThroughIndex = Math.min(typeNameArgList.length, boundingElts.lengt h);
5744 for (int i = 0; i < loopThroughIndex; i++) {
5745 TypeName argTypeName = typeNameArgList[i];
5746 Type2 argType = argTypeName.type;
5747 Type2 boundType = boundingElts[i].bound;
5748 if (argType != null && boundType != null) {
5749 if (!argType.isSubtypeOf(boundType)) {
5750 _errorReporter.reportError(StaticTypeWarningCode.TYPE_ARGUMENT_NOT_M ATCHING_BOUNDS, argTypeName, [argTypeName.name, boundingElts[i].name]);
5751 return true;
5752 }
5753 }
5754 }
5755 }
5756 return false;
5757 }
5758 /**
5759 * Return the type of the given expression that is to be used for type analysi s.
5760 * @param expression the expression whose type is to be returned
5761 * @return the type of the given expression
5762 */
5763 Type2 getType(Expression expression) {
5764 Type2 type = expression.staticType;
5765 return type == null ? _dynamicType : type;
5766 }
5767 }
5768 /**
5769 * The enumeration {@code ResolverErrorCode} defines the error codes used for er rors detected by the
5770 * resolver. The convention for this class is for the name of the error code to indicate the problem
5771 * that caused the error to be generated and for the error message to explain wh at is wrong and,
5772 * when appropriate, how the problem can be corrected.
5773 * @coverage dart.engine.resolver
5774 */
5775 class ResolverErrorCode implements ErrorCode {
5776 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");
5777 static final ResolverErrorCode CANNOT_BE_RESOLVED = new ResolverErrorCode('CAN NOT_BE_RESOLVED', 1, ErrorType.STATIC_WARNING, "Cannot resolve the name '%s'");
5778 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");
5779 static final ResolverErrorCode MISSING_LIBRARY_DIRECTIVE_WITH_PART = new Resol verErrorCode('MISSING_LIBRARY_DIRECTIVE_WITH_PART', 3, ErrorType.COMPILE_TIME_ER ROR, "Libraries that have parts must have a library directive");
5780 static final ResolverErrorCode MISSING_PART_OF_DIRECTIVE = new ResolverErrorCo de('MISSING_PART_OF_DIRECTIVE', 4, ErrorType.COMPILE_TIME_ERROR, "The included p art must have a part-of directive");
5781 static final List<ResolverErrorCode> values = [BREAK_LABEL_ON_SWITCH_MEMBER, C ANNOT_BE_RESOLVED, CONTINUE_LABEL_ON_SWITCH, MISSING_LIBRARY_DIRECTIVE_WITH_PART , MISSING_PART_OF_DIRECTIVE];
5782 final String __name;
5783 final int __ordinal;
5784 int get ordinal => __ordinal;
5785 /**
5786 * The type of this error.
5787 */
5788 ErrorType _type;
5789 /**
5790 * The message template used to create the message to be displayed for this er ror.
5791 */
5792 String _message;
5793 /**
5794 * Initialize a newly created error code to have the given type and message.
5795 * @param type the type of this error
5796 * @param message the message template used to create the message to be displa yed for the error
5797 */
5798 ResolverErrorCode(this.__name, this.__ordinal, ErrorType type, String message) {
5799 this._type = type;
5800 this._message = message;
5801 }
5802 ErrorSeverity get errorSeverity => _type.severity;
5803 String get message => _message;
5804 ErrorType get type => _type;
5805 bool needsRecompilation() => true;
5806 String toString() => __name;
5807 }
OLDNEW
« no previous file with comments | « pkg/analyzer-experimental/lib/src/generated/parser.dart ('k') | pkg/analyzer-experimental/lib/src/generated/scanner.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698