@@ -16,6 +16,7 @@ import scala.util.Properties.isJavaAtLeast
16
16
object DottyPlugin extends AutoPlugin {
17
17
object autoImport {
18
18
val isDotty = settingKey[Boolean ](" Is this project compiled with Dotty?" )
19
+ val isDottyJS = settingKey[Boolean ](" Is this project compiled with Dotty and Scala.js?" )
19
20
20
21
// NOTE:
21
22
// - this is a def to support `scalaVersion := dottyLatestNightlyBuild`
@@ -93,7 +94,7 @@ object DottyPlugin extends AutoPlugin {
93
94
val name = moduleID.name
94
95
if (name != " dotty" && name != " dotty-library" && name != " dotty-compiler" )
95
96
moduleID.crossVersion match {
96
- case _ : librarymanagement.Binary =>
97
+ case binary : librarymanagement.Binary =>
97
98
val compatVersion =
98
99
CrossVersion .partialVersion(scalaVersion) match {
99
100
case Some ((3 , _)) =>
@@ -107,7 +108,7 @@ object DottyPlugin extends AutoPlugin {
107
108
" "
108
109
}
109
110
if (compatVersion.nonEmpty)
110
- moduleID.cross(CrossVersion .constant(compatVersion))
111
+ moduleID.cross(CrossVersion .constant(binary.prefix + compatVersion + binary.suffix ))
111
112
else
112
113
moduleID
113
114
case _ =>
@@ -170,6 +171,29 @@ object DottyPlugin extends AutoPlugin {
170
171
Seq (
171
172
isDotty := scalaVersion.value.startsWith(" 0." ) || scalaVersion.value.startsWith(" 3." ),
172
173
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
+
173
197
scalaOrganization := {
174
198
if (isDotty.value)
175
199
" ch.epfl.lamp"
@@ -317,12 +341,51 @@ object DottyPlugin extends AutoPlugin {
317
341
318
342
// Because managedScalaInstance is false, sbt won't add the standard library to our dependencies for us
319
343
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
323
350
Seq ()
324
351
},
325
352
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
+
326
389
// Turns off the warning:
327
390
// [warn] Binary version (0.9.0-RC1) for dependency ...;0.9.0-RC1
328
391
// [warn] in ... differs from Scala binary version in project (0.9).
0 commit comments