use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType in project checker-framework by typetools.
the class WholeProgramInferenceScenesHelper method updateTypeElementFromATM.
/**
* Updates an {@link scenelib.annotations.el.ATypeElement} to have the annotations of an {@link
* org.checkerframework.framework.type.AnnotatedTypeMirror} passed as argument. Annotations in
* the original set that should be ignored (see {@link #shouldIgnore}) are not added to the
* resulting set. This method also checks if the AnnotatedTypeMirror has explicit annotations in
* source code, and if that is the case no annotations are added for that location.
*
* <p>This method removes from the ATypeElement all annotations supported by atf before
* inserting new ones. It is assumed that every time this method is called, the
* AnnotatedTypeMirror has a better type estimate for the ATypeElement. Therefore, it is not a
* problem to remove all annotations before inserting the new annotations.
*
* @param newATM the AnnotatedTypeMirror whose annotations will be added to the ATypeElement
* @param curATM used to check if the element which will be updated has explicit annotations in
* source code
* @param atf the annotated type factory of a given type system, whose type hierarchy will be
* used
* @param typeToUpdate the ATypeElement which will be updated
* @param idx used to write annotations on compound types of an ATypeElement
* @param defLoc the location where the annotation will be added
*/
private void updateTypeElementFromATM(AnnotatedTypeMirror newATM, AnnotatedTypeMirror curATM, AnnotatedTypeFactory atf, ATypeElement typeToUpdate, int idx, TypeUseLocation defLoc) {
// The others stay intact.
if (idx == 1) {
// This if avoids clearing the annotations multiple times in cases
// of type variables and compound types.
Set<Annotation> annosToRemove = getSupportedAnnosInSet(typeToUpdate.tlAnnotationsHere, atf);
// This method may be called consecutive times for the same ATypeElement.
// Each time it is called, the AnnotatedTypeMirror has a better type
// estimate for the ATypeElement. Therefore, it is not a problem to remove
// all annotations before inserting the new annotations.
typeToUpdate.tlAnnotationsHere.removeAll(annosToRemove);
}
// Only update the ATypeElement if there are no explicit annotations
if (curATM.getExplicitAnnotations().size() == 0) {
for (AnnotationMirror am : newATM.getAnnotations()) {
addAnnotationsToATypeElement(newATM, atf, typeToUpdate, defLoc, am, curATM.hasEffectiveAnnotation(am));
}
} else if (curATM.getKind() == TypeKind.TYPEVAR) {
// vars upper bound from being inserted.
for (AnnotationMirror am : newATM.getAnnotations()) {
if (curATM.getAnnotationInHierarchy(am) != null) {
// in the same hierarchy.
break;
}
addAnnotationsToATypeElement(newATM, atf, typeToUpdate, defLoc, am, curATM.hasEffectiveAnnotation(am));
}
}
// Recursively update compound type and type variable type if they exist.
if (newATM.getKind() == TypeKind.ARRAY && curATM.getKind() == TypeKind.ARRAY) {
AnnotatedArrayType newAAT = (AnnotatedArrayType) newATM;
AnnotatedArrayType oldAAT = (AnnotatedArrayType) curATM;
updateTypeElementFromATM(newAAT.getComponentType(), oldAAT.getComponentType(), atf, typeToUpdate.innerTypes.vivify(new InnerTypeLocation(TypeAnnotationPosition.getTypePathFromBinary(Collections.nCopies(2 * idx, 0)))), idx + 1, defLoc);
}
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType in project checker-framework by typetools.
the class StubParser method annotateAsArray.
/**
* Add the annotations from {@code type} to {@code atype}. Type annotations that parsed as
* declaration annotations (ie those in {@code declAnnos} are applied to the innermost component
* type.
*
* @param atype annotated type to which to add annotations
* @param type parsed type
* @param declAnnos annotations stored on the declaration of the variable with this type or null
*/
private void annotateAsArray(AnnotatedArrayType atype, ReferenceType type, NodeList<AnnotationExpr> declAnnos) {
annotateInnermostComponentType(atype, declAnnos);
Type typeDef = type;
AnnotatedTypeMirror currentAtype = atype;
while (typeDef.isArrayType() && currentAtype.getKind() == TypeKind.ARRAY) {
// handle generic type
clearAnnotations(currentAtype, typeDef);
List<AnnotationExpr> annotations = typeDef.getAnnotations();
if (annotations != null) {
annotate(currentAtype, annotations);
}
typeDef = ((com.github.javaparser.ast.type.ArrayType) typeDef).getComponentType();
currentAtype = ((AnnotatedArrayType) currentAtype).getComponentType();
if (typeDef.isArrayType() ^ currentAtype.getKind() == TypeKind.ARRAY) {
stubWarn("Mismatched array lengths; atype: " + atype + "%n type: " + type);
}
}
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType in project checker-framework by typetools.
the class DefaultReflectionResolver method resolveMethodCall.
/**
* Resolves a call to {@link Method#invoke(Object, Object...)}.
*
* @param factory the {@link AnnotatedTypeFactory} of the underlying type system
* @param tree the method invocation tree that has to be resolved
* @param origResult the original result from {@code factory.methodFromUse}.
*/
private Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> resolveMethodCall(AnnotatedTypeFactory factory, MethodInvocationTree tree, Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> origResult) {
debugReflection("Try to resolve reflective method call: " + tree);
List<MethodInvocationTree> possibleMethods = resolveReflectiveMethod(tree, factory);
// Reflective method could not be resolved
if (possibleMethods.size() == 0) {
return origResult;
}
Set<? extends AnnotationMirror> returnLub = null;
Set<? extends AnnotationMirror> receiverGlb = null;
Set<? extends AnnotationMirror> paramsGlb = null;
// and parameter types
for (MethodInvocationTree resolvedTree : possibleMethods) {
debugReflection("Resolved method invocation: " + resolvedTree);
if (!checkMethodAgruments(resolvedTree)) {
debugReflection("Spoofed tree's arguments did not match declaration" + resolvedTree.toString());
// in QualifierPolymorphism.PolyCollector.visitArray(...)
continue;
}
Pair<AnnotatedExecutableType, List<AnnotatedTypeMirror>> resolvedResult = factory.methodFromUse(resolvedTree);
// Lub return types
returnLub = lub(returnLub, resolvedResult.first.getReturnType().getAnnotations(), factory);
// Check for static methods whose receiver is null
if (resolvedResult.first.getReceiverType() == null) {
// If the method is static the first argument to Method.invoke isn't used,
// so assume top.
receiverGlb = glb(receiverGlb, factory.getQualifierHierarchy().getTopAnnotations(), factory);
} else {
receiverGlb = glb(receiverGlb, resolvedResult.first.getReceiverType().getAnnotations(), factory);
}
// the types of different formal parameters.
for (AnnotatedTypeMirror mirror : resolvedResult.first.getParameterTypes()) {
paramsGlb = glb(paramsGlb, mirror.getAnnotations(), factory);
}
}
if (returnLub == null) {
// None of the spoofed tree's arguments matched the declared method
return origResult;
}
/*
* Clear all original (return, receiver, parameter type) annotations and
* set lub/glb annotations from resolved method(s)
*/
// return value
origResult.first.getReturnType().clearAnnotations();
origResult.first.getReturnType().addAnnotations(returnLub);
// receiver type
origResult.first.getParameterTypes().get(0).clearAnnotations();
origResult.first.getParameterTypes().get(0).addAnnotations(receiverGlb);
// parameter types
if (paramsGlb != null) {
AnnotatedArrayType origArrayType = (AnnotatedArrayType) origResult.first.getParameterTypes().get(1);
origArrayType.getComponentType().clearAnnotations();
origArrayType.getComponentType().addAnnotations(paramsGlb);
}
debugReflection("Resolved annotations: " + origResult.first);
return origResult;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType in project checker-framework by typetools.
the class TypeFromExpressionVisitor method visitNewArray.
@Override
public AnnotatedTypeMirror visitNewArray(NewArrayTree node, AnnotatedTypeFactory f) {
// Don't use fromTypeTree here, because node.getType() is not an
// array type!
AnnotatedArrayType result = (AnnotatedArrayType) f.type(node);
if (// e.g., byte[] b = {(byte)1, (byte)2};
node.getType() == null)
return result;
annotateArrayAsArray(result, node, f);
return result;
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType 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);
}
Aggregations