Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 library rasta.kernel_visitor; | 5 library rasta.kernel_visitor; |
| 6 | 6 |
| 7 import 'package:kernel/ast.dart' as ir; | 7 import 'package:kernel/ast.dart' as ir; |
| 8 | 8 |
| 9 import 'package:kernel/accessors.dart' show | 9 import 'package:kernel/accessors.dart' show |
| 10 Accessor, | 10 Accessor, |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 throw new Unsupported("Not implemented yet."); | 251 throw new Unsupported("Not implemented yet."); |
| 252 } | 252 } |
| 253 | 253 |
| 254 @override | 254 @override |
| 255 ir.AssertStatement visitAssert(Assert node) { | 255 ir.AssertStatement visitAssert(Assert node) { |
| 256 return new ir.AssertStatement( | 256 return new ir.AssertStatement( |
| 257 node.condition.accept(this), | 257 node.condition.accept(this), |
| 258 node.message?.accept(this)); | 258 node.message?.accept(this)); |
| 259 } | 259 } |
| 260 | 260 |
| 261 ir.ForInStatement buildForIn(ForIn node, {bool isAsync}) { | 261 ir.LabeledStatement getBreakTarget(JumpTarget target) { |
| 262 return new ir.ForInStatement( | 262 return breakTargets.putIfAbsent( |
| 263 buildStatementInBlock(node.declaredIdentifier), | 263 target, () => new ir.LabeledStatement(null)); |
| 264 node.expression.accept(this), | |
| 265 buildStatementInBlock(node.body), | |
| 266 isAsync: isAsync); | |
| 267 } | 264 } |
| 268 | 265 |
| 269 @override | 266 ir.LabeledStatement getContinueTarget(JumpTarget target) { |
| 270 ir.ForInStatement visitAsyncForIn(AsyncForIn node) { | 267 return continueTargets.putIfAbsent( |
| 271 return buildForIn(node, isAsync: true); | 268 target, () => new ir.LabeledStatement(null)); |
| 272 } | 269 } |
| 273 | 270 |
| 274 @override | 271 ir.SwitchCase getContinueSwitchTarget(JumpTarget target) { |
| 275 ir.Throw visitAwait(Await node) { | 272 return continueSwitchTargets[target]; |
| 276 return buildUnsupported(node, "Await"); | |
| 277 } | 273 } |
| 278 | 274 |
| 279 ir.Statement buildBreakTarget( | 275 ir.Statement buildBreakTarget( |
| 280 ir.Statement statement, | 276 ir.Statement statement, |
| 281 Node node, | 277 Node node, |
| 282 JumpTarget jumpTarget) { | 278 JumpTarget jumpTarget) { |
| 283 assert(jumpTarget == elements.getTargetDefinition(node)); | 279 assert(jumpTarget == elements.getTargetDefinition(node)); |
| 284 if (jumpTarget != null && jumpTarget.isBreakTarget) { | 280 if (jumpTarget != null && jumpTarget.isBreakTarget) { |
| 285 ir.LabeledStatement breakTarget = getBreakTarget(jumpTarget); | 281 ir.LabeledStatement breakTarget = getBreakTarget(jumpTarget); |
| 286 breakTarget.body = statement; | 282 breakTarget.body = statement; |
| 287 statement.parent = breakTarget; | 283 statement.parent = breakTarget; |
| 288 return breakTarget; | 284 return breakTarget; |
| 289 } else { | 285 } else { |
| 290 return statement; | 286 return statement; |
| 291 } | 287 } |
| 292 } | 288 } |
| 293 | 289 |
| 290 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.
| |
| 291 ir.Statement statement, | |
| 292 Node node, | |
| 293 JumpTarget jumpTarget) { | |
| 294 assert(jumpTarget == elements.getTargetDefinition(node)); | |
| 295 if (jumpTarget != null && jumpTarget.isContinueTarget) { | |
| 296 ir.LabeledStatement continueTarget = getContinueTarget(jumpTarget); | |
| 297 continueTarget.body = statement; | |
| 298 statement.parent = continueTarget; | |
| 299 return continueTarget; | |
| 300 } else { | |
| 301 return statement; | |
| 302 } | |
| 303 } | |
| 304 | |
| 305 ir.Statement buildForIn(ForIn node, {bool isAsync}) { | |
| 306 ir.VariableDeclaration variable = | |
| 307 buildStatementInBlock(node.declaredIdentifier); | |
| 308 ir.Expression iterable = node.expression.accept(this); | |
| 309 JumpTarget jumpTarget = elements.getTargetDefinition(node); | |
| 310 ir.Statement body = buildContinueTarget( | |
| 311 buildStatementInBlock(node.body), node, jumpTarget); | |
| 312 return buildBreakTarget( | |
| 313 new ir.ForInStatement(variable, iterable, body, isAsync: isAsync), | |
| 314 node, jumpTarget); | |
| 315 } | |
| 316 | |
| 317 @override | |
| 318 ir.Statement visitAsyncForIn(AsyncForIn node) { | |
| 319 return buildForIn(node, isAsync: true); | |
| 320 } | |
| 321 | |
| 322 @override | |
| 323 ir.Throw visitAwait(Await node) { | |
| 324 return buildUnsupported(node, "Await"); | |
| 325 } | |
| 326 | |
| 294 @override | 327 @override |
| 295 ir.Statement visitBlock(Block node) { | 328 ir.Statement visitBlock(Block node) { |
| 296 return buildBreakTarget( | 329 return buildBreakTarget( |
| 297 buildStatementInBlock(node), node, elements.getTargetDefinition(node)); | 330 buildStatementInBlock(node), node, elements.getTargetDefinition(node)); |
| 298 } | 331 } |
| 299 | 332 |
| 300 void buildStatement(Statement statement, List<ir.Statement> statements) { | 333 void buildStatement(Statement statement, List<ir.Statement> statements) { |
| 301 ir.Node irNode = statement.accept(this); | 334 ir.Node irNode = statement.accept(this); |
| 302 if (irNode is VariableDeclarations) { | 335 if (irNode is VariableDeclarations) { |
| 303 statements.addAll(irNode.variables); | 336 statements.addAll(irNode.variables); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 424 | 457 |
| 425 @override | 458 @override |
| 426 ir.ConditionalExpression visitConditional(Conditional node) { | 459 ir.ConditionalExpression visitConditional(Conditional node) { |
| 427 return new ir.ConditionalExpression( | 460 return new ir.ConditionalExpression( |
| 428 node.condition.accept(this), | 461 node.condition.accept(this), |
| 429 node.thenExpression.accept(this), | 462 node.thenExpression.accept(this), |
| 430 node.elseExpression.accept(this)); | 463 node.elseExpression.accept(this)); |
| 431 } | 464 } |
| 432 | 465 |
| 433 @override | 466 @override |
| 434 ir.BreakStatement visitContinueStatement(ContinueStatement node) { | 467 ir.Statement visitContinueStatement(ContinueStatement node) { |
| 435 JumpTarget target = elements.getTargetOf(node); | 468 JumpTarget target = elements.getTargetOf(node); |
| 436 ir.SwitchCase switchCase = getContinueSwitchTarget(target); | 469 ir.SwitchCase switchCase = getContinueSwitchTarget(target); |
| 437 if (switchCase == null) { | 470 if (switchCase == null) { |
| 438 return new ir.BreakStatement(getContinueTarget(target)); | 471 return new ir.BreakStatement(getContinueTarget(target)); |
| 439 } else { | 472 } else { |
| 440 return new ir.ContinueSwitchStatement(switchCase); | 473 return new ir.ContinueSwitchStatement(switchCase); |
| 441 } | 474 } |
| 442 } | 475 } |
| 443 | 476 |
| 444 @override | 477 @override |
| 445 ir.Statement visitDoWhile(DoWhile node) { | 478 ir.Statement visitDoWhile(DoWhile node) { |
| 446 ir.Statement body = buildStatementInBlock(node.body); | 479 JumpTarget jumpTarget = elements.getTargetDefinition(node); |
| 480 ir.Statement body = buildContinueTarget( | |
| 481 buildStatementInBlock(node.body), node, jumpTarget); | |
| 447 ir.Expression condition = node.condition?.accept(this); | 482 ir.Expression condition = node.condition?.accept(this); |
| 448 | |
| 449 // TODO(ahe): Unify jump target handling between For, While, and Do. | |
| 450 JumpTarget jumpTarget = elements.getTargetDefinition(node); | |
| 451 | |
| 452 if (jumpTarget != null && jumpTarget.isContinueTarget) { | |
| 453 ir.LabeledStatement continueTarget = getContinueTarget(jumpTarget); | |
| 454 continueTarget.body = body; | |
| 455 body.parent = continueTarget; | |
| 456 body = continueTarget; | |
| 457 } | |
| 458 | |
| 459 return buildBreakTarget( | 483 return buildBreakTarget( |
| 460 new ir.DoStatement(body, condition), node, jumpTarget); | 484 new ir.DoStatement(body, condition), node, jumpTarget); |
| 461 } | 485 } |
| 462 | 486 |
| 463 @override | 487 @override |
| 464 ir.EmptyStatement visitEmptyStatement(EmptyStatement node) { | 488 ir.EmptyStatement visitEmptyStatement(EmptyStatement node) { |
| 465 return new ir.EmptyStatement(); | 489 return new ir.EmptyStatement(); |
| 466 } | 490 } |
| 467 | 491 |
| 468 @override | 492 @override |
| 469 ir.Throw visitEnum(Enum node) { | 493 ir.Throw visitEnum(Enum node) { |
| 470 return buildUnsupported(node, "Enum"); | 494 return buildUnsupported(node, "Enum"); |
| 471 } | 495 } |
| 472 | 496 |
| 473 @override | 497 @override |
| 474 ir.ExpressionStatement visitExpressionStatement(ExpressionStatement node) { | 498 ir.ExpressionStatement visitExpressionStatement(ExpressionStatement node) { |
| 475 return new ir.ExpressionStatement(node.expression.accept(this)); | 499 return new ir.ExpressionStatement(node.expression.accept(this)); |
| 476 } | 500 } |
| 477 | 501 |
| 478 ir.LabeledStatement getBreakTarget(JumpTarget target) { | |
| 479 return breakTargets.putIfAbsent( | |
| 480 target, () => new ir.LabeledStatement(null)); | |
| 481 } | |
| 482 | |
| 483 ir.LabeledStatement getContinueTarget(JumpTarget target) { | |
| 484 return continueTargets.putIfAbsent( | |
| 485 target, () => new ir.LabeledStatement(null)); | |
| 486 } | |
| 487 | |
| 488 ir.SwitchCase getContinueSwitchTarget(JumpTarget target) { | |
| 489 return continueSwitchTargets[target]; | |
| 490 } | |
| 491 | |
| 492 @override | 502 @override |
| 493 ir.Statement visitFor(For node) { | 503 ir.Statement visitFor(For node) { |
| 494 VariableDefinitions initializers = | 504 VariableDefinitions initializers = |
| 495 node.initializer?.asVariableDefinitions(); | 505 node.initializer?.asVariableDefinitions(); |
| 496 ir.Expression initializer; | 506 ir.Expression initializer; |
| 497 List<ir.VariableDeclaration> variables; | 507 List<ir.VariableDeclaration> variables; |
| 498 if (initializers != null) { | 508 if (initializers != null) { |
| 499 ir.Block block = buildStatementInBlock(initializers, forceBlock: true); | 509 ir.Block block = buildStatementInBlock(initializers, forceBlock: true); |
| 500 variables = new List<ir.VariableDeclaration>.from(block.statements); | 510 variables = new List<ir.VariableDeclaration>.from(block.statements); |
| 501 } else { | 511 } else { |
| 502 if (node.initializer != null) { | 512 if (node.initializer != null) { |
| 503 initializer = node.initializer.accept(this); | 513 initializer = node.initializer.accept(this); |
| 504 } | 514 } |
| 505 variables = const <ir.VariableDeclaration>[]; | 515 variables = const <ir.VariableDeclaration>[]; |
| 506 } | 516 } |
| 507 ir.Expression condition = node.condition?.accept(this); | 517 ir.Expression condition = node.condition?.accept(this); |
| 508 List<ir.Expression> updates = <ir.Expression>[]; | 518 List<ir.Expression> updates = <ir.Expression>[]; |
| 509 for (Expression update in node.update) { | 519 for (Expression update in node.update) { |
| 510 updates.add(update.accept(this)); | 520 updates.add(update.accept(this)); |
| 511 } | 521 } |
| 512 ir.Statement body = buildStatementInBlock(node.body); | 522 |
| 513 JumpTarget jumpTarget = elements.getTargetDefinition(node); | 523 JumpTarget jumpTarget = elements.getTargetDefinition(node); |
| 514 | 524 ir.Statement body = buildContinueTarget( |
| 515 if (jumpTarget != null && jumpTarget.isContinueTarget) { | 525 buildStatementInBlock(node.body), node, jumpTarget); |
| 516 ir.LabeledStatement continueTarget = getContinueTarget(jumpTarget); | |
| 517 continueTarget.body = body; | |
| 518 body.parent = continueTarget; | |
| 519 body = continueTarget; | |
| 520 } | |
| 521 ir.ForStatement forStatement = new ir.ForStatement( | 526 ir.ForStatement forStatement = new ir.ForStatement( |
| 522 variables, condition, updates, body); | 527 variables, condition, updates, body); |
| 523 ir.Statement result = buildBreakTarget(forStatement, node, jumpTarget); | 528 ir.Statement result = buildBreakTarget(forStatement, node, jumpTarget); |
| 524 if (initializer != null) { | 529 if (initializer != null) { |
| 525 result = new ir.Block(<ir.Statement>[ | 530 result = new ir.Block(<ir.Statement>[ |
| 526 new ir.ExpressionStatement(initializer), result]); | 531 new ir.ExpressionStatement(initializer), result]); |
| 527 } | 532 } |
| 528 return result; | 533 return result; |
| 529 } | 534 } |
| 530 | 535 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 741 irCase.body = body; | 746 irCase.body = body; |
| 742 body.parent = irCase; | 747 body.parent = irCase; |
| 743 } | 748 } |
| 744 | 749 |
| 745 return buildBreakTarget( | 750 return buildBreakTarget( |
| 746 new ir.SwitchStatement(expression, cases), | 751 new ir.SwitchStatement(expression, cases), |
| 747 node, elements.getTargetDefinition(node)); | 752 node, elements.getTargetDefinition(node)); |
| 748 } | 753 } |
| 749 | 754 |
| 750 @override | 755 @override |
| 751 ir.ForInStatement visitSyncForIn(SyncForIn node) { | 756 ir.Statement visitSyncForIn(SyncForIn node) { |
| 752 return buildForIn(node, isAsync: false); | 757 return buildForIn(node, isAsync: false); |
| 753 } | 758 } |
| 754 | 759 |
| 755 @override | 760 @override |
| 756 ir.Throw visitThrow(Throw node) { | 761 ir.Throw visitThrow(Throw node) { |
| 757 return new ir.Throw(node?.expression?.accept(this)); | 762 return new ir.Throw(node?.expression?.accept(this)); |
| 758 } | 763 } |
| 759 | 764 |
| 760 @override | 765 @override |
| 761 ir.Statement visitTryStatement(TryStatement node) { | 766 ir.Statement visitTryStatement(TryStatement node) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 780 } | 785 } |
| 781 | 786 |
| 782 @override | 787 @override |
| 783 ir.Throw visitTypeVariable(TypeVariable node) { | 788 ir.Throw visitTypeVariable(TypeVariable node) { |
| 784 return buildUnsupported(node, "TypeVariable"); | 789 return buildUnsupported(node, "TypeVariable"); |
| 785 } | 790 } |
| 786 | 791 |
| 787 @override | 792 @override |
| 788 ir.Statement visitWhile(While node) { | 793 ir.Statement visitWhile(While node) { |
| 789 ir.Expression condition = node.condition?.accept(this); | 794 ir.Expression condition = node.condition?.accept(this); |
| 790 | |
| 791 ir.Statement body = buildStatementInBlock(node.body); | |
| 792 JumpTarget jumpTarget = elements.getTargetDefinition(node); | 795 JumpTarget jumpTarget = elements.getTargetDefinition(node); |
| 793 | 796 ir.Statement body = buildContinueTarget( |
| 794 if (jumpTarget != null && jumpTarget.isContinueTarget) { | 797 buildStatementInBlock(node.body), node, jumpTarget); |
| 795 ir.LabeledStatement continueTarget = getContinueTarget(jumpTarget); | |
| 796 continueTarget.body = body; | |
| 797 body.parent = continueTarget; | |
| 798 body = continueTarget; | |
| 799 } | |
| 800 | |
| 801 return buildBreakTarget( | 798 return buildBreakTarget( |
| 802 new ir.WhileStatement(condition, body), node, jumpTarget); | 799 new ir.WhileStatement(condition, body), node, jumpTarget); |
| 803 } | 800 } |
| 804 | 801 |
| 805 @override | 802 @override |
| 806 ir.YieldStatement visitYield(Yield node) { | 803 ir.YieldStatement visitYield(Yield node) { |
| 807 return new ir.YieldStatement( | 804 return new ir.YieldStatement( |
| 808 node.expression.accept(this), isYieldStar: node.hasStar); | 805 node.expression.accept(this), isYieldStar: node.hasStar); |
| 809 } | 806 } |
| 810 | 807 |
| (...skipping 1757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2568 GenerativeConstructorFunction(this.function, this.initializers); | 2565 GenerativeConstructorFunction(this.function, this.initializers); |
| 2569 | 2566 |
| 2570 accept(ir.Visitor v) => throw "unsupported"; | 2567 accept(ir.Visitor v) => throw "unsupported"; |
| 2571 | 2568 |
| 2572 visitChildren(ir.Visitor v) => throw "unsupported"; | 2569 visitChildren(ir.Visitor v) => throw "unsupported"; |
| 2573 | 2570 |
| 2574 String toString() { | 2571 String toString() { |
| 2575 return "GenerativeConstructorFunction($function, $initializers)"; | 2572 return "GenerativeConstructorFunction($function, $initializers)"; |
| 2576 } | 2573 } |
| 2577 } | 2574 } |
| OLD | NEW |