class JSCodePhase extends StdPhase with JSExportsPhase
- Alphabetic
- By Inheritance
- JSCodePhase
- JSExportsPhase
- StdPhase
- GlobalPhase
- Phase
- AnyRef
- Any
- Hide All
- Show All
- Public
- All
Instance Constructors
- new JSCodePhase(prev: Phase)
Value Members
-
final
def
!=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
final
def
##(): Int
- Definition Classes
- AnyRef → Any
-
final
def
==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
def
apply(cunit: G.CompilationUnit): Unit
Generates the Scala.js IR for a compilation unit This method iterates over all the class and interface definitions found in the compilation unit and emits their IR (.sjsir).
Generates the Scala.js IR for a compilation unit This method iterates over all the class and interface definitions found in the compilation unit and emits their IR (.sjsir).
Some classes are never actually emitted:
- Classes representing primitive types
- The scala.Array class
- Implementation classes for JS traits
Some classes representing anonymous functions are not actually emitted. Instead, a temporary representation of their
apply
method is built and recorded, so that it can be inlined as a JavaScript anonymous function in the method that instantiates it.Other ClassDefs are emitted according to their nature: * Non-native JS class ->
genNonNativeJSClass()
* Other JS type (<: js.Any) ->genJSClassData()
* Interface ->genInterface()
* Normal class ->genClass()
- Definition Classes
- JSCodePhase → GlobalPhase
-
final
def
applyPhase(unit: G.CompilationUnit): Unit
- Definition Classes
- GlobalPhase
-
final
def
asInstanceOf[T0]: T0
- Definition Classes
- Any
-
final
val
assignsFields: Boolean
- Definition Classes
- Phase
-
def
cancelled(unit: G.CompilationUnit): Boolean
- Definition Classes
- GlobalPhase
-
def
checkable: Boolean
- Definition Classes
- Phase
-
def
clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( ... ) @native()
- val currentClassSym: ScopedVar[G.Symbol]
-
def
description: String
- Definition Classes
- JSCodePhase → Phase
-
def
ensureBoxed(expr: Tree, tpeEnteringPosterasure: G.Type)(implicit pos: G.Position): Tree
Ensures that the value of the given tree is boxed.
Ensures that the value of the given tree is boxed.
- expr
Tree to be boxed if needed.
- tpeEnteringPosterasure
The type of
expr
as it was entering the posterasure phase.
-
final
def
eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
def
equals(other: Any): Boolean
- Definition Classes
- Phase → AnyRef → Any
-
final
def
erasedTypes: Boolean
- Definition Classes
- Phase
-
def
erasedTypes_=(value: Boolean): Unit
- Attributes
- protected
- Definition Classes
- Phase
-
def
exprToStat(tree: Tree): Tree
Turn a JavaScript expression of type Unit into a statement
-
def
finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( classOf[java.lang.Throwable] )
-
def
flagMask: Long
- Definition Classes
- Phase
-
final
val
flatClasses: Boolean
- Definition Classes
- Phase
-
val
fmask: Long
- Definition Classes
- Phase
-
def
fromAny(expr: Tree, tpeEnteringPosterasure: G.Type)(implicit pos: G.Position): Tree
Extracts a value typed as Any to the given type after posterasure.
Extracts a value typed as Any to the given type after posterasure.
- expr
Tree to be extracted.
- tpeEnteringPosterasure
The type of
expr
as it was entering the posterasure phase.
-
def
genAnonJSClassNew(sym: G.Symbol, jsSuperClassValue: Tree, args: List[TreeOrJSSpread])(implicit pos: G.Position): Tree
Generate an instance of an anonymous (non-lambda) JS class inline
Generate an instance of an anonymous (non-lambda) JS class inline
- sym
Class to generate the instance of
- jsSuperClassValue
JS class value of the super class
- args
Arguments to the constructor
- pos
Position of the original New tree
-
def
genApply(tree: G.Apply, isStat: Boolean): Tree
Gen JS code for an Apply node (method call)
Gen JS code for an Apply node (method call)
There's a whole bunch of varieties of Apply nodes: regular method calls, super calls, constructor calls, isInstanceOf/asInstanceOf, primitives, JS calls, etc. They are further dispatched in here.
- def genApplyJSClassMethod(receiver: Tree, method: G.Symbol, arguments: List[Tree])(implicit pos: G.Position): Tree
-
def
genApplyMethod(receiver: Tree, method: G.Symbol, arguments: List[Tree])(implicit pos: G.Position): Tree
Gen JS code for a call to a Scala method.
- def genApplyMethodMaybeStatically(receiver: Tree, method: G.Symbol, arguments: List[Tree])(implicit pos: G.Position): Tree
- def genApplyMethodStatically(receiver: Tree, method: G.Symbol, arguments: List[Tree])(implicit pos: G.Position): Tree
- def genApplyStatic(method: G.Symbol, arguments: List[Tree])(implicit pos: G.Position): Tree
-
def
genArrayValue(tree: G.Tree, elems: List[G.Tree]): Tree
Gen JS code for an array literal, in the context of
tree
(itstpe
andpos
) but with the elementselems
. -
def
genArrayValue(tree: G.ArrayValue): Tree
Gen JS code for an array literal.
-
def
genAsInstanceOf(value: Tree, to: G.Type)(implicit pos: G.Position): Tree
Gen JS code for an asInstanceOf cast (for reference types only)
-
def
genClass(cd: G.ClassDef): ClassDef
Gen the IR ClassDef for a class definition (maybe a module class).
-
def
genClassFields(cd: G.ClassDef): List[AnyFieldDef]
Gen definitions for the fields of a class.
Gen definitions for the fields of a class. The fields are initialized with the zero of their types.
-
def
genConstructorExports(classSym: G.Symbol): List[TopLevelMethodExportDef]
- Definition Classes
- JSExportsPhase
-
def
genEqEqPrimitive(ltpe: G.Type, rtpe: G.Type, lsrc: Tree, rsrc: Tree)(implicit pos: G.Position): Tree
Gen JS code for a call to Any.==
- def genExposedFieldIRType(f: G.Symbol): Type
- def genExpr(name: JSName)(implicit pos: G.Position): Tree
-
def
genExpr(tree: G.Tree): Tree
Gen JS code for a tree in expression position (in the IR).
-
def
genExprOrGlobalScope(tree: G.Tree): MaybeGlobalScope
Gen JS code for a tree in expression position (in the IR) or the global scope.
-
def
genInterface(cd: G.ClassDef): ClassDef
Gen the IR ClassDef for an interface definition.
-
def
genIsInstanceOf(value: Tree, to: G.Type)(implicit pos: G.Position): Tree
Gen JS code for an isInstanceOf test (for reference types only)
-
def
genJSArrayToVarArgs(arrayRef: Tree)(implicit pos: G.Position): Tree
Wraps a
js.Array
to use as varargs. - def genJSClassCapturesAndConstructor(classSym: G.Symbol, constructorTrees: List[G.DefDef]): (Option[List[ParamDef]], JSMethodDef)
-
def
genJSClassData(cd: G.ClassDef): ClassDef
Gen the IR ClassDef for a JS class or trait.
-
def
genJSClassDispatchers(classSym: G.Symbol, dispatchMethodsNames: List[JSName]): List[MemberDef]
- Definition Classes
- JSExportsPhase
-
def
genJSClassExports(classSym: G.Symbol): List[TopLevelJSClassExportDef]
- Definition Classes
- JSExportsPhase
-
def
genJSConstructorExport(alts: List[G.Symbol]): (Option[List[ParamDef]], JSMethodDef)
- Definition Classes
- JSExportsPhase
-
def
genJSFunction(cd: G.ClassDef, captures: List[Tree]): Tree
Gen JS code for a JS function class.
Gen JS code for a JS function class.
This is called when emitting a ClassDef that represents an anonymous class extending
js.FunctionN
. These are generated by the SAM synthesizer when the target type is ajs.FunctionN
. Since JS functions are not classes, we deconstruct the ClassDef, then reconstruct it to be a genuine Closure.Compared to
tryGenAnonFunctionClass()
, this function must always succeed, because we really cannot afford keeping them as anonymous classes. The good news is that it can do so, because the body of SAM lambdas is hoisted in the enclosing class. Hence, the apply() method is just a forwarder to calling that hoisted method.From a class looking like this:
final class <anon>(outer, capture1, ..., captureM) extends js.FunctionN[...] { def apply(param1, ..., paramN) = { outer.lambdaImpl(param1, ..., paramN, capture1, ..., captureM) } } new <anon>(o, c1, ..., cM)
we generate a function:
lambda<o, c1, ..., cM>[notype]( outer, capture1, ..., captureM, param1, ..., paramN) { outer.lambdaImpl(param1, ..., paramN, capture1, ..., captureM) }
-
def
genLabelDef(tree: G.LabelDef): Tree
Gen JS code for LabelDef The only LabelDefs that can reach here are the desugaring of while and do..while loops.
Gen JS code for LabelDef The only LabelDefs that can reach here are the desugaring of while and do..while loops. All other LabelDefs (for tail calls or matches) are caught upstream and transformed in ad hoc ways.
So here we recognize all the possible forms of trees that can result of while or do..while loops, and we reconstruct the loop for emission to JS.
-
def
genLoadModule(sym0: G.Symbol)(implicit pos: G.Position): Tree
Generate loading of a module value.
Generate loading of a module value.
Can be given either the module symbol or its module class symbol.
If the module we load refers to the global scope (i.e., it is annotated with
@JSGlobalScope
), report a compile error specifying that a global scope object should only be used as the qualifier of a.
-selection. -
def
genLoadModuleOrGlobalScope(sym0: G.Symbol)(implicit pos: G.Position): MaybeGlobalScope
Generate loading of a module value or the global scope.
Generate loading of a module value or the global scope.
Can be given either the module symbol of its module class symbol.
Unlike
genLoadModule
, this method does not fail if the module we load refers to the global scope. -
def
genMatch(tree: G.Tree, isStat: Boolean): Tree
Gen JS code for a Match, i.e., a switch-able pattern match.
Gen JS code for a Match, i.e., a switch-able pattern match.
In most cases, this straightforwardly translates to a Match in the IR, which will eventually become a
switch
in JavaScript.However, sometimes there is a guard in here, despite the fact that matches cannot have guards (in the JVM nor in the IR). The JVM backend emits a jump to the default clause when a guard is not fulfilled. We cannot do that, since we do not have arbitrary jumps. We therefore use a funny encoding with two nested
Labeled
blocks. For example,x match { case 1 if y > 0 => a case 2 => b case _ => c }
arrives at the back-end as
x match { case 1 => if (y > 0) a else default() case 2 => b case _ => default() { c } }
which we then translate into the following IR:
matchResult[I]: { default[V]: { x match { case 1 => return(matchResult) if (y > 0) a else return(default) (void 0) case 2 => return(matchResult) b case _ => () } } c }
-
def
genMemberExportOrDispatcher(classSym: G.Symbol, jsName: JSName, isProp: Boolean, alts: List[G.Symbol], static: Boolean): MemberDef
- Definition Classes
- JSExportsPhase
-
def
genMemberExports(classSym: G.Symbol): List[MemberDef]
Generates exported methods and properties for a class.
Generates exported methods and properties for a class.
- classSym
symbol of the class we export for
- Definition Classes
- JSExportsPhase
- def genMethod(dd: G.DefDef): Option[MethodDef]
-
def
genMethodDef(namespace: MemberNamespace, methodName: MethodIdent, originalName: OriginalName, paramsSyms: List[G.Symbol], resultIRType: Type, tree: G.Tree, optimizerHints: OptimizerHints): MethodDef
Generates the MethodDef of a (non-constructor) method
Generates the MethodDef of a (non-constructor) method
Most normal methods are emitted straightforwardly. If the result type is Unit, then the body is emitted as a statement. Otherwise, it is emitted as an expression.
The additional complexity of this method handles the transformation of a peculiarity of recursive tail calls: the local ValDef that replaces
this
. -
def
genMethodWithCurrentLocalNameScope(dd: G.DefDef): Option[MethodDef]
Gen JS code for a method definition in a class or in an impl class.
Gen JS code for a method definition in a class or in an impl class. On the JS side, method names are mangled to encode the full signature of the Scala method, as described in
JSEncoding
, to support overloading.Some methods are not emitted at all: * Primitives, since they are never actually called (with exceptions) * Abstract methods * Constructors of hijacked classes * Methods with the
@JavaDefaultMethod
annotation mixed in classes.
Constructors are emitted by generating their body as a statement.
Interface methods with the
@JavaDefaultMethod
annotation produce default methods forwarding to the trait impl class method.
Other (normal) methods are emitted with
genMethodDef()
.@JavaDefaultMethod }}} default methods forwarding to the trait impl class method.
Other (normal) methods are emitted with
genMethodDef()
.@JavaDefaultMethod }}}
Constructors are emitted by generating their body as a statement.
Interface methods with the
@JavaDefaultMethod
annotation produce default methods forwarding to the trait impl class method.
Other (normal) methods are emitted with
genMethodDef()
.@JavaDefaultMethod }}} default methods forwarding to the trait impl class method.
Other (normal) methods are emitted with
genMethodDef()
. -
def
genModuleAccessorExports(classSym: G.Symbol): List[TopLevelExportDef]
- Definition Classes
- JSExportsPhase
-
def
genNew(className: ClassName, ctor: G.Symbol, arguments: List[Tree])(implicit pos: G.Position): Tree
Gen JS code for a call to a Scala class constructor.
-
def
genNew(clazz: G.Symbol, ctor: G.Symbol, arguments: List[Tree])(implicit pos: G.Position): Tree
Gen JS code for a call to a Scala class constructor.
-
def
genNewArray(arrayTypeRef: ArrayTypeRef, arguments: List[Tree])(implicit pos: G.Position): Tree
Gen JS code for creating a new Array: new Array[T](length) For multidimensional arrays (dimensions > 1), the arguments can specify up to
dimensions
lengths for the first dimensions of the array. -
def
genNonNativeJSClass(cd: G.ClassDef): ClassDef
Gen the IR ClassDef for a non-native JS class.
-
def
genOptimizedMatchEndLabeled(label: LabelIdent, tpe: Type, translatedCases: List[Tree], returnCount: Int)(implicit pos: G.Position): Tree
Gen JS code for a Labeled block from a pattern match'es match-end, while trying to optimize it away as an If chain.
Gen JS code for a Labeled block from a pattern match'es match-end, while trying to optimize it away as an If chain.
It is important to do so at compile-time because, when successful, the resulting IR can be much better optimized by the optimizer.
The optimizer also does something similar, but *after* it has processed the body of the Labeled block, at which point it has already lost any information about stack-allocated values.
!!! There is quite of bit of code duplication with OptimizerCore.tryOptimizePatternMatch.
- def genParamDef(sym: G.Symbol): ParamDef
-
def
genStat(tree: G.Tree): Tree
Gen JS code for a tree in statement position (in the IR).
-
def
genStatOrExpr(tree: G.Tree, isStat: Boolean): Tree
Gen JS code for a tree in statement or expression position (in the IR).
Gen JS code for a tree in statement or expression position (in the IR).
This is the main transformation method. Each node of the Scala AST is transformed into an equivalent portion of the JS AST.
-
def
genStaticExports(classSym: G.Symbol): List[MemberDef]
- Definition Classes
- JSExportsPhase
-
def
genStaticForwardersForClassOrInterface(existingMembers: List[MemberDef], sym: G.Symbol)(implicit pos: G.Position): List[MemberDef]
Gen the static forwarders to the members of a class or interface for methods of its companion object.
Gen the static forwarders to the members of a class or interface for methods of its companion object.
This is only done if there exists a companion object and it is not a JS type.
Precondition:
isCandidateForForwarders(sym)
is true -
def
genStaticForwardersFromModuleClass(existingMembers: List[MemberDef], moduleClass: G.Symbol)(implicit pos: G.Position): List[MemberDef]
Gen the static forwarders for the methods of a module class.
Gen the static forwarders for the methods of a module class.
Precondition:
isCandidateForForwarders(moduleClass)
is true -
def
genTopLevelExports(classSym: G.Symbol): List[TopLevelExportDef]
- Definition Classes
- JSExportsPhase
-
def
genTranslatedMatch(cases: List[G.LabelDef], matchEnd: G.LabelDef)(implicit pos: G.Position): Tree
Gen JS code for a translated match
Gen JS code for a translated match
This implementation relies heavily on the patterns of trees emitted by the pattern match phase, including its variants across versions of scalac that we support.
The trees output by the pattern matcher are assumed to follow these rules: * Each case LabelDef (in
cases
) must not take any argument. * The last one must be a catch-all (case _ =>) that never falls through. * Jumps to thematchEnd
are allowed anywhere in the body of the corresponding case label-defs, but not outside. * Jumps to case label-defs are restricted to jumping to the very next case, and only in positions denoted by <jump> in: <case-body> ::= If(_, <case-body>, <case-body>) | Block(_, <case-body>) | <jump> | _ These restrictions, together with the fact that we are in statement position (thanks to the above transformation), mean that they can be simply replaced byskip
.To implement jumps to
matchEnd
, which have one argument which is the result of the match, we enclose all the cases in one big labeled block. Jumps are then compiled asreturn
s out of the block. -
def
genTry(tree: G.Try, isStat: Boolean): Tree
Gen JS code for a try..catch or try..finally block
Gen JS code for a try..catch or try..finally block
try..finally blocks are compiled straightforwardly to try..finally blocks of JS.
try..catch blocks are a bit more subtle, as JS does not have type-based selection of exceptions to catch. We thus encode explicitly the type tests, like in:
try { ... } catch (e) { if (e.isInstanceOf[IOException]) { ... } else if (e.isInstanceOf[Exception]) { ... } else { throw e; // default, re-throw } }
-
final
def
getClass(): Class[_]
- Definition Classes
- AnyRef → Any
- Annotations
- @native()
-
def
hasNext: Boolean
- Definition Classes
- Phase
-
def
hashCode(): Int
- Definition Classes
- Phase → AnyRef → Any
-
val
id: Id
- Definition Classes
- Phase
- def isAbstractMethod(dd: G.DefDef): Boolean
-
def
isCandidateForForwarders(sym: G.Symbol): Boolean
Is the given Scala class, interface or module class a candidate for static forwarders?
-
final
def
isInstanceOf[T0]: Boolean
- Definition Classes
- Any
-
def
iterator: Iterator[Phase]
- Definition Classes
- Phase
-
def
keepsTypeParams: Boolean
- Definition Classes
- Phase
-
def
makePrimitiveBox(expr: Tree, tpe: G.Type)(implicit pos: G.Position): Tree
Gen a boxing operation (tpe is the primitive type)
-
def
makePrimitiveUnbox(expr: Tree, tpe: G.Type)(implicit pos: G.Position): Tree
Gen an unboxing operation (tpe is the primitive type)
-
def
name: String
- Definition Classes
- JSCodePhase → StdPhase → Phase
-
final
def
ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
def
newFlags: Long
- Definition Classes
- StdPhase → Phase
-
def
next: Phase
- Definition Classes
- Phase
-
def
nextFlags: Long
- Definition Classes
- StdPhase → Phase
-
final
def
notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
final
def
notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native()
-
val
prev: Phase
- Definition Classes
- Phase
-
final
val
refChecked: Boolean
- Definition Classes
- Phase
-
def
run(): Unit
- Definition Classes
- JSCodePhase → GlobalPhase → Phase
-
def
shouldSkipThisPhaseForJava: Boolean
- Attributes
- protected
- Definition Classes
- GlobalPhase
-
final
val
specialized: Boolean
- Definition Classes
- Phase
-
final
def
synchronized[T0](arg0: ⇒ T0): T0
- Definition Classes
- AnyRef
-
def
toString(): String
- Definition Classes
- Phase → AnyRef → Any
-
final
def
wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
final
def
wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws( ... ) @native()
-
final
def
withCurrentUnitNoLog(unit: G.CompilationUnit)(task: ⇒ Unit): Unit
- Definition Classes
- GlobalPhase
- Annotations
- @inline()
- object MaybeAsInstanceOf
- object WrapArray