| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 | |
| 5 // IrNodes are kept in a separate library to have precise control over their | |
| 6 // dependencies on other parts of the system. | |
| 7 library dart2js.ir_nodes; | 4 library dart2js.ir_nodes; |
| 8 | 5 |
| 9 import '../constants/expressions.dart'; | 6 import '../constants/expressions.dart'; |
| 10 import '../constants/values.dart' as values show ConstantValue; | 7 import '../constants/values.dart' as values show ConstantValue; |
| 11 import '../dart_types.dart' show DartType, GenericType, TypeVariableType; | 8 import '../dart_types.dart' show DartType, InterfaceType, TypeVariableType; |
| 12 import '../dart2jslib.dart' as dart2js show | |
| 13 CURRENT_ELEMENT_SPANNABLE, | |
| 14 InternalErrorFunction, | |
| 15 invariant; | |
| 16 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
| 17 import '../io/source_information.dart' show SourceInformation; | 10 import '../io/source_information.dart' show SourceInformation; |
| 18 import '../universe/universe.dart' show Selector, SelectorKind; | 11 import '../universe/universe.dart' show Selector, SelectorKind; |
| 19 | 12 |
| 20 abstract class Node { | 13 abstract class Node { |
| 21 /// A pointer to the parent node. Is null until set by optimization passes. | 14 /// A pointer to the parent node. Is null until set by optimization passes. |
| 22 Node parent; | 15 Node parent; |
| 23 | 16 |
| 24 accept(Visitor visitor); | 17 accept(Visitor visitor); |
| 25 } | 18 } |
| 26 | 19 |
| 20 /// Expressions can be evaluated, and may diverge, throw, and/or have |
| 21 /// side-effects. |
| 22 /// |
| 23 /// Evaluation continues by stepping into a sub-expression, invoking a |
| 24 /// continuation, or throwing an exception. |
| 25 /// |
| 26 /// Expressions do not a return value. Expressions that produce values should |
| 27 /// invoke a [Continuation] with the result as argument. Alternatively, values |
| 28 /// that can be obtained without side-effects, divergence, or throwing |
| 29 /// exceptions can be built using a [LetPrim]. |
| 27 abstract class Expression extends Node { | 30 abstract class Expression extends Node { |
| 28 Expression plug(Expression expr) => throw 'impossible'; | 31 Expression plug(Expression expr) => throw 'impossible'; |
| 29 } | 32 } |
| 30 | 33 |
| 31 /// The base class of things that variables can refer to: primitives, | 34 /// The base class of things that variables can refer to: primitives, |
| 32 /// continuations, function and continuation parameters, etc. | 35 /// continuations, function and continuation parameters, etc. |
| 33 abstract class Definition<T extends Definition<T>> extends Node { | 36 abstract class Definition<T extends Definition<T>> extends Node { |
| 34 // The head of a linked-list of occurrences, in no particular order. | 37 // The head of a linked-list of occurrences, in no particular order. |
| 35 Reference<T> firstRef; | 38 Reference<T> firstRef; |
| 36 | 39 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 52 previous.next = firstRef; | 55 previous.next = firstRef; |
| 53 if (firstRef != null) firstRef.previous = previous; | 56 if (firstRef != null) firstRef.previous = previous; |
| 54 firstRef = other.firstRef; | 57 firstRef = other.firstRef; |
| 55 other.firstRef = null; | 58 other.firstRef = null; |
| 56 } | 59 } |
| 57 } | 60 } |
| 58 | 61 |
| 59 /// An expression that cannot throw or diverge and has no side-effects. | 62 /// An expression that cannot throw or diverge and has no side-effects. |
| 60 /// All primitives are named using the identity of the [Primitive] object. | 63 /// All primitives are named using the identity of the [Primitive] object. |
| 61 /// | 64 /// |
| 62 /// Primitives may allocate objects, this is not considered side-effect here. | 65 /// Primitives may allocate objects; this is not considered side-effect here. |
| 63 /// | 66 /// |
| 64 /// Although primitives may not mutate state, they may depend on state. | 67 /// Although primitives may not mutate state, they may depend on state. |
| 68 /// |
| 69 /// All primitives except [Parameter] must be bound by a [LetPrim]. |
| 65 abstract class Primitive extends Definition<Primitive> { | 70 abstract class Primitive extends Definition<Primitive> { |
| 66 /// The [VariableElement] or [ParameterElement] from which the primitive | 71 /// The [VariableElement] or [ParameterElement] from which the primitive |
| 67 /// binding originated. | 72 /// binding originated. |
| 68 Entity hint; | 73 Entity hint; |
| 69 | 74 |
| 70 /// Use the given element as a hint for naming this primitive. | 75 /// Use the given element as a hint for naming this primitive. |
| 71 /// | 76 /// |
| 72 /// Has no effect if this primitive already has a non-null [element]. | 77 /// Has no effect if this primitive already has a non-null [element]. |
| 73 void useElementAsHint(Entity hint) { | 78 void useElementAsHint(Entity hint) { |
| 74 if (this.hint == null) { | 79 if (this.hint == null) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 98 if (previous == null) { | 103 if (previous == null) { |
| 99 assert(definition.firstRef == this); | 104 assert(definition.firstRef == this); |
| 100 definition.firstRef = next; | 105 definition.firstRef = next; |
| 101 } else { | 106 } else { |
| 102 previous.next = next; | 107 previous.next = next; |
| 103 } | 108 } |
| 104 if (next != null) next.previous = previous; | 109 if (next != null) next.previous = previous; |
| 105 } | 110 } |
| 106 } | 111 } |
| 107 | 112 |
| 108 /// Binding a value (primitive or constant): 'let val x = V in E'. The bound | 113 /// Evaluates a primitive and binds it to variable: `let val x = V in E`. |
| 109 /// value is in scope in the body. | 114 /// |
| 110 /// During one-pass construction a LetVal with an empty body is used to | 115 /// The bound value is in scope in the body. |
| 111 /// represent the one-hole context 'let val x = V in []'. | 116 /// |
| 117 /// During one-pass construction a LetPrim with an empty body is used to |
| 118 /// represent the one-hole context `let val x = V in []`. |
| 112 class LetPrim extends Expression implements InteriorNode { | 119 class LetPrim extends Expression implements InteriorNode { |
| 113 final Primitive primitive; | 120 final Primitive primitive; |
| 114 Expression body; | 121 Expression body; |
| 115 | 122 |
| 116 LetPrim(this.primitive, [this.body = null]); | 123 LetPrim(this.primitive, [this.body = null]); |
| 117 | 124 |
| 118 Expression plug(Expression expr) { | 125 Expression plug(Expression expr) { |
| 119 assert(body == null); | 126 assert(body == null); |
| 120 return body = expr; | 127 return body = expr; |
| 121 } | 128 } |
| 122 | 129 |
| 123 accept(Visitor visitor) => visitor.visitLetPrim(this); | 130 accept(Visitor visitor) => visitor.visitLetPrim(this); |
| 124 } | 131 } |
| 125 | 132 |
| 126 | 133 |
| 127 /// Binding continuations. | 134 /// Binding continuations. |
| 128 /// | 135 /// |
| 129 /// let cont k0(v0 ...) = E0 | 136 /// let cont k0(v0 ...) = E0 |
| 130 /// k1(v1 ...) = E1 | 137 /// k1(v1 ...) = E1 |
| 131 /// ... | 138 /// ... |
| 132 /// in E | 139 /// in E |
| 133 /// | 140 /// |
| 134 /// The bound continuations are in scope in the body and the continuation | 141 /// The bound continuations are in scope in the body and the continuation |
| 135 /// parameters are in scope in the respective continuation bodies. | 142 /// parameters are in scope in the respective continuation bodies. |
| 143 /// |
| 136 /// During one-pass construction a LetCont whose first continuation has an empty | 144 /// During one-pass construction a LetCont whose first continuation has an empty |
| 137 /// body is used to represent the one-hole context | 145 /// body is used to represent the one-hole context |
| 138 /// 'let cont ... k(v) = [] ... in E'. | 146 /// `let cont ... k(v) = [] ... in E`. |
| 139 class LetCont extends Expression implements InteriorNode { | 147 class LetCont extends Expression implements InteriorNode { |
| 140 List<Continuation> continuations; | 148 List<Continuation> continuations; |
| 141 Expression body; | 149 Expression body; |
| 142 | 150 |
| 143 LetCont(Continuation continuation, this.body) | 151 LetCont(Continuation continuation, this.body) |
| 144 : continuations = <Continuation>[continuation]; | 152 : continuations = <Continuation>[continuation]; |
| 145 | 153 |
| 146 LetCont.many(this.continuations, this.body); | 154 LetCont.many(this.continuations, this.body); |
| 147 | 155 |
| 148 Expression plug(Expression expr) { | 156 Expression plug(Expression expr) { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 /// Node child = node.body; | 216 /// Node child = node.body; |
| 209 /// InteriorNode parent = node.parent; | 217 /// InteriorNode parent = node.parent; |
| 210 /// | 218 /// |
| 211 /// child.parent = parent; | 219 /// child.parent = parent; |
| 212 /// parent.body = child; | 220 /// parent.body = child; |
| 213 abstract class InteriorNode extends Node { | 221 abstract class InteriorNode extends Node { |
| 214 Expression get body; | 222 Expression get body; |
| 215 void set body(Expression body); | 223 void set body(Expression body); |
| 216 } | 224 } |
| 217 | 225 |
| 218 /// Invoke a static function or static getter/setter. | 226 /// Invoke a static function. |
| 227 /// |
| 228 /// All optional arguments declared by [target] are passed in explicitly, and |
| 229 /// occur at the end of [arguments] list, in normalized order. |
| 230 /// |
| 231 /// Discussion: |
| 232 /// All information in the [selector] is technically redundant; it will likely |
| 233 /// be removed. |
| 219 class InvokeStatic extends Expression implements Invoke { | 234 class InvokeStatic extends Expression implements Invoke { |
| 220 /// [FunctionElement] or [FieldElement]. | 235 final FunctionElement target; |
| 221 final Entity target; | |
| 222 | |
| 223 /** | |
| 224 * The selector encodes how the function is invoked: number of positional | |
| 225 * arguments, names used in named arguments. This information is required | |
| 226 * to build the [StaticCallSiteTypeInformation] for the inference graph. | |
| 227 */ | |
| 228 final Selector selector; | 236 final Selector selector; |
| 229 | |
| 230 final List<Reference<Primitive>> arguments; | 237 final List<Reference<Primitive>> arguments; |
| 231 final Reference<Continuation> continuation; | 238 final Reference<Continuation> continuation; |
| 232 final SourceInformation sourceInformation; | 239 final SourceInformation sourceInformation; |
| 233 | 240 |
| 234 InvokeStatic(this.target, | 241 InvokeStatic(this.target, |
| 235 this.selector, | 242 this.selector, |
| 236 List<Primitive> args, | 243 List<Primitive> args, |
| 237 Continuation cont, | 244 Continuation cont, |
| 238 this.sourceInformation) | 245 this.sourceInformation) |
| 239 : arguments = _referenceList(args), | 246 : arguments = _referenceList(args), |
| 240 continuation = new Reference<Continuation>(cont) { | 247 continuation = new Reference<Continuation>(cont); |
| 241 assert(target is ErroneousElement || selector.name == target.name); | |
| 242 } | |
| 243 | 248 |
| 244 accept(Visitor visitor) => visitor.visitInvokeStatic(this); | 249 accept(Visitor visitor) => visitor.visitInvokeStatic(this); |
| 245 } | 250 } |
| 246 | 251 |
| 247 /// A [CallingConvention] codifies how arguments are matched to parameters when | 252 /// Invoke a method on an object. |
| 248 /// emitting code for a function call. | 253 /// |
| 249 class CallingConvention { | 254 /// This includes getters, setters, operators, and index getter/setters. |
| 250 final String name; | 255 /// |
| 251 const CallingConvention(this.name); | 256 /// Tearing off a method is treated like a getter invocation (getters and |
| 252 /// The normal way of calling a Dart function: Positional arguments are | 257 /// tear-offs cannot be distinguished at compile-time). |
| 253 /// matched with (mandatory and optional) positionals parameters from left to | 258 /// |
| 254 /// right and named arguments are matched by name. | 259 /// The [selector] records the names of named arguments. The value of named |
| 255 static const CallingConvention DART = const CallingConvention("Dart call"); | 260 /// arguments occur at the end of the [arguments] list, in normalized order. |
| 256 /// Intercepted calls have an additional first argument that is the actual | 261 /// |
| 257 /// receiver of the call. See the documentation of [Interceptor] for more | 262 /// Discussion: |
| 258 /// information. | 263 /// If the [selector] is a [TypedSelector], the type information contained |
| 259 static const CallingConvention JS_INTERCEPTED = | 264 /// there is used by optimization passes. This is likely to change. |
| 260 const CallingConvention("intercepted JavaScript call"); | |
| 261 } | |
| 262 | |
| 263 /// Invoke a method, operator, getter, setter, or index getter/setter. | |
| 264 /// Converting a method to a function object is treated as a getter invocation. | |
| 265 class InvokeMethod extends Expression implements Invoke { | 265 class InvokeMethod extends Expression implements Invoke { |
| 266 Reference<Primitive> receiver; | 266 Reference<Primitive> receiver; |
| 267 Selector selector; | 267 Selector selector; |
| 268 CallingConvention callingConvention; | |
| 269 final List<Reference<Primitive>> arguments; | 268 final List<Reference<Primitive>> arguments; |
| 270 final Reference<Continuation> continuation; | 269 final Reference<Continuation> continuation; |
| 271 final SourceInformation sourceInformation; | 270 final SourceInformation sourceInformation; |
| 272 | 271 |
| 273 InvokeMethod(Primitive receiver, | 272 InvokeMethod(Primitive receiver, |
| 274 Selector selector, | 273 this.selector, |
| 275 List<Primitive> arguments, | 274 List<Primitive> arguments, |
| 276 Continuation continuation, | 275 Continuation continuation, |
| 277 {SourceInformation sourceInformation}) | 276 {this.sourceInformation}) |
| 278 : this.internal(new Reference<Primitive>(receiver), | 277 : this.receiver = new Reference<Primitive>(receiver), |
| 279 selector, | 278 this.arguments = _referenceList(arguments), |
| 280 _referenceList(arguments), | 279 this.continuation = new Reference<Continuation>(continuation); |
| 281 new Reference<Continuation>(continuation), | |
| 282 sourceInformation); | |
| 283 | |
| 284 InvokeMethod.internal(this.receiver, | |
| 285 this.selector, | |
| 286 this.arguments, | |
| 287 this.continuation, | |
| 288 this.sourceInformation, | |
| 289 [this.callingConvention = CallingConvention.DART]) { | |
| 290 assert(isValid); | |
| 291 } | |
| 292 | |
| 293 /// Returns whether the arguments match the selector under the given calling | |
| 294 /// convention. | |
| 295 /// | |
| 296 /// This check is designed to be used in an assert, as it also checks that the | |
| 297 /// selector, arguments, and calling convention have meaningful values. | |
| 298 bool get isValid { | |
| 299 if (selector == null || callingConvention == null) return false; | |
| 300 if (callingConvention != CallingConvention.DART && | |
| 301 callingConvention != CallingConvention.JS_INTERCEPTED) { | |
| 302 return false; | |
| 303 } | |
| 304 int numberOfArguments = | |
| 305 callingConvention == CallingConvention.JS_INTERCEPTED | |
| 306 ? arguments.length - 1 | |
| 307 : arguments.length; | |
| 308 return selector.kind == SelectorKind.CALL || | |
| 309 selector.kind == SelectorKind.OPERATOR || | |
| 310 (selector.kind == SelectorKind.GETTER && numberOfArguments == 0) || | |
| 311 (selector.kind == SelectorKind.SETTER && numberOfArguments == 1) || | |
| 312 (selector.kind == SelectorKind.INDEX && numberOfArguments == 1) || | |
| 313 (selector.kind == SelectorKind.INDEX && numberOfArguments == 2); | |
| 314 } | |
| 315 | 280 |
| 316 accept(Visitor visitor) => visitor.visitInvokeMethod(this); | 281 accept(Visitor visitor) => visitor.visitInvokeMethod(this); |
| 317 } | 282 } |
| 318 | 283 |
| 319 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. | 284 /// Invoke [target] on [receiver], bypassing dispatch and override semantics. |
| 320 /// | 285 /// |
| 321 /// That is, if [receiver] is an instance of a class that overrides [target] | 286 /// That is, if [receiver] is an instance of a class that overrides [target] |
| 322 /// with a different implementation, the overriding implementation is bypassed | 287 /// with a different implementation, the overriding implementation is bypassed |
| 323 /// and [target]'s implementation is invoked. | 288 /// and [target]'s implementation is invoked. |
| 324 /// | 289 /// |
| 325 /// As with [InvokeMethod], this can be used to invoke a method, operator, | 290 /// As with [InvokeMethod], this can be used to invoke a method, operator, |
| 326 /// getter, setter, or index getter/setter. | 291 /// getter, setter, or index getter/setter. |
| 327 /// | 292 /// |
| 328 /// If it is known that [target] does not use its receiver argument, then | 293 /// If it is known that [target] does not use its receiver argument, then |
| 329 /// [receiver] may refer to a null constant primitive. This happens for direct | 294 /// [receiver] may refer to a null constant primitive. This happens for direct |
| 330 /// invocations to intercepted methods, where the effective receiver is instead | 295 /// invocations to intercepted methods, where the effective receiver is instead |
| 331 /// passed as a formal parameter. | 296 /// passed as a formal parameter. |
| 332 /// | 297 /// |
| 333 /// TODO(sra): Review. A direct call to a method that is mixed into a native | 298 /// TODO(sra): Review. A direct call to a method that is mixed into a native |
| 334 /// class will still require an explicit argument. | 299 /// class will still require an explicit argument. |
| 335 /// | 300 /// |
| 336 /// When targeting Dart, this instruction is used to represent super calls. | 301 /// All optional arguments declared by [target] are passed in explicitly, and |
| 337 /// Here, [receiver] must always be a reference to `this`, and [target] must be | 302 /// occur at the end of [arguments] list, in normalized order. |
| 338 /// a method that is available in the super class. | |
| 339 class InvokeMethodDirectly extends Expression implements Invoke { | 303 class InvokeMethodDirectly extends Expression implements Invoke { |
| 340 Reference<Primitive> receiver; | 304 Reference<Primitive> receiver; |
| 341 final Element target; | 305 final FunctionElement target; |
| 342 final Selector selector; | 306 final Selector selector; |
| 343 final List<Reference<Primitive>> arguments; | 307 final List<Reference<Primitive>> arguments; |
| 344 final Reference<Continuation> continuation; | 308 final Reference<Continuation> continuation; |
| 345 | 309 |
| 346 InvokeMethodDirectly(Primitive receiver, | 310 InvokeMethodDirectly(Primitive receiver, |
| 347 this.target, | 311 this.target, |
| 348 this.selector, | 312 this.selector, |
| 349 List<Primitive> args, | 313 List<Primitive> arguments, |
| 350 Continuation cont) | 314 Continuation continuation) |
| 351 : this.receiver = new Reference<Primitive>(receiver), | 315 : this.receiver = new Reference<Primitive>(receiver), |
| 352 arguments = _referenceList(args), | 316 this.arguments = _referenceList(arguments), |
| 353 continuation = new Reference<Continuation>(cont) { | 317 this.continuation = new Reference<Continuation>(continuation); |
| 354 assert(selector != null); | |
| 355 assert(selector.kind == SelectorKind.CALL || | |
| 356 selector.kind == SelectorKind.OPERATOR || | |
| 357 (selector.kind == SelectorKind.GETTER && arguments.isEmpty) || | |
| 358 (selector.kind == SelectorKind.SETTER && arguments.length == 1) || | |
| 359 (selector.kind == SelectorKind.INDEX && arguments.length == 1) || | |
| 360 (selector.kind == SelectorKind.INDEX && arguments.length == 2)); | |
| 361 } | |
| 362 | 318 |
| 363 accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this); | 319 accept(Visitor visitor) => visitor.visitInvokeMethodDirectly(this); |
| 364 } | 320 } |
| 365 | 321 |
| 366 /// Non-const call to a constructor. The [target] may be a generative | 322 /// Non-const call to a constructor. |
| 367 /// constructor, factory, or redirecting factory. | 323 /// |
| 324 /// The [target] may be a generative constructor (forwarding or normal) |
| 325 /// or a non-redirecting factory. |
| 326 /// |
| 327 /// All optional arguments declared by [target] are passed in explicitly, and |
| 328 /// occur in the [arguments] list, in normalized order. |
| 329 /// |
| 330 /// Last in the [arguments] list, after the mandatory and optional arguments, |
| 331 /// the internal representation of each type argument occurs, unless it could |
| 332 /// be determined at build-time that the constructed class has no need for its |
| 333 /// runtime type information. |
| 334 /// |
| 335 /// Note that [InvokeConstructor] does it itself allocate an object. |
| 336 /// The invoked constructor will do that using [CreateInstance]. |
| 368 class InvokeConstructor extends Expression implements Invoke { | 337 class InvokeConstructor extends Expression implements Invoke { |
| 369 final DartType type; | 338 final DartType type; |
| 370 final FunctionElement target; | 339 final ConstructorElement target; |
| 371 final List<Reference<Primitive>> arguments; | 340 final List<Reference<Primitive>> arguments; |
| 372 final Reference<Continuation> continuation; | 341 final Reference<Continuation> continuation; |
| 373 final Selector selector; | 342 final Selector selector; |
| 374 | 343 |
| 375 /// The class being instantiated. This is the same as `target.enclosingClass` | |
| 376 /// and `type.element`. | |
| 377 ClassElement get targetClass => target.enclosingElement; | |
| 378 | |
| 379 /// True if this is an invocation of a factory constructor. | |
| 380 bool get isFactory => target.isFactoryConstructor; | |
| 381 | |
| 382 InvokeConstructor(this.type, | 344 InvokeConstructor(this.type, |
| 383 this.target, | 345 this.target, |
| 384 this.selector, | 346 this.selector, |
| 385 List<Primitive> args, | 347 List<Primitive> args, |
| 386 Continuation cont) | 348 Continuation cont) |
| 387 : arguments = _referenceList(args), | 349 : arguments = _referenceList(args), |
| 388 continuation = new Reference<Continuation>(cont) { | 350 continuation = new Reference<Continuation>(cont); |
| 389 assert(dart2js.invariant(target, | |
| 390 target.isErroneous || | |
| 391 type.isDynamic || | |
| 392 type.element == target.enclosingClass.declaration, | |
| 393 message: "Constructor invocation target is not a constructor: " | |
| 394 "$target.")); | |
| 395 } | |
| 396 | 351 |
| 397 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); | 352 accept(Visitor visitor) => visitor.visitInvokeConstructor(this); |
| 398 } | 353 } |
| 399 | 354 |
| 400 /// "as" casts and "is" checks. | 355 // TODO(asgerf): Make a Primitive for "is" and an Expression for "as". |
| 401 // We might want to turn "is"-checks into a [Primitive] as it can never diverge. | 356 |
| 402 // But then we need to special-case for is-checks with an erroneous .type as | 357 /// An "as" cast or an "is" check. |
| 403 // these will throw. | |
| 404 class TypeOperator extends Expression { | 358 class TypeOperator extends Expression { |
| 405 Reference<Primitive> value; | 359 Reference<Primitive> value; |
| 406 final DartType type; | 360 final DartType type; |
| 407 | 361 |
| 408 /// If [type] is a [GenericType], this holds the internal representation of | 362 /// If [type] is an [InterfaceType], this holds the internal representation of |
| 409 /// the type arguments to [type]. Since these may reference type variables | 363 /// the type arguments to [type]. Since these may reference type variables |
| 410 /// from the enclosing class, they are not constant. | 364 /// from the enclosing class, they are not constant. |
| 411 /// | 365 /// |
| 412 /// If [type] is a [TypeVariableType], this is a singleton list with | 366 /// If [type] is a [TypeVariableType], this is a singleton list with |
| 413 /// the internal representation of the type held in that type variable. | 367 /// the internal representation of the type held in that type variable. |
| 414 /// | 368 /// |
| 415 /// Otherwise the list is empty. | 369 /// Otherwise the list is empty. |
| 416 final List<Reference<Primitive>> typeArguments; | 370 final List<Reference<Primitive>> typeArguments; |
| 417 final Reference<Continuation> continuation; | 371 final Reference<Continuation> continuation; |
| 418 // TODO(johnniwinther): Use `Operator` class to encapsule the operator type. | |
| 419 final bool isTypeTest; | 372 final bool isTypeTest; |
| 420 | 373 |
| 421 TypeOperator(Primitive value, | 374 TypeOperator(Primitive value, |
| 422 this.type, | 375 this.type, |
| 423 List<Primitive> typeArguments, | 376 List<Primitive> typeArguments, |
| 424 Continuation cont, | 377 Continuation cont, |
| 425 {bool this.isTypeTest}) | 378 {bool this.isTypeTest}) |
| 426 : this.value = new Reference<Primitive>(value), | 379 : this.value = new Reference<Primitive>(value), |
| 427 this.typeArguments = _referenceList(typeArguments), | 380 this.typeArguments = _referenceList(typeArguments), |
| 428 this.continuation = new Reference<Continuation>(cont) { | 381 this.continuation = new Reference<Continuation>(cont) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 this.value = new Reference<Primitive>(value); | 466 this.value = new Reference<Primitive>(value); |
| 514 | 467 |
| 515 accept(Visitor visitor) => visitor.visitSetMutableVariable(this); | 468 accept(Visitor visitor) => visitor.visitSetMutableVariable(this); |
| 516 | 469 |
| 517 Expression plug(Expression expr) { | 470 Expression plug(Expression expr) { |
| 518 assert(body == null); | 471 assert(body == null); |
| 519 return body = expr; | 472 return body = expr; |
| 520 } | 473 } |
| 521 } | 474 } |
| 522 | 475 |
| 523 /// Create a potentially recursive function and store it in a [MutableVariable]. | |
| 524 /// The function can access itself using [GetMutableVariable] on [variable]. | |
| 525 /// There must not exist a [SetMutableVariable] to [variable]. | |
| 526 /// | |
| 527 /// This can be seen as a let rec binding: | |
| 528 /// | |
| 529 /// let rec [variable] = [definition] in [body] | |
| 530 /// | |
| 531 class DeclareFunction extends Expression | |
| 532 implements InteriorNode, DartSpecificNode { | |
| 533 final MutableVariable variable; | |
| 534 final FunctionDefinition definition; | |
| 535 Expression body; | |
| 536 | |
| 537 DeclareFunction(this.variable, this.definition); | |
| 538 | |
| 539 Expression plug(Expression expr) { | |
| 540 assert(body == null); | |
| 541 return body = expr; | |
| 542 } | |
| 543 | |
| 544 accept(Visitor visitor) => visitor.visitDeclareFunction(this); | |
| 545 } | |
| 546 | |
| 547 /// Invoke a continuation in tail position. | 476 /// Invoke a continuation in tail position. |
| 548 class InvokeContinuation extends Expression { | 477 class InvokeContinuation extends Expression { |
| 549 Reference<Continuation> continuation; | 478 Reference<Continuation> continuation; |
| 550 List<Reference<Primitive>> arguments; | 479 List<Reference<Primitive>> arguments; |
| 551 | 480 |
| 552 // An invocation of a continuation is recursive if it occurs in the body of | 481 // An invocation of a continuation is recursive if it occurs in the body of |
| 553 // the continuation itself. | 482 // the continuation itself. |
| 554 bool isRecursive; | 483 bool isRecursive; |
| 555 | 484 |
| 556 InvokeContinuation(Continuation cont, List<Primitive> args, | 485 InvokeContinuation(Continuation cont, List<Primitive> args, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 579 | 508 |
| 580 class IsTrue extends Condition { | 509 class IsTrue extends Condition { |
| 581 final Reference<Primitive> value; | 510 final Reference<Primitive> value; |
| 582 | 511 |
| 583 IsTrue(Primitive val) : value = new Reference<Primitive>(val); | 512 IsTrue(Primitive val) : value = new Reference<Primitive>(val); |
| 584 | 513 |
| 585 accept(Visitor visitor) => visitor.visitIsTrue(this); | 514 accept(Visitor visitor) => visitor.visitIsTrue(this); |
| 586 } | 515 } |
| 587 | 516 |
| 588 /// Choose between a pair of continuations based on a condition value. | 517 /// Choose between a pair of continuations based on a condition value. |
| 518 /// |
| 519 /// The two continuations must not declare any parameters. |
| 589 class Branch extends Expression { | 520 class Branch extends Expression { |
| 590 final Condition condition; | 521 final Condition condition; |
| 591 final Reference<Continuation> trueContinuation; | 522 final Reference<Continuation> trueContinuation; |
| 592 final Reference<Continuation> falseContinuation; | 523 final Reference<Continuation> falseContinuation; |
| 593 | 524 |
| 594 Branch(this.condition, Continuation trueCont, Continuation falseCont) | 525 Branch(this.condition, Continuation trueCont, Continuation falseCont) |
| 595 : trueContinuation = new Reference<Continuation>(trueCont), | 526 : trueContinuation = new Reference<Continuation>(trueCont), |
| 596 falseContinuation = new Reference<Continuation>(falseCont); | 527 falseContinuation = new Reference<Continuation>(falseCont); |
| 597 | 528 |
| 598 accept(Visitor visitor) => visitor.visitBranch(this); | 529 accept(Visitor visitor) => visitor.visitBranch(this); |
| 599 } | 530 } |
| 600 | 531 |
| 601 /// Marker interface for nodes that are only handled in the JavaScript backend. | |
| 602 /// | |
| 603 /// These nodes are generated by the unsugar step or the [JsIrBuilder] and need | |
| 604 /// special translation to the Tree IR, which is implemented in JsTreeBuilder. | |
| 605 abstract class JsSpecificNode implements Node {} | |
| 606 | |
| 607 /// Marker interface for nodes that are only handled inthe Dart backend. | |
| 608 abstract class DartSpecificNode implements Node {} | |
| 609 | |
| 610 /// Directly assigns to a field on a given object. | 532 /// Directly assigns to a field on a given object. |
| 611 class SetField extends Expression implements InteriorNode, JsSpecificNode { | 533 class SetField extends Expression implements InteriorNode { |
| 612 final Reference<Primitive> object; | 534 final Reference<Primitive> object; |
| 613 Element field; | 535 FieldElement field; |
| 614 final Reference<Primitive> value; | 536 final Reference<Primitive> value; |
| 615 Expression body; | 537 Expression body; |
| 616 | 538 |
| 617 SetField(Primitive object, this.field, Primitive value) | 539 SetField(Primitive object, this.field, Primitive value) |
| 618 : this.object = new Reference<Primitive>(object), | 540 : this.object = new Reference<Primitive>(object), |
| 619 this.value = new Reference<Primitive>(value); | 541 this.value = new Reference<Primitive>(value); |
| 620 | 542 |
| 621 Expression plug(Expression expr) { | 543 Expression plug(Expression expr) { |
| 622 assert(body == null); | 544 assert(body == null); |
| 623 return body = expr; | 545 return body = expr; |
| 624 } | 546 } |
| 625 | 547 |
| 626 accept(Visitor visitor) => visitor.visitSetField(this); | 548 accept(Visitor visitor) => visitor.visitSetField(this); |
| 627 } | 549 } |
| 628 | 550 |
| 629 /// Directly reads from a field on a given object. | 551 /// Directly reads from a field on a given object. |
| 630 class GetField extends Primitive implements JsSpecificNode { | 552 class GetField extends Primitive { |
| 631 final Reference<Primitive> object; | 553 final Reference<Primitive> object; |
| 632 Element field; | 554 FieldElement field; |
| 633 | 555 |
| 634 GetField(Primitive object, this.field) | 556 GetField(Primitive object, this.field) |
| 635 : this.object = new Reference<Primitive>(object); | 557 : this.object = new Reference<Primitive>(object); |
| 636 | 558 |
| 637 accept(Visitor visitor) => visitor.visitGetField(this); | 559 accept(Visitor visitor) => visitor.visitGetField(this); |
| 638 } | 560 } |
| 639 | 561 |
| 640 /// Reads the value of a static field or tears off a static method. | 562 /// Reads the value of a static field or tears off a static method. |
| 641 class GetStatic extends Primitive { | 563 class GetStatic extends Primitive { |
| 564 /// Can be [FieldElement] or [FunctionElement]. |
| 642 final Element element; | 565 final Element element; |
| 643 final SourceInformation sourceInformation; | 566 final SourceInformation sourceInformation; |
| 644 | 567 |
| 645 GetStatic(this.element, this.sourceInformation); | 568 GetStatic(this.element, this.sourceInformation); |
| 646 | 569 |
| 647 accept(Visitor visitor) => visitor.visitGetStatic(this); | 570 accept(Visitor visitor) => visitor.visitGetStatic(this); |
| 648 } | 571 } |
| 649 | 572 |
| 650 /// Sets the value of a static field. | 573 /// Sets the value of a static field. |
| 651 class SetStatic extends Expression implements InteriorNode { | 574 class SetStatic extends Expression implements InteriorNode { |
| 652 final Element element; | 575 final FieldElement element; |
| 653 final Reference<Primitive> value; | 576 final Reference<Primitive> value; |
| 654 Expression body; | 577 Expression body; |
| 655 final SourceInformation sourceInformation; | 578 final SourceInformation sourceInformation; |
| 656 | 579 |
| 657 SetStatic(this.element, Primitive value, this.sourceInformation) | 580 SetStatic(this.element, Primitive value, this.sourceInformation) |
| 658 : this.value = new Reference<Primitive>(value); | 581 : this.value = new Reference<Primitive>(value); |
| 659 | 582 |
| 660 Expression plug(Expression expr) { | 583 Expression plug(Expression expr) { |
| 661 assert(body == null); | 584 assert(body == null); |
| 662 return body = expr; | 585 return body = expr; |
| 663 } | 586 } |
| 664 | 587 |
| 665 accept(Visitor visitor) => visitor.visitSetStatic(this); | 588 accept(Visitor visitor) => visitor.visitSetStatic(this); |
| 666 } | 589 } |
| 667 | 590 |
| 668 /// Reads the value of a lazily initialized static field. | 591 /// Reads the value of a lazily initialized static field. |
| 669 /// | 592 /// |
| 670 /// If the field has not yet been initialized, its initializer is evaluated | 593 /// If the field has not yet been initialized, its initializer is evaluated |
| 671 /// and assigned to the field. | 594 /// and assigned to the field. |
| 672 /// | 595 /// |
| 673 /// [continuation] is then invoked with the value of the field as argument. | 596 /// [continuation] is then invoked with the value of the field as argument. |
| 674 class GetLazyStatic extends Expression { | 597 class GetLazyStatic extends Expression { |
| 675 final FieldElement element; | 598 final FieldElement element; |
| 676 final Reference<Continuation> continuation; | 599 final Reference<Continuation> continuation; |
| 677 final SourceInformation sourceInformation; | 600 final SourceInformation sourceInformation; |
| 678 | 601 |
| 679 GetLazyStatic(this.element, | 602 GetLazyStatic(this.element, |
| 680 Continuation cont, | 603 Continuation continuation, |
| 681 this.sourceInformation) | 604 this.sourceInformation) |
| 682 : continuation = new Reference<Continuation>(cont); | 605 : continuation = new Reference<Continuation>(continuation); |
| 683 | 606 |
| 684 accept(Visitor visitor) => visitor.visitGetLazyStatic(this); | 607 accept(Visitor visitor) => visitor.visitGetLazyStatic(this); |
| 685 } | 608 } |
| 686 | 609 |
| 687 /// Creates an object for holding boxed variables captured by a closure. | 610 /// Creates an object for holding boxed variables captured by a closure. |
| 688 class CreateBox extends Primitive implements JsSpecificNode { | 611 class CreateBox extends Primitive { |
| 689 accept(Visitor visitor) => visitor.visitCreateBox(this); | 612 accept(Visitor visitor) => visitor.visitCreateBox(this); |
| 690 } | 613 } |
| 691 | 614 |
| 692 /// Creates an instance of a class and initializes its fields and runtime type | 615 /// Creates an instance of a class and initializes its fields and runtime type |
| 693 /// information. | 616 /// information. |
| 694 class CreateInstance extends Primitive implements JsSpecificNode { | 617 class CreateInstance extends Primitive { |
| 695 final ClassElement classElement; | 618 final ClassElement classElement; |
| 696 | 619 |
| 697 /// Initial values for the fields on the class. | 620 /// Initial values for the fields on the class. |
| 698 /// The order corresponds to the order of fields on the class. | 621 /// The order corresponds to the order of fields on the class. |
| 699 final List<Reference<Primitive>> arguments; | 622 final List<Reference<Primitive>> arguments; |
| 700 | 623 |
| 701 /// The runtime type information structure which contains the type arguments. | 624 /// The runtime type information structure which contains the type arguments. |
| 702 /// | 625 /// |
| 703 /// May be `null` to indicate that no type information is needed because the | 626 /// May be `null` to indicate that no type information is needed because the |
| 704 /// compiler determined that the type information for instances of this class | 627 /// compiler determined that the type information for instances of this class |
| 705 /// is not needed at runtime. | 628 /// is not needed at runtime. |
| 706 final List<Reference<Primitive>> typeInformation; | 629 final List<Reference<Primitive>> typeInformation; |
| 707 | 630 |
| 708 CreateInstance(this.classElement, List<Primitive> arguments, | 631 CreateInstance(this.classElement, List<Primitive> arguments, |
| 709 List<Primitive> typeInformation) | 632 List<Primitive> typeInformation) |
| 710 : this.arguments = _referenceList(arguments), | 633 : this.arguments = _referenceList(arguments), |
| 711 this.typeInformation = _referenceList(typeInformation); | 634 this.typeInformation = _referenceList(typeInformation); |
| 712 | 635 |
| 713 accept(Visitor visitor) => visitor.visitCreateInstance(this); | 636 accept(Visitor visitor) => visitor.visitCreateInstance(this); |
| 714 } | 637 } |
| 715 | 638 |
| 716 class Identical extends Primitive implements JsSpecificNode { | 639 /// Compare objects for identity. |
| 640 /// |
| 641 /// It is an error pass in a value that does not correspond to a Dart value, |
| 642 /// such as an interceptor or a box. |
| 643 class Identical extends Primitive { |
| 717 final Reference<Primitive> left; | 644 final Reference<Primitive> left; |
| 718 final Reference<Primitive> right; | 645 final Reference<Primitive> right; |
| 719 Identical(Primitive left, Primitive right) | 646 Identical(Primitive left, Primitive right) |
| 720 : left = new Reference<Primitive>(left), | 647 : left = new Reference<Primitive>(left), |
| 721 right = new Reference<Primitive>(right); | 648 right = new Reference<Primitive>(right); |
| 722 accept(Visitor visitor) => visitor.visitIdentical(this); | 649 accept(Visitor visitor) => visitor.visitIdentical(this); |
| 723 } | 650 } |
| 724 | 651 |
| 725 class Interceptor extends Primitive implements JsSpecificNode { | 652 class Interceptor extends Primitive { |
| 726 final Reference<Primitive> input; | 653 final Reference<Primitive> input; |
| 727 final Set<ClassElement> interceptedClasses; | 654 final Set<ClassElement> interceptedClasses; |
| 728 Interceptor(Primitive input, this.interceptedClasses) | 655 Interceptor(Primitive input, this.interceptedClasses) |
| 729 : this.input = new Reference<Primitive>(input); | 656 : this.input = new Reference<Primitive>(input); |
| 730 accept(Visitor visitor) => visitor.visitInterceptor(this); | 657 accept(Visitor visitor) => visitor.visitInterceptor(this); |
| 731 } | 658 } |
| 732 | 659 |
| 733 /// Create an instance of [Invocation] for use in a call to `noSuchMethod`. | 660 /// Create an instance of [Invocation] for use in a call to `noSuchMethod`. |
| 734 class CreateInvocationMirror extends Primitive implements JsSpecificNode { | 661 class CreateInvocationMirror extends Primitive { |
| 735 final Selector selector; | 662 final Selector selector; |
| 736 final List<Reference<Primitive>> arguments; | 663 final List<Reference<Primitive>> arguments; |
| 737 | 664 |
| 738 CreateInvocationMirror(this.selector, List<Primitive> arguments) | 665 CreateInvocationMirror(this.selector, List<Primitive> arguments) |
| 739 : this.arguments = _referenceList(arguments); | 666 : this.arguments = _referenceList(arguments); |
| 740 | 667 |
| 741 accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this); | 668 accept(Visitor visitor) => visitor.visitCreateInvocationMirror(this); |
| 742 } | 669 } |
| 743 | 670 |
| 744 class Constant extends Primitive { | 671 class Constant extends Primitive { |
| 745 final ConstantExpression expression; | 672 final ConstantExpression expression; |
| 746 | 673 |
| 747 Constant(this.expression); | 674 Constant(this.expression); |
| 748 | 675 |
| 749 values.ConstantValue get value => expression.value; | 676 values.ConstantValue get value => expression.value; |
| 750 | 677 |
| 751 accept(Visitor visitor) => visitor.visitConstant(this); | 678 accept(Visitor visitor) => visitor.visitConstant(this); |
| 752 } | 679 } |
| 753 | 680 |
| 754 /// Reify the given type variable as a [Type]. | |
| 755 /// This depends on the current binding of 'this'. | |
| 756 class ReifyTypeVar extends Primitive implements DartSpecificNode { | |
| 757 final TypeVariableElement typeVariable; | |
| 758 | |
| 759 ReifyTypeVar(this.typeVariable); | |
| 760 | |
| 761 values.ConstantValue get constant => null; | |
| 762 | |
| 763 accept(Visitor visitor) => visitor.visitReifyTypeVar(this); | |
| 764 } | |
| 765 | |
| 766 class LiteralList extends Primitive { | 681 class LiteralList extends Primitive { |
| 767 /// The List type being created; this is not the type argument. | 682 /// The List type being created; this is not the type argument. |
| 768 final GenericType type; | 683 final InterfaceType type; |
| 769 final List<Reference<Primitive>> values; | 684 final List<Reference<Primitive>> values; |
| 770 | 685 |
| 771 LiteralList(this.type, List<Primitive> values) | 686 LiteralList(this.type, List<Primitive> values) |
| 772 : this.values = _referenceList(values); | 687 : this.values = _referenceList(values); |
| 773 | 688 |
| 774 accept(Visitor visitor) => visitor.visitLiteralList(this); | 689 accept(Visitor visitor) => visitor.visitLiteralList(this); |
| 775 } | 690 } |
| 776 | 691 |
| 777 class LiteralMapEntry { | 692 class LiteralMapEntry { |
| 778 final Reference<Primitive> key; | 693 final Reference<Primitive> key; |
| 779 final Reference<Primitive> value; | 694 final Reference<Primitive> value; |
| 780 | 695 |
| 781 LiteralMapEntry(Primitive key, Primitive value) | 696 LiteralMapEntry(Primitive key, Primitive value) |
| 782 : this.key = new Reference<Primitive>(key), | 697 : this.key = new Reference<Primitive>(key), |
| 783 this.value = new Reference<Primitive>(value); | 698 this.value = new Reference<Primitive>(value); |
| 784 } | 699 } |
| 785 | 700 |
| 786 class LiteralMap extends Primitive { | 701 class LiteralMap extends Primitive { |
| 787 final GenericType type; | 702 final InterfaceType type; |
| 788 final List<LiteralMapEntry> entries; | 703 final List<LiteralMapEntry> entries; |
| 789 | 704 |
| 790 LiteralMap(this.type, this.entries); | 705 LiteralMap(this.type, this.entries); |
| 791 | 706 |
| 792 accept(Visitor visitor) => visitor.visitLiteralMap(this); | 707 accept(Visitor visitor) => visitor.visitLiteralMap(this); |
| 793 } | 708 } |
| 794 | 709 |
| 795 /// Create a non-recursive function. | 710 /// Currently unused. |
| 796 class CreateFunction extends Primitive implements DartSpecificNode { | 711 /// |
| 712 /// Nested functions (from Dart code) are translated to classes by closure |
| 713 /// conversion, hence they are instantiated with [CreateInstance]. |
| 714 /// |
| 715 /// We keep this around for now because it might come in handy when we |
| 716 /// handle async/await in the CPS IR. |
| 717 /// |
| 718 /// Instantiates a nested function. [MutableVariable]s are in scope in the |
| 719 /// inner function, but primitives are not shared across function boundaries. |
| 720 class CreateFunction extends Primitive { |
| 797 final FunctionDefinition definition; | 721 final FunctionDefinition definition; |
| 798 | 722 |
| 799 CreateFunction(this.definition); | 723 CreateFunction(this.definition); |
| 800 | 724 |
| 801 accept(Visitor visitor) => visitor.visitCreateFunction(this); | 725 accept(Visitor visitor) => visitor.visitCreateFunction(this); |
| 802 } | 726 } |
| 803 | 727 |
| 804 class Parameter extends Primitive { | 728 class Parameter extends Primitive { |
| 805 Parameter(Entity hint) { | 729 Parameter(Entity hint) { |
| 806 super.hint = hint; | 730 super.hint = hint; |
| 807 } | 731 } |
| 808 | 732 |
| 809 // In addition to a parent pointer to the containing Continuation or | 733 // In addition to a parent pointer to the containing Continuation or |
| 810 // FunctionDefinition, parameters have an index into the list of parameters | 734 // FunctionDefinition, parameters have an index into the list of parameters |
| 811 // bound by the parent. This gives constant-time access to the continuation | 735 // bound by the parent. This gives constant-time access to the continuation |
| 812 // from the parent. | 736 // from the parent. |
| 813 int parentIndex; | 737 int parentIndex; |
| 814 | 738 |
| 815 accept(Visitor visitor) => visitor.visitParameter(this); | 739 accept(Visitor visitor) => visitor.visitParameter(this); |
| 816 | 740 |
| 817 String toString() => 'Parameter(${hint == null ? null : hint.name})'; | 741 String toString() => 'Parameter(${hint == null ? null : hint.name})'; |
| 818 } | 742 } |
| 819 | 743 |
| 820 /// Continuations are normally bound by 'let cont'. A continuation with one | 744 /// Continuations are normally bound by 'let cont'. A continuation with one |
| 821 /// parameter and no body is used to represent a function's return continuation. | 745 /// parameter and no body is used to represent a function's return continuation. |
| 822 /// The return continuation is bound by the Function, not by 'let cont'. | 746 /// The return continuation is bound by the function, not by 'let cont'. |
| 823 class Continuation extends Definition<Continuation> implements InteriorNode { | 747 class Continuation extends Definition<Continuation> implements InteriorNode { |
| 824 final List<Parameter> parameters; | 748 final List<Parameter> parameters; |
| 825 Expression body = null; | 749 Expression body = null; |
| 826 | 750 |
| 827 // In addition to a parent pointer to the containing LetCont, continuations | 751 // In addition to a parent pointer to the containing LetCont, continuations |
| 828 // have an index into the list of continuations bound by the LetCont. This | 752 // have an index into the list of continuations bound by the LetCont. This |
| 829 // gives constant-time access to the continuation from the parent. | 753 // gives constant-time access to the continuation from the parent. |
| 830 int parent_index; | 754 int parent_index; |
| 831 | 755 |
| 832 // A continuation is recursive if it has any recursive invocations. | 756 // A continuation is recursive if it has any recursive invocations. |
| 833 bool isRecursive; | 757 bool isRecursive; |
| 834 | 758 |
| 835 bool get isReturnContinuation => body == null; | 759 bool get isReturnContinuation => body == null; |
| 836 | 760 |
| 837 Continuation(this.parameters, {this.isRecursive: false}); | 761 Continuation(this.parameters, {this.isRecursive: false}); |
| 838 | 762 |
| 839 Continuation.retrn() : parameters = <Parameter>[new Parameter(null)]; | 763 Continuation.retrn() : parameters = <Parameter>[new Parameter(null)]; |
| 840 | 764 |
| 841 accept(Visitor visitor) => visitor.visitContinuation(this); | 765 accept(Visitor visitor) => visitor.visitContinuation(this); |
| 842 } | 766 } |
| 843 | 767 |
| 844 abstract class RootNode extends Node { | |
| 845 Element get element; | |
| 846 | |
| 847 /// True if there is no body for this root node. | |
| 848 /// | |
| 849 /// In some parts of the compiler, empty root nodes are used as placeholders | |
| 850 /// for abstract methods, external constructors, fields without initializers, | |
| 851 /// etc. | |
| 852 bool get isEmpty; | |
| 853 | |
| 854 /// List of parameters, or an empty list if this is a field. | |
| 855 /// For fields, this list is immutable. | |
| 856 List<Definition> get parameters; | |
| 857 } | |
| 858 | |
| 859 // This is basically a function definition with an empty parameter list and a | |
| 860 // field element instead of a function element and no const declarations, and | |
| 861 // never a getter or setter, though that's less important. | |
| 862 class FieldDefinition extends RootNode implements DartSpecificNode { | |
| 863 final FieldElement element; | |
| 864 List<Definition> get parameters => const <Definition>[]; | |
| 865 final Body body; | |
| 866 | |
| 867 FieldDefinition(this.element, this.body); | |
| 868 | |
| 869 FieldDefinition.withoutInitializer(this.element) | |
| 870 : this.body = null; | |
| 871 | |
| 872 accept(Visitor visitor) => visitor.visitFieldDefinition(this); | |
| 873 | |
| 874 bool get isEmpty => body == null; | |
| 875 } | |
| 876 | |
| 877 /// Identifies a mutable variable. | 768 /// Identifies a mutable variable. |
| 878 class MutableVariable extends Definition { | 769 class MutableVariable extends Definition { |
| 879 Entity hint; | 770 Entity hint; |
| 880 | 771 |
| 881 MutableVariable(this.hint); | 772 MutableVariable(this.hint); |
| 882 | 773 |
| 883 accept(Visitor v) => v.visitMutableVariable(this); | 774 accept(Visitor v) => v.visitMutableVariable(this); |
| 884 } | 775 } |
| 885 | 776 |
| 886 class Body extends InteriorNode { | 777 /// A function definition, consisting of parameters and a body. |
| 887 Expression body; | 778 /// |
| 888 final Continuation returnContinuation; | 779 /// There is an explicit parameter for the `this` argument, and a return |
| 889 Body(this.body, this.returnContinuation); | 780 /// continuation to invoke when returning from the function. |
| 890 accept(Visitor visitor) => visitor.visitBody(this); | 781 class FunctionDefinition extends InteriorNode { |
| 891 } | |
| 892 | |
| 893 /// A function definition, consisting of parameters and a body. The parameters | |
| 894 /// include a distinguished continuation parameter (held by the body). | |
| 895 class FunctionDefinition extends RootNode { | |
| 896 final ExecutableElement element; | 782 final ExecutableElement element; |
| 897 final Parameter thisParameter; | 783 final Parameter thisParameter; |
| 898 /// Mixed list of [Parameter]s and [MutableVariable]s. | 784 final List<Parameter> parameters; |
| 899 final List<Definition> parameters; | 785 final Continuation returnContinuation; |
| 900 final Body body; | 786 Expression body; |
| 901 final List<ConstDeclaration> localConstants; | |
| 902 | |
| 903 /// Values for optional parameters. | |
| 904 final List<ConstantExpression> defaultParameterValues; | |
| 905 | 787 |
| 906 FunctionDefinition(this.element, | 788 FunctionDefinition(this.element, |
| 907 this.thisParameter, | 789 this.thisParameter, |
| 908 this.parameters, | 790 this.parameters, |
| 909 this.body, | 791 this.returnContinuation, |
| 910 this.localConstants, | 792 this.body); |
| 911 this.defaultParameterValues); | |
| 912 | |
| 913 FunctionDefinition.abstract(this.element, | |
| 914 this.parameters, | |
| 915 this.defaultParameterValues) | |
| 916 : body = null, | |
| 917 thisParameter = null, | |
| 918 localConstants = const <ConstDeclaration>[]; | |
| 919 | 793 |
| 920 accept(Visitor visitor) => visitor.visitFunctionDefinition(this); | 794 accept(Visitor visitor) => visitor.visitFunctionDefinition(this); |
| 921 | |
| 922 bool get isEmpty => body == null; | |
| 923 } | |
| 924 | |
| 925 abstract class Initializer extends Node implements DartSpecificNode {} | |
| 926 | |
| 927 class FieldInitializer extends Initializer { | |
| 928 final FieldElement element; | |
| 929 final Body body; | |
| 930 | |
| 931 FieldInitializer(this.element, this.body); | |
| 932 accept(Visitor visitor) => visitor.visitFieldInitializer(this); | |
| 933 } | |
| 934 | |
| 935 class SuperInitializer extends Initializer { | |
| 936 final ConstructorElement target; | |
| 937 final List<Body> arguments; | |
| 938 final Selector selector; | |
| 939 SuperInitializer(this.target, this.arguments, this.selector); | |
| 940 accept(Visitor visitor) => visitor.visitSuperInitializer(this); | |
| 941 } | |
| 942 | |
| 943 class ConstructorDefinition extends RootNode implements DartSpecificNode { | |
| 944 final ConstructorElement element; | |
| 945 final Parameter thisParameter; | |
| 946 /// Mixed list of [Parameter]s and [MutableVariable]s. | |
| 947 final List<Definition> parameters; | |
| 948 final Body body; | |
| 949 final List<ConstDeclaration> localConstants; | |
| 950 final List<Initializer> initializers; | |
| 951 | |
| 952 /// Values for optional parameters. | |
| 953 final List<ConstantExpression> defaultParameterValues; | |
| 954 | |
| 955 ConstructorDefinition(this.element, | |
| 956 this.thisParameter, | |
| 957 this.parameters, | |
| 958 this.body, | |
| 959 this.initializers, | |
| 960 this.localConstants, | |
| 961 this.defaultParameterValues); | |
| 962 | |
| 963 // 'Abstract' here means "has no body" and is used to represent external | |
| 964 // constructors. | |
| 965 ConstructorDefinition.abstract( | |
| 966 this.element, | |
| 967 this.parameters, | |
| 968 this.defaultParameterValues) | |
| 969 : body = null, | |
| 970 initializers = null, | |
| 971 thisParameter = null, | |
| 972 localConstants = const <ConstDeclaration>[]; | |
| 973 | |
| 974 accept(Visitor visitor) => visitor.visitConstructorDefinition(this); | |
| 975 | |
| 976 bool get isEmpty => body == null; | |
| 977 } | 795 } |
| 978 | 796 |
| 979 /// Converts the internal representation of a type to a Dart object of type | 797 /// Converts the internal representation of a type to a Dart object of type |
| 980 /// [Type]. | 798 /// [Type]. |
| 981 class ReifyRuntimeType extends Primitive implements JsSpecificNode { | 799 class ReifyRuntimeType extends Primitive { |
| 982 /// Reference to the internal representation of a type (as produced, for | 800 /// Reference to the internal representation of a type (as produced, for |
| 983 /// example, by [ReadTypeVariable]). | 801 /// example, by [ReadTypeVariable]). |
| 984 final Reference<Primitive> value; | 802 final Reference<Primitive> value; |
| 985 ReifyRuntimeType(Primitive value) | 803 ReifyRuntimeType(Primitive value) |
| 986 : this.value = new Reference<Primitive>(value); | 804 : this.value = new Reference<Primitive>(value); |
| 987 | 805 |
| 988 @override | 806 @override |
| 989 accept(Visitor visitor) => visitor.visitReifyRuntimeType(this); | 807 accept(Visitor visitor) => visitor.visitReifyRuntimeType(this); |
| 990 } | 808 } |
| 991 | 809 |
| 992 /// Read the value the type variable [variable] from the target object. | 810 /// Read the value the type variable [variable] from the target object. |
| 993 /// | 811 /// |
| 994 /// The resulting value is an internal representation (and not neccessarily a | 812 /// The resulting value is an internal representation (and not neccessarily a |
| 995 /// Dart object), and must be reified by [ReifyRuntimeType], if it should be | 813 /// Dart object), and must be reified by [ReifyRuntimeType], if it should be |
| 996 /// used as a Dart value. | 814 /// used as a Dart value. |
| 997 class ReadTypeVariable extends Primitive implements JsSpecificNode { | 815 class ReadTypeVariable extends Primitive { |
| 998 final TypeVariableType variable; | 816 final TypeVariableType variable; |
| 999 final Reference<Primitive> target; | 817 final Reference<Primitive> target; |
| 1000 | 818 |
| 1001 ReadTypeVariable(this.variable, Primitive target) | 819 ReadTypeVariable(this.variable, Primitive target) |
| 1002 : this.target = new Reference<Primitive>(target); | 820 : this.target = new Reference<Primitive>(target); |
| 1003 | 821 |
| 1004 @override | 822 @override |
| 1005 accept(Visitor visitor) => visitor.visitReadTypeVariable(this); | 823 accept(Visitor visitor) => visitor.visitReadTypeVariable(this); |
| 1006 } | 824 } |
| 1007 | 825 |
| 1008 /// Representation of a closed type (that is, a type without type variables). | 826 /// Representation of a closed type (that is, a type without type variables). |
| 1009 /// | 827 /// |
| 1010 /// The resulting value is constructed from [dartType] by replacing the type | 828 /// The resulting value is constructed from [dartType] by replacing the type |
| 1011 /// variables with consecutive values from [arguments], in the order generated | 829 /// variables with consecutive values from [arguments], in the order generated |
| 1012 /// by [DartType.forEachTypeVariable]. The type variables in [dartType] are | 830 /// by [DartType.forEachTypeVariable]. The type variables in [dartType] are |
| 1013 /// treated as 'holes' in the term, which means that it must be ensured at | 831 /// treated as 'holes' in the term, which means that it must be ensured at |
| 1014 /// construction, that duplicate occurences of a type variable in [dartType] | 832 /// construction, that duplicate occurences of a type variable in [dartType] |
| 1015 /// are assigned the same value. | 833 /// are assigned the same value. |
| 1016 class TypeExpression extends Primitive implements JsSpecificNode { | 834 class TypeExpression extends Primitive { |
| 1017 final DartType dartType; | 835 final DartType dartType; |
| 1018 final List<Reference<Primitive>> arguments; | 836 final List<Reference<Primitive>> arguments; |
| 1019 | 837 |
| 1020 TypeExpression(this.dartType, | 838 TypeExpression(this.dartType, |
| 1021 [List<Primitive> arguments = const <Primitive>[]]) | 839 [List<Primitive> arguments = const <Primitive>[]]) |
| 1022 : this.arguments = _referenceList(arguments); | 840 : this.arguments = _referenceList(arguments); |
| 1023 | 841 |
| 1024 @override | 842 @override |
| 1025 accept(Visitor visitor) { | 843 accept(Visitor visitor) { |
| 1026 return visitor.visitTypeExpression(this); | 844 return visitor.visitTypeExpression(this); |
| 1027 } | 845 } |
| 1028 } | 846 } |
| 1029 | 847 |
| 1030 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { | 848 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) { |
| 1031 return definitions.map((e) => new Reference<Primitive>(e)).toList(); | 849 return definitions.map((e) => new Reference<Primitive>(e)).toList(); |
| 1032 } | 850 } |
| 1033 | 851 |
| 1034 abstract class Visitor<T> { | 852 abstract class Visitor<T> { |
| 1035 const Visitor(); | 853 const Visitor(); |
| 1036 | 854 |
| 1037 T visit(Node node); | 855 T visit(Node node); |
| 1038 | 856 |
| 1039 // Concrete classes. | 857 // Concrete classes. |
| 1040 T visitFieldDefinition(FieldDefinition node); | |
| 1041 T visitFunctionDefinition(FunctionDefinition node); | 858 T visitFunctionDefinition(FunctionDefinition node); |
| 1042 T visitConstructorDefinition(ConstructorDefinition node); | |
| 1043 T visitBody(Body node); | |
| 1044 | |
| 1045 // Initializers | |
| 1046 T visitFieldInitializer(FieldInitializer node); | |
| 1047 T visitSuperInitializer(SuperInitializer node); | |
| 1048 | 859 |
| 1049 // Expressions. | 860 // Expressions. |
| 1050 T visitLetPrim(LetPrim node); | 861 T visitLetPrim(LetPrim node); |
| 1051 T visitLetCont(LetCont node); | 862 T visitLetCont(LetCont node); |
| 1052 T visitLetHandler(LetHandler node); | 863 T visitLetHandler(LetHandler node); |
| 1053 T visitLetMutable(LetMutable node); | 864 T visitLetMutable(LetMutable node); |
| 1054 T visitInvokeContinuation(InvokeContinuation node); | 865 T visitInvokeContinuation(InvokeContinuation node); |
| 1055 T visitInvokeStatic(InvokeStatic node); | 866 T visitInvokeStatic(InvokeStatic node); |
| 1056 T visitInvokeMethod(InvokeMethod node); | 867 T visitInvokeMethod(InvokeMethod node); |
| 1057 T visitInvokeMethodDirectly(InvokeMethodDirectly node); | 868 T visitInvokeMethodDirectly(InvokeMethodDirectly node); |
| 1058 T visitInvokeConstructor(InvokeConstructor node); | 869 T visitInvokeConstructor(InvokeConstructor node); |
| 1059 T visitConcatenateStrings(ConcatenateStrings node); | 870 T visitConcatenateStrings(ConcatenateStrings node); |
| 1060 T visitThrow(Throw node); | 871 T visitThrow(Throw node); |
| 1061 T visitRethrow(Rethrow node); | 872 T visitRethrow(Rethrow node); |
| 1062 T visitBranch(Branch node); | 873 T visitBranch(Branch node); |
| 1063 T visitTypeOperator(TypeOperator node); | 874 T visitTypeOperator(TypeOperator node); |
| 1064 T visitSetMutableVariable(SetMutableVariable node); | 875 T visitSetMutableVariable(SetMutableVariable node); |
| 1065 T visitDeclareFunction(DeclareFunction node); | |
| 1066 T visitSetStatic(SetStatic node); | 876 T visitSetStatic(SetStatic node); |
| 1067 T visitGetLazyStatic(GetLazyStatic node); | 877 T visitGetLazyStatic(GetLazyStatic node); |
| 878 T visitSetField(SetField node); |
| 1068 | 879 |
| 1069 // Definitions. | 880 // Definitions. |
| 1070 T visitLiteralList(LiteralList node); | 881 T visitLiteralList(LiteralList node); |
| 1071 T visitLiteralMap(LiteralMap node); | 882 T visitLiteralMap(LiteralMap node); |
| 1072 T visitConstant(Constant node); | 883 T visitConstant(Constant node); |
| 1073 T visitReifyTypeVar(ReifyTypeVar node); | |
| 1074 T visitCreateFunction(CreateFunction node); | 884 T visitCreateFunction(CreateFunction node); |
| 1075 T visitGetMutableVariable(GetMutableVariable node); | 885 T visitGetMutableVariable(GetMutableVariable node); |
| 1076 T visitParameter(Parameter node); | 886 T visitParameter(Parameter node); |
| 1077 T visitContinuation(Continuation node); | 887 T visitContinuation(Continuation node); |
| 1078 T visitMutableVariable(MutableVariable node); | 888 T visitMutableVariable(MutableVariable node); |
| 1079 T visitNonTailThrow(NonTailThrow node); | 889 T visitNonTailThrow(NonTailThrow node); |
| 1080 T visitGetStatic(GetStatic node); | 890 T visitGetStatic(GetStatic node); |
| 1081 | |
| 1082 // JavaScript specific nodes. | |
| 1083 | |
| 1084 // Conditions. | |
| 1085 T visitIsTrue(IsTrue node); | |
| 1086 | |
| 1087 // Expressions. | |
| 1088 T visitSetField(SetField node); | |
| 1089 | |
| 1090 // Definitions. | |
| 1091 T visitIdentical(Identical node); | 891 T visitIdentical(Identical node); |
| 1092 T visitInterceptor(Interceptor node); | 892 T visitInterceptor(Interceptor node); |
| 1093 T visitCreateInstance(CreateInstance node); | 893 T visitCreateInstance(CreateInstance node); |
| 1094 T visitGetField(GetField node); | 894 T visitGetField(GetField node); |
| 1095 T visitCreateBox(CreateBox node); | 895 T visitCreateBox(CreateBox node); |
| 1096 T visitReifyRuntimeType(ReifyRuntimeType node); | 896 T visitReifyRuntimeType(ReifyRuntimeType node); |
| 1097 T visitReadTypeVariable(ReadTypeVariable node); | 897 T visitReadTypeVariable(ReadTypeVariable node); |
| 1098 T visitTypeExpression(TypeExpression node); | 898 T visitTypeExpression(TypeExpression node); |
| 1099 T visitCreateInvocationMirror(CreateInvocationMirror node); | 899 T visitCreateInvocationMirror(CreateInvocationMirror node); |
| 900 |
| 901 // Conditions. |
| 902 T visitIsTrue(IsTrue node); |
| 1100 } | 903 } |
| 1101 | 904 |
| 1102 /// Recursively visits the entire CPS term, and calls abstract `process*` | 905 /// Recursively visits the entire CPS term, and calls abstract `process*` |
| 1103 /// (i.e. `processLetPrim`) functions in pre-order. | 906 /// (i.e. `processLetPrim`) functions in pre-order. |
| 1104 class RecursiveVisitor implements Visitor { | 907 class RecursiveVisitor implements Visitor { |
| 1105 const RecursiveVisitor(); | 908 const RecursiveVisitor(); |
| 1106 | 909 |
| 1107 visit(Node node) => node.accept(this); | 910 visit(Node node) => node.accept(this); |
| 1108 | 911 |
| 1109 processReference(Reference ref) {} | 912 processReference(Reference ref) {} |
| 1110 | 913 |
| 1111 processBody(Body node) {} | |
| 1112 visitBody(Body node) { | |
| 1113 processBody(node); | |
| 1114 visit(node.returnContinuation); | |
| 1115 visit(node.body); | |
| 1116 } | |
| 1117 | |
| 1118 processFieldDefinition(FieldDefinition node) {} | |
| 1119 visitFieldDefinition(FieldDefinition node) { | |
| 1120 processFieldDefinition(node); | |
| 1121 if (node.body != null) { | |
| 1122 visit(node.body); | |
| 1123 } | |
| 1124 } | |
| 1125 | |
| 1126 processFunctionDefinition(FunctionDefinition node) {} | 914 processFunctionDefinition(FunctionDefinition node) {} |
| 1127 visitFunctionDefinition(FunctionDefinition node) { | 915 visitFunctionDefinition(FunctionDefinition node) { |
| 1128 processFunctionDefinition(node); | 916 processFunctionDefinition(node); |
| 1129 if (node.thisParameter != null) visit(node.thisParameter); | 917 if (node.thisParameter != null) visit(node.thisParameter); |
| 1130 node.parameters.forEach(visit); | 918 node.parameters.forEach(visit); |
| 1131 if (node.body != null) { | 919 visit(node.returnContinuation); |
| 1132 visit(node.body); | |
| 1133 } | |
| 1134 } | |
| 1135 | |
| 1136 processConstructorDefinition(ConstructorDefinition node) {} | |
| 1137 visitConstructorDefinition(ConstructorDefinition node) { | |
| 1138 processConstructorDefinition(node); | |
| 1139 if (node.thisParameter != null) visit(node.thisParameter); | |
| 1140 node.parameters.forEach(visit); | |
| 1141 if (node.initializers != null) { | |
| 1142 node.initializers.forEach(visit); | |
| 1143 } | |
| 1144 if (node.body != null) { | |
| 1145 visit(node.body); | |
| 1146 } | |
| 1147 } | |
| 1148 | |
| 1149 processFieldInitializer(FieldInitializer node) {} | |
| 1150 visitFieldInitializer(FieldInitializer node) { | |
| 1151 processFieldInitializer(node); | |
| 1152 visit(node.body); | 920 visit(node.body); |
| 1153 } | 921 } |
| 1154 | 922 |
| 1155 processSuperInitializer(SuperInitializer node) {} | |
| 1156 visitSuperInitializer(SuperInitializer node) { | |
| 1157 processSuperInitializer(node); | |
| 1158 node.arguments.forEach(visit); | |
| 1159 } | |
| 1160 | |
| 1161 // Expressions. | 923 // Expressions. |
| 1162 | 924 |
| 1163 processLetPrim(LetPrim node) {} | 925 processLetPrim(LetPrim node) {} |
| 1164 visitLetPrim(LetPrim node) { | 926 visitLetPrim(LetPrim node) { |
| 1165 processLetPrim(node); | 927 processLetPrim(node); |
| 1166 visit(node.primitive); | 928 visit(node.primitive); |
| 1167 visit(node.body); | 929 visit(node.body); |
| 1168 } | 930 } |
| 1169 | 931 |
| 1170 processLetCont(LetCont node) {} | 932 processLetCont(LetCont node) {} |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 } | 1023 } |
| 1262 | 1024 |
| 1263 processSetMutableVariable(SetMutableVariable node) {} | 1025 processSetMutableVariable(SetMutableVariable node) {} |
| 1264 visitSetMutableVariable(SetMutableVariable node) { | 1026 visitSetMutableVariable(SetMutableVariable node) { |
| 1265 processSetMutableVariable(node); | 1027 processSetMutableVariable(node); |
| 1266 processReference(node.variable); | 1028 processReference(node.variable); |
| 1267 processReference(node.value); | 1029 processReference(node.value); |
| 1268 visit(node.body); | 1030 visit(node.body); |
| 1269 } | 1031 } |
| 1270 | 1032 |
| 1271 processDeclareFunction(DeclareFunction node) {} | |
| 1272 visitDeclareFunction(DeclareFunction node) { | |
| 1273 processDeclareFunction(node); | |
| 1274 visit(node.variable); | |
| 1275 visit(node.definition); | |
| 1276 visit(node.body); | |
| 1277 } | |
| 1278 | |
| 1279 processGetLazyStatic(GetLazyStatic node) {} | 1033 processGetLazyStatic(GetLazyStatic node) {} |
| 1280 visitGetLazyStatic(GetLazyStatic node) { | 1034 visitGetLazyStatic(GetLazyStatic node) { |
| 1281 processGetLazyStatic(node); | 1035 processGetLazyStatic(node); |
| 1282 processReference(node.continuation); | 1036 processReference(node.continuation); |
| 1283 } | 1037 } |
| 1284 | 1038 |
| 1285 // Definitions. | |
| 1286 | |
| 1287 processLiteralList(LiteralList node) {} | 1039 processLiteralList(LiteralList node) {} |
| 1288 visitLiteralList(LiteralList node) { | 1040 visitLiteralList(LiteralList node) { |
| 1289 processLiteralList(node); | 1041 processLiteralList(node); |
| 1290 node.values.forEach(processReference); | 1042 node.values.forEach(processReference); |
| 1291 } | 1043 } |
| 1292 | 1044 |
| 1293 processLiteralMap(LiteralMap node) {} | 1045 processLiteralMap(LiteralMap node) {} |
| 1294 visitLiteralMap(LiteralMap node) { | 1046 visitLiteralMap(LiteralMap node) { |
| 1295 processLiteralMap(node); | 1047 processLiteralMap(node); |
| 1296 for (LiteralMapEntry entry in node.entries) { | 1048 for (LiteralMapEntry entry in node.entries) { |
| 1297 processReference(entry.key); | 1049 processReference(entry.key); |
| 1298 processReference(entry.value); | 1050 processReference(entry.value); |
| 1299 } | 1051 } |
| 1300 } | 1052 } |
| 1301 | 1053 |
| 1302 processConstant(Constant node) {} | 1054 processConstant(Constant node) {} |
| 1303 visitConstant(Constant node) { | 1055 visitConstant(Constant node) { |
| 1304 processConstant(node); | 1056 processConstant(node); |
| 1305 } | 1057 } |
| 1306 | 1058 |
| 1307 processReifyTypeVar(ReifyTypeVar node) {} | |
| 1308 visitReifyTypeVar(ReifyTypeVar node) { | |
| 1309 processReifyTypeVar(node); | |
| 1310 } | |
| 1311 | |
| 1312 processCreateFunction(CreateFunction node) {} | 1059 processCreateFunction(CreateFunction node) {} |
| 1313 visitCreateFunction(CreateFunction node) { | 1060 visitCreateFunction(CreateFunction node) { |
| 1314 processCreateFunction(node); | 1061 processCreateFunction(node); |
| 1315 visit(node.definition); | 1062 visit(node.definition); |
| 1316 } | 1063 } |
| 1317 | 1064 |
| 1318 processMutableVariable(node) {} | 1065 processMutableVariable(node) {} |
| 1319 visitMutableVariable(MutableVariable node) { | 1066 visitMutableVariable(MutableVariable node) { |
| 1320 processMutableVariable(node); | 1067 processMutableVariable(node); |
| 1321 } | 1068 } |
| 1322 | 1069 |
| 1323 processGetMutableVariable(GetMutableVariable node) {} | 1070 processGetMutableVariable(GetMutableVariable node) {} |
| 1324 visitGetMutableVariable(GetMutableVariable node) { | 1071 visitGetMutableVariable(GetMutableVariable node) { |
| 1325 processGetMutableVariable(node); | 1072 processGetMutableVariable(node); |
| 1326 processReference(node.variable); | 1073 processReference(node.variable); |
| 1327 } | 1074 } |
| 1328 | 1075 |
| 1329 processParameter(Parameter node) {} | 1076 processParameter(Parameter node) {} |
| 1330 visitParameter(Parameter node) { | 1077 visitParameter(Parameter node) { |
| 1331 processParameter(node); | 1078 processParameter(node); |
| 1332 } | 1079 } |
| 1333 | 1080 |
| 1334 processContinuation(Continuation node) {} | 1081 processContinuation(Continuation node) {} |
| 1335 visitContinuation(Continuation node) { | 1082 visitContinuation(Continuation node) { |
| 1336 processContinuation(node); | 1083 processContinuation(node); |
| 1337 node.parameters.forEach(visitParameter); | 1084 node.parameters.forEach(visitParameter); |
| 1338 if (node.body != null) visit(node.body); | 1085 if (node.body != null) visit(node.body); |
| 1339 } | 1086 } |
| 1340 | 1087 |
| 1341 // Conditions. | |
| 1342 | |
| 1343 processIsTrue(IsTrue node) {} | 1088 processIsTrue(IsTrue node) {} |
| 1344 visitIsTrue(IsTrue node) { | 1089 visitIsTrue(IsTrue node) { |
| 1345 processIsTrue(node); | 1090 processIsTrue(node); |
| 1346 processReference(node.value); | 1091 processReference(node.value); |
| 1347 } | 1092 } |
| 1348 | 1093 |
| 1349 // JavaScript specific nodes. | |
| 1350 processIdentical(Identical node) {} | 1094 processIdentical(Identical node) {} |
| 1351 visitIdentical(Identical node) { | 1095 visitIdentical(Identical node) { |
| 1352 processIdentical(node); | 1096 processIdentical(node); |
| 1353 processReference(node.left); | 1097 processReference(node.left); |
| 1354 processReference(node.right); | 1098 processReference(node.right); |
| 1355 } | 1099 } |
| 1356 | 1100 |
| 1357 processInterceptor(Interceptor node) {} | 1101 processInterceptor(Interceptor node) {} |
| 1358 visitInterceptor(Interceptor node) { | 1102 visitInterceptor(Interceptor node) { |
| 1359 processInterceptor(node); | 1103 processInterceptor(node); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1421 processNonTailThrow(node); | 1165 processNonTailThrow(node); |
| 1422 processReference(node.value); | 1166 processReference(node.value); |
| 1423 } | 1167 } |
| 1424 | 1168 |
| 1425 processCreateInvocationMirror(CreateInvocationMirror node) {} | 1169 processCreateInvocationMirror(CreateInvocationMirror node) {} |
| 1426 visitCreateInvocationMirror(CreateInvocationMirror node) { | 1170 visitCreateInvocationMirror(CreateInvocationMirror node) { |
| 1427 processCreateInvocationMirror(node); | 1171 processCreateInvocationMirror(node); |
| 1428 node.arguments.forEach(processReference); | 1172 node.arguments.forEach(processReference); |
| 1429 } | 1173 } |
| 1430 } | 1174 } |
| OLD | NEW |