| OLD | NEW | 
|---|
| 1 // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 file. | 3 // BSD-style license that can be found in the LICENSE file. | 
| 4 | 4 | 
| 5 library tree_ir_nodes; | 5 library tree_ir_nodes; | 
| 6 | 6 | 
| 7 import '../constants/values.dart' as values; | 7 import '../constants/values.dart' as values; | 
| 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 
| 9 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; | 
| 10 import '../io/source_information.dart' show SourceInformation; | 10 import '../io/source_information.dart' show SourceInformation; | 
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 439   final FunctionDefinition definition; | 439   final FunctionDefinition definition; | 
| 440 | 440 | 
| 441   FunctionExpression(this.definition); | 441   FunctionExpression(this.definition); | 
| 442 | 442 | 
| 443   accept(ExpressionVisitor visitor) => visitor.visitFunctionExpression(this); | 443   accept(ExpressionVisitor visitor) => visitor.visitFunctionExpression(this); | 
| 444   accept1(ExpressionVisitor1 visitor, arg) { | 444   accept1(ExpressionVisitor1 visitor, arg) { | 
| 445     return visitor.visitFunctionExpression(this, arg); | 445     return visitor.visitFunctionExpression(this, arg); | 
| 446   } | 446   } | 
| 447 } | 447 } | 
| 448 | 448 | 
| 449 /// A [LabeledStatement] or [WhileTrue] or [WhileCondition]. | 449 /// A [LabeledStatement] or [WhileTrue] or [For]. | 
| 450 abstract class JumpTarget extends Statement { | 450 abstract class JumpTarget extends Statement { | 
| 451   Label get label; | 451   Label get label; | 
| 452   Statement get body; | 452   Statement get body; | 
| 453 } | 453 } | 
| 454 | 454 | 
| 455 /** | 455 /** | 
| 456  * A labeled statement.  Breaks to the label within the labeled statement | 456  * A labeled statement.  Breaks to the label within the labeled statement | 
| 457  * target the successor statement. | 457  * target the successor statement. | 
| 458  */ | 458  */ | 
| 459 class LabeledStatement extends JumpTarget { | 459 class LabeledStatement extends JumpTarget { | 
| 460   Statement next; | 460   Statement next; | 
| 461   final Label label; | 461   final Label label; | 
| 462   Statement body; | 462   Statement body; | 
| 463 | 463 | 
| 464   LabeledStatement(this.label, this.body, this.next) { | 464   LabeledStatement(this.label, this.body, this.next) { | 
| 465     assert(label.binding == null); | 465     assert(label.binding == null); | 
| 466     label.binding = this; | 466     label.binding = this; | 
| 467   } | 467   } | 
| 468 | 468 | 
| 469   accept(StatementVisitor visitor) => visitor.visitLabeledStatement(this); | 469   accept(StatementVisitor visitor) => visitor.visitLabeledStatement(this); | 
| 470   accept1(StatementVisitor1 visitor, arg) { | 470   accept1(StatementVisitor1 visitor, arg) { | 
| 471     return visitor.visitLabeledStatement(this, arg); | 471     return visitor.visitLabeledStatement(this, arg); | 
| 472   } | 472   } | 
| 473 } | 473 } | 
| 474 | 474 | 
| 475 /// A [WhileTrue] or [WhileCondition] loop. | 475 /// A [WhileTrue] or [For] loop. | 
| 476 abstract class Loop extends JumpTarget { | 476 abstract class Loop extends JumpTarget { | 
| 477 } | 477 } | 
| 478 | 478 | 
| 479 /** | 479 /** | 
| 480  * A labeled while(true) loop. | 480  * A labeled while(true) loop. | 
| 481  */ | 481  */ | 
| 482 class WhileTrue extends Loop { | 482 class WhileTrue extends Loop { | 
| 483   final Label label; | 483   final Label label; | 
| 484   Statement body; | 484   Statement body; | 
| 485 | 485 | 
| 486   WhileTrue(this.label, this.body) { | 486   WhileTrue(this.label, this.body) { | 
| 487     assert(label.binding == null); | 487     assert(label.binding == null); | 
| 488     label.binding = this; | 488     label.binding = this; | 
| 489   } | 489   } | 
| 490 | 490 | 
| 491   Statement get next => null; | 491   Statement get next => null; | 
| 492   void set next(Statement s) => throw 'UNREACHABLE'; | 492   void set next(Statement s) => throw 'UNREACHABLE'; | 
| 493 | 493 | 
| 494   accept(StatementVisitor visitor) => visitor.visitWhileTrue(this); | 494   accept(StatementVisitor visitor) => visitor.visitWhileTrue(this); | 
| 495   accept1(StatementVisitor1 visitor, arg) => visitor.visitWhileTrue(this, arg); | 495   accept1(StatementVisitor1 visitor, arg) => visitor.visitWhileTrue(this, arg); | 
| 496 } | 496 } | 
| 497 | 497 | 
| 498 /** | 498 /** | 
| 499  * A while loop with a condition. If the condition is false, control resumes | 499  * A loop with a condition and update expressions. If there are any update | 
| 500  * at the [next] statement. | 500  * expressions, this generates a for loop, otherwise a while loop. | 
|  | 501  * | 
|  | 502  * When the condition is false, control resumes at the [next] statement. | 
| 501  * | 503  * | 
| 502  * It is NOT valid to target this statement with a [Break]. | 504  * It is NOT valid to target this statement with a [Break]. | 
| 503  * The only way to reach [next] is for the condition to evaluate to false. | 505  * The only way to reach [next] is for the condition to evaluate to false. | 
| 504  * | 506  * | 
| 505  * [WhileCondition] statements are introduced in the [LoopRewriter] and is | 507  * [For] statements are introduced in the [LoopRewriter] and are | 
| 506  * assumed not to occur before then. | 508  * assumed not to occur before then. | 
| 507  */ | 509  */ | 
| 508 class WhileCondition extends Loop { | 510 class For extends Loop { | 
| 509   final Label label; | 511   final Label label; | 
| 510   Expression condition; | 512   Expression condition; | 
|  | 513   List<Expression> updates; | 
| 511   Statement body; | 514   Statement body; | 
| 512   Statement next; | 515   Statement next; | 
| 513 | 516 | 
| 514   WhileCondition(this.label, this.condition, this.body, | 517   For(this.label, | 
| 515                  this.next) { | 518       this.condition, | 
|  | 519       this.updates, | 
|  | 520       this.body, | 
|  | 521       this.next) { | 
| 516     assert(label.binding == null); | 522     assert(label.binding == null); | 
| 517     label.binding = this; | 523     label.binding = this; | 
| 518   } | 524   } | 
| 519 | 525 | 
| 520   accept(StatementVisitor visitor) => visitor.visitWhileCondition(this); | 526   accept(StatementVisitor visitor) => visitor.visitFor(this); | 
| 521   accept1(StatementVisitor1 visitor, arg) { | 527   accept1(StatementVisitor1 visitor, arg) { | 
| 522     return visitor.visitWhileCondition(this, arg); | 528     return visitor.visitFor(this, arg); | 
| 523   } | 529   } | 
| 524 } | 530 } | 
| 525 | 531 | 
| 526 /// A [Break] or [Continue] statement. | 532 /// A [Break] or [Continue] statement. | 
| 527 abstract class Jump extends Statement { | 533 abstract class Jump extends Statement { | 
| 528   Label get target; | 534   Label get target; | 
| 529 } | 535 } | 
| 530 | 536 | 
| 531 /** | 537 /** | 
| 532  * A break from an enclosing [LabeledStatement].  The break targets the | 538  * A break from an enclosing [LabeledStatement].  The break targets the | 
| 533  * labeled statement's successor statement. | 539  * labeled statement's successor statement. | 
| 534  */ | 540  */ | 
| 535 class Break extends Jump { | 541 class Break extends Jump { | 
| 536   final Label target; | 542   final Label target; | 
| 537 | 543 | 
| 538   Statement get next => null; | 544   Statement get next => null; | 
| 539   void set next(Statement s) => throw 'UNREACHABLE'; | 545   void set next(Statement s) => throw 'UNREACHABLE'; | 
| 540 | 546 | 
| 541   Break(this.target) { | 547   Break(this.target) { | 
| 542     ++target.useCount; | 548     ++target.useCount; | 
| 543   } | 549   } | 
| 544 | 550 | 
| 545   accept(StatementVisitor visitor) => visitor.visitBreak(this); | 551   accept(StatementVisitor visitor) => visitor.visitBreak(this); | 
| 546   accept1(StatementVisitor1 visitor, arg) => visitor.visitBreak(this, arg); | 552   accept1(StatementVisitor1 visitor, arg) => visitor.visitBreak(this, arg); | 
| 547 } | 553 } | 
| 548 | 554 | 
| 549 /** | 555 /** | 
| 550  * A continue to an enclosing [WhileTrue] or [WhileCondition] loop. | 556  * A continue to an enclosing [WhileTrue] or [For] loop. | 
| 551  * The continue targets the loop's body. | 557  * The continue targets the loop's body. | 
| 552  */ | 558  */ | 
| 553 class Continue extends Jump { | 559 class Continue extends Jump { | 
| 554   final Label target; | 560   final Label target; | 
| 555 | 561 | 
| 556   Statement get next => null; | 562   Statement get next => null; | 
| 557   void set next(Statement s) => throw 'UNREACHABLE'; | 563   void set next(Statement s) => throw 'UNREACHABLE'; | 
| 558 | 564 | 
| 559   Continue(this.target) { | 565   Continue(this.target) { | 
| 560     ++target.useCount; | 566     ++target.useCount; | 
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1006 abstract class StatementVisitor<S> { | 1012 abstract class StatementVisitor<S> { | 
| 1007   S visitStatement(Statement node) => node.accept(this); | 1013   S visitStatement(Statement node) => node.accept(this); | 
| 1008   S visitLabeledStatement(LabeledStatement node); | 1014   S visitLabeledStatement(LabeledStatement node); | 
| 1009   S visitReturn(Return node); | 1015   S visitReturn(Return node); | 
| 1010   S visitThrow(Throw node); | 1016   S visitThrow(Throw node); | 
| 1011   S visitRethrow(Rethrow node); | 1017   S visitRethrow(Rethrow node); | 
| 1012   S visitBreak(Break node); | 1018   S visitBreak(Break node); | 
| 1013   S visitContinue(Continue node); | 1019   S visitContinue(Continue node); | 
| 1014   S visitIf(If node); | 1020   S visitIf(If node); | 
| 1015   S visitWhileTrue(WhileTrue node); | 1021   S visitWhileTrue(WhileTrue node); | 
| 1016   S visitWhileCondition(WhileCondition node); | 1022   S visitFor(For node); | 
| 1017   S visitExpressionStatement(ExpressionStatement node); | 1023   S visitExpressionStatement(ExpressionStatement node); | 
| 1018   S visitTry(Try node); | 1024   S visitTry(Try node); | 
| 1019   S visitUnreachable(Unreachable node); | 1025   S visitUnreachable(Unreachable node); | 
| 1020   S visitForeignStatement(ForeignStatement node); | 1026   S visitForeignStatement(ForeignStatement node); | 
| 1021 } | 1027 } | 
| 1022 | 1028 | 
| 1023 abstract class StatementVisitor1<S, A> { | 1029 abstract class StatementVisitor1<S, A> { | 
| 1024   S visitStatement(Statement node, A arg) => node.accept1(this, arg); | 1030   S visitStatement(Statement node, A arg) => node.accept1(this, arg); | 
| 1025   S visitLabeledStatement(LabeledStatement node, A arg); | 1031   S visitLabeledStatement(LabeledStatement node, A arg); | 
| 1026   S visitReturn(Return node, A arg); | 1032   S visitReturn(Return node, A arg); | 
| 1027   S visitThrow(Throw node, A arg); | 1033   S visitThrow(Throw node, A arg); | 
| 1028   S visitRethrow(Rethrow node, A arg); | 1034   S visitRethrow(Rethrow node, A arg); | 
| 1029   S visitBreak(Break node, A arg); | 1035   S visitBreak(Break node, A arg); | 
| 1030   S visitContinue(Continue node, A arg); | 1036   S visitContinue(Continue node, A arg); | 
| 1031   S visitIf(If node, A arg); | 1037   S visitIf(If node, A arg); | 
| 1032   S visitWhileTrue(WhileTrue node, A arg); | 1038   S visitWhileTrue(WhileTrue node, A arg); | 
| 1033   S visitWhileCondition(WhileCondition node, A arg); | 1039   S visitFor(For node, A arg); | 
| 1034   S visitExpressionStatement(ExpressionStatement node, A arg); | 1040   S visitExpressionStatement(ExpressionStatement node, A arg); | 
| 1035   S visitTry(Try node, A arg); | 1041   S visitTry(Try node, A arg); | 
| 1036   S visitUnreachable(Unreachable node, A arg); | 1042   S visitUnreachable(Unreachable node, A arg); | 
| 1037   S visitForeignStatement(ForeignStatement node, A arg); | 1043   S visitForeignStatement(ForeignStatement node, A arg); | 
| 1038 } | 1044 } | 
| 1039 | 1045 | 
| 1040 abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor { | 1046 abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor { | 
| 1041   visitExpression(Expression e) => e.accept(this); | 1047   visitExpression(Expression e) => e.accept(this); | 
| 1042   visitStatement(Statement s) => s.accept(this); | 1048   visitStatement(Statement s) => s.accept(this); | 
| 1043 | 1049 | 
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1133   visitIf(If node) { | 1139   visitIf(If node) { | 
| 1134     visitExpression(node.condition); | 1140     visitExpression(node.condition); | 
| 1135     visitStatement(node.thenStatement); | 1141     visitStatement(node.thenStatement); | 
| 1136     visitStatement(node.elseStatement); | 1142     visitStatement(node.elseStatement); | 
| 1137   } | 1143   } | 
| 1138 | 1144 | 
| 1139   visitWhileTrue(WhileTrue node) { | 1145   visitWhileTrue(WhileTrue node) { | 
| 1140     visitStatement(node.body); | 1146     visitStatement(node.body); | 
| 1141   } | 1147   } | 
| 1142 | 1148 | 
| 1143   visitWhileCondition(WhileCondition node) { | 1149   visitFor(For node) { | 
| 1144     visitExpression(node.condition); | 1150     visitExpression(node.condition); | 
|  | 1151     node.updates.forEach(visitExpression); | 
| 1145     visitStatement(node.body); | 1152     visitStatement(node.body); | 
| 1146     visitStatement(node.next); | 1153     visitStatement(node.next); | 
| 1147   } | 1154   } | 
| 1148 | 1155 | 
| 1149   visitExpressionStatement(ExpressionStatement inputNode) { | 1156   visitExpressionStatement(ExpressionStatement inputNode) { | 
| 1150     // Iterate over chains of expression statements to avoid deep recursion. | 1157     // Iterate over chains of expression statements to avoid deep recursion. | 
| 1151     Statement node = inputNode; | 1158     Statement node = inputNode; | 
| 1152     while (node is ExpressionStatement) { | 1159     while (node is ExpressionStatement) { | 
| 1153       ExpressionStatement stmt = node; | 1160       ExpressionStatement stmt = node; | 
| 1154       visitExpression(stmt.expression); | 1161       visitExpression(stmt.expression); | 
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1364     node.thenStatement = visitStatement(node.thenStatement); | 1371     node.thenStatement = visitStatement(node.thenStatement); | 
| 1365     node.elseStatement = visitStatement(node.elseStatement); | 1372     node.elseStatement = visitStatement(node.elseStatement); | 
| 1366     return node; | 1373     return node; | 
| 1367   } | 1374   } | 
| 1368 | 1375 | 
| 1369   visitWhileTrue(WhileTrue node) { | 1376   visitWhileTrue(WhileTrue node) { | 
| 1370     node.body = visitStatement(node.body); | 1377     node.body = visitStatement(node.body); | 
| 1371     return node; | 1378     return node; | 
| 1372   } | 1379   } | 
| 1373 | 1380 | 
| 1374   visitWhileCondition(WhileCondition node) { | 1381   visitFor(For node) { | 
| 1375     node.condition = visitExpression(node.condition); | 1382     node.condition = visitExpression(node.condition); | 
|  | 1383     _replaceExpressions(node.updates); | 
| 1376     node.body = visitStatement(node.body); | 1384     node.body = visitStatement(node.body); | 
| 1377     node.next = visitStatement(node.next); | 1385     node.next = visitStatement(node.next); | 
| 1378     return node; | 1386     return node; | 
| 1379   } | 1387   } | 
| 1380 | 1388 | 
| 1381   visitExpressionStatement(ExpressionStatement node) { | 1389   visitExpressionStatement(ExpressionStatement node) { | 
| 1382     // Iterate over chains of expression statements to avoid deep recursion. | 1390     // Iterate over chains of expression statements to avoid deep recursion. | 
| 1383     Statement first = node; | 1391     Statement first = node; | 
| 1384     while (true) { | 1392     while (true) { | 
| 1385       node.expression = visitExpression(node.expression); | 1393       node.expression = visitExpression(node.expression); | 
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1526 | 1534 | 
| 1527   /// Number of uses of the current fallthrough target. | 1535   /// Number of uses of the current fallthrough target. | 
| 1528   int get useCount => _stack.last.useCount; | 1536   int get useCount => _stack.last.useCount; | 
| 1529 | 1537 | 
| 1530   /// Indicate that a statement will fall through to the current fallthrough | 1538   /// Indicate that a statement will fall through to the current fallthrough | 
| 1531   /// target. | 1539   /// target. | 
| 1532   void use() { | 1540   void use() { | 
| 1533     ++_stack.last.useCount; | 1541     ++_stack.last.useCount; | 
| 1534   } | 1542   } | 
| 1535 } | 1543 } | 
| OLD | NEW | 
|---|