org.checkerframework.framework.type.TypeHierarchy Maven / Gradle / Ivy
Show all versions of checker Show documentation
package org.checkerframework.framework.type;
import org.checkerframework.framework.util.AnnotatedTypes;
import java.util.Collection;
import javax.lang.model.element.AnnotationMirror;
/** Compares AnnotatedTypeMirrors for subtype relationships. See also {@link QualifierHierarchy}. */
public interface TypeHierarchy {
// This can be used if:
// * the type is fully annotated,
// * the basetypes are Java subtypes, and
// * you want to check the full type
// Otherwise, call QualifierHierarchy.
// `TypeHierarchy` is an interface because the only implementation, DefaultTypeHierarchy, has
// public visitor methods that clients should never call.
/**
* Returns true if {@code subtype} is a subtype of or convertible to {@code supertype} for all
* hierarchies present. If the underlying Java type of {@code subtype} is not a subtype of or
* convertible to the underlying Java type of {@code supertype}, then the behavior of this
* method is undefined.
*
* Ideally, types that require conversions would be converted before isSubtype is called, but
* instead, isSubtype performs some of these conversions.
*
*
JLS 5.1 specifies 13 categories of conversions.
*
*
3 categories are converted in isSubtype:
*
*
* - Boxing conversions: isSubtype calls {@link AnnotatedTypeFactory#getBoxedType}
*
- Unboxing conversions: isSubtype calls {@link AnnotatedTypeFactory#getUnboxedType}
*
- String conversions: Any type to String. isSubtype calls {@link AnnotatedTypes#asSuper}
* which calls {@link AnnotatedTypeFactory#getStringType(AnnotatedTypeMirror)}
*
*
* 2 happen elsewhere:
*
*
* - Unchecked conversions: Generic type to raw type. Raw types are instantiated with bounds
* in AnnotatedTypeFactory#fromTypeTree before is subtype is called
*
- Capture conversions: Wildcards are captured in {@link
* AnnotatedTypeFactory#applyCaptureConversion(AnnotatedTypeMirror)}
*
*
* 7 are not explicitly converted and are treated as though the types are actually subtypes.
*
*
* - Identity conversions: type to same type
*
- Widening primitive conversions: primitive to primitive (no loss of information, byte to
* short for example)
*
- Narrowing primitive conversions: primitive to primitive (possibly loss of information,
* short to byte for example)
*
- Widening and Narrowing Primitive Conversion: byte to char
*
- Widening reference conversions: Upcast
*
- Narrowing reference conversions: Downcast
*
- Value set conversions: floating-point value from one value set to another without
* changing its type.
*
*
* @param subtype possible subtype
* @param supertype possible supertype
* @return true if {@code subtype} is a subtype of {@code supertype} for all hierarchies present
*/
boolean isSubtype(AnnotatedTypeMirror subtype, AnnotatedTypeMirror supertype);
/**
* Tests whether the effective annotations of {@code subtype} are equal to or are sub-qualifiers
* of the effective annotations of {@code supertype}, according to the type qualifier hierarchy.
*
* The underlying types of {@code subtype} and {@code supertype} 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.
*
* @param subtype possible subtype
* @param supertype possible supertype
* @return true iff the effective annotations of {@code subtype} are equal to or are
* sub-qualifiers of the effective annotations of {@code supertype}
*/
boolean isSubtypeShallowEffective(AnnotatedTypeMirror subtype, AnnotatedTypeMirror supertype);
/**
* Tests whether the effective annotation in the same hierarchy as {@code hierarchy} of {@code
* subtype} are equal to or are sub-qualifiers of the effective annotation of {@code supertype}
* in the same hierarchy as {@code hierarchy}, according to the type qualifier hierarchy. Other
* annotations in {@code subtype} and {@code supertype} are ignored.
*
*
The underlying types of {@code subtype} and {@code supertype} 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.
*
* @param subtype possible subtype
* @param supertype possible supertype
* @param hierarchy an annotation whose hierarchy is used to compare {@code subtype} and {@code
* supertype}
* @return true iff the effective annotation in the same hierarchy as {@code hierarchy} of
* {@code subtype} are equal to or are sub-qualifiers of the effective annotation of {@code
* supertype} in the same hierarchy as {@code hierarchy}
*/
boolean isSubtypeShallowEffective(
AnnotatedTypeMirror subtype, AnnotatedTypeMirror supertype, AnnotationMirror hierarchy);
/**
* Tests whether the effective annotations of {@code subtype} are equal to or are sub-qualifiers
* of {@code superQualifiers}, according to the type qualifier hierarchy. Other annotations in
* {@code subtype} are ignored.
*
*
The underlying type of {@code subtype} is only used by this method for special cases when
* qualifier subtyping depends on the Java basetype.
*
* @param subtype possible subtype
* @param superQualifiers possible superQualifiers
* @return true iff the effective annotations of {@code subtype} are equal to or are
* sub-qualifiers of {@code superQualifiers}
*/
boolean isSubtypeShallowEffective(
AnnotatedTypeMirror subtype, Collection superQualifiers);
/**
* Tests whether {@code subQualifiers} are equal to or are sub-qualifiers of the effective
* annotations of {@code supertype}, according to the type qualifier hierarchy. Other
* annotations in {@code supertype} are ignored.
*
*
The underlying type of {@code supertype} is used by this method for special cases when
* qualifier subtyping depends on the Java basetype.
*
* @param subQualifiers possible subQualifiers
* @param supertype possible supertype
* @return true iff {@code subQualifiers} are equal to or are sub-qualifiers of the effective
* annotations of {@code supertype}
*/
boolean isSubtypeShallowEffective(
Collection subQualifiers, AnnotatedTypeMirror supertype);
/**
* Tests whether the effective annotation of {@code subtype} in the same hierarchy as {@code
* superQualifier} is equal to or sub-qualifier of {@code superQualifier}, according to the type
* qualifier hierarchy. The underlying types of {@code subtype} is only used by this method for
* special cases when qualifier subtyping depends on the Java basetype. Other annotations in
* {@code subtype} are ignored.
*
* @param subtype possible subtype
* @param superQualifier possible super qualifier
* @return true iffhe effective annotation of {@code subtype} in the same hierarchy as {@code
* superQualifier} is equal to or sub-qualifier of {@code superQualifier}
*/
boolean isSubtypeShallowEffective(AnnotatedTypeMirror subtype, AnnotationMirror superQualifier);
/**
* Tests whether {@code subQualifier} is equal to or sub-qualifier of the effective annotation
* of {@code supertype} in the same hierarchy as {@code subQualifier} according to the type
* qualifier hierarchy. The underlying types of {@code supertype} is only used by this method
* for special cases when qualifier subtyping depends on the Java basetype. Other annotations in
* {@code supertype} are ignored.
*
* @param subQualifier possible subQualifier
* @param supertype possible supertype
* @return true {@code subQualifier} is equal to or sub-qualifier of the effective annotation of
* {@code supertype} in the same hierarchy as {@code subQualifier}
*/
boolean isSubtypeShallowEffective(AnnotationMirror subQualifier, AnnotatedTypeMirror supertype);
}