package org.checkerframework.common.subtyping; import java.lang.annotation.Annotation; import java.util.HashSet; import java.util.Set; import org.checkerframework.common.basetype.BaseAnnotatedTypeFactory; import org.checkerframework.common.basetype.BaseTypeChecker; import org.checkerframework.framework.qual.SubtypeOf; import org.checkerframework.framework.type.AnnotationClassLoader; public class SubtypingAnnotatedTypeFactory extends BaseAnnotatedTypeFactory { public SubtypingAnnotatedTypeFactory(BaseTypeChecker checker) { super(checker); postInit(); } @Override protected Set<Class<? extends Annotation>> createSupportedTypeQualifiers() { AnnotationClassLoader loader = new AnnotationClassLoader(checker); Set<Class<? extends Annotation>> qualSet = new HashSet<Class<? extends Annotation>>(); String qualNames = checker.getOption("quals"); String qualDirectories = checker.getOption("qualDirs"); if (qualNames == null && qualDirectories == null) { checker.userErrorAbort( "SubtypingChecker: missing required option. Use -Aquals or -AqualDirs"); throw new Error("This can't happen"); // dead code } // load individually named qualifiers if (qualNames != null) { for (String qualName : qualNames.split(",")) { qualSet.add(loader.loadExternalAnnotationClass(qualName)); } } // load directories of qualifiers if (qualDirectories != null) { for (String dirName : qualDirectories.split(":")) { qualSet.addAll(loader.loadExternalAnnotationClassesFromDirectory(dirName)); } } // check for subtype meta-annotation for (Class<? extends Annotation> qual : qualSet) { Annotation subtypeOfAnnotation = qual.getAnnotation(SubtypeOf.class); if (subtypeOfAnnotation != null) { for (Class<? extends Annotation> superqual : qual.getAnnotation(SubtypeOf.class).value()) { if (!qualSet.contains(superqual)) { checker.userErrorAbort( "SubtypingChecker: qualifier " + qual + " was specified via -Aquals but its super-qualifier " + superqual + " was not"); } } } } return qualSet; } }