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 |