-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1148 from sjrd/scalajs-gen-exprs
Implement most of the Scala.js IR code generator.
- Loading branch information
Showing
11 changed files
with
1,502 additions
and
90 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
package dotty.tools.backend.sjs | ||
|
||
import dotty.tools.dotc.core._ | ||
import Contexts._ | ||
import Flags._ | ||
import Symbols._ | ||
import NameOps._ | ||
import StdNames._ | ||
|
||
import JSDefinitions._ | ||
|
||
/** Management of the interoperability with JavaScript. */ | ||
object JSInterop { | ||
|
||
/** Is this symbol a JavaScript type? */ | ||
def isJSType(sym: Symbol)(implicit ctx: Context): Boolean = { | ||
//sym.hasAnnotation(jsdefn.RawJSTypeAnnot) | ||
ctx.atPhase(ctx.erasurePhase) { implicit ctx => | ||
sym.derivesFrom(jsdefn.JSAnyClass) | ||
} | ||
} | ||
|
||
/** Is this symbol a Scala.js-defined JS class, i.e., a non-native JS class? */ | ||
def isScalaJSDefinedJSClass(sym: Symbol)(implicit ctx: Context): Boolean = | ||
isJSType(sym) && !sym.hasAnnotation(jsdefn.JSNativeAnnot) | ||
|
||
/** Should this symbol be translated into a JS getter? | ||
* | ||
* This is true for any parameterless method, i.e., defined without `()`. | ||
* Unlike `SymDenotations.isGetter`, it applies to user-defined methods as | ||
* much as *accessor* methods created for `val`s and `var`s. | ||
*/ | ||
def isJSGetter(sym: Symbol)(implicit ctx: Context): Boolean = { | ||
sym.info.firstParamTypes.isEmpty && ctx.atPhase(ctx.erasurePhase) { implicit ctx => | ||
sym.info.isParameterless | ||
} | ||
} | ||
|
||
/** Should this symbol be translated into a JS setter? | ||
* | ||
* This is true for any method whose name ends in `_=`. | ||
* Unlike `SymDenotations.isGetter`, it applies to user-defined methods as | ||
* much as *accessor* methods created for `var`s. | ||
*/ | ||
def isJSSetter(sym: Symbol)(implicit ctx: Context): Boolean = | ||
sym.name.isSetterName && sym.is(Method) | ||
|
||
/** Should this symbol be translated into a JS bracket access? | ||
* | ||
* This is true for methods annotated with `@JSBracketAccess`. | ||
*/ | ||
def isJSBracketAccess(sym: Symbol)(implicit ctx: Context): Boolean = | ||
sym.hasAnnotation(jsdefn.JSBracketAccessAnnot) | ||
|
||
/** Should this symbol be translated into a JS bracket call? | ||
* | ||
* This is true for methods annotated with `@JSBracketCall`. | ||
*/ | ||
def isJSBracketCall(sym: Symbol)(implicit ctx: Context): Boolean = | ||
sym.hasAnnotation(jsdefn.JSBracketCallAnnot) | ||
|
||
/** Is this symbol a default param accessor for a JS method? | ||
* | ||
* For default param accessors of *constructors*, we need to test whether | ||
* the companion *class* of the owner is a JS type; not whether the owner | ||
* is a JS type. | ||
*/ | ||
def isJSDefaultParam(sym: Symbol)(implicit ctx: Context): Boolean = { | ||
sym.name.isDefaultGetterName && { | ||
val owner = sym.owner | ||
if (owner.is(ModuleClass) && | ||
sym.name.asTermName.defaultGetterToMethod == nme.CONSTRUCTOR) { | ||
isJSType(owner.linkedClass) | ||
} else { | ||
isJSType(owner) | ||
} | ||
} | ||
} | ||
|
||
/** Gets the unqualified JS name of a symbol. | ||
* | ||
* If it is not explicitly specified with an `@JSName` annotation, the | ||
* JS name is inferred from the Scala name. | ||
*/ | ||
def jsNameOf(sym: Symbol)(implicit ctx: Context): String = { | ||
sym.getAnnotation(jsdefn.JSNameAnnot).flatMap(_.argumentConstant(0)).fold { | ||
val base = sym.name.unexpandedName.decode.toString.stripSuffix("_=") | ||
if (sym.is(ModuleClass)) base.stripSuffix("$") | ||
else if (!sym.is(Method)) base.stripSuffix(" ") | ||
else base | ||
} { constant => | ||
constant.stringValue | ||
} | ||
} | ||
|
||
/** Gets the fully qualified JS name of a static class of module Symbol. | ||
* | ||
* This is the JS name of the symbol qualified by the fully qualified JS | ||
* name of its original owner if the latter is a native JS object. | ||
*/ | ||
def fullJSNameOf(sym: Symbol)(implicit ctx: Context): String = { | ||
assert(sym.isClass, s"fullJSNameOf called for non-class symbol $sym") | ||
sym.getAnnotation(jsdefn.JSFullNameAnnot).flatMap(_.argumentConstant(0)).fold { | ||
jsNameOf(sym) | ||
} { constant => | ||
constant.stringValue | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters