use of org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet in project gradle by gradle.
the class ClassSetAnalysisData method reduceToTypesAffecting.
/**
* Returns a shrunk down version of this class set, which only contains information about types that could affect the other set.
* This is useful for reducing the size of classpath snapshots, since a classpath usually contains a lot more types than the client
* actually uses.
*
* Apart from the obvious classes that are directly used by the other set, we also need to keep any classes that might affect any number
* of classes, like package-info, module-info and inlineable constants.
*/
public ClassSetAnalysisData reduceToTypesAffecting(ClassSetAnalysisData other, CompilerApiData compilerApiData) {
if (fullRebuildCause != null) {
return this;
}
Set<String> usedClasses = new HashSet<>(classHashes.size());
for (Map.Entry<String, DependentsSet> entry : dependents.entrySet()) {
if (entry.getValue().isDependencyToAll()) {
usedClasses.add(entry.getKey());
}
}
for (String cls : classHashes.keySet()) {
if (cls.endsWith(PACKAGE_INFO)) {
usedClasses.add(cls);
}
}
usedClasses.addAll(other.dependents.keySet());
Multimap<String, String> dependencies = getForwardDependencyView();
Set<String> visited = new HashSet<>(usedClasses.size());
Deque<String> pending = new ArrayDeque<>(usedClasses);
while (!pending.isEmpty()) {
String cls = pending.poll();
if (visited.add(cls)) {
usedClasses.add(cls);
pending.addAll(dependencies.get(cls));
}
}
Set<String> usedConstantSources = compilerApiData.isSupportsConstantsMapping() ? compilerApiData.getConstantToClassMapping().getConstantDependents().keySet() : classesToConstants.keySet();
usedClasses.addAll(usedConstantSources);
Map<String, HashCode> classHashes = new HashMap<>(usedClasses.size());
Map<String, DependentsSet> dependents = new HashMap<>(usedClasses.size());
Map<String, IntSet> classesToConstants = new HashMap<>(usedClasses.size());
for (String usedClass : usedClasses) {
HashCode hash = this.classHashes.get(usedClass);
if (hash != null) {
classHashes.put(usedClass, hash);
DependentsSet dependentsSet = this.dependents.get(usedClass);
if (dependentsSet != null) {
if (dependentsSet.isDependencyToAll()) {
dependents.put(usedClass, dependentsSet);
} else {
Set<String> usedAccessibleClasses = new HashSet<>(dependentsSet.getAccessibleDependentClasses());
usedAccessibleClasses.retainAll(usedClasses);
if (!usedAccessibleClasses.isEmpty()) {
dependents.put(usedClass, DependentsSet.dependentClasses(Collections.emptySet(), usedAccessibleClasses));
}
}
}
IntSet constants = this.classesToConstants.get(usedClass);
if (constants != null && usedConstantSources.contains(usedClass)) {
classesToConstants.put(usedClass, constants);
}
}
}
return new ClassSetAnalysisData(classHashes, dependents, classesToConstants, null);
}
use of org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet in project gradle by gradle.
the class SourceFileChangeProcessor method processChange.
public void processChange(Set<String> classNames, RecompilationSpec spec) {
spec.addClassesToCompile(classNames);
DependentsSet actualDependents = previousCompilation.findDependentsOfSourceChanges(classNames);
if (actualDependents.isDependencyToAll()) {
spec.setFullRebuildCause(actualDependents.getDescription());
return;
}
spec.addClassesToCompile(actualDependents.getAllDependentClasses());
spec.addResourcesToGenerate(actualDependents.getDependentResources());
}
use of org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet in project gradle by gradle.
the class AbstractRecompilationSpecProvider method processClasspathChanges.
private void processClasspathChanges(CurrentCompilation current, PreviousCompilation previous, RecompilationSpec spec) {
DependentsSet dependents = current.findDependentsOfClasspathChanges(previous);
if (dependents.isDependencyToAll()) {
spec.setFullRebuildCause(dependents.getDescription());
return;
}
spec.addClassesToCompile(dependents.getPrivateDependentClasses());
spec.addClassesToCompile(dependents.getAccessibleDependentClasses());
spec.addResourcesToGenerate(dependents.getDependentResources());
}
use of org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet in project gradle by gradle.
the class ClassSetAnalysis method findDirectDependents.
/**
* Finds all the classes and resources that are directly affected by the given one. This includes:
*
* - Classes that referenced this class in their bytecode
* - Classes that use a constant declared in this class
* - Classes and resources that were generated from this class
*/
private DependentsSet findDirectDependents(String className) {
Set<String> generatedClasses = annotationProcessingData.getGeneratedTypesByOrigin().getOrDefault(className, Collections.emptySet());
Set<GeneratedResource> generatedResources = annotationProcessingData.getGeneratedResourcesByOrigin().getOrDefault(className, Collections.emptySet());
DependentsSet generatedDeps = DependentsSet.dependents(Collections.emptySet(), generatedClasses, generatedResources);
return DependentsSet.merge(Arrays.asList(classAnalysis.getDependents(className), compilerApiData.getConstantDependentsForClass(className), generatedDeps));
}
use of org.gradle.api.internal.tasks.compile.incremental.compilerapi.deps.DependentsSet in project gradle by gradle.
the class ClassSetAnalysis method findChangesSince.
/**
* Computes the types affected by the changes since some other class set, including transitively affected classes.
*/
public ClassSetDiff findChangesSince(ClassSetAnalysis other) {
DependentsSet directChanges = classAnalysis.getChangedClassesSince(other.classAnalysis);
if (directChanges.isDependencyToAll()) {
return new ClassSetDiff(directChanges, Collections.emptyMap());
}
DependentsSet transitiveChanges = other.findTransitiveDependents(directChanges.getAllDependentClasses(), Collections.emptyMap());
if (transitiveChanges.isDependencyToAll()) {
return new ClassSetDiff(transitiveChanges, Collections.emptyMap());
}
DependentsSet allChanges = DependentsSet.merge(Arrays.asList(directChanges, transitiveChanges));
Map<String, IntSet> changedConstants = findChangedConstants(other, allChanges);
return new ClassSetDiff(allChanges, changedConstants);
}
Aggregations