CompilerDependencies

Holds reference to runtime.jar and jdk-headers.jar. Paths to these
jars are no longer hardcoded.

Many tests now compile runtime before execution. Because of this:
* Single test invocation is significantly slower now for some tests
* This can be fixed by making tests independent from runtime (this
must be done anyway)

Some tests still depend on runtime.jar built by "ant dist", this
is to be fixed.
This commit is contained in:
Stepan Koltsov
2012-04-09 03:04:50 +04:00
parent aae7ba734d
commit 10dd366216
48 changed files with 422 additions and 128 deletions
@@ -61,6 +61,9 @@ public class CompilerArguments {
@Argument(value = "stdlib", description = "Path to the stdlib.jar")
public String stdlib;
@Argument(value = "jdkHeaders", description = "Path to the kotlin-jdk-headers.jar")
public String jdkHeaders;
@Argument(value = "help", alias = "h", description = "show help")
public boolean help;
@@ -24,7 +24,9 @@ import org.jetbrains.jet.compiler.CompileEnvironmentException;
import org.jetbrains.jet.compiler.CompilerPlugin;
import org.jetbrains.jet.compiler.MessageRenderer;
import org.jetbrains.jet.lang.diagnostics.Severity;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
import java.io.PrintStream;
@@ -121,7 +123,32 @@ public class KotlinCompiler {
}
}
CompileEnvironment environment = new CompileEnvironment(messageRenderer, arguments.verbose, mode);
File jdkHeadersJar;
if (mode.includeJdkHeaders()) {
if (arguments.jdkHeaders != null) {
jdkHeadersJar = new File(arguments.jdkHeaders);
} else {
jdkHeadersJar = PathUtil.getAltHeadersPath();
}
}
else {
jdkHeadersJar = null;
}
File runtimeJar;
if (mode.includeKotlinRuntime()) {
if (arguments.stdlib != null) {
runtimeJar = new File(arguments.stdlib);
} else {
runtimeJar = PathUtil.getDefaultRuntimePath();
}
}
else {
runtimeJar = null;
}
CompilerDependencies dependencies = new CompilerDependencies(mode, jdkHeadersJar,runtimeJar);
CompileEnvironment environment = new CompileEnvironment(messageRenderer, arguments.verbose, dependencies);
try {
configureEnvironment(environment, arguments, errStream);
@@ -204,8 +231,8 @@ public class KotlinCompiler {
environment.getEnvironment().getCompilerPlugins().addAll(plugins);
}
if (arguments.stdlib != null) {
environment.setStdlib(arguments.stdlib);
if (environment.getCompilerDependencies().getRuntimeJar() != null) {
environment.addToClasspath(environment.getCompilerDependencies().getRuntimeJar());
}
if (arguments.classpath != null) {
@@ -17,7 +17,6 @@
package org.jetbrains.jet.compiler;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.psi.JavaPsiFacade;
@@ -34,20 +33,31 @@ import org.jetbrains.jet.codegen.GeneratedClassLoader;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.plugin.JetLanguage;
import org.jetbrains.jet.plugin.JetMainDetector;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.utils.PathUtil;
import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.*;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
/**
* The environment for compiling a bunch of source files or
@@ -60,32 +70,28 @@ public class CompileEnvironment {
private final MessageRenderer messageRenderer;
private PrintStream errorStream = System.err;
private URL stdlibUrl;
private boolean ignoreErrors = false;
private final CompilerSpecialMode mode;
@NotNull
private final CompilerDependencies compilerDependencies;
private final boolean verbose;
public CompileEnvironment() {
this(MessageRenderer.PLAIN, false, CompilerSpecialMode.REGULAR);
public CompileEnvironment(CompilerDependencies compilerDependencies) {
this(MessageRenderer.PLAIN, false, compilerDependencies);
}
/**
* NOTE: It's very important to call dispose for every object of this class or there will be memory leaks.
* @see Disposer
*
* @param messageRenderer
* @param verbose
*/
public CompileEnvironment(MessageRenderer messageRenderer, boolean verbose, CompilerSpecialMode mode) {
this.mode = mode;
public CompileEnvironment(MessageRenderer messageRenderer, boolean verbose, @NotNull CompilerDependencies compilerDependencies) {
this.compilerDependencies = compilerDependencies;
this.verbose = verbose;
rootDisposable = new Disposable() {
@Override
public void dispose() {
}
};
environment = new JetCoreEnvironment(rootDisposable, mode.includeJdkHeaders());
environment = new JetCoreEnvironment(rootDisposable, compilerDependencies);
this.messageRenderer = messageRenderer;
}
@@ -121,22 +127,21 @@ public class CompileEnvironment {
}
public void ensureRuntime() {
if (mode == CompilerSpecialMode.REGULAR) {
if (compilerDependencies.getCompilerSpecialMode() == CompilerSpecialMode.REGULAR) {
ensureRuntime(environment);
} else if (mode == CompilerSpecialMode.JDK_HEADERS) {
} else if (compilerDependencies.getCompilerSpecialMode() == CompilerSpecialMode.JDK_HEADERS) {
ensureJdkRuntime(environment);
} else if (mode == CompilerSpecialMode.STDLIB) {
} else if (compilerDependencies.getCompilerSpecialMode() == CompilerSpecialMode.STDLIB) {
ensureJdkRuntime(environment);
} else if (mode == CompilerSpecialMode.BUILTINS) {
} else if (compilerDependencies.getCompilerSpecialMode() == CompilerSpecialMode.BUILTINS) {
// nop
} else {
throw new IllegalStateException("unknown mode: " + mode);
throw new IllegalStateException("unknown mode: " + compilerDependencies.getCompilerSpecialMode());
}
}
public static void ensureRuntime(@NotNull JetCoreEnvironment env) {
ensureJdkRuntime(env);
ensureKotlinRuntime(env);
}
private static void ensureKotlinRuntime(JetCoreEnvironment env) {
@@ -192,8 +197,6 @@ public class CompileEnvironment {
public boolean compileModuleScript(String moduleScriptFile, @Nullable String jarPath, @Nullable String outputDir, boolean jarRuntime) {
CompileEnvironment moduleCompilationEnvironment = copyEnvironment(false);
try {
moduleCompilationEnvironment.stdlibUrl = stdlibUrl;
List<Module> modules = moduleCompilationEnvironment.loadModuleScript(moduleScriptFile);
if (modules == null) {
@@ -207,6 +210,9 @@ public class CompileEnvironment {
final String directory = new File(moduleScriptFile).getParent();
for (Module moduleBuilder : modules) {
CompileEnvironment compileEnvironment = copyEnvironment(verbose);
if (compilerDependencies.getRuntimeJar() != null) {
compileEnvironment.addToClasspath(compilerDependencies.getRuntimeJar());
}
try {
ClassFileFactory moduleFactory = compileEnvironment.compileModule(moduleBuilder, directory);
if (moduleFactory == null) {
@@ -234,7 +240,7 @@ public class CompileEnvironment {
}
private CompileEnvironment copyEnvironment(boolean verbose) {
CompileEnvironment compileEnvironment = new CompileEnvironment(messageRenderer, verbose, mode);
CompileEnvironment compileEnvironment = new CompileEnvironment(messageRenderer, verbose, compilerDependencies);
compileEnvironment.setIgnoreErrors(ignoreErrors);
compileEnvironment.setErrorStream(errorStream);
// copy across any compiler plugins
@@ -247,6 +253,10 @@ public class CompileEnvironment {
scriptCompileSession.addSources(moduleFile);
ensureRuntime();
if (compilerDependencies.getRuntimeJar() != null) {
addToClasspath(compilerDependencies.getRuntimeJar());
}
if (!scriptCompileSession.analyze()) {
return null;
}
@@ -256,8 +266,18 @@ public class CompileEnvironment {
}
private List<Module> runDefineModules(String moduleFile, ClassFileFactory factory) {
GeneratedClassLoader loader = stdlibUrl != null ? new GeneratedClassLoader(factory, new URLClassLoader(new URL[] {stdlibUrl}, AllModules.class.getClassLoader()))
: new GeneratedClassLoader(factory, CompileEnvironment.class.getClassLoader());
File stdlibJar = compilerDependencies.getRuntimeJar();
GeneratedClassLoader loader;
if (stdlibJar != null) {
try {
loader = new GeneratedClassLoader(factory, new URLClassLoader(new URL[]{stdlibJar.toURI().toURL()}, AllModules.class.getClassLoader()));
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
else {
loader = new GeneratedClassLoader(factory, CompileEnvironment.class.getClassLoader());
}
try {
Class namespaceClass = loader.loadClass(JvmAbi.PACKAGE_CLASS);
final Method method = namespaceClass.getDeclaredMethod("project");
@@ -282,7 +302,7 @@ public class CompileEnvironment {
public ClassFileFactory compileModule(Module moduleBuilder, String directory) {
CompileSession moduleCompileSession = newCompileSession();
moduleCompileSession.setStubs(mode.isStubs());
moduleCompileSession.setStubs(compilerDependencies.getCompilerSpecialMode().isStubs());
if (moduleBuilder.getSourceFiles().isEmpty()) {
throw new CompileEnvironmentException("No source files where defined");
@@ -403,7 +423,7 @@ public class CompileEnvironment {
public boolean compileBunchOfSources(String sourceFileOrDir, String jar, String outputDir, boolean includeRuntime) {
CompileSession session = newCompileSession();
session.setStubs(mode.isStubs());
session.setStubs(compilerDependencies.getCompilerSpecialMode().isStubs());
session.addSources(sourceFileOrDir);
@@ -412,7 +432,7 @@ public class CompileEnvironment {
public boolean compileBunchOfSourceDirectories(List<String> sources, String jar, String outputDir, boolean includeRuntime) {
CompileSession session = newCompileSession();
session.setStubs(mode.isStubs());
session.setStubs(compilerDependencies.getCompilerSpecialMode().isStubs());
for (String source : sources) {
session.addSources(source);
@@ -455,7 +475,7 @@ public class CompileEnvironment {
}
private CompileSession newCompileSession() {
CompileSession answer = new CompileSession(environment, messageRenderer, errorStream, verbose, mode);
CompileSession answer = new CompileSession(environment, messageRenderer, errorStream, verbose, compilerDependencies);
environment.setSession(answer);
return answer;
}
@@ -499,16 +519,14 @@ public class CompileEnvironment {
public void setStdlib(String stdlib) {
File file = new File(stdlib);
addToClasspath(file);
try {
stdlibUrl = file.toURL();
}
catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}
public JetCoreEnvironment getEnvironment() {
return environment;
}
@NotNull
public CompilerDependencies getCompilerDependencies() {
return compilerDependencies;
}
}
@@ -43,7 +43,7 @@ import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.AnalyzeExhaust;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.jet.utils.Progress;
@@ -68,15 +68,16 @@ public class CompileSession {
private final MessageRenderer messageRenderer;
private final PrintStream errorStream;
private final boolean isVerbose;
private final CompilerSpecialMode compilerSpecialMode;
private final CompilerDependencies compilerDependencies;
private AnalyzeExhaust bindingContext;
public CompileSession(JetCoreEnvironment environment, MessageRenderer messageRenderer, PrintStream errorStream, boolean verbose, CompilerSpecialMode mode) {
public CompileSession(JetCoreEnvironment environment, MessageRenderer messageRenderer, PrintStream errorStream, boolean verbose,
@NotNull CompilerDependencies compilerDependencies) {
this.environment = environment;
this.messageRenderer = messageRenderer;
this.errorStream = errorStream;
isVerbose = verbose;
this.compilerSpecialMode = mode;
this.compilerDependencies = compilerDependencies;
messageCollector = new MessageCollector(this.messageRenderer);
}
@@ -176,7 +177,8 @@ public class CompileSession {
Predicate<PsiFile> filesToAnalyzeCompletely =
stubs ? Predicates.<PsiFile>alwaysFalse() : Predicates.<PsiFile>alwaysTrue();
bindingContext = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
environment.getProject(), sourceFiles, filesToAnalyzeCompletely, JetControlFlowDataTraceFactory.EMPTY, compilerSpecialMode);
environment.getProject(), sourceFiles, filesToAnalyzeCompletely, JetControlFlowDataTraceFactory.EMPTY,
compilerDependencies);
for (Diagnostic diagnostic : bindingContext.getBindingContext().getDiagnostics()) {
reportDiagnostic(messageCollector, diagnostic);
@@ -221,7 +223,7 @@ public class CompileSession {
public GenerationState generate(boolean module) {
Project project = environment.getProject();
GenerationState generationState = new GenerationState(project, ClassBuilderFactories.binaries(stubs),
isVerbose ? new BackendProgress() : Progress.DEAF, bindingContext, sourceFiles, compilerSpecialMode);
isVerbose ? new BackendProgress() : Progress.DEAF, bindingContext, sourceFiles, compilerDependencies.getCompilerSpecialMode());
generationState.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
List<CompilerPlugin> plugins = environment.getCompilerPlugins();
@@ -23,8 +23,11 @@ import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElementFinder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.asJava.JavaElementFinder;
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
import org.jetbrains.jet.lang.resolve.java.CompilerDependencies;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.lang.resolve.java.JetFilesProvider;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.jet.plugin.JetFileType;
@@ -43,7 +46,7 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
private List<CompilerPlugin> compilerPlugins = new ArrayList<CompilerPlugin>();
private CompileSession session;
public JetCoreEnvironment(Disposable parentDisposable, boolean includeJdkHeaders) {
public JetCoreEnvironment(Disposable parentDisposable, @NotNull CompilerDependencies compilerDependencies) {
super(parentDisposable);
registerFileType(JetFileType.INSTANCE, "kt");
registerFileType(JetFileType.INSTANCE, "kts");
@@ -58,8 +61,15 @@ public class JetCoreEnvironment extends JavaCoreEnvironment {
.getExtensionPoint(PsiElementFinder.EP_NAME)
.registerExtension(new JavaElementFinder(myProject));
if (includeJdkHeaders) {
for (VirtualFile root : PathUtil.getAltHeadersRoots()) {
CompilerSpecialMode compilerSpecialMode = compilerDependencies.getCompilerSpecialMode();
if (compilerSpecialMode.includeJdkHeaders()) {
for (VirtualFile root : compilerDependencies.getJdkHeaderRoots()) {
addLibraryRoot(root);
}
}
if (compilerSpecialMode.includeKotlinRuntime()) {
for (VirtualFile root : compilerDependencies.getRuntimeRoots()) {
addLibraryRoot(root);
}
}