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 |