abstract class ExplicitInnerJS[G <: Global with Singleton] extends PluginComponent with InfoTransform with TypingTransformers with CompatComponent
Makes the references to inner JS class values explicit.
Roughly, for every inner JS class of the form:
class Outer { class Inner extends ParentJSClass }
this phase creates a field Inner$jsclass
in Outer
to hold the JS class
value for Inner
. The rhs of that field is a call to a magic method, used
to retain information that the back-end will need.
class Outer { <synthetic> val Inner$jsclass: AnyRef = createJSClass(classOf[Inner], js.constructorOf[ParentJSClass]) class Inner extends ParentJSClass }
These fields will be read by code generated in ExplicitLocalJS
.
A $jsclass
field is also generated for classes declared inside *static
JS objects*. Indeed, even though those classes have a unique, globally
accessible class value, that class value needs to be *exposed* as a field
of the enclosing object. In those cases, the rhs of the field is a direct
call to runtime.constructorOf[classOf[Inner]]
.
Finally, for *modules* declared inside static JS objects, we generate an
explicit exposed getter as well. For non-static objects, scalac already
generates a getter with the @ExposedJSMember
annotation, so we do not
need to do anything. But for static objects, it doesn't, so we have to do
it ourselves here.
To illustrate the two above paragraphs, for the following input:
object Outer extends js.Object { class InnerClass extends ParentJSClass object InnerObject extends SomeOtherJSClass }
this phase will generate
object Outer extends js.Object { ... @ExposedJSMember @JSName("InnerClass") val InnerClass$jsclass: AnyRef = runtime.constructorOf(classOf[InnerClass]) @ExposedJSMember @JSName("InnerObject") def InnerObject$jsobject: AnyRef = InnerObject }
Note that this field must also be added to outer classes and traits coming
from separate compilation, therefore this phase is an InfoTransform
.
Since the transformInfo
also applies to classes defined in the current
compilation unit, the tree traversal must not create the field symbols a
second time when synthesizing the ValDef
. Instead, it must reuse the same
symbols that transformInfo
will create.
It seems the easiest way to do that is to run the entire transform
"in
the future", with exitingPhase(ExplicitInnerJS)
. This design is similar
to how explicitouter
works.
- Alphabetic
- By Inheritance
- ExplicitInnerJS
- CompatComponent
- TypingTransformers
- InfoTransform
- Transform
- PluginComponent
- SubComponent
- AnyRef
- Any
- Hide All
- Show All
- Public
- All
Instance Constructors
- new ExplicitInnerJS(global: G)
Type Members
-
implicit
class
BTypesCompat
extends AnyRef
- Definition Classes
- CompatComponent
-
implicit final
class
GlobalCompat
extends AnyRef
- Definition Classes
- CompatComponent
-
implicit final
class
SAMFunctionCompatOps
extends AnyRef
- Definition Classes
- CompatComponent
-
implicit final
class
StdTermNamesCompat
extends AnyRef
- Definition Classes
- CompatComponent
-
implicit final
class
StdTypeNamesCompat
extends AnyRef
- Definition Classes
- CompatComponent
-
implicit final
class
SymbolCompat
extends AnyRef
- Definition Classes
- CompatComponent
-
implicit final
class
TyperCompat
extends AnyRef
- Definition Classes
- CompatComponent
- class ExplicitInnerJSTransformer extends TypingTransformer
-
class
Phase extends scala.tools.nsc.transform.InfoTransform.Phase
- Definition Classes
- InfoTransform
-
type
SAMFunctionCompat = G.SAMFunction
- Definition Classes
- CompatComponent
-
abstract
class
StdPhase extends GlobalPhase
- Definition Classes
- SubComponent
-
abstract
class
TypingTransformer extends scala.tools.nsc.Global.Transformer
- Definition Classes
- TypingTransformers
Abstract Value Members
- abstract val jsAddons: JSGlobalAddons { val global: ExplicitInnerJS.this.global.type }
-
abstract
val
runsAfter: List[String]
- Definition Classes
- SubComponent
Concrete Value Members
-
object
SAMFunctionAttachCompat
- Definition Classes
- CompatComponent
-
object
SAMFunctionAttachCompatDef
- Definition Classes
- CompatComponent
-
object
WarningCategoryCompat
- Definition Classes
- CompatComponent
-
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
-
lazy val
SAMFunctionCompat: G.SAMFunction.type
- Definition Classes
- CompatComponent
-
val
WarningCategory: CompatComponent.WarningCategoryCompat.Reporting.WarningCategory.type
- Definition Classes
- CompatComponent
-
final
def
afterOwnPhase[T](op: ⇒ T): T
- Definition Classes
- SubComponent
- Annotations
- @inline()
-
final
def
asInstanceOf[T0]: T0
- Definition Classes
- Any
-
final
def
beforeOwnPhase[T](op: ⇒ T): T
- Definition Classes
- SubComponent
- Annotations
- @inline()
-
def
changesBaseClasses: Boolean
This class does not change linearization.
This class does not change linearization.
- Attributes
- protected
- Definition Classes
- ExplicitInnerJS → InfoTransform
-
def
clone(): AnyRef
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( ... )
-
def
description: String
- Definition Classes
- ExplicitInnerJS → PluginComponent
-
def
enabled: Boolean
- Definition Classes
- SubComponent
-
final
def
eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
def
equals(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
-
def
finalize(): Unit
- Attributes
- protected[java.lang]
- Definition Classes
- AnyRef
- Annotations
- @throws( classOf[java.lang.Throwable] )
-
final
def
getClass(): Class[_]
- Definition Classes
- AnyRef → Any
-
val
global: G
- Definition Classes
- ExplicitInnerJS → CompatComponent → TypingTransformers → SubComponent
-
def
hashCode(): Int
- Definition Classes
- SubComponent → AnyRef → Any
-
val
initial: Boolean
- Definition Classes
- SubComponent
-
final
val
internal: Boolean(false)
- Definition Classes
- PluginComponent → SubComponent
-
def
isImplClass(sym: G.Symbol): Boolean
- Definition Classes
- CompatComponent
-
final
def
isInstanceOf[T0]: Boolean
- Definition Classes
- Any
-
lazy val
isScala211: Boolean
- Definition Classes
- CompatComponent
-
def
keepsTypeParams: Boolean
- Attributes
- protected
- Definition Classes
- InfoTransform
-
final
def
ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
-
def
newPhase(prev: scala.tools.nsc.Phase): StdPhase
- Definition Classes
- InfoTransform → Transform → SubComponent
-
def
newTransformer(unit: G.CompilationUnit): G.Transformer
- Attributes
- protected
- Definition Classes
- ExplicitInnerJS → Transform
-
final
def
notify(): Unit
- Definition Classes
- AnyRef
-
final
def
notifyAll(): Unit
- Definition Classes
- AnyRef
-
def
ownPhase: scala.tools.nsc.Phase
- Definition Classes
- SubComponent
-
val
phaseName: String
- Definition Classes
- ExplicitInnerJS → SubComponent
-
def
phaseNewFlags: Long
- Definition Classes
- SubComponent
-
def
phaseNextFlags: Long
- Definition Classes
- SubComponent
-
val
requires: List[String]
- Definition Classes
- SubComponent
-
val
runsBefore: List[String]
- Definition Classes
- SubComponent
-
val
runsRightAfter: Option[String]
- Definition Classes
- PluginComponent → SubComponent
-
lazy val
scalaUsesImplClasses: Boolean
- Definition Classes
- CompatComponent
-
final
def
synchronized[T0](arg0: ⇒ T0): T0
- Definition Classes
- AnyRef
-
val
terminal: Boolean
- Definition Classes
- SubComponent
-
def
toString(): String
- Definition Classes
- AnyRef → Any
-
def
transformInfo(sym: G.Symbol, tp: G.Type): G.Type
Transforms the info of types to add the
Inner$jsclass
fields.Transforms the info of types to add the
Inner$jsclass
fields.This method was inspired by
ExplicitOuter.transformInfo
.- Definition Classes
- ExplicitInnerJS → InfoTransform
-
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( ... )