| 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 '../cps_ir/cps_ir_nodes.dart' as cps_ir; | 9 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; |
| 10 import '../dart_types.dart' show DartType, GenericType; | 10 import '../dart_types.dart' show DartType, GenericType; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 * The base class of all Tree nodes. | 35 * The base class of all Tree nodes. |
| 36 */ | 36 */ |
| 37 abstract class Node { | 37 abstract class Node { |
| 38 } | 38 } |
| 39 | 39 |
| 40 /** | 40 /** |
| 41 * The base class of [Expression]s. | 41 * The base class of [Expression]s. |
| 42 */ | 42 */ |
| 43 abstract class Expression extends Node { | 43 abstract class Expression extends Node { |
| 44 accept(ExpressionVisitor v); | 44 accept(ExpressionVisitor v); |
| 45 accept1(ExpressionVisitor1 v, arg); |
| 45 | 46 |
| 46 /// Temporary variable used by [StatementRewriter]. | 47 /// Temporary variable used by [StatementRewriter]. |
| 47 /// If set to true, this expression has already had enclosing assignments | 48 /// If set to true, this expression has already had enclosing assignments |
| 48 /// propagated into its variables, and should not be processed again. | 49 /// propagated into its variables, and should not be processed again. |
| 49 /// It is only set for expressions that are known to be in risk of redundant | 50 /// It is only set for expressions that are known to be in risk of redundant |
| 50 /// processing. | 51 /// processing. |
| 51 bool processed = false; | 52 bool processed = false; |
| 52 } | 53 } |
| 53 | 54 |
| 54 abstract class Statement extends Node { | 55 abstract class Statement extends Node { |
| 55 Statement get next; | 56 Statement get next; |
| 56 void set next(Statement s); | 57 void set next(Statement s); |
| 57 accept(StatementVisitor v); | 58 accept(StatementVisitor v); |
| 59 accept1(StatementVisitor1 v, arg); |
| 58 } | 60 } |
| 59 | 61 |
| 60 /** | 62 /** |
| 61 * Labels name [LabeledStatement]s. | 63 * Labels name [LabeledStatement]s. |
| 62 */ | 64 */ |
| 63 class Label { | 65 class Label { |
| 64 // A counter used to generate names. The counter is reset to 0 for each | 66 // A counter used to generate names. The counter is reset to 0 for each |
| 65 // function emitted. | 67 // function emitted. |
| 66 static int counter = 0; | 68 static int counter = 0; |
| 67 static String _newName() => 'L${counter++}'; | 69 static String _newName() => 'L${counter++}'; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 /// - left-hand of an [Assign] | 101 /// - left-hand of an [Assign] |
| 100 /// - left-hand of a [FunctionDeclaration] | 102 /// - left-hand of a [FunctionDeclaration] |
| 101 /// - parameter in a [FunctionDefinition] | 103 /// - parameter in a [FunctionDefinition] |
| 102 int writeCount = 0; | 104 int writeCount = 0; |
| 103 | 105 |
| 104 Variable(this.host, this.element) { | 106 Variable(this.host, this.element) { |
| 105 assert(host != null); | 107 assert(host != null); |
| 106 } | 108 } |
| 107 | 109 |
| 108 accept(ExpressionVisitor visitor) => visitor.visitVariable(this); | 110 accept(ExpressionVisitor visitor) => visitor.visitVariable(this); |
| 111 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitVariable(this, arg); |
| 109 } | 112 } |
| 110 | 113 |
| 111 /** | 114 /** |
| 112 * Common interface for invocations with arguments. | 115 * Common interface for invocations with arguments. |
| 113 */ | 116 */ |
| 114 abstract class Invoke { | 117 abstract class Invoke { |
| 115 List<Expression> get arguments; | 118 List<Expression> get arguments; |
| 116 Selector get selector; | 119 Selector get selector; |
| 117 } | 120 } |
| 118 | 121 |
| 119 /** | 122 /** |
| 120 * A call to a static function or getter/setter to a static field. | 123 * A call to a static function or getter/setter to a static field. |
| 121 * | 124 * |
| 122 * In contrast to the CPS-based IR, the arguments can be arbitrary expressions. | 125 * In contrast to the CPS-based IR, the arguments can be arbitrary expressions. |
| 123 */ | 126 */ |
| 124 class InvokeStatic extends Expression implements Invoke { | 127 class InvokeStatic extends Expression implements Invoke { |
| 125 final Entity target; | 128 final Entity target; |
| 126 final List<Expression> arguments; | 129 final List<Expression> arguments; |
| 127 final Selector selector; | 130 final Selector selector; |
| 128 | 131 |
| 129 InvokeStatic(this.target, this.selector, this.arguments); | 132 InvokeStatic(this.target, this.selector, this.arguments); |
| 130 | 133 |
| 131 accept(ExpressionVisitor visitor) => visitor.visitInvokeStatic(this); | 134 accept(ExpressionVisitor visitor) => visitor.visitInvokeStatic(this); |
| 135 accept1(ExpressionVisitor1 visitor, arg) { |
| 136 return visitor.visitInvokeStatic(this, arg); |
| 137 } |
| 132 } | 138 } |
| 133 | 139 |
| 134 /** | 140 /** |
| 135 * A call to a method, operator, getter, setter or index getter/setter. | 141 * A call to a method, operator, getter, setter or index getter/setter. |
| 136 * | 142 * |
| 137 * In contrast to the CPS-based IR, the receiver and arguments can be | 143 * In contrast to the CPS-based IR, the receiver and arguments can be |
| 138 * arbitrary expressions. | 144 * arbitrary expressions. |
| 139 */ | 145 */ |
| 140 class InvokeMethod extends Expression implements Invoke { | 146 class InvokeMethod extends Expression implements Invoke { |
| 141 Expression receiver; | 147 Expression receiver; |
| 142 final Selector selector; | 148 final Selector selector; |
| 143 final List<Expression> arguments; | 149 final List<Expression> arguments; |
| 144 | 150 |
| 145 InvokeMethod(this.receiver, this.selector, this.arguments) { | 151 InvokeMethod(this.receiver, this.selector, this.arguments) { |
| 146 assert(receiver != null); | 152 assert(receiver != null); |
| 147 } | 153 } |
| 148 | 154 |
| 149 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this); | 155 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this); |
| 156 accept1(ExpressionVisitor1 visitor, arg) { |
| 157 return visitor.visitInvokeMethod(this, arg); |
| 158 } |
| 150 } | 159 } |
| 151 | 160 |
| 152 class InvokeSuperMethod extends Expression implements Invoke { | 161 class InvokeSuperMethod extends Expression implements Invoke { |
| 153 final Selector selector; | 162 final Selector selector; |
| 154 final List<Expression> arguments; | 163 final List<Expression> arguments; |
| 155 | 164 |
| 156 InvokeSuperMethod(this.selector, this.arguments); | 165 InvokeSuperMethod(this.selector, this.arguments); |
| 157 | 166 |
| 158 accept(ExpressionVisitor visitor) => visitor.visitInvokeSuperMethod(this); | 167 accept(ExpressionVisitor visitor) => visitor.visitInvokeSuperMethod(this); |
| 168 accept1(ExpressionVisitor1 visitor, arg) { |
| 169 return visitor.visitInvokeSuperMethod(this, arg); |
| 170 } |
| 159 } | 171 } |
| 160 | 172 |
| 161 /** | 173 /** |
| 162 * Call to a factory or generative constructor. | 174 * Call to a factory or generative constructor. |
| 163 */ | 175 */ |
| 164 class InvokeConstructor extends Expression implements Invoke { | 176 class InvokeConstructor extends Expression implements Invoke { |
| 165 final DartType type; | 177 final DartType type; |
| 166 final FunctionElement target; | 178 final FunctionElement target; |
| 167 final List<Expression> arguments; | 179 final List<Expression> arguments; |
| 168 final Selector selector; | 180 final Selector selector; |
| 169 final values.ConstantValue constant; | 181 final values.ConstantValue constant; |
| 170 | 182 |
| 171 InvokeConstructor(this.type, this.target, this.selector, this.arguments, | 183 InvokeConstructor(this.type, this.target, this.selector, this.arguments, |
| 172 [this.constant]); | 184 [this.constant]); |
| 173 | 185 |
| 174 ClassElement get targetClass => target.enclosingElement; | 186 ClassElement get targetClass => target.enclosingElement; |
| 175 | 187 |
| 176 accept(ExpressionVisitor visitor) => visitor.visitInvokeConstructor(this); | 188 accept(ExpressionVisitor visitor) => visitor.visitInvokeConstructor(this); |
| 189 accept1(ExpressionVisitor1 visitor, arg) { |
| 190 return visitor.visitInvokeConstructor(this, arg); |
| 191 } |
| 177 } | 192 } |
| 178 | 193 |
| 179 /// Calls [toString] on each argument and concatenates the results. | 194 /// Calls [toString] on each argument and concatenates the results. |
| 180 class ConcatenateStrings extends Expression { | 195 class ConcatenateStrings extends Expression { |
| 181 final List<Expression> arguments; | 196 final List<Expression> arguments; |
| 182 final values.ConstantValue constant; | 197 final values.ConstantValue constant; |
| 183 | 198 |
| 184 ConcatenateStrings(this.arguments, [this.constant]); | 199 ConcatenateStrings(this.arguments, [this.constant]); |
| 185 | 200 |
| 186 accept(ExpressionVisitor visitor) => visitor.visitConcatenateStrings(this); | 201 accept(ExpressionVisitor visitor) => visitor.visitConcatenateStrings(this); |
| 202 accept1(ExpressionVisitor1 visitor, arg) { |
| 203 return visitor.visitConcatenateStrings(this, arg); |
| 204 } |
| 187 } | 205 } |
| 188 | 206 |
| 189 /** | 207 /** |
| 190 * A constant. | 208 * A constant. |
| 191 */ | 209 */ |
| 192 class Constant extends Expression { | 210 class Constant extends Expression { |
| 193 final ConstantExpression expression; | 211 final ConstantExpression expression; |
| 194 | 212 |
| 195 Constant(this.expression); | 213 Constant(this.expression); |
| 196 | 214 |
| 197 Constant.primitive(values.PrimitiveConstantValue primitiveValue) | 215 Constant.primitive(values.PrimitiveConstantValue primitiveValue) |
| 198 : expression = new PrimitiveConstantExpression(primitiveValue); | 216 : expression = new PrimitiveConstantExpression(primitiveValue); |
| 199 | 217 |
| 200 accept(ExpressionVisitor visitor) => visitor.visitConstant(this); | 218 accept(ExpressionVisitor visitor) => visitor.visitConstant(this); |
| 219 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitConstant(this, arg); |
| 201 | 220 |
| 202 values.ConstantValue get value => expression.value; | 221 values.ConstantValue get value => expression.value; |
| 203 } | 222 } |
| 204 | 223 |
| 205 class This extends Expression { | 224 class This extends Expression { |
| 206 accept(ExpressionVisitor visitor) => visitor.visitThis(this); | 225 accept(ExpressionVisitor visitor) => visitor.visitThis(this); |
| 226 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitThis(this, arg); |
| 207 } | 227 } |
| 208 | 228 |
| 209 class ReifyTypeVar extends Expression { | 229 class ReifyTypeVar extends Expression { |
| 210 TypeVariableElement typeVariable; | 230 TypeVariableElement typeVariable; |
| 211 | 231 |
| 212 ReifyTypeVar(this.typeVariable); | 232 ReifyTypeVar(this.typeVariable); |
| 213 | 233 |
| 214 accept(ExpressionVisitor visitor) => visitor.visitReifyTypeVar(this); | 234 accept(ExpressionVisitor visitor) => visitor.visitReifyTypeVar(this); |
| 235 accept1(ExpressionVisitor1 visitor, arg) { |
| 236 return visitor.visitReifyTypeVar(this, arg); |
| 237 } |
| 215 } | 238 } |
| 216 | 239 |
| 217 class LiteralList extends Expression { | 240 class LiteralList extends Expression { |
| 218 final GenericType type; | 241 final GenericType type; |
| 219 final List<Expression> values; | 242 final List<Expression> values; |
| 220 | 243 |
| 221 LiteralList(this.type, this.values); | 244 LiteralList(this.type, this.values); |
| 222 | 245 |
| 223 accept(ExpressionVisitor visitor) => visitor.visitLiteralList(this); | 246 accept(ExpressionVisitor visitor) => visitor.visitLiteralList(this); |
| 247 accept1(ExpressionVisitor1 visitor, arg) { |
| 248 return visitor.visitLiteralList(this, arg); |
| 249 } |
| 224 } | 250 } |
| 225 | 251 |
| 226 class LiteralMapEntry { | 252 class LiteralMapEntry { |
| 227 Expression key; | 253 Expression key; |
| 228 Expression value; | 254 Expression value; |
| 229 | 255 |
| 230 LiteralMapEntry(this.key, this.value); | 256 LiteralMapEntry(this.key, this.value); |
| 231 } | 257 } |
| 232 | 258 |
| 233 class LiteralMap extends Expression { | 259 class LiteralMap extends Expression { |
| 234 final GenericType type; | 260 final GenericType type; |
| 235 final List<LiteralMapEntry> entries; | 261 final List<LiteralMapEntry> entries; |
| 236 | 262 |
| 237 LiteralMap(this.type, this.entries); | 263 LiteralMap(this.type, this.entries); |
| 238 | 264 |
| 239 accept(ExpressionVisitor visitor) => visitor.visitLiteralMap(this); | 265 accept(ExpressionVisitor visitor) => visitor.visitLiteralMap(this); |
| 266 accept1(ExpressionVisitor1 visitor, arg) { |
| 267 return visitor.visitLiteralMap(this, arg); |
| 268 } |
| 240 } | 269 } |
| 241 | 270 |
| 242 class TypeOperator extends Expression { | 271 class TypeOperator extends Expression { |
| 243 Expression receiver; | 272 Expression receiver; |
| 244 final DartType type; | 273 final DartType type; |
| 245 final bool isTypeTest; | 274 final bool isTypeTest; |
| 246 | 275 |
| 247 TypeOperator(this.receiver, this.type, {bool this.isTypeTest}); | 276 TypeOperator(this.receiver, this.type, {bool this.isTypeTest}); |
| 248 | 277 |
| 249 accept(ExpressionVisitor visitor) => visitor.visitTypeOperator(this); | 278 accept(ExpressionVisitor visitor) => visitor.visitTypeOperator(this); |
| 279 accept1(ExpressionVisitor1 visitor, arg) { |
| 280 return visitor.visitTypeOperator(this, arg); |
| 281 } |
| 250 | 282 |
| 251 String get operator => isTypeTest ? 'is' : 'as'; | 283 String get operator => isTypeTest ? 'is' : 'as'; |
| 252 } | 284 } |
| 253 | 285 |
| 254 /// A conditional expression. | 286 /// A conditional expression. |
| 255 class Conditional extends Expression { | 287 class Conditional extends Expression { |
| 256 Expression condition; | 288 Expression condition; |
| 257 Expression thenExpression; | 289 Expression thenExpression; |
| 258 Expression elseExpression; | 290 Expression elseExpression; |
| 259 | 291 |
| 260 Conditional(this.condition, this.thenExpression, this.elseExpression); | 292 Conditional(this.condition, this.thenExpression, this.elseExpression); |
| 261 | 293 |
| 262 accept(ExpressionVisitor visitor) => visitor.visitConditional(this); | 294 accept(ExpressionVisitor visitor) => visitor.visitConditional(this); |
| 295 accept1(ExpressionVisitor1 visitor, arg) { |
| 296 return visitor.visitConditional(this, arg); |
| 297 } |
| 263 } | 298 } |
| 264 | 299 |
| 265 /// An && or || expression. The operator is internally represented as a boolean | 300 /// An && or || expression. The operator is internally represented as a boolean |
| 266 /// [isAnd] to simplify rewriting of logical operators. | 301 /// [isAnd] to simplify rewriting of logical operators. |
| 267 class LogicalOperator extends Expression { | 302 class LogicalOperator extends Expression { |
| 268 Expression left; | 303 Expression left; |
| 269 bool isAnd; | 304 bool isAnd; |
| 270 Expression right; | 305 Expression right; |
| 271 | 306 |
| 272 LogicalOperator(this.left, this.right, this.isAnd); | 307 LogicalOperator(this.left, this.right, this.isAnd); |
| 273 LogicalOperator.and(this.left, this.right) : isAnd = true; | 308 LogicalOperator.and(this.left, this.right) : isAnd = true; |
| 274 LogicalOperator.or(this.left, this.right) : isAnd = false; | 309 LogicalOperator.or(this.left, this.right) : isAnd = false; |
| 275 | 310 |
| 276 String get operator => isAnd ? '&&' : '||'; | 311 String get operator => isAnd ? '&&' : '||'; |
| 277 | 312 |
| 278 accept(ExpressionVisitor visitor) => visitor.visitLogicalOperator(this); | 313 accept(ExpressionVisitor visitor) => visitor.visitLogicalOperator(this); |
| 314 accept1(ExpressionVisitor1 visitor, arg) { |
| 315 return visitor.visitLogicalOperator(this, arg); |
| 316 } |
| 279 } | 317 } |
| 280 | 318 |
| 281 /// Logical negation. | 319 /// Logical negation. |
| 282 class Not extends Expression { | 320 class Not extends Expression { |
| 283 Expression operand; | 321 Expression operand; |
| 284 | 322 |
| 285 Not(this.operand); | 323 Not(this.operand); |
| 286 | 324 |
| 287 accept(ExpressionVisitor visitor) => visitor.visitNot(this); | 325 accept(ExpressionVisitor visitor) => visitor.visitNot(this); |
| 326 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitNot(this, arg); |
| 288 } | 327 } |
| 289 | 328 |
| 290 class FunctionExpression extends Expression { | 329 class FunctionExpression extends Expression { |
| 291 final FunctionDefinition definition; | 330 final FunctionDefinition definition; |
| 292 | 331 |
| 293 FunctionExpression(this.definition) { | 332 FunctionExpression(this.definition) { |
| 294 assert(definition.element.type.returnType.treatAsDynamic); | 333 assert(definition.element.type.returnType.treatAsDynamic); |
| 295 } | 334 } |
| 296 | 335 |
| 297 accept(ExpressionVisitor visitor) => visitor.visitFunctionExpression(this); | 336 accept(ExpressionVisitor visitor) => visitor.visitFunctionExpression(this); |
| 337 accept1(ExpressionVisitor1 visitor, arg) { |
| 338 return visitor.visitFunctionExpression(this, arg); |
| 339 } |
| 298 } | 340 } |
| 299 | 341 |
| 300 /// Declares a local function. | 342 /// Declares a local function. |
| 301 /// Used for functions that may not occur in expression context due to | 343 /// Used for functions that may not occur in expression context due to |
| 302 /// being recursive or having a return type. | 344 /// being recursive or having a return type. |
| 303 /// The [variable] must not occur as the left-hand side of an [Assign] or | 345 /// The [variable] must not occur as the left-hand side of an [Assign] or |
| 304 /// any other [FunctionDeclaration]. | 346 /// any other [FunctionDeclaration]. |
| 305 class FunctionDeclaration extends Statement { | 347 class FunctionDeclaration extends Statement { |
| 306 Variable variable; | 348 Variable variable; |
| 307 final FunctionDefinition definition; | 349 final FunctionDefinition definition; |
| 308 Statement next; | 350 Statement next; |
| 309 | 351 |
| 310 FunctionDeclaration(this.variable, this.definition, this.next) { | 352 FunctionDeclaration(this.variable, this.definition, this.next) { |
| 311 ++variable.writeCount; | 353 ++variable.writeCount; |
| 312 } | 354 } |
| 313 | 355 |
| 314 accept(StatementVisitor visitor) => visitor.visitFunctionDeclaration(this); | 356 accept(StatementVisitor visitor) => visitor.visitFunctionDeclaration(this); |
| 357 accept1(StatementVisitor1 visitor, arg) { |
| 358 return visitor.visitFunctionDeclaration(this, arg); |
| 359 } |
| 315 } | 360 } |
| 316 | 361 |
| 317 /// A [LabeledStatement] or [WhileTrue] or [WhileCondition]. | 362 /// A [LabeledStatement] or [WhileTrue] or [WhileCondition]. |
| 318 abstract class JumpTarget extends Statement { | 363 abstract class JumpTarget extends Statement { |
| 319 Label get label; | 364 Label get label; |
| 320 Statement get body; | 365 Statement get body; |
| 321 } | 366 } |
| 322 | 367 |
| 323 /** | 368 /** |
| 324 * A labeled statement. Breaks to the label within the labeled statement | 369 * A labeled statement. Breaks to the label within the labeled statement |
| 325 * target the successor statement. | 370 * target the successor statement. |
| 326 */ | 371 */ |
| 327 class LabeledStatement extends JumpTarget { | 372 class LabeledStatement extends JumpTarget { |
| 328 Statement next; | 373 Statement next; |
| 329 final Label label; | 374 final Label label; |
| 330 Statement body; | 375 Statement body; |
| 331 | 376 |
| 332 LabeledStatement(this.label, this.body, this.next) { | 377 LabeledStatement(this.label, this.body, this.next) { |
| 333 assert(label.binding == null); | 378 assert(label.binding == null); |
| 334 label.binding = this; | 379 label.binding = this; |
| 335 } | 380 } |
| 336 | 381 |
| 337 accept(StatementVisitor visitor) => visitor.visitLabeledStatement(this); | 382 accept(StatementVisitor visitor) => visitor.visitLabeledStatement(this); |
| 383 accept1(StatementVisitor1 visitor, arg) { |
| 384 return visitor.visitLabeledStatement(this, arg); |
| 385 } |
| 338 } | 386 } |
| 339 | 387 |
| 340 /// A [WhileTrue] or [WhileCondition] loop. | 388 /// A [WhileTrue] or [WhileCondition] loop. |
| 341 abstract class Loop extends JumpTarget { | 389 abstract class Loop extends JumpTarget { |
| 342 } | 390 } |
| 343 | 391 |
| 344 /** | 392 /** |
| 345 * A labeled while(true) loop. | 393 * A labeled while(true) loop. |
| 346 */ | 394 */ |
| 347 class WhileTrue extends Loop { | 395 class WhileTrue extends Loop { |
| 348 final Label label; | 396 final Label label; |
| 349 Statement body; | 397 Statement body; |
| 350 | 398 |
| 351 WhileTrue(this.label, this.body) { | 399 WhileTrue(this.label, this.body) { |
| 352 assert(label.binding == null); | 400 assert(label.binding == null); |
| 353 label.binding = this; | 401 label.binding = this; |
| 354 } | 402 } |
| 355 | 403 |
| 356 Statement get next => null; | 404 Statement get next => null; |
| 357 void set next(Statement s) => throw 'UNREACHABLE'; | 405 void set next(Statement s) => throw 'UNREACHABLE'; |
| 358 | 406 |
| 359 accept(StatementVisitor visitor) => visitor.visitWhileTrue(this); | 407 accept(StatementVisitor visitor) => visitor.visitWhileTrue(this); |
| 408 accept1(StatementVisitor1 visitor, arg) => visitor.visitWhileTrue(this, arg); |
| 360 } | 409 } |
| 361 | 410 |
| 362 /** | 411 /** |
| 363 * A while loop with a condition. If the condition is false, control resumes | 412 * A while loop with a condition. If the condition is false, control resumes |
| 364 * at the [next] statement. | 413 * at the [next] statement. |
| 365 * | 414 * |
| 366 * It is NOT valid to target this statement with a [Break]. | 415 * It is NOT valid to target this statement with a [Break]. |
| 367 * The only way to reach [next] is for the condition to evaluate to false. | 416 * The only way to reach [next] is for the condition to evaluate to false. |
| 368 * | 417 * |
| 369 * [WhileCondition] statements are introduced in the [LoopRewriter] and is | 418 * [WhileCondition] statements are introduced in the [LoopRewriter] and is |
| 370 * assumed not to occur before then. | 419 * assumed not to occur before then. |
| 371 */ | 420 */ |
| 372 class WhileCondition extends Loop { | 421 class WhileCondition extends Loop { |
| 373 final Label label; | 422 final Label label; |
| 374 Expression condition; | 423 Expression condition; |
| 375 Statement body; | 424 Statement body; |
| 376 Statement next; | 425 Statement next; |
| 377 | 426 |
| 378 WhileCondition(this.label, this.condition, this.body, | 427 WhileCondition(this.label, this.condition, this.body, |
| 379 this.next) { | 428 this.next) { |
| 380 assert(label.binding == null); | 429 assert(label.binding == null); |
| 381 label.binding = this; | 430 label.binding = this; |
| 382 } | 431 } |
| 383 | 432 |
| 384 accept(StatementVisitor visitor) => visitor.visitWhileCondition(this); | 433 accept(StatementVisitor visitor) => visitor.visitWhileCondition(this); |
| 434 accept1(StatementVisitor1 visitor, arg) { |
| 435 return visitor.visitWhileCondition(this, arg); |
| 436 } |
| 385 } | 437 } |
| 386 | 438 |
| 387 /// A [Break] or [Continue] statement. | 439 /// A [Break] or [Continue] statement. |
| 388 abstract class Jump extends Statement { | 440 abstract class Jump extends Statement { |
| 389 Label get target; | 441 Label get target; |
| 390 } | 442 } |
| 391 | 443 |
| 392 /** | 444 /** |
| 393 * A break from an enclosing [LabeledStatement]. The break targets the | 445 * A break from an enclosing [LabeledStatement]. The break targets the |
| 394 * labeled statement's successor statement. | 446 * labeled statement's successor statement. |
| 395 */ | 447 */ |
| 396 class Break extends Jump { | 448 class Break extends Jump { |
| 397 final Label target; | 449 final Label target; |
| 398 | 450 |
| 399 Statement get next => null; | 451 Statement get next => null; |
| 400 void set next(Statement s) => throw 'UNREACHABLE'; | 452 void set next(Statement s) => throw 'UNREACHABLE'; |
| 401 | 453 |
| 402 Break(this.target) { | 454 Break(this.target) { |
| 403 ++target.useCount; | 455 ++target.useCount; |
| 404 } | 456 } |
| 405 | 457 |
| 406 accept(StatementVisitor visitor) => visitor.visitBreak(this); | 458 accept(StatementVisitor visitor) => visitor.visitBreak(this); |
| 459 accept1(StatementVisitor1 visitor, arg) => visitor.visitBreak(this, arg); |
| 407 } | 460 } |
| 408 | 461 |
| 409 /** | 462 /** |
| 410 * A continue to an enclosing [WhileTrue] or [WhileCondition] loop. | 463 * A continue to an enclosing [WhileTrue] or [WhileCondition] loop. |
| 411 * The continue targets the loop's body. | 464 * The continue targets the loop's body. |
| 412 */ | 465 */ |
| 413 class Continue extends Jump { | 466 class Continue extends Jump { |
| 414 final Label target; | 467 final Label target; |
| 415 | 468 |
| 416 Statement get next => null; | 469 Statement get next => null; |
| 417 void set next(Statement s) => throw 'UNREACHABLE'; | 470 void set next(Statement s) => throw 'UNREACHABLE'; |
| 418 | 471 |
| 419 Continue(this.target) { | 472 Continue(this.target) { |
| 420 ++target.useCount; | 473 ++target.useCount; |
| 421 } | 474 } |
| 422 | 475 |
| 423 accept(StatementVisitor visitor) => visitor.visitContinue(this); | 476 accept(StatementVisitor visitor) => visitor.visitContinue(this); |
| 477 accept1(StatementVisitor1 visitor, arg) => visitor.visitContinue(this, arg); |
| 424 } | 478 } |
| 425 | 479 |
| 426 /** | 480 /** |
| 427 * An assignments of an [Expression] to a [Variable]. | 481 * An assignments of an [Expression] to a [Variable]. |
| 428 * | 482 * |
| 429 * In contrast to the CPS-based IR, non-primitive expressions can be assigned | 483 * In contrast to the CPS-based IR, non-primitive expressions can be assigned |
| 430 * to variables. | 484 * to variables. |
| 431 */ | 485 */ |
| 432 class Assign extends Statement { | 486 class Assign extends Statement { |
| 433 Statement next; | 487 Statement next; |
| 434 Variable variable; | 488 Variable variable; |
| 435 Expression definition; | 489 Expression definition; |
| 436 | 490 |
| 437 /// If true, this declares a new copy of the closure variable. | 491 /// If true, this declares a new copy of the closure variable. |
| 438 /// The consequences are similar to [cps_ir.SetClosureVariable]. | 492 /// The consequences are similar to [cps_ir.SetClosureVariable]. |
| 439 /// All uses of the variable must be nested inside the [next] statement. | 493 /// All uses of the variable must be nested inside the [next] statement. |
| 440 bool isDeclaration; | 494 bool isDeclaration; |
| 441 | 495 |
| 442 Assign(this.variable, this.definition, this.next, | 496 Assign(this.variable, this.definition, this.next, |
| 443 { this.isDeclaration: false }) { | 497 { this.isDeclaration: false }) { |
| 444 variable.writeCount++; | 498 variable.writeCount++; |
| 445 } | 499 } |
| 446 | 500 |
| 447 bool get hasExactlyOneUse => variable.readCount == 1; | 501 bool get hasExactlyOneUse => variable.readCount == 1; |
| 448 | 502 |
| 449 accept(StatementVisitor visitor) => visitor.visitAssign(this); | 503 accept(StatementVisitor visitor) => visitor.visitAssign(this); |
| 504 accept1(StatementVisitor1 visitor, arg) => visitor.visitAssign(this, arg); |
| 450 } | 505 } |
| 451 | 506 |
| 452 /** | 507 /** |
| 453 * A return exit from the function. | 508 * A return exit from the function. |
| 454 * | 509 * |
| 455 * In contrast to the CPS-based IR, the return value is an arbitrary | 510 * In contrast to the CPS-based IR, the return value is an arbitrary |
| 456 * expression. | 511 * expression. |
| 457 */ | 512 */ |
| 458 class Return extends Statement { | 513 class Return extends Statement { |
| 459 /// Should not be null. Use [Constant] with [NullConstantValue] for void | 514 /// Should not be null. Use [Constant] with [NullConstantValue] for void |
| 460 /// returns. | 515 /// returns. |
| 461 Expression value; | 516 Expression value; |
| 462 | 517 |
| 463 Statement get next => null; | 518 Statement get next => null; |
| 464 void set next(Statement s) => throw 'UNREACHABLE'; | 519 void set next(Statement s) => throw 'UNREACHABLE'; |
| 465 | 520 |
| 466 Return(this.value); | 521 Return(this.value); |
| 467 | 522 |
| 468 accept(StatementVisitor visitor) => visitor.visitReturn(this); | 523 accept(StatementVisitor visitor) => visitor.visitReturn(this); |
| 524 accept1(StatementVisitor1 visitor, arg) => visitor.visitReturn(this, arg); |
| 469 } | 525 } |
| 470 | 526 |
| 471 /** | 527 /** |
| 472 * A conditional branch based on the true value of an [Expression]. | 528 * A conditional branch based on the true value of an [Expression]. |
| 473 */ | 529 */ |
| 474 class If extends Statement { | 530 class If extends Statement { |
| 475 Expression condition; | 531 Expression condition; |
| 476 Statement thenStatement; | 532 Statement thenStatement; |
| 477 Statement elseStatement; | 533 Statement elseStatement; |
| 478 | 534 |
| 479 Statement get next => null; | 535 Statement get next => null; |
| 480 void set next(Statement s) => throw 'UNREACHABLE'; | 536 void set next(Statement s) => throw 'UNREACHABLE'; |
| 481 | 537 |
| 482 If(this.condition, this.thenStatement, this.elseStatement); | 538 If(this.condition, this.thenStatement, this.elseStatement); |
| 483 | 539 |
| 484 accept(StatementVisitor visitor) => visitor.visitIf(this); | 540 accept(StatementVisitor visitor) => visitor.visitIf(this); |
| 541 accept1(StatementVisitor1 visitor, arg) => visitor.visitIf(this, arg); |
| 485 } | 542 } |
| 486 | 543 |
| 487 class ExpressionStatement extends Statement { | 544 class ExpressionStatement extends Statement { |
| 488 Statement next; | 545 Statement next; |
| 489 Expression expression; | 546 Expression expression; |
| 490 | 547 |
| 491 ExpressionStatement(this.expression, this.next); | 548 ExpressionStatement(this.expression, this.next); |
| 492 | 549 |
| 493 accept(StatementVisitor visitor) => visitor.visitExpressionStatement(this); | 550 accept(StatementVisitor visitor) => visitor.visitExpressionStatement(this); |
| 551 accept1(StatementVisitor1 visitor, arg) { |
| 552 return visitor.visitExpressionStatement(this, arg); |
| 553 } |
| 494 } | 554 } |
| 495 | 555 |
| 496 abstract class ExecutableDefinition { | 556 abstract class ExecutableDefinition { |
| 497 ExecutableElement get element; | 557 ExecutableElement get element; |
| 498 Statement body; | 558 Statement body; |
| 499 | 559 |
| 500 applyPass(Pass pass); | 560 applyPass(Pass pass); |
| 501 } | 561 } |
| 502 | 562 |
| 503 class FieldDefinition extends Node implements ExecutableDefinition { | 563 class FieldDefinition extends Node implements ExecutableDefinition { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 E visitReifyTypeVar(ReifyTypeVar node); | 599 E visitReifyTypeVar(ReifyTypeVar node); |
| 540 E visitConditional(Conditional node); | 600 E visitConditional(Conditional node); |
| 541 E visitLogicalOperator(LogicalOperator node); | 601 E visitLogicalOperator(LogicalOperator node); |
| 542 E visitNot(Not node); | 602 E visitNot(Not node); |
| 543 E visitLiteralList(LiteralList node); | 603 E visitLiteralList(LiteralList node); |
| 544 E visitLiteralMap(LiteralMap node); | 604 E visitLiteralMap(LiteralMap node); |
| 545 E visitTypeOperator(TypeOperator node); | 605 E visitTypeOperator(TypeOperator node); |
| 546 E visitFunctionExpression(FunctionExpression node); | 606 E visitFunctionExpression(FunctionExpression node); |
| 547 } | 607 } |
| 548 | 608 |
| 609 abstract class ExpressionVisitor1<E, A> { |
| 610 E visitExpression(Expression e, A arg) => e.accept1(this, arg); |
| 611 E visitVariable(Variable node, A arg); |
| 612 E visitInvokeStatic(InvokeStatic node, A arg); |
| 613 E visitInvokeMethod(InvokeMethod node, A arg); |
| 614 E visitInvokeSuperMethod(InvokeSuperMethod node, A arg); |
| 615 E visitInvokeConstructor(InvokeConstructor node, A arg); |
| 616 E visitConcatenateStrings(ConcatenateStrings node, A arg); |
| 617 E visitConstant(Constant node, A arg); |
| 618 E visitThis(This node, A arg); |
| 619 E visitReifyTypeVar(ReifyTypeVar node, A arg); |
| 620 E visitConditional(Conditional node, A arg); |
| 621 E visitLogicalOperator(LogicalOperator node, A arg); |
| 622 E visitNot(Not node, A arg); |
| 623 E visitLiteralList(LiteralList node, A arg); |
| 624 E visitLiteralMap(LiteralMap node, A arg); |
| 625 E visitTypeOperator(TypeOperator node, A arg); |
| 626 E visitFunctionExpression(FunctionExpression node, A arg); |
| 627 } |
| 628 |
| 549 abstract class StatementVisitor<S> { | 629 abstract class StatementVisitor<S> { |
| 550 S visitStatement(Statement s) => s.accept(this); | 630 S visitStatement(Statement s) => s.accept(this); |
| 551 S visitLabeledStatement(LabeledStatement node); | 631 S visitLabeledStatement(LabeledStatement node); |
| 552 S visitAssign(Assign node); | 632 S visitAssign(Assign node); |
| 553 S visitReturn(Return node); | 633 S visitReturn(Return node); |
| 554 S visitBreak(Break node); | 634 S visitBreak(Break node); |
| 555 S visitContinue(Continue node); | 635 S visitContinue(Continue node); |
| 556 S visitIf(If node); | 636 S visitIf(If node); |
| 557 S visitWhileTrue(WhileTrue node); | 637 S visitWhileTrue(WhileTrue node); |
| 558 S visitWhileCondition(WhileCondition node); | 638 S visitWhileCondition(WhileCondition node); |
| 559 S visitFunctionDeclaration(FunctionDeclaration node); | 639 S visitFunctionDeclaration(FunctionDeclaration node); |
| 560 S visitExpressionStatement(ExpressionStatement node); | 640 S visitExpressionStatement(ExpressionStatement node); |
| 561 } | 641 } |
| 562 | 642 |
| 643 abstract class StatementVisitor1<S, A> { |
| 644 S visitStatement(Statement s, A arg) => s.accept1(this, arg); |
| 645 S visitLabeledStatement(LabeledStatement node, A arg); |
| 646 S visitAssign(Assign node, A arg); |
| 647 S visitReturn(Return node, A arg); |
| 648 S visitBreak(Break node, A arg); |
| 649 S visitContinue(Continue node, A arg); |
| 650 S visitIf(If node, A arg); |
| 651 S visitWhileTrue(WhileTrue node, A arg); |
| 652 S visitWhileCondition(WhileCondition node, A arg); |
| 653 S visitFunctionDeclaration(FunctionDeclaration node, A arg); |
| 654 S visitExpressionStatement(ExpressionStatement node, A arg); |
| 655 } |
| 656 |
| 563 abstract class Visitor<S, E> implements ExpressionVisitor<E>, | 657 abstract class Visitor<S, E> implements ExpressionVisitor<E>, |
| 564 StatementVisitor<S> { | 658 StatementVisitor<S> { |
| 565 E visitExpression(Expression e) => e.accept(this); | 659 E visitExpression(Expression e) => e.accept(this); |
| 566 S visitStatement(Statement s) => s.accept(this); | 660 S visitStatement(Statement s) => s.accept(this); |
| 567 } | 661 } |
| 568 | 662 |
| 663 abstract class Visitor1<S, E, A> implements ExpressionVisitor1<E, A>, |
| 664 StatementVisitor1<S, A> { |
| 665 E visitExpression(Expression e, A arg) => e.accept1(this, arg); |
| 666 S visitStatement(Statement s, A arg) => s.accept1(this, arg); |
| 667 } |
| 668 |
| 569 class RecursiveVisitor extends Visitor { | 669 class RecursiveVisitor extends Visitor { |
| 570 visitFunctionDefinition(FunctionDefinition node) { | 670 visitFunctionDefinition(FunctionDefinition node) { |
| 571 visitStatement(node.body); | 671 visitStatement(node.body); |
| 572 } | 672 } |
| 573 | 673 |
| 574 visitVariable(Variable node) {} | 674 visitVariable(Variable node) {} |
| 575 | 675 |
| 576 visitInvokeStatic(InvokeStatic node) { | 676 visitInvokeStatic(InvokeStatic node) { |
| 577 node.arguments.forEach(visitExpression); | 677 node.arguments.forEach(visitExpression); |
| 578 } | 678 } |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 672 visitFunctionDeclaration(FunctionDeclaration node) { | 772 visitFunctionDeclaration(FunctionDeclaration node) { |
| 673 visitFunctionDefinition(node.definition); | 773 visitFunctionDefinition(node.definition); |
| 674 visitStatement(node.next); | 774 visitStatement(node.next); |
| 675 } | 775 } |
| 676 | 776 |
| 677 visitExpressionStatement(ExpressionStatement node) { | 777 visitExpressionStatement(ExpressionStatement node) { |
| 678 visitExpression(node.expression); | 778 visitExpression(node.expression); |
| 679 visitStatement(node.next); | 779 visitStatement(node.next); |
| 680 } | 780 } |
| 681 } | 781 } |
| OLD | NEW |