From 3b6da2c96d4c3696b107a93202c3abdc6350ec16 Mon Sep 17 00:00:00 2001 From: "kirill.safonov" Date: Tue, 13 Mar 2012 23:34:08 +0400 Subject: [PATCH] Flex compiler: support 'clear output directories on rebuild' setting (IDEA-81612) --- .../intellij/compiler/impl/CompileDriver.java | 59 ++------------- .../intellij/compiler/impl/CompilerUtil.java | 75 ++++++++++++++++++- 2 files changed, 77 insertions(+), 57 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 35f0c70eada4..0d7a54633fec 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -1092,7 +1092,7 @@ public class CompileDriver { if (scopeOutputs.size() > 0) { CompilerUtil.runInContext(context, CompilerBundle.message("progress.clearing.output"), new ThrowableRunnable() { public void run() { - clearOutputDirectories(scopeOutputs); + CompilerUtil.clearOutputDirectories(scopeOutputs); } }); } @@ -1515,7 +1515,7 @@ public class CompileDriver { final boolean isTestMode = ApplicationManager.getApplication().isUnitTestMode(); final VirtualFile[] allSources = context.getProjectCompileScope().getFiles(null, true); if (myShouldClearOutputDirectory) { - clearOutputDirectories(myAllOutputDirectories); + CompilerUtil.clearOutputDirectories(myAllOutputDirectories); } else { // refresh is still required try { @@ -1641,34 +1641,6 @@ public class CompileDriver { return outputDirs; } - private static void clearOutputDirectories(final Collection outputDirectories) { - final long start = System.currentTimeMillis(); - // do not delete directories themselves, or we'll get rootsChanged() otherwise - final Collection filesToDelete = new ArrayList(outputDirectories.size() * 2); - for (File outputDirectory : outputDirectories) { - File[] files = outputDirectory.listFiles(); - if (files != null) { - ContainerUtil.addAll(filesToDelete, files); - } - } - if (filesToDelete.size() > 0) { - FileUtil.asyncDelete(filesToDelete); - - // 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); - } - } - private void clearCompilerSystemDirectory(final CompileContextEx context) { CompilerCacheManager.getInstance(myProject).clearCaches(context); FileUtil.delete(CompilerPathsEx.getZipStoreDirectory(myProject)); @@ -2373,10 +2345,11 @@ public class CompileDriver { } if (checkOutputAndSourceIntersection && myShouldClearOutputDirectory) { - CompilerPathsEx.CLEAR_ALL_OUTPUTS_KEY.set(scope, true); if (!validateOutputAndSourcePathsIntersection()) { return false; } + // myShouldClearOutputDirectory may change in validateOutputAndSourcePathsIntersection() + CompilerPathsEx.CLEAR_ALL_OUTPUTS_KEY.set(scope, myShouldClearOutputDirectory); } else { CompilerPathsEx.CLEAR_ALL_OUTPUTS_KEY.set(scope, false); @@ -2547,31 +2520,11 @@ public class CompileDriver { ContainerUtil.addIfNotNull(artifact.getOutputFile(), allOutputs); } final Set affectedOutputPaths = new HashSet(); - for (Module module : allModules) { - final ModuleRootManager rootManager = ModuleRootManager.getInstance(module); - final VirtualFile[] sourceRoots = rootManager.getSourceRoots(); - for (final VirtualFile outputPath : allOutputs) { - for (VirtualFile sourceRoot : sourceRoots) { - if (VfsUtil.isAncestor(outputPath, sourceRoot, true) || VfsUtil.isAncestor(sourceRoot, outputPath, false)) { - affectedOutputPaths.add(outputPath); - } - } - } - } + CompilerUtil.computeIntersectingPaths(myProject, allOutputs, affectedOutputPaths); affectedOutputPaths.addAll(ArtifactCompilerUtil.getArtifactOutputsContainingSourceFiles(myProject)); if (!affectedOutputPaths.isEmpty()) { - final StringBuilder paths = new StringBuilder(); - for (final VirtualFile affectedOutputPath : affectedOutputPaths) { - if (paths.length() > 0) { - paths.append(",\n"); - } - paths.append(affectedOutputPath.getPath().replace('/', File.separatorChar)); - } - final int answer = Messages.showOkCancelDialog(myProject, - CompilerBundle.message("warning.sources.under.output.paths", paths.toString()), - CommonBundle.getErrorTitle(), Messages.getWarningIcon()); - if (answer == 0) { // ok + if (CompilerUtil.askUserToContinueWithNoClearing(myProject, affectedOutputPaths)) { myShouldClearOutputDirectory = false; return true; } diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java index 170025f9e786..4cd1ce584ef3 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java @@ -20,20 +20,24 @@ */ package com.intellij.compiler.impl; +import com.intellij.CommonBundle; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompileContext; import com.intellij.openapi.compiler.CompilerBundle; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.CharsetToolkit; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.*; import com.intellij.openapi.vfs.newvfs.RefreshQueue; import com.intellij.pom.java.LanguageLevel; import com.intellij.util.ThrowableRunnable; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -247,4 +251,67 @@ public class CompilerUtil { public static void logDuration(final String activityName, long duration) { LOG.info(activityName + " took " + duration + " ms: " + duration /60000 + " min " +(duration %60000)/1000 + "sec"); } + + public static void clearOutputDirectories(final Collection outputDirectories) { + final long start = System.currentTimeMillis(); + // do not delete directories themselves, or we'll get rootsChanged() otherwise + final Collection filesToDelete = new ArrayList(outputDirectories.size() * 2); + for (File outputDirectory : outputDirectories) { + File[] files = outputDirectory.listFiles(); + if (files != null) { + ContainerUtil.addAll(filesToDelete, files); + } + } + if (filesToDelete.size() > 0) { + FileUtil.asyncDelete(filesToDelete); + + // ensure output directories exist + for (final File file : outputDirectories) { + file.mkdirs(); + } + final long clearStop = System.currentTimeMillis(); + + refreshIODirectories(outputDirectories); + + final long refreshStop = System.currentTimeMillis(); + + logDuration("Clearing output dirs", clearStop - start); + logDuration("Refreshing output directories", refreshStop - clearStop); + } + } + + public static void computeIntersectingPaths(final Project project, + final Collection outputPaths, + final Collection result) { + for (Module module : ModuleManager.getInstance(project).getModules()) { + final ModuleRootManager rootManager = ModuleRootManager.getInstance(module); + final VirtualFile[] sourceRoots = rootManager.getSourceRoots(); + for (final VirtualFile outputPath : outputPaths) { + for (VirtualFile sourceRoot : sourceRoots) { + if (VfsUtilCore.isAncestor(outputPath, sourceRoot, true) || VfsUtilCore.isAncestor(sourceRoot, outputPath, false)) { + result.add(outputPath); + } + } + } + } + } + + public static boolean askUserToContinueWithNoClearing(Project project, Collection affectedOutputPaths) { + final StringBuilder paths = new StringBuilder(); + for (final VirtualFile affectedOutputPath : affectedOutputPaths) { + if (paths.length() > 0) { + paths.append(",\n"); + } + paths.append(affectedOutputPath.getPath().replace('/', File.separatorChar)); + } + final int answer = Messages.showOkCancelDialog(project, + CompilerBundle.message("warning.sources.under.output.paths", paths.toString()), + CommonBundle.getErrorTitle(), Messages.getWarningIcon()); + if (answer == Messages.OK) { // ok + return true; + } + else { + return false; + } + } }