Class QualifierHierarchy
- Direct Known Subclasses:
ElementQualifierHierarchy
,NoElementQualifierHierarchy
getWidth()
gives the number of hierarchies
that this object represents. Each hierarchy has its own top and bottom, and subtyping
relationships exist only within each hierarchy.
Note the distinction in terminology between a qualifier hierarchy, which has one top and one
bottom, and a QualifierHierarchy
, which represents multiple qualifier hierarchies.
All type annotations need to be type qualifiers recognized within this hierarchy.
This assumes that every annotated type in a program is annotated with exactly one qualifier from each hierarchy.
-
Field Summary
Modifier and TypeFieldDescriptionprotected GenericAnnotatedTypeFactory<?,
?, ?, ?> The associated type factory. -
Constructor Summary
ConstructorDescriptionQualifierHierarchy
(GenericAnnotatedTypeFactory<?, ?, ?, ?> atypeFactory) Creates a new QualifierHierarchy. -
Method Summary
Modifier and TypeMethodDescriptionstatic void
assertSameSize
(Collection<? extends Object> c1, Collection<? extends Object> c2, Collection<? extends Object> result) Throws an exception if the result and the inputs do not all have the same size.static void
assertSameSize
(Collection<?> c1, Collection<?> c2) Throws an exception if the given collections do not have the same size.static boolean
Returns true if and only ifAnnotatedTypeMirror.getPrimaryAnnotations()
can return a set with fewer qualifiers than the width of the QualifierHierarchy.findAnnotationInHierarchy
(Collection<? extends AnnotationMirror> qualifiers, AnnotationMirror top) Returns the annotation inqualifiers
that is in the hierarchy for whichtop
is top.findAnnotationInSameHierarchy
(Collection<? extends AnnotationMirror> qualifiers, AnnotationMirror qualifier) Returns the annotation inqualifiers
that is in the same hierarchy asqualifier
.abstract AnnotationMirror
getBottomAnnotation
(AnnotationMirror qualifier) Return the bottom for the given qualifier, that is, the qualifier that is a subtype ofqualifier
but no further subtypes exist.abstract AnnotationMirrorSet
Returns the bottom type qualifiers in the hierarchy.abstract @Nullable AnnotationMirror
getPolymorphicAnnotation
(AnnotationMirror qualifier) Returns the polymorphic qualifier for the hierarchy containingqualifier
, ornull
if there is no polymorphic qualifier in that hierarchy.abstract AnnotationMirror
getTopAnnotation
(AnnotationMirror qualifier) Return the top qualifier for the given qualifier, that is, the qualifier that is a supertype ofqualifier
but no further supertypes exist.abstract AnnotationMirrorSet
Returns the top (ultimate super) type qualifiers in the type system.int
getWidth()
Returns the width of this hierarchy, i.e.protected abstract @Nullable AnnotationMirror
greatestLowerBoundQualifiers
(AnnotationMirror qualifier1, AnnotationMirror qualifier2) Returns the greatest lower bound for the qualifiers qualifier1 and qualifier2.final @Nullable AnnotationMirror
greatestLowerBoundQualifiersOnly
(AnnotationMirror qualifier1, AnnotationMirror qualifier2) Returns the greatest lower bound for the qualifiers qualifier1 and qualifier2.greatestLowerBoundShallow
(AnnotationMirror qualifier1, TypeMirror tm1, AnnotationMirror qualifier2, TypeMirror tm2) Returns the greatest lower bound for the qualifiers qualifier1 and qualifier2.final Set<? extends AnnotationMirror>
greatestLowerBoundsShallow
(Collection<? extends AnnotationMirror> qualifiers1, TypeMirror tm1, Collection<? extends AnnotationMirror> qualifiers2, TypeMirror tm2) Returns the greatest lower bound of the two sets of qualifiers.abstract boolean
isPolymorphicQualifier
(AnnotationMirror qualifier) Returnstrue
if the qualifier is a polymorphic qualifier; otherwise, returnsfalse
.protected abstract boolean
isSubtypeQualifiers
(AnnotationMirror subQualifier, AnnotationMirror superQualifier) Tests whethersubQualifier
is equal to or a sub-qualifier ofsuperQualifier
, according to the type qualifier hierarchy, ignoring Java basetypes.final boolean
isSubtypeQualifiersOnly
(AnnotationMirror subQualifier, AnnotationMirror superQualifier) Tests whethersubQualifier
is equal to or a sub-qualifier ofsuperQualifier
, according to the type qualifier hierarchy, ignoring Java basetypes.final boolean
isSubtypeShallow
(Collection<? extends AnnotationMirror> subQualifiers, Collection<? extends AnnotationMirror> superQualifiers, TypeMirror typeMirror) Tests whether all qualifiers insubQualifiers
are a subqualifier of or equal to the qualifier in the same hierarchy insuperQualifiers
.final boolean
isSubtypeShallow
(Collection<? extends AnnotationMirror> subQualifiers, TypeMirror subType, Collection<? extends AnnotationMirror> superQualifiers, TypeMirror superType) Tests whether all qualifiers insubQualifiers
are a subqualifier or equal to the qualifier in the same hierarchy insuperQualifiers
.final boolean
isSubtypeShallow
(AnnotationMirror subQualifier, AnnotationMirror superQualifier, TypeMirror typeMirror) Tests whethersubQualifier
is equal to or a sub-qualifier ofsuperQualifier
, according to the type qualifier hierarchy.boolean
isSubtypeShallow
(AnnotationMirror subQualifier, TypeMirror subType, AnnotationMirror superQualifier, TypeMirror superType) Tests whethersubQualifier
is equal to or a sub-qualifier ofsuperQualifier
, according to the type qualifier hierarchy.boolean
isValid()
Determine whether this is valid.protected abstract @Nullable AnnotationMirror
leastUpperBoundQualifiers
(AnnotationMirror qualifier1, AnnotationMirror qualifier2) Returns the least upper bound (LUB) of the qualifiersqualifier1
andqualifier2
.final @Nullable AnnotationMirror
leastUpperBoundQualifiersOnly
(AnnotationMirror qualifier1, AnnotationMirror qualifier2) Returns the least upper bound (LUB) of the qualifiersqualifier1
andqualifier2
.leastUpperBoundShallow
(AnnotationMirror qualifier1, TypeMirror tm1, AnnotationMirror qualifier2, TypeMirror tm2) Returns the least upper bound (LUB) of the qualifiersqualifier1
andqualifier2
.final Set<? extends AnnotationMirror>
leastUpperBoundsShallow
(Collection<? extends AnnotationMirror> qualifiers1, TypeMirror tm1, Collection<? extends AnnotationMirror> qualifiers2, TypeMirror tm2) Returns the least upper bound of the two sets of qualifiers.int
Returns the number of iterations dataflow should perform beforewidenedUpperBound(AnnotationMirror, AnnotationMirror)
is called or -1 if it should never be called.<T> boolean
updateMappingToMutableSet
(Map<T, AnnotationMirrorSet> map, T key, AnnotationMirror qualifier) Update a mapping fromkey
to a set of AnnotationMirrors.widenedUpperBound
(AnnotationMirror newQualifier, AnnotationMirror previousQualifier) If the qualifier hierarchy has an infinite ascending chain, then the dataflow analysis might never reach a fixed point.
-
Field Details
-
atypeFactory
The associated type factory. This is used only for checking whether types are relevant.
-
-
Constructor Details
-
QualifierHierarchy
Creates a new QualifierHierarchy.- Parameters:
atypeFactory
- the associated type factory
-
-
Method Details
-
isValid
public boolean isValid()Determine whether this is valid.- Returns:
- true if this is valid
-
getWidth
public int getWidth()Returns the width of this hierarchy, i.e. the expected number of annotations on any valid type.- Returns:
- the width of this QualifierHierarchy
-
getTopAnnotations
Returns the top (ultimate super) type qualifiers in the type system. The size of this set is equal togetWidth()
.- Returns:
- the top (ultimate super) type qualifiers in the type system
-
getTopAnnotation
Return the top qualifier for the given qualifier, that is, the qualifier that is a supertype ofqualifier
but no further supertypes exist.- Parameters:
qualifier
- any qualifier from one of the qualifier hierarchies represented by this- Returns:
- the top qualifier of
qualifier
's hierarchy
-
getBottomAnnotations
Returns the bottom type qualifiers in the hierarchy. The size of this set is equal togetWidth()
.- Returns:
- the bottom type qualifiers in the hierarchy
-
getBottomAnnotation
Return the bottom for the given qualifier, that is, the qualifier that is a subtype ofqualifier
but no further subtypes exist.- Parameters:
qualifier
- any qualifier from one of the qualifier hierarchies represented by this- Returns:
- the bottom qualifier of
qualifier
's hierarchy
-
getPolymorphicAnnotation
Returns the polymorphic qualifier for the hierarchy containingqualifier
, ornull
if there is no polymorphic qualifier in that hierarchy.- Parameters:
qualifier
- any qualifier from one of the qualifier hierarchies represented by this- Returns:
- the polymorphic qualifier for the hierarchy containing
qualifier
, ornull
if there is no polymorphic qualifier in that hierarchy
-
isPolymorphicQualifier
Returnstrue
if the qualifier is a polymorphic qualifier; otherwise, returnsfalse
.- Parameters:
qualifier
- qualifier- Returns:
true
if the qualifier is a polymorphic qualifier; otherwise, returnsfalse
.
-
isSubtypeQualifiers
protected abstract boolean isSubtypeQualifiers(AnnotationMirror subQualifier, AnnotationMirror superQualifier) Tests whethersubQualifier
is equal to or a sub-qualifier ofsuperQualifier
, according to the type qualifier hierarchy, ignoring Java basetypes.Clients should generally call
isSubtypeShallow(javax.lang.model.element.AnnotationMirror, javax.lang.model.type.TypeMirror, javax.lang.model.element.AnnotationMirror, javax.lang.model.type.TypeMirror)
. However, subtypes should generally override this method (if needed).This method behaves the same as
isSubtypeQualifiersOnly(AnnotationMirror, AnnotationMirror)
, which calls this method. This method is for clients inside the framework, and it hasprotected
access to prevent use by clients outside the framework. This makes it easy to find places where code outside the framework is ignoring Java basetypes -- at calls toisSubtypeQualifiersOnly(javax.lang.model.element.AnnotationMirror, javax.lang.model.element.AnnotationMirror)
.- Parameters:
subQualifier
- possible subqualifiersuperQualifier
- possible superqualifier- Returns:
- true iff
subQualifier
is a subqualifier of, or equal to,superQualifier
-
isSubtypeQualifiersOnly
public final boolean isSubtypeQualifiersOnly(AnnotationMirror subQualifier, AnnotationMirror superQualifier) Tests whethersubQualifier
is equal to or a sub-qualifier ofsuperQualifier
, according to the type qualifier hierarchy, ignoring Java basetypes.This method is for clients outside the framework, and should not be used by framework code.
- Parameters:
subQualifier
- possible subqualifiersuperQualifier
- possible superqualifier- Returns:
- true iff
subQualifier
is a subqualifier of, or equal to,superQualifier
-
isSubtypeShallow
public boolean isSubtypeShallow(AnnotationMirror subQualifier, TypeMirror subType, AnnotationMirror superQualifier, TypeMirror superType) Tests whethersubQualifier
is equal to or a sub-qualifier ofsuperQualifier
, according to the type qualifier hierarchy. The typessubType
andsuperType
are not necessarily in a Java subtyping relationship with one another and are only used by this method for special cases when qualifier subtyping depends on the Java basetype.Clients should usually call
isSubtypeShallow()
(this method). Rarely, to ignore the Java basetype, a client can callisSubtypeQualifiersOnly(javax.lang.model.element.AnnotationMirror, javax.lang.model.element.AnnotationMirror)
.Subtypes should override
isSubtypeQualifiers(javax.lang.model.element.AnnotationMirror, javax.lang.model.element.AnnotationMirror)
(not this method), unless qualifier subtyping depends on Java basetypes.- Parameters:
subQualifier
- possible subqualifiersubType
- the Java basetype associated withsubQualifier
superQualifier
- possible superqualifiersuperType
- the Java basetype associated withsuperQualifier
- Returns:
- true iff
subQualifier
is a subqualifier of, or equal to,superQualifier
-
isSubtypeShallow
public final boolean isSubtypeShallow(AnnotationMirror subQualifier, AnnotationMirror superQualifier, TypeMirror typeMirror) Tests whethersubQualifier
is equal to or a sub-qualifier ofsuperQualifier
, according to the type qualifier hierarchy. The typetypeMirror
is only used by this method for special cases when qualifier subtyping depends on the Java basetype.Clients should usually call
isSubtypeShallow(AnnotationMirror, AnnotationMirror, TypeMirror)
(this method) orisSubtypeShallow(AnnotationMirror, TypeMirror, AnnotationMirror, TypeMirror)
. Rarely, to ignore the Java basetype, a client can callisSubtypeQualifiersOnly(javax.lang.model.element.AnnotationMirror, javax.lang.model.element.AnnotationMirror)
.Subtypes should override
isSubtypeQualifiers(javax.lang.model.element.AnnotationMirror, javax.lang.model.element.AnnotationMirror)
(not this method), unless qualifier subtyping depends on Java basetypes.- Parameters:
subQualifier
- possible subqualifiersuperQualifier
- possible superqualifiertypeMirror
- the Java basetype associated with bothsubQualifier
andsuperQualifier
- Returns:
- true iff
subQualifier
is a subqualifier of, or equal to,superQualifier
-
isSubtypeShallow
public final boolean isSubtypeShallow(Collection<? extends AnnotationMirror> subQualifiers, TypeMirror subType, Collection<? extends AnnotationMirror> superQualifiers, TypeMirror superType) Tests whether all qualifiers insubQualifiers
are a subqualifier or equal to the qualifier in the same hierarchy insuperQualifiers
. The typessubType
andsuperType
are not necessarily in a Java subtyping relationship with one another and are only used by this method for special cases when qualifier subtyping depends on the Java basetype.Subtypes more often override
isSubtypeShallow(AnnotationMirror, TypeMirror, AnnotationMirror, TypeMirror)
than this method.- Parameters:
subQualifiers
- set of qualifiers; exactly one per hierarchysubType
- the type associated withsubQualifiers
superQualifiers
- set of qualifiers; exactly one per hierarchysuperType
- the type associated withsuperQualifiers
- Returns:
- true iff all qualifiers in
subQualifiers
are a subqualifier or equal to the qualifier in the same hierarchy insuperQualifiers
-
isSubtypeShallow
public final boolean isSubtypeShallow(Collection<? extends AnnotationMirror> subQualifiers, Collection<? extends AnnotationMirror> superQualifiers, TypeMirror typeMirror) Tests whether all qualifiers insubQualifiers
are a subqualifier of or equal to the qualifier in the same hierarchy insuperQualifiers
. The typetypeMirror
is only used by this method for special cases when qualifier subtyping depends on the Java basetype.Subtypes more often override
isSubtypeShallow(AnnotationMirror, TypeMirror, AnnotationMirror, TypeMirror)
than this method.- Parameters:
subQualifiers
- a set of qualifiers; exactly one per hierarchysuperQualifiers
- a set of qualifiers; exactly one per hierarchytypeMirror
- the type associated with both sets of qualifiers- Returns:
- true iff all qualifiers in
subQualifiers
are a subqualifier or equal to the qualifier in the same hierarchy insuperQualifiers
-
leastUpperBoundQualifiers
protected abstract @Nullable AnnotationMirror leastUpperBoundQualifiers(AnnotationMirror qualifier1, AnnotationMirror qualifier2) Returns the least upper bound (LUB) of the qualifiersqualifier1
andqualifier2
. Returnsnull
if the qualifiers are not from the same qualifier hierarchy. Ignores Java basetypes.Examples:
- For NonNull, leastUpperBound('Nullable', 'NonNull') ⇒ Nullable
- Parameters:
qualifier1
- the first qualifier; may not be in the same hierarchy asqualifier2
qualifier2
- the second qualifier; may not be in the same hierarchy asqualifier1
- Returns:
- the least upper bound of the qualifiers, or
null
if the qualifiers are from different hierarchies
-
leastUpperBoundQualifiersOnly
public final @Nullable AnnotationMirror leastUpperBoundQualifiersOnly(AnnotationMirror qualifier1, AnnotationMirror qualifier2) Returns the least upper bound (LUB) of the qualifiersqualifier1
andqualifier2
. Returnsnull
if the qualifiers are not from the same qualifier hierarchy. Ignores Java basetypes.Examples:
- For NonNull, leastUpperBound('Nullable', 'NonNull') ⇒ Nullable
- Parameters:
qualifier1
- the first qualifier; may not be in the same hierarchy asqualifier2
qualifier2
- the second qualifier; may not be in the same hierarchy asqualifier1
- Returns:
- the least upper bound of the qualifiers, or
null
if the qualifiers are from different hierarchies
-
leastUpperBoundShallow
public @Nullable AnnotationMirror leastUpperBoundShallow(AnnotationMirror qualifier1, TypeMirror tm1, AnnotationMirror qualifier2, TypeMirror tm2) Returns the least upper bound (LUB) of the qualifiersqualifier1
andqualifier2
. Returnsnull
if the qualifiers are not from the same qualifier hierarchy.Examples:
- leastUpperBound('Nullable', 'NonNull') ⇒ Nullable
- Parameters:
qualifier1
- the first qualifier; may not be in the same hierarchy asqualifier2
tm1
- the type on which qualifier1 appearsqualifier2
- the second qualifier; may not be in the same hierarchy asqualifier1
tm2
- the type on which qualifier2 appears- Returns:
- the least upper bound of the qualifiers, or
null
if the qualifiers are from different hierarchies
-
leastUpperBoundsShallow
public final Set<? extends AnnotationMirror> leastUpperBoundsShallow(Collection<? extends AnnotationMirror> qualifiers1, TypeMirror tm1, Collection<? extends AnnotationMirror> qualifiers2, TypeMirror tm2) Returns the least upper bound of the two sets of qualifiers. The result is the lub of the qualifier for the same hierarchy in each set.- Parameters:
qualifiers1
- set of qualifiers; exactly one per hierarchytm1
- the type on which qualifiers1 appearqualifiers2
- set of qualifiers; exactly one per hierarchytm2
- the type on which qualifiers2 appear- Returns:
- the least upper bound of the two sets of qualifiers
-
numberOfIterationsBeforeWidening
public int numberOfIterationsBeforeWidening()Returns the number of iterations dataflow should perform beforewidenedUpperBound(AnnotationMirror, AnnotationMirror)
is called or -1 if it should never be called.- Returns:
- the number of iterations dataflow should perform before
widenedUpperBound(AnnotationMirror, AnnotationMirror)
is called or -1 if it should never be called.
-
widenedUpperBound
public AnnotationMirror widenedUpperBound(AnnotationMirror newQualifier, AnnotationMirror previousQualifier) If the qualifier hierarchy has an infinite ascending chain, then the dataflow analysis might never reach a fixed point. To prevent this, implement this method such that it returns an upper bound for the two qualifiers that is a strict super type of the least upper bound. If this method is implemented, also overridenumberOfIterationsBeforeWidening()
to return a positive number.newQualifier
is newest qualifier dataflow computed for some expression andpreviousQualifier
is the qualifier dataflow computed on the last iteration.If the qualifier hierarchy has no infinite ascending chain, returns the least upper bound of the two annotations.
- Parameters:
newQualifier
- new qualifier dataflow computed for some expression; must be in the same hierarchy aspreviousQualifier
previousQualifier
- the previous qualifier dataflow computed on the last iteration; must be in the same hierarchy aspreviousQualifier
- Returns:
- an upper bound that is higher than the least upper bound of newQualifier and previousQualifier (or the lub if the qualifier hierarchy does not require this)
-
greatestLowerBoundQualifiers
protected abstract @Nullable AnnotationMirror greatestLowerBoundQualifiers(AnnotationMirror qualifier1, AnnotationMirror qualifier2) Returns the greatest lower bound for the qualifiers qualifier1 and qualifier2. Returns null if the qualifiers are not from the same qualifier hierarchy.- Parameters:
qualifier1
- first qualifierqualifier2
- second qualifier- Returns:
- greatest lower bound of the two annotations, or null if the two annotations are not from the same hierarchy
-
greatestLowerBoundQualifiersOnly
public final @Nullable AnnotationMirror greatestLowerBoundQualifiersOnly(AnnotationMirror qualifier1, AnnotationMirror qualifier2) Returns the greatest lower bound for the qualifiers qualifier1 and qualifier2. Returns null if the qualifiers are not from the same qualifier hierarchy.- Parameters:
qualifier1
- first qualifierqualifier2
- second qualifier- Returns:
- greatest lower bound of the two annotations, or null if the two annotations are not from the same hierarchy
-
greatestLowerBoundShallow
public @Nullable AnnotationMirror greatestLowerBoundShallow(AnnotationMirror qualifier1, TypeMirror tm1, AnnotationMirror qualifier2, TypeMirror tm2) Returns the greatest lower bound for the qualifiers qualifier1 and qualifier2. Returns null if the qualifiers are not from the same qualifier hierarchy.- Parameters:
qualifier1
- first qualifiertm1
- the type that is annotated by qualifier1qualifier2
- second qualifiertm2
- the type that is annotated by qualifier2- Returns:
- greatest lower bound of the two annotations, or null if the two annotations are not from the same hierarchy
-
greatestLowerBoundsShallow
public final Set<? extends AnnotationMirror> greatestLowerBoundsShallow(Collection<? extends AnnotationMirror> qualifiers1, TypeMirror tm1, Collection<? extends AnnotationMirror> qualifiers2, TypeMirror tm2) Returns the greatest lower bound of the two sets of qualifiers. The result is the lub of the qualifier for the same hierarchy in each set.- Parameters:
qualifiers1
- set of qualifiers; exactly one per hierarchytm1
- the type that is annotated by qualifier1qualifiers2
- set of qualifiers; exactly one per hierarchytm2
- the type that is annotated by qualifier2- Returns:
- the greatest lower bound of the two sets of qualifiers
-
canHaveEmptyAnnotationSet
Returns true if and only ifAnnotatedTypeMirror.getPrimaryAnnotations()
can return a set with fewer qualifiers than the width of the QualifierHierarchy.- Parameters:
type
- the type to test- Returns:
- true if and only if
AnnotatedTypeMirror.getPrimaryAnnotations()
can return a set with fewer qualifiers than the width of the QualifierHierarchy
-
findAnnotationInSameHierarchy
public @Nullable AnnotationMirror findAnnotationInSameHierarchy(Collection<? extends AnnotationMirror> qualifiers, AnnotationMirror qualifier) Returns the annotation inqualifiers
that is in the same hierarchy asqualifier
.The default implementation calls
getTopAnnotation(AnnotationMirror)
and then callsfindAnnotationInHierarchy(Collection, AnnotationMirror)
. So, ifqualifier
is a top qualifier, then callfindAnnotationInHierarchy(Collection, AnnotationMirror)
directly is faster.- Parameters:
qualifiers
- set of annotations to searchqualifier
- annotation that is in the same hierarchy as the returned annotation- Returns:
- annotation in the same hierarchy as qualifier, or null if one is not found
-
findAnnotationInHierarchy
public @Nullable AnnotationMirror findAnnotationInHierarchy(Collection<? extends AnnotationMirror> qualifiers, AnnotationMirror top) Returns the annotation inqualifiers
that is in the hierarchy for whichtop
is top.- Parameters:
qualifiers
- set of annotations to searchtop
- the top annotation in the hierarchy to which the returned annotation belongs- Returns:
- annotation in the same hierarchy as annotationMirror, or null if one is not found
-
updateMappingToMutableSet
public <T> boolean updateMappingToMutableSet(Map<T, AnnotationMirrorSet> map, T key, AnnotationMirror qualifier) Update a mapping fromkey
to a set of AnnotationMirrors. Ifkey
is not already in the map, then put it in the map with a value of a new set containingqualifier
. If the map containskey
, then addqualifier
to the set to whichkey
maps. If that set contains a qualifier in the same hierarchy asqualifier
, then don't add it and return false.- Type Parameters:
T
- type of the map's keys- Parameters:
map
- the mapping to modifykey
- the key to update or addqualifier
- the value to update or add- Returns:
- true if the update was done; false if there was a qualifier hierarchy collision
-
assertSameSize
Throws an exception if the given collections do not have the same size.- Parameters:
c1
- the first collectionc2
- the second collection
-
assertSameSize
public static void assertSameSize(Collection<? extends Object> c1, Collection<? extends Object> c2, Collection<? extends Object> result) Throws an exception if the result and the inputs do not all have the same size.- Parameters:
c1
- the first collectionc2
- the second collectionresult
- the result collection
-