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

Side by Side Diff: packages/analyzer/lib/src/dart/element/builder.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library analyzer.src.dart.element.builder;
6
7 import 'dart:collection';
8
9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/token.dart';
11 import 'package:analyzer/dart/ast/visitor.dart';
12 import 'package:analyzer/dart/element/element.dart';
13 import 'package:analyzer/dart/element/type.dart';
14 import 'package:analyzer/error/error.dart';
15 import 'package:analyzer/exception/exception.dart';
16 import 'package:analyzer/src/dart/element/element.dart';
17 import 'package:analyzer/src/dart/element/type.dart';
18 import 'package:analyzer/src/error/codes.dart';
19 import 'package:analyzer/src/generated/engine.dart';
20 import 'package:analyzer/src/generated/resolver.dart';
21 import 'package:analyzer/src/generated/sdk.dart';
22 import 'package:analyzer/src/generated/source.dart';
23 import 'package:analyzer/src/generated/utilities_dart.dart';
24
25 /**
26 * A `CompilationUnitBuilder` builds an element model for a single compilation
27 * unit.
28 */
29 class CompilationUnitBuilder {
30 /**
31 * Build the compilation unit element for the given [source] based on the
32 * compilation [unit] associated with the source. Throw an AnalysisException
33 * if the element could not be built. [librarySource] is the source for the
34 * containing library.
35 */
36 CompilationUnitElementImpl buildCompilationUnit(
37 Source source, CompilationUnit unit, Source librarySource) {
38 return PerformanceStatistics.resolve.makeCurrentWhile(() {
39 if (unit == null) {
40 return null;
41 }
42 ElementHolder holder = new ElementHolder();
43 CompilationUnitElementImpl element =
44 new CompilationUnitElementImpl(source.shortName);
45 ElementBuilder builder = new ElementBuilder(holder, element);
46 unit.accept(builder);
47 element.accessors = holder.accessors;
48 element.enums = holder.enums;
49 element.functions = holder.functions;
50 element.source = source;
51 element.librarySource = librarySource;
52 element.typeAliases = holder.typeAliases;
53 element.types = holder.types;
54 element.topLevelVariables = holder.topLevelVariables;
55 unit.element = element;
56 holder.validate();
57 return element;
58 });
59 }
60 }
61
62 /**
63 * Instances of the class `DirectiveElementBuilder` build elements for top
64 * level library directives.
65 */
66 class DirectiveElementBuilder extends SimpleAstVisitor<Object> {
67 /**
68 * The analysis context within which directive elements are being built.
69 */
70 final AnalysisContext context;
71
72 /**
73 * The library element for which directive elements are being built.
74 */
75 final LibraryElementImpl libraryElement;
76
77 /**
78 * Map from sources referenced by this library to their modification times.
79 */
80 final Map<Source, int> sourceModificationTimeMap;
81
82 /**
83 * Map from sources imported by this library to their corresponding library
84 * elements.
85 */
86 final Map<Source, LibraryElement> importLibraryMap;
87
88 /**
89 * Map from sources imported by this library to their corresponding source
90 * kinds.
91 */
92 final Map<Source, SourceKind> importSourceKindMap;
93
94 /**
95 * Map from sources exported by this library to their corresponding library
96 * elements.
97 */
98 final Map<Source, LibraryElement> exportLibraryMap;
99
100 /**
101 * Map from sources exported by this library to their corresponding source
102 * kinds.
103 */
104 final Map<Source, SourceKind> exportSourceKindMap;
105
106 /**
107 * The [ImportElement]s created so far.
108 */
109 final List<ImportElement> imports = <ImportElement>[];
110
111 /**
112 * The [ExportElement]s created so far.
113 */
114 final List<ExportElement> exports = <ExportElement>[];
115
116 /**
117 * The errors found while building directive elements.
118 */
119 final List<AnalysisError> errors = <AnalysisError>[];
120
121 /**
122 * Map from prefix names to their corresponding elements.
123 */
124 final HashMap<String, PrefixElementImpl> nameToPrefixMap =
125 new HashMap<String, PrefixElementImpl>();
126
127 /**
128 * Indicates whether an explicit import of `dart:core` has been found.
129 */
130 bool explicitlyImportsCore = false;
131
132 DirectiveElementBuilder(
133 this.context,
134 this.libraryElement,
135 this.sourceModificationTimeMap,
136 this.importLibraryMap,
137 this.importSourceKindMap,
138 this.exportLibraryMap,
139 this.exportSourceKindMap);
140
141 @override
142 Object visitCompilationUnit(CompilationUnit node) {
143 //
144 // Resolve directives.
145 //
146 for (Directive directive in node.directives) {
147 directive.accept(this);
148 }
149 //
150 // Ensure "dart:core" import.
151 //
152 Source librarySource = libraryElement.source;
153 Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE);
154 if (!explicitlyImportsCore && coreLibrarySource != librarySource) {
155 ImportElementImpl importElement = new ImportElementImpl(-1);
156 importElement.importedLibrary = importLibraryMap[coreLibrarySource];
157 importElement.synthetic = true;
158 imports.add(importElement);
159 }
160 //
161 // Populate the library element.
162 //
163 libraryElement.imports = imports;
164 libraryElement.exports = exports;
165 return null;
166 }
167
168 @override
169 Object visitExportDirective(ExportDirective node) {
170 // Remove previous element. (It will remain null if the target is missing.)
171 node.element = null;
172 Source exportedSource = node.selectedSource;
173 int exportedTime = sourceModificationTimeMap[exportedSource] ?? -1;
174 // The exported source will be null if the URI in the export
175 // directive was invalid.
176 LibraryElement exportedLibrary = exportLibraryMap[exportedSource];
177 if (exportedLibrary != null) {
178 ExportElementImpl exportElement = new ExportElementImpl(node.offset);
179 exportElement.metadata = _getElementAnnotations(node.metadata);
180 StringLiteral uriLiteral = node.uri;
181 if (uriLiteral != null) {
182 exportElement.uriOffset = uriLiteral.offset;
183 exportElement.uriEnd = uriLiteral.end;
184 }
185 exportElement.uri = node.selectedUriContent;
186 exportElement.combinators = _buildCombinators(node);
187 exportElement.exportedLibrary = exportedLibrary;
188 setElementDocumentationComment(exportElement, node);
189 node.element = exportElement;
190 exports.add(exportElement);
191 if (exportedTime >= 0 &&
192 exportSourceKindMap[exportedSource] != SourceKind.LIBRARY) {
193 int offset = node.offset;
194 int length = node.length;
195 if (uriLiteral != null) {
196 offset = uriLiteral.offset;
197 length = uriLiteral.length;
198 }
199 errors.add(new AnalysisError(
200 libraryElement.source,
201 offset,
202 length,
203 CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
204 [uriLiteral.toSource()]));
205 }
206 }
207 return null;
208 }
209
210 @override
211 Object visitImportDirective(ImportDirective node) {
212 // Remove previous element. (It will remain null if the target is missing.)
213 node.element = null;
214 Source importedSource = node.selectedSource;
215 int importedTime = sourceModificationTimeMap[importedSource] ?? -1;
216 // The imported source will be null if the URI in the import
217 // directive was invalid.
218 LibraryElement importedLibrary = importLibraryMap[importedSource];
219 if (importedLibrary != null) {
220 if (importedLibrary.isDartCore) {
221 explicitlyImportsCore = true;
222 }
223 ImportElementImpl importElement = new ImportElementImpl(node.offset);
224 importElement.metadata = _getElementAnnotations(node.metadata);
225 StringLiteral uriLiteral = node.uri;
226 if (uriLiteral != null) {
227 importElement.uriOffset = uriLiteral.offset;
228 importElement.uriEnd = uriLiteral.end;
229 }
230 importElement.uri = node.selectedUriContent;
231 importElement.deferred = node.deferredKeyword != null;
232 importElement.combinators = _buildCombinators(node);
233 importElement.importedLibrary = importedLibrary;
234 setElementDocumentationComment(importElement, node);
235 SimpleIdentifier prefixNode = node.prefix;
236 if (prefixNode != null) {
237 importElement.prefixOffset = prefixNode.offset;
238 String prefixName = prefixNode.name;
239 PrefixElementImpl prefix = nameToPrefixMap[prefixName];
240 if (prefix == null) {
241 prefix = new PrefixElementImpl.forNode(prefixNode);
242 nameToPrefixMap[prefixName] = prefix;
243 }
244 importElement.prefix = prefix;
245 prefixNode.staticElement = prefix;
246 }
247 node.element = importElement;
248 imports.add(importElement);
249 if (importedTime >= 0 &&
250 importSourceKindMap[importedSource] != SourceKind.LIBRARY) {
251 int offset = node.offset;
252 int length = node.length;
253 if (uriLiteral != null) {
254 offset = uriLiteral.offset;
255 length = uriLiteral.length;
256 }
257 ErrorCode errorCode = importElement.isDeferred
258 ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
259 : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY;
260 errors.add(new AnalysisError(libraryElement.source, offset, length,
261 errorCode, [uriLiteral.toSource()]));
262 }
263 }
264 return null;
265 }
266
267 @override
268 Object visitLibraryDirective(LibraryDirective node) {
269 (node.element as LibraryElementImpl)?.metadata =
270 _getElementAnnotations(node.metadata);
271 return null;
272 }
273
274 @override
275 Object visitPartDirective(PartDirective node) {
276 (node.element as CompilationUnitElementImpl)?.metadata =
277 _getElementAnnotations(node.metadata);
278 return null;
279 }
280
281 /**
282 * Gather a list of the [ElementAnnotation]s referred to by the [Annotation]s
283 * in [metadata].
284 */
285 List<ElementAnnotation> _getElementAnnotations(
286 NodeList<Annotation> metadata) {
287 if (metadata.isEmpty) {
288 return ElementAnnotation.EMPTY_LIST;
289 }
290 return metadata.map((Annotation a) => a.elementAnnotation).toList();
291 }
292
293 /**
294 * Build the element model representing the combinators declared by
295 * the given [directive].
296 */
297 static List<NamespaceCombinator> _buildCombinators(
298 NamespaceDirective directive) {
299 _NamespaceCombinatorBuilder namespaceCombinatorBuilder =
300 new _NamespaceCombinatorBuilder();
301 for (Combinator combinator in directive.combinators) {
302 combinator.accept(namespaceCombinatorBuilder);
303 }
304 return namespaceCombinatorBuilder.combinators;
305 }
306 }
307
308 /**
309 * Instances of the class `ElementBuilder` traverse an AST structure and build t he element
310 * model representing the AST structure.
311 */
312 class ElementBuilder extends RecursiveAstVisitor<Object> {
313 /**
314 * The compilation unit element into which the elements being built will be
315 * stored.
316 */
317 final CompilationUnitElementImpl compilationUnitElement;
318
319 /**
320 * The element holder associated with the element that is currently being buil t.
321 */
322 ElementHolder _currentHolder;
323
324 /**
325 * A flag indicating whether a variable declaration is within the body of a me thod or function.
326 */
327 bool _inFunction = false;
328
329 /**
330 * A collection holding the elements defined in a class that need to have
331 * their function type fixed to take into account type parameters of the
332 * enclosing class, or `null` if we are not currently processing nodes within
333 * a class.
334 */
335 List<ExecutableElementImpl> _functionTypesToFix = null;
336
337 /**
338 * A table mapping field names to field elements for the fields defined in the current class, or
339 * `null` if we are not in the scope of a class.
340 */
341 HashMap<String, FieldElement> _fieldMap;
342
343 /**
344 * Initialize a newly created element builder to build the elements for a
345 * compilation unit. The [initialHolder] is the element holder to which the
346 * children of the visited compilation unit node will be added.
347 */
348 ElementBuilder(ElementHolder initialHolder, this.compilationUnitElement) {
349 _currentHolder = initialHolder;
350 }
351
352 /**
353 * Prepares for incremental resolution of a function body.
354 */
355 void initForFunctionBodyIncrementalResolution() {
356 _inFunction = true;
357 }
358
359 @override
360 Object visitAnnotation(Annotation node) {
361 // Although it isn't valid to do so because closures are not constant
362 // expressions, it's possible for one of the arguments to the constructor to
363 // contain a closure. Wrapping the processing of the annotation this way
364 // prevents these closures from being added to the list of functions in the
365 // annotated declaration.
366 ElementHolder holder = new ElementHolder();
367 ElementHolder previousHolder = _currentHolder;
368 _currentHolder = holder;
369 try {
370 super.visitAnnotation(node);
371 } finally {
372 _currentHolder = previousHolder;
373 }
374 return null;
375 }
376
377 @override
378 Object visitCatchClause(CatchClause node) {
379 SimpleIdentifier exceptionParameter = node.exceptionParameter;
380 if (exceptionParameter != null) {
381 // exception
382 LocalVariableElementImpl exception =
383 new LocalVariableElementImpl.forNode(exceptionParameter);
384 if (node.exceptionType == null) {
385 exception.hasImplicitType = true;
386 }
387 exception.setVisibleRange(node.offset, node.length);
388 _currentHolder.addLocalVariable(exception);
389 exceptionParameter.staticElement = exception;
390 // stack trace
391 SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
392 if (stackTraceParameter != null) {
393 LocalVariableElementImpl stackTrace =
394 new LocalVariableElementImpl.forNode(stackTraceParameter);
395 _setCodeRange(stackTrace, stackTraceParameter);
396 stackTrace.setVisibleRange(node.offset, node.length);
397 _currentHolder.addLocalVariable(stackTrace);
398 stackTraceParameter.staticElement = stackTrace;
399 }
400 }
401 return super.visitCatchClause(node);
402 }
403
404 @override
405 Object visitClassDeclaration(ClassDeclaration node) {
406 ElementHolder holder = new ElementHolder();
407 _functionTypesToFix = new List<ExecutableElementImpl>();
408 //
409 // Process field declarations before constructors and methods so that field
410 // formal parameters can be correctly resolved to their fields.
411 //
412 ElementHolder previousHolder = _currentHolder;
413 _currentHolder = holder;
414 try {
415 List<ClassMember> nonFields = new List<ClassMember>();
416 node.visitChildren(
417 new _ElementBuilder_visitClassDeclaration(this, nonFields));
418 _buildFieldMap(holder.fieldsWithoutFlushing);
419 int count = nonFields.length;
420 for (int i = 0; i < count; i++) {
421 nonFields[i].accept(this);
422 }
423 } finally {
424 _currentHolder = previousHolder;
425 }
426 SimpleIdentifier className = node.name;
427 ClassElementImpl element = new ClassElementImpl.forNode(className);
428 _setCodeRange(element, node);
429 element.metadata = _createElementAnnotations(node.metadata);
430 element.typeParameters = holder.typeParameters;
431 setElementDocumentationComment(element, node);
432 element.abstract = node.isAbstract;
433 element.accessors = holder.accessors;
434 List<ConstructorElement> constructors = holder.constructors;
435 if (constructors.isEmpty) {
436 constructors = _createDefaultConstructors(element);
437 }
438 element.constructors = constructors;
439 element.fields = holder.fields;
440 element.methods = holder.methods;
441 // Function types must be initialized after the enclosing element has been
442 // set, for them to pick up the type parameters.
443 for (ExecutableElementImpl e in _functionTypesToFix) {
444 e.type = new FunctionTypeImpl(e);
445 }
446 _functionTypesToFix = null;
447 _currentHolder.addType(element);
448 className.staticElement = element;
449 _fieldMap = null;
450 holder.validate();
451 return null;
452 }
453
454 @override
455 Object visitClassTypeAlias(ClassTypeAlias node) {
456 ElementHolder holder = new ElementHolder();
457 _visitChildren(holder, node);
458 SimpleIdentifier className = node.name;
459 ClassElementImpl element = new ClassElementImpl.forNode(className);
460 _setCodeRange(element, node);
461 element.metadata = _createElementAnnotations(node.metadata);
462 element.abstract = node.abstractKeyword != null;
463 element.mixinApplication = true;
464 element.typeParameters = holder.typeParameters;
465 setElementDocumentationComment(element, node);
466 _currentHolder.addType(element);
467 className.staticElement = element;
468 holder.validate();
469 return null;
470 }
471
472 @override
473 Object visitCompilationUnit(CompilationUnit node) {
474 if (compilationUnitElement is ElementImpl) {
475 _setCodeRange(compilationUnitElement, node);
476 }
477 return super.visitCompilationUnit(node);
478 }
479
480 @override
481 Object visitConstructorDeclaration(ConstructorDeclaration node) {
482 ElementHolder holder = new ElementHolder();
483 bool wasInFunction = _inFunction;
484 _inFunction = true;
485 try {
486 _visitChildren(holder, node);
487 } finally {
488 _inFunction = wasInFunction;
489 }
490 FunctionBody body = node.body;
491 SimpleIdentifier constructorName = node.name;
492 ConstructorElementImpl element =
493 new ConstructorElementImpl.forNode(constructorName);
494 _setCodeRange(element, node);
495 element.metadata = _createElementAnnotations(node.metadata);
496 setElementDocumentationComment(element, node);
497 if (node.externalKeyword != null) {
498 element.external = true;
499 }
500 if (node.factoryKeyword != null) {
501 element.factory = true;
502 }
503 element.functions = holder.functions;
504 element.labels = holder.labels;
505 element.localVariables = holder.localVariables;
506 element.parameters = holder.parameters;
507 element.const2 = node.constKeyword != null;
508 if (body.isAsynchronous) {
509 element.asynchronous = true;
510 }
511 if (body.isGenerator) {
512 element.generator = true;
513 }
514 _currentHolder.addConstructor(element);
515 node.element = element;
516 if (constructorName == null) {
517 Identifier returnType = node.returnType;
518 if (returnType != null) {
519 element.nameOffset = returnType.offset;
520 element.nameEnd = returnType.end;
521 }
522 } else {
523 constructorName.staticElement = element;
524 element.periodOffset = node.period.offset;
525 element.nameEnd = constructorName.end;
526 }
527 holder.validate();
528 return null;
529 }
530
531 @override
532 Object visitDeclaredIdentifier(DeclaredIdentifier node) {
533 SimpleIdentifier variableName = node.identifier;
534 LocalVariableElementImpl element =
535 new LocalVariableElementImpl.forNode(variableName);
536 _setCodeRange(element, node);
537 element.metadata = _createElementAnnotations(node.metadata);
538 ForEachStatement statement = node.parent as ForEachStatement;
539 element.setVisibleRange(statement.offset, statement.length);
540 element.const3 = node.isConst;
541 element.final2 = node.isFinal;
542 if (node.type == null) {
543 element.hasImplicitType = true;
544 }
545 _currentHolder.addLocalVariable(element);
546 variableName.staticElement = element;
547 return super.visitDeclaredIdentifier(node);
548 }
549
550 @override
551 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
552 ElementHolder holder = new ElementHolder();
553 NormalFormalParameter normalParameter = node.parameter;
554 SimpleIdentifier parameterName = normalParameter.identifier;
555 ParameterElementImpl parameter;
556 if (normalParameter is FieldFormalParameter) {
557 parameter =
558 new DefaultFieldFormalParameterElementImpl.forNode(parameterName);
559 FieldElement field =
560 _fieldMap == null ? null : _fieldMap[parameterName.name];
561 if (field != null) {
562 (parameter as DefaultFieldFormalParameterElementImpl).field = field;
563 }
564 } else {
565 parameter = new DefaultParameterElementImpl.forNode(parameterName);
566 }
567 _setCodeRange(parameter, node);
568 parameter.const3 = node.isConst;
569 parameter.final2 = node.isFinal;
570 parameter.parameterKind = node.kind;
571 // set initializer, default value range
572 Expression defaultValue = node.defaultValue;
573 if (defaultValue != null) {
574 _visit(holder, defaultValue);
575 FunctionElementImpl initializer =
576 new FunctionElementImpl.forOffset(defaultValue.beginToken.offset);
577 initializer.hasImplicitReturnType = true;
578 initializer.functions = holder.functions;
579 initializer.labels = holder.labels;
580 initializer.localVariables = holder.localVariables;
581 initializer.parameters = holder.parameters;
582 initializer.synthetic = true;
583 initializer.type = new FunctionTypeImpl(initializer);
584 parameter.initializer = initializer;
585 parameter.defaultValueCode = defaultValue.toSource();
586 }
587 // visible range
588 _setParameterVisibleRange(node, parameter);
589 if (normalParameter is SimpleFormalParameter &&
590 normalParameter.type == null) {
591 parameter.hasImplicitType = true;
592 }
593 _currentHolder.addParameter(parameter);
594 parameterName.staticElement = parameter;
595 normalParameter.accept(this);
596 holder.validate();
597 return null;
598 }
599
600 @override
601 Object visitEnumDeclaration(EnumDeclaration node) {
602 SimpleIdentifier enumName = node.name;
603 EnumElementImpl enumElement = new EnumElementImpl.forNode(enumName);
604 _setCodeRange(enumElement, node);
605 enumElement.metadata = _createElementAnnotations(node.metadata);
606 setElementDocumentationComment(enumElement, node);
607 InterfaceTypeImpl enumType = enumElement.type;
608 //
609 // Build the elements for the constants. These are minimal elements; the
610 // rest of the constant elements (and elements for other fields) must be
611 // built later after we can access the type provider.
612 //
613 List<FieldElement> fields = new List<FieldElement>();
614 NodeList<EnumConstantDeclaration> constants = node.constants;
615 for (EnumConstantDeclaration constant in constants) {
616 SimpleIdentifier constantName = constant.name;
617 FieldElementImpl constantField =
618 new ConstFieldElementImpl.forNode(constantName);
619 constantField.static = true;
620 constantField.const3 = true;
621 constantField.type = enumType;
622 setElementDocumentationComment(constantField, constant);
623 fields.add(constantField);
624 new PropertyAccessorElementImpl_ImplicitGetter(constantField);
625 constantName.staticElement = constantField;
626 }
627 enumElement.fields = fields;
628
629 _currentHolder.addEnum(enumElement);
630 enumName.staticElement = enumElement;
631 return super.visitEnumDeclaration(node);
632 }
633
634 @override
635 Object visitExportDirective(ExportDirective node) {
636 List<ElementAnnotation> annotations =
637 _createElementAnnotations(node.metadata);
638 compilationUnitElement.setAnnotations(node.offset, annotations);
639 return super.visitExportDirective(node);
640 }
641
642 @override
643 Object visitFieldFormalParameter(FieldFormalParameter node) {
644 if (node.parent is! DefaultFormalParameter) {
645 SimpleIdentifier parameterName = node.identifier;
646 FieldElement field =
647 _fieldMap == null ? null : _fieldMap[parameterName.name];
648 FieldFormalParameterElementImpl parameter =
649 new FieldFormalParameterElementImpl.forNode(parameterName);
650 _setCodeRange(parameter, node);
651 parameter.const3 = node.isConst;
652 parameter.final2 = node.isFinal;
653 parameter.parameterKind = node.kind;
654 if (field != null) {
655 parameter.field = field;
656 }
657 _currentHolder.addParameter(parameter);
658 parameterName.staticElement = parameter;
659 }
660 //
661 // The children of this parameter include any parameters defined on the type
662 // of this parameter.
663 //
664 ElementHolder holder = new ElementHolder();
665 _visitChildren(holder, node);
666 ParameterElementImpl element = node.element;
667 element.metadata = _createElementAnnotations(node.metadata);
668 element.parameters = holder.parameters;
669 element.typeParameters = holder.typeParameters;
670 holder.validate();
671 return null;
672 }
673
674 @override
675 Object visitFunctionDeclaration(FunctionDeclaration node) {
676 FunctionExpression expression = node.functionExpression;
677 if (expression != null) {
678 ElementHolder holder = new ElementHolder();
679 bool wasInFunction = _inFunction;
680 _inFunction = true;
681 try {
682 _visitChildren(holder, node);
683 } finally {
684 _inFunction = wasInFunction;
685 }
686 FunctionBody body = expression.body;
687 Token property = node.propertyKeyword;
688 if (property == null || _inFunction) {
689 SimpleIdentifier functionName = node.name;
690 FunctionElementImpl element =
691 new FunctionElementImpl.forNode(functionName);
692 _setCodeRange(element, node);
693 element.metadata = _createElementAnnotations(node.metadata);
694 setElementDocumentationComment(element, node);
695 if (node.externalKeyword != null) {
696 element.external = true;
697 }
698 element.functions = holder.functions;
699 element.labels = holder.labels;
700 element.localVariables = holder.localVariables;
701 element.parameters = holder.parameters;
702 element.typeParameters = holder.typeParameters;
703 if (body.isAsynchronous) {
704 element.asynchronous = true;
705 }
706 if (body.isGenerator) {
707 element.generator = true;
708 }
709 if (_inFunction) {
710 Block enclosingBlock = node.getAncestor((node) => node is Block);
711 if (enclosingBlock != null) {
712 element.setVisibleRange(
713 enclosingBlock.offset, enclosingBlock.length);
714 }
715 }
716 if (node.returnType == null) {
717 element.hasImplicitReturnType = true;
718 }
719 _currentHolder.addFunction(element);
720 expression.element = element;
721 functionName.staticElement = element;
722 } else {
723 SimpleIdentifier propertyNameNode = node.name;
724 if (propertyNameNode == null) {
725 // TODO(brianwilkerson) Report this internal error.
726 return null;
727 }
728 String propertyName = propertyNameNode.name;
729 TopLevelVariableElementImpl variable = _currentHolder
730 .getTopLevelVariable(propertyName) as TopLevelVariableElementImpl;
731 if (variable == null) {
732 variable = new TopLevelVariableElementImpl(node.name.name, -1);
733 variable.final2 = true;
734 variable.synthetic = true;
735 _currentHolder.addTopLevelVariable(variable);
736 }
737 if (node.isGetter) {
738 PropertyAccessorElementImpl getter =
739 new PropertyAccessorElementImpl.forNode(propertyNameNode);
740 _setCodeRange(getter, node);
741 getter.metadata = _createElementAnnotations(node.metadata);
742 setElementDocumentationComment(getter, node);
743 if (node.externalKeyword != null) {
744 getter.external = true;
745 }
746 getter.functions = holder.functions;
747 getter.labels = holder.labels;
748 getter.localVariables = holder.localVariables;
749 if (body.isAsynchronous) {
750 getter.asynchronous = true;
751 }
752 if (body.isGenerator) {
753 getter.generator = true;
754 }
755 getter.variable = variable;
756 getter.getter = true;
757 getter.static = true;
758 variable.getter = getter;
759 if (node.returnType == null) {
760 getter.hasImplicitReturnType = true;
761 }
762 _currentHolder.addAccessor(getter);
763 expression.element = getter;
764 propertyNameNode.staticElement = getter;
765 } else {
766 PropertyAccessorElementImpl setter =
767 new PropertyAccessorElementImpl.forNode(propertyNameNode);
768 _setCodeRange(setter, node);
769 setter.metadata = _createElementAnnotations(node.metadata);
770 setElementDocumentationComment(setter, node);
771 if (node.externalKeyword != null) {
772 setter.external = true;
773 }
774 setter.functions = holder.functions;
775 setter.labels = holder.labels;
776 setter.localVariables = holder.localVariables;
777 setter.parameters = holder.parameters;
778 if (body.isAsynchronous) {
779 setter.asynchronous = true;
780 }
781 if (body.isGenerator) {
782 setter.generator = true;
783 }
784 setter.variable = variable;
785 setter.setter = true;
786 setter.static = true;
787 if (node.returnType == null) {
788 setter.hasImplicitReturnType = true;
789 }
790 variable.setter = setter;
791 variable.final2 = false;
792 _currentHolder.addAccessor(setter);
793 expression.element = setter;
794 propertyNameNode.staticElement = setter;
795 }
796 }
797 holder.validate();
798 }
799 return null;
800 }
801
802 @override
803 Object visitFunctionExpression(FunctionExpression node) {
804 if (node.parent is FunctionDeclaration) {
805 // visitFunctionDeclaration has already created the element for the
806 // declaration. We just need to visit children.
807 return super.visitFunctionExpression(node);
808 }
809 ElementHolder holder = new ElementHolder();
810 bool wasInFunction = _inFunction;
811 _inFunction = true;
812 try {
813 _visitChildren(holder, node);
814 } finally {
815 _inFunction = wasInFunction;
816 }
817 FunctionBody body = node.body;
818 FunctionElementImpl element =
819 new FunctionElementImpl.forOffset(node.beginToken.offset);
820 _setCodeRange(element, node);
821 element.functions = holder.functions;
822 element.labels = holder.labels;
823 element.localVariables = holder.localVariables;
824 element.parameters = holder.parameters;
825 element.typeParameters = holder.typeParameters;
826 if (body.isAsynchronous) {
827 element.asynchronous = true;
828 }
829 if (body.isGenerator) {
830 element.generator = true;
831 }
832 if (_inFunction) {
833 Block enclosingBlock = node.getAncestor((node) => node is Block);
834 if (enclosingBlock != null) {
835 element.setVisibleRange(enclosingBlock.offset, enclosingBlock.length);
836 }
837 }
838 if (_functionTypesToFix != null) {
839 _functionTypesToFix.add(element);
840 } else {
841 element.type = new FunctionTypeImpl(element);
842 }
843 element.hasImplicitReturnType = true;
844 _currentHolder.addFunction(element);
845 node.element = element;
846 holder.validate();
847 return null;
848 }
849
850 @override
851 Object visitFunctionTypeAlias(FunctionTypeAlias node) {
852 ElementHolder holder = new ElementHolder();
853 _visitChildren(holder, node);
854 SimpleIdentifier aliasName = node.name;
855 List<ParameterElement> parameters = holder.parameters;
856 List<TypeParameterElement> typeParameters = holder.typeParameters;
857 FunctionTypeAliasElementImpl element =
858 new FunctionTypeAliasElementImpl.forNode(aliasName);
859 _setCodeRange(element, node);
860 element.metadata = _createElementAnnotations(node.metadata);
861 setElementDocumentationComment(element, node);
862 element.parameters = parameters;
863 element.typeParameters = typeParameters;
864 _createTypeParameterTypes(typeParameters);
865 element.type = new FunctionTypeImpl.forTypedef(element);
866 _currentHolder.addTypeAlias(element);
867 aliasName.staticElement = element;
868 holder.validate();
869 return null;
870 }
871
872 @override
873 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
874 if (node.parent is! DefaultFormalParameter) {
875 SimpleIdentifier parameterName = node.identifier;
876 ParameterElementImpl parameter =
877 new ParameterElementImpl.forNode(parameterName);
878 _setCodeRange(parameter, node);
879 parameter.parameterKind = node.kind;
880 _setParameterVisibleRange(node, parameter);
881 _currentHolder.addParameter(parameter);
882 parameterName.staticElement = parameter;
883 }
884 //
885 // The children of this parameter include any parameters defined on the type
886 //of this parameter.
887 //
888 ElementHolder holder = new ElementHolder();
889 _visitChildren(holder, node);
890 ParameterElementImpl element = node.element;
891 element.metadata = _createElementAnnotations(node.metadata);
892 element.parameters = holder.parameters;
893 element.typeParameters = holder.typeParameters;
894 holder.validate();
895 return null;
896 }
897
898 @override
899 Object visitImportDirective(ImportDirective node) {
900 List<ElementAnnotation> annotations =
901 _createElementAnnotations(node.metadata);
902 compilationUnitElement.setAnnotations(node.offset, annotations);
903 return super.visitImportDirective(node);
904 }
905
906 @override
907 Object visitLabeledStatement(LabeledStatement node) {
908 bool onSwitchStatement = node.statement is SwitchStatement;
909 for (Label label in node.labels) {
910 SimpleIdentifier labelName = label.label;
911 LabelElementImpl element =
912 new LabelElementImpl.forNode(labelName, onSwitchStatement, false);
913 _currentHolder.addLabel(element);
914 labelName.staticElement = element;
915 }
916 return super.visitLabeledStatement(node);
917 }
918
919 @override
920 Object visitLibraryDirective(LibraryDirective node) {
921 List<ElementAnnotation> annotations =
922 _createElementAnnotations(node.metadata);
923 compilationUnitElement.setAnnotations(node.offset, annotations);
924 return super.visitLibraryDirective(node);
925 }
926
927 @override
928 Object visitMethodDeclaration(MethodDeclaration node) {
929 try {
930 ElementHolder holder = new ElementHolder();
931 bool wasInFunction = _inFunction;
932 _inFunction = true;
933 try {
934 _visitChildren(holder, node);
935 } finally {
936 _inFunction = wasInFunction;
937 }
938 bool isStatic = node.isStatic;
939 Token property = node.propertyKeyword;
940 FunctionBody body = node.body;
941 if (property == null) {
942 SimpleIdentifier methodName = node.name;
943 String nameOfMethod = methodName.name;
944 if (nameOfMethod == TokenType.MINUS.lexeme &&
945 node.parameters.parameters.length == 0) {
946 nameOfMethod = "unary-";
947 }
948 MethodElementImpl element =
949 new MethodElementImpl(nameOfMethod, methodName.offset);
950 _setCodeRange(element, node);
951 element.metadata = _createElementAnnotations(node.metadata);
952 setElementDocumentationComment(element, node);
953 element.abstract = node.isAbstract;
954 if (node.externalKeyword != null) {
955 element.external = true;
956 }
957 element.functions = holder.functions;
958 element.labels = holder.labels;
959 element.localVariables = holder.localVariables;
960 element.parameters = holder.parameters;
961 element.static = isStatic;
962 element.typeParameters = holder.typeParameters;
963 if (body.isAsynchronous) {
964 element.asynchronous = true;
965 }
966 if (body.isGenerator) {
967 element.generator = true;
968 }
969 if (node.returnType == null) {
970 element.hasImplicitReturnType = true;
971 }
972 _currentHolder.addMethod(element);
973 methodName.staticElement = element;
974 } else {
975 SimpleIdentifier propertyNameNode = node.name;
976 String propertyName = propertyNameNode.name;
977 FieldElementImpl field = _currentHolder.getField(propertyName,
978 synthetic: true) as FieldElementImpl;
979 if (field == null) {
980 field = new FieldElementImpl(node.name.name, -1);
981 field.final2 = true;
982 field.static = isStatic;
983 field.synthetic = true;
984 _currentHolder.addField(field);
985 }
986 if (node.isGetter) {
987 PropertyAccessorElementImpl getter =
988 new PropertyAccessorElementImpl.forNode(propertyNameNode);
989 _setCodeRange(getter, node);
990 getter.metadata = _createElementAnnotations(node.metadata);
991 setElementDocumentationComment(getter, node);
992 if (node.externalKeyword != null) {
993 getter.external = true;
994 }
995 getter.functions = holder.functions;
996 getter.labels = holder.labels;
997 getter.localVariables = holder.localVariables;
998 if (body.isAsynchronous) {
999 getter.asynchronous = true;
1000 }
1001 if (body.isGenerator) {
1002 getter.generator = true;
1003 }
1004 getter.variable = field;
1005 getter.abstract = node.isAbstract;
1006 getter.getter = true;
1007 getter.static = isStatic;
1008 field.getter = getter;
1009 if (node.returnType == null) {
1010 getter.hasImplicitReturnType = true;
1011 }
1012 _currentHolder.addAccessor(getter);
1013 propertyNameNode.staticElement = getter;
1014 } else {
1015 PropertyAccessorElementImpl setter =
1016 new PropertyAccessorElementImpl.forNode(propertyNameNode);
1017 _setCodeRange(setter, node);
1018 setter.metadata = _createElementAnnotations(node.metadata);
1019 setElementDocumentationComment(setter, node);
1020 if (node.externalKeyword != null) {
1021 setter.external = true;
1022 }
1023 setter.functions = holder.functions;
1024 setter.labels = holder.labels;
1025 setter.localVariables = holder.localVariables;
1026 setter.parameters = holder.parameters;
1027 if (body.isAsynchronous) {
1028 setter.asynchronous = true;
1029 }
1030 if (body.isGenerator) {
1031 setter.generator = true;
1032 }
1033 setter.variable = field;
1034 setter.abstract = node.isAbstract;
1035 setter.setter = true;
1036 setter.static = isStatic;
1037 if (node.returnType == null) {
1038 setter.hasImplicitReturnType = true;
1039 }
1040 field.setter = setter;
1041 field.final2 = false;
1042 _currentHolder.addAccessor(setter);
1043 propertyNameNode.staticElement = setter;
1044 }
1045 }
1046 holder.validate();
1047 } catch (exception, stackTrace) {
1048 if (node.name.staticElement == null) {
1049 ClassDeclaration classNode =
1050 node.getAncestor((node) => node is ClassDeclaration);
1051 StringBuffer buffer = new StringBuffer();
1052 buffer.write("The element for the method ");
1053 buffer.write(node.name);
1054 buffer.write(" in ");
1055 buffer.write(classNode.name);
1056 buffer.write(" was not set while trying to build the element model.");
1057 AnalysisEngine.instance.logger.logError(
1058 buffer.toString(), new CaughtException(exception, stackTrace));
1059 } else {
1060 String message =
1061 "Exception caught in ElementBuilder.visitMethodDeclaration()";
1062 AnalysisEngine.instance.logger
1063 .logError(message, new CaughtException(exception, stackTrace));
1064 }
1065 } finally {
1066 if (node.name.staticElement == null) {
1067 ClassDeclaration classNode =
1068 node.getAncestor((node) => node is ClassDeclaration);
1069 StringBuffer buffer = new StringBuffer();
1070 buffer.write("The element for the method ");
1071 buffer.write(node.name);
1072 buffer.write(" in ");
1073 buffer.write(classNode.name);
1074 buffer.write(" was not set while trying to resolve types.");
1075 AnalysisEngine.instance.logger.logError(
1076 buffer.toString(),
1077 new CaughtException(
1078 new AnalysisException(buffer.toString()), null));
1079 }
1080 }
1081 return null;
1082 }
1083
1084 @override
1085 Object visitPartDirective(PartDirective node) {
1086 List<ElementAnnotation> annotations =
1087 _createElementAnnotations(node.metadata);
1088 compilationUnitElement.setAnnotations(node.offset, annotations);
1089 return super.visitPartDirective(node);
1090 }
1091
1092 @override
1093 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
1094 if (node.parent is! DefaultFormalParameter) {
1095 SimpleIdentifier parameterName = node.identifier;
1096 ParameterElementImpl parameter =
1097 new ParameterElementImpl.forNode(parameterName);
1098 _setCodeRange(parameter, node);
1099 parameter.const3 = node.isConst;
1100 parameter.final2 = node.isFinal;
1101 parameter.parameterKind = node.kind;
1102 _setParameterVisibleRange(node, parameter);
1103 if (node.type == null) {
1104 parameter.hasImplicitType = true;
1105 }
1106 _currentHolder.addParameter(parameter);
1107 parameterName.staticElement = parameter;
1108 }
1109 super.visitSimpleFormalParameter(node);
1110 (node.element as ElementImpl).metadata =
1111 _createElementAnnotations(node.metadata);
1112 return null;
1113 }
1114
1115 @override
1116 Object visitSwitchCase(SwitchCase node) {
1117 for (Label label in node.labels) {
1118 SimpleIdentifier labelName = label.label;
1119 LabelElementImpl element =
1120 new LabelElementImpl.forNode(labelName, false, true);
1121 _currentHolder.addLabel(element);
1122 labelName.staticElement = element;
1123 }
1124 return super.visitSwitchCase(node);
1125 }
1126
1127 @override
1128 Object visitSwitchDefault(SwitchDefault node) {
1129 for (Label label in node.labels) {
1130 SimpleIdentifier labelName = label.label;
1131 LabelElementImpl element =
1132 new LabelElementImpl.forNode(labelName, false, true);
1133 _currentHolder.addLabel(element);
1134 labelName.staticElement = element;
1135 }
1136 return super.visitSwitchDefault(node);
1137 }
1138
1139 @override
1140 Object visitTypeParameter(TypeParameter node) {
1141 SimpleIdentifier parameterName = node.name;
1142 TypeParameterElementImpl typeParameter =
1143 new TypeParameterElementImpl.forNode(parameterName);
1144 _setCodeRange(typeParameter, node);
1145 typeParameter.metadata = _createElementAnnotations(node.metadata);
1146 TypeParameterTypeImpl typeParameterType =
1147 new TypeParameterTypeImpl(typeParameter);
1148 typeParameter.type = typeParameterType;
1149 _currentHolder.addTypeParameter(typeParameter);
1150 parameterName.staticElement = typeParameter;
1151 return super.visitTypeParameter(node);
1152 }
1153
1154 @override
1155 Object visitVariableDeclaration(VariableDeclaration node) {
1156 bool isConst = node.isConst;
1157 bool isFinal = node.isFinal;
1158 bool hasInitializer = node.initializer != null;
1159 VariableDeclarationList varList = node.parent;
1160 FieldDeclaration fieldNode =
1161 varList.parent is FieldDeclaration ? varList.parent : null;
1162 VariableElementImpl element;
1163 if (fieldNode != null) {
1164 SimpleIdentifier fieldName = node.name;
1165 FieldElementImpl field;
1166 if ((isConst || isFinal && !fieldNode.isStatic) && hasInitializer) {
1167 field = new ConstFieldElementImpl.forNode(fieldName);
1168 } else {
1169 field = new FieldElementImpl.forNode(fieldName);
1170 }
1171 element = field;
1172 field.static = fieldNode.isStatic;
1173 _setCodeRange(element, node);
1174 setElementDocumentationComment(element, fieldNode);
1175 field.hasImplicitType = varList.type == null;
1176 _currentHolder.addField(field);
1177 fieldName.staticElement = field;
1178 } else if (_inFunction) {
1179 SimpleIdentifier variableName = node.name;
1180 LocalVariableElementImpl variable;
1181 if (isConst && hasInitializer) {
1182 variable = new ConstLocalVariableElementImpl.forNode(variableName);
1183 } else {
1184 variable = new LocalVariableElementImpl.forNode(variableName);
1185 }
1186 element = variable;
1187 _setCodeRange(element, node);
1188 _setVariableVisibleRange(variable, node);
1189 variable.hasImplicitType = varList.type == null;
1190 _currentHolder.addLocalVariable(variable);
1191 variableName.staticElement = element;
1192 } else {
1193 SimpleIdentifier variableName = node.name;
1194 TopLevelVariableElementImpl variable;
1195 if (isConst && hasInitializer) {
1196 variable = new ConstTopLevelVariableElementImpl.forNode(variableName);
1197 } else {
1198 variable = new TopLevelVariableElementImpl.forNode(variableName);
1199 }
1200 element = variable;
1201 _setCodeRange(element, node);
1202 if (varList.parent is TopLevelVariableDeclaration) {
1203 setElementDocumentationComment(element, varList.parent);
1204 }
1205 variable.hasImplicitType = varList.type == null;
1206 _currentHolder.addTopLevelVariable(variable);
1207 variableName.staticElement = element;
1208 }
1209 element.const3 = isConst;
1210 element.final2 = isFinal;
1211 if (hasInitializer) {
1212 ElementHolder holder = new ElementHolder();
1213 _visit(holder, node.initializer);
1214 FunctionElementImpl initializer =
1215 new FunctionElementImpl.forOffset(node.initializer.beginToken.offset);
1216 initializer.hasImplicitReturnType = true;
1217 initializer.functions = holder.functions;
1218 initializer.labels = holder.labels;
1219 initializer.localVariables = holder.localVariables;
1220 initializer.synthetic = true;
1221 initializer.type = new FunctionTypeImpl(initializer);
1222 element.initializer = initializer;
1223 holder.validate();
1224 }
1225 if (element is PropertyInducingElementImpl) {
1226 PropertyAccessorElementImpl_ImplicitGetter getter =
1227 new PropertyAccessorElementImpl_ImplicitGetter(element);
1228 _currentHolder.addAccessor(getter);
1229 if (!isConst && !isFinal) {
1230 PropertyAccessorElementImpl_ImplicitSetter setter =
1231 new PropertyAccessorElementImpl_ImplicitSetter(element);
1232 _currentHolder.addAccessor(setter);
1233 }
1234 }
1235 return null;
1236 }
1237
1238 @override
1239 Object visitVariableDeclarationList(VariableDeclarationList node) {
1240 super.visitVariableDeclarationList(node);
1241 AstNode parent = node.parent;
1242 List<ElementAnnotation> elementAnnotations;
1243 if (parent is FieldDeclaration) {
1244 elementAnnotations = _createElementAnnotations(parent.metadata);
1245 } else if (parent is TopLevelVariableDeclaration) {
1246 elementAnnotations = _createElementAnnotations(parent.metadata);
1247 } else {
1248 // Local variable declaration
1249 elementAnnotations = _createElementAnnotations(node.metadata);
1250 }
1251 for (VariableDeclaration variableDeclaration in node.variables) {
1252 ElementImpl element = variableDeclaration.element as ElementImpl;
1253 _setCodeRange(element, node.parent);
1254 element.metadata = elementAnnotations;
1255 }
1256 return null;
1257 }
1258
1259 /**
1260 * Build the table mapping field names to field elements for the fields define d in the current
1261 * class.
1262 *
1263 * @param fields the field elements defined in the current class
1264 */
1265 void _buildFieldMap(List<FieldElement> fields) {
1266 _fieldMap = new HashMap<String, FieldElement>();
1267 int count = fields.length;
1268 for (int i = 0; i < count; i++) {
1269 FieldElement field = fields[i];
1270 _fieldMap[field.name] ??= field;
1271 }
1272 }
1273
1274 /**
1275 * Creates the [ConstructorElement]s array with the single default constructor element.
1276 *
1277 * @param interfaceType the interface type for which to create a default const ructor
1278 * @return the [ConstructorElement]s array with the single default constructor element
1279 */
1280 List<ConstructorElement> _createDefaultConstructors(
1281 ClassElementImpl definingClass) {
1282 ConstructorElementImpl constructor =
1283 new ConstructorElementImpl.forNode(null);
1284 constructor.synthetic = true;
1285 constructor.enclosingElement = definingClass;
1286 return <ConstructorElement>[constructor];
1287 }
1288
1289 /**
1290 * For each [Annotation] found in [annotations], create a new
1291 * [ElementAnnotation] object and set the [Annotation] to point to it.
1292 */
1293 List<ElementAnnotation> _createElementAnnotations(
1294 NodeList<Annotation> annotations) {
1295 if (annotations.isEmpty) {
1296 return ElementAnnotation.EMPTY_LIST;
1297 }
1298 return annotations.map((Annotation a) {
1299 ElementAnnotationImpl elementAnnotation =
1300 new ElementAnnotationImpl(compilationUnitElement);
1301 a.elementAnnotation = elementAnnotation;
1302 return elementAnnotation;
1303 }).toList();
1304 }
1305
1306 /**
1307 * Create the types associated with the given type parameters, setting the typ e of each type
1308 * parameter, and return an array of types corresponding to the given paramete rs.
1309 *
1310 * @param typeParameters the type parameters for which types are to be created
1311 * @return an array of types corresponding to the given parameters
1312 */
1313 List<DartType> _createTypeParameterTypes(
1314 List<TypeParameterElement> typeParameters) {
1315 int typeParameterCount = typeParameters.length;
1316 List<DartType> typeArguments = new List<DartType>(typeParameterCount);
1317 for (int i = 0; i < typeParameterCount; i++) {
1318 TypeParameterElementImpl typeParameter =
1319 typeParameters[i] as TypeParameterElementImpl;
1320 TypeParameterTypeImpl typeParameterType =
1321 new TypeParameterTypeImpl(typeParameter);
1322 typeParameter.type = typeParameterType;
1323 typeArguments[i] = typeParameterType;
1324 }
1325 return typeArguments;
1326 }
1327
1328 /**
1329 * Return the body of the function that contains the given [parameter], or
1330 * `null` if no function body could be found.
1331 */
1332 FunctionBody _getFunctionBody(FormalParameter parameter) {
1333 AstNode parent = parameter?.parent?.parent;
1334 if (parent is ConstructorDeclaration) {
1335 return parent.body;
1336 } else if (parent is FunctionExpression) {
1337 return parent.body;
1338 } else if (parent is MethodDeclaration) {
1339 return parent.body;
1340 }
1341 return null;
1342 }
1343
1344 void _setCodeRange(ElementImpl element, AstNode node) {
1345 element.setCodeRange(node.offset, node.length);
1346 }
1347
1348 /**
1349 * Sets the visible source range for formal parameter.
1350 */
1351 void _setParameterVisibleRange(
1352 FormalParameter node, ParameterElementImpl element) {
1353 FunctionBody body = _getFunctionBody(node);
1354 if (body is BlockFunctionBody || body is ExpressionFunctionBody) {
1355 element.setVisibleRange(body.offset, body.length);
1356 }
1357 }
1358
1359 void _setVariableVisibleRange(
1360 LocalVariableElementImpl element, VariableDeclaration node) {
1361 AstNode scopeNode;
1362 AstNode parent2 = node.parent.parent;
1363 if (parent2 is ForStatement) {
1364 scopeNode = parent2;
1365 } else {
1366 scopeNode = node.getAncestor((node) => node is Block);
1367 }
1368 element.setVisibleRange(scopeNode.offset, scopeNode.length);
1369 }
1370
1371 /**
1372 * Make the given holder be the current holder while visiting the given node.
1373 *
1374 * @param holder the holder that will gather elements that are built while vis iting the children
1375 * @param node the node to be visited
1376 */
1377 void _visit(ElementHolder holder, AstNode node) {
1378 if (node != null) {
1379 ElementHolder previousHolder = _currentHolder;
1380 _currentHolder = holder;
1381 try {
1382 node.accept(this);
1383 } finally {
1384 _currentHolder = previousHolder;
1385 }
1386 }
1387 }
1388
1389 /**
1390 * Make the given holder be the current holder while visiting the children of the given node.
1391 *
1392 * @param holder the holder that will gather elements that are built while vis iting the children
1393 * @param node the node whose children are to be visited
1394 */
1395 void _visitChildren(ElementHolder holder, AstNode node) {
1396 if (node != null) {
1397 ElementHolder previousHolder = _currentHolder;
1398 _currentHolder = holder;
1399 try {
1400 node.visitChildren(this);
1401 } finally {
1402 _currentHolder = previousHolder;
1403 }
1404 }
1405 }
1406 }
1407
1408 class _ElementBuilder_visitClassDeclaration extends UnifyingAstVisitor<Object> {
1409 final ElementBuilder builder;
1410
1411 List<ClassMember> nonFields;
1412
1413 _ElementBuilder_visitClassDeclaration(this.builder, this.nonFields) : super();
1414
1415 @override
1416 Object visitConstructorDeclaration(ConstructorDeclaration node) {
1417 nonFields.add(node);
1418 return null;
1419 }
1420
1421 @override
1422 Object visitMethodDeclaration(MethodDeclaration node) {
1423 nonFields.add(node);
1424 return null;
1425 }
1426
1427 @override
1428 Object visitNode(AstNode node) => node.accept(builder);
1429 }
1430
1431 /**
1432 * Instances of the class [_NamespaceCombinatorBuilder] can be used to visit
1433 * [Combinator] AST nodes and generate [NamespaceCombinator] elements.
1434 */
1435 class _NamespaceCombinatorBuilder extends SimpleAstVisitor<Object> {
1436 /**
1437 * Elements generated so far.
1438 */
1439 final List<NamespaceCombinator> combinators = <NamespaceCombinator>[];
1440
1441 @override
1442 Object visitHideCombinator(HideCombinator node) {
1443 HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
1444 hide.hiddenNames = _getIdentifiers(node.hiddenNames);
1445 combinators.add(hide);
1446 return null;
1447 }
1448
1449 @override
1450 Object visitShowCombinator(ShowCombinator node) {
1451 ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
1452 show.offset = node.offset;
1453 show.end = node.end;
1454 show.shownNames = _getIdentifiers(node.shownNames);
1455 combinators.add(show);
1456 return null;
1457 }
1458
1459 /**
1460 * Return the lexical identifiers associated with the given [identifiers].
1461 */
1462 static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) {
1463 return identifiers.map((identifier) => identifier.name).toList();
1464 }
1465 }
OLDNEW
« no previous file with comments | « packages/analyzer/lib/src/dart/constant/value.dart ('k') | packages/analyzer/lib/src/dart/element/element.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698