Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart

Issue 1004683002: Refactor IrBuilder to use SemanticVisitor. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 dart2js.ir_builder_task; 5 library dart2js.ir_builder_task;
6 6
7 import '../closure.dart' as closurelib; 7 import '../closure.dart' as closurelib;
8 import '../closure.dart' hide ClosureScope; 8 import '../closure.dart' hide ClosureScope;
9 import '../constants/expressions.dart'; 9 import '../constants/expressions.dart';
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
11 import '../dart2jslib.dart'; 11 import '../dart2jslib.dart';
12 import '../elements/elements.dart'; 12 import '../elements/elements.dart';
13 import '../elements/modelx.dart' show SynthesizedConstructorElementX, 13 import '../elements/modelx.dart' show SynthesizedConstructorElementX,
14 ConstructorBodyElementX, FunctionSignatureX; 14 ConstructorBodyElementX, FunctionSignatureX;
15 import '../io/source_file.dart'; 15 import '../io/source_file.dart';
16 import '../io/source_information.dart'; 16 import '../io/source_information.dart';
17 import '../js_backend/js_backend.dart' show JavaScriptBackend; 17 import '../js_backend/js_backend.dart' show JavaScriptBackend;
18 import '../resolution/semantic_visitor.dart';
19 import '../resolution/operators.dart' as op;
18 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator; 20 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator;
19 import '../tree/tree.dart' as ast; 21 import '../tree/tree.dart' as ast;
20 import '../universe/universe.dart' show SelectorKind; 22 import '../universe/universe.dart' show SelectorKind;
21 import 'cps_ir_nodes.dart' as ir; 23 import 'cps_ir_nodes.dart' as ir;
22 import 'cps_ir_builder.dart'; 24 import 'cps_ir_builder.dart';
23 25
24 /** 26 /**
25 * This task iterates through all resolved elements and builds [ir.Node]s. The 27 * This task iterates through all resolved elements and builds [ir.Node]s. The
26 * nodes are stored in the [nodes] map and accessible through [hasIr] and 28 * nodes are stored in the [nodes] map and accessible through [hasIr] and
27 * [getIr]. 29 * [getIr].
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 111 }
110 112
111 bool get inCheckedMode { 113 bool get inCheckedMode {
112 bool result = false; 114 bool result = false;
113 assert((result = true)); 115 assert((result = true));
114 return result; 116 return result;
115 } 117 }
116 118
117 } 119 }
118 120
119 class _GetterElements {
120 ir.Primitive result;
121 ir.Primitive index;
122 ir.Primitive receiver;
123
124 _GetterElements({this.result, this.index, this.receiver}) ;
125 }
126
127 /** 121 /**
128 * A tree visitor that builds [IrNodes]. The visit methods add statements using 122 * A tree visitor that builds [IrNodes]. The visit methods add statements using
129 * to the [builder] and return the last added statement for trees that represent 123 * to the [builder] and return the last added statement for trees that represent
130 * an expression. 124 * an expression.
131 */ 125 */
132 abstract class IrBuilderVisitor extends ResolvedVisitor<ir.Primitive> 126 abstract class IrBuilderVisitor extends SemanticVisitor<ir.Primitive, dynamic>
133 with IrBuilderMixin<ast.Node> { 127 with IrBuilderMixin<ast.Node>,
128 GroupStaticMixin<ir.Primitive, dynamic>,
floitsch 2015/03/12 18:04:02 Just looking at this, I have no idea what this (an
Johnni Winther 2015/03/16 13:28:13 Is 'GroupStaticSemantics' better ?
floitsch 2015/03/16 13:38:41 Maybe BaseImplementationOfStaticsMixin?
Johnni Winther 2015/03/20 13:40:59 Done.
129 GroupLocalMixin<ir.Primitive, dynamic>,
130 GroupDynamicMixin<ir.Primitive, dynamic>,
131 GroupConstantMixin<ir.Primitive, dynamic>,
132 GroupSuperMixin<ir.Primitive, dynamic>,
133 ErrorBulkMixin<ir.Primitive, dynamic>
134 implements SemanticSendVisitor<ir.Primitive, dynamic> {
134 final Compiler compiler; 135 final Compiler compiler;
135 final SourceInformationBuilder sourceInformationBuilder; 136 final SourceInformationBuilder sourceInformationBuilder;
136 137
137 // In SSA terms, join-point continuation parameters are the phis and the 138 // In SSA terms, join-point continuation parameters are the phis and the
138 // continuation invocation arguments are the corresponding phi inputs. To 139 // continuation invocation arguments are the corresponding phi inputs. To
139 // support name introduction and renaming for source level variables, we use 140 // support name introduction and renaming for source level variables, we use
140 // nested (delimited) visitors for constructing subparts of the IR that will 141 // nested (delimited) visitors for constructing subparts of the IR that will
141 // need renaming. Each source variable is assigned an index. 142 // need renaming. Each source variable is assigned an index.
142 // 143 //
143 // Each nested visitor maintains a list of free variable uses in the body. 144 // Each nested visitor maintains a list of free variable uses in the body.
144 // These are implemented as a list of parameters, each with their own use 145 // These are implemented as a list of parameters, each with their own use
145 // list of references. When the delimited subexpression is plugged into the 146 // list of references. When the delimited subexpression is plugged into the
146 // surrounding context, the free occurrences can be captured or become free 147 // surrounding context, the free occurrences can be captured or become free
147 // occurrences in the next outer delimited subexpression. 148 // occurrences in the next outer delimited subexpression.
148 // 149 //
149 // Each nested visitor maintains a list that maps indexes of variables 150 // Each nested visitor maintains a list that maps indexes of variables
150 // assigned in the delimited subexpression to their reaching definition --- 151 // assigned in the delimited subexpression to their reaching definition ---
151 // that is, the definition in effect at the hole in 'current'. These are 152 // that is, the definition in effect at the hole in 'current'. These are
152 // used to determine if a join-point continuation needs to be passed 153 // used to determine if a join-point continuation needs to be passed
153 // arguments, and what the arguments are. 154 // arguments, and what the arguments are.
154 155
155 /// Construct a top-level visitor. 156 /// Construct a top-level visitor.
156 IrBuilderVisitor(TreeElements elements, 157 IrBuilderVisitor(TreeElements elements,
157 this.compiler, 158 this.compiler,
158 this.sourceInformationBuilder) 159 this.sourceInformationBuilder)
159 : super(elements); 160 : super(elements);
160 161
162 @override
163 bulkHandleNode(ast.Node node, String message) => giveup(node, message);
164
165 @override
166 ir.Primitive apply(ast.Node node, _) => node.accept(this);
167
168 @override
169 SemanticSendVisitor get sendVisitor => this;
170
161 /** 171 /**
162 * Builds the [ir.ExecutableDefinition] for an executable element. In case the 172 * Builds the [ir.ExecutableDefinition] for an executable element. In case the
163 * function uses features that cannot be expressed in the IR, this element 173 * function uses features that cannot be expressed in the IR, this element
164 * returns `null`. 174 * returns `null`.
165 */ 175 */
166 ir.ExecutableDefinition buildExecutable(ExecutableElement element); 176 ir.ExecutableDefinition buildExecutable(ExecutableElement element);
167 177
168 ClosureScope getClosureScopeForNode(ast.Node node); 178 ClosureScope getClosureScopeForNode(ast.Node node);
169 ClosureEnvironment getClosureEnvironment(); 179 ClosureEnvironment getClosureEnvironment();
170 180
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
583 assert(irBuilder.isOpen); 593 assert(irBuilder.isOpen);
584 var oldCascadeReceiver = _currentCascadeReceiver; 594 var oldCascadeReceiver = _currentCascadeReceiver;
585 // Throw away the result of visiting the expression. 595 // Throw away the result of visiting the expression.
586 // Instead we return the result of visiting the CascadeReceiver. 596 // Instead we return the result of visiting the CascadeReceiver.
587 this.visit(node.expression); 597 this.visit(node.expression);
588 ir.Primitive receiver = _currentCascadeReceiver; 598 ir.Primitive receiver = _currentCascadeReceiver;
589 _currentCascadeReceiver = oldCascadeReceiver; 599 _currentCascadeReceiver = oldCascadeReceiver;
590 return receiver; 600 return receiver;
591 } 601 }
592 602
593 // ==== Sends ==== 603 // ==== Sends ====
floitsch 2015/03/12 18:04:02 nit (and not your code): if we have sections in th
Johnni Winther 2015/03/16 13:28:13 Converted into 2nd level headers.
594 ir.Primitive visitAssert(ast.Send node) { 604 @override
605 ir.Primitive visitAssert(
606 ast.Send node,
607 ast.Node condition,
608 _) {
595 assert(irBuilder.isOpen); 609 assert(irBuilder.isOpen);
596 return giveup(node, 'Assert'); 610 return giveup(node, 'Assert');
597 } 611 }
598 612
599 ir.Primitive visitNamedArgument(ast.NamedArgument node) { 613 ir.Primitive visitNamedArgument(ast.NamedArgument node) {
600 assert(irBuilder.isOpen); 614 assert(irBuilder.isOpen);
601 return visit(node.expression); 615 return visit(node.expression);
602 } 616 }
603 617
604 ir.Primitive visitClosureSend(ast.Send node) { 618 @override
605 assert(irBuilder.isOpen); 619 ir.Primitive visitExpressionInvoke(ast.Send node,
606 Element element = elements[node]; 620 ast.Node expression,
607 Selector selector = elements.getSelector(node); 621 ast.NodeList arguments,
608 ir.Primitive receiver = (element == null) 622 Selector selector, _) {
609 ? visit(node.selector) 623 ir.Primitive receiver = visit(expression);
610 : irBuilder.buildLocalGet(element);
611 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 624 List<ir.Primitive> arguments = node.arguments.mapToList(visit);
612 arguments = normalizeDynamicArguments(selector, arguments); 625 arguments = normalizeDynamicArguments(selector, arguments);
613 return irBuilder.buildCallInvocation(receiver, selector, arguments); 626 return irBuilder.buildCallInvocation(receiver, selector, arguments);
614 } 627 }
615 628
616 /// If [node] is null, returns this.
617 /// If [node] is super, returns null (for special handling)
618 /// Otherwise visits [node] and returns the result.
619 ir.Primitive visitReceiver(ast.Expression node) {
620 if (node == null) return irBuilder.buildThis();
621 if (node.isSuper()) return null;
622 return visit(node);
623 }
624
625 /// Returns `true` if [node] is a super call. 629 /// Returns `true` if [node] is a super call.
626 // TODO(johnniwinther): Remove the need for this. 630 // TODO(johnniwinther): Remove the need for this.
627 bool isSuperCall(ast.Send node) { 631 bool isSuperCall(ast.Send node) {
628 return node != null && node.receiver != null && node.receiver.isSuper(); 632 return node != null && node.receiver != null && node.receiver.isSuper();
629 } 633 }
630 634
631 ir.Primitive visitDynamicSend(ast.Send node) { 635 @override
632 assert(irBuilder.isOpen); 636 ir.Primitive handleConstantGet(ast.Send node,
633 Selector selector = elements.getSelector(node); 637 ConstantExpression constant, _) {
634 ir.Primitive receiver = visitReceiver(node.receiver); 638 return irBuilder.buildConstantLiteral(constant);
635 List<ir.Primitive> arguments = node.arguments.mapToList(visit);
636 arguments = normalizeDynamicArguments(selector, arguments);
637 return irBuilder.buildDynamicInvocation(receiver, selector, arguments);
638 } 639 }
639 640
640 _GetterElements translateGetter(ast.Send node, Selector selector) { 641 /// If [node] is null, returns this.
641 Element element = elements[node]; 642 /// Otherwise visits [node] and returns the result.
642 ir.Primitive result; 643 ir.Primitive translateReceiver(ast.Expression node) {
643 ir.Primitive receiver; 644 return node != null ? visit(node) : irBuilder.buildThis();
644 ir.Primitive index;
645
646 if (element != null && element.isConst) {
647 // Reference to constant local, top-level or static field
648 result = translateConstant(node);
649 } else if (Elements.isLocal(element)) {
650 // Reference to local variable
651 result = irBuilder.buildLocalGet(element);
652 } else if (element == null ||
653 Elements.isInstanceField(element) ||
654 Elements.isInstanceMethod(element) ||
655 selector.isIndex ||
656 // TODO(johnniwinther): clean up semantics of resolution.
657 node.isSuperCall) {
658 // Dynamic dispatch to a getter. Sometimes resolution will suggest a
659 // target element, but in these cases we must still emit a dynamic
660 // dispatch. The target element may be an instance method in case we are
661 // converting a method to a function object.
662
663 receiver = visitReceiver(node.receiver);
664 List<ir.Primitive> arguments = new List<ir.Primitive>();
665 if (selector.isIndex) {
666 index = visit(node.arguments.head);
667 arguments.add(index);
668 }
669
670 assert(selector.kind == SelectorKind.GETTER ||
671 selector.kind == SelectorKind.INDEX);
672 if (isSuperCall(node)) {
673 result = irBuilder.buildSuperInvocation(element, selector, arguments);
674 } else {
675 result =
676 irBuilder.buildDynamicInvocation(receiver, selector, arguments);
677 }
678 } else if (element.isField || element.isGetter || element.isErroneous ||
679 element.isSetter) {
680 // TODO(johnniwinther): Change handling of setter selectors.
681 // Access to a static field or getter (non-static case handled above).
682 // Even if there is only a setter, we compile as if it was a getter,
683 // so the vm can fail at runtime.
684 assert(selector.kind == SelectorKind.GETTER ||
685 selector.kind == SelectorKind.SETTER);
686 result = irBuilder.buildStaticGet(element, selector,
687 sourceInformation: sourceInformationBuilder.buildGet(node));
688 } else if (Elements.isStaticOrTopLevelFunction(element)) {
689 // Convert a top-level or static function to a function object.
690 result = translateConstant(node);
691 } else {
692 throw "Unexpected SendSet getter: $node, $element";
693 }
694 return new _GetterElements(
695 result: result,index: index, receiver: receiver);
696 } 645 }
697 646
698 ir.Primitive visitGetterSend(ast.Send node) { 647 @override
699 assert(irBuilder.isOpen); 648 ir.Primitive handleDynamicGet(
700 return translateGetter(node, elements.getSelector(node)).result; 649 ast.Send node,
701 650 ast.Node receiver,
651 Selector selector,
652 _) {
653 return irBuilder.buildDynamicGet(
654 translateReceiver(receiver),
655 selector);
702 } 656 }
703 657
704 ir.Primitive translateLogicalOperator(ast.Operator op, 658 @override
705 ast.Expression left, 659 ir.Primitive visitDynamicTypeLiteralGet(
706 ast.Expression right) { 660 ast.Send node,
661 ConstantExpression constant,
662 _) {
663 return irBuilder.buildConstantLiteral(constant);
664 }
665
666 @override
667 ir.Primitive handleLocalGet(
668 ast.Send node,
669 LocalElement element,
670 _) {
671 return irBuilder.buildLocalGet(element);
672 }
673
674 @override
675 ir.Primitive handleStaticFieldGet(
676 ast.Send node,
677 FieldElement field,
678 _) {
679 return irBuilder.buildStaticGet(field);
680 }
681
682 @override
683 ir.Primitive handleStaticFunctionGet(
684 ast.Send node,
685 MethodElement function,
686 _) {
687 // TODO(karlklose): support foreign functions.
688 if (function.isForeign(compiler.backend)) {
689 return giveup(node, 'handleStaticFunctionGet: foreign: $function');
690 }
691 return irBuilder.buildStaticGet(function);
692 }
693
694 @override
695 ir.Primitive handleStaticGetterGet(
696 ast.Send node,
697 FunctionElement getter,
698 _) {
699 return irBuilder.buildStaticInvocation(getter,
700 new Selector.getter(getter.name, getter.library), const []);
701 }
702
703 @override
704 ir.Primitive visitSuperFieldGet(
705 ast.Send node,
706 FieldElement field,
707 _) {
708 return irBuilder.buildSuperGet(field);
709 }
710
711 @override
712 ir.Primitive visitSuperGetterGet(
713 ast.Send node,
714 FunctionElement getter,
715 _) {
716 return irBuilder.buildSuperGet(getter);
717 }
718
719 @override
720 ir.Primitive visitSuperMethodGet(
721 ast.Send node,
722 MethodElement method,
723 _) {
724 return irBuilder.buildSuperGet(method);
725 }
726
727 @override
728 ir.Primitive visitThisGet(ast.Identifier node, _) {
729 return irBuilder.buildThis();
730 }
731
732 ir.Primitive translateTypeVariableTypeLiteral(TypeVariableElement element) {
733 // TODO(johnniwinther): This should be a method on [IrBuilder].
734 ir.Primitive prim = new ir.ReifyTypeVar(element);
735 irBuilder.add(new ir.LetPrim(prim));
736 return prim;
737 }
738
739 @override
740 ir.Primitive visitTypeVariableTypeLiteralGet(ast.Send node,
741 TypeVariableElement element, _) {
742 return translateTypeVariableTypeLiteral(element);
743 }
744
745 ir.Primitive translateLogicalOperator(ast.Expression left,
746 ast.Expression right,
747 {bool isLazyOr}) {
707 ir.Primitive leftValue = visit(left); 748 ir.Primitive leftValue = visit(left);
708 749
709 ir.Primitive buildRightValue(IrBuilder rightBuilder) { 750 ir.Primitive buildRightValue(IrBuilder rightBuilder) {
710 return withBuilder(rightBuilder, () => visit(right)); 751 return withBuilder(rightBuilder, () => visit(right));
711 } 752 }
712 753
713 return irBuilder.buildLogicalOperator( 754 return irBuilder.buildLogicalOperator(
714 leftValue, buildRightValue, isLazyOr: op.source == '||'); 755 leftValue, buildRightValue, isLazyOr: isLazyOr);
715 } 756 }
716 757
717 ir.Primitive visitOperatorSend(ast.Send node) { 758 @override
718 assert(irBuilder.isOpen); 759 ir.Primitive visitLogicalAnd(
719 ast.Operator op = node.selector; 760 ast.Send node, ast.Node left, ast.Node right, _) {
720 if (isUserDefinableOperator(op.source)) { 761 return translateLogicalOperator(left, right, isLazyOr: false);
721 return visitDynamicSend(node); 762 }
722 } 763
723 if (op.source == '&&' || op.source == '||') { 764 @override
724 assert(node.receiver != null); 765 ir.Primitive visitLogicalOr(
725 assert(!node.arguments.isEmpty); 766 ast.Send node, ast.Node left, ast.Node right, _) {
726 assert(node.arguments.tail.isEmpty); 767 return translateLogicalOperator(left, right, isLazyOr: true);
727 return translateLogicalOperator(op, node.receiver, node.arguments.head); 768 }
728 } 769
729 if (op.source == "!") { 770 @override
730 assert(node.receiver != null); 771 ir.Primitive visitAs(
731 assert(node.arguments.isEmpty); 772 ast.Send node,
732 return irBuilder.buildNegation(visit(node.receiver)); 773 ast.Node expression,
733 } 774 DartType type,
734 if (op.source == "!=") { 775 _) {
735 assert(node.receiver != null); 776 ir.Primitive receiver = visit(expression);
736 assert(!node.arguments.isEmpty); 777 return irBuilder.buildTypeOperator(receiver, type, isTypeTest: false);
737 assert(node.arguments.tail.isEmpty); 778 }
738 return irBuilder.buildNegation(visitDynamicSend(node)); 779
739 } 780 @override
740 assert(invariant(node, op.source == "is" || op.source == "as", 781 ir.Primitive visitIs(
741 message: "unexpected operator $op")); 782 ast.Send node,
742 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); 783 ast.Node expression,
743 ir.Primitive receiver = visit(node.receiver); 784 DartType type,
785 _) {
786 ir.Primitive receiver = visit(expression);
744 return irBuilder.buildTypeOperator( 787 return irBuilder.buildTypeOperator(
745 receiver, type, 788 receiver, type,
746 isTypeTest: op.source == "is", 789 isTypeTest: true,
747 isNotCheck: node.isIsNotCheck); 790 isNotCheck: false);
748 } 791 }
749 792
750 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]] 793 @override
751 // where (C', xs) = arguments.fold(Build, C) 794 ir.Primitive visitIsNot(ast.Send node,
752 ir.Primitive visitStaticSend(ast.Send node) { 795 ast.Node expression, DartType type, _) {
753 assert(irBuilder.isOpen); 796 ir.Primitive receiver = visit(expression);
754 Element element = elements[node]; 797 return irBuilder.buildTypeOperator(
755 assert(!element.isConstructor); 798 receiver, type,
756 // TODO(lry): support foreign functions. 799 isTypeTest: true,
757 if (element.isForeign(compiler.backend)) { 800 isNotCheck: true);
758 return giveup(node, 'StaticSend: foreign'); 801 }
802
803 ir.Primitive translateBinary(ast.Node left,
804 op.BinaryOperator operator,
805 ast.Node right) {
806 Selector selector = new Selector.binaryOperator(operator.selectorName);
807 ir.Primitive receiver = visit(left);
808 List<ir.Primitive> arguments = [visit(right)];
809 arguments = normalizeDynamicArguments(selector, arguments);
810 return irBuilder.buildDynamicInvocation(receiver, selector, arguments);
811 }
812
813 @override
814 ir.Primitive visitBinary(ast.Send node,
815 ast.Node left,
816 op.BinaryOperator operator,
817 ast.Node right, _) {
818 return translateBinary(left, operator, right);
819 }
820
821 @override
822 ir.Primitive visitIndex(ast.Send node,
823 ast.Node receiver,
824 ast.Node index, _) {
825 Selector selector = new Selector.index();
826 ir.Primitive target = visit(receiver);
827 List<ir.Primitive> arguments = [visit(index)];
828 arguments = normalizeDynamicArguments(selector, arguments);
829 return irBuilder.buildDynamicInvocation(target, selector, arguments);
830 }
831
832 ir.Primitive translateSuperBinary(FunctionElement function,
833 op.BinaryOperator operator,
834 ast.Node argument) {
835 Selector selector = new Selector.binaryOperator(operator.selectorName);
836 List<ir.Primitive> arguments = [visit(argument)];
837 arguments = normalizeDynamicArguments(selector, arguments);
838 return irBuilder.buildSuperInvocation(function, selector, arguments);
839 }
840
841 @override
842 ir.Primitive visitSuperBinary(
843 ast.Send node,
844 FunctionElement function,
845 op.BinaryOperator operator,
846 ast.Node argument,
847 _) {
848 return translateSuperBinary(function, operator, argument);
849 }
850
851 @override
852 ir.Primitive visitSuperIndex(
853 ast.Send node,
854 FunctionElement function,
855 ast.Node index,
856 _) {
857 Selector selector = new Selector.index();
858 List<ir.Primitive> arguments = [visit(index)];
859 arguments = normalizeDynamicArguments(selector, arguments);
860 return irBuilder.buildSuperInvocation(function, selector, arguments);
861 }
862
863 @override
864 ir.Primitive visitEquals(
865 ast.Send node,
866 ast.Node left,
867 ast.Node right,
868 _) {
869 return translateBinary(left, op.BinaryOperator.EQ, right);
870 }
871
872 @override
873 ir.Primitive visitSuperEquals(
874 ast.Send node,
875 FunctionElement function,
876 ast.Node argument,
877 _) {
878 return translateSuperBinary(function, op.BinaryOperator.EQ, argument);
879 }
880
881 @override
882 ir.Primitive visitNot(
883 ast.Send node,
884 ast.Node expression,
885 _) {
886 return irBuilder.buildNegation(visit(expression));
887 }
888
889 @override
890 ir.Primitive visitNotEquals(
891 ast.Send node,
892 ast.Node left,
893 ast.Node right,
894 _) {
895 return irBuilder.buildNegation(
896 translateBinary(left, op.BinaryOperator.NOT_EQ, right));
897 }
898
899 @override
900 ir.Primitive visitSuperNotEquals(
901 ast.Send node,
902 FunctionElement function,
903 ast.Node argument,
904 _) {
905 return irBuilder.buildNegation(
906 translateSuperBinary(function, op.BinaryOperator.NOT_EQ, argument));
907 }
908
909 @override
910 ir.Primitive visitUnary(ast.Send node,
911 op.UnaryOperator operator, ast.Node expression, _) {
912 // TODO(johnniwinther): Clean up the creation of selectors.
913 Selector selector =
914 new Selector(SelectorKind.OPERATOR, operator.selectorName, null, 0);
915 ir.Primitive receiver = translateReceiver(expression);
916 return irBuilder.buildDynamicInvocation(receiver, selector, const []);
917 }
918
919 @override
920 ir.Primitive visitSuperUnary(
921 ast.Send node,
922 op.UnaryOperator operator,
923 FunctionElement function,
924 _) {
925 // TODO(johnniwinther): Clean up the creation of selectors.
926 Selector selector =
927 new Selector(SelectorKind.OPERATOR, operator.selectorName, null, 0);
928 return irBuilder.buildSuperInvocation(function, selector, const []);
929 }
930
931 // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
932 // semantic correlation between arguments and invocation.
933 List<ir.Primitive> translateDynamicArguments(ast.NodeList nodeList,
934 Selector selector) {
935 List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit);
936 return normalizeDynamicArguments(selector, arguments);
937 }
938
939 // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
940 // semantic correlation between arguments and invocation.
941 List<ir.Primitive> translateStaticArguments(ast.NodeList nodeList,
942 Element element,
943 Selector selector) {
944 List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit);
945 return normalizeStaticArguments(selector, element, arguments);
946 }
947
948 ir.Primitive translateCallInvoke(ir.Primitive target,
949 ast.NodeList arguments,
950 Selector selector) {
951
952 return irBuilder.buildCallInvocation(target, selector,
953 translateDynamicArguments(arguments, selector));
954 }
955
956 ir.Primitive translateConstantInvoke(ConstantExpression constant,
957 ast.NodeList arguments,
958 Selector selector) {
959 return translateCallInvoke(
960 irBuilder.buildConstantLiteral(constant),
961 arguments,
962 selector);
963 }
964
965 @override
966 ir.Primitive handleConstantInvoke(
967 ast.Send node,
968 ConstantExpression constant,
969 ast.NodeList arguments,
970 Selector selector,
971 _) {
972 return translateConstantInvoke(constant, arguments, selector);
973 }
974
975 @override
976 ir.Primitive handleDynamicInvoke(
977 ast.Send node,
978 ast.Node receiver,
979 ast.NodeList arguments,
980 Selector selector,
981 _) {
982 return irBuilder.buildDynamicInvocation(
983 translateReceiver(receiver), selector,
984 translateDynamicArguments(arguments, selector));
985 }
986
987 ir.Primitive handleLocalInvoke(
988 ast.Send node,
989 LocalElement element,
990 ast.NodeList arguments,
991 Selector selector,
992 _) {
993 return irBuilder.buildLocalInvocation(element, selector,
994 translateDynamicArguments(arguments, selector));
995 }
996
997 @override
998 ir.Primitive handleStaticFieldInvoke(
999 ast.Send node,
1000 FieldElement field,
1001 ast.NodeList arguments,
1002 Selector selector,
1003 _) {
1004 return translateCallInvoke(
1005 irBuilder.buildStaticGet(field),
1006 arguments, selector);
1007 }
1008
1009 @override
1010 ir.Primitive handleStaticFunctionInvoke(
1011 ast.Send node,
1012 MethodElement function,
1013 ast.NodeList arguments,
1014 Selector selector,
1015 _) {
1016 // TODO(karlklose): support foreign functions.
1017 if (function.isForeign(compiler.backend)) {
1018 return giveup(node, 'handleStaticFunctionInvoke: foreign: $function');
759 } 1019 }
760 1020 return irBuilder.buildStaticInvocation(function, selector,
761 Selector selector = elements.getSelector(node); 1021 translateStaticArguments(arguments, function, selector));
762 1022 }
763 if (selector.isCall && (element.isGetter || element.isField)) { 1023
764 // We are invoking a static field or getter as if it was a method, e.g: 1024 @override
765 // 1025 ir.Primitive handleStaticGetterInvoke(
766 // get foo => {..} 1026 ast.Send node,
767 // main() { foo(1, 2, 3); } 1027 FunctionElement getter,
768 // 1028 ast.NodeList arguments,
769 // We invoke the getter of 'foo' and then invoke the 'call' method 1029 Selector selector,
770 // on the result, using the given arguments. 1030 _) {
771 Selector getter = new Selector.getterFrom(selector); 1031 return translateCallInvoke(
772 Selector call = new Selector.callClosureFrom(selector); 1032 irBuilder.buildStaticGet(getter),
773 ir.Primitive receiver = irBuilder.buildStaticGet(element, getter); 1033 arguments, selector);
774 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 1034 }
775 arguments = normalizeDynamicArguments(selector, arguments); 1035
776 return irBuilder.buildCallInvocation(receiver, call, arguments); 1036 @override
777 } else if (selector.isGetter) { 1037 ir.Primitive visitSuperFieldInvoke(
778 // We are reading a static field or invoking a static getter. 1038 ast.Send node,
779 return irBuilder.buildStaticGet(element, selector); 1039 FieldElement field,
780 } else { 1040 ast.NodeList arguments,
781 // We are invoking a static method. 1041 Selector selector,
782 assert(selector.isCall); 1042 _) {
783 assert(element is FunctionElement); 1043 return translateCallInvoke(
784 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 1044 irBuilder.buildSuperGet(field),
785 arguments = normalizeStaticArguments(selector, element, arguments); 1045 arguments, selector);
786 return irBuilder.buildStaticInvocation(element, selector, arguments, 1046 }
787 sourceInformation: sourceInformationBuilder.buildCall(node)); 1047
788 } 1048 @override
789 } 1049 ir.Primitive visitSuperGetterInvoke(
790 1050 ast.Send node,
791 ir.Primitive visitSuperSend(ast.Send node) { 1051 FunctionElement getter,
792 assert(irBuilder.isOpen); 1052 ast.NodeList arguments,
793 Selector selector = elements.getSelector(node); 1053 Selector selector,
794 Element target = elements[node]; 1054 _) {
795 1055 return translateCallInvoke(
796 if (selector.isCall && (target.isGetter || target.isField)) { 1056 irBuilder.buildStaticGet(getter),
797 // We are invoking a field or getter as if it was a method, e.g: 1057 arguments, selector);
798 // 1058 }
799 // class A { get foo => {..} } 1059
800 // class B extends A { 1060 @override
801 // m() { 1061 ir.Primitive visitSuperMethodInvoke(
802 // super.foo(1, 2, 3); } 1062 ast.Send node,
803 // } 1063 MethodElement method,
804 // } 1064 ast.NodeList arguments,
805 // 1065 Selector selector,
806 // We invoke the getter of 'foo' and then invoke the 'call' method on 1066 _) {
807 // the result, using the given arguments. 1067 return irBuilder.buildStaticInvocation(method, selector,
808 Selector getter = new Selector.getterFrom(selector); 1068 translateDynamicArguments(arguments, selector));
809 Selector call = new Selector.callClosureFrom(selector); 1069 }
810 ir.Primitive receiver = 1070
811 irBuilder.buildSuperInvocation(target, getter, []); 1071 @override
812 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 1072 ir.Primitive visitThisInvoke(
813 arguments = normalizeDynamicArguments(selector, arguments); 1073 ast.Send node,
814 return irBuilder.buildCallInvocation(receiver, call, arguments); 1074 ast.NodeList arguments,
815 } else if (selector.isCall) { 1075 Selector selector,
816 // We are invoking a method. 1076 _) {
817 assert(target is FunctionElement); 1077 return translateCallInvoke(irBuilder.buildThis(), arguments, selector);
818 List<ir.Primitive> arguments = node.arguments.mapToList(visit); 1078 }
819 arguments = normalizeStaticArguments(selector, target, arguments); 1079
820 return irBuilder.buildSuperInvocation(target, selector, arguments); 1080 @override
821 } else { 1081 ir.Primitive visitTypeVariableTypeLiteralInvoke(
822 // We are invoking a getter, operator, indexer, etc. 1082 ast.Send node,
823 List<ir.Primitive> arguments = node.argumentsNode == null 1083 TypeVariableElement element,
824 ? <ir.Primitive>[] 1084 ast.NodeList arguments,
825 : node.arguments.mapToList(visit); 1085 Selector selector,
826 return irBuilder.buildSuperInvocation(target, selector, arguments); 1086 _) {
827 } 1087 return translateCallInvoke(
828 } 1088 translateTypeVariableTypeLiteral(element),
829 1089 arguments,
830 visitTypePrefixSend(ast.Send node) { 1090 selector);
831 compiler.internalError(node, "visitTypePrefixSend should not be called."); 1091 }
832 } 1092
833 1093 @override
834 ir.Primitive visitTypeLiteralSend(ast.Send node) { 1094 ir.Primitive visitTypedefTypeLiteralInvoke(
835 assert(irBuilder.isOpen); 1095 ast.Send node,
836 // If the user is trying to invoke the type literal or variable, 1096 TypeConstantExpression constant,
837 // it must be treated as a function call. 1097 ast.NodeList arguments,
838 if (node.argumentsNode != null) { 1098 Selector selector, _) {
839 // TODO(sigurdm): Handle this to match proposed semantics of issue #19725. 1099 return translateConstantInvoke(constant, arguments, selector);
840 return giveup(node, 'Type literal invoked as function');
841 }
842
843 DartType type = elements.getTypeLiteralType(node);
844 if (type is TypeVariableType) {
845 return buildReifyTypeVariable(irBuilder.buildThis(), type);
846 } else {
847 return translateConstant(node);
848 }
849 } 1100 }
850 1101
851 ir.Primitive buildReifyTypeVariable(ir.Primitive target, 1102 ir.Primitive buildReifyTypeVariable(ir.Primitive target,
852 TypeVariableType variable); 1103 TypeVariableType variable);
853 1104
854 ir.Primitive visitSendSet(ast.SendSet node) { 1105 @override
855 assert(irBuilder.isOpen); 1106 ir.Primitive visitIndexSet(
856 Element element = elements[node]; 1107 ast.SendSet node,
857 ast.Operator op = node.assignmentOperator; 1108 ast.Node receiver,
858 // For complex operators, this is the result of getting (before assigning) 1109 ast.Node index,
859 ir.Primitive originalValue; 1110 ast.Node rhs,
860 // For []+= style operators, this saves the index. 1111 _) {
861 ir.Primitive index; 1112 return irBuilder.buildDynamicIndexSet(
862 ir.Primitive receiver; 1113 visit(receiver), visit(index), visit(rhs));
863 // This is what gets assigned. 1114 }
864 ir.Primitive valueToStore; 1115
865 Selector selector = elements.getSelector(node); 1116 @override
1117 ir.Primitive visitSuperIndexSet(
1118 ast.SendSet node,
1119 FunctionElement function,
1120 ast.Node index,
1121 ast.Node rhs,
1122 _) {
1123 return irBuilder.buildSuperIndexSet(function, visit(index), visit(rhs));
1124 }
1125
1126 @override
1127 ir.Primitive visitCompoundIndexSet(
1128 ast.SendSet node,
1129 ast.Node receiver,
1130 ast.Node index,
1131 op.AssignmentOperator operator,
1132 ast.Node rhs,
1133 _) {
1134 ir.Primitive target = visit(receiver);
1135 ir.Primitive indexValue = visit(index);
1136 return translateCompound(
1137 getValue: () {
1138 Selector selector =
1139 new Selector.binaryOperator(operator.selectorName);
1140 List<ir.Primitive> arguments = [indexValue];
1141 arguments = normalizeDynamicArguments(selector, arguments);
1142 return irBuilder.buildDynamicInvocation(target, selector, arguments);
1143 },
1144 operator: operator,
1145 rhs: rhs,
1146 setValue: (ir.Primitive result) {
1147 irBuilder.buildDynamicIndexSet(target, indexValue, result);
1148 });
1149 }
1150
1151 @override
1152 ir.Primitive visitSuperCompoundIndexSet(
1153 ast.SendSet node,
1154 FunctionElement getter,
1155 FunctionElement setter,
1156 ast.Node index,
1157 op.AssignmentOperator operator,
1158 ast.Node rhs,
1159 _) {
1160 ir.Primitive indexValue = visit(index);
1161 return translateCompound(
1162 getValue: () {
1163 Selector selector =
1164 new Selector.binaryOperator(operator.selectorName);
1165 List<ir.Primitive> arguments = [indexValue];
1166 arguments = normalizeDynamicArguments(selector, arguments);
1167 return irBuilder.buildSuperInvocation(getter, selector, arguments);
1168 },
1169 operator: operator,
1170 rhs: rhs,
1171 setValue: (ir.Primitive result) {
1172 irBuilder.buildSuperIndexSet(setter, indexValue, result);
1173 });
1174 }
1175
1176 ir.Primitive translatePrefixPostfix(
1177 {ir.Primitive getValue(),
1178 op.IncDecOperator operator,
1179 void setValue(ir.Primitive value),
1180 bool isPrefix}) {
1181 ir.Primitive value = getValue();
866 Selector operatorSelector = 1182 Selector operatorSelector =
867 elements.getOperatorSelectorInComplexSendSet(node); 1183 new Selector.binaryOperator(operator.selectorName);
868 Selector getterSelector = 1184 List<ir.Primitive> arguments = [irBuilder.buildIntegerLiteral(1)];
869 elements.getGetterSelectorInComplexSendSet(node); 1185 arguments = normalizeDynamicArguments(operatorSelector, arguments);
870 assert( 1186 ir.Primitive result =
871 // Indexing send-sets have an argument for the index. 1187 irBuilder.buildDynamicInvocation(value, operatorSelector, arguments);
872 (selector.isIndexSet ? 1 : 0) + 1188 setValue(result);
873 // Non-increment send-sets have one more argument. 1189 return isPrefix ? result : value;
874 (ast.Operator.INCREMENT_OPERATORS.contains(op.source) ? 0 : 1) 1190 }
875 == node.argumentCount()); 1191
876 1192 ir.Primitive translateCompound(
877 ast.Node getAssignArgument() { 1193 {ir.Primitive getValue(),
878 assert(invariant(node, !node.arguments.isEmpty, 1194 op.AssignmentOperator operator,
879 message: "argument expected")); 1195 ast.Node rhs,
880 return selector.isIndexSet 1196 void setValue(ir.Primitive value)}) {
881 ? node.arguments.tail.head 1197 ir.Primitive value = getValue();
882 : node.arguments.head; 1198 Selector operatorSelector =
883 } 1199 new Selector.binaryOperator(operator.selectorName);
884 1200 List<ir.Primitive> arguments = [visit(rhs)];
885 // Get the value into valueToStore 1201 arguments = normalizeDynamicArguments(operatorSelector, arguments);
886 if (op.source == "=") { 1202 ir.Primitive result =
887 if (selector.isIndexSet) { 1203 irBuilder.buildDynamicInvocation(value, operatorSelector, arguments);
888 receiver = visitReceiver(node.receiver); 1204 setValue(result);
889 index = visit(node.arguments.head); 1205 return result;
890 } else if (element == null || Elements.isInstanceField(element)) { 1206 }
891 receiver = visitReceiver(node.receiver); 1207
892 } 1208 @override
893 valueToStore = visit(getAssignArgument()); 1209 ir.Primitive handleDynamicCompound(
894 } else { 1210 ast.Send node,
895 // Get the original value into getter 1211 ast.Node receiver,
896 assert(ast.Operator.COMPLEX_OPERATORS.contains(op.source)); 1212 op.AssignmentOperator operator,
897 1213 ast.Node rhs,
898 _GetterElements getterResult = translateGetter(node, getterSelector); 1214 Selector getterSelector,
899 index = getterResult.index; 1215 Selector setterSelector,
900 receiver = getterResult.receiver; 1216 _) {
901 originalValue = getterResult.result; 1217 ir.Primitive target = translateReceiver(receiver);
902 1218 return translateCompound(
903 // Do the modification of the value in getter. 1219 getValue: () => irBuilder.buildDynamicGet(target, getterSelector),
904 ir.Primitive arg; 1220 operator: operator,
905 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source)) { 1221 rhs: rhs,
906 arg = irBuilder.buildIntegerLiteral(1); 1222 setValue: (ir.Primitive result) {
907 } else { 1223 irBuilder.buildDynamicSet(target, setterSelector, result);
908 arg = visit(getAssignArgument()); 1224 });
909 } 1225 }
910 valueToStore = new ir.Parameter(null); 1226
911 ir.Continuation k = new ir.Continuation([valueToStore]); 1227 @override
912 ir.Expression invoke = 1228 ir.Primitive handleDynamicPostfixPrefix(
913 new ir.InvokeMethod(originalValue, operatorSelector, k, [arg]); 1229 ast.Send node,
914 irBuilder.add(new ir.LetCont(k, invoke)); 1230 ast.Node receiver,
915 } 1231 op.IncDecOperator operator,
916 1232 Selector getterSelector,
917 if (Elements.isLocal(element)) { 1233 Selector setterSelector,
918 irBuilder.buildLocalSet(element, valueToStore); 1234 arg,
919 } else if ((!node.isSuperCall && Elements.isErroneous(element)) || 1235 {bool isPrefix}) {
920 Elements.isStaticOrTopLevel(element)) { 1236 ir.Primitive target = translateReceiver(receiver);
921 irBuilder.buildStaticSet( 1237 return translatePrefixPostfix(
922 element, elements.getSelector(node), valueToStore); 1238 getValue: () => irBuilder.buildDynamicGet(target, getterSelector),
923 } else { 1239 operator: operator,
924 // Setter or index-setter invocation 1240 setValue: (ir.Primitive result) {
925 Selector selector = elements.getSelector(node); 1241 irBuilder.buildDynamicSet(target, setterSelector, result);
926 assert(selector.kind == SelectorKind.SETTER || 1242 },
927 selector.kind == SelectorKind.INDEX); 1243 isPrefix: isPrefix);
928 if (selector.isIndexSet) { 1244 }
929 if (isSuperCall(node)) { 1245
930 irBuilder.buildSuperIndexSet(element, index, valueToStore); 1246 @override
931 } else { 1247 ir.Primitive handleDynamicSet(
932 irBuilder.buildDynamicIndexSet(receiver, index, valueToStore); 1248 ast.SendSet node,
933 } 1249 ast.Node receiver,
934 } else { 1250 Selector selector,
935 if (isSuperCall(node)) { 1251 ast.Node rhs,
936 irBuilder.buildSuperSet(element, selector, valueToStore); 1252 _) {
937 } else { 1253 return irBuilder.buildDynamicSet(
938 irBuilder.buildDynamicSet(receiver, selector, valueToStore); 1254 translateReceiver(receiver),
939 } 1255 selector,
940 } 1256 visit(rhs));
941 } 1257 }
942 1258
943 if (node.isPostfix) { 1259 @override
944 assert(originalValue != null); 1260 ir.Primitive handleLocalCompound(
945 return originalValue; 1261 ast.Send node,
946 } else { 1262 LocalElement element,
947 return valueToStore; 1263 op.AssignmentOperator operator,
948 } 1264 ast.Node rhs,
1265 _) {
1266 return translateCompound(
1267 getValue: () => irBuilder.buildLocalGet(element),
1268 operator: operator,
1269 rhs: rhs,
1270 setValue: (ir.Primitive result) {
1271 irBuilder.buildLocalSet(element, result);
1272 });
1273 }
1274
1275 @override
1276 ir.Primitive handleLocalPostfixPrefix(
1277 ast.Send node,
1278 LocalElement element,
1279 op.IncDecOperator operator,
1280 arg,
1281 {bool isPrefix}) {
1282 return translatePrefixPostfix(
1283 getValue: () => irBuilder.buildLocalGet(element),
1284 operator: operator,
1285 setValue: (ir.Primitive result) {
1286 irBuilder.buildLocalSet(element, result);
1287 },
1288 isPrefix: isPrefix);
1289 }
1290
1291 @override
1292 ir.Primitive handleLocalSet(
1293 ast.SendSet node,
1294 LocalElement element,
1295 ast.Node rhs,
1296 _) {
1297 return irBuilder.buildLocalSet(element, visit(rhs));
1298 }
1299
1300 @override
1301 ir.Primitive handleStaticFieldCompound(
1302 ast.Send node,
1303 FieldElement field,
1304 op.AssignmentOperator operator,
1305 ast.Node rhs,
1306 _) {
1307 return translateCompound(
1308 getValue: () => irBuilder.buildStaticGet(field),
1309 operator: operator,
1310 rhs: rhs,
1311 setValue: (ir.Primitive result) {
1312 irBuilder.buildStaticSet(field, result);
1313 });
1314 }
1315
1316 @override
1317 ir.Primitive handleStaticFieldPostfixPrefix(
1318 ast.Send node,
1319 FieldElement field,
1320 op.IncDecOperator operator,
1321 arg,
1322 {bool isPrefix}) {
1323 return translatePrefixPostfix(
1324 getValue: () => irBuilder.buildStaticGet(field),
1325 operator: operator,
1326 setValue: (ir.Primitive result) {
1327 irBuilder.buildStaticSet(field, result);
1328 },
1329 isPrefix: isPrefix);
1330 }
1331
1332 @override
1333 ir.Primitive handleStaticFieldSet(
1334 ast.SendSet node,
1335 FieldElement field,
1336 ast.Node rhs,
1337 _) {
1338 return irBuilder.buildStaticSet(field, visit(rhs));
1339 }
1340
1341 @override
1342 ir.Primitive visitSuperFieldSet(
1343 ast.SendSet node,
1344 FieldElement field,
1345 ast.Node rhs,
1346 _) {
1347 return irBuilder.buildSuperSet(field, visit(rhs));
1348 }
1349
1350 @override
1351 ir.Primitive visitSuperSetterSet(
1352 ast.SendSet node,
1353 FunctionElement setter,
1354 ast.Node rhs,
1355 _) {
1356 return irBuilder.buildSuperSet(setter, visit(rhs));
1357 }
1358
1359 @override
1360 ir.Primitive handleStaticGetterSetterCompound(
1361 ast.Send node,
1362 FunctionElement getter,
1363 FunctionElement setter,
1364 op.AssignmentOperator operator,
1365 ast.Node rhs,
1366 _) {
1367 return translateCompound(
1368 getValue: () => irBuilder.buildStaticGet(getter),
1369 operator: operator,
1370 rhs: rhs,
1371 setValue: (ir.Primitive result) {
1372 irBuilder.buildStaticSet(setter, result);
1373 });
1374 }
1375
1376 @override
1377 ir.Primitive handleSuperFieldFieldPostfixPrefix(
1378 ast.Send node,
1379 FieldElement readField,
1380 FieldElement writtenField,
1381 op.IncDecOperator operator,
1382 arg,
1383 {bool isPrefix}) {
1384 return translatePrefixPostfix(
1385 getValue: () => irBuilder.buildSuperGet(readField),
1386 operator: operator,
1387 setValue: (ir.Primitive result) {
1388 irBuilder.buildSuperSet(writtenField, result);
1389 },
1390 isPrefix: isPrefix);
1391 }
1392
1393 @override
1394 ir.Primitive handleSuperFieldSetterPostfixPrefix(
1395 ast.Send node,
1396 FieldElement field,
1397 FunctionElement setter,
1398 op.IncDecOperator operator,
1399 arg,
1400 {bool isPrefix}) {
1401 return translatePrefixPostfix(
1402 getValue: () => irBuilder.buildSuperGet(field),
1403 operator: operator,
1404 setValue: (ir.Primitive result) {
1405 irBuilder.buildSuperSet(setter, result);
1406 },
1407 isPrefix: isPrefix);
1408 }
1409
1410 @override
1411 ir.Primitive handleSuperGetterFieldPostfixPrefix(
1412 ast.Send node,
1413 FunctionElement getter,
1414 FieldElement field,
1415 op.IncDecOperator operator,
1416 arg,
1417 {bool isPrefix}) {
1418 return translatePrefixPostfix(
1419 getValue: () => irBuilder.buildSuperGet(getter),
1420 operator: operator,
1421 setValue: (ir.Primitive result) {
1422 irBuilder.buildSuperSet(field, result);
1423 },
1424 isPrefix: isPrefix);
1425 }
1426
1427 @override
1428 ir.Primitive handleSuperGetterSetterPostfixPrefix(
1429 ast.Send node,
1430 FunctionElement getter,
1431 FunctionElement setter,
1432 op.IncDecOperator operator,
1433 arg,
1434 {bool isPrefix}) {
1435 return translatePrefixPostfix(
1436 getValue: () => irBuilder.buildSuperGet(getter),
1437 operator: operator,
1438 setValue: (ir.Primitive result) {
1439 irBuilder.buildSuperSet(setter, result);
1440 },
1441 isPrefix: isPrefix);
1442 }
1443
1444 @override
1445 ir.Primitive handleSuperMethodSetterPostfixPrefix(
1446 ast.Send node,
1447 FunctionElement method,
1448 FunctionElement setter,
1449 op.IncDecOperator operator,
1450 arg,
1451 {bool isPrefix}) {
1452 return translatePrefixPostfix(
1453 getValue: () => irBuilder.buildSuperGet(method),
1454 operator: operator,
1455 setValue: (ir.Primitive result) {
1456 irBuilder.buildSuperSet(setter, result);
1457 },
1458 isPrefix: isPrefix);
1459 }
1460
1461 @override
1462 ir.Primitive handleStaticGetterSetterPostfixPrefix(
1463 ast.Send node,
1464 FunctionElement getter,
1465 FunctionElement setter,
1466 op.IncDecOperator operator,
1467 arg,
1468 {bool isPrefix}) {
1469 return translatePrefixPostfix(
1470 getValue: () => irBuilder.buildStaticGet(getter),
1471 operator: operator,
1472 setValue: (ir.Primitive result) {
1473 irBuilder.buildStaticSet(setter, result);
1474 },
1475 isPrefix: isPrefix);
1476 }
1477
1478 @override
1479 ir.Primitive handleStaticMethodSetterCompound(
1480 ast.Send node,
1481 FunctionElement method,
1482 FunctionElement setter,
1483 op.AssignmentOperator operator,
1484 ast.Node rhs,
1485 _) {
1486 return translateCompound(
1487 getValue: () => irBuilder.buildStaticGet(method),
1488 operator: operator,
1489 rhs: rhs,
1490 setValue: (ir.Primitive result) {
1491 irBuilder.buildStaticSet(setter, result);
1492 });
1493 }
1494
1495 @override
1496 ir.Primitive handleStaticMethodSetterPostfixPrefix(
1497 ast.Send node,
1498 FunctionElement getter,
1499 FunctionElement setter,
1500 op.IncDecOperator operator,
1501 arg,
1502 {bool isPrefix}) {
1503 return translatePrefixPostfix(
1504 getValue: () => irBuilder.buildStaticGet(getter),
1505 operator: operator,
1506 setValue: (ir.Primitive result) {
1507 irBuilder.buildStaticSet(setter, result);
1508 },
1509 isPrefix: isPrefix);
1510 }
1511
1512 @override
1513 ir.Primitive handleStaticSetterSet(
1514 ast.SendSet node,
1515 FunctionElement setter,
1516 ast.Node rhs,
1517 _) {
1518 return irBuilder.buildStaticSet(setter, visit(rhs));
1519 }
1520
1521 @override
1522 ir.Primitive visitSuperFieldCompound(
1523 ast.Send node,
1524 FieldElement field,
1525 op.AssignmentOperator operator,
1526 ast.Node rhs,
1527 _) {
1528 return translateCompound(
1529 getValue: () => irBuilder.buildSuperGet(field),
1530 operator: operator,
1531 rhs: rhs,
1532 setValue: (ir.Primitive result) {
1533 irBuilder.buildSuperSet(field, result);
1534 });
1535 }
1536
1537 @override
1538 ir.Primitive visitSuperFieldFieldPostfix(
1539 ast.Send node,
1540 FieldElement readField,
1541 FieldElement writtenField,
1542 op.IncDecOperator operator,
1543 _) {
1544 return translatePrefixPostfix(
1545 getValue: () => irBuilder.buildStaticGet(readField),
1546 operator: operator,
1547 setValue: (ir.Primitive result) {
1548 irBuilder.buildStaticSet(writtenField, result);
1549 },
1550 isPrefix: false);
1551 }
1552
1553 @override
1554 ir.Primitive visitSuperFieldFieldPrefix(
1555 ast.Send node,
1556 FieldElement readField,
1557 FieldElement writtenField,
1558 op.IncDecOperator operator,
1559 _) {
1560 return translatePrefixPostfix(
1561 getValue: () => irBuilder.buildStaticGet(readField),
1562 operator: operator,
1563 setValue: (ir.Primitive result) {
1564 irBuilder.buildStaticSet(writtenField, result);
1565 },
1566 isPrefix: true);
1567 }
1568
1569 @override
1570 ir.Primitive visitSuperFieldSetterCompound(
1571 ast.Send node,
1572 FieldElement field,
1573 FunctionElement setter,
1574 op.AssignmentOperator operator,
1575 ast.Node rhs,
1576 _) {
1577 return translateCompound(
1578 getValue: () => irBuilder.buildSuperGet(field),
1579 operator: operator,
1580 rhs: rhs,
1581 setValue: (ir.Primitive result) {
1582 irBuilder.buildSuperSet(setter, result);
1583 });
1584 }
1585
1586 @override
1587 ir.Primitive visitSuperGetterFieldCompound(
1588 ast.Send node,
1589 FunctionElement getter,
1590 FieldElement field,
1591 op.AssignmentOperator operator,
1592 ast.Node rhs,
1593 _) {
1594 return translateCompound(
1595 getValue: () => irBuilder.buildSuperGet(getter),
1596 operator: operator,
1597 rhs: rhs,
1598 setValue: (ir.Primitive result) {
1599 irBuilder.buildSuperSet(field, result);
1600 });
1601 }
1602
1603 @override
1604 ir.Primitive visitSuperGetterSetterCompound(
1605 ast.Send node,
1606 FunctionElement getter,
1607 FunctionElement setter,
1608 op.AssignmentOperator operator,
1609 ast.Node rhs,
1610 _) {
1611 return translateCompound(
1612 getValue: () => irBuilder.buildSuperGet(getter),
1613 operator: operator,
1614 rhs: rhs,
1615 setValue: (ir.Primitive result) {
1616 irBuilder.buildSuperSet(setter, result);
1617 });
1618 }
1619
1620 @override
1621 ir.Primitive visitSuperMethodSetterCompound(
1622 ast.Send node,
1623 FunctionElement method,
1624 FunctionElement setter,
1625 op.AssignmentOperator operator,
1626 ast.Node rhs,
1627 _) {
1628 return translateCompound(
1629 getValue: () => irBuilder.buildSuperGet(method),
1630 operator: operator,
1631 rhs: rhs,
1632 setValue: (ir.Primitive result) {
1633 irBuilder.buildSuperSet(setter, result);
1634 });
949 } 1635 }
950 1636
951 ir.Primitive visitNewExpression(ast.NewExpression node) { 1637 ir.Primitive visitNewExpression(ast.NewExpression node) {
952 if (node.isConst) { 1638 if (node.isConst) {
953 return translateConstant(node); 1639 return translateConstant(node);
954 } 1640 }
955 FunctionElement element = elements[node.send]; 1641 FunctionElement element = elements[node.send];
956 Selector selector = elements.getSelector(node.send); 1642 Selector selector = elements.getSelector(node.send);
957 DartType type = elements.getType(node); 1643 DartType type = elements.getType(node);
958 ast.Node selectorNode = node.send.selector; 1644 ast.Node selectorNode = node.send.selector;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 try { 1678 try {
993 return action(); 1679 return action();
994 } catch(e, tr) { 1680 } catch(e, tr) {
995 if (e == ABORT_IRNODE_BUILDER) { 1681 if (e == ABORT_IRNODE_BUILDER) {
996 return null; 1682 return null;
997 } 1683 }
998 rethrow; 1684 rethrow;
999 } 1685 }
1000 } 1686 }
1001 1687
1002 void internalError(String reason, {ast.Node node}) { 1688 void internalError(ast.Node node, String message) {
1003 giveup(node); 1689 giveup(node);
1004 } 1690 }
1691
1692 @override
1693 visitNode(ast.Node node) {
1694 internalError(node, "Unhandled node");
1695 }
1005 } 1696 }
1006 1697
1007 final String ABORT_IRNODE_BUILDER = "IrNode builder aborted"; 1698 final String ABORT_IRNODE_BUILDER = "IrNode builder aborted";
1008 1699
1009 dynamic giveup(ast.Node node, [String reason]) { 1700 dynamic giveup(ast.Node node, [String reason]) {
1010 throw ABORT_IRNODE_BUILDER; 1701 throw ABORT_IRNODE_BUILDER;
1011 } 1702 }
1012 1703
1013 /// Classifies local variables and local functions as captured, if they 1704 /// Classifies local variables and local functions as captured, if they
1014 /// are accessed from within a nested function. 1705 /// are accessed from within a nested function.
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after
1843 SourceInformation buildCall(ast.Node node) { 2534 SourceInformation buildCall(ast.Node node) {
1844 return new PositionSourceInformation( 2535 return new PositionSourceInformation(
1845 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); 2536 new TokenSourceLocation(sourceFile, node.getBeginToken(), name));
1846 } 2537 }
1847 2538
1848 @override 2539 @override
1849 SourceInformationBuilder forContext(AstElement element) { 2540 SourceInformationBuilder forContext(AstElement element) {
1850 return new PositionSourceInformationBuilder(element); 2541 return new PositionSourceInformationBuilder(element);
1851 } 2542 }
1852 } 2543 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698