blob: 4205abce0ac756124762d2c41f302bd0c0143798 [file] [log] [blame]
// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
import com.google.common.collect.Iterables;
import java.util.Objects;
import java.util.function.Function;
public class BottomUpClassHierarchyTraversal<T extends DexClass>
extends ClassHierarchyTraversal<T, BottomUpClassHierarchyTraversal<T>> {
private final Function<T, Iterable<T>> immediateSubtypesProvider;
private BottomUpClassHierarchyTraversal(
AppView<? extends AppInfoWithClassHierarchy> appView,
Function<T, Iterable<T>> immediateSubtypesProvider,
Scope scope) {
super(appView, scope);
this.immediateSubtypesProvider = immediateSubtypesProvider;
}
/**
* Returns a visitor that can be used to visit all the classes (including class path and library
* classes) that are reachable from a given set of sources.
*/
public static BottomUpClassHierarchyTraversal<DexClass> forAllClasses(
AppView<? extends AppInfoWithClassHierarchy> appView, SubtypingInfo subtypingInfo) {
return new BottomUpClassHierarchyTraversal<>(
appView,
clazz ->
Iterables.filter(
Iterables.transform(
subtypingInfo.allImmediateSubtypes(clazz.getType()),
appView::contextIndependentDefinitionFor),
Objects::nonNull),
Scope.ALL_CLASSES);
}
/**
* Returns a visitor that can be used to visit all the program classes that are reachable from a
* given set of sources.
*/
public static BottomUpClassHierarchyTraversal<DexProgramClass> forProgramClasses(
AppView<? extends AppInfoWithClassHierarchy> appView,
ImmediateProgramSubtypingInfo immediateSubtypingInfo) {
return forProgramClasses(appView, immediateSubtypingInfo::getSubclasses);
}
/**
* Returns a visitor that can be used to visit all the program classes that are reachable from a
* given set of sources.
*/
public static BottomUpClassHierarchyTraversal<DexProgramClass> forProgramClasses(
AppView<? extends AppInfoWithClassHierarchy> appView,
Function<DexProgramClass, Iterable<DexProgramClass>> immediateSubtypesProvider) {
return new BottomUpClassHierarchyTraversal<>(
appView, immediateSubtypesProvider, Scope.ONLY_PROGRAM_CLASSES);
}
@Override
BottomUpClassHierarchyTraversal<T> self() {
return this;
}
@Override
void addDependentsToWorklist(DexClass clazz) {
@SuppressWarnings("unchecked")
T clazzWithTypeT = (T) clazz;
if (excludeInterfaces && clazzWithTypeT.isInterface()) {
return;
}
if (visited.contains(clazzWithTypeT)) {
return;
}
worklist.addFirst(clazzWithTypeT);
// Add subtypes to worklist.
for (DexClass subclass : immediateSubtypesProvider.apply(clazzWithTypeT)) {
if (scope != Scope.ONLY_PROGRAM_CLASSES || subclass.isProgramClass()) {
addDependentsToWorklist(subclass);
}
}
}
}