use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class AnnotatedTypes method findTypeArguments.
/**
* Given a method or constructor invocation, return a mapping of the type variables to their
* type arguments, if any exist.
*
* <p>It uses the method or constructor invocation type arguments if they were specified and
* otherwise it infers them based on the passed arguments or the return type context, according
* to JLS 15.12.2.
*
* @param atypeFactory the annotated type factory
* @param expr the method or constructor invocation tree; the passed argument has to be a
* subtype of MethodInvocationTree or NewClassTree
* @param elt the element corresponding to the tree
* @param preType the (partially annotated) type corresponding to the tree - the result of
* AnnotatedTypes.asMemberOf with the receiver and elt.
* @return the mapping of the type variables to type arguments for this method or constructor
* invocation
*/
public static Map<TypeVariable, AnnotatedTypeMirror> findTypeArguments(final ProcessingEnvironment processingEnv, final AnnotatedTypeFactory atypeFactory, final ExpressionTree expr, final ExecutableElement elt, final AnnotatedExecutableType preType) {
// Is the method a generic method?
if (elt.getTypeParameters().isEmpty()) {
return Collections.emptyMap();
}
List<? extends Tree> targs;
if (expr instanceof MethodInvocationTree) {
targs = ((MethodInvocationTree) expr).getTypeArguments();
} else if (expr instanceof NewClassTree) {
targs = ((NewClassTree) expr).getTypeArguments();
} else if (expr instanceof MemberReferenceTree) {
targs = ((MemberReferenceTree) expr).getTypeArguments();
if (targs == null) {
// TODO: Add type argument inference as part of fix for #979
return new HashMap<>();
}
} else {
// This case should never happen.
ErrorReporter.errorAbort("AnnotatedTypes.findTypeArguments: unexpected tree: " + expr);
// dead code
return null;
}
// Has the user supplied type arguments?
if (!targs.isEmpty()) {
List<? extends AnnotatedTypeVariable> tvars = preType.getTypeVariables();
Map<TypeVariable, AnnotatedTypeMirror> typeArguments = new HashMap<>();
for (int i = 0; i < elt.getTypeParameters().size(); ++i) {
AnnotatedTypeVariable typeVar = tvars.get(i);
AnnotatedTypeMirror typeArg = atypeFactory.getAnnotatedTypeFromTypeTree(targs.get(i));
// TODO: the call to getTypeParameterDeclaration shouldn't be necessary - typeVar
// already should be a declaration.
typeArguments.put(typeVar.getUnderlyingType(), typeArg);
}
return typeArguments;
} else {
return atypeFactory.getTypeArgumentInference().inferTypeArgs(atypeFactory, expr, elt, preType);
}
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class AnnotatedTypes method getAnnotatedTypeMirrorOfParameter.
/**
* Given an AnnotatedExecutableType of a method or constructor declaration, get the parameter
* type expect at the indexth position (unwrapping var args if necessary).
*
* @param methodType AnnotatedExecutableType of method or constructor containing parameter to
* return
* @param index position of parameter type to return
* @return if that parameter is a varArgs, return the component of the var args and NOT the
* array type. Otherwise, return the exact type of the parameter in the index position.
*/
public static AnnotatedTypeMirror getAnnotatedTypeMirrorOfParameter(AnnotatedExecutableType methodType, int index) {
List<AnnotatedTypeMirror> parameterTypes = methodType.getParameterTypes();
boolean hasVarArg = methodType.getElement().isVarArgs();
final int lastIndex = parameterTypes.size() - 1;
final AnnotatedTypeMirror lastType = parameterTypes.get(lastIndex);
final boolean parameterBeforeVarargs = index < lastIndex;
if (!parameterBeforeVarargs && lastType instanceof AnnotatedArrayType) {
final AnnotatedArrayType arrayType = (AnnotatedArrayType) lastType;
if (hasVarArg) {
return arrayType.getComponentType();
}
}
return parameterTypes.get(index);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class AtmLubVisitor method lubWithNull.
private AnnotatedTypeMirror lubWithNull(AnnotatedNullType nullType, AnnotatedTypeMirror otherType, AnnotatedTypeMirror lub) {
AnnotatedTypeMirror otherAsLub;
if (otherType.getKind() == TypeKind.NULL) {
otherAsLub = otherType.deepCopy();
} else {
otherAsLub = AnnotatedTypes.asSuper(atypeFactory, otherType, lub);
}
lub = otherAsLub.deepCopy();
if (otherAsLub.getKind() != TypeKind.TYPEVAR && otherAsLub.getKind() != TypeKind.WILDCARD) {
for (AnnotationMirror nullAnno : nullType.getAnnotations()) {
AnnotationMirror otherAnno = otherAsLub.getAnnotationInHierarchy(nullAnno);
AnnotationMirror lubAnno = qualifierHierarchy.leastUpperBound(nullAnno, otherAnno);
lub.replaceAnnotation(lubAnno);
}
return lub;
}
// LUB(@N null, T), where T's upper bound is @U and T's lower bound is @L
// if @L <: @U <: @N then LUB(@N null, T) = @N T
// if @L <: @N <:@U && @N != @L then LUB(@N null, T) = @U T
// if @N <: @L <: @U then LUB(@N null, T) = T
Set<AnnotationMirror> lowerBounds = AnnotatedTypes.findEffectiveLowerBoundAnnotations(qualifierHierarchy, otherAsLub);
for (AnnotationMirror lowerBound : lowerBounds) {
AnnotationMirror nullAnno = nullType.getAnnotationInHierarchy(lowerBound);
AnnotationMirror upperBound = otherAsLub.getEffectiveAnnotationInHierarchy(lowerBound);
if (qualifierHierarchy.isSubtype(upperBound, nullAnno)) {
// @L <: @U <: @N
lub.replaceAnnotation(nullAnno);
} else if (qualifierHierarchy.isSubtype(lowerBound, nullAnno) && !qualifierHierarchy.isSubtype(nullAnno, lowerBound)) {
// @L <: @N <:@U && @N != @L
lub.replaceAnnotation(upperBound);
}
// else @N <: @L <: @U
}
return lub;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class AtmLubVisitor method lub.
/**
* Returns an ATM that is the least upper bound of type1 and type2 and whose Java type is
* lubJavaType. lubJavaType must be a super type or convertible to the Java types of type1 and
* type2.
*/
AnnotatedTypeMirror lub(AnnotatedTypeMirror type1, AnnotatedTypeMirror type2, TypeMirror lubJavaType) {
AnnotatedTypeMirror lub = AnnotatedTypeMirror.createType(lubJavaType, atypeFactory, false);
if (type1.getKind() == TypeKind.NULL) {
return lubWithNull((AnnotatedNullType) type1, type2, lub);
}
if (type2.getKind() == TypeKind.NULL) {
return lubWithNull((AnnotatedNullType) type2, type1, lub);
}
AnnotatedTypeMirror type1AsLub = AnnotatedTypes.asSuper(atypeFactory, type1, lub);
AnnotatedTypeMirror type2AsLub = AnnotatedTypes.asSuper(atypeFactory, type2, lub);
visit(type1AsLub, type2AsLub, lub);
visited.clear();
return lub;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class AliasingTransfer method processPostconditions.
/**
* Handling pseudo-assignments. Called by {@code CFAbstractTransfer.visitMethodInvocation()}.
*
* <p>Case 2: Given a method call, traverses all formal parameters of the method declaration,
* and if it doesn't have the {@literal @}NonLeaked or {@literal @}LeakedToResult annotations,
* we remove the node of the respective argument in the method call from the store. If parameter
* has {@literal @}LeakedToResult, {@code visitMethodInvocation()} handles it.
*/
@Override
protected void processPostconditions(MethodInvocationNode n, CFStore store, ExecutableElement methodElement, Tree tree) {
super.processPostconditions(n, store, methodElement, tree);
if (TreeUtils.isEnumSuper(n.getTree())) {
// Skipping the init() method for enums.
return;
}
List<Node> args = n.getArguments();
List<? extends VariableElement> params = methodElement.getParameters();
assert (args.size() == params.size()) : "Number of arguments in " + "the method call " + n.toString() + " is different from the" + " number of parameters for the method declaration: " + methodElement.getSimpleName().toString();
AnnotatedExecutableType annotatedType = factory.getAnnotatedType(methodElement);
List<AnnotatedTypeMirror> paramTypes = annotatedType.getParameterTypes();
for (int i = 0; i < args.size(); i++) {
Node arg = args.get(i);
AnnotatedTypeMirror paramType = paramTypes.get(i);
if (!paramType.hasAnnotation(NonLeaked.class) && !paramType.hasAnnotation(LeakedToResult.class)) {
store.clearValue(FlowExpressions.internalReprOf(factory, arg));
}
}
// Now, doing the same as above for the receiver parameter
Node receiver = n.getTarget().getReceiver();
AnnotatedDeclaredType receiverType = annotatedType.getReceiverType();
if (receiverType != null && !receiverType.hasAnnotation(LeakedToResult.class) && !receiverType.hasAnnotation(NonLeaked.class)) {
store.clearValue(FlowExpressions.internalReprOf(factory, receiver));
}
}
Aggregations