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

org.checkerframework.framework.type.SubtypeIsSupersetQualifierHierarchy 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.LinkedHashSet;
import java.util.List;
import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.AnnotationMirror;
import org.checkerframework.framework.qual.AnnotatedFor;
import org.checkerframework.framework.util.QualifierKind;
import org.checkerframework.javacutil.AnnotationBuilder;
import org.checkerframework.javacutil.AnnotationUtils;
import org.checkerframework.javacutil.BugInCF;

/**
 * A {@link org.checkerframework.framework.type.QualifierHierarchy} where, when a qualifier has
 * arguments, the subtype relation is determined by a superset test on the elements (arguments). The
 * elements must be strings.
 *
 * 

This assumes that if the lub or glb of two qualifiers has elements, then both of the arguments * had the same kind as the result does. */ @AnnotatedFor("nullness") public class SubtypeIsSupersetQualifierHierarchy extends MostlyNoElementQualifierHierarchy { /** The processing environment; used for creating annotations. */ ProcessingEnvironment processingEnv; /** * Creates a SubtypeIsSupersetQualifierHierarchy from the given classes. * * @param qualifierClasses classes of annotations that are the qualifiers for this hierarchy * @param processingEnv processing environment */ public SubtypeIsSupersetQualifierHierarchy( Collection> qualifierClasses, ProcessingEnvironment processingEnv) { super(qualifierClasses, processingEnv.getElementUtils()); this.processingEnv = processingEnv; } @Override protected boolean isSubtypeWithElements( AnnotationMirror subAnno, QualifierKind subKind, AnnotationMirror superAnno, QualifierKind superKind) { if (subKind == superKind) { List superValues = valuesStringList(superAnno); List subValues = valuesStringList(subAnno); return subValues.containsAll(superValues); } return subKind.isSubtypeOf(superKind); } @Override protected AnnotationMirror leastUpperBoundWithElements( AnnotationMirror a1, QualifierKind qualifierKind1, AnnotationMirror a2, QualifierKind qualifierKind2, QualifierKind lubKind) { if (qualifierKind1 == qualifierKind2) { List a1Values = valuesStringList(a1); List a2Values = valuesStringList(a2); LinkedHashSet set = new LinkedHashSet<>(a1Values); set.retainAll(a2Values); return createAnnotationMirrorWithValue(lubKind, set); } else if (lubKind == qualifierKind1) { return a1; } else if (lubKind == qualifierKind2) { return a2; } else { throw new BugInCF("Unexpected QualifierKinds %s %s", qualifierKind1, qualifierKind2, lubKind); } } @Override protected AnnotationMirror greatestLowerBoundWithElements( AnnotationMirror a1, QualifierKind qualifierKind1, AnnotationMirror a2, QualifierKind qualifierKind2, QualifierKind glbKind) { if (qualifierKind1 == qualifierKind2) { List a1Values = valuesStringList(a1); List a2Values = valuesStringList(a2); LinkedHashSet set = new LinkedHashSet<>(a1Values); set.addAll(a2Values); return createAnnotationMirrorWithValue(glbKind, set); } else if (glbKind == qualifierKind1) { return a1; } else if (glbKind == qualifierKind2) { return a2; } else { throw new BugInCF("Unexpected QualifierKinds %s %s", qualifierKind1, qualifierKind2, glbKind); } } /** * Returns a mutable list containing the {@code values} element of the given annotation. The * {@code values} element must be an array of strings. * * @param anno an annotation * @return a mutable list containing the {@code values} element; may be the empty list */ private List valuesStringList(AnnotationMirror anno) { @SuppressWarnings("deprecation") // concrete annotation class is not known List result = AnnotationUtils.getElementValueArray(anno, "value", String.class, true); return result; } /** * Returns an AnnotationMirror corresponding to the given kind and values. * * @param kind the qualifier kind * @param values the annotation's {@code values} element/argument * @return an annotation of the given kind and values */ private AnnotationMirror createAnnotationMirrorWithValue( QualifierKind kind, LinkedHashSet values) { AnnotationBuilder builder = new AnnotationBuilder(processingEnv, kind.getAnnotationClass()); builder.setValue("value", values.toArray()); return builder.build(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy