class ClassHierarchy extends AnyRef
Represents a project's class hierarchy. The class hierarchy only contains
information about those classes that were explicitly added to it. Hence, the class hierarchy
may contain holes. However, the type java.lang.Object
is always part of the class hierarchy.
Thread safety
This class is effectively immutable; concurrent access to the class hierarchy is supported.
- Source
- ClassHierarchy.scala
- Note
Java 9 module definitions are completely ignored.
,Unless explicitly documented, it is an error to pass an instance of
ObjectType
to any method if theObjectType
was not previously added. If in doubt, first check if the type is known (isKnown
/ifKnown
).
- Alphabetic
- By Inheritance
- ClassHierarchy
- AnyRef
- Any
- Hide All
- Show All
- Public
- Protected
Value Members
- final def !=(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- final def ##: Int
- Definition Classes
- AnyRef → Any
- final def ==(arg0: Any): Boolean
- Definition Classes
- AnyRef → Any
- def allSubclassTypes(objectType: ObjectType, reflexive: Boolean): Iterator[ObjectType]
Returns all (direct and indirect) subclass types of the given class type.
Returns all (direct and indirect) subclass types of the given class type.
- Note
No explicit
isKnown
check is required; if the type is unknown, an empty iterator is returned.
- def allSubtypes(objectType: ObjectType, reflexive: Boolean): Set[ObjectType]
The set of all class- and interface-types that (directly or indirectly) inherit from the given type.
The set of all class- and interface-types that (directly or indirectly) inherit from the given type.
- objectType
An
ObjectType
.- reflexive
If
true
the given type is also included in the returned set.- returns
The set of all direct and indirect subtypes of the given type.
- Note
No explicit
,isKnown
check is required; if the type is unknown the returned set will be empty unlessreflexive
is true.If you don't need the set, it is more efficient to use
,foreachSubtype
.If the type hierarchy is not complete, the answer may also be incomplete. E.g., if x inherits from y and y inherits from z, but y is not known to the class hierarchy then x will not be in the set of all (known) subtypes of z.
- def allSubtypesForeachIterator(objectType: ObjectType, reflexive: Boolean): ForeachRefIterator[ObjectType]
- def allSubtypesIterator(objectType: ObjectType, reflexive: Boolean): Iterator[ObjectType]
- def allSuperclassTypesInInitializationOrder(objectType: ObjectType): QualifiedCollection[List[ObjectType]]
Returns the list of all super types in initialization order.
Returns the list of all super types in initialization order. I.e., it will return the top level super class first - i.e.,
java.lang.Object
and then all sub class types.If the given type is
java.lang.Object
, the empty list is returned.Interfaces are not further considered, because they generally don't need any instance initialization. If the given type is an interface type, the returned list will hence only contain
java.lang.Object
.- Note
If the class hierarchy is not complete, it may happen that the super class chain is not complete. In this case an org.opalj.collection.IncompleteCollection will be returned.
- def allSuperclassesIterator(ot: ObjectType, reflexive: Boolean = false)(implicit project: ClassFileRepository): Iterator[ClassFile]
Efficient, best-effort iterator over all super types of the given type.
- def allSuperinterfacetypes(objectType: ObjectType, reflexive: Boolean = false): UIDSet[ObjectType]
Returns the set of all interfaces directly or indirectly implemented by the given type.
Returns the set of all interfaces directly or indirectly implemented by the given type.
- reflexive
If
true
the returned set will also contain the given type if it is an interface type.
- Exceptions thrown
NullPointerException
if the project is very broken (e.g., if a class states that it inherits from class C, but class C is actually an interface).
- def allSupertypes(objectType: ObjectType, reflexive: Boolean = false): UIDSet[ObjectType]
The set of all supertypes of the given type.
The set of all supertypes of the given type.
- reflexive
If
true
, the returned set will also contain the given type.
- Note
Whenever possible, one of the higher-order functions should be used to avoid the creation of intermediate data-structures.
- def allSupertypesOf(types: UIDSet[ObjectType], reflexive: Boolean): UIDSet[ObjectType]
Calculates the set of all supertypes of the given
types
. - final def asInstanceOf[T0]: T0
- Definition Classes
- Any
- def asTSV: String
A dump of the class hierarchy information in TSV format.
A dump of the class hierarchy information in TSV format. The following information will be dumped:
- type
- id
- (is) interface
- (is) final
- (is) root type
- (is) leaf type
- (is) supertype information complete
- super class
- super interfaces
- sub classes
- sub interfaces
- final def canBeStoredIn(elementValueType: FieldType, elementValueTypeIsPrecise: Boolean, arrayType: ArrayType, arrayTypeIsPrecise: Boolean): Answer
Determines if a value of type
elementValueType
can be stored in an array of typearrayType
.Determines if a value of type
elementValueType
can be stored in an array of typearrayType
. E.g., a value of typeIntegerType
can be stored in an array (one-dimensional) of typeArrayType(IntegerType)
. This method takes the fact that a type may just model an upper type bound into account.- elementValueType
The type of the value that should be stored in the array. This type is compared against the component type of the array.
- elementValueTypeIsPrecise
Specifies if the type information is precise; i.e., whether
elementValueType
models the precise runtime type (true
) or just an upper bound (false
). If theelementValueType
is a base/ primitive type, then this value should betrue
; but actually it is ignored.- arrayType
The type of the array.
- arrayTypeIsPrecise
Specifies if the type information is precise; i.e., whether arrayType models the precise runtime type (
true
) or just an upper bound (false
).
- Annotations
- @tailrec()
- def clone(): AnyRef
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.CloneNotSupportedException]) @native() @IntrinsicCandidate()
- def directSubclassesOf(objectType: ObjectType): UIDSet[ObjectType]
- def directSubinterfacesOf(objectType: ObjectType): UIDSet[ObjectType]
- def directSubtypesCount(objectTypeId: Int): Int
- def directSubtypesCount(objectType: ObjectType): Int
- def directSubtypesOf(upperTypeBound: UIDSet[ObjectType]): UIDSet[ObjectType]
Computes the set of types which are subtypes (reflexive) of all types identified by the given
upper type bound
.Computes the set of types which are subtypes (reflexive) of all types identified by the given
upper type bound
. E.g., the class X which implements I and J, would be a direct subtype of the upper type bound consisting of I and J. If the bound consists of only one type, then the bound is returned.- upperTypeBound
A set of types that are in no inheritance relationship.
upperTypeBound
must not be empty.
- def directSubtypesOf(objectType: ObjectType): Iterator[ObjectType]
The direct subtypes of the given type (not reflexive).
- def directSuperinterfacesOf(objectType: ObjectType): UIDSet[ObjectType]
- def directSupertypes(objectType: ObjectType): UIDSet[ObjectType]
- final def eq(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- def equals(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef → Any
- def existsSubclass(objectType: ObjectType, project: ClassFileRepository)(p: (ClassFile) => Boolean): Boolean
Tests if a subtype of the given
ObjectType
exists that satisfies the given predicate.Tests if a subtype of the given
ObjectType
exists that satisfies the given predicate. In this case the subtype relation is not reflexive.Subtypes for which no
ClassFile
object is available are ignored.- Note
No explicit
isKnown
check is required; if the type is unknown nothing will happen.
- def foreachDirectSubclassType[T](objectType: ObjectType, project: ClassFileRepository)(f: (ClassFile) => T): Unit
Executes the given function
f
for each known direct subclass of the givenObjectType
.Executes the given function
f
for each known direct subclass of the givenObjectType
. In this case the subclass relation is not reflexive and interfaces inheriting from the given object type are ignored.Subtypes for which no
ClassFile
object is available are ignored.- Note
No explicit
isKnown
check is required; if the type is unknown nothing will happen.
- def foreachDirectSubtypeOf[U](objectType: ObjectType)(f: (ObjectType) => U): Unit
- def foreachDirectSupertype(objectType: ObjectType)(f: (ObjectType) => Unit): Unit
- def foreachDirectSupertypeCF[U](objectType: ObjectType)(f: (ClassFile) => U)(implicit project: ClassFileRepository): Unit
- def foreachKnownType[T](f: (ObjectType) => T): Unit
Calls the given function
f
for each type that is known to the class hierarchy. - def foreachSubclass(objectType: ObjectType, project: ClassFileRepository)(f: (ClassFile) => Unit): Unit
Executes the given function
f
for each subclass of the givenObjectType
.Executes the given function
f
for each subclass of the givenObjectType
. In this case the subclass relation is not reflexive. Furthermore, it may be possible that f is invoked multiple times using the sameClassFile
object if the given objectType identifies an interface.Subtypes for which no
ClassFile
object is available are ignored.- Note
No explicit
,isKnown
check is required; if the type is unknown nothing will happen.For details regarding incomplete class hierarchies see
foreachSubtype
.
- def foreachSubinterfaceType(interfaceType: ObjectType)(f: (ObjectType) => Boolean): Unit
Iterates over all subinterfaces of the given interface type (or java.lang.Object) until the callback function returns "false".
- def foreachSubtype(objectType: ObjectType, reflexive: Boolean = false)(process: (ObjectType) => Boolean): Unit
Iterates over all subtypes of the given type, by first iterating over the subclass types and then iterating over the subinterface types (if the given object type defines an interface type or identifies
java.lang.Object
).Iterates over all subtypes of the given type, by first iterating over the subclass types and then iterating over the subinterface types (if the given object type defines an interface type or identifies
java.lang.Object
).- process
The process function will be called for each subtype of the given type. If process returns false, subtypes of the current type will no longer be traversed. However, if a subtype of the current type is reachable via another path (by means of interface inheritance) then that subtype may be processed.
- Note
Classes are always traversed first.
- def foreachSubtype(objectType: ObjectType)(f: (ObjectType) => Unit): Unit
Calls the function
f
for each known (direct or indirect) subtype of the given type.Calls the function
f
for each known (direct or indirect) subtype of the given type.- objectType
An
ObjectType
.
- Note
No explicit
,isKnown
check is required; if the type is unknown nothing will happen.For details regarding incomplete class hierarchies see allSubtypes. *
- def foreachSubtypeCF(objectType: ObjectType, reflexive: Boolean = false)(process: (ClassFile) => Boolean)(implicit project: ClassFileRepository): Unit
- def foreachSuperclass(objectType: ObjectType, project: ClassFileRepository)(f: (ClassFile) => Unit): Unit
Calls the function
f
for each supertype of the given object type for which the classfile is available.Calls the function
f
for each supertype of the given object type for which the classfile is available.It is possible that the class file of the same super interface type
I
is passed multiple times tof
whenI
is implemented multiple times by the given type's supertypes.The algorithm first iterates over the type's super classes before it iterates over the super interfaces.
- Note
See foreachSupertype for details.
- def foreachSuperinterfaceType(t: ObjectType)(f: (ObjectType) => Boolean): Unit
Iterates over all direct and indirect (also by means of super classes) superinterfaces of the type until the callback function returns "false".
- def foreachSupertype(ot: ObjectType, reflexive: Boolean = false)(f: (ObjectType) => Unit): Unit
Calls the given function
f
for each of the given type's supertypes. - final def getClass(): Class[_ <: AnyRef]
- Definition Classes
- AnyRef → Any
- Annotations
- @native() @IntrinsicCandidate()
- final def getObjectType(objectTypeId: Int): ObjectType
Returns the
ObjectType
with the given Id.Returns the
ObjectType
with the given Id. The id has to be the id of a valid ObjectType. - def getSupertypeDeclaration(subtype: ClassSignature, supertype: ObjectType)(implicit project: ClassFileRepository): Option[ClassTypeSignature]
Determines whether the given ClassSignature of
subtype
implements or extends the givensupertype
.Determines whether the given ClassSignature of
subtype
implements or extends the givensupertype
. In case that thesubtype
does implement or extend thesupertype
, anOption
of ClassTypeSignature is returned. Otherwise None will be returned.- subtype
Any type or interface.
- supertype
Any type or interface.
- returns
Option
of ClassTypeSignature if thesubtype
extends or implements the givensupertype
,None
otherwise.
subtype: ClassSignature from class A where A extends List<String> supertype: List as ObjectType This method scans all super classes and super interfaces of A in order to find the concrete class declaration of List where it is bound to String. The above example would yield the ClassTypeSignature of List<String>.
Example: - def hasSubtypes(objectType: ObjectType): Answer
Returns
Yes
if the class hierarchy contains subtypes of the given type andNo
if it contains no subtypes.Returns
Yes
if the class hierarchy contains subtypes of the given type andNo
if it contains no subtypes.Unknown
is returned if the given type is not known.Please note, that the answer will be
No
even though the (running) project contains (in)direct subtypes of the given type, but the class hierarchy is not complete. I.e., not all class files (libraries) used by the project are analyzed. A second case is that some class files are generated at runtime that inherit from the givenObjectType
.- objectType
Some
ObjectType
.
- Note
No explicit
isKnown
check is required.
- def hashCode(): Int
- Definition Classes
- AnyRef → Any
- Annotations
- @native() @IntrinsicCandidate()
- final def ifKnown[T](objectType: ObjectType)(f: (ObjectType) => T): Option[T]
Tests if the given objectType is known and if so executes the given function.
Tests if the given objectType is known and if so executes the given function.
- Annotations
- @inline()
ifKnown(ObjectType.Serializable){isDirectSupertypeInformationComplete}
Example: - def isASubtypeOf(subtype: ClassTypeSignature, supertype: FormalTypeParameter)(implicit p: ClassFileRepository): Answer
Determines if the given class or interface type encoded in a ClassTypeSignature
subtype
is actually a subtype of the class, interface or intersection type encoded in the FormalTypeParameter of thesupertype
parameter.Determines if the given class or interface type encoded in a ClassTypeSignature
subtype
is actually a subtype of the class, interface or intersection type encoded in the FormalTypeParameter of thesupertype
parameter. The subtype relation is fulfilled if the subtype is a subtype of the class bound and/or all interface types that are prescribed by the formal type specification.- subtype
Any
ClassTypeSignature
.- supertype
Any
FormalTypeParameter
.- returns
Yes
ifsubtype
is a subtype of the givensupertype
.No
ifsubtype
is not a subtype ofsupertype
andUnknown
if the analysis is not conclusive. The latter can happen if the class hierarchy is not complete and hence precise information about a type's supertypes is not available.
- Note
This method does consider generics types specified within the FormalTypeParameter.
- def isASubtypeOf(subtype: ClassTypeSignature, supertype: ClassTypeSignature)(implicit project: ClassFileRepository): Answer
Determines if the given class or interface type encoded by the ClassTypeSignature
subtype
is actually a subtype of the class or interface type encoded in the ClassTypeSignature of thesupertype
.Determines if the given class or interface type encoded by the ClassTypeSignature
subtype
is actually a subtype of the class or interface type encoded in the ClassTypeSignature of thesupertype
.- subtype
Any
ClassTypeSignature
.- supertype
Any
ClassTypeSignature
.- returns
Yes
ifsubtype
is a subtype of the givensupertype
.No
ifsubtype
is not a subtype ofsupertype
andUnknown
if the analysis is not conclusive. The latter can happen if the class hierarchy is not complete and hence precise information about a type's supertypes is not available.
Introduction
Before looking in some examples, we have to set up the terminology. Type definition: List<String, ? extends Number, ?> ContainerType - A ContainerType is a type with parameters. In the previous type definition is
List
the ContainerType. TypeArgument - A TypeArgument is one of the parameters of the ContainerType. The above type definition has three TypeArguments. (String, ? extends Number and ?) VarianceIndicator - A VarianceIndicator is defined in the context of TypeArguments. There is a CovariantIndicator which can be defined in the type definition by using theextends
keyword. (? extends Number is a covariant TypeArgument). The other one is the ContravariantIndicator which is defined using thesuper
keyword. , 1
instance // definition subtype: List<String> // List<E> supertype: List<String> // List<E> If the ContainerType of the
subtype
is equal to the ContainerType of thesupertype
and non of the TypeArguments has a VarianceIndicator, then exists a subtype relation if and only if all of the TypeArguments are equal. , 2
subtype: SomeClass // SomeClass extends SomeInterface<String> supertype: SomeInterface<String> // SomeInterface<E> Is the
subtype
a ConcreteType without org.opalj.br.FormalTypeParameters and thesupertype
is a GenericType then we first have to check whether thesubtype
is a subtype of the givensupertype
. If not, then thesubtype
is not an actual subtype of the givensupertype
. Otherwise we have to find the definition of thesupertype
in the type definition or the type definition of a super class or a super interface (interface definition of SomeInterface<String>). Once found thesupertype
, we can compare all TypeArguments of the supertype definition of thesubtype
and the givensupertype
. (We are comparing String and String in this example) If all of them are equal,subtype
is an actual subtype of thesupertype
. , 3
subtype: Foo<Integer, String> // Foo<T,E> extends Bar<E> supertype: Bar<String> // Bar<E> Does the
subtype
andsupertype
have FormalTypeParameters and the ContainerType of thesubtype
is a subtype of the ContainerType of thesupertype
, we have to compare the shared TypeArguments. In our example the subtype Foo has two FormalTypeParameter (T,E) and the supertype Bar has only one FormalTypeParameter (E). Since both of them specify E in the ClassSignature of Foo, they share E as FormalTypeParameter. So it is necessary to check whether the actual bound TypeArgument at the position of E is equal. At first we have to locate the shared parameter in the ClassSignature, so it is possible to find the correct TypeArguments. The above example shows that the shared parameter E is in the second position of the FormalTypeParameters of Foo and at the first position of the FormalTypeParameters of Bar. Second and last we know can compare the according TypeArguments. All other parameters can be ignored because they are no important to decide the subtype relation.- Note
This method relies – in case of a comparison of non generic types – on
isSubtypeOf(org.opalj.br.ObjectType,org.opalj.br.ObjectType)
ofProject
which performs an upwards search only. E.g., given the following type hierarchy:class D inherits from C
class E inherits from D
and the query isSubtypeOf(D,E) the answer will beUnknown
ifC
isUnknown
andNo
otherwise.
Examples: - def isASubtypeOf(subtypes: UIDSet[_ <: ReferenceType], supertype: ReferenceType): Answer
- def isASubtypeOf(subtype: ReferenceType, supertypes: UIDSet[_ <: ReferenceType]): Answer
Returns
Yes
if the subtype is a subtype of all given supertypes.Returns
Yes
if the subtype is a subtype of all given supertypes. Hence, supertypes should not contain more than one class type. - def isASubtypeOf(subtypes: UIDSet[_ <: ReferenceType], supertypes: UIDSet[_ <: ReferenceType]): Answer
Determines if the type described by the first set of upper type bounds is a subtype of the second type.
Determines if the type described by the first set of upper type bounds is a subtype of the second type. I.e., it checks, if for all types of the
subtypes
upper type bound, a type in thesupertypes
type exists that is a supertype of the respective subtype. Ifsubtypes
is empty,Yes
will be returned; an empty upper type bound is expected to modelnull
. - final def isASubtypeOf(subtype: ReferenceType, supertype: ReferenceType): Answer
Determines if
subtype
is a subtype ofsupertype
using this class hierarchy.Determines if
subtype
is a subtype ofsupertype
using this class hierarchy.This method can be used as a foundation for implementing the logic of the JVM's
instanceof
andclasscast
instructions. But, in both cases additional logic for handlingnull
values and for considering the runtime type needs to be implemented by the caller of this method.- subtype
Any class, interface or array type.
- supertype
Any class, interface or array type.
- returns
Yes
ifsubtype
is indeed a subtype of the givensupertype
.No
ifsubtype
is not a subtype ofsupertype
andUnknown
if the analysis is not conclusive. The latter can happen if the class hierarchy is not completely available and hence precise information about a type's supertypes is not available.
- Annotations
- @tailrec()
- Note
The answer
No
does not necessarily imply that two runtime values for which the given types are only upper bounds are not (w.r.t. their runtime types) in a subtype relation. E.g., ifsubtype
denotes the typejava.util.List
andsupertype
denotes the typejava.util.ArrayList
then the answer is clearlyNo
. But, at runtime, this may not be the case. I.e., only the answerYes
is conclusive. In case ofNo
further information needs to be taken into account by the caller to determine what it means that the (upper) type (bounds) of the underlying values are not in an inheritance relation.
- def isASubtypeOf(subtype: ObjectType, theSupertype: ObjectType): Answer
Determines if the given class or interface type
subtype
is actually a subtype of the class or interface typesupertype
.Determines if the given class or interface type
subtype
is actually a subtype of the class or interface typesupertype
.This method can be used as a foundation for implementing the logic of the JVM's
instanceof
andcheckcast
instructions. But, in that case additional logic for handlingnull
values and for considering the runtime type needs to be implemented by the caller of this method.- subtype
Any
ObjectType
.- theSupertype
Any
ObjectType
.- returns
Yes
ifsubtype
is a subtype of the givensupertype
.No
ifsubtype
is not a subtype ofsupertype
andUnknown
if the analysis is not conclusive. The latter can happen if the class hierarchy is not complete and hence precise information about a type's supertypes is not available.
- Note
No explicit
isKnown
check is required.
- def isDirectSuperclassTypeInformationComplete(objectType: ObjectType): Boolean
Returns
true
if the type hierarchy information related to the given type's supertypes is complete.Returns
true
if the type hierarchy information related to the given type's supertypes is complete.- Annotations
- @inline()
- Note
No explicit
isKnown
check is required.
- final def isInstanceOf[T0]: Boolean
- Definition Classes
- Any
- def isInterface(objectType: ObjectType): Answer
Returns
true
if the givenobjectType
is known and defines an interface type.Returns
true
if the givenobjectType
is known and defines an interface type.- objectType
An
ObjectType
.
- Annotations
- @inline()
- Note
No explicit
isKnown
check is required.
- final def isKnown(objectTypeId: Int): Boolean
- Annotations
- @inline()
- final def isKnown(objectType: ObjectType): Boolean
Returns
true
if the class hierarchy has some information about the given type.Returns
true
if the class hierarchy has some information about the given type.- Annotations
- @inline()
- Note
Consider using isKnown(objectTypeId : Int) if you need the object ids anyway.
- def isKnownToBeFinal(referenceType: ReferenceType): Boolean
Returns
true
if the given type is known and isfinal
.Returns
true
if the given type is known and isfinal
. I.e., the declaring class was explicitly declared final or – if the type identifies an array type – the component type is either known to be final or is a primitive/base type.- returns
false
is returned if:- the object type/component type is unknown,
- the object type/component type is known not to be final or
- the information about the object type/component type is incomplete
- Annotations
- @inline()
- Note
No explicit
isKnown
check is required.
- def isKnownToBeFinal(objectTypeId: Int): Boolean
- Annotations
- @inline()
- def isKnownToBeFinal(objectType: ObjectType): Boolean
Returns
true
if the given type isfinal
.Returns
true
if the given type isfinal
. I.e., the declaring class was explicitly declaredfinal
and no subtypes exist.- returns
false
is returned if:- the object type is unknown,
- the object type is known not to be final or
- the information is incomplete
- Annotations
- @inline()
- Note
No explicit
isKnown
check is required.
- def isSubtypeOf(subtypes: UIDSet[_ <: ReferenceType], supertype: ReferenceType): Boolean
- def isSubtypeOf(subtype: ReferenceType, supertypes: UIDSet[_ <: ReferenceType]): Boolean
Returns
true
if the subtype is a subtype of all given supertypes.Returns
true
if the subtype is a subtype of all given supertypes. Hence, supertypes should not contain more than one class type. - def isSubtypeOf(subtypes: UIDSet[_ <: ReferenceType], supertypes: UIDSet[_ <: ReferenceType]): Boolean
Determines if the type described by the first set of upper type bounds is a subtype of the second type.
Determines if the type described by the first set of upper type bounds is a subtype of the second type. I.e., it checks, if for all types of the
subtypes
upper type bound, a type in thesupertypes
type exists that is a supertype of the respective subtype. Ifsubtypes
is empty,true
will be returned; an empty upper type bound is expected to modelnull
. - def isSubtypeOf(subtype: ObjectType, theSupertype: ObjectType): Boolean
Returns
true
if subtype is a subtype ofsupertype
;false
is returned if the subtyping relationship is unknown ORsubtype
is not a subtype ofsupertype
.Returns
true
if subtype is a subtype ofsupertype
;false
is returned if the subtyping relationship is unknown ORsubtype
is not a subtype ofsupertype
.isSubtypeOf
is reflexive.See
isASubtypeOf
if more precise information about the subtyping relationship is required. - final def isSubtypeOf(subtype: ReferenceType, supertype: ReferenceType): Boolean
Determines if
subtype
is a subtype ofsupertype
using this class hierarchy.Determines if
subtype
is a subtype ofsupertype
using this class hierarchy.This method can be used as a foundation for implementing the logic of the JVM's
instanceof
andclasscast
instructions. But, in both cases additional logic for handlingnull
values and for considering the runtime type needs to be implemented by the caller of this method.- subtype
Any class, interface or array type.
- supertype
Any class, interface or array type.
- returns
true
ifsubtype
is indeed a subtype of the givensupertype
.false
is returned if the typing relation is unknown OR ifsubtype
is definitively not a subtype ofsupertype
.
- Annotations
- @tailrec()
- Note
The answer
false
does not necessarily imply that two runtime values for which the given types are only upper bounds are not (w.r.t. their runtime types) in a subtype relation. E.g., ifsubtype
denotes the typejava.util.List
andsupertype
denotes the typejava.util.ArrayList
then the answer is clearlyfalse
. But, at runtime, this may not be the case. I.e., only the answertrue
is conclusive. In case offalse
further information needs to be taken into account by the caller to determine what it means that the (upper) type (bounds) of the underlying values are not in an inheritance relation.
- final def isSupertypeInformationComplete(objectType: ObjectType): Boolean
Returns
true
if the type hierarchy has complete information about all supertypes of the given type.Returns
true
if the type hierarchy has complete information about all supertypes of the given type.- Annotations
- @inline()
- Note
No explicit
isKnown
check is required.
- final def isUnknown(objectTypeId: Int): Boolean
- Annotations
- @inline()
- final def isUnknown(objectType: ObjectType): Boolean
Returns
true
if the type is unknown.Returns
true
if the type is unknown. This istrue
for all types that are referred to in the body of a method, but which are not referred to in the declarations of the class files that were analyzed.- Annotations
- @inline()
- Note
Consider using isUnknown(objectTypeId : Int) if you need the object ids anyway.
- def joinAnyArrayTypeWithMultipleTypesBound(thatUpperTypeBound: UIDSet[ObjectType]): UIDSet[ObjectType]
Calculates the most specific common supertype of any array type and some class-/interface type.
Calculates the most specific common supertype of any array type and some class-/interface type.
Recall that (Java) arrays implement
Cloneable
andSerializable
. - def joinAnyArrayTypeWithObjectType(thatUpperTypeBound: ObjectType): UIDSet[ObjectType]
Calculates the most specific common supertype of any array type and some class-/interface type.
Calculates the most specific common supertype of any array type and some class-/interface type.
Recall that (Java) arrays implement
Cloneable
andSerializable
. - def joinArrayType(upperTypeBoundA: ArrayType, upperTypeBoundB: UIDSet[_ <: ReferenceType]): UIDSet[_ <: ReferenceType]
- def joinArrayTypes(thisUpperTypeBound: ArrayType, thatUpperTypeBound: ArrayType): Either[ArrayType, UIDSet[ObjectType]]
Calculates the most specific common supertype of two array types.
Calculates the most specific common supertype of two array types.
- returns
Left(<SOME_ARRAYTYPE>)
if the calculated type can be represented using anArrayType
andRight(UIDList(ObjectType.Serializable, ObjectType.Cloneable))
if the two arrays do not have anArrayType
as a most specific common supertype.
- def joinObjectTypes(upperTypeBoundA: ObjectType, upperTypeBoundB: ObjectType, reflexive: Boolean): UIDSet[ObjectType]
Tries to calculate the most specific common supertype of the two given types.
Tries to calculate the most specific common supertype of the two given types. If
reflexive
isfalse
, the two types do not have to be in an inheritance relation.If the class hierarchy is not complete, a best guess is made.
- def joinObjectTypes(upperTypeBoundA: ObjectType, upperTypeBoundB: UIDSet[ObjectType], reflexive: Boolean): UIDSet[ObjectType]
Tries to calculate the most specific common supertype of the given types.
Tries to calculate the most specific common supertype of the given types. If
reflexive
isfalse
, the given types do not have to be in an inheritance relation.- upperTypeBoundB
A list (set) of
ObjectType
s that are not in a mutual inheritance relation.- returns
(I) Returns (if reflexive is
true
)upperTypeBoundA
if it is a supertype of at least one type ofupperTypeBoundB
. (II) ReturnsupperTypeBoundB
ifupperTypeBoundA
is a subtype of all types ofupperTypeBoundB
. Otherwise a new upper type bound is calculated and returned.
- def joinObjectTypesUntilSingleUpperBound(upperTypeBound: UIDSet[ObjectType]): ObjectType
Given an upper type bound a most specific type that is a common supertype of the given types is determined.
Given an upper type bound a most specific type that is a common supertype of the given types is determined.
- See also
joinObjectTypesUntilSingleUpperBound(upperTypeBoundA: ObjectType, upperTypeBoundB: ObjectType, reflexive: Boolean)
for further details.
- def joinObjectTypesUntilSingleUpperBound(upperTypeBoundA: ObjectType, upperTypeBoundB: ObjectType, reflexive: Boolean): ObjectType
- def joinReferenceType(upperTypeBoundA: ReferenceType, upperTypeBoundB: UIDSet[_ <: ReferenceType]): UIDSet[_ <: ReferenceType]
- def joinReferenceTypes(upperTypeBoundA: UIDSet[_ <: ReferenceType], upperTypeBoundB: UIDSet[_ <: ReferenceType]): UIDSet[_ <: ReferenceType]
- def joinReferenceTypesUntilSingleUpperBound(upperTypeBound: UIDSet[_ <: ReferenceType]): ReferenceType
- def joinUpperTypeBounds(utbA: UIDSet[_ <: ReferenceType], utbB: UIDSet[_ <: ReferenceType]): UIDSet[_ <: ReferenceType]
- def joinUpperTypeBounds(upperTypeBoundsA: UIDSet[ObjectType], upperTypeBoundsB: UIDSet[ObjectType], reflexive: Boolean): UIDSet[ObjectType]
Calculates the most specific common supertype of the given types.
Calculates the most specific common supertype of the given types. If
reflexive
isfalse
, no two types across both sets have to be in an inheritance relation; if in doubt usetrue
.- upperTypeBoundsB
A list (set) of
ObjectType
s that are not in an inheritance relation if reflexive isfalse
.
/* Consider the following type hierarchy: * Object <- Collection <- List * Object <- Collection <- Set * Object <- Externalizable * Object <- Serializable */ Object o = new ... if (...) { Set s = (Set) o; (( Externalizable)s).save(...) // => o(s) has to be a subtype of Set AND Externalizable } else { List l = (List) l; ((Serializable)l).store(...) // => o(l) has to be a subtype of List AND Serializable } // Here, o is either a set or a list. Hence, it is at least a Collection, // but we cannot deduce anything w.r.t. Serializable and Externalizable.
Example: - def leafClassTypesIterator: Iterator[ObjectType]
- def leafTypes(types: UIDSet[ObjectType]): UIDSet[ObjectType]
Selects all types of the given set of types that do not have any subtype in the given set.
Selects all types of the given set of types that do not have any subtype in the given set. If the given set is empty, a set containing
java.lang.Object
is returned. A set which contains only one type will directly be returned.- types
A set of types that contains for each type stored in the set all direct and indirect supertypes or none. For example, the intersection of the sets of all supertypes (as returned, e.g., by
ClassHierarchy.allSupertypes
) of two (independent) types satisfies this condition. Iftypes
is empty, the returned leaf type isObjectType.Object
. which should always be a safe fallback.
- val leafTypes: UIDSet[ObjectType]
- implicit val logContext: LogContext
- final def ne(arg0: AnyRef): Boolean
- Definition Classes
- AnyRef
- final def notify(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @IntrinsicCandidate()
- final def notifyAll(): Unit
- Definition Classes
- AnyRef
- Annotations
- @native() @IntrinsicCandidate()
- def processSubtypes[T](objectType: ObjectType, reflexive: Boolean = false)(initial: T)(f: (T, ObjectType) => (T, Boolean, Boolean)): T
Enables the guided processing of all subtypes of the given type.
Enables the guided processing of all subtypes of the given type. This function enables you to compute some value based on the subtypes of the given type and – at the same time – to control the process of traversing the subtypes.
- initial
The initial value of the computation. This is also the value that will be returned if the given type has no subtypes and
reflexive
isfalse
.- f
A function that computes the new value given the current value and which also returns the information whether the computation should be aborted using the current value of type
t
or if the subtypes of the current subtype should be traversed. The commented signature off
is:f: (T, ObjectType) => (T /*result*/ , Boolean /*skip subtypes*/ , Boolean /*abort*/ )
- def rootClassTypesIterator: Iterator[ObjectType]
The set of all class types (excluding interfaces) which have no super type or for which the supertype information is incomplete; that is all (pseudo) root types.
The set of all class types (excluding interfaces) which have no super type or for which the supertype information is incomplete; that is all (pseudo) root types. If the class hierarchy is complete, then this set contains exactly one element and that element must identify
java.lang.Object
.- Note
The returned root class types are not necessarily a subset of
,rootTypes
. A class which has an unknown super class, but implements a known interface is considered to belong to be a root class type but is not a member ofrootTypes
because some supertype information exists!If we load an application and all the jars used to implement it or a library and all the library it depends on, then the class hierarchy should not contain multiple root types. However, the (complete) JDK contains some references to Eclipse classes which are not part of the JDK.
- def rootInterfaceTypes(collection: Growable[ObjectType]): rootInterfaceTypes.collection.type
Iterates over all interfaces which only inherit from
java.lang.Object
and adds the types to the givenGrowable
collection.Iterates over all interfaces which only inherit from
java.lang.Object
and adds the types to the givenGrowable
collection. I.e., iterates over all interfaces which are at the top of the interface inheritance hierarchy. - val rootTypes: UIDSet[ObjectType]
- def statistics: String
Returns some statistical data about the class hierarchy.
- def subtypeInformation(objectType: ObjectType): Option[SubtypeInformation]
Returns the subtype information if the given type is known.
Returns the subtype information if the given type is known. If the given type is unknown
None
is returned. - def superclassType(objectTypeId: Int): ObjectType
Returns the supertype of the object type identified by the given object type id or
null
if the type is unknown or if the type has no supertype. - def superclassType(objectType: ObjectType): Option[ObjectType]
Returns the immediate superclass of the given object type, if the given type is known and if it has a superclass.
Returns the immediate superclass of the given object type, if the given type is known and if it has a superclass. I.e., in case of
java.lang.Object
None is returned. - def superclasses(objectType: ObjectType, project: ClassFileRepository)(classFileFilter: (ClassFile) => Boolean = _ => true): Iterable[ClassFile]
Returns the set of all classes/interfaces from which the given type inherits and for which the respective class file is available.
Returns the set of all classes/interfaces from which the given type inherits and for which the respective class file is available.
- returns
An
Iterable
over all class files of all super types of the givenobjectType
that pass the given filter and for which the class file is available.
- Note
It may be more efficient to use
foreachSuperclass(ObjectType, ObjectType => Option[ClassFile])(ClassFile => Unit)
- def superinterfaceTypes(objectType: ObjectType): Option[UIDSet[ObjectType]]
Returns
Some(<SUPERTYPES>)
if this type is known and information about the supertypes is available.Returns
Some(<SUPERTYPES>)
if this type is known and information about the supertypes is available. I.e., if this type is not known,None
is returned; if the given type's superinterfaces are known (even if this class does not implement (directly or indirectly) any interface)Some(UIDSet(<OBJECTTYPES>))
is returned. - def supertypeInformation(objectType: ObjectType): Option[SupertypeInformation]
Returns the supertype information if the given type is known.
Returns the supertype information if the given type is known. If the given type is unknown
None
is returned. - def supertypes(objectType: ObjectType): UIDSet[ObjectType]
- final def synchronized[T0](arg0: => T0): T0
- Definition Classes
- AnyRef
- def toGraph(): Node
Returns a view of the class hierarchy as a graph (which can then be transformed into a dot representation Graphviz).
Returns a view of the class hierarchy as a graph (which can then be transformed into a dot representation Graphviz). This graph can be a multi-graph if the class hierarchy contains holes.
- def toString(): String
- Definition Classes
- ClassHierarchy → AnyRef → Any
- def updatedLogContext(newLogContext: LogContext): ClassHierarchy
- final def wait(arg0: Long, arg1: Int): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(arg0: Long): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
- final def wait(): Unit
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.InterruptedException])
Deprecated Value Members
- def finalize(): Unit
- Attributes
- protected[lang]
- Definition Classes
- AnyRef
- Annotations
- @throws(classOf[java.lang.Throwable]) @Deprecated
- Deprecated