From f883281c19885d4c3390c68eeb803835ebf7310f Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Fri, 25 Dec 2009 17:11:29 +0300 Subject: [PATCH] when forcing recompilation of module, optionally clear module's output paths if possible --- .../compiler/CompilerManagerImpl.java | 4 +- .../intellij/compiler/impl/CompileDriver.java | 101 +++++++++++++----- .../openapi/compiler/ex/CompilerPathsEx.java | 3 + 3 files changed, 81 insertions(+), 27 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerManagerImpl.java b/java/compiler/impl/src/com/intellij/compiler/CompilerManagerImpl.java index d7aa30c8c28f..1f5fbdf98164 100644 --- a/java/compiler/impl/src/com/intellij/compiler/CompilerManagerImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/CompilerManagerImpl.java @@ -217,11 +217,11 @@ public class CompilerManagerImpl extends CompilerManager { } public void compile(@NotNull Module module, CompileStatusNotification callback, final boolean trackDependencies) { - compile(createModuleCompileScope(module, false), callback, trackDependencies); + new CompileDriver(myProject).compile(createModuleCompileScope(module, false), new ListenerNotificator(callback), trackDependencies, true); } public void compile(@NotNull CompileScope scope, CompileStatusNotification callback, final boolean trackDependencies) { - new CompileDriver(myProject).compile(scope, new ListenerNotificator(callback), trackDependencies); + new CompileDriver(myProject).compile(scope, new ListenerNotificator(callback), trackDependencies, false); } public void make(CompileStatusNotification callback) { 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 f3dfa835b771..1069a109be97 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -84,6 +84,7 @@ import com.intellij.util.StringBuilderSpinAllocator; import com.intellij.util.ThrowableRunnable; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; +import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.OrderedSet; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NonNls; @@ -235,7 +236,8 @@ public class CompileDriver { return new DependencyCache(myCachesDirectoryPath + File.separator + ".dependency-info"); } - public void compile(CompileScope scope, CompileStatusNotification callback, boolean trackDependencies) { + public void compile(CompileScope scope, CompileStatusNotification callback, boolean trackDependencies, boolean clearingOutputDirsPossible) { + myShouldClearOutputDirectory &= clearingOutputDirsPossible; if (trackDependencies) { scope = new TrackDependenciesScope(scope); } @@ -595,13 +597,18 @@ public class CompileDriver { try { if (isRebuild) { deleteAll(context); - if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { - if (LOG.isDebugEnabled()) { - logErrorMessages(context); - } - return ExitStatus.ERRORS; + } + else if (forceCompile) { + if (myShouldClearOutputDirectory) { + clearAffectedOutputPathsIfPossible(context); } } + if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) { + if (LOG.isDebugEnabled()) { + logErrorMessages(context); + } + return ExitStatus.ERRORS; + } if (!onlyCheckStatus) { if (!executeCompileTasks(context, true)) { @@ -794,6 +801,49 @@ public class CompileDriver { } } + private void clearAffectedOutputPathsIfPossible(CompileContextEx context) { + final MultiMap outputToModulesMap = new MultiMap(); + for (Module module : ModuleManager.getInstance(myProject).getModules()) { + final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module); + if (compilerModuleExtension == null) { + continue; + } + final String outputPathUrl = compilerModuleExtension.getCompilerOutputUrl(); + if (outputPathUrl != null) { + final String path = VirtualFileManager.extractPath(outputPathUrl); + outputToModulesMap.putValue(new File(path), module); + } + + final String outputPathForTestsUrl = compilerModuleExtension.getCompilerOutputUrlForTests(); + if (outputPathForTestsUrl != null) { + final String path = VirtualFileManager.extractPath(outputPathForTestsUrl); + outputToModulesMap.putValue(new File(path), module); + } + } + final Set affectedModules = new HashSet(Arrays.asList(context.getCompileScope().getAffectedModules())); + final List scopeOutputs = new ArrayList(affectedModules.size() * 2); + for (File output : outputToModulesMap.keySet()) { + final Collection modules = outputToModulesMap.get(output); + boolean shouldInclude = true; + for (Module module : modules) { + if (!affectedModules.contains(module)) { + shouldInclude = false; + break; + } + } + if (shouldInclude) { + scopeOutputs.add(output); + } + } + if (scopeOutputs.size() > 0) { + CompilerUtil.runInContext(context, CompilerBundle.message("progress.clearing.output"), new ThrowableRunnable() { + public void run() { + clearOutputDirectories(scopeOutputs); + } + }); + } + } + private static void logErrorMessages(final CompileContext context) { final CompilerMessage[] errors = context.getMessages(CompilerMessageCategory.ERROR); if (errors.length > 0) { @@ -1188,6 +1238,10 @@ public class CompileDriver { for (final String path : CompilerPathsEx.getOutputPaths(modules)) { outputDirs.add(new File(path)); } + for (Pair pair : myGenerationCompilerModuleToOutputDirMap.keySet()) { + outputDirs.add(new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), false))); + outputDirs.add(new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), true))); + } final CompilerConfiguration config = CompilerConfiguration.getInstance(myProject); if (config.isAnnotationProcessorsEnabled()) { for (Module module : modules) { @@ -1202,35 +1256,32 @@ public class CompileDriver { return outputDirs; } - private void clearOutputDirectories(final Set _outputDirectories) { + private static void clearOutputDirectories(final Collection outputDirectories) { final long start = System.currentTimeMillis(); // do not delete directories themselves, or we'll get rootsChanged() otherwise - final List outputDirectories = new ArrayList(_outputDirectories); - for (Pair pair : myGenerationCompilerModuleToOutputDirMap.keySet()) { - outputDirectories.add(new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), false))); - outputDirectories.add(new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), true))); - } - Collection filesToDelete = new ArrayList(outputDirectories.size() * 2); + final Collection filesToDelete = new ArrayList(outputDirectories.size() * 2); for (File outputDirectory : outputDirectories) { File[] files = outputDirectory.listFiles(); if (files != null) { filesToDelete.addAll(Arrays.asList(files)); } } - FileUtil.asyncDelete(filesToDelete); + if (filesToDelete.size() > 0) { + FileUtil.asyncDelete(filesToDelete); - // ensure output directories exist - for (final File file : outputDirectories) { - file.mkdirs(); + // ensure output directories exist + for (final File file : outputDirectories) { + file.mkdirs(); + } + final long clearStop = System.currentTimeMillis(); + + CompilerUtil.refreshIODirectories(outputDirectories); + + final long refreshStop = System.currentTimeMillis(); + + CompilerUtil.logDuration("Clearing output dirs", clearStop - start); + CompilerUtil.logDuration("Refreshing output directories", refreshStop - clearStop); } - final long clearStop = System.currentTimeMillis(); - - CompilerUtil.refreshIODirectories(outputDirectories); - - final long refreshStop = System.currentTimeMillis(); - - CompilerUtil.logDuration("Clearing output dirs", clearStop - start); - CompilerUtil.logDuration("Refreshing output directories", refreshStop - clearStop); } private void clearCompilerSystemDirectory(final CompileContextEx context) { diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ex/CompilerPathsEx.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ex/CompilerPathsEx.java index 3017682409c6..bb2d830651ce 100644 --- a/java/compiler/openapi/src/com/intellij/openapi/compiler/ex/CompilerPathsEx.java +++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ex/CompilerPathsEx.java @@ -90,6 +90,9 @@ public class CompilerPathsEx extends CompilerPaths { final Set outputPaths = new OrderedSet((TObjectHashingStrategy)TObjectHashingStrategy.CANONICAL); for (Module module : modules) { final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module); + if (compilerModuleExtension == null) { + continue; + } String outputPathUrl = compilerModuleExtension.getCompilerOutputUrl(); if (outputPathUrl != null) { outputPaths.add(VirtualFileManager.extractPath(outputPathUrl).replace('/', File.separatorChar));