From 3138bdedd25f15ce2f2dd9c6faa2d349c6139aba Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Thu, 14 Feb 2019 13:50:34 +0100 Subject: [PATCH] Fix cache invalidation of compiler instance In #5835 I changed the scalaInstance used for bootstrapped projects to use class directories instead of jars for the local dependencies, but this breaks the cache invalidation mechanism used by sbt to decide whether to keep using the same compiler instance or not, in particular this means that running: > dotty-library-bootstrapped/compile Then if we edit code in the compiler, we expect the next call to `dotty-library-bootstrapped/compile` to use the new compiler, but it kept using the original one since the cache wasn't invalidated. --- project/Build.scala | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index b6e79623743c..dcbcfac16ac6 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -227,28 +227,33 @@ object Build { // Compile using the non-bootstrapped and non-published dotty managedScalaInstance := false, scalaInstance := { - // TODO: Here we use the output class directories directly, this might impact - // performance when running the compiler (especially on Windows where file - // IO is slow). We should benchmark whether using jars is actually faster - // in practice (especially on our CI), this could be done using - // `exportJars := true`. - val all = fullClasspath.in(`dotty-doc`, Compile).value - def getArtifact(name: String): File = - all.find(_.get(artifact.key).exists(_.name == name)) - .getOrElse(throw new MessageOnlyException(s"Artifact for $name not found in $all")) + val externalDeps = externalDependencyClasspath.in(`dotty-doc`, Compile).value + def getExternalDep(name: String): File = + externalDeps.find(_.get(artifact.key).exists(_.name == name)) + .getOrElse(throw new MessageOnlyException(s"Artifact for $name not found in $externalDeps")) .data - val scalaLibrary = getArtifact("scala-library") - val dottyLibrary = getArtifact("dotty-library") - val compiler = getArtifact("dotty-compiler") + val scalaLibrary = getExternalDep("scala-library") + + // IMPORTANT: We need to use actual jars to form the ScalaInstance and not + // just directories containing classfiles because sbt maintains a cache of + // compiler instances. This cache is invalidated based on timestamps + // however this is only implemented on jars, directories are never + // invalidated. + val dottyLibrary = packageBin.in(`dotty-library`, Compile).value + val dottyInterfaces = packageBin.in(`dotty-interfaces`, Compile).value + val dottyCompiler = packageBin.in(`dotty-compiler`, Compile).value + val dottyDoc = packageBin.in(`dotty-doc`, Compile).value + + val allJars = Seq(dottyLibrary, dottyInterfaces, dottyCompiler, dottyDoc) ++ externalDeps.map(_.data) makeScalaInstance( state.value, scalaVersion.value, scalaLibrary, dottyLibrary, - compiler, - all.map(_.data) + dottyCompiler, + allJars ) } )