| 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 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 return new StaticAccess.unresolved(null); | 534 return new StaticAccess.unresolved(null); |
| 535 } else { | 535 } else { |
| 536 return handleStaticallyResolvedAccess( | 536 return handleStaticallyResolvedAccess( |
| 537 node, element, getter, isCompound: isCompound); | 537 node, element, getter, isCompound: isCompound); |
| 538 } | 538 } |
| 539 } | 539 } |
| 540 } | 540 } |
| 541 | 541 |
| 542 ConstructorAccessSemantics computeConstructorAccessSemantics( | 542 ConstructorAccessSemantics computeConstructorAccessSemantics( |
| 543 ConstructorElement constructor, | 543 ConstructorElement constructor, |
| 544 CallStructure callStructure, |
| 544 DartType type, | 545 DartType type, |
| 545 {bool mustBeConstant: false}) { | 546 {bool mustBeConstant: false}) { |
| 546 if (mustBeConstant && !constructor.isConst) { | 547 if (mustBeConstant && !constructor.isConst) { |
| 547 return new ConstructorAccessSemantics( | 548 return new ConstructorAccessSemantics( |
| 548 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, constructor, type); | 549 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, constructor, type); |
| 549 } | 550 } |
| 550 if (constructor.isErroneous) { | 551 if (constructor.isErroneous) { |
| 551 if (constructor is ErroneousElement) { | 552 if (constructor is ErroneousElement) { |
| 552 ErroneousElement error = constructor; | 553 ErroneousElement error = constructor; |
| 553 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { | 554 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
| 554 return new ConstructorAccessSemantics( | 555 return new ConstructorAccessSemantics( |
| 555 ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR, constructor, type); | 556 ConstructorAccessKind.UNRESOLVED_CONSTRUCTOR, constructor, type); |
| 556 } | 557 } |
| 557 } | 558 } |
| 558 return new ConstructorAccessSemantics( | 559 return new ConstructorAccessSemantics( |
| 559 ConstructorAccessKind.UNRESOLVED_TYPE, constructor, type); | 560 ConstructorAccessKind.UNRESOLVED_TYPE, constructor, type); |
| 560 } else if (constructor.isRedirectingFactory) { | 561 } else { |
| 561 ConstructorElement effectiveTarget = constructor.effectiveTarget; | 562 if (!callStructure.signatureApplies(constructor)) { |
| 562 if (effectiveTarget == constructor || | |
| 563 effectiveTarget.isErroneous || | |
| 564 (mustBeConstant && !effectiveTarget.isConst)) { | |
| 565 return new ConstructorAccessSemantics( | 563 return new ConstructorAccessSemantics( |
| 566 ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY, | 564 ConstructorAccessKind.INCOMPATIBLE, |
| 567 constructor, | 565 constructor, |
| 568 type); | 566 type); |
| 569 } | 567 } |
| 570 ConstructorAccessSemantics effectiveTargetSemantics = | 568 if (constructor.isRedirectingFactory) { |
| 571 computeConstructorAccessSemantics( | 569 ConstructorElement effectiveTarget = constructor.effectiveTarget; |
| 572 effectiveTarget, | 570 if (effectiveTarget == constructor || |
| 573 constructor.computeEffectiveTargetType(type)); | 571 effectiveTarget.isErroneous || |
| 574 if (effectiveTargetSemantics.isErroneous) { | 572 (mustBeConstant && !effectiveTarget.isConst)) { |
| 573 return new ConstructorAccessSemantics( |
| 574 ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY, |
| 575 constructor, |
| 576 type); |
| 577 } |
| 578 ConstructorAccessSemantics effectiveTargetSemantics = |
| 579 computeConstructorAccessSemantics( |
| 580 effectiveTarget, |
| 581 callStructure, |
| 582 constructor.computeEffectiveTargetType(type)); |
| 583 if (effectiveTargetSemantics.isErroneous) { |
| 584 return new RedirectingFactoryConstructorAccessSemantics( |
| 585 ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY, |
| 586 constructor, |
| 587 type, |
| 588 effectiveTargetSemantics); |
| 589 } |
| 575 return new RedirectingFactoryConstructorAccessSemantics( | 590 return new RedirectingFactoryConstructorAccessSemantics( |
| 576 ConstructorAccessKind.ERRONEOUS_REDIRECTING_FACTORY, | 591 ConstructorAccessKind.REDIRECTING_FACTORY, |
| 577 constructor, | 592 constructor, |
| 578 type, | 593 type, |
| 579 effectiveTargetSemantics); | 594 effectiveTargetSemantics); |
| 595 } else if (constructor.isFactoryConstructor) { |
| 596 return new ConstructorAccessSemantics( |
| 597 ConstructorAccessKind.FACTORY, constructor, type); |
| 598 } else if (constructor.isRedirectingGenerative) { |
| 599 if (constructor.enclosingClass.isAbstract) { |
| 600 return new ConstructorAccessSemantics( |
| 601 ConstructorAccessKind.ABSTRACT, constructor, type); |
| 602 } |
| 603 return new ConstructorAccessSemantics( |
| 604 ConstructorAccessKind.REDIRECTING_GENERATIVE, constructor, type); |
| 605 } else if (constructor.enclosingClass.isAbstract) { |
| 606 return new ConstructorAccessSemantics( |
| 607 ConstructorAccessKind.ABSTRACT, constructor, type); |
| 608 } else { |
| 609 return new ConstructorAccessSemantics( |
| 610 ConstructorAccessKind.GENERATIVE, constructor, type); |
| 580 } | 611 } |
| 581 return new RedirectingFactoryConstructorAccessSemantics( | |
| 582 ConstructorAccessKind.REDIRECTING_FACTORY, | |
| 583 constructor, | |
| 584 type, | |
| 585 effectiveTargetSemantics); | |
| 586 } else if (constructor.isFactoryConstructor) { | |
| 587 return new ConstructorAccessSemantics( | |
| 588 ConstructorAccessKind.FACTORY, constructor, type); | |
| 589 } else if (constructor.isRedirectingGenerative) { | |
| 590 if (constructor.enclosingClass.isAbstract) { | |
| 591 return new ConstructorAccessSemantics( | |
| 592 ConstructorAccessKind.ABSTRACT, constructor, type); | |
| 593 } | |
| 594 return new ConstructorAccessSemantics( | |
| 595 ConstructorAccessKind.REDIRECTING_GENERATIVE, constructor, type); | |
| 596 } else if (constructor.enclosingClass.isAbstract) { | |
| 597 return new ConstructorAccessSemantics( | |
| 598 ConstructorAccessKind.ABSTRACT, constructor, type); | |
| 599 } else { | |
| 600 return new ConstructorAccessSemantics( | |
| 601 ConstructorAccessKind.GENERATIVE, constructor, type); | |
| 602 } | 612 } |
| 603 } | 613 } |
| 604 | 614 |
| 605 NewStructure computeNewStructure(NewExpression node) { | 615 NewStructure computeNewStructure(NewExpression node) { |
| 606 Element element = elements[node.send]; | 616 Element element = elements[node.send]; |
| 607 Selector selector = elements.getSelector(node.send); | 617 Selector selector = elements.getSelector(node.send); |
| 608 DartType type = elements.getType(node); | 618 DartType type = elements.getType(node); |
| 609 | 619 |
| 610 ConstructorAccessSemantics constructorAccessSemantics = | 620 ConstructorAccessSemantics constructorAccessSemantics = |
| 611 computeConstructorAccessSemantics( | 621 computeConstructorAccessSemantics( |
| 612 element, type, mustBeConstant: node.isConst); | 622 element, selector.callStructure, type, |
| 623 mustBeConstant: node.isConst); |
| 613 if (node.isConst) { | 624 if (node.isConst) { |
| 614 ConstantExpression constant = elements.getConstant(node); | 625 ConstantExpression constant = elements.getConstant(node); |
| 615 if (constructorAccessSemantics.isErroneous || | 626 if (constructorAccessSemantics.isErroneous || |
| 616 constant is! ConstructedConstantExpression) { | 627 constant == null || |
| 628 constant.kind == ConstantExpressionKind.ERRONEOUS) { |
| 617 // This is a non-constant constant constructor invocation, like | 629 // This is a non-constant constant constructor invocation, like |
| 618 // `const Const(method())`. | 630 // `const Const(method())`. |
| 619 constructorAccessSemantics = new ConstructorAccessSemantics( | 631 constructorAccessSemantics = new ConstructorAccessSemantics( |
| 620 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type); | 632 ConstructorAccessKind.NON_CONSTANT_CONSTRUCTOR, element, type); |
| 621 } else { | 633 } else { |
| 622 return new ConstInvokeStructure(constant); | 634 ConstantInvokeKind kind; |
| 635 switch (constant.kind) { |
| 636 case ConstantExpressionKind.CONSTRUCTED: |
| 637 kind = ConstantInvokeKind.CONSTRUCTED; |
| 638 break; |
| 639 case ConstantExpressionKind.BOOL_FROM_ENVIRONMENT: |
| 640 kind = ConstantInvokeKind.BOOL_FROM_ENVIRONMENT; |
| 641 break; |
| 642 case ConstantExpressionKind.INT_FROM_ENVIRONMENT: |
| 643 kind = ConstantInvokeKind.INT_FROM_ENVIRONMENT; |
| 644 break; |
| 645 case ConstantExpressionKind.STRING_FROM_ENVIRONMENT: |
| 646 kind = ConstantInvokeKind.STRING_FROM_ENVIRONMENT; |
| 647 break; |
| 648 default: |
| 649 return internalError( |
| 650 node, "Unexpected constant kind $kind: ${constant.getText()}"); |
| 651 } |
| 652 return new ConstInvokeStructure(kind, constant); |
| 623 } | 653 } |
| 624 } | 654 } |
| 625 return new NewInvokeStructure(constructorAccessSemantics, selector); | 655 return new NewInvokeStructure(constructorAccessSemantics, selector); |
| 626 } | 656 } |
| 627 } | 657 } |
| 628 | 658 |
| 629 abstract class DeclStructure<R, A> { | 659 abstract class DeclStructure<R, A> { |
| 630 final FunctionElement element; | 660 final FunctionElement element; |
| 631 | 661 |
| 632 DeclStructure(this.element); | 662 DeclStructure(this.element); |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 954 return internalError(node, "Unexpected variable $element."); | 984 return internalError(node, "Unexpected variable $element."); |
| 955 } | 985 } |
| 956 if (element.isConst) { | 986 if (element.isConst) { |
| 957 ConstantExpression constant = elements.getConstant(element.initializer); | 987 ConstantExpression constant = elements.getConstant(element.initializer); |
| 958 return new ConstantVariableStructure(kind, node, element, constant); | 988 return new ConstantVariableStructure(kind, node, element, constant); |
| 959 } else { | 989 } else { |
| 960 return new NonConstantVariableStructure(kind, node, element); | 990 return new NonConstantVariableStructure(kind, node, element); |
| 961 } | 991 } |
| 962 } | 992 } |
| 963 } | 993 } |
| OLD | NEW |