when forcing recompilation of module, optionally clear module's output paths if possible

This commit is contained in:
Eugene Zhuravlev
2009-12-25 17:12:56 +03:00
parent 43daadda08
commit f883281c19
3 changed files with 81 additions and 27 deletions
@@ -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) {
@@ -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<File, Module> outputToModulesMap = new MultiMap<File, Module>();
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<Module> affectedModules = new HashSet<Module>(Arrays.asList(context.getCompileScope().getAffectedModules()));
final List<File> scopeOutputs = new ArrayList<File>(affectedModules.size() * 2);
for (File output : outputToModulesMap.keySet()) {
final Collection<Module> 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<RuntimeException>() {
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<IntermediateOutputCompiler, Module> 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<File> _outputDirectories) {
private static void clearOutputDirectories(final Collection<File> outputDirectories) {
final long start = System.currentTimeMillis();
// do not delete directories themselves, or we'll get rootsChanged() otherwise
final List<File> outputDirectories = new ArrayList<File>(_outputDirectories);
for (Pair<IntermediateOutputCompiler, Module> 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<File> filesToDelete = new ArrayList<File>(outputDirectories.size() * 2);
final Collection<File> filesToDelete = new ArrayList<File>(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) {
@@ -90,6 +90,9 @@ public class CompilerPathsEx extends CompilerPaths {
final Set<String> outputPaths = new OrderedSet<String>((TObjectHashingStrategy<String>)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));