diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java index 0aab018bb789..dc71440c418e 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/CompileContext.java @@ -234,46 +234,51 @@ public class CompileContext extends UserDataHolderBase implements MessageHandler } void onChunkBuildComplete(@NotNull ModuleChunk chunk) throws IOException { - getDataManager().closeSourceToOutputStorages(chunk, isCompilingTests()); - getDataManager().flush(true); + final boolean compilingTests = isCompilingTests(); myProjectDescriptor.fsState.clearContextRoundData(); myProjectDescriptor.fsState.clearContextChunk(); - if (!myErrorsFound && !myCancelStatus.isCanceled()) { - final boolean compilingTests = isCompilingTests(); - final DirtyMarkScope dirtyScope = compilingTests ? DirtyMarkScope.TESTS : DirtyMarkScope.PRODUCTION; - boolean marked = false; - for (Module module : chunk.getModules()) { - if (isMake()) { - // ensure non-incremental flag cleared - myNonIncrementalModules.remove(new Pair(module, dirtyScope)); - } - if (isProjectRebuild()) { - myProjectDescriptor.fsState.markInitialScanPerformed(module.getName(), compilingTests); - } - final List roots = myProjectDescriptor.rootsIndex.getModuleRoots(module); - for (RootDescriptor descriptor : roots) { - if (compilingTests? descriptor.isTestRoot : !descriptor.isTestRoot) { - marked |= myProjectDescriptor.fsState.markAllUpToDate(getScope(), descriptor, myTimestamps, myCompilationStartStamp); + final BuildDataManager dataManager = getDataManager(); + try { + if (!myErrorsFound && !myCancelStatus.isCanceled()) { + final DirtyMarkScope dirtyScope = compilingTests ? DirtyMarkScope.TESTS : DirtyMarkScope.PRODUCTION; + boolean marked = false; + for (Module module : chunk.getModules()) { + if (isMake()) { + // ensure non-incremental flag cleared + myNonIncrementalModules.remove(new Pair(module, dirtyScope)); + } + if (isProjectRebuild()) { + myProjectDescriptor.fsState.markInitialScanPerformed(module.getName(), compilingTests); + } + final List roots = myProjectDescriptor.rootsIndex.getModuleRoots(module); + for (RootDescriptor descriptor : roots) { + if (compilingTests? descriptor.isTestRoot : !descriptor.isTestRoot) { + marked |= myProjectDescriptor.fsState.markAllUpToDate(getScope(), descriptor, myTimestamps, myCompilationStartStamp); + } } } - } - // clean mapping only after everything else is processed - final Map> map = Utils.CHUNK_PER_MODULE_REMOVED_SOURCES_KEY.get(this); - if (map != null) { - for (Map.Entry> entry : map.entrySet()) { - final SourceToOutputMapping mapping = getDataManager().getSourceToOutputMap(entry.getKey(), isCompilingTests()); - for (String path : entry.getValue()) { - mapping.remove(path); + // clean mapping only after everything else is processed + final Map> map = Utils.CHUNK_PER_MODULE_REMOVED_SOURCES_KEY.get(this); + if (map != null) { + for (Map.Entry> entry : map.entrySet()) { + final SourceToOutputMapping mapping = dataManager.getSourceToOutputMap(entry.getKey(), isCompilingTests()); + for (String path : entry.getValue()) { + mapping.remove(path); + } } } - } - if (marked) { - processMessage(UptoDateFilesSavedEvent.INSTANCE); + if (marked) { + processMessage(UptoDateFilesSavedEvent.INSTANCE); + } } } + finally { + dataManager.closeSourceToOutputStorages(chunk, compilingTests); + dataManager.flush(true); + } } public CompileScope getScope() { 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 0017e49625f2..c5db47f94d44 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/IncProjectBuilder.java @@ -489,7 +489,8 @@ public class IncProjectBuilder { final Map> perModuleRemovedSources = new HashMap>(); for (Module module : chunk.getModules()) { - final Collection deletedPaths = myProjectDescriptor.fsState.getDeletedPaths(module.getName(), context.isCompilingTests()); + final Collection deletedPaths = myProjectDescriptor.fsState.getAndClearDeletedPaths(module.getName(), + context.isCompilingTests()); if (deletedPaths.isEmpty()) { continue; } @@ -525,7 +526,6 @@ public class IncProjectBuilder { new File(output).delete(); } } - //sourceToOutputStorage.remove(deletedSource); // check if deleted source was associated with a form final SourceToFormMapping sourceToFormMap = context.getDataManager().getSourceToFormMap(); @@ -545,10 +545,20 @@ public class IncProjectBuilder { allChunkRemovedSources.addAll(currentData); } Utils.CHUNK_REMOVED_SOURCES_KEY.set(context, allChunkRemovedSources); - Utils.CHUNK_PER_MODULE_REMOVED_SOURCES_KEY.set(context, perModuleRemovedSources); - for (Module module : chunk.getModules()) { - myProjectDescriptor.fsState.clearDeletedPaths(module.getName(), context.isCompilingTests()); + + final Map> existing = Utils.CHUNK_PER_MODULE_REMOVED_SOURCES_KEY.get(context); + if (existing != null) { + for (Map.Entry> entry : existing.entrySet()) { + final Collection paths = perModuleRemovedSources.get(entry.getKey()); + if (paths != null) { + paths.addAll(entry.getValue()); + } + else { + perModuleRemovedSources.put(entry.getKey(), entry.getValue()); + } + } } + Utils.CHUNK_PER_MODULE_REMOVED_SOURCES_KEY.set(context, perModuleRemovedSources); } } catch (IOException e) { 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 e5fb5aefa815..24fb0f2a61ec 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 @@ -113,6 +113,14 @@ public class FSState { } } + public Collection getAndClearDeletedPaths(final String moduleName, final boolean forTests) { + final FilesDelta delta = myDeltas.get(moduleName); + if (delta != null) { + return delta.getAndClearDeletedPaths(forTests); + } + return Collections.emptyList(); + } + @NotNull protected final FilesDelta getDelta(final String moduleName) { synchronized (myDeltas) { diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FilesDelta.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FilesDelta.java index 883272e104b3..b3079ec10f65 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FilesDelta.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/fs/FilesDelta.java @@ -127,6 +127,18 @@ final class FilesDelta { deleted.clear(); } + public Set getAndClearDeletedPaths(boolean isTest) { + final Set deleted = isTest? myDeletedTests : myDeletedProduction; + synchronized (deleted) { + try { + return new HashSet(deleted); + } + finally { + deleted.clear(); + } + } + } + public Map> getSourcesToRecompile(boolean forTests) { return forTests? myTestsToRecompile : mySourcesToRecompile; }