Chromium Code Reviews| 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); |
| } |