Package edu.umd.cs.findbugs.ba.ch
Class Subtypes2
java.lang.Object
edu.umd.cs.findbugs.ba.ch.Subtypes2
Class for performing class hierarchy queries. Does not require
JavaClass objects to be in memory. Instead, uses XClass objects.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static class
Object to record the results of a supertype search.private static class
An in-progress traversal of one path from a class or interface to java.lang.Object. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final Map
<ClassDescriptor, ClassVertex> private final org.apache.bcel.generic.ObjectType
(package private) static final org.apache.bcel.generic.ObjectType
static final boolean
static final boolean
static final boolean
private final DualKeyHashMap
<org.apache.bcel.generic.ReferenceType, org.apache.bcel.generic.ReferenceType, org.apache.bcel.generic.ReferenceType> private final InheritanceGraph
(package private) static final org.apache.bcel.generic.ObjectType
(package private) boolean
(package private) ClassDescriptor
(package private) ClassDescriptor
private final org.apache.bcel.generic.ObjectType
private final Map
<ClassDescriptor, Set<ClassDescriptor>> private final Map
<ClassDescriptor, Subtypes2.SupertypeQueryResults> -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoid
addApplicationClass
(XClass appXClass) Add an application class, and its transitive supertypes, to the inheritance graph.void
Add a class or interface, and its transitive supertypes, to the inheritance graph.private ClassVertex
addClassAndGetClassVertex
(XClass xclass) Add an XClass and all of its supertypes to the InheritanceGraph.private ClassVertex
addClassVertexForMissingClass
(ClassDescriptor missingClassDescriptor, boolean isInterfaceEdge) Add a ClassVertex representing a missing class.private void
addInheritanceEdge
(ClassVertex vertex, ClassDescriptor superclassDescriptor, boolean isInterfaceEdge, LinkedList<XClass> workList) Add supertype edge to the InheritanceGraph.private void
addSupertypeEdges
(ClassVertex vertex, LinkedList<XClass> workList) Add supertype edges to the InheritanceGraph for given ClassVertex.private void
addToWorkList
(LinkedList<Subtypes2.SupertypeTraversalPath> workList, Subtypes2.SupertypeTraversalPath curPath, ClassDescriptor supertypeDescriptor) private void
addVertexToGraph
(ClassDescriptor classDescriptor, ClassVertex vertex) private org.apache.bcel.generic.ReferenceType
checkFirstCommonSuperclassQueryCache
(org.apache.bcel.generic.ReferenceType a, org.apache.bcel.generic.ReferenceType b) private org.apache.bcel.generic.ReferenceType
computeFirstCommonSuperclassOfDifferentDimensionArrays
(org.apache.bcel.generic.ArrayType aArrType, org.apache.bcel.generic.ArrayType bArrType) Get the first common superclass of arrays with different numbers of dimensions.private org.apache.bcel.generic.ObjectType
computeFirstCommonSuperclassOfObjectTypes
(org.apache.bcel.generic.ObjectType a, org.apache.bcel.generic.ObjectType b) private org.apache.bcel.generic.ReferenceType
computeFirstCommonSuperclassOfReferenceTypes
(org.apache.bcel.generic.ReferenceType a, org.apache.bcel.generic.ReferenceType b) private org.apache.bcel.generic.ReferenceType
computeFirstCommonSuperclassOfSameDimensionArrays
(org.apache.bcel.generic.ArrayType aArrType, org.apache.bcel.generic.ArrayType bArrType) Get first common supertype of arrays with the same number of dimensions.private Set
<ClassDescriptor> computeKnownSubtypes
(ClassDescriptor classDescriptor) Compute set of known subtypes of class named by given ClassDescriptor.private Set
<ClassDescriptor> computeKnownSupertypes
(ClassDescriptor classDescriptor) private Subtypes2.SupertypeQueryResults
computeSupertypes
(ClassDescriptor classDescriptor) Compute supertypes for class named by given ClassDescriptor.private ArrayList
<ClassVertex> getAllSuperclassVertices
(ClassVertex vertex) Get list of all superclasses of class represented by given class vertex, in order, including the class itself (which is trivially its own superclass as far as "first common superclass" queries are concerned.)getDirectSubtypes
(ClassDescriptor classDescriptor) Get known subtypes of given class.org.apache.bcel.generic.ObjectType
getFirstCommonSuperclass
(org.apache.bcel.generic.ObjectType a, org.apache.bcel.generic.ObjectType b) Get the first common superclass of the given object types.org.apache.bcel.generic.ReferenceType
getFirstCommonSuperclass
(org.apache.bcel.generic.ReferenceType a, org.apache.bcel.generic.ReferenceType b) Get the first common superclass of the given reference types.getGraph()
getSubtypes
(ClassDescriptor classDescriptor) Get known subtypes of given class.getSupertypeQueryResults
(ClassDescriptor classDescriptor) Look up or compute the SupertypeQueryResults for class named by given ClassDescriptor.getTransitiveCommonSubtypes
(ClassDescriptor classDescriptor1, ClassDescriptor classDescriptor2) Get the set of common subtypes of the two given classes.Get Collection of all XClass objects (resolved classes) seen so far.boolean
hasKnownSubclasses
(ClassDescriptor classDescriptor) boolean
hasSubtypes
(ClassDescriptor classDescriptor) Determine whether or not the given class has any known subtypes.static boolean
instanceOf
(ClassDescriptor subDescriptor, Class<?> c) static boolean
instanceOf
(ClassDescriptor subDescriptor, String dottedSupertype) static boolean
instanceOf
(String dottedSubtype, String dottedSupertype) static boolean
instanceOf
(org.apache.bcel.classfile.JavaClass subtype, String dottedSupertype) boolean
isApplicationClass
(ClassDescriptor descriptor) static boolean
isCollection
(org.apache.bcel.generic.ReferenceType target) static boolean
isContainer
(org.apache.bcel.generic.ReferenceType target) A collection, a map, or some other containerstatic boolean
isEnum
(org.apache.bcel.classfile.JavaClass javaClass) static boolean
isJSP
(org.apache.bcel.classfile.JavaClass javaClass) static boolean
isRecord
(org.apache.bcel.classfile.JavaClass javaClass) boolean
isSubtype
(ClassDescriptor subDesc, ClassDescriptor superDesc) boolean
isSubtype
(ClassDescriptor subDesc, ClassDescriptor... superDesc) boolean
isSubtype
(org.apache.bcel.generic.ObjectType type, org.apache.bcel.generic.ObjectType possibleSupertype) Determine whether or not a given ObjectType is a subtype of another.boolean
isSubtype
(org.apache.bcel.generic.ReferenceType type, org.apache.bcel.generic.ReferenceType possibleSupertype) Determine whether or not a given ReferenceType is a subtype of another.boolean
isSubtype0
(ClassDescriptor subDesc, ClassDescriptor superDesc) private ClassVertex
optionallyResolveClassVertex
(ClassDescriptor classDescriptor) private void
putFirstCommonSuperclassQueryCache
(org.apache.bcel.generic.ReferenceType a, org.apache.bcel.generic.ReferenceType b, org.apache.bcel.generic.ReferenceType answer) private ClassVertex
resolveClassVertex
(ClassDescriptor classDescriptor) Resolve a class named by given ClassDescriptor and return its resolved ClassVertex.private boolean
traverseEdge
(ClassVertex vertex, ClassDescriptor supertypeDescriptor, boolean isInterfaceEdge, InheritanceGraphVisitor visitor) void
traverseSupertypes
(ClassDescriptor start, InheritanceGraphVisitor visitor) Starting at the class or interface named by the given ClassDescriptor, traverse the inheritance graph, exploring all paths from the class or interface to java.lang.Object.void
traverseSupertypesDepthFirst
(ClassDescriptor start, SupertypeTraversalVisitor visitor) Starting at the class or interface named by the given ClassDescriptor, traverse the inheritance graph depth first, visiting each class only once.private void
traverseSupertypesDepthFirstHelper
(ClassDescriptor cur, SupertypeTraversalVisitor visitor, Set<ClassDescriptor> seen)
-
Field Details
-
ENABLE_SUBTYPES2_FOR_COMMON_SUPERCLASS_QUERIES
public static final boolean ENABLE_SUBTYPES2_FOR_COMMON_SUPERCLASS_QUERIES- See Also:
-
DEBUG
public static final boolean DEBUG -
DEBUG_QUERIES
public static final boolean DEBUG_QUERIES -
graph
-
classDescriptorToVertexMap
-
supertypeSetMap
-
subtypeSetMap
-
xclassSet
-
firstCommonSuperclassQueryCache
private final DualKeyHashMap<org.apache.bcel.generic.ReferenceType,org.apache.bcel.generic.ReferenceType, firstCommonSuperclassQueryCacheorg.apache.bcel.generic.ReferenceType> -
SERIALIZABLE
private final org.apache.bcel.generic.ObjectType SERIALIZABLE -
CLONEABLE
private final org.apache.bcel.generic.ObjectType CLONEABLE -
COLLECTION_TYPE
static final org.apache.bcel.generic.ObjectType COLLECTION_TYPE -
MAP_TYPE
static final org.apache.bcel.generic.ObjectType MAP_TYPE -
prevSubDesc
ClassDescriptor prevSubDesc -
prevSuperDesc
ClassDescriptor prevSuperDesc -
prevResult
boolean prevResult
-
-
Constructor Details
-
Subtypes2
public Subtypes2()Constructor.
-
-
Method Details
-
getGraph
- Returns:
- Returns the graph.
-
isCollection
public static boolean isCollection(org.apache.bcel.generic.ReferenceType target) throws ClassNotFoundException - Throws:
ClassNotFoundException
-
isContainer
public static boolean isContainer(org.apache.bcel.generic.ReferenceType target) throws ClassNotFoundException A collection, a map, or some other container- Throws:
ClassNotFoundException
-
isJSP
public static boolean isJSP(org.apache.bcel.classfile.JavaClass javaClass) -
isEnum
public static boolean isEnum(org.apache.bcel.classfile.JavaClass javaClass) -
isRecord
public static boolean isRecord(org.apache.bcel.classfile.JavaClass javaClass) -
instanceOf
public static boolean instanceOf(@DottedClassName String dottedSubtype, @DottedClassName String dottedSupertype) -
instanceOf
-
instanceOf
public static boolean instanceOf(ClassDescriptor subDescriptor, @DottedClassName String dottedSupertype) -
instanceOf
public static boolean instanceOf(org.apache.bcel.classfile.JavaClass subtype, @DottedClassName String dottedSupertype) -
addApplicationClass
Add an application class, and its transitive supertypes, to the inheritance graph.- Parameters:
appXClass
- application XClass to add to the inheritance graph
-
isApplicationClass
-
addClass
Add a class or interface, and its transitive supertypes, to the inheritance graph.- Parameters:
xclass
- XClass to add to the inheritance graph
-
addClassAndGetClassVertex
Add an XClass and all of its supertypes to the InheritanceGraph.- Parameters:
xclass
- an XClass- Returns:
- the ClassVertex representing the class in the InheritanceGraph
-
addVertexToGraph
-
isSubtype
public boolean isSubtype(org.apache.bcel.generic.ReferenceType type, org.apache.bcel.generic.ReferenceType possibleSupertype) throws ClassNotFoundException Determine whether or not a given ReferenceType is a subtype of another. Throws ClassNotFoundException if the question cannot be answered definitively due to a missing class.- Parameters:
type
- a ReferenceTypepossibleSupertype
- another Reference type- Returns:
- true if
type
is a subtype ofpossibleSupertype
, false if not - Throws:
ClassNotFoundException
- if a missing class prevents a definitive answer
-
isSubtype
public boolean isSubtype(ClassDescriptor subDesc, ClassDescriptor superDesc) throws ClassNotFoundException - Throws:
ClassNotFoundException
-
isSubtype
public boolean isSubtype(ClassDescriptor subDesc, ClassDescriptor... superDesc) throws ClassNotFoundException - Throws:
ClassNotFoundException
-
isSubtype0
public boolean isSubtype0(ClassDescriptor subDesc, ClassDescriptor superDesc) throws ClassNotFoundException - Throws:
ClassNotFoundException
-
isSubtype
public boolean isSubtype(org.apache.bcel.generic.ObjectType type, org.apache.bcel.generic.ObjectType possibleSupertype) throws ClassNotFoundException Determine whether or not a given ObjectType is a subtype of another. Throws ClassNotFoundException if the question cannot be answered definitively due to a missing class.- Parameters:
type
- a ReferenceTypepossibleSupertype
- another Reference type- Returns:
- true if
type
is a subtype ofpossibleSupertype
, false if not - Throws:
ClassNotFoundException
- if a missing class prevents a definitive answer
-
getFirstCommonSuperclass
public org.apache.bcel.generic.ReferenceType getFirstCommonSuperclass(org.apache.bcel.generic.ReferenceType a, org.apache.bcel.generic.ReferenceType b) throws ClassNotFoundException Get the first common superclass of the given reference types. Note that an interface type is never returned unlessa
andb
are the same type. Otherwise, we try to return as accurate a type as possible. This method is used as the meet operator in TypeDataflowAnalysis, and is intended to follow (more or less) the JVM bytecode verifier semantics.This method should be used in preference to the getFirstCommonSuperclass() method in
ReferenceType
.- Parameters:
a
- a ReferenceTypeb
- another ReferenceType- Returns:
- the first common superclass of
a
andb
- Throws:
ClassNotFoundException
-
computeFirstCommonSuperclassOfReferenceTypes
private org.apache.bcel.generic.ReferenceType computeFirstCommonSuperclassOfReferenceTypes(org.apache.bcel.generic.ReferenceType a, org.apache.bcel.generic.ReferenceType b) throws ClassNotFoundException - Throws:
ClassNotFoundException
-
computeFirstCommonSuperclassOfSameDimensionArrays
private org.apache.bcel.generic.ReferenceType computeFirstCommonSuperclassOfSameDimensionArrays(org.apache.bcel.generic.ArrayType aArrType, org.apache.bcel.generic.ArrayType bArrType) throws ClassNotFoundException Get first common supertype of arrays with the same number of dimensions.- Parameters:
aArrType
- an ArrayTypebArrType
- another ArrayType with the same number of dimensions- Returns:
- first common supertype
- Throws:
ClassNotFoundException
-
computeFirstCommonSuperclassOfDifferentDimensionArrays
private org.apache.bcel.generic.ReferenceType computeFirstCommonSuperclassOfDifferentDimensionArrays(org.apache.bcel.generic.ArrayType aArrType, org.apache.bcel.generic.ArrayType bArrType) Get the first common superclass of arrays with different numbers of dimensions.- Parameters:
aArrType
- an ArrayTypebArrType
- another ArrayType- Returns:
- ReferenceType representing first common superclass
-
getFirstCommonSuperclass
public org.apache.bcel.generic.ObjectType getFirstCommonSuperclass(org.apache.bcel.generic.ObjectType a, org.apache.bcel.generic.ObjectType b) throws ClassNotFoundException Get the first common superclass of the given object types. Note that an interface type is never returned unlessa
andb
are the same type. Otherwise, we try to return as accurate a type as possible. This method is used as the meet operator in TypeDataflowAnalysis, and is intended to follow (more or less) the JVM bytecode verifier semantics.This method should be used in preference to the getFirstCommonSuperclass() method in
ReferenceType
.- Parameters:
a
- an ObjectTypeb
- another ObjectType- Returns:
- the first common superclass of
a
andb
- Throws:
ClassNotFoundException
-
computeFirstCommonSuperclassOfObjectTypes
private org.apache.bcel.generic.ObjectType computeFirstCommonSuperclassOfObjectTypes(org.apache.bcel.generic.ObjectType a, org.apache.bcel.generic.ObjectType b) throws ClassNotFoundException - Throws:
ClassNotFoundException
-
putFirstCommonSuperclassQueryCache
private void putFirstCommonSuperclassQueryCache(org.apache.bcel.generic.ReferenceType a, org.apache.bcel.generic.ReferenceType b, org.apache.bcel.generic.ReferenceType answer) -
checkFirstCommonSuperclassQueryCache
private org.apache.bcel.generic.ReferenceType checkFirstCommonSuperclassQueryCache(org.apache.bcel.generic.ReferenceType a, org.apache.bcel.generic.ReferenceType b) -
getAllSuperclassVertices
private ArrayList<ClassVertex> getAllSuperclassVertices(ClassVertex vertex) throws ClassNotFoundException Get list of all superclasses of class represented by given class vertex, in order, including the class itself (which is trivially its own superclass as far as "first common superclass" queries are concerned.)- Parameters:
vertex
- a ClassVertex- Returns:
- list of all superclass vertices in order
- Throws:
ClassNotFoundException
-
getSubtypes
public Set<ClassDescriptor> getSubtypes(ClassDescriptor classDescriptor) throws ClassNotFoundException Get known subtypes of given class. The set returned DOES include the class itself.- Parameters:
classDescriptor
- ClassDescriptor naming a class- Returns:
- Set of ClassDescriptors which are the known subtypes of the class
- Throws:
ClassNotFoundException
-
hasSubtypes
Determine whether or not the given class has any known subtypes.- Parameters:
classDescriptor
- ClassDescriptor naming a class- Returns:
- true if the class has subtypes, false if it has no subtypes
- Throws:
ClassNotFoundException
-
getDirectSubtypes
public Set<ClassDescriptor> getDirectSubtypes(ClassDescriptor classDescriptor) throws ClassNotFoundException Get known subtypes of given class.- Parameters:
classDescriptor
- ClassDescriptor naming a class- Returns:
- Set of ClassDescriptors which are the known subtypes of the class
- Throws:
ClassNotFoundException
-
getTransitiveCommonSubtypes
public Set<ClassDescriptor> getTransitiveCommonSubtypes(ClassDescriptor classDescriptor1, ClassDescriptor classDescriptor2) throws ClassNotFoundException Get the set of common subtypes of the two given classes.- Parameters:
classDescriptor1
- a ClassDescriptor naming a classclassDescriptor2
- a ClassDescriptor naming another class- Returns:
- Set containing all common transitive subtypes of the two classes
- Throws:
ClassNotFoundException
-
getXClassCollection
Get Collection of all XClass objects (resolved classes) seen so far.- Returns:
- Collection of all XClass objects
-
traverseSupertypes
public void traverseSupertypes(ClassDescriptor start, InheritanceGraphVisitor visitor) throws ClassNotFoundException Starting at the class or interface named by the given ClassDescriptor, traverse the inheritance graph, exploring all paths from the class or interface to java.lang.Object.- Parameters:
start
- ClassDescriptor naming the class where the traversal should startvisitor
- an InheritanceGraphVisitor- Throws:
ClassNotFoundException
- if the start vertex cannot be resolved
-
traverseSupertypesDepthFirst
public void traverseSupertypesDepthFirst(ClassDescriptor start, SupertypeTraversalVisitor visitor) throws ClassNotFoundException Starting at the class or interface named by the given ClassDescriptor, traverse the inheritance graph depth first, visiting each class only once. This is much faster than traversing all paths in certain circumstances.- Parameters:
start
- ClassDescriptor naming the class where the traversal should startvisitor
- an InheritanceGraphVisitor- Throws:
ClassNotFoundException
- if the start vertex cannot be resolved
-
traverseSupertypesDepthFirstHelper
private void traverseSupertypesDepthFirstHelper(ClassDescriptor cur, SupertypeTraversalVisitor visitor, Set<ClassDescriptor> seen) throws ClassNotFoundException - Throws:
ClassNotFoundException
-
addToWorkList
private void addToWorkList(LinkedList<Subtypes2.SupertypeTraversalPath> workList, Subtypes2.SupertypeTraversalPath curPath, ClassDescriptor supertypeDescriptor) -
traverseEdge
private boolean traverseEdge(ClassVertex vertex, @CheckForNull ClassDescriptor supertypeDescriptor, boolean isInterfaceEdge, InheritanceGraphVisitor visitor) -
computeKnownSubtypes
private Set<ClassDescriptor> computeKnownSubtypes(ClassDescriptor classDescriptor) throws ClassNotFoundException Compute set of known subtypes of class named by given ClassDescriptor.- Parameters:
classDescriptor
- a ClassDescriptor- Throws:
ClassNotFoundException
-
hasKnownSubclasses
- Throws:
ClassNotFoundException
-
computeKnownSupertypes
private Set<ClassDescriptor> computeKnownSupertypes(ClassDescriptor classDescriptor) throws ClassNotFoundException - Throws:
ClassNotFoundException
-
getSupertypeQueryResults
Look up or compute the SupertypeQueryResults for class named by given ClassDescriptor.- Parameters:
classDescriptor
- a ClassDescriptor- Returns:
- SupertypeQueryResults for the class named by the ClassDescriptor
-
computeSupertypes
Compute supertypes for class named by given ClassDescriptor.- Parameters:
classDescriptor
- a ClassDescriptor- Returns:
- SupertypeQueryResults containing known supertypes of the class
-
resolveClassVertex
private ClassVertex resolveClassVertex(ClassDescriptor classDescriptor) throws ClassNotFoundException Resolve a class named by given ClassDescriptor and return its resolved ClassVertex.- Parameters:
classDescriptor
- a ClassDescriptor- Returns:
- resolved ClassVertex representing the class in the InheritanceGraph
- Throws:
ClassNotFoundException
- if the class named by the ClassDescriptor does not exist
-
optionallyResolveClassVertex
-
addSupertypeEdges
Add supertype edges to the InheritanceGraph for given ClassVertex. If any direct supertypes have not been processed, add them to the worklist.- Parameters:
vertex
- a ClassVertex whose supertype edges need to be addedworkList
- work list of ClassVertexes that need to have their supertype edges added
-
addInheritanceEdge
private void addInheritanceEdge(ClassVertex vertex, ClassDescriptor superclassDescriptor, boolean isInterfaceEdge, @CheckForNull LinkedList<XClass> workList) Add supertype edge to the InheritanceGraph.- Parameters:
vertex
- source ClassVertex (subtype)superclassDescriptor
- ClassDescriptor of a direct supertypeisInterfaceEdge
- true if supertype is (as far as we know) an interfaceworkList
- work list of ClassVertexes that need to have their supertype edges added (null if no further work will be generated)
-
addClassVertexForMissingClass
private ClassVertex addClassVertexForMissingClass(ClassDescriptor missingClassDescriptor, boolean isInterfaceEdge) Add a ClassVertex representing a missing class.- Parameters:
missingClassDescriptor
- ClassDescriptor naming a missing classisInterfaceEdge
-- Returns:
- the ClassVertex representing the missing class
-