@@ -16,6 +16,7 @@ import scala.util.Properties.isJavaAtLeast
1616object 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`
@@ -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