use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.
the class BaseTypeVisitor method createTypeFactory.
/**
* Constructs an instance of the appropriate type factory for the implemented type system.
*
* <p>The default implementation uses the checker naming convention to create the appropriate type
* factory. If no factory is found, it returns {@link BaseAnnotatedTypeFactory}. It reflectively
* invokes the constructor that accepts this checker and compilation unit tree (in that order) as
* arguments.
*
* <p>Subclasses have to override this method to create the appropriate visitor if they do not
* follow the checker naming convention.
*
* @return the appropriate type factory
*/
// unchecked cast to type variable
@SuppressWarnings("unchecked")
protected Factory createTypeFactory() {
// Try to reflectively load the type factory.
Class<?> checkerClass = checker.getClass();
while (checkerClass != BaseTypeChecker.class) {
AnnotatedTypeFactory result = BaseTypeChecker.invokeConstructorFor(BaseTypeChecker.getRelatedClassName(checkerClass, "AnnotatedTypeFactory"), new Class<?>[] { BaseTypeChecker.class }, new Object[] { checker });
if (result != null) {
return (Factory) result;
}
checkerClass = checkerClass.getSuperclass();
}
try {
return (Factory) new BaseAnnotatedTypeFactory(checker);
} catch (Throwable t) {
throw new BugInCF("Unexpected " + t.getClass().getSimpleName() + " when invoking BaseAnnotatedTypeFactory for checker " + checker.getClass().getSimpleName(), t);
}
}
use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.
the class BaseTypeVisitor method checkThrownExpression.
/**
* Checks the type of the thrown expression.
*
* <p>By default, this method checks that the thrown expression is a subtype of top.
*
* <p>Issue error if the thrown expression is not a sub type of the annotation given by {@link
* #getThrowUpperBoundAnnotations()}, the same as {@link
* #getExceptionParameterLowerBoundAnnotations()} by default.
*
* <p>Subclasses may override this method to change the behavior of this check. Subclasses wishing
* to enforce that the thrown expression be a subtype of a type besides {@link
* #getExceptionParameterLowerBoundAnnotations}, should override {@link
* #getThrowUpperBoundAnnotations()}.
*
* @param node ThrowTree to check
*/
protected void checkThrownExpression(ThrowTree node) {
AnnotatedTypeMirror throwType = atypeFactory.getAnnotatedType(node.getExpression());
Set<? extends AnnotationMirror> required = getThrowUpperBoundAnnotations();
switch(throwType.getKind()) {
case NULL:
case DECLARED:
Set<AnnotationMirror> found = throwType.getAnnotations();
if (!atypeFactory.getQualifierHierarchy().isSubtype(found, required)) {
checker.reportError(node.getExpression(), "throw", found, required);
}
break;
case TYPEVAR:
case WILDCARD:
// TODO: this code might change after the type var changes.
Set<AnnotationMirror> foundEffective = throwType.getEffectiveAnnotations();
if (!atypeFactory.getQualifierHierarchy().isSubtype(foundEffective, required)) {
checker.reportError(node.getExpression(), "throw", foundEffective, required);
}
break;
case UNION:
AnnotatedUnionType unionType = (AnnotatedUnionType) throwType;
Set<AnnotationMirror> foundPrimary = unionType.getAnnotations();
if (!atypeFactory.getQualifierHierarchy().isSubtype(foundPrimary, required)) {
checker.reportError(node.getExpression(), "throw", foundPrimary, required);
}
for (AnnotatedTypeMirror altern : unionType.getAlternatives()) {
if (!atypeFactory.getQualifierHierarchy().isSubtype(altern.getAnnotations(), required)) {
checker.reportError(node.getExpression(), "throw", altern.getAnnotations(), required);
}
}
break;
default:
throw new BugInCF("Unexpected throw expression type: " + throwType.getKind());
}
}
use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.
the class BaseTypeVisitor method isTypeAnnotation.
/**
* Return true if the given annotation is a type annotation: that is, its definition is
* meta-annotated with {@code @Target({TYPE_USE,....})}.
*/
private boolean isTypeAnnotation(AnnotationTree anno) {
Tree annoType = anno.getAnnotationType();
ClassSymbol annoSymbol;
switch(annoType.getKind()) {
case IDENTIFIER:
annoSymbol = (ClassSymbol) ((JCIdent) annoType).sym;
break;
case MEMBER_SELECT:
annoSymbol = (ClassSymbol) ((JCFieldAccess) annoType).sym;
break;
default:
throw new BugInCF("Unhandled kind: " + annoType.getKind() + " for " + anno);
}
for (AnnotationMirror metaAnno : annoSymbol.getAnnotationMirrors()) {
if (AnnotationUtils.areSameByName(metaAnno, TARGET)) {
AnnotationValue av = metaAnno.getElementValues().get(targetValueElement);
return AnnotationUtils.annotationValueContainsToString(av, "TYPE_USE");
}
}
return false;
}
use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.
the class BaseTypeVisitor method testJointJavacJavaParserVisitor.
/**
* Test {@link org.checkerframework.framework.ajava.JointJavacJavaParserVisitor} if the checker
* has the "ajavaChecks" option.
*
* <p>Parse the current source file with JavaParser and check that the AST can be matched with the
* Tree prodoced by javac. Crash if not.
*
* <p>Subclasses may override this method to disable the test if even the option is provided.
*/
protected void testJointJavacJavaParserVisitor() {
if (root == null || !checker.hasOption("ajavaChecks")) {
return;
}
Map<Tree, com.github.javaparser.ast.Node> treePairs = new HashMap<>();
try (InputStream reader = root.getSourceFile().openInputStream()) {
CompilationUnit javaParserRoot = JavaParserUtil.parseCompilationUnit(reader);
JavaParserUtil.concatenateAddedStringLiterals(javaParserRoot);
new JointVisitorWithDefaultAction() {
@Override
public void defaultJointAction(Tree javacTree, com.github.javaparser.ast.Node javaParserNode) {
treePairs.put(javacTree, javaParserNode);
}
}.visitCompilationUnit(root, javaParserRoot);
ExpectedTreesVisitor expectedTreesVisitor = new ExpectedTreesVisitor();
expectedTreesVisitor.visitCompilationUnit(root, null);
for (Tree expected : expectedTreesVisitor.getTrees()) {
if (!treePairs.containsKey(expected)) {
throw new BugInCF("Javac tree not matched to JavaParser node: %s [%s @ %d], in file: %s", expected, expected.getClass(), positions.getStartPosition(root, expected), root.getSourceFile().getName());
}
}
} catch (IOException e) {
throw new BugInCF("Error reading Java source file", e);
}
}
use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.
the class DefaultTypeArgumentInference method reduceAfConstraints.
/**
* Given a set of AFConstraints, remove all constraints that are not relevant to inference and
* return a set of AFConstraints in which the F is a use of one of the type parameters to infer.
*/
protected void reduceAfConstraints(final AnnotatedTypeFactory typeFactory, final Set<AFConstraint> outgoing, final Queue<AFConstraint> toProcess, final Set<TypeVariable> targets) {
final Set<AFConstraint> visited = new HashSet<>();
List<AFReducer> reducers = Arrays.asList(new A2FReducer(typeFactory), new F2AReducer(typeFactory), new FIsAReducer(typeFactory));
Set<AFConstraint> newConstraints = new HashSet<>(10);
while (!toProcess.isEmpty()) {
newConstraints.clear();
AFConstraint constraint = toProcess.remove();
if (!visited.contains(constraint)) {
if (constraint.isIrreducible(targets)) {
outgoing.add(constraint);
} else {
final Iterator<AFReducer> reducerIterator = reducers.iterator();
boolean handled = false;
while (!handled && reducerIterator.hasNext()) {
handled = reducerIterator.next().reduce(constraint, newConstraints);
}
if (!handled) {
throw new BugInCF("Unhandled constraint type: " + constraint);
}
toProcess.addAll(newConstraints);
}
visited.add(constraint);
}
}
}
Aggregations