mirror of https://github.com/sbt/sbt.git
API for embedding incremental compilation
This commit is contained in:
commit
4a53ace752
|
|
@ -0,0 +1,29 @@
|
|||
package xsbti.compile;
|
||||
|
||||
/**
|
||||
* Configures modifications to the classpath based on the Scala instance used for compilation.
|
||||
* This is typically used for the Scala compiler only and all values set to false for the Java compiler.
|
||||
*/
|
||||
public interface ClasspathOptions
|
||||
{
|
||||
/** If true, includes the Scala library on the boot classpath. This should usually be true.*/
|
||||
boolean bootLibrary();
|
||||
|
||||
/** If true, includes the Scala compiler on the standard classpath.
|
||||
* This is typically false and is instead managed by the build tool or environment.
|
||||
*/
|
||||
boolean compiler();
|
||||
|
||||
/** If true, includes extra jars from the Scala instance on the standard classpath.
|
||||
* This is typically false and is instead managed by the build tool or environment.
|
||||
*/
|
||||
boolean extra();
|
||||
|
||||
/** If true, automatically configures the boot classpath. This should usually be true.*/
|
||||
boolean autoBoot();
|
||||
|
||||
/** If true, the Scala library jar is filtered from the standard classpath.
|
||||
* This should usually be true because the library should be included on the boot classpath of the Scala compiler and not the standard classpath.
|
||||
*/
|
||||
boolean filterLibrary();
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package xsbti.compile;
|
||||
|
||||
/**
|
||||
* Defines the order in which Scala and Java sources are compiled when compiling a set of sources with both Java and Scala sources.
|
||||
* This setting has no effect if only Java sources or only Scala sources are being compiled.
|
||||
* It is generally more efficient to use JavaThenScala or ScalaThenJava when mixed compilation is not required.
|
||||
*/
|
||||
public enum CompileOrder
|
||||
{
|
||||
/**
|
||||
* Allows Scala sources to depend on Java sources and allows Java sources to depend on Scala sources.
|
||||
*
|
||||
* In this mode, both Java and Scala sources are passed to the Scala compiler, which generates class files for the Scala sources.
|
||||
* Then, Java sources are passed to the Java compiler, which generates class files for the Java sources.
|
||||
* The Scala classes compiled in the first step are included on the classpath to the Java compiler.
|
||||
*/
|
||||
Mixed,
|
||||
/**
|
||||
* Allows Scala sources to depend on the Java sources in the compilation, but does not allow Java sources to depend on Scala sources.
|
||||
*
|
||||
* In this mode, both Java and Scala sources are passed to the Scala compiler, which generates class files for the Scala sources.
|
||||
* Then, Java sources are passed to the Java compiler, which generates class files for the Java sources.
|
||||
* The Scala classes compiled in the first step are included on the classpath to the Java compiler.
|
||||
*/
|
||||
JavaThenScala,
|
||||
/**
|
||||
* Allows Java sources to depend on the Scala sources in the compilation, but does not allow Scala sources to depend on Java sources.
|
||||
*
|
||||
* In this mode, both Java and Scala sources are passed to the Scala compiler, which generates class files for the Scala sources.
|
||||
* Then, Java sources are passed to the Java compiler, which generates class files for the Java sources.
|
||||
* The Scala classes compiled in the first step are included on the classpath to the Java compiler.
|
||||
*/
|
||||
ScalaThenJava;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package xsbti.compile;
|
||||
|
||||
public interface Compilers<ScalaCompiler>
|
||||
{
|
||||
JavaCompiler javac();
|
||||
// should be cached by client if desired
|
||||
ScalaCompiler scalac();
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package xsbti.compile;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Determines if an entry on a classpath contains a class.
|
||||
*/
|
||||
public interface DefinesClass
|
||||
{
|
||||
/**
|
||||
* Returns true if the classpath entry contains the requested class.
|
||||
*/
|
||||
boolean apply(String className);
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package xsbti.compile;
|
||||
|
||||
import xsbti.Logger;
|
||||
import java.io.File;
|
||||
|
||||
/*
|
||||
* This API is subject to change.
|
||||
*
|
||||
* It is the client's responsibility to:
|
||||
* 1. Manage class loaders. Usually the client will want to:
|
||||
* i. Keep the class loader used by the ScalaInstance warm.
|
||||
* ii. Keep the class loader of the incremental recompilation classes (xsbti.compile) warm.
|
||||
* iii. Share the class loader for Scala classes between the incremental compiler implementation and the ScalaInstance where possible (must be binary compatible)
|
||||
* 2. Manage the compiler interface jar. The interface must be compiled against the exact Scala version used for compilation and a compatible Java version.
|
||||
* 3. Manage compilation order between different compilations.
|
||||
* i. Execute a compilation for each dependency, obtaining an Analysis for each.
|
||||
* ii. Provide the Analysis from previous compilations to dependent compilations in the analysis map.
|
||||
* 4. Provide an implementation of JavaCompiler for compiling Java sources.
|
||||
* 5. Define a function that determines if a classpath entry contains a class (Setup.definesClass).
|
||||
* i. This is provided by the client so that the client can cache this information across compilations when compiling multiple sets of sources.
|
||||
* ii. The cache should be cleared for each new compilation run or else recompilation will not properly account for changes to the classpath.
|
||||
* 6. Provide a cache directory.
|
||||
* i. This directory is used by IncrementalCompiler to persist data between compilations.
|
||||
* ii. It should be a different directory for each set of sources being compiled.
|
||||
* 7. Manage parallel execution.
|
||||
* i. Each compilation may be performed in a different thread as long as the dependencies have been compiled already.
|
||||
* ii. Implementations of all types should be immutable and arrays treated as immutable.
|
||||
* 8. Ensure general invariants:
|
||||
* i. The implementations of all types are immutable, except for the already discussed Setup.definesClass.
|
||||
* ii. Arrays are treated as immutable.
|
||||
* iii. No value is ever null.
|
||||
*/
|
||||
public interface IncrementalCompiler<Analysis, ScalaCompiler>
|
||||
{
|
||||
/**
|
||||
* Performs an incremental compilation as configured by `in`.
|
||||
* The returned Analysis should be provided to compilations depending on the classes from this compilation.
|
||||
*/
|
||||
Analysis compile(Inputs<Analysis, ScalaCompiler> in, Logger log);
|
||||
|
||||
/**
|
||||
* Creates a compiler instance that can be used by the `compile` method.
|
||||
*
|
||||
* @param instance The Scala version to use
|
||||
* @param interfaceJar The compiler interface jar compiled for the Scala version being used
|
||||
* @param options Configures how arguments to the underlying Scala compiler will be built.
|
||||
*/
|
||||
ScalaCompiler newScalaCompiler(ScalaInstance instance, File interfaceJar, ClasspathOptions options, Logger log);
|
||||
|
||||
/**
|
||||
* Compiles the source interface for a Scala version. The resulting jar can then be used by the `newScalaCompiler` method
|
||||
* to create a ScalaCompiler for incremental compilation. It is the client's responsibility to manage compiled jars for
|
||||
* different Scala versions.
|
||||
*
|
||||
* @param sourceJar The jar file containing the compiler interface sources. These are published as sbt's compiler-interface-src module.
|
||||
* @param targetJar Where to create the output jar file containing the compiled classes.
|
||||
* @param instance The ScalaInstance to compile the compiler interface for.
|
||||
* @param log The logger to use during compilation. */
|
||||
void compileInterfaceJar(File sourceJar, File targetJar, ScalaInstance instance, Logger log);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package xsbti.compile;
|
||||
|
||||
/** Configures a single compilation of a single set of sources.*/
|
||||
public interface Inputs<Analysis,ScalaCompiler>
|
||||
{
|
||||
/** The Scala and Java compilers to use for compilation.*/
|
||||
Compilers<ScalaCompiler> compilers();
|
||||
|
||||
/** Standard compilation options, such as the sources and classpath to use. */
|
||||
Options options();
|
||||
|
||||
/** Configures incremental compilation.*/
|
||||
Setup<Analysis> setup();
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package xsbti.compile;
|
||||
|
||||
import java.io.File;
|
||||
import xsbti.Logger;
|
||||
|
||||
/**
|
||||
* Interface to a Java compiler.
|
||||
*/
|
||||
public interface JavaCompiler
|
||||
{
|
||||
/** Compiles Java sources using the provided classpath, output directory, and additional options.
|
||||
* If supported, the number of reported errors should be limited to `maximumErrors`.
|
||||
* Output should be sent to the provided logger.*/
|
||||
void compile(File[] sources, File[] classpath, File outputDirectory, String[] options, int maximumErrors, Logger log);
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package xsbti.compile;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/** Standard compilation options.*/
|
||||
public interface Options
|
||||
{
|
||||
/** The classpath to use for compilation.
|
||||
* This will be modified according to the ClasspathOptions used to configure the ScalaCompiler.*/
|
||||
File[] classpath();
|
||||
|
||||
/** All sources that should be recompiled.
|
||||
* This should include Scala and Java sources, which are identified by their extension. */
|
||||
File[] sources();
|
||||
|
||||
/** The directory where class files should be generated.
|
||||
* Incremental compilation will manage the class files in this directory.
|
||||
* In particular, outdated class files will be deleted before compilation.
|
||||
* It is important that this directory is exclusively used for one set of sources. */
|
||||
File classesDirectory();
|
||||
|
||||
/** The options to pass to the Scala compiler other than the sources and classpath to use. */
|
||||
String[] options();
|
||||
|
||||
/** The options to pass to the Java compiler other than the sources and classpath to use. */
|
||||
String[] javacOptions();
|
||||
|
||||
/** The maximum number of errors that the Scala compiler should report.*/
|
||||
int maxErrors();
|
||||
|
||||
/** Controls the order in which Java and Scala sources are compiled.*/
|
||||
CompileOrder order();
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package xsbti.compile;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Defines Scala instance, which is a reference version String, a unique version String, a set of jars, and a class loader for a Scala version.
|
||||
*
|
||||
* Note that in this API a 'jar' can actually be any valid classpath entry.
|
||||
*/
|
||||
public interface ScalaInstance
|
||||
{
|
||||
/** The version used to refer to this Scala version.
|
||||
* It need not be unique and can be a dynamic version like 2.10.0-SNAPSHOT.
|
||||
*/
|
||||
String version();
|
||||
|
||||
/** A class loader providing access to the classes and resources in the library and compiler jars. */
|
||||
ClassLoader loader();
|
||||
|
||||
/** The library jar file.*/
|
||||
File libraryJar();
|
||||
|
||||
/** The compiler jar file.*/
|
||||
File compilerJar();
|
||||
|
||||
/** Jars provided by this Scala instance other than the compiler and library jars. */
|
||||
File[] extraJars();
|
||||
|
||||
/** All jar files provided by this Scala instance.*/
|
||||
File[] jars();
|
||||
|
||||
/** The unique identifier for this Scala instance. An implementation should usually obtain this from the compiler.properties file in the compiler jar. */
|
||||
String actualVersion();
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package xsbti.compile;
|
||||
|
||||
import java.io.File;
|
||||
import xsbti.Maybe;
|
||||
|
||||
/** Configures incremental recompilation. */
|
||||
public interface Setup<Analysis>
|
||||
{
|
||||
/** Provides the Analysis for the given classpath entry.*/
|
||||
Maybe<Analysis> analysisMap(File file);
|
||||
|
||||
/** Provides a function to determine if classpath entry `file` contains a given class.
|
||||
* The returned function should generally cache information about `file`, such as the list of entries in a jar.
|
||||
*/
|
||||
DefinesClass definesClass(File file);
|
||||
|
||||
/** If true, no sources are actually compiled and the Analysis from the previous compilation is returned.*/
|
||||
boolean skip();
|
||||
|
||||
/** The directory used to cache information across compilations.
|
||||
* This directory can be removed to force a full recompilation.
|
||||
* The directory should be unique and not shared between compilations. */
|
||||
File cacheDirectory();
|
||||
}
|
||||
Loading…
Reference in New Issue