Skip to content

Commit febfc72

Browse files
committed
fix: have a full stdlib for Scala.js :)
1 parent 066b018 commit febfc72

File tree

2 files changed

+93
-96
lines changed

2 files changed

+93
-96
lines changed

project/Build.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import sbt.PublishBinPlugin.autoImport._
2323
import dotty.tools.sbtplugin.RepublishPlugin
2424
import dotty.tools.sbtplugin.RepublishPlugin.autoImport._
2525
import dotty.tools.sbtplugin.ScalaLibraryPlugin
26+
import dotty.tools.sbtplugin.ScalaLibraryPlugin.autoImport._
2627
import dotty.tools.sbtplugin.DottyJSPlugin
2728
import dotty.tools.sbtplugin.DottyJSPlugin.autoImport._
2829

@@ -1646,6 +1647,8 @@ object Build {
16461647
mimaForwardIssueFilters := MiMaFilters.Scala3Library.ForwardsBreakingChanges,
16471648
mimaBackwardIssueFilters := MiMaFilters.Scala3Library.BackwardsBreakingChanges,
16481649
customMimaReportBinaryIssues("MiMaFilters.Scala3Library"),
1650+
// Should we also patch .sjsir files
1651+
keepSJSIR := false,
16491652
)
16501653

16511654
/* Configuration of the org.scala-lang:scala3-library_3:*.**.**-nonbootstrapped project */
@@ -1768,6 +1771,8 @@ object Build {
17681771
mimaForwardIssueFilters := MiMaFilters.Scala3Library.ForwardsBreakingChanges,
17691772
mimaBackwardIssueFilters := MiMaFilters.Scala3Library.BackwardsBreakingChanges,
17701773
customMimaReportBinaryIssues("MiMaFilters.Scala3Library"),
1774+
// Should we also patch .sjsir files
1775+
keepSJSIR := false,
17711776
)
17721777

17731778
/* Configuration of the org.scala-lang:scala3-library_3:*.**.**-bootstrapped project */
@@ -1816,6 +1821,7 @@ object Build {
18161821
// We add a dependency to the JVM library to have the classfile available
18171822
// (as they are not part of this artifact)
18181823
.dependsOn(`scala3-library-bootstrapped-new`)
1824+
.enablePlugins(ScalaLibraryPlugin)
18191825
.settings(publishSettings)
18201826
.settings(
18211827
name := "scala-library-sjs",
@@ -1922,6 +1928,8 @@ object Build {
19221928
}
19231929
}).transform(node).head
19241930
},
1931+
// Should we also patch .sjsir files
1932+
keepSJSIR := true,
19251933
)
19261934

19271935
/* Configuration of the org.scala-lang:scala3-library_sjs1_3:*.**.**-bootstrapped project */

project/ScalaLibraryPlugin.scala

Lines changed: 85 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -14,76 +14,47 @@ object ScalaLibraryPlugin extends AutoPlugin {
1414

1515
private val scala2Version = "2.13.16"
1616

17-
val fetchScala2ClassFiles = taskKey[(Set[File], File)]("Fetch the files to use that were compiled with Scala 2")
18-
val fetchScala2SJSIR = taskKey[(Set[File], File)]("Fetch the .sjsir to use from Scala 2")
17+
object autoImport {
18+
val keepSJSIR = settingKey[Boolean]("Should we patch .sjsir too?")
19+
}
1920

20-
override def projectSettings = Seq (
21-
fetchScala2ClassFiles := {
22-
val stream = streams.value
23-
val cache = stream.cacheDirectory
24-
val target = cache / "scala-library-classes"
25-
val report = update.value
26-
27-
val scalaLibraryBinaryJar = report.select(
28-
configuration = configurationFilter(),
29-
module = (_: ModuleID).name == "scala-library",
30-
artifact = artifactFilter(`type` = "jar")).headOption.getOrElse {
31-
sys.error(s"Could not fetch scala-library binary JAR")
32-
}
21+
import autoImport._
3322

34-
if (!target.exists()) {
35-
IO.createDirectory(target)
36-
}
37-
38-
(FileFunction.cached(cache / "fetch-scala-library-classes", FilesInfo.lastModified, FilesInfo.exists) { _ =>
39-
stream.log.info(s"Unpacking scala-library binaries to persistent directory: ${target.getAbsolutePath}")
40-
IO.unzip(scalaLibraryBinaryJar, target)
41-
(target ** "*.class").get.toSet
42-
} (Set(scalaLibraryBinaryJar)), target)
43-
44-
},
45-
fetchScala2SJSIR := {
23+
override def projectSettings = Seq (
24+
(Compile / manipulateBytecode) := {
4625
val stream = streams.value
26+
val target = (Compile / classDirectory).value
4727
val lm = dependencyResolution.value
4828
val log = stream.log
4929
val cache = stream.cacheDirectory
5030
val retrieveDir = cache / "scalajs-scalalib" / scalaVersion.value
31+
5132
val comp = lm.retrieve("org.scala-js" % "scalajs-scalalib_2.13" % s"$scala2Version+$scalaJSVersion", scalaModuleInfo = None, retrieveDir, log)
5233
.fold(w => throw w.resolveException, identity)
34+
.filterNot(_.getPath().contains("javalib"))
35+
.filter(!_.getPath().contains("scalajs-scalalib_2.13") || keepSJSIR.value)
36+
.distinct
5337

54-
println(comp(0))
55-
56-
val target = cache / "scala-library-sjsir"
57-
58-
59-
if (!target.exists()) {
60-
IO.createDirectory(target)
61-
}
62-
63-
(FileFunction.cached(cache / "fetch-scala-library-sjsir", FilesInfo.lastModified, FilesInfo.exists) { _ =>
64-
stream.log.info(s"Unpacking scalajs-scalalib binaries to persistent directory: ${target.getAbsolutePath}")
65-
IO.unzip(comp(0), target)
66-
(target ** "*.sjsir").get.toSet
67-
} (Set(comp(0))), target)
38+
// Fetch classfiles and sjsir files
39+
val patches: Seq[(Set[File], File)] = comp.map(fetch(stream, _))
6840

69-
},
70-
(Compile / manipulateBytecode) := {
71-
val stream = streams.value
72-
val target = (Compile / classDirectory).value
73-
val (files, reference) = fetchScala2ClassFiles.value;
7441
val previous = (Compile / manipulateBytecode).value
42+
7543
val analysis = previous.analysis match {
7644
case analysis: sbt.internal.inc.Analysis => analysis
7745
case _ => sys.error("Unexpected analysis type")
7846
}
79-
8047
var stamps = analysis.stamps
81-
for (file <- files;
82-
id <- file.relativeTo(reference);
83-
if filesToCopy(id.toString().replace("\\", "/")); // Only Override Some Very Specific Files
84-
dest = target / (id.toString);
85-
ref <- dest.relativeTo((LocalRootProject / baseDirectory).value)
86-
) {
48+
49+
// Patch the files that are in the list
50+
for {
51+
(files, reference) <- patches
52+
file <- files
53+
id <- file.relativeTo(reference)
54+
if filesToCopy(id.toString().replace("\\", "/")) // Only Override Some Very Specific Files
55+
dest = target / (id.toString)
56+
ref <- dest.relativeTo((LocalRootProject / baseDirectory).value)
57+
} {
8758
// Copy the files to the classDirectory
8859
IO.copyFile(file, dest)
8960
// Update the timestamp in the analysis
@@ -92,64 +63,82 @@ object ScalaLibraryPlugin extends AutoPlugin {
9263
Stamper.forFarmHashP(dest.toPath()))
9364
}
9465

66+
9567
val overwrittenBinaries = Files.walk((Compile / classDirectory).value.toPath())
9668
.iterator()
9769
.asScala
9870
.map(_.toFile)
9971
.map(_.relativeTo((Compile / classDirectory).value).get)
10072
.toSet
10173

102-
val diff = files.filterNot(_.relativeTo(reference).exists(overwrittenBinaries))
103-
104-
// Copy all the specialized classes in the stdlib
105-
// no need to update any stamps as these classes exist nowhere in the analysis
106-
for (orig <- diff; dest <- orig.relativeTo(reference)) {
107-
IO.copyFile(orig, ((Compile / classDirectory).value / dest.toString()))
74+
for ((files, reference) <- patches) {
75+
val diff = files.filterNot(file => overwrittenBinaries.contains(file.relativeTo(reference).get))
76+
// Copy all the specialized classes in the stdlib
77+
// no need to update any stamps as these classes exist nowhere in the analysis
78+
for (orig <- diff; dest <- orig.relativeTo(reference)) {
79+
IO.copyFile(orig, ((Compile / classDirectory).value / dest.toString()))
80+
}
10881
}
10982

11083
previous
11184
.withAnalysis(analysis.copy(stamps = stamps)) // update the analysis with the correct stamps
11285
.withHasModified(true) // mark it as updated for sbt to update its caches
86+
11387
}
11488
)
11589

90+
def fetch(stream: TaskStreams, jar: File) = {
91+
val cache = stream.cacheDirectory
92+
val target = cache / jar.getName()
93+
94+
if (!target.exists()) {
95+
IO.createDirectory(target)
96+
}
97+
98+
(FileFunction.cached(cache / "fetch-scala-library-classes", FilesInfo.lastModified, FilesInfo.exists) { _ =>
99+
stream.log.info(s"Unpacking scala-library binaries to persistent directory: ${target.getAbsolutePath}")
100+
IO.unzip(jar, target)
101+
(target ** "*.class").get.toSet ++ (target ** "*.sjsir").get.toSet
102+
} (Set(jar)), target)
103+
}
104+
116105
private lazy val filesToCopy = Set(
117-
"scala/Tuple1.class",
118-
"scala/Tuple2.class",
119-
"scala/collection/DoubleStepper.class",
120-
"scala/collection/IntStepper.class",
121-
"scala/collection/LongStepper.class",
122-
"scala/collection/immutable/DoubleVectorStepper.class",
123-
"scala/collection/immutable/IntVectorStepper.class",
124-
"scala/collection/immutable/LongVectorStepper.class",
125-
"scala/jdk/DoubleAccumulator.class",
126-
"scala/jdk/IntAccumulator.class",
127-
"scala/jdk/LongAccumulator.class",
128-
"scala/jdk/FunctionWrappers$FromJavaDoubleBinaryOperator.class",
129-
"scala/jdk/FunctionWrappers$FromJavaBooleanSupplier.class",
130-
"scala/jdk/FunctionWrappers$FromJavaDoubleConsumer.class",
131-
"scala/jdk/FunctionWrappers$FromJavaDoublePredicate.class",
132-
"scala/jdk/FunctionWrappers$FromJavaDoubleSupplier.class",
133-
"scala/jdk/FunctionWrappers$FromJavaDoubleToIntFunction.class",
134-
"scala/jdk/FunctionWrappers$FromJavaDoubleToLongFunction.class",
135-
"scala/jdk/FunctionWrappers$FromJavaIntBinaryOperator.class",
136-
"scala/jdk/FunctionWrappers$FromJavaDoubleUnaryOperator.class",
137-
"scala/jdk/FunctionWrappers$FromJavaIntPredicate.class",
138-
"scala/jdk/FunctionWrappers$FromJavaIntConsumer.class",
139-
"scala/jdk/FunctionWrappers$FromJavaIntSupplier.class",
140-
"scala/jdk/FunctionWrappers$FromJavaIntToDoubleFunction.class",
141-
"scala/jdk/FunctionWrappers$FromJavaIntToLongFunction.class",
142-
"scala/jdk/FunctionWrappers$FromJavaIntUnaryOperator.class",
143-
"scala/jdk/FunctionWrappers$FromJavaLongBinaryOperator.class",
144-
"scala/jdk/FunctionWrappers$FromJavaLongConsumer.class",
145-
"scala/jdk/FunctionWrappers$FromJavaLongPredicate.class",
146-
"scala/jdk/FunctionWrappers$FromJavaLongSupplier.class",
147-
"scala/jdk/FunctionWrappers$FromJavaLongToDoubleFunction.class",
148-
"scala/jdk/FunctionWrappers$FromJavaLongToIntFunction.class",
149-
"scala/jdk/FunctionWrappers$FromJavaLongUnaryOperator.class",
150-
"scala/collection/ArrayOps$ReverseIterator.class",
151-
"scala/runtime/NonLocalReturnControl.class",
152-
"scala/util/Sorting.class", "scala/util/Sorting$.class", // Contains @specialized annotation
153-
)
106+
"scala/Tuple1",
107+
"scala/Tuple2",
108+
"scala/collection/DoubleStepper",
109+
"scala/collection/IntStepper",
110+
"scala/collection/LongStepper",
111+
"scala/collection/immutable/DoubleVectorStepper",
112+
"scala/collection/immutable/IntVectorStepper",
113+
"scala/collection/immutable/LongVectorStepper",
114+
"scala/jdk/DoubleAccumulator",
115+
"scala/jdk/IntAccumulator",
116+
"scala/jdk/LongAccumulator",
117+
"scala/jdk/FunctionWrappers$FromJavaDoubleBinaryOperator",
118+
"scala/jdk/FunctionWrappers$FromJavaBooleanSupplier",
119+
"scala/jdk/FunctionWrappers$FromJavaDoubleConsumer",
120+
"scala/jdk/FunctionWrappers$FromJavaDoublePredicate",
121+
"scala/jdk/FunctionWrappers$FromJavaDoubleSupplier",
122+
"scala/jdk/FunctionWrappers$FromJavaDoubleToIntFunction",
123+
"scala/jdk/FunctionWrappers$FromJavaDoubleToLongFunction",
124+
"scala/jdk/FunctionWrappers$FromJavaIntBinaryOperator",
125+
"scala/jdk/FunctionWrappers$FromJavaDoubleUnaryOperator",
126+
"scala/jdk/FunctionWrappers$FromJavaIntPredicate",
127+
"scala/jdk/FunctionWrappers$FromJavaIntConsumer",
128+
"scala/jdk/FunctionWrappers$FromJavaIntSupplier",
129+
"scala/jdk/FunctionWrappers$FromJavaIntToDoubleFunction",
130+
"scala/jdk/FunctionWrappers$FromJavaIntToLongFunction",
131+
"scala/jdk/FunctionWrappers$FromJavaIntUnaryOperator",
132+
"scala/jdk/FunctionWrappers$FromJavaLongBinaryOperator",
133+
"scala/jdk/FunctionWrappers$FromJavaLongConsumer",
134+
"scala/jdk/FunctionWrappers$FromJavaLongPredicate",
135+
"scala/jdk/FunctionWrappers$FromJavaLongSupplier",
136+
"scala/jdk/FunctionWrappers$FromJavaLongToDoubleFunction",
137+
"scala/jdk/FunctionWrappers$FromJavaLongToIntFunction",
138+
"scala/jdk/FunctionWrappers$FromJavaLongUnaryOperator",
139+
"scala/collection/ArrayOps$ReverseIterator",
140+
"scala/runtime/NonLocalReturnControl",
141+
"scala/util/Sorting", "scala/util/Sorting$",
142+
).flatMap(f => Seq(s"$f.class", s"$f.sjsir"))
154143

155144
}

0 commit comments

Comments
 (0)