| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |