From 0f5eca70d408d7ed8dc75099bef0c5268d77ee0d Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 22 May 2012 18:16:48 +0200 Subject: [PATCH] external build: ensure compiler callback is called at the end of compilation --- .../intellij/compiler/impl/CompileDriver.java | 77 +++++++++---------- .../options/CompileStepBeforeRun.java | 24 +++--- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 55674307cf3d..697ea1fba91a 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -98,6 +98,7 @@ import org.jetbrains.jps.api.JpsRemoteProto; import org.jetbrains.jps.api.JpsServerResponseHandler; import org.jetbrains.jps.api.RequestFuture; +import javax.swing.*; import java.io.*; import java.util.*; import java.util.concurrent.TimeUnit; @@ -415,8 +416,8 @@ public class CompileDriver { } @Nullable - private RequestFuture compileOnServer(final @NotNull CompileContextImpl compileContext, @NotNull Collection modules, @NotNull Collection artifacts, - final @NotNull Collection paths, @Nullable final CompileStatusNotification callback) + private RequestFuture compileInExternalProcess(final @NotNull CompileContextImpl compileContext, @NotNull Collection modules, @NotNull Collection artifacts, + final @NotNull Collection paths, @Nullable final CompileStatusNotification callback) throws Exception { Collection moduleNames = Collections.emptyList(); if (modules.size() > 0) { @@ -546,10 +547,7 @@ public class CompileDriver { return buildManager.scheduleBuild(myProject, compileContext.isRebuild(), compileContext.isMake(), moduleNames, artifactNames, paths, builderParams, new DefaultMessageHandler(myProject) { @Override public void sessionTerminated() { - final ExitStatus status = COMPILE_SERVER_BUILD_STATUS.get(compileContext); - if (status != null) { - notifyCompilationCompleted(compileContext, callback, status); - } + notifyCompilationCompleted(compileContext, callback, COMPILE_SERVER_BUILD_STATUS.get(compileContext)); } @Override @@ -643,7 +641,7 @@ public class CompileDriver { final boolean checkCachesVersion) { ApplicationManager.getApplication().assertIsDispatchThread(); - final boolean useServer = useOutOfProcessBuild(); + final boolean useExtProcessBuild = useOutOfProcessBuild(); final String contentName = forceCompile ? CompilerBundle.message("compiler.content.name.compile") : CompilerBundle.message("compiler.content.name.make"); @@ -656,12 +654,12 @@ public class CompileDriver { PsiDocumentManager.getInstance(myProject).commitAllDocuments(); FileDocumentManager.getInstance().saveAllDocuments(); - final DependencyCache dependencyCache = useServer? null: createDependencyCache(); + final DependencyCache dependencyCache = useExtProcessBuild ? null: createDependencyCache(); final CompileContextImpl compileContext = new CompileContextImpl(myProject, compileTask, scope, dependencyCache, !isRebuild && !forceCompile, isRebuild); compileContext.putUserData(COMPILATION_START_TIMESTAMP, LocalTimeCounter.currentTime()); - if (!useServer) { + if (!useExtProcessBuild) { for (Map.Entry, Pair> entry : myGenerationCompilerModuleToOutputDirMap.entrySet()) { final Pair outputs = entry.getValue(); final Pair key = entry.getKey(); @@ -673,21 +671,18 @@ public class CompileDriver { } final Runnable compileWork; - if (useServer) { + if (useExtProcessBuild) { compileWork = new Runnable() { public void run() { final ProgressIndicator indicator = compileContext.getProgressIndicator(); - if (indicator.isCanceled()) { + if (indicator.isCanceled() || myProject.isDisposed()) { if (callback != null) { callback.finished(true, 0, 0, compileContext); } return; } - long start = System.currentTimeMillis(); + final long start = System.currentTimeMillis(); try { - if (myProject.isDisposed()) { - return; - } LOG.info("COMPILATION STARTED " + (CompilerWorkspaceConfiguration.useServerlessOutOfProcessBuild() ? "(BUILD PROCESS)" : "(COMPILE SERVER)")); if (message != null) { compileContext.addMessage(message); @@ -695,7 +690,7 @@ public class CompileDriver { final Collection paths = fetchFiles(compileContext); final List modules = paths.isEmpty()? Arrays.asList(compileContext.getCompileScope().getAffectedModules()) : Collections.emptyList(); final Set artifacts = ArtifactCompileScope.getArtifactsToBuild(myProject, compileContext.getCompileScope(), true); - final RequestFuture future = compileOnServer(compileContext, modules, artifacts, paths, callback); + final RequestFuture future = compileInExternalProcess(compileContext, modules, artifacts, paths, callback); if (future != null) { while (!future.waitFor(200L , TimeUnit.MILLISECONDS)) { if (indicator.isCanceled()) { @@ -707,7 +702,7 @@ public class CompileDriver { callback.finished(false, compileContext.getMessageCount(CompilerMessageCategory.ERROR), compileContext.getMessageCount(CompilerMessageCategory.WARNING), compileContext); } } - catch (Exception e) { + catch (Throwable e) { LOG.error(e); // todo callback.finished(false, compileContext.getMessageCount(CompilerMessageCategory.ERROR), compileContext.getMessageCount(CompilerMessageCategory.WARNING), compileContext); } @@ -876,31 +871,35 @@ public class CompileDriver { } } + /** @noinspection SSBasedInspection*/ private void notifyCompilationCompleted(final CompileContextImpl compileContext, final CompileStatusNotification callback, final ExitStatus _status) { final long duration = System.currentTimeMillis() - compileContext.getStartCompilationStamp(); - ApplicationManager.getApplication().invokeLater(new Runnable() { + SwingUtilities.invokeLater(new Runnable() { public void run() { - if (myProject.isDisposed()) { - return; + int errorCount = 0; + int warningCount = 0; + try { + errorCount = compileContext.getMessageCount(CompilerMessageCategory.ERROR); + warningCount = compileContext.getMessageCount(CompilerMessageCategory.WARNING); + if (!myProject.isDisposed()) { + final String statusMessage = createStatusMessage(_status, warningCount, errorCount); + final MessageType messageType = errorCount > 0 ? MessageType.ERROR : warningCount > 0 ? MessageType.WARNING : MessageType.INFO; + if (duration > ONE_MINUTE_MS) { + ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.MESSAGES_WINDOW, messageType, statusMessage); + } + CompilerManager.NOTIFICATION_GROUP.createNotification(_status == ExitStatus.UP_TO_DATE ? "Compilation: all files are up to date" : statusMessage, messageType).notify(myProject); + if (_status != ExitStatus.UP_TO_DATE && compileContext.getMessageCount(null) > 0) { + compileContext.addMessage(CompilerMessageCategory.INFORMATION, statusMessage, null, -1, -1); + } + } } - final int errorCount = compileContext.getMessageCount(CompilerMessageCategory.ERROR); - final int warningCount = compileContext.getMessageCount(CompilerMessageCategory.WARNING); - final String statusMessage = createStatusMessage(_status, warningCount, errorCount); - final MessageType messageType = errorCount > 0 ? MessageType.ERROR : warningCount > 0 ? MessageType.WARNING : MessageType.INFO; - if (duration > ONE_MINUTE_MS) { - ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.MESSAGES_WINDOW, messageType, statusMessage); - } - - CompilerManager.NOTIFICATION_GROUP.createNotification(_status == ExitStatus.UP_TO_DATE ? "Compilation: all files are up to date" : statusMessage, messageType).notify(myProject); - - if (_status != ExitStatus.UP_TO_DATE && compileContext.getMessageCount(null) > 0) { - compileContext.addMessage(CompilerMessageCategory.INFORMATION, statusMessage, null, -1, -1); - } - if (callback != null) { - callback.finished(_status == ExitStatus.CANCELLED, errorCount, warningCount, compileContext); + finally { + if (callback != null) { + callback.finished(_status == ExitStatus.CANCELLED, errorCount, warningCount, compileContext); + } } } - }, ModalityState.NON_MODAL); + }); } private void checkCachesVersion(final CompileContextImpl compileContext, final long currentVFSTimestamp) { @@ -2316,10 +2315,10 @@ public class CompileDriver { } private boolean validateCompilerConfiguration(final CompileScope scope, boolean checkOutputAndSourceIntersection) { - if (useOutOfProcessBuild()) { - return true; - } try { + if (useOutOfProcessBuild()) { + return true; + } final Module[] scopeModules = scope.getAffectedModules()/*ModuleManager.getInstance(myProject).getModules()*/; final List modulesWithoutOutputPathSpecified = new ArrayList(); boolean isProjectCompilePathSpecified = true; diff --git a/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java b/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java index e7891d8930de..b4b7d42c9cfe 100644 --- a/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java +++ b/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java @@ -23,8 +23,6 @@ import com.intellij.execution.configurations.RunConfigurationBase; import com.intellij.execution.configurations.RunProfileWithCompileBeforeLaunchOption; import com.intellij.execution.remote.RemoteConfiguration; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompileScope; import com.intellij.openapi.compiler.CompileStatusNotification; @@ -34,6 +32,7 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.Ref; import com.intellij.util.concurrency.Semaphore; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -109,20 +108,21 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider result = new Ref(Boolean.FALSE); try { + + final Semaphore done = new Semaphore(); + done.down(); final CompileStatusNotification callback = new CompileStatusNotification() { public void finished(final boolean aborted, final int errors, final int warnings, CompileContext compileContext) { if (errors == 0 && !aborted) { - result[0] = true; + result.set(Boolean.TRUE); } - done.up(); } }; - ApplicationManager.getApplication().invokeAndWait(new Runnable() { + SwingUtilities.invokeAndWait(new Runnable() { public void run() { CompileScope scope; final CompilerManager compilerManager = CompilerManager.getInstance(myProject); @@ -147,20 +147,22 @@ public class CompileStepBeforeRun extends BeforeRunTaskProvider