package testlib.util; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import javax.lang.model.element.AnnotationMirror; import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory; import org.checkerframework.common.basetype.BaseTypeChecker; import org.checkerframework.framework.qual.Bottom; import org.checkerframework.framework.qual.TypeUseLocation; import org.checkerframework.framework.qual.Unqualified; import org.checkerframework.framework.type.*; import org.checkerframework.framework.type.treeannotator.ImplicitsTreeAnnotator; import org.checkerframework.framework.type.treeannotator.ListTreeAnnotator; import org.checkerframework.framework.type.treeannotator.PropagationTreeAnnotator; import org.checkerframework.framework.type.treeannotator.TreeAnnotator; import org.checkerframework.framework.util.GraphQualifierHierarchy; import org.checkerframework.framework.util.MultiGraphQualifierHierarchy.MultiGraphFactory; import org.checkerframework.javacutil.AnnotationUtils; public class FlowTestAnnotatedTypeFactory extends BaseAnnotatedTypeFactory { protected final AnnotationMirror VALUE, BOTTOM; public FlowTestAnnotatedTypeFactory(BaseTypeChecker checker) { super(checker, true); VALUE = AnnotationUtils.fromClass(elements, Value.class); BOTTOM = AnnotationUtils.fromClass(elements, Bottom.class); this.postInit(); addTypeNameImplicit(java.lang.Void.class, BOTTOM); this.defaults.addCheckedCodeDefault(BOTTOM, TypeUseLocation.LOWER_BOUND); } @Override protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() { return new HashSet<Class<? extends Annotation>>( Arrays.asList( Value.class, Odd.class, MonotonicOdd.class, Unqualified.class, Bottom.class)); } @Override public TreeAnnotator createTreeAnnotator() { ImplicitsTreeAnnotator implicitsTreeAnnotator = new ImplicitsTreeAnnotator(this); implicitsTreeAnnotator.addTreeKind(com.sun.source.tree.Tree.Kind.NULL_LITERAL, BOTTOM); return new ListTreeAnnotator(new PropagationTreeAnnotator(this), implicitsTreeAnnotator); } @Override public QualifierHierarchy createQualifierHierarchy(MultiGraphFactory factory) { return new FlowQualifierHierarchy(factory, BOTTOM); } class FlowQualifierHierarchy extends GraphQualifierHierarchy { public FlowQualifierHierarchy(MultiGraphFactory f, AnnotationMirror bottom) { super(f, bottom); } @Override public boolean isSubtype(AnnotationMirror subAnno, AnnotationMirror superAnno) { if (AnnotationUtils.areSameIgnoringValues(superAnno, VALUE) && AnnotationUtils.areSameIgnoringValues(subAnno, VALUE)) { return AnnotationUtils.areSame(superAnno, subAnno); } if (AnnotationUtils.areSameIgnoringValues(superAnno, VALUE)) { superAnno = VALUE; } if (AnnotationUtils.areSameIgnoringValues(subAnno, VALUE)) { subAnno = VALUE; } return super.isSubtype(subAnno, superAnno); } } }