Search in sources :

Example 96 with AnnotatedTypeMirror

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);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) TypeSymbol(com.sun.tools.javac.code.Symbol.TypeSymbol) Symbol(com.sun.tools.javac.code.Symbol) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) IgnoreInWholeProgramInference(org.checkerframework.framework.qual.IgnoreInWholeProgramInference) AClass(scenelib.annotations.el.AClass) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AField(scenelib.annotations.el.AField)

Example 97 with AnnotatedTypeMirror

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);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) AnnotatedNullType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedNullType) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Example 98 with AnnotatedTypeMirror

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);
}
Also used : AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) UnderlyingAST(org.checkerframework.dataflow.cfg.UnderlyingAST) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 99 with AnnotatedTypeMirror

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;
    }
}
Also used : AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) WildcardType(javax.lang.model.type.WildcardType) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Example 100 with AnnotatedTypeMirror

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;
}
Also used : Attribute(com.sun.tools.javac.code.Attribute) Symbol(com.sun.tools.javac.code.Symbol) JCTree(com.sun.tools.javac.tree.JCTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotationMirror(javax.lang.model.element.AnnotationMirror) WildcardType(javax.lang.model.type.WildcardType) TypeVariable(javax.lang.model.type.TypeVariable) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.sun.source.tree.Tree) List(com.sun.tools.javac.util.List)

Aggregations

AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)188 AnnotationMirror (javax.lang.model.element.AnnotationMirror)42 ExpressionTree (com.sun.source.tree.ExpressionTree)32 AnnotatedDeclaredType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType)27 Tree (com.sun.source.tree.Tree)25 AnnotatedTypeVariable (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)25 VariableTree (com.sun.source.tree.VariableTree)22 ArrayList (java.util.ArrayList)22 AnnotatedExecutableType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)21 MethodTree (com.sun.source.tree.MethodTree)20 TypeVariable (javax.lang.model.type.TypeVariable)19 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)18 AnnotatedArrayType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType)17 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)16 TypeMirror (javax.lang.model.type.TypeMirror)16 VariableElement (javax.lang.model.element.VariableElement)15 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)13 MemberSelectTree (com.sun.source.tree.MemberSelectTree)13 NewClassTree (com.sun.source.tree.NewClassTree)13 Element (javax.lang.model.element.Element)13