Skip to content

Commit 539dd06

Browse files
authored
Merge pull request #9637 from sjrd/make-sjs-usable-for-people
2 parents 5a23f53 + 0a7d9dc commit 539dd06

File tree

6 files changed

+103
-17
lines changed

6 files changed

+103
-17
lines changed

project/Build.scala

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,6 @@ object MyScalaJSPlugin extends AutoPlugin {
3636
override def projectSettings: Seq[Setting[_]] = Def.settings(
3737
commonBootstrappedSettings,
3838

39-
/* Remove the Scala.js compiler plugin for scalac, and enable the
40-
* Scala.js back-end of dotty instead.
41-
*/
42-
libraryDependencies := {
43-
val deps = libraryDependencies.value
44-
deps.filterNot(_.name.startsWith("scalajs-compiler")).map(_.withDottyCompat(scalaVersion.value))
45-
},
46-
scalacOptions += "-scalajs",
47-
4839
// Replace the JVM JUnit dependency by the Scala.js one
4940
libraryDependencies ~= {
5041
_.filter(!_.name.startsWith("junit-interface"))
@@ -289,8 +280,11 @@ object Build {
289280
Some((packageBin in (`dotty-sbt-bridge`, Compile)).value)
290281
},
291282

292-
// Use the same name as the non-bootstrapped projects for the artifacts
293-
moduleName ~= { _.stripSuffix("-bootstrapped") },
283+
// Use the same name as the non-bootstrapped projects for the artifacts.
284+
// Remove the `js` suffix because JS artifacts are published using their special crossVersion.
285+
// The order of the two `stripSuffix`es is important, so that
286+
// dotty-library-bootstrappedjs becomes dotty-library.
287+
moduleName ~= { _.stripSuffix("js").stripSuffix("-bootstrapped") },
294288

295289
// Enforce that the only Scala 2 classfiles we unpickle come from scala-library
296290
/*
@@ -778,8 +772,14 @@ object Build {
778772
asDottyLibrary(Bootstrapped).
779773
enablePlugins(MyScalaJSPlugin).
780774
settings(
775+
libraryDependencies +=
776+
("org.scala-js" %% "scalajs-library" % scalaJSVersion).withDottyCompat(scalaVersion.value),
781777
unmanagedSourceDirectories in Compile :=
782778
(unmanagedSourceDirectories in (`dotty-library-bootstrapped`, Compile)).value,
779+
780+
// Make sure `dotty-bootstrapped/test` doesn't fail on this project for no reason
781+
test in Test := {},
782+
testOnly in Test := {},
783783
)
784784

785785
lazy val tastyCoreSettings = Seq(
@@ -1397,7 +1397,8 @@ object Build {
13971397
def asDottyRoot(implicit mode: Mode): Project = project.withCommonSettings.
13981398
aggregate(`dotty-interfaces`, dottyLibrary, dottyCompiler, tastyCore, dottyDoc, `dotty-sbt-bridge`).
13991399
bootstrappedAggregate(`scala-library`, `scala-compiler`, `scala-reflect`, scalap,
1400-
`dotty-language-server`, `dotty-staging`, `dotty-tasty-inspector`, `dotty-tastydoc`).
1400+
`dotty-language-server`, `dotty-staging`, `dotty-tasty-inspector`, `dotty-tastydoc`,
1401+
`dotty-library-bootstrappedJS`).
14011402
dependsOn(tastyCore).
14021403
dependsOn(dottyCompiler).
14031404
dependsOn(dottyLibrary).
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package test
2+
3+
import scala.scalajs.js
4+
import org.scalajs.dom
5+
6+
object Main {
7+
def main(args: Array[String]): Unit = {
8+
println("Hello Scala.js")
9+
dom.console.log("using a Scala.js dependency")
10+
}
11+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
enablePlugins(ScalaJSPlugin)
2+
3+
scalaVersion := sys.props("plugin.scalaVersion")
4+
5+
// Test withDottyCompat for %%% dependencies
6+
libraryDependencies += ("org.scala-js" %%% "scalajs-dom" % "1.1.0").withDottyCompat(scalaVersion.value)
7+
8+
scalaJSUseMainModuleInitializer := true
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % sys.props("plugin.version"))
2+
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.1.1")

sbt-dotty/sbt-test/scalajs/basic/test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
> run

sbt-dotty/src/dotty/tools/sbtplugin/DottyPlugin.scala

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import scala.util.Properties.isJavaAtLeast
1616
object DottyPlugin extends AutoPlugin {
1717
object autoImport {
1818
val isDotty = settingKey[Boolean]("Is this project compiled with Dotty?")
19+
val isDottyJS = settingKey[Boolean]("Is this project compiled with Dotty and Scala.js?")
1920

2021
// NOTE:
2122
// - this is a def to support `scalaVersion := dottyLatestNightlyBuild`
@@ -93,7 +94,7 @@ object DottyPlugin extends AutoPlugin {
9394
val name = moduleID.name
9495
if (name != "dotty" && name != "dotty-library" && name != "dotty-compiler")
9596
moduleID.crossVersion match {
96-
case _: librarymanagement.Binary =>
97+
case binary: librarymanagement.Binary =>
9798
val compatVersion =
9899
CrossVersion.partialVersion(scalaVersion) match {
99100
case Some((3, _)) =>
@@ -107,7 +108,7 @@ object DottyPlugin extends AutoPlugin {
107108
""
108109
}
109110
if (compatVersion.nonEmpty)
110-
moduleID.cross(CrossVersion.constant(compatVersion))
111+
moduleID.cross(CrossVersion.constant(binary.prefix + compatVersion + binary.suffix))
111112
else
112113
moduleID
113114
case _ =>
@@ -170,6 +171,29 @@ object DottyPlugin extends AutoPlugin {
170171
Seq(
171172
isDotty := scalaVersion.value.startsWith("0.") || scalaVersion.value.startsWith("3."),
172173

174+
/* The way the integration with Scala.js works basically assumes that the settings of ScalaJSPlugin
175+
* will be applied before those of DottyPlugin. It seems to be the case in the tests I did, perhaps
176+
* because ScalaJSPlugin is explicitly enabled, while DottyPlugin is triggered. However, I could
177+
* not find an authoritative source on the topic.
178+
*
179+
* There is an alternative implementation that would not have that assumption: it would be to have
180+
* another DottyJSPlugin, that would be auto-triggered by the presence of *both* DottyPlugin and
181+
* ScalaJSPlugin. That plugin would be guaranteed to have its settings be applied after both of them,
182+
* by the documented rules. However, that would require sbt-dotty to depend on sbt-scalajs to be
183+
* able to refer to ScalaJSPlugin.
184+
*
185+
* When the logic of sbt-dotty moves to sbt itself, the logic specific to the Dotty-Scala.js
186+
* combination will have to move to sbt-scalajs. Doing so currently wouldn't work since we
187+
* observe that the settings of DottyPlugin are applied after ScalaJSPlugin, so ScalaJSPlugin
188+
* wouldn't be able to fix up things like the dependency on dotty-library.
189+
*/
190+
isDottyJS := {
191+
isDotty.value && (crossVersion.value match {
192+
case binary: librarymanagement.Binary => binary.prefix.contains("sjs1_")
193+
case _ => false
194+
})
195+
},
196+
173197
scalaOrganization := {
174198
if (isDotty.value)
175199
"ch.epfl.lamp"
@@ -317,12 +341,51 @@ object DottyPlugin extends AutoPlugin {
317341

318342
// Because managedScalaInstance is false, sbt won't add the standard library to our dependencies for us
319343
libraryDependencies ++= {
320-
if (isDotty.value && autoScalaLibrary.value)
321-
Seq(scalaOrganization.value %% "dotty-library" % scalaVersion.value)
322-
else
344+
if (isDotty.value && autoScalaLibrary.value) {
345+
val name =
346+
if (isDottyJS.value) "dotty-library_sjs1"
347+
else "dotty-library"
348+
Seq(scalaOrganization.value %% name % scalaVersion.value)
349+
} else
323350
Seq()
324351
},
325352

353+
// Patch up some more options if this is Dotty with Scala.js
354+
scalacOptions := {
355+
val prev = scalacOptions.value
356+
/* The `&& !prev.contains("-scalajs")` is future-proof, for when sbt-scalajs adds that
357+
* option itself but sbt-dotty is still required for the other Dotty-related stuff.
358+
*/
359+
if (isDottyJS.value && !prev.contains("-scalajs")) prev :+ "-scalajs"
360+
else prev
361+
},
362+
libraryDependencies := {
363+
val prev = libraryDependencies.value
364+
if (!isDottyJS.value) {
365+
prev
366+
} else {
367+
prev
368+
/* Remove the dependencies we don't want:
369+
* * We don't want scalajs-library, because we need the one that comes
370+
* as a dependency of dotty-library_sjs1
371+
* * We don't want scalajs-compiler, because that's a compiler plugin,
372+
* which is replaced by the `-scalajs` flag in dotc.
373+
*/
374+
.filterNot { moduleID =>
375+
moduleID.organization == "org.scala-js" && (
376+
moduleID.name == "scalajs-library" || moduleID.name == "scalajs-compiler"
377+
)
378+
}
379+
// Apply withDottyCompat to the dependency on scalajs-test-bridge
380+
.map { moduleID =>
381+
if (moduleID.organization == "org.scala-js" && moduleID.name == "scalajs-test-bridge")
382+
moduleID.withDottyCompat(scalaVersion.value)
383+
else
384+
moduleID
385+
}
386+
}
387+
},
388+
326389
// Turns off the warning:
327390
// [warn] Binary version (0.9.0-RC1) for dependency ...;0.9.0-RC1
328391
// [warn] in ... differs from Scala binary version in project (0.9).

0 commit comments

Comments
 (0)