external build: fixed problem with files remaining dirty after 'Make Project'

This commit is contained in:
nik
2014-12-11 12:40:30 +03:00
parent 9f0322b844
commit 9421b80596
8 changed files with 39 additions and 12 deletions
@@ -0,0 +1,3 @@
Compiling files:
moduleA/src/a/ShortName.java
End of files
@@ -0,0 +1,4 @@
package b;
public class Client {
ShortName dep;
}
@@ -0,0 +1,2 @@
package b;
public class ShortName {}
@@ -19,12 +19,14 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.ModuleChunk;
import org.jetbrains.jps.ProjectPaths;
import org.jetbrains.jps.builders.BuildRootIndex;
import org.jetbrains.jps.builders.BuildTarget;
import org.jetbrains.jps.builders.BuildTargetIndex;
import org.jetbrains.jps.builders.DirtyFilesHolder;
import org.jetbrains.jps.builders.java.dependencyView.Callbacks;
import org.jetbrains.jps.builders.java.dependencyView.Mappings;
@@ -339,16 +341,16 @@ public class JavaBuilderUtil {
private static class ModulesBasedFileFilter implements Mappings.DependentFilesFilter {
private final CompileContext myContext;
private final Set<JpsModule> myChunkModules;
private final Set<ModuleBuildTarget> myChunkTargets;
private final Map<JpsModule, Set<JpsModule>> myCache = new HashMap<JpsModule, Set<JpsModule>>();
private final Set<? extends BuildTarget<?>> myChunkTargets;
private final Map<BuildTarget<?>, Set<BuildTarget<?>>> myCache = new HashMap<BuildTarget<?>, Set<BuildTarget<?>>>();
private final BuildRootIndex myBuildRootIndex;
private final BuildTargetIndex myBuildTargetIndex;
private ModulesBasedFileFilter(CompileContext context, ModuleChunk chunk) {
myContext = context;
myChunkModules = chunk.getModules();
myChunkTargets = chunk.getTargets();
myBuildRootIndex = context.getProjectDescriptor().getBuildRootIndex();
myBuildTargetIndex = context.getProjectDescriptor().getBuildTargetIndex();
}
@Override
@@ -357,16 +359,16 @@ public class JavaBuilderUtil {
if (rd == null) {
return true;
}
final JpsModule moduleOfFile = rd.target.getModule();
if (myChunkModules.contains(moduleOfFile)) {
final ModuleBuildTarget targetOfFile = rd.target;
if (myChunkTargets.contains(targetOfFile)) {
return true;
}
Set<JpsModule> moduleOfFileWithDependencies = myCache.get(moduleOfFile);
if (moduleOfFileWithDependencies == null) {
moduleOfFileWithDependencies = ProjectPaths.getModulesWithDependentsRecursively(moduleOfFile, true);
myCache.put(moduleOfFile, moduleOfFileWithDependencies);
Set<BuildTarget<?>> targetOfFileWithDependencies = myCache.get(targetOfFile);
if (targetOfFileWithDependencies == null) {
targetOfFileWithDependencies = myBuildTargetIndex.getDependenciesRecursively(targetOfFile, myContext);
myCache.put(targetOfFile, targetOfFileWithDependencies);
}
return Utils.intersects(moduleOfFileWithDependencies, myChunkModules);
return ContainerUtil.intersects(targetOfFileWithDependencies, myChunkTargets);
}
@Override
@@ -56,4 +56,16 @@ public class MarkDirtyTest extends IncrementalTestCase {
public void testRecompileTwinDependencies() {
doTest().assertFailed();
}
public void testDoNotMarkDirtyCompiledChunks() {
//'b.Client' from production sources of 'b' may not depend on 'a.ShortName' from module 'a' so it shouldn't be marked as dirty.
//Otherwise we can get 'dirty' sources after full make if production of 'b' was compiled before 'a'
JpsModule b = addModule("b", "moduleB/src");
addTestRoot(b, "moduleB/testSrc");
JpsModule a = addModule("a", "moduleA/src");
addTestRoot(a, "moduleA/testSrc");
JpsModuleRootModificationUtil.addDependency(b, a, JpsJavaDependencyScope.TEST, false);
doTestBuild(1).assertSuccessful();
//makeAll().assertUpToDate();
}
}