| 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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 Expression value; | 143 Expression value; |
| 144 SourceInformation sourceInformation; | 144 SourceInformation sourceInformation; |
| 145 | 145 |
| 146 Assign(this.variable, this.value, {this.sourceInformation}) { | 146 Assign(this.variable, this.value, {this.sourceInformation}) { |
| 147 variable.writeCount++; | 147 variable.writeCount++; |
| 148 } | 148 } |
| 149 | 149 |
| 150 accept(ExpressionVisitor v) => v.visitAssign(this); | 150 accept(ExpressionVisitor v) => v.visitAssign(this); |
| 151 accept1(ExpressionVisitor1 v, arg) => v.visitAssign(this, arg); | 151 accept1(ExpressionVisitor1 v, arg) => v.visitAssign(this, arg); |
| 152 | 152 |
| 153 static ExpressionStatement makeStatement(Variable variable, | 153 static ExpressionStatement makeStatement(Variable variable, Expression value, |
| 154 Expression value, | 154 [Statement next]) { |
| 155 [Statement next]) { | |
| 156 return new ExpressionStatement(new Assign(variable, value), next); | 155 return new ExpressionStatement(new Assign(variable, value), next); |
| 157 } | 156 } |
| 158 } | 157 } |
| 159 | 158 |
| 160 /** | 159 /** |
| 161 * Common interface for invocations with arguments. | 160 * Common interface for invocations with arguments. |
| 162 */ | 161 */ |
| 163 abstract class Invoke { | 162 abstract class Invoke { |
| 164 List<Expression> get arguments; | 163 List<Expression> get arguments; |
| 165 } | 164 } |
| 166 | 165 |
| 167 /** | 166 /** |
| 168 * A call to a static function or getter/setter to a static field. | 167 * A call to a static function or getter/setter to a static field. |
| 169 * | 168 * |
| 170 * In contrast to the CPS-based IR, the arguments can be arbitrary expressions. | 169 * In contrast to the CPS-based IR, the arguments can be arbitrary expressions. |
| 171 */ | 170 */ |
| 172 class InvokeStatic extends Expression implements Invoke { | 171 class InvokeStatic extends Expression implements Invoke { |
| 173 final Entity target; | 172 final Entity target; |
| 174 final List<Expression> arguments; | 173 final List<Expression> arguments; |
| 175 final Selector selector; | 174 final Selector selector; |
| 176 final SourceInformation sourceInformation; | 175 final SourceInformation sourceInformation; |
| 177 | 176 |
| 178 InvokeStatic(this.target, this.selector, this.arguments, | 177 InvokeStatic(this.target, this.selector, this.arguments, |
| 179 [this.sourceInformation]); | 178 [this.sourceInformation]); |
| 180 | 179 |
| 181 accept(ExpressionVisitor visitor) => visitor.visitInvokeStatic(this); | 180 accept(ExpressionVisitor visitor) => visitor.visitInvokeStatic(this); |
| 182 accept1(ExpressionVisitor1 visitor, arg) { | 181 accept1(ExpressionVisitor1 visitor, arg) { |
| 183 return visitor.visitInvokeStatic(this, arg); | 182 return visitor.visitInvokeStatic(this, arg); |
| 184 } | 183 } |
| 185 } | 184 } |
| 186 | 185 |
| 187 /** | 186 /** |
| 188 * A call to a method, operator, getter, setter or index getter/setter. | 187 * A call to a method, operator, getter, setter or index getter/setter. |
| 189 * | 188 * |
| 190 * If [receiver] is `null`, an error is thrown before the arguments are | 189 * If [receiver] is `null`, an error is thrown before the arguments are |
| 191 * evaluated. This corresponds to the JS evaluation order. | 190 * evaluated. This corresponds to the JS evaluation order. |
| 192 */ | 191 */ |
| 193 class InvokeMethod extends Expression implements Invoke { | 192 class InvokeMethod extends Expression implements Invoke { |
| 194 Expression receiver; | 193 Expression receiver; |
| 195 final Selector selector; | 194 final Selector selector; |
| 196 final TypeMask mask; | 195 final TypeMask mask; |
| 197 final List<Expression> arguments; | 196 final List<Expression> arguments; |
| 198 final SourceInformation sourceInformation; | 197 final SourceInformation sourceInformation; |
| 199 | 198 |
| 200 /// If true, it is known that the receiver cannot be `null`. | 199 /// If true, it is known that the receiver cannot be `null`. |
| 201 bool receiverIsNotNull = false; | 200 bool receiverIsNotNull = false; |
| 202 | 201 |
| 203 InvokeMethod(this.receiver, | 202 InvokeMethod(this.receiver, this.selector, this.mask, this.arguments, |
| 204 this.selector, | 203 this.sourceInformation) { |
| 205 this.mask, | |
| 206 this.arguments, | |
| 207 this.sourceInformation) { | |
| 208 assert(receiver != null); | 204 assert(receiver != null); |
| 209 } | 205 } |
| 210 | 206 |
| 211 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this); | 207 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this); |
| 212 accept1(ExpressionVisitor1 visitor, arg) { | 208 accept1(ExpressionVisitor1 visitor, arg) { |
| 213 return visitor.visitInvokeMethod(this, arg); | 209 return visitor.visitInvokeMethod(this, arg); |
| 214 } | 210 } |
| 215 } | 211 } |
| 216 | 212 |
| 217 /// Invoke [target] on [receiver], bypassing ordinary dispatch semantics. | 213 /// Invoke [target] on [receiver], bypassing ordinary dispatch semantics. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 238 | 234 |
| 239 /** | 235 /** |
| 240 * Call to a factory or generative constructor. | 236 * Call to a factory or generative constructor. |
| 241 */ | 237 */ |
| 242 class InvokeConstructor extends Expression implements Invoke { | 238 class InvokeConstructor extends Expression implements Invoke { |
| 243 final DartType type; | 239 final DartType type; |
| 244 final FunctionElement target; | 240 final FunctionElement target; |
| 245 final List<Expression> arguments; | 241 final List<Expression> arguments; |
| 246 final Selector selector; | 242 final Selector selector; |
| 247 final SourceInformation sourceInformation; | 243 final SourceInformation sourceInformation; |
| 244 |
| 248 /// TODO(karlklose): get rid of this field. Instead use the constant's | 245 /// TODO(karlklose): get rid of this field. Instead use the constant's |
| 249 /// expression to find the constructor to be called in dart2dart. | 246 /// expression to find the constructor to be called in dart2dart. |
| 250 final values.ConstantValue constant; | 247 final values.ConstantValue constant; |
| 251 | 248 |
| 252 InvokeConstructor(this.type, this.target, this.selector, this.arguments, | 249 InvokeConstructor(this.type, this.target, this.selector, this.arguments, |
| 253 this.sourceInformation, [this.constant]); | 250 this.sourceInformation, |
| 251 [this.constant]); |
| 254 | 252 |
| 255 ClassElement get targetClass => target.enclosingElement; | 253 ClassElement get targetClass => target.enclosingElement; |
| 256 | 254 |
| 257 accept(ExpressionVisitor visitor) { | 255 accept(ExpressionVisitor visitor) { |
| 258 return visitor.visitInvokeConstructor(this); | 256 return visitor.visitInvokeConstructor(this); |
| 259 } | 257 } |
| 260 | 258 |
| 261 accept1(ExpressionVisitor1 visitor, arg) { | 259 accept1(ExpressionVisitor1 visitor, arg) { |
| 262 return visitor.visitInvokeConstructor(this, arg); | 260 return visitor.visitInvokeConstructor(this, arg); |
| 263 } | 261 } |
| 264 } | 262 } |
| 265 | 263 |
| 266 /// Call a method using a one-shot interceptor. | 264 /// Call a method using a one-shot interceptor. |
| 267 /// | 265 /// |
| 268 /// There is no explicit receiver, the first argument serves that purpose. | 266 /// There is no explicit receiver, the first argument serves that purpose. |
| 269 class OneShotInterceptor extends Expression implements Invoke { | 267 class OneShotInterceptor extends Expression implements Invoke { |
| 270 final Selector selector; | 268 final Selector selector; |
| 271 final TypeMask mask; | 269 final TypeMask mask; |
| 272 final List<Expression> arguments; | 270 final List<Expression> arguments; |
| 273 final SourceInformation sourceInformation; | 271 final SourceInformation sourceInformation; |
| 274 | 272 |
| 275 OneShotInterceptor(this.selector, | 273 OneShotInterceptor( |
| 276 this.mask, | 274 this.selector, this.mask, this.arguments, this.sourceInformation); |
| 277 this.arguments, | |
| 278 this.sourceInformation); | |
| 279 | 275 |
| 280 accept(ExpressionVisitor visitor) => visitor.visitOneShotInterceptor(this); | 276 accept(ExpressionVisitor visitor) => visitor.visitOneShotInterceptor(this); |
| 281 accept1(ExpressionVisitor1 visitor, arg) { | 277 accept1(ExpressionVisitor1 visitor, arg) { |
| 282 return visitor.visitOneShotInterceptor(this, arg); | 278 return visitor.visitOneShotInterceptor(this, arg); |
| 283 } | 279 } |
| 284 } | 280 } |
| 285 | 281 |
| 286 /** | 282 /** |
| 287 * A constant. | 283 * A constant. |
| 288 */ | 284 */ |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 /// | 319 /// |
| 324 /// Note that if this is a type test, then [type] cannot be `Object`, `dynamic`, | 320 /// Note that if this is a type test, then [type] cannot be `Object`, `dynamic`, |
| 325 /// or the `Null` type. These cases are compiled to other node types. | 321 /// or the `Null` type. These cases are compiled to other node types. |
| 326 class TypeOperator extends Expression { | 322 class TypeOperator extends Expression { |
| 327 Expression value; | 323 Expression value; |
| 328 final DartType type; | 324 final DartType type; |
| 329 final List<Expression> typeArguments; | 325 final List<Expression> typeArguments; |
| 330 final bool isTypeTest; | 326 final bool isTypeTest; |
| 331 | 327 |
| 332 TypeOperator(this.value, this.type, this.typeArguments, | 328 TypeOperator(this.value, this.type, this.typeArguments, |
| 333 {bool this.isTypeTest}); | 329 {bool this.isTypeTest}); |
| 334 | 330 |
| 335 accept(ExpressionVisitor visitor) => visitor.visitTypeOperator(this); | 331 accept(ExpressionVisitor visitor) => visitor.visitTypeOperator(this); |
| 336 accept1(ExpressionVisitor1 visitor, arg) { | 332 accept1(ExpressionVisitor1 visitor, arg) { |
| 337 return visitor.visitTypeOperator(this, arg); | 333 return visitor.visitTypeOperator(this, arg); |
| 338 } | 334 } |
| 339 | 335 |
| 340 String get operator => isTypeTest ? 'is' : 'as'; | 336 String get operator => isTypeTest ? 'is' : 'as'; |
| 341 } | 337 } |
| 342 | 338 |
| 343 /** | 339 /** |
| 344 * Apply a built-in operator. | 340 * Apply a built-in operator. |
| 345 * | 341 * |
| 346 * It must be known that the arguments have the proper types. | 342 * It must be known that the arguments have the proper types. |
| 347 * Null is not a valid argument to any of the built-in operators. | 343 * Null is not a valid argument to any of the built-in operators. |
| 348 */ | 344 */ |
| 349 class ApplyBuiltinOperator extends Expression { | 345 class ApplyBuiltinOperator extends Expression { |
| 350 BuiltinOperator operator; | 346 BuiltinOperator operator; |
| 351 List<Expression> arguments; | 347 List<Expression> arguments; |
| 352 SourceInformation sourceInformation; | 348 SourceInformation sourceInformation; |
| 353 | 349 |
| 354 ApplyBuiltinOperator(this.operator, this.arguments, this.sourceInformation); | 350 ApplyBuiltinOperator(this.operator, this.arguments, this.sourceInformation); |
| 355 | 351 |
| 356 accept(ExpressionVisitor visitor) { | 352 accept(ExpressionVisitor visitor) { |
| 357 return visitor.visitApplyBuiltinOperator(this); | 353 return visitor.visitApplyBuiltinOperator(this); |
| 358 } | 354 } |
| 355 |
| 359 accept1(ExpressionVisitor1 visitor, arg) { | 356 accept1(ExpressionVisitor1 visitor, arg) { |
| 360 return visitor.visitApplyBuiltinOperator(this, arg); | 357 return visitor.visitApplyBuiltinOperator(this, arg); |
| 361 } | 358 } |
| 362 } | 359 } |
| 363 | 360 |
| 364 class ApplyBuiltinMethod extends Expression { | 361 class ApplyBuiltinMethod extends Expression { |
| 365 BuiltinMethod method; | 362 BuiltinMethod method; |
| 366 Expression receiver; | 363 Expression receiver; |
| 367 List<Expression> arguments; | 364 List<Expression> arguments; |
| 368 | 365 |
| 369 bool receiverIsNotNull; | 366 bool receiverIsNotNull; |
| 370 | 367 |
| 371 ApplyBuiltinMethod(this.method, | 368 ApplyBuiltinMethod(this.method, this.receiver, this.arguments, |
| 372 this.receiver, | 369 {this.receiverIsNotNull: false}); |
| 373 this.arguments, | |
| 374 {this.receiverIsNotNull: false}); | |
| 375 | 370 |
| 376 accept(ExpressionVisitor visitor) { | 371 accept(ExpressionVisitor visitor) { |
| 377 return visitor.visitApplyBuiltinMethod(this); | 372 return visitor.visitApplyBuiltinMethod(this); |
| 378 } | 373 } |
| 374 |
| 379 accept1(ExpressionVisitor1 visitor, arg) { | 375 accept1(ExpressionVisitor1 visitor, arg) { |
| 380 return visitor.visitApplyBuiltinMethod(this, arg); | 376 return visitor.visitApplyBuiltinMethod(this, arg); |
| 381 } | 377 } |
| 382 } | 378 } |
| 383 | 379 |
| 384 /// A conditional expression. | 380 /// A conditional expression. |
| 385 class Conditional extends Expression { | 381 class Conditional extends Expression { |
| 386 Expression condition; | 382 Expression condition; |
| 387 Expression thenExpression; | 383 Expression thenExpression; |
| 388 Expression elseExpression; | 384 Expression elseExpression; |
| 389 | 385 |
| 390 Conditional(this.condition, this.thenExpression, this.elseExpression); | 386 Conditional(this.condition, this.thenExpression, this.elseExpression); |
| 391 | 387 |
| 392 accept(ExpressionVisitor visitor) => visitor.visitConditional(this); | 388 accept(ExpressionVisitor visitor) => visitor.visitConditional(this); |
| 393 accept1(ExpressionVisitor1 visitor, arg) { | 389 accept1(ExpressionVisitor1 visitor, arg) { |
| 394 return visitor.visitConditional(this, arg); | 390 return visitor.visitConditional(this, arg); |
| 395 } | 391 } |
| 396 | 392 |
| 397 String toString() => 'Conditional(condition=$condition,thenExpression=' | 393 String toString() => 'Conditional(condition=$condition,thenExpression=' |
| 398 '$thenExpression,elseExpression=$elseExpression)'; | 394 '$thenExpression,elseExpression=$elseExpression)'; |
| 399 } | 395 } |
| 400 | 396 |
| 401 /// An && or || expression. The operator is internally represented as a boolean | 397 /// An && or || expression. The operator is internally represented as a boolean |
| 402 /// [isAnd] to simplify rewriting of logical operators. | 398 /// [isAnd] to simplify rewriting of logical operators. |
| 403 /// Note the the result of && and || is one of the arguments, which might not be | 399 /// Note the the result of && and || is one of the arguments, which might not be |
| 404 /// boolean. 'ShortCircuitOperator' might have been a better name. | 400 /// boolean. 'ShortCircuitOperator' might have been a better name. |
| 405 class LogicalOperator extends Expression { | 401 class LogicalOperator extends Expression { |
| 406 Expression left; | 402 Expression left; |
| 407 bool isAnd; | 403 bool isAnd; |
| 408 Expression right; | 404 Expression right; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 label.binding = this; | 449 label.binding = this; |
| 454 } | 450 } |
| 455 | 451 |
| 456 accept(StatementVisitor visitor) => visitor.visitLabeledStatement(this); | 452 accept(StatementVisitor visitor) => visitor.visitLabeledStatement(this); |
| 457 accept1(StatementVisitor1 visitor, arg) { | 453 accept1(StatementVisitor1 visitor, arg) { |
| 458 return visitor.visitLabeledStatement(this, arg); | 454 return visitor.visitLabeledStatement(this, arg); |
| 459 } | 455 } |
| 460 } | 456 } |
| 461 | 457 |
| 462 /// A [WhileTrue] or [For] loop. | 458 /// A [WhileTrue] or [For] loop. |
| 463 abstract class Loop extends JumpTarget { | 459 abstract class Loop extends JumpTarget {} |
| 464 } | |
| 465 | 460 |
| 466 /** | 461 /** |
| 467 * A labeled while(true) loop. | 462 * A labeled while(true) loop. |
| 468 */ | 463 */ |
| 469 class WhileTrue extends Loop { | 464 class WhileTrue extends Loop { |
| 470 final Label label; | 465 final Label label; |
| 471 Statement body; | 466 Statement body; |
| 472 | 467 |
| 473 WhileTrue(this.label, this.body) { | 468 WhileTrue(this.label, this.body) { |
| 474 assert(label.binding == null); | 469 assert(label.binding == null); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 494 * [For] statements are introduced in the [LoopRewriter] and are | 489 * [For] statements are introduced in the [LoopRewriter] and are |
| 495 * assumed not to occur before then. | 490 * assumed not to occur before then. |
| 496 */ | 491 */ |
| 497 class For extends Loop { | 492 class For extends Loop { |
| 498 final Label label; | 493 final Label label; |
| 499 Expression condition; | 494 Expression condition; |
| 500 List<Expression> updates; | 495 List<Expression> updates; |
| 501 Statement body; | 496 Statement body; |
| 502 Statement next; | 497 Statement next; |
| 503 | 498 |
| 504 For(this.label, | 499 For(this.label, this.condition, this.updates, this.body, this.next) { |
| 505 this.condition, | |
| 506 this.updates, | |
| 507 this.body, | |
| 508 this.next) { | |
| 509 assert(label.binding == null); | 500 assert(label.binding == null); |
| 510 label.binding = this; | 501 label.binding = this; |
| 511 } | 502 } |
| 512 | 503 |
| 513 accept(StatementVisitor visitor) => visitor.visitFor(this); | 504 accept(StatementVisitor visitor) => visitor.visitFor(this); |
| 514 accept1(StatementVisitor1 visitor, arg) { | 505 accept1(StatementVisitor1 visitor, arg) { |
| 515 return visitor.visitFor(this, arg); | 506 return visitor.visitFor(this, arg); |
| 516 } | 507 } |
| 517 } | 508 } |
| 518 | 509 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 */ | 592 */ |
| 602 class If extends Statement { | 593 class If extends Statement { |
| 603 Expression condition; | 594 Expression condition; |
| 604 Statement thenStatement; | 595 Statement thenStatement; |
| 605 Statement elseStatement; | 596 Statement elseStatement; |
| 606 SourceInformation sourceInformation; | 597 SourceInformation sourceInformation; |
| 607 | 598 |
| 608 Statement get next => null; | 599 Statement get next => null; |
| 609 void set next(Statement s) => throw 'UNREACHABLE'; | 600 void set next(Statement s) => throw 'UNREACHABLE'; |
| 610 | 601 |
| 611 If(this.condition, | 602 If(this.condition, this.thenStatement, this.elseStatement, |
| 612 this.thenStatement, | 603 this.sourceInformation); |
| 613 this.elseStatement, | |
| 614 this.sourceInformation); | |
| 615 | 604 |
| 616 accept(StatementVisitor visitor) => visitor.visitIf(this); | 605 accept(StatementVisitor visitor) => visitor.visitIf(this); |
| 617 accept1(StatementVisitor1 visitor, arg) => visitor.visitIf(this, arg); | 606 accept1(StatementVisitor1 visitor, arg) => visitor.visitIf(this, arg); |
| 618 } | 607 } |
| 619 | 608 |
| 620 class ExpressionStatement extends Statement { | 609 class ExpressionStatement extends Statement { |
| 621 Statement next; | 610 Statement next; |
| 622 Expression expression; | 611 Expression expression; |
| 623 | 612 |
| 624 ExpressionStatement(this.expression, this.next); | 613 ExpressionStatement(this.expression, this.next); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 } | 649 } |
| 661 } | 650 } |
| 662 | 651 |
| 663 class FunctionDefinition extends Node { | 652 class FunctionDefinition extends Node { |
| 664 final ExecutableElement element; | 653 final ExecutableElement element; |
| 665 final List<Variable> parameters; | 654 final List<Variable> parameters; |
| 666 final SourceInformation sourceInformation; | 655 final SourceInformation sourceInformation; |
| 667 Statement body; | 656 Statement body; |
| 668 | 657 |
| 669 /// Creates a function definition and updates `writeCount` for [parameters]. | 658 /// Creates a function definition and updates `writeCount` for [parameters]. |
| 670 FunctionDefinition( | 659 FunctionDefinition(this.element, this.parameters, this.body, |
| 671 this.element, | |
| 672 this.parameters, | |
| 673 this.body, | |
| 674 {this.sourceInformation}) { | 660 {this.sourceInformation}) { |
| 675 for (Variable param in parameters) { | 661 for (Variable param in parameters) { |
| 676 param.writeCount++; // Being a parameter counts as a write. | 662 param.writeCount++; // Being a parameter counts as a write. |
| 677 } | 663 } |
| 678 } | 664 } |
| 679 } | 665 } |
| 680 | 666 |
| 681 class CreateBox extends Expression { | 667 class CreateBox extends Expression { |
| 682 accept(ExpressionVisitor visitor) => visitor.visitCreateBox(this); | 668 accept(ExpressionVisitor visitor) => visitor.visitCreateBox(this); |
| 683 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitCreateBox(this, arg); | 669 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitCreateBox(this, arg); |
| 684 } | 670 } |
| 685 | 671 |
| 686 class CreateInstance extends Expression { | 672 class CreateInstance extends Expression { |
| 687 ClassElement classElement; | 673 ClassElement classElement; |
| 688 List<Expression> arguments; | 674 List<Expression> arguments; |
| 689 Expression typeInformation; | 675 Expression typeInformation; |
| 690 SourceInformation sourceInformation; | 676 SourceInformation sourceInformation; |
| 691 | 677 |
| 692 CreateInstance(this.classElement, this.arguments, | 678 CreateInstance(this.classElement, this.arguments, this.typeInformation, |
| 693 this.typeInformation, this.sourceInformation); | 679 this.sourceInformation); |
| 694 | 680 |
| 695 accept(ExpressionVisitor visitor) => visitor.visitCreateInstance(this); | 681 accept(ExpressionVisitor visitor) => visitor.visitCreateInstance(this); |
| 696 accept1(ExpressionVisitor1 visitor, arg) { | 682 accept1(ExpressionVisitor1 visitor, arg) { |
| 697 return visitor.visitCreateInstance(this, arg); | 683 return visitor.visitCreateInstance(this, arg); |
| 698 } | 684 } |
| 699 } | 685 } |
| 700 | 686 |
| 701 class GetField extends Expression { | 687 class GetField extends Expression { |
| 702 Expression object; | 688 Expression object; |
| 703 Element field; | 689 Element field; |
| 704 bool objectIsNotNull; | 690 bool objectIsNotNull; |
| 705 SourceInformation sourceInformation; | 691 SourceInformation sourceInformation; |
| 706 | 692 |
| 707 GetField( | 693 GetField(this.object, this.field, this.sourceInformation, |
| 708 this.object, | |
| 709 this.field, | |
| 710 this.sourceInformation, | |
| 711 {this.objectIsNotNull: false}); | 694 {this.objectIsNotNull: false}); |
| 712 | 695 |
| 713 accept(ExpressionVisitor visitor) => visitor.visitGetField(this); | 696 accept(ExpressionVisitor visitor) => visitor.visitGetField(this); |
| 714 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitGetField(this, arg); | 697 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitGetField(this, arg); |
| 715 } | 698 } |
| 716 | 699 |
| 717 class SetField extends Expression { | 700 class SetField extends Expression { |
| 718 Expression object; | 701 Expression object; |
| 719 Element field; | 702 Element field; |
| 720 Expression value; | 703 Expression value; |
| 721 SourceInformation sourceInformation; | 704 SourceInformation sourceInformation; |
| 722 | 705 |
| 723 /// If non-null, this is a compound assignment to the field, using the given | 706 /// If non-null, this is a compound assignment to the field, using the given |
| 724 /// operator. The operator must be a compoundable operator. | 707 /// operator. The operator must be a compoundable operator. |
| 725 BuiltinOperator compound; | 708 BuiltinOperator compound; |
| 726 | 709 |
| 727 SetField( | 710 SetField(this.object, this.field, this.value, this.sourceInformation, |
| 728 this.object, | |
| 729 this.field, | |
| 730 this.value, | |
| 731 this.sourceInformation, | |
| 732 {this.compound}); | 711 {this.compound}); |
| 733 | 712 |
| 734 accept(ExpressionVisitor visitor) => visitor.visitSetField(this); | 713 accept(ExpressionVisitor visitor) => visitor.visitSetField(this); |
| 735 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitSetField(this, arg); | 714 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitSetField(this, arg); |
| 736 } | 715 } |
| 737 | 716 |
| 738 | |
| 739 /// Read the type test property from [object]. The value is truthy/fasly rather | 717 /// Read the type test property from [object]. The value is truthy/fasly rather |
| 740 /// than bool. [object] must not be `null`. | 718 /// than bool. [object] must not be `null`. |
| 741 class GetTypeTestProperty extends Expression { | 719 class GetTypeTestProperty extends Expression { |
| 742 Expression object; | 720 Expression object; |
| 743 DartType dartType; | 721 DartType dartType; |
| 744 | 722 |
| 745 GetTypeTestProperty(this.object, this.dartType); | 723 GetTypeTestProperty(this.object, this.dartType); |
| 746 | 724 |
| 747 accept(ExpressionVisitor visitor) => | 725 accept(ExpressionVisitor visitor) => visitor.visitGetTypeTestProperty(this); |
| 748 visitor.visitGetTypeTestProperty(this); | |
| 749 accept1(ExpressionVisitor1 visitor, arg) => | 726 accept1(ExpressionVisitor1 visitor, arg) => |
| 750 visitor.visitGetTypeTestProperty(this, arg); | 727 visitor.visitGetTypeTestProperty(this, arg); |
| 751 } | 728 } |
| 752 | 729 |
| 753 /// Read the value of a field, possibly provoking its initializer to evaluate, | 730 /// Read the value of a field, possibly provoking its initializer to evaluate, |
| 754 /// or tear off a static method. | 731 /// or tear off a static method. |
| 755 class GetStatic extends Expression { | 732 class GetStatic extends Expression { |
| 756 Element element; | 733 Element element; |
| 757 SourceInformation sourceInformation; | 734 SourceInformation sourceInformation; |
| 758 bool useLazyGetter = false; | 735 bool useLazyGetter = false; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 accept1(ExpressionVisitor1 visitor, arg) { | 845 accept1(ExpressionVisitor1 visitor, arg) { |
| 869 return visitor.visitInterceptor(this, arg); | 846 return visitor.visitInterceptor(this, arg); |
| 870 } | 847 } |
| 871 } | 848 } |
| 872 | 849 |
| 873 class ForeignCode extends Node { | 850 class ForeignCode extends Node { |
| 874 final js.Template codeTemplate; | 851 final js.Template codeTemplate; |
| 875 final types.TypeMask type; | 852 final types.TypeMask type; |
| 876 final List<Expression> arguments; | 853 final List<Expression> arguments; |
| 877 final native.NativeBehavior nativeBehavior; | 854 final native.NativeBehavior nativeBehavior; |
| 878 final List<bool> nullableArguments; // One 'bit' per argument. | 855 final List<bool> nullableArguments; // One 'bit' per argument. |
| 879 final Element dependency; | 856 final Element dependency; |
| 880 final SourceInformation sourceInformation; | 857 final SourceInformation sourceInformation; |
| 881 | 858 |
| 882 ForeignCode( | 859 ForeignCode(this.codeTemplate, this.type, this.arguments, this.nativeBehavior, |
| 883 this.codeTemplate, | 860 this.nullableArguments, this.dependency, this.sourceInformation) { |
| 884 this.type, | |
| 885 this.arguments, | |
| 886 this.nativeBehavior, | |
| 887 this.nullableArguments, | |
| 888 this.dependency, | |
| 889 this.sourceInformation) { | |
| 890 assert(arguments.length == nullableArguments.length); | 861 assert(arguments.length == nullableArguments.length); |
| 891 } | 862 } |
| 892 } | 863 } |
| 893 | 864 |
| 894 class ForeignExpression extends ForeignCode implements Expression { | 865 class ForeignExpression extends ForeignCode implements Expression { |
| 895 ForeignExpression( | 866 ForeignExpression( |
| 896 js.Template codeTemplate, types.TypeMask type, | 867 js.Template codeTemplate, |
| 897 List<Expression> arguments, native.NativeBehavior nativeBehavior, | 868 types.TypeMask type, |
| 869 List<Expression> arguments, |
| 870 native.NativeBehavior nativeBehavior, |
| 898 List<bool> nullableArguments, | 871 List<bool> nullableArguments, |
| 899 Element dependency, | 872 Element dependency, |
| 900 SourceInformation sourceInformation) | 873 SourceInformation sourceInformation) |
| 901 : super(codeTemplate, type, arguments, nativeBehavior, nullableArguments, | 874 : super(codeTemplate, type, arguments, nativeBehavior, nullableArguments, |
| 902 dependency, sourceInformation); | 875 dependency, sourceInformation); |
| 903 | 876 |
| 904 accept(ExpressionVisitor visitor) { | 877 accept(ExpressionVisitor visitor) { |
| 905 return visitor.visitForeignExpression(this); | 878 return visitor.visitForeignExpression(this); |
| 906 } | 879 } |
| 907 | 880 |
| 908 accept1(ExpressionVisitor1 visitor, arg) { | 881 accept1(ExpressionVisitor1 visitor, arg) { |
| 909 return visitor.visitForeignExpression(this, arg); | 882 return visitor.visitForeignExpression(this, arg); |
| 910 } | 883 } |
| 911 } | 884 } |
| 912 | 885 |
| 913 class ForeignStatement extends ForeignCode implements Statement { | 886 class ForeignStatement extends ForeignCode implements Statement { |
| 914 ForeignStatement( | 887 ForeignStatement( |
| 915 js.Template codeTemplate, types.TypeMask type, | 888 js.Template codeTemplate, |
| 916 List<Expression> arguments, native.NativeBehavior nativeBehavior, | 889 types.TypeMask type, |
| 890 List<Expression> arguments, |
| 891 native.NativeBehavior nativeBehavior, |
| 917 List<bool> nullableArguments, | 892 List<bool> nullableArguments, |
| 918 Element dependency, | 893 Element dependency, |
| 919 SourceInformation sourceInformation) | 894 SourceInformation sourceInformation) |
| 920 : super(codeTemplate, type, arguments, nativeBehavior, nullableArguments, | 895 : super(codeTemplate, type, arguments, nativeBehavior, nullableArguments, |
| 921 dependency, sourceInformation); | 896 dependency, sourceInformation); |
| 922 | 897 |
| 923 accept(StatementVisitor visitor) { | 898 accept(StatementVisitor visitor) { |
| 924 return visitor.visitForeignStatement(this); | 899 return visitor.visitForeignStatement(this); |
| 925 } | 900 } |
| 926 | 901 |
| 927 accept1(StatementVisitor1 visitor, arg) { | 902 accept1(StatementVisitor1 visitor, arg) { |
| 928 return visitor.visitForeignStatement(this, arg); | 903 return visitor.visitForeignStatement(this, arg); |
| 929 } | 904 } |
| 930 | 905 |
| 931 @override | 906 @override |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 986 | 961 |
| 987 class ReceiverCheck extends Statement { | 962 class ReceiverCheck extends Statement { |
| 988 Expression condition; | 963 Expression condition; |
| 989 Expression value; | 964 Expression value; |
| 990 Selector selector; | 965 Selector selector; |
| 991 bool useSelector; | 966 bool useSelector; |
| 992 bool useInvoke; | 967 bool useInvoke; |
| 993 Statement next; | 968 Statement next; |
| 994 SourceInformation sourceInformation; | 969 SourceInformation sourceInformation; |
| 995 | 970 |
| 996 ReceiverCheck({this.condition, this.value, this.selector, this.useSelector, | 971 ReceiverCheck( |
| 997 this.useInvoke, this.next, this.sourceInformation}); | 972 {this.condition, |
| 973 this.value, |
| 974 this.selector, |
| 975 this.useSelector, |
| 976 this.useInvoke, |
| 977 this.next, |
| 978 this.sourceInformation}); |
| 998 | 979 |
| 999 accept(StatementVisitor visitor) { | 980 accept(StatementVisitor visitor) { |
| 1000 return visitor.visitReceiverCheck(this); | 981 return visitor.visitReceiverCheck(this); |
| 1001 } | 982 } |
| 1002 | 983 |
| 1003 accept1(StatementVisitor1 visitor, arg) { | 984 accept1(StatementVisitor1 visitor, arg) { |
| 1004 return visitor.visitReceiverCheck(this, arg); | 985 return visitor.visitReceiverCheck(this, arg); |
| 1005 } | 986 } |
| 1006 } | 987 } |
| 1007 | 988 |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1232 | 1213 |
| 1233 visitGetField(GetField node) { | 1214 visitGetField(GetField node) { |
| 1234 visitExpression(node.object); | 1215 visitExpression(node.object); |
| 1235 } | 1216 } |
| 1236 | 1217 |
| 1237 visitSetField(SetField node) { | 1218 visitSetField(SetField node) { |
| 1238 visitExpression(node.object); | 1219 visitExpression(node.object); |
| 1239 visitExpression(node.value); | 1220 visitExpression(node.value); |
| 1240 } | 1221 } |
| 1241 | 1222 |
| 1242 visitGetStatic(GetStatic node) { | 1223 visitGetStatic(GetStatic node) {} |
| 1243 } | |
| 1244 | 1224 |
| 1245 visitSetStatic(SetStatic node) { | 1225 visitSetStatic(SetStatic node) { |
| 1246 visitExpression(node.value); | 1226 visitExpression(node.value); |
| 1247 } | 1227 } |
| 1248 | 1228 |
| 1249 visitGetTypeTestProperty(GetTypeTestProperty node) { | 1229 visitGetTypeTestProperty(GetTypeTestProperty node) { |
| 1250 visitExpression(node.object); | 1230 visitExpression(node.object); |
| 1251 } | 1231 } |
| 1252 | 1232 |
| 1253 visitCreateBox(CreateBox node) { | 1233 visitCreateBox(CreateBox node) {} |
| 1254 } | |
| 1255 | 1234 |
| 1256 visitCreateInstance(CreateInstance node) { | 1235 visitCreateInstance(CreateInstance node) { |
| 1257 node.arguments.forEach(visitExpression); | 1236 node.arguments.forEach(visitExpression); |
| 1258 if (node.typeInformation != null) visitExpression(node.typeInformation); | 1237 if (node.typeInformation != null) visitExpression(node.typeInformation); |
| 1259 } | 1238 } |
| 1260 | 1239 |
| 1261 visitReifyRuntimeType(ReifyRuntimeType node) { | 1240 visitReifyRuntimeType(ReifyRuntimeType node) { |
| 1262 visitExpression(node.value); | 1241 visitExpression(node.value); |
| 1263 } | 1242 } |
| 1264 | 1243 |
| 1265 visitReadTypeVariable(ReadTypeVariable node) { | 1244 visitReadTypeVariable(ReadTypeVariable node) { |
| 1266 visitExpression(node.target); | 1245 visitExpression(node.target); |
| 1267 } | 1246 } |
| 1268 | 1247 |
| 1269 visitTypeExpression(TypeExpression node) { | 1248 visitTypeExpression(TypeExpression node) { |
| 1270 node.arguments.forEach(visitExpression); | 1249 node.arguments.forEach(visitExpression); |
| 1271 } | 1250 } |
| 1272 | 1251 |
| 1273 visitCreateInvocationMirror(CreateInvocationMirror node) { | 1252 visitCreateInvocationMirror(CreateInvocationMirror node) { |
| 1274 node.arguments.forEach(visitExpression); | 1253 node.arguments.forEach(visitExpression); |
| 1275 } | 1254 } |
| 1276 | 1255 |
| 1277 visitUnreachable(Unreachable node) { | 1256 visitUnreachable(Unreachable node) {} |
| 1278 } | |
| 1279 | 1257 |
| 1280 visitApplyBuiltinOperator(ApplyBuiltinOperator node) { | 1258 visitApplyBuiltinOperator(ApplyBuiltinOperator node) { |
| 1281 node.arguments.forEach(visitExpression); | 1259 node.arguments.forEach(visitExpression); |
| 1282 } | 1260 } |
| 1283 | 1261 |
| 1284 visitApplyBuiltinMethod(ApplyBuiltinMethod node) { | 1262 visitApplyBuiltinMethod(ApplyBuiltinMethod node) { |
| 1285 visitExpression(node.receiver); | 1263 visitExpression(node.receiver); |
| 1286 node.arguments.forEach(visitExpression); | 1264 node.arguments.forEach(visitExpression); |
| 1287 } | 1265 } |
| 1288 | 1266 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1321 visitStatement(node.next); | 1299 visitStatement(node.next); |
| 1322 } | 1300 } |
| 1323 | 1301 |
| 1324 visitReceiverCheck(ReceiverCheck node) { | 1302 visitReceiverCheck(ReceiverCheck node) { |
| 1325 if (node.condition != null) visitExpression(node.condition); | 1303 if (node.condition != null) visitExpression(node.condition); |
| 1326 visitExpression(node.value); | 1304 visitExpression(node.value); |
| 1327 visitStatement(node.next); | 1305 visitStatement(node.next); |
| 1328 } | 1306 } |
| 1329 } | 1307 } |
| 1330 | 1308 |
| 1331 abstract class Transformer implements ExpressionVisitor<Expression>, | 1309 abstract class Transformer |
| 1332 StatementVisitor<Statement> { | 1310 implements ExpressionVisitor<Expression>, StatementVisitor<Statement> { |
| 1333 Expression visitExpression(Expression e) => e.accept(this); | 1311 Expression visitExpression(Expression e) => e.accept(this); |
| 1334 Statement visitStatement(Statement s) => s.accept(this); | 1312 Statement visitStatement(Statement s) => s.accept(this); |
| 1335 } | 1313 } |
| 1336 | 1314 |
| 1337 class RecursiveTransformer extends Transformer { | 1315 class RecursiveTransformer extends Transformer { |
| 1338 void _replaceExpressions(List<Expression> list) { | 1316 void _replaceExpressions(List<Expression> list) { |
| 1339 for (int i = 0; i < list.length; i++) { | 1317 for (int i = 0; i < list.length; i++) { |
| 1340 list[i] = visitExpression(list[i]); | 1318 list[i] = visitExpression(list[i]); |
| 1341 } | 1319 } |
| 1342 } | 1320 } |
| 1343 | 1321 |
| 1344 visitVariableUse(VariableUse node) => node; | 1322 visitVariableUse(VariableUse node) => node; |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1593 | 1571 |
| 1594 class FallthroughTarget { | 1572 class FallthroughTarget { |
| 1595 final Statement target; | 1573 final Statement target; |
| 1596 int useCount = 0; | 1574 int useCount = 0; |
| 1597 | 1575 |
| 1598 FallthroughTarget(this.target); | 1576 FallthroughTarget(this.target); |
| 1599 } | 1577 } |
| 1600 | 1578 |
| 1601 /// A stack machine for tracking fallthrough while traversing the Tree IR. | 1579 /// A stack machine for tracking fallthrough while traversing the Tree IR. |
| 1602 class FallthroughStack { | 1580 class FallthroughStack { |
| 1603 final List<FallthroughTarget> _stack = | 1581 final List<FallthroughTarget> _stack = <FallthroughTarget>[ |
| 1604 <FallthroughTarget>[new FallthroughTarget(null)]; | 1582 new FallthroughTarget(null) |
| 1583 ]; |
| 1605 | 1584 |
| 1606 /// Set a new fallthrough target. | 1585 /// Set a new fallthrough target. |
| 1607 void push(Statement newFallthrough) { | 1586 void push(Statement newFallthrough) { |
| 1608 _stack.add(new FallthroughTarget(newFallthrough)); | 1587 _stack.add(new FallthroughTarget(newFallthrough)); |
| 1609 } | 1588 } |
| 1610 | 1589 |
| 1611 /// Remove the current fallthrough target. | 1590 /// Remove the current fallthrough target. |
| 1612 void pop() { | 1591 void pop() { |
| 1613 _stack.removeLast(); | 1592 _stack.removeLast(); |
| 1614 } | 1593 } |
| 1615 | 1594 |
| 1616 /// The current fallthrough target, or `null` if control will fall over | 1595 /// The current fallthrough target, or `null` if control will fall over |
| 1617 /// the end of the method. | 1596 /// the end of the method. |
| 1618 Statement get target => _stack.last.target; | 1597 Statement get target => _stack.last.target; |
| 1619 | 1598 |
| 1620 /// Number of uses of the current fallthrough target. | 1599 /// Number of uses of the current fallthrough target. |
| 1621 int get useCount => _stack.last.useCount; | 1600 int get useCount => _stack.last.useCount; |
| 1622 | 1601 |
| 1623 /// Indicate that a statement will fall through to the current fallthrough | 1602 /// Indicate that a statement will fall through to the current fallthrough |
| 1624 /// target. | 1603 /// target. |
| 1625 void use() { | 1604 void use() { |
| 1626 ++_stack.last.useCount; | 1605 ++_stack.last.useCount; |
| 1627 } | 1606 } |
| 1628 } | 1607 } |
| OLD | NEW |