| Index: pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
|
| diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
|
| index 92abcc8bf4e6fd2339c50be1d1a1a9813b4354eb..8227e7f62a7c47388cd15533175cea0c4af83c5b 100644
|
| --- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
|
| +++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
|
| @@ -42,13 +42,6 @@ abstract class Node {
|
| abstract class Expression extends Node {
|
| accept(ExpressionVisitor v);
|
| accept1(ExpressionVisitor1 v, arg);
|
| -
|
| - /// Temporary variable used by [StatementRewriter].
|
| - /// If set to true, this expression has already had enclosing assignments
|
| - /// propagated into its variables, and should not be processed again.
|
| - /// It is only set for expressions that are known to be in risk of redundant
|
| - /// processing.
|
| - bool processed = false;
|
| }
|
|
|
| abstract class Statement extends Node {
|
| @@ -143,6 +136,24 @@ class VariableUse extends Expression {
|
| }
|
| }
|
|
|
| +class Assign extends Expression {
|
| + Variable variable;
|
| + Expression value;
|
| +
|
| + Assign(this.variable, this.value) {
|
| + variable.writeCount++;
|
| + }
|
| +
|
| + accept(ExpressionVisitor v) => v.visitAssign(this);
|
| + accept1(ExpressionVisitor1 v, arg) => v.visitAssign(this, arg);
|
| +
|
| + static ExpressionStatement makeStatement(Variable variable,
|
| + Expression value,
|
| + [Statement next]) {
|
| + return new ExpressionStatement(new Assign(variable, value), next);
|
| + }
|
| +}
|
| +
|
| /**
|
| * Common interface for invocations with arguments.
|
| */
|
| @@ -519,33 +530,26 @@ class Continue extends Jump {
|
| accept1(StatementVisitor1 visitor, arg) => visitor.visitContinue(this, arg);
|
| }
|
|
|
| -/**
|
| - * An assignments of an [Expression] to a [Variable].
|
| - *
|
| - * In contrast to the CPS-based IR, non-primitive expressions can be assigned
|
| - * to variables.
|
| - */
|
| -class Assign extends Statement {
|
| - Statement next;
|
| +/// Declares a captured [variable] with an initial [value].
|
| +///
|
| +/// All uses of the variable must be inside the [next] statement.
|
| +class VariableDeclaration extends Statement implements DartSpecificNode {
|
| Variable variable;
|
| Expression value;
|
| + Statement next;
|
|
|
| - /// If true, this assignes to a fresh variable scoped to the [next]
|
| - /// statement.
|
| - ///
|
| - /// Variable declarations themselves are hoisted to function level.
|
| - bool isDeclaration;
|
| -
|
| - /// Creates an assignment to [variable] and updates its `writeCount`.
|
| - Assign(this.variable, this.value, this.next,
|
| - { this.isDeclaration: false }) {
|
| - variable.writeCount++;
|
| + VariableDeclaration(this.variable, this.value, this.next) {
|
| + assert(variable.isCaptured); // Because otherwise no declaration is needed.
|
| + ++variable.writeCount;
|
| }
|
|
|
| - bool get hasExactlyOneUse => variable.readCount == 1;
|
| + accept(StatementVisitor visitor) {
|
| + return visitor.visitVariableDeclaration(this);
|
| + }
|
|
|
| - accept(StatementVisitor visitor) => visitor.visitAssign(this);
|
| - accept1(StatementVisitor1 visitor, arg) => visitor.visitAssign(this, arg);
|
| + accept1(StatementVisitor1 visitor, arg) {
|
| + return visitor.visitVariableDeclaration(this, arg);
|
| + }
|
| }
|
|
|
| /**
|
| @@ -818,16 +822,15 @@ class GetField extends Expression implements JsSpecificNode {
|
| accept1(ExpressionVisitor1 visitor, arg) => visitor.visitGetField(this, arg);
|
| }
|
|
|
| -class SetField extends Statement implements JsSpecificNode {
|
| +class SetField extends Expression implements JsSpecificNode {
|
| Expression object;
|
| Element field;
|
| Expression value;
|
| - Statement next;
|
|
|
| - SetField(this.object, this.field, this.value, this.next);
|
| + SetField(this.object, this.field, this.value);
|
|
|
| - accept(StatementVisitor visitor) => visitor.visitSetField(this);
|
| - accept1(StatementVisitor1 visitor, arg) => visitor.visitSetField(this, arg);
|
| + accept(ExpressionVisitor visitor) => visitor.visitSetField(this);
|
| + accept1(ExpressionVisitor1 visitor, arg) => visitor.visitSetField(this, arg);
|
| }
|
|
|
| class ReifyRuntimeType extends Expression implements JsSpecificNode {
|
| @@ -880,6 +883,7 @@ class TypeExpression extends Expression {
|
| abstract class ExpressionVisitor<E> {
|
| E visitExpression(Expression node) => node.accept(this);
|
| E visitVariableUse(VariableUse node);
|
| + E visitAssign(Assign node);
|
| E visitInvokeStatic(InvokeStatic node);
|
| E visitInvokeMethod(InvokeMethod node);
|
| E visitInvokeMethodDirectly(InvokeMethodDirectly node);
|
| @@ -901,11 +905,13 @@ abstract class ExpressionVisitor<E> {
|
| E visitReifyRuntimeType(ReifyRuntimeType node);
|
| E visitReadTypeVariable(ReadTypeVariable node);
|
| E visitTypeExpression(TypeExpression node);
|
| + E visitSetField(SetField node);
|
| }
|
|
|
| abstract class ExpressionVisitor1<E, A> {
|
| E visitExpression(Expression node, A arg) => node.accept1(this, arg);
|
| E visitVariableUse(VariableUse node, A arg);
|
| + E visitAssign(Assign node, A arg);
|
| E visitInvokeStatic(InvokeStatic node, A arg);
|
| E visitInvokeMethod(InvokeMethod node, A arg);
|
| E visitInvokeMethodDirectly(InvokeMethodDirectly node, A arg);
|
| @@ -927,12 +933,12 @@ abstract class ExpressionVisitor1<E, A> {
|
| E visitReifyRuntimeType(ReifyRuntimeType node, A arg);
|
| E visitReadTypeVariable(ReadTypeVariable node, A arg);
|
| E visitTypeExpression(TypeExpression node, A arg);
|
| + E visitSetField(SetField node, A arg);
|
| }
|
|
|
| abstract class StatementVisitor<S> {
|
| S visitStatement(Statement node) => node.accept(this);
|
| S visitLabeledStatement(LabeledStatement node);
|
| - S visitAssign(Assign node);
|
| S visitReturn(Return node);
|
| S visitBreak(Break node);
|
| S visitContinue(Continue node);
|
| @@ -940,15 +946,14 @@ abstract class StatementVisitor<S> {
|
| S visitWhileTrue(WhileTrue node);
|
| S visitWhileCondition(WhileCondition node);
|
| S visitFunctionDeclaration(FunctionDeclaration node);
|
| + S visitVariableDeclaration(VariableDeclaration node);
|
| S visitExpressionStatement(ExpressionStatement node);
|
| S visitTry(Try node);
|
| - S visitSetField(SetField node);
|
| }
|
|
|
| abstract class StatementVisitor1<S, A> {
|
| S visitStatement(Statement node, A arg) => node.accept1(this, arg);
|
| S visitLabeledStatement(LabeledStatement node, A arg);
|
| - S visitAssign(Assign node, A arg);
|
| S visitReturn(Return node, A arg);
|
| S visitBreak(Break node, A arg);
|
| S visitContinue(Continue node, A arg);
|
| @@ -956,9 +961,9 @@ abstract class StatementVisitor1<S, A> {
|
| S visitWhileTrue(WhileTrue node, A arg);
|
| S visitWhileCondition(WhileCondition node, A arg);
|
| S visitFunctionDeclaration(FunctionDeclaration node, A arg);
|
| + S visitVariableDeclaration(VariableDeclaration node, A arg);
|
| S visitExpressionStatement(ExpressionStatement node, A arg);
|
| S visitTry(Try node, A arg);
|
| - S visitSetField(SetField node, A arg);
|
| }
|
|
|
| abstract class RootVisitor<T> {
|
| @@ -981,6 +986,7 @@ abstract class InitializerVisitor<T> {
|
| T visitSuperInitializer(SuperInitializer node);
|
| }
|
|
|
| +
|
| abstract class InitializerVisitor1<T, A> {
|
| T visitInitializer(Initializer node, A arg) => node.accept1(this, arg);
|
| T visitFieldInitializer(FieldInitializer node, A arg);
|
| @@ -993,12 +999,22 @@ abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor {
|
|
|
| visitInnerFunction(FunctionDefinition node);
|
|
|
| - visitVariable(Variable node) {}
|
| + visitVariable(Variable variable) {}
|
|
|
| visitVariableUse(VariableUse node) {
|
| visitVariable(node.variable);
|
| }
|
|
|
| + visitVariableDeclaration(VariableDeclaration node) {
|
| + visitVariable(node.variable);
|
| + visitStatement(node.next);
|
| + }
|
| +
|
| + visitAssign(Assign node) {
|
| + visitVariable(node.variable);
|
| + visitExpression(node.value);
|
| + }
|
| +
|
| visitInvokeStatic(InvokeStatic node) {
|
| node.arguments.forEach(visitExpression);
|
| }
|
| @@ -1066,12 +1082,6 @@ abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor {
|
| visitStatement(node.next);
|
| }
|
|
|
| - visitAssign(Assign node) {
|
| - visitExpression(node.value);
|
| - visitVariable(node.variable);
|
| - visitStatement(node.next);
|
| - }
|
| -
|
| visitReturn(Return node) {
|
| visitExpression(node.value);
|
| }
|
| @@ -1118,7 +1128,6 @@ abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor {
|
| visitSetField(SetField node) {
|
| visitExpression(node.object);
|
| visitExpression(node.value);
|
| - visitStatement(node.next);
|
| }
|
|
|
| visitCreateBox(CreateBox node) {
|
| @@ -1161,6 +1170,16 @@ class RecursiveTransformer extends Transformer {
|
|
|
| visitVariableUse(VariableUse node) => node;
|
|
|
| + visitVariableDeclaration(VariableDeclaration node) {
|
| + node.next = visitStatement(node.next);
|
| + return node;
|
| + }
|
| +
|
| + visitAssign(Assign node) {
|
| + node.value = visitExpression(node.value);
|
| + return node;
|
| + }
|
| +
|
| visitInvokeStatic(InvokeStatic node) {
|
| _replaceExpressions(node.arguments);
|
| return node;
|
| @@ -1241,12 +1260,6 @@ class RecursiveTransformer extends Transformer {
|
| return node;
|
| }
|
|
|
| - visitAssign(Assign node) {
|
| - node.value = visitExpression(node.value);
|
| - node.next = visitStatement(node.next);
|
| - return node;
|
| - }
|
| -
|
| visitReturn(Return node) {
|
| node.value = visitExpression(node.value);
|
| return node;
|
| @@ -1301,7 +1314,6 @@ class RecursiveTransformer extends Transformer {
|
| visitSetField(SetField node) {
|
| node.object = visitExpression(node.object);
|
| node.value = visitExpression(node.value);
|
| - node.next = visitStatement(node.next);
|
| return node;
|
| }
|
|
|
|
|