public class JavaSerializationShrinkerGraph extends java.lang.Object implements ShrinkerGraph<java.lang.String>
ShrinkerGraph implementation that uses strings, maps and Java serialization.| Modifier and Type | Method and Description |
|---|---|
void |
addAnnotation(java.lang.String node,
java.lang.String annotationName)
Adds an annotation to the given node.
|
java.lang.String |
addClass(java.lang.String name,
java.lang.String superName,
java.lang.String[] interfaces,
int modifiers,
java.io.File classFile)
Creates a new node representing the given class, and adds it to the graph.
|
void |
addDependency(java.lang.String source,
java.lang.String target,
DependencyType type)
Adds a new dependency (edge) to the graph.
|
java.lang.String |
addMember(java.lang.String owner,
java.lang.String name,
java.lang.String desc,
int modifiers)
Creates a new node representing the given class member (method or field), and adds it to the
graph.
|
void |
addRoots(java.util.Map<java.lang.String,DependencyType> symbolsToKeep,
AbstractShrinker.CounterSet counterSet)
Adds the given roots to the graph, for the given
AbstractShrinker.CounterSet. |
void |
addTypeFromGenericSignature(java.lang.String klass,
java.lang.String type)
Records a type referenced in the generic signatures by the given class.
|
void |
checkDependencies(ShrinkerLogger shrinkerLogger)
Checks that all edges in the graph point to fully known nodes.
|
void |
clearCounters(com.android.ide.common.internal.WaitableExecutor executor)
Clears all the counters, for all nodes.
|
static JavaSerializationShrinkerGraph |
empty(java.io.File stateDir) |
java.lang.String |
findMatchingMethod(java.lang.String klass,
java.lang.String method)
Searches the given class for a method with the same name and descriptor as the provided
method.
|
java.lang.Iterable<java.lang.String> |
getAllProgramClasses()
Returns all nodes that represent program classes.
|
java.lang.Iterable<java.lang.String> |
getAnnotations(java.lang.String node)
Returns all annotations present on the given node.
|
java.lang.String |
getClassName(java.lang.String klass)
Returns the internal class name for the given class node.
|
java.lang.String |
getClassReference(java.lang.String className)
Returns the node representing the given class.
|
java.util.Set<Dependency<java.lang.String>> |
getDependencies(java.lang.String node)
Returns all dependencies of the given node, i.e.
|
java.util.Set<java.lang.String> |
getFields(java.lang.String klass)
Returns all fields of the given class.
|
java.lang.String |
getFullMemberName(java.lang.String member)
Returns the full name of a given method or field, e.g.
|
java.lang.String[] |
getInterfaces(java.lang.String klass)
Gets the interfaces of a given class.
|
java.lang.String |
getMemberDescriptor(java.lang.String member)
Returns the name of a given method or field.
|
java.lang.String |
getMemberName(java.lang.String member)
Returns the name of a given method or field.
|
java.lang.String |
getMemberReference(java.lang.String className,
java.lang.String memberName,
java.lang.String desc)
Returns the node representing a given class member (method or field).
|
java.util.Set<java.lang.String> |
getMethods(java.lang.String klass)
Returns all methods of the given class.
|
int |
getModifiers(java.lang.String node)
Returns the modifiers for the given node, as used by
ClassVisitor. |
java.lang.String |
getOwnerClass(java.lang.String member)
Returns the owner class of a given method or field.
|
java.util.Set<java.lang.String> |
getReachableClasses(AbstractShrinker.CounterSet counterSet)
Returns all classes that are reachable in a given
AbstractShrinker.CounterSet. |
java.util.Set<java.lang.String> |
getReachableMembersLocalNames(java.lang.String klass,
AbstractShrinker.CounterSet counterSet)
Returns all the reachable members of the given class, in the name:desc format, without the
class name at the front.
|
java.util.Map<java.lang.String,DependencyType> |
getRoots(AbstractShrinker.CounterSet counterSet)
Returns the roots.
|
java.io.File |
getSourceFile(java.lang.String klass)
Returns the source file that this class was read from.
|
java.lang.String |
getSuperclass(java.lang.String klass)
Returns the superclass of the given class.
|
java.util.Set<java.lang.String> |
getTypesFromGenericSignatures(java.lang.String klass)
Gets all types referenced from generic signatures of a given class.
|
boolean |
incrementAndCheck(java.lang.String node,
DependencyType type,
AbstractShrinker.CounterSet counterSet)
Increments the counter of the given type (
DependencyType) and checks if this
operation made the node reachable, atomically. |
boolean |
isClassKnown(java.lang.String klass)
Checks if the given given (representing a class) was added to the graph.
|
boolean |
isProgramClass(java.lang.String klass)
Checks if the given class comes from the program or the platform (and we don't control it).
|
boolean |
isReachable(java.lang.String node,
AbstractShrinker.CounterSet counterSet)
Checks if the given node is reachable, using the given
AbstractShrinker.CounterSet. |
static JavaSerializationShrinkerGraph |
readFromDir(java.io.File dir,
java.lang.ClassLoader classLoader)
Constructs a graph by deserializing saved state.
|
void |
removeAllCodeDependencies(java.lang.String node)
Removes all
DependencyType.REQUIRED_CODE_REFERENCE and DependencyType.REQUIRED_CODE_REFERENCE_REFLECTION edges that start from the given node. |
void |
saveState()
Serializes the graph to disk, in a location that will be known when building incrementally.
|
public static JavaSerializationShrinkerGraph empty(java.io.File stateDir)
public static JavaSerializationShrinkerGraph readFromDir(@NonNull java.io.File dir, @NonNull java.lang.ClassLoader classLoader) throws java.io.IOException
dir - directory where the state was savedclassLoader - class loader used to resolve class namesjava.io.IOException@NonNull
public java.lang.String addMember(@NonNull
java.lang.String owner,
@NonNull
java.lang.String name,
@NonNull
java.lang.String desc,
int modifiers)
ShrinkerGraphaddMember in interface ShrinkerGraph<java.lang.String>owner - internal name of the owner classname - class member namedesc - class member descriptormodifiers - modifiers bit set, as used by ClassVisitor@NonNull
public java.lang.String getMemberReference(@NonNull
java.lang.String className,
@NonNull
java.lang.String memberName,
@NonNull
java.lang.String desc)
ShrinkerGraphgetMemberReference in interface ShrinkerGraph<java.lang.String>className - internal name of the owner classmemberName - member namedesc - member descriptorpublic void addDependency(@NonNull
java.lang.String source,
@NonNull
java.lang.String target,
@NonNull
DependencyType type)
ShrinkerGraphaddDependency in interface ShrinkerGraph<java.lang.String>source - source nodetarget - target nodetype - edge type@NonNull public java.util.Set<Dependency<java.lang.String>> getDependencies(@NonNull java.lang.String node)
ShrinkerGraphgetDependencies in interface ShrinkerGraph<java.lang.String>@NonNull
public java.util.Set<java.lang.String> getMethods(@NonNull
java.lang.String klass)
ShrinkerGraphgetMethods in interface ShrinkerGraph<java.lang.String>@NonNull
public java.util.Set<java.lang.String> getFields(@NonNull
java.lang.String klass)
ShrinkerGraphgetFields in interface ShrinkerGraph<java.lang.String>public boolean incrementAndCheck(@NonNull
java.lang.String node,
@NonNull
DependencyType type,
@NonNull
AbstractShrinker.CounterSet counterSet)
ShrinkerGraphDependencyType) and checks if this
operation made the node reachable, atomically.incrementAndCheck in interface ShrinkerGraph<java.lang.String>node - graph nodetype - type of countercounterSet - the AbstractShrinker.CounterSet to usepublic void saveState()
throws java.io.IOException
ShrinkerGraphsaveState in interface ShrinkerGraph<java.lang.String>java.io.IOExceptionpublic boolean isReachable(@NonNull
java.lang.String node,
@NonNull
AbstractShrinker.CounterSet counterSet)
ShrinkerGraphAbstractShrinker.CounterSet.isReachable in interface ShrinkerGraph<java.lang.String>public void removeAllCodeDependencies(@NonNull
java.lang.String node)
ShrinkerGraphDependencyType.REQUIRED_CODE_REFERENCE and DependencyType.REQUIRED_CODE_REFERENCE_REFLECTION edges that start from the given node.removeAllCodeDependencies in interface ShrinkerGraph<java.lang.String>@Nullable
public java.lang.String getSuperclass(@NonNull
java.lang.String klass)
throws ClassLookupException
ShrinkerGraphgetSuperclass in interface ShrinkerGraph<java.lang.String>ClassLookupException - if the node for the superclass has not been created (yet?).@Nullable
public java.lang.String findMatchingMethod(@NonNull
java.lang.String klass,
@NonNull
java.lang.String method)
ShrinkerGraphfindMatchingMethod in interface ShrinkerGraph<java.lang.String>klass - class to searchmethod - method to matchpublic boolean isProgramClass(@NonNull
java.lang.String klass)
ShrinkerGraphProgram classes are written to the output and can be changed in the process. Library classes come from the SDK and we don't control them.
isProgramClass in interface ShrinkerGraph<java.lang.String>@NonNull
public java.lang.String[] getInterfaces(java.lang.String klass)
throws ClassLookupException
ShrinkerGraphgetInterfaces in interface ShrinkerGraph<java.lang.String>ClassLookupException - if the node for one of the interfaces has not been created (yet)public void checkDependencies(ShrinkerLogger shrinkerLogger)
ShrinkerGraphIf it's not the case, warnings are emitted using the given ShrinkerLogger and
these edges are removed from the graph.
checkDependencies in interface ShrinkerGraph<java.lang.String>public void addTypeFromGenericSignature(@NonNull
java.lang.String klass,
@NonNull
java.lang.String type)
ShrinkerGraphaddTypeFromGenericSignature in interface ShrinkerGraph<java.lang.String>@NonNull
public java.util.Set<java.lang.String> getTypesFromGenericSignatures(@NonNull
java.lang.String klass)
ShrinkerGraphgetTypesFromGenericSignatures in interface ShrinkerGraph<java.lang.String>@NonNull
public java.util.Set<java.lang.String> getReachableClasses(@NonNull
AbstractShrinker.CounterSet counterSet)
ShrinkerGraphAbstractShrinker.CounterSet.getReachableClasses in interface ShrinkerGraph<java.lang.String>public java.io.File getSourceFile(@NonNull
java.lang.String klass)
ShrinkerGraphgetSourceFile in interface ShrinkerGraph<java.lang.String>@NonNull
public java.util.Set<java.lang.String> getReachableMembersLocalNames(@NonNull
java.lang.String klass,
@NonNull
AbstractShrinker.CounterSet counterSet)
ShrinkerGraphgetReachableMembersLocalNames in interface ShrinkerGraph<java.lang.String>@NonNull
public java.lang.String getOwnerClass(@NonNull
java.lang.String member)
ShrinkerGraphgetOwnerClass in interface ShrinkerGraph<java.lang.String>member - node representing a given class member@NonNull
public java.lang.String getClassReference(@NonNull
java.lang.String className)
ShrinkerGraphgetClassReference in interface ShrinkerGraph<java.lang.String>className - internal name of the class@NonNull
public java.lang.String addClass(@NonNull
java.lang.String name,
@Nullable
java.lang.String superName,
@Nullable
java.lang.String[] interfaces,
int modifiers,
@Nullable
java.io.File classFile)
ShrinkerGraphaddClass in interface ShrinkerGraph<java.lang.String>name - internal name of the classsuperName - internal name of the superclassinterfaces - internal names of the interfacesmodifiers - modifiers bit set, as used by ClassVisitorclassFile - class file that contains the given class@NonNull public java.lang.Iterable<java.lang.String> getAllProgramClasses()
ShrinkerGraphgetAllProgramClasses in interface ShrinkerGraph<java.lang.String>ShrinkerGraph.isProgramClass(Object)@NonNull
public java.lang.String getClassName(@NonNull
java.lang.String klass)
ShrinkerGraphgetClassName in interface ShrinkerGraph<java.lang.String>public int getModifiers(@NonNull
java.lang.String node)
ShrinkerGraphClassVisitor.getModifiers in interface ShrinkerGraph<java.lang.String>public void addAnnotation(@NonNull
java.lang.String node,
@NonNull
java.lang.String annotationName)
ShrinkerGraphaddAnnotation in interface ShrinkerGraph<java.lang.String>node - node to store the data forannotationName - internal name of the annotation@NonNull
public java.lang.Iterable<java.lang.String> getAnnotations(@NonNull
java.lang.String node)
ShrinkerGraphgetAnnotations in interface ShrinkerGraph<java.lang.String>public void addRoots(@NonNull
java.util.Map<java.lang.String,DependencyType> symbolsToKeep,
@NonNull
AbstractShrinker.CounterSet counterSet)
ShrinkerGraphAbstractShrinker.CounterSet.
Roots are the sources from which graph walking starts. When we walk the graph looking for
reachable nodes, keys in the map will get their counters incremented, using the DependencyType from the matching map value. They can be considered as nodes with incoming
edges that don't have a start node.
addRoots in interface ShrinkerGraph<java.lang.String>@NonNull public java.util.Map<java.lang.String,DependencyType> getRoots(@NonNull AbstractShrinker.CounterSet counterSet)
ShrinkerGraphgetRoots in interface ShrinkerGraph<java.lang.String>#addRoots(Map, CounterSet)public void clearCounters(@NonNull
com.android.ide.common.internal.WaitableExecutor executor)
ShrinkerGraphclearCounters in interface ShrinkerGraph<java.lang.String>public java.lang.String getMemberName(@NonNull
java.lang.String member)
ShrinkerGraphgetMemberName in interface ShrinkerGraph<java.lang.String>public java.lang.String getFullMemberName(@NonNull
java.lang.String member)
ShrinkerGraphgetFullMemberName in interface ShrinkerGraph<java.lang.String>public java.lang.String getMemberDescriptor(@NonNull
java.lang.String member)
ShrinkerGraphgetMemberDescriptor in interface ShrinkerGraph<java.lang.String>public boolean isClassKnown(@NonNull
java.lang.String klass)
ShrinkerGraphWhen project dependencies are setup incorrectly, unknown classes may be referenced from program classes. In this case nodes for the unknown classes are created "by name" when analyzing program classes, but at a later stage we need to make sure the references are actually valid (otherwise we emit a warning).
isClassKnown in interface ShrinkerGraph<java.lang.String>