Skip to content

Commit 3a9b34a

Browse files
authored
Merge pull request #2745 from tanishiking/module-kind
Support WebAssembly: Correctly detect Scala.js 1.x scalaJSLinkerConfig#...
2 parents bcf77a7 + 7721f37 commit 3a9b34a

File tree

5 files changed

+74
-13
lines changed

5 files changed

+74
-13
lines changed

bridges/scalajs-1/src/main/scala/bloop/scalajs/JsBridge.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ object JsBridge {
8181
.withModuleKind(scalaJSModuleKind)
8282
.withSourceMap(config.emitSourceMaps)
8383
.withMinify(isFullLinkJS)
84+
.withExperimentalUseWebAssembly(config.useWebAssembly)
8485

8586
(config.kind, scalaJSModuleKindSplitStyle) match {
8687
case (ModuleKindJS.ESModule, Some(value)) =>

frontend/src/main/scala/bloop/engine/Interpreter.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,8 +620,16 @@ object Interpreter {
620620
None
621621
)
622622
.flatMap { state =>
623+
// TODO: We should use `jsEnvInput` to obtain the JS files to run
624+
// (or even use https://github.com/scala-js/scala-js-js-envs to run ideally),
625+
// https://github.com/scala-js/scala-js/blob/6a145af4dc575340a40b80459d1bf15184c3a2da/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala#L252-L255
626+
// and get command line options from `jsEnv` tasks for Node.js options.
627+
// https://github.com/scala-js/scala-js/blob/6a145af4dc575340a40b80459d1bf15184c3a2da/sbt-plugin/src/main/scala/org/scalajs/sbtplugin/ScalaJSPlugin.scala#L238-L240
628+
// For now, we just filter .js files (so we don't include sourcemap, .wasm files, and __loader.js generated for Wasm), and run them.
629+
val files = targetDirectory.list
630+
.map(_.toString())
631+
.filter(name => name.endsWith(".js") && !name.endsWith("__loader.js"))
623632
// We use node to run the program (is this a special case?)
624-
val files = targetDirectory.list.map(_.toString())
625633
val args = ("node" +: files ::: cmd.args).toArray
626634
if (!state.status.isOk) Task.now(state)
627635
else Tasks.runNativeOrJs(state, cwd, args)

integrations/sbt-bloop/src/main/scala/bloop/integrations/sbt/SbtBloop.scala

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ object BloopKeys {
9494
settingKey[Option[String]]("Scala.js-independent definition of `scalaJSStage`")
9595
val bloopScalaJSModuleKind: SettingKey[Option[String]] =
9696
settingKey[Option[String]]("Scala.js-independent definition of `scalaJSModuleKind`")
97+
val bloopScalaJSSourceMap: SettingKey[Option[Boolean]] =
98+
settingKey("Proxy for Scala.js definition of `scalajsLinkerConfig#sourceMap`")
99+
val bloopScalaJSUseWebAssembly: SettingKey[Option[Boolean]] =
100+
settingKey("Proxy for Scala.js definition of `scalajsLinkerConfig#experimentalUseWebAssembly`")
97101
val bloopMainClass: SettingKey[Option[String]] =
98102
settingKey[Option[String]]("The main class to run a bloop target")
99103
val bloopSupportedConfigurations: SettingKey[Seq[Configuration]] =
@@ -137,6 +141,8 @@ object BloopDefaults {
137141
import Compat._
138142
import sbt.{Task, Defaults, State}
139143

144+
private final val StandardConfigClassName = "org.scalajs.linker.interface.StandardConfig"
145+
140146
val productDirectoriesUndeprecatedKey: TaskKey[Seq[File]] =
141147
sbt.TaskKey[Seq[File]]("productDirectories", rank = KeyRanks.CTask)
142148

@@ -237,6 +243,8 @@ object BloopDefaults {
237243
List(
238244
BloopKeys.bloopScalaJSStage := findOutScalaJsStage.value,
239245
BloopKeys.bloopScalaJSModuleKind := findOutScalaJsModuleKind.value,
246+
BloopKeys.bloopScalaJSSourceMap := findOutScalaJsSourceMap.value,
247+
BloopKeys.bloopScalaJSUseWebAssembly := findOutScalaJsUseWebAssembly.value,
240248
// Override checksums so that `updates` don't check md5 for all jars
241249
Keys.update / Keys.checksums := Vector("sha1"),
242250
Keys.updateClassifiers / Keys.checksums := Vector("sha1"),
@@ -312,23 +320,64 @@ object BloopDefaults {
312320
}
313321
} catch {
314322
case _: ClassNotFoundException => Def.setting(None)
323+
case _: NoSuchMethodException => Def.setting(None)
315324
}
316325
}
317326

318327
def findOutScalaJsModuleKind: Def.Initialize[Option[String]] = Def.settingDyn {
319328
try {
320-
val stageClass = Class.forName("core.tools.linker.backend.ModuleKind")
321-
val stageSetting = proxyForSetting("scalaJSModuleKind", stageClass)
329+
val NoModuleClazz = Class.forName("org.scalajs.linker.interface.ModuleKind$NoModule$")
330+
val CommonJSModuleClazz =
331+
Class.forName("org.scalajs.linker.interface.ModuleKind$CommonJSModule$")
332+
val ESModuleClazz = Class.forName("org.scalajs.linker.interface.ModuleKind$ESModule$")
333+
val StandardConfigClazz = Class.forName(StandardConfigClassName)
334+
val method = StandardConfigClazz.getDeclaredMethod("moduleKind")
335+
322336
Def.setting {
323-
stageSetting.value.toString match {
324-
case "Some(NoModule)" => Some(NoJSModule)
325-
case "Some(CommonJSModule)" => Some(CommonJSModule)
326-
case "Some(ESModule)" => Some(ESModule)
327-
case _ => None
337+
proxyForSetting("scalaJSLinkerConfig", StandardConfigClazz).value.flatMap { config =>
338+
val moduleKind = method.invoke(config)
339+
if (NoModuleClazz.isInstance(moduleKind)) Some(NoJSModule)
340+
else if (ESModuleClazz.isInstance(moduleKind)) Some(ESModule)
341+
else if (CommonJSModuleClazz.isInstance(moduleKind)) Some(CommonJSModule)
342+
else None
328343
}
329344
}
330345
} catch {
331346
case _: ClassNotFoundException => Def.setting(None)
347+
case _: NoSuchMethodException => Def.setting(None)
348+
}
349+
}
350+
351+
def findOutScalaJsSourceMap: Def.Initialize[Option[Boolean]] = Def.settingDyn {
352+
try {
353+
val StandardConfigClazz = Class.forName(StandardConfigClassName)
354+
val method = StandardConfigClazz.getDeclaredMethod("sourceMap")
355+
Def.setting {
356+
proxyForSetting("scalaJSLinkerConfig", StandardConfigClazz).value.flatMap { config =>
357+
val sourceMap = method.invoke(config)
358+
Some(sourceMap.asInstanceOf[Boolean])
359+
}
360+
}
361+
} catch {
362+
case _: ClassNotFoundException => Def.setting(None)
363+
case _: NoSuchMethodException => Def.setting(None)
364+
}
365+
}
366+
367+
def findOutScalaJsUseWebAssembly: Def.Initialize[Option[Boolean]] = Def.settingDyn {
368+
try {
369+
val StandardConfigClazz = Class.forName(StandardConfigClassName)
370+
val method = StandardConfigClazz.getDeclaredMethod("experimentalUseWebAssembly")
371+
Def.setting {
372+
proxyForSetting("scalaJSLinkerConfig", StandardConfigClazz).value.flatMap { config =>
373+
// https://github.com/scala-js/scala-js/blob/6a145af4dc575340a40b80459d1bf15184c3a2da/linker-interface/shared/src/main/scala/org/scalajs/linker/interface/StandardConfig.scala#L88-L89
374+
val sourceMap = method.invoke(config)
375+
Some(sourceMap.asInstanceOf[Boolean])
376+
}
377+
}
378+
} catch {
379+
case _: ClassNotFoundException => Def.setting(None)
380+
case _: NoSuchMethodException => Def.setting(None)
332381
}
333382
}
334383

@@ -762,7 +811,7 @@ object BloopDefaults {
762811
.find(module => module.organization == "org.scala-js" && module.name.startsWith("scalajs-library_"))
763812
.map(_.revision)
764813
.getOrElse(BuildInfo.latestScalaJsVersion)
765-
814+
766815
val scalaJsStage = BloopKeys.bloopScalaJSStage.value match {
767816
case Some(ScalaJsFastOpt) => Config.LinkerMode.Debug
768817
case Some(ScalaJsFullOpt) => Config.LinkerMode.Release
@@ -776,10 +825,11 @@ object BloopDefaults {
776825
case _ => Config.ModuleKindJS.NoModule
777826
}
778827

779-
val scalaJsEmitSourceMaps =
780-
ScalaJsKeys.scalaJSEmitSourceMaps.?.value.getOrElse(false)
828+
val scalaJsEmitSourceMaps = BloopKeys.bloopScalaJSSourceMap.value.getOrElse(false)
829+
val scalaJsUseWebAssembly = BloopKeys.bloopScalaJSUseWebAssembly.value.getOrElse(false)
781830
val jsdom = Some(false)
782-
val jsConfig = Config.JsConfig(scalaJsVersion, scalaJsStage, scalaJsModule, scalaJsEmitSourceMaps, jsdom, None, None, Nil)
831+
val jsConfig = Config.JsConfig(scalaJsVersion, scalaJsStage, scalaJsModule, scalaJsEmitSourceMaps, jsdom, None, None, Nil,
832+
/* moduleSplitStyle*/ None, scalaJsUseWebAssembly)
783833
Config.Platform.Js(jsConfig, mainClass)
784834
}
785835
} else {

integrations/sbt-bloop/src/main/scala/bloop/integrations/sbt/ScalaJsKeys.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package bloop.integrations.sbt
22

33
object ScalaJsKeys {
44
import sbt.{SettingKey, settingKey}
5+
6+
@deprecated("Use bloopScalaJSSourceMap instead.")
57
val scalaJSEmitSourceMaps: SettingKey[Boolean] =
68
settingKey("Proxy for Scala.js definition of `scalaJSEmitSourceMaps`")
79
}

project/Dependencies.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ object Dependencies {
4343
val asmVersion = "9.8"
4444
val ztExecVersion = "1.12"
4545
val debugAdapterVersion = "4.2.8"
46-
val bloopConfigVersion = "2.3.2"
46+
val bloopConfigVersion = "2.3.3"
4747
val semanticdbVersion = "4.9.9"
4848
val millVersion = "0.12.7"
4949
val zinc = "org.scala-sbt" %% "zinc" % zincVersion

0 commit comments

Comments
 (0)