use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class WholeProgramInferenceScenes method updateInferredFieldType.
/**
* Updates the type of the field lhs in the Scene of the class with tree classTree. If the field
* has a declaration annotation with the {@link IgnoreInWholeProgramInference} meta-annotation,
* no type annotation will be inferred for that field.
*
* <p>If the Scene contains no entry for the field lhs, the entry will be created and its type
* will be the type of rhs. If the Scene previously contained an entry/type for lhs, its new
* type will be the LUB between the previous type and the type of rhs.
*
* <p>
*
* @param lhs the field whose type will be refined
* @param rhs the expression being assigned to the field
* @param classTree the ClassTree for the enclosing class of the assignment
* @param atf the annotated type factory of a given type system, whose type hierarchy will be
* used to update the field's type
*/
@Override
public void updateInferredFieldType(FieldAccessNode lhs, Node rhs, ClassTree classTree, AnnotatedTypeFactory atf) {
ClassSymbol classSymbol = getEnclosingClassSymbol(classTree, lhs);
// https://github.com/typetools/checker-framework/issues/682
if (classSymbol == null) {
// TODO: Handle anonymous classes.
return;
}
// https://github.com/typetools/checker-framework/issues/682
if (!classSymbol.getEnclosedElements().contains((Symbol) lhs.getElement())) {
return;
}
// @IgnoreInWholeProgramInference meta-annotation, exit this routine.
for (AnnotationMirror declAnno : atf.getDeclAnnotations(TreeUtils.elementFromTree(lhs.getTree()))) {
if (AnnotationUtils.areSameByClass(declAnno, IgnoreInWholeProgramInference.class)) {
return;
}
Element elt = declAnno.getAnnotationType().asElement();
if (elt.getAnnotation(IgnoreInWholeProgramInference.class) != null) {
return;
}
}
String className = classSymbol.flatname.toString();
String jaifPath = helper.getJaifPath(className);
AClass clazz = helper.getAClass(className, jaifPath);
AField field = clazz.fields.vivify(lhs.getFieldName());
AnnotatedTypeMirror lhsATM = atf.getAnnotatedType(lhs.getTree());
AnnotatedTypeMirror rhsATM = atf.getAnnotatedType(rhs.getTree());
helper.updateAnnotationSetInScene(field.type, atf, jaifPath, rhsATM, lhsATM, TypeUseLocation.FIELD);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class WholeProgramInferenceScenesHelper method updateAnnotationSetInScene.
/**
* Updates the set of annotations in a location of a Scene.
*
* <ul>
* <li>If there was no previous annotation for that location, then the updated set will be the
* annotations in newATM.
* <li>If there was a previous annotation, the updated set will be the LUB between the
* previous annotation and newATM.
* </ul>
*
* <p>
*
* @param type ATypeElement of the Scene which will be modified
* @param atf the annotated type factory of a given type system, whose type hierarchy will be
* used
* @param jaifPath used to identify a Scene
* @param rhsATM the RHS of the annotated type on the source code
* @param lhsATM the LHS of the annotated type on the source code
* @param defLoc the location where the annotation will be added
*/
protected void updateAnnotationSetInScene(ATypeElement type, AnnotatedTypeFactory atf, String jaifPath, AnnotatedTypeMirror rhsATM, AnnotatedTypeMirror lhsATM, TypeUseLocation defLoc) {
if (rhsATM instanceof AnnotatedNullType && ignoreNullAssignments) {
return;
}
AnnotatedTypeMirror atmFromJaif = AnnotatedTypeMirror.createType(rhsATM.getUnderlyingType(), atf, false);
typeElementToATM(atmFromJaif, type, atf);
updatesATMWithLUB(atf, rhsATM, atmFromJaif);
if (lhsATM instanceof AnnotatedTypeVariable) {
Set<AnnotationMirror> upperAnnos = ((AnnotatedTypeVariable) lhsATM).getUpperBound().getEffectiveAnnotations();
// current type on the source code, halt.
if (upperAnnos.size() == rhsATM.getAnnotations().size() && atf.getQualifierHierarchy().isSubtype(rhsATM.getAnnotations(), upperAnnos)) {
return;
}
}
updateTypeElementFromATM(rhsATM, lhsATM, atf, type, 1, defLoc);
modifiedScenes.add(jaifPath);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class CFAbstractTransfer method getValueFromFactory.
/**
* @return the abstract value of a non-leaf tree {@code tree}, as computed by the {@link
* AnnotatedTypeFactory}.
*/
protected V getValueFromFactory(Tree tree, Node node) {
GenericAnnotatedTypeFactory<V, S, T, ? extends CFAbstractAnalysis<V, S, T>> factory = analysis.atypeFactory;
Tree preTree = analysis.getCurrentTree();
Pair<Tree, AnnotatedTypeMirror> preCtxt = factory.getVisitorState().getAssignmentContext();
analysis.setCurrentTree(tree);
// is there an assignment context node available?
if (node != null && node.getAssignmentContext() != null) {
// get the declared type of the assignment context by looking up the
// assignment context tree's type in the factory while flow is
// disabled.
Tree contextTree = node.getAssignmentContext().getContextTree();
AnnotatedTypeMirror assCtxt = null;
if (contextTree != null) {
assCtxt = factory.getAnnotatedTypeLhs(contextTree);
} else {
Element assCtxtElement = node.getAssignmentContext().getElementForType();
if (assCtxtElement != null) {
// if contextTree is null, use the element to get the type
assCtxt = factory.getAnnotatedType(assCtxtElement);
}
}
if (assCtxt != null) {
if (assCtxt instanceof AnnotatedExecutableType) {
// For a MethodReturnContext, we get the full type of the
// method, but we only want the return type.
assCtxt = ((AnnotatedExecutableType) assCtxt).getReturnType();
}
factory.getVisitorState().setAssignmentContext(Pair.of(node.getAssignmentContext().getContextTree(), assCtxt));
}
}
AnnotatedTypeMirror at = factory.getAnnotatedType(tree);
analysis.setCurrentTree(preTree);
factory.getVisitorState().setAssignmentContext(preCtxt);
return analysis.createAbstractValue(at);
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class CFAbstractValue method getEffectTypeVar.
/**
* Returns the AnnotatedTypeVariable associated with the given TypeMirror or null.
*
* <p>If TypeMirror is a type variable, then the AnnotatedTypeVariable return is the declaration
* of that TypeMirror. If the TypeMirror is a wildcard that extends a type variable, the
* AnnotatedTypeVariable return is the declaration of that type variable. Otherwise, null is
* returned.
*/
private AnnotatedTypeVariable getEffectTypeVar(TypeMirror typeMirror) {
if (typeMirror == null) {
return null;
} else if (typeMirror.getKind() == TypeKind.WILDCARD) {
return getEffectTypeVar(((WildcardType) typeMirror).getExtendsBound());
} else if (typeMirror.getKind() == TypeKind.TYPEVAR) {
TypeVariable typevar = ((TypeVariable) typeMirror);
AnnotatedTypeMirror atm = analysis.getTypeFactory().getAnnotatedType(typevar.asElement());
return (AnnotatedTypeVariable) atm;
} else {
return null;
}
}
use of org.checkerframework.framework.type.AnnotatedTypeMirror in project checker-framework by typetools.
the class CFTreeBuilder method createAnnotatedType.
private Tree createAnnotatedType(AnnotatedTypeMirror annotatedType) {
// Implementation based on com.sun.tools.javac.tree.TreeMaker.Type
// Convert the annotations from a set of AnnotationMirrors
// to a list of AnnotationTrees.
Set<AnnotationMirror> annotations = annotatedType.getAnnotations();
List<JCTree.JCAnnotation> annotationTrees = List.nil();
for (AnnotationMirror am : annotations) {
// TODO: what TypeAnnotationPosition should be used?
Attribute.TypeCompound typeCompound = TypeAnnotationUtils.createTypeCompoundFromAnnotationMirror(am, TypeAnnotationUtils.unknownTAPosition(), env);
JCTree.JCAnnotation annotationTree = maker.Annotation(typeCompound);
JCTree.JCAnnotation typeAnnotationTree = maker.TypeAnnotation(annotationTree.getAnnotationType(), annotationTree.getArguments());
typeAnnotationTree.attribute = typeCompound;
annotationTrees = annotationTrees.append(typeAnnotationTree);
}
// Convert the underlying type from a TypeMirror to an
// ExpressionTree and combine with the AnnotationTrees
// to form a ClassTree of kind ANNOTATION_TYPE.
Tree underlyingTypeTree;
switch(annotatedType.getKind()) {
case BYTE:
underlyingTypeTree = maker.TypeIdent(TypeTag.BYTE);
break;
case CHAR:
underlyingTypeTree = maker.TypeIdent(TypeTag.BYTE);
break;
case SHORT:
underlyingTypeTree = maker.TypeIdent(TypeTag.SHORT);
break;
case INT:
underlyingTypeTree = maker.TypeIdent(TypeTag.INT);
break;
case LONG:
underlyingTypeTree = maker.TypeIdent(TypeTag.LONG);
break;
case FLOAT:
underlyingTypeTree = maker.TypeIdent(TypeTag.FLOAT);
break;
case DOUBLE:
underlyingTypeTree = maker.TypeIdent(TypeTag.DOUBLE);
break;
case BOOLEAN:
underlyingTypeTree = maker.TypeIdent(TypeTag.BOOLEAN);
break;
case VOID:
underlyingTypeTree = maker.TypeIdent(TypeTag.VOID);
break;
case TYPEVAR:
{
// No recursive annotations.
AnnotatedTypeMirror.AnnotatedTypeVariable variable = (AnnotatedTypeMirror.AnnotatedTypeVariable) annotatedType;
TypeVariable underlyingTypeVar = variable.getUnderlyingType();
underlyingTypeTree = maker.Ident((Symbol.TypeSymbol) (underlyingTypeVar).asElement());
break;
}
case WILDCARD:
{
AnnotatedTypeMirror.AnnotatedWildcardType wildcard = (AnnotatedTypeMirror.AnnotatedWildcardType) annotatedType;
WildcardType wildcardType = wildcard.getUnderlyingType();
if (wildcardType.getExtendsBound() != null) {
Tree annotatedExtendsBound = createAnnotatedType(wildcard.getExtendsBound());
underlyingTypeTree = maker.Wildcard(maker.TypeBoundKind(BoundKind.EXTENDS), (JCTree) annotatedExtendsBound);
} else if (wildcardType.getSuperBound() != null) {
Tree annotatedSuperBound = createAnnotatedType(wildcard.getSuperBound());
underlyingTypeTree = maker.Wildcard(maker.TypeBoundKind(BoundKind.SUPER), (JCTree) annotatedSuperBound);
} else {
underlyingTypeTree = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
}
break;
}
case DECLARED:
{
underlyingTypeTree = maker.Type((Type) annotatedType.getUnderlyingType());
if (underlyingTypeTree instanceof JCTree.JCTypeApply) {
// Replace the type parameters with annotated versions.
AnnotatedTypeMirror.AnnotatedDeclaredType annotatedDeclaredType = (AnnotatedTypeMirror.AnnotatedDeclaredType) annotatedType;
List<JCTree.JCExpression> typeArgTrees = List.nil();
for (AnnotatedTypeMirror arg : annotatedDeclaredType.getTypeArguments()) {
typeArgTrees = typeArgTrees.append((JCTree.JCExpression) createAnnotatedType(arg));
}
JCTree.JCExpression clazz = (JCTree.JCExpression) ((JCTree.JCTypeApply) underlyingTypeTree).getType();
underlyingTypeTree = maker.TypeApply(clazz, typeArgTrees);
}
break;
}
case ARRAY:
{
AnnotatedTypeMirror.AnnotatedArrayType annotatedArrayType = (AnnotatedTypeMirror.AnnotatedArrayType) annotatedType;
Tree annotatedComponentTree = createAnnotatedType(annotatedArrayType.getComponentType());
underlyingTypeTree = maker.TypeArray((JCTree.JCExpression) annotatedComponentTree);
break;
}
case ERROR:
underlyingTypeTree = maker.TypeIdent(TypeTag.ERROR);
break;
default:
assert false : "unexpected type: " + annotatedType;
underlyingTypeTree = null;
break;
}
((JCTree) underlyingTypeTree).setType((Type) annotatedType.getUnderlyingType());
if (annotationTrees.isEmpty()) {
return underlyingTypeTree;
}
JCTree.JCAnnotatedType annotatedTypeTree = maker.AnnotatedType(annotationTrees, (JCTree.JCExpression) underlyingTypeTree);
annotatedTypeTree.setType((Type) annotatedType.getUnderlyingType());
return annotatedTypeTree;
}
Aggregations