Merge pull request #6206 from adpi2/sbt-dotty

Manage Scala 3 instances and fetch compiler bridges
This commit is contained in:
eugene yokota 2020-12-24 11:52:00 -05:00 committed by GitHub
commit 9ca5a4675f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
64 changed files with 654 additions and 59 deletions

View File

@ -66,7 +66,7 @@ public final class MetaBuildLoader extends URLClassLoader {
public static MetaBuildLoader makeLoader(final AppProvider appProvider) throws IOException {
final String jlineJars = "jline-?[0-9.]+-sbt-.*|jline-terminal(-(jna|jansi))?-[0-9.]+";
final String testInterfaceJars = "test-interface-[0-9.]+";
final String compilerInterfaceJars = "compiler-interface-[0-9.]+(-.*)?";
final String compilerInterfaceJars = "compiler-interface(-.*)?";
final String jansiJars = "jansi-[0-9.]+";
final String jnaJars = "jna-(platform-)?[0-9.]+";
final String fullPattern =

View File

@ -88,6 +88,7 @@ import sbt.util.InterfaceUtil.{ t2, toJavaFunction => f1 }
import sbt.util._
import sjsonnew._
import sjsonnew.support.scalajson.unsafe.Converter
import xsbti.compile.TastyFiles
import xsbti.{ FileConverter, Position }
import scala.collection.immutable.ListMap
@ -668,15 +669,21 @@ object Defaults extends BuildCommon {
),
cleanIvy := IvyActions.cleanCachedResolutionCache(ivyModule.value, streams.value.log),
clean := clean.dependsOn(cleanIvy).value,
scalaCompilerBridgeBinaryJar := None,
scalaCompilerBridgeSource := ZincLmUtil.getDefaultBridgeModule(scalaVersion.value),
consoleProject / scalaCompilerBridgeSource := ZincLmUtil.getDefaultBridgeModule(
scalaCompilerBridgeBinaryJar := Def.settingDyn {
val sv = scalaVersion.value
if (ScalaArtifacts.isScala3(sv)) fetchBridgeBinaryJarTask(sv)
else Def.task[Option[File]](None)
}.value,
scalaCompilerBridgeSource := ZincLmUtil.getDefaultBridgeSourceModule(scalaVersion.value),
consoleProject / scalaCompilerBridgeBinaryJar := None,
consoleProject / scalaCompilerBridgeSource := ZincLmUtil.getDefaultBridgeSourceModule(
appConfiguration.value.provider.scalaProvider.version
),
)
// must be a val: duplication detected by object identity
private[this] lazy val compileBaseGlobal: Seq[Setting[_]] = globalDefaults(
Seq(
auxiliaryClassFiles := Nil,
incOptions := IncOptions.of(),
classpathOptions :== ClasspathOptionsUtil.boot,
classpathOptions in console :== ClasspathOptionsUtil.repl,
@ -736,6 +743,18 @@ object Defaults extends BuildCommon {
if (plugin) scalaBase / ("sbt-" + sbtv) else scalaBase
}
private def fetchBridgeBinaryJarTask(scalaVersion: String): Initialize[Task[Option[File]]] =
Def.task {
val bridgeJar = ZincLmUtil.fetchDefaultBridgeModule(
scalaVersion,
dependencyResolution.value,
updateConfiguration.value,
(update / unresolvedWarningConfiguration).value,
streams.value.log
)
Some(bridgeJar)
}
def compilersSetting = {
compilers := {
val st = state.value
@ -860,9 +879,14 @@ object Defaults extends BuildCommon {
compileAnalysisTargetRoot.value / compileAnalysisFilename.value
},
externalHooks := IncOptions.defaultExternal,
auxiliaryClassFiles ++= {
if (ScalaArtifacts.isScala3(scalaVersion.value)) List(TastyFiles.instance)
else Nil
},
incOptions := {
val old = incOptions.value
old
.withAuxiliaryClassFiles(auxiliaryClassFiles.value.toArray)
.withExternalHooks(externalHooks.value)
.withClassfileManagerType(
Option(
@ -1034,21 +1058,22 @@ object Defaults extends BuildCommon {
}
def scalaInstanceFromUpdate: Initialize[Task[ScalaInstance]] = Def.task {
val sv = scalaVersion.value
val toolReport = update.value.configuration(Configurations.ScalaTool) getOrElse
sys.error(noToolConfiguration(managedScalaInstance.value))
def files(id: String) =
for {
m <- toolReport.modules if m.module.name == id;
m <- toolReport.modules if m.module.name.startsWith(id)
(art, file) <- m.artifacts if art.`type` == Artifact.DefaultType
} yield file
def file(id: String) = files(id).headOption getOrElse sys.error(s"Missing ${id}.jar")
def file(id: String) = files(id).headOption getOrElse sys.error(s"Missing $id jar file")
val allJars = toolReport.modules.flatMap(_.artifacts.map(_._2))
val libraryJar = file(ScalaArtifacts.LibraryID)
val compilerJar = file(ScalaArtifacts.CompilerID)
val libraryJars = ScalaArtifacts.libraryIds(sv).map(file)
val compilerJar = file(ScalaArtifacts.compilerId(sv))
mkScalaInstance(
scalaVersion.value,
sv,
allJars,
Array(libraryJar),
libraryJars,
compilerJar,
state.value.extendedClassLoaderCache,
scalaInstanceTopLoader.value,
@ -3820,7 +3845,7 @@ object Classpaths {
version: String
): Seq[ModuleID] =
if (auto)
modifyForPlugin(plugin, ModuleID(org, ScalaArtifacts.LibraryID, version)) :: Nil
modifyForPlugin(plugin, ScalaArtifacts.libraryDependency(org, version)) :: Nil
else
Nil

View File

@ -248,6 +248,7 @@ object Keys {
val aggregate = settingKey[Boolean]("Configures task aggregation.").withRank(BMinusSetting)
val sourcePositionMappers = taskKey[Seq[xsbti.Position => Option[xsbti.Position]]]("Maps positions in generated source files to the original source it was generated from").withRank(DTask)
private[sbt] val externalHooks = taskKey[ExternalHooks]("The external hooks used by zinc.")
val auxiliaryClassFiles = taskKey[Seq[AuxiliaryClassFiles]]("The auxiliary class files that must be managed by Zinc (for instance the TASTy files)")
val fileConverter = settingKey[FileConverter]("The file converter used to convert between Path and VirtualFile")
val allowMachinePath = settingKey[Boolean]("Allow machine-specific paths during conversion.")
val reportAbsolutePath = settingKey[Boolean]("Report absolute paths during compilation.")

View File

@ -173,6 +173,7 @@ object LMCoursier {
}
def coursierConfigurationTask: Def.Initialize[Task[CoursierConfiguration]] = Def.task {
val sv = scalaVersion.value
coursierConfiguration(
csrRecursiveResolvers.value,
csrInterProjectDependencies.value.toVector,
@ -182,9 +183,9 @@ object LMCoursier {
None,
csrMavenProfiles.value,
scalaOrganization.value,
scalaVersion.value,
sv,
scalaBinaryVersion.value,
autoScalaLibrary.value,
autoScalaLibrary.value && !ScalaArtifacts.isScala3(sv),
scalaModuleInfo.value,
allExcludeDependencies.value,
CoursierInputsTasks.credentialsTask.value,
@ -200,6 +201,7 @@ object LMCoursier {
}
def updateClassifierConfigurationTask: Def.Initialize[Task[CoursierConfiguration]] = Def.task {
val sv = scalaVersion.value
coursierConfiguration(
csrRecursiveResolvers.value,
csrInterProjectDependencies.value.toVector,
@ -209,9 +211,9 @@ object LMCoursier {
Some(transitiveClassifiers.value.map(Classifier(_))),
csrMavenProfiles.value,
scalaOrganization.value,
scalaVersion.value,
sv,
scalaBinaryVersion.value,
autoScalaLibrary.value,
autoScalaLibrary.value && !ScalaArtifacts.isScala3(sv),
scalaModuleInfo.value,
allExcludeDependencies.value,
CoursierInputsTasks.credentialsTask.value,
@ -227,6 +229,7 @@ object LMCoursier {
}
def updateSbtClassifierConfigurationTask: Def.Initialize[Task[CoursierConfiguration]] = Def.task {
val sv = scalaVersion.value
coursierConfiguration(
csrSbtResolvers.value,
Vector(),
@ -236,9 +239,9 @@ object LMCoursier {
None,
csrMavenProfiles.value,
scalaOrganization.value,
scalaVersion.value,
sv,
scalaBinaryVersion.value,
autoScalaLibrary.value,
autoScalaLibrary.value && !ScalaArtifacts.isScala3(sv),
scalaModuleInfo.value,
allExcludeDependencies.value,
CoursierInputsTasks.credentialsTask.value,
@ -254,6 +257,7 @@ object LMCoursier {
}
def scalaCompilerBridgeConfigurationTask: Def.Initialize[Task[CoursierConfiguration]] = Def.task {
val sv = scalaVersion.value
coursierConfiguration(
csrResolvers.value,
Vector(),
@ -263,9 +267,9 @@ object LMCoursier {
None,
csrMavenProfiles.value,
scalaOrganization.value,
scalaVersion.value,
sv,
scalaBinaryVersion.value,
autoScalaLibrary.value,
autoScalaLibrary.value && !ScalaArtifacts.isScala3(sv),
scalaModuleInfo.value,
allExcludeDependencies.value,
CoursierInputsTasks.credentialsTask.value,

View File

@ -85,7 +85,7 @@ private[sbt] object Load {
componentProvider = app.provider.components,
secondaryCacheDir = Option(zincDir),
dependencyResolution = dependencyResolution,
compilerBridgeSource = ZincLmUtil.getDefaultBridgeModule(scalaProvider.version),
compilerBridgeSource = ZincLmUtil.getDefaultBridgeSourceModule(scalaProvider.version),
scalaJarsTarget = zincDir,
state.get(BasicKeys.classLoaderCache),
log = log

View File

@ -0,0 +1,3 @@
ThisBuild / scalaVersion := "3.0.0-M2"
lazy val root = project.in(file("."))

View File

@ -0,0 +1,3 @@
class A {
def initialized: Boolean = false
}

View File

@ -0,0 +1,3 @@
class B {
def foo(a: A): Boolean = a.initialized
}

View File

@ -0,0 +1,11 @@
> compile
$ exists target/scala-3.0.0-M2/classes/A.tasty
$ exists target/scala-3.0.0-M2/classes/B.tasty
$ delete src/main/scala/B.scala
> compile
$ exists target/scala-3.0.0-M2/classes/A.tasty
-$ exists target/scala-3.0.0-M2/classes/B.tasty

View File

@ -1,4 +1,5 @@
import sbt.internal.inc.classpath.ClasspathUtilities
import xsbti.AppConfiguration
lazy val checkFull = taskKey[Unit]("")
lazy val check = taskKey[Unit]("")
@ -19,7 +20,8 @@ lazy val root = (project in file("."))
.settings(
ivyPaths := IvyPaths(baseDirectory.value, Some(target.value / "ivy-cache")),
publishTo := Some(Resolver.file("Test Publish Repo", file("test-repo"))),
resolvers += (baseDirectory { base => "Test Repo" at (base / "test-repo").toURI.toString }).value,
scalaCompilerBridgeResolvers += userLocalFileResolver(appConfiguration.value),
resolvers += baseDirectory { base => "Test Repo" at (base / "test-repo").toURI.toString }.value,
moduleName := artifactID,
projectID := (if (baseDirectory.value / "retrieve" exists) retrieveID else publishedID),
artifact in (Compile, packageBin) := mainArtifact,
@ -67,3 +69,9 @@ def checkTask(classpath: TaskKey[Classpath]) = Def.task {
try { Class.forName("test.Test", false, loader); () }
catch { case _: ClassNotFoundException | _: NoClassDefFoundError => sys.error(s"Dependency not retrieved properly: $deps, $cp") }
}
// use the user local resolver to fetch the SNAPSHOT version of the compiler-bridge
def userLocalFileResolver(appConfig: AppConfiguration): Resolver = {
val ivyHome = appConfig.provider.scalaProvider.launcher.ivyHome
Resolver.file("User Local", ivyHome / "local")(Resolver.defaultIvyPatterns)
}

View File

@ -1,3 +1,5 @@
import xsbti.AppConfiguration
ThisBuild / scalaVersion := "2.12.12"
// TTL of Coursier is 24h
@ -11,6 +13,7 @@ val b = project
.settings(
localCache,
libraryDependencies += "org.example" %% "artifacta" % "1.0.0-SNAPSHOT" withSources() classifier("tests"),
scalaCompilerBridgeResolvers += userLocalFileResolver(appConfiguration.value),
externalResolvers := Vector(
MavenCache("demo", ((baseDirectory in ThisBuild).value / "demo-repo")),
DefaultMavenRepository
@ -26,3 +29,9 @@ val a = project
publishArtifact in (Test,packageBin) := true,
publishTo := Some(MavenCache("demo", ((baseDirectory in ThisBuild).value / "demo-repo")))
)
// use the user local resolver to fetch the SNAPSHOT version of the compiler-bridge
def userLocalFileResolver(appConfig: AppConfiguration): Resolver = {
val ivyHome = appConfig.provider.scalaProvider.launcher.ivyHome
Resolver.file("User Local", ivyHome / "local")(Resolver.defaultIvyPatterns)
}

View File

@ -1,3 +1,5 @@
import xsbti.AppConfiguration
ThisBuild / csrCacheDirectory := (ThisBuild / baseDirectory).value / "coursier-cache"
def commonSettings: Vector[Def.Setting[_]] =
@ -5,6 +7,7 @@ def commonSettings: Vector[Def.Setting[_]] =
organization := "com.example",
ivyPaths := IvyPaths( (baseDirectory in ThisBuild).value, Some((baseDirectory in LocalRootProject).value / "ivy-cache")),
dependencyCacheDirectory := (baseDirectory in LocalRootProject).value / "dependency",
scalaCompilerBridgeResolvers += userLocalFileResolver(appConfiguration.value),
resolvers += Resolver.file("buggy", (baseDirectory in LocalRootProject).value / "repo")(
Patterns(
ivyPatterns = Vector("[organization]/[module]/[revision]/ivy.xml"),
@ -28,3 +31,9 @@ lazy val b = project dependsOn(a) settings(
updateOptions := updateOptions.value.withCachedResolution(true), //comment this line to make ws compile
libraryDependencies += "a" % "b" % "1.0.1" % "compile->runtime"
)
// use the user local resolver to fetch the SNAPSHOT version of the compiler-bridge
def userLocalFileResolver(appConfig: AppConfiguration): Resolver = {
val ivyHome = appConfig.provider.scalaProvider.launcher.ivyHome
Resolver.file("User Local", ivyHome / "local")(Resolver.defaultIvyPatterns)
}

View File

@ -1,3 +1,5 @@
import xsbti.AppConfiguration
// ThisBuild / useCoursier := false
ThisBuild / organization := "com.example"
ThisBuild / scalaVersion := "2.13.3"
ThisBuild / versionScheme := Some("semver-spec")
@ -7,6 +9,7 @@ def commonSettings: Seq[Def.Setting[_]] =
Seq(
fullResolvers := fullResolvers.value.filterNot(_.name == "inter-project"),
publishTo := Some(MavenCache("local-maven", (LocalRootProject / target).value / "local-maven")),
scalaCompilerBridgeResolvers += userLocalFileResolver(appConfiguration.value),
resolvers += MavenCache("local-maven", (LocalRootProject / target).value / "local-maven"),
)
@ -65,3 +68,8 @@ val use2 = project
"org.typelevel" %% "cats-effect" % "3.0.0-M4",
),
)
// use the user local resolver to fetch the SNAPSHOT version of the compiler-bridge
def userLocalFileResolver(appConfig: AppConfiguration): Resolver = {
val ivyHome = appConfig.provider.scalaProvider.launcher.ivyHome
Resolver.file("User Local", ivyHome / "local")(Resolver.defaultIvyPatterns)
}

View File

@ -52,5 +52,5 @@ checkDependencies := {
if !m.evicted
} yield m.module.withExtraAttributes(Map.empty)).toSet
assert(resolved == expected)
assert(resolved == expected, s"$resolved != $expected")
}

View File

@ -0,0 +1,19 @@
autoScalaLibrary := false
scalaVersion := "3.0.0-M2"
libraryDependencies += "com.chuusai" % "shapeless_2.13" % "2.3.3"
val checkScalaLibrary = TaskKey[Unit]("checkScalaLibrary")
checkScalaLibrary := {
val scalaLibsJars = (Compile / managedClasspath).value
.map(_.data.getName)
.filter(name => name.startsWith("scala-library") || name.startsWith("scala3-library"))
.sorted
val expectedScalaLibsJars = Seq(
"scala-library-2.13.0.jar"
)
assert(
scalaLibsJars == expectedScalaLibsJars,
s"$scalaLibsJars != $expectedScalaLibsJars"
)
}

View File

@ -0,0 +1 @@
> checkScalaLibrary

View File

@ -0,0 +1 @@
val A = "A"

View File

@ -0,0 +1,8 @@
ThisBuild / scalaVersion := "3.0.0-M2"
lazy val check = taskKey[Unit]("")
check := {
val bridge = scalaCompilerBridgeBinaryJar.value
bridge.getOrElse(sys.error(s"bridge JAR is missing"))
}

View File

@ -0,0 +1,2 @@
> check
> compile

View File

@ -0,0 +1,9 @@
scalaVersion := "3.0.0-M2"
val makeHome = taskKey[Unit]("Populates the 'home/lib' directory with Scala jars from the default ScalaInstance")
makeHome := {
val lib = baseDirectory.value / "home" / "lib"
for(jar <- scalaInstance.value.allJars)
IO.copyFile(jar, lib / jar.getName)
}

View File

@ -0,0 +1,11 @@
scalaVersion := "3.0.0-M2"
scalaHome := Some(baseDirectory.value / "home")
val checkUpdate = taskKey[Unit]("Ensures that resolved Scala artifacts are replaced with ones from the configured Scala home directory")
checkUpdate := {
val report = update.value
val lib = (scalaHome.value.get / "lib").getCanonicalFile
for(f <- report.allFiles)
assert(f.getParentFile == lib, "Artifact not in Scala home directory: " + f.getAbsolutePath)
}

View File

@ -0,0 +1,4 @@
> makeHome
$ copy-file changes/real-build.sbt build.sbt
> reload
> checkUpdate

View File

@ -0,0 +1,48 @@
ThisBuild / useCoursier := false
scalaOrganization := "org.other"
scalaVersion := "3.0.0-M2"
resolvers += Resolver.file("buggy", (baseDirectory in LocalRootProject).value / "repo")(
Patterns(
ivyPatterns = Vector("[organization]/[module]/[revision]/ivy.xml"),
artifactPatterns = Vector("[organization]/[module]/[revision]/dummy.jar"),
isMavenCompatible = false,
descriptorOptional = true,
skipConsistencyCheck = true
)
)
libraryDependencies += "org.typelevel" %% "cats-core" % "2.3.0"
val checkDependencies = taskKey[Unit]("Checks that dependencies are correct.")
checkDependencies := {
val expected: Set[ModuleID] = Set(
"org.scala-lang.modules" % "scala-asm" % "7.3.1-scala-1",
"org.jline" % "jline-reader" % "3.15.0",
"com.google.protobuf" % "protobuf-java" % "3.7.0",
"org.typelevel" % "cats-kernel_3.0.0-M2" % "2.3.0",
"org.jline" % "jline-terminal-jna" % "3.15.0",
"org.jline" % "jline-terminal" % "3.15.0",
"org.scala-sbt" % "compiler-interface" % "1.3.5",
"net.java.dev.jna" % "jna" % "5.3.1",
"org.other" % "scala-library" % "2.13.4",
"org.other" % "scala3-library_3.0.0-M2" % "3.0.0-M2",
"org.typelevel" % "simulacrum-scalafix-annotations_3.0.0-M2" % "0.5.1",
"org.other" % "scala3-compiler_3.0.0-M2" % "3.0.0-M2",
"org.other" % "scala3-interfaces" % "3.0.0-M2",
"org.other" % "tasty-core_3.0.0-M2" % "3.0.0-M2",
"org.typelevel" % "cats-core_3.0.0-M2" % "2.3.0",
"org.scala-sbt" % "util-interface" % "1.3.0"
)
val resolved: Set[ModuleID] =
(for {
c <- update.value.configurations
m <- c.modules
if !m.evicted
} yield m.module.withExtraAttributes(Map.empty)).toSet
assert(resolved == expected, s"$resolved != $expected")
}

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="org.other" module="scala-library" revision="2.13.4" status="integration" publication="20200731084418" e:info.apiURL="https://www.scala-lang.org/api/2.13.4-bin-SNAPSHOT/">
<description homepage="https://www.scala-lang.org">Scala Standard Library</description>
</info>
<configurations>
<conf name="plugin" visibility="public" description=""/>
<conf name="pom" visibility="public" description=""/>
<conf extends="runtime" name="test" visibility="public" description=""/>
<conf name="provided" visibility="public" description=""/>
<conf extends="compile,optional,provided" name="compile-internal" visibility="public" description=""/>
<conf name="docs" visibility="public" description=""/>
<conf name="optional" visibility="public" description=""/>
<conf name="compile" visibility="public" description=""/>
<conf extends="test,optional,provided" name="test-internal" visibility="public" description=""/>
<conf extends="runtime" name="default" visibility="public" description=""/>
<conf name="sources" visibility="public" description=""/>
<conf extends="compile" name="runtime" visibility="public" description=""/>
<conf extends="runtime,optional" name="runtime-internal" visibility="public" description=""/>
</configurations>
<publications>
<artifact name="scala-library" type="pom" ext="pom" conf="pom"/>
<artifact e:classifier="sources" name="scala-library" type="src" ext="jar" conf="sources"/>
<artifact e:classifier="javadoc" name="scala-library" type="doc" ext="jar" conf="docs"/>
<artifact name="scala-library" type="jar" ext="jar" conf="compile"/>
</publications>
<dependencies/>
</ivy-module>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="org.other" module="scala3-compiler_3.0.0-M2" revision="3.0.0-M2" status="integration" publication="20201202164220">
<description homepage="https://github.com/lampepfl/dotty">scala3-compiler</description>
</info>
<configurations>
<conf name="plugin" visibility="public" description=""/>
<conf name="pom" visibility="public" description=""/>
<conf extends="runtime" name="test" visibility="public" description=""/>
<conf name="provided" visibility="public" description=""/>
<conf extends="compile,optional,provided" name="compile-internal" visibility="public" description=""/>
<conf name="docs" visibility="public" description=""/>
<conf name="optional" visibility="public" description=""/>
<conf name="compile" visibility="public" description=""/>
<conf extends="test,optional,provided" name="test-internal" visibility="public" description=""/>
<conf name="sourcedeps" visibility="public" description=""/>
<conf name="sources" visibility="public" description=""/>
<conf extends="compile" name="runtime" visibility="public" description=""/>
<conf extends="runtime,optional" name="runtime-internal" visibility="public" description=""/>
</configurations>
<publications>
<artifact name="scala3-compiler_3.0.0-M2" type="pom" ext="pom" conf="pom"/>
<artifact e:classifier="sources" name="scala3-compiler_3.0.0-M2" type="src" ext="jar" conf="sources"/>
<artifact e:classifier="javadoc" name="scala3-compiler_3.0.0-M2" type="doc" ext="jar" conf="docs"/>
<artifact name="scala3-compiler_3.0.0-M2" type="jar" ext="jar" conf="compile"/>
</publications>
<dependencies>
<dependency org="org.other" name="scala3-interfaces" rev="3.0.0-M2" conf="compile->default(compile)"> </dependency>
<dependency org="org.other" name="scala3-library_3.0.0-M2" rev="3.0.0-M2" conf="compile->default(compile)"> </dependency>
<dependency org="org.other" name="tasty-core_3.0.0-M2" rev="3.0.0-M2" conf="compile->default(compile)"> </dependency>
<dependency org="com.novocode" name="junit-interface" rev="0.11" conf="test->default(compile)"> </dependency>
<dependency org="org.scala-lang.modules" name="scala-asm" rev="7.3.1-scala-1" conf="compile->default(compile)"> </dependency>
<dependency org="org.scala-sbt" name="compiler-interface" rev="1.3.5" conf="compile->default(compile)"> </dependency>
<dependency org="org.jline" name="jline-reader" rev="3.15.0" conf="compile->default(compile)"> </dependency>
<dependency org="org.jline" name="jline-terminal" rev="3.15.0" conf="compile->default(compile)"> </dependency>
<dependency org="org.jline" name="jline-terminal-jna" rev="3.15.0" conf="compile->default(compile)"> </dependency>
<dependency org="org.scala-js" name="scalajs-ir_2.13" rev="1.3.1" conf="sourcedeps->default(compile)"> </dependency>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="org.other" module="scala3-interfaces" revision="3.0.0-M2" status="integration" publication="20201021102556">
<description homepage="https://github.com/lampepfl/dotty">scala3-interfaces</description>
</info>
<configurations>
<conf name="plugin" visibility="public" description=""/>
<conf name="pom" visibility="public" description=""/>
<conf extends="runtime" name="test" visibility="public" description=""/>
<conf name="provided" visibility="public" description=""/>
<conf extends="compile,optional,provided" name="compile-internal" visibility="public" description=""/>
<conf name="docs" visibility="public" description=""/>
<conf name="optional" visibility="public" description=""/>
<conf name="compile" visibility="public" description=""/>
<conf extends="test,optional,provided" name="test-internal" visibility="public" description=""/>
<conf name="sources" visibility="public" description=""/>
<conf extends="compile" name="runtime" visibility="public" description=""/>
<conf extends="runtime,optional" name="runtime-internal" visibility="public" description=""/>
</configurations>
<publications>
<artifact e:classifier="sources" name="scala3-interfaces" type="src" ext="jar" conf="sources"/>
<artifact e:classifier="javadoc" name="scala3-interfaces" type="doc" ext="jar" conf="docs"/>
<artifact name="scala3-interfaces" type="jar" ext="jar" conf="compile"/>
<artifact name="scala3-interfaces" type="pom" ext="pom" conf="pom"/>
</publications>
<dependencies>
<dependency org="com.novocode" name="junit-interface" rev="0.11" conf="test->default(compile)"> </dependency>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="org.other" module="scala3-library_3.0.0-M2" revision="3.0.0-M2" status="integration" publication="20201021102715">
<description homepage="https://github.com/lampepfl/dotty">scala3-library-bootstrapped</description>
</info>
<configurations>
<conf name="plugin" visibility="public" description=""/>
<conf name="pom" visibility="public" description=""/>
<conf extends="runtime" name="test" visibility="public" description=""/>
<conf name="provided" visibility="public" description=""/>
<conf extends="compile,optional,provided" name="compile-internal" visibility="public" description=""/>
<conf name="docs" visibility="public" description=""/>
<conf name="optional" visibility="public" description=""/>
<conf name="compile" visibility="public" description=""/>
<conf extends="test,optional,provided" name="test-internal" visibility="public" description=""/>
<conf name="sources" visibility="public" description=""/>
<conf extends="compile" name="runtime" visibility="public" description=""/>
<conf extends="runtime,optional" name="runtime-internal" visibility="public" description=""/>
</configurations>
<publications>
<artifact name="scala3-library_3.0.0-M2" type="pom" ext="pom" conf="pom"/>
<artifact e:classifier="sources" name="scala3-library_3.0.0-M2" type="src" ext="jar" conf="sources"/>
<artifact e:classifier="javadoc" name="scala3-library_3.0.0-M2" type="doc" ext="jar" conf="docs"/>
<artifact name="scala3-library_3.0.0-M2" type="jar" ext="jar" conf="compile"/>
</publications>
<dependencies>
<dependency org="com.novocode" name="junit-interface" rev="0.11" conf="test->default(compile)"> </dependency>
<dependency org="org.other" name="scala-library" rev="2.13.4" conf="compile->default(compile)"> </dependency>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<ivy-module version="2.0" xmlns:e="http://ant.apache.org/ivy/extra">
<info organisation="org.other" module="tasty-core_3.0.0-M2" revision="3.0.0-M2" status="integration" publication="20201021102716">
<description homepage="https://github.com/lampepfl/dotty">tasty-core-bootstrapped</description>
</info>
<configurations>
<conf name="plugin" visibility="public" description=""/>
<conf name="pom" visibility="public" description=""/>
<conf extends="runtime" name="test" visibility="public" description=""/>
<conf name="provided" visibility="public" description=""/>
<conf extends="compile,optional,provided" name="compile-internal" visibility="public" description=""/>
<conf name="docs" visibility="public" description=""/>
<conf name="optional" visibility="public" description=""/>
<conf name="compile" visibility="public" description=""/>
<conf extends="test,optional,provided" name="test-internal" visibility="public" description=""/>
<conf name="sources" visibility="public" description=""/>
<conf extends="compile" name="runtime" visibility="public" description=""/>
<conf extends="runtime,optional" name="runtime-internal" visibility="public" description=""/>
</configurations>
<publications>
<artifact name="tasty-core_3.0.0-M2" type="pom" ext="pom" conf="pom"/>
<artifact e:classifier="sources" name="tasty-core_3.0.0-M2" type="src" ext="jar" conf="sources"/>
<artifact e:classifier="javadoc" name="tasty-core_3.0.0-M2" type="doc" ext="jar" conf="docs"/>
<artifact name="tasty-core_3.0.0-M2" type="jar" ext="jar" conf="compile"/>
</publications>
<dependencies>
<dependency org="org.other" name="scala3-library_3.0.0-M2" rev="3.0.0-M2" conf="compile->default(compile)"> </dependency>
<dependency org="com.novocode" name="junit-interface" rev="0.11" conf="test->default(compile)"> </dependency>
</dependencies>
</ivy-module>

View File

@ -0,0 +1,3 @@
# this test is pending because the IvyDependencyResolution is not yet able
# to override the Scala 3 artifacts
> checkDependencies

View File

@ -0,0 +1,3 @@
ThisBuild / scalaVersion := "3.0.0-M2"
lazy val root = project.in(file("."))

View File

@ -0,0 +1 @@
> consoleProject

View File

@ -0,0 +1,25 @@
Copyright (c) 2015 The dotty-example-project contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1 @@
Cut-n-pasted from https://github.com/scala/scala3-example-project/tree/353ccef820699f20eb012420a9deb28814481031

View File

@ -0,0 +1 @@
ThisBuild / scalaVersion := "3.0.0-M3"

View File

@ -0,0 +1,16 @@
object Main {
def main(args: Array[String]): Unit = {
runExample("Trait Params")(TraitParams.test)
}
private def runExample(name: String)(f: => Unit) = {
println(Console.MAGENTA + s"$name example:" + Console.RESET)
f
println()
}
}

View File

@ -0,0 +1,21 @@
/**
* Trait Parameters: https://dotty.epfl.ch/docs/reference/other-new-features/trait-parameters.html
*/
object TraitParams {
trait Base(val msg: String)
class A extends Base("Hello")
class B extends Base("Dotty!")
// Union types only exist in Dotty, so there's no chance that this will accidentally be compiled with Scala 2
private def printMessages(msgs: (A | B)*) = println(msgs.map(_.msg).mkString(" "))
def test: Unit = {
printMessages(new A, new B)
// Sanity check the classpath: this won't run if the dotty jar is not present.
val x: Int => Int = z => z
x(1)
}
}

View File

@ -0,0 +1 @@
> run

View File

@ -0,0 +1,13 @@
ThisBuild / scalaVersion := "3.0.0-M3"
lazy val check = taskKey[Unit]("check the Scala 3 instance class loader")
lazy val xsbtiClass = classOf[xsbti.compile.Compilers]
check := {
val scala3Loader = scalaInstance.value.loader
assert(
scala3Loader.loadClass(xsbtiClass.getCanonicalName) == xsbtiClass,
"The Scala 3 instance classloader does not load the same `xsbti` classes than sbt"
)
}

View File

@ -0,0 +1 @@
> check

View File

@ -0,0 +1,9 @@
package app
import mylib._
object Main {
def main(args: Array[String]): Unit = {
println(MyLib.square(5))
}
}

View File

@ -0,0 +1,15 @@
ThisBuild / scalaVersion := "2.13.4"
ThisBuild / scalacOptions += "-Ytasty-reader"
lazy val scala3code = project
.enablePlugins(ScalaJSPlugin)
.settings(scalaVersion := "3.0.0-M1")
lazy val app = project
.enablePlugins(ScalaJSPlugin)
.dependsOn(scala3code)
.settings(
scalaVersion := "2.13.4",
scalacOptions += "-Ytasty-reader",
scalaJSUseMainModuleInitializer := true
)

View File

@ -0,0 +1 @@
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.3.1")

View File

@ -0,0 +1,5 @@
package mylib
object MyLib {
def square(x: Int): Int = x * x
}

View File

@ -0,0 +1 @@
> app/run

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,23 @@
ThisBuild / scalaVersion := "3.0.0-M1"
lazy val scala213 = "2.13.4"
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,
scalacOptions += "-Ytasty-reader"
)
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,3 @@
> fooApp/compile
> barApp/compile

View File

@ -0,0 +1,25 @@
Copyright (c) 2015 The dotty-example-project contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1 @@
Cut-n-pasted from https://github.com/scala/scala3-example-project/tree/353ccef820699f20eb012420a9deb28814481031

View File

@ -0,0 +1,13 @@
ThisBuild / scalaVersion := "3.0.0-M2"
ThisBuild / semanticdbEnabled := true
lazy val check = taskKey[Unit]("check the Scala 3 semanticdb files")
Compile / check := checkTask("Main.semanticdb")
Test / check := checkTask("Test.semanticdb")
def checkTask(fileName: String): Def.Initialize[Task[Unit]] = Def.task {
val _ = compile.value
val dir = semanticdbTargetRoot.value
assert(IO.listFiles(dir).exists(_.getName == fileName), s"$fileName is missing")
}

View File

@ -0,0 +1,8 @@
object Main {
val msg = "Hello, World!"
def main(args: Array[String]): Unit = {
println(msg)
}
}

View File

@ -0,0 +1,3 @@
object Test {
assert(Main.msg == "Hello, World!")
}

View File

@ -0,0 +1,3 @@
> Compile / check
> Test / check

View File

@ -9,48 +9,34 @@ package sbt
package internal
package inc
import java.io.File
import java.nio.file.{ Files, Path }
import java.util.concurrent.Callable
import sbt.internal.inc.classpath.ClasspathUtil
import sbt.io.IO
import sbt.internal.librarymanagement._
import sbt.internal.util.{ BufferedLogger, FullLogger }
import sbt.io.IO
import sbt.librarymanagement._
import sbt.librarymanagement.syntax._
import sbt.util.InterfaceUtil.{ toSupplier => f0 }
import xsbti.ArtifactInfo._
import xsbti.compile.{
ClasspathOptionsUtil,
CompilerBridgeProvider,
ScalaInstance => XScalaInstance
}
import xsbti.{ ComponentProvider, GlobalLock, Logger }
import xsbti.compile.{ ClasspathOptionsUtil, CompilerBridgeProvider }
import java.io.File
import java.nio.file.{ Files, Path }
import java.util.concurrent.Callable
private[sbt] object ZincComponentCompiler {
import xsbti.compile.ScalaInstance
final val binSeparator = "-bin_"
final val javaClassVersion = System.getProperty("java.class.version")
private[inc] final val sbtOrgTemp = JsonUtil.sbtOrgTemp
private[inc] final val modulePrefixTemp = "temp-module-"
private[sbt] final lazy val incrementalVersion: String = ZincComponentManager.version
private val CompileConf = Some(Configurations.Compile.name)
private val lock: AnyRef = new {}
private[sbt] def getDefaultBridgeModule(scalaVersion: String): ModuleID = {
val compilerBridgeId = scalaVersion match {
case sc if (sc startsWith "2.10.") => "compiler-bridge_2.10"
case sc if (sc startsWith "2.11.") => "compiler-bridge_2.11"
case sc if (sc startsWith "2.12.") => "compiler-bridge_2.12"
case "2.13.0-M1" => "compiler-bridge_2.12"
case _ => "compiler-bridge_2.13"
}
ModuleID(SbtOrganization, compilerBridgeId, incrementalVersion)
.withConfigurations(CompileConf)
.sources()
}
/** Defines the internal implementation of a bridge provider. */
private class ZincCompilerBridgeProvider(
userProvidedBridgeSources: Option[ModuleID],
@ -67,7 +53,7 @@ private[sbt] object ZincComponentCompiler {
*/
def compiledBridge(
bridgeSources: ModuleID,
scalaInstance: ScalaInstance,
scalaInstance: XScalaInstance,
logger: Logger,
): File = lock.synchronized {
val raw = new RawCompiler(scalaInstance, ClasspathOptionsUtil.auto, logger)
@ -77,9 +63,10 @@ private[sbt] object ZincComponentCompiler {
zinc.compiledBridgeJar
}
override def fetchCompiledBridge(scalaInstance: ScalaInstance, logger: Logger): File = {
override def fetchCompiledBridge(scalaInstance: XScalaInstance, logger: Logger): File = {
val scalaVersion = scalaInstance.actualVersion()
val bridgeSources = userProvidedBridgeSources.getOrElse(getDefaultBridgeModule(scalaVersion))
val bridgeSources = userProvidedBridgeSources
.getOrElse(ZincLmUtil.getDefaultBridgeSourceModule(scalaVersion))
compiledBridge(bridgeSources, scalaInstance, logger)
}
@ -125,7 +112,7 @@ private[sbt] object ZincComponentCompiler {
ScalaArtifacts(scalaCompilerJar, Vector(scalaLibraryJar), others)
}
override def fetchScalaInstance(scalaVersion: String, logger: Logger): ScalaInstance = {
override def fetchScalaInstance(scalaVersion: String, logger: Logger): XScalaInstance = {
val scalaArtifacts = getScalaArtifacts(scalaVersion, logger)
val scalaCompilerJar = scalaArtifacts.compilerJar
val scalaLibraryJars = scalaArtifacts.libraryJars
@ -141,7 +128,7 @@ private[sbt] object ZincComponentCompiler {
val properties = ResourceLoader.getSafePropertiesFor("compiler.properties", loader)
val loaderVersion = Option(properties.getProperty("version.number"))
val scalaV = loaderVersion.getOrElse("unknown")
new inc.ScalaInstance(
new ScalaInstance(
scalaV,
loader,
loaderLibraryOnly,

View File

@ -8,14 +8,21 @@
package sbt.internal.inc
import java.io.File
import sbt.internal.inc.classpath.ClassLoaderCache
import sbt.librarymanagement.{ DependencyResolution, ModuleID }
import sbt.internal.util.MessageOnlyException
import sbt.librarymanagement.{
DependencyResolution,
ModuleID,
ScalaArtifacts,
UnresolvedWarningConfiguration,
UpdateConfiguration
}
import sbt.librarymanagement.syntax._
import xsbti.ArtifactInfo.SbtOrganization
import xsbti._
import xsbti.compile._
import xsbti.compile.{ ClasspathOptions, ScalaInstance => XScalaInstance }
object ZincLmUtil {
import xsbti.compile.ScalaInstance
/**
* Instantiate a Scala compiler that is instrumented to analyze dependencies.
@ -23,7 +30,7 @@ object ZincLmUtil {
* compilation.
*/
def scalaCompiler(
scalaInstance: ScalaInstance,
scalaInstance: XScalaInstance,
classpathOptions: ClasspathOptions,
globalLock: GlobalLock,
componentProvider: ComponentProvider,
@ -49,6 +56,48 @@ object ZincLmUtil {
)
}
def getDefaultBridgeModule(scalaVersion: String): ModuleID =
ZincComponentCompiler.getDefaultBridgeModule(scalaVersion)
def fetchDefaultBridgeModule(
scalaVersion: String,
dependencyResolution: DependencyResolution,
updateConfiguration: UpdateConfiguration,
warningConfig: UnresolvedWarningConfiguration,
logger: Logger
): File = {
val bridgeModule = getDefaultBridgeModule(scalaVersion)
val descriptor = dependencyResolution.wrapDependencyInModule(bridgeModule)
dependencyResolution
.update(descriptor, updateConfiguration, warningConfig, logger)
.toOption
.flatMap { report =>
val jars = report.select(
configurationFilter(Compile.name),
moduleFilter(bridgeModule.organization, bridgeModule.name, bridgeModule.revision),
artifactFilter(`extension` = "jar", classifier = "")
)
if (jars.size > 1)
sys.error(s"There should be only one jar for $bridgeModule but found $jars")
else jars.headOption
}
.getOrElse(throw new MessageOnlyException(s"Missing $bridgeModule"))
}
def getDefaultBridgeModule(scalaVersion: String): ModuleID = {
if (ScalaArtifacts.isScala3(scalaVersion)) {
ModuleID(ScalaArtifacts.Organization, "scala3-sbt-bridge", scalaVersion)
.withConfigurations(Some(Compile.name))
} else {
val compilerBridgeId = scalaVersion match {
case sc if sc startsWith "2.10." => "compiler-bridge_2.10"
case sc if sc startsWith "2.11." => "compiler-bridge_2.11"
case sc if sc startsWith "2.12." => "compiler-bridge_2.12"
case "2.13.0-M1" => "compiler-bridge_2.12"
case _ => "compiler-bridge_2.13"
}
ModuleID(SbtOrganization, compilerBridgeId, ZincComponentManager.version)
.withConfigurations(Some(Compile.name))
}
}
def getDefaultBridgeSourceModule(scalaVersion: String): ModuleID =
getDefaultBridgeModule(scalaVersion).sources()
}

View File

@ -62,7 +62,7 @@ abstract class IvyBridgeProviderSpecification
case Some(v: String) => v
case _ => throw new IllegalStateException("No zinc version specified")
}
val bridge0 = ZincComponentCompiler.getDefaultBridgeModule(scalaVersion)
val bridge0 = ZincLmUtil.getDefaultBridgeSourceModule(scalaVersion)
// redefine the compiler bridge version
// using the version of zinc used during testing
// this way when building with zinc as a source dependency