Skip to content

Commit d6fe8b9

Browse files
committed
Scala.js: Add support for js.constructorOf[T].
To do this, we add a new mini-phase that rewrites calls of the form scala.scalajs.js.constructor[T] to scala.scalajs.runtime.constructorOf(classOf[T]) The back-end already knew how to compile calls to `runtime.constructorOf`, so there were no changes needed there. The new mini-phase will also serve in the future for handling inner and local JS classes.
1 parent fe5f7a4 commit d6fe8b9

File tree

3 files changed

+70
-7
lines changed

3 files changed

+70
-7
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ class Compiler {
7272
List(new ElimOpaque, // Turn opaque into normal aliases
7373
new TryCatchPatterns, // Compile cases in try/catch
7474
new PatternMatcher, // Compile pattern matches
75+
new ExplicitJSClasses, // Make all JS classes explicit (Scala.js only)
7576
new ExplicitOuter, // Add accessors to outer classes from nested ones.
7677
new ExplicitSelf, // Make references to non-trivial self types explicit as casts
7778
new StringInterpolatorOpt, // Optimizes raw and s string interpolators by rewriting them to string concatentations
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package dotty.tools
2+
package dotc
3+
package transform
4+
5+
import MegaPhase._
6+
import core.DenotTransformers._
7+
import core.Symbols._
8+
import core.Contexts._
9+
import core.Phases._
10+
import core.Types._
11+
import core.Flags._
12+
import core.Decorators._
13+
import core.StdNames.nme
14+
import core.Names._
15+
import core.NameOps._
16+
import ast.Trees._
17+
import SymUtils._
18+
import dotty.tools.dotc.ast.tpd
19+
20+
import dotty.tools.backend.sjs.JSDefinitions.jsdefn
21+
22+
/** This phase makes all JS classes explicit (their definitions and references to them).
23+
*
24+
* Ultimately, this will be the equivalent of the two phases `ExplicitInnerJS`
25+
* and `ExplicitLocalJS` from Scala 2. Currently, this phase only performs the
26+
* following transformations:
27+
*
28+
* - Rewrite `js.constructorOf[T]` into `scala.scalajs.runtime.constructorOf(classOf[T])`,
29+
* where the `classOf[T]` is represented as a `Literal`.
30+
*/
31+
class ExplicitJSClasses extends MiniPhase with InfoTransformer { thisPhase =>
32+
import ExplicitJSClasses._
33+
import ast.tpd._
34+
35+
override def phaseName: String = ExplicitJSClasses.name
36+
37+
override def isEnabled(using Context): Boolean =
38+
ctx.settings.scalajs.value
39+
40+
override def runsAfter: Set[String] = Set(PatternMatcher.name, HoistSuperArgs.name)
41+
42+
override def changesMembers: Boolean = true // the phase adds fields for inner JS classes
43+
44+
override def transformInfo(tp: Type, sym: Symbol)(using Context): Type = {
45+
// Currently we don't do anything here. Eventually we'll add fields for inner JS classes.
46+
tp
47+
}
48+
49+
override def infoMayChange(sym: Symbol)(using Context): Boolean =
50+
sym.isClass && !sym.is(JavaDefined)
51+
52+
override def transformTypeApply(tree: TypeApply)(using Context): tpd.Tree = {
53+
tree match {
54+
case TypeApply(fun, tpt :: Nil) if fun.symbol == jsdefn.JSPackage_constructorOf =>
55+
ref(jsdefn.Runtime_constructorOf).appliedTo(clsOf(tpt.tpe))
56+
case _ =>
57+
tree
58+
}
59+
}
60+
}
61+
62+
object ExplicitJSClasses {
63+
val name: String = "explicitJSClasses"
64+
}

project/Build.scala

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,17 +1064,16 @@ object Build {
10641064
++ (dir / "shared/src/test/require-jdk7/org/scalajs/testsuite/javalib/util" ** "*.scala").get
10651065

10661066
++ (dir / "js/src/test/scala/org/scalajs/testsuite/compiler" ** (("*.scala": FileFilter)
1067-
-- "InteroperabilityTest.scala" // various compile errors
1068-
-- "OptimizerTest.scala" // compile errors: false + string and () + string
1069-
-- "ReflectionTest.scala" // tests fail
1067+
-- "InteroperabilityTest.scala" // various compile errors, pending update upstream
1068+
-- "OptimizerTest.scala" // compile errors: false + string and () + string, pending update upstream
1069+
-- "ReflectionTest.scala" // tests fail (wrong load spec for JS globals)
10701070
-- "RegressionJSTest.scala" // non-native JS classes
10711071
-- "RuntimeTypesTest.scala" // compile errors: no ClassTag for Null and Nothing
10721072
)).get
10731073

10741074
++ (dir / "js/src/test/scala/org/scalajs/testsuite/javalib" ** (("*.scala": FileFilter)
10751075
-- "FormatterJSTest.scala" // compile error with the f"" interpolator
10761076
-- "ObjectJSTest.scala" // non-native JS classes
1077-
-- "ThrowableJSTest.scala" // test fails ("java.lang.Error: stub") because it uses js.constructorOf
10781077
)).get
10791078

10801079
++ (dir / "js/src/test/scala/org/scalajs/testsuite/jsinterop" ** (("*.scala": FileFilter)
@@ -1083,15 +1082,14 @@ object Build {
10831082
-- "ExportsTest.scala" // JS exports
10841083
-- "IterableTest.scala" // non-native JS classes
10851084
-- "JSExportStaticTest.scala" // JS exports
1086-
-- "JSNativeInPackage.scala" // IR checking errors
1085+
-- "JSNativeInPackage.scala" // tests fail (wrong load spec for JS globals)
10871086
-- "JSOptionalTest.scala" // non-native JS classes
10881087
-- "JSSymbolTest.scala" // non-native JS classes
10891088
-- "MiscInteropTest.scala" // non-native JS classes
10901089
-- "ModulesWithGlobalFallbackTest.scala" // non-native JS classes
10911090
-- "NestedJSClassTest.scala" // non-native JS classes
10921091
-- "NonNativeJSTypeTest.scala" // non-native JS classes
10931092
-- "PromiseMock.scala" // non-native JS classes
1094-
-- "SpecialTest.scala" // test fails ("java.lang.Error: stub") because it uses js.constructorOf
10951093
)).get
10961094

10971095
++ (dir / "js/src/test/scala/org/scalajs/testsuite/junit" ** (("*.scala": FileFilter)
@@ -1104,7 +1102,7 @@ object Build {
11041102

11051103
++ (dir / "js/src/test/scala/org/scalajs/testsuite/library" ** (("*.scala": FileFilter)
11061104
-- "BigIntTest.scala" // Ambiguous reference because of new non-shadowing rule in Scala 3, pending update upstream
1107-
-- "ObjectTest.scala" // compile errors
1105+
-- "ObjectTest.scala" // compile errors caused by #9588
11081106
-- "StackTraceTest.scala" // would require `npm install source-map-support`
11091107
-- "UnionTypeTest.scala" // requires a Scala 2 macro
11101108
)).get

0 commit comments

Comments
 (0)