Trees

object Trees
class Object
trait Matchable
class Any
Trees.type

Type members

Classlikes

sealed abstract class AnyFieldDef extends MemberDef
sealed case class Apply(flags: ApplyFlags, receiver: Tree, method: MethodIdent, args: List[Tree])(tpe: Type)(implicit pos: Position) extends Tree

Apply an instance method with dynamic dispatch (the default).

Apply an instance method with dynamic dispatch (the default).

sealed case class ApplyDynamicImport(flags: ApplyFlags, className: ClassName, method: MethodIdent, args: List[Tree])(implicit pos: Position) extends Tree

Apply a static method via dynamic import.

Apply a static method via dynamic import.

final class ApplyFlags extends AnyVal
Companion:
object
object ApplyFlags
Companion:
class
sealed case class ApplyStatic(flags: ApplyFlags, className: ClassName, method: MethodIdent, args: List[Tree])(tpe: Type)(implicit pos: Position) extends Tree

Apply a static method.

Apply a static method.

sealed case class ApplyStatically(flags: ApplyFlags, receiver: Tree, className: ClassName, method: MethodIdent, args: List[Tree])(tpe: Type)(implicit pos: Position) extends Tree

Apply an instance method with static dispatch (e.g., super calls).

Apply an instance method with static dispatch (e.g., super calls).

sealed case class ArrayLength(array: Tree)(implicit pos: Position) extends Tree
sealed case class ArraySelect(array: Tree, index: Tree)(tpe: Type)(implicit pos: Position) extends AssignLhs
sealed case class ArrayValue(typeRef: ArrayTypeRef, elems: List[Tree])(implicit pos: Position) extends Tree
sealed case class AsInstanceOf(expr: Tree, tpe: Type)(implicit pos: Position) extends Tree
sealed case class Assign(lhs: AssignLhs, rhs: Tree)(implicit pos: Position) extends Tree
sealed trait AssignLhs extends Tree
sealed case class BinaryOp(op: Code, lhs: Tree, rhs: Tree)(implicit pos: Position) extends Tree

Binary operation (always preserves pureness).

Binary operation (always preserves pureness).

Companion:
object
object BinaryOp
Companion:
class
sealed class Block extends Tree
Companion:
object
object Block
Companion:
class
sealed case class BooleanLiteral(value: Boolean)(implicit pos: Position) extends Literal
sealed case class ByteLiteral(value: Byte)(implicit pos: Position) extends Literal
sealed case class CharLiteral(value: Char)(implicit pos: Position) extends Literal
final class ClassDef(val name: ClassIdent, val originalName: OriginalName, val kind: ClassKind, val jsClassCaptures: Option[List[ParamDef]], val superClass: Option[ClassIdent], val interfaces: List[ClassIdent], val jsSuperClass: Option[Tree], val jsNativeLoadSpec: Option[JSNativeLoadSpec], val memberDefs: List[MemberDef], val topLevelExportDefs: List[TopLevelExportDef])(val optimizerHints: OptimizerHints)(implicit val pos: Position) extends IRNode
Companion:
object
object ClassDef
Companion:
class
sealed case class ClassIdent(name: ClassName)(implicit pos: Position) extends IRNode
sealed case class ClassOf(typeRef: TypeRef)(implicit pos: Position) extends Literal
sealed case class Clone(expr: Tree)(implicit pos: Position) extends Tree
sealed case class Closure(arrow: Boolean, captureParams: List[ParamDef], params: List[ParamDef], restParam: Option[ParamDef], body: Tree, captureValues: List[Tree])(implicit pos: Position) extends Tree

Closure with explicit captures.

Closure with explicit captures.

Value parameters:
arrow

If true, the closure is an Arrow Function (=>), which does not have an this parameter, and cannot be constructed (called with new). If false, it is a regular Function (function).

sealed case class CreateJSClass(className: ClassName, captureValues: List[Tree])(implicit pos: Position) extends Tree

Creates a JavaScript class value.

Creates a JavaScript class value.

Value parameters:
captureValues

Actual values for the captured parameters (in the ClassDef's jsClassCaptures.get)

className

Reference to the ClassDef for the class definition, which must have jsClassCaptures.nonEmpty

sealed case class Debugger()(implicit pos: Position) extends Tree
sealed case class DoWhile(body: Tree, cond: Tree)(implicit pos: Position) extends Tree
sealed case class DoubleLiteral(value: Double)(implicit pos: Position) extends Literal
sealed case class FieldDef(flags: MemberFlags, name: FieldIdent, originalName: OriginalName, ftpe: Type)(implicit pos: Position) extends AnyFieldDef
sealed case class FieldIdent(name: FieldName)(implicit pos: Position) extends IRNode
sealed case class FloatLiteral(value: Float)(implicit pos: Position) extends Literal
sealed case class ForIn(obj: Tree, keyVar: LocalIdent, keyVarOriginalName: OriginalName, body: Tree)(implicit pos: Position) extends Tree
sealed case class GetClass(expr: Tree)(implicit pos: Position) extends Tree
sealed abstract class IRNode

Base class for all nodes in the IR.

Base class for all nodes in the IR.

Usually, one of the direct subclasses of IRNode should be used instead.

sealed case class IdentityHashCode(expr: Tree)(implicit pos: Position) extends Tree
sealed case class If(cond: Tree, thenp: Tree, elsep: Tree)(tpe: Type)(implicit pos: Position) extends Tree
sealed case class IntLiteral(value: Int)(implicit pos: Position) extends MatchableLiteral
sealed case class IsInstanceOf(expr: Tree, testType: Type)(implicit pos: Position) extends Tree
sealed case class JSArrayConstr(items: List[TreeOrJSSpread])(implicit pos: Position) extends Tree
sealed case class JSBinaryOp(op: Code, lhs: Tree, rhs: Tree)(implicit pos: Position) extends Tree

Binary operation (always preserves pureness).

Binary operation (always preserves pureness).

Operations which do not preserve pureness are not allowed in this tree. These are notably +=, -=, *=, /= and %=

Companion:
object
object JSBinaryOp
Companion:
class
sealed case class JSDelete(qualifier: Tree, item: Tree)(implicit pos: Position) extends Tree

delete qualifier[item]

delete qualifier[item]

sealed case class JSFieldDef(flags: MemberFlags, name: Tree, ftpe: Type)(implicit pos: Position) extends AnyFieldDef
sealed case class JSFunctionApply(fun: Tree, args: List[TreeOrJSSpread])(implicit pos: Position) extends Tree
sealed case class JSGlobalRef(name: String)(implicit pos: Position) extends AssignLhs
Companion:
object
Companion:
class
sealed case class JSImportCall(arg: Tree)(implicit pos: Position) extends Tree

JavaScript dynamic import of the form import(arg).

JavaScript dynamic import of the form import(arg).

This form is its own node, rather than using something like

JSFunctionApply(JSImport())

because import is not a first-class term in JavaScript. ImportCall is a dedicated syntactic form that cannot be dissociated.

sealed case class JSImportMeta()(implicit pos: Position) extends Tree

JavaScript meta-property import.meta.

JavaScript meta-property import.meta.

This form is its own node, rather than using something like

JSSelect(JSImport(), StringLiteral("meta"))

because import is not a first-class term in JavaScript. import.meta is a dedicated syntactic form that cannot be dissociated.

sealed case class JSLinkingInfo()(implicit pos: Position) extends Tree
sealed case class JSMethodApply(receiver: Tree, method: Tree, args: List[TreeOrJSSpread])(implicit pos: Position) extends Tree
sealed case class JSMethodDef(flags: MemberFlags, name: Tree, args: List[ParamDef], restParam: Option[ParamDef], body: Tree)(optimizerHints: OptimizerHints, hash: Option[TreeHash])(implicit pos: Position) extends JSMethodPropDef
sealed abstract class JSMethodPropDef extends MemberDef
sealed abstract class JSNativeLoadSpec

Loading specification for a native JS class or object.

Loading specification for a native JS class or object.

Companion:
object
Companion:
class
sealed case class JSNativeMemberDef(flags: MemberFlags, name: MethodIdent, jsNativeLoadSpec: JSNativeLoadSpec)(implicit pos: Position) extends MemberDef
sealed case class JSNew(ctor: Tree, args: List[TreeOrJSSpread])(implicit pos: Position) extends Tree
sealed case class JSNewTarget()(implicit pos: Position) extends Tree

JavaScript meta-property new.target.

JavaScript meta-property new.target.

This form is its own node, rather than using something like

JSSelect(JSNew(), StringLiteral("target"))

because new is not a first-class term in JavaScript. new.target is a dedicated syntactic form that cannot be dissociated.

sealed case class JSObjectConstr(fields: List[(Tree, Tree)])(implicit pos: Position) extends Tree
sealed case class JSPrivateSelect(qualifier: Tree, className: ClassName, field: FieldIdent)(implicit pos: Position) extends AssignLhs
sealed case class JSPropertyDef(flags: MemberFlags, name: Tree, getterBody: Option[Tree], setterArgAndBody: Option[(ParamDef, Tree)])(implicit pos: Position) extends JSMethodPropDef
sealed case class JSSelect(qualifier: Tree, item: Tree)(implicit pos: Position) extends AssignLhs
sealed case class JSSpread(items: Tree)(implicit pos: Position) extends IRNode with TreeOrJSSpread

...items, the "spread" operator of ECMAScript 6.

...items, the "spread" operator of ECMAScript 6.

Value parameters:
items

An Array whose items will be spread (not an arbitrary iterable)

sealed case class JSSuperConstructorCall(args: List[TreeOrJSSpread])(implicit pos: Position) extends Tree

Super constructor call in the constructor of a non-native JS class.

Super constructor call in the constructor of a non-native JS class.

Exactly one such node must appear in the constructor of a non-native JS class, at the top-level (possibly as a direct child of a top-level Block). Any other use of this node is invalid.

Statements before this node, as well as the args, cannot contain any This() node. Statements after this node can use This().

After the execution of this node, it is guaranteed that all fields declared in the current class have been created and initialized. Up to that point, accessing any field declared in this class (e.g., through an overridden method called from the super constructor) is undefined behavior.

All in all, the shape of a constructor is therefore:

{
  statementsNotUsingThis();
  JSSuperConstructorCall(...argsNotUsingThis);
  statementsThatMayUseThis()
}

which currently translates to something of the following shape:

{
  statementsNotUsingThis();
  super(...argsNotUsingThis);
  this.privateField1 = 0;
  this["publicField2"] = false;
  statementsThatMayUseThis()
}
sealed case class JSSuperMethodCall(superClass: Tree, receiver: Tree, method: Tree, args: List[TreeOrJSSpread])(implicit pos: Position) extends Tree

Calls a method inherited from the given superClass on receiver.

Calls a method inherited from the given superClass on receiver.

Intuitively, this corresponds to

superClass.prototype[method].call(receiver, ...args)

but retains more structure at the IR level than using an explicit encoding of the above expression.

Given the non-native JS classes

class Bar extends js.Object
class Foo extends Bar

The node

JSSuperBrackerCall(LoadJSConstructor(ClassName("Bar")), receiver, method, args)

which is printed as

super(constructorOf[Bar])::receiver[method](...args)

has the following semantics:

Bar.prototype[method].call(receiver, ...args)

If this happens to be located in an instance method of Foo, and receiver happens to be This(), this is equivalent to the ES6 statement

super[method](...args)
sealed case class JSSuperSelect(superClass: Tree, receiver: Tree, item: Tree)(implicit pos: Position) extends AssignLhs

Selects a property inherited from the given superClass on receiver.

Selects a property inherited from the given superClass on receiver.

Given the non-native JS classes

class Bar extends js.Object
class Foo extends Bar

The node

JSSuperBrackerSelect(LoadJSConstructor(ClassName("Bar")), qualifier, item)

which is printed as

super(constructorOf[Bar])::qualifier[item]

has the semantics of an ES6 super reference

super[item]

as if it were in an instance method of Foo with qualifier as the this value.

sealed case class JSTypeOfGlobalRef(globalRef: JSGlobalRef)(implicit pos: Position) extends Tree
sealed case class JSUnaryOp(op: Code, lhs: Tree)(implicit pos: Position) extends Tree

Unary operation (always preserves pureness).

Unary operation (always preserves pureness).

Operations which do not preserve pureness are not allowed in this tree. These are notably ++ and --

Companion:
object
object JSUnaryOp
Companion:
class
sealed case class LabelIdent(name: LabelName)(implicit pos: Position) extends IRNode
sealed case class Labeled(label: LabelIdent, tpe: Type, body: Tree)(implicit pos: Position) extends Tree
sealed trait Literal extends Tree

Marker for literals. Literals are always pure.

Marker for literals. Literals are always pure.

sealed case class LoadJSConstructor(className: ClassName)(implicit pos: Position) extends Tree

Loads the constructor of a JS class (native or not).

Loads the constructor of a JS class (native or not).

className must represent a non-trait JS class (native or not).

This is used typically to instantiate a JS class, and most importantly if it is a non-native JS class. Given the class

class Foo(x: Int) extends js.Object

The instantiation new Foo(1) would be represented as

JSNew(LoadJSConstructor(ClassName("Foo")), List(IntLiteral(1)))

This node is also useful to encode o.isInstanceOf[Foo]:

JSBinaryOp(instanceof, o, LoadJSConstructor(ClassName("Foo")))

If Foo is non-native, the presence of this node makes it instantiable, and therefore reachable.

sealed case class LoadJSModule(className: ClassName)(implicit pos: Position) extends Tree

Like LoadModule but for a JS module class.

Like LoadModule but for a JS module class.

sealed case class LoadModule(className: ClassName)(implicit pos: Position) extends Tree
sealed case class LocalIdent(name: LocalName)(implicit pos: Position) extends IRNode
sealed case class LongLiteral(value: Long)(implicit pos: Position) extends Literal
sealed case class Match(selector: Tree, cases: List[(List[MatchableLiteral], Tree)], default: Tree)(tpe: Type)(implicit pos: Position) extends Tree

A break-free switch (without fallthrough behavior).

A break-free switch (without fallthrough behavior).

Unlike a JavaScript switch, it can be used in expression position. It supports alternatives explicitly (hence the List[MatchableLiteral] in cases), whereas in a switch one would use the fallthrough behavior to implement alternatives. (This is not a pattern matching construct like in Scala.)

The selector must be either an int (IntType) or a java.lang.String. The cases can be any MatchableLiteral, even if they do not make sense for the type of the selecter (they simply will never match).

Because +0.0 === -0.0 in JavaScript, and because those semantics are used in a JS switch, we have to prevent the selector from ever being -0.0. Otherwise, it would be matched by a case IntLiteral(0). At the same time, we must allow at least int and java.lang.String to support all switchable matches from Scala. Since the latter two have no common super type that does not allow -0.0, we really have to special-case those two types.

This is also why we restrict MatchableLiterals to IntLiteral, StringLiteral and Null. Allowing more cases would only make IR checking more complicated, without bringing any added value.

sealed trait MatchableLiteral extends Literal

Marker for literals that can be used in a Match case.

Marker for literals that can be used in a Match case.

Matchable literals are:

  • IntLiteral
  • StringLiteral
  • Null

See Match for the rationale about that specific set.

sealed abstract class MemberDef extends IRNode

Any member of a ClassDef.

Any member of a ClassDef.

Partitioned into AnyFieldDef, MethodDef and JSMethodPropDef.

final class MemberFlags extends AnyVal
Companion:
object
Companion:
class
final class MemberNamespace extends AnyVal
Companion:
object
Companion:
class
sealed case class MethodDef(flags: MemberFlags, name: MethodIdent, originalName: OriginalName, args: List[ParamDef], resultType: Type, body: Option[Tree])(optimizerHints: OptimizerHints, hash: Option[TreeHash])(implicit pos: Position) extends MemberDef
sealed case class MethodIdent(name: MethodName)(implicit pos: Position) extends IRNode
sealed case class New(className: ClassName, ctor: MethodIdent, args: List[Tree])(implicit pos: Position) extends Tree
sealed case class NewArray(typeRef: ArrayTypeRef, lengths: List[Tree])(implicit pos: Position) extends Tree
sealed case class Null()(implicit pos: Position) extends MatchableLiteral
final class OptimizerHints extends AnyVal
Companion:
object
Companion:
class
sealed case class ParamDef(name: LocalIdent, originalName: OriginalName, ptpe: Type, mutable: Boolean)(implicit pos: Position) extends IRNode
sealed case class RecordSelect(record: Tree, field: FieldIdent)(tpe: Type)(implicit pos: Position) extends AssignLhs
sealed case class RecordValue(tpe: RecordType, elems: List[Tree])(implicit pos: Position) extends Tree
sealed case class Return(expr: Tree, label: LabelIdent)(implicit pos: Position) extends Tree
sealed case class Select(qualifier: Tree, className: ClassName, field: FieldIdent)(tpe: Type)(implicit pos: Position) extends AssignLhs
sealed case class SelectJSNativeMember(className: ClassName, member: MethodIdent)(implicit pos: Position) extends Tree
sealed case class SelectStatic(className: ClassName, field: FieldIdent)(tpe: Type)(implicit pos: Position) extends AssignLhs
sealed case class ShortLiteral(value: Short)(implicit pos: Position) extends Literal
sealed case class Skip()(implicit pos: Position) extends Tree
sealed case class StoreModule(className: ClassName, value: Tree)(implicit pos: Position) extends Tree
sealed case class StringLiteral(value: String)(implicit pos: Position) extends MatchableLiteral
sealed case class This()(tpe: Type)(implicit pos: Position) extends Tree
sealed case class Throw(expr: Tree)(implicit pos: Position) extends Tree
sealed abstract class TopLevelExportDef extends IRNode
Companion:
object
Companion:
class
sealed case class TopLevelFieldExportDef(moduleID: String, exportName: String, field: FieldIdent)(implicit pos: Position) extends TopLevelExportDef
sealed case class TopLevelJSClassExportDef(moduleID: String, exportName: String)(implicit pos: Position) extends TopLevelExportDef
sealed case class TopLevelMethodExportDef(moduleID: String, methodDef: JSMethodDef)(implicit pos: Position) extends TopLevelExportDef
sealed case class TopLevelModuleExportDef(moduleID: String, exportName: String)(implicit pos: Position) extends TopLevelExportDef

Export for a top-level object.

Export for a top-level object.

This exports the singleton instance of the containing module class. The instance is initialized during ES module instantiation.

sealed case class Transient(value: Value)(implicit pos: Position) extends Tree

A transient node for custom purposes.

A transient node for custom purposes.

A transient node is never a valid input to the Serializers nor to the linker, but can be used in a transient state for internal purposes.

Value parameters:
value

The payload of the transient node, without any specified meaning.

Companion:
object
object Transient
Companion:
class
sealed abstract class Tree extends IRNode with TreeOrJSSpread

Node for a statement or expression in the IR.

Node for a statement or expression in the IR.

final class TreeHash(val hash: Array[Byte])

A hash of a tree (usually a MethodDef).

A hash of a tree (usually a MethodDef).

Contains a SHA-1 hash.

sealed trait TreeOrJSSpread extends IRNode

Either a Tree or a JSSpread.

Either a Tree or a JSSpread.

This is the type of actual arguments to JS applications.

sealed case class TryCatch(block: Tree, errVar: LocalIdent, errVarOriginalName: OriginalName, handler: Tree)(tpe: Type)(implicit pos: Position) extends Tree
sealed case class TryFinally(block: Tree, finalizer: Tree)(implicit pos: Position) extends Tree
sealed case class UnaryOp(op: Code, lhs: Tree)(implicit pos: Position) extends Tree

Unary operation (always preserves pureness).

Unary operation (always preserves pureness).

Companion:
object
object UnaryOp
Companion:
class
sealed case class Undefined()(implicit pos: Position) extends Literal
sealed case class VarDef(name: LocalIdent, originalName: OriginalName, vtpe: Type, mutable: Boolean, rhs: Tree)(implicit pos: Position) extends Tree
sealed case class VarRef(ident: LocalIdent)(tpe: Type)(implicit pos: Position) extends AssignLhs
sealed case class While(cond: Tree, body: Tree)(implicit pos: Position) extends Tree

Value members

Concrete methods

Tests whether the given name is a valid JavaScript identifier name.

Tests whether the given name is a valid JavaScript identifier name.

This test does not exclude keywords.