String inputFileTreeChanges()

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();
    }