| 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 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 * A call to a method, operator, getter, setter or index getter/setter. | 194 * A call to a method, operator, getter, setter or index getter/setter. |
| 195 * | 195 * |
| 196 * If [receiver] is `null`, an error is thrown before the arguments are | 196 * If [receiver] is `null`, an error is thrown before the arguments are |
| 197 * evaluated. This corresponds to the JS evaluation order. | 197 * evaluated. This corresponds to the JS evaluation order. |
| 198 */ | 198 */ |
| 199 class InvokeMethod extends Expression implements Invoke { | 199 class InvokeMethod extends Expression implements Invoke { |
| 200 Expression receiver; | 200 Expression receiver; |
| 201 final Selector selector; | 201 final Selector selector; |
| 202 final TypeMask mask; | 202 final TypeMask mask; |
| 203 final List<Expression> arguments; | 203 final List<Expression> arguments; |
| 204 final SourceInformation sourceInformation; |
| 204 | 205 |
| 205 /// If true, it is known that the receiver cannot be `null`. | 206 /// If true, it is known that the receiver cannot be `null`. |
| 206 bool receiverIsNotNull = false; | 207 bool receiverIsNotNull = false; |
| 207 | 208 |
| 208 InvokeMethod(this.receiver, this.selector, this.mask, this.arguments) { | 209 InvokeMethod(this.receiver, |
| 210 this.selector, |
| 211 this.mask, |
| 212 this.arguments, |
| 213 this.sourceInformation) { |
| 209 assert(receiver != null); | 214 assert(receiver != null); |
| 210 } | 215 } |
| 211 | 216 |
| 212 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this); | 217 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this); |
| 213 accept1(ExpressionVisitor1 visitor, arg) { | 218 accept1(ExpressionVisitor1 visitor, arg) { |
| 214 return visitor.visitInvokeMethod(this, arg); | 219 return visitor.visitInvokeMethod(this, arg); |
| 215 } | 220 } |
| 216 } | 221 } |
| 217 | 222 |
| 218 /// Invoke [target] on [receiver], bypassing ordinary dispatch semantics. | 223 /// Invoke [target] on [receiver], bypassing ordinary dispatch semantics. |
| 219 /// | 224 /// |
| 220 /// Since the [receiver] is not used for method lookup, it may be `null` | 225 /// Since the [receiver] is not used for method lookup, it may be `null` |
| 221 /// without an error being thrown. | 226 /// without an error being thrown. |
| 222 class InvokeMethodDirectly extends Expression implements Invoke { | 227 class InvokeMethodDirectly extends Expression implements Invoke { |
| 223 Expression receiver; | 228 Expression receiver; |
| 224 final Element target; | 229 final Element target; |
| 225 final Selector selector; | 230 final Selector selector; |
| 226 final List<Expression> arguments; | 231 final List<Expression> arguments; |
| 232 final SourceInformation sourceInformation; |
| 227 | 233 |
| 228 InvokeMethodDirectly(this.receiver, this.target, this.selector, | 234 InvokeMethodDirectly(this.receiver, this.target, this.selector, |
| 229 this.arguments); | 235 this.arguments, this.sourceInformation); |
| 230 | 236 |
| 231 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethodDirectly(this); | 237 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethodDirectly(this); |
| 232 accept1(ExpressionVisitor1 visitor, arg) { | 238 accept1(ExpressionVisitor1 visitor, arg) { |
| 233 return visitor.visitInvokeMethodDirectly(this, arg); | 239 return visitor.visitInvokeMethodDirectly(this, arg); |
| 234 } | 240 } |
| 235 } | 241 } |
| 236 | 242 |
| 237 /** | 243 /** |
| 238 * Call to a factory or generative constructor. | 244 * Call to a factory or generative constructor. |
| 239 */ | 245 */ |
| 240 class InvokeConstructor extends Expression implements Invoke { | 246 class InvokeConstructor extends Expression implements Invoke { |
| 241 final DartType type; | 247 final DartType type; |
| 242 final FunctionElement target; | 248 final FunctionElement target; |
| 243 final List<Expression> arguments; | 249 final List<Expression> arguments; |
| 244 final Selector selector; | 250 final Selector selector; |
| 251 final SourceInformation sourceInformation; |
| 245 /// TODO(karlklose): get rid of this field. Instead use the constant's | 252 /// TODO(karlklose): get rid of this field. Instead use the constant's |
| 246 /// expression to find the constructor to be called in dart2dart. | 253 /// expression to find the constructor to be called in dart2dart. |
| 247 final values.ConstantValue constant; | 254 final values.ConstantValue constant; |
| 248 | 255 |
| 249 InvokeConstructor(this.type, this.target, this.selector, this.arguments, | 256 InvokeConstructor(this.type, this.target, this.selector, this.arguments, |
| 250 [this.constant]); | 257 this.sourceInformation, [this.constant]); |
| 251 | 258 |
| 252 ClassElement get targetClass => target.enclosingElement; | 259 ClassElement get targetClass => target.enclosingElement; |
| 253 | 260 |
| 254 accept(ExpressionVisitor visitor) { | 261 accept(ExpressionVisitor visitor) { |
| 255 return visitor.visitInvokeConstructor(this); | 262 return visitor.visitInvokeConstructor(this); |
| 256 } | 263 } |
| 257 | 264 |
| 258 accept1(ExpressionVisitor1 visitor, arg) { | 265 accept1(ExpressionVisitor1 visitor, arg) { |
| 259 return visitor.visitInvokeConstructor(this, arg); | 266 return visitor.visitInvokeConstructor(this, arg); |
| 260 } | 267 } |
| 261 } | 268 } |
| 262 | 269 |
| 263 /** | 270 /** |
| 264 * A constant. | 271 * A constant. |
| 265 */ | 272 */ |
| 266 class Constant extends Expression { | 273 class Constant extends Expression { |
| 267 final values.ConstantValue value; | 274 final values.ConstantValue value; |
| 275 final SourceInformation sourceInformation; |
| 268 | 276 |
| 269 Constant(this.value); | 277 Constant(this.value, {this.sourceInformation}); |
| 270 | 278 |
| 271 Constant.bool(values.BoolConstantValue constantValue) | 279 Constant.bool(values.BoolConstantValue constantValue) |
| 272 : value = constantValue; | 280 : value = constantValue, |
| 281 sourceInformation = null; |
| 273 | 282 |
| 274 accept(ExpressionVisitor visitor) => visitor.visitConstant(this); | 283 accept(ExpressionVisitor visitor) => visitor.visitConstant(this); |
| 275 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitConstant(this, arg); | 284 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitConstant(this, arg); |
| 285 |
| 286 String toString() => 'Constant(value=${value.toStructuredString()})'; |
| 276 } | 287 } |
| 277 | 288 |
| 278 class This extends Expression { | 289 class This extends Expression { |
| 279 accept(ExpressionVisitor visitor) => visitor.visitThis(this); | 290 accept(ExpressionVisitor visitor) => visitor.visitThis(this); |
| 280 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitThis(this, arg); | 291 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitThis(this, arg); |
| 281 } | 292 } |
| 282 | 293 |
| 283 class LiteralList extends Expression { | 294 class LiteralList extends Expression { |
| 284 final InterfaceType type; | 295 final InterfaceType type; |
| 285 final List<Expression> values; | 296 final List<Expression> values; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 Expression condition; | 368 Expression condition; |
| 358 Expression thenExpression; | 369 Expression thenExpression; |
| 359 Expression elseExpression; | 370 Expression elseExpression; |
| 360 | 371 |
| 361 Conditional(this.condition, this.thenExpression, this.elseExpression); | 372 Conditional(this.condition, this.thenExpression, this.elseExpression); |
| 362 | 373 |
| 363 accept(ExpressionVisitor visitor) => visitor.visitConditional(this); | 374 accept(ExpressionVisitor visitor) => visitor.visitConditional(this); |
| 364 accept1(ExpressionVisitor1 visitor, arg) { | 375 accept1(ExpressionVisitor1 visitor, arg) { |
| 365 return visitor.visitConditional(this, arg); | 376 return visitor.visitConditional(this, arg); |
| 366 } | 377 } |
| 378 |
| 379 String toString() => 'Conditional(condition=$condition,thenExpression=' |
| 380 '$thenExpression,elseExpression=$elseExpression)'; |
| 367 } | 381 } |
| 368 | 382 |
| 369 /// An && or || expression. The operator is internally represented as a boolean | 383 /// An && or || expression. The operator is internally represented as a boolean |
| 370 /// [isAnd] to simplify rewriting of logical operators. | 384 /// [isAnd] to simplify rewriting of logical operators. |
| 371 class LogicalOperator extends Expression { | 385 class LogicalOperator extends Expression { |
| 372 Expression left; | 386 Expression left; |
| 373 bool isAnd; | 387 bool isAnd; |
| 374 Expression right; | 388 Expression right; |
| 375 | 389 |
| 376 LogicalOperator(this.left, this.right, this.isAnd); | 390 LogicalOperator(this.left, this.right, this.isAnd); |
| 377 LogicalOperator.and(this.left, this.right) : isAnd = true; | 391 LogicalOperator.and(this.left, this.right) : isAnd = true; |
| 378 LogicalOperator.or(this.left, this.right) : isAnd = false; | 392 LogicalOperator.or(this.left, this.right) : isAnd = false; |
| 379 | 393 |
| 380 String get operator => isAnd ? '&&' : '||'; | 394 String get operator => isAnd ? '&&' : '||'; |
| 381 | 395 |
| 382 accept(ExpressionVisitor visitor) => visitor.visitLogicalOperator(this); | 396 accept(ExpressionVisitor visitor) => visitor.visitLogicalOperator(this); |
| 383 accept1(ExpressionVisitor1 visitor, arg) { | 397 accept1(ExpressionVisitor1 visitor, arg) { |
| 384 return visitor.visitLogicalOperator(this, arg); | 398 return visitor.visitLogicalOperator(this, arg); |
| 385 } | 399 } |
| 400 |
| 401 String toString() => 'LogicalOperator(left=$left,right=$right,isAnd=$isAnd)'; |
| 386 } | 402 } |
| 387 | 403 |
| 388 /// Logical negation. | 404 /// Logical negation. |
| 389 // TODO(asgerf): Replace this class with the IsFalsy builtin operator? | 405 // TODO(asgerf): Replace this class with the IsFalsy builtin operator? |
| 390 // Right now the tree builder compiles IsFalsy to Not. | 406 // Right now the tree builder compiles IsFalsy to Not. |
| 391 class Not extends Expression { | 407 class Not extends Expression { |
| 392 Expression operand; | 408 Expression operand; |
| 393 | 409 |
| 394 Not(this.operand); | 410 Not(this.operand); |
| 395 | 411 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 * | 550 * |
| 535 * In contrast to the CPS-based IR, the return value is an arbitrary | 551 * In contrast to the CPS-based IR, the return value is an arbitrary |
| 536 * expression. | 552 * expression. |
| 537 */ | 553 */ |
| 538 class Return extends Statement { | 554 class Return extends Statement { |
| 539 /// Should not be null. Use [Constant] with [NullConstantValue] for void | 555 /// Should not be null. Use [Constant] with [NullConstantValue] for void |
| 540 /// returns. | 556 /// returns. |
| 541 /// Even in constructors this holds true. Take special care when translating | 557 /// Even in constructors this holds true. Take special care when translating |
| 542 /// back to dart, where `return null;` in a constructor is an error. | 558 /// back to dart, where `return null;` in a constructor is an error. |
| 543 Expression value; | 559 Expression value; |
| 560 SourceInformation sourceInformation; |
| 544 | 561 |
| 545 Statement get next => null; | 562 Statement get next => null; |
| 546 void set next(Statement s) => throw 'UNREACHABLE'; | 563 void set next(Statement s) => throw 'UNREACHABLE'; |
| 547 | 564 |
| 548 Return(this.value); | 565 Return(this.value, {this.sourceInformation}); |
| 549 | 566 |
| 550 accept(StatementVisitor visitor) => visitor.visitReturn(this); | 567 accept(StatementVisitor visitor) => visitor.visitReturn(this); |
| 551 accept1(StatementVisitor1 visitor, arg) => visitor.visitReturn(this, arg); | 568 accept1(StatementVisitor1 visitor, arg) => visitor.visitReturn(this, arg); |
| 552 } | 569 } |
| 553 | 570 |
| 554 /// A throw statement. | 571 /// A throw statement. |
| 555 /// | 572 /// |
| 556 /// In the Tree IR, throw is a statement (like JavaScript and unlike Dart). | 573 /// In the Tree IR, throw is a statement (like JavaScript and unlike Dart). |
| 557 /// It does not have a successor statement. | 574 /// It does not have a successor statement. |
| 558 class Throw extends Statement { | 575 class Throw extends Statement { |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 | 674 |
| 658 class CreateBox extends Expression { | 675 class CreateBox extends Expression { |
| 659 accept(ExpressionVisitor visitor) => visitor.visitCreateBox(this); | 676 accept(ExpressionVisitor visitor) => visitor.visitCreateBox(this); |
| 660 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitCreateBox(this, arg); | 677 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitCreateBox(this, arg); |
| 661 } | 678 } |
| 662 | 679 |
| 663 class CreateInstance extends Expression { | 680 class CreateInstance extends Expression { |
| 664 ClassElement classElement; | 681 ClassElement classElement; |
| 665 List<Expression> arguments; | 682 List<Expression> arguments; |
| 666 List<Expression> typeInformation; | 683 List<Expression> typeInformation; |
| 684 SourceInformation sourceInformation; |
| 667 | 685 |
| 668 CreateInstance(this.classElement, this.arguments, this.typeInformation); | 686 CreateInstance(this.classElement, this.arguments, |
| 687 this.typeInformation, this.sourceInformation); |
| 669 | 688 |
| 670 accept(ExpressionVisitor visitor) => visitor.visitCreateInstance(this); | 689 accept(ExpressionVisitor visitor) => visitor.visitCreateInstance(this); |
| 671 accept1(ExpressionVisitor1 visitor, arg) { | 690 accept1(ExpressionVisitor1 visitor, arg) { |
| 672 return visitor.visitCreateInstance(this, arg); | 691 return visitor.visitCreateInstance(this, arg); |
| 673 } | 692 } |
| 674 } | 693 } |
| 675 | 694 |
| 676 class GetField extends Expression { | 695 class GetField extends Expression { |
| 677 Expression object; | 696 Expression object; |
| 678 Element field; | 697 Element field; |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 Expression value; | 761 Expression value; |
| 743 | 762 |
| 744 SetIndex(this.object, this.index, this.value); | 763 SetIndex(this.object, this.index, this.value); |
| 745 | 764 |
| 746 accept(ExpressionVisitor v) => v.visitSetIndex(this); | 765 accept(ExpressionVisitor v) => v.visitSetIndex(this); |
| 747 accept1(ExpressionVisitor1 v, arg) => v.visitSetIndex(this, arg); | 766 accept1(ExpressionVisitor1 v, arg) => v.visitSetIndex(this, arg); |
| 748 } | 767 } |
| 749 | 768 |
| 750 class ReifyRuntimeType extends Expression { | 769 class ReifyRuntimeType extends Expression { |
| 751 Expression value; | 770 Expression value; |
| 771 SourceInformation sourceInformation; |
| 752 | 772 |
| 753 ReifyRuntimeType(this.value); | 773 ReifyRuntimeType(this.value, this.sourceInformation); |
| 754 | 774 |
| 755 accept(ExpressionVisitor visitor) { | 775 accept(ExpressionVisitor visitor) { |
| 756 return visitor.visitReifyRuntimeType(this); | 776 return visitor.visitReifyRuntimeType(this); |
| 757 } | 777 } |
| 758 | 778 |
| 759 accept1(ExpressionVisitor1 visitor, arg) { | 779 accept1(ExpressionVisitor1 visitor, arg) { |
| 760 return visitor.visitReifyRuntimeType(this, arg); | 780 return visitor.visitReifyRuntimeType(this, arg); |
| 761 } | 781 } |
| 762 } | 782 } |
| 763 | 783 |
| 764 class ReadTypeVariable extends Expression { | 784 class ReadTypeVariable extends Expression { |
| 765 final TypeVariableType variable; | 785 final TypeVariableType variable; |
| 766 Expression target; | 786 Expression target; |
| 787 final SourceInformation sourceInformation; |
| 767 | 788 |
| 768 ReadTypeVariable(this.variable, this.target); | 789 ReadTypeVariable(this.variable, this.target, this.sourceInformation); |
| 769 | 790 |
| 770 accept(ExpressionVisitor visitor) { | 791 accept(ExpressionVisitor visitor) { |
| 771 return visitor.visitReadTypeVariable(this); | 792 return visitor.visitReadTypeVariable(this); |
| 772 } | 793 } |
| 773 | 794 |
| 774 accept1(ExpressionVisitor1 visitor, arg) { | 795 accept1(ExpressionVisitor1 visitor, arg) { |
| 775 return visitor.visitReadTypeVariable(this, arg); | 796 return visitor.visitReadTypeVariable(this, arg); |
| 776 } | 797 } |
| 777 } | 798 } |
| 778 | 799 |
| (...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1431 | 1452 |
| 1432 /// Number of uses of the current fallthrough target. | 1453 /// Number of uses of the current fallthrough target. |
| 1433 int get useCount => _stack.last.useCount; | 1454 int get useCount => _stack.last.useCount; |
| 1434 | 1455 |
| 1435 /// Indicate that a statement will fall through to the current fallthrough | 1456 /// Indicate that a statement will fall through to the current fallthrough |
| 1436 /// target. | 1457 /// target. |
| 1437 void use() { | 1458 void use() { |
| 1438 ++_stack.last.useCount; | 1459 ++_stack.last.useCount; |
| 1439 } | 1460 } |
| 1440 } | 1461 } |
| OLD | NEW |