Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1446)

Side by Side Diff: pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart

Issue 2246623002: Delete CPS IR (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library tree_ir_nodes;
6
7 import '../constants/values.dart' as values;
8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType;
9 import '../elements/elements.dart';
10 import '../io/source_information.dart' show SourceInformation;
11 import '../types/types.dart' show TypeMask;
12 import '../universe/selector.dart' show Selector;
13
14 import '../cps_ir/builtin_operator.dart';
15 export '../cps_ir/builtin_operator.dart';
16 import '../cps_ir/cps_ir_nodes.dart' show TypeExpressionKind;
17 export '../cps_ir/cps_ir_nodes.dart' show TypeExpressionKind;
18
19 // These imports are only used for the JavaScript specific nodes. If we want to
20 // support more than one native backend, we should probably create better
21 // abstractions for native code and its type and effect system.
22 import '../js/js.dart' as js show Template;
23 import '../native/native.dart' as native show NativeBehavior;
24 import '../types/types.dart' as types show TypeMask;
25
26 // The Tree language is the target of translation out of the CPS-based IR.
27 //
28 // The translation from CPS to Dart consists of several stages. Among the
29 // stages are translation to direct style, translation out of SSA, eliminating
30 // unnecessary names, recognizing high-level control constructs. Combining
31 // these separate concerns is complicated and the constraints of the CPS-based
32 // language do not permit a multi-stage translation.
33 //
34 // For that reason, CPS is translated to the direct-style language Tree.
35 // Translation out of SSA, unnaming, and control-flow, as well as 'instruction
36 // selection' are performed on the Tree language.
37 //
38 // In contrast to the CPS-based IR, non-primitive expressions can be named and
39 // arguments (to calls, primitives, and blocks) can be arbitrary expressions.
40 //
41 // Additionally, variables are considered in scope within inner functions;
42 // closure variables are thus handled directly instead of using ref cells.
43
44 /**
45 * The base class of all Tree nodes.
46 */
47 abstract class Node {
48 /// Workaround for a slow Object.hashCode in the VM.
49 static int _usedHashCodes = 0;
50 final int hashCode = ++_usedHashCodes;
51 }
52
53 /**
54 * The base class of [Expression]s.
55 */
56 abstract class Expression extends Node {
57 accept(ExpressionVisitor v);
58 accept1(ExpressionVisitor1 v, arg);
59
60 SourceInformation get sourceInformation => null;
61 }
62
63 abstract class Statement extends Node {
64 Statement get next;
65 void set next(Statement s);
66 accept(StatementVisitor v);
67 accept1(StatementVisitor1 v, arg);
68 }
69
70 /**
71 * Labels name [LabeledStatement]s.
72 */
73 class Label {
74 /// Number of [Break] or [Continue] statements that target this label.
75 /// The [Break] constructor will increment this automatically, but the
76 /// counter must be decremented by hand when a [Break] becomes orphaned.
77 int useCount = 0;
78
79 /// The [LabeledStatement] or [WhileTrue] binding this label.
80 JumpTarget binding;
81 }
82
83 /**
84 * A local variable in the tree IR.
85 *
86 * All tree IR variables are mutable.
87 *
88 * To use a variable as an expression, reference it from a [VariableUse], with
89 * one [VariableUse] per expression.
90 *
91 * [Variable]s are reference counted. The node constructors [VariableUse],
92 * [Assign], [FunctionDefinition], and [Try] automatically update the reference
93 * count for their variables, but when transforming the tree, the transformer
94 * is responsible for updating reference counts.
95 */
96 class Variable extends Node {
97 /// Function that declares this variable.
98 ExecutableElement host;
99
100 /// [Entity] used for synthesizing a name for the variable.
101 /// Different variables may have the same entity. May be null.
102 Entity element;
103
104 /// Number of places where this variable occurs in a [VariableUse].
105 int readCount = 0;
106
107 /// Number of places where this variable occurs as:
108 /// - left-hand of an [Assign]
109 /// - parameter in a [FunctionDefinition]
110 /// - catch parameter in a [Try]
111 int writeCount = 0;
112
113 /// True if an inner JS function might access this variable through a
114 /// [ForeignCode] node.
115 bool isCaptured = false;
116
117 Variable(this.host, this.element) {
118 assert(host != null);
119 }
120
121 String toString() =>
122 element == null ? 'Variable.${hashCode}' : element.toString();
123 }
124
125 /// Read the value of a variable.
126 class VariableUse extends Expression {
127 Variable variable;
128 SourceInformation sourceInformation;
129
130 /// Creates a use of [variable] and updates its `readCount`.
131 VariableUse(this.variable, {this.sourceInformation}) {
132 variable.readCount++;
133 }
134
135 accept(ExpressionVisitor visitor) => visitor.visitVariableUse(this);
136 accept1(ExpressionVisitor1 visitor, arg) {
137 return visitor.visitVariableUse(this, arg);
138 }
139 }
140
141 class Assign extends Expression {
142 Variable variable;
143 Expression value;
144 SourceInformation sourceInformation;
145
146 Assign(this.variable, this.value, {this.sourceInformation}) {
147 variable.writeCount++;
148 }
149
150 accept(ExpressionVisitor v) => v.visitAssign(this);
151 accept1(ExpressionVisitor1 v, arg) => v.visitAssign(this, arg);
152
153 static ExpressionStatement makeStatement(Variable variable, Expression value,
154 [Statement next]) {
155 return new ExpressionStatement(new Assign(variable, value), next);
156 }
157 }
158
159 /**
160 * Common interface for invocations with arguments.
161 */
162 abstract class Invoke {
163 List<Expression> get arguments;
164 }
165
166 /**
167 * A call to a static function or getter/setter to a static field.
168 *
169 * In contrast to the CPS-based IR, the arguments can be arbitrary expressions.
170 */
171 class InvokeStatic extends Expression implements Invoke {
172 final Entity target;
173 final List<Expression> arguments;
174 final Selector selector;
175 final SourceInformation sourceInformation;
176
177 InvokeStatic(this.target, this.selector, this.arguments,
178 [this.sourceInformation]);
179
180 accept(ExpressionVisitor visitor) => visitor.visitInvokeStatic(this);
181 accept1(ExpressionVisitor1 visitor, arg) {
182 return visitor.visitInvokeStatic(this, arg);
183 }
184 }
185
186 /**
187 * A call to a method, operator, getter, setter or index getter/setter.
188 *
189 * If [receiver] is `null`, an error is thrown before the arguments are
190 * evaluated. This corresponds to the JS evaluation order.
191 */
192 class InvokeMethod extends Expression implements Invoke {
193 Expression receiver;
194 final Selector selector;
195 final TypeMask mask;
196 final List<Expression> arguments;
197 final SourceInformation sourceInformation;
198
199 /// If true, it is known that the receiver cannot be `null`.
200 bool receiverIsNotNull = false;
201
202 InvokeMethod(this.receiver, this.selector, this.mask, this.arguments,
203 this.sourceInformation) {
204 assert(receiver != null);
205 }
206
207 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethod(this);
208 accept1(ExpressionVisitor1 visitor, arg) {
209 return visitor.visitInvokeMethod(this, arg);
210 }
211 }
212
213 /// Invoke [target] on [receiver], bypassing ordinary dispatch semantics.
214 ///
215 /// Since the [receiver] is not used for method lookup, it may be `null`
216 /// without an error being thrown.
217 class InvokeMethodDirectly extends Expression implements Invoke {
218 Expression receiver;
219 final Element target;
220 final Selector selector;
221 final List<Expression> arguments;
222 final SourceInformation sourceInformation;
223
224 InvokeMethodDirectly(this.receiver, this.target, this.selector,
225 this.arguments, this.sourceInformation);
226
227 bool get isTearOff => selector.isGetter && !target.isGetter;
228
229 accept(ExpressionVisitor visitor) => visitor.visitInvokeMethodDirectly(this);
230 accept1(ExpressionVisitor1 visitor, arg) {
231 return visitor.visitInvokeMethodDirectly(this, arg);
232 }
233 }
234
235 /**
236 * Call to a factory or generative constructor.
237 */
238 class InvokeConstructor extends Expression implements Invoke {
239 final DartType type;
240 final FunctionElement target;
241 final List<Expression> arguments;
242 final Selector selector;
243 final SourceInformation sourceInformation;
244
245 /// TODO(karlklose): get rid of this field. Instead use the constant's
246 /// expression to find the constructor to be called in dart2dart.
247 final values.ConstantValue constant;
248
249 InvokeConstructor(this.type, this.target, this.selector, this.arguments,
250 this.sourceInformation,
251 [this.constant]);
252
253 ClassElement get targetClass => target.enclosingElement;
254
255 accept(ExpressionVisitor visitor) {
256 return visitor.visitInvokeConstructor(this);
257 }
258
259 accept1(ExpressionVisitor1 visitor, arg) {
260 return visitor.visitInvokeConstructor(this, arg);
261 }
262 }
263
264 /// Call a method using a one-shot interceptor.
265 ///
266 /// There is no explicit receiver, the first argument serves that purpose.
267 class OneShotInterceptor extends Expression implements Invoke {
268 final Selector selector;
269 final TypeMask mask;
270 final List<Expression> arguments;
271 final SourceInformation sourceInformation;
272
273 OneShotInterceptor(
274 this.selector, this.mask, this.arguments, this.sourceInformation);
275
276 accept(ExpressionVisitor visitor) => visitor.visitOneShotInterceptor(this);
277 accept1(ExpressionVisitor1 visitor, arg) {
278 return visitor.visitOneShotInterceptor(this, arg);
279 }
280 }
281
282 /**
283 * A constant.
284 */
285 class Constant extends Expression {
286 final values.ConstantValue value;
287 final SourceInformation sourceInformation;
288
289 Constant(this.value, {this.sourceInformation});
290
291 Constant.bool(values.BoolConstantValue constantValue)
292 : value = constantValue,
293 sourceInformation = null;
294
295 accept(ExpressionVisitor visitor) => visitor.visitConstant(this);
296 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitConstant(this, arg);
297
298 String toString() => 'Constant(value=${value.toStructuredText()})';
299 }
300
301 class This extends Expression {
302 accept(ExpressionVisitor visitor) => visitor.visitThis(this);
303 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitThis(this, arg);
304 }
305
306 class LiteralList extends Expression {
307 final InterfaceType type;
308 final List<Expression> values;
309
310 LiteralList(this.type, this.values);
311
312 accept(ExpressionVisitor visitor) => visitor.visitLiteralList(this);
313 accept1(ExpressionVisitor1 visitor, arg) {
314 return visitor.visitLiteralList(this, arg);
315 }
316 }
317
318 /// Type test or type cast.
319 ///
320 /// Note that if this is a type test, then [type] cannot be `Object`, `dynamic`,
321 /// or the `Null` type. These cases are compiled to other node types.
322 class TypeOperator extends Expression {
323 Expression value;
324 final DartType type;
325 final List<Expression> typeArguments;
326 final bool isTypeTest;
327
328 TypeOperator(this.value, this.type, this.typeArguments,
329 {bool this.isTypeTest});
330
331 accept(ExpressionVisitor visitor) => visitor.visitTypeOperator(this);
332 accept1(ExpressionVisitor1 visitor, arg) {
333 return visitor.visitTypeOperator(this, arg);
334 }
335
336 String get operator => isTypeTest ? 'is' : 'as';
337 }
338
339 /**
340 * Apply a built-in operator.
341 *
342 * It must be known that the arguments have the proper types.
343 * Null is not a valid argument to any of the built-in operators.
344 */
345 class ApplyBuiltinOperator extends Expression {
346 BuiltinOperator operator;
347 List<Expression> arguments;
348 SourceInformation sourceInformation;
349
350 ApplyBuiltinOperator(this.operator, this.arguments, this.sourceInformation);
351
352 accept(ExpressionVisitor visitor) {
353 return visitor.visitApplyBuiltinOperator(this);
354 }
355
356 accept1(ExpressionVisitor1 visitor, arg) {
357 return visitor.visitApplyBuiltinOperator(this, arg);
358 }
359 }
360
361 class ApplyBuiltinMethod extends Expression {
362 BuiltinMethod method;
363 Expression receiver;
364 List<Expression> arguments;
365
366 bool receiverIsNotNull;
367
368 ApplyBuiltinMethod(this.method, this.receiver, this.arguments,
369 {this.receiverIsNotNull: false});
370
371 accept(ExpressionVisitor visitor) {
372 return visitor.visitApplyBuiltinMethod(this);
373 }
374
375 accept1(ExpressionVisitor1 visitor, arg) {
376 return visitor.visitApplyBuiltinMethod(this, arg);
377 }
378 }
379
380 /// A conditional expression.
381 class Conditional extends Expression {
382 Expression condition;
383 Expression thenExpression;
384 Expression elseExpression;
385
386 Conditional(this.condition, this.thenExpression, this.elseExpression);
387
388 accept(ExpressionVisitor visitor) => visitor.visitConditional(this);
389 accept1(ExpressionVisitor1 visitor, arg) {
390 return visitor.visitConditional(this, arg);
391 }
392
393 String toString() => 'Conditional(condition=$condition,thenExpression='
394 '$thenExpression,elseExpression=$elseExpression)';
395 }
396
397 /// An && or || expression. The operator is internally represented as a boolean
398 /// [isAnd] to simplify rewriting of logical operators.
399 /// Note the result of && and || is one of the arguments, which might not be
400 /// boolean. 'ShortCircuitOperator' might have been a better name.
401 class LogicalOperator extends Expression {
402 Expression left;
403 bool isAnd;
404 Expression right;
405
406 LogicalOperator(this.left, this.right, this.isAnd);
407 LogicalOperator.and(this.left, this.right) : isAnd = true;
408 LogicalOperator.or(this.left, this.right) : isAnd = false;
409
410 String get operator => isAnd ? '&&' : '||';
411
412 accept(ExpressionVisitor visitor) => visitor.visitLogicalOperator(this);
413 accept1(ExpressionVisitor1 visitor, arg) {
414 return visitor.visitLogicalOperator(this, arg);
415 }
416
417 String toString() => 'LogicalOperator(left=$left,right=$right,isAnd=$isAnd)';
418 }
419
420 /// Logical negation.
421 // TODO(asgerf): Replace this class with the IsFalsy builtin operator?
422 // Right now the tree builder compiles IsFalsy to Not.
423 class Not extends Expression {
424 Expression operand;
425
426 Not(this.operand);
427
428 accept(ExpressionVisitor visitor) => visitor.visitNot(this);
429 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitNot(this, arg);
430 }
431
432 /// A [LabeledStatement] or [WhileTrue] or [For].
433 abstract class JumpTarget extends Statement {
434 Label get label;
435 Statement get body;
436 }
437
438 /**
439 * A labeled statement. Breaks to the label within the labeled statement
440 * target the successor statement.
441 */
442 class LabeledStatement extends JumpTarget {
443 Statement next;
444 final Label label;
445 Statement body;
446
447 LabeledStatement(this.label, this.body, this.next) {
448 assert(label.binding == null);
449 label.binding = this;
450 }
451
452 accept(StatementVisitor visitor) => visitor.visitLabeledStatement(this);
453 accept1(StatementVisitor1 visitor, arg) {
454 return visitor.visitLabeledStatement(this, arg);
455 }
456 }
457
458 /// A [WhileTrue] or [For] loop.
459 abstract class Loop extends JumpTarget {}
460
461 /**
462 * A labeled while(true) loop.
463 */
464 class WhileTrue extends Loop {
465 final Label label;
466 Statement body;
467
468 WhileTrue(this.label, this.body) {
469 assert(label.binding == null);
470 label.binding = this;
471 }
472
473 Statement get next => null;
474 void set next(Statement s) => throw 'UNREACHABLE';
475
476 accept(StatementVisitor visitor) => visitor.visitWhileTrue(this);
477 accept1(StatementVisitor1 visitor, arg) => visitor.visitWhileTrue(this, arg);
478 }
479
480 /**
481 * A loop with a condition and update expressions. If there are any update
482 * expressions, this generates a for loop, otherwise a while loop.
483 *
484 * When the condition is false, control resumes at the [next] statement.
485 *
486 * It is NOT valid to target this statement with a [Break].
487 * The only way to reach [next] is for the condition to evaluate to false.
488 *
489 * [For] statements are introduced in the [LoopRewriter] and are
490 * assumed not to occur before then.
491 */
492 class For extends Loop {
493 final Label label;
494 Expression condition;
495 List<Expression> updates;
496 Statement body;
497 Statement next;
498
499 For(this.label, this.condition, this.updates, this.body, this.next) {
500 assert(label.binding == null);
501 label.binding = this;
502 }
503
504 accept(StatementVisitor visitor) => visitor.visitFor(this);
505 accept1(StatementVisitor1 visitor, arg) {
506 return visitor.visitFor(this, arg);
507 }
508 }
509
510 /// A [Break] or [Continue] statement.
511 abstract class Jump extends Statement {
512 Label get target;
513 }
514
515 /**
516 * A break from an enclosing [LabeledStatement]. The break targets the
517 * labeled statement's successor statement.
518 */
519 class Break extends Jump {
520 final Label target;
521
522 Statement get next => null;
523 void set next(Statement s) => throw 'UNREACHABLE';
524
525 Break(this.target) {
526 ++target.useCount;
527 }
528
529 accept(StatementVisitor visitor) => visitor.visitBreak(this);
530 accept1(StatementVisitor1 visitor, arg) => visitor.visitBreak(this, arg);
531 }
532
533 /**
534 * A continue to an enclosing [WhileTrue] or [For] loop.
535 * The continue targets the loop's body.
536 */
537 class Continue extends Jump {
538 final Label target;
539
540 Statement get next => null;
541 void set next(Statement s) => throw 'UNREACHABLE';
542
543 Continue(this.target) {
544 ++target.useCount;
545 }
546
547 accept(StatementVisitor visitor) => visitor.visitContinue(this);
548 accept1(StatementVisitor1 visitor, arg) => visitor.visitContinue(this, arg);
549 }
550
551 /**
552 * A return exit from the function.
553 *
554 * In contrast to the CPS-based IR, the return value is an arbitrary
555 * expression.
556 */
557 class Return extends Statement {
558 /// Should not be null. Use [Constant] with [NullConstantValue] for void
559 /// returns.
560 /// Even in constructors this holds true. Take special care when translating
561 /// back to dart, where `return null;` in a constructor is an error.
562 Expression value;
563 SourceInformation sourceInformation;
564
565 Statement get next => null;
566 void set next(Statement s) => throw 'UNREACHABLE';
567
568 Return(this.value, {this.sourceInformation});
569
570 accept(StatementVisitor visitor) => visitor.visitReturn(this);
571 accept1(StatementVisitor1 visitor, arg) => visitor.visitReturn(this, arg);
572 }
573
574 /// A throw statement.
575 ///
576 /// In the Tree IR, throw is a statement (like JavaScript and unlike Dart).
577 /// It does not have a successor statement.
578 class Throw extends Statement {
579 Expression value;
580
581 Statement get next => null;
582 void set next(Statement s) => throw 'UNREACHABLE';
583
584 Throw(this.value);
585
586 accept(StatementVisitor visitor) => visitor.visitThrow(this);
587 accept1(StatementVisitor1 visitor, arg) => visitor.visitThrow(this, arg);
588 }
589
590 /**
591 * A conditional branch based on the true value of an [Expression].
592 */
593 class If extends Statement {
594 Expression condition;
595 Statement thenStatement;
596 Statement elseStatement;
597 SourceInformation sourceInformation;
598
599 Statement get next => null;
600 void set next(Statement s) => throw 'UNREACHABLE';
601
602 If(this.condition, this.thenStatement, this.elseStatement,
603 this.sourceInformation);
604
605 accept(StatementVisitor visitor) => visitor.visitIf(this);
606 accept1(StatementVisitor1 visitor, arg) => visitor.visitIf(this, arg);
607 }
608
609 class ExpressionStatement extends Statement {
610 Statement next;
611 Expression expression;
612
613 ExpressionStatement(this.expression, this.next);
614
615 accept(StatementVisitor visitor) => visitor.visitExpressionStatement(this);
616 accept1(StatementVisitor1 visitor, arg) {
617 return visitor.visitExpressionStatement(this, arg);
618 }
619 }
620
621 class Try extends Statement {
622 Statement tryBody;
623 List<Variable> catchParameters;
624 Statement catchBody;
625
626 Statement get next => null;
627 void set next(Statement s) => throw 'UNREACHABLE';
628
629 Try(this.tryBody, this.catchParameters, this.catchBody) {
630 for (Variable variable in catchParameters) {
631 variable.writeCount++; // Being a catch parameter counts as a write.
632 }
633 }
634
635 accept(StatementVisitor visitor) => visitor.visitTry(this);
636 accept1(StatementVisitor1 visitor, arg) {
637 return visitor.visitTry(this, arg);
638 }
639 }
640
641 /// A statement that is known to be unreachable.
642 class Unreachable extends Statement {
643 Statement get next => null;
644 void set next(Statement value) => throw 'UNREACHABLE';
645
646 accept(StatementVisitor visitor) => visitor.visitUnreachable(this);
647 accept1(StatementVisitor1 visitor, arg) {
648 return visitor.visitUnreachable(this, arg);
649 }
650 }
651
652 class FunctionDefinition extends Node {
653 final ExecutableElement element;
654 final List<Variable> parameters;
655 final SourceInformation sourceInformation;
656 Statement body;
657
658 /// Creates a function definition and updates `writeCount` for [parameters].
659 FunctionDefinition(this.element, this.parameters, this.body,
660 {this.sourceInformation}) {
661 for (Variable param in parameters) {
662 param.writeCount++; // Being a parameter counts as a write.
663 }
664 }
665 }
666
667 class CreateBox extends Expression {
668 accept(ExpressionVisitor visitor) => visitor.visitCreateBox(this);
669 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitCreateBox(this, arg);
670 }
671
672 class CreateInstance extends Expression {
673 ClassElement classElement;
674 List<Expression> arguments;
675 Expression typeInformation;
676 SourceInformation sourceInformation;
677
678 CreateInstance(this.classElement, this.arguments, this.typeInformation,
679 this.sourceInformation);
680
681 accept(ExpressionVisitor visitor) => visitor.visitCreateInstance(this);
682 accept1(ExpressionVisitor1 visitor, arg) {
683 return visitor.visitCreateInstance(this, arg);
684 }
685 }
686
687 class GetField extends Expression {
688 Expression object;
689 Element field;
690 bool objectIsNotNull;
691 SourceInformation sourceInformation;
692
693 GetField(this.object, this.field, this.sourceInformation,
694 {this.objectIsNotNull: false});
695
696 accept(ExpressionVisitor visitor) => visitor.visitGetField(this);
697 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitGetField(this, arg);
698 }
699
700 class SetField extends Expression {
701 Expression object;
702 Element field;
703 Expression value;
704 SourceInformation sourceInformation;
705
706 /// If non-null, this is a compound assignment to the field, using the given
707 /// operator. The operator must be a compoundable operator.
708 BuiltinOperator compound;
709
710 SetField(this.object, this.field, this.value, this.sourceInformation,
711 {this.compound});
712
713 accept(ExpressionVisitor visitor) => visitor.visitSetField(this);
714 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitSetField(this, arg);
715 }
716
717 /// Read the type test property from [object]. The value is truthy/fasly rather
718 /// than bool. [object] must not be `null`.
719 class GetTypeTestProperty extends Expression {
720 Expression object;
721 DartType dartType;
722
723 GetTypeTestProperty(this.object, this.dartType);
724
725 accept(ExpressionVisitor visitor) => visitor.visitGetTypeTestProperty(this);
726 accept1(ExpressionVisitor1 visitor, arg) =>
727 visitor.visitGetTypeTestProperty(this, arg);
728 }
729
730 /// Read the value of a field, possibly provoking its initializer to evaluate,
731 /// or tear off a static method.
732 class GetStatic extends Expression {
733 Element element;
734 SourceInformation sourceInformation;
735 bool useLazyGetter = false;
736
737 GetStatic(this.element, this.sourceInformation);
738
739 GetStatic.lazy(this.element, this.sourceInformation) : useLazyGetter = true;
740
741 accept(ExpressionVisitor visitor) => visitor.visitGetStatic(this);
742 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitGetStatic(this, arg);
743 }
744
745 class SetStatic extends Expression {
746 Element element;
747 Expression value;
748 SourceInformation sourceInformation;
749 BuiltinOperator compound;
750
751 SetStatic(this.element, this.value, this.sourceInformation, {this.compound});
752
753 accept(ExpressionVisitor visitor) => visitor.visitSetStatic(this);
754 accept1(ExpressionVisitor1 visitor, arg) => visitor.visitSetStatic(this, arg);
755 }
756
757 class GetLength extends Expression {
758 Expression object;
759
760 GetLength(this.object);
761
762 accept(ExpressionVisitor v) => v.visitGetLength(this);
763 accept1(ExpressionVisitor1 v, arg) => v.visitGetLength(this, arg);
764 }
765
766 class GetIndex extends Expression {
767 Expression object;
768 Expression index;
769
770 GetIndex(this.object, this.index);
771
772 accept(ExpressionVisitor v) => v.visitGetIndex(this);
773 accept1(ExpressionVisitor1 v, arg) => v.visitGetIndex(this, arg);
774 }
775
776 class SetIndex extends Expression {
777 Expression object;
778 Expression index;
779 Expression value;
780 BuiltinOperator compound;
781
782 SetIndex(this.object, this.index, this.value, {this.compound});
783
784 accept(ExpressionVisitor v) => v.visitSetIndex(this);
785 accept1(ExpressionVisitor1 v, arg) => v.visitSetIndex(this, arg);
786 }
787
788 class ReifyRuntimeType extends Expression {
789 Expression value;
790 SourceInformation sourceInformation;
791
792 ReifyRuntimeType(this.value, this.sourceInformation);
793
794 accept(ExpressionVisitor visitor) {
795 return visitor.visitReifyRuntimeType(this);
796 }
797
798 accept1(ExpressionVisitor1 visitor, arg) {
799 return visitor.visitReifyRuntimeType(this, arg);
800 }
801 }
802
803 class ReadTypeVariable extends Expression {
804 final TypeVariableType variable;
805 Expression target;
806 final SourceInformation sourceInformation;
807
808 ReadTypeVariable(this.variable, this.target, this.sourceInformation);
809
810 accept(ExpressionVisitor visitor) {
811 return visitor.visitReadTypeVariable(this);
812 }
813
814 accept1(ExpressionVisitor1 visitor, arg) {
815 return visitor.visitReadTypeVariable(this, arg);
816 }
817 }
818
819 class CreateInvocationMirror extends Expression {
820 final Selector selector;
821 final List<Expression> arguments;
822
823 CreateInvocationMirror(this.selector, this.arguments);
824
825 accept(ExpressionVisitor visitor) {
826 return visitor.visitCreateInvocationMirror(this);
827 }
828
829 accept1(ExpressionVisitor1 visitor, arg) {
830 return visitor.visitCreateInvocationMirror(this, arg);
831 }
832 }
833
834 class Interceptor extends Expression {
835 Expression input;
836 Set<ClassElement> interceptedClasses;
837 final SourceInformation sourceInformation;
838
839 Interceptor(this.input, this.interceptedClasses, this.sourceInformation);
840
841 accept(ExpressionVisitor visitor) {
842 return visitor.visitInterceptor(this);
843 }
844
845 accept1(ExpressionVisitor1 visitor, arg) {
846 return visitor.visitInterceptor(this, arg);
847 }
848 }
849
850 class ForeignCode extends Node {
851 final js.Template codeTemplate;
852 final types.TypeMask type;
853 final List<Expression> arguments;
854 final native.NativeBehavior nativeBehavior;
855 final List<bool> nullableArguments; // One 'bit' per argument.
856 final Element dependency;
857 final SourceInformation sourceInformation;
858
859 ForeignCode(this.codeTemplate, this.type, this.arguments, this.nativeBehavior,
860 this.nullableArguments, this.dependency, this.sourceInformation) {
861 assert(arguments.length == nullableArguments.length);
862 }
863 }
864
865 class ForeignExpression extends ForeignCode implements Expression {
866 ForeignExpression(
867 js.Template codeTemplate,
868 types.TypeMask type,
869 List<Expression> arguments,
870 native.NativeBehavior nativeBehavior,
871 List<bool> nullableArguments,
872 Element dependency,
873 SourceInformation sourceInformation)
874 : super(codeTemplate, type, arguments, nativeBehavior, nullableArguments,
875 dependency, sourceInformation);
876
877 accept(ExpressionVisitor visitor) {
878 return visitor.visitForeignExpression(this);
879 }
880
881 accept1(ExpressionVisitor1 visitor, arg) {
882 return visitor.visitForeignExpression(this, arg);
883 }
884 }
885
886 class ForeignStatement extends ForeignCode implements Statement {
887 ForeignStatement(
888 js.Template codeTemplate,
889 types.TypeMask type,
890 List<Expression> arguments,
891 native.NativeBehavior nativeBehavior,
892 List<bool> nullableArguments,
893 Element dependency,
894 SourceInformation sourceInformation)
895 : super(codeTemplate, type, arguments, nativeBehavior, nullableArguments,
896 dependency, sourceInformation);
897
898 accept(StatementVisitor visitor) {
899 return visitor.visitForeignStatement(this);
900 }
901
902 accept1(StatementVisitor1 visitor, arg) {
903 return visitor.visitForeignStatement(this, arg);
904 }
905
906 @override
907 Statement get next => null;
908
909 @override
910 void set next(Statement s) => throw 'UNREACHABLE';
911 }
912
913 /// Denotes the internal representation of [dartType], where all type variables
914 /// are replaced by the values in [arguments].
915 /// (See documentation on the TypeExpression CPS node for more details.)
916 class TypeExpression extends Expression {
917 final TypeExpressionKind kind;
918 final DartType dartType;
919 final List<Expression> arguments;
920
921 TypeExpression(this.kind, this.dartType, this.arguments);
922
923 accept(ExpressionVisitor visitor) {
924 return visitor.visitTypeExpression(this);
925 }
926
927 accept1(ExpressionVisitor1 visitor, arg) {
928 return visitor.visitTypeExpression(this, arg);
929 }
930 }
931
932 class Await extends Expression {
933 Expression input;
934
935 Await(this.input);
936
937 accept(ExpressionVisitor visitor) {
938 return visitor.visitAwait(this);
939 }
940
941 accept1(ExpressionVisitor1 visitor, arg) {
942 return visitor.visitAwait(this, arg);
943 }
944 }
945
946 class Yield extends Statement {
947 Statement next;
948 Expression input;
949 final bool hasStar;
950
951 Yield(this.input, this.hasStar, this.next);
952
953 accept(StatementVisitor visitor) {
954 return visitor.visitYield(this);
955 }
956
957 accept1(StatementVisitor1 visitor, arg) {
958 return visitor.visitYield(this, arg);
959 }
960 }
961
962 class ReceiverCheck extends Statement {
963 Expression condition;
964 Expression value;
965 Selector selector;
966 bool useSelector;
967 bool useInvoke;
968 Statement next;
969 SourceInformation sourceInformation;
970
971 ReceiverCheck(
972 {this.condition,
973 this.value,
974 this.selector,
975 this.useSelector,
976 this.useInvoke,
977 this.next,
978 this.sourceInformation});
979
980 accept(StatementVisitor visitor) {
981 return visitor.visitReceiverCheck(this);
982 }
983
984 accept1(StatementVisitor1 visitor, arg) {
985 return visitor.visitReceiverCheck(this, arg);
986 }
987 }
988
989 abstract class ExpressionVisitor<E> {
990 E visitExpression(Expression node) => node.accept(this);
991 E visitVariableUse(VariableUse node);
992 E visitAssign(Assign node);
993 E visitInvokeStatic(InvokeStatic node);
994 E visitInvokeMethod(InvokeMethod node);
995 E visitInvokeMethodDirectly(InvokeMethodDirectly node);
996 E visitInvokeConstructor(InvokeConstructor node);
997 E visitOneShotInterceptor(OneShotInterceptor node);
998 E visitConstant(Constant node);
999 E visitThis(This node);
1000 E visitConditional(Conditional node);
1001 E visitLogicalOperator(LogicalOperator node);
1002 E visitNot(Not node);
1003 E visitLiteralList(LiteralList node);
1004 E visitTypeOperator(TypeOperator node);
1005 E visitGetField(GetField node);
1006 E visitSetField(SetField node);
1007 E visitGetStatic(GetStatic node);
1008 E visitSetStatic(SetStatic node);
1009 E visitGetTypeTestProperty(GetTypeTestProperty node);
1010 E visitCreateBox(CreateBox node);
1011 E visitCreateInstance(CreateInstance node);
1012 E visitReifyRuntimeType(ReifyRuntimeType node);
1013 E visitReadTypeVariable(ReadTypeVariable node);
1014 E visitTypeExpression(TypeExpression node);
1015 E visitCreateInvocationMirror(CreateInvocationMirror node);
1016 E visitInterceptor(Interceptor node);
1017 E visitApplyBuiltinOperator(ApplyBuiltinOperator node);
1018 E visitApplyBuiltinMethod(ApplyBuiltinMethod node);
1019 E visitForeignExpression(ForeignExpression node);
1020 E visitGetLength(GetLength node);
1021 E visitGetIndex(GetIndex node);
1022 E visitSetIndex(SetIndex node);
1023 E visitAwait(Await node);
1024 }
1025
1026 abstract class ExpressionVisitor1<E, A> {
1027 E visitExpression(Expression node, A arg) => node.accept1(this, arg);
1028 E visitVariableUse(VariableUse node, A arg);
1029 E visitAssign(Assign node, A arg);
1030 E visitInvokeStatic(InvokeStatic node, A arg);
1031 E visitInvokeMethod(InvokeMethod node, A arg);
1032 E visitInvokeMethodDirectly(InvokeMethodDirectly node, A arg);
1033 E visitInvokeConstructor(InvokeConstructor node, A arg);
1034 E visitOneShotInterceptor(OneShotInterceptor node, A arg);
1035 E visitConstant(Constant node, A arg);
1036 E visitThis(This node, A arg);
1037 E visitConditional(Conditional node, A arg);
1038 E visitLogicalOperator(LogicalOperator node, A arg);
1039 E visitNot(Not node, A arg);
1040 E visitLiteralList(LiteralList node, A arg);
1041 E visitTypeOperator(TypeOperator node, A arg);
1042 E visitGetField(GetField node, A arg);
1043 E visitSetField(SetField node, A arg);
1044 E visitGetStatic(GetStatic node, A arg);
1045 E visitSetStatic(SetStatic node, A arg);
1046 E visitGetTypeTestProperty(GetTypeTestProperty node, A arg);
1047 E visitCreateBox(CreateBox node, A arg);
1048 E visitCreateInstance(CreateInstance node, A arg);
1049 E visitReifyRuntimeType(ReifyRuntimeType node, A arg);
1050 E visitReadTypeVariable(ReadTypeVariable node, A arg);
1051 E visitTypeExpression(TypeExpression node, A arg);
1052 E visitCreateInvocationMirror(CreateInvocationMirror node, A arg);
1053 E visitInterceptor(Interceptor node, A arg);
1054 E visitApplyBuiltinOperator(ApplyBuiltinOperator node, A arg);
1055 E visitApplyBuiltinMethod(ApplyBuiltinMethod node, A arg);
1056 E visitForeignExpression(ForeignExpression node, A arg);
1057 E visitGetLength(GetLength node, A arg);
1058 E visitGetIndex(GetIndex node, A arg);
1059 E visitSetIndex(SetIndex node, A arg);
1060 E visitAwait(Await node, A arg);
1061 }
1062
1063 abstract class StatementVisitor<S> {
1064 S visitStatement(Statement node) => node.accept(this);
1065 S visitLabeledStatement(LabeledStatement node);
1066 S visitReturn(Return node);
1067 S visitThrow(Throw node);
1068 S visitBreak(Break node);
1069 S visitContinue(Continue node);
1070 S visitIf(If node);
1071 S visitWhileTrue(WhileTrue node);
1072 S visitFor(For node);
1073 S visitExpressionStatement(ExpressionStatement node);
1074 S visitTry(Try node);
1075 S visitUnreachable(Unreachable node);
1076 S visitForeignStatement(ForeignStatement node);
1077 S visitYield(Yield node);
1078 S visitReceiverCheck(ReceiverCheck node);
1079 }
1080
1081 abstract class StatementVisitor1<S, A> {
1082 S visitStatement(Statement node, A arg) => node.accept1(this, arg);
1083 S visitLabeledStatement(LabeledStatement node, A arg);
1084 S visitReturn(Return node, A arg);
1085 S visitThrow(Throw node, A arg);
1086 S visitBreak(Break node, A arg);
1087 S visitContinue(Continue node, A arg);
1088 S visitIf(If node, A arg);
1089 S visitWhileTrue(WhileTrue node, A arg);
1090 S visitFor(For node, A arg);
1091 S visitExpressionStatement(ExpressionStatement node, A arg);
1092 S visitTry(Try node, A arg);
1093 S visitUnreachable(Unreachable node, A arg);
1094 S visitForeignStatement(ForeignStatement node, A arg);
1095 S visitYield(Yield node, A arg);
1096 S visitReceiverCheck(ReceiverCheck node, A arg);
1097 }
1098
1099 abstract class RecursiveVisitor implements StatementVisitor, ExpressionVisitor {
1100 visitExpression(Expression e) => e.accept(this);
1101 visitStatement(Statement s) => s.accept(this);
1102
1103 visitVariable(Variable variable) {}
1104
1105 visitVariableUse(VariableUse node) {
1106 visitVariable(node.variable);
1107 }
1108
1109 visitAssign(Assign node) {
1110 visitVariable(node.variable);
1111 visitExpression(node.value);
1112 }
1113
1114 visitInvokeStatic(InvokeStatic node) {
1115 node.arguments.forEach(visitExpression);
1116 }
1117
1118 visitInvokeMethod(InvokeMethod node) {
1119 visitExpression(node.receiver);
1120 node.arguments.forEach(visitExpression);
1121 }
1122
1123 visitInvokeMethodDirectly(InvokeMethodDirectly node) {
1124 visitExpression(node.receiver);
1125 node.arguments.forEach(visitExpression);
1126 }
1127
1128 visitInvokeConstructor(InvokeConstructor node) {
1129 node.arguments.forEach(visitExpression);
1130 }
1131
1132 visitOneShotInterceptor(OneShotInterceptor node) {
1133 node.arguments.forEach(visitExpression);
1134 }
1135
1136 visitConstant(Constant node) {}
1137
1138 visitThis(This node) {}
1139
1140 visitConditional(Conditional node) {
1141 visitExpression(node.condition);
1142 visitExpression(node.thenExpression);
1143 visitExpression(node.elseExpression);
1144 }
1145
1146 visitLogicalOperator(LogicalOperator node) {
1147 visitExpression(node.left);
1148 visitExpression(node.right);
1149 }
1150
1151 visitNot(Not node) {
1152 visitExpression(node.operand);
1153 }
1154
1155 visitLiteralList(LiteralList node) {
1156 node.values.forEach(visitExpression);
1157 }
1158
1159 visitTypeOperator(TypeOperator node) {
1160 visitExpression(node.value);
1161 node.typeArguments.forEach(visitExpression);
1162 }
1163
1164 visitLabeledStatement(LabeledStatement node) {
1165 visitStatement(node.body);
1166 visitStatement(node.next);
1167 }
1168
1169 visitReturn(Return node) {
1170 visitExpression(node.value);
1171 }
1172
1173 visitThrow(Throw node) {
1174 visitExpression(node.value);
1175 }
1176
1177 visitBreak(Break node) {}
1178
1179 visitContinue(Continue node) {}
1180
1181 visitIf(If node) {
1182 visitExpression(node.condition);
1183 visitStatement(node.thenStatement);
1184 visitStatement(node.elseStatement);
1185 }
1186
1187 visitWhileTrue(WhileTrue node) {
1188 visitStatement(node.body);
1189 }
1190
1191 visitFor(For node) {
1192 visitExpression(node.condition);
1193 node.updates.forEach(visitExpression);
1194 visitStatement(node.body);
1195 visitStatement(node.next);
1196 }
1197
1198 visitExpressionStatement(ExpressionStatement inputNode) {
1199 // Iterate over chains of expression statements to avoid deep recursion.
1200 Statement node = inputNode;
1201 while (node is ExpressionStatement) {
1202 ExpressionStatement stmt = node;
1203 visitExpression(stmt.expression);
1204 node = stmt.next;
1205 }
1206 visitStatement(node);
1207 }
1208
1209 visitTry(Try node) {
1210 visitStatement(node.tryBody);
1211 visitStatement(node.catchBody);
1212 }
1213
1214 visitGetField(GetField node) {
1215 visitExpression(node.object);
1216 }
1217
1218 visitSetField(SetField node) {
1219 visitExpression(node.object);
1220 visitExpression(node.value);
1221 }
1222
1223 visitGetStatic(GetStatic node) {}
1224
1225 visitSetStatic(SetStatic node) {
1226 visitExpression(node.value);
1227 }
1228
1229 visitGetTypeTestProperty(GetTypeTestProperty node) {
1230 visitExpression(node.object);
1231 }
1232
1233 visitCreateBox(CreateBox node) {}
1234
1235 visitCreateInstance(CreateInstance node) {
1236 node.arguments.forEach(visitExpression);
1237 if (node.typeInformation != null) visitExpression(node.typeInformation);
1238 }
1239
1240 visitReifyRuntimeType(ReifyRuntimeType node) {
1241 visitExpression(node.value);
1242 }
1243
1244 visitReadTypeVariable(ReadTypeVariable node) {
1245 visitExpression(node.target);
1246 }
1247
1248 visitTypeExpression(TypeExpression node) {
1249 node.arguments.forEach(visitExpression);
1250 }
1251
1252 visitCreateInvocationMirror(CreateInvocationMirror node) {
1253 node.arguments.forEach(visitExpression);
1254 }
1255
1256 visitUnreachable(Unreachable node) {}
1257
1258 visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
1259 node.arguments.forEach(visitExpression);
1260 }
1261
1262 visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
1263 visitExpression(node.receiver);
1264 node.arguments.forEach(visitExpression);
1265 }
1266
1267 visitInterceptor(Interceptor node) {
1268 visitExpression(node.input);
1269 }
1270
1271 visitForeignCode(ForeignCode node) {
1272 node.arguments.forEach(visitExpression);
1273 }
1274
1275 visitForeignExpression(ForeignExpression node) => visitForeignCode(node);
1276 visitForeignStatement(ForeignStatement node) => visitForeignCode(node);
1277
1278 visitGetLength(GetLength node) {
1279 visitExpression(node.object);
1280 }
1281
1282 visitGetIndex(GetIndex node) {
1283 visitExpression(node.object);
1284 visitExpression(node.index);
1285 }
1286
1287 visitSetIndex(SetIndex node) {
1288 visitExpression(node.object);
1289 visitExpression(node.index);
1290 visitExpression(node.value);
1291 }
1292
1293 visitAwait(Await node) {
1294 visitExpression(node.input);
1295 }
1296
1297 visitYield(Yield node) {
1298 visitExpression(node.input);
1299 visitStatement(node.next);
1300 }
1301
1302 visitReceiverCheck(ReceiverCheck node) {
1303 if (node.condition != null) visitExpression(node.condition);
1304 visitExpression(node.value);
1305 visitStatement(node.next);
1306 }
1307 }
1308
1309 abstract class Transformer
1310 implements ExpressionVisitor<Expression>, StatementVisitor<Statement> {
1311 Expression visitExpression(Expression e) => e.accept(this);
1312 Statement visitStatement(Statement s) => s.accept(this);
1313 }
1314
1315 class RecursiveTransformer extends Transformer {
1316 void _replaceExpressions(List<Expression> list) {
1317 for (int i = 0; i < list.length; i++) {
1318 list[i] = visitExpression(list[i]);
1319 }
1320 }
1321
1322 visitVariableUse(VariableUse node) => node;
1323
1324 visitAssign(Assign node) {
1325 node.value = visitExpression(node.value);
1326 return node;
1327 }
1328
1329 visitInvokeStatic(InvokeStatic node) {
1330 _replaceExpressions(node.arguments);
1331 return node;
1332 }
1333
1334 visitInvokeMethod(InvokeMethod node) {
1335 node.receiver = visitExpression(node.receiver);
1336 _replaceExpressions(node.arguments);
1337 return node;
1338 }
1339
1340 visitInvokeMethodDirectly(InvokeMethodDirectly node) {
1341 node.receiver = visitExpression(node.receiver);
1342 _replaceExpressions(node.arguments);
1343 return node;
1344 }
1345
1346 visitInvokeConstructor(InvokeConstructor node) {
1347 _replaceExpressions(node.arguments);
1348 return node;
1349 }
1350
1351 visitOneShotInterceptor(OneShotInterceptor node) {
1352 _replaceExpressions(node.arguments);
1353 return node;
1354 }
1355
1356 visitConstant(Constant node) => node;
1357
1358 visitThis(This node) => node;
1359
1360 visitConditional(Conditional node) {
1361 node.condition = visitExpression(node.condition);
1362 node.thenExpression = visitExpression(node.thenExpression);
1363 node.elseExpression = visitExpression(node.elseExpression);
1364 return node;
1365 }
1366
1367 visitLogicalOperator(LogicalOperator node) {
1368 node.left = visitExpression(node.left);
1369 node.right = visitExpression(node.right);
1370 return node;
1371 }
1372
1373 visitNot(Not node) {
1374 node.operand = visitExpression(node.operand);
1375 return node;
1376 }
1377
1378 visitLiteralList(LiteralList node) {
1379 _replaceExpressions(node.values);
1380 return node;
1381 }
1382
1383 visitTypeOperator(TypeOperator node) {
1384 node.value = visitExpression(node.value);
1385 _replaceExpressions(node.typeArguments);
1386 return node;
1387 }
1388
1389 visitLabeledStatement(LabeledStatement node) {
1390 node.body = visitStatement(node.body);
1391 node.next = visitStatement(node.next);
1392 return node;
1393 }
1394
1395 visitReturn(Return node) {
1396 node.value = visitExpression(node.value);
1397 return node;
1398 }
1399
1400 visitThrow(Throw node) {
1401 node.value = visitExpression(node.value);
1402 return node;
1403 }
1404
1405 visitBreak(Break node) => node;
1406
1407 visitContinue(Continue node) => node;
1408
1409 visitIf(If node) {
1410 node.condition = visitExpression(node.condition);
1411 node.thenStatement = visitStatement(node.thenStatement);
1412 node.elseStatement = visitStatement(node.elseStatement);
1413 return node;
1414 }
1415
1416 visitWhileTrue(WhileTrue node) {
1417 node.body = visitStatement(node.body);
1418 return node;
1419 }
1420
1421 visitFor(For node) {
1422 node.condition = visitExpression(node.condition);
1423 _replaceExpressions(node.updates);
1424 node.body = visitStatement(node.body);
1425 node.next = visitStatement(node.next);
1426 return node;
1427 }
1428
1429 visitExpressionStatement(ExpressionStatement node) {
1430 // Iterate over chains of expression statements to avoid deep recursion.
1431 Statement first = node;
1432 while (true) {
1433 node.expression = visitExpression(node.expression);
1434 if (node.next is ExpressionStatement) {
1435 node = node.next;
1436 } else {
1437 break;
1438 }
1439 }
1440 node.next = visitStatement(node.next);
1441 return first;
1442 }
1443
1444 visitTry(Try node) {
1445 node.tryBody = visitStatement(node.tryBody);
1446 node.catchBody = visitStatement(node.catchBody);
1447 return node;
1448 }
1449
1450 visitGetField(GetField node) {
1451 node.object = visitExpression(node.object);
1452 return node;
1453 }
1454
1455 visitSetField(SetField node) {
1456 node.object = visitExpression(node.object);
1457 node.value = visitExpression(node.value);
1458 return node;
1459 }
1460
1461 visitGetStatic(GetStatic node) => node;
1462
1463 visitSetStatic(SetStatic node) {
1464 node.value = visitExpression(node.value);
1465 return node;
1466 }
1467
1468 visitGetTypeTestProperty(GetTypeTestProperty node) {
1469 node.object = visitExpression(node.object);
1470 return node;
1471 }
1472
1473 visitCreateBox(CreateBox node) => node;
1474
1475 visitCreateInstance(CreateInstance node) {
1476 _replaceExpressions(node.arguments);
1477 if (node.typeInformation != null) {
1478 node.typeInformation = visitExpression(node.typeInformation);
1479 }
1480 return node;
1481 }
1482
1483 visitReifyRuntimeType(ReifyRuntimeType node) {
1484 node.value = visitExpression(node.value);
1485 return node;
1486 }
1487
1488 visitReadTypeVariable(ReadTypeVariable node) {
1489 node.target = visitExpression(node.target);
1490 return node;
1491 }
1492
1493 visitTypeExpression(TypeExpression node) {
1494 _replaceExpressions(node.arguments);
1495 return node;
1496 }
1497
1498 visitCreateInvocationMirror(CreateInvocationMirror node) {
1499 _replaceExpressions(node.arguments);
1500 return node;
1501 }
1502
1503 visitForeignExpression(ForeignExpression node) {
1504 _replaceExpressions(node.arguments);
1505 return node;
1506 }
1507
1508 visitForeignStatement(ForeignStatement node) {
1509 _replaceExpressions(node.arguments);
1510 return node;
1511 }
1512
1513 visitUnreachable(Unreachable node) {
1514 return node;
1515 }
1516
1517 visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
1518 _replaceExpressions(node.arguments);
1519 return node;
1520 }
1521
1522 visitApplyBuiltinMethod(ApplyBuiltinMethod node) {
1523 node.receiver = visitExpression(node.receiver);
1524 _replaceExpressions(node.arguments);
1525 return node;
1526 }
1527
1528 visitInterceptor(Interceptor node) {
1529 node.input = visitExpression(node.input);
1530 return node;
1531 }
1532
1533 visitGetLength(GetLength node) {
1534 node.object = visitExpression(node.object);
1535 return node;
1536 }
1537
1538 visitGetIndex(GetIndex node) {
1539 node.object = visitExpression(node.object);
1540 node.index = visitExpression(node.index);
1541 return node;
1542 }
1543
1544 visitSetIndex(SetIndex node) {
1545 node.object = visitExpression(node.object);
1546 node.index = visitExpression(node.index);
1547 node.value = visitExpression(node.value);
1548 return node;
1549 }
1550
1551 visitAwait(Await node) {
1552 node.input = visitExpression(node.input);
1553 return node;
1554 }
1555
1556 visitYield(Yield node) {
1557 node.input = visitExpression(node.input);
1558 node.next = visitStatement(node.next);
1559 return node;
1560 }
1561
1562 visitReceiverCheck(ReceiverCheck node) {
1563 if (node.condition != null) {
1564 node.condition = visitExpression(node.condition);
1565 }
1566 node.value = visitExpression(node.value);
1567 node.next = visitStatement(node.next);
1568 return node;
1569 }
1570 }
1571
1572 class FallthroughTarget {
1573 final Statement target;
1574 int useCount = 0;
1575
1576 FallthroughTarget(this.target);
1577 }
1578
1579 /// A stack machine for tracking fallthrough while traversing the Tree IR.
1580 class FallthroughStack {
1581 final List<FallthroughTarget> _stack = <FallthroughTarget>[
1582 new FallthroughTarget(null)
1583 ];
1584
1585 /// Set a new fallthrough target.
1586 void push(Statement newFallthrough) {
1587 _stack.add(new FallthroughTarget(newFallthrough));
1588 }
1589
1590 /// Remove the current fallthrough target.
1591 void pop() {
1592 _stack.removeLast();
1593 }
1594
1595 /// The current fallthrough target, or `null` if control will fall over
1596 /// the end of the method.
1597 Statement get target => _stack.last.target;
1598
1599 /// Number of uses of the current fallthrough target.
1600 int get useCount => _stack.last.useCount;
1601
1602 /// Indicate that a statement will fall through to the current fallthrough
1603 /// target.
1604 void use() {
1605 ++_stack.last.useCount;
1606 }
1607 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/tree_ir/tree_ir_integrity.dart ('k') | pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698