Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump zinc to 1.4.4 #1094

Merged
merged 6 commits into from
Jan 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion build.sc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ object Deps {
val sourcecode = ivy"com.lihaoyi::sourcecode:0.2.1"
val upickle = ivy"com.lihaoyi::upickle:1.2.2"
val utest = ivy"com.lihaoyi::utest:0.7.5"
val zinc = ivy"org.scala-sbt::zinc:1.4.0-M1"
val zinc = ivy"org.scala-sbt::zinc:1.4.4"
val bsp = ivy"ch.epfl.scala:bsp4j:2.0.0-M13"
val jarjarabrams = ivy"com.eed3si9n.jarjarabrams::jarjar-abrams-core:0.3.0"
}
Expand Down Expand Up @@ -309,6 +309,25 @@ object scalalib extends MillModule {
def testArgs = T{Seq(
"-DMILL_SCALA_WORKER=" + runClasspath().map(_.path).mkString(",")
)}

override def generatedSources = T{
val dest = T.ctx.dest
val artifacts = T.traverse(dev.moduleDeps)(_.publishSelfDependency)()
os.write(dest / "Versions.scala",
s"""package mill.scalalib.worker
|
|/**
| * Dependency versions.
| * Generated from mill in build.sc.
| */
|object Versions {
| /** Version of Zinc. */
| val zinc = "${Deps.zinc.dep.version}"
|}
|
|""".stripMargin)
super.generatedSources() ++ Seq(PathRef(dest))
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions contrib/proguard/test/src/ProguardTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ object ProguardTests extends TestSuite {
override def millSourcePath: os.Path =
TestUtil.getSrcPathBase() / millOuterCtx.enclosing.split('.')

override def scalaVersion = "2.12.0"
override def scalaVersion = "2.12.1"

def proguardContribClasspath = T{
mill.modules.Util.millProjectModule("MILL_PROGUARD_LIB", "mill-contrib-proguard", repositoriesTask())
Expand Down Expand Up @@ -54,7 +54,7 @@ object ProguardTests extends TestSuite {
val javaVersion = sys.props("java.version")
val acceptFailure = isGithubActions && javaVersion.startsWith("11")
try {

val Right((path, _)) = eval.apply(proguard.proguard)
assert(os.exists(path.path))

Expand Down
49 changes: 32 additions & 17 deletions scalalib/src/ZincWorkerModule.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package mill.scalalib

import coursier.core.Repository
import coursier.Repository
import mill.Agg
import mill.T
import mill.api.{Ctx, FixSizedCache, KeyedLockedCache}
import mill.define.{Command, Discover, ExternalModule, Worker}
import mill.scalalib.Lib.resolveDependencies
import mill.scalalib.api.Util.{isBinaryBridgeAvailable, isDotty, isDottyOrScala3}
import mill.scalalib.api.ZincWorkerApi
import mill.util.JsonFormatters._

object ZincWorkerModule extends ExternalModule with ZincWorkerModule with CoursierModule {
lazy val millDiscover = Discover[this.type]
Expand Down Expand Up @@ -43,7 +42,6 @@ trait ZincWorkerModule extends mill.Module with OfflineSupportModule { self: Cou
case _ => 1
}
ctx.log.debug(s"ZinkWorker: using cache size ${jobs}")
val cp = compilerInterfaceClasspath()
val cl = mill.api.ClassLoader.create(
classpath().map(_.path.toNIO.toUri.toURL).toVector,
getClass.getClassLoader
Expand All @@ -64,7 +62,7 @@ trait ZincWorkerModule extends mill.Module with OfflineSupportModule { self: Cou
.newInstance(
Left((
T.ctx(),
(x: String, y: String) => scalaCompilerBridgeJar(x, y, cp, repositoriesTask()).asSuccess.get.value
(x: String, y: String) => scalaCompilerBridgeJar(x, y, repositoriesTask()).asSuccess.get.value
)),
mill.scalalib.api.Util.grepJar(_, "scala-library", _, sources = false),
mill.scalalib.api.Util.grepJar(_, "scala-compiler", _, sources = false),
Expand All @@ -76,7 +74,6 @@ trait ZincWorkerModule extends mill.Module with OfflineSupportModule { self: Cou

def scalaCompilerBridgeJar(scalaVersion: String,
scalaOrganization: String,
compileClassPath: Agg[mill.api.PathRef],
repositories: Seq[Repository]) = {
val (scalaVersion0, scalaBinaryVersion0) = scalaVersion match {
case _ => (scalaVersion, mill.scalalib.api.Util.scalaBinaryVersion(scalaVersion))
Expand All @@ -98,39 +95,57 @@ trait ZincWorkerModule extends mill.Module with OfflineSupportModule { self: Cou
}
val useSources = !isBinaryBridgeAvailable(scalaVersion)

resolveDependencies(
val bridgeJar = resolveDependencies(
repositories,
Lib.depToDependency(_, scalaVersion0),
Seq(bridgeDep),
useSources
).map{deps =>
val cp = if (useSources) Some(compileClassPath.map(_.path).toArray) else None
val res = mill.scalalib.api.Util.grepJar(deps.map(_.path), bridgeName, bridgeVersion, useSources)
(cp, res)
useSources,
Some(overrideScalaLibrary(scalaVersion, scalaOrganization))
).map( deps =>
mill.scalalib.api.Util.grepJar(deps.map(_.path), bridgeName, bridgeVersion, useSources)
)

if (useSources) {
for {
jar <- bridgeJar
classpath <- compilerInterfaceClasspath(scalaVersion, scalaOrganization, repositories)
} yield (Some(classpath.map(_.path).toArray), jar)
} else {
bridgeJar.map((None, _))
}
}

def compilerInterfaceClasspath = T{
def compilerInterfaceClasspath(scalaVersion: String,
scalaOrganization: String,
repositories: Seq[Repository]) = {
resolveDependencies(
repositoriesTask(),
repositories,
Lib.depToDependency(_, "2.12.4", ""),
Seq(ivy"org.scala-sbt:compiler-interface:${Versions.zinc}"),
ctx = Some(implicitly[mill.util.Ctx.Log])
// Since Zinc 1.4.0, the compiler-interface depends on the Scala library
// We need to override it with the scalaVersion and scalaOrganization of the module
mapDependencies = Some(overrideScalaLibrary(scalaVersion, scalaOrganization))
)
}

def overrideScalaLibrary(scalaVersion: String, scalaOrganization: String)
(dep: coursier.Dependency): coursier.Dependency = {
if (dep.module.name.value == "scala-library") {
dep.withModule(dep.module.withOrganization(coursier.Organization(scalaOrganization)))
.withVersion(scalaVersion)
} else dep
}

override def prepareOffline(): Command[Unit] = T.command {
super.prepareOffline()
classpath()
compilerInterfaceClasspath()
// worker()
()
}

def prepareOfflineCompiler(scalaVersion: String, scalaOrganization: String): Command[Unit] = T.command {
classpath()
val cp = compilerInterfaceClasspath()
scalaCompilerBridgeJar(scalaVersion, scalaOrganization, cp, repositoriesTask())
scalaCompilerBridgeJar(scalaVersion, scalaOrganization, repositoriesTask())
()
}

Expand Down
70 changes: 50 additions & 20 deletions scalalib/worker/src/ZincWorkerImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@ package mill.scalalib.worker

import java.io.File
import java.util.Optional

import mill.api.Loose.Agg
import mill.api.{BuildProblemReporter, KeyedLockedCache, PathRef, Problem, ProblemPosition, Severity}
import mill.scalalib.api.Util.{grepJar, isDotty, isDottyOrScala3, isScala3, scalaBinaryVersion}
import mill.scalalib.api.{CompilationResult, ZincWorkerApi}
import sbt.internal.inc._
import sbt.internal.util.{ConsoleAppender, ConsoleOut}
import sbt.util.LogExchange
import xsbti.{PathBasedFile, VirtualFile}
import xsbti.compile.{CompilerCache => _, FileAnalysisStore => _, ScalaInstance => _, _}

import scala.ref.WeakReference

case class MockedLookup(am: File => Optional[CompileAnalysis]) extends PerClasspathEntryLookup {
override def analysis(classpathEntry: File): Optional[CompileAnalysis] =
case class MockedLookup(am: VirtualFile => Optional[CompileAnalysis]) extends PerClasspathEntryLookup {
override def analysis(classpathEntry: VirtualFile): Optional[CompileAnalysis] =
am(classpathEntry)

override def definesClass(classpathEntry: File): DefinesClass =
override def definesClass(classpathEntry: VirtualFile): DefinesClass =
Locate.definesClass(classpathEntry)
}

Expand Down Expand Up @@ -85,7 +85,8 @@ class ZincWorkerImpl(compilerBridge: Either[
// Zinc does not have an entry point for Java-only compilation, so we need
// to make up a dummy ScalaCompiler instance.
val scalac = ZincUtil.scalaCompiler(
new ScalaInstance("", null, null, dummyFile, dummyFile, new Array(0), Some("")), null,
new ScalaInstance("", null, null, dummyFile, dummyFile, new Array(0), Some("")),
dummyFile,
classpathOptions // this is used for javac too
)

Expand Down Expand Up @@ -133,7 +134,14 @@ class ZincWorkerImpl(compilerBridge: Either[
compilerJars: Array[File],
compilerBridgeClasspath: Array[os.Path],
compilerBridgeSourcesJar: os.Path): Unit = {
val compileLog = compileDest / "compile-log.txt"
if (scalaVersion == "2.12.0") {
// The Scala 2.10.0 compiler fails on compiling the compiler bridge
throw new IllegalArgumentException(
"The current version of Zinc is incompatible with Scala 2.12.0.\n" +
"Use Scala 2.12.1 or greater (2.12.12 is recommended)."
)
}

ctx0.log.info("Compiling compiler interface...")

os.makeDir.all(workingDir)
Expand All @@ -142,7 +150,14 @@ class ZincWorkerImpl(compilerBridge: Either[
val sourceFolder = mill.api.IO.unpackZip(compilerBridgeSourcesJar)(workingDir)
val classloader = mill.api.ClassLoader.create(compilerJars.map(_.toURI.toURL), null)(ctx0)

val sources = os.walk(sourceFolder.path).filter(a => a.ext == "scala" || a.ext == "java")
val (sources, resources) =
os.walk(sourceFolder.path).filter(os.isFile)
.partition(a => a.ext == "scala" || a.ext == "java")

resources.foreach { res =>
val dest = compileDest / res.relativeTo(sourceFolder.path)
os.move(res, dest, replaceExisting = true, createFolders = true)
}

val argsArray = Array[String](
"-d", compileDest.toString,
Expand Down Expand Up @@ -174,7 +189,7 @@ class ZincWorkerImpl(compilerBridge: Either[
compilerBridge match {
case Right(compiled) => compiled(scalaVersion)
case Left((ctx0, bridgeProvider)) =>
val workingDir = ctx0.dest / scalaVersion
val workingDir = ctx0.dest / s"zinc-${Versions.zinc}" / scalaVersion
val lock = synchronized(compilerBridgeLocks.getOrElseUpdate(scalaVersion, new Object()))
val compiledDest = workingDir / 'compiled
lock.synchronized{
Expand Down Expand Up @@ -423,9 +438,13 @@ class ZincWorkerImpl(compilerBridge: Either[
}
val analysisMap0 = upstreamCompileOutput.map(_.swap).toMap

def analysisMap(f: File): Optional[CompileAnalysis] = {
analysisMap0.get(os.Path(f)) match{
case Some(zincPath) => FileAnalysisStore.binary(zincPath.toIO).get().map[CompileAnalysis](_.getAnalysis)
def analysisMap(f: VirtualFile): Optional[CompileAnalysis] = {
val analysisFile = f match {
case pathBased: PathBasedFile => analysisMap0.get(os.Path(pathBased.toPath))
case _ => None
}
analysisFile match {
case Some(zincPath) => FileAnalysisStore.binary(zincPath.toIO).get().map(_.getAnalysis)
case None => Optional.empty[CompileAnalysis]
}
}
Expand All @@ -437,15 +456,21 @@ class ZincWorkerImpl(compilerBridge: Either[
if (compileToJar) ctx.dest / "classes.jar"
else ctx.dest / "classes"

val zincIOFile = zincFile.toIO
val classesIODir = classesDir.toIO
val store = FileAnalysisStore.binary(zincFile.toIO)

val store = FileAnalysisStore.binary(zincIOFile)
val converter = PlainVirtualFileConverter.converter
val classpath = (compileClasspath.iterator ++ Some(classesDir))
.map(path => converter.toVirtualFile(path.toNIO))
.toArray
val virtualSources = sources.iterator
.map(path => converter.toVirtualFile(path.toNIO))
.toArray

val inputs = ic.inputs(
classpath = classesIODir +: compileClasspath.map(_.toIO).toArray,
sources = sources.toArray.map(_.toIO),
classesDirectory = classesIODir,
classpath = classpath,
sources = virtualSources,
classesDirectory = classesDir.toNIO,
earlyJarPath = None,
scalacOptions = scalacOptions.toArray,
javacOptions = javacOptions.toArray,
maxErrors = 10,
Expand All @@ -455,18 +480,23 @@ class ZincWorkerImpl(compilerBridge: Either[
setup = ic.setup(
lookup,
skip = false,
zincIOFile,
zincFile.toNIO,
new FreshCompilerCache,
IncOptions.of(),
newReporter,
None,
None,
Array()
),
pr = {
val prev = store.get()
PreviousResult.of(prev.map(_.getAnalysis), prev.map(_.getMiniSetup))
PreviousResult.of(
prev.map(_.getAnalysis): Optional[CompileAnalysis],
prev.map(_.getMiniSetup): Optional[MiniSetup])
},
temporaryClassesDirectory = java.util.Optional.empty()
temporaryClassesDirectory = java.util.Optional.empty(),
converter = converter,
stampReader = Stamps.timeWrapBinaryStamps(converter)
)

try {
Expand Down