blob: 720688c874a0393bf1127a68cf5d2ad30fd55879 [file] [log] [blame]
package org.checkerframework.framework.testchecker.util;
import com.sun.source.tree.Tree;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Collection;
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.common.subtyping.qual.Bottom;
import org.checkerframework.common.subtyping.qual.Unqualified;
import org.checkerframework.framework.qual.TypeUseLocation;
import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType;
import org.checkerframework.framework.type.NoElementQualifierHierarchy;
import org.checkerframework.framework.type.QualifierHierarchy;
import org.checkerframework.framework.util.DefaultQualifierKindHierarchy;
import org.checkerframework.framework.util.QualifierKindHierarchy;
import org.checkerframework.framework.util.defaults.QualifierDefaults;
import org.checkerframework.javacutil.AnnotationBuilder;
/**
* 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 EvenOddChecker 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, because 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 = AnnotationBuilder.fromClass(elements, Bottom.class);
this.postInit();
}
@Override
protected void addCheckedCodeDefaults(QualifierDefaults defs) {
defs.addCheckedCodeDefault(BOTTOM, TypeUseLocation.LOWER_BOUND);
AnnotationMirror unqualified = AnnotationBuilder.fromClass(elements, Unqualified.class);
defs.addCheckedCodeDefault(unqualified, TypeUseLocation.OTHERWISE);
}
@Override
protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() {
return new HashSet<>(
Arrays.asList(Odd.class, MonotonicOdd.class, Even.class, Unqualified.class, Bottom.class));
}
@Override
public QualifierHierarchy createQualifierHierarchy() {
return new NoElementQualifierHierarchy(getSupportedTypeQualifiers(), elements) {
@Override
protected QualifierKindHierarchy createQualifierKindHierarchy(
Collection<Class<? extends Annotation>> qualifierClasses) {
return new DefaultQualifierKindHierarchy(qualifierClasses, Bottom.class);
}
};
}
}