package org.checkerframework.framework.type;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.util.Types;
import org.checkerframework.framework.util.AnnotatedTypes;
/** Compares AnnotatedTypeMirrors for subtype relationships. See also QualifierHierarchy */
public interface TypeHierarchy {
/**
* 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.
*
* <p>Ideally, types that require conversions would be converted before isSubtype is called, but
* instead, isSubtype performs some of these conversions.
*
* <p>JLS 5.1 specifies 13 categories of conversions.
*
* <p>4 categories are converted in isSubtype:
*
* <ul>
* <li>Boxing conversions: isSubtype calls {@link AnnotatedTypes#asSuper(Types,
* AnnotatedTypeFactory, AnnotatedTypeMirror, AnnotatedTypeMirror)} which calls {@link
* AnnotatedTypeFactory#getBoxedType}
* <li>Unboxing conversions: isSubtype calls {@link AnnotatedTypes#asSuper(Types,
* AnnotatedTypeFactory, AnnotatedTypeMirror, AnnotatedTypeMirror)} which calls {@link
* AnnotatedTypeFactory#getUnboxedType}
* <li>Capture conversions: Wildcards are treated as though they were converted to type
* variables
* <li>String conversions: Any type to String. isSubtype calls {@link AnnotatedTypes#asSuper}
* which calls {@link AnnotatedTypeFactory#getStringType(AnnotatedTypeMirror)}
* </ul>
*
* 1 happens elsewhere:
*
* <ul>
* <li>Unchecked conversions: Generic type to raw type. Raw types are instantiated with bounds
* in AnnotatedTypeFactory#fromTypeTree before is subtype is called
* </ul>
*
* 7 are not explicitly converted and are treated as though the types are actually subtypes.
*
* <ul>
* <li>Identity conversions: type to same type
* <li>Widening primitive conversions: primitive to primitive (no loss of information, byte to
* short for example)
* <li>Narrowing primitive conversions: primitive to primitive (possibly loss of information,
* short to byte for example)
* <li>Widening and Narrowing Primitive Conversion: byte to char
* <li>Widening reference conversions: Upcast
* <li>Narrowing reference conversions: Downcast
* <li>Value set conversions: floating-point value from one value set to another without
* changing its type.
* </ul>
*
* @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);
/**
* The same as {@link #isSubtype(AnnotatedTypeMirror, AnnotatedTypeMirror)}, but only for the
* hierarchy of which {@code top} is the top.
*
* @param subtype possible subtype
* @param supertype possible supertype
* @param top the qualifier at the top of the hierarchy for which the subtype check should be
* preformed
* @return returns true if {@code subtype} is a subtype of {@code supertype} in the qualifier
* hierarchy whose top is {@code top}
*/
boolean isSubtype(
AnnotatedTypeMirror subtype, AnnotatedTypeMirror supertype, AnnotationMirror top);
}