From ec7e061d69d95b8fe244d36cbd50562172b985a9 Mon Sep 17 00:00:00 2001 From: nik Date: Fri, 23 Nov 2012 20:15:04 +0400 Subject: [PATCH] external build: unified processing of forced compilation [rev by jeka] --- .../compiler/BaseCompilerTestCase.java | 15 +++++---- .../jps/incremental/BuildOperations.java | 20 ++++------- .../jps/incremental/IncProjectBuilder.java | 33 +++++++++++++++---- .../jps/incremental/fs/BuildFSState.java | 4 +-- .../jetbrains/jps/incremental/fs/FSState.java | 8 +++-- 5 files changed, 49 insertions(+), 31 deletions(-) diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java index 42d566552ee9..08cbb7581ea1 100644 --- a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java +++ b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java @@ -149,18 +149,21 @@ public abstract class BaseCompilerTestCase extends ModuleTestCase { return make(scope, CompilerFilter.ALL); } - protected CompilationLog make(Module module) { - return make(getCompilerManager().createModuleCompileScope(module, false), CompilerFilter.ALL); + protected CompilationLog make(Module... modules) { + return make(getCompilerManager().createModulesCompileScope(modules, false), CompilerFilter.ALL); } - private CompilerManager getCompilerManager() { + protected CompilationLog recompile(Module... modules) { + return compile(getCompilerManager().createModulesCompileScope(modules, false), CompilerFilter.ALL, true); + } + + protected CompilerManager getCompilerManager() { return CompilerManager.getInstance(myProject); } protected void assertModulesUpToDate() { - //todo[nik,jeka] uncomment this when isUpToDate become supported in external compiler - //boolean upToDate = getCompilerManager().isUpToDate(getCompilerManager().createProjectCompileScope(myProject)); - //assertTrue("Modules are not up to date", upToDate); + boolean upToDate = getCompilerManager().isUpToDate(getCompilerManager().createProjectCompileScope(myProject)); + assertTrue("Modules are not up to date", upToDate); } protected CompilationLog compile(boolean force, VirtualFile... files) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java index 868b0c6345ec..80db6062c94c 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/BuildOperations.java @@ -42,22 +42,16 @@ public class BuildOperations { if (context.isProjectRebuild()) { FSOperations.markDirtyFiles(context, target, timestamps, true, null, null); + pd.fsState.markInitialScanPerformed(target); configuration.save(); } else if (context.getScope().isRecompilationForced(target) || configuration.isTargetDirty() || configuration.outputRootWasDeleted(context)) { - if (target instanceof ModuleBuildTarget) { - // Using special FSState initialization, because for correct results of "integrate" operation of JavaBuilder - // we still need to know which sources were deleted from previous compilation - initTargetFSState(context, target, true); - } - else { - IncProjectBuilder.clearOutputFiles(context, target); - pd.dataManager.cleanTargetStorages(target); - FSOperations.markDirtyFiles(context, target, timestamps, true, null, null); - } + initTargetFSState(context, target, true); + IncProjectBuilder.clearOutputFiles(context, target); + pd.dataManager.cleanTargetStorages(target); configuration.save(); } - else if (pd.fsState.markInitialScanPerformed(target)) { + else if (!pd.fsState.isInitialScanPerformed(target)) { initTargetFSState(context, target, false); } } @@ -80,6 +74,7 @@ public class BuildOperations { fsState.registerDeleted(target, file, timestamps); } } + pd.fsState.markInitialScanPerformed(target); } public static > @@ -113,9 +108,6 @@ public class BuildOperations { // ensure non-incremental flag cleared context.clearNonIncrementalMark((ModuleBuildTarget)target); } - if (context.isProjectRebuild()) { - fsState.markInitialScanPerformed(target); - } final Timestamps timestamps = pd.timestamps.getStorage(); for (BuildRootDescriptor rd : pd.getBuildRootIndex().getTargetRoots(target, context)) { marked |= fsState.markAllUpToDate(context, rd, timestamps); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java index de4640983d81..d0b24b047a50 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -60,6 +60,7 @@ public class IncProjectBuilder { private static final String CLASSPATH_INDEX_FINE_NAME = "classpath.index"; private static final boolean GENERATE_CLASSPATH_INDEX = Boolean.parseBoolean(System.getProperty(GlobalOptions.GENERATE_CLASSPATH_INDEX_OPTION, "false")); + private static final Key>> TARGET_WITH_CLEARED_OUTPUT = Key.create("_targets_with_cleared_output_"); private static final int MAX_BUILDER_THREADS; static { int maxThreads = 4; @@ -362,11 +363,26 @@ public class IncProjectBuilder { context.processMessage(new FileDeletedEvent(outs)); } } + registerTargetsWithClearedOutput(context, Collections.singletonList(target)); if (dirsToDelete != null) { FSOperations.pruneEmptyDirs(context, dirsToDelete); } } + private static void registerTargetsWithClearedOutput(CompileContext context, Collection> targets) { + Set> data = context.getUserData(TARGET_WITH_CLEARED_OUTPUT); + if (data == null) { + data = new THashSet>(); + context.putUserData(TARGET_WITH_CLEARED_OUTPUT, data); + } + data.addAll(targets); + } + + private static boolean isTargetOutputCleared(CompileContext context, BuildTarget target) { + Set> data = context.getUserData(TARGET_WITH_CLEARED_OUTPUT); + return data != null && data.contains(target); + } + private void clearOutputs(CompileContext context) throws ProjectBuildException, IOException { final MultiMap> rootsToDelete = new MultiMapBasedOnSet>(); final Set allSourceRoots = new HashSet(); @@ -417,6 +433,7 @@ public class IncProjectBuilder { else if (outputRoot.isFile()) { filesToDelete.add(outputRoot); } + registerTargetsWithClearedOutput(context, entry.getValue()); } else { context.processMessage(new CompilerMessage( @@ -594,13 +611,11 @@ public class IncProjectBuilder { } private void buildTargetsChunk(CompileContext context, final BuildTargetChunk chunk) throws ProjectBuildException { - boolean doneSomething = false; + boolean doneSomething; try { Utils.ERRORS_DETECTED_KEY.set(context, Boolean.FALSE); BuildOperations.ensureFSStateInitialized(context, chunk); - if (context.isMake()) { - doneSomething = processDeletedPaths(context, chunk.getTargets()); - } + doneSomething = processDeletedPaths(context, chunk.getTargets()); myProjectDescriptor.fsState.beforeChunkBuildStart(context, chunk); @@ -696,11 +711,16 @@ public class IncProjectBuilder { final THashSet dirsToDelete = new THashSet(FileUtil.FILE_HASHING_STRATEGY); for (BuildTarget target : targets) { + final Collection deletedPaths = myProjectDescriptor.fsState.getAndClearDeletedPaths(target); if (deletedPaths.isEmpty()) { continue; } targetToRemovedSources.put(target, deletedPaths); + if (isTargetOutputCleared(context, target)) { + continue; + } + final boolean shouldPruneEmptyDirs = target instanceof ModuleBasedTarget; final SourceToOutputMapping sourceToOutputStorage = context.getProjectDescriptor().dataManager.getSourceToOutputMap(target); final ProjectBuilderLogger logger = context.getLoggingManager().getProjectBuilderLogger(); @@ -821,9 +841,7 @@ public class IncProjectBuilder { } for (ModuleLevelBuilder builder : builders) { - if (context.isMake()) { - processDeletedPaths(context, chunk.getTargets()); - } + processDeletedPaths(context, chunk.getTargets()); final ModuleLevelBuilder.ExitCode buildResult = builder.build(context, chunk, dirtyFilesHolder, outputConsumer); doneSomething |= (buildResult != ModuleLevelBuilder.ExitCode.NOTHING_DONE); @@ -953,6 +971,7 @@ public class IncProjectBuilder { // keys for data that must be visible to all threads GLOBAL_CONTEXT_KEYS.add(ExternalJavacDescriptor.KEY); GLOBAL_CONTEXT_KEYS.add(FSOperations.ALL_OUTPUTS_KEY); + GLOBAL_CONTEXT_KEYS.add(TARGET_WITH_CLEARED_OUTPUT); } private static CompileContext createContextWrapper(final CompileContext delegate) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java index efe700837ac7..705595eb885b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/BuildFSState.java @@ -43,8 +43,8 @@ public class BuildFSState extends FSState { } @Override - public boolean markInitialScanPerformed(BuildTarget target) { - return myAlwaysScanFS || super.markInitialScanPerformed(target); + public boolean isInitialScanPerformed(BuildTarget target) { + return !myAlwaysScanFS && super.isInitialScanPerformed(target); } @Override diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FSState.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FSState.java index 6bb25ac9d830..0cfa276a207f 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FSState.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FSState.java @@ -160,7 +160,11 @@ public class FSState { return delta != null && delta.hasChanges(); } - public boolean markInitialScanPerformed(BuildTarget target) { - return myInitialScanPerformed.add(target); + public void markInitialScanPerformed(BuildTarget target) { + myInitialScanPerformed.add(target); + } + + public boolean isInitialScanPerformed(BuildTarget target) { + return myInitialScanPerformed.contains(target); } }