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