Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
.
  • Loading branch information
lihaoyi committed Sep 1, 2025
commit 690ba714decdf4688af389d9af53b0a86e05fb9e
226 changes: 4 additions & 222 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,9 @@ object Build {
"-deprecation",
"-unchecked",
//"-Wconf:cat=deprecation&msg=Unsafe:s", // example usage
//"-Xfatal-warnings", // -Werror in modern usage
"-Werror",
//"-Wunused:all",
//"-rewrite", // requires -Werror:false since no rewrites are applied with errors
"-encoding", "UTF8",
"-language:implicitConversions",
),
Expand Down Expand Up @@ -719,6 +721,7 @@ object Build {
("io.get-coursier" %% "coursier" % "2.0.16" % Test).cross(CrossVersion.for3Use2_13),
"com.lihaoyi" %% "pprint" % "0.9.3",
),

// For convenience, change the baseDirectory when running the compiler
Compile / forkOptions := (Compile / forkOptions).value.withWorkingDirectory((ThisBuild / baseDirectory).value),
Compile / run / forkOptions := (Compile / run / forkOptions).value.withWorkingDirectory((ThisBuild / baseDirectory).value),
Expand Down Expand Up @@ -2491,227 +2494,6 @@ object Build {
javaOptions := (`scala3-compiler-bootstrapped` / javaOptions).value
)

/** Scala 2 library compiled by dotty using the latest published sources of the library.
*
* This version of the library is not (yet) TASTy/binary compatible with the Scala 2 compiled library.
*/
lazy val `scala2-library-bootstrapped` = project.in(file("scala2-library-bootstrapped")).
withCommonSettings(Bootstrapped).
dependsOn(dottyCompiler(Bootstrapped) % "provided; compile->runtime; test->test").
settings(commonBootstrappedSettings).
settings(scala2LibraryBootstrappedSettings).
settings(moduleName := "scala2-library")
// -Ycheck:all is set in project/scripts/scala2-library-tasty-mima.sh

/** Scala 2 library compiled by dotty using the latest published sources of the library.
*
* This version of the library is not (yet) TASTy/binary compatible with the Scala 2 compiled library.
*/
lazy val `scala2-library-cc` = project.in(file("scala2-library-cc")).
withCommonSettings(Bootstrapped).
dependsOn(dottyCompiler(Bootstrapped) % "provided; compile->runtime; test->test").
settings(commonBootstrappedSettings).
settings(scala2LibraryBootstrappedSettings).
settings(
moduleName := "scala2-library-cc",
scalacOptions += "-Ycheck:all",
)

lazy val scala2LibraryBootstrappedSettings = Seq(
javaOptions := (`scala3-compiler-bootstrapped` / javaOptions).value,
Compile / scalacOptions ++= {
Seq("-sourcepath", ((Compile/sourceManaged).value / "scala-library-src").toString)
},
Compile / doc / scalacOptions += "-Ydocument-synthetic-types",
scalacOptions += "-Ycompile-scala2-library",
scalacOptions += "-Yscala2Unpickler:never",
// scalacOptions -= "-Xfatal-warnings",
Compile / compile / logLevel.withRank(KeyRanks.Invisible) := Level.Error,
ivyConfigurations += SourceDeps.hide,
transitiveClassifiers := Seq("sources"),
libraryDependencies +=
("org.scala-lang" % "scala-library" % stdlibBootstrappedVersion % "sourcedeps"),
(Compile / sourceGenerators) += Def.task {
val s = streams.value
val cacheDir = s.cacheDirectory
val trgDir = (Compile / sourceManaged).value / "scala-library-src"

val report = updateClassifiers.value
val scalaLibrarySourcesJar = report.select(
configuration = configurationFilter("sourcedeps"),
module = (_: ModuleID).name == "scala-library",
artifact = artifactFilter(`type` = "src")).headOption.getOrElse {
sys.error(s"Could not fetch scala-library sources")
}

FileFunction.cached(cacheDir / s"fetchScalaLibrarySrc",
FilesInfo.lastModified, FilesInfo.exists) { dependencies =>
s.log.info(s"Unpacking scala-library sources to $trgDir...")
if (trgDir.exists)
IO.delete(trgDir)
IO.createDirectory(trgDir)
IO.unzip(scalaLibrarySourcesJar, trgDir)

val (ignoredSources, sources) =
((trgDir ** "*.scala") +++ (trgDir ** "*.java")).get.toSet
.partition{file =>
// sources from https://github.com/scala/scala/tree/2.13.x/src/library-aux
val path = file.getPath.replace('\\', '/')
path.endsWith("scala-library-src/scala/Any.scala") ||
path.endsWith("scala-library-src/scala/AnyVal.scala") ||
path.endsWith("scala-library-src/scala/AnyRef.scala") ||
path.endsWith("scala-library-src/scala/Nothing.scala") ||
path.endsWith("scala-library-src/scala/Null.scala") ||
path.endsWith("scala-library-src/scala/Singleton.scala")
}
// These sources should be never compiled, filtering them out was not working correctly sometimes
ignoredSources.foreach(_.delete())
sources
} (Set(scalaLibrarySourcesJar)).toSeq
}.taskValue,
(Compile / sources) := {
val files = (Compile / sources).value
val overwrittenSourcesDir = (Compile / scalaSource).value
val overwrittenSources = files.flatMap(_.relativeTo(overwrittenSourcesDir)).toSet
val reference = (Compile/sourceManaged).value / "scala-library-src"
files.filterNot(_.relativeTo(reference).exists(overwrittenSources))
},
(Test / managedClasspath) ~= {
_.filterNot(file => file.data.getName == s"scala-library-$stdlibBootstrappedVersion.jar")
},
mimaCheckDirection := "both",
mimaBackwardIssueFilters := Scala2LibraryBootstrappedMiMaFilters.BackwardsBreakingChanges,
mimaForwardIssueFilters := Scala2LibraryBootstrappedMiMaFilters.ForwardsBreakingChanges,
customMimaReportBinaryIssues("Scala2LibraryBootstrappedMiMaFilters"),
mimaPreviousArtifacts += "org.scala-lang" % "scala-library" % stdlibBootstrappedVersion,
mimaExcludeAnnotations ++= Seq(
"scala.annotation.experimental",
"scala.annotation.specialized",
"scala.annotation.unspecialized",
),
tastyMiMaTastyQueryVersionOverride := Some("1.1.2"),
tastyMiMaPreviousArtifacts += "org.scala-lang" % "scala-library" % stdlibBootstrappedVersion,
tastyMiMaCurrentClasspath := {
val javaBootCp = tastyMiMaJavaBootClasspath.value
val classDir = (Compile / classDirectory).value.toPath()
val cp0 = Attributed.data((Compile / fullClasspath).value).map(_.toPath())
val cp: Seq[Path] = classDir +: (javaBootCp ++ cp0)
(cp, classDir)
},
tastyMiMaConfig ~= { _.withMoreProblemFilters(TastyMiMaFilters.StdlibBootstrapped) },
tastyMiMaReportIssues := tastyMiMaReportIssues.dependsOn(Def.task {
val minorVersion = mimaPreviousDottyVersion.split('.')(1)
// TODO find a way around this and test in the CI
streams.value.log.warn(
s"""To allow TASTy-MiMa to read TASTy files generated by this version of the compile you must:
| * Modify the TASTy version to the latest stable release (latest version supported by TASTy-MiMa) in in tasty/src/dotty/tools/tasty/TastyFormat.scala
| - final val MinorVersion = $minorVersion
| - final val ExperimentalVersion = 0
| * Clean everything to generate a compiler with those new TASTy versions
| * Run ${name.value}/tastyMiMaReportIssues
|""".stripMargin)

}).value,
Compile / exportJars := true,
artifactName := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) =>
moduleName.value + "-" + dottyVersion + "." + artifact.extension
},
run := {
val log = streams.value.log
val projectName = projectInfo.value.nameFormal
val args: Seq[String] = spaceDelimited("<arg>").parsed
val rootDir = (ThisBuild / baseDirectory).value
val srcDir = (Compile / scalaSource).value.relativeTo(rootDir).get
val reference = (Compile/sourceManaged).value.relativeTo(rootDir).get / "scala-library-src"
args match {
case Seq("list") =>
log.info(s"Printing list of non-overriden files in $reference")
reference.allPaths.get()
.flatMap(_.relativeTo(reference))
.filter(_.ext == "scala")
.sorted
.foreach(println)
case Seq(cmd @ ("clone" | "overwrite"), files*) =>
log.info("Cloning scala-library sources: " + files.mkString(", "))
for (file <- files) {
val fileRootedAtInLibraryFolder = file.stripPrefix("src/library/")
val referenceStdlibPaths = reference / fileRootedAtInLibraryFolder
val destination = srcDir / fileRootedAtInLibraryFolder
if (!referenceStdlibPaths.exists) {
log.error("Not found " + referenceStdlibPaths)
} else if (destination.exists && cmd == "clone") {
log.warn(s"Already exists $destination (use `overwrite` command to overwrite)")
} else {
val action = if (cmd == "clone") "Cloning" else "Overwriting"
log.info(s"$action $destination")
IO.copyFile(referenceStdlibPaths, destination)
}
}
case "diff" +: rest =>
log.info(s"Diffing ${name.value}/src with scala-library sources")
if (rest.size > 1) {
log.error(s"Too many arguments for $projectName/run diff")
} else {
val path = rest.headOption.getOrElse("")
val fullPath = srcDir / path
if (!fullPath.exists) {
log.error(s"$fullPath does not exist")
} else {
// `--diff-filter=ACMR` is missing `D` on purpose not to show all the files that have not been overwritten.
val command = s"git diff --diff-filter=ACMR --no-index --color=always -- $reference/$path $fullPath"
log.info(command)
import _root_.scala.sys.process._
command.!
}
}
case _ =>
val projectName = projectInfo.value.nameFormal
println(
s"""Usage:
|> $projectName/run list
| -- lists all files that are not overriden in ${name.value}/src
|
|> $projectName/run clone <sources>*
| -- clones the specified sources from the ${name.value}/src
| -- example: $projectName/run clone scala/Option.scala
|
|> $projectName/run overwrite <sources>*
| -- (danger) overwrites the specified sources from the ${name.value}/src
|
|> $projectName/run diff [path]
| -- shows the git diff between the reference library sources the sources used to compile $projectName
| -- [path] optional path in the library, eg:
| -- $projectName/run diff scala/Predef.scala
| -- $projectName/run diff scala/collection/immutable
|""".stripMargin)
}
}
)

/** Packages the TASTy files of `scala2-library-bootstrapped` in a jar */
lazy val `scala2-library-tasty` = project.in(file("scala2-library-tasty")).
withCommonSettings(Bootstrapped).
settings(
moduleName := "scala2-library-tasty-experimental",
exportJars := true,
Compile / packageBin / mappings := {
(`scala2-library-bootstrapped` / Compile / packageBin / mappings).value
.filter(_._2.endsWith(".tasty"))
},
)

/** Packages the TASTy files of `scala2-library-cc` in a jar */
lazy val `scala2-library-cc-tasty` = project.in(file("scala2-library-cc-tasty")).
withCommonSettings(Bootstrapped).
settings(
moduleName := "scala2-library-cc-tasty-experimental",
exportJars := true,
Compile / packageBin / mappings := {
(`scala2-library-cc` / Compile / packageBin / mappings).value
.filter(_._2.endsWith(".tasty"))
},
)

lazy val `scala3-sbt-bridge` = project.in(file("sbt-bridge/src")).
// We cannot depend on any bootstrapped project to compile the bridge, since the
// bridge is needed to compile these projects.
Expand Down
You are viewing a condensed version of this merge commit. You can view the full changes here.