use of org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet in project gradle by gradle.
the class ClassSetAnalysis method findTransitiveDependents.
/**
* Computes the transitive dependents of a set of changed classes. If the classes had any changes to inlineable constants, these need to be provided as the second parameter.
*
* If incremental annotation processing encountered issues in the previous compilation, a full recompilation is required.
* If any inlineable constants have changed and the compiler does not support exact constant dependency tracking, then a full recompilation is required.
* Otherwise follows the below rules for all of the given classes, as well as the classes that were marked as "always recompile" by annotation processing:
*
* Starts at this class and capture all classes that reference this class and all classes and resources that were generated from this class.
* Then does the same analysis for all classes that expose this class on their ABI recursively until no more new classes are discovered.
*/
public DependentsSet findTransitiveDependents(Collection<String> classes, Map<String, IntSet> changedConstantsByClass) {
if (classes.isEmpty()) {
return DependentsSet.empty();
}
String fullRebuildCause = annotationProcessingData.getFullRebuildCause();
if (fullRebuildCause != null) {
return DependentsSet.dependencyToAll(fullRebuildCause);
}
if (!compilerApiData.isSupportsConstantsMapping()) {
for (Map.Entry<String, IntSet> changedConstantsOfClass : changedConstantsByClass.entrySet()) {
if (!changedConstantsOfClass.getValue().isEmpty()) {
return DependentsSet.dependencyToAll("an inlineable constant in '" + changedConstantsOfClass.getKey() + "' has changed");
}
}
}
Set<String> privateDependents = new HashSet<>();
Set<String> accessibleDependents = new HashSet<>();
Set<GeneratedResource> dependentResources = new HashSet<>(annotationProcessingData.getGeneratedResourcesDependingOnAllOthers());
Set<String> visited = new HashSet<>();
Deque<String> remaining = new ArrayDeque<>(classes);
remaining.addAll(annotationProcessingData.getGeneratedTypesDependingOnAllOthers());
while (!remaining.isEmpty()) {
String current = remaining.pop();
if (!visited.add(current)) {
continue;
}
accessibleDependents.add(current);
DependentsSet dependents = findDirectDependents(current);
if (dependents.isDependencyToAll()) {
return dependents;
}
dependentResources.addAll(dependents.getDependentResources());
privateDependents.addAll(dependents.getPrivateDependentClasses());
remaining.addAll(dependents.getAccessibleDependentClasses());
}
privateDependents.removeAll(classes);
accessibleDependents.removeAll(classes);
return DependentsSet.dependents(privateDependents, accessibleDependents, dependentResources);
}
use of org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet in project gradle by gradle.
the class ClassSetAnalysisData method getChangedClassesSince.
/**
* Returns the additions, changes and removals compared to the other class set.
* Only includes changes that could possibly trigger recompilation.
* For example, adding a new class can't affect anyone, since it didn't exist before.
*
* Does not include classes that are transitively affected by the additions/removals/changes.
*/
public DependentsSet getChangedClassesSince(ClassSetAnalysisData other) {
if (fullRebuildCause != null) {
return DependentsSet.dependencyToAll(fullRebuildCause);
}
if (other.fullRebuildCause != null) {
return DependentsSet.dependencyToAll(other.fullRebuildCause);
}
ImmutableSet.Builder<String> changed = ImmutableSet.builder();
for (String added : Sets.difference(classHashes.keySet(), other.classHashes.keySet())) {
DependentsSet dependents = getDependents(added);
if (dependents.isDependencyToAll()) {
return dependents;
}
if (added.endsWith(PACKAGE_INFO)) {
changed.add(added);
}
}
for (Map.Entry<String, HashCode> removedOrChanged : Sets.difference(other.classHashes.entrySet(), classHashes.entrySet())) {
DependentsSet dependents = getDependents(removedOrChanged.getKey());
if (dependents.isDependencyToAll()) {
return dependents;
}
changed.add(removedOrChanged.getKey());
}
return DependentsSet.dependentClasses(ImmutableSet.of(), changed.build());
}
use of org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet in project gradle by gradle.
the class ConstantToDependentsMappingMerger method updateClassToConstantsMapping.
private ConstantToDependentsMapping updateClassToConstantsMapping(ConstantToDependentsMapping newMapping, ConstantToDependentsMapping oldMapping, Set<String> changedClasses) {
ConstantToDependentsMappingBuilder builder = ConstantToDependentsMapping.builder();
oldMapping.getConstantDependents().keySet().stream().filter(constantOrigin -> !changedClasses.contains(constantOrigin)).forEach(constantOrigin -> {
DependentsSet dependents = oldMapping.getConstantDependentsForClass(constantOrigin);
Set<String> accessibleDependents = new HashSet<>(dependents.getAccessibleDependentClasses());
accessibleDependents.removeIf(changedClasses::contains);
builder.addAccessibleDependents(constantOrigin, accessibleDependents);
Set<String> privateDependents = new HashSet<>(dependents.getPrivateDependentClasses());
privateDependents.removeIf(changedClasses::contains);
builder.addPrivateDependents(constantOrigin, privateDependents);
});
newMapping.getConstantDependents().keySet().forEach(constantOrigin -> {
DependentsSet dependents = newMapping.getConstantDependentsForClass(constantOrigin);
builder.addAccessibleDependents(constantOrigin, dependents.getAccessibleDependentClasses());
builder.addPrivateDependents(constantOrigin, dependents.getPrivateDependentClasses());
});
return builder.build();
}
Aggregations