| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 part of dart2js.semantics_visitor; | 5 part of dart2js.semantics_visitor; |
| 6 | 6 |
| 7 enum SendStructureKind { | 7 enum SendStructureKind { |
| 8 GET, | 8 GET, |
| 9 SET, | 9 SET, |
| 10 INVOKE, | 10 INVOKE, |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 Element element = elements[node.send]; | 460 Element element = elements[node.send]; |
| 461 Selector selector = elements.getSelector(node.send); | 461 Selector selector = elements.getSelector(node.send); |
| 462 DartType type = elements.getType(node); | 462 DartType type = elements.getType(node); |
| 463 | 463 |
| 464 ConstructorAccessSemantics constructorAccessSemantics = | 464 ConstructorAccessSemantics constructorAccessSemantics = |
| 465 computeConstructorAccessSemantics(element, type); | 465 computeConstructorAccessSemantics(element, type); |
| 466 return new NewInvokeStructure(constructorAccessSemantics, selector); | 466 return new NewInvokeStructure(constructorAccessSemantics, selector); |
| 467 } | 467 } |
| 468 } | 468 } |
| 469 | 469 |
| 470 abstract class DeclStructure<R, A> { |
| 471 final FunctionElement element; |
| 472 |
| 473 DeclStructure(this.element); |
| 474 |
| 475 /// Calls the matching visit method on [visitor] with [node] and [arg]. |
| 476 R dispatch(SemanticDeclarationVisitor<R, A> visitor, |
| 477 FunctionExpression node, |
| 478 A arg); |
| 479 } |
| 480 |
| 481 enum ConstructorKind { |
| 482 GENERATIVE, |
| 483 REDIRECTING_GENERATIVE, |
| 484 FACTORY, |
| 485 REDIRECTING_FACTORY, |
| 486 } |
| 487 |
| 488 class ConstructorDeclStructure<R, A> extends DeclStructure<R, A> { |
| 489 final ConstructorKind kind; |
| 490 |
| 491 ConstructorDeclStructure(this.kind, ConstructorElement constructor) |
| 492 : super(constructor); |
| 493 |
| 494 R dispatch(SemanticDeclarationVisitor<R, A> visitor, |
| 495 FunctionExpression node, |
| 496 A arg) { |
| 497 switch (kind) { |
| 498 case ConstructorKind.GENERATIVE: |
| 499 return visitor.visitGenerativeConstructorDeclaration( |
| 500 node, element, node.parameters, node.initializers, node.body, arg); |
| 501 case ConstructorKind.REDIRECTING_GENERATIVE: |
| 502 return visitor.visitRedirectingGenerativeConstructorDeclaration( |
| 503 node, element, node.parameters, node.initializers, arg); |
| 504 case ConstructorKind.FACTORY: |
| 505 return visitor.visitFactoryConstructorDeclaration( |
| 506 node, element, node.parameters, node.body, arg); |
| 507 default: |
| 508 break; |
| 509 } |
| 510 throw new SpannableAssertionFailure(node, |
| 511 "Unhandled constructor declaration kind: ${kind}"); |
| 512 } |
| 513 } |
| 514 |
| 515 class RedirectingFactoryConstructorDeclStructure<R, A> |
| 516 extends DeclStructure<R, A> { |
| 517 InterfaceType redirectionTargetType; |
| 518 ConstructorElement redirectionTarget; |
| 519 |
| 520 RedirectingFactoryConstructorDeclStructure( |
| 521 ConstructorElement constructor, |
| 522 this.redirectionTargetType, |
| 523 this.redirectionTarget) |
| 524 : super(constructor); |
| 525 |
| 526 R dispatch(SemanticDeclarationVisitor<R, A> visitor, |
| 527 FunctionExpression node, |
| 528 A arg) { |
| 529 return visitor.visitRedirectingFactoryConstructorDeclaration( |
| 530 node, element, node.parameters, |
| 531 redirectionTargetType, redirectionTarget, arg); |
| 532 } |
| 533 } |
| 534 |
| 535 enum FunctionKind { |
| 536 TOP_LEVEL_GETTER, |
| 537 TOP_LEVEL_SETTER, |
| 538 TOP_LEVEL_FUNCTION, |
| 539 STATIC_GETTER, |
| 540 STATIC_SETTER, |
| 541 STATIC_FUNCTION, |
| 542 ABSTRACT_GETTER, |
| 543 ABSTRACT_SETTER, |
| 544 ABSTRACT_METHOD, |
| 545 INSTANCE_GETTER, |
| 546 INSTANCE_SETTER, |
| 547 INSTANCE_METHOD, |
| 548 LOCAL_FUNCTION, |
| 549 CLOSURE, |
| 550 } |
| 551 |
| 552 class FunctionDeclStructure<R, A> |
| 553 extends DeclStructure<R, A> { |
| 554 final FunctionKind kind; |
| 555 |
| 556 FunctionDeclStructure(this.kind, FunctionElement function) |
| 557 : super(function); |
| 558 |
| 559 R dispatch(SemanticDeclarationVisitor<R, A> visitor, |
| 560 FunctionExpression node, |
| 561 A arg) { |
| 562 switch (kind) { |
| 563 case FunctionKind.TOP_LEVEL_GETTER: |
| 564 return visitor.visitTopLevelGetterDeclaration( |
| 565 node, element, node.body, arg); |
| 566 case FunctionKind.TOP_LEVEL_SETTER: |
| 567 return visitor.visitTopLevelSetterDeclaration( |
| 568 node, element, node.parameters, node.body, arg); |
| 569 case FunctionKind.TOP_LEVEL_FUNCTION: |
| 570 return visitor.visitTopLevelFunctionDeclaration( |
| 571 node, element, node.parameters, node.body, arg); |
| 572 case FunctionKind.STATIC_GETTER: |
| 573 return visitor.visitStaticGetterDeclaration( |
| 574 node, element, node.body, arg); |
| 575 case FunctionKind.STATIC_SETTER: |
| 576 return visitor.visitStaticSetterDeclaration( |
| 577 node, element, node.parameters, node.body, arg); |
| 578 case FunctionKind.STATIC_FUNCTION: |
| 579 return visitor.visitStaticFunctionDeclaration( |
| 580 node, element, node.parameters, node.body, arg); |
| 581 case FunctionKind.ABSTRACT_GETTER: |
| 582 return visitor.visitAbstractGetterDeclaration( |
| 583 node, element, arg); |
| 584 case FunctionKind.ABSTRACT_SETTER: |
| 585 return visitor.visitAbstractSetterDeclaration( |
| 586 node, element, node.parameters, arg); |
| 587 case FunctionKind.ABSTRACT_METHOD: |
| 588 return visitor.visitAbstractMethodDeclaration( |
| 589 node, element, node.parameters, arg); |
| 590 case FunctionKind.INSTANCE_GETTER: |
| 591 return visitor.visitInstanceGetterDeclaration( |
| 592 node, element, node.body, arg); |
| 593 case FunctionKind.INSTANCE_SETTER: |
| 594 return visitor.visitInstanceSetterDeclaration( |
| 595 node, element, node.parameters, node.body, arg); |
| 596 case FunctionKind.INSTANCE_METHOD: |
| 597 return visitor.visitInstanceMethodDeclaration( |
| 598 node, element, node.parameters, node.body, arg); |
| 599 case FunctionKind.LOCAL_FUNCTION: |
| 600 return visitor.visitLocalFunctionDeclaration( |
| 601 node, element, node.parameters, node.body, arg); |
| 602 case FunctionKind.CLOSURE: |
| 603 return visitor.visitClosureDeclaration( |
| 604 node, element, node.parameters, node.body, arg); |
| 605 } |
| 606 } |
| 607 } |
| 608 |
| 609 abstract class DeclarationResolverMixin { |
| 610 TreeElements get elements; |
| 611 |
| 612 internalError(Spannable spannable, String message); |
| 613 |
| 614 ConstructorKind computeConstructorKind(ConstructorElement constructor) { |
| 615 if (constructor.isRedirectingFactory) { |
| 616 return ConstructorKind.REDIRECTING_FACTORY; |
| 617 } else if (constructor.isFactoryConstructor) { |
| 618 return ConstructorKind.FACTORY; |
| 619 } else if (constructor.isRedirectingGenerative) { |
| 620 return ConstructorKind.REDIRECTING_GENERATIVE; |
| 621 } else { |
| 622 return ConstructorKind.GENERATIVE; |
| 623 } |
| 624 } |
| 625 |
| 626 DeclStructure computeFunctionStructure(FunctionExpression node) { |
| 627 FunctionElement element = elements.getFunctionDefinition(node); |
| 628 if (element.isConstructor) { |
| 629 ConstructorElement constructor = element; |
| 630 ConstructorKind kind = computeConstructorKind(constructor); |
| 631 if (kind == ConstructorKind.REDIRECTING_FACTORY) { |
| 632 return new RedirectingFactoryConstructorDeclStructure( |
| 633 constructor, |
| 634 elements.getType(node.body), |
| 635 constructor.immediateRedirectionTarget); |
| 636 } else { |
| 637 return new ConstructorDeclStructure(kind, element); |
| 638 } |
| 639 } else { |
| 640 FunctionKind kind; |
| 641 if (element.isLocal) { |
| 642 if (element.name.isEmpty) { |
| 643 kind = FunctionKind.CLOSURE; |
| 644 } else { |
| 645 kind = FunctionKind.LOCAL_FUNCTION; |
| 646 } |
| 647 } else if (element.isInstanceMember) { |
| 648 if (element.isGetter) { |
| 649 kind = element.isAbstract |
| 650 ? FunctionKind.ABSTRACT_GETTER |
| 651 : FunctionKind.INSTANCE_GETTER; |
| 652 } else if (element.isSetter) { |
| 653 kind = element.isAbstract |
| 654 ? FunctionKind.ABSTRACT_SETTER |
| 655 : FunctionKind.INSTANCE_SETTER; |
| 656 } else { |
| 657 kind = element.isAbstract |
| 658 ? FunctionKind.ABSTRACT_METHOD |
| 659 : FunctionKind.INSTANCE_METHOD; |
| 660 } |
| 661 } else if (element.isStatic) { |
| 662 if (element.isGetter) { |
| 663 kind = FunctionKind.STATIC_GETTER; |
| 664 } else if (element.isSetter) { |
| 665 kind = FunctionKind.STATIC_SETTER; |
| 666 } else { |
| 667 kind = FunctionKind.STATIC_FUNCTION; |
| 668 } |
| 669 } else if (element.isTopLevel) { |
| 670 if (element.isGetter) { |
| 671 kind = FunctionKind.TOP_LEVEL_GETTER; |
| 672 } else if (element.isSetter) { |
| 673 kind = FunctionKind.TOP_LEVEL_SETTER; |
| 674 } else { |
| 675 kind = FunctionKind.TOP_LEVEL_FUNCTION; |
| 676 } |
| 677 } else { |
| 678 return internalError(node, "Unhandled function expression."); |
| 679 } |
| 680 return new FunctionDeclStructure(kind, element); |
| 681 } |
| 682 } |
| 683 |
| 684 InitializerStructure computeInitializerStructure(Send node) { |
| 685 Element element = elements[node]; |
| 686 if (node.asSendSet() != null) { |
| 687 return new FieldInitializerStructure(element); |
| 688 } else if (Initializers.isConstructorRedirect(node)) { |
| 689 return new ThisConstructorInvokeStructure( |
| 690 element, elements.getSelector(node)); |
| 691 } else if (Initializers.isSuperConstructorCall(node)) { |
| 692 return new SuperConstructorInvokeStructure( |
| 693 element, |
| 694 elements.analyzedElement.enclosingClass.supertype, |
| 695 elements.getSelector(node)); |
| 696 } |
| 697 return internalError(node, "Unhandled initializer."); |
| 698 } |
| 699 |
| 700 List<ParameterStructure> computeParameterStructures(NodeList parameters) { |
| 701 List<ParameterStructure> list = <ParameterStructure>[]; |
| 702 int index = 0; |
| 703 for (Node node in parameters) { |
| 704 NodeList optionalParameters = node.asNodeList(); |
| 705 if (optionalParameters != null) { |
| 706 bool isNamed = optionalParameters.beginToken.stringValue == '{'; |
| 707 for (Node node in optionalParameters) { |
| 708 list.add(computeParameterStructure( |
| 709 node, index++, isRequired: false, isNamed: isNamed)); |
| 710 } |
| 711 } else { |
| 712 list.add(computeParameterStructure(node, index++)); |
| 713 } |
| 714 } |
| 715 return list; |
| 716 } |
| 717 |
| 718 ParameterStructure computeParameterStructure( |
| 719 VariableDefinitions definitions, |
| 720 int index, |
| 721 {bool isRequired: true, bool isNamed: false}) { |
| 722 Node node = definitions.definitions.nodes.single; |
| 723 ParameterElement element = elements[node]; |
| 724 if (element == null) { |
| 725 throw new SpannableAssertionFailure( |
| 726 node, "No parameter structure for $node."); |
| 727 } |
| 728 if (isRequired) { |
| 729 return new RequiredParameterStructure( |
| 730 definitions, node, element, index); |
| 731 } else { |
| 732 ConstantExpression defaultValue; |
| 733 if (element.initializer != null) { |
| 734 defaultValue = elements.getConstant(element.initializer); |
| 735 } |
| 736 if (isNamed) { |
| 737 return new NamedParameterStructure( |
| 738 definitions, node, element, defaultValue); |
| 739 } else { |
| 740 return new OptionalParameterStructure( |
| 741 definitions, node, element, defaultValue, index); |
| 742 } |
| 743 } |
| 744 } |
| 745 |
| 746 void computeVariableStructures( |
| 747 VariableDefinitions definitions, |
| 748 void callback(Node node, VariableStructure structure)) { |
| 749 for (Node node in definitions.definitions) { |
| 750 callback(definitions, computeVariableStructure(node)); |
| 751 } |
| 752 } |
| 753 |
| 754 VariableStructure computeVariableStructure(Node node) { |
| 755 VariableElement element = elements[node]; |
| 756 VariableKind kind; |
| 757 if (element.isLocal) { |
| 758 kind = VariableKind.LOCAL_VARIABLE; |
| 759 } else if (element.isInstanceMember) { |
| 760 kind = VariableKind.INSTANCE_FIELD; |
| 761 } else if (element.isStatic) { |
| 762 kind = VariableKind.STATIC_FIELD; |
| 763 } else if (element.isTopLevel) { |
| 764 kind = VariableKind.TOP_LEVEL_FIELD; |
| 765 } else { |
| 766 return internalError(node, "Unexpected variable $element."); |
| 767 } |
| 768 if (element.isConst) { |
| 769 ConstantExpression constant = elements.getConstant(element.initializer); |
| 770 return new ConstantVariableStructure(kind, node, element, constant); |
| 771 } else { |
| 772 return new NonConstantVariableStructure(kind, node, element); |
| 773 } |
| 774 } |
| 775 } |
| OLD | NEW |