Implement Scala 2.13-3.0 sandwich

Fixes https://github.com/sbt/sbt/issues/5369
Ref https://contributors.scala-lang.org/t/roadmap-for-the-tasty-reader-for-scala-2/4231

This implements support for inter-project dependencies between Scala 2.13 and Dotty, and vice versa. Scala 2.13 depending on Dotty would require 2.13.4 and above.
This commit is contained in:
Eugene Yokota 2020-08-16 17:38:07 -04:00
parent b09fd9d640
commit f8139da192
13 changed files with 78 additions and 7 deletions

View File

@ -3450,14 +3450,38 @@ object Classpaths {
def deliverPattern(outputPath: File): String =
(outputPath / "[artifact]-[revision](-[classifier]).[ext]").absolutePath
private[sbt] def isScala2Scala3Sandwich(sbv1: String, sbv2: String): Boolean = {
def compare(a: String, b: String): Boolean =
a == "2.13" && (b.startsWith("0.") || b.startsWith("3.0"))
compare(sbv1, sbv2) || compare(sbv2, sbv1)
}
def projectDependenciesTask: Initialize[Task[Seq[ModuleID]]] =
Def.task {
val sbv = scalaBinaryVersion.value
val ref = thisProjectRef.value
val data = settingsData.value
val deps = buildDependencies.value
deps.classpath(ref) flatMap { dep =>
(projectID in dep.project) get data map {
_.withConfigurations(dep.configuration).withExplicitArtifacts(Vector.empty)
val depProjIdOpt = (dep.project / projectID).get(data)
val depSVOpt = (dep.project / scalaVersion).get(data)
val depSBVOpt = (dep.project / scalaBinaryVersion).get(data)
val depCrossOpt = (dep.project / crossVersion).get(data)
(depProjIdOpt, depSVOpt, depSBVOpt, depCrossOpt) match {
case (Some(depProjId), Some(depSV), Some(depSBV), Some(depCross)) =>
if (sbv == depSBV || depCross != CrossVersion.binary)
Some(
depProjId.withConfigurations(dep.configuration).withExplicitArtifacts(Vector.empty)
)
else if (isScala2Scala3Sandwich(sbv, depSBV) && depCross == CrossVersion.binary)
Some(
depProjId
.withCrossVersion(CrossVersion.constant(depSBV))
.withConfigurations(dep.configuration)
.withExplicitArtifacts(Vector.empty)
)
else sys.error(s"scalaBinaryVersion mismatch: expected $sbv but found ${depSBV}")
case _ => None
}
}
}

View File

@ -1,4 +1,4 @@
lazy val dottyVersion = "0.14.0-RC1"
ThisBuild / scalaVersion := "0.26.0-RC1"
lazy val plugin = project
.in(file("plugin"))
@ -6,7 +6,6 @@ lazy val plugin = project
name := "dividezero",
version := "0.0.1",
organization := "ch.epfl.lamp",
scalaVersion := dottyVersion,
scalacOptions ++= Seq(
"-language:implicitConversions"

View File

@ -1 +1 @@
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.3.1")
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.4.1")

View File

@ -0,0 +1,5 @@
package example
object D {
val x = C.x
}

View File

@ -0,0 +1,5 @@
package example
object C {
val x = 1
}

View File

@ -0,0 +1,24 @@
ThisBuild / scalaVersion := "0.23.0"
ThisBuild / resolvers += "scala-integration" at "https://scala-ci.typesafe.com/artifactory/scala-integration/"
// TODO use 2.13.4 when it's out
lazy val scala213 = "2.13.4-bin-aeee8f0"
lazy val root = (project in file("."))
.aggregate(fooApp, fooCore, barApp, barCore)
lazy val fooApp = (project in file("foo-app"))
.dependsOn(fooCore)
lazy val fooCore = (project in file("foo-core"))
.settings(
scalaVersion := scala213
)
lazy val barApp = (project in file("bar-app"))
.dependsOn(barCore)
.settings(
scalaVersion := scala213
)
lazy val barCore = (project in file("bar-core"))

View File

@ -0,0 +1,5 @@
package example
object B {
val x = A.x
}

View File

@ -0,0 +1,5 @@
package example
object A {
val x = 1
}

View File

@ -0,0 +1 @@
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.4.1")

View File

@ -0,0 +1,3 @@
> fooApp/compile
> barApp/compile

View File

@ -1 +1 @@
scalaVersion := "0.14.0-RC1"
ThisBuild / scalaVersion := "0.26.0-RC1"

View File

@ -1 +1 @@
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.3.1")
addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.4.1")