do not mark for recompilation files that depend on the files compiled with errors

This commit is contained in:
Eugene Zhuravlev
2016-05-19 15:09:42 +02:00
parent a4877d214f
commit 52436089d9
8 changed files with 74 additions and 12 deletions
@@ -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
@@ -0,0 +1,9 @@
package packageA;
public class Client {
public void method(Server server) {
server.method();
}
}
@@ -0,0 +1,7 @@
package packageA;
public class Server {
public void method() {
System.out.println("Server.method");
}
}
@@ -0,0 +1,7 @@
package packageA;
public class Server {
public void method() {
System.out.println("Server.method"); <some-error!>
}
}
@@ -56,6 +56,7 @@ public class JavaBuilderUtil {
private static final Key<Set<File>> ALL_AFFECTED_FILES_KEY = Key.create("_all_affected_files_");
private static final Key<Set<File>> ALL_COMPILED_FILES_KEY = Key.create("_all_compiled_files_");
private static final Key<Set<File>> FILES_TO_COMPILE_KEY = Key.create("_files_to_compile_");
private static final Key<Set<File>> COMPILED_WITH_ERRORS_KEY = Key.create("_compiled_with_errors_");
private static final Key<Set<File>> SUCCESSFULLY_COMPILED_FILES_KEY = Key.create("_successfully_compiled_files_");
private static final Key<List<FileFilter>> SKIP_MARKING_DIRTY_FILTERS_KEY = Key.create("_skip_marking_dirty_filters_");
private static final Key<Pair<Mappings, Callbacks.Backend>> 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<File> 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<File> affectedBeforeDif = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
affectedBeforeDif.addAll(allAffectedFiles);
final Set<File> 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)
);
@@ -184,12 +184,10 @@ public class Mappings {
}
}
private void compensateRemovedContent(final Collection<File> compiled) {
if (compiled != null) {
for (final File file : compiled) {
if (!mySourceFileToClasses.containsKey(file)) {
mySourceFileToClasses.put(file, new HashSet<ClassRepr>());
}
private void compensateRemovedContent(final @NotNull Collection<File> compiled, final @NotNull Collection<File> compiledWithErrors) {
for (final File file : compiled) {
if (!compiledWithErrors.contains(file) && !mySourceFileToClasses.containsKey(file)) {
mySourceFileToClasses.put(file, new HashSet<ClassRepr>());
}
}
}
@@ -944,6 +942,7 @@ public class Mappings {
final Mappings myDelta;
final Collection<File> myFilesToCompile;
final Collection<File> myCompiledFiles;
final Collection<File> myCompiledWithErrors;
final Collection<File> 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<String> removed,
final Collection<File> filesToCompile,
final Collection<File> compiledWithErrors,
final Collection<File> compiledFiles,
final Collection<File> 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.<File>emptySet()
);
}
if (!myEasyMode) {
final Collection<String> removed = myDelta.myRemovedFiles;
@@ -2231,11 +2238,12 @@ public class Mappings {
(final Mappings delta,
final Collection<String> removed,
final Collection<File> filesToCompile,
final Collection<File> compiledWithErrors,
final Collection<File> compiledFiles,
final Collection<File> 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,
@@ -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<File> filesWithErrors = null;
try {
if (hasSourcesToCompile) {
final AtomicReference<String> 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<File> myFilesWithErrors = new HashSet<File>();
private final Set<File> myFilesWithErrors = new THashSet<File>(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<File> getFilesWithErrors() {
return myFilesWithErrors;
}
@@ -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();
}