mirror of
https://github.com/enso-org/enso.git
synced 2024-11-22 22:10:15 +03:00
9182f91e35
* Use moduleDependencies instead of modulePath * Fix compilation of editions * Fix compilation of distribution-manager * polyglot-api needs to explicitly compile module-info * Fix compilationOrder in library-manager and edition-updater * engine-runner-common is module * JPMSPlugin provides default implementation of compileModuleInfo * Remove unused setting key from JPMSUtils.compileModuleInfo * JPMSPlugin has internalModuleDependencies and exportedModule tasks. * Use BuildVersion instead of buildInfo * Manual compilation of module-info.java is reported as warning * Define org.enso.scalalibs.wrapper meta project. * Fix module check in JPMSPlugin. This is a fix for projects that declare `Compile /exportJars := true` * version-output is a module * ydoc-server uses internalModuleDependencies * persistance is module * engine-common uses internalModuleDependencies * polyglot-api does not override compileModuleInfo task * runtime-parser uses internalModuleDependencies * edition-updater is module * Update moduleDependencies for distribution-manager * editions is module * Fix some dependencies of modules * scala-yaml is a module * Add scala-compiler to scala-libs-wrapper * cli depends on scala-library module * Add dependencies for distribution-manager module * Add some scala-library dependencies in some modules * engine-runner uses internalModuleDependencies * Fix module dependencies of library-manager * Rename org.enso.scalalibs.wrapper to org.enso.scala.wrapper * Add jsoniter-scala-macros to org.enso.scala.wrapper fat module * Fix dependencies of some projects * polyglot-api does not depend on truffle-api * Fix dependencies of some projects * runtime does not use com.google.common * runtime is a module * text-buffer is a module * refactoring-utils is a module * runtime-compiler is a module * runtime-instrument-common is a module * connected-lock-manager is a module * JPMSUtils reports project name in some error messages * Modularize some instruments * module-info compilation is cached * runtime-instrument-runtime-server is module * runtime-language-epb is module * Remove runtime-fat-jar * engine-runner is not a fat jar * JPMSPlugin defines exportedModuleBin task * Redefine componentModulesPaths task * interpreter-dsl is module * Redefine componentModulesPaths task * fmt sbt * scala-libs-wrapper is a modular fat jar * Add some module deps to org.enso.runtime * engine-runner is not a fat jar * Rename package in logging-config * Rename package in logging-service * Rename package in logging-service-logback * Fix dependencies of exportedModuleBin task * Mixed projects have own compileJava task this task does not compile only module-info.java but all the java sources. So that we can see errors more easily. When only module-info.java is compiled, the only errors that we can see are that we did not include some modules on module-path. * Fix definition of exportedModule task. * Remove usages of non-existing buildInfo and replace it with BuildVersion * Fix some dependencies of org.enso.runtime module * module-info compilation is handled directly by FrgaalCompiler * module-info compilation is forced for projects that has only Scala sources with single module-info.java * Fix compilation of org.enso.runtime * manual module-info compilation is not a warning * Rename packages in logging-utils-akka * Create org.enso.language.server.deps.wrapper module * language-server is module * Creat akka-wrapper modular fat jar * fmt * Define common settings for modularFatJarWrapper * Fix compilation of json-rpc-server * Use akka and zio wrappers * language-server depends on org.eclipse.jgit * Fix some dependencies - update library manifests works now! * update library manifests invokes runner directly * buildEngineDistribution does not copy runner.jar * Remove EngineRunnerBootLoader * Fix compilation of std libs * --patch-module and --add-exports are also passed to javac * Rename package in runtime-integration-tests. The package name org.enso.compiler clashes with the package from the module * Remove usage of buildInfo * FrgaalJavaCompiler can deal with non-existing module-info.java when shouldCompileModuleInfo is true. It just generates a warning in such case as it suggests that there is something wrong with the project configuration. * Revert AliasAnalysisTest.scala * Fix dependencies and java cmdline options for runtime-integration-tests * Rename test package * runtime-integration-test depends on logging-service-logback/Test/compile * Rename package in logging-service-logback/Test * Fix FrgaalJavaCompiler creation for projects * Sanitize Test/javaOptions arguments * Sanitize Test/javaOptions arguments * All the JPMSPlugin settings are scoped * Remove unused sbt tasks * modularFatJarWrapperSettings do not override javacOptions * Resolve issue "Cannot find TestLoggerProvider" in runtime-integration-tests * org.enso.runtime module is open * Test that test classes are unconditionally opened and exported * polyglot-api-macros is a module * JPMSPlugin handles --add-opens cmdline option * RuntimeServerTest ensures instruments are initialized * Add some exports to org.enso.runtime.compiler * Add instruments on module-path to runtime-integration-tests * Replace TestLogProviderOnClassPath with TestLogProviderOnModulePath * Replace buildInfo with BuildVersion * Add jpms-wrapper-scalatest * ReportLogsOnFailure is in non-modular testkit project * Add necessary dependencies to testkit project * Revert "Add jpms-wrapper-scalatest" This reverts commit732b3427a2
. * modularize filewatcher and wrap its dependencies * Initial fix for language-server/test * frgaal compiler setting are scoped for Compile and Test * Rename package in language-server/test * Exclude com.sun.jna from wrapper jars * Rename package in library-manager-test * testkit is an automatic module * process-utils is module * akka-wrapper contains akka-http * Some fixes for library-manager-test * Fix dependencies for akka-wrapper * scala-libs-wrapper exports shapeless * lang server deps wrapper exports pureconfig * json-rpc-server requires org.slf4j * Add some dependencies * lang server deps wrapper exports pureconfig.generic * language server test requires bouncycastle provider * language server depends on cli * directory-watcher wrapper requires org.slf4j * WatcherAdapter logs unsuccessful initialization errors * Fix error reporting in WatcherAdapter * Fix rest of the language-server tests * language-server-deps-wrapper depends on scala-libs-wrapper * Fix rest of the language-server tests * Missing module-info.class in an internal project is a warning, not an error * Rename jpms-methvin-directory-watcher-wrapper to a simpler name * compileOrder has to be specified before libraryDependencies * exclude module-info.java from polyglot-api-macros * Remove temporary logging in customFrgaalCompilerSettings * Fix compilation of logging-service-logback * Fix compilation of runtime-benchmarks * Fix runtime-benchmarks/run * HostClassLoader delegates to org.graalvm.polyglot class loader if org.enso.runtime is not on boot layer * org.enso.runtime.lnaguage.epb module must be opened to allow it to be used by annnotation processor * fmt * Fix afetr merge * Add module deps after merge * Print stack trace of the uncaught exception from the annotation processor * Remove akka-actor-typed from akka-wrapper * runtime-instrument-common depends on slf4j * Fix module-path for runtime-instrument-repl-debugger * runtime-benchmarks depends on runtime-language-arrow * --module-path is passed directly to frgaal * Fix some module-related cmd line options for std-benchmarks * Revert "--module-path is passed directly to frgaal" This reverts commitda63f66a0e
. * Avoid closing of System.err when closing Context * Avoid processing altogether when requested annotations are empty * Pass shouldNotLimitModules opt to frgaal * Pass module-path and add-modules options with -J prefix to frgaal * BenchProcessor annotation processor creates its own truffle module layer * bench-processor and benchmarks-common are modules * fmt * Fix after mege * Enable JMH annotation processor * Fix compileOrder in some projects * Insert TruffleBoundary to QualifiedName. This is a revert * Fix building of engine-runner native image * Add more deps to the native image * Force module-info compilation in instruments. This fixes some weird sbt bug * Don't run engine-runner/assembly from Rust build script * Update docs of JPMSPlugin * fmt * runtime-benchmarks depends on benchmarks-common module * Fix benchmark report writing * std-benchmarks annot processing does not take settings from runtime-benchmarks * Suppress interpreter only warning in annotation processor * Runtime version manager does not expect runtime.jar fat jar * fmt * Fix module entry point * Move some polyglot tests to runtime-integration-tests. Also make their output silent * pkg has no dependency on org.graalvm.truffle * Fix compiler dependencies test * Rename all runtime.jar in fake releases * Add language-server with dependencies to component dir * No module-info.class in target dir is warning not error * language-server does not depend on netbeans lookup uitl * Declare LanguageServerApi service provider in module-info * connected-lock-manager-server is JPMS module * task-progress-notifications is module * Add fansi-wrapper module * Fix compilation of connected-lock-manager-server * Define correct Test/internalModuleDependencies for project-manager * fmt * Fix LauncherRunnerSpec - no runtime.jar * Add fansi-wrapper to runtime-integration-tests and runtime-benchmarks * Fix engine-runner native image build * Use newer JNA version - fixes running of hyperd * DRY * scala-compiler DRY * fmt * More build.sbt refactoring * Include runtime-instrument-id-execution in engine-runner native image * TruffleBoundary for QualifiedName.toString * Finding a needle in a haystack 🤦 * More scala-library DRY * more mixed-java/scala goodies * Fix compilation of syntax-rust-definition * Test that engine-runner does not depend on language-server * Append rather than assign `moduleDependencies` `++=` is less error prone than `:=`. Also discovered some unnecessary dependencies. * Replace : with File.pathSeparator * [WIP] Make logging in ProjectService more verbose * language-server/test didn't start because of missing lookup and fansi modules * Formatting * org.enso.cli.task.notifications needs Akka and Circe to link * project-manager/test depends on buildEngineDistribution * [WIP] Even more verbose logging for creating projects * [WIP] Even more verbose logging for creating projects * Revert "[WIP] Even more verbose logging for creating projects" This reverts commita7067c8472
. * Revert "[WIP] Even more verbose logging for creating projects" This reverts commitfc6f53d4f1
. * Revert "[WIP] Make logging in ProjectService more verbose" This reverts commit427428e142
. * All the project with JPMSPlugin has stripped artifact names * Revert all placeholder fake release components to runtime.jar without version * Eliminate a cross version hack We shouldn't be specifying Scala dependencies with a Scala cross version in the suffix. * Address SBT lint warnings * Revert "Eliminate a cross version hack" This reverts commit8861dab288
. * logging-service-logback is mixedJavaScalaProject * fmt * Stripped artifact name contains classifier. This fixes tests as those were named like `artifact-tests.jar`. * Don't use LocalProject unless really needed * Add more logging when BenchProcessor fails * logging-service-logback is not mixed project * Work with java.io.File.getPath to avoid mixing slash and backslash on Windows * Reapply "Eliminate a cross version hack" This reverts commitedaa436ee8
. * Pass scalaBinaryVersion correctly * Remove scala-compiler from the distribution * Fix IllegalAccessErrors from serde * typos * License review * fmt * Move testLogProviderOnModulePath to TestJPMSConfiguration * logging-service-logback is not a mixed project --------- Co-authored-by: Jaroslav Tulach <jaroslav.tulach@enso.org> Co-authored-by: Hubert Plociniczak <hubert.plociniczak@gmail.com>
400 lines
13 KiB
Scala
400 lines
13 KiB
Scala
/*
|
|
* The FrgaalJavaCompiler adapts ForkedJava from Zinc
|
|
* to invoke Frgaal compiler instead of javac.
|
|
*
|
|
* Zinc - The incremental compiler for Scala.
|
|
* Copyright Lightbend, Inc. and Mark Harrah
|
|
*
|
|
* Licensed under Apache License 2.0
|
|
* (http://www.apache.org/licenses/LICENSE-2.0).
|
|
*/
|
|
|
|
import sbt._
|
|
import sbt.internal.inc.CompilerArguments
|
|
import sbt.internal.inc.javac.JavacLogger
|
|
import sbt.io.IO
|
|
import sbt.util.Logger
|
|
import xsbti.{PathBasedFile, Reporter, VirtualFile, Logger => XLogger}
|
|
import xsbti.compile.{IncToolOptions, Output, JavaCompiler => XJavaCompiler}
|
|
|
|
import java.io.File
|
|
import java.nio.file.{Path, Paths}
|
|
import scala.sys.process.Process
|
|
import scala.util.Using
|
|
import java.io.FileWriter
|
|
import xsbti.Severity
|
|
import xsbti.Position
|
|
|
|
object FrgaalJavaCompiler {
|
|
private val ENSO_SOURCES = ".enso-sources"
|
|
|
|
val frgaal = "org.frgaal" % "compiler" % "21.0.0" % "provided"
|
|
val sourceLevel = "21"
|
|
|
|
val debugArg =
|
|
"-J-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=localhost:8000"
|
|
|
|
/** Returns custom setting for compiler that delegates to `Frgaal`.
|
|
* @param classpath The dependencyClasspath of the current project
|
|
* @param sbtCompilers Configuration for compilers for current sbt project
|
|
* @param javaVersion Target Java version
|
|
* @param shouldCompileModuleInfo If true, module-info.java will be compiled
|
|
* in addition to other Java sources. See the docs
|
|
* of `shouldCompileModuleInfo` task in `build.sbt` and
|
|
* the docs of [[JPMSPlugin]].
|
|
* @param javaSourceDir The directory where Java sources are located
|
|
* @param shouldNotLimitModules Should `--limit-modules` cmdline option be passed to java process
|
|
* to limit set of modules frgaal is able to see?
|
|
* @return
|
|
*/
|
|
def compilers(
|
|
classpath: sbt.Keys.Classpath,
|
|
sbtCompilers: xsbti.compile.Compilers,
|
|
javaVersion: String,
|
|
shouldCompileModuleInfo: Boolean,
|
|
javaSourceDir: File,
|
|
shouldNotLimitModules: Boolean
|
|
) = {
|
|
// Enable Java 11+ features by invoking Frgaal instead of regular javac
|
|
val javaHome = Option(System.getProperty("java.home")).map(Paths.get(_))
|
|
|
|
// Locate frgaal compiler jar from the list of dependencies
|
|
val frgaalModule = FrgaalJavaCompiler.frgaal
|
|
val frgaalCheck = (module: ModuleID) =>
|
|
module.organization == frgaalModule.organization &&
|
|
module.name == frgaalModule.name &&
|
|
module.revision == frgaalModule.revision
|
|
val frgaalOnClasspath =
|
|
classpath
|
|
.find(f =>
|
|
f.metadata
|
|
.get(AttributeKey[ModuleID]("moduleID"))
|
|
.map(frgaalCheck)
|
|
.getOrElse(false)
|
|
)
|
|
.map(_.data.toPath)
|
|
if (frgaalOnClasspath.isEmpty) {
|
|
throw new RuntimeException("Failed to resolve Frgaal compiler. Aborting!")
|
|
}
|
|
val frgaalJavac = new FrgaalJavaCompiler(
|
|
javaHome,
|
|
frgaalOnClasspath.get,
|
|
javaSourceDir = javaSourceDir,
|
|
target = javaVersion,
|
|
shouldCompileModuleInfo = shouldCompileModuleInfo,
|
|
shouldNotLimitModules = shouldNotLimitModules
|
|
)
|
|
val javaTools = sbt.internal.inc.javac
|
|
.JavaTools(frgaalJavac, sbtCompilers.javaTools.javadoc())
|
|
xsbti.compile.Compilers.of(sbtCompilers.scalac, javaTools)
|
|
}
|
|
|
|
/** Helper method to launch programs.
|
|
*/
|
|
def launch(
|
|
javaHome: Option[Path],
|
|
compilerJar: Path,
|
|
sources0: Seq[VirtualFile],
|
|
options: Seq[String],
|
|
output: Output,
|
|
log: Logger,
|
|
reporter: Reporter,
|
|
source: Option[String],
|
|
target: String,
|
|
shouldCompileModuleInfo: Boolean,
|
|
javaSourceDir: File,
|
|
shouldNotLimitModules: Boolean
|
|
): Boolean = {
|
|
val (jArgs, nonJArgs) = options.partition(_.startsWith("-J"))
|
|
val debugAnotProcessorOpt = jArgs.contains(debugArg)
|
|
val strippedJArgs = jArgs
|
|
.map(_.stripPrefix("-J"))
|
|
val outputOption = CompilerArguments.outputOption(output)
|
|
val sources = sources0 map { case x: PathBasedFile =>
|
|
x.toPath.toAbsolutePath.toString
|
|
}
|
|
|
|
def asPath(a: Any): Path = a match {
|
|
case p: PathBasedFile => p.toPath
|
|
case p: Path => p
|
|
}
|
|
|
|
def asCommon(a: Any, b: Any): Path = {
|
|
var ap = asPath(a)
|
|
val bp = asPath(b)
|
|
|
|
var i = 0
|
|
while (
|
|
i < Math.min(ap.getNameCount(), bp.getNameCount()) && ap.getName(
|
|
i
|
|
) == bp.getName(i)
|
|
) {
|
|
i += 1;
|
|
}
|
|
|
|
while (ap.getNameCount() > i) {
|
|
ap = ap.getParent()
|
|
}
|
|
ap
|
|
}
|
|
|
|
val out = output.getSingleOutputAsPath().get()
|
|
val shared = sources0.fold(out)(asCommon).asInstanceOf[Path]
|
|
|
|
val allSources = if (shouldCompileModuleInfo) {
|
|
val moduleInfo = javaSourceDir.toPath.resolve("module-info.java").toFile
|
|
if (!moduleInfo.exists()) {
|
|
log.warn(
|
|
s"[FrgaalJavaCompiler] module-info.java not found in $javaSourceDir, but " +
|
|
"settings of the project require to compile it. Ensure that the setting of " +
|
|
"`shouldCompileModuleInfoManually` is correctly set."
|
|
)
|
|
log.info(
|
|
s"[FrgaalJavaCompiler] compiling ${sources.size} Java sources to $out ..."
|
|
)
|
|
sources
|
|
} else {
|
|
log.info(
|
|
s"[FrgaalJavaCompiler] compiling ${sources.size + 1} Java sources with module-info.java to $out ..."
|
|
)
|
|
Seq(moduleInfo.getAbsolutePath) ++ sources
|
|
}
|
|
} else {
|
|
log.info(
|
|
s"[FrgaalJavaCompiler] compiling ${sources.size} Java sources to $out ..."
|
|
)
|
|
sources
|
|
}
|
|
|
|
// searching for $shared/src/main/java or
|
|
// $shared/src/test/java or
|
|
// $shared/src/bench/java or etc.
|
|
def findUnder(depth: Int, dir: Path): Path = {
|
|
var d = dir
|
|
while (d.getNameCount() > depth) {
|
|
val threeUp = d.subpath(0, d.getNameCount() - depth)
|
|
val relShare = shared.subpath(0, shared.getNameCount())
|
|
if (relShare.equals(threeUp)) {
|
|
return d
|
|
} else {
|
|
d = d.getParent()
|
|
}
|
|
}
|
|
throw new IllegalArgumentException(
|
|
"Cannot findUnder for " + dir + " and " + shared +
|
|
"\nout: " + out + "\nsources: " + sources
|
|
)
|
|
}
|
|
def checkTarget(x: Any) = {
|
|
val p = asPath(x)
|
|
val namesCheck =
|
|
for (i <- 0 until p.getNameCount)
|
|
yield "target".equals(p.getName(i).toString()) || p
|
|
.getName(i)
|
|
.toString()
|
|
.endsWith("-windows") || p.getName(i).toString().endsWith("-unix")
|
|
val inATargetDir = namesCheck.exists(x => x)
|
|
inATargetDir
|
|
}
|
|
|
|
val (withTarget, noTarget) = sources0.partition(checkTarget)
|
|
val in = if (noTarget.isEmpty) {
|
|
None
|
|
} else {
|
|
Some(
|
|
findUnder(
|
|
1,
|
|
noTarget.tail.fold(asPath(noTarget.head))(asCommon).asInstanceOf[Path]
|
|
)
|
|
)
|
|
}
|
|
val generated = if (withTarget.isEmpty) {
|
|
None
|
|
} else {
|
|
Some(
|
|
findUnder(
|
|
4,
|
|
withTarget.tail
|
|
.fold(asPath(withTarget.head))(asCommon)
|
|
.asInstanceOf[Path]
|
|
)
|
|
)
|
|
}
|
|
|
|
if (shared.toFile().exists()) {
|
|
val ensoMarker = new File(shared.toFile(), ENSO_SOURCES)
|
|
val ensoConfig = new File(
|
|
shared.toFile(),
|
|
ENSO_SOURCES + "-" + out.getFileName().toString()
|
|
)
|
|
val ensoProperties = new java.util.Properties()
|
|
|
|
def storeArray(name: String, values: Seq[String]) = {
|
|
values.zipWithIndex.foreach { case (value, idx) =>
|
|
ensoProperties.setProperty(s"$name.$idx", value)
|
|
}
|
|
}
|
|
if (in.isDefined) {
|
|
ensoProperties.setProperty("input", in.get.toString())
|
|
}
|
|
if (generated.isDefined) {
|
|
ensoProperties.setProperty("generated", generated.get.toString())
|
|
}
|
|
ensoProperties.setProperty("output", out.toString())
|
|
storeArray("options", options)
|
|
source.foreach(v => ensoProperties.setProperty("source", v))
|
|
ensoProperties.setProperty("target", target)
|
|
javaHome.foreach(v =>
|
|
ensoProperties.setProperty("java.home", v.toString())
|
|
)
|
|
|
|
Using(new FileWriter(ensoConfig)) { w =>
|
|
ensoProperties.store(w, "# Enso compiler configuration")
|
|
}
|
|
Using(new FileWriter(ensoMarker)) { _ => }
|
|
} else {
|
|
throw new IllegalStateException(
|
|
"Cannot write Enso source options to " + shared + " values:\n" +
|
|
"options: " + options + " sources0: " + sources + " output: " + output
|
|
)
|
|
}
|
|
|
|
val frgaalOptions: Seq[String] =
|
|
source.map(v => Seq("-source", v)).getOrElse(Seq()) ++ Seq(
|
|
"-target",
|
|
target
|
|
)
|
|
val allArguments = outputOption ++ frgaalOptions ++ nonJArgs ++ allSources
|
|
|
|
withArgumentFile(allArguments) { argsFile =>
|
|
// List of modules that Frgaal can use for compilation
|
|
val limitModules = Seq(
|
|
"java.base",
|
|
"jdk.zipfs",
|
|
"jdk.internal.vm.compiler.management",
|
|
"java.desktop",
|
|
"java.net.http",
|
|
"java.sql",
|
|
"jdk.jfr"
|
|
)
|
|
val limitModulesArgs =
|
|
if (shouldNotLimitModules) Seq()
|
|
else
|
|
Seq(
|
|
"--limit-modules",
|
|
limitModules.mkString(",")
|
|
)
|
|
// strippedJArgs needs to be passed via cmd line, and not via the argument file
|
|
val forkArgs = (strippedJArgs ++ limitModulesArgs ++ Seq(
|
|
"-jar",
|
|
compilerJar.toString
|
|
)) :+
|
|
s"@${normalizeSlash(argsFile.getAbsolutePath)}"
|
|
val exe = getJavaExecutable(javaHome, "java")
|
|
val cwd = new File(new File(".").getAbsolutePath).getCanonicalFile
|
|
val javacLogger = new JavacLogger(log, reporter, cwd)
|
|
var exitCode = -1
|
|
if (debugAnotProcessorOpt) {
|
|
log.info(
|
|
s"Frgaal compiler is about to be launched with $debugArg, which means that" +
|
|
" it will wait for a debugger to attach. The output from the compiler is by default" +
|
|
" redirected, therefore \"Listening to the debugger\" message will not be displayed." +
|
|
" You should attach the debugger now."
|
|
)
|
|
}
|
|
log.debug("[frgaal] Running " + (exe +: forkArgs).mkString(" "))
|
|
try {
|
|
exitCode = Process(exe +: forkArgs, cwd) ! javacLogger
|
|
} finally {
|
|
javacLogger.flush("frgaal", exitCode)
|
|
}
|
|
if (exitCode != 0) {
|
|
class FrgaalPosition extends xsbti.Position {
|
|
def line(): java.util.Optional[Integer] = java.util.Optional.empty()
|
|
def lineContent() = "Frgaal errors"
|
|
def offset(): java.util.Optional[Integer] = java.util.Optional.empty()
|
|
def pointer(): java.util.Optional[Integer] =
|
|
java.util.Optional.empty()
|
|
def pointerSpace(): java.util.Optional[String] =
|
|
java.util.Optional.empty()
|
|
def sourceFile(): java.util.Optional[java.io.File] =
|
|
java.util.Optional.empty()
|
|
def sourcePath(): java.util.Optional[String] =
|
|
java.util.Optional.empty()
|
|
}
|
|
|
|
class FrgaalProblem extends xsbti.Problem {
|
|
def category() = "Compiler error"
|
|
def severity(): Severity = Severity.Error
|
|
def message() = "Error in frgaal compilation"
|
|
def position(): Position = new FrgaalPosition()
|
|
}
|
|
reporter.log(new FrgaalProblem())
|
|
}
|
|
// We return true or false, depending on success.
|
|
exitCode == 0
|
|
}
|
|
}
|
|
|
|
/** Helper method to create an argument file that we pass to Javac. Gets over the windows
|
|
* command line length limitation.
|
|
* @param args The string arguments to pass to Javac.
|
|
* @param f A function which is passed the arg file.
|
|
* @tparam T The return type.
|
|
* @return The result of using the argument file.
|
|
*/
|
|
def withArgumentFile[T](args: Seq[String])(f: File => T): T = {
|
|
import IO.{withTemporaryDirectory, write, Newline}
|
|
withTemporaryDirectory { tmp =>
|
|
val argFile = new File(tmp, "argfile")
|
|
write(argFile, args.map(escapeSpaces).mkString(Newline))
|
|
f(argFile)
|
|
}
|
|
}
|
|
// javac's argument file seems to allow naive space escaping with quotes. escaping a quote with a backslash does not work
|
|
private def escapeSpaces(s: String): String = '\"' + normalizeSlash(s) + '\"'
|
|
private def normalizeSlash(s: String) = s.replace(File.separatorChar, '/')
|
|
|
|
/** create the executable name for java */
|
|
def getJavaExecutable(javaHome: Option[Path], name: String): String =
|
|
javaHome match {
|
|
case None => name
|
|
case Some(jh) =>
|
|
jh.resolve("bin").resolve(name).toAbsolutePath.toString
|
|
}
|
|
}
|
|
|
|
/** An implementation of compiling java which forks Frgaal instance. */
|
|
final class FrgaalJavaCompiler(
|
|
javaHome: Option[Path],
|
|
compilerPath: Path,
|
|
target: String,
|
|
javaSourceDir: File,
|
|
source: Option[String] = None,
|
|
shouldCompileModuleInfo: Boolean = false,
|
|
shouldNotLimitModules: Boolean = false
|
|
) extends XJavaCompiler {
|
|
def run(
|
|
sources: Array[VirtualFile],
|
|
options: Array[String],
|
|
output: Output,
|
|
incToolOptions: IncToolOptions,
|
|
reporter: Reporter,
|
|
log: XLogger
|
|
): Boolean =
|
|
FrgaalJavaCompiler.launch(
|
|
javaHome,
|
|
compilerPath,
|
|
sources,
|
|
options,
|
|
output,
|
|
log,
|
|
reporter,
|
|
source,
|
|
target,
|
|
shouldCompileModuleInfo,
|
|
javaSourceDir,
|
|
shouldNotLimitModules
|
|
)
|
|
}
|