All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.checkerframework.framework.type.NoElementQualifierHierarchy Maven / Gradle / Ivy

Go to download

The Checker Framework enhances Java's type system to make it more powerful and useful. This lets software developers detect and prevent errors in their Java programs. The Checker Framework includes compiler plug-ins ("checkers") that find bugs or verify their absence. It also permits you to write your own compiler plug-ins.

There is a newer version: 3.43.0
Show newest version
package org.checkerframework.framework.type;

import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.util.Elements;
import org.checkerframework.checker.initialization.qual.UnderInitialization;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.RequiresNonNull;
import org.checkerframework.framework.qual.AnnotatedFor;
import org.checkerframework.framework.util.DefaultQualifierKindHierarchy;
import org.checkerframework.framework.util.QualifierKind;
import org.checkerframework.framework.util.QualifierKindHierarchy;
import org.checkerframework.javacutil.AnnotationBuilder;
import org.checkerframework.javacutil.AnnotationMirrorSet;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.BugInCF;
import org.checkerframework.javacutil.TypeSystemError;

/**
 * A {@link QualifierHierarchy} where no qualifier has arguments; that is, no qualifier is
 * represented by an annotation with elements. The meta-annotation {@link
 * org.checkerframework.framework.qual.SubtypeOf} specifies the subtyping relationships.
 *
 * 

It uses a {@link QualifierKindHierarchy} to model the relationships between qualifiers. * Subclasses can override {@link #createQualifierKindHierarchy(Collection)} to return a subclass of * QualifierKindHierarchy. */ @AnnotatedFor("nullness") public class NoElementQualifierHierarchy extends QualifierHierarchy { /** {@link QualifierKindHierarchy}. */ protected final QualifierKindHierarchy qualifierKindHierarchy; /** Set of top annotation mirrors. */ protected final AnnotationMirrorSet tops; /** Set of bottom annotation mirrors. */ protected final AnnotationMirrorSet bottoms; /** Mapping from {@link QualifierKind} to its corresponding {@link AnnotationMirror}. */ protected final Map kindToAnnotationMirror; /** Set of all annotations in all the hierarchies. */ protected final Set qualifiers; /** * Creates a NoElementQualifierHierarchy from the given classes. * * @param qualifierClasses classes of annotations that are the qualifiers * @param elements element utils * @param atypeFactory the associated type factory */ public NoElementQualifierHierarchy( Collection> qualifierClasses, Elements elements, GenericAnnotatedTypeFactory atypeFactory) { super(atypeFactory); this.qualifierKindHierarchy = createQualifierKindHierarchy(qualifierClasses); this.kindToAnnotationMirror = createAnnotationMirrors(elements); this.qualifiers = AnnotationMirrorSet.unmodifiableSet(kindToAnnotationMirror.values()); this.tops = createTops(); this.bottoms = createBottoms(); } /** * Create the {@link QualifierKindHierarchy}. (Subclasses may override to return a subclass of * QualifierKindHierarchy.) * * @param qualifierClasses classes of annotations that are the qualifiers * @return the newly created qualifier kind hierarchy */ protected QualifierKindHierarchy createQualifierKindHierarchy( @UnderInitialization NoElementQualifierHierarchy this, Collection> qualifierClasses) { return new DefaultQualifierKindHierarchy(qualifierClasses); } /** * Creates and returns a mapping from qualifier kind to an annotation mirror created from the * qualifier kind's annotation class. * * @param elements element utils * @return a mapping from qualifier kind to its annotation mirror */ @RequiresNonNull("this.qualifierKindHierarchy") protected Map createAnnotationMirrors( @UnderInitialization NoElementQualifierHierarchy this, Elements elements) { Map quals = new TreeMap<>(); for (QualifierKind kind : qualifierKindHierarchy.allQualifierKinds()) { if (kind.hasElements()) { throw new TypeSystemError(kind + " has elements"); } quals.put(kind, AnnotationBuilder.fromClass(elements, kind.getAnnotationClass())); } return Collections.unmodifiableMap(quals); } /** * Creates and returns the unmodifiable set of top {@link AnnotationMirror}s. * * @return the unmodifiable set of top {@link AnnotationMirror}s */ @RequiresNonNull({"this.kindToAnnotationMirror", "this.qualifierKindHierarchy"}) protected AnnotationMirrorSet createTops(@UnderInitialization NoElementQualifierHierarchy this) { AnnotationMirrorSet tops = new AnnotationMirrorSet(); for (QualifierKind top : qualifierKindHierarchy.getTops()) { @SuppressWarnings( "nullness:assignment" // All QualifierKinds are keys in kindToAnnotationMirror ) @NonNull AnnotationMirror topAnno = kindToAnnotationMirror.get(top); tops.add(topAnno); } return AnnotationMirrorSet.unmodifiableSet(tops); } /** * Creates and returns the unmodifiable set of bottom {@link AnnotationMirror}s. * * @return the unmodifiable set of bottom {@link AnnotationMirror}s */ @RequiresNonNull({"this.kindToAnnotationMirror", "this.qualifierKindHierarchy"}) protected AnnotationMirrorSet createBottoms( @UnderInitialization NoElementQualifierHierarchy this) { AnnotationMirrorSet bottoms = new AnnotationMirrorSet(); for (QualifierKind bottom : qualifierKindHierarchy.getBottoms()) { @SuppressWarnings( "nullness:assignment" // All QualifierKinds are keys in kindToAnnotationMirror ) @NonNull AnnotationMirror bottomAnno = kindToAnnotationMirror.get(bottom); bottoms.add(bottomAnno); } return AnnotationMirrorSet.unmodifiableSet(bottoms); } /** * Returns the {@link QualifierKind} for the given annotation. * * @param anno an annotation that is a qualifier in this * @return the {@code QualifierKind} for the given annotation */ protected QualifierKind getQualifierKind(AnnotationMirror anno) { String name = AnnotationUtils.annotationName(anno); QualifierKind kind = qualifierKindHierarchy.getQualifierKind(name); if (kind == null) { throw new BugInCF("Annotation not in hierarchy: %s", anno); } return kind; } @Override public @Nullable AnnotationMirror findAnnotationInSameHierarchy( Collection annos, AnnotationMirror annotationMirror) { if (annos.isEmpty()) { return null; } QualifierKind kind = getQualifierKind(annotationMirror); for (AnnotationMirror candidate : annos) { QualifierKind candidateKind = getQualifierKind(candidate); if (candidateKind.isInSameHierarchyAs(kind)) { return candidate; } } return null; } @Override public @Nullable AnnotationMirror findAnnotationInHierarchy( Collection annos, AnnotationMirror top) { return findAnnotationInSameHierarchy(annos, top); } @Override public AnnotationMirrorSet getTopAnnotations() { return tops; } @Override @SuppressWarnings("nullness:return" // every QualifierKind is a key in its corresponding // kindToAnnotationMirror ) public AnnotationMirror getTopAnnotation(AnnotationMirror start) { QualifierKind kind = getQualifierKind(start); return kindToAnnotationMirror.get(kind.getTop()); } @Override public AnnotationMirrorSet getBottomAnnotations() { return bottoms; } @Override @SuppressWarnings("nullness:return" // every QualifierKind is a key in its corresponding // kindToAnnotationMirror ) public AnnotationMirror getBottomAnnotation(AnnotationMirror start) { QualifierKind kind = getQualifierKind(start); return kindToAnnotationMirror.get(kind.getBottom()); } @Override public @Nullable AnnotationMirror getPolymorphicAnnotation(AnnotationMirror start) { QualifierKind poly = getQualifierKind(start).getPolymorphic(); if (poly == null) { return null; } return kindToAnnotationMirror.get(poly); } @Override public boolean isPolymorphicQualifier(AnnotationMirror qualifier) { return getQualifierKind(qualifier).isPoly(); } @Override public boolean isSubtypeQualifiers(AnnotationMirror subAnno, AnnotationMirror superAnno) { QualifierKind subKind = getQualifierKind(subAnno); QualifierKind superKind = getQualifierKind(superAnno); return subKind.isSubtypeOf(superKind); } @Override public @Nullable AnnotationMirror leastUpperBoundQualifiers( AnnotationMirror a1, AnnotationMirror a2) { QualifierKind qual1 = getQualifierKind(a1); QualifierKind qual2 = getQualifierKind(a2); QualifierKind lub = qualifierKindHierarchy.leastUpperBound(qual1, qual2); if (lub == null) { return null; } return kindToAnnotationMirror.get(lub); } @Override public @Nullable AnnotationMirror greatestLowerBoundQualifiers( AnnotationMirror a1, AnnotationMirror a2) { QualifierKind qual1 = getQualifierKind(a1); QualifierKind qual2 = getQualifierKind(a2); QualifierKind glb = qualifierKindHierarchy.greatestLowerBound(qual1, qual2); if (glb == null) { return null; } return kindToAnnotationMirror.get(glb); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy