Class CFAbstractValue<V extends CFAbstractValue<V>>
- Type Parameters:
V
- the values that this CFAbstractValue wraps
- All Implemented Interfaces:
AbstractValue<V>
- Direct Known Subclasses:
AccumulationValue
,CFValue
,KeyForValue
,NullnessValue
A value holds a set of annotations and a type mirror. The set of annotations represents the primary annotation on a type; therefore, the set of annotations must have an annotation for each hierarchy unless the type mirror is a type variable or a wildcard that extends a type variable. Both type variables and wildcards may be missing a primary annotation. For this set of annotations, there is an additional constraint that only wildcards that extend type variables can be missing annotations.
In order to compute leastUpperBound(CFAbstractValue)
and mostSpecific(CFAbstractValue, CFAbstractValue)
, the case where one value has an annotation in a
hierarchy and the other does not must be handled. For type variables, the AnnotatedTypeMirror.AnnotatedTypeVariable
for the declaration of the type variable is used. The AnnotatedTypeMirror.AnnotatedTypeVariable
is computed using the type mirror. For wildcards, it is not always
possible to get the AnnotatedTypeMirror.AnnotatedWildcardType
for the type mirror. However, a
CFAbstractValue's type mirror is only a wildcard if the type of some expression is a wildcard.
The type of an expression is only a wildcard because the Checker Framework does not implement
capture conversion. For these uses of uncaptured wildcards, only the primary annotation on the
upper bound is ever used. So, the set of annotations represents the primary annotation on the
wildcard's upper bound. If that upper bound is a type variable, then the set of annotations could
be missing an annotation in a hierarchy.
-
Nested Class Summary
Modifier and TypeClassDescriptionprotected class
Combines two sets of AnnotationMirrors by hierarchy.protected class
Computes the GLB of two sets of annotations.protected class
Computes the least upper bound or, ifshouldWiden
is true, an upper bounds of two sets of annotations. -
Field Summary
Modifier and TypeFieldDescriptionprotected final CFAbstractAnalysis<V,
?, ?> The analysis class this value belongs to.protected final AnnotationMirrorSet
The annotations in this abstract value.protected final AnnotatedTypeFactory
The type factory.protected final QualifierHierarchy
The qualifier hierarchy.protected final TypeMirror
The underlying (Java) type in this abstract value. -
Constructor Summary
ModifierConstructorDescriptionprotected
CFAbstractValue
(CFAbstractAnalysis<V, ?, ?> analysis, AnnotationMirrorSet annotations, TypeMirror underlyingType) Creates a new CFAbstractValue. -
Method Summary
Modifier and TypeMethodDescriptionboolean
Returns whether or not the set of annotations can be missing an annotation for any hierarchy.boolean
Returns a set of annotations.greatestLowerBound
(@Nullable V other) Compute the greatest lower bound of two values.int
hashCode()
final V
leastUpperBound
(@Nullable V other) Compute the least upper bound of two values.final V
leastUpperBound
(@Nullable V other, TypeMirror typeMirror) Compute the least upper bound of two abstract values.mostSpecific
(@Nullable V other, @Nullable V backup) Returns the more specific of two valuesthis
andother
.toString()
Returns the string representation.Returns the string representation, using fully-qualified names.Returns the string representation, using simple (not fully-qualified) names.protected V
upperBound
(@Nullable V other, TypeMirror upperBoundTypeMirror, boolean shouldWiden) Returns an upper bound ofthis
andother
.static boolean
validateSet
(AnnotationMirrorSet annos, TypeMirror typeMirror, AnnotatedTypeFactory atypeFactory) Returns true if the set has an annotation from every hierarchy (or if it doesn't need to); returns false if the set is missing an annotation from some hierarchy.final V
widenUpperBound
(@Nullable V previous) Compute an upper bound of two values that is wider than the least upper bound of the two values.
-
Field Details
-
analysis
The analysis class this value belongs to. -
atypeFactory
The type factory. -
qualHierarchy
The qualifier hierarchy. -
underlyingType
The underlying (Java) type in this abstract value. -
annotations
The annotations in this abstract value.
-
-
Constructor Details
-
CFAbstractValue
protected CFAbstractValue(CFAbstractAnalysis<V, ?, ?> analysis, AnnotationMirrorSet annotations, TypeMirror underlyingType) Creates a new CFAbstractValue.- Parameters:
analysis
- the analysis class this value belongs toannotations
- the annotations in this abstract valueunderlyingType
- the underlying (Java) type in this abstract value
-
-
Method Details
-
validateSet
public static boolean validateSet(AnnotationMirrorSet annos, TypeMirror typeMirror, AnnotatedTypeFactory atypeFactory) Returns true if the set has an annotation from every hierarchy (or if it doesn't need to); returns false if the set is missing an annotation from some hierarchy.- Parameters:
annos
- set of annotationstypeMirror
- where the annotations are writtenatypeFactory
- the type factory- Returns:
- true if no annotations are missing
-
canBeMissingAnnotations
public boolean canBeMissingAnnotations()Returns whether or not the set of annotations can be missing an annotation for any hierarchy.- Returns:
- whether or not the set of annotations can be missing an annotation
-
getAnnotations
Returns a set of annotations. IfcanBeMissingAnnotations()
returns true, then the set of annotations may not have an annotation for every hierarchy.To get the single annotation in a particular hierarchy, use
QualifierHierarchy.findAnnotationInHierarchy(java.util.Collection<? extends javax.lang.model.element.AnnotationMirror>, javax.lang.model.element.AnnotationMirror)
.- Returns:
- a set of annotations
-
getUnderlyingType
-
equals
-
hashCode
-
toStringFullyQualified
Returns the string representation, using fully-qualified names.- Returns:
- the string representation, using fully-qualified names
-
toStringSimple
Returns the string representation, using simple (not fully-qualified) names.- Returns:
- the string representation, using simple (not fully-qualified) names
-
toString
Returns the string representation. -
mostSpecific
Returns the more specific of two valuesthis
andother
. If they do not contain information for all hierarchies, then it is possible that information from boththis
andother
are taken.If neither of the two is more specific for one of the hierarchies (i.e., if the two are incomparable as determined by
QualifierHierarchy.isSubtypeShallow(AnnotationMirror, TypeMirror, AnnotationMirror, TypeMirror)
, then the respective value frombackup
is used.- Parameters:
other
- the other value to obtain information frombackup
- the value to use ifthis
andother
are incomparable- Returns:
- the more specific of two values
this
andother
-
leastUpperBound
Compute the least upper bound of two values.Important: This method must fulfill the following contract:
- Does not change
this
. - Does not change
other
. - Returns a fresh object which is not aliased yet.
- Returns an object of the same (dynamic) type as
this
, even if the signature is more permissive. - Is commutative.
Subclasses should override
upperBound(CFAbstractValue, TypeMirror, boolean)
instead of this method.- Specified by:
leastUpperBound
in interfaceAbstractValue<V extends CFAbstractValue<V>>
- Parameters:
other
- the other value- Returns:
- the least upper bound of the two values
- Does not change
-
leastUpperBound
Compute the least upper bound of two abstract values. The returned value has a Java type oftypeMirror
.typeMirror
should be an upper bound of the Java types ofthis
another
, but it does not have be to the least upper bound.Subclasses should override
upperBound(CFAbstractValue, TypeMirror, boolean)
instead of this method.- Parameters:
other
- another valuetypeMirror
- the underlying Java type of the returned value, which may or may not be the least upper bound- Returns:
- the least upper bound of two abstract values
-
widenUpperBound
Compute an upper bound of two values that is wider than the least upper bound of the two values. Used to jump to a higher abstraction to allow faster termination of the fixed point computations inAnalysis
.A particular analysis might not require widening and should implement this method by calling leastUpperBound.
Important: This method must fulfill the following contract:
- Does not change
this
. - Does not change
previous
. - Returns a fresh object which is not aliased yet.
- Returns an object of the same (dynamic) type as
this
, even if the signature is more permissive. - Is commutative.
upperBound(CFAbstractValue, TypeMirror, boolean)
instead of this method.- Parameters:
previous
- must be the previous value- Returns:
- an upper bound of two values that is wider than the least upper bound of the two values
- Does not change
-
upperBound
Returns an upper bound ofthis
andother
. The underlying type of the value returned isupperBoundTypeMirror
. IfshouldWiden
is false, this method returns the least upper bound ofthis
andother
.This is the implementation of
leastUpperBound(CFAbstractValue, TypeMirror)
,leastUpperBound(CFAbstractValue)
,widenUpperBound(CFAbstractValue)
, andupperBound(CFAbstractValue, boolean)
. Subclasses may override it.- Parameters:
other
- an abstract valueupperBoundTypeMirror
- the underlying type of the returned valueshouldWiden
- true if the method should perform widening- Returns:
- an upper bound of this and
other
-
greatestLowerBound
Compute the greatest lower bound of two values.Important: This method must fulfill the following contract:
- Does not change
this
. - Does not change
other
. - Returns a fresh object which is not aliased yet.
- Returns an object of the same (dynamic) type as
this
, even if the signature is more permissive. - Is commutative.
- Parameters:
other
- another value- Returns:
- the greatest lower bound of two values
- Does not change
-