use of org.gradle.api.internal.tasks.compile.incremental.deps.ClassSetAnalysisData in project gradle by gradle.
the class IncrementalCompilerDecorator method getCompiler.
private Compiler<JavaCompileSpec> getCompiler(IncrementalTaskInputs inputs, CompilationSourceDirs sourceDirs) {
if (!inputs.isIncremental()) {
LOG.info("{} - is not incremental (e.g. outputs have changed, no previous execution, etc.).", displayName);
return cleaningCompiler;
}
if (!sourceDirs.canInferSourceRoots()) {
LOG.info("{} - is not incremental. Unable to infer the source directories.", displayName);
return cleaningCompiler;
}
List<AnnotationProcessorDeclaration> nonIncrementalProcessors = getNonIncrementalProcessors();
if (!nonIncrementalProcessors.isEmpty()) {
warnAboutNonIncrementalProcessors(nonIncrementalProcessors);
return cleaningCompiler;
}
ClassSetAnalysisData data = compileCaches.getLocalClassSetAnalysisStore().get();
if (data == null) {
LOG.info("{} - is not incremental. No class analysis data available from the previous build.", displayName);
return cleaningCompiler;
}
PreviousCompilation previousCompilation = new PreviousCompilation(new ClassSetAnalysis(data), compileCaches.getLocalJarClasspathSnapshotStore(), compileCaches.getJarSnapshotCache(), compileCaches.getAnnotationProcessorPathStore());
return new SelectiveCompiler(inputs, previousCompilation, cleaningCompiler, staleClassDetecter, compilationInitializer, jarClasspathSnapshotMaker);
}
use of org.gradle.api.internal.tasks.compile.incremental.deps.ClassSetAnalysisData in project gradle by gradle.
the class JarChangeDependentsFinder method getActualDependents.
public DependentsSet getActualDependents(InputFileDetails jarChangeDetails, JarArchive jarArchive) {
if (jarChangeDetails.isAdded()) {
if (jarClasspathSnapshot.isAnyClassDuplicated(jarArchive)) {
// to avoid calculation which class gets on the classpath first, rebuild all
return DependentsSet.dependencyToAll("at least one of the classes of '" + jarArchive.file.getName() + "' is already present in classpath");
} else {
// none of the new classes in the jar are duplicated on classpath, don't rebuild
return DependentsSet.empty();
}
}
final JarSnapshot previous = previousCompilation.getJarSnapshot(jarChangeDetails.getFile());
if (previous == null) {
// for example, a class (in jar) with a constant might have changed into a class without a constant - we need to rebuild everything
return DependentsSet.dependencyToAll("missing jar snapshot of '" + jarArchive.file.getName() + "' from previous build");
}
if (jarChangeDetails.isRemoved()) {
DependentsSet allClasses = previous.getAllClasses();
if (allClasses.isDependencyToAll()) {
return DependentsSet.dependencyToAll("at least one of the classes of removed jar '" + jarArchive.file.getName() + "' requires it");
}
// recompile all dependents of all the classes from jar
return previousCompilation.getDependents(allClasses.getDependentClasses(), previous.getAllConstants(allClasses));
}
if (jarChangeDetails.isModified()) {
final JarSnapshot currentSnapshot = jarClasspathSnapshot.getSnapshot(jarArchive);
AffectedClasses affected = currentSnapshot.getAffectedClassesSince(previous);
DependentsSet altered = affected.getAltered();
if (altered.isDependencyToAll()) {
// at least one of the classes changed in the jar is a 'dependency-to-all'
return altered;
}
if (jarClasspathSnapshot.isAnyClassDuplicated(affected.getAdded())) {
// For safe measure rebuild everything
return DependentsSet.dependencyToAll("at least one of the classes of modified jar '" + jarArchive.file.getName() + "' is already present in the classpath");
}
// recompile all dependents of the classes changed in the jar
final Set<String> dependentClasses = Sets.newHashSet(altered.getDependentClasses());
final Deque<String> queue = Lists.newLinkedList(dependentClasses);
while (!queue.isEmpty()) {
final String dependentClass = queue.poll();
jarClasspathSnapshot.forEachSnapshot(new Action<JarSnapshot>() {
@Override
public void execute(JarSnapshot jarSnapshot) {
if (jarSnapshot != previous) {
// we need to find in the other jars classes that would potentially extend classes changed
// in the current snapshot (they are intermediates)
ClassSetAnalysisData data = jarSnapshot.getData().data;
Set<String> children = data.getChildren(dependentClass);
for (String child : children) {
if (dependentClasses.add(child)) {
queue.add(child);
}
}
}
}
});
}
return previousCompilation.getDependents(dependentClasses, currentSnapshot.getRelevantConstants(previous, dependentClasses));
}
throw new IllegalArgumentException("Unknown input file details provided: " + jarChangeDetails);
}
use of org.gradle.api.internal.tasks.compile.incremental.deps.ClassSetAnalysisData in project gradle by gradle.
the class JarSnapshotDataSerializer method read.
@Override
public JarSnapshotData read(Decoder decoder) throws Exception {
HashCode hash = hashCodeSerializer.read(decoder);
Map<String, HashCode> hashes = mapSerializer.read(decoder);
ClassSetAnalysisData data = analysisSerializer.read(decoder);
return new JarSnapshotData(hash, hashes, data);
}
use of org.gradle.api.internal.tasks.compile.incremental.deps.ClassSetAnalysisData in project gradle by gradle.
the class ClassSetAnalysisUpdater method updateAnalysis.
public void updateAnalysis(JavaCompileSpec spec) {
Timer clock = Timers.startTimer();
Set<File> baseDirs = Sets.newLinkedHashSet();
baseDirs.add(spec.getDestinationDir());
Iterables.addAll(baseDirs, Iterables.filter(spec.getCompileClasspath(), IS_CLASS_DIRECTORY));
ClassFilesAnalyzer analyzer = new ClassFilesAnalyzer(this.analyzer, fileHasher);
for (File baseDir : baseDirs) {
fileOperations.fileTree(baseDir).visit(analyzer);
}
ClassSetAnalysisData data = analyzer.getAnalysis();
stash.put(data);
LOG.info("Class dependency analysis for incremental compilation took {}.", clock.getElapsed());
}
use of org.gradle.api.internal.tasks.compile.incremental.deps.ClassSetAnalysisData in project gradle by gradle.
the class ClassSetAnalysisUpdater method updateAnalysis.
public void updateAnalysis(JavaCompileSpec spec, WorkResult result) {
if (result instanceof RecompilationNotNecessary) {
return;
}
Timer clock = Time.startTimer();
CompilationResultAnalyzer analyzer = new CompilationResultAnalyzer(this.analyzer, fileHasher);
visitAnnotationProcessingResult(spec, result, analyzer);
visitClassFiles(spec, analyzer);
ClassSetAnalysisData data = analyzer.getAnalysis();
stash.put(data);
LOG.info("Class dependency analysis for incremental compilation took {}.", clock.getElapsed());
}
Aggregations