package testlib.util; import com.sun.source.tree.Tree; import java.lang.annotation.Annotation; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.util.Elements; import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory; import org.checkerframework.common.basetype.BaseTypeChecker; import org.checkerframework.common.basetype.BaseTypeVisitor; 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.AnnotatedTypeMirror.AnnotatedDeclaredType; 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; /** * A simple checker used for testing the Checker Framework. It treats the {@code @Odd} and * {@code @Even} annotations as a subtype-style qualifiers with no special semantics. * * <p>This checker should only be used for testing the framework. */ public final class TestChecker extends BaseTypeChecker { @Override protected BaseTypeVisitor<?> createSourceVisitor() { return new TestVisitor(this); } } class TestVisitor extends BaseTypeVisitor<TestAnnotatedTypeFactory> { public TestVisitor(BaseTypeChecker checker) { super(checker); } @Override protected TestAnnotatedTypeFactory createTypeFactory() { return new TestAnnotatedTypeFactory(checker); } @Override public boolean isValidUse( AnnotatedDeclaredType type, AnnotatedDeclaredType useType, Tree tree) { // TODO: super would result in error, b/c of // default on classes. return true; } } class TestAnnotatedTypeFactory extends BaseAnnotatedTypeFactory { protected AnnotationMirror BOTTOM; public TestAnnotatedTypeFactory(BaseTypeChecker checker) { super(checker, true); Elements elements = processingEnv.getElementUtils(); 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( Odd.class, MonotonicOdd.class, Even.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 GraphQualifierHierarchy(factory, BOTTOM); } }