use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class WholeProgramInferenceScenes method updateInferredMethodReceiverType.
/**
* Updates the receiver type of the method {@code methodElt} in the Scene of the method's
* enclosing class based on the overridden method {@code overriddenMethod} receiver type.
*
* <p>For the receiver in methodElt:
*
* <ul>
* <li>If the Scene does not contain an annotated type for the receiver, then the type of the
* receiver on the overridden method will be added to the receiver in the Scene.
* <li>If the Scene previously contained an annotated type for the receiver, then its new type
* will be the LUB between the previous type and the type of the receiver on the
* overridden method.
* </ul>
*
* <p>
*
* @param methodTree the tree of the method that contains the receiver
* @param methodElt the element of the method
* @param overriddenMethod the overridden method
* @param atf the annotated type factory of a given type system, whose type hierarchy will be
* used to update the receiver type
*/
@Override
public void updateInferredMethodReceiverType(MethodTree methodTree, ExecutableElement methodElt, AnnotatedExecutableType overriddenMethod, AnnotatedTypeFactory atf) {
ClassSymbol classSymbol = getEnclosingClassSymbol(methodTree);
String className = classSymbol.flatname.toString();
String jaifPath = helper.getJaifPath(className);
AClass clazz = helper.getAClass(className, jaifPath);
String methodName = JVMNames.getJVMMethodName(methodElt);
AMethod method = clazz.methods.vivify(methodName);
AnnotatedDeclaredType argADT = overriddenMethod.getReceiverType();
if (argADT != null) {
AnnotatedTypeMirror paramATM = atf.getAnnotatedType(methodTree).getReceiverType();
if (paramATM != null) {
AField receiver = method.receiver;
helper.updateAnnotationSetInScene(receiver.type, atf, jaifPath, argADT, paramATM, TypeUseLocation.RECEIVER);
}
}
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class WholeProgramInferenceScenes method updateInferredExecutableParameterTypes.
/**
* Helper method for updating parameter types based on calls to a method or constructor.
*/
private void updateInferredExecutableParameterTypes(ExecutableElement methodElt, AnnotatedTypeFactory atf, String jaifPath, AMethod method, List<Node> arguments) {
for (int i = 0; i < arguments.size(); i++) {
VariableElement ve = methodElt.getParameters().get(i);
AnnotatedTypeMirror paramATM = atf.getAnnotatedType(ve);
Node arg = arguments.get(i);
Tree treeNode = arg.getTree();
if (treeNode == null) {
// https://github.com/typetools/checker-framework/issues/682
continue;
}
AnnotatedTypeMirror argATM = atf.getAnnotatedType(treeNode);
AField param = method.parameters.vivify(i);
helper.updateAnnotationSetInScene(param.type, atf, jaifPath, argATM, paramATM, TypeUseLocation.PARAMETER);
}
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class WholeProgramInferenceScenes method updateInferredParameterType.
/**
* Updates the parameter type represented by lhs of the method methodTree in the Scene of the
* receiverTree's enclosing class based on assignments to the parameter inside the method body.
*
* <ul>
* <li>If the Scene does not contain an annotated type for that parameter, then the type of
* the respective value passed as argument in the method call methodInvNode will be added
* to the parameter in the Scene.
* <li>If the Scene previously contained an annotated type for that parameter, then its new
* type will be the LUB between the previous type and the type of the respective value
* passed as argument in the method call.
* </ul>
*
* <p>
*
* @param lhs the node representing the parameter
* @param rhs the node being assigned to the parameter
* @param classTree the tree of the class that contains the parameter
* @param methodTree the tree of the method that contains the parameter
* @param atf the annotated type factory of a given type system, whose type hierarchy will be
* used to update the parameter type
*/
@Override
public void updateInferredParameterType(LocalVariableNode lhs, Node rhs, ClassTree classTree, MethodTree methodTree, AnnotatedTypeFactory atf) {
ClassSymbol classSymbol = getEnclosingClassSymbol(classTree, lhs);
// https://github.com/typetools/checker-framework/issues/682
if (classSymbol == null)
return;
String className = classSymbol.flatname.toString();
String jaifPath = helper.getJaifPath(className);
AClass clazz = helper.getAClass(className, jaifPath);
String methodName = JVMNames.getJVMMethodName(methodTree);
AMethod method = clazz.methods.vivify(methodName);
List<? extends VariableTree> params = methodTree.getParameters();
// Look-up parameter by name:
for (int i = 0; i < params.size(); i++) {
VariableTree vt = params.get(i);
if (vt.getName().contentEquals(lhs.getName())) {
Tree treeNode = rhs.getTree();
if (treeNode == null) {
// https://github.com/typetools/checker-framework/issues/682
continue;
}
AnnotatedTypeMirror paramATM = atf.getAnnotatedType(vt);
AnnotatedTypeMirror argATM = atf.getAnnotatedType(treeNode);
AField param = method.parameters.vivify(i);
helper.updateAnnotationSetInScene(param.type, atf, jaifPath, argATM, paramATM, TypeUseLocation.PARAMETER);
break;
}
}
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class WholeProgramInferenceScenes method updateInferredMethodReturnType.
/**
* Updates the return type of the method methodTree in the Scene of the class with symbol
* classSymbol.
*
* <p>If the Scene does not contain an annotated return type for the method methodTree, then the
* type of the value passed to the return expression will be added to the return type of that
* method in the Scene. If the Scene previously contained an annotated return type for the
* method methodTree, its new type will be the LUB between the previous type and the type of the
* value passed to the return expression.
*
* <p>
*
* @param retNode the node that contains the expression returned
* @param classSymbol the symbol of the class that contains the method
* @param methodTree the tree of the method whose return type may be updated
* @param atf the annotated type factory of a given type system, whose type hierarchy will be
* used to update the method's return type
*/
@Override
public void updateInferredMethodReturnType(ReturnNode retNode, ClassSymbol classSymbol, MethodTree methodTree, AnnotatedTypeFactory atf) {
// TODO: Handle anonymous classes.
if (classSymbol == null)
return;
String className = classSymbol.flatname.toString();
String jaifPath = helper.getJaifPath(className);
AClass clazz = helper.getAClass(className, jaifPath);
AMethod method = clazz.methods.vivify(JVMNames.getJVMMethodName(methodTree));
// Method return type
AnnotatedTypeMirror lhsATM = atf.getAnnotatedType(methodTree).getReturnType();
// Type of the expression returned
AnnotatedTypeMirror rhsATM = atf.getAnnotatedType(retNode.getTree().getExpression());
helper.updateAnnotationSetInScene(method.returnType, atf, jaifPath, rhsATM, lhsATM, TypeUseLocation.RETURN);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class WholeProgramInferenceScenesHelper method shouldIgnore.
/**
* Returns true if {@code am} should not be inserted in source code, for example {@link
* org.checkerframework.common.value.qual.BottomVal}. This happens when {@code am} cannot be
* inserted in source code or is the default for the location passed as argument.
*
* <p>Invisible qualifiers, which are annotations that contain the {@link
* org.checkerframework.framework.qual.InvisibleQualifier} meta-annotation, also return true.
*
* <p>TODO: Merge functionality somewhere else with {@link
* org.checkerframework.framework.type.GenericAnnotatedTypeFactory#createQualifierDefaults}.
* Look into the createQualifierDefaults method before changing anything here. See Issue 683
* https://github.com/typetools/checker-framework/issues/683
*/
private boolean shouldIgnore(AnnotationMirror am, TypeUseLocation location, AnnotatedTypeFactory atf, AnnotatedTypeMirror atm) {
Element elt = am.getAnnotationType().asElement();
// Checks if am is an implementation detail (a type qualifier used
// internally by the type system and not meant to be seen by the user.)
Target target = elt.getAnnotation(Target.class);
if (target != null && target.value().length == 0)
return true;
if (elt.getAnnotation(InvisibleQualifier.class) != null)
return true;
// Checks if am is default
if (elt.getAnnotation(DefaultQualifierInHierarchy.class) != null) {
return true;
}
DefaultQualifier defaultQual = elt.getAnnotation(DefaultQualifier.class);
if (defaultQual != null) {
for (TypeUseLocation loc : defaultQual.locations()) {
if (loc == TypeUseLocation.ALL || loc == location) {
return true;
}
}
}
DefaultFor defaultQualForLocation = elt.getAnnotation(DefaultFor.class);
if (defaultQualForLocation != null) {
for (TypeUseLocation loc : defaultQualForLocation.value()) {
if (loc == TypeUseLocation.ALL || loc == location) {
return true;
}
}
}
// Checks if am is an implicit annotation.
// This case checks if it is meta-annotated with @ImplicitFor.
// TODO: Handle cases of implicit annotations added via an
// org.checkerframework.framework.type.treeannotator.ImplicitsTreeAnnotator.
ImplicitFor implicitFor = elt.getAnnotation(ImplicitFor.class);
if (implicitFor != null) {
org.checkerframework.framework.qual.TypeKind[] types = implicitFor.types();
TypeKind atmKind = atm.getUnderlyingType().getKind();
if (hasMatchingTypeKind(atmKind, types)) {
return true;
}
try {
Class<?>[] names = implicitFor.typeNames();
for (Class<?> c : names) {
TypeMirror underlyingtype = atm.getUnderlyingType();
while (underlyingtype instanceof javax.lang.model.type.ArrayType) {
underlyingtype = ((javax.lang.model.type.ArrayType) underlyingtype).getComponentType();
}
if (c.getCanonicalName().equals(atm.getUnderlyingType().toString())) {
return true;
}
}
} catch (MirroredTypesException e) {
}
}
return false;
}
Aggregations