Made incremental cache per-module.

Reused IDEA framework which manages per-module storage.
This commit is contained in:
Evgeny Gerashchenko
2014-08-12 20:30:51 +04:00
parent ff2e2d0203
commit 5fade9a5a6
16 changed files with 241 additions and 190 deletions
@@ -29,7 +29,9 @@ import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentException;
import org.jetbrains.jet.config.CompilerConfiguration;
import java.io.PrintStream;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.jetbrains.jet.cli.common.ExitCode.*;
@@ -48,13 +50,13 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
@NotNull
public ExitCode exec(@NotNull PrintStream errStream, @NotNull String... args) {
return exec(errStream, MessageRenderer.PLAIN_WITH_RELATIVE_PATH, args);
return exec(errStream, Collections.<Class, Object>emptyMap(), MessageRenderer.PLAIN_WITH_RELATIVE_PATH, args);
}
@SuppressWarnings("UnusedDeclaration") // Used via reflection in CompilerRunnerUtil#invokeExecMethod
@NotNull
public ExitCode execAndOutputHtml(@NotNull PrintStream errStream, @NotNull String... args) {
return exec(errStream, MessageRenderer.TAGS, args);
public ExitCode execAndOutputHtml(@NotNull PrintStream errStream, @NotNull Map<Class, Object> services, @NotNull String... args) {
return exec(errStream, services, MessageRenderer.TAGS, args);
}
@Nullable
@@ -97,7 +99,12 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
protected abstract A createArguments();
@NotNull
private ExitCode exec(@NotNull PrintStream errStream, @NotNull MessageRenderer messageRenderer, @NotNull String[] args) {
private ExitCode exec(
@NotNull PrintStream errStream,
@NotNull Map<Class, Object> services,
@NotNull MessageRenderer messageRenderer,
@NotNull String[] args
) {
A arguments = parseArguments(errStream, messageRenderer, args);
if (arguments == null) {
return INTERNAL_ERROR;
@@ -119,7 +126,7 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
}
try {
return exec(collector, arguments);
return exec(collector, services, arguments);
}
finally {
errStream.print(messageRenderer.renderConclusion());
@@ -127,13 +134,13 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
}
@NotNull
public ExitCode exec(@NotNull MessageCollector messageCollector, @NotNull A arguments) {
public ExitCode exec(@NotNull MessageCollector messageCollector, @NotNull Map<Class, Object> services, @NotNull A arguments) {
GroupingMessageCollector groupingCollector = new GroupingMessageCollector(messageCollector);
try {
Disposable rootDisposable = Disposer.newDisposable();
try {
MessageSeverityCollector severityCollector = new MessageSeverityCollector(groupingCollector);
ExitCode code = doExecute(arguments, severityCollector, rootDisposable);
ExitCode code = doExecute(arguments, services, severityCollector, rootDisposable);
return severityCollector.anyReported(CompilerMessageSeverity.ERROR) ? COMPILATION_ERROR : code;
}
finally {
@@ -151,7 +158,12 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
}
@NotNull
protected abstract ExitCode doExecute(@NotNull A arguments, @NotNull MessageCollector messageCollector, @NotNull Disposable rootDisposable);
protected abstract ExitCode doExecute(
@NotNull A arguments,
@NotNull Map<Class, Object> services,
@NotNull MessageCollector messageCollector,
@NotNull Disposable rootDisposable
);
protected void printVersionIfNeeded(
@NotNull PrintStream errStream,
@@ -51,6 +51,7 @@ import org.jetbrains.k2js.facade.MainCallParameters;
import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import static org.jetbrains.jet.cli.common.ExitCode.COMPILATION_ERROR;
import static org.jetbrains.jet.cli.common.ExitCode.OK;
@@ -73,6 +74,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
@Override
protected ExitCode doExecute(
@NotNull K2JSCompilerArguments arguments,
@NotNull Map<Class, Object> services,
@NotNull MessageCollector messageCollector,
@NotNull Disposable rootDisposable
) {
@@ -18,6 +18,7 @@ package org.jetbrains.jet.cli.jvm;
import org.jetbrains.jet.config.CompilerConfigurationKey;
import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter;
import org.jetbrains.jet.lang.resolve.kotlin.incremental.cache.IncrementalCacheProvider;
import java.io.File;
import java.util.List;
@@ -43,6 +44,9 @@ public class JVMConfigurationKeys {
public static final CompilerConfigurationKey<File> INCREMENTAL_CACHE_BASE_DIR =
CompilerConfigurationKey.create("incremental cache base dir");
public static final CompilerConfigurationKey<IncrementalCacheProvider> INCREMENTAL_CACHE_PROVIDER =
CompilerConfigurationKey.create("incremental cache provider");
public static final CompilerConfigurationKey<List<String>> MODULE_IDS =
CompilerConfigurationKey.create("module id strings");
}
@@ -35,6 +35,7 @@ import org.jetbrains.jet.codegen.CompilationException;
import org.jetbrains.jet.config.CommonConfigurationKeys;
import org.jetbrains.jet.config.CompilerConfiguration;
import org.jetbrains.jet.lang.resolve.AnalyzerScriptParameter;
import org.jetbrains.jet.lang.resolve.kotlin.incremental.cache.IncrementalCacheProvider;
import org.jetbrains.jet.utils.KotlinPaths;
import org.jetbrains.jet.utils.KotlinPathsFromHomeDir;
import org.jetbrains.jet.utils.PathUtil;
@@ -42,6 +43,7 @@ import org.jetbrains.jet.utils.PathUtil;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static com.google.common.base.Predicates.in;
import static org.jetbrains.jet.cli.common.ExitCode.*;
@@ -57,6 +59,7 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
@NotNull
protected ExitCode doExecute(
@NotNull K2JVMCompilerArguments arguments,
@NotNull Map<Class, Object> services,
@NotNull MessageCollector messageCollector,
@NotNull Disposable rootDisposable
) {
@@ -69,6 +72,11 @@ public class K2JVMCompiler extends CLICompiler<K2JVMCompilerArguments> {
CompilerConfiguration configuration = new CompilerConfiguration();
IncrementalCacheProvider incrementalCacheProvider = (IncrementalCacheProvider) services.get(IncrementalCacheProvider.class);
if (incrementalCacheProvider != null) {
configuration.put(JVMConfigurationKeys.INCREMENTAL_CACHE_PROVIDER, incrementalCacheProvider);
}
try {
configuration.addAll(JVMConfigurationKeys.CLASSPATH_KEY, getClasspath(paths, arguments));
configuration.addAll(JVMConfigurationKeys.ANNOTATIONS_PATH_KEY, getAnnotationsPath(paths, arguments));
@@ -57,7 +57,6 @@ import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCache;
import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCacheProvider;
import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalPackage;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.plugin.MainFunctionDetector;
import org.jetbrains.jet.utils.KotlinPaths;
@@ -291,22 +290,6 @@ public class KotlinToJVMBytecodeCompiler {
CliLightClassGenerationSupport support = CliLightClassGenerationSupport.getInstanceForCli(environment.getProject());
BindingTrace sharedTrace = support.getTrace();
ModuleDescriptorImpl sharedModule = support.newModule();
IncrementalCacheProvider incrementalCacheProvider = IncrementalCacheProvider.OBJECT$.getInstance();
File incrementalCacheBaseDir = environment.getConfiguration().get(JVMConfigurationKeys.INCREMENTAL_CACHE_BASE_DIR);
final IncrementalCache incrementalCache;
if (incrementalCacheProvider != null && incrementalCacheBaseDir != null) {
incrementalCache = incrementalCacheProvider.getIncrementalCache(incrementalCacheBaseDir);
Disposer.register(environment.getApplication(), new Disposable() {
@Override
public void dispose() {
incrementalCache.close();
}
});
}
else {
incrementalCache = null;
}
return AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
environment.getProject(),
@@ -315,7 +298,7 @@ public class KotlinToJVMBytecodeCompiler {
Predicates.<PsiFile>alwaysTrue(),
sharedModule,
environment.getConfiguration().get(JVMConfigurationKeys.MODULE_IDS),
incrementalCache
environment.getConfiguration().get(JVMConfigurationKeys.INCREMENTAL_CACHE_PROVIDER)
);
}
}
@@ -342,22 +325,16 @@ public class KotlinToJVMBytecodeCompiler {
File outputDirectory
) {
CompilerConfiguration configuration = environment.getConfiguration();
File incrementalCacheDir = configuration.get(JVMConfigurationKeys.INCREMENTAL_CACHE_BASE_DIR);
IncrementalCacheProvider incrementalCacheProvider = IncrementalCacheProvider.OBJECT$.getInstance();
IncrementalCacheProvider incrementalCacheProvider = configuration.get(JVMConfigurationKeys.INCREMENTAL_CACHE_PROVIDER);
Collection<FqName> packagesWithRemovedFiles;
if (incrementalCacheDir == null || moduleId == null || incrementalCacheProvider == null) {
if (moduleId == null || incrementalCacheProvider == null) {
packagesWithRemovedFiles = null;
}
else {
IncrementalCache incrementalCache = incrementalCacheProvider.getIncrementalCache(incrementalCacheDir);
try {
packagesWithRemovedFiles = IncrementalPackage.getPackagesWithRemovedFiles(
incrementalCache, moduleId, environment.getSourceFiles());
}
finally {
incrementalCache.close();
}
IncrementalCache incrementalCache = incrementalCacheProvider.getIncrementalCache(moduleId);
packagesWithRemovedFiles = IncrementalPackage.getPackagesWithRemovedFiles(
incrementalCache, moduleId, environment.getSourceFiles());
}
BindingTraceContext diagnosticHolder = new BindingTraceContext();
GenerationState generationState = new GenerationState(
@@ -25,6 +25,7 @@ import com.intellij.psi.search.GlobalSearchScope;
import kotlin.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.analyzer.AnalyzerFacade;
import org.jetbrains.jet.context.ContextPackage;
@@ -43,6 +44,7 @@ import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCache;
import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalPackageFragmentProvider;
import org.jetbrains.jet.lang.resolve.kotlin.incremental.IncrementalCacheProvider;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactory;
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactoryService;
@@ -149,7 +151,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
Predicate<PsiFile> filesToAnalyzeCompletely,
ModuleDescriptorImpl module,
List<String> moduleIds,
IncrementalCache incrementalCache
@Nullable IncrementalCacheProvider incrementalCacheProvider
) {
GlobalContext globalContext = ContextPackage.GlobalContext();
TopDownAnalysisParameters topDownAnalysisParameters = TopDownAnalysisParameters.create(
@@ -164,8 +166,10 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
try {
List<PackageFragmentProvider> additionalProviders = new ArrayList<PackageFragmentProvider>();
if (incrementalCache != null && moduleIds != null) {
if (moduleIds != null && incrementalCacheProvider != null) {
for (String moduleId : moduleIds) {
IncrementalCache incrementalCache = incrementalCacheProvider.getIncrementalCache(moduleId);
additionalProviders.add(
new IncrementalPackageFragmentProvider(
files, module, globalContext.getStorageManager(), injector.getDeserializationGlobalContextForJava(),
@@ -16,21 +16,6 @@
package org.jetbrains.jet.lang.resolve.kotlin.incremental
import java.io.File
import java.util.ServiceLoader
public trait IncrementalCacheProvider {
// IncrementalCache should be always closed after using
public fun getIncrementalCache(baseDir: File): IncrementalCache
public class object {
public fun getInstance(): IncrementalCacheProvider? {
val serviceLoader = ServiceLoader.load(javaClass<IncrementalCacheProvider>(), javaClass<IncrementalCacheProvider>().getClassLoader())
val implementations = serviceLoader.toList()
if (implementations.size > 1) {
throw IllegalStateException("More than one IncrementalCacheProvider: " + implementations)
}
return implementations.firstOrNull()
}
}
public fun getIncrementalCache(moduleId: String): IncrementalCache
}
@@ -77,6 +77,21 @@ public class ClassPreloadingUtils {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
// When compiler is invoked from JPS, we should use loaded incremental cache interface from its class loader,
// because implementation is loaded from it, as well
if (name.startsWith("org.jetbrains.jet.lang.resolve.kotlin.incremental.cache.IncrementalCache")) {
if (parent == null) {
return super.loadClass(name);
}
try {
return parent.loadClass(name);
}
catch (ClassNotFoundException e) {
return super.loadClass(name);
}
}
// Look in this class loader and then in the parent one
Class<?> aClass = super.loadClass(name);
if (aClass == null) {
@@ -85,7 +85,6 @@ public class JvmResolveUtil {
lightClassGenerationSupport.setModule(module);
}
return AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(project, files, bindingTraceContext, filesToAnalyzeCompletely,
module,
null, null);
module, null, null);
}
}