| 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 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 import 'package:kernel/frontend/accessors.dart' | 6 import 'package:kernel/frontend/accessors.dart' |
| 7 show | 7 show |
| 8 Accessor, | 8 Accessor, |
| 9 IndexAccessor, | 9 IndexAccessor, |
| 10 NullAwarePropertyAccessor, | 10 NullAwarePropertyAccessor, |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 380 throw new UnsupportedError("applyInitializers"); | 380 throw new UnsupportedError("applyInitializers"); |
| 381 } | 381 } |
| 382 | 382 |
| 383 @override | 383 @override |
| 384 ir.AssertStatement visitAssert(Assert node) { | 384 ir.AssertStatement visitAssert(Assert node) { |
| 385 return new ir.AssertStatement( | 385 return new ir.AssertStatement( |
| 386 visitForValue(node.condition), visitForValue(node.message)); | 386 visitForValue(node.condition), visitForValue(node.message)); |
| 387 } | 387 } |
| 388 | 388 |
| 389 ir.LabeledStatement getBreakTarget(JumpTarget target) { | 389 ir.LabeledStatement getBreakTarget(JumpTarget target) { |
| 390 return breakTargets.putIfAbsent( | 390 return breakTargets.putIfAbsent(target, |
| 391 target, () => new ir.LabeledStatement(null)); | 391 () => associateNode(new ir.LabeledStatement(null), target.statement)); |
| 392 } | 392 } |
| 393 | 393 |
| 394 ir.LabeledStatement getContinueTarget(JumpTarget target) { | 394 ir.LabeledStatement getContinueTarget(JumpTarget target) { |
| 395 return continueTargets.putIfAbsent( | 395 return continueTargets.putIfAbsent(target, |
| 396 target, () => new ir.LabeledStatement(null)); | 396 () => associateNode(new ir.LabeledStatement(null), target.statement)); |
| 397 } | 397 } |
| 398 | 398 |
| 399 ir.SwitchCase getContinueSwitchTarget(JumpTarget target) { | 399 ir.SwitchCase getContinueSwitchTarget(JumpTarget target) { |
| 400 return continueSwitchTargets[target]; | 400 return continueSwitchTargets[target]; |
| 401 } | 401 } |
| 402 | 402 |
| 403 /// The optional positional parameter isBreakTarget can be added in cases | 403 /// The optional positional parameter isBreakTarget can be added in cases |
| 404 /// where a break statement was added but the element model and underlying | 404 /// where a break statement was added but the element model and underlying |
| 405 /// JumpTargets don't know about it. | 405 /// JumpTargets don't know about it. |
| 406 ir.Statement buildBreakTarget( | 406 ir.Statement buildBreakTarget( |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 buildStatement(statement, statements); | 584 buildStatement(statement, statements); |
| 585 } | 585 } |
| 586 } else { | 586 } else { |
| 587 if (buildStatement(node, statements)) forceBlock = true; | 587 if (buildStatement(node, statements)) forceBlock = true; |
| 588 if (!forceBlock && statements.length == 1) { | 588 if (!forceBlock && statements.length == 1) { |
| 589 return statements.single; | 589 return statements.single; |
| 590 } | 590 } |
| 591 // One VariableDefinitions statement node (dart2js AST) may generate | 591 // One VariableDefinitions statement node (dart2js AST) may generate |
| 592 // multiple statements in Kernel IR so we sometimes fall through here. | 592 // multiple statements in Kernel IR so we sometimes fall through here. |
| 593 } | 593 } |
| 594 return new ir.Block(statements); | 594 return associateNode(new ir.Block(statements), node); |
| 595 } | 595 } |
| 596 | 596 |
| 597 @override | 597 @override |
| 598 ir.Statement visitBreakStatement(BreakStatement node) { | 598 ir.Statement visitBreakStatement(BreakStatement node) { |
| 599 JumpTarget target = elements.getTargetOf(node); | 599 JumpTarget target = elements.getTargetOf(node); |
| 600 if (target == null || !target.statement.isValidBreakTarget()) { | 600 if (target == null || !target.statement.isValidBreakTarget()) { |
| 601 // This is a break in an invalid position. | 601 // This is a break in an invalid position. |
| 602 return new ir.InvalidStatement(); | 602 return new ir.InvalidStatement(); |
| 603 } | 603 } |
| 604 // A break can break to itself in the degenerate case `label: break | 604 // A break can break to itself in the degenerate case `label: break |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 updates.add(visitForEffect(update)); | 782 updates.add(visitForEffect(update)); |
| 783 } | 783 } |
| 784 | 784 |
| 785 JumpTarget jumpTarget = elements.getTargetDefinition(node); | 785 JumpTarget jumpTarget = elements.getTargetDefinition(node); |
| 786 ir.Statement body = | 786 ir.Statement body = |
| 787 buildContinueTarget(buildStatementInBlock(node.body), node, jumpTarget); | 787 buildContinueTarget(buildStatementInBlock(node.body), node, jumpTarget); |
| 788 ir.ForStatement forStatement = associateNode( | 788 ir.ForStatement forStatement = associateNode( |
| 789 new ir.ForStatement(variables, condition, updates, body), node); | 789 new ir.ForStatement(variables, condition, updates, body), node); |
| 790 ir.Statement result = buildBreakTarget(forStatement, node, jumpTarget); | 790 ir.Statement result = buildBreakTarget(forStatement, node, jumpTarget); |
| 791 if (initializer != null) { | 791 if (initializer != null) { |
| 792 result = new ir.Block( | 792 result = associateNode( |
| 793 <ir.Statement>[new ir.ExpressionStatement(initializer), result]); | 793 new ir.Block( |
| 794 <ir.Statement>[new ir.ExpressionStatement(initializer), result]), |
| 795 node.initializer); |
| 794 } | 796 } |
| 795 return result; | 797 return result; |
| 796 } | 798 } |
| 797 | 799 |
| 798 @override | 800 @override |
| 799 ir.FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) { | 801 ir.FunctionDeclaration visitFunctionDeclaration(FunctionDeclaration node) { |
| 800 return node.function.accept(this); | 802 return node.function.accept(this); |
| 801 } | 803 } |
| 802 | 804 |
| 803 @override | 805 @override |
| (...skipping 15 matching lines...) Expand all Loading... |
| 819 } | 821 } |
| 820 | 822 |
| 821 @override | 823 @override |
| 822 ir.Statement visitLabeledStatement(LabeledStatement node) { | 824 ir.Statement visitLabeledStatement(LabeledStatement node) { |
| 823 Statement statement = node.statement; | 825 Statement statement = node.statement; |
| 824 ir.Statement result = (statement is Block) | 826 ir.Statement result = (statement is Block) |
| 825 // If [statement] is a Block, we need to ensure that we don't bypass | 827 // If [statement] is a Block, we need to ensure that we don't bypass |
| 826 // its visit method (so it can build break targets correctly). | 828 // its visit method (so it can build break targets correctly). |
| 827 ? statement.accept(this) | 829 ? statement.accept(this) |
| 828 : buildStatementInBlock(statement); | 830 : buildStatementInBlock(statement); |
| 831 associateNode(result, statement); |
| 829 | 832 |
| 830 // A [LabeledStatement] isn't the actual jump target, instead, [statement] | 833 // A [LabeledStatement] isn't the actual jump target, instead, [statement] |
| 831 // is the target. This allows uniform handling of break and continue in | 834 // is the target. This allows uniform handling of break and continue in |
| 832 // loops. The following code simply assert that [result] has been generated | 835 // loops. The following code simply assert that [result] has been generated |
| 833 // correctly with respect to jump targets. | 836 // correctly with respect to jump targets. |
| 834 JumpTarget jumpTarget = elements.getTargetDefinition(node.statement); | 837 JumpTarget jumpTarget = elements.getTargetDefinition(node.statement); |
| 835 if (jumpTarget != null) { | 838 if (jumpTarget != null) { |
| 836 if (jumpTarget.isBreakTarget) { | 839 if (jumpTarget.isBreakTarget) { |
| 837 ir.LabeledStatement target = breakTargets[jumpTarget]; | 840 ir.LabeledStatement target = breakTargets[jumpTarget]; |
| 838 if (target != null && target != result && target.parent == null) { | 841 if (target != null && target != result && target.parent == null) { |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 expressions.add(visitForValue(match.expression)); | 995 expressions.add(visitForValue(match.expression)); |
| 993 } else { | 996 } else { |
| 994 // Assert that labelOrCase is one of two known types: [CaseMatch] or | 997 // Assert that labelOrCase is one of two known types: [CaseMatch] or |
| 995 // [Label]. We ignore cases, as any users have been resolved to use the | 998 // [Label]. We ignore cases, as any users have been resolved to use the |
| 996 // case directly. | 999 // case directly. |
| 997 assert(labelOrCase.asLabel() != null); | 1000 assert(labelOrCase.asLabel() != null); |
| 998 } | 1001 } |
| 999 } | 1002 } |
| 1000 // We ignore the node's statements here, they're generated below in | 1003 // We ignore the node's statements here, they're generated below in |
| 1001 // [visitSwitchStatement] once we've set up all the jump targets. | 1004 // [visitSwitchStatement] once we've set up all the jump targets. |
| 1002 return new ir.SwitchCase(expressions, null, isDefault: node.isDefaultCase); | 1005 return associateNode( |
| 1006 new ir.SwitchCase(expressions, null, isDefault: node.isDefaultCase), |
| 1007 node); |
| 1003 } | 1008 } |
| 1004 | 1009 |
| 1005 /// Returns true if [node] would let execution reach the next node (aka | 1010 /// Returns true if [node] would let execution reach the next node (aka |
| 1006 /// fall-through in switch cases). | 1011 /// fall-through in switch cases). |
| 1007 bool fallsThrough(ir.Statement node) { | 1012 bool fallsThrough(ir.Statement node) { |
| 1008 return !(node is ir.BreakStatement || | 1013 return !(node is ir.BreakStatement || |
| 1009 node is ir.ReturnStatement || | 1014 node is ir.ReturnStatement || |
| 1010 node is ir.ContinueSwitchStatement || | 1015 node is ir.ContinueSwitchStatement || |
| 1011 (node is ir.ExpressionStatement && node.expression is ir.Throw)); | 1016 (node is ir.ExpressionStatement && node.expression is ir.Throw)); |
| 1012 } | 1017 } |
| (...skipping 1849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2862 : this(null, true, node, initializers); | 2867 : this(null, true, node, initializers); |
| 2863 | 2868 |
| 2864 accept(ir.Visitor v) => throw "unsupported"; | 2869 accept(ir.Visitor v) => throw "unsupported"; |
| 2865 | 2870 |
| 2866 visitChildren(ir.Visitor v) => throw "unsupported"; | 2871 visitChildren(ir.Visitor v) => throw "unsupported"; |
| 2867 | 2872 |
| 2868 String toString() { | 2873 String toString() { |
| 2869 return "IrFunction($kind, $isConstructor, $node, $initializers)"; | 2874 return "IrFunction($kind, $isConstructor, $node, $initializers)"; |
| 2870 } | 2875 } |
| 2871 } | 2876 } |
| OLD | NEW |