use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.
the class BaseTypeChecker method instantiateSubcheckers.
/*
* Performs a depth first search for all checkers this checker depends on.
* The depth first search ensures that the collection has the correct order the checkers need to be run in.
*
* Modifies the alreadyInitializedSubcheckerMap map by adding all recursively newly instantiated subcheckers' class objects and instances.
* A LinkedHashMap is used because, unlike HashMap, it preserves the order in which entries were inserted.
*
* Returns the unmodifiable list of immediate subcheckers of this checker.
*/
private List<BaseTypeChecker> instantiateSubcheckers(LinkedHashMap<Class<? extends BaseTypeChecker>, BaseTypeChecker> alreadyInitializedSubcheckerMap) {
LinkedHashSet<Class<? extends BaseTypeChecker>> classesOfImmediateSubcheckers = getImmediateSubcheckerClasses();
if (classesOfImmediateSubcheckers.isEmpty()) {
return Collections.emptyList();
}
ArrayList<BaseTypeChecker> immediateSubcheckers = new ArrayList<>(classesOfImmediateSubcheckers.size());
for (Class<? extends BaseTypeChecker> subcheckerClass : classesOfImmediateSubcheckers) {
BaseTypeChecker subchecker = alreadyInitializedSubcheckerMap.get(subcheckerClass);
if (subchecker != null) {
// Add the already initialized subchecker to the list of immediate subcheckers so
// that this checker can refer to it.
immediateSubcheckers.add(subchecker);
continue;
}
BaseTypeChecker instance;
try {
instance = subcheckerClass.getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new BugInCF("Could not create an instance of " + subcheckerClass);
}
instance.setProcessingEnvironment(this.processingEnv);
instance.treePathCacher = this.getTreePathCacher();
// Prevent the new checker from storing non-immediate subcheckers
instance.subcheckers = Collections.emptyList();
immediateSubcheckers.add(instance);
instance.immediateSubcheckers = instance.instantiateSubcheckers(alreadyInitializedSubcheckerMap);
instance.setParentChecker(this);
alreadyInitializedSubcheckerMap.put(subcheckerClass, instance);
}
return Collections.unmodifiableList(immediateSubcheckers);
}
use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.
the class AccumulationAnnotatedTypeFactory method convertToPredicate.
/**
* Converts the given annotation mirror to a predicate.
*
* @param anno an annotation
* @return the predicate, as a String, that is equivalent to that annotation. May return the empty
* string.
*/
protected String convertToPredicate(AnnotationMirror anno) {
if (AnnotationUtils.areSame(anno, bottom)) {
return "false";
} else if (isPredicate(anno)) {
String result = AnnotationUtils.getElementValueOrNull(anno, "value", String.class, false);
return result == null ? "" : result;
} else if (isAccumulatorAnnotation(anno)) {
List<String> values = getAccumulatedValues(anno);
StringJoiner sj = new StringJoiner(" && ");
for (String value : values) {
sj.add(value);
}
return sj.toString();
} else {
throw new BugInCF("annotation is not bottom, a predicate, or an accumulator: " + anno);
}
}
use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.
the class BaseTypeValidator method reportInvalidBounds.
/**
* Most errors reported by this class are of the form type.invalid. This method reports when the
* bounds of a wildcard or type variable don't make sense. Bounds make sense when the effective
* annotations on the upper bound are supertypes of those on the lower bounds for all hierarchies.
* To ensure that this subtlety is not lost on users, we report "bound" and print the bounds along
* with the invalid type rather than a "type.invalid".
*
* @param type the type with invalid bounds
* @param tree where to report the error
*/
protected void reportInvalidBounds(final AnnotatedTypeMirror type, final Tree tree) {
final String label;
final AnnotatedTypeMirror upperBound;
final AnnotatedTypeMirror lowerBound;
switch(type.getKind()) {
case TYPEVAR:
label = "type parameter";
upperBound = ((AnnotatedTypeVariable) type).getUpperBound();
lowerBound = ((AnnotatedTypeVariable) type).getLowerBound();
break;
case WILDCARD:
label = "wildcard";
upperBound = ((AnnotatedWildcardType) type).getExtendsBound();
lowerBound = ((AnnotatedWildcardType) type).getSuperBound();
break;
default:
throw new BugInCF("Type is not bounded.%ntype=%s%ntree=%s", type, tree);
}
checker.reportError(tree, "bound", label, type.toString(), upperBound.toString(true), lowerBound.toString(true));
isValid = false;
}
use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.
the class PerFileSuite method getParametersList.
/**
* Returns a list of one-element arrays, each containing a Java File.
*/
@SuppressWarnings({ "unchecked", // JUnit needs to be annotated
"nullness" })
private List<Object[]> getParametersList(TestClass klass) throws Throwable {
FrameworkMethod method = getParametersMethod(klass);
List<File> javaFiles;
// which returns List<Object []> or getParametersMethod would fail
if (method == null) {
throw new BugInCF("no method annotated with @Parameters");
}
if (method.getReturnType().isArray()) {
String[] dirs = (String[]) method.invokeExplosively(null);
javaFiles = TestUtilities.findNestedJavaTestFiles(dirs);
} else {
javaFiles = (List<File>) method.invokeExplosively(null);
}
List<Object[]> argumentLists = CollectionsPlume.mapList((File javaFile) -> new Object[] { javaFile }, javaFiles);
return argumentLists;
}
use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.
the class PerFileSuite method getParametersMethod.
/**
* Returns method annotated @Parameters, typically the getTestDirs or getTestFiles method.
*/
private FrameworkMethod getParametersMethod(TestClass testClass) {
final List<FrameworkMethod> parameterMethods = testClass.getAnnotatedMethods(Parameters.class);
if (parameterMethods.size() != 1) {
// Construct error message
String methods;
if (parameterMethods.isEmpty()) {
methods = "[No methods specified]";
} else {
StringJoiner sj = new StringJoiner(", ");
for (FrameworkMethod method : parameterMethods) {
sj.add(method.getName());
}
methods = sj.toString();
}
throw new BugInCF(requiredFormsMessage, testClass.getName(), methods);
}
// else
FrameworkMethod method = parameterMethods.get(0);
Class<?> returnType = method.getReturnType();
String methodName = method.getName();
switch(methodName) {
case "getTestDirs":
if (returnType.isArray()) {
if (returnType.getComponentType() != String.class) {
throw new RuntimeException("Component type of getTestDirs must be java.lang.String, found " + returnType.getComponentType().getCanonicalName());
}
}
break;
case "getTestFiles":
// subtype thereof is not easy.
if (!List.class.getCanonicalName().equals(returnType.getCanonicalName())) {
throw new RuntimeException("getTestFiles must return a List<File>, found " + returnType);
}
break;
default:
throw new BugInCF(requiredFormsMessage, testClass.getName(), method);
}
int modifiers = method.getMethod().getModifiers();
if (!Modifier.isStatic(modifiers) || !Modifier.isPublic(modifiers)) {
throw new RuntimeException("Parameter method (" + method.getName() + ") must be public and static");
}
return method;
}
Aggregations