| 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/visitor.dart'; | 10 import 'package:analyzer/dart/ast/visitor.dart'; |
| 11 import 'package:analyzer/dart/element/element.dart'; | 11 import 'package:analyzer/dart/element/element.dart'; |
| 12 import 'package:analyzer/dart/element/type.dart'; |
| 12 import 'package:analyzer/src/dart/element/element.dart'; | 13 import 'package:analyzer/src/dart/element/element.dart'; |
| 14 import 'package:analyzer/src/dart/element/type.dart'; |
| 13 import 'package:analyzer/src/generated/engine.dart'; | 15 import 'package:analyzer/src/generated/engine.dart'; |
| 14 import 'package:analyzer/src/generated/error.dart'; | 16 import 'package:analyzer/src/generated/error.dart'; |
| 17 import 'package:analyzer/src/generated/java_engine.dart'; |
| 18 import 'package:analyzer/src/generated/resolver.dart'; |
| 15 import 'package:analyzer/src/generated/scanner.dart'; | 19 import 'package:analyzer/src/generated/scanner.dart'; |
| 16 import 'package:analyzer/src/generated/sdk.dart'; | 20 import 'package:analyzer/src/generated/sdk.dart'; |
| 17 import 'package:analyzer/src/generated/source.dart'; | 21 import 'package:analyzer/src/generated/source.dart'; |
| 22 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 23 |
| 24 /** |
| 25 * A `CompilationUnitBuilder` builds an element model for a single compilation |
| 26 * unit. |
| 27 */ |
| 28 class CompilationUnitBuilder { |
| 29 /** |
| 30 * Build the compilation unit element for the given [source] based on the |
| 31 * compilation [unit] associated with the source. Throw an AnalysisException |
| 32 * if the element could not be built. [librarySource] is the source for the |
| 33 * containing library. |
| 34 */ |
| 35 CompilationUnitElementImpl buildCompilationUnit( |
| 36 Source source, CompilationUnit unit, Source librarySource) { |
| 37 return PerformanceStatistics.resolve.makeCurrentWhile(() { |
| 38 if (unit == null) { |
| 39 return null; |
| 40 } |
| 41 ElementHolder holder = new ElementHolder(); |
| 42 ElementBuilder builder = new ElementBuilder(holder); |
| 43 unit.accept(builder); |
| 44 CompilationUnitElementImpl element = |
| 45 new CompilationUnitElementImpl(source.shortName); |
| 46 element.accessors = holder.accessors; |
| 47 element.enums = holder.enums; |
| 48 element.functions = holder.functions; |
| 49 element.source = source; |
| 50 element.librarySource = librarySource; |
| 51 element.typeAliases = holder.typeAliases; |
| 52 element.types = holder.types; |
| 53 element.topLevelVariables = holder.topLevelVariables; |
| 54 unit.element = element; |
| 55 holder.validate(); |
| 56 return element; |
| 57 }); |
| 58 } |
| 59 } |
| 18 | 60 |
| 19 /** | 61 /** |
| 20 * Instances of the class `DirectiveElementBuilder` build elements for top | 62 * Instances of the class `DirectiveElementBuilder` build elements for top |
| 21 * level library directives. | 63 * level library directives. |
| 22 */ | 64 */ |
| 23 class DirectiveElementBuilder extends SimpleAstVisitor<Object> { | 65 class DirectiveElementBuilder extends SimpleAstVisitor<Object> { |
| 24 /** | 66 /** |
| 25 * The analysis context within which directive elements are being built. | 67 * The analysis context within which directive elements are being built. |
| 26 */ | 68 */ |
| 27 final AnalysisContext context; | 69 final AnalysisContext context; |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 223 _NamespaceCombinatorBuilder namespaceCombinatorBuilder = | 265 _NamespaceCombinatorBuilder namespaceCombinatorBuilder = |
| 224 new _NamespaceCombinatorBuilder(); | 266 new _NamespaceCombinatorBuilder(); |
| 225 for (Combinator combinator in directive.combinators) { | 267 for (Combinator combinator in directive.combinators) { |
| 226 combinator.accept(namespaceCombinatorBuilder); | 268 combinator.accept(namespaceCombinatorBuilder); |
| 227 } | 269 } |
| 228 return namespaceCombinatorBuilder.combinators; | 270 return namespaceCombinatorBuilder.combinators; |
| 229 } | 271 } |
| 230 } | 272 } |
| 231 | 273 |
| 232 /** | 274 /** |
| 275 * Instances of the class `ElementBuilder` traverse an AST structure and build t
he element |
| 276 * model representing the AST structure. |
| 277 */ |
| 278 class ElementBuilder extends RecursiveAstVisitor<Object> { |
| 279 /** |
| 280 * The element holder associated with the element that is currently being buil
t. |
| 281 */ |
| 282 ElementHolder _currentHolder; |
| 283 |
| 284 /** |
| 285 * A flag indicating whether a variable declaration is in the context of a fie
ld declaration. |
| 286 */ |
| 287 bool _inFieldContext = false; |
| 288 |
| 289 /** |
| 290 * A flag indicating whether a variable declaration is within the body of a me
thod or function. |
| 291 */ |
| 292 bool _inFunction = false; |
| 293 |
| 294 /** |
| 295 * A collection holding the elements defined in a class that need to have |
| 296 * their function type fixed to take into account type parameters of the |
| 297 * enclosing class, or `null` if we are not currently processing nodes within |
| 298 * a class. |
| 299 */ |
| 300 List<ExecutableElementImpl> _functionTypesToFix = null; |
| 301 |
| 302 /** |
| 303 * A table mapping field names to field elements for the fields defined in the
current class, or |
| 304 * `null` if we are not in the scope of a class. |
| 305 */ |
| 306 HashMap<String, FieldElement> _fieldMap; |
| 307 |
| 308 /** |
| 309 * Initialize a newly created element builder to build the elements for a comp
ilation unit. |
| 310 * |
| 311 * @param initialHolder the element holder associated with the compilation uni
t being built |
| 312 */ |
| 313 ElementBuilder(ElementHolder initialHolder) { |
| 314 _currentHolder = initialHolder; |
| 315 } |
| 316 |
| 317 @override |
| 318 Object visitBlock(Block node) { |
| 319 bool wasInField = _inFieldContext; |
| 320 _inFieldContext = false; |
| 321 try { |
| 322 node.visitChildren(this); |
| 323 } finally { |
| 324 _inFieldContext = wasInField; |
| 325 } |
| 326 return null; |
| 327 } |
| 328 |
| 329 @override |
| 330 Object visitCatchClause(CatchClause node) { |
| 331 SimpleIdentifier exceptionParameter = node.exceptionParameter; |
| 332 if (exceptionParameter != null) { |
| 333 // exception |
| 334 LocalVariableElementImpl exception = |
| 335 new LocalVariableElementImpl.forNode(exceptionParameter); |
| 336 if (node.exceptionType == null) { |
| 337 exception.hasImplicitType = true; |
| 338 } |
| 339 _currentHolder.addLocalVariable(exception); |
| 340 exceptionParameter.staticElement = exception; |
| 341 // stack trace |
| 342 SimpleIdentifier stackTraceParameter = node.stackTraceParameter; |
| 343 if (stackTraceParameter != null) { |
| 344 LocalVariableElementImpl stackTrace = |
| 345 new LocalVariableElementImpl.forNode(stackTraceParameter); |
| 346 _currentHolder.addLocalVariable(stackTrace); |
| 347 stackTraceParameter.staticElement = stackTrace; |
| 348 } |
| 349 } |
| 350 return super.visitCatchClause(node); |
| 351 } |
| 352 |
| 353 @override |
| 354 Object visitClassDeclaration(ClassDeclaration node) { |
| 355 ElementHolder holder = new ElementHolder(); |
| 356 _functionTypesToFix = new List<ExecutableElementImpl>(); |
| 357 // |
| 358 // Process field declarations before constructors and methods so that field |
| 359 // formal parameters can be correctly resolved to their fields. |
| 360 // |
| 361 ElementHolder previousHolder = _currentHolder; |
| 362 _currentHolder = holder; |
| 363 try { |
| 364 List<ClassMember> nonFields = new List<ClassMember>(); |
| 365 node.visitChildren( |
| 366 new _ElementBuilder_visitClassDeclaration(this, nonFields)); |
| 367 _buildFieldMap(holder.fieldsWithoutFlushing); |
| 368 int count = nonFields.length; |
| 369 for (int i = 0; i < count; i++) { |
| 370 nonFields[i].accept(this); |
| 371 } |
| 372 } finally { |
| 373 _currentHolder = previousHolder; |
| 374 } |
| 375 SimpleIdentifier className = node.name; |
| 376 ClassElementImpl element = new ClassElementImpl.forNode(className); |
| 377 List<TypeParameterElement> typeParameters = holder.typeParameters; |
| 378 List<DartType> typeArguments = _createTypeParameterTypes(typeParameters); |
| 379 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element); |
| 380 interfaceType.typeArguments = typeArguments; |
| 381 element.type = interfaceType; |
| 382 element.typeParameters = typeParameters; |
| 383 _setDoc(element, node); |
| 384 element.abstract = node.isAbstract; |
| 385 element.accessors = holder.accessors; |
| 386 List<ConstructorElement> constructors = holder.constructors; |
| 387 if (constructors.isEmpty) { |
| 388 constructors = _createDefaultConstructors(element); |
| 389 } |
| 390 element.constructors = constructors; |
| 391 element.fields = holder.fields; |
| 392 element.methods = holder.methods; |
| 393 // Function types must be initialized after the enclosing element has been |
| 394 // set, for them to pick up the type parameters. |
| 395 for (ExecutableElementImpl e in _functionTypesToFix) { |
| 396 e.type = new FunctionTypeImpl(e); |
| 397 } |
| 398 _functionTypesToFix = null; |
| 399 _currentHolder.addType(element); |
| 400 className.staticElement = element; |
| 401 _fieldMap = null; |
| 402 holder.validate(); |
| 403 return null; |
| 404 } |
| 405 |
| 406 /** |
| 407 * Implementation of this method should be synchronized with |
| 408 * [visitClassDeclaration]. |
| 409 */ |
| 410 void visitClassDeclarationIncrementally(ClassDeclaration node) { |
| 411 // |
| 412 // Process field declarations before constructors and methods so that field |
| 413 // formal parameters can be correctly resolved to their fields. |
| 414 // |
| 415 ClassElement classElement = node.element; |
| 416 _buildFieldMap(classElement.fields); |
| 417 } |
| 418 |
| 419 @override |
| 420 Object visitClassTypeAlias(ClassTypeAlias node) { |
| 421 ElementHolder holder = new ElementHolder(); |
| 422 _visitChildren(holder, node); |
| 423 SimpleIdentifier className = node.name; |
| 424 ClassElementImpl element = new ClassElementImpl.forNode(className); |
| 425 element.abstract = node.abstractKeyword != null; |
| 426 element.mixinApplication = true; |
| 427 List<TypeParameterElement> typeParameters = holder.typeParameters; |
| 428 element.typeParameters = typeParameters; |
| 429 List<DartType> typeArguments = _createTypeParameterTypes(typeParameters); |
| 430 InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element); |
| 431 interfaceType.typeArguments = typeArguments; |
| 432 element.type = interfaceType; |
| 433 _setDoc(element, node); |
| 434 _currentHolder.addType(element); |
| 435 className.staticElement = element; |
| 436 holder.validate(); |
| 437 return null; |
| 438 } |
| 439 |
| 440 @override |
| 441 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 442 ElementHolder holder = new ElementHolder(); |
| 443 bool wasInFunction = _inFunction; |
| 444 _inFunction = true; |
| 445 try { |
| 446 _visitChildren(holder, node); |
| 447 } finally { |
| 448 _inFunction = wasInFunction; |
| 449 } |
| 450 FunctionBody body = node.body; |
| 451 SimpleIdentifier constructorName = node.name; |
| 452 ConstructorElementImpl element = |
| 453 new ConstructorElementImpl.forNode(constructorName); |
| 454 _setDoc(element, node); |
| 455 if (node.externalKeyword != null) { |
| 456 element.external = true; |
| 457 } |
| 458 if (node.factoryKeyword != null) { |
| 459 element.factory = true; |
| 460 } |
| 461 element.functions = holder.functions; |
| 462 element.labels = holder.labels; |
| 463 element.localVariables = holder.localVariables; |
| 464 element.parameters = holder.parameters; |
| 465 element.const2 = node.constKeyword != null; |
| 466 if (body.isAsynchronous) { |
| 467 element.asynchronous = true; |
| 468 } |
| 469 if (body.isGenerator) { |
| 470 element.generator = true; |
| 471 } |
| 472 _currentHolder.addConstructor(element); |
| 473 node.element = element; |
| 474 if (constructorName == null) { |
| 475 Identifier returnType = node.returnType; |
| 476 if (returnType != null) { |
| 477 element.nameOffset = returnType.offset; |
| 478 element.nameEnd = returnType.end; |
| 479 } |
| 480 } else { |
| 481 constructorName.staticElement = element; |
| 482 element.periodOffset = node.period.offset; |
| 483 element.nameEnd = constructorName.end; |
| 484 } |
| 485 holder.validate(); |
| 486 return null; |
| 487 } |
| 488 |
| 489 @override |
| 490 Object visitDeclaredIdentifier(DeclaredIdentifier node) { |
| 491 SimpleIdentifier variableName = node.identifier; |
| 492 LocalVariableElementImpl element = |
| 493 new LocalVariableElementImpl.forNode(variableName); |
| 494 ForEachStatement statement = node.parent as ForEachStatement; |
| 495 int declarationEnd = node.offset + node.length; |
| 496 int statementEnd = statement.offset + statement.length; |
| 497 element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1); |
| 498 element.const3 = node.isConst; |
| 499 element.final2 = node.isFinal; |
| 500 if (node.type == null) { |
| 501 element.hasImplicitType = true; |
| 502 } |
| 503 _currentHolder.addLocalVariable(element); |
| 504 variableName.staticElement = element; |
| 505 return super.visitDeclaredIdentifier(node); |
| 506 } |
| 507 |
| 508 @override |
| 509 Object visitDefaultFormalParameter(DefaultFormalParameter node) { |
| 510 ElementHolder holder = new ElementHolder(); |
| 511 NormalFormalParameter normalParameter = node.parameter; |
| 512 SimpleIdentifier parameterName = normalParameter.identifier; |
| 513 ParameterElementImpl parameter; |
| 514 if (normalParameter is FieldFormalParameter) { |
| 515 parameter = new DefaultFieldFormalParameterElementImpl(parameterName); |
| 516 FieldElement field = |
| 517 _fieldMap == null ? null : _fieldMap[parameterName.name]; |
| 518 if (field != null) { |
| 519 (parameter as DefaultFieldFormalParameterElementImpl).field = field; |
| 520 } |
| 521 } else { |
| 522 parameter = new DefaultParameterElementImpl(parameterName); |
| 523 } |
| 524 parameter.const3 = node.isConst; |
| 525 parameter.final2 = node.isFinal; |
| 526 parameter.parameterKind = node.kind; |
| 527 // set initializer, default value range |
| 528 Expression defaultValue = node.defaultValue; |
| 529 if (defaultValue != null) { |
| 530 _visit(holder, defaultValue); |
| 531 FunctionElementImpl initializer = |
| 532 new FunctionElementImpl.forOffset(defaultValue.beginToken.offset); |
| 533 initializer.functions = holder.functions; |
| 534 initializer.labels = holder.labels; |
| 535 initializer.localVariables = holder.localVariables; |
| 536 initializer.parameters = holder.parameters; |
| 537 initializer.synthetic = true; |
| 538 parameter.initializer = initializer; |
| 539 parameter.defaultValueCode = defaultValue.toSource(); |
| 540 } |
| 541 // visible range |
| 542 _setParameterVisibleRange(node, parameter); |
| 543 if (normalParameter is SimpleFormalParameter && |
| 544 normalParameter.type == null) { |
| 545 parameter.hasImplicitType = true; |
| 546 } |
| 547 _currentHolder.addParameter(parameter); |
| 548 parameterName.staticElement = parameter; |
| 549 normalParameter.accept(this); |
| 550 holder.validate(); |
| 551 return null; |
| 552 } |
| 553 |
| 554 @override |
| 555 Object visitEnumDeclaration(EnumDeclaration node) { |
| 556 SimpleIdentifier enumName = node.name; |
| 557 ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName); |
| 558 enumElement.enum2 = true; |
| 559 _setDoc(enumElement, node); |
| 560 InterfaceTypeImpl enumType = new InterfaceTypeImpl(enumElement); |
| 561 enumElement.type = enumType; |
| 562 // The equivalent code for enums in the spec shows a single constructor, |
| 563 // but that constructor is not callable (since it is a compile-time error |
| 564 // to subclass, mix-in, implement, or explicitly instantiate an enum). So |
| 565 // we represent this as having no constructors. |
| 566 enumElement.constructors = ConstructorElement.EMPTY_LIST; |
| 567 _currentHolder.addEnum(enumElement); |
| 568 enumName.staticElement = enumElement; |
| 569 return super.visitEnumDeclaration(node); |
| 570 } |
| 571 |
| 572 @override |
| 573 Object visitFieldDeclaration(FieldDeclaration node) { |
| 574 bool wasInField = _inFieldContext; |
| 575 _inFieldContext = true; |
| 576 try { |
| 577 node.visitChildren(this); |
| 578 } finally { |
| 579 _inFieldContext = wasInField; |
| 580 } |
| 581 return null; |
| 582 } |
| 583 |
| 584 @override |
| 585 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 586 if (node.parent is! DefaultFormalParameter) { |
| 587 SimpleIdentifier parameterName = node.identifier; |
| 588 FieldElement field = |
| 589 _fieldMap == null ? null : _fieldMap[parameterName.name]; |
| 590 FieldFormalParameterElementImpl parameter = |
| 591 new FieldFormalParameterElementImpl(parameterName); |
| 592 parameter.const3 = node.isConst; |
| 593 parameter.final2 = node.isFinal; |
| 594 parameter.parameterKind = node.kind; |
| 595 if (field != null) { |
| 596 parameter.field = field; |
| 597 } |
| 598 _currentHolder.addParameter(parameter); |
| 599 parameterName.staticElement = parameter; |
| 600 } |
| 601 // |
| 602 // The children of this parameter include any parameters defined on the type |
| 603 // of this parameter. |
| 604 // |
| 605 ElementHolder holder = new ElementHolder(); |
| 606 _visitChildren(holder, node); |
| 607 ParameterElementImpl element = node.element; |
| 608 element.parameters = holder.parameters; |
| 609 element.typeParameters = holder.typeParameters; |
| 610 holder.validate(); |
| 611 return null; |
| 612 } |
| 613 |
| 614 @override |
| 615 Object visitFunctionDeclaration(FunctionDeclaration node) { |
| 616 FunctionExpression expression = node.functionExpression; |
| 617 if (expression != null) { |
| 618 ElementHolder holder = new ElementHolder(); |
| 619 bool wasInFunction = _inFunction; |
| 620 _inFunction = true; |
| 621 try { |
| 622 _visitChildren(holder, node); |
| 623 } finally { |
| 624 _inFunction = wasInFunction; |
| 625 } |
| 626 FunctionBody body = expression.body; |
| 627 Token property = node.propertyKeyword; |
| 628 if (property == null || _inFunction) { |
| 629 SimpleIdentifier functionName = node.name; |
| 630 FunctionElementImpl element = |
| 631 new FunctionElementImpl.forNode(functionName); |
| 632 _setDoc(element, node); |
| 633 if (node.externalKeyword != null) { |
| 634 element.external = true; |
| 635 } |
| 636 element.functions = holder.functions; |
| 637 element.labels = holder.labels; |
| 638 element.localVariables = holder.localVariables; |
| 639 element.parameters = holder.parameters; |
| 640 element.typeParameters = holder.typeParameters; |
| 641 if (body.isAsynchronous) { |
| 642 element.asynchronous = true; |
| 643 } |
| 644 if (body.isGenerator) { |
| 645 element.generator = true; |
| 646 } |
| 647 if (_inFunction) { |
| 648 Block enclosingBlock = node.getAncestor((node) => node is Block); |
| 649 if (enclosingBlock != null) { |
| 650 int functionEnd = node.offset + node.length; |
| 651 int blockEnd = enclosingBlock.offset + enclosingBlock.length; |
| 652 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); |
| 653 } |
| 654 } |
| 655 if (node.returnType == null) { |
| 656 element.hasImplicitReturnType = true; |
| 657 } |
| 658 _currentHolder.addFunction(element); |
| 659 expression.element = element; |
| 660 functionName.staticElement = element; |
| 661 } else { |
| 662 SimpleIdentifier propertyNameNode = node.name; |
| 663 if (propertyNameNode == null) { |
| 664 // TODO(brianwilkerson) Report this internal error. |
| 665 return null; |
| 666 } |
| 667 String propertyName = propertyNameNode.name; |
| 668 TopLevelVariableElementImpl variable = _currentHolder |
| 669 .getTopLevelVariable(propertyName) as TopLevelVariableElementImpl; |
| 670 if (variable == null) { |
| 671 variable = new TopLevelVariableElementImpl(node.name.name, -1); |
| 672 variable.final2 = true; |
| 673 variable.synthetic = true; |
| 674 _currentHolder.addTopLevelVariable(variable); |
| 675 } |
| 676 if (node.isGetter) { |
| 677 PropertyAccessorElementImpl getter = |
| 678 new PropertyAccessorElementImpl.forNode(propertyNameNode); |
| 679 _setDoc(getter, node); |
| 680 if (node.externalKeyword != null) { |
| 681 getter.external = true; |
| 682 } |
| 683 getter.functions = holder.functions; |
| 684 getter.labels = holder.labels; |
| 685 getter.localVariables = holder.localVariables; |
| 686 if (body.isAsynchronous) { |
| 687 getter.asynchronous = true; |
| 688 } |
| 689 if (body.isGenerator) { |
| 690 getter.generator = true; |
| 691 } |
| 692 getter.variable = variable; |
| 693 getter.getter = true; |
| 694 getter.static = true; |
| 695 variable.getter = getter; |
| 696 if (node.returnType == null) { |
| 697 getter.hasImplicitReturnType = true; |
| 698 } |
| 699 _currentHolder.addAccessor(getter); |
| 700 expression.element = getter; |
| 701 propertyNameNode.staticElement = getter; |
| 702 } else { |
| 703 PropertyAccessorElementImpl setter = |
| 704 new PropertyAccessorElementImpl.forNode(propertyNameNode); |
| 705 _setDoc(setter, node); |
| 706 if (node.externalKeyword != null) { |
| 707 setter.external = true; |
| 708 } |
| 709 setter.functions = holder.functions; |
| 710 setter.labels = holder.labels; |
| 711 setter.localVariables = holder.localVariables; |
| 712 setter.parameters = holder.parameters; |
| 713 if (body.isAsynchronous) { |
| 714 setter.asynchronous = true; |
| 715 } |
| 716 if (body.isGenerator) { |
| 717 setter.generator = true; |
| 718 } |
| 719 setter.variable = variable; |
| 720 setter.setter = true; |
| 721 setter.static = true; |
| 722 if (node.returnType == null) { |
| 723 setter.hasImplicitReturnType = true; |
| 724 } |
| 725 variable.setter = setter; |
| 726 variable.final2 = false; |
| 727 _currentHolder.addAccessor(setter); |
| 728 expression.element = setter; |
| 729 propertyNameNode.staticElement = setter; |
| 730 } |
| 731 } |
| 732 holder.validate(); |
| 733 } |
| 734 return null; |
| 735 } |
| 736 |
| 737 @override |
| 738 Object visitFunctionExpression(FunctionExpression node) { |
| 739 if (node.parent is FunctionDeclaration) { |
| 740 // visitFunctionDeclaration has already created the element for the |
| 741 // declaration. We just need to visit children. |
| 742 return super.visitFunctionExpression(node); |
| 743 } |
| 744 ElementHolder holder = new ElementHolder(); |
| 745 bool wasInFunction = _inFunction; |
| 746 _inFunction = true; |
| 747 try { |
| 748 _visitChildren(holder, node); |
| 749 } finally { |
| 750 _inFunction = wasInFunction; |
| 751 } |
| 752 FunctionBody body = node.body; |
| 753 FunctionElementImpl element = |
| 754 new FunctionElementImpl.forOffset(node.beginToken.offset); |
| 755 element.functions = holder.functions; |
| 756 element.labels = holder.labels; |
| 757 element.localVariables = holder.localVariables; |
| 758 element.parameters = holder.parameters; |
| 759 element.typeParameters = holder.typeParameters; |
| 760 if (body.isAsynchronous) { |
| 761 element.asynchronous = true; |
| 762 } |
| 763 if (body.isGenerator) { |
| 764 element.generator = true; |
| 765 } |
| 766 if (_inFunction) { |
| 767 Block enclosingBlock = node.getAncestor((node) => node is Block); |
| 768 if (enclosingBlock != null) { |
| 769 int functionEnd = node.offset + node.length; |
| 770 int blockEnd = enclosingBlock.offset + enclosingBlock.length; |
| 771 element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1); |
| 772 } |
| 773 } |
| 774 if (_functionTypesToFix != null) { |
| 775 _functionTypesToFix.add(element); |
| 776 } else { |
| 777 element.type = new FunctionTypeImpl(element); |
| 778 } |
| 779 element.hasImplicitReturnType = true; |
| 780 _currentHolder.addFunction(element); |
| 781 node.element = element; |
| 782 holder.validate(); |
| 783 return null; |
| 784 } |
| 785 |
| 786 @override |
| 787 Object visitFunctionTypeAlias(FunctionTypeAlias node) { |
| 788 ElementHolder holder = new ElementHolder(); |
| 789 _visitChildren(holder, node); |
| 790 SimpleIdentifier aliasName = node.name; |
| 791 List<ParameterElement> parameters = holder.parameters; |
| 792 List<TypeParameterElement> typeParameters = holder.typeParameters; |
| 793 FunctionTypeAliasElementImpl element = |
| 794 new FunctionTypeAliasElementImpl.forNode(aliasName); |
| 795 _setDoc(element, node); |
| 796 element.parameters = parameters; |
| 797 element.typeParameters = typeParameters; |
| 798 _createTypeParameterTypes(typeParameters); |
| 799 element.type = new FunctionTypeImpl.forTypedef(element); |
| 800 _currentHolder.addTypeAlias(element); |
| 801 aliasName.staticElement = element; |
| 802 holder.validate(); |
| 803 return null; |
| 804 } |
| 805 |
| 806 @override |
| 807 Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) { |
| 808 if (node.parent is! DefaultFormalParameter) { |
| 809 SimpleIdentifier parameterName = node.identifier; |
| 810 ParameterElementImpl parameter = |
| 811 new ParameterElementImpl.forNode(parameterName); |
| 812 parameter.parameterKind = node.kind; |
| 813 _setParameterVisibleRange(node, parameter); |
| 814 _currentHolder.addParameter(parameter); |
| 815 parameterName.staticElement = parameter; |
| 816 } |
| 817 // |
| 818 // The children of this parameter include any parameters defined on the type |
| 819 //of this parameter. |
| 820 // |
| 821 ElementHolder holder = new ElementHolder(); |
| 822 _visitChildren(holder, node); |
| 823 ParameterElementImpl element = node.element; |
| 824 element.parameters = holder.parameters; |
| 825 element.typeParameters = holder.typeParameters; |
| 826 holder.validate(); |
| 827 return null; |
| 828 } |
| 829 |
| 830 @override |
| 831 Object visitLabeledStatement(LabeledStatement node) { |
| 832 bool onSwitchStatement = node.statement is SwitchStatement; |
| 833 for (Label label in node.labels) { |
| 834 SimpleIdentifier labelName = label.label; |
| 835 LabelElementImpl element = |
| 836 new LabelElementImpl(labelName, onSwitchStatement, false); |
| 837 _currentHolder.addLabel(element); |
| 838 labelName.staticElement = element; |
| 839 } |
| 840 return super.visitLabeledStatement(node); |
| 841 } |
| 842 |
| 843 @override |
| 844 Object visitMethodDeclaration(MethodDeclaration node) { |
| 845 try { |
| 846 ElementHolder holder = new ElementHolder(); |
| 847 bool wasInFunction = _inFunction; |
| 848 _inFunction = true; |
| 849 try { |
| 850 _visitChildren(holder, node); |
| 851 } finally { |
| 852 _inFunction = wasInFunction; |
| 853 } |
| 854 bool isStatic = node.isStatic; |
| 855 Token property = node.propertyKeyword; |
| 856 FunctionBody body = node.body; |
| 857 if (property == null) { |
| 858 SimpleIdentifier methodName = node.name; |
| 859 String nameOfMethod = methodName.name; |
| 860 if (nameOfMethod == TokenType.MINUS.lexeme && |
| 861 node.parameters.parameters.length == 0) { |
| 862 nameOfMethod = "unary-"; |
| 863 } |
| 864 MethodElementImpl element = |
| 865 new MethodElementImpl(nameOfMethod, methodName.offset); |
| 866 _setDoc(element, node); |
| 867 element.abstract = node.isAbstract; |
| 868 if (node.externalKeyword != null) { |
| 869 element.external = true; |
| 870 } |
| 871 element.functions = holder.functions; |
| 872 element.labels = holder.labels; |
| 873 element.localVariables = holder.localVariables; |
| 874 element.parameters = holder.parameters; |
| 875 element.static = isStatic; |
| 876 element.typeParameters = holder.typeParameters; |
| 877 if (body.isAsynchronous) { |
| 878 element.asynchronous = true; |
| 879 } |
| 880 if (body.isGenerator) { |
| 881 element.generator = true; |
| 882 } |
| 883 if (node.returnType == null) { |
| 884 element.hasImplicitReturnType = true; |
| 885 } |
| 886 _currentHolder.addMethod(element); |
| 887 methodName.staticElement = element; |
| 888 } else { |
| 889 SimpleIdentifier propertyNameNode = node.name; |
| 890 String propertyName = propertyNameNode.name; |
| 891 FieldElementImpl field = |
| 892 _currentHolder.getField(propertyName) as FieldElementImpl; |
| 893 if (field == null) { |
| 894 field = new FieldElementImpl(node.name.name, -1); |
| 895 field.final2 = true; |
| 896 field.static = isStatic; |
| 897 field.synthetic = true; |
| 898 _currentHolder.addField(field); |
| 899 } |
| 900 if (node.isGetter) { |
| 901 PropertyAccessorElementImpl getter = |
| 902 new PropertyAccessorElementImpl.forNode(propertyNameNode); |
| 903 _setDoc(getter, node); |
| 904 if (node.externalKeyword != null) { |
| 905 getter.external = true; |
| 906 } |
| 907 getter.functions = holder.functions; |
| 908 getter.labels = holder.labels; |
| 909 getter.localVariables = holder.localVariables; |
| 910 if (body.isAsynchronous) { |
| 911 getter.asynchronous = true; |
| 912 } |
| 913 if (body.isGenerator) { |
| 914 getter.generator = true; |
| 915 } |
| 916 getter.variable = field; |
| 917 getter.abstract = node.isAbstract; |
| 918 getter.getter = true; |
| 919 getter.static = isStatic; |
| 920 field.getter = getter; |
| 921 if (node.returnType == null) { |
| 922 getter.hasImplicitReturnType = true; |
| 923 } |
| 924 _currentHolder.addAccessor(getter); |
| 925 propertyNameNode.staticElement = getter; |
| 926 } else { |
| 927 PropertyAccessorElementImpl setter = |
| 928 new PropertyAccessorElementImpl.forNode(propertyNameNode); |
| 929 _setDoc(setter, node); |
| 930 if (node.externalKeyword != null) { |
| 931 setter.external = true; |
| 932 } |
| 933 setter.functions = holder.functions; |
| 934 setter.labels = holder.labels; |
| 935 setter.localVariables = holder.localVariables; |
| 936 setter.parameters = holder.parameters; |
| 937 if (body.isAsynchronous) { |
| 938 setter.asynchronous = true; |
| 939 } |
| 940 if (body.isGenerator) { |
| 941 setter.generator = true; |
| 942 } |
| 943 setter.variable = field; |
| 944 setter.abstract = node.isAbstract; |
| 945 setter.setter = true; |
| 946 setter.static = isStatic; |
| 947 if (node.returnType == null) { |
| 948 setter.hasImplicitReturnType = true; |
| 949 } |
| 950 field.setter = setter; |
| 951 field.final2 = false; |
| 952 _currentHolder.addAccessor(setter); |
| 953 propertyNameNode.staticElement = setter; |
| 954 } |
| 955 } |
| 956 holder.validate(); |
| 957 } catch (exception, stackTrace) { |
| 958 if (node.name.staticElement == null) { |
| 959 ClassDeclaration classNode = |
| 960 node.getAncestor((node) => node is ClassDeclaration); |
| 961 StringBuffer buffer = new StringBuffer(); |
| 962 buffer.write("The element for the method "); |
| 963 buffer.write(node.name); |
| 964 buffer.write(" in "); |
| 965 buffer.write(classNode.name); |
| 966 buffer.write(" was not set while trying to build the element model."); |
| 967 AnalysisEngine.instance.logger.logError( |
| 968 buffer.toString(), new CaughtException(exception, stackTrace)); |
| 969 } else { |
| 970 String message = |
| 971 "Exception caught in ElementBuilder.visitMethodDeclaration()"; |
| 972 AnalysisEngine.instance.logger |
| 973 .logError(message, new CaughtException(exception, stackTrace)); |
| 974 } |
| 975 } finally { |
| 976 if (node.name.staticElement == null) { |
| 977 ClassDeclaration classNode = |
| 978 node.getAncestor((node) => node is ClassDeclaration); |
| 979 StringBuffer buffer = new StringBuffer(); |
| 980 buffer.write("The element for the method "); |
| 981 buffer.write(node.name); |
| 982 buffer.write(" in "); |
| 983 buffer.write(classNode.name); |
| 984 buffer.write(" was not set while trying to resolve types."); |
| 985 AnalysisEngine.instance.logger.logError( |
| 986 buffer.toString(), |
| 987 new CaughtException( |
| 988 new AnalysisException(buffer.toString()), null)); |
| 989 } |
| 990 } |
| 991 return null; |
| 992 } |
| 993 |
| 994 @override |
| 995 Object visitSimpleFormalParameter(SimpleFormalParameter node) { |
| 996 if (node.parent is! DefaultFormalParameter) { |
| 997 SimpleIdentifier parameterName = node.identifier; |
| 998 ParameterElementImpl parameter = |
| 999 new ParameterElementImpl.forNode(parameterName); |
| 1000 parameter.const3 = node.isConst; |
| 1001 parameter.final2 = node.isFinal; |
| 1002 parameter.parameterKind = node.kind; |
| 1003 _setParameterVisibleRange(node, parameter); |
| 1004 if (node.type == null) { |
| 1005 parameter.hasImplicitType = true; |
| 1006 } |
| 1007 _currentHolder.addParameter(parameter); |
| 1008 parameterName.staticElement = parameter; |
| 1009 } |
| 1010 return super.visitSimpleFormalParameter(node); |
| 1011 } |
| 1012 |
| 1013 @override |
| 1014 Object visitSwitchCase(SwitchCase node) { |
| 1015 for (Label label in node.labels) { |
| 1016 SimpleIdentifier labelName = label.label; |
| 1017 LabelElementImpl element = new LabelElementImpl(labelName, false, true); |
| 1018 _currentHolder.addLabel(element); |
| 1019 labelName.staticElement = element; |
| 1020 } |
| 1021 return super.visitSwitchCase(node); |
| 1022 } |
| 1023 |
| 1024 @override |
| 1025 Object visitSwitchDefault(SwitchDefault node) { |
| 1026 for (Label label in node.labels) { |
| 1027 SimpleIdentifier labelName = label.label; |
| 1028 LabelElementImpl element = new LabelElementImpl(labelName, false, true); |
| 1029 _currentHolder.addLabel(element); |
| 1030 labelName.staticElement = element; |
| 1031 } |
| 1032 return super.visitSwitchDefault(node); |
| 1033 } |
| 1034 |
| 1035 @override |
| 1036 Object visitTypeParameter(TypeParameter node) { |
| 1037 SimpleIdentifier parameterName = node.name; |
| 1038 TypeParameterElementImpl typeParameter = |
| 1039 new TypeParameterElementImpl.forNode(parameterName); |
| 1040 TypeParameterTypeImpl typeParameterType = |
| 1041 new TypeParameterTypeImpl(typeParameter); |
| 1042 typeParameter.type = typeParameterType; |
| 1043 _currentHolder.addTypeParameter(typeParameter); |
| 1044 parameterName.staticElement = typeParameter; |
| 1045 return super.visitTypeParameter(node); |
| 1046 } |
| 1047 |
| 1048 @override |
| 1049 Object visitVariableDeclaration(VariableDeclaration node) { |
| 1050 bool isConst = node.isConst; |
| 1051 bool isFinal = node.isFinal; |
| 1052 bool hasInitializer = node.initializer != null; |
| 1053 VariableElementImpl element; |
| 1054 if (_inFieldContext) { |
| 1055 SimpleIdentifier fieldName = node.name; |
| 1056 FieldElementImpl field; |
| 1057 if ((isConst || isFinal) && hasInitializer) { |
| 1058 field = new ConstFieldElementImpl.forNode(fieldName); |
| 1059 } else { |
| 1060 field = new FieldElementImpl.forNode(fieldName); |
| 1061 } |
| 1062 element = field; |
| 1063 if (node.parent.parent is FieldDeclaration) { |
| 1064 _setDoc(element, node.parent.parent); |
| 1065 } |
| 1066 if ((node.parent as VariableDeclarationList).type == null) { |
| 1067 field.hasImplicitType = true; |
| 1068 } |
| 1069 _currentHolder.addField(field); |
| 1070 fieldName.staticElement = field; |
| 1071 } else if (_inFunction) { |
| 1072 SimpleIdentifier variableName = node.name; |
| 1073 LocalVariableElementImpl variable; |
| 1074 if (isConst && hasInitializer) { |
| 1075 variable = new ConstLocalVariableElementImpl.forNode(variableName); |
| 1076 } else { |
| 1077 variable = new LocalVariableElementImpl.forNode(variableName); |
| 1078 } |
| 1079 element = variable; |
| 1080 Block enclosingBlock = node.getAncestor((node) => node is Block); |
| 1081 // TODO(brianwilkerson) This isn't right for variables declared in a for |
| 1082 // loop. |
| 1083 variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length); |
| 1084 if ((node.parent as VariableDeclarationList).type == null) { |
| 1085 variable.hasImplicitType = true; |
| 1086 } |
| 1087 _currentHolder.addLocalVariable(variable); |
| 1088 variableName.staticElement = element; |
| 1089 } else { |
| 1090 SimpleIdentifier variableName = node.name; |
| 1091 TopLevelVariableElementImpl variable; |
| 1092 if (isConst && hasInitializer) { |
| 1093 variable = new ConstTopLevelVariableElementImpl.forNode(variableName); |
| 1094 } else { |
| 1095 variable = new TopLevelVariableElementImpl.forNode(variableName); |
| 1096 } |
| 1097 element = variable; |
| 1098 if (node.parent.parent is TopLevelVariableDeclaration) { |
| 1099 _setDoc(element, node.parent.parent); |
| 1100 } |
| 1101 if ((node.parent as VariableDeclarationList).type == null) { |
| 1102 variable.hasImplicitType = true; |
| 1103 } |
| 1104 _currentHolder.addTopLevelVariable(variable); |
| 1105 variableName.staticElement = element; |
| 1106 } |
| 1107 element.const3 = isConst; |
| 1108 element.final2 = isFinal; |
| 1109 if (hasInitializer) { |
| 1110 ElementHolder holder = new ElementHolder(); |
| 1111 bool wasInFieldContext = _inFieldContext; |
| 1112 _inFieldContext = false; |
| 1113 try { |
| 1114 _visit(holder, node.initializer); |
| 1115 } finally { |
| 1116 _inFieldContext = wasInFieldContext; |
| 1117 } |
| 1118 FunctionElementImpl initializer = |
| 1119 new FunctionElementImpl.forOffset(node.initializer.beginToken.offset); |
| 1120 initializer.functions = holder.functions; |
| 1121 initializer.labels = holder.labels; |
| 1122 initializer.localVariables = holder.localVariables; |
| 1123 initializer.synthetic = true; |
| 1124 element.initializer = initializer; |
| 1125 holder.validate(); |
| 1126 } |
| 1127 if (element is PropertyInducingElementImpl) { |
| 1128 if (_inFieldContext) { |
| 1129 (element as FieldElementImpl).static = |
| 1130 (node.parent.parent as FieldDeclaration).isStatic; |
| 1131 } |
| 1132 PropertyAccessorElementImpl getter = |
| 1133 new PropertyAccessorElementImpl.forVariable(element); |
| 1134 getter.getter = true; |
| 1135 if (element.hasImplicitType) { |
| 1136 getter.hasImplicitReturnType = true; |
| 1137 } |
| 1138 _currentHolder.addAccessor(getter); |
| 1139 element.getter = getter; |
| 1140 if (!isConst && !isFinal) { |
| 1141 PropertyAccessorElementImpl setter = |
| 1142 new PropertyAccessorElementImpl.forVariable(element); |
| 1143 setter.setter = true; |
| 1144 ParameterElementImpl parameter = |
| 1145 new ParameterElementImpl("_${element.name}", element.nameOffset); |
| 1146 parameter.synthetic = true; |
| 1147 parameter.parameterKind = ParameterKind.REQUIRED; |
| 1148 setter.parameters = <ParameterElement>[parameter]; |
| 1149 _currentHolder.addAccessor(setter); |
| 1150 element.setter = setter; |
| 1151 } |
| 1152 } |
| 1153 return null; |
| 1154 } |
| 1155 |
| 1156 /** |
| 1157 * Build the table mapping field names to field elements for the fields define
d in the current |
| 1158 * class. |
| 1159 * |
| 1160 * @param fields the field elements defined in the current class |
| 1161 */ |
| 1162 void _buildFieldMap(List<FieldElement> fields) { |
| 1163 _fieldMap = new HashMap<String, FieldElement>(); |
| 1164 int count = fields.length; |
| 1165 for (int i = 0; i < count; i++) { |
| 1166 FieldElement field = fields[i]; |
| 1167 _fieldMap[field.name] = field; |
| 1168 } |
| 1169 } |
| 1170 |
| 1171 /** |
| 1172 * Creates the [ConstructorElement]s array with the single default constructor
element. |
| 1173 * |
| 1174 * @param interfaceType the interface type for which to create a default const
ructor |
| 1175 * @return the [ConstructorElement]s array with the single default constructor
element |
| 1176 */ |
| 1177 List<ConstructorElement> _createDefaultConstructors( |
| 1178 ClassElementImpl definingClass) { |
| 1179 ConstructorElementImpl constructor = |
| 1180 new ConstructorElementImpl.forNode(null); |
| 1181 constructor.synthetic = true; |
| 1182 constructor.returnType = definingClass.type; |
| 1183 constructor.enclosingElement = definingClass; |
| 1184 constructor.type = new FunctionTypeImpl(constructor); |
| 1185 return <ConstructorElement>[constructor]; |
| 1186 } |
| 1187 |
| 1188 /** |
| 1189 * Create the types associated with the given type parameters, setting the typ
e of each type |
| 1190 * parameter, and return an array of types corresponding to the given paramete
rs. |
| 1191 * |
| 1192 * @param typeParameters the type parameters for which types are to be created |
| 1193 * @return an array of types corresponding to the given parameters |
| 1194 */ |
| 1195 List<DartType> _createTypeParameterTypes( |
| 1196 List<TypeParameterElement> typeParameters) { |
| 1197 int typeParameterCount = typeParameters.length; |
| 1198 List<DartType> typeArguments = new List<DartType>(typeParameterCount); |
| 1199 for (int i = 0; i < typeParameterCount; i++) { |
| 1200 TypeParameterElementImpl typeParameter = |
| 1201 typeParameters[i] as TypeParameterElementImpl; |
| 1202 TypeParameterTypeImpl typeParameterType = |
| 1203 new TypeParameterTypeImpl(typeParameter); |
| 1204 typeParameter.type = typeParameterType; |
| 1205 typeArguments[i] = typeParameterType; |
| 1206 } |
| 1207 return typeArguments; |
| 1208 } |
| 1209 |
| 1210 /** |
| 1211 * Return the body of the function that contains the given parameter, or `null
` if no |
| 1212 * function body could be found. |
| 1213 * |
| 1214 * @param node the parameter contained in the function whose body is to be ret
urned |
| 1215 * @return the body of the function that contains the given parameter |
| 1216 */ |
| 1217 FunctionBody _getFunctionBody(FormalParameter node) { |
| 1218 AstNode parent = node.parent; |
| 1219 while (parent != null) { |
| 1220 if (parent is ConstructorDeclaration) { |
| 1221 return parent.body; |
| 1222 } else if (parent is FunctionExpression) { |
| 1223 return parent.body; |
| 1224 } else if (parent is MethodDeclaration) { |
| 1225 return parent.body; |
| 1226 } |
| 1227 parent = parent.parent; |
| 1228 } |
| 1229 return null; |
| 1230 } |
| 1231 |
| 1232 /** |
| 1233 * If the given [node] has a documentation comment, remember its content |
| 1234 * and range into the given [element]. |
| 1235 */ |
| 1236 void _setDoc(ElementImpl element, AnnotatedNode node) { |
| 1237 Comment comment = node.documentationComment; |
| 1238 if (comment != null && comment.isDocumentation) { |
| 1239 element.documentationComment = |
| 1240 comment.tokens.map((Token t) => t.lexeme).join('\n'); |
| 1241 element.setDocRange(comment.offset, comment.length); |
| 1242 } |
| 1243 } |
| 1244 |
| 1245 /** |
| 1246 * Sets the visible source range for formal parameter. |
| 1247 */ |
| 1248 void _setParameterVisibleRange( |
| 1249 FormalParameter node, ParameterElementImpl element) { |
| 1250 FunctionBody body = _getFunctionBody(node); |
| 1251 if (body != null) { |
| 1252 element.setVisibleRange(body.offset, body.length); |
| 1253 } |
| 1254 } |
| 1255 |
| 1256 /** |
| 1257 * Make the given holder be the current holder while visiting the given node. |
| 1258 * |
| 1259 * @param holder the holder that will gather elements that are built while vis
iting the children |
| 1260 * @param node the node to be visited |
| 1261 */ |
| 1262 void _visit(ElementHolder holder, AstNode node) { |
| 1263 if (node != null) { |
| 1264 ElementHolder previousHolder = _currentHolder; |
| 1265 _currentHolder = holder; |
| 1266 try { |
| 1267 node.accept(this); |
| 1268 } finally { |
| 1269 _currentHolder = previousHolder; |
| 1270 } |
| 1271 } |
| 1272 } |
| 1273 |
| 1274 /** |
| 1275 * Make the given holder be the current holder while visiting the children of
the given node. |
| 1276 * |
| 1277 * @param holder the holder that will gather elements that are built while vis
iting the children |
| 1278 * @param node the node whose children are to be visited |
| 1279 */ |
| 1280 void _visitChildren(ElementHolder holder, AstNode node) { |
| 1281 if (node != null) { |
| 1282 ElementHolder previousHolder = _currentHolder; |
| 1283 _currentHolder = holder; |
| 1284 try { |
| 1285 node.visitChildren(this); |
| 1286 } finally { |
| 1287 _currentHolder = previousHolder; |
| 1288 } |
| 1289 } |
| 1290 } |
| 1291 } |
| 1292 |
| 1293 class _ElementBuilder_visitClassDeclaration extends UnifyingAstVisitor<Object> { |
| 1294 final ElementBuilder builder; |
| 1295 |
| 1296 List<ClassMember> nonFields; |
| 1297 |
| 1298 _ElementBuilder_visitClassDeclaration(this.builder, this.nonFields) : super(); |
| 1299 |
| 1300 @override |
| 1301 Object visitConstructorDeclaration(ConstructorDeclaration node) { |
| 1302 nonFields.add(node); |
| 1303 return null; |
| 1304 } |
| 1305 |
| 1306 @override |
| 1307 Object visitMethodDeclaration(MethodDeclaration node) { |
| 1308 nonFields.add(node); |
| 1309 return null; |
| 1310 } |
| 1311 |
| 1312 @override |
| 1313 Object visitNode(AstNode node) => node.accept(builder); |
| 1314 } |
| 1315 |
| 1316 /** |
| 233 * Instances of the class [_NamespaceCombinatorBuilder] can be used to visit | 1317 * Instances of the class [_NamespaceCombinatorBuilder] can be used to visit |
| 234 * [Combinator] AST nodes and generate [NamespaceCombinator] elements. | 1318 * [Combinator] AST nodes and generate [NamespaceCombinator] elements. |
| 235 */ | 1319 */ |
| 236 class _NamespaceCombinatorBuilder extends SimpleAstVisitor<Object> { | 1320 class _NamespaceCombinatorBuilder extends SimpleAstVisitor<Object> { |
| 237 /** | 1321 /** |
| 238 * Elements generated so far. | 1322 * Elements generated so far. |
| 239 */ | 1323 */ |
| 240 final List<NamespaceCombinator> combinators = <NamespaceCombinator>[]; | 1324 final List<NamespaceCombinator> combinators = <NamespaceCombinator>[]; |
| 241 | 1325 |
| 242 @override | 1326 @override |
| (...skipping 14 matching lines...) Expand all Loading... |
| 257 return null; | 1341 return null; |
| 258 } | 1342 } |
| 259 | 1343 |
| 260 /** | 1344 /** |
| 261 * Return the lexical identifiers associated with the given [identifiers]. | 1345 * Return the lexical identifiers associated with the given [identifiers]. |
| 262 */ | 1346 */ |
| 263 static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) { | 1347 static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) { |
| 264 return identifiers.map((identifier) => identifier.name).toList(); | 1348 return identifiers.map((identifier) => identifier.name).toList(); |
| 265 } | 1349 } |
| 266 } | 1350 } |
| OLD | NEW |