-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Make Scala.js usable for people #9637
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9a2247f
80b1fd3
2b6417b
0a7d9dc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package test | ||
|
||
import scala.scalajs.js | ||
import org.scalajs.dom | ||
|
||
object Main { | ||
def main(args: Array[String]): Unit = { | ||
println("Hello Scala.js") | ||
dom.console.log("using a Scala.js dependency") | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
enablePlugins(ScalaJSPlugin) | ||
|
||
scalaVersion := sys.props("plugin.scalaVersion") | ||
|
||
// Test withDottyCompat for %%% dependencies | ||
libraryDependencies += ("org.scala-js" %%% "scalajs-dom" % "1.1.0").withDottyCompat(scalaVersion.value) | ||
|
||
scalaJSUseMainModuleInitializer := true |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % sys.props("plugin.version")) | ||
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.1.1") |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
> run |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,6 +16,7 @@ import scala.util.Properties.isJavaAtLeast | |
object DottyPlugin extends AutoPlugin { | ||
object autoImport { | ||
val isDotty = settingKey[Boolean]("Is this project compiled with Dotty?") | ||
val isDottyJS = settingKey[Boolean]("Is this project compiled with Dotty and Scala.js?") | ||
|
||
// NOTE: | ||
// - this is a def to support `scalaVersion := dottyLatestNightlyBuild` | ||
|
@@ -93,7 +94,7 @@ object DottyPlugin extends AutoPlugin { | |
val name = moduleID.name | ||
if (name != "dotty" && name != "dotty-library" && name != "dotty-compiler") | ||
moduleID.crossVersion match { | ||
case _: librarymanagement.Binary => | ||
case binary: librarymanagement.Binary => | ||
val compatVersion = | ||
CrossVersion.partialVersion(scalaVersion) match { | ||
case Some((3, _)) => | ||
|
@@ -107,7 +108,7 @@ object DottyPlugin extends AutoPlugin { | |
"" | ||
} | ||
if (compatVersion.nonEmpty) | ||
moduleID.cross(CrossVersion.constant(compatVersion)) | ||
moduleID.cross(CrossVersion.constant(binary.prefix + compatVersion + binary.suffix)) | ||
else | ||
moduleID | ||
case _ => | ||
|
@@ -170,6 +171,29 @@ object DottyPlugin extends AutoPlugin { | |
Seq( | ||
isDotty := scalaVersion.value.startsWith("0.") || scalaVersion.value.startsWith("3."), | ||
|
||
/* The way the integration with Scala.js works basically assumes that the settings of ScalaJSPlugin | ||
* will be applied before those of DottyPlugin. It seems to be the case in the tests I did, perhaps | ||
* because ScalaJSPlugin is explicitly enabled, while DottyPlugin is triggered. However, I could | ||
* not find an authoritative source on the topic. | ||
* | ||
* There is an alternative implementation that would not have that assumption: it would be to have | ||
* another DottyJSPlugin, that would be auto-triggered by the presence of *both* DottyPlugin and | ||
* ScalaJSPlugin. That plugin would be guaranteed to have its settings be applied after both of them, | ||
* by the documented rules. However, that would require sbt-dotty to depend on sbt-scalajs to be | ||
* able to refer to ScalaJSPlugin. | ||
* | ||
* When the logic of sbt-dotty moves to sbt itself, the logic specific to the Dotty-Scala.js | ||
* combination will have to move to sbt-scalajs. Doing so currently wouldn't work since we | ||
* observe that the settings of DottyPlugin are applied after ScalaJSPlugin, so ScalaJSPlugin | ||
* wouldn't be able to fix up things like the dependency on dotty-library. | ||
*/ | ||
isDottyJS := { | ||
isDotty.value && (crossVersion.value match { | ||
case binary: librarymanagement.Binary => binary.prefix.contains("sjs1_") | ||
case _ => false | ||
}) | ||
}, | ||
|
||
scalaOrganization := { | ||
if (isDotty.value) | ||
"ch.epfl.lamp" | ||
|
@@ -317,12 +341,51 @@ object DottyPlugin extends AutoPlugin { | |
|
||
// Because managedScalaInstance is false, sbt won't add the standard library to our dependencies for us | ||
libraryDependencies ++= { | ||
if (isDotty.value && autoScalaLibrary.value) | ||
Seq(scalaOrganization.value %% "dotty-library" % scalaVersion.value) | ||
else | ||
if (isDotty.value && autoScalaLibrary.value) { | ||
val name = | ||
if (isDottyJS.value) "dotty-library_sjs1" | ||
else "dotty-library" | ||
Seq(scalaOrganization.value %% name % scalaVersion.value) | ||
} else | ||
Seq() | ||
}, | ||
|
||
// Patch up some more options if this is Dotty with Scala.js | ||
sjrd marked this conversation as resolved.
Show resolved
Hide resolved
|
||
scalacOptions := { | ||
val prev = scalacOptions.value | ||
/* The `&& !prev.contains("-scalajs")` is future-proof, for when sbt-scalajs adds that | ||
* option itself but sbt-dotty is still required for the other Dotty-related stuff. | ||
*/ | ||
if (isDottyJS.value && !prev.contains("-scalajs")) prev :+ "-scalajs" | ||
else prev | ||
}, | ||
libraryDependencies := { | ||
val prev = libraryDependencies.value | ||
if (!isDottyJS.value) { | ||
prev | ||
} else { | ||
prev | ||
/* Remove the dependencies we don't want: | ||
* * We don't want scalajs-library, because we need the one that comes | ||
* as a dependency of dotty-library_sjs1 | ||
* * We don't want scalajs-compiler, because that's a compiler plugin, | ||
* which is replaced by the `-scalajs` flag in dotc. | ||
*/ | ||
.filterNot { moduleID => | ||
moduleID.organization == "org.scala-js" && ( | ||
moduleID.name == "scalajs-library" || moduleID.name == "scalajs-compiler" | ||
) | ||
} | ||
// Apply withDottyCompat to the dependency on scalajs-test-bridge | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume this applies transitively to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, because the dependency on scalajs-test-interface will be lookup up in its POM file. And in the POM file, this has already been hard-wired to scalajs-test-interface_2.13. |
||
.map { moduleID => | ||
if (moduleID.organization == "org.scala-js" && moduleID.name == "scalajs-test-bridge") | ||
moduleID.withDottyCompat(scalaVersion.value) | ||
else | ||
moduleID | ||
} | ||
} | ||
}, | ||
|
||
// Turns off the warning: | ||
// [warn] Binary version (0.9.0-RC1) for dependency ...;0.9.0-RC1 | ||
// [warn] in ... differs from Scala binary version in project (0.9). | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way this works basically assumes that the settings of
ScalaJSPlugin
will be applied before those ofDottyPlugin
. It seems to be the case in the tests I did, perhaps becauseScalaJSPlugin
is explicitly enabled, whileDottyPlugin
is triggered. However, I could not find an authoritative source on the topic.I have an alternative implementation in mind, that would not have that assumption: it would be to have another
DottyJSPlugin
, that would be auto-triggered by the presence ofDottyPlugin
andScalaJSPlugin
. That plugin would be guaranteed to have its settings be applied after both of them, by the documented rules. However, that would requiresbt-dotty
to depend onsbt-scalajs
to be able to refer toScalaJSPlugin
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hopefully in the not-too-distant future sbt-dotty will be obsoleted by sbt supporting dotty natively, so we need to plan for that too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When that happens, the Scala.js-Dotty combination will have to be handled by sbt-scalajs. Currently though, since apparently
DottyPlugin
gets applied afterScalaJSPlugin
, there's nothing sbt-scalajs can do, AFAICT.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, can you add a comment mentioning this around here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.