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/expressions.dart'; | 7 import '../constants/expressions.dart'; |
8 import '../constants/values.dart' as values; | 8 import '../constants/values.dart' as values; |
9 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; | 9 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
10 import '../elements/elements.dart'; | 10 import '../elements/elements.dart'; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 /// counter must be decremented by hand when a [Break] becomes orphaned. | 71 /// counter must be decremented by hand when a [Break] becomes orphaned. |
72 int useCount = 0; | 72 int useCount = 0; |
73 | 73 |
74 /// The [LabeledStatement] or [WhileTrue] binding this label. | 74 /// The [LabeledStatement] or [WhileTrue] binding this label. |
75 JumpTarget binding; | 75 JumpTarget binding; |
76 } | 76 } |
77 | 77 |
78 /** | 78 /** |
79 * A local variable in the tree IR. | 79 * A local variable in the tree IR. |
80 * | 80 * |
81 * All tree IR variables are mutable, and may in Dart-mode be referenced inside | 81 * All tree IR variables are mutable. |
82 * nested functions. | |
83 * | 82 * |
84 * To use a variable as an expression, reference it from a [VariableUse], with | 83 * To use a variable as an expression, reference it from a [VariableUse], with |
85 * one [VariableUse] per expression. | 84 * one [VariableUse] per expression. |
86 * | 85 * |
87 * [Variable]s are reference counted. The node constructors [VariableUse], | 86 * [Variable]s are reference counted. The node constructors [VariableUse], |
88 * [Assign], [FunctionDefinition], and [Try] automatically update the reference | 87 * [Assign], [FunctionDefinition], and [Try] automatically update the reference |
89 * count for their variables, but when transforming the tree, the transformer | 88 * count for their variables, but when transforming the tree, the transformer |
90 * is responsible for updating reference counts. | 89 * is responsible for updating reference counts. |
91 */ | 90 */ |
92 class Variable extends Node { | 91 class Variable extends Node { |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 final List<LiteralMapEntry> entries; | 316 final List<LiteralMapEntry> entries; |
318 | 317 |
319 LiteralMap(this.type, this.entries); | 318 LiteralMap(this.type, this.entries); |
320 | 319 |
321 accept(ExpressionVisitor visitor) => visitor.visitLiteralMap(this); | 320 accept(ExpressionVisitor visitor) => visitor.visitLiteralMap(this); |
322 accept1(ExpressionVisitor1 visitor, arg) { | 321 accept1(ExpressionVisitor1 visitor, arg) { |
323 return visitor.visitLiteralMap(this, arg); | 322 return visitor.visitLiteralMap(this, arg); |
324 } | 323 } |
325 } | 324 } |
326 | 325 |
| 326 /// Type test or type cast. |
| 327 /// |
| 328 /// Note that if this is a type test, then [type] cannot be `Object`, `dynamic`, |
| 329 /// or the `Null` type. These cases are compiled to other node types. |
327 class TypeOperator extends Expression { | 330 class TypeOperator extends Expression { |
328 Expression value; | 331 Expression value; |
329 final DartType type; | 332 final DartType type; |
330 final List<Expression> typeArguments; | 333 final List<Expression> typeArguments; |
331 final bool isTypeTest; | 334 final bool isTypeTest; |
332 | 335 |
333 TypeOperator(this.value, this.type, this.typeArguments, | 336 TypeOperator(this.value, this.type, this.typeArguments, |
334 {bool this.isTypeTest}); | 337 {bool this.isTypeTest}); |
335 | 338 |
336 accept(ExpressionVisitor visitor) => visitor.visitTypeOperator(this); | 339 accept(ExpressionVisitor visitor) => visitor.visitTypeOperator(this); |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 variable.writeCount++; // Being a catch parameter counts as a write. | 614 variable.writeCount++; // Being a catch parameter counts as a write. |
612 } | 615 } |
613 } | 616 } |
614 | 617 |
615 accept(StatementVisitor visitor) => visitor.visitTry(this); | 618 accept(StatementVisitor visitor) => visitor.visitTry(this); |
616 accept1(StatementVisitor1 visitor, arg) { | 619 accept1(StatementVisitor1 visitor, arg) { |
617 return visitor.visitTry(this, arg); | 620 return visitor.visitTry(this, arg); |
618 } | 621 } |
619 } | 622 } |
620 | 623 |
| 624 /// A statement that is known to be unreachable. |
| 625 class Unreachable extends Statement { |
| 626 Statement get next => null; |
| 627 void set next(Statement value) => throw 'UNREACHABLE'; |
| 628 |
| 629 accept(StatementVisitor visitor) => visitor.visitUnreachable(this); |
| 630 accept1(StatementVisitor1 visitor, arg) { |
| 631 return visitor.visitUnreachable(this, arg); |
| 632 } |
| 633 } |
| 634 |
621 class FunctionDefinition extends Node { | 635 class FunctionDefinition extends Node { |
622 final ExecutableElement element; | 636 final ExecutableElement element; |
623 final List<Variable> parameters; | 637 final List<Variable> parameters; |
624 Statement body; | 638 Statement body; |
625 | 639 |
626 /// Creates a function definition and updates `writeCount` for [parameters]. | 640 /// Creates a function definition and updates `writeCount` for [parameters]. |
627 FunctionDefinition(this.element, this.parameters, this.body) { | 641 FunctionDefinition(this.element, this.parameters, this.body) { |
628 for (Variable param in parameters) { | 642 for (Variable param in parameters) { |
629 param.writeCount++; // Being a parameter counts as a write. | 643 param.writeCount++; // Being a parameter counts as a write. |
630 } | 644 } |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 S visitReturn(Return node); | 835 S visitReturn(Return node); |
822 S visitThrow(Throw node); | 836 S visitThrow(Throw node); |
823 S visitRethrow(Rethrow node); | 837 S visitRethrow(Rethrow node); |
824 S visitBreak(Break node); | 838 S visitBreak(Break node); |
825 S visitContinue(Continue node); | 839 S visitContinue(Continue node); |
826 S visitIf(If node); | 840 S visitIf(If node); |
827 S visitWhileTrue(WhileTrue node); | 841 S visitWhileTrue(WhileTrue node); |
828 S visitWhileCondition(WhileCondition node); | 842 S visitWhileCondition(WhileCondition node); |
829 S visitExpressionStatement(ExpressionStatement node); | 843 S visitExpressionStatement(ExpressionStatement node); |
830 S visitTry(Try node); | 844 S visitTry(Try node); |
| 845 S visitUnreachable(Unreachable node); |
831 } | 846 } |
832 | 847 |
833 abstract class StatementVisitor1<S, A> { | 848 abstract class StatementVisitor1<S, A> { |
834 S visitStatement(Statement node, A arg) => node.accept1(this, arg); | 849 S visitStatement(Statement node, A arg) => node.accept1(this, arg); |
835 S visitLabeledStatement(LabeledStatement node, A arg); | 850 S visitLabeledStatement(LabeledStatement node, A arg); |
836 S visitReturn(Return node, A arg); | 851 S visitReturn(Return node, A arg); |
837 S visitThrow(Throw node, A arg); | 852 S visitThrow(Throw node, A arg); |
838 S visitRethrow(Rethrow node, A arg); | 853 S visitRethrow(Rethrow node, A arg); |
839 S visitBreak(Break node, A arg); | 854 S visitBreak(Break node, A arg); |
840 S visitContinue(Continue node, A arg); | 855 S visitContinue(Continue node, A arg); |
841 S visitIf(If node, A arg); | 856 S visitIf(If node, A arg); |
842 S visitWhileTrue(WhileTrue node, A arg); | 857 S visitWhileTrue(WhileTrue node, A arg); |
843 S visitWhileCondition(WhileCondition node, A arg); | 858 S visitWhileCondition(WhileCondition node, A arg); |
844 S visitExpressionStatement(ExpressionStatement node, A arg); | 859 S visitExpressionStatement(ExpressionStatement node, A arg); |
845 S visitTry(Try node, A arg); | 860 S visitTry(Try node, A arg); |
| 861 S visitUnreachable(Unreachable node, A arg); |
846 } | 862 } |
847 | 863 |
848 abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor { | 864 abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor { |
849 visitExpression(Expression e) => e.accept(this); | 865 visitExpression(Expression e) => e.accept(this); |
850 visitStatement(Statement s) => s.accept(this); | 866 visitStatement(Statement s) => s.accept(this); |
851 | 867 |
852 visitInnerFunction(FunctionDefinition node); | 868 visitInnerFunction(FunctionDefinition node); |
853 | 869 |
854 visitVariable(Variable variable) {} | 870 visitVariable(Variable variable) {} |
855 | 871 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1000 visitExpression(node.target); | 1016 visitExpression(node.target); |
1001 } | 1017 } |
1002 | 1018 |
1003 visitTypeExpression(TypeExpression node) { | 1019 visitTypeExpression(TypeExpression node) { |
1004 node.arguments.forEach(visitExpression); | 1020 node.arguments.forEach(visitExpression); |
1005 } | 1021 } |
1006 | 1022 |
1007 visitCreateInvocationMirror(CreateInvocationMirror node) { | 1023 visitCreateInvocationMirror(CreateInvocationMirror node) { |
1008 node.arguments.forEach(visitExpression); | 1024 node.arguments.forEach(visitExpression); |
1009 } | 1025 } |
| 1026 |
| 1027 visitUnreachable(Unreachable node) {} |
1010 } | 1028 } |
1011 | 1029 |
1012 abstract class Transformer implements ExpressionVisitor<Expression>, | 1030 abstract class Transformer implements ExpressionVisitor<Expression>, |
1013 StatementVisitor<Statement> { | 1031 StatementVisitor<Statement> { |
1014 Expression visitExpression(Expression e) => e.accept(this); | 1032 Expression visitExpression(Expression e) => e.accept(this); |
1015 Statement visitStatement(Statement s) => s.accept(this); | 1033 Statement visitStatement(Statement s) => s.accept(this); |
1016 } | 1034 } |
1017 | 1035 |
1018 class RecursiveTransformer extends Transformer { | 1036 class RecursiveTransformer extends Transformer { |
1019 void visitInnerFunction(FunctionDefinition node) { | 1037 void visitInnerFunction(FunctionDefinition node) { |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1196 | 1214 |
1197 visitTypeExpression(TypeExpression node) { | 1215 visitTypeExpression(TypeExpression node) { |
1198 _replaceExpressions(node.arguments); | 1216 _replaceExpressions(node.arguments); |
1199 return node; | 1217 return node; |
1200 } | 1218 } |
1201 | 1219 |
1202 visitCreateInvocationMirror(CreateInvocationMirror node) { | 1220 visitCreateInvocationMirror(CreateInvocationMirror node) { |
1203 _replaceExpressions(node.arguments); | 1221 _replaceExpressions(node.arguments); |
1204 return node; | 1222 return node; |
1205 } | 1223 } |
| 1224 |
| 1225 visitUnreachable(Unreachable node) { |
| 1226 return node; |
| 1227 } |
1206 } | 1228 } |
OLD | NEW |