Chromium Code Reviews| 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 GroupStaticMixin<ir.Primitive, dynamic>, | |
| 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 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 stackTraceVariable: stackTraceVariable, | 484 stackTraceVariable: stackTraceVariable, |
| 475 buildCatchBlock: subbuild(catchClause.block))); | 485 buildCatchBlock: subbuild(catchClause.block))); |
| 476 } | 486 } |
| 477 | 487 |
| 478 irBuilder.buildTry( | 488 irBuilder.buildTry( |
| 479 tryStatementInfo: irBuilder.tryStatements[node], | 489 tryStatementInfo: irBuilder.tryStatements[node], |
| 480 buildTryBlock: subbuild(node.tryBlock), | 490 buildTryBlock: subbuild(node.tryBlock), |
| 481 catchClauseInfos: catchClauseInfos); | 491 catchClauseInfos: catchClauseInfos); |
| 482 } | 492 } |
| 483 | 493 |
| 484 // ==== Expressions ==== | 494 // ## Expressions ## |
| 485 ir.Primitive visitConditional(ast.Conditional node) { | 495 ir.Primitive visitConditional(ast.Conditional node) { |
| 486 return irBuilder.buildConditional( | 496 return irBuilder.buildConditional( |
| 487 build(node.condition), | 497 build(node.condition), |
| 488 subbuild(node.thenExpression), | 498 subbuild(node.thenExpression), |
| 489 subbuild(node.elseExpression)); | 499 subbuild(node.elseExpression)); |
| 490 } | 500 } |
| 491 | 501 |
| 492 // For all simple literals: | 502 // For all simple literals: |
| 493 // Build(Literal(c), C) = C[let val x = Constant(c) in [], x] | 503 // Build(Literal(c), C) = C[let val x = Constant(c) in [], x] |
| 494 ir.Primitive visitLiteralBool(ast.LiteralBool node) { | 504 ir.Primitive visitLiteralBool(ast.LiteralBool node) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 ## |
| 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 sourceInformation: sourceInformationBuilder.buildGet(node)); | |
| 681 } | |
| 682 | |
| 683 @override | |
| 684 ir.Primitive handleStaticFunctionGet( | |
| 685 ast.Send node, | |
| 686 MethodElement function, | |
| 687 _) { | |
| 688 // TODO(karlklose): support foreign functions. | |
| 689 if (function.isForeign(compiler.backend)) { | |
| 690 return giveup(node, 'handleStaticFunctionGet: foreign: $function'); | |
| 691 } | |
| 692 return irBuilder.buildStaticGet(function); | |
| 693 } | |
| 694 | |
| 695 @override | |
| 696 ir.Primitive handleStaticGetterGet( | |
| 697 ast.Send node, | |
| 698 FunctionElement getter, | |
| 699 _) { | |
| 700 return irBuilder.buildStaticInvocation(getter, | |
| 701 new Selector.getter(getter.name, getter.library), const []); | |
| 702 } | |
| 703 | |
| 704 @override | |
| 705 ir.Primitive visitSuperFieldGet( | |
| 706 ast.Send node, | |
| 707 FieldElement field, | |
| 708 _) { | |
| 709 return irBuilder.buildSuperGet(field); | |
| 710 } | |
| 711 | |
| 712 @override | |
| 713 ir.Primitive visitSuperGetterGet( | |
| 714 ast.Send node, | |
| 715 FunctionElement getter, | |
| 716 _) { | |
| 717 return irBuilder.buildSuperGet(getter); | |
| 718 } | |
| 719 | |
| 720 @override | |
| 721 ir.Primitive visitSuperMethodGet( | |
| 722 ast.Send node, | |
| 723 MethodElement method, | |
| 724 _) { | |
| 725 return irBuilder.buildSuperGet(method); | |
| 726 } | |
| 727 | |
| 728 @override | |
| 729 ir.Primitive visitThisGet(ast.Identifier node, _) { | |
| 730 return irBuilder.buildThis(); | |
| 731 } | |
| 732 | |
| 733 ir.Primitive translateTypeVariableTypeLiteral(TypeVariableElement element) { | |
| 734 return buildReifyTypeVariable(irBuilder.buildThis(), element.type); | |
| 735 } | |
| 736 | |
| 737 @override | |
| 738 ir.Primitive visitTypeVariableTypeLiteralGet(ast.Send node, | |
| 739 TypeVariableElement element, _) { | |
| 740 return translateTypeVariableTypeLiteral(element); | |
| 741 } | |
| 742 | |
| 743 ir.Primitive translateLogicalOperator(ast.Expression left, | |
| 744 ast.Expression right, | |
| 745 {bool isLazyOr}) { | |
| 707 ir.Primitive leftValue = visit(left); | 746 ir.Primitive leftValue = visit(left); |
| 708 | 747 |
| 709 ir.Primitive buildRightValue(IrBuilder rightBuilder) { | 748 ir.Primitive buildRightValue(IrBuilder rightBuilder) { |
| 710 return withBuilder(rightBuilder, () => visit(right)); | 749 return withBuilder(rightBuilder, () => visit(right)); |
| 711 } | 750 } |
| 712 | 751 |
| 713 return irBuilder.buildLogicalOperator( | 752 return irBuilder.buildLogicalOperator( |
| 714 leftValue, buildRightValue, isLazyOr: op.source == '||'); | 753 leftValue, buildRightValue, isLazyOr: isLazyOr); |
| 715 } | 754 } |
| 716 | 755 |
| 717 ir.Primitive visitOperatorSend(ast.Send node) { | 756 @override |
| 718 assert(irBuilder.isOpen); | 757 ir.Primitive visitLogicalAnd( |
| 719 ast.Operator op = node.selector; | 758 ast.Send node, ast.Node left, ast.Node right, _) { |
| 720 if (isUserDefinableOperator(op.source)) { | 759 return translateLogicalOperator(left, right, isLazyOr: false); |
| 721 return visitDynamicSend(node); | 760 } |
| 722 } | 761 |
| 723 if (op.source == '&&' || op.source == '||') { | 762 @override |
| 724 assert(node.receiver != null); | 763 ir.Primitive visitLogicalOr( |
| 725 assert(!node.arguments.isEmpty); | 764 ast.Send node, ast.Node left, ast.Node right, _) { |
| 726 assert(node.arguments.tail.isEmpty); | 765 return translateLogicalOperator(left, right, isLazyOr: true); |
| 727 return translateLogicalOperator(op, node.receiver, node.arguments.head); | 766 } |
| 728 } | 767 |
| 729 if (op.source == "!") { | 768 @override |
| 730 assert(node.receiver != null); | 769 ir.Primitive visitAs( |
| 731 assert(node.arguments.isEmpty); | 770 ast.Send node, |
| 732 return irBuilder.buildNegation(visit(node.receiver)); | 771 ast.Node expression, |
| 733 } | 772 DartType type, |
| 734 if (op.source == "!=") { | 773 _) { |
| 735 assert(node.receiver != null); | 774 ir.Primitive receiver = visit(expression); |
| 736 assert(!node.arguments.isEmpty); | 775 return irBuilder.buildTypeOperator(receiver, type, isTypeTest: false); |
| 737 assert(node.arguments.tail.isEmpty); | 776 } |
| 738 return irBuilder.buildNegation(visitDynamicSend(node)); | 777 |
| 739 } | 778 @override |
| 740 assert(invariant(node, op.source == "is" || op.source == "as", | 779 ir.Primitive visitIs( |
| 741 message: "unexpected operator $op")); | 780 ast.Send node, |
| 742 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); | 781 ast.Node expression, |
| 743 ir.Primitive receiver = visit(node.receiver); | 782 DartType type, |
| 783 _) { | |
| 784 ir.Primitive receiver = visit(expression); | |
| 744 return irBuilder.buildTypeOperator( | 785 return irBuilder.buildTypeOperator( |
| 745 receiver, type, | 786 receiver, type, |
| 746 isTypeTest: op.source == "is", | 787 isTypeTest: true, |
| 747 isNotCheck: node.isIsNotCheck); | 788 isNotCheck: false); |
| 748 } | 789 } |
| 749 | 790 |
| 750 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]] | 791 @override |
| 751 // where (C', xs) = arguments.fold(Build, C) | 792 ir.Primitive visitIsNot(ast.Send node, |
| 752 ir.Primitive visitStaticSend(ast.Send node) { | 793 ast.Node expression, DartType type, _) { |
| 753 assert(irBuilder.isOpen); | 794 ir.Primitive receiver = visit(expression); |
| 754 Element element = elements[node]; | 795 return irBuilder.buildTypeOperator( |
| 755 assert(!element.isConstructor); | 796 receiver, type, |
| 756 // TODO(lry): support foreign functions. | 797 isTypeTest: true, |
| 757 if (element.isForeign(compiler.backend)) { | 798 isNotCheck: true); |
| 758 return giveup(node, 'StaticSend: foreign'); | 799 } |
| 800 | |
| 801 ir.Primitive translateBinary(ast.Node left, | |
| 802 op.BinaryOperator operator, | |
| 803 ast.Node right) { | |
| 804 Selector selector = new Selector.binaryOperator(operator.selectorName); | |
| 805 ir.Primitive receiver = visit(left); | |
| 806 List<ir.Primitive> arguments = [visit(right)]; | |
| 807 arguments = normalizeDynamicArguments(selector, arguments); | |
| 808 return irBuilder.buildDynamicInvocation(receiver, selector, arguments); | |
| 809 } | |
| 810 | |
| 811 @override | |
| 812 ir.Primitive visitBinary(ast.Send node, | |
| 813 ast.Node left, | |
| 814 op.BinaryOperator operator, | |
| 815 ast.Node right, _) { | |
| 816 return translateBinary(left, operator, right); | |
| 817 } | |
| 818 | |
| 819 @override | |
| 820 ir.Primitive visitIndex(ast.Send node, | |
| 821 ast.Node receiver, | |
| 822 ast.Node index, _) { | |
| 823 Selector selector = new Selector.index(); | |
| 824 ir.Primitive target = visit(receiver); | |
| 825 List<ir.Primitive> arguments = [visit(index)]; | |
| 826 arguments = normalizeDynamicArguments(selector, arguments); | |
| 827 return irBuilder.buildDynamicInvocation(target, selector, arguments); | |
| 828 } | |
| 829 | |
| 830 ir.Primitive translateSuperBinary(FunctionElement function, | |
| 831 op.BinaryOperator operator, | |
| 832 ast.Node argument) { | |
| 833 Selector selector = new Selector.binaryOperator(operator.selectorName); | |
| 834 List<ir.Primitive> arguments = [visit(argument)]; | |
| 835 arguments = normalizeDynamicArguments(selector, arguments); | |
| 836 return irBuilder.buildSuperInvocation(function, selector, arguments); | |
| 837 } | |
| 838 | |
| 839 @override | |
| 840 ir.Primitive visitSuperBinary( | |
| 841 ast.Send node, | |
| 842 FunctionElement function, | |
| 843 op.BinaryOperator operator, | |
| 844 ast.Node argument, | |
| 845 _) { | |
| 846 return translateSuperBinary(function, operator, argument); | |
| 847 } | |
| 848 | |
| 849 @override | |
| 850 ir.Primitive visitSuperIndex( | |
| 851 ast.Send node, | |
| 852 FunctionElement function, | |
| 853 ast.Node index, | |
| 854 _) { | |
| 855 Selector selector = new Selector.index(); | |
| 856 List<ir.Primitive> arguments = [visit(index)]; | |
| 857 arguments = normalizeDynamicArguments(selector, arguments); | |
| 858 return irBuilder.buildSuperInvocation(function, selector, arguments); | |
| 859 } | |
| 860 | |
| 861 @override | |
| 862 ir.Primitive visitEquals( | |
| 863 ast.Send node, | |
| 864 ast.Node left, | |
| 865 ast.Node right, | |
| 866 _) { | |
| 867 return translateBinary(left, op.BinaryOperator.EQ, right); | |
| 868 } | |
| 869 | |
| 870 @override | |
| 871 ir.Primitive visitSuperEquals( | |
| 872 ast.Send node, | |
| 873 FunctionElement function, | |
| 874 ast.Node argument, | |
| 875 _) { | |
| 876 return translateSuperBinary(function, op.BinaryOperator.EQ, argument); | |
| 877 } | |
| 878 | |
| 879 @override | |
| 880 ir.Primitive visitNot( | |
| 881 ast.Send node, | |
| 882 ast.Node expression, | |
| 883 _) { | |
| 884 return irBuilder.buildNegation(visit(expression)); | |
| 885 } | |
| 886 | |
| 887 @override | |
| 888 ir.Primitive visitNotEquals( | |
| 889 ast.Send node, | |
| 890 ast.Node left, | |
| 891 ast.Node right, | |
| 892 _) { | |
| 893 return irBuilder.buildNegation( | |
| 894 translateBinary(left, op.BinaryOperator.NOT_EQ, right)); | |
| 895 } | |
| 896 | |
| 897 @override | |
| 898 ir.Primitive visitSuperNotEquals( | |
| 899 ast.Send node, | |
| 900 FunctionElement function, | |
| 901 ast.Node argument, | |
| 902 _) { | |
| 903 return irBuilder.buildNegation( | |
| 904 translateSuperBinary(function, op.BinaryOperator.NOT_EQ, argument)); | |
| 905 } | |
| 906 | |
| 907 @override | |
| 908 ir.Primitive visitUnary(ast.Send node, | |
| 909 op.UnaryOperator operator, ast.Node expression, _) { | |
| 910 // TODO(johnniwinther): Clean up the creation of selectors. | |
| 911 Selector selector = | |
| 912 new Selector(SelectorKind.OPERATOR, operator.selectorName, null, 0); | |
| 913 ir.Primitive receiver = translateReceiver(expression); | |
| 914 return irBuilder.buildDynamicInvocation(receiver, selector, const []); | |
| 915 } | |
| 916 | |
| 917 @override | |
| 918 ir.Primitive visitSuperUnary( | |
| 919 ast.Send node, | |
| 920 op.UnaryOperator operator, | |
| 921 FunctionElement function, | |
| 922 _) { | |
| 923 // TODO(johnniwinther): Clean up the creation of selectors. | |
| 924 Selector selector = | |
| 925 new Selector(SelectorKind.OPERATOR, operator.selectorName, null, 0); | |
| 926 return irBuilder.buildSuperInvocation(function, selector, const []); | |
| 927 } | |
| 928 | |
| 929 // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct | |
| 930 // semantic correlation between arguments and invocation. | |
| 931 List<ir.Primitive> translateDynamicArguments(ast.NodeList nodeList, | |
| 932 Selector selector) { | |
| 933 List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit); | |
| 934 return normalizeDynamicArguments(selector, arguments); | |
| 935 } | |
| 936 | |
| 937 // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct | |
| 938 // semantic correlation between arguments and invocation. | |
| 939 List<ir.Primitive> translateStaticArguments(ast.NodeList nodeList, | |
| 940 Element element, | |
| 941 Selector selector) { | |
| 942 List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit); | |
| 943 return normalizeStaticArguments(selector, element, arguments); | |
| 944 } | |
| 945 | |
| 946 ir.Primitive translateCallInvoke(ir.Primitive target, | |
| 947 ast.NodeList arguments, | |
| 948 Selector selector) { | |
| 949 | |
| 950 return irBuilder.buildCallInvocation(target, selector, | |
| 951 translateDynamicArguments(arguments, selector)); | |
| 952 } | |
| 953 | |
| 954 ir.Primitive translateConstantInvoke(ConstantExpression constant, | |
| 955 ast.NodeList arguments, | |
| 956 Selector selector) { | |
| 957 return translateCallInvoke( | |
| 958 irBuilder.buildConstantLiteral(constant), | |
| 959 arguments, | |
| 960 selector); | |
| 961 } | |
| 962 | |
| 963 @override | |
| 964 ir.Primitive handleConstantInvoke( | |
| 965 ast.Send node, | |
| 966 ConstantExpression constant, | |
| 967 ast.NodeList arguments, | |
| 968 Selector selector, | |
| 969 _) { | |
| 970 return translateConstantInvoke(constant, arguments, selector); | |
| 971 } | |
| 972 | |
| 973 @override | |
| 974 ir.Primitive handleDynamicInvoke( | |
| 975 ast.Send node, | |
| 976 ast.Node receiver, | |
| 977 ast.NodeList arguments, | |
| 978 Selector selector, | |
| 979 _) { | |
| 980 return irBuilder.buildDynamicInvocation( | |
| 981 translateReceiver(receiver), selector, | |
| 982 translateDynamicArguments(arguments, selector)); | |
| 983 } | |
| 984 | |
| 985 ir.Primitive handleLocalInvoke( | |
| 986 ast.Send node, | |
| 987 LocalElement element, | |
| 988 ast.NodeList arguments, | |
| 989 Selector selector, | |
| 990 _) { | |
| 991 return irBuilder.buildLocalInvocation(element, selector, | |
| 992 translateDynamicArguments(arguments, selector)); | |
| 993 } | |
| 994 | |
| 995 @override | |
| 996 ir.Primitive handleStaticFieldInvoke( | |
| 997 ast.Send node, | |
| 998 FieldElement field, | |
| 999 ast.NodeList arguments, | |
| 1000 Selector selector, | |
| 1001 _) { | |
| 1002 return translateCallInvoke( | |
| 1003 irBuilder.buildStaticGet(field), | |
| 1004 arguments, selector); | |
| 1005 } | |
| 1006 | |
| 1007 @override | |
| 1008 ir.Primitive handleStaticFunctionInvoke( | |
| 1009 ast.Send node, | |
| 1010 MethodElement function, | |
| 1011 ast.NodeList arguments, | |
| 1012 Selector selector, | |
| 1013 _) { | |
| 1014 // TODO(karlklose): support foreign functions. | |
| 1015 if (function.isForeign(compiler.backend)) { | |
| 1016 return giveup(node, 'handleStaticFunctionInvoke: foreign: $function'); | |
| 759 } | 1017 } |
| 760 | 1018 return irBuilder.buildStaticInvocation(function, selector, |
| 761 Selector selector = elements.getSelector(node); | 1019 translateStaticArguments(arguments, function, selector), |
| 762 | 1020 sourceInformation: sourceInformationBuilder.buildCall(node)); |
| 763 if (selector.isCall && (element.isGetter || element.isField)) { | 1021 } |
| 764 // We are invoking a static field or getter as if it was a method, e.g: | 1022 |
| 765 // | 1023 @override |
| 766 // get foo => {..} | 1024 ir.Primitive handleStaticGetterInvoke( |
| 767 // main() { foo(1, 2, 3); } | 1025 ast.Send node, |
| 768 // | 1026 FunctionElement getter, |
| 769 // We invoke the getter of 'foo' and then invoke the 'call' method | 1027 ast.NodeList arguments, |
| 770 // on the result, using the given arguments. | 1028 Selector selector, |
| 771 Selector getter = new Selector.getterFrom(selector); | 1029 _) { |
| 772 Selector call = new Selector.callClosureFrom(selector); | 1030 return translateCallInvoke( |
| 773 ir.Primitive receiver = irBuilder.buildStaticGet(element, getter); | 1031 irBuilder.buildStaticGet(getter), |
| 774 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 1032 arguments, selector); |
| 775 arguments = normalizeDynamicArguments(selector, arguments); | 1033 } |
| 776 return irBuilder.buildCallInvocation(receiver, call, arguments); | 1034 |
| 777 } else if (selector.isGetter) { | 1035 @override |
| 778 // We are reading a static field or invoking a static getter. | 1036 ir.Primitive visitSuperFieldInvoke( |
| 779 return irBuilder.buildStaticGet(element, selector); | 1037 ast.Send node, |
| 780 } else { | 1038 FieldElement field, |
| 781 // We are invoking a static method. | 1039 ast.NodeList arguments, |
| 782 assert(selector.isCall); | 1040 Selector selector, |
| 783 assert(element is FunctionElement); | 1041 _) { |
| 784 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 1042 return translateCallInvoke( |
| 785 arguments = normalizeStaticArguments(selector, element, arguments); | 1043 irBuilder.buildSuperGet(field), |
|
karlklose
2015/03/18 10:42:56
Indentation is wrong.
Johnni Winther
2015/03/20 13:40:59
Done.
| |
| 786 return irBuilder.buildStaticInvocation(element, selector, arguments, | 1044 arguments, selector); |
| 787 sourceInformation: sourceInformationBuilder.buildCall(node)); | 1045 } |
| 788 } | 1046 |
| 789 } | 1047 @override |
| 790 | 1048 ir.Primitive visitSuperGetterInvoke( |
| 791 ir.Primitive visitSuperSend(ast.Send node) { | 1049 ast.Send node, |
| 792 assert(irBuilder.isOpen); | 1050 FunctionElement getter, |
| 793 Selector selector = elements.getSelector(node); | 1051 ast.NodeList arguments, |
| 794 Element target = elements[node]; | 1052 Selector selector, |
| 795 | 1053 _) { |
| 796 if (selector.isCall && (target.isGetter || target.isField)) { | 1054 return translateCallInvoke( |
| 797 // We are invoking a field or getter as if it was a method, e.g: | 1055 irBuilder.buildSuperGet(getter), |
| 798 // | 1056 arguments, selector); |
| 799 // class A { get foo => {..} } | 1057 } |
| 800 // class B extends A { | 1058 |
| 801 // m() { | 1059 @override |
| 802 // super.foo(1, 2, 3); } | 1060 ir.Primitive visitSuperMethodInvoke( |
| 803 // } | 1061 ast.Send node, |
| 804 // } | 1062 MethodElement method, |
| 805 // | 1063 ast.NodeList arguments, |
| 806 // We invoke the getter of 'foo' and then invoke the 'call' method on | 1064 Selector selector, |
| 807 // the result, using the given arguments. | 1065 _) { |
| 808 Selector getter = new Selector.getterFrom(selector); | 1066 return irBuilder.buildSuperInvocation(method, selector, |
| 809 Selector call = new Selector.callClosureFrom(selector); | 1067 translateDynamicArguments(arguments, selector)); |
| 810 ir.Primitive receiver = | 1068 } |
| 811 irBuilder.buildSuperInvocation(target, getter, []); | 1069 |
| 812 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 1070 @override |
| 813 arguments = normalizeDynamicArguments(selector, arguments); | 1071 ir.Primitive visitThisInvoke( |
| 814 return irBuilder.buildCallInvocation(receiver, call, arguments); | 1072 ast.Send node, |
| 815 } else if (selector.isCall) { | 1073 ast.NodeList arguments, |
| 816 // We are invoking a method. | 1074 Selector selector, |
| 817 assert(target is FunctionElement); | 1075 _) { |
| 818 List<ir.Primitive> arguments = node.arguments.mapToList(visit); | 1076 return translateCallInvoke(irBuilder.buildThis(), arguments, selector); |
| 819 arguments = normalizeStaticArguments(selector, target, arguments); | 1077 } |
| 820 return irBuilder.buildSuperInvocation(target, selector, arguments); | 1078 |
| 821 } else { | 1079 @override |
| 822 // We are invoking a getter, operator, indexer, etc. | 1080 ir.Primitive visitTypeVariableTypeLiteralInvoke( |
| 823 List<ir.Primitive> arguments = node.argumentsNode == null | 1081 ast.Send node, |
| 824 ? <ir.Primitive>[] | 1082 TypeVariableElement element, |
| 825 : node.arguments.mapToList(visit); | 1083 ast.NodeList arguments, |
| 826 return irBuilder.buildSuperInvocation(target, selector, arguments); | 1084 Selector selector, |
| 827 } | 1085 _) { |
| 828 } | 1086 return translateCallInvoke( |
| 829 | 1087 translateTypeVariableTypeLiteral(element), |
| 830 visitTypePrefixSend(ast.Send node) { | 1088 arguments, |
| 831 compiler.internalError(node, "visitTypePrefixSend should not be called."); | 1089 selector); |
| 832 } | 1090 } |
| 833 | 1091 |
| 834 ir.Primitive visitTypeLiteralSend(ast.Send node) { | 1092 @override |
| 835 assert(irBuilder.isOpen); | 1093 ir.Primitive visitTypedefTypeLiteralInvoke( |
| 836 // If the user is trying to invoke the type literal or variable, | 1094 ast.Send node, |
| 837 // it must be treated as a function call. | 1095 TypeConstantExpression constant, |
| 838 if (node.argumentsNode != null) { | 1096 ast.NodeList arguments, |
| 839 // TODO(sigurdm): Handle this to match proposed semantics of issue #19725. | 1097 Selector selector, _) { |
| 840 return giveup(node, 'Type literal invoked as function'); | 1098 return translateConstantInvoke(constant, arguments, selector); |
| 841 } | 1099 } |
| 842 | 1100 |
| 843 DartType type = elements.getTypeLiteralType(node); | 1101 // TODO(johnniwinther): This should be a method on [IrBuilder]. |
| 844 if (type is TypeVariableType) { | |
| 845 return buildReifyTypeVariable(irBuilder.buildThis(), type); | |
| 846 } else { | |
| 847 return translateConstant(node); | |
| 848 } | |
| 849 } | |
| 850 | |
| 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]; | |
|
karlklose
2015/03/18 10:42:56
Add type arguments to list literal.
Johnni Winther
2015/03/20 13:41:00
Done.
| |
| 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)]; |
|
karlklose
2015/03/18 10:42:56
Type argument for list literal.
Johnni Winther
2015/03/20 13:41:00
Done.
| |
| 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.buildSuperGet(readField), | |
| 1546 operator: operator, | |
| 1547 setValue: (ir.Primitive result) { | |
| 1548 irBuilder.buildSuperSet(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.buildSuperGet(readField), | |
| 1562 operator: operator, | |
| 1563 setValue: (ir.Primitive result) { | |
| 1564 irBuilder.buildSuperSet(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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |