in src/main/java/org/apache/maven/plugin/compiler/IncrementalBuild.java [540:619]
String inputFileTreeChanges() throws IOException {
final Map<Path, SourceInfo> previousBuild;
try {
previousBuild = loadCache();
} catch (NoSuchFileException e) {
return "Compiling all files.";
} catch (IOException e) {
return causeOfRebuild("information about the previous build cannot be read", true)
.append(System.lineSeparator())
.append(e)
.toString();
}
boolean rebuild = false;
boolean allChanged = true;
List<Path> added = new ArrayList<>();
for (SourceFile source : sourceFiles) {
SourceInfo previous = previousBuild.remove(source.file);
if (previous != null) {
if (source.lastModified - previous.lastModified <= staleMillis) {
/*
* Source file has not been modified. But we still need to check if the output file exists.
* It may be, for example, because the compilation failed during the previous build because
* of another class.
*/
allChanged = false;
if (previous.omitted) {
continue;
}
Path output = source.getOutputFile();
if (Files.exists(output, LINK_OPTIONS)) {
continue; // Source file has not been modified and output file exists.
}
} else if (rebuildOnChange) {
return causeOfRebuild("at least one source file changed", false)
.toString();
}
} else if (!source.ignoreModification) {
if (showCompilationChanges) {
added.add(source.file);
}
rebuild |= rebuildOnAdd;
}
source.isNewOrModified = true;
}
/*
* The files remaining in `previousBuild` are files that have been removed since the last build.
* If no file has been removed, then there is no need to rebuild the whole project (added files
* do not require a full build).
*/
if (previousBuild.isEmpty()) {
if (allChanged) {
return causeOfRebuild("all source files changed", false).toString();
}
if (!rebuild) {
return null;
}
}
/*
* If some files have been removed, we need to delete the corresponding output files.
* If the output file extension is ".class", then many files may be deleted because
* the output file may be accompanied by inner classes (e.g. {@code "Foo$0.class"}).
*/
for (Map.Entry<Path, SourceInfo> removed : previousBuild.entrySet()) {
removed.getValue().deleteClassFiles(removed.getKey());
}
/*
* At this point, it has been decided that all source files will be recompiled.
* Format a message saying why.
*/
StringBuilder causeOfRebuild = causeOfRebuild("of added or removed source files", showCompilationChanges);
if (showCompilationChanges) {
for (Path fileAdded : added) {
causeOfRebuild.append(System.lineSeparator()).append(" + ").append(fileAdded);
}
for (Path fileRemoved : previousBuild.keySet()) {
causeOfRebuild.append(System.lineSeparator()).append(" - ").append(fileRemoved);
}
}
return causeOfRebuild.toString();
}