sbt_inc.SbtIncrementalCompiler Maven / Gradle / Ivy
package sbt_inc;
import com.typesafe.zinc.Compiler;
import com.typesafe.zinc.*;
import org.apache.maven.plugin.logging.Log;
import scala.Option;
import scala_maven_executions.MainHelper;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class SbtIncrementalCompiler {
public static final String SBT_GROUP_ID = "com.typesafe.sbt";
public static final String COMPILER_INTEGRATION_ARTIFACT_ID = "incremental-compiler";
public static final String COMPILER_INTERFACE_ARTIFACT_ID = "compiler-interface";
public static final String COMPILER_INTERFACE_CLASSIFIER = "sources";
public static final String XSBTI_ARTIFACT_ID = "sbt-interface";
private static final String ANALYSIS_MAP_ARG_SEPARATOR = ",";
private static final String ANALYSIS_MAP_PAIR_SEPARATOR = File.pathSeparator;
private Log log;
private ZincClient zinc;
private boolean useServer = false;
private File compilerJar;
private File libraryJar;
private List extraJars;
private List extraArgs;
private xsbti.Logger logger;
private Compiler compiler;
public SbtIncrementalCompiler(boolean useZincServer, int zincPort, File libraryJar, File compilerJar, List extraJars, File xsbtiJar, File interfaceJar, Log l, List args) throws Exception {
this.log = l;
if (useZincServer) {
this.zinc = new ZincClient(zincPort);
if (zinc.serverAvailable()) {
l.info("Using zinc server for incremental compilation");
this.useServer = true;
this.compilerJar = compilerJar;
this.libraryJar = libraryJar;
this.extraJars = extraJars;
this.extraArgs = args;
} else {
l.warn("Zinc server is not available at port " + zincPort + " - reverting to normal incremental compile");
this.useServer = false;
}
}
if (!useServer) {
l.info("Using incremental compilation");
if (args.size() > 0) l.warn("extra args for zinc are ignored in non-server mode");
this.logger = new SbtLogger(l);
Setup setup = Setup.create(compilerJar, libraryJar, extraJars, xsbtiJar, interfaceJar, null, false);
if (l.isDebugEnabled()) Setup.debug(setup, logger);
this.compiler = Compiler.create(setup, logger);
}
}
private IncOptions defaultOptions() {
sbt.inc.IncOptions defaultSbtOptions = sbt.inc.IncOptions.Default();
return new IncOptions(
defaultSbtOptions.transitiveStep(),
defaultSbtOptions.recompileAllFraction(),
defaultSbtOptions.relationsDebug(),
defaultSbtOptions.apiDebug(),
defaultSbtOptions.apiDiffContextSize(),
defaultSbtOptions.apiDumpDirectory(),
false,
Option.empty(),
defaultSbtOptions.recompileOnMacroDef(),
defaultSbtOptions.nameHashing());
}
public void compile(File baseDir, List classpathElements, List sources, File classesDirectory, List scalacOptions, List javacOptions, File cacheFile, Map cacheMap, String compileOrder) throws Exception {
if (useServer) {
zincCompile(baseDir, classpathElements, sources, classesDirectory, scalacOptions, javacOptions, cacheFile, cacheMap, compileOrder);
} else {
if (log.isDebugEnabled()) log.debug("Incremental compiler = " + compiler + " [" + Integer.toHexString(compiler.hashCode()) + "]");
List classpath = pathsToFiles(classpathElements);
Inputs inputs = Inputs.create(classpath, sources, classesDirectory, scalacOptions, javacOptions, cacheFile, cacheMap, compileOrder, defaultOptions(), true);
if (log.isDebugEnabled()) Inputs.debug(inputs, logger);
compiler.compile(inputs, logger);
}
}
private void zincCompile(File baseDir, List classpathElements, List sources, File classesDirectory, List scalacOptions, List javacOptions, File cacheFile, Map cacheMap, String compileOrder) throws Exception {
List arguments = new ArrayList(extraArgs);
arguments.add("-log-level");
arguments.add(logLevelToString(log));
arguments.add("-scala-compiler");
arguments.add(compilerJar.getAbsolutePath());
arguments.add("-scala-library");
arguments.add(libraryJar.getAbsolutePath());
arguments.add("-scala-extra");
List extraPaths = new ArrayList();
for (File extraJar : extraJars) {
extraPaths.add(extraJar.getAbsolutePath());
}
arguments.add(MainHelper.toMultiPath(extraPaths));
if (!classpathElements.isEmpty()) {
arguments.add("-classpath");
arguments.add(MainHelper.toMultiPath(classpathElements));
}
arguments.add("-d");
arguments.add(classesDirectory.getAbsolutePath());
for (String scalacOption : scalacOptions) {
arguments.add("-S" + scalacOption);
}
for (String javacOption : javacOptions) {
arguments.add("-C" + javacOption);
}
arguments.add("-compile-order");
arguments.add(compileOrder);
arguments.add("-analysis-cache");
arguments.add(cacheFile.getAbsolutePath());
arguments.add("-analysis-map");
arguments.add(cacheMapToString(cacheMap));
for (File source : sources) {
arguments.add(source.getAbsolutePath());
}
int exitCode = zinc.run(arguments, baseDir, System.out, System.err);
if (exitCode != 0) {
xsbti.Problem[] problems = null;
throw new sbt.compiler.CompileFailed(arguments.toArray(new String[arguments.size()]), "Compile failed via zinc server", problems);
}
}
private List pathsToFiles(List paths) {
List files = new ArrayList(paths.size());
for (String path : paths) {
files.add(new File(path));
}
return files;
}
private String logLevelToString(Log l) {
if (l.isDebugEnabled()) return "debug";
else if (l.isInfoEnabled()) return "info";
else if (l.isWarnEnabled()) return "warn";
else if (l.isErrorEnabled()) return "error";
else return "info";
}
private String cacheMapToString(Map cacheMap) throws Exception {
String analysisMap = "";
boolean addArgSeparator = false;
for (Map.Entry entry : cacheMap.entrySet()) {
if (addArgSeparator) analysisMap += ANALYSIS_MAP_ARG_SEPARATOR;
analysisMap += entry.getKey().getAbsolutePath();
analysisMap += ANALYSIS_MAP_PAIR_SEPARATOR;
analysisMap += entry.getValue().getAbsolutePath();
addArgSeparator = true;
}
return analysisMap;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy