diff --git a/java/java-tests/testData/compileServer/incremental/common/dontMarkDependentsAfterCompileErrors.log b/java/java-tests/testData/compileServer/incremental/common/dontMarkDependentsAfterCompileErrors.log new file mode 100644 index 000000000000..1c32b67c353f --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/dontMarkDependentsAfterCompileErrors.log @@ -0,0 +1,9 @@ +Cleaning output files: +out/production/DontMarkDependentsAfterCompileErrors/packageA/Server.class +End of files +Compiling files: +src/packageA/Server.java +End of files +Compiling files: +src/packageA/Server.java +End of files \ No newline at end of file diff --git a/java/java-tests/testData/compileServer/incremental/common/dontMarkDependentsAfterCompileErrors/src/packageA/Client.java b/java/java-tests/testData/compileServer/incremental/common/dontMarkDependentsAfterCompileErrors/src/packageA/Client.java new file mode 100644 index 000000000000..fd6869be0e49 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/dontMarkDependentsAfterCompileErrors/src/packageA/Client.java @@ -0,0 +1,9 @@ +package packageA; + +public class Client { + + public void method(Server server) { + server.method(); + } + +} diff --git a/java/java-tests/testData/compileServer/incremental/common/dontMarkDependentsAfterCompileErrors/src/packageA/Server.java b/java/java-tests/testData/compileServer/incremental/common/dontMarkDependentsAfterCompileErrors/src/packageA/Server.java new file mode 100644 index 000000000000..5168430764ac --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/dontMarkDependentsAfterCompileErrors/src/packageA/Server.java @@ -0,0 +1,7 @@ +package packageA; + +public class Server { + public void method() { + System.out.println("Server.method"); + } +} diff --git a/java/java-tests/testData/compileServer/incremental/common/dontMarkDependentsAfterCompileErrors/src/packageA/Server.java.new b/java/java-tests/testData/compileServer/incremental/common/dontMarkDependentsAfterCompileErrors/src/packageA/Server.java.new new file mode 100644 index 000000000000..2dd0712564a5 --- /dev/null +++ b/java/java-tests/testData/compileServer/incremental/common/dontMarkDependentsAfterCompileErrors/src/packageA/Server.java.new @@ -0,0 +1,7 @@ +package packageA; + +public class Server { + public void method() { + System.out.println("Server.method"); + } +} diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java index 5c56bc3ac3cb..5f273028135a 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/JavaBuilderUtil.java @@ -56,6 +56,7 @@ public class JavaBuilderUtil { private static final Key> ALL_AFFECTED_FILES_KEY = Key.create("_all_affected_files_"); private static final Key> ALL_COMPILED_FILES_KEY = Key.create("_all_compiled_files_"); private static final Key> FILES_TO_COMPILE_KEY = Key.create("_files_to_compile_"); + private static final Key> COMPILED_WITH_ERRORS_KEY = Key.create("_compiled_with_errors_"); private static final Key> SUCCESSFULLY_COMPILED_FILES_KEY = Key.create("_successfully_compiled_files_"); private static final Key> SKIP_MARKING_DIRTY_FILTERS_KEY = Key.create("_skip_marking_dirty_filters_"); private static final Key> MAPPINGS_DELTA_KEY = Key.create("_mappings_delta_"); @@ -70,6 +71,10 @@ public class JavaBuilderUtil { getFilesContainer(context, FILES_TO_COMPILE_KEY).addAll(files); } + public static void registerFilesWithErrors(CompileContext context, Collection files) { + getFilesContainer(context, COMPILED_WITH_ERRORS_KEY).addAll(files); + } + public static void registerSuccessfullyCompiled(CompileContext context, File file) { registerSuccessfullyCompiled(context, Collections.singleton(file)); } @@ -174,9 +179,12 @@ public class JavaBuilderUtil { final Set affectedBeforeDif = new THashSet(FileUtil.FILE_HASHING_STRATEGY); affectedBeforeDif.addAll(allAffectedFiles); + final Set compiledWithErrors = getFilesContainer(context, COMPILED_WITH_ERRORS_KEY); + COMPILED_WITH_ERRORS_KEY.set(context, null); + final ModulesBasedFileFilter moduleBasedFilter = new ModulesBasedFileFilter(context, chunk); final boolean incremental = globalMappings.differentiateOnIncrementalMake( - delta, removedPaths, filesToCompile, allCompiledFiles, allAffectedFiles, moduleBasedFilter, + delta, removedPaths, filesToCompile, compiledWithErrors, allCompiledFiles, allAffectedFiles, moduleBasedFilter, CONSTANT_SEARCH_SERVICE.get(context) ); diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java index 3f825e954366..431088265d7e 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/java/dependencyView/Mappings.java @@ -184,12 +184,10 @@ public class Mappings { } } - private void compensateRemovedContent(final Collection compiled) { - if (compiled != null) { - for (final File file : compiled) { - if (!mySourceFileToClasses.containsKey(file)) { - mySourceFileToClasses.put(file, new HashSet()); - } + private void compensateRemovedContent(final @NotNull Collection compiled, final @NotNull Collection compiledWithErrors) { + for (final File file : compiled) { + if (!compiledWithErrors.contains(file) && !mySourceFileToClasses.containsKey(file)) { + mySourceFileToClasses.put(file, new HashSet()); } } } @@ -944,6 +942,7 @@ public class Mappings { final Mappings myDelta; final Collection myFilesToCompile; final Collection myCompiledFiles; + final Collection myCompiledWithErrors; final Collection myAffectedFiles; @Nullable final DependentFilesFilter myFilter; @@ -1067,6 +1066,7 @@ public class Mappings { this.myDelta = delta; this.myFilesToCompile = null; this.myCompiledFiles = null; + this.myCompiledWithErrors = null; this.myAffectedFiles = null; this.myFilter = null; this.myConstantSearch = null; @@ -1087,6 +1087,7 @@ public class Mappings { this.myDelta = delta; this.myFilesToCompile = filesToCompile; this.myCompiledFiles = null; + this.myCompiledWithErrors = null; this.myAffectedFiles = null; this.myFilter = null; this.myConstantSearch = null; @@ -1101,6 +1102,7 @@ public class Mappings { private Differential(final Mappings delta, final Collection removed, final Collection filesToCompile, + final Collection compiledWithErrors, final Collection compiledFiles, final Collection affectedFiles, @NotNull final DependentFilesFilter filter, @@ -1110,6 +1112,7 @@ public class Mappings { this.myDelta = delta; this.myFilesToCompile = filesToCompile; this.myCompiledFiles = compiledFiles; + this.myCompiledWithErrors = compiledWithErrors; this.myAffectedFiles = affectedFiles; this.myFilter = filter; this.myConstantSearch = constantSearch; @@ -1123,7 +1126,11 @@ public class Mappings { } private void processDisappearedClasses() { - myDelta.compensateRemovedContent(myFilesToCompile); + if (myFilesToCompile != null) { + myDelta.compensateRemovedContent( + myFilesToCompile, myCompiledWithErrors != null ? myCompiledWithErrors : Collections.emptySet() + ); + } if (!myEasyMode) { final Collection removed = myDelta.myRemovedFiles; @@ -2231,11 +2238,12 @@ public class Mappings { (final Mappings delta, final Collection removed, final Collection filesToCompile, + final Collection compiledWithErrors, final Collection compiledFiles, final Collection affectedFiles, @NotNull final DependentFilesFilter filter, @Nullable final Callbacks.ConstantAffectionResolver constantSearch) { - return new Differential(delta, removed, filesToCompile, compiledFiles, affectedFiles, filter, constantSearch).differentiate(); + return new Differential(delta, removed, filesToCompile, compiledWithErrors, compiledFiles, affectedFiles, filter, constantSearch).differentiate(); } private void cleanupBackDependency(final int className, diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java index 9b107033d1fb..7223d8bbed58 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/java/JavaBuilder.java @@ -246,6 +246,7 @@ public class JavaBuilder extends ModuleLevelBuilder { // begin compilation round final OutputFilesSink outputSink = new OutputFilesSink(context, outputConsumer, JavaBuilderUtil.getDependenciesRegistrar(context), chunk.getPresentableShortName()); + Collection filesWithErrors = null; try { if (hasSourcesToCompile) { final AtomicReference ref = COMPILER_VERSION_INFO.get(context); @@ -290,7 +291,8 @@ public class JavaBuilder extends ModuleLevelBuilder { } finally { // heuristic: incorrect paths data recovery, so that the next make should not contain non-existing sources in 'recompile' list - for (File file : diagnosticSink.getFilesWithErrors()) { + filesWithErrors = diagnosticSink.getFilesWithErrors(); + for (File file : filesWithErrors) { if (!file.exists()) { FSOperations.markDeleted(context, file); } @@ -315,6 +317,9 @@ public class JavaBuilder extends ModuleLevelBuilder { } finally { JavaBuilderUtil.registerFilesToCompile(context, files); + if (filesWithErrors != null) { + JavaBuilderUtil.registerFilesWithErrors(context, filesWithErrors); + } JavaBuilderUtil.registerSuccessfullyCompiled(context, outputSink.getSuccessfullyCompiled()); } @@ -949,7 +954,7 @@ public class JavaBuilder extends ModuleLevelBuilder { private final CompileContext myContext; private volatile int myErrorCount; private volatile int myWarningCount; - private final Set myFilesWithErrors = new HashSet(); + private final Set myFilesWithErrors = new THashSet(FileUtil.FILE_HASHING_STRATEGY); private DiagnosticSink(CompileContext context) { myContext = context; @@ -1036,7 +1041,9 @@ public class JavaBuilder extends ModuleLevelBuilder { } final String srcPath; if (sourceFile != null) { - myFilesWithErrors.add(sourceFile); + if (kind == BuildMessage.Kind.ERROR) { + myFilesWithErrors.add(sourceFile); + } srcPath = FileUtil.toSystemIndependentName(sourceFile.getPath()); } else { @@ -1065,6 +1072,7 @@ public class JavaBuilder extends ModuleLevelBuilder { return myWarningCount; } + @NotNull public Collection getFilesWithErrors() { return myFilesWithErrors; } diff --git a/jps/jps-builders/testSrc/org/jetbrains/ether/CommonTest.java b/jps/jps-builders/testSrc/org/jetbrains/ether/CommonTest.java index 68e1a5c53afe..f40c48a5a1ef 100644 --- a/jps/jps-builders/testSrc/org/jetbrains/ether/CommonTest.java +++ b/jps/jps-builders/testSrc/org/jetbrains/ether/CommonTest.java @@ -59,6 +59,12 @@ public class CommonTest extends IncrementalTestCase { doTestBuild(2); } + public void testDontMarkDependentsAfterCompileErrors() throws Exception { + setupInitialProject(); + + doTestBuild(2); + } + public void testDeleteClassPackageDoesntMatchRoot() throws Exception { doTest(); }