Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1051)

Side by Side Diff: lib/kernel_visitor.dart

Issue 1980373004: Implement jump targets in for-in. (Closed) Base URL: git@github.com:dart-lang/rasta.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698