diff --git a/main/src/main/java/sbt/internal/MetaBuildLoader.java b/main/src/main/java/sbt/internal/MetaBuildLoader.java index 26e10afd3..f9cc8b9c7 100644 --- a/main/src/main/java/sbt/internal/MetaBuildLoader.java +++ b/main/src/main/java/sbt/internal/MetaBuildLoader.java @@ -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 = diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 19c5525b2..757772ab1 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -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 diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 2df1d1e3f..540648454 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -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.") diff --git a/main/src/main/scala/sbt/coursierint/LMCoursier.scala b/main/src/main/scala/sbt/coursierint/LMCoursier.scala index b7281a62e..7bd0b6302 100644 --- a/main/src/main/scala/sbt/coursierint/LMCoursier.scala +++ b/main/src/main/scala/sbt/coursierint/LMCoursier.scala @@ -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, diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index a502e2364..ac969a4ba 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -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 diff --git a/sbt/src/sbt-test/compiler-project/scala3-tasty-management/build.sbt b/sbt/src/sbt-test/compiler-project/scala3-tasty-management/build.sbt new file mode 100644 index 000000000..208b8c684 --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/scala3-tasty-management/build.sbt @@ -0,0 +1,3 @@ +ThisBuild / scalaVersion := "3.0.0-M2" + +lazy val root = project.in(file(".")) diff --git a/sbt/src/sbt-test/compiler-project/scala3-tasty-management/src/main/scala/A.scala b/sbt/src/sbt-test/compiler-project/scala3-tasty-management/src/main/scala/A.scala new file mode 100644 index 000000000..c52c45808 --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/scala3-tasty-management/src/main/scala/A.scala @@ -0,0 +1,3 @@ +class A { + def initialized: Boolean = false +} diff --git a/sbt/src/sbt-test/compiler-project/scala3-tasty-management/src/main/scala/B.scala b/sbt/src/sbt-test/compiler-project/scala3-tasty-management/src/main/scala/B.scala new file mode 100644 index 000000000..066d5fc59 --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/scala3-tasty-management/src/main/scala/B.scala @@ -0,0 +1,3 @@ +class B { + def foo(a: A): Boolean = a.initialized +} diff --git a/sbt/src/sbt-test/compiler-project/scala3-tasty-management/test b/sbt/src/sbt-test/compiler-project/scala3-tasty-management/test new file mode 100644 index 000000000..3efda69bb --- /dev/null +++ b/sbt/src/sbt-test/compiler-project/scala3-tasty-management/test @@ -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 diff --git a/sbt/src/sbt-test/dependency-management/artifact/build.sbt b/sbt/src/sbt-test/dependency-management/artifact/build.sbt index bc8d53abd..d0d5afc46 100644 --- a/sbt/src/sbt-test/dependency-management/artifact/build.sbt +++ b/sbt/src/sbt-test/dependency-management/artifact/build.sbt @@ -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) +} diff --git a/sbt/src/sbt-test/dependency-management/cache-classifiers/multi.sbt b/sbt/src/sbt-test/dependency-management/cache-classifiers/multi.sbt index 4e22c07f8..69771b0b8 100644 --- a/sbt/src/sbt-test/dependency-management/cache-classifiers/multi.sbt +++ b/sbt/src/sbt-test/dependency-management/cache-classifiers/multi.sbt @@ -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) +} diff --git a/sbt/src/sbt-test/dependency-management/cached-resolution-configurations/build.sbt b/sbt/src/sbt-test/dependency-management/cached-resolution-configurations/build.sbt index d52b9e114..018bab537 100644 --- a/sbt/src/sbt-test/dependency-management/cached-resolution-configurations/build.sbt +++ b/sbt/src/sbt-test/dependency-management/cached-resolution-configurations/build.sbt @@ -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) +} diff --git a/sbt/src/sbt-test/dependency-management/evicted-semver-spec/build.sbt b/sbt/src/sbt-test/dependency-management/evicted-semver-spec/build.sbt index 6d1caf3a7..9460b811d 100644 --- a/sbt/src/sbt-test/dependency-management/evicted-semver-spec/build.sbt +++ b/sbt/src/sbt-test/dependency-management/evicted-semver-spec/build.sbt @@ -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) +} diff --git a/sbt/src/sbt-test/dependency-management/scala-organization/build.sbt b/sbt/src/sbt-test/dependency-management/scala-organization/build.sbt index 42d335c4d..068fe0611 100644 --- a/sbt/src/sbt-test/dependency-management/scala-organization/build.sbt +++ b/sbt/src/sbt-test/dependency-management/scala-organization/build.sbt @@ -52,5 +52,5 @@ checkDependencies := { if !m.evicted } yield m.module.withExtraAttributes(Map.empty)).toSet - assert(resolved == expected) + assert(resolved == expected, s"$resolved != $expected") } diff --git a/sbt/src/sbt-test/dependency-management/scala3-auto-scala-library/build.sbt b/sbt/src/sbt-test/dependency-management/scala3-auto-scala-library/build.sbt new file mode 100644 index 000000000..9478d98dd --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-auto-scala-library/build.sbt @@ -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" + ) +} diff --git a/sbt/src/sbt-test/dependency-management/scala3-auto-scala-library/test b/sbt/src/sbt-test/dependency-management/scala3-auto-scala-library/test new file mode 100644 index 000000000..f56f5a75e --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-auto-scala-library/test @@ -0,0 +1 @@ +> checkScalaLibrary diff --git a/sbt/src/sbt-test/dependency-management/scala3-compiler-bridge-binary/A.scala b/sbt/src/sbt-test/dependency-management/scala3-compiler-bridge-binary/A.scala new file mode 100644 index 000000000..c3ab8e5cc --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-compiler-bridge-binary/A.scala @@ -0,0 +1 @@ +val A = "A" diff --git a/sbt/src/sbt-test/dependency-management/scala3-compiler-bridge-binary/build.sbt b/sbt/src/sbt-test/dependency-management/scala3-compiler-bridge-binary/build.sbt new file mode 100644 index 000000000..998afcca4 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-compiler-bridge-binary/build.sbt @@ -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")) +} diff --git a/sbt/src/sbt-test/dependency-management/scala3-compiler-bridge-binary/test b/sbt/src/sbt-test/dependency-management/scala3-compiler-bridge-binary/test new file mode 100644 index 000000000..5f1fbe2c5 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-compiler-bridge-binary/test @@ -0,0 +1,2 @@ +> check +> compile diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-home/build.sbt b/sbt/src/sbt-test/dependency-management/scala3-scala-home/build.sbt new file mode 100644 index 000000000..e3dcd92e1 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-scala-home/build.sbt @@ -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) +} diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-home/changes/real-build.sbt b/sbt/src/sbt-test/dependency-management/scala3-scala-home/changes/real-build.sbt new file mode 100644 index 000000000..876da64cf --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-scala-home/changes/real-build.sbt @@ -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) +} diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-home/test b/sbt/src/sbt-test/dependency-management/scala3-scala-home/test new file mode 100644 index 000000000..7eadb9215 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-scala-home/test @@ -0,0 +1,4 @@ +> makeHome +$ copy-file changes/real-build.sbt build.sbt +> reload +> checkUpdate diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-organization/build.sbt b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/build.sbt new file mode 100644 index 000000000..dfd1b73e5 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/build.sbt @@ -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") +} diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala-library/2.13.4/dummy.jar b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala-library/2.13.4/dummy.jar new file mode 100644 index 000000000..e69de29bb diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala-library/2.13.4/ivy.xml b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala-library/2.13.4/ivy.xml new file mode 100644 index 000000000..6ef3dce02 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala-library/2.13.4/ivy.xml @@ -0,0 +1,28 @@ + + + + Scala Standard Library + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-compiler_3.0.0-M2/3.0.0-M2/dummy.jar b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-compiler_3.0.0-M2/3.0.0-M2/dummy.jar new file mode 100644 index 000000000..e69de29bb diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-compiler_3.0.0-M2/3.0.0-M2/ivy.xml b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-compiler_3.0.0-M2/3.0.0-M2/ivy.xml new file mode 100644 index 000000000..5b6236f36 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-compiler_3.0.0-M2/3.0.0-M2/ivy.xml @@ -0,0 +1,39 @@ + + + + scala3-compiler + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-interfaces/3.0.0-M2/dummy.jar b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-interfaces/3.0.0-M2/dummy.jar new file mode 100644 index 000000000..e69de29bb diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-interfaces/3.0.0-M2/ivy.xml b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-interfaces/3.0.0-M2/ivy.xml new file mode 100644 index 000000000..cab483d67 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-interfaces/3.0.0-M2/ivy.xml @@ -0,0 +1,29 @@ + + + + scala3-interfaces + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-library_3.0.0-M2/3.0.0-M2/dummy.jar b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-library_3.0.0-M2/3.0.0-M2/dummy.jar new file mode 100644 index 000000000..e69de29bb diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-library_3.0.0-M2/3.0.0-M2/ivy.xml b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-library_3.0.0-M2/3.0.0-M2/ivy.xml new file mode 100644 index 000000000..593d39bb4 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/scala3-library_3.0.0-M2/3.0.0-M2/ivy.xml @@ -0,0 +1,30 @@ + + + + scala3-library-bootstrapped + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/tasty-core_3.0.0-M2/3.0.0-M2/dummy.jar b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/tasty-core_3.0.0-M2/3.0.0-M2/dummy.jar new file mode 100644 index 000000000..e69de29bb diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/tasty-core_3.0.0-M2/3.0.0-M2/ivy.xml b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/tasty-core_3.0.0-M2/3.0.0-M2/ivy.xml new file mode 100644 index 000000000..5716a9b6e --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/repo/org.other/tasty-core_3.0.0-M2/3.0.0-M2/ivy.xml @@ -0,0 +1,30 @@ + + + + tasty-core-bootstrapped + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sbt/src/sbt-test/dependency-management/scala3-scala-organization/test b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/test new file mode 100644 index 000000000..6e1b1a750 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/scala3-scala-organization/test @@ -0,0 +1,3 @@ +# this test is pending because the IvyDependencyResolution is not yet able +# to override the Scala 3 artifacts +> checkDependencies diff --git a/sbt/src/sbt-test/project/scala3-console-project/build.sbt b/sbt/src/sbt-test/project/scala3-console-project/build.sbt new file mode 100644 index 000000000..208b8c684 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-console-project/build.sbt @@ -0,0 +1,3 @@ +ThisBuild / scalaVersion := "3.0.0-M2" + +lazy val root = project.in(file(".")) diff --git a/sbt/src/sbt-test/project/scala3-console-project/test b/sbt/src/sbt-test/project/scala3-console-project/test new file mode 100644 index 000000000..b80db65f1 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-console-project/test @@ -0,0 +1 @@ +> consoleProject diff --git a/sbt/src/sbt-test/project/scala3-example-project/LICENSE b/sbt/src/sbt-test/project/scala3-example-project/LICENSE new file mode 100644 index 000000000..728844ee3 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-example-project/LICENSE @@ -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. + diff --git a/sbt/src/sbt-test/project/scala3-example-project/README.md b/sbt/src/sbt-test/project/scala3-example-project/README.md new file mode 100644 index 000000000..daa544226 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-example-project/README.md @@ -0,0 +1 @@ +Cut-n-pasted from https://github.com/scala/scala3-example-project/tree/353ccef820699f20eb012420a9deb28814481031 diff --git a/sbt/src/sbt-test/project/scala3-example-project/build.sbt b/sbt/src/sbt-test/project/scala3-example-project/build.sbt new file mode 100644 index 000000000..14f3f6017 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-example-project/build.sbt @@ -0,0 +1 @@ +ThisBuild / scalaVersion := "3.0.0-M3" diff --git a/sbt/src/sbt-test/project/scala3-example-project/src/main/scala-3/Main.scala b/sbt/src/sbt-test/project/scala3-example-project/src/main/scala-3/Main.scala new file mode 100644 index 000000000..8a44ae4ef --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-example-project/src/main/scala-3/Main.scala @@ -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() + } + +} diff --git a/sbt/src/sbt-test/project/scala3-example-project/src/main/scala-3/TraitParams.scala b/sbt/src/sbt-test/project/scala3-example-project/src/main/scala-3/TraitParams.scala new file mode 100644 index 000000000..1ca8d7c42 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-example-project/src/main/scala-3/TraitParams.scala @@ -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) + } +} diff --git a/sbt/src/sbt-test/project/scala3-example-project/test b/sbt/src/sbt-test/project/scala3-example-project/test new file mode 100644 index 000000000..62ea636c1 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-example-project/test @@ -0,0 +1 @@ +> run diff --git a/sbt/src/sbt-test/project/scala3-instance-loader/build.sbt b/sbt/src/sbt-test/project/scala3-instance-loader/build.sbt new file mode 100644 index 000000000..53bf8a0d3 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-instance-loader/build.sbt @@ -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" + ) +} \ No newline at end of file diff --git a/sbt/src/sbt-test/project/scala3-instance-loader/test b/sbt/src/sbt-test/project/scala3-instance-loader/test new file mode 100644 index 000000000..15675b169 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-instance-loader/test @@ -0,0 +1 @@ +> check diff --git a/sbt/src/sbt-test/project/scala3-sandwich-sjs/app/src/main/scala/app/Main.scala b/sbt/src/sbt-test/project/scala3-sandwich-sjs/app/src/main/scala/app/Main.scala new file mode 100644 index 000000000..e3a0fa2ce --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-sandwich-sjs/app/src/main/scala/app/Main.scala @@ -0,0 +1,9 @@ +package app + +import mylib._ + +object Main { + def main(args: Array[String]): Unit = { + println(MyLib.square(5)) + } +} diff --git a/sbt/src/sbt-test/project/scala3-sandwich-sjs/build.sbt b/sbt/src/sbt-test/project/scala3-sandwich-sjs/build.sbt new file mode 100644 index 000000000..01e81e167 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-sandwich-sjs/build.sbt @@ -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 + ) diff --git a/sbt/src/sbt-test/project/scala3-sandwich-sjs/project/plugins.sbt b/sbt/src/sbt-test/project/scala3-sandwich-sjs/project/plugins.sbt new file mode 100644 index 000000000..8f1d0ac9b --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-sandwich-sjs/project/plugins.sbt @@ -0,0 +1 @@ +addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.3.1") diff --git a/sbt/src/sbt-test/project/scala3-sandwich-sjs/scala3code/src/main/scala/mylib/MyLib.scala b/sbt/src/sbt-test/project/scala3-sandwich-sjs/scala3code/src/main/scala/mylib/MyLib.scala new file mode 100644 index 000000000..ae2f3af75 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-sandwich-sjs/scala3code/src/main/scala/mylib/MyLib.scala @@ -0,0 +1,5 @@ +package mylib + +object MyLib { + def square(x: Int): Int = x * x +} diff --git a/sbt/src/sbt-test/project/scala3-sandwich-sjs/test b/sbt/src/sbt-test/project/scala3-sandwich-sjs/test new file mode 100644 index 000000000..63092ffa4 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-sandwich-sjs/test @@ -0,0 +1 @@ +> app/run diff --git a/sbt/src/sbt-test/project/scala3-sandwich/bar-app/D.scala b/sbt/src/sbt-test/project/scala3-sandwich/bar-app/D.scala new file mode 100644 index 000000000..b937ae06c --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-sandwich/bar-app/D.scala @@ -0,0 +1,5 @@ +package example + +object D { + val x = C.x +} diff --git a/sbt/src/sbt-test/project/scala3-sandwich/bar-core/C.scala b/sbt/src/sbt-test/project/scala3-sandwich/bar-core/C.scala new file mode 100644 index 000000000..4d4fcc6df --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-sandwich/bar-core/C.scala @@ -0,0 +1,5 @@ +package example + +object C { + val x = 1 +} diff --git a/sbt/src/sbt-test/project/scala3-sandwich/build.sbt b/sbt/src/sbt-test/project/scala3-sandwich/build.sbt new file mode 100644 index 000000000..69a2ca58f --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-sandwich/build.sbt @@ -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")) diff --git a/sbt/src/sbt-test/project/scala3-sandwich/foo-app/B.scala b/sbt/src/sbt-test/project/scala3-sandwich/foo-app/B.scala new file mode 100644 index 000000000..ed82c07d1 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-sandwich/foo-app/B.scala @@ -0,0 +1,5 @@ +package example + +object B { + val x = A.x +} diff --git a/sbt/src/sbt-test/project/scala3-sandwich/foo-core/A.scala b/sbt/src/sbt-test/project/scala3-sandwich/foo-core/A.scala new file mode 100644 index 000000000..be4b82a9f --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-sandwich/foo-core/A.scala @@ -0,0 +1,5 @@ +package example + +object A { + val x = 1 +} diff --git a/sbt/src/sbt-test/project/scala3-sandwich/test b/sbt/src/sbt-test/project/scala3-sandwich/test new file mode 100644 index 000000000..19ccc5787 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-sandwich/test @@ -0,0 +1,3 @@ +> fooApp/compile + +> barApp/compile diff --git a/sbt/src/sbt-test/project/scala3-semanticdb/LICENSE b/sbt/src/sbt-test/project/scala3-semanticdb/LICENSE new file mode 100644 index 000000000..728844ee3 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-semanticdb/LICENSE @@ -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. + diff --git a/sbt/src/sbt-test/project/scala3-semanticdb/README.md b/sbt/src/sbt-test/project/scala3-semanticdb/README.md new file mode 100644 index 000000000..daa544226 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-semanticdb/README.md @@ -0,0 +1 @@ +Cut-n-pasted from https://github.com/scala/scala3-example-project/tree/353ccef820699f20eb012420a9deb28814481031 diff --git a/sbt/src/sbt-test/project/scala3-semanticdb/build.sbt b/sbt/src/sbt-test/project/scala3-semanticdb/build.sbt new file mode 100644 index 000000000..7b302985e --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-semanticdb/build.sbt @@ -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") +} \ No newline at end of file diff --git a/sbt/src/sbt-test/project/scala3-semanticdb/src/main/scala/Main.scala b/sbt/src/sbt-test/project/scala3-semanticdb/src/main/scala/Main.scala new file mode 100644 index 000000000..9deb66d0b --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-semanticdb/src/main/scala/Main.scala @@ -0,0 +1,8 @@ + +object Main { + val msg = "Hello, World!" + + def main(args: Array[String]): Unit = { + println(msg) + } +} diff --git a/sbt/src/sbt-test/project/scala3-semanticdb/src/test/scala/Test.scala b/sbt/src/sbt-test/project/scala3-semanticdb/src/test/scala/Test.scala new file mode 100644 index 000000000..f197443c9 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-semanticdb/src/test/scala/Test.scala @@ -0,0 +1,3 @@ +object Test { + assert(Main.msg == "Hello, World!") +} \ No newline at end of file diff --git a/sbt/src/sbt-test/project/scala3-semanticdb/test b/sbt/src/sbt-test/project/scala3-semanticdb/test new file mode 100644 index 000000000..699323992 --- /dev/null +++ b/sbt/src/sbt-test/project/scala3-semanticdb/test @@ -0,0 +1,3 @@ +> Compile / check +> Test / check + diff --git a/zinc-lm-integration/src/main/scala/sbt/internal/inc/ZincComponentCompiler.scala b/zinc-lm-integration/src/main/scala/sbt/internal/inc/ZincComponentCompiler.scala index 6adc67505..3ca2d2ab0 100644 --- a/zinc-lm-integration/src/main/scala/sbt/internal/inc/ZincComponentCompiler.scala +++ b/zinc-lm-integration/src/main/scala/sbt/internal/inc/ZincComponentCompiler.scala @@ -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, diff --git a/zinc-lm-integration/src/main/scala/sbt/internal/inc/ZincLmUtil.scala b/zinc-lm-integration/src/main/scala/sbt/internal/inc/ZincLmUtil.scala index e0d0d4722..3205052ef 100644 --- a/zinc-lm-integration/src/main/scala/sbt/internal/inc/ZincLmUtil.scala +++ b/zinc-lm-integration/src/main/scala/sbt/internal/inc/ZincLmUtil.scala @@ -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() } diff --git a/zinc-lm-integration/src/test/scala/sbt/internal/inc/IvyBridgeProviderSpecification.scala b/zinc-lm-integration/src/test/scala/sbt/internal/inc/IvyBridgeProviderSpecification.scala index 7d4720420..a4c30bf0c 100644 --- a/zinc-lm-integration/src/test/scala/sbt/internal/inc/IvyBridgeProviderSpecification.scala +++ b/zinc-lm-integration/src/test/scala/sbt/internal/inc/IvyBridgeProviderSpecification.scala @@ -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