From 4eb3310f8ebb55fc45a600155002228d6ac087c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Sat, 12 Sep 2020 17:43:32 +0200 Subject: [PATCH] Fix #9785: Scala.js: Handle the `typeof JSGlobalRef(_)` corner case. This requires two things: - make sure that `SelectStatic` does not expand references to global scopes, and - when compiling `js.typeOf(globalRef)`, emit a `JSTypeOfGlobalRef(_)` instead of a `JSUnaryOp(typeof, JSGlobalRef(_))`. --- compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala | 6 +++++- compiler/src/dotty/tools/dotc/transform/SelectStatic.scala | 3 +++ project/Build.scala | 7 ++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala index fbe76d4bb805..3621b6fcb0ae 100644 --- a/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala +++ b/compiler/src/dotty/tools/backend/sjs/JSCodeGen.scala @@ -2932,7 +2932,11 @@ class JSCodeGen()(using genCtx: Context) { case TYPEOF => // js.typeOf(arg) val arg = genArgs1 - genAsInstanceOf(js.JSUnaryOp(js.JSUnaryOp.typeof, arg), defn.StringType) + val typeofExpr = arg match { + case arg: js.JSGlobalRef => js.JSTypeOfGlobalRef(arg) + case _ => js.JSUnaryOp(js.JSUnaryOp.typeof, arg) + } + js.AsInstanceOf(typeofExpr, jstpe.ClassType(jsNames.BoxedStringClass)) case STRICT_EQ => // js.special.strictEquals(arg1, arg2) diff --git a/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala b/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala index f4c923b73a99..6e4622fc8d4e 100644 --- a/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala +++ b/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala @@ -11,6 +11,8 @@ import dotty.tools.dotc.core._ import dotty.tools.dotc.transform.MegaPhase._ import dotty.tools.dotc.transform.SymUtils._ +import dotty.tools.backend.sjs.JSDefinitions.jsdefn + /** Removes selects that would be compiled into GetStatic * otherwise backend needs to be aware that some qualifiers need to be dropped. * Similar transformation seems to be performed by flatten in nsc @@ -31,6 +33,7 @@ class SelectStatic extends MiniPhase with IdentityDenotTransformer { val tree1 = if isStaticRef && !tree.qualifier.symbol.isAllOf(JavaModule) && !tree.qualifier.isType then if isPureExpr(tree.qualifier) then ref(sym) + else if ctx.settings.scalajs.value && sym.is(Module) && sym.moduleClass.hasAnnotation(jsdefn.JSGlobalScopeAnnot) then ref(sym) else Block(List(tree.qualifier), ref(sym)) else tree diff --git a/project/Build.scala b/project/Build.scala index b7f2b33daf09..d92724fe1832 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1009,6 +1009,12 @@ object Build { scalaJSLinkerConfig ~= { _.withSemantics(build.TestSuiteLinkerOptions.semantics _) }, scalaJSModuleInitializers in Test ++= build.TestSuiteLinkerOptions.moduleInitializers, + jsEnvInput in Test := { + val resourceDir = fetchScalaJSSource.value / "test-suite/js/src/test/resources" + val f = (resourceDir / "NonNativeJSTypeTestNatives.js").toPath + org.scalajs.jsenv.Input.Script(f) +: (jsEnvInput in Test).value + }, + managedSources in Compile ++= { val dir = fetchScalaJSSource.value / "test-suite/js/src/main/scala" val filter = ( @@ -1049,7 +1055,6 @@ object Build { -- "ExportsTest.scala" // JS exports -- "IterableTest.scala" // non-native JS classes -- "JSExportStaticTest.scala" // JS exports - -- "JSNativeInPackage.scala" // #9785 tests fail due to js.typeOf(globalVar) being incorrect -- "JSOptionalTest.scala" // non-native JS classes -- "JSSymbolTest.scala" // non-native JS classes -- "MiscInteropTest.scala" // non-native JS classes