Search in sources :

Example 6 with DependentsSet

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);
}
Also used : DependentsSet(org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet) IntSet(it.unimi.dsi.fastutil.ints.IntSet) GeneratedResource(org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.GeneratedResource) HashMap(java.util.HashMap) Map(java.util.Map) ArrayDeque(java.util.ArrayDeque) HashSet(java.util.HashSet) IntOpenHashSet(it.unimi.dsi.fastutil.ints.IntOpenHashSet)

Example 7 with DependentsSet

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());
}
Also used : HashCode(org.gradle.internal.hash.HashCode) ImmutableSet(com.google.common.collect.ImmutableSet) DependentsSet(org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet) HashMap(java.util.HashMap) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 8 with DependentsSet

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();
}
Also used : HashSet(java.util.HashSet) DependentsSet(org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet) Set(java.util.Set) Nullable(javax.annotation.Nullable) DependentsSet(org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet) HashSet(java.util.HashSet)

Aggregations

DependentsSet (org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet)8 IntSet (it.unimi.dsi.fastutil.ints.IntSet)3 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 Map (java.util.Map)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 ArrayDeque (java.util.ArrayDeque)2 GeneratedResource (org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.GeneratedResource)2 HashCode (org.gradle.internal.hash.HashCode)2 ImmutableSet (com.google.common.collect.ImmutableSet)1 IntOpenHashSet (it.unimi.dsi.fastutil.ints.IntOpenHashSet)1 Set (java.util.Set)1 Nullable (javax.annotation.Nullable)1