@@ -28,6 +28,35 @@ import sbtbuildinfo.BuildInfoPlugin.autoImport._
2828
2929import scala .util .Properties .isJavaAtLeast
3030
31+ object MyScalaJSPlugin extends AutoPlugin {
32+ import Build ._
33+
34+ override def requires : Plugins = ScalaJSPlugin
35+
36+ override def projectSettings : Seq [Setting [_]] = Def .settings(
37+ commonBootstrappedSettings,
38+
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+
48+ // Replace the JVM JUnit dependency by the Scala.js one
49+ libraryDependencies ~= {
50+ _.filter(! _.name.startsWith(" junit-interface" ))
51+ },
52+ libraryDependencies +=
53+ (" org.scala-js" %% " scalajs-junit-test-runtime" % scalaJSVersion % " test" ).withDottyCompat(scalaVersion.value),
54+
55+ // Typecheck the Scala.js IR found on the classpath
56+ scalaJSLinkerConfig ~= (_.withCheckIR(true )),
57+ )
58+ }
59+
3160object Build {
3261 val scalacVersion = " 2.12.8"
3362 val referenceVersion = " 0.14.0-RC1"
@@ -101,6 +130,8 @@ object Build {
101130 val ideTestsCompilerArguments = taskKey[Seq [String ]](" Compiler arguments to use in IDE tests" )
102131 val ideTestsDependencyClasspath = taskKey[Seq [File ]](" Dependency classpath to use in IDE tests" )
103132
133+ val fetchScalaJSSource = taskKey[File ](" Fetch the sources of Scala.js" )
134+
104135 lazy val SourceDeps = config(" sourcedeps" )
105136
106137 // Settings shared by the build (scoped in ThisBuild). Used in build.sbt
@@ -712,6 +743,23 @@ object Build {
712743 case Bootstrapped => `dotty-library-bootstrapped`
713744 }
714745
746+ /** The dotty standard library compiled with the Scala.js back-end, to produce
747+ * the corresponding .sjsir files.
748+ *
749+ * This artifact must be on the classpath on every "Dotty.js" project.
750+ *
751+ * Currently, only a very small fraction of the dotty library is actually
752+ * included in this project, and hence available to Dotty.js projects. More
753+ * will be added in the future as things are confirmed to be supported.
754+ */
755+ lazy val `dotty-library-bootstrappedJS` : Project = project.in(file(" library-js" )).
756+ asDottyLibrary(Bootstrapped ).
757+ enablePlugins(MyScalaJSPlugin ).
758+ settings(
759+ unmanagedSourceDirectories in Compile :=
760+ (unmanagedSourceDirectories in (`dotty-library-bootstrapped`, Compile )).value,
761+ )
762+
715763 lazy val `dotty-sbt-bridge` = project.in(file(" sbt-bridge/src" )).
716764 // We cannot depend on any bootstrapped project to compile the bridge, since the
717765 // bridge is needed to compile these projects.
@@ -817,36 +865,102 @@ object Build {
817865 * useful, as that would not provide the linker and JS runners.
818866 */
819867 lazy val sjsSandbox = project.in(file(" sandbox/scalajs" )).
820- enablePlugins(ScalaJSPlugin ).
821- dependsOn(dottyLibrary(Bootstrapped )).
822- settings(commonBootstrappedSettings).
868+ enablePlugins(MyScalaJSPlugin ).
869+ dependsOn(`dotty-library-bootstrappedJS`).
823870 settings(
824- /* Remove the Scala.js compiler plugin for scalac, and enable the
825- * Scala.js back-end of dotty instead.
826- */
827- libraryDependencies := {
828- val deps = libraryDependencies.value
829- deps.filterNot(_.name.startsWith(" scalajs-compiler" )).map(_.withDottyCompat(scalaVersion.value))
830- },
831- scalacOptions += " -scalajs" ,
871+ scalaJSUseMainModuleInitializer := true ,
872+ )
873+
874+ /** Scala.js test suite.
875+ *
876+ * This project downloads the sources of the upstream Scala.js test suite,
877+ * and tests them with the dotty Scala.js back-end. Currently, only a very
878+ * small fraction of the upstream test suite is actually compiled and run.
879+ * It will grow in the future, as more stuff is confirmed to be supported.
880+ */
881+ lazy val sjsJUnitTests = project.in(file(" tests/sjs-junit" )).
882+ enablePlugins(MyScalaJSPlugin ).
883+ dependsOn(`dotty-library-bootstrappedJS`).
884+ settings(
885+ scalacOptions --= Seq (" -Xfatal-warnings" , " -deprecation" ),
886+
887+ sourceDirectory in fetchScalaJSSource := target.value / s " scala-js-src- $scalaJSVersion" ,
888+
889+ fetchScalaJSSource := {
890+ import org .eclipse .jgit .api ._
891+
892+ val s = streams.value
893+ val ver = scalaJSVersion
894+ val trgDir = (sourceDirectory in fetchScalaJSSource).value
895+
896+ if (! trgDir.exists) {
897+ s.log.info(s " Fetching Scala.js source version $ver" )
898+ IO .createDirectory(trgDir)
899+ new CloneCommand ()
900+ .setDirectory(trgDir)
901+ .setURI(" https://github.com/scala-js/scala-js.git" )
902+ .call()
903+ }
904+
905+ // Checkout proper ref. We do this anyway so we fail if something is wrong
906+ val git = Git .open(trgDir)
907+ s.log.info(s " Checking out Scala.js source version $ver" )
908+ git.checkout().setName(s " v $ver" ).call()
832909
833- // Replace the JVM JUnit dependency by the Scala.js one
834- libraryDependencies ~= {
835- _.filter(! _.name.startsWith(" junit-interface" ))
910+ trgDir
836911 },
912+
913+ // We need JUnit in the Compile configuration
837914 libraryDependencies +=
838- (" org.scala-js" %% " scalajs-junit-test-runtime" % scalaJSVersion % " test " ).withDottyCompat(scalaVersion.value),
915+ (" org.scala-js" %% " scalajs-junit-test-runtime" % scalaJSVersion).withDottyCompat(scalaVersion.value),
839916
840- // The main class cannot be found automatically due to the empty inc.Analysis
841- mainClass in Compile := Some ( " hello.HelloWorld " ),
917+ sourceGenerators in Compile += Def .task {
918+ import org . scalajs . linker . CheckedBehavior
842919
843- scalaJSUseMainModuleInitializer := true ,
920+ val stage = scalaJSStage.value
844921
845- /* Debug-friendly Scala.js optimizer options.
846- * In particular, typecheck the Scala.js IR found on the classpath.
847- */
848- scalaJSLinkerConfig ~= {
849- _.withCheckIR(true ).withParallel(false )
922+ val linkerConfig = stage match {
923+ case FastOptStage => (scalaJSLinkerConfig in (Compile , fastOptJS)).value
924+ case FullOptStage => (scalaJSLinkerConfig in (Compile , fullOptJS)).value
925+ }
926+
927+ val moduleKind = linkerConfig.moduleKind
928+ val sems = linkerConfig.semantics
929+
930+ ConstantHolderGenerator .generate(
931+ (sourceManaged in Compile ).value,
932+ " org.scalajs.testsuite.utils.BuildInfo" ,
933+ " scalaVersion" -> scalaVersion.value,
934+ " hasSourceMaps" -> false , // MyScalaJSPlugin.wantSourceMaps.value,
935+ " isNoModule" -> (moduleKind == ModuleKind .NoModule ),
936+ " isESModule" -> (moduleKind == ModuleKind .ESModule ),
937+ " isCommonJSModule" -> (moduleKind == ModuleKind .CommonJSModule ),
938+ " isFullOpt" -> (stage == FullOptStage ),
939+ " compliantAsInstanceOfs" -> (sems.asInstanceOfs == CheckedBehavior .Compliant ),
940+ " compliantArrayIndexOutOfBounds" -> (sems.arrayIndexOutOfBounds == CheckedBehavior .Compliant ),
941+ " compliantModuleInit" -> (sems.moduleInit == CheckedBehavior .Compliant ),
942+ " strictFloats" -> sems.strictFloats,
943+ " productionMode" -> sems.productionMode,
944+ " es2015" -> linkerConfig.esFeatures.useECMAScript2015,
945+ )
946+ }.taskValue,
947+
948+ managedSources in Compile ++= {
949+ val dir = fetchScalaJSSource.value / " test-suite/js/src/main/scala"
950+ val filter = (
951+ (" *.scala" : FileFilter )
952+ -- " Typechecking*.scala"
953+ -- " NonNativeTypeTestSeparateRun.scala"
954+ )
955+ (dir ** filter).get
956+ },
957+
958+ managedSources in Test ++= {
959+ val dir = fetchScalaJSSource.value / " test-suite"
960+ (
961+ (dir / " shared/src/test/scala/org/scalajs/testsuite/compiler" ** " IntTest.scala" ).get
962+ ++ (dir / " shared/src/test/scala/org/scalajs/testsuite/utils" ** " *.scala" ).get
963+ )
850964 }
851965 )
852966
0 commit comments