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

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

Issue 2425853003: Begin separating API and local element builders. (Closed)
Patch Set: Don't visit function bodies in ApiElementBuilder. Created 4 years, 2 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
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.dart.element.builder; 5 library analyzer.src.dart.element.builder;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import 'package:analyzer/dart/ast/ast.dart'; 9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/token.dart'; 10 import 'package:analyzer/dart/ast/token.dart';
11 import 'package:analyzer/dart/ast/visitor.dart'; 11 import 'package:analyzer/dart/ast/visitor.dart';
12 import 'package:analyzer/dart/element/element.dart'; 12 import 'package:analyzer/dart/element/element.dart';
13 import 'package:analyzer/dart/element/type.dart'; 13 import 'package:analyzer/dart/element/type.dart';
14 import 'package:analyzer/error/error.dart'; 14 import 'package:analyzer/error/error.dart';
15 import 'package:analyzer/exception/exception.dart'; 15 import 'package:analyzer/exception/exception.dart';
16 import 'package:analyzer/src/dart/element/element.dart'; 16 import 'package:analyzer/src/dart/element/element.dart';
17 import 'package:analyzer/src/dart/element/type.dart'; 17 import 'package:analyzer/src/dart/element/type.dart';
18 import 'package:analyzer/src/error/codes.dart'; 18 import 'package:analyzer/src/error/codes.dart';
19 import 'package:analyzer/src/generated/engine.dart'; 19 import 'package:analyzer/src/generated/engine.dart';
20 import 'package:analyzer/src/generated/resolver.dart'; 20 import 'package:analyzer/src/generated/resolver.dart';
21 import 'package:analyzer/src/generated/sdk.dart'; 21 import 'package:analyzer/src/generated/sdk.dart';
22 import 'package:analyzer/src/generated/source.dart'; 22 import 'package:analyzer/src/generated/source.dart';
23 import 'package:analyzer/src/generated/utilities_dart.dart'; 23 import 'package:analyzer/src/generated/utilities_dart.dart';
24 24
25 /** 25 /**
26 * A `CompilationUnitBuilder` builds an element model for a single compilation 26 * Instances of the class `ApiElementBuilder` traverse an AST structure and
27 * unit. 27 * build elements outside of function bodies and initializers.
28 */ 28 */
29 class CompilationUnitBuilder { 29 class ApiElementBuilder extends _BaseElementBuilder {
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 /** 30 /**
325 * A flag indicating whether a variable declaration is within the body of a me thod or function. 31 * A flag indicating whether a variable declaration is within the body of a me thod or function.
326 */ 32 */
327 bool _inFunction = false; 33 bool _inFunction = false;
328 34
329 /** 35 /**
330 * A table mapping field names to field elements for the fields defined in the current class, or 36 * A table mapping field names to field elements for the fields defined in the current class, or
331 * `null` if we are not in the scope of a class. 37 * `null` if we are not in the scope of a class.
332 */ 38 */
333 HashMap<String, FieldElement> _fieldMap; 39 HashMap<String, FieldElement> _fieldMap;
334 40
335 /** 41 /**
336 * Initialize a newly created element builder to build the elements for a 42 * Initialize a newly created element builder to build the elements for a
337 * compilation unit. The [initialHolder] is the element holder to which the 43 * compilation unit. The [initialHolder] is the element holder to which the
338 * children of the visited compilation unit node will be added. 44 * children of the visited compilation unit node will be added.
339 */ 45 */
340 ElementBuilder(ElementHolder initialHolder, this.compilationUnitElement) { 46 ApiElementBuilder(ElementHolder initialHolder,
341 _currentHolder = initialHolder; 47 CompilationUnitElementImpl compilationUnitElement)
342 } 48 : super(initialHolder, compilationUnitElement);
343 49
344 /** 50 /**
345 * Prepares for incremental resolution of a function body. 51 * Prepares for incremental resolution of a function body.
346 */ 52 */
347 void initForFunctionBodyIncrementalResolution() { 53 void initForFunctionBodyIncrementalResolution() {
348 _inFunction = true; 54 _inFunction = true;
349 } 55 }
350 56
351 @override 57 @override
352 Object visitAnnotation(Annotation node) { 58 Object visitAnnotation(Annotation node) {
353 // Although it isn't valid to do so because closures are not constant 59 // Although it isn't valid to do so because closures are not constant
354 // expressions, it's possible for one of the arguments to the constructor to 60 // expressions, it's possible for one of the arguments to the constructor to
355 // contain a closure. Wrapping the processing of the annotation this way 61 // contain a closure. Wrapping the processing of the annotation this way
356 // prevents these closures from being added to the list of functions in the 62 // prevents these closures from being added to the list of functions in the
357 // annotated declaration. 63 // annotated declaration.
358 ElementHolder holder = new ElementHolder(); 64 ElementHolder holder = new ElementHolder();
359 ElementHolder previousHolder = _currentHolder; 65 ElementHolder previousHolder = _currentHolder;
360 _currentHolder = holder; 66 _currentHolder = holder;
361 try { 67 try {
362 super.visitAnnotation(node); 68 super.visitAnnotation(node);
363 } finally { 69 } finally {
364 _currentHolder = previousHolder; 70 _currentHolder = previousHolder;
365 } 71 }
366 return null; 72 return null;
367 } 73 }
368 74
369 @override 75 @override
370 Object visitCatchClause(CatchClause node) { 76 Object visitBlockFunctionBody(BlockFunctionBody node) {
371 SimpleIdentifier exceptionParameter = node.exceptionParameter; 77 return null;
372 if (exceptionParameter != null) {
373 // exception
374 LocalVariableElementImpl exception =
375 new LocalVariableElementImpl.forNode(exceptionParameter);
376 if (node.exceptionType == null) {
377 exception.hasImplicitType = true;
378 }
379 exception.setVisibleRange(node.offset, node.length);
380 _currentHolder.addLocalVariable(exception);
381 exceptionParameter.staticElement = exception;
382 // stack trace
383 SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
384 if (stackTraceParameter != null) {
385 LocalVariableElementImpl stackTrace =
386 new LocalVariableElementImpl.forNode(stackTraceParameter);
387 _setCodeRange(stackTrace, stackTraceParameter);
388 stackTrace.setVisibleRange(node.offset, node.length);
389 _currentHolder.addLocalVariable(stackTrace);
390 stackTraceParameter.staticElement = stackTrace;
391 }
392 }
393 return super.visitCatchClause(node);
394 } 78 }
395 79
396 @override 80 @override
397 Object visitClassDeclaration(ClassDeclaration node) { 81 Object visitClassDeclaration(ClassDeclaration node) {
398 ElementHolder holder = new ElementHolder(); 82 ElementHolder holder = new ElementHolder();
399 // 83 //
400 // Process field declarations before constructors and methods so that field 84 // Process field declarations before constructors and methods so that field
401 // formal parameters can be correctly resolved to their fields. 85 // formal parameters can be correctly resolved to their fields.
402 // 86 //
403 ElementHolder previousHolder = _currentHolder; 87 ElementHolder previousHolder = _currentHolder;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 } else { 191 } else {
508 constructorName.staticElement = element; 192 constructorName.staticElement = element;
509 element.periodOffset = node.period.offset; 193 element.periodOffset = node.period.offset;
510 element.nameEnd = constructorName.end; 194 element.nameEnd = constructorName.end;
511 } 195 }
512 holder.validate(); 196 holder.validate();
513 return null; 197 return null;
514 } 198 }
515 199
516 @override 200 @override
517 Object visitDeclaredIdentifier(DeclaredIdentifier node) {
518 SimpleIdentifier variableName = node.identifier;
519 LocalVariableElementImpl element =
520 new LocalVariableElementImpl.forNode(variableName);
521 _setCodeRange(element, node);
522 element.metadata = _createElementAnnotations(node.metadata);
523 ForEachStatement statement = node.parent as ForEachStatement;
524 element.setVisibleRange(statement.offset, statement.length);
525 element.const3 = node.isConst;
526 element.final2 = node.isFinal;
527 if (node.type == null) {
528 element.hasImplicitType = true;
529 }
530 _currentHolder.addLocalVariable(element);
531 variableName.staticElement = element;
532 return super.visitDeclaredIdentifier(node);
533 }
534
535 @override
536 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
537 ElementHolder holder = new ElementHolder();
538 NormalFormalParameter normalParameter = node.parameter;
539 SimpleIdentifier parameterName = normalParameter.identifier;
540 ParameterElementImpl parameter;
541 if (normalParameter is FieldFormalParameter) {
542 parameter =
543 new DefaultFieldFormalParameterElementImpl.forNode(parameterName);
544 FieldElement field =
545 _fieldMap == null ? null : _fieldMap[parameterName.name];
546 if (field != null) {
547 (parameter as DefaultFieldFormalParameterElementImpl).field = field;
548 }
549 } else {
550 parameter = new DefaultParameterElementImpl.forNode(parameterName);
551 }
552 _setCodeRange(parameter, node);
553 parameter.const3 = node.isConst;
554 parameter.final2 = node.isFinal;
555 parameter.parameterKind = node.kind;
556 // set initializer, default value range
557 Expression defaultValue = node.defaultValue;
558 if (defaultValue != null) {
559 _visit(holder, defaultValue);
560 FunctionElementImpl initializer =
561 new FunctionElementImpl.forOffset(defaultValue.beginToken.offset);
562 initializer.hasImplicitReturnType = true;
563 initializer.functions = holder.functions;
564 initializer.labels = holder.labels;
565 initializer.localVariables = holder.localVariables;
566 initializer.parameters = holder.parameters;
567 initializer.synthetic = true;
568 initializer.type = new FunctionTypeImpl(initializer);
569 parameter.initializer = initializer;
570 parameter.defaultValueCode = defaultValue.toSource();
571 }
572 // visible range
573 _setParameterVisibleRange(node, parameter);
574 if (normalParameter is SimpleFormalParameter &&
575 normalParameter.type == null) {
576 parameter.hasImplicitType = true;
577 }
578 _currentHolder.addParameter(parameter);
579 parameterName.staticElement = parameter;
580 normalParameter.accept(this);
581 holder.validate();
582 return null;
583 }
584
585 @override
586 Object visitEnumDeclaration(EnumDeclaration node) { 201 Object visitEnumDeclaration(EnumDeclaration node) {
587 SimpleIdentifier enumName = node.name; 202 SimpleIdentifier enumName = node.name;
588 EnumElementImpl enumElement = new EnumElementImpl.forNode(enumName); 203 EnumElementImpl enumElement = new EnumElementImpl.forNode(enumName);
589 _setCodeRange(enumElement, node); 204 _setCodeRange(enumElement, node);
590 enumElement.metadata = _createElementAnnotations(node.metadata); 205 enumElement.metadata = _createElementAnnotations(node.metadata);
591 setElementDocumentationComment(enumElement, node); 206 setElementDocumentationComment(enumElement, node);
592 InterfaceTypeImpl enumType = enumElement.type; 207 InterfaceTypeImpl enumType = enumElement.type;
593 // 208 //
594 // Build the elements for the constants. These are minimal elements; the 209 // Build the elements for the constants. These are minimal elements; the
595 // rest of the constant elements (and elements for other fields) must be 210 // rest of the constant elements (and elements for other fields) must be
(...skipping 22 matching lines...) Expand all
618 233
619 @override 234 @override
620 Object visitExportDirective(ExportDirective node) { 235 Object visitExportDirective(ExportDirective node) {
621 List<ElementAnnotation> annotations = 236 List<ElementAnnotation> annotations =
622 _createElementAnnotations(node.metadata); 237 _createElementAnnotations(node.metadata);
623 compilationUnitElement.setAnnotations(node.offset, annotations); 238 compilationUnitElement.setAnnotations(node.offset, annotations);
624 return super.visitExportDirective(node); 239 return super.visitExportDirective(node);
625 } 240 }
626 241
627 @override 242 @override
243 Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
244 return null;
245 }
246
247 @override
628 Object visitFieldFormalParameter(FieldFormalParameter node) { 248 Object visitFieldFormalParameter(FieldFormalParameter node) {
629 if (node.parent is! DefaultFormalParameter) { 249 if (node.parent is! DefaultFormalParameter) {
630 SimpleIdentifier parameterName = node.identifier; 250 SimpleIdentifier parameterName = node.identifier;
631 FieldElement field = 251 FieldElement field =
632 _fieldMap == null ? null : _fieldMap[parameterName.name]; 252 _fieldMap == null ? null : _fieldMap[parameterName.name];
633 FieldFormalParameterElementImpl parameter = 253 FieldFormalParameterElementImpl parameter =
634 new FieldFormalParameterElementImpl.forNode(parameterName); 254 new FieldFormalParameterElementImpl.forNode(parameterName);
635 _setCodeRange(parameter, node); 255 _setCodeRange(parameter, node);
636 parameter.const3 = node.isConst; 256 parameter.const3 = node.isConst;
637 parameter.final2 = node.isFinal; 257 parameter.final2 = node.isFinal;
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 element.typeParameters = typeParameters; 464 element.typeParameters = typeParameters;
845 _createTypeParameterTypes(typeParameters); 465 _createTypeParameterTypes(typeParameters);
846 element.type = new FunctionTypeImpl.forTypedef(element); 466 element.type = new FunctionTypeImpl.forTypedef(element);
847 _currentHolder.addTypeAlias(element); 467 _currentHolder.addTypeAlias(element);
848 aliasName.staticElement = element; 468 aliasName.staticElement = element;
849 holder.validate(); 469 holder.validate();
850 return null; 470 return null;
851 } 471 }
852 472
853 @override 473 @override
854 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
855 if (node.parent is! DefaultFormalParameter) {
856 SimpleIdentifier parameterName = node.identifier;
857 ParameterElementImpl parameter =
858 new ParameterElementImpl.forNode(parameterName);
859 _setCodeRange(parameter, node);
860 parameter.parameterKind = node.kind;
861 _setParameterVisibleRange(node, parameter);
862 _currentHolder.addParameter(parameter);
863 parameterName.staticElement = parameter;
864 }
865 //
866 // The children of this parameter include any parameters defined on the type
867 //of this parameter.
868 //
869 ElementHolder holder = new ElementHolder();
870 _visitChildren(holder, node);
871 ParameterElementImpl element = node.element;
872 element.metadata = _createElementAnnotations(node.metadata);
873 element.parameters = holder.parameters;
874 element.typeParameters = holder.typeParameters;
875 holder.validate();
876 return null;
877 }
878
879 @override
880 Object visitImportDirective(ImportDirective node) { 474 Object visitImportDirective(ImportDirective node) {
881 List<ElementAnnotation> annotations = 475 List<ElementAnnotation> annotations =
882 _createElementAnnotations(node.metadata); 476 _createElementAnnotations(node.metadata);
883 compilationUnitElement.setAnnotations(node.offset, annotations); 477 compilationUnitElement.setAnnotations(node.offset, annotations);
884 return super.visitImportDirective(node); 478 return super.visitImportDirective(node);
885 } 479 }
886 480
887 @override 481 @override
888 Object visitLabeledStatement(LabeledStatement node) {
889 bool onSwitchStatement = node.statement is SwitchStatement;
890 for (Label label in node.labels) {
891 SimpleIdentifier labelName = label.label;
892 LabelElementImpl element =
893 new LabelElementImpl.forNode(labelName, onSwitchStatement, false);
894 _currentHolder.addLabel(element);
895 labelName.staticElement = element;
896 }
897 return super.visitLabeledStatement(node);
898 }
899
900 @override
901 Object visitLibraryDirective(LibraryDirective node) { 482 Object visitLibraryDirective(LibraryDirective node) {
902 List<ElementAnnotation> annotations = 483 List<ElementAnnotation> annotations =
903 _createElementAnnotations(node.metadata); 484 _createElementAnnotations(node.metadata);
904 compilationUnitElement.setAnnotations(node.offset, annotations); 485 compilationUnitElement.setAnnotations(node.offset, annotations);
905 return super.visitLibraryDirective(node); 486 return super.visitLibraryDirective(node);
906 } 487 }
907 488
908 @override 489 @override
909 Object visitMethodDeclaration(MethodDeclaration node) { 490 Object visitMethodDeclaration(MethodDeclaration node) {
910 try { 491 try {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 645
1065 @override 646 @override
1066 Object visitPartDirective(PartDirective node) { 647 Object visitPartDirective(PartDirective node) {
1067 List<ElementAnnotation> annotations = 648 List<ElementAnnotation> annotations =
1068 _createElementAnnotations(node.metadata); 649 _createElementAnnotations(node.metadata);
1069 compilationUnitElement.setAnnotations(node.offset, annotations); 650 compilationUnitElement.setAnnotations(node.offset, annotations);
1070 return super.visitPartDirective(node); 651 return super.visitPartDirective(node);
1071 } 652 }
1072 653
1073 @override 654 @override
655 Object visitVariableDeclaration(VariableDeclaration node) {
656 bool isConst = node.isConst;
657 bool isFinal = node.isFinal;
658 Expression initializerNode = node.initializer;
659 bool hasInitializer = initializerNode != null;
660 VariableDeclarationList varList = node.parent;
661 FieldDeclaration fieldNode =
662 varList.parent is FieldDeclaration ? varList.parent : null;
663 VariableElementImpl element;
664 if (fieldNode != null) {
665 SimpleIdentifier fieldName = node.name;
666 FieldElementImpl field;
667 if ((isConst || isFinal && !fieldNode.isStatic) && hasInitializer) {
668 field = new ConstFieldElementImpl.forNode(fieldName);
669 } else {
670 field = new FieldElementImpl.forNode(fieldName);
671 }
672 element = field;
673 field.static = fieldNode.isStatic;
674 _setCodeRange(element, node);
675 setElementDocumentationComment(element, fieldNode);
676 field.hasImplicitType = varList.type == null;
677 _currentHolder.addField(field);
678 fieldName.staticElement = field;
679 } else {
680 SimpleIdentifier variableName = node.name;
681 TopLevelVariableElementImpl variable;
682 if (isConst && hasInitializer) {
683 variable = new ConstTopLevelVariableElementImpl.forNode(variableName);
684 } else {
685 variable = new TopLevelVariableElementImpl.forNode(variableName);
686 }
687 element = variable;
688 _setCodeRange(element, node);
689 if (varList.parent is TopLevelVariableDeclaration) {
690 setElementDocumentationComment(element, varList.parent);
691 }
692 variable.hasImplicitType = varList.type == null;
693 _currentHolder.addTopLevelVariable(variable);
694 variableName.staticElement = element;
695 }
696 element.const3 = isConst;
697 element.final2 = isFinal;
698 if (element is PropertyInducingElementImpl) {
699 PropertyAccessorElementImpl_ImplicitGetter getter =
700 new PropertyAccessorElementImpl_ImplicitGetter(element);
701 _currentHolder.addAccessor(getter);
702 if (!isConst && !isFinal) {
703 PropertyAccessorElementImpl_ImplicitSetter setter =
704 new PropertyAccessorElementImpl_ImplicitSetter(element);
705 _currentHolder.addAccessor(setter);
706 }
707 }
708 return null;
709 }
710
711 @override
712 Object visitVariableDeclarationList(VariableDeclarationList node) {
713 super.visitVariableDeclarationList(node);
714 AstNode parent = node.parent;
715 List<ElementAnnotation> elementAnnotations;
716 if (parent is FieldDeclaration) {
717 elementAnnotations = _createElementAnnotations(parent.metadata);
718 } else if (parent is TopLevelVariableDeclaration) {
719 elementAnnotations = _createElementAnnotations(parent.metadata);
720 } else {
721 // Local variable declaration
722 elementAnnotations = _createElementAnnotations(node.metadata);
723 }
724 _setVariableDeclarationListAnnotations(node, elementAnnotations);
725 return null;
726 }
727
728 /**
729 * Build the table mapping field names to field elements for the fields define d in the current
730 * class.
731 *
732 * @param fields the field elements defined in the current class
733 */
734 void _buildFieldMap(List<FieldElement> fields) {
735 _fieldMap = new HashMap<String, FieldElement>();
736 int count = fields.length;
737 for (int i = 0; i < count; i++) {
738 FieldElement field = fields[i];
739 _fieldMap[field.name] ??= field;
740 }
741 }
742
743 /**
744 * Creates the [ConstructorElement]s array with the single default constructor element.
745 *
746 * @param interfaceType the interface type for which to create a default const ructor
747 * @return the [ConstructorElement]s array with the single default constructor element
748 */
749 List<ConstructorElement> _createDefaultConstructors(
750 ClassElementImpl definingClass) {
751 ConstructorElementImpl constructor =
752 new ConstructorElementImpl.forNode(null);
753 constructor.synthetic = true;
754 constructor.enclosingElement = definingClass;
755 return <ConstructorElement>[constructor];
756 }
757
758 /**
759 * Create the types associated with the given type parameters, setting the typ e of each type
760 * parameter, and return an array of types corresponding to the given paramete rs.
761 *
762 * @param typeParameters the type parameters for which types are to be created
763 * @return an array of types corresponding to the given parameters
764 */
765 List<DartType> _createTypeParameterTypes(
766 List<TypeParameterElement> typeParameters) {
767 int typeParameterCount = typeParameters.length;
768 List<DartType> typeArguments = new List<DartType>(typeParameterCount);
769 for (int i = 0; i < typeParameterCount; i++) {
770 TypeParameterElementImpl typeParameter =
771 typeParameters[i] as TypeParameterElementImpl;
772 TypeParameterTypeImpl typeParameterType =
773 new TypeParameterTypeImpl(typeParameter);
774 typeParameter.type = typeParameterType;
775 typeArguments[i] = typeParameterType;
776 }
777 return typeArguments;
778 }
779
780 @override
781 void _setFieldParameterField(FieldFormalParameterElementImpl parameter) {
782 FieldElement field = _fieldMap == null ? null : _fieldMap[parameter.name];
783 if (field != null) {
784 parameter.field = field;
785 }
786 }
787 }
788
789 /**
790 * A `CompilationUnitBuilder` builds an element model for a single compilation
791 * unit.
792 */
793 class CompilationUnitBuilder {
794 /**
795 * Build the compilation unit element for the given [source] based on the
796 * compilation [unit] associated with the source. Throw an AnalysisException
797 * if the element could not be built. [librarySource] is the source for the
798 * containing library.
799 */
800 CompilationUnitElementImpl buildCompilationUnit(
801 Source source, CompilationUnit unit, Source librarySource) {
802 return PerformanceStatistics.resolve.makeCurrentWhile(() {
803 if (unit == null) {
804 return null;
805 }
806 ElementHolder holder = new ElementHolder();
807 CompilationUnitElementImpl element =
808 new CompilationUnitElementImpl(source.shortName);
809 ElementBuilder builder = new ElementBuilder(holder, element);
810 unit.accept(builder);
811 element.accessors = holder.accessors;
812 element.enums = holder.enums;
813 element.functions = holder.functions;
814 element.source = source;
815 element.librarySource = librarySource;
816 element.typeAliases = holder.typeAliases;
817 element.types = holder.types;
818 element.topLevelVariables = holder.topLevelVariables;
819 unit.element = element;
820 holder.validate();
821 return element;
822 });
823 }
824 }
825
826 /**
827 * Instances of the class `DirectiveElementBuilder` build elements for top
828 * level library directives.
829 */
830 class DirectiveElementBuilder extends SimpleAstVisitor<Object> {
831 /**
832 * The analysis context within which directive elements are being built.
833 */
834 final AnalysisContext context;
835
836 /**
837 * The library element for which directive elements are being built.
838 */
839 final LibraryElementImpl libraryElement;
840
841 /**
842 * Map from sources referenced by this library to their modification times.
843 */
844 final Map<Source, int> sourceModificationTimeMap;
845
846 /**
847 * Map from sources imported by this library to their corresponding library
848 * elements.
849 */
850 final Map<Source, LibraryElement> importLibraryMap;
851
852 /**
853 * Map from sources imported by this library to their corresponding source
854 * kinds.
855 */
856 final Map<Source, SourceKind> importSourceKindMap;
857
858 /**
859 * Map from sources exported by this library to their corresponding library
860 * elements.
861 */
862 final Map<Source, LibraryElement> exportLibraryMap;
863
864 /**
865 * Map from sources exported by this library to their corresponding source
866 * kinds.
867 */
868 final Map<Source, SourceKind> exportSourceKindMap;
869
870 /**
871 * The [ImportElement]s created so far.
872 */
873 final List<ImportElement> imports = <ImportElement>[];
874
875 /**
876 * The [ExportElement]s created so far.
877 */
878 final List<ExportElement> exports = <ExportElement>[];
879
880 /**
881 * The errors found while building directive elements.
882 */
883 final List<AnalysisError> errors = <AnalysisError>[];
884
885 /**
886 * Map from prefix names to their corresponding elements.
887 */
888 final HashMap<String, PrefixElementImpl> nameToPrefixMap =
889 new HashMap<String, PrefixElementImpl>();
890
891 /**
892 * Indicates whether an explicit import of `dart:core` has been found.
893 */
894 bool explicitlyImportsCore = false;
895
896 DirectiveElementBuilder(
897 this.context,
898 this.libraryElement,
899 this.sourceModificationTimeMap,
900 this.importLibraryMap,
901 this.importSourceKindMap,
902 this.exportLibraryMap,
903 this.exportSourceKindMap);
904
905 @override
906 Object visitCompilationUnit(CompilationUnit node) {
907 //
908 // Resolve directives.
909 //
910 for (Directive directive in node.directives) {
911 directive.accept(this);
912 }
913 //
914 // Ensure "dart:core" import.
915 //
916 Source librarySource = libraryElement.source;
917 Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE);
918 if (!explicitlyImportsCore && coreLibrarySource != librarySource) {
919 ImportElementImpl importElement = new ImportElementImpl(-1);
920 importElement.importedLibrary = importLibraryMap[coreLibrarySource];
921 importElement.synthetic = true;
922 imports.add(importElement);
923 }
924 //
925 // Populate the library element.
926 //
927 libraryElement.imports = imports;
928 libraryElement.exports = exports;
929 return null;
930 }
931
932 @override
933 Object visitExportDirective(ExportDirective node) {
934 // Remove previous element. (It will remain null if the target is missing.)
935 node.element = null;
936 Source exportedSource = node.selectedSource;
937 int exportedTime = sourceModificationTimeMap[exportedSource] ?? -1;
938 // The exported source will be null if the URI in the export
939 // directive was invalid.
940 LibraryElement exportedLibrary = exportLibraryMap[exportedSource];
941 if (exportedLibrary != null) {
942 ExportElementImpl exportElement = new ExportElementImpl(node.offset);
943 exportElement.metadata = _getElementAnnotations(node.metadata);
944 StringLiteral uriLiteral = node.uri;
945 if (uriLiteral != null) {
946 exportElement.uriOffset = uriLiteral.offset;
947 exportElement.uriEnd = uriLiteral.end;
948 }
949 exportElement.uri = node.selectedUriContent;
950 exportElement.combinators = _buildCombinators(node);
951 exportElement.exportedLibrary = exportedLibrary;
952 setElementDocumentationComment(exportElement, node);
953 node.element = exportElement;
954 exports.add(exportElement);
955 if (exportedTime >= 0 &&
956 exportSourceKindMap[exportedSource] != SourceKind.LIBRARY) {
957 int offset = node.offset;
958 int length = node.length;
959 if (uriLiteral != null) {
960 offset = uriLiteral.offset;
961 length = uriLiteral.length;
962 }
963 errors.add(new AnalysisError(
964 libraryElement.source,
965 offset,
966 length,
967 CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
968 [uriLiteral.toSource()]));
969 }
970 }
971 return null;
972 }
973
974 @override
975 Object visitImportDirective(ImportDirective node) {
976 // Remove previous element. (It will remain null if the target is missing.)
977 node.element = null;
978 Source importedSource = node.selectedSource;
979 int importedTime = sourceModificationTimeMap[importedSource] ?? -1;
980 // The imported source will be null if the URI in the import
981 // directive was invalid.
982 LibraryElement importedLibrary = importLibraryMap[importedSource];
983 if (importedLibrary != null) {
984 if (importedLibrary.isDartCore) {
985 explicitlyImportsCore = true;
986 }
987 ImportElementImpl importElement = new ImportElementImpl(node.offset);
988 importElement.metadata = _getElementAnnotations(node.metadata);
989 StringLiteral uriLiteral = node.uri;
990 if (uriLiteral != null) {
991 importElement.uriOffset = uriLiteral.offset;
992 importElement.uriEnd = uriLiteral.end;
993 }
994 importElement.uri = node.selectedUriContent;
995 importElement.deferred = node.deferredKeyword != null;
996 importElement.combinators = _buildCombinators(node);
997 importElement.importedLibrary = importedLibrary;
998 setElementDocumentationComment(importElement, node);
999 SimpleIdentifier prefixNode = node.prefix;
1000 if (prefixNode != null) {
1001 importElement.prefixOffset = prefixNode.offset;
1002 String prefixName = prefixNode.name;
1003 PrefixElementImpl prefix = nameToPrefixMap[prefixName];
1004 if (prefix == null) {
1005 prefix = new PrefixElementImpl.forNode(prefixNode);
1006 nameToPrefixMap[prefixName] = prefix;
1007 }
1008 importElement.prefix = prefix;
1009 prefixNode.staticElement = prefix;
1010 }
1011 node.element = importElement;
1012 imports.add(importElement);
1013 if (importedTime >= 0 &&
1014 importSourceKindMap[importedSource] != SourceKind.LIBRARY) {
1015 int offset = node.offset;
1016 int length = node.length;
1017 if (uriLiteral != null) {
1018 offset = uriLiteral.offset;
1019 length = uriLiteral.length;
1020 }
1021 ErrorCode errorCode = importElement.isDeferred
1022 ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
1023 : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY;
1024 errors.add(new AnalysisError(libraryElement.source, offset, length,
1025 errorCode, [uriLiteral.toSource()]));
1026 }
1027 }
1028 return null;
1029 }
1030
1031 @override
1032 Object visitLibraryDirective(LibraryDirective node) {
1033 (node.element as LibraryElementImpl)?.metadata =
1034 _getElementAnnotations(node.metadata);
1035 return null;
1036 }
1037
1038 @override
1039 Object visitPartDirective(PartDirective node) {
1040 (node.element as CompilationUnitElementImpl)?.metadata =
1041 _getElementAnnotations(node.metadata);
1042 return null;
1043 }
1044
1045 /**
1046 * Gather a list of the [ElementAnnotation]s referred to by the [Annotation]s
1047 * in [metadata].
1048 */
1049 List<ElementAnnotation> _getElementAnnotations(
1050 NodeList<Annotation> metadata) {
1051 if (metadata.isEmpty) {
1052 return ElementAnnotation.EMPTY_LIST;
1053 }
1054 return metadata.map((Annotation a) => a.elementAnnotation).toList();
1055 }
1056
1057 /**
1058 * Build the element model representing the combinators declared by
1059 * the given [directive].
1060 */
1061 static List<NamespaceCombinator> _buildCombinators(
1062 NamespaceDirective directive) {
1063 _NamespaceCombinatorBuilder namespaceCombinatorBuilder =
1064 new _NamespaceCombinatorBuilder();
1065 for (Combinator combinator in directive.combinators) {
1066 combinator.accept(namespaceCombinatorBuilder);
1067 }
1068 return namespaceCombinatorBuilder.combinators;
1069 }
1070 }
1071
1072 /**
1073 * Instances of the class `ElementBuilder` traverse an AST structure and build t he element
1074 * model representing the AST structure.
1075 */
1076 class ElementBuilder extends ApiElementBuilder {
1077 /**
1078 * Initialize a newly created element builder to build the elements for a
1079 * compilation unit. The [initialHolder] is the element holder to which the
1080 * children of the visited compilation unit node will be added.
1081 */
1082 ElementBuilder(ElementHolder initialHolder,
1083 CompilationUnitElement compilationUnitElement)
1084 : super(initialHolder, compilationUnitElement);
1085
1086 @override
1087 Object visitBlockFunctionBody(BlockFunctionBody node) {
1088 _buildLocal(node);
1089 return null;
1090 }
1091
1092 @override
1093 Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
1094 _buildLocal(node);
1095 return null;
1096 }
1097
1098 @override
1099 Object visitVariableDeclaration(VariableDeclaration node) {
1100 super.visitVariableDeclaration(node);
1101 VariableElementImpl element = node.element as VariableElementImpl;
1102 _buildVariableInitializer(element, node.initializer);
1103 return null;
1104 }
1105
1106 void _buildLocal(AstNode node) {
1107 node.accept(
1108 new LocalElementBuilder(_currentHolder, compilationUnitElement));
1109 }
1110 }
1111
1112 /**
1113 * Traverse a [FunctionBody] and build elements for AST structures.
1114 */
1115 class LocalElementBuilder extends _BaseElementBuilder {
1116 /**
1117 * Initialize a newly created element builder to build the elements for a
1118 * compilation unit. The [initialHolder] is the element holder to which the
1119 * children of the visited compilation unit node will be added.
1120 */
1121 LocalElementBuilder(ElementHolder initialHolder,
1122 CompilationUnitElementImpl compilationUnitElement)
1123 : super(initialHolder, compilationUnitElement);
1124
1125 @override
1126 Object visitCatchClause(CatchClause node) {
1127 SimpleIdentifier exceptionParameter = node.exceptionParameter;
1128 if (exceptionParameter != null) {
1129 // exception
1130 LocalVariableElementImpl exception =
1131 new LocalVariableElementImpl.forNode(exceptionParameter);
1132 if (node.exceptionType == null) {
1133 exception.hasImplicitType = true;
1134 }
1135 exception.setVisibleRange(node.offset, node.length);
1136 _currentHolder.addLocalVariable(exception);
1137 exceptionParameter.staticElement = exception;
1138 // stack trace
1139 SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
1140 if (stackTraceParameter != null) {
1141 LocalVariableElementImpl stackTrace =
1142 new LocalVariableElementImpl.forNode(stackTraceParameter);
1143 _setCodeRange(stackTrace, stackTraceParameter);
1144 stackTrace.setVisibleRange(node.offset, node.length);
1145 _currentHolder.addLocalVariable(stackTrace);
1146 stackTraceParameter.staticElement = stackTrace;
1147 }
1148 }
1149 return super.visitCatchClause(node);
1150 }
1151
1152 @override
1153 Object visitDeclaredIdentifier(DeclaredIdentifier node) {
1154 SimpleIdentifier variableName = node.identifier;
1155 LocalVariableElementImpl element =
1156 new LocalVariableElementImpl.forNode(variableName);
1157 _setCodeRange(element, node);
1158 element.metadata = _createElementAnnotations(node.metadata);
1159 ForEachStatement statement = node.parent as ForEachStatement;
1160 element.setVisibleRange(statement.offset, statement.length);
1161 element.const3 = node.isConst;
1162 element.final2 = node.isFinal;
1163 if (node.type == null) {
1164 element.hasImplicitType = true;
1165 }
1166 _currentHolder.addLocalVariable(element);
1167 variableName.staticElement = element;
1168 return null;
1169 }
1170
1171 @override
1172 Object visitFunctionDeclaration(FunctionDeclaration node) {
1173 FunctionExpression expression = node.functionExpression;
1174 if (expression == null) {
1175 return null;
1176 }
1177
1178 ElementHolder holder = new ElementHolder();
1179 _visitChildren(holder, node);
1180
1181 FunctionElementImpl element = new FunctionElementImpl.forNode(node.name);
1182 _setCodeRange(element, node);
1183 setElementDocumentationComment(element, node);
1184 element.metadata = _createElementAnnotations(node.metadata);
1185 if (node.externalKeyword != null) {
1186 element.external = true;
1187 }
1188 element.functions = holder.functions;
1189 element.labels = holder.labels;
1190 element.localVariables = holder.localVariables;
1191 element.parameters = holder.parameters;
1192 element.typeParameters = holder.typeParameters;
1193
1194 FunctionBody body = expression.body;
1195 if (body.isAsynchronous) {
1196 element.asynchronous = body.isAsynchronous;
1197 }
1198 if (body.isGenerator) {
1199 element.generator = true;
1200 }
1201
1202 {
1203 Block enclosingBlock = node.getAncestor((node) => node is Block);
1204 if (enclosingBlock != null) {
1205 element.setVisibleRange(enclosingBlock.offset, enclosingBlock.length);
1206 }
1207 }
1208
1209 if (node.returnType == null) {
1210 element.hasImplicitReturnType = true;
1211 }
1212
1213 _currentHolder.addFunction(element);
1214 expression.element = element;
1215 node.name.staticElement = element;
1216 holder.validate();
1217 return null;
1218 }
1219
1220 @override
1221 Object visitFunctionExpression(FunctionExpression node) {
1222 if (node.parent is FunctionDeclaration) {
1223 // visitFunctionDeclaration has already created the element for the
1224 // declaration. We just need to visit children.
1225 return super.visitFunctionExpression(node);
1226 }
1227
1228 ElementHolder holder = new ElementHolder();
1229 _visitChildren(holder, node);
1230 FunctionElementImpl element =
1231 new FunctionElementImpl.forOffset(node.beginToken.offset);
1232 _setCodeRange(element, node);
1233 element.functions = holder.functions;
1234 element.labels = holder.labels;
1235 element.localVariables = holder.localVariables;
1236 element.parameters = holder.parameters;
1237 element.typeParameters = holder.typeParameters;
1238
1239 FunctionBody body = node.body;
1240 if (body.isAsynchronous) {
1241 element.asynchronous = true;
1242 }
1243 if (body.isGenerator) {
1244 element.generator = true;
1245 }
1246
1247 {
1248 Block enclosingBlock = node.getAncestor((node) => node is Block);
1249 if (enclosingBlock != null) {
1250 element.setVisibleRange(enclosingBlock.offset, enclosingBlock.length);
1251 }
1252 }
1253
1254 element.type = new FunctionTypeImpl(element);
1255 element.hasImplicitReturnType = true;
1256 _currentHolder.addFunction(element);
1257 node.element = element;
1258 holder.validate();
1259 return null;
1260 }
1261
1262 @override
1263 Object visitLabeledStatement(LabeledStatement node) {
1264 bool onSwitchStatement = node.statement is SwitchStatement;
1265 for (Label label in node.labels) {
1266 SimpleIdentifier labelName = label.label;
1267 LabelElementImpl element =
1268 new LabelElementImpl.forNode(labelName, onSwitchStatement, false);
1269 _currentHolder.addLabel(element);
1270 labelName.staticElement = element;
1271 }
1272 return super.visitLabeledStatement(node);
1273 }
1274
1275 @override
1276 Object visitSwitchCase(SwitchCase node) {
1277 for (Label label in node.labels) {
1278 SimpleIdentifier labelName = label.label;
1279 LabelElementImpl element =
1280 new LabelElementImpl.forNode(labelName, false, true);
1281 _currentHolder.addLabel(element);
1282 labelName.staticElement = element;
1283 }
1284 return super.visitSwitchCase(node);
1285 }
1286
1287 @override
1288 Object visitSwitchDefault(SwitchDefault node) {
1289 for (Label label in node.labels) {
1290 SimpleIdentifier labelName = label.label;
1291 LabelElementImpl element =
1292 new LabelElementImpl.forNode(labelName, false, true);
1293 _currentHolder.addLabel(element);
1294 labelName.staticElement = element;
1295 }
1296 return super.visitSwitchDefault(node);
1297 }
1298
1299 @override
1300 Object visitVariableDeclaration(VariableDeclaration node) {
1301 bool isConst = node.isConst;
1302 bool isFinal = node.isFinal;
1303 Expression initializerNode = node.initializer;
1304 VariableDeclarationList varList = node.parent;
1305 SimpleIdentifier variableName = node.name;
1306 LocalVariableElementImpl element;
1307 if (isConst && initializerNode != null) {
1308 element = new ConstLocalVariableElementImpl.forNode(variableName);
1309 } else {
1310 element = new LocalVariableElementImpl.forNode(variableName);
1311 }
1312 _setCodeRange(element, node);
1313 _setVariableVisibleRange(element, node);
1314 element.hasImplicitType = varList.type == null;
1315 _currentHolder.addLocalVariable(element);
1316 variableName.staticElement = element;
1317 element.const3 = isConst;
1318 element.final2 = isFinal;
1319 _buildVariableInitializer(element, initializerNode);
1320 return null;
1321 }
1322
1323 @override
1324 Object visitVariableDeclarationList(VariableDeclarationList node) {
1325 super.visitVariableDeclarationList(node);
1326 List<ElementAnnotation> elementAnnotations =
1327 _createElementAnnotations(node.metadata);
1328 _setVariableDeclarationListAnnotations(node, elementAnnotations);
1329 return null;
1330 }
1331
1332 void _setVariableVisibleRange(
1333 LocalVariableElementImpl element, VariableDeclaration node) {
1334 AstNode scopeNode;
1335 AstNode parent2 = node.parent.parent;
1336 if (parent2 is ForStatement) {
1337 scopeNode = parent2;
1338 } else {
1339 scopeNode = node.getAncestor((node) => node is Block);
1340 }
1341 element.setVisibleRange(scopeNode.offset, scopeNode.length);
1342 }
1343 }
1344
1345 /**
1346 * Base class for API and local element builders.
1347 */
1348 abstract class _BaseElementBuilder extends RecursiveAstVisitor<Object> {
1349 /**
1350 * The compilation unit element into which the elements being built will be
1351 * stored.
1352 */
1353 final CompilationUnitElementImpl compilationUnitElement;
1354
1355 /**
1356 * The element holder associated with the element that is currently being buil t.
1357 */
1358 ElementHolder _currentHolder;
1359
1360 _BaseElementBuilder(this._currentHolder, this.compilationUnitElement);
1361
1362 @override
1363 Object visitDefaultFormalParameter(DefaultFormalParameter node) {
1364 ElementHolder holder = new ElementHolder();
1365 NormalFormalParameter normalParameter = node.parameter;
1366 SimpleIdentifier parameterName = normalParameter.identifier;
1367 ParameterElementImpl parameter;
1368 if (normalParameter is FieldFormalParameter) {
1369 DefaultFieldFormalParameterElementImpl fieldParameter =
1370 new DefaultFieldFormalParameterElementImpl.forNode(parameterName);
1371 _setFieldParameterField(fieldParameter);
1372 parameter = fieldParameter;
1373 } else {
1374 parameter = new DefaultParameterElementImpl.forNode(parameterName);
1375 }
1376 _setCodeRange(parameter, node);
1377 parameter.const3 = node.isConst;
1378 parameter.final2 = node.isFinal;
1379 parameter.parameterKind = node.kind;
1380 // set initializer, default value range
1381 Expression defaultValue = node.defaultValue;
1382 if (defaultValue != null) {
1383 _visit(holder, defaultValue);
1384 FunctionElementImpl initializer =
1385 new FunctionElementImpl.forOffset(defaultValue.beginToken.offset);
1386 initializer.hasImplicitReturnType = true;
1387 initializer.functions = holder.functions;
1388 initializer.labels = holder.labels;
1389 initializer.localVariables = holder.localVariables;
1390 initializer.parameters = holder.parameters;
1391 initializer.synthetic = true;
1392 initializer.type = new FunctionTypeImpl(initializer);
1393 parameter.initializer = initializer;
1394 parameter.defaultValueCode = defaultValue.toSource();
1395 }
1396 // visible range
1397 _setParameterVisibleRange(node, parameter);
1398 if (normalParameter is SimpleFormalParameter &&
1399 normalParameter.type == null) {
1400 parameter.hasImplicitType = true;
1401 }
1402 _currentHolder.addParameter(parameter);
1403 parameterName.staticElement = parameter;
1404 normalParameter.accept(this);
1405 holder.validate();
1406 return null;
1407 }
1408
1409 @override
1410 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
1411 if (node.parent is! DefaultFormalParameter) {
1412 SimpleIdentifier parameterName = node.identifier;
1413 ParameterElementImpl parameter =
1414 new ParameterElementImpl.forNode(parameterName);
1415 _setCodeRange(parameter, node);
1416 parameter.parameterKind = node.kind;
1417 _setParameterVisibleRange(node, parameter);
1418 _currentHolder.addParameter(parameter);
1419 parameterName.staticElement = parameter;
1420 }
1421 //
1422 // The children of this parameter include any parameters defined on the type
1423 //of this parameter.
1424 //
1425 ElementHolder holder = new ElementHolder();
1426 _visitChildren(holder, node);
1427 ParameterElementImpl element = node.element;
1428 element.metadata = _createElementAnnotations(node.metadata);
1429 element.parameters = holder.parameters;
1430 element.typeParameters = holder.typeParameters;
1431 holder.validate();
1432 return null;
1433 }
1434
1435 @override
1074 Object visitSimpleFormalParameter(SimpleFormalParameter node) { 1436 Object visitSimpleFormalParameter(SimpleFormalParameter node) {
1075 if (node.parent is! DefaultFormalParameter) { 1437 if (node.parent is! DefaultFormalParameter) {
1076 SimpleIdentifier parameterName = node.identifier; 1438 SimpleIdentifier parameterName = node.identifier;
1077 ParameterElementImpl parameter = 1439 ParameterElementImpl parameter =
1078 new ParameterElementImpl.forNode(parameterName); 1440 new ParameterElementImpl.forNode(parameterName);
1079 _setCodeRange(parameter, node); 1441 _setCodeRange(parameter, node);
1080 parameter.const3 = node.isConst; 1442 parameter.const3 = node.isConst;
1081 parameter.final2 = node.isFinal; 1443 parameter.final2 = node.isFinal;
1082 parameter.parameterKind = node.kind; 1444 parameter.parameterKind = node.kind;
1083 _setParameterVisibleRange(node, parameter); 1445 _setParameterVisibleRange(node, parameter);
1084 if (node.type == null) { 1446 if (node.type == null) {
1085 parameter.hasImplicitType = true; 1447 parameter.hasImplicitType = true;
1086 } 1448 }
1087 _currentHolder.addParameter(parameter); 1449 _currentHolder.addParameter(parameter);
1088 parameterName.staticElement = parameter; 1450 parameterName.staticElement = parameter;
1089 } 1451 }
1090 super.visitSimpleFormalParameter(node); 1452 super.visitSimpleFormalParameter(node);
1091 (node.element as ElementImpl).metadata = 1453 (node.element as ElementImpl).metadata =
1092 _createElementAnnotations(node.metadata); 1454 _createElementAnnotations(node.metadata);
1093 return null; 1455 return null;
1094 } 1456 }
1095 1457
1096 @override 1458 @override
1097 Object visitSwitchCase(SwitchCase node) {
1098 for (Label label in node.labels) {
1099 SimpleIdentifier labelName = label.label;
1100 LabelElementImpl element =
1101 new LabelElementImpl.forNode(labelName, false, true);
1102 _currentHolder.addLabel(element);
1103 labelName.staticElement = element;
1104 }
1105 return super.visitSwitchCase(node);
1106 }
1107
1108 @override
1109 Object visitSwitchDefault(SwitchDefault node) {
1110 for (Label label in node.labels) {
1111 SimpleIdentifier labelName = label.label;
1112 LabelElementImpl element =
1113 new LabelElementImpl.forNode(labelName, false, true);
1114 _currentHolder.addLabel(element);
1115 labelName.staticElement = element;
1116 }
1117 return super.visitSwitchDefault(node);
1118 }
1119
1120 @override
1121 Object visitTypeParameter(TypeParameter node) { 1459 Object visitTypeParameter(TypeParameter node) {
1122 SimpleIdentifier parameterName = node.name; 1460 SimpleIdentifier parameterName = node.name;
1123 TypeParameterElementImpl typeParameter = 1461 TypeParameterElementImpl typeParameter =
1124 new TypeParameterElementImpl.forNode(parameterName); 1462 new TypeParameterElementImpl.forNode(parameterName);
1125 _setCodeRange(typeParameter, node); 1463 _setCodeRange(typeParameter, node);
1126 typeParameter.metadata = _createElementAnnotations(node.metadata); 1464 typeParameter.metadata = _createElementAnnotations(node.metadata);
1127 TypeParameterTypeImpl typeParameterType = 1465 TypeParameterTypeImpl typeParameterType =
1128 new TypeParameterTypeImpl(typeParameter); 1466 new TypeParameterTypeImpl(typeParameter);
1129 typeParameter.type = typeParameterType; 1467 typeParameter.type = typeParameterType;
1130 _currentHolder.addTypeParameter(typeParameter); 1468 _currentHolder.addTypeParameter(typeParameter);
1131 parameterName.staticElement = typeParameter; 1469 parameterName.staticElement = typeParameter;
1132 return super.visitTypeParameter(node); 1470 return super.visitTypeParameter(node);
1133 } 1471 }
1134 1472
1135 @override 1473 void _buildVariableInitializer(VariableElementImpl element, Expression node) {
1136 Object visitVariableDeclaration(VariableDeclaration node) { 1474 if (node != null) {
1137 bool isConst = node.isConst;
1138 bool isFinal = node.isFinal;
1139 bool hasInitializer = node.initializer != null;
1140 VariableDeclarationList varList = node.parent;
1141 FieldDeclaration fieldNode =
1142 varList.parent is FieldDeclaration ? varList.parent : null;
1143 VariableElementImpl element;
1144 if (fieldNode != null) {
1145 SimpleIdentifier fieldName = node.name;
1146 FieldElementImpl field;
1147 if ((isConst || isFinal && !fieldNode.isStatic) && hasInitializer) {
1148 field = new ConstFieldElementImpl.forNode(fieldName);
1149 } else {
1150 field = new FieldElementImpl.forNode(fieldName);
1151 }
1152 element = field;
1153 field.static = fieldNode.isStatic;
1154 _setCodeRange(element, node);
1155 setElementDocumentationComment(element, fieldNode);
1156 field.hasImplicitType = varList.type == null;
1157 _currentHolder.addField(field);
1158 fieldName.staticElement = field;
1159 } else if (_inFunction) {
1160 SimpleIdentifier variableName = node.name;
1161 LocalVariableElementImpl variable;
1162 if (isConst && hasInitializer) {
1163 variable = new ConstLocalVariableElementImpl.forNode(variableName);
1164 } else {
1165 variable = new LocalVariableElementImpl.forNode(variableName);
1166 }
1167 element = variable;
1168 _setCodeRange(element, node);
1169 _setVariableVisibleRange(variable, node);
1170 variable.hasImplicitType = varList.type == null;
1171 _currentHolder.addLocalVariable(variable);
1172 variableName.staticElement = element;
1173 } else {
1174 SimpleIdentifier variableName = node.name;
1175 TopLevelVariableElementImpl variable;
1176 if (isConst && hasInitializer) {
1177 variable = new ConstTopLevelVariableElementImpl.forNode(variableName);
1178 } else {
1179 variable = new TopLevelVariableElementImpl.forNode(variableName);
1180 }
1181 element = variable;
1182 _setCodeRange(element, node);
1183 if (varList.parent is TopLevelVariableDeclaration) {
1184 setElementDocumentationComment(element, varList.parent);
1185 }
1186 variable.hasImplicitType = varList.type == null;
1187 _currentHolder.addTopLevelVariable(variable);
1188 variableName.staticElement = element;
1189 }
1190 element.const3 = isConst;
1191 element.final2 = isFinal;
1192 if (hasInitializer) {
1193 ElementHolder holder = new ElementHolder(); 1475 ElementHolder holder = new ElementHolder();
1194 _visit(holder, node.initializer); 1476 _visit(holder, node);
1195 FunctionElementImpl initializer = 1477 FunctionElementImpl initializer =
1196 new FunctionElementImpl.forOffset(node.initializer.beginToken.offset); 1478 new FunctionElementImpl.forOffset(node.beginToken.offset);
1197 initializer.hasImplicitReturnType = true; 1479 initializer.hasImplicitReturnType = true;
1198 initializer.functions = holder.functions; 1480 initializer.functions = holder.functions;
1199 initializer.labels = holder.labels; 1481 initializer.labels = holder.labels;
1200 initializer.localVariables = holder.localVariables; 1482 initializer.localVariables = holder.localVariables;
1201 initializer.synthetic = true; 1483 initializer.synthetic = true;
1202 initializer.type = new FunctionTypeImpl(initializer); 1484 initializer.type = new FunctionTypeImpl(initializer);
1203 element.initializer = initializer; 1485 element.initializer = initializer;
1204 holder.validate(); 1486 holder.validate();
1205 } 1487 }
1206 if (element is PropertyInducingElementImpl) {
1207 PropertyAccessorElementImpl_ImplicitGetter getter =
1208 new PropertyAccessorElementImpl_ImplicitGetter(element);
1209 _currentHolder.addAccessor(getter);
1210 if (!isConst && !isFinal) {
1211 PropertyAccessorElementImpl_ImplicitSetter setter =
1212 new PropertyAccessorElementImpl_ImplicitSetter(element);
1213 _currentHolder.addAccessor(setter);
1214 }
1215 }
1216 return null;
1217 }
1218
1219 @override
1220 Object visitVariableDeclarationList(VariableDeclarationList node) {
1221 super.visitVariableDeclarationList(node);
1222 AstNode parent = node.parent;
1223 List<ElementAnnotation> elementAnnotations;
1224 if (parent is FieldDeclaration) {
1225 elementAnnotations = _createElementAnnotations(parent.metadata);
1226 } else if (parent is TopLevelVariableDeclaration) {
1227 elementAnnotations = _createElementAnnotations(parent.metadata);
1228 } else {
1229 // Local variable declaration
1230 elementAnnotations = _createElementAnnotations(node.metadata);
1231 }
1232 for (VariableDeclaration variableDeclaration in node.variables) {
1233 ElementImpl element = variableDeclaration.element as ElementImpl;
1234 _setCodeRange(element, node.parent);
1235 element.metadata = elementAnnotations;
1236 }
1237 return null;
1238 }
1239
1240 /**
1241 * Build the table mapping field names to field elements for the fields define d in the current
1242 * class.
1243 *
1244 * @param fields the field elements defined in the current class
1245 */
1246 void _buildFieldMap(List<FieldElement> fields) {
1247 _fieldMap = new HashMap<String, FieldElement>();
1248 int count = fields.length;
1249 for (int i = 0; i < count; i++) {
1250 FieldElement field = fields[i];
1251 _fieldMap[field.name] ??= field;
1252 }
1253 } 1488 }
1254 1489
1255 /** 1490 /**
1256 * Creates the [ConstructorElement]s array with the single default constructor element.
1257 *
1258 * @param interfaceType the interface type for which to create a default const ructor
1259 * @return the [ConstructorElement]s array with the single default constructor element
1260 */
1261 List<ConstructorElement> _createDefaultConstructors(
1262 ClassElementImpl definingClass) {
1263 ConstructorElementImpl constructor =
1264 new ConstructorElementImpl.forNode(null);
1265 constructor.synthetic = true;
1266 constructor.enclosingElement = definingClass;
1267 return <ConstructorElement>[constructor];
1268 }
1269
1270 /**
1271 * For each [Annotation] found in [annotations], create a new 1491 * For each [Annotation] found in [annotations], create a new
1272 * [ElementAnnotation] object and set the [Annotation] to point to it. 1492 * [ElementAnnotation] object and set the [Annotation] to point to it.
1273 */ 1493 */
1274 List<ElementAnnotation> _createElementAnnotations( 1494 List<ElementAnnotation> _createElementAnnotations(
1275 NodeList<Annotation> annotations) { 1495 NodeList<Annotation> annotations) {
1276 if (annotations.isEmpty) { 1496 if (annotations.isEmpty) {
1277 return ElementAnnotation.EMPTY_LIST; 1497 return ElementAnnotation.EMPTY_LIST;
1278 } 1498 }
1279 return annotations.map((Annotation a) { 1499 return annotations.map((Annotation a) {
1280 ElementAnnotationImpl elementAnnotation = 1500 ElementAnnotationImpl elementAnnotation =
1281 new ElementAnnotationImpl(compilationUnitElement); 1501 new ElementAnnotationImpl(compilationUnitElement);
1282 a.elementAnnotation = elementAnnotation; 1502 a.elementAnnotation = elementAnnotation;
1283 return elementAnnotation; 1503 return elementAnnotation;
1284 }).toList(); 1504 }).toList();
1285 } 1505 }
1286 1506
1287 /** 1507 /**
1288 * Create the types associated with the given type parameters, setting the typ e of each type
1289 * parameter, and return an array of types corresponding to the given paramete rs.
1290 *
1291 * @param typeParameters the type parameters for which types are to be created
1292 * @return an array of types corresponding to the given parameters
1293 */
1294 List<DartType> _createTypeParameterTypes(
1295 List<TypeParameterElement> typeParameters) {
1296 int typeParameterCount = typeParameters.length;
1297 List<DartType> typeArguments = new List<DartType>(typeParameterCount);
1298 for (int i = 0; i < typeParameterCount; i++) {
1299 TypeParameterElementImpl typeParameter =
1300 typeParameters[i] as TypeParameterElementImpl;
1301 TypeParameterTypeImpl typeParameterType =
1302 new TypeParameterTypeImpl(typeParameter);
1303 typeParameter.type = typeParameterType;
1304 typeArguments[i] = typeParameterType;
1305 }
1306 return typeArguments;
1307 }
1308
1309 /**
1310 * Return the body of the function that contains the given [parameter], or 1508 * Return the body of the function that contains the given [parameter], or
1311 * `null` if no function body could be found. 1509 * `null` if no function body could be found.
1312 */ 1510 */
1313 FunctionBody _getFunctionBody(FormalParameter parameter) { 1511 FunctionBody _getFunctionBody(FormalParameter parameter) {
1314 AstNode parent = parameter?.parent?.parent; 1512 AstNode parent = parameter?.parent?.parent;
1315 if (parent is ConstructorDeclaration) { 1513 if (parent is ConstructorDeclaration) {
1316 return parent.body; 1514 return parent.body;
1317 } else if (parent is FunctionExpression) { 1515 } else if (parent is FunctionExpression) {
1318 return parent.body; 1516 return parent.body;
1319 } else if (parent is MethodDeclaration) { 1517 } else if (parent is MethodDeclaration) {
1320 return parent.body; 1518 return parent.body;
1321 } 1519 }
1322 return null; 1520 return null;
1323 } 1521 }
1324 1522
1325 void _setCodeRange(ElementImpl element, AstNode node) { 1523 void _setCodeRange(ElementImpl element, AstNode node) {
1326 element.setCodeRange(node.offset, node.length); 1524 element.setCodeRange(node.offset, node.length);
1327 } 1525 }
1328 1526
1527 void _setFieldParameterField(FieldFormalParameterElementImpl parameter) {}
1528
1329 /** 1529 /**
1330 * Sets the visible source range for formal parameter. 1530 * Sets the visible source range for formal parameter.
1331 */ 1531 */
1332 void _setParameterVisibleRange( 1532 void _setParameterVisibleRange(
1333 FormalParameter node, ParameterElementImpl element) { 1533 FormalParameter node, ParameterElementImpl element) {
1334 FunctionBody body = _getFunctionBody(node); 1534 FunctionBody body = _getFunctionBody(node);
1335 if (body is BlockFunctionBody || body is ExpressionFunctionBody) { 1535 if (body is BlockFunctionBody || body is ExpressionFunctionBody) {
1336 element.setVisibleRange(body.offset, body.length); 1536 element.setVisibleRange(body.offset, body.length);
1337 } 1537 }
1338 } 1538 }
1339 1539
1340 void _setVariableVisibleRange( 1540 void _setVariableDeclarationListAnnotations(VariableDeclarationList node,
1341 LocalVariableElementImpl element, VariableDeclaration node) { 1541 List<ElementAnnotation> elementAnnotations) {
1342 AstNode scopeNode; 1542 for (VariableDeclaration variableDeclaration in node.variables) {
1343 AstNode parent2 = node.parent.parent; 1543 ElementImpl element = variableDeclaration.element as ElementImpl;
1344 if (parent2 is ForStatement) { 1544 _setCodeRange(element, node.parent);
1345 scopeNode = parent2; 1545 element.metadata = elementAnnotations;
1346 } else {
1347 scopeNode = node.getAncestor((node) => node is Block);
1348 } 1546 }
1349 element.setVisibleRange(scopeNode.offset, scopeNode.length);
1350 } 1547 }
1351 1548
1352 /** 1549 /**
1353 * Make the given holder be the current holder while visiting the given node. 1550 * Make the given holder be the current holder while visiting the given node.
1354 * 1551 *
1355 * @param holder the holder that will gather elements that are built while vis iting the children 1552 * @param holder the holder that will gather elements that are built while vis iting the children
1356 * @param node the node to be visited 1553 * @param node the node to be visited
1357 */ 1554 */
1358 void _visit(ElementHolder holder, AstNode node) { 1555 void _visit(ElementHolder holder, AstNode node) {
1359 if (node != null) { 1556 if (node != null) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 return null; 1634 return null;
1438 } 1635 }
1439 1636
1440 /** 1637 /**
1441 * Return the lexical identifiers associated with the given [identifiers]. 1638 * Return the lexical identifiers associated with the given [identifiers].
1442 */ 1639 */
1443 static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) { 1640 static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) {
1444 return identifiers.map((identifier) => identifier.name).toList(); 1641 return identifiers.map((identifier) => identifier.name).toList();
1445 } 1642 }
1446 } 1643 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/lib/src/generated/resolver.dart » ('j') | pkg/analyzer/lib/src/generated/resolver.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698