Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart |
| index 200a27a393041e5a52bf12cc667c5045ae1c03c8..1c945b46b1a246ac84623c5c4e225e8f289ddbdc 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart |
| @@ -6,8 +6,13 @@ library dart_tree; |
| import '../dart2jslib.dart' as dart2js; |
| import '../elements/elements.dart' |
| - show Element, FunctionElement, FunctionSignature, ParameterElement; |
| + show Element, FunctionElement, FunctionSignature, ParameterElement, |
| + ClassElement; |
| +import '../universe/universe.dart'; |
| import '../ir/ir_nodes.dart' as ir; |
| +import '../tree/tree.dart' as ast; |
| +import '../scanner/scannerlib.dart'; |
| +import '../dart_types.dart' show DartType, GenericType; |
| // The Tree language is the target of translation out of the CPS-based IR. |
| // |
| @@ -102,6 +107,43 @@ class InvokeStatic extends Expression { |
| } |
| /** |
| + * A call to a method, operator, getter, setter or index getter/setter. |
| + * |
| + * In contrast to the CPS-based IR, the receiver and arguments can be |
| + * arbitrary expressions. |
| + */ |
| +class InvokeMethod extends Expression { |
| + Expression receiver; |
| + final Selector selector; |
| + final List<Expression> arguments; |
| + |
| + InvokeMethod(this.receiver, this.selector, this.arguments) { |
| + assert(receiver != null); |
| + } |
| + |
| + final bool isPure = false; |
| + |
| + accept(Visitor visitor) => visitor.visitInvokeMethod(this); |
| +} |
| + |
| +/** |
| + * Non-const call to a factory or generative constructor. |
| + */ |
| +class InvokeConstructor extends Expression { |
| + final GenericType type; |
| + final FunctionElement target; |
| + final List<Expression> arguments; |
| + |
| + InvokeConstructor(this.type, this.target, this.arguments); |
| + |
| + ClassElement get targetClass => target.enclosingElement; |
| + |
| + final bool isPure = false; |
| + |
| + accept(Visitor visitor) => visitor.visitInvokeConstructor(this); |
| +} |
| + |
| +/** |
| * A constant. |
| */ |
| class Constant extends Expression { |
| @@ -213,6 +255,8 @@ abstract class Visitor<S, E> { |
| E visitExpression(Expression e) => e.accept(this); |
| E visitVariable(Variable node); |
| E visitInvokeStatic(InvokeStatic node); |
| + E visitInvokeMethod(InvokeMethod node); |
| + E visitInvokeConstructor(InvokeConstructor node); |
| E visitConstant(Constant node); |
| S visitStatement(Statement s) => s.accept(this); |
| @@ -371,6 +415,38 @@ class Builder extends ir.Visitor<Node> { |
| } |
| } |
| + Statement visitInvokeMethod(ir.InvokeMethod node) { |
| + Variable receiver = variables[node.receiver.definition]; |
| + List<Expression> arguments = translateArguments(node.arguments); |
| + Expression invoke = new InvokeMethod(receiver, node.selector, arguments); |
| + ir.Continuation cont = node.continuation.definition; |
| + if (cont == returnContinuation) { |
| + return new Return(invoke); |
| + } else { |
| + assert(cont.hasExactlyOneUse); |
| + assert(cont.parameters.length == 1); |
| + return buildParameterAssignments(cont.parameters, [invoke], |
| + () => visit(cont.body)); |
| + } |
| + } |
| + |
| + Statement visitInvokeConstructor(ir.InvokeConstructor node) { |
| + List<Expression> arguments = translateArguments(node.arguments); |
| + Expression invoke = new InvokeConstructor( |
|
Kevin Millikin (Google)
2014/05/09 11:12:59
I would break this at = since it is the lowest pre
|
| + node.type, |
| + node.target, |
| + arguments); |
| + ir.Continuation cont = node.continuation.definition; |
| + if (cont == returnContinuation) { |
| + return new Return(invoke); |
| + } else { |
| + assert(cont.hasExactlyOneUse); |
| + assert(cont.parameters.length == 1); |
| + return buildParameterAssignments(cont.parameters, [invoke], |
| + () => visit(cont.body)); |
| + } |
| + } |
| + |
| Statement visitInvokeContinuation(ir.InvokeContinuation node) { |
| // Invocations of the return continuation are translated to returns. |
| // Other continuation invocations are replaced with assignments of the |
| @@ -529,6 +605,21 @@ class Unnamer extends Visitor<Statement, Expression> { |
| return node; |
| } |
| + Expression visitInvokeMethod(InvokeMethod node) { |
| + for (int i = node.arguments.length - 1; i >= 0; --i) { |
| + node.arguments[i] = visitExpression(node.arguments[i]); |
| + } |
| + node.receiver = visitExpression(node.receiver); |
| + return node; |
| + } |
| + |
| + Expression visitInvokeConstructor(InvokeConstructor node) { |
| + for (int i = node.arguments.length - 1; i >= 0; --i) { |
| + node.arguments[i] = visitExpression(node.arguments[i]); |
| + } |
| + return node; |
| + } |
| + |
| Statement visitReturn(Return node) { |
| node.value = visitExpression(node.value); |
| return node; |