Index: lib/kernel_visitor.dart |
diff --git a/lib/kernel_visitor.dart b/lib/kernel_visitor.dart |
index 62ef46d9c4d5f5b52236fe6484b3746964bfa034..24d961e5fe79548fdbd736ba21f6adbf47691463 100644 |
--- a/lib/kernel_visitor.dart |
+++ b/lib/kernel_visitor.dart |
@@ -258,22 +258,18 @@ class KernelVisitor extends Object |
node.message?.accept(this)); |
} |
- ir.ForInStatement buildForIn(ForIn node, {bool isAsync}) { |
- return new ir.ForInStatement( |
- buildStatementInBlock(node.declaredIdentifier), |
- node.expression.accept(this), |
- buildStatementInBlock(node.body), |
- isAsync: isAsync); |
+ ir.LabeledStatement getBreakTarget(JumpTarget target) { |
+ return breakTargets.putIfAbsent( |
+ target, () => new ir.LabeledStatement(null)); |
} |
- @override |
- ir.ForInStatement visitAsyncForIn(AsyncForIn node) { |
- return buildForIn(node, isAsync: true); |
+ ir.LabeledStatement getContinueTarget(JumpTarget target) { |
+ return continueTargets.putIfAbsent( |
+ target, () => new ir.LabeledStatement(null)); |
} |
- @override |
- ir.Throw visitAwait(Await node) { |
- return buildUnsupported(node, "Await"); |
+ ir.SwitchCase getContinueSwitchTarget(JumpTarget target) { |
+ return continueSwitchTargets[target]; |
} |
ir.Statement buildBreakTarget( |
@@ -291,6 +287,43 @@ class KernelVisitor extends Object |
} |
} |
+ ir.Statement buildContinueTarget( |
kasperl
2016/05/19 14:13:30
This helper makes a big difference for the readabi
ahe
2016/05/19 18:41:46
Acknowledged.
|
+ ir.Statement statement, |
+ Node node, |
+ JumpTarget jumpTarget) { |
+ assert(jumpTarget == elements.getTargetDefinition(node)); |
+ if (jumpTarget != null && jumpTarget.isContinueTarget) { |
+ ir.LabeledStatement continueTarget = getContinueTarget(jumpTarget); |
+ continueTarget.body = statement; |
+ statement.parent = continueTarget; |
+ return continueTarget; |
+ } else { |
+ return statement; |
+ } |
+ } |
+ |
+ ir.Statement buildForIn(ForIn node, {bool isAsync}) { |
+ ir.VariableDeclaration variable = |
+ buildStatementInBlock(node.declaredIdentifier); |
+ ir.Expression iterable = node.expression.accept(this); |
+ JumpTarget jumpTarget = elements.getTargetDefinition(node); |
+ ir.Statement body = buildContinueTarget( |
+ buildStatementInBlock(node.body), node, jumpTarget); |
+ return buildBreakTarget( |
+ new ir.ForInStatement(variable, iterable, body, isAsync: isAsync), |
+ node, jumpTarget); |
+ } |
+ |
+ @override |
+ ir.Statement visitAsyncForIn(AsyncForIn node) { |
+ return buildForIn(node, isAsync: true); |
+ } |
+ |
+ @override |
+ ir.Throw visitAwait(Await node) { |
+ return buildUnsupported(node, "Await"); |
+ } |
+ |
@override |
ir.Statement visitBlock(Block node) { |
return buildBreakTarget( |
@@ -431,7 +464,7 @@ class KernelVisitor extends Object |
} |
@override |
- ir.BreakStatement visitContinueStatement(ContinueStatement node) { |
+ ir.Statement visitContinueStatement(ContinueStatement node) { |
JumpTarget target = elements.getTargetOf(node); |
ir.SwitchCase switchCase = getContinueSwitchTarget(target); |
if (switchCase == null) { |
@@ -443,19 +476,10 @@ class KernelVisitor extends Object |
@override |
ir.Statement visitDoWhile(DoWhile node) { |
- ir.Statement body = buildStatementInBlock(node.body); |
- ir.Expression condition = node.condition?.accept(this); |
- |
- // TODO(ahe): Unify jump target handling between For, While, and Do. |
JumpTarget jumpTarget = elements.getTargetDefinition(node); |
- |
- if (jumpTarget != null && jumpTarget.isContinueTarget) { |
- ir.LabeledStatement continueTarget = getContinueTarget(jumpTarget); |
- continueTarget.body = body; |
- body.parent = continueTarget; |
- body = continueTarget; |
- } |
- |
+ ir.Statement body = buildContinueTarget( |
+ buildStatementInBlock(node.body), node, jumpTarget); |
+ ir.Expression condition = node.condition?.accept(this); |
return buildBreakTarget( |
new ir.DoStatement(body, condition), node, jumpTarget); |
} |
@@ -475,20 +499,6 @@ class KernelVisitor extends Object |
return new ir.ExpressionStatement(node.expression.accept(this)); |
} |
- ir.LabeledStatement getBreakTarget(JumpTarget target) { |
- return breakTargets.putIfAbsent( |
- target, () => new ir.LabeledStatement(null)); |
- } |
- |
- ir.LabeledStatement getContinueTarget(JumpTarget target) { |
- return continueTargets.putIfAbsent( |
- target, () => new ir.LabeledStatement(null)); |
- } |
- |
- ir.SwitchCase getContinueSwitchTarget(JumpTarget target) { |
- return continueSwitchTargets[target]; |
- } |
- |
@override |
ir.Statement visitFor(For node) { |
VariableDefinitions initializers = |
@@ -509,15 +519,10 @@ class KernelVisitor extends Object |
for (Expression update in node.update) { |
updates.add(update.accept(this)); |
} |
- ir.Statement body = buildStatementInBlock(node.body); |
- JumpTarget jumpTarget = elements.getTargetDefinition(node); |
- if (jumpTarget != null && jumpTarget.isContinueTarget) { |
- ir.LabeledStatement continueTarget = getContinueTarget(jumpTarget); |
- continueTarget.body = body; |
- body.parent = continueTarget; |
- body = continueTarget; |
- } |
+ JumpTarget jumpTarget = elements.getTargetDefinition(node); |
+ ir.Statement body = buildContinueTarget( |
+ buildStatementInBlock(node.body), node, jumpTarget); |
ir.ForStatement forStatement = new ir.ForStatement( |
variables, condition, updates, body); |
ir.Statement result = buildBreakTarget(forStatement, node, jumpTarget); |
@@ -748,7 +753,7 @@ class KernelVisitor extends Object |
} |
@override |
- ir.ForInStatement visitSyncForIn(SyncForIn node) { |
+ ir.Statement visitSyncForIn(SyncForIn node) { |
return buildForIn(node, isAsync: false); |
} |
@@ -787,17 +792,9 @@ class KernelVisitor extends Object |
@override |
ir.Statement visitWhile(While node) { |
ir.Expression condition = node.condition?.accept(this); |
- |
- ir.Statement body = buildStatementInBlock(node.body); |
JumpTarget jumpTarget = elements.getTargetDefinition(node); |
- |
- if (jumpTarget != null && jumpTarget.isContinueTarget) { |
- ir.LabeledStatement continueTarget = getContinueTarget(jumpTarget); |
- continueTarget.body = body; |
- body.parent = continueTarget; |
- body = continueTarget; |
- } |
- |
+ ir.Statement body = buildContinueTarget( |
+ buildStatementInBlock(node.body), node, jumpTarget); |
return buildBreakTarget( |
new ir.WhileStatement(condition, body), node, jumpTarget); |
} |