Skip to content

Commit

Permalink
Change the way of injecting javac temp dir to keep binary compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszwawrzyk committed Oct 1, 2018
1 parent b9caefd commit 9f833af
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 64 deletions.
8 changes: 1 addition & 7 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -164,13 +164,7 @@ lazy val zinc = (project in file("zinc"))
.configure(addBaseSettingsAndTestDeps)
.settings(
name := "zinc",
mimaSettings,
mimaBinaryIssueFilters ++= Seq(
exclude[DirectMissingMethodProblem]("sbt.internal.inc.MixedAnalyzingCompiler.searchClasspathAndLookup"),
exclude[IncompatibleResultTypeProblem]("sbt.internal.inc.MixedAnalyzingCompiler.javac"),
exclude[IncompatibleMethTypeProblem]("sbt.internal.inc.MixedAnalyzingCompiler.this"),

)
mimaSettings
)

lazy val zincTesting = (project in internalPath / "zinc-testing")
Expand Down
32 changes: 16 additions & 16 deletions internal/compiler-bridge/src/main/scala/xsbt/STJ.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ final class STJ(outputDirs: Iterable[File]) {
type RelClass = String

/** Creates an identifier for a class located inside a jar.
* For plain class files it is enough to simply use the path.
* A class in jar `JaredClass` is identified as a path to jar
* and path to the class within that jar. Those two values
* are held in one string separated by `!`. Slashes in both
* paths are consistent with `File.separatorChar` as the actual
* string is usually kept in `File` object.
*
* As an example given a jar file "C:\develop\zinc\target\output.jar"
* and relative path to the class "sbt/internal/inc/Compile.class"
* The resulting identifier would be:
* "C:\develop\zinc\target\output.jar!sbt\internal\inc\Compile.class"
*
* @param jar jar file that contains the class
* @param cls relative path to the class within the jar
* @return identifier/path to a class in jar.
*/
* For plain class files it is enough to simply use the path.
* A class in jar `JaredClass` is identified as a path to jar
* and path to the class within that jar. Those two values
* are held in one string separated by `!`. Slashes in both
* paths are consistent with `File.separatorChar` as the actual
* string is usually kept in `File` object.
*
* As an example given a jar file "C:\develop\zinc\target\output.jar"
* and relative path to the class "sbt/internal/inc/Compile.class"
* The resulting identifier would be:
* "C:\develop\zinc\target\output.jar!sbt\internal\inc\Compile.class"
*
* @param jar jar file that contains the class
* @param cls relative path to the class within the jar
* @return identifier/path to a class in jar.
*/
def jaredClass(jar: File, cls: RelClass): JaredClass = {
// This identifier will be stored as a java.io.File. Its constructor will normalize slashes
// which means that the identifier to be consistent should at all points have consistent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ case class ProjectStructure(
scalaVersion: String
) extends BridgeProviderSpecification {

val useStraightToJar = false
val useStraightToJar = true

val compiler = new IncrementalCompilerImpl
val maxErrors = 100
Expand Down
83 changes: 43 additions & 40 deletions zinc/src/main/scala/sbt/internal/inc/MixedAnalyzingCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import xsbti.compile.{ ClassFileManager => XClassFileManager }
/** An instance of an analyzing compiler that can run both javac + scalac. */
final class MixedAnalyzingCompiler(
val scalac: xsbti.compile.ScalaCompiler,
val javac: (Seq[File] => Seq[File]) => AnalyzingJavaCompiler,
val javac: AnalyzingJavaCompiler,
val config: CompileConfiguration,
val log: Logger
) {
Expand Down Expand Up @@ -105,27 +105,26 @@ final class MixedAnalyzingCompiler(
case Some(outputJar) =>
val outputDir = STJ.javacOutputTempDir(outputJar)
IO.createDirectory(outputDir)
val compiler = javac(originalCp => outputDir +: originalCp)
compiler.compile(javaSrcs,
joptions,
CompileOutput(outputDir),
Some(outputJar),
callback,
incToolOptions,
config.reporter,
log,
config.progress)
javac.compile(javaSrcs,
joptions,
CompileOutput(outputDir),
Some(outputJar),
callback,
incToolOptions,
config.reporter,
log,
config.progress)
putJavacOutputInJar(outputJar, outputDir)
case None =>
javac(identity).compile(javaSrcs,
joptions,
output,
finalJarOutput = None,
callback,
incToolOptions,
config.reporter,
log,
config.progress)
javac.compile(javaSrcs,
joptions,
output,
finalJarOutput = None,
callback,
incToolOptions,
config.reporter,
log,
config.progress)
}
}
}
Expand Down Expand Up @@ -298,42 +297,46 @@ object MixedAnalyzingCompiler {

/** Returns the search classpath (for dependencies) and a function which can also do so. */
def searchClasspathAndLookup(
config: CompileConfiguration,
classpath: Seq[File]
config: CompileConfiguration
): (Seq[File], String => Option[File]) = {
import config._
import currentSetup._
// If we are compiling straight to jar, javac does not have this option
// it will be compiled to a temporary directory (with deterministic name)
// and then added to the final jar. This temporary directory has to be
// available for Analyze to work phase to work.
val tempJavacOutput = STJ.getOutputJar(currentSetup.output).map(STJ.javacOutputTempDir).toSeq
val absClasspath = classpath.map(_.getAbsoluteFile)
val cArgs =
new CompilerArguments(config.compiler.scalaInstance, config.compiler.classpathOptions)
val searchClasspath = explicitBootClasspath(config.currentSetup.options.scalacOptions) ++ withBootclasspath(
new CompilerArguments(compiler.scalaInstance, compiler.classpathOptions)
val searchClasspath = explicitBootClasspath(options.scalacOptions) ++ withBootclasspath(
cArgs,
absClasspath
)
(searchClasspath, Locate.entry(searchClasspath, config.perClasspathEntryLookup))
) ++ tempJavacOutput
(searchClasspath, Locate.entry(searchClasspath, perClasspathEntryLookup))
}

/** Returns a "lookup file for a given class name" function. */
def classPathLookup(config: CompileConfiguration): String => Option[File] =
searchClasspathAndLookup(config, config.classpath)._2
searchClasspathAndLookup(config)._2

def apply(config: CompileConfiguration)(
implicit log: Logger
): MixedAnalyzingCompiler = {
import config._
val (searchClasspath, entry) = searchClasspathAndLookup(config)
// Construct a compiler which can handle both java and scala sources.
new MixedAnalyzingCompiler(
config.compiler,
compiler,
// TODO - Construction of analyzing Java compiler MAYBE should be earlier...
(modifyClasspath: Seq[File] => Seq[File]) => {
val newCp = modifyClasspath(config.classpath)
val (searchClasspath, entry) = searchClasspathAndLookup(config, newCp)
new AnalyzingJavaCompiler(
config.javac,
newCp,
config.compiler.scalaInstance,
config.compiler.classpathOptions,
entry,
searchClasspath
)
},
new AnalyzingJavaCompiler(
javac,
classpath,
compiler.scalaInstance,
compiler.classpathOptions,
entry,
searchClasspath
),
config,
log
)
Expand Down

0 comments on commit 9f833af

Please sign in to comment.