use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class BaseTypeVisitor method visitTypeCast.
@Override
public Void visitTypeCast(TypeCastTree node, Void p) {
// validate "node" instead of "node.getType()" to prevent duplicate errors.
boolean valid = validateTypeOf(node) && validateTypeOf(node.getExpression());
if (valid) {
checkTypecastSafety(node);
checkTypecastRedundancy(node);
}
if (atypeFactory.getDependentTypesHelper().hasDependentAnnotations()) {
AnnotatedTypeMirror type = atypeFactory.getAnnotatedType(node);
atypeFactory.getDependentTypesHelper().checkTypeForErrorExpressions(type, node.getType());
}
if (node.getType().getKind() == Tree.Kind.INTERSECTION_TYPE) {
AnnotatedIntersectionType intersection = (AnnotatedIntersectionType) atypeFactory.getAnnotatedType(node);
checkExplicitAnnotationsOnIntersectionBounds(intersection, ((IntersectionTypeTree) node.getType()).getBounds());
}
return super.visitTypeCast(node, p);
// return scan(node.getExpression(), p);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class BaseTypeVisitor method visitMethodInvocation.
/**
* Performs a method invocation check.
*
* <p>An invocation of a method, m, on the receiver, r is valid only if:
*
* <ul>
* <li>passed arguments are subtypes of corresponding m parameters
* <li>r is a subtype of m receiver type
* <li>if m is generic, passed type arguments are subtypes of m type variables
* </ul>
*/
@Override
public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
// hard to check), also see CFGBuilder.visitMethodInvocation.
if (TreeUtils.elementFromUse(node) == null || TreeUtils.isEnumSuper(node)) {
return super.visitMethodInvocation(node, p);
}
if (shouldSkipUses(node)) {
return super.visitMethodInvocation(node, p);
}
ParameterizedExecutableType mType = atypeFactory.methodFromUse(node);
AnnotatedExecutableType invokedMethod = mType.executableType;
List<AnnotatedTypeMirror> typeargs = mType.typeArgs;
if (!atypeFactory.ignoreUninferredTypeArguments) {
for (AnnotatedTypeMirror typearg : typeargs) {
if (typearg.getKind() == TypeKind.WILDCARD && ((AnnotatedWildcardType) typearg).isUninferredTypeArgument()) {
checker.reportError(node, "type.arguments.not.inferred", invokedMethod.getElement().getSimpleName());
// only issue error once per method
break;
}
}
}
List<AnnotatedTypeParameterBounds> paramBounds = CollectionsPlume.mapList(AnnotatedTypeVariable::getBounds, invokedMethod.getTypeVariables());
ExecutableElement method = invokedMethod.getElement();
CharSequence methodName = ElementUtils.getSimpleNameOrDescription(method);
try {
checkTypeArguments(node, paramBounds, typeargs, node.getTypeArguments(), methodName, invokedMethod.getTypeVariables());
List<AnnotatedTypeMirror> params = AnnotatedTypes.expandVarArgsParameters(atypeFactory, invokedMethod, node.getArguments());
checkArguments(params, node.getArguments(), methodName, method.getParameters());
checkVarargs(invokedMethod, node);
if (ElementUtils.isMethod(invokedMethod.getElement(), vectorCopyInto, atypeFactory.getProcessingEnv())) {
typeCheckVectorCopyIntoArgument(node, params);
}
ExecutableElement invokedMethodElement = invokedMethod.getElement();
if (!ElementUtils.isStatic(invokedMethodElement) && !TreeUtils.isSuperConstructorCall(node)) {
checkMethodInvocability(invokedMethod, node);
}
// check precondition annotations
checkPreconditions(node, atypeFactory.getContractsFromMethod().getPreconditions(invokedMethodElement));
if (TreeUtils.isSuperConstructorCall(node)) {
checkSuperConstructorCall(node);
} else if (TreeUtils.isThisConstructorCall(node)) {
checkThisConstructorCall(node);
}
} catch (RuntimeException t) {
// is fixed this should be removed and crashes should be reported normally.
if (node.getTypeArguments().size() == typeargs.size()) {
// They type arguments were explicitly written.
throw t;
}
if (!atypeFactory.ignoreUninferredTypeArguments) {
checker.reportError(node, "type.arguments.not.inferred", invokedMethod.getElement().getSimpleName());
}
// else ignore the crash.
}
// Do not call super, as that would observe the arguments without
// a set assignment context.
scan(node.getMethodSelect(), p);
// super.visitMethodInvocation(node, p);
return null;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class BaseTypeVisitor method visitNewClass.
/**
* Performs a new class invocation check.
*
* <p>An invocation of a constructor, c, is valid only if:
*
* <ul>
* <li>passed arguments are subtypes of corresponding c parameters
* <li>if c is generic, passed type arguments are subtypes of c type variables
* </ul>
*/
@Override
public Void visitNewClass(NewClassTree node, Void p) {
if (checker.shouldSkipUses(TreeUtils.constructor(node))) {
return super.visitNewClass(node, p);
}
ParameterizedExecutableType fromUse = atypeFactory.constructorFromUse(node);
AnnotatedExecutableType constructorType = fromUse.executableType;
List<AnnotatedTypeMirror> typeargs = fromUse.typeArgs;
List<? extends ExpressionTree> passedArguments = node.getArguments();
List<AnnotatedTypeMirror> params = AnnotatedTypes.expandVarArgsParameters(atypeFactory, constructorType, passedArguments);
ExecutableElement constructor = constructorType.getElement();
CharSequence constructorName = ElementUtils.getSimpleNameOrDescription(constructor);
checkArguments(params, passedArguments, constructorName, constructor.getParameters());
checkVarargs(constructorType, node);
List<AnnotatedTypeParameterBounds> paramBounds = CollectionsPlume.mapList(AnnotatedTypeVariable::getBounds, constructorType.getTypeVariables());
checkTypeArguments(node, paramBounds, typeargs, node.getTypeArguments(), constructorName, constructor.getTypeParameters());
boolean valid = validateTypeOf(node);
if (valid) {
AnnotatedDeclaredType dt = atypeFactory.getAnnotatedType(node);
atypeFactory.getDependentTypesHelper().checkTypeForErrorExpressions(dt, node);
checkConstructorInvocation(dt, constructorType, node);
}
// Do not call super, as that would observe the arguments without
// a set assignment context.
scan(node.getEnclosingExpression(), p);
scan(node.getIdentifier(), p);
scan(node.getClassBody(), p);
return null;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class BaseTypeVisitor method visitUnary.
// **********************************************************************
// Check for illegal re-assignment
// **********************************************************************
/**
* Performs assignability check.
*/
@Override
public Void visitUnary(UnaryTree node, Void p) {
Tree.Kind nodeKind = node.getKind();
if ((nodeKind == Tree.Kind.PREFIX_DECREMENT) || (nodeKind == Tree.Kind.PREFIX_INCREMENT) || (nodeKind == Tree.Kind.POSTFIX_DECREMENT) || (nodeKind == Tree.Kind.POSTFIX_INCREMENT)) {
AnnotatedTypeMirror varType = atypeFactory.getAnnotatedTypeLhs(node.getExpression());
AnnotatedTypeMirror valueType = atypeFactory.getAnnotatedTypeRhsUnaryAssign(node);
String errorKey = (nodeKind == Tree.Kind.PREFIX_INCREMENT || nodeKind == Tree.Kind.POSTFIX_INCREMENT) ? "unary.increment" : "unary.decrement";
commonAssignmentCheck(varType, valueType, node, errorKey);
}
return super.visitUnary(node, p);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class BaseTypeVisitor method checkTypeArguments.
/**
* Checks that the annotations on the type arguments supplied to a type or a method invocation are
* within the bounds of the type variables as declared, and issues the "type.argument" error if
* they are not.
*
* @param toptree the tree for error reporting, only used for inferred type arguments
* @param paramBounds the bounds of the type parameters from a class or method declaration
* @param typeargs the type arguments from the type or method invocation
* @param typeargTrees the type arguments as trees, used for error reporting
*/
protected void checkTypeArguments(Tree toptree, List<? extends AnnotatedTypeParameterBounds> paramBounds, List<? extends AnnotatedTypeMirror> typeargs, List<? extends Tree> typeargTrees, CharSequence typeOrMethodName, List<?> paramNames) {
// If there are no type variables, do nothing.
if (paramBounds.isEmpty()) {
return;
}
int size = paramBounds.size();
assert size == typeargs.size() : "BaseTypeVisitor.checkTypeArguments: mismatch between type arguments: " + typeargs + " and type parameter bounds" + paramBounds;
for (int i = 0; i < size; i++) {
AnnotatedTypeParameterBounds bounds = paramBounds.get(i);
AnnotatedTypeMirror typeArg = typeargs.get(i);
if (isIgnoredUninferredWildcard(bounds.getUpperBound())) {
continue;
}
AnnotatedTypeMirror paramUpperBound = bounds.getUpperBound();
Tree reportErrorToTree;
if (typeargTrees == null || typeargTrees.isEmpty()) {
// The type arguments were inferred, report the error on the method invocation.
reportErrorToTree = toptree;
} else {
reportErrorToTree = typeargTrees.get(i);
}
checkHasQualifierParameterAsTypeArgument(typeArg, paramUpperBound, toptree);
commonAssignmentCheck(paramUpperBound, typeArg, reportErrorToTree, "type.argument", paramNames.get(i), typeOrMethodName);
if (!atypeFactory.getTypeHierarchy().isSubtype(bounds.getLowerBound(), typeArg)) {
FoundRequired fr = FoundRequired.of(typeArg, bounds);
checker.reportError(reportErrorToTree, "type.argument", paramNames.get(i), typeOrMethodName, fr.found, fr.required);
}
}
}
Aggregations