From c462d23a0e2f07b11850d8fe80f2edfcf6d7fc8d Mon Sep 17 00:00:00 2001 From: Michael Nedzelsky Date: Thu, 25 Jun 2015 21:30:51 +0300 Subject: [PATCH] add support for cancel compilation from IDE #KT-8158 Fixed --- .../kotlin/codegen/KotlinCodegenFacade.java | 7 ++++ .../kotlin/codegen/PackageCodegen.java | 2 ++ .../kotlin/cli/common/CLICompiler.java | 21 ++++++++++++ .../jetbrains/kotlin/cli/js/K2JSCompiler.java | 8 +++++ .../compiler/KotlinToJVMBytecodeCompiler.java | 11 ++++++ .../resolve/jvm/KotlinJavaPsiFacade.java | 4 +-- .../org/jetbrains/kotlin/context/context.kt | 34 ++++++++++++++++--- .../kotlin/resolve/calls/CallResolver.java | 8 ++--- .../resolve/calls/CandidateResolver.java | 4 +-- .../resolve/calls/tasks/TaskPrioritizer.kt | 30 +++++++++------- .../kotlin/jps/build/KotlinBuilder.kt | 30 ++++++++++++---- .../kotlin/js/facade/K2JSTranslator.java | 5 +++ 12 files changed, 132 insertions(+), 32 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java index e701295b824..34eb94fd93e 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/KotlinCodegenFacade.java @@ -20,6 +20,7 @@ import com.google.common.collect.Sets; import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.codegen.state.GenerationState; +import org.jetbrains.kotlin.context.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.JetFile; import org.jetbrains.kotlin.psi.JetScript; @@ -54,8 +55,12 @@ public class KotlinCodegenFacade { @NotNull GenerationState state, @NotNull CompilationErrorHandler errorHandler ) { + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); + prepareForCompilation(state); + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); + MultiMap packageFqNameToFiles = new MultiMap(); for (JetFile file : state.getFiles()) { if (file == null) throw new IllegalArgumentException("A null file given for compilation"); @@ -64,9 +69,11 @@ public class KotlinCodegenFacade { Set packagesWithObsoleteParts = new HashSet(state.getPackagesWithObsoleteParts()); for (FqName fqName : Sets.union(packagesWithObsoleteParts, packageFqNameToFiles.keySet())) { + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); generatePackage(state, fqName, packageFqNameToFiles.get(fqName), errorHandler); } + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); state.getFactory().done(); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackageCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackageCodegen.java index 6d8b95f2418..7e1e99b3290 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PackageCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PackageCodegen.java @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.codegen.context.MethodContext; import org.jetbrains.kotlin.codegen.context.PackageContext; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.config.IncrementalCompilation; +import org.jetbrains.kotlin.context.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor; @@ -211,6 +212,7 @@ public class PackageCodegen { Map generateCallableMemberTasks = new HashMap(); for (JetFile file : files) { + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); try { ClassBuilder builder = generate(file, generateCallableMemberTasks); if (builder != null) { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.java b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.java index f69f42dbb30..809e6716373 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.java @@ -30,6 +30,9 @@ import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler; import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentException; import org.jetbrains.kotlin.config.CompilerConfiguration; import org.jetbrains.kotlin.config.Services; +import org.jetbrains.kotlin.context.CompilationCanceledException; +import org.jetbrains.kotlin.context.CompilationCanceledStatus; +import org.jetbrains.kotlin.context.ProgressIndicatorAndCompilationCanceledStatus; import java.io.PrintStream; import java.util.List; @@ -156,6 +159,9 @@ public abstract class CLICompiler { } } + CompilationCanceledStatus canceledStatus = services.get(CompilationCanceledStatus.class); + ProgressIndicatorAndCompilationCanceledStatus.setCompilationCanceledStatus(canceledStatus); + for (int i = 0; i < repeatCount; i++) { if (i > 0) { K2JVMCompiler.Companion.resetInitStartTime(); @@ -166,6 +172,21 @@ public abstract class CLICompiler { ExitCode code = doExecute(arguments, services, severityCollector, rootDisposable); exitCode = severityCollector.anyReported(CompilerMessageSeverity.ERROR) ? COMPILATION_ERROR : code; } + catch(CompilationCanceledException e) { + messageCollector.report(CompilerMessageSeverity.INFO, "Compilation was canceled", CompilerMessageLocation.NO_LOCATION); + return ExitCode.OK; + } + catch(RuntimeException e) { + Throwable cause = e.getCause(); + if (cause instanceof CompilationCanceledException) { + messageCollector + .report(CompilerMessageSeverity.INFO, "Compilation was canceled", CompilerMessageLocation.NO_LOCATION); + return ExitCode.OK; + } + else { + throw e; + } + } finally { Disposer.dispose(rootDisposable); } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java b/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java index 2b175dff0e5..4e0dc325e33 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java @@ -44,6 +44,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment; import org.jetbrains.kotlin.cli.jvm.config.JVMConfigurationKeys; import org.jetbrains.kotlin.config.CompilerConfiguration; import org.jetbrains.kotlin.config.Services; +import org.jetbrains.kotlin.context.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS; import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult; import org.jetbrains.kotlin.js.config.Config; @@ -142,6 +143,8 @@ public class K2JSCompiler extends CLICompiler { return COMPILATION_ERROR; } + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); + AnalysisResult analysisResult = analyzerWithCompilerReport.getAnalysisResult(); assert analysisResult instanceof JsAnalysisResult : "analysisResult should be instance of JsAnalysisResult, but " + analysisResult; JsAnalysisResult jsAnalysisResult = (JsAnalysisResult) analysisResult; @@ -179,6 +182,8 @@ public class K2JSCompiler extends CLICompiler { throw new RuntimeException(e); } + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); + AnalyzerWithCompilerReport.reportDiagnostics(translationResult.getDiagnostics(), messageSeverityCollector); if (!(translationResult instanceof TranslationResult.Success)) return ExitCode.COMPILATION_ERROR; @@ -197,6 +202,9 @@ public class K2JSCompiler extends CLICompiler { if (outputDir == null) { outputDir = outputFile.getAbsoluteFile().getParentFile(); } + + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); + OutputUtilsPackage.writeAll(outputFiles, outputDir, messageSeverityCollector); return OK; diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java index 73b43b60036..95654ea6c77 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.java @@ -43,6 +43,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.Progress; import org.jetbrains.kotlin.config.CompilerConfiguration; import org.jetbrains.kotlin.context.ModuleContext; +import org.jetbrains.kotlin.context.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.idea.MainFunctionDetector; import org.jetbrains.kotlin.load.kotlin.PackageClassUtils; import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCache; @@ -123,6 +124,8 @@ public class KotlinToJVMBytecodeCompiler { ) { Map outputFiles = Maps.newHashMap(); + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); + String targetDescription = "in modules [" + Joiner.on(", ").join(Collections2.transform(chunk, new Function() { @Override public String apply(@Nullable Module input) { @@ -134,9 +137,12 @@ public class KotlinToJVMBytecodeCompiler { return false; } + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); + result.throwIfError(); for (Module module : chunk) { + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); List jetFiles = CompileEnvironmentUtil.getJetFiles( environment.getProject(), getAbsolutePaths(directory, module), new Function1() { @Override @@ -151,6 +157,7 @@ public class KotlinToJVMBytecodeCompiler { } for (Module module : chunk) { + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); writeOutput(configuration, outputFiles.get(module), new File(module.getOutputDirectory()), jarPath, jarRuntime, null); } return true; @@ -386,6 +393,8 @@ public class KotlinToJVMBytecodeCompiler { diagnosticHolder, outputDirectory ); + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); + long generationStart = PerformanceCounter.Companion.currentThreadCpuTime(); KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION); @@ -395,6 +404,7 @@ public class KotlinToJVMBytecodeCompiler { String message = "GENERATE: " + sourceFiles.size() + " files (" + environment.countLinesOfCode(sourceFiles) + " lines) " + desc + "in " + TimeUnit.NANOSECONDS.toMillis(generationNanos) + " ms"; K2JVMCompiler.Companion.reportPerf(environment.getConfiguration(), message); + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); AnalyzerWithCompilerReport.reportDiagnostics( new FilteredJvmDiagnostics( @@ -403,6 +413,7 @@ public class KotlinToJVMBytecodeCompiler { ), environment.getConfiguration().get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY) ); + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); return generationState; } } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/KotlinJavaPsiFacade.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/KotlinJavaPsiFacade.java index 73395b5a88b..f0756fca33b 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/KotlinJavaPsiFacade.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/KotlinJavaPsiFacade.java @@ -17,7 +17,6 @@ package org.jetbrains.kotlin.resolve.jvm; import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; @@ -40,6 +39,7 @@ import com.intellij.util.messages.MessageBus; import kotlin.KotlinPackage; import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.context.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.name.ClassId; import java.util.ArrayList; @@ -85,7 +85,7 @@ public class KotlinJavaPsiFacade { } public PsiClass findClass(@NotNull ClassId classId, @NotNull GlobalSearchScope scope) { - ProgressIndicatorProvider.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly String qualifiedName = classId.asSingleFqName().asString(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/context/context.kt b/compiler/frontend/src/org/jetbrains/kotlin/context/context.kt index 194fa0e1d11..85ec3b669ee 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/context/context.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/context/context.kt @@ -16,6 +16,8 @@ package org.jetbrains.kotlin.context +import com.intellij.openapi.progress.ProcessCanceledException +import com.intellij.openapi.progress.ProgressIndicatorProvider import com.intellij.openapi.project.Project import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ModuleDescriptor @@ -27,17 +29,18 @@ import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap import org.jetbrains.kotlin.storage.ExceptionTracker import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.StorageManager +import kotlin.platform.platformStatic -public trait GlobalContext { +public interface GlobalContext { public val storageManager: StorageManager public val exceptionTracker: ExceptionTracker } -public trait ProjectContext : GlobalContext { +public interface ProjectContext : GlobalContext { public val project: Project } -public trait ModuleContext : ProjectContext { +public interface ModuleContext : ProjectContext { public val module: ModuleDescriptor public val platformToKotlinClassMap: PlatformToKotlinClassMap @@ -47,7 +50,7 @@ public trait ModuleContext : ProjectContext { get() = module.builtIns } -public trait MutableModuleContext: ModuleContext { +public interface MutableModuleContext: ModuleContext { override val module: ModuleDescriptorImpl public fun setDependencies(vararg dependencies: ModuleDescriptorImpl) { @@ -112,6 +115,29 @@ public fun ContextForNewModule( return MutableModuleContextImpl(module, projectContext) } +public class CompilationCanceledException : ProcessCanceledException() + +public interface CompilationCanceledStatus { + fun checkCanceled(): Unit +} + +public class ProgressIndicatorAndCompilationCanceledStatus { + companion object { + private var canceledStatus: CompilationCanceledStatus? = null + + platformStatic + synchronized public fun setCompilationCanceledStatus(newCanceledStatus: CompilationCanceledStatus?): Unit { + canceledStatus = newCanceledStatus + } + + platformStatic + public fun checkCanceled(): Unit { + ProgressIndicatorProvider.checkCanceled() + canceledStatus?.checkCanceled() + } + } +} + deprecated("Used temporarily while we are in transition from to lazy resolve") public open class TypeLazinessToken { deprecated("Used temporarily while we are in transition from to lazy resolve") diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java index 25bc146a196..5668b1c629a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CallResolver.java @@ -17,11 +17,11 @@ package org.jetbrains.kotlin.resolve.calls; import com.google.common.collect.Lists; -import com.intellij.openapi.progress.ProgressIndicatorProvider; import kotlin.Unit; import kotlin.jvm.functions.Function0; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.context.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.lexer.JetTokens; import org.jetbrains.kotlin.name.Name; @@ -74,8 +74,8 @@ public class CallResolver { private TaskPrioritizer taskPrioritizer; private AdditionalCheckerProvider additionalCheckerProvider; - private static PerformanceCounter callResolvePerfCounter = new PerformanceCounter("Call resolve", true); - private static PerformanceCounter candidatePerfCounter = new PerformanceCounter("Call resolve candidate analysis", true); + private static final PerformanceCounter callResolvePerfCounter = new PerformanceCounter("Call resolve", true); + private static final PerformanceCounter candidatePerfCounter = new PerformanceCounter("Call resolve candidate analysis", true); @Inject public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) { @@ -255,7 +255,7 @@ public class CallResolver { @NotNull public OverloadResolutionResults resolveFunctionCall(@NotNull BasicCallResolutionContext context) { - ProgressIndicatorProvider.checkCanceled(); + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); JetExpression calleeExpression = context.call.getCalleeExpression(); if (calleeExpression instanceof JetSimpleNameExpression) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.java index 1d507a75c77..f7d7f1959f3 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/CandidateResolver.java @@ -19,11 +19,11 @@ package org.jetbrains.kotlin.resolve.calls; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import com.intellij.openapi.progress.ProgressIndicatorProvider; import kotlin.jvm.functions.Function1; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; +import org.jetbrains.kotlin.context.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.*; @@ -76,7 +76,7 @@ public class CandidateResolver { @NotNull CallCandidateResolutionContext context, @NotNull ResolutionTask task) { - ProgressIndicatorProvider.checkCanceled(); + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); MutableResolvedCall candidateCall = context.candidateCall; D candidate = candidateCall.getCandidateDescriptor(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TaskPrioritizer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TaskPrioritizer.kt index 12db613343d..32907152767 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TaskPrioritizer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tasks/TaskPrioritizer.kt @@ -18,28 +18,32 @@ package org.jetbrains.kotlin.resolve.calls.tasks import com.google.common.collect.Lists import com.google.common.collect.Sets -import com.intellij.openapi.progress.ProgressIndicatorProvider +import org.jetbrains.kotlin.context.ProgressIndicatorAndCompilationCanceledStatus import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.Call +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.calls.CallResolverUtil.isOrOverridesSynthesized import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext import org.jetbrains.kotlin.resolve.calls.smartcasts.SmartCastUtils -import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.BOTH_RECEIVERS +import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.DISPATCH_RECEIVER +import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.EXTENSION_RECEIVER +import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.NO_EXPLICIT_RECEIVER +import org.jetbrains.kotlin.resolve.calls.tasks.collectors.CallableDescriptorCollector +import org.jetbrains.kotlin.resolve.calls.tasks.collectors.CallableDescriptorCollectors +import org.jetbrains.kotlin.resolve.calls.tasks.collectors.filtered +import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils import org.jetbrains.kotlin.resolve.scopes.receivers.QualifierReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue -import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER +import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.checker.JetTypeChecker import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils -import org.jetbrains.kotlin.storage.StorageManager -import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext - -import org.jetbrains.kotlin.resolve.calls.CallResolverUtil.isOrOverridesSynthesized -import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.* -import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER -import org.jetbrains.kotlin.resolve.* -import org.jetbrains.kotlin.resolve.calls.util.* -import org.jetbrains.kotlin.resolve.calls.tasks.collectors.* +import org.jetbrains.kotlin.types.isDynamic public class TaskPrioritizer(private val storageManager: StorageManager) { @@ -106,7 +110,7 @@ public class TaskPrioritizer(private val storageManager: StorageManager) { } private fun doComputeTasks(receiver: ReceiverValue, c: TaskPrioritizerContext) { - ProgressIndicatorProvider.checkCanceled() + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() val resolveInvoke = c.context.call.getDispatchReceiver().exists() if (resolveInvoke) { diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt index 4c15866bb05..46b432d6321 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/build/KotlinBuilder.kt @@ -48,6 +48,8 @@ import org.jetbrains.kotlin.config.CompilerRunnerConstants import org.jetbrains.kotlin.config.CompilerRunnerConstants.INTERNAL_ERROR_PREFIX import org.jetbrains.kotlin.config.IncrementalCompilation import org.jetbrains.kotlin.config.Services +import org.jetbrains.kotlin.context.CompilationCanceledStatus +import org.jetbrains.kotlin.context.CompilationCanceledException import org.jetbrains.kotlin.jps.JpsKotlinCompilerSettings import org.jetbrains.kotlin.jps.incremental.* import org.jetbrains.kotlin.jps.incremental.IncrementalCacheImpl.RecompilationDecision.DO_NOTHING @@ -59,7 +61,10 @@ import org.jetbrains.kotlin.load.kotlin.header.isCompatiblePackageFacadeKind import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCache import org.jetbrains.kotlin.load.kotlin.incremental.cache.IncrementalCacheProvider import org.jetbrains.kotlin.resolve.jvm.JvmClassName -import org.jetbrains.kotlin.utils.* +import org.jetbrains.kotlin.utils.LibraryUtils +import org.jetbrains.kotlin.utils.PathUtil +import org.jetbrains.kotlin.utils.keysToMap +import org.jetbrains.kotlin.utils.sure import org.jetbrains.org.objectweb.asm.ClassReader import java.io.File import java.util.ArrayList @@ -94,7 +99,11 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR val messageCollector = MessageCollectorAdapter(context) try { return doBuild(chunk, context, dirtyFilesHolder, messageCollector, outputConsumer) - } catch (e: Throwable) { + } + catch (e: StopBuildException) { + throw e + } + catch (e: Throwable) { messageCollector.report( CompilerMessageSeverity.EXCEPTION, OutputMessageUtil.renderException(e), @@ -133,7 +142,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR val incrementalCaches = chunk.getTargets().keysToMap { dataManager.getKotlinCache(it) } - val environment = createCompileEnvironment(incrementalCaches) + val environment = createCompileEnvironment(incrementalCaches, context) if (!environment.success()) { environment.reportErrorsTo(messageCollector) return ABORT @@ -169,6 +178,8 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR registerOutputItems(outputConsumer, generatedFiles) + context.checkCanceled() + val recompilationDecision: IncrementalCacheImpl.RecompilationDecision if (JpsUtils.isJsKotlinModule(chunk.representativeTarget())) { recompilationDecision = DO_NOTHING @@ -237,7 +248,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR val representativeTarget = chunk.representativeTarget() - fun concatenate(strings: Array?, cp: List) = array(*(strings ?: array()), *cp.copyToArray()) + fun concatenate(strings: Array?, cp: List) = arrayOf(*(strings ?: arrayOf()), *cp.toTypedArray()) for (argumentProvider in ServiceLoader.load(javaClass())) { // appending to pluginOptions @@ -257,9 +268,12 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR return compileToJvm(allCompiledFiles, chunk, commonArguments, context, dirtyFilesHolder, environment, filesToCompile, messageCollector) } - private fun createCompileEnvironment(incrementalCaches: Map): CompilerEnvironment { + private fun createCompileEnvironment(incrementalCaches: Map, context: CompileContext): CompilerEnvironment { val compilerServices = Services.Builder() .register(javaClass(), IncrementalCacheProviderImpl(incrementalCaches)) + .register(javaClass(), object: CompilationCanceledStatus { + override fun checkCanceled(): Unit = if (context.getCancelStatus().isCanceled()) throw CompilationCanceledException() + }) .build() return CompilerEnvironment.getEnvironmentFor( @@ -268,6 +282,8 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR className.startsWith("org.jetbrains.kotlin.load.kotlin.incremental.cache.") || className == "org.jetbrains.kotlin.config.Services" || className.startsWith("org.apache.log4j.") // For logging from compiler + || className == "org.jetbrains.kotlin.context.CompilationCanceledStatus" + || className == "org.jetbrains.kotlin.context.CompilationCanceledException" }, compilerServices ) @@ -556,7 +572,7 @@ private fun getAllCompiledFilesContainer(context: CompileContext): MutableSet>("_processed_targets_with_removed_files_") @@ -566,7 +582,7 @@ private fun getProcessedTargetsWithRemovedFilesContainer(context: CompileContext set = HashSet() PROCESSED_TARGETS_WITH_REMOVED_FILES.set(context, set) } - return set!! + return set } private fun hasKotlinDirtyOrRemovedFiles( diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java index f3b813c6778..14a17d7df7f 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.java @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.facade; import com.google.dart.compiler.backend.js.ast.JsProgram; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.context.ProgressIndicatorAndCompilationCanceledStatus; import org.jetbrains.kotlin.descriptors.ModuleDescriptor; import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS; import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult; @@ -67,6 +68,7 @@ public final class K2JSTranslator { ) throws TranslationException { if (analysisResult == null) { analysisResult = TopDownAnalyzerFacadeForJS.analyzeFiles(files, config); + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); } BindingTrace bindingTrace = analysisResult.getBindingTrace(); @@ -75,12 +77,15 @@ public final class K2JSTranslator { Diagnostics diagnostics = bindingTrace.getBindingContext().getDiagnostics(); TranslationContext context = Translation.generateAst(bindingTrace, files, mainCallParameters, moduleDescriptor, config); + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics); JsProgram program = JsInliner.process(context); + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); if (hasError(diagnostics)) return new TranslationResult.Fail(diagnostics); expandIsCalls(program, context); + ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); return new TranslationResult.Success(config, files, program, diagnostics, moduleDescriptor); } }