Interface QualifierHierarchy

All Known Implementing Classes:
AccumulationAnnotatedTypeFactory.AccumulationQualifierHierarchy, AliasingAnnotatedTypeFactory.AliasingQualifierHierarchy, ClassValAnnotatedTypeFactory.ClassValQualifierHierarchy, ElementQualifierHierarchy, FenumAnnotatedTypeFactory.FenumQualifierHierarchy, InitializationAnnotatedTypeFactory.InitializationQualifierHierarchy, MethodValAnnotatedTypeFactory.MethodValQualifierHierarchy, MostlyNoElementQualifierHierarchy, NoElementQualifierHierarchy, NullnessAnnotatedTypeFactory.NullnessQualifierHierarchy, SubtypeIsSubsetQualifierHierarchy, SubtypeIsSupersetQualifierHierarchy, UnitsAnnotatedTypeFactory.UnitsQualifierHierarchy, UpperBoundAnnotatedTypeFactory.UpperBoundQualifierHierarchy

@AnnotatedFor("nullness") public interface QualifierHierarchy
Represents multiple type qualifier hierarchies. 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.

  • Method Details

    • isValid

      default boolean isValid()
      Determine whether this is valid.
      Returns:
      whether this is valid
    • getWidth

      default 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

      Set<? extends AnnotationMirror> getTopAnnotations()
      Returns the top (ultimate super) type qualifiers in the type system. The size of this set is equal to getWidth().
      Returns:
      the top (ultimate super) type qualifiers in the type system
    • getTopAnnotation

      AnnotationMirror getTopAnnotation(AnnotationMirror qualifier)
      Return the top qualifier for the given qualifier, that is, the qualifier that is a supertype of qualifier 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

      Set<? extends AnnotationMirror> getBottomAnnotations()
      Returns the bottom type qualifiers in the hierarchy. The size of this set is equal to getWidth().
      Returns:
      the bottom type qualifiers in the hierarchy
    • getBottomAnnotation

      AnnotationMirror getBottomAnnotation(AnnotationMirror qualifier)
      Return the bottom for the given qualifier, that is, the qualifier that is a subtype of qualifier 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

      @Nullable AnnotationMirror getPolymorphicAnnotation(AnnotationMirror qualifier)
      Returns the polymorphic qualifier for the hierarchy containing qualifier, or null 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, or null if there is no polymorphic qualifier in that hierarchy
    • isPolymorphicQualifier

      boolean isPolymorphicQualifier(AnnotationMirror qualifier)
      Returns true if the qualifier is a polymorphic qualifier; otherwise, returns false.
      Parameters:
      qualifier - qualifier
      Returns:
      true if the qualifier is a polymorphic qualifier; otherwise, returns false.
    • isSubtype

      boolean isSubtype(AnnotationMirror subQualifier, AnnotationMirror superQualifier)
      Tests whether subQualifier is equal to or a sub-qualifier of superQualifier, according to the type qualifier hierarchy.
      Parameters:
      subQualifier - possible subqualifier of superQualifier
      superQualifier - possible superqualifier of subQualifier
      Returns:
      true iff subQualifier is a subqualifier of, or equal to, superQualifier
    • isSubtype

      default boolean isSubtype(Collection<? extends AnnotationMirror> subQualifiers, Collection<? extends AnnotationMirror> superQualifiers)
      Tests whether all qualifiers in subQualifiers are a subqualifier or equal to the qualifier in the same hierarchy in superQualifiers.
      Parameters:
      subQualifiers - set of qualifiers; exactly one per hierarchy
      superQualifiers - set of qualifiers; exactly one per hierarchy
      Returns:
      true iff all qualifiers in subQualifiers are a subqualifier or equal to the qualifier in the same hierarchy in superQualifiers
    • leastUpperBound

      @Nullable AnnotationMirror leastUpperBound(AnnotationMirror qualifier1, AnnotationMirror qualifier2)
      Returns the least upper bound (LUB) of the qualifiers qualifier1 and qualifier2. Returns null if the qualifiers are not from the same qualifier hierarchy.

      Examples:

      • For NonNull, leastUpperBound('Nullable', 'NonNull') ⇒ Nullable
      Parameters:
      qualifier1 - the first qualifier; may not be in the same hierarchy as qualifier2
      qualifier2 - the second qualifier; may not be in the same hierarchy as qualifier1
      Returns:
      the least upper bound of the qualifiers, or null if the qualifiers are from different hierarchies
    • leastUpperBounds

      default Set<? extends AnnotationMirror> leastUpperBounds(Collection<? extends AnnotationMirror> qualifiers1, Collection<? extends AnnotationMirror> qualifiers2)
      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 hierarchy
      qualifiers2 - set of qualifiers; exactly one per hierarchy
      Returns:
      the least upper bound of the two sets of qualifiers
    • numberOfIterationsBeforeWidening

      default int numberOfIterationsBeforeWidening()
      Returns the number of iterations dataflow should perform before widenedUpperBound(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

      default 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 override numberOfIterationsBeforeWidening() to return a positive number.

      newQualifier is newest qualifier dataflow computed for some expression and previousQualifier 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 as previousQualifier
      previousQualifier - the previous qualifier dataflow computed on the last iteration; must be in the same hierarchy as previousQualifier
      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)
    • greatestLowerBound

      @Nullable AnnotationMirror greatestLowerBound(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 qualifier
      qualifier2 - second qualifier
      Returns:
      greatest lower bound of the two annotations or null if the two annotations are not from the same hierarchy
    • greatestLowerBounds

      default Set<? extends AnnotationMirror> greatestLowerBounds(Collection<? extends AnnotationMirror> qualifiers1, Collection<? extends AnnotationMirror> qualifiers2)
      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 hierarchy
      qualifiers2 - set of qualifiers; exactly one per hierarchy
      Returns:
      the greatest lower bound of the two sets of qualifiers
    • canHaveEmptyAnnotationSet

      static boolean canHaveEmptyAnnotationSet(AnnotatedTypeMirror type)
      Returns true if and only if AnnotatedTypeMirror.getAnnotations() 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.getAnnotations() can return a set with fewer qualifiers than the width of the QualifierHierarchy
    • findAnnotationInSameHierarchy

      default @Nullable AnnotationMirror findAnnotationInSameHierarchy(Collection<? extends AnnotationMirror> qualifiers, AnnotationMirror qualifier)
      Returns the annotation in qualifiers that is in the same hierarchy as qualifier.

      The default implementation calls getTopAnnotation(AnnotationMirror) and then calls findAnnotationInHierarchy(Collection, AnnotationMirror). So, if qualifier is a top qualifier, then call findAnnotationInHierarchy(Collection, AnnotationMirror) directly is faster.

      Parameters:
      qualifiers - set of annotations to search
      qualifier - 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

      default @Nullable AnnotationMirror findAnnotationInHierarchy(Collection<? extends AnnotationMirror> qualifiers, AnnotationMirror top)
      Returns the annotation in qualifiers that is in the hierarchy for which top is top.
      Parameters:
      qualifiers - set of annotations to search
      top - 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

      default <T> boolean updateMappingToMutableSet(Map<T,AnnotationMirrorSet> map, T key, AnnotationMirror qualifier)
      Update a mapping from key to a set of AnnotationMirrors. If key is not already in the map, then put it in the map with a value of a new set containing qualifier. If the map contains key, then add qualifier to the set to which key maps. If that set contains a qualifier in the same hierarchy as qualifier, then don't add it and return false.
      Type Parameters:
      T - type of the map's keys
      Parameters:
      map - the mapping to modify
      key - the key to update or add
      qualifier - the value to update or add
      Returns:
      true if the update was done; false if there was a qualifier hierarchy collision
    • assertSameSize

      static void assertSameSize(Collection<?> c1, Collection<?> c2)
      Throws an exception if the given collections do not have the same size.
      Parameters:
      c1 - the first collection
      c2 - the second collection
    • assertSameSize

      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 collection
      c2 - the second collection
      result - the result collection