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