| OLD | NEW |
| 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 Loading... |
| 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 BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>, |
| 129 BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>, |
| 130 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, |
| 131 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, |
| 132 BaseImplementationOfSuperIncDecsMixin<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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 result.add(irBuilder.makeSuperInitializer(target, | 304 result.add(irBuilder.makeSuperInitializer(target, |
| 295 <ir.RunnableBody>[], | 305 <ir.RunnableBody>[], |
| 296 selector)); | 306 selector)); |
| 297 } | 307 } |
| 298 } | 308 } |
| 299 return result; | 309 return result; |
| 300 } | 310 } |
| 301 | 311 |
| 302 ir.Primitive visit(ast.Node node) => node.accept(this); | 312 ir.Primitive visit(ast.Node node) => node.accept(this); |
| 303 | 313 |
| 304 // ==== Statements ==== | 314 // ## Statements ## |
| 305 visitBlock(ast.Block node) { | 315 visitBlock(ast.Block node) { |
| 306 irBuilder.buildBlock(node.statements.nodes, build); | 316 irBuilder.buildBlock(node.statements.nodes, build); |
| 307 } | 317 } |
| 308 | 318 |
| 309 ir.Primitive visitBreakStatement(ast.BreakStatement node) { | 319 ir.Primitive visitBreakStatement(ast.BreakStatement node) { |
| 310 if (!irBuilder.buildBreak(elements.getTargetOf(node))) { | 320 if (!irBuilder.buildBreak(elements.getTargetOf(node))) { |
| 311 compiler.internalError(node, "'break' target not found"); | 321 compiler.internalError(node, "'break' target not found"); |
| 312 } | 322 } |
| 313 return null; | 323 return null; |
| 314 } | 324 } |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 stackTraceVariable: stackTraceVariable, | 492 stackTraceVariable: stackTraceVariable, |
| 483 buildCatchBlock: subbuild(catchClause.block))); | 493 buildCatchBlock: subbuild(catchClause.block))); |
| 484 } | 494 } |
| 485 | 495 |
| 486 irBuilder.buildTry( | 496 irBuilder.buildTry( |
| 487 tryStatementInfo: irBuilder.tryStatements[node], | 497 tryStatementInfo: irBuilder.tryStatements[node], |
| 488 buildTryBlock: subbuild(node.tryBlock), | 498 buildTryBlock: subbuild(node.tryBlock), |
| 489 catchClauseInfos: catchClauseInfos); | 499 catchClauseInfos: catchClauseInfos); |
| 490 } | 500 } |
| 491 | 501 |
| 492 // ==== Expressions ==== | 502 // ## Expressions ## |
| 493 ir.Primitive visitConditional(ast.Conditional node) { | 503 ir.Primitive visitConditional(ast.Conditional node) { |
| 494 return irBuilder.buildConditional( | 504 return irBuilder.buildConditional( |
| 495 build(node.condition), | 505 build(node.condition), |
| 496 subbuild(node.thenExpression), | 506 subbuild(node.thenExpression), |
| 497 subbuild(node.elseExpression)); | 507 subbuild(node.elseExpression)); |
| 498 } | 508 } |
| 499 | 509 |
| 500 // For all simple literals: | 510 // For all simple literals: |
| 501 // Build(Literal(c), C) = C[let val x = Constant(c) in [], x] | 511 // Build(Literal(c), C) = C[let val x = Constant(c) in [], x] |
| 502 ir.Primitive visitLiteralBool(ast.LiteralBool node) { | 512 ir.Primitive visitLiteralBool(ast.LiteralBool node) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 591 assert(irBuilder.isOpen); | 601 assert(irBuilder.isOpen); |
| 592 var oldCascadeReceiver = _currentCascadeReceiver; | 602 var oldCascadeReceiver = _currentCascadeReceiver; |
| 593 // Throw away the result of visiting the expression. | 603 // Throw away the result of visiting the expression. |
| 594 // Instead we return the result of visiting the CascadeReceiver. | 604 // Instead we return the result of visiting the CascadeReceiver. |
| 595 this.visit(node.expression); | 605 this.visit(node.expression); |
| 596 ir.Primitive receiver = _currentCascadeReceiver; | 606 ir.Primitive receiver = _currentCascadeReceiver; |
| 597 _currentCascadeReceiver = oldCascadeReceiver; | 607 _currentCascadeReceiver = oldCascadeReceiver; |
| 598 return receiver; | 608 return receiver; |
| 599 } | 609 } |
| 600 | 610 |
| 601 // ==== Sends ==== | 611 // ## Sends ## |
| 602 ir.Primitive visitAssert(ast.Send node) { | 612 @override |
| 613 ir.Primitive visitAssert( |
| 614 ast.Send node, |
| 615 ast.Node condition, |
| 616 _) { |
| 603 assert(irBuilder.isOpen); | 617 assert(irBuilder.isOpen); |
| 604 return giveup(node, 'Assert'); | 618 return giveup(node, 'Assert'); |
| 605 } | 619 } |
| 606 | 620 |
| 607 ir.Primitive visitNamedArgument(ast.NamedArgument node) { | 621 ir.Primitive visitNamedArgument(ast.NamedArgument node) { |
| 608 assert(irBuilder.isOpen); | 622 assert(irBuilder.isOpen); |
| 609 return visit(node.expression); | 623 return visit(node.expression); |
| 610 } | 624 } |
| 611 | 625 |
| 612 ir.Primitive visitClosureSend(ast.Send node) { | 626 @override |
| 613 assert(irBuilder.isOpen); | 627 ir.Primitive visitExpressionInvoke(ast.Send node, |
| 614 Element element = elements[node]; | 628 ast.Node expression, |
| 615 Selector selector = elements.getSelector(node); | 629 ast.NodeList arguments, |
| 616 ir.Primitive receiver = (element == null) | 630 Selector selector, _) { |
| 617 ? visit(node.selector) | 631 ir.Primitive receiver = visit(expression); |
| 618 : irBuilder.buildLocalGet(element); | |
| 619 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 632 List<ir.Primitive> arguments = node.arguments.mapToList(visit); |
| 620 arguments = normalizeDynamicArguments(selector, arguments); | 633 arguments = normalizeDynamicArguments(selector, arguments); |
| 621 return irBuilder.buildCallInvocation(receiver, selector, arguments); | 634 return irBuilder.buildCallInvocation(receiver, selector, arguments); |
| 622 } | 635 } |
| 623 | 636 |
| 624 /// If [node] is null, returns this. | |
| 625 /// If [node] is super, returns null (for special handling) | |
| 626 /// Otherwise visits [node] and returns the result. | |
| 627 ir.Primitive visitReceiver(ast.Expression node) { | |
| 628 if (node == null) return irBuilder.buildThis(); | |
| 629 if (node.isSuper()) return null; | |
| 630 return visit(node); | |
| 631 } | |
| 632 | |
| 633 /// Returns `true` if [node] is a super call. | 637 /// Returns `true` if [node] is a super call. |
| 634 // TODO(johnniwinther): Remove the need for this. | 638 // TODO(johnniwinther): Remove the need for this. |
| 635 bool isSuperCall(ast.Send node) { | 639 bool isSuperCall(ast.Send node) { |
| 636 return node != null && node.receiver != null && node.receiver.isSuper(); | 640 return node != null && node.receiver != null && node.receiver.isSuper(); |
| 637 } | 641 } |
| 638 | 642 |
| 639 ir.Primitive visitDynamicSend(ast.Send node) { | 643 @override |
| 640 assert(irBuilder.isOpen); | 644 ir.Primitive handleConstantGet(ast.Send node, |
| 641 Selector selector = elements.getSelector(node); | 645 ConstantExpression constant, _) { |
| 642 ir.Primitive receiver = visitReceiver(node.receiver); | 646 return irBuilder.buildConstantLiteral(constant); |
| 643 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | |
| 644 arguments = normalizeDynamicArguments(selector, arguments); | |
| 645 return irBuilder.buildDynamicInvocation(receiver, selector, arguments); | |
| 646 } | 647 } |
| 647 | 648 |
| 648 _GetterElements translateGetter(ast.Send node, Selector selector) { | 649 /// If [node] is null, returns this. |
| 649 Element element = elements[node]; | 650 /// Otherwise visits [node] and returns the result. |
| 650 ir.Primitive result; | 651 ir.Primitive translateReceiver(ast.Expression node) { |
| 651 ir.Primitive receiver; | 652 return node != null ? visit(node) : irBuilder.buildThis(); |
| 652 ir.Primitive index; | |
| 653 | |
| 654 if (element != null && element.isConst) { | |
| 655 // Reference to constant local, top-level or static field | |
| 656 result = translateConstant(node); | |
| 657 } else if (Elements.isLocal(element)) { | |
| 658 // Reference to local variable | |
| 659 result = irBuilder.buildLocalGet(element); | |
| 660 } else if (element == null || | |
| 661 Elements.isInstanceField(element) || | |
| 662 Elements.isInstanceMethod(element) || | |
| 663 selector.isIndex || | |
| 664 // TODO(johnniwinther): clean up semantics of resolution. | |
| 665 node.isSuperCall) { | |
| 666 // Dynamic dispatch to a getter. Sometimes resolution will suggest a | |
| 667 // target element, but in these cases we must still emit a dynamic | |
| 668 // dispatch. The target element may be an instance method in case we are | |
| 669 // converting a method to a function object. | |
| 670 | |
| 671 receiver = visitReceiver(node.receiver); | |
| 672 List<ir.Primitive> arguments = new List<ir.Primitive>(); | |
| 673 if (selector.isIndex) { | |
| 674 index = visit(node.arguments.head); | |
| 675 arguments.add(index); | |
| 676 } | |
| 677 | |
| 678 assert(selector.kind == SelectorKind.GETTER || | |
| 679 selector.kind == SelectorKind.INDEX); | |
| 680 if (isSuperCall(node)) { | |
| 681 result = irBuilder.buildSuperInvocation(element, selector, arguments); | |
| 682 } else { | |
| 683 result = | |
| 684 irBuilder.buildDynamicInvocation(receiver, selector, arguments); | |
| 685 } | |
| 686 } else if (element.isField || element.isGetter || element.isErroneous || | |
| 687 element.isSetter) { | |
| 688 // TODO(johnniwinther): Change handling of setter selectors. | |
| 689 // Access to a static field or getter (non-static case handled above). | |
| 690 // Even if there is only a setter, we compile as if it was a getter, | |
| 691 // so the vm can fail at runtime. | |
| 692 assert(selector.kind == SelectorKind.GETTER || | |
| 693 selector.kind == SelectorKind.SETTER); | |
| 694 result = irBuilder.buildStaticGet(element, selector, | |
| 695 sourceInformation: sourceInformationBuilder.buildGet(node)); | |
| 696 } else if (Elements.isStaticOrTopLevelFunction(element)) { | |
| 697 // Convert a top-level or static function to a function object. | |
| 698 result = translateConstant(node); | |
| 699 } else { | |
| 700 throw "Unexpected SendSet getter: $node, $element"; | |
| 701 } | |
| 702 return new _GetterElements( | |
| 703 result: result,index: index, receiver: receiver); | |
| 704 } | 653 } |
| 705 | 654 |
| 706 ir.Primitive visitGetterSend(ast.Send node) { | 655 @override |
| 707 assert(irBuilder.isOpen); | 656 ir.Primitive handleDynamicGet( |
| 708 return translateGetter(node, elements.getSelector(node)).result; | 657 ast.Send node, |
| 709 | 658 ast.Node receiver, |
| 659 Selector selector, |
| 660 _) { |
| 661 return irBuilder.buildDynamicGet( |
| 662 translateReceiver(receiver), |
| 663 selector); |
| 710 } | 664 } |
| 711 | 665 |
| 712 ir.Primitive translateLogicalOperator(ast.Operator op, | 666 @override |
| 713 ast.Expression left, | 667 ir.Primitive visitDynamicTypeLiteralGet( |
| 714 ast.Expression right) { | 668 ast.Send node, |
| 669 ConstantExpression constant, |
| 670 _) { |
| 671 return irBuilder.buildConstantLiteral(constant); |
| 672 } |
| 673 |
| 674 @override |
| 675 ir.Primitive handleLocalGet( |
| 676 ast.Send node, |
| 677 LocalElement element, |
| 678 _) { |
| 679 if (element.isConst) { |
| 680 return translateConstant(node); |
| 681 } |
| 682 return irBuilder.buildLocalGet(element); |
| 683 } |
| 684 |
| 685 @override |
| 686 ir.Primitive handleStaticFieldGet( |
| 687 ast.Send node, |
| 688 FieldElement field, |
| 689 _) { |
| 690 if (field.isConst) { |
| 691 return translateConstant(node); |
| 692 } |
| 693 return irBuilder.buildStaticGet(field, |
| 694 sourceInformation: sourceInformationBuilder.buildGet(node)); |
| 695 } |
| 696 |
| 697 @override |
| 698 ir.Primitive handleStaticFunctionGet( |
| 699 ast.Send node, |
| 700 MethodElement function, |
| 701 _) { |
| 702 // TODO(karlklose): support foreign functions. |
| 703 if (function.isForeign(compiler.backend)) { |
| 704 return giveup(node, 'handleStaticFunctionGet: foreign: $function'); |
| 705 } |
| 706 return translateConstant(node); |
| 707 } |
| 708 |
| 709 @override |
| 710 ir.Primitive handleStaticGetterGet( |
| 711 ast.Send node, |
| 712 FunctionElement getter, |
| 713 _) { |
| 714 return irBuilder.buildStaticInvocation(getter, |
| 715 new Selector.getter(getter.name, getter.library), const []); |
| 716 } |
| 717 |
| 718 @override |
| 719 ir.Primitive visitSuperFieldGet( |
| 720 ast.Send node, |
| 721 FieldElement field, |
| 722 _) { |
| 723 return irBuilder.buildSuperGet(field); |
| 724 } |
| 725 |
| 726 @override |
| 727 ir.Primitive visitSuperGetterGet( |
| 728 ast.Send node, |
| 729 FunctionElement getter, |
| 730 _) { |
| 731 return irBuilder.buildSuperGet(getter); |
| 732 } |
| 733 |
| 734 @override |
| 735 ir.Primitive visitSuperMethodGet( |
| 736 ast.Send node, |
| 737 MethodElement method, |
| 738 _) { |
| 739 return irBuilder.buildSuperGet(method); |
| 740 } |
| 741 |
| 742 @override |
| 743 ir.Primitive visitThisGet(ast.Identifier node, _) { |
| 744 return irBuilder.buildThis(); |
| 745 } |
| 746 |
| 747 ir.Primitive translateTypeVariableTypeLiteral(TypeVariableElement element) { |
| 748 return buildReifyTypeVariable(irBuilder.buildThis(), element.type); |
| 749 } |
| 750 |
| 751 @override |
| 752 ir.Primitive visitTypeVariableTypeLiteralGet(ast.Send node, |
| 753 TypeVariableElement element, _) { |
| 754 return translateTypeVariableTypeLiteral(element); |
| 755 } |
| 756 |
| 757 ir.Primitive translateLogicalOperator(ast.Expression left, |
| 758 ast.Expression right, |
| 759 {bool isLazyOr}) { |
| 715 ir.Primitive leftValue = visit(left); | 760 ir.Primitive leftValue = visit(left); |
| 716 | 761 |
| 717 ir.Primitive buildRightValue(IrBuilder rightBuilder) { | 762 ir.Primitive buildRightValue(IrBuilder rightBuilder) { |
| 718 return withBuilder(rightBuilder, () => visit(right)); | 763 return withBuilder(rightBuilder, () => visit(right)); |
| 719 } | 764 } |
| 720 | 765 |
| 721 return irBuilder.buildLogicalOperator( | 766 return irBuilder.buildLogicalOperator( |
| 722 leftValue, buildRightValue, isLazyOr: op.source == '||'); | 767 leftValue, buildRightValue, isLazyOr: isLazyOr); |
| 723 } | 768 } |
| 724 | 769 |
| 725 ir.Primitive visitOperatorSend(ast.Send node) { | 770 @override |
| 726 assert(irBuilder.isOpen); | 771 ir.Primitive visitLogicalAnd( |
| 727 ast.Operator op = node.selector; | 772 ast.Send node, ast.Node left, ast.Node right, _) { |
| 728 if (isUserDefinableOperator(op.source)) { | 773 return translateLogicalOperator(left, right, isLazyOr: false); |
| 729 return visitDynamicSend(node); | 774 } |
| 730 } | 775 |
| 731 if (op.source == '&&' || op.source == '||') { | 776 @override |
| 732 assert(node.receiver != null); | 777 ir.Primitive visitLogicalOr( |
| 733 assert(!node.arguments.isEmpty); | 778 ast.Send node, ast.Node left, ast.Node right, _) { |
| 734 assert(node.arguments.tail.isEmpty); | 779 return translateLogicalOperator(left, right, isLazyOr: true); |
| 735 return translateLogicalOperator(op, node.receiver, node.arguments.head); | 780 } |
| 736 } | 781 |
| 737 if (op.source == "!") { | 782 @override |
| 738 assert(node.receiver != null); | 783 ir.Primitive visitAs( |
| 739 assert(node.arguments.isEmpty); | 784 ast.Send node, |
| 740 return irBuilder.buildNegation(visit(node.receiver)); | 785 ast.Node expression, |
| 741 } | 786 DartType type, |
| 742 if (op.source == "!=") { | 787 _) { |
| 743 assert(node.receiver != null); | 788 ir.Primitive receiver = visit(expression); |
| 744 assert(!node.arguments.isEmpty); | 789 return irBuilder.buildTypeOperator(receiver, type, isTypeTest: false); |
| 745 assert(node.arguments.tail.isEmpty); | 790 } |
| 746 return irBuilder.buildNegation(visitDynamicSend(node)); | 791 |
| 747 } | 792 @override |
| 748 assert(invariant(node, op.source == "is" || op.source == "as", | 793 ir.Primitive visitIs( |
| 749 message: "unexpected operator $op")); | 794 ast.Send node, |
| 750 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); | 795 ast.Node expression, |
| 751 ir.Primitive receiver = visit(node.receiver); | 796 DartType type, |
| 797 _) { |
| 798 ir.Primitive receiver = visit(expression); |
| 752 return irBuilder.buildTypeOperator( | 799 return irBuilder.buildTypeOperator( |
| 753 receiver, type, | 800 receiver, type, |
| 754 isTypeTest: op.source == "is", | 801 isTypeTest: true, |
| 755 isNotCheck: node.isIsNotCheck); | 802 isNotCheck: false); |
| 756 } | 803 } |
| 757 | 804 |
| 758 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]] | 805 @override |
| 759 // where (C', xs) = arguments.fold(Build, C) | 806 ir.Primitive visitIsNot(ast.Send node, |
| 760 ir.Primitive visitStaticSend(ast.Send node) { | 807 ast.Node expression, DartType type, _) { |
| 761 assert(irBuilder.isOpen); | 808 ir.Primitive receiver = visit(expression); |
| 762 Element element = elements[node]; | 809 return irBuilder.buildTypeOperator( |
| 763 assert(!element.isConstructor); | 810 receiver, type, |
| 764 // TODO(lry): support foreign functions. | 811 isTypeTest: true, |
| 765 if (element.isForeign(compiler.backend)) { | 812 isNotCheck: true); |
| 766 return giveup(node, 'StaticSend: foreign'); | 813 } |
| 814 |
| 815 ir.Primitive translateBinary(ast.Node left, |
| 816 op.BinaryOperator operator, |
| 817 ast.Node right) { |
| 818 Selector selector = new Selector.binaryOperator(operator.selectorName); |
| 819 ir.Primitive receiver = visit(left); |
| 820 List<ir.Primitive> arguments = <ir.Primitive>[visit(right)]; |
| 821 arguments = normalizeDynamicArguments(selector, arguments); |
| 822 return irBuilder.buildDynamicInvocation(receiver, selector, arguments); |
| 823 } |
| 824 |
| 825 @override |
| 826 ir.Primitive visitBinary(ast.Send node, |
| 827 ast.Node left, |
| 828 op.BinaryOperator operator, |
| 829 ast.Node right, _) { |
| 830 return translateBinary(left, operator, right); |
| 831 } |
| 832 |
| 833 @override |
| 834 ir.Primitive visitIndex(ast.Send node, |
| 835 ast.Node receiver, |
| 836 ast.Node index, _) { |
| 837 Selector selector = new Selector.index(); |
| 838 ir.Primitive target = visit(receiver); |
| 839 List<ir.Primitive> arguments = <ir.Primitive>[visit(index)]; |
| 840 arguments = normalizeDynamicArguments(selector, arguments); |
| 841 return irBuilder.buildDynamicInvocation(target, selector, arguments); |
| 842 } |
| 843 |
| 844 ir.Primitive translateSuperBinary(FunctionElement function, |
| 845 op.BinaryOperator operator, |
| 846 ast.Node argument) { |
| 847 Selector selector = new Selector.binaryOperator(operator.selectorName); |
| 848 List<ir.Primitive> arguments = <ir.Primitive>[visit(argument)]; |
| 849 arguments = normalizeDynamicArguments(selector, arguments); |
| 850 return irBuilder.buildSuperInvocation(function, selector, arguments); |
| 851 } |
| 852 |
| 853 @override |
| 854 ir.Primitive visitSuperBinary( |
| 855 ast.Send node, |
| 856 FunctionElement function, |
| 857 op.BinaryOperator operator, |
| 858 ast.Node argument, |
| 859 _) { |
| 860 return translateSuperBinary(function, operator, argument); |
| 861 } |
| 862 |
| 863 @override |
| 864 ir.Primitive visitSuperIndex( |
| 865 ast.Send node, |
| 866 FunctionElement function, |
| 867 ast.Node index, |
| 868 _) { |
| 869 Selector selector = new Selector.index(); |
| 870 List<ir.Primitive> arguments = <ir.Primitive>[visit(index)]; |
| 871 arguments = normalizeDynamicArguments(selector, arguments); |
| 872 return irBuilder.buildSuperInvocation(function, selector, arguments); |
| 873 } |
| 874 |
| 875 @override |
| 876 ir.Primitive visitEquals( |
| 877 ast.Send node, |
| 878 ast.Node left, |
| 879 ast.Node right, |
| 880 _) { |
| 881 return translateBinary(left, op.BinaryOperator.EQ, right); |
| 882 } |
| 883 |
| 884 @override |
| 885 ir.Primitive visitSuperEquals( |
| 886 ast.Send node, |
| 887 FunctionElement function, |
| 888 ast.Node argument, |
| 889 _) { |
| 890 return translateSuperBinary(function, op.BinaryOperator.EQ, argument); |
| 891 } |
| 892 |
| 893 @override |
| 894 ir.Primitive visitNot( |
| 895 ast.Send node, |
| 896 ast.Node expression, |
| 897 _) { |
| 898 return irBuilder.buildNegation(visit(expression)); |
| 899 } |
| 900 |
| 901 @override |
| 902 ir.Primitive visitNotEquals( |
| 903 ast.Send node, |
| 904 ast.Node left, |
| 905 ast.Node right, |
| 906 _) { |
| 907 return irBuilder.buildNegation( |
| 908 translateBinary(left, op.BinaryOperator.NOT_EQ, right)); |
| 909 } |
| 910 |
| 911 @override |
| 912 ir.Primitive visitSuperNotEquals( |
| 913 ast.Send node, |
| 914 FunctionElement function, |
| 915 ast.Node argument, |
| 916 _) { |
| 917 return irBuilder.buildNegation( |
| 918 translateSuperBinary(function, op.BinaryOperator.NOT_EQ, argument)); |
| 919 } |
| 920 |
| 921 @override |
| 922 ir.Primitive visitUnary(ast.Send node, |
| 923 op.UnaryOperator operator, ast.Node expression, _) { |
| 924 // TODO(johnniwinther): Clean up the creation of selectors. |
| 925 Selector selector = |
| 926 new Selector(SelectorKind.OPERATOR, operator.selectorName, null, 0); |
| 927 ir.Primitive receiver = translateReceiver(expression); |
| 928 return irBuilder.buildDynamicInvocation(receiver, selector, const []); |
| 929 } |
| 930 |
| 931 @override |
| 932 ir.Primitive visitSuperUnary( |
| 933 ast.Send node, |
| 934 op.UnaryOperator operator, |
| 935 FunctionElement function, |
| 936 _) { |
| 937 // TODO(johnniwinther): Clean up the creation of selectors. |
| 938 Selector selector = |
| 939 new Selector(SelectorKind.OPERATOR, operator.selectorName, null, 0); |
| 940 return irBuilder.buildSuperInvocation(function, selector, const []); |
| 941 } |
| 942 |
| 943 // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct |
| 944 // semantic correlation between arguments and invocation. |
| 945 List<ir.Primitive> translateDynamicArguments(ast.NodeList nodeList, |
| 946 Selector selector) { |
| 947 List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit); |
| 948 return normalizeDynamicArguments(selector, arguments); |
| 949 } |
| 950 |
| 951 // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct |
| 952 // semantic correlation between arguments and invocation. |
| 953 List<ir.Primitive> translateStaticArguments(ast.NodeList nodeList, |
| 954 Element element, |
| 955 Selector selector) { |
| 956 List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit); |
| 957 return normalizeStaticArguments(selector, element, arguments); |
| 958 } |
| 959 |
| 960 ir.Primitive translateCallInvoke(ir.Primitive target, |
| 961 ast.NodeList arguments, |
| 962 Selector selector) { |
| 963 |
| 964 return irBuilder.buildCallInvocation(target, selector, |
| 965 translateDynamicArguments(arguments, selector)); |
| 966 } |
| 967 |
| 968 ir.Primitive translateConstantInvoke(ConstantExpression constant, |
| 969 ast.NodeList arguments, |
| 970 Selector selector) { |
| 971 return translateCallInvoke( |
| 972 irBuilder.buildConstantLiteral(constant), |
| 973 arguments, |
| 974 selector); |
| 975 } |
| 976 |
| 977 @override |
| 978 ir.Primitive handleConstantInvoke( |
| 979 ast.Send node, |
| 980 ConstantExpression constant, |
| 981 ast.NodeList arguments, |
| 982 Selector selector, |
| 983 _) { |
| 984 return translateConstantInvoke(constant, arguments, selector); |
| 985 } |
| 986 |
| 987 @override |
| 988 ir.Primitive handleDynamicInvoke( |
| 989 ast.Send node, |
| 990 ast.Node receiver, |
| 991 ast.NodeList arguments, |
| 992 Selector selector, |
| 993 _) { |
| 994 return irBuilder.buildDynamicInvocation( |
| 995 translateReceiver(receiver), selector, |
| 996 translateDynamicArguments(arguments, selector)); |
| 997 } |
| 998 |
| 999 ir.Primitive handleLocalInvoke( |
| 1000 ast.Send node, |
| 1001 LocalElement element, |
| 1002 ast.NodeList arguments, |
| 1003 Selector selector, |
| 1004 _) { |
| 1005 return irBuilder.buildLocalInvocation(element, selector, |
| 1006 translateDynamicArguments(arguments, selector)); |
| 1007 } |
| 1008 |
| 1009 @override |
| 1010 ir.Primitive handleStaticFieldInvoke( |
| 1011 ast.Send node, |
| 1012 FieldElement field, |
| 1013 ast.NodeList arguments, |
| 1014 Selector selector, |
| 1015 _) { |
| 1016 return translateCallInvoke( |
| 1017 irBuilder.buildStaticGet(field), |
| 1018 arguments, selector); |
| 1019 } |
| 1020 |
| 1021 @override |
| 1022 ir.Primitive handleStaticFunctionInvoke( |
| 1023 ast.Send node, |
| 1024 MethodElement function, |
| 1025 ast.NodeList arguments, |
| 1026 Selector selector, |
| 1027 _) { |
| 1028 // TODO(karlklose): support foreign functions. |
| 1029 if (function.isForeign(compiler.backend)) { |
| 1030 return giveup(node, 'handleStaticFunctionInvoke: foreign: $function'); |
| 767 } | 1031 } |
| 768 | 1032 return irBuilder.buildStaticInvocation(function, selector, |
| 769 Selector selector = elements.getSelector(node); | 1033 translateStaticArguments(arguments, function, selector), |
| 770 | 1034 sourceInformation: sourceInformationBuilder.buildCall(node)); |
| 771 if (selector.isCall && (element.isGetter || element.isField)) { | 1035 } |
| 772 // We are invoking a static field or getter as if it was a method, e.g: | 1036 |
| 773 // | 1037 @override |
| 774 // get foo => {..} | 1038 ir.Primitive handleStaticGetterInvoke( |
| 775 // main() { foo(1, 2, 3); } | 1039 ast.Send node, |
| 776 // | 1040 FunctionElement getter, |
| 777 // We invoke the getter of 'foo' and then invoke the 'call' method | 1041 ast.NodeList arguments, |
| 778 // on the result, using the given arguments. | 1042 Selector selector, |
| 779 Selector getter = new Selector.getterFrom(selector); | 1043 _) { |
| 780 Selector call = new Selector.callClosureFrom(selector); | 1044 return translateCallInvoke( |
| 781 ir.Primitive receiver = irBuilder.buildStaticGet(element, getter); | 1045 irBuilder.buildStaticGet(getter), |
| 782 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 1046 arguments, selector); |
| 783 arguments = normalizeDynamicArguments(selector, arguments); | 1047 } |
| 784 return irBuilder.buildCallInvocation(receiver, call, arguments); | 1048 |
| 785 } else if (selector.isGetter) { | 1049 @override |
| 786 // We are reading a static field or invoking a static getter. | 1050 ir.Primitive visitSuperFieldInvoke( |
| 787 return irBuilder.buildStaticGet(element, selector); | 1051 ast.Send node, |
| 788 } else { | 1052 FieldElement field, |
| 789 // We are invoking a static method. | 1053 ast.NodeList arguments, |
| 790 assert(selector.isCall); | 1054 Selector selector, |
| 791 assert(element is FunctionElement); | 1055 _) { |
| 792 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 1056 return translateCallInvoke( |
| 793 arguments = normalizeStaticArguments(selector, element, arguments); | 1057 irBuilder.buildSuperGet(field), |
| 794 return irBuilder.buildStaticInvocation(element, selector, arguments, | 1058 arguments, selector); |
| 795 sourceInformation: sourceInformationBuilder.buildCall(node)); | 1059 } |
| 796 } | 1060 |
| 797 } | 1061 @override |
| 798 | 1062 ir.Primitive visitSuperGetterInvoke( |
| 799 ir.Primitive visitSuperSend(ast.Send node) { | 1063 ast.Send node, |
| 800 assert(irBuilder.isOpen); | 1064 FunctionElement getter, |
| 801 Selector selector = elements.getSelector(node); | 1065 ast.NodeList arguments, |
| 802 Element target = elements[node]; | 1066 Selector selector, |
| 803 | 1067 _) { |
| 804 if (selector.isCall && (target.isGetter || target.isField)) { | 1068 return translateCallInvoke( |
| 805 // We are invoking a field or getter as if it was a method, e.g: | 1069 irBuilder.buildSuperGet(getter), |
| 806 // | 1070 arguments, selector); |
| 807 // class A { get foo => {..} } | 1071 } |
| 808 // class B extends A { | 1072 |
| 809 // m() { | 1073 @override |
| 810 // super.foo(1, 2, 3); } | 1074 ir.Primitive visitSuperMethodInvoke( |
| 811 // } | 1075 ast.Send node, |
| 812 // } | 1076 MethodElement method, |
| 813 // | 1077 ast.NodeList arguments, |
| 814 // We invoke the getter of 'foo' and then invoke the 'call' method on | 1078 Selector selector, |
| 815 // the result, using the given arguments. | 1079 _) { |
| 816 Selector getter = new Selector.getterFrom(selector); | 1080 return irBuilder.buildSuperInvocation(method, selector, |
| 817 Selector call = new Selector.callClosureFrom(selector); | 1081 translateDynamicArguments(arguments, selector)); |
| 818 ir.Primitive receiver = | 1082 } |
| 819 irBuilder.buildSuperInvocation(target, getter, []); | 1083 |
| 820 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 1084 @override |
| 821 arguments = normalizeDynamicArguments(selector, arguments); | 1085 ir.Primitive visitThisInvoke( |
| 822 return irBuilder.buildCallInvocation(receiver, call, arguments); | 1086 ast.Send node, |
| 823 } else if (selector.isCall) { | 1087 ast.NodeList arguments, |
| 824 // We are invoking a method. | 1088 Selector selector, |
| 825 assert(target is FunctionElement); | 1089 _) { |
| 826 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 1090 return translateCallInvoke(irBuilder.buildThis(), arguments, selector); |
| 827 arguments = normalizeStaticArguments(selector, target, arguments); | 1091 } |
| 828 return irBuilder.buildSuperInvocation(target, selector, arguments); | 1092 |
| 829 } else { | 1093 @override |
| 830 // We are invoking a getter, operator, indexer, etc. | 1094 ir.Primitive visitTypeVariableTypeLiteralInvoke( |
| 831 List<ir.Primitive> arguments = node.argumentsNode == null | 1095 ast.Send node, |
| 832 ? <ir.Primitive>[] | 1096 TypeVariableElement element, |
| 833 : node.arguments.mapToList(visit); | 1097 ast.NodeList arguments, |
| 834 return irBuilder.buildSuperInvocation(target, selector, arguments); | 1098 Selector selector, |
| 835 } | 1099 _) { |
| 836 } | 1100 return translateCallInvoke( |
| 837 | 1101 translateTypeVariableTypeLiteral(element), |
| 838 visitTypePrefixSend(ast.Send node) { | 1102 arguments, |
| 839 compiler.internalError(node, "visitTypePrefixSend should not be called."); | 1103 selector); |
| 840 } | 1104 } |
| 841 | 1105 |
| 842 ir.Primitive visitTypeLiteralSend(ast.Send node) { | 1106 @override |
| 843 assert(irBuilder.isOpen); | 1107 ir.Primitive visitTypedefTypeLiteralInvoke( |
| 844 // If the user is trying to invoke the type literal or variable, | 1108 ast.Send node, |
| 845 // it must be treated as a function call. | 1109 TypeConstantExpression constant, |
| 846 if (node.argumentsNode != null) { | 1110 ast.NodeList arguments, |
| 847 // TODO(sigurdm): Handle this to match proposed semantics of issue #19725. | 1111 Selector selector, _) { |
| 848 return giveup(node, 'Type literal invoked as function'); | 1112 return translateConstantInvoke(constant, arguments, selector); |
| 849 } | 1113 } |
| 850 | 1114 |
| 851 DartType type = elements.getTypeLiteralType(node); | 1115 // TODO(johnniwinther): This should be a method on [IrBuilder]. |
| 852 if (type is TypeVariableType) { | |
| 853 return buildReifyTypeVariable(irBuilder.buildThis(), type); | |
| 854 } else { | |
| 855 return translateConstant(node); | |
| 856 } | |
| 857 } | |
| 858 | |
| 859 ir.Primitive buildReifyTypeVariable(ir.Primitive target, | 1116 ir.Primitive buildReifyTypeVariable(ir.Primitive target, |
| 860 TypeVariableType variable); | 1117 TypeVariableType variable); |
| 861 | 1118 |
| 862 ir.Primitive visitSendSet(ast.SendSet node) { | 1119 @override |
| 863 assert(irBuilder.isOpen); | 1120 ir.Primitive visitIndexSet( |
| 864 Element element = elements[node]; | 1121 ast.SendSet node, |
| 865 ast.Operator op = node.assignmentOperator; | 1122 ast.Node receiver, |
| 866 // For complex operators, this is the result of getting (before assigning) | 1123 ast.Node index, |
| 867 ir.Primitive originalValue; | 1124 ast.Node rhs, |
| 868 // For []+= style operators, this saves the index. | 1125 _) { |
| 869 ir.Primitive index; | 1126 return irBuilder.buildDynamicIndexSet( |
| 870 ir.Primitive receiver; | 1127 visit(receiver), visit(index), visit(rhs)); |
| 871 // This is what gets assigned. | 1128 } |
| 872 ir.Primitive valueToStore; | 1129 |
| 873 Selector selector = elements.getSelector(node); | 1130 @override |
| 1131 ir.Primitive visitSuperIndexSet( |
| 1132 ast.SendSet node, |
| 1133 FunctionElement function, |
| 1134 ast.Node index, |
| 1135 ast.Node rhs, |
| 1136 _) { |
| 1137 return irBuilder.buildSuperIndexSet(function, visit(index), visit(rhs)); |
| 1138 } |
| 1139 |
| 1140 @override |
| 1141 ir.Primitive visitCompoundIndexSet( |
| 1142 ast.SendSet node, |
| 1143 ast.Node receiver, |
| 1144 ast.Node index, |
| 1145 op.AssignmentOperator operator, |
| 1146 ast.Node rhs, |
| 1147 _) { |
| 1148 ir.Primitive target = visit(receiver); |
| 1149 ir.Primitive indexValue = visit(index); |
| 1150 return translateCompound( |
| 1151 getValue: () { |
| 1152 Selector selector = new Selector.index(); |
| 1153 List<ir.Primitive> arguments = <ir.Primitive>[indexValue]; |
| 1154 arguments = normalizeDynamicArguments(selector, arguments); |
| 1155 return irBuilder.buildDynamicInvocation(target, selector, arguments); |
| 1156 }, |
| 1157 operator: operator, |
| 1158 rhs: rhs, |
| 1159 setValue: (ir.Primitive result) { |
| 1160 irBuilder.buildDynamicIndexSet(target, indexValue, result); |
| 1161 }); |
| 1162 } |
| 1163 |
| 1164 @override |
| 1165 ir.Primitive visitSuperCompoundIndexSet( |
| 1166 ast.SendSet node, |
| 1167 FunctionElement getter, |
| 1168 FunctionElement setter, |
| 1169 ast.Node index, |
| 1170 op.AssignmentOperator operator, |
| 1171 ast.Node rhs, |
| 1172 _) { |
| 1173 ir.Primitive indexValue = visit(index); |
| 1174 return translateCompound( |
| 1175 getValue: () { |
| 1176 Selector selector = new Selector.index(); |
| 1177 List<ir.Primitive> arguments = <ir.Primitive>[indexValue]; |
| 1178 arguments = normalizeDynamicArguments(selector, arguments); |
| 1179 return irBuilder.buildSuperInvocation(getter, selector, arguments); |
| 1180 }, |
| 1181 operator: operator, |
| 1182 rhs: rhs, |
| 1183 setValue: (ir.Primitive result) { |
| 1184 irBuilder.buildSuperIndexSet(setter, indexValue, result); |
| 1185 }); |
| 1186 } |
| 1187 |
| 1188 ir.Primitive translatePrefixPostfix( |
| 1189 {ir.Primitive getValue(), |
| 1190 op.IncDecOperator operator, |
| 1191 void setValue(ir.Primitive value), |
| 1192 bool isPrefix}) { |
| 1193 ir.Primitive value = getValue(); |
| 874 Selector operatorSelector = | 1194 Selector operatorSelector = |
| 875 elements.getOperatorSelectorInComplexSendSet(node); | 1195 new Selector.binaryOperator(operator.selectorName); |
| 876 Selector getterSelector = | 1196 List<ir.Primitive> arguments = |
| 877 elements.getGetterSelectorInComplexSendSet(node); | 1197 <ir.Primitive>[irBuilder.buildIntegerLiteral(1)]; |
| 878 assert( | 1198 arguments = normalizeDynamicArguments(operatorSelector, arguments); |
| 879 // Indexing send-sets have an argument for the index. | 1199 ir.Primitive result = |
| 880 (selector.isIndexSet ? 1 : 0) + | 1200 irBuilder.buildDynamicInvocation(value, operatorSelector, arguments); |
| 881 // Non-increment send-sets have one more argument. | 1201 setValue(result); |
| 882 (ast.Operator.INCREMENT_OPERATORS.contains(op.source) ? 0 : 1) | 1202 return isPrefix ? result : value; |
| 883 == node.argumentCount()); | 1203 } |
| 884 | 1204 |
| 885 ast.Node getAssignArgument() { | 1205 ir.Primitive translateCompound( |
| 886 assert(invariant(node, !node.arguments.isEmpty, | 1206 {ir.Primitive getValue(), |
| 887 message: "argument expected")); | 1207 op.AssignmentOperator operator, |
| 888 return selector.isIndexSet | 1208 ast.Node rhs, |
| 889 ? node.arguments.tail.head | 1209 void setValue(ir.Primitive value)}) { |
| 890 : node.arguments.head; | 1210 ir.Primitive value = getValue(); |
| 891 } | 1211 Selector operatorSelector = |
| 892 | 1212 new Selector.binaryOperator(operator.selectorName); |
| 893 // Get the value into valueToStore | 1213 List<ir.Primitive> arguments = <ir.Primitive>[visit(rhs)]; |
| 894 if (op.source == "=") { | 1214 arguments = normalizeDynamicArguments(operatorSelector, arguments); |
| 895 if (selector.isIndexSet) { | 1215 ir.Primitive result = |
| 896 receiver = visitReceiver(node.receiver); | 1216 irBuilder.buildDynamicInvocation(value, operatorSelector, arguments); |
| 897 index = visit(node.arguments.head); | 1217 setValue(result); |
| 898 } else if (element == null || Elements.isInstanceField(element)) { | 1218 return result; |
| 899 receiver = visitReceiver(node.receiver); | 1219 } |
| 900 } | 1220 |
| 901 valueToStore = visit(getAssignArgument()); | 1221 @override |
| 902 } else { | 1222 ir.Primitive handleDynamicCompound( |
| 903 // Get the original value into getter | 1223 ast.Send node, |
| 904 assert(ast.Operator.COMPLEX_OPERATORS.contains(op.source)); | 1224 ast.Node receiver, |
| 905 | 1225 op.AssignmentOperator operator, |
| 906 _GetterElements getterResult = translateGetter(node, getterSelector); | 1226 ast.Node rhs, |
| 907 index = getterResult.index; | 1227 Selector getterSelector, |
| 908 receiver = getterResult.receiver; | 1228 Selector setterSelector, |
| 909 originalValue = getterResult.result; | 1229 _) { |
| 910 | 1230 ir.Primitive target = translateReceiver(receiver); |
| 911 // Do the modification of the value in getter. | 1231 return translateCompound( |
| 912 ir.Primitive arg; | 1232 getValue: () => irBuilder.buildDynamicGet(target, getterSelector), |
| 913 if (ast.Operator.INCREMENT_OPERATORS.contains(op.source)) { | 1233 operator: operator, |
| 914 arg = irBuilder.buildIntegerLiteral(1); | 1234 rhs: rhs, |
| 915 } else { | 1235 setValue: (ir.Primitive result) { |
| 916 arg = visit(getAssignArgument()); | 1236 irBuilder.buildDynamicSet(target, setterSelector, result); |
| 917 } | 1237 }); |
| 918 valueToStore = new ir.Parameter(null); | 1238 } |
| 919 ir.Continuation k = new ir.Continuation([valueToStore]); | 1239 |
| 920 ir.Expression invoke = | 1240 @override |
| 921 new ir.InvokeMethod(originalValue, operatorSelector, k, [arg]); | 1241 ir.Primitive handleDynamicPostfixPrefix( |
| 922 irBuilder.add(new ir.LetCont(k, invoke)); | 1242 ast.Send node, |
| 923 } | 1243 ast.Node receiver, |
| 924 | 1244 op.IncDecOperator operator, |
| 925 if (Elements.isLocal(element)) { | 1245 Selector getterSelector, |
| 926 irBuilder.buildLocalSet(element, valueToStore); | 1246 Selector setterSelector, |
| 927 } else if ((!node.isSuperCall && Elements.isErroneous(element)) || | 1247 arg, |
| 928 Elements.isStaticOrTopLevel(element)) { | 1248 {bool isPrefix}) { |
| 929 irBuilder.buildStaticSet( | 1249 ir.Primitive target = translateReceiver(receiver); |
| 930 element, elements.getSelector(node), valueToStore); | 1250 return translatePrefixPostfix( |
| 931 } else { | 1251 getValue: () => irBuilder.buildDynamicGet(target, getterSelector), |
| 932 // Setter or index-setter invocation | 1252 operator: operator, |
| 933 Selector selector = elements.getSelector(node); | 1253 setValue: (ir.Primitive result) { |
| 934 assert(selector.kind == SelectorKind.SETTER || | 1254 irBuilder.buildDynamicSet(target, setterSelector, result); |
| 935 selector.kind == SelectorKind.INDEX); | 1255 }, |
| 936 if (selector.isIndexSet) { | 1256 isPrefix: isPrefix); |
| 937 if (isSuperCall(node)) { | 1257 } |
| 938 irBuilder.buildSuperIndexSet(element, index, valueToStore); | 1258 |
| 939 } else { | 1259 @override |
| 940 irBuilder.buildDynamicIndexSet(receiver, index, valueToStore); | 1260 ir.Primitive handleDynamicSet( |
| 941 } | 1261 ast.SendSet node, |
| 942 } else { | 1262 ast.Node receiver, |
| 943 if (isSuperCall(node)) { | 1263 Selector selector, |
| 944 irBuilder.buildSuperSet(element, selector, valueToStore); | 1264 ast.Node rhs, |
| 945 } else { | 1265 _) { |
| 946 irBuilder.buildDynamicSet(receiver, selector, valueToStore); | 1266 return irBuilder.buildDynamicSet( |
| 947 } | 1267 translateReceiver(receiver), |
| 948 } | 1268 selector, |
| 949 } | 1269 visit(rhs)); |
| 950 | 1270 } |
| 951 if (node.isPostfix) { | 1271 |
| 952 assert(originalValue != null); | 1272 @override |
| 953 return originalValue; | 1273 ir.Primitive handleLocalCompound( |
| 954 } else { | 1274 ast.Send node, |
| 955 return valueToStore; | 1275 LocalElement element, |
| 956 } | 1276 op.AssignmentOperator operator, |
| 1277 ast.Node rhs, |
| 1278 _) { |
| 1279 return translateCompound( |
| 1280 getValue: () => irBuilder.buildLocalGet(element), |
| 1281 operator: operator, |
| 1282 rhs: rhs, |
| 1283 setValue: (ir.Primitive result) { |
| 1284 irBuilder.buildLocalSet(element, result); |
| 1285 }); |
| 1286 } |
| 1287 |
| 1288 @override |
| 1289 ir.Primitive handleLocalPostfixPrefix( |
| 1290 ast.Send node, |
| 1291 LocalElement element, |
| 1292 op.IncDecOperator operator, |
| 1293 arg, |
| 1294 {bool isPrefix}) { |
| 1295 return translatePrefixPostfix( |
| 1296 getValue: () => irBuilder.buildLocalGet(element), |
| 1297 operator: operator, |
| 1298 setValue: (ir.Primitive result) { |
| 1299 irBuilder.buildLocalSet(element, result); |
| 1300 }, |
| 1301 isPrefix: isPrefix); |
| 1302 } |
| 1303 |
| 1304 @override |
| 1305 ir.Primitive handleLocalSet( |
| 1306 ast.SendSet node, |
| 1307 LocalElement element, |
| 1308 ast.Node rhs, |
| 1309 _) { |
| 1310 return irBuilder.buildLocalSet(element, visit(rhs)); |
| 1311 } |
| 1312 |
| 1313 @override |
| 1314 ir.Primitive handleStaticFieldCompound( |
| 1315 ast.Send node, |
| 1316 FieldElement field, |
| 1317 op.AssignmentOperator operator, |
| 1318 ast.Node rhs, |
| 1319 _) { |
| 1320 return translateCompound( |
| 1321 getValue: () => irBuilder.buildStaticGet(field), |
| 1322 operator: operator, |
| 1323 rhs: rhs, |
| 1324 setValue: (ir.Primitive result) { |
| 1325 irBuilder.buildStaticSet(field, result); |
| 1326 }); |
| 1327 } |
| 1328 |
| 1329 @override |
| 1330 ir.Primitive handleStaticFieldPostfixPrefix( |
| 1331 ast.Send node, |
| 1332 FieldElement field, |
| 1333 op.IncDecOperator operator, |
| 1334 arg, |
| 1335 {bool isPrefix}) { |
| 1336 return translatePrefixPostfix( |
| 1337 getValue: () => irBuilder.buildStaticGet(field), |
| 1338 operator: operator, |
| 1339 setValue: (ir.Primitive result) { |
| 1340 irBuilder.buildStaticSet(field, result); |
| 1341 }, |
| 1342 isPrefix: isPrefix); |
| 1343 } |
| 1344 |
| 1345 @override |
| 1346 ir.Primitive handleStaticFieldSet( |
| 1347 ast.SendSet node, |
| 1348 FieldElement field, |
| 1349 ast.Node rhs, |
| 1350 _) { |
| 1351 return irBuilder.buildStaticSet(field, visit(rhs)); |
| 1352 } |
| 1353 |
| 1354 @override |
| 1355 ir.Primitive visitSuperFieldSet( |
| 1356 ast.SendSet node, |
| 1357 FieldElement field, |
| 1358 ast.Node rhs, |
| 1359 _) { |
| 1360 return irBuilder.buildSuperSet(field, visit(rhs)); |
| 1361 } |
| 1362 |
| 1363 @override |
| 1364 ir.Primitive visitSuperSetterSet( |
| 1365 ast.SendSet node, |
| 1366 FunctionElement setter, |
| 1367 ast.Node rhs, |
| 1368 _) { |
| 1369 return irBuilder.buildSuperSet(setter, visit(rhs)); |
| 1370 } |
| 1371 |
| 1372 @override |
| 1373 ir.Primitive handleStaticGetterSetterCompound( |
| 1374 ast.Send node, |
| 1375 FunctionElement getter, |
| 1376 FunctionElement setter, |
| 1377 op.AssignmentOperator operator, |
| 1378 ast.Node rhs, |
| 1379 _) { |
| 1380 return translateCompound( |
| 1381 getValue: () => irBuilder.buildStaticGet(getter), |
| 1382 operator: operator, |
| 1383 rhs: rhs, |
| 1384 setValue: (ir.Primitive result) { |
| 1385 irBuilder.buildStaticSet(setter, result); |
| 1386 }); |
| 1387 } |
| 1388 |
| 1389 @override |
| 1390 ir.Primitive handleSuperFieldFieldPostfixPrefix( |
| 1391 ast.Send node, |
| 1392 FieldElement readField, |
| 1393 FieldElement writtenField, |
| 1394 op.IncDecOperator operator, |
| 1395 arg, |
| 1396 {bool isPrefix}) { |
| 1397 return translatePrefixPostfix( |
| 1398 getValue: () => irBuilder.buildSuperGet(readField), |
| 1399 operator: operator, |
| 1400 setValue: (ir.Primitive result) { |
| 1401 irBuilder.buildSuperSet(writtenField, result); |
| 1402 }, |
| 1403 isPrefix: isPrefix); |
| 1404 } |
| 1405 |
| 1406 @override |
| 1407 ir.Primitive handleSuperFieldSetterPostfixPrefix( |
| 1408 ast.Send node, |
| 1409 FieldElement field, |
| 1410 FunctionElement setter, |
| 1411 op.IncDecOperator operator, |
| 1412 arg, |
| 1413 {bool isPrefix}) { |
| 1414 return translatePrefixPostfix( |
| 1415 getValue: () => irBuilder.buildSuperGet(field), |
| 1416 operator: operator, |
| 1417 setValue: (ir.Primitive result) { |
| 1418 irBuilder.buildSuperSet(setter, result); |
| 1419 }, |
| 1420 isPrefix: isPrefix); |
| 1421 } |
| 1422 |
| 1423 @override |
| 1424 ir.Primitive handleSuperGetterFieldPostfixPrefix( |
| 1425 ast.Send node, |
| 1426 FunctionElement getter, |
| 1427 FieldElement field, |
| 1428 op.IncDecOperator operator, |
| 1429 arg, |
| 1430 {bool isPrefix}) { |
| 1431 return translatePrefixPostfix( |
| 1432 getValue: () => irBuilder.buildSuperGet(getter), |
| 1433 operator: operator, |
| 1434 setValue: (ir.Primitive result) { |
| 1435 irBuilder.buildSuperSet(field, result); |
| 1436 }, |
| 1437 isPrefix: isPrefix); |
| 1438 } |
| 1439 |
| 1440 @override |
| 1441 ir.Primitive handleSuperGetterSetterPostfixPrefix( |
| 1442 ast.Send node, |
| 1443 FunctionElement getter, |
| 1444 FunctionElement setter, |
| 1445 op.IncDecOperator operator, |
| 1446 arg, |
| 1447 {bool isPrefix}) { |
| 1448 return translatePrefixPostfix( |
| 1449 getValue: () => irBuilder.buildSuperGet(getter), |
| 1450 operator: operator, |
| 1451 setValue: (ir.Primitive result) { |
| 1452 irBuilder.buildSuperSet(setter, result); |
| 1453 }, |
| 1454 isPrefix: isPrefix); |
| 1455 } |
| 1456 |
| 1457 @override |
| 1458 ir.Primitive handleSuperMethodSetterPostfixPrefix( |
| 1459 ast.Send node, |
| 1460 FunctionElement method, |
| 1461 FunctionElement setter, |
| 1462 op.IncDecOperator operator, |
| 1463 arg, |
| 1464 {bool isPrefix}) { |
| 1465 return translatePrefixPostfix( |
| 1466 getValue: () => irBuilder.buildSuperGet(method), |
| 1467 operator: operator, |
| 1468 setValue: (ir.Primitive result) { |
| 1469 irBuilder.buildSuperSet(setter, result); |
| 1470 }, |
| 1471 isPrefix: isPrefix); |
| 1472 } |
| 1473 |
| 1474 @override |
| 1475 ir.Primitive handleStaticGetterSetterPostfixPrefix( |
| 1476 ast.Send node, |
| 1477 FunctionElement getter, |
| 1478 FunctionElement setter, |
| 1479 op.IncDecOperator operator, |
| 1480 arg, |
| 1481 {bool isPrefix}) { |
| 1482 return translatePrefixPostfix( |
| 1483 getValue: () => irBuilder.buildStaticGet(getter), |
| 1484 operator: operator, |
| 1485 setValue: (ir.Primitive result) { |
| 1486 irBuilder.buildStaticSet(setter, result); |
| 1487 }, |
| 1488 isPrefix: isPrefix); |
| 1489 } |
| 1490 |
| 1491 @override |
| 1492 ir.Primitive handleStaticMethodSetterCompound( |
| 1493 ast.Send node, |
| 1494 FunctionElement method, |
| 1495 FunctionElement setter, |
| 1496 op.AssignmentOperator operator, |
| 1497 ast.Node rhs, |
| 1498 _) { |
| 1499 return translateCompound( |
| 1500 getValue: () => irBuilder.buildStaticGet(method), |
| 1501 operator: operator, |
| 1502 rhs: rhs, |
| 1503 setValue: (ir.Primitive result) { |
| 1504 irBuilder.buildStaticSet(setter, result); |
| 1505 }); |
| 1506 } |
| 1507 |
| 1508 @override |
| 1509 ir.Primitive handleStaticMethodSetterPostfixPrefix( |
| 1510 ast.Send node, |
| 1511 FunctionElement getter, |
| 1512 FunctionElement setter, |
| 1513 op.IncDecOperator operator, |
| 1514 arg, |
| 1515 {bool isPrefix}) { |
| 1516 return translatePrefixPostfix( |
| 1517 getValue: () => irBuilder.buildStaticGet(getter), |
| 1518 operator: operator, |
| 1519 setValue: (ir.Primitive result) { |
| 1520 irBuilder.buildStaticSet(setter, result); |
| 1521 }, |
| 1522 isPrefix: isPrefix); |
| 1523 } |
| 1524 |
| 1525 @override |
| 1526 ir.Primitive handleDynamicIndexPostfixPrefix( |
| 1527 ast.Send node, |
| 1528 ast.Node receiver, |
| 1529 ast.Node index, |
| 1530 op.IncDecOperator operator, |
| 1531 arg, |
| 1532 {bool isPrefix}) { |
| 1533 ir.Primitive target = visit(receiver); |
| 1534 ir.Primitive indexValue = visit(index); |
| 1535 return translatePrefixPostfix( |
| 1536 getValue: () { |
| 1537 Selector selector = new Selector.index(); |
| 1538 List<ir.Primitive> arguments = <ir.Primitive>[indexValue]; |
| 1539 arguments = normalizeDynamicArguments(selector, arguments); |
| 1540 return irBuilder.buildDynamicInvocation(target, selector, arguments); |
| 1541 }, |
| 1542 operator: operator, |
| 1543 setValue: (ir.Primitive result) { |
| 1544 Selector selector = new Selector.indexSet(); |
| 1545 List<ir.Primitive> arguments = <ir.Primitive>[indexValue, result]; |
| 1546 arguments = normalizeDynamicArguments(selector, arguments); |
| 1547 irBuilder.buildDynamicInvocation(target, selector, arguments); |
| 1548 }, |
| 1549 isPrefix: isPrefix); |
| 1550 } |
| 1551 |
| 1552 @override |
| 1553 ir.Primitive handleSuperIndexPostfixPrefix( |
| 1554 ast.Send node, |
| 1555 FunctionElement indexFunction, |
| 1556 FunctionElement indexSetFunction, |
| 1557 ast.Node index, |
| 1558 op.IncDecOperator operator, |
| 1559 arg, |
| 1560 {bool isPrefix}) { |
| 1561 ir.Primitive indexValue = visit(index); |
| 1562 return translatePrefixPostfix( |
| 1563 getValue: () { |
| 1564 Selector selector = new Selector.index(); |
| 1565 List<ir.Primitive> arguments = <ir.Primitive>[indexValue]; |
| 1566 arguments = normalizeDynamicArguments(selector, arguments); |
| 1567 return irBuilder.buildSuperInvocation( |
| 1568 indexFunction, selector, arguments); |
| 1569 }, |
| 1570 operator: operator, |
| 1571 setValue: (ir.Primitive result) { |
| 1572 Selector selector = new Selector.indexSet(); |
| 1573 List<ir.Primitive> arguments = <ir.Primitive>[indexValue, result]; |
| 1574 arguments = normalizeDynamicArguments(selector, arguments); |
| 1575 irBuilder.buildSuperInvocation( |
| 1576 indexSetFunction, selector, arguments); |
| 1577 }, |
| 1578 isPrefix: isPrefix); |
| 1579 } |
| 1580 |
| 1581 @override |
| 1582 ir.Primitive handleStaticSetterSet( |
| 1583 ast.SendSet node, |
| 1584 FunctionElement setter, |
| 1585 ast.Node rhs, |
| 1586 _) { |
| 1587 return irBuilder.buildStaticSet(setter, visit(rhs)); |
| 1588 } |
| 1589 |
| 1590 @override |
| 1591 ir.Primitive visitSuperFieldCompound( |
| 1592 ast.Send node, |
| 1593 FieldElement field, |
| 1594 op.AssignmentOperator operator, |
| 1595 ast.Node rhs, |
| 1596 _) { |
| 1597 return translateCompound( |
| 1598 getValue: () => irBuilder.buildSuperGet(field), |
| 1599 operator: operator, |
| 1600 rhs: rhs, |
| 1601 setValue: (ir.Primitive result) { |
| 1602 irBuilder.buildSuperSet(field, result); |
| 1603 }); |
| 1604 } |
| 1605 |
| 1606 @override |
| 1607 ir.Primitive visitSuperFieldFieldPostfix( |
| 1608 ast.Send node, |
| 1609 FieldElement readField, |
| 1610 FieldElement writtenField, |
| 1611 op.IncDecOperator operator, |
| 1612 _) { |
| 1613 return translatePrefixPostfix( |
| 1614 getValue: () => irBuilder.buildSuperGet(readField), |
| 1615 operator: operator, |
| 1616 setValue: (ir.Primitive result) { |
| 1617 irBuilder.buildSuperSet(writtenField, result); |
| 1618 }, |
| 1619 isPrefix: false); |
| 1620 } |
| 1621 |
| 1622 @override |
| 1623 ir.Primitive visitSuperFieldFieldPrefix( |
| 1624 ast.Send node, |
| 1625 FieldElement readField, |
| 1626 FieldElement writtenField, |
| 1627 op.IncDecOperator operator, |
| 1628 _) { |
| 1629 return translatePrefixPostfix( |
| 1630 getValue: () => irBuilder.buildSuperGet(readField), |
| 1631 operator: operator, |
| 1632 setValue: (ir.Primitive result) { |
| 1633 irBuilder.buildSuperSet(writtenField, result); |
| 1634 }, |
| 1635 isPrefix: true); |
| 1636 } |
| 1637 |
| 1638 @override |
| 1639 ir.Primitive visitSuperFieldSetterCompound( |
| 1640 ast.Send node, |
| 1641 FieldElement field, |
| 1642 FunctionElement setter, |
| 1643 op.AssignmentOperator operator, |
| 1644 ast.Node rhs, |
| 1645 _) { |
| 1646 return translateCompound( |
| 1647 getValue: () => irBuilder.buildSuperGet(field), |
| 1648 operator: operator, |
| 1649 rhs: rhs, |
| 1650 setValue: (ir.Primitive result) { |
| 1651 irBuilder.buildSuperSet(setter, result); |
| 1652 }); |
| 1653 } |
| 1654 |
| 1655 @override |
| 1656 ir.Primitive visitSuperGetterFieldCompound( |
| 1657 ast.Send node, |
| 1658 FunctionElement getter, |
| 1659 FieldElement field, |
| 1660 op.AssignmentOperator operator, |
| 1661 ast.Node rhs, |
| 1662 _) { |
| 1663 return translateCompound( |
| 1664 getValue: () => irBuilder.buildSuperGet(getter), |
| 1665 operator: operator, |
| 1666 rhs: rhs, |
| 1667 setValue: (ir.Primitive result) { |
| 1668 irBuilder.buildSuperSet(field, result); |
| 1669 }); |
| 1670 } |
| 1671 |
| 1672 @override |
| 1673 ir.Primitive visitSuperGetterSetterCompound( |
| 1674 ast.Send node, |
| 1675 FunctionElement getter, |
| 1676 FunctionElement setter, |
| 1677 op.AssignmentOperator operator, |
| 1678 ast.Node rhs, |
| 1679 _) { |
| 1680 return translateCompound( |
| 1681 getValue: () => irBuilder.buildSuperGet(getter), |
| 1682 operator: operator, |
| 1683 rhs: rhs, |
| 1684 setValue: (ir.Primitive result) { |
| 1685 irBuilder.buildSuperSet(setter, result); |
| 1686 }); |
| 1687 } |
| 1688 |
| 1689 @override |
| 1690 ir.Primitive visitSuperMethodSetterCompound( |
| 1691 ast.Send node, |
| 1692 FunctionElement method, |
| 1693 FunctionElement setter, |
| 1694 op.AssignmentOperator operator, |
| 1695 ast.Node rhs, |
| 1696 _) { |
| 1697 return translateCompound( |
| 1698 getValue: () => irBuilder.buildSuperGet(method), |
| 1699 operator: operator, |
| 1700 rhs: rhs, |
| 1701 setValue: (ir.Primitive result) { |
| 1702 irBuilder.buildSuperSet(setter, result); |
| 1703 }); |
| 957 } | 1704 } |
| 958 | 1705 |
| 959 ir.Primitive visitNewExpression(ast.NewExpression node) { | 1706 ir.Primitive visitNewExpression(ast.NewExpression node) { |
| 960 if (node.isConst) { | 1707 if (node.isConst) { |
| 961 return translateConstant(node); | 1708 return translateConstant(node); |
| 962 } | 1709 } |
| 963 FunctionElement element = elements[node.send]; | 1710 FunctionElement element = elements[node.send]; |
| 964 Selector selector = elements.getSelector(node.send); | 1711 Selector selector = elements.getSelector(node.send); |
| 965 DartType type = elements.getType(node); | 1712 DartType type = elements.getType(node); |
| 966 ast.Node selectorNode = node.send.selector; | 1713 ast.Node selectorNode = node.send.selector; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 try { | 1747 try { |
| 1001 return action(); | 1748 return action(); |
| 1002 } catch(e, tr) { | 1749 } catch(e, tr) { |
| 1003 if (e == ABORT_IRNODE_BUILDER) { | 1750 if (e == ABORT_IRNODE_BUILDER) { |
| 1004 return null; | 1751 return null; |
| 1005 } | 1752 } |
| 1006 rethrow; | 1753 rethrow; |
| 1007 } | 1754 } |
| 1008 } | 1755 } |
| 1009 | 1756 |
| 1010 void internalError(String reason, {ast.Node node}) { | 1757 void internalError(ast.Node node, String message) { |
| 1011 giveup(node); | 1758 giveup(node); |
| 1012 } | 1759 } |
| 1760 |
| 1761 @override |
| 1762 visitNode(ast.Node node) { |
| 1763 internalError(node, "Unhandled node"); |
| 1764 } |
| 1013 } | 1765 } |
| 1014 | 1766 |
| 1015 final String ABORT_IRNODE_BUILDER = "IrNode builder aborted"; | 1767 final String ABORT_IRNODE_BUILDER = "IrNode builder aborted"; |
| 1016 | 1768 |
| 1017 dynamic giveup(ast.Node node, [String reason]) { | 1769 dynamic giveup(ast.Node node, [String reason]) { |
| 1018 throw ABORT_IRNODE_BUILDER; | 1770 throw ABORT_IRNODE_BUILDER; |
| 1019 } | 1771 } |
| 1020 | 1772 |
| 1021 /// Classifies local variables and local functions as captured, if they | 1773 /// Classifies local variables and local functions as captured, if they |
| 1022 /// are accessed from within a nested function. | 1774 /// are accessed from within a nested function. |
| (...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1851 SourceInformation buildCall(ast.Node node) { | 2603 SourceInformation buildCall(ast.Node node) { |
| 1852 return new PositionSourceInformation( | 2604 return new PositionSourceInformation( |
| 1853 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); | 2605 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); |
| 1854 } | 2606 } |
| 1855 | 2607 |
| 1856 @override | 2608 @override |
| 1857 SourceInformationBuilder forContext(AstElement element) { | 2609 SourceInformationBuilder forContext(AstElement element) { |
| 1858 return new PositionSourceInformationBuilder(element); | 2610 return new PositionSourceInformationBuilder(element); |
| 1859 } | 2611 } |
| 1860 } | 2612 } |
| OLD | NEW |