Search in sources :

Example 1 with ThisReference

use of org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference in project checker-framework by typetools.

the class CFAbstractTransfer method addFieldValues.

private void addFieldValues(S info, AnnotatedTypeFactory factory, ClassTree classTree, MethodTree methodTree) {
    // Add knowledge about final fields, or values of non-final fields
    // if we are inside a constructor (information about initializers)
    TypeMirror classType = TreeUtils.typeOf(classTree);
    List<Pair<VariableElement, V>> fieldValues = analysis.getFieldValues();
    for (Pair<VariableElement, V> p : fieldValues) {
        VariableElement element = p.first;
        V value = p.second;
        if (ElementUtils.isFinal(element) || TreeUtils.isConstructor(methodTree)) {
            Receiver receiver;
            if (ElementUtils.isStatic(element)) {
                receiver = new ClassName(classType);
            } else {
                receiver = new ThisReference(classType);
            }
            TypeMirror fieldType = ElementUtils.getType(element);
            Receiver field = new FieldAccess(receiver, fieldType, element);
            info.insertValue(field, value);
        }
    }
    // add properties about fields (static information from type)
    boolean isNotFullyInitializedReceiver = isNotFullyInitializedReceiver(methodTree);
    if (isNotFullyInitializedReceiver && !TreeUtils.isConstructor(methodTree)) {
        // and the method isn't a constructor
        return;
    }
    for (Tree member : classTree.getMembers()) {
        if (member instanceof VariableTree) {
            VariableTree vt = (VariableTree) member;
            final VariableElement element = TreeUtils.elementFromDeclaration(vt);
            AnnotatedTypeMirror type = ((GenericAnnotatedTypeFactory<?, ?, ?, ?>) factory).getAnnotatedTypeLhs(vt);
            TypeMirror fieldType = ElementUtils.getType(element);
            Receiver receiver;
            if (ElementUtils.isStatic(element)) {
                receiver = new ClassName(classType);
            } else {
                receiver = new ThisReference(classType);
            }
            V value = analysis.createAbstractValue(type);
            if (value == null)
                continue;
            if (TreeUtils.isConstructor(methodTree)) {
                // if we are in a constructor,
                // then we can still use the static type, but only
                // if there is also an initializer that already does
                // some initialization.
                boolean found = false;
                for (Pair<VariableElement, V> fieldValue : fieldValues) {
                    if (fieldValue.first.equals(element)) {
                        value = value.leastUpperBound(fieldValue.second);
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    // no initializer found, cannot use static type
                    continue;
                }
            }
            Receiver field = new FieldAccess(receiver, fieldType, element);
            info.insertValue(field, value);
        }
    }
}
Also used : GenericAnnotatedTypeFactory(org.checkerframework.framework.type.GenericAnnotatedTypeFactory) VariableTree(com.sun.source.tree.VariableTree) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) VariableElement(javax.lang.model.element.VariableElement) ThisReference(org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess) Pair(org.checkerframework.javacutil.Pair)

Example 2 with ThisReference

use of org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference in project checker-framework by typetools.

the class InitializationStore method insertValue.

/**
 * {@inheritDoc}
 *
 * <p>If the receiver is a field, and has an invariant annotation, then it can be considered
 * initialized.
 */
@Override
public void insertValue(Receiver r, V value) {
    if (value == null) {
        // top and top is also the default value.
        return;
    }
    InitializationAnnotatedTypeFactory<?, ?, ?, ?> atypeFactory = (InitializationAnnotatedTypeFactory<?, ?, ?, ?>) analysis.getTypeFactory();
    QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();
    AnnotationMirror invariantAnno = atypeFactory.getFieldInvariantAnnotation();
    // Remember fields that have the 'invariant' annotation in the store.
    if (r instanceof FieldAccess) {
        FieldAccess fieldAccess = (FieldAccess) r;
        if (!fieldValues.containsKey(r)) {
            Set<AnnotationMirror> declaredAnnos = atypeFactory.getAnnotatedType(fieldAccess.getField()).getAnnotations();
            if (AnnotationUtils.containsSame(declaredAnnos, invariantAnno)) {
                if (!invariantFields.containsKey(fieldAccess)) {
                    invariantFields.put(fieldAccess, analysis.createSingleAnnotationValue(invariantAnno, r.getType()));
                }
            }
        }
    }
    super.insertValue(r, value);
    for (AnnotationMirror a : value.getAnnotations()) {
        if (qualifierHierarchy.isSubtype(a, invariantAnno)) {
            if (r instanceof FieldAccess) {
                FieldAccess fa = (FieldAccess) r;
                if (fa.getReceiver() instanceof ThisReference || fa.getReceiver() instanceof ClassName) {
                    addInitializedField(fa.getField());
                }
            }
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess) ThisReference(org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference)

Example 3 with ThisReference

use of org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference in project checker-framework by typetools.

the class InitializationVisitor method checkContract.

@Override
protected boolean checkContract(Receiver expr, AnnotationMirror necessaryAnnotation, AnnotationMirror inferredAnnotation, CFAbstractStore<?, ?> store) {
    // also use the information about initialized fields to check contracts
    final AnnotationMirror invariantAnno = atypeFactory.getFieldInvariantAnnotation();
    if (atypeFactory.getQualifierHierarchy().isSubtype(invariantAnno, necessaryAnnotation)) {
        if (expr instanceof FieldAccess) {
            FieldAccess fa = (FieldAccess) expr;
            if (fa.getReceiver() instanceof ThisReference || fa.getReceiver() instanceof ClassName) {
                @SuppressWarnings("unchecked") Store s = (Store) store;
                if (s.isFieldInitialized(fa.getField())) {
                    AnnotatedTypeMirror fieldType = atypeFactory.getAnnotatedType(fa.getField());
                    // is this an invariant-field?
                    if (AnnotationUtils.containsSame(fieldType.getAnnotations(), invariantAnno)) {
                        return true;
                    }
                }
            } else {
                Set<AnnotationMirror> recvAnnoSet;
                @SuppressWarnings("unchecked") Value value = (Value) store.getValue(fa.getReceiver());
                if (value != null) {
                    recvAnnoSet = value.getAnnotations();
                } else if (fa.getReceiver() instanceof LocalVariable) {
                    Element elem = ((LocalVariable) fa.getReceiver()).getElement();
                    AnnotatedTypeMirror recvType = atypeFactory.getAnnotatedType(elem);
                    recvAnnoSet = recvType.getAnnotations();
                } else {
                    // Is there anything better we could do?
                    return false;
                }
                boolean isRecvCommitted = false;
                for (AnnotationMirror anno : recvAnnoSet) {
                    if (atypeFactory.isCommitted(anno)) {
                        isRecvCommitted = true;
                    }
                }
                AnnotatedTypeMirror fieldType = atypeFactory.getAnnotatedType(fa.getField());
                // has the invariant type.
                if (isRecvCommitted && AnnotationUtils.containsSame(fieldType.getAnnotations(), invariantAnno)) {
                    return true;
                }
            }
        }
    }
    return super.checkContract(expr, necessaryAnnotation, inferredAnnotation, store);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) VariableElement(javax.lang.model.element.VariableElement) Element(javax.lang.model.element.Element) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) CFAbstractValue(org.checkerframework.framework.flow.CFAbstractValue) LocalVariable(org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable) CFAbstractStore(org.checkerframework.framework.flow.CFAbstractStore) FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess) ThisReference(org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 4 with ThisReference

use of org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference in project checker-framework by typetools.

the class FlowExpressionParseUtil method parseSuper.

private static Receiver parseSuper(String s, Types types, FlowExpressionContext context) throws FlowExpressionParseException {
    // super literal
    List<? extends TypeMirror> superTypes = types.directSupertypes(context.receiver.getType());
    // find class supertype
    TypeMirror superType = null;
    for (TypeMirror t : superTypes) {
        // ignore interface types
        if (!(t instanceof ClassType)) {
            continue;
        }
        ClassType tt = (ClassType) t;
        if (!tt.isInterface()) {
            superType = t;
            break;
        }
    }
    if (superType == null) {
        throw constructParserException(s, "super class not found");
    }
    return new ThisReference(superType);
}
Also used : TypeMirror(javax.lang.model.type.TypeMirror) ClassType(com.sun.tools.javac.code.Type.ClassType) ThisReference(org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference)

Example 5 with ThisReference

use of org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference in project checker-framework by typetools.

the class FlowExpressionParseUtil method parseIdentifier.

private static Receiver parseIdentifier(String s, ProcessingEnvironment env, TreePath path, FlowExpressionContext context) throws FlowExpressionParseException {
    Resolver resolver = new Resolver(env);
    if (!context.parsingMember && context.useLocalScope) {
        // Attempt to match a local variable within the scope of the
        // given path before attempting to match a field.
        VariableElement varElem = resolver.findLocalVariableOrParameterOrField(s, path);
        if (varElem != null) {
            if (varElem.getKind() == ElementKind.FIELD) {
                boolean isOriginalReceiver = context.receiver instanceof ThisReference;
                return getReceiverField(s, context, isOriginalReceiver, varElem);
            } else {
                return new LocalVariable(varElem);
            }
        }
    }
    // field access
    TypeMirror receiverType = context.receiver.getType();
    boolean originalReceiver = true;
    VariableElement fieldElem = null;
    if (receiverType.getKind() == TypeKind.ARRAY && s.equals("length")) {
        fieldElem = resolver.findField(s, receiverType, path);
    }
    // Search for field in each enclosing class.
    while (receiverType.getKind() == TypeKind.DECLARED) {
        fieldElem = resolver.findField(s, receiverType, path);
        if (fieldElem != null) {
            break;
        }
        receiverType = getTypeOfEnclosingClass((DeclaredType) receiverType);
        originalReceiver = false;
    }
    if (fieldElem != null && fieldElem.getKind() == ElementKind.FIELD) {
        return getReceiverField(s, context, originalReceiver, fieldElem);
    }
    // Class name
    Element classElem = resolver.findClass(s, path);
    TypeMirror classType = ElementUtils.getType(classElem);
    if (classType != null) {
        return new ClassName(classType);
    }
    throw constructParserException(s, "identifier not found");
}
Also used : Resolver(org.checkerframework.javacutil.Resolver) TypeMirror(javax.lang.model.type.TypeMirror) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) LocalVariable(org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) VariableElement(javax.lang.model.element.VariableElement) ThisReference(org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference) DeclaredType(javax.lang.model.type.DeclaredType)

Aggregations

ThisReference (org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference)6 ClassName (org.checkerframework.dataflow.analysis.FlowExpressions.ClassName)5 FieldAccess (org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess)4 VariableElement (javax.lang.model.element.VariableElement)3 TypeMirror (javax.lang.model.type.TypeMirror)3 LocalVariable (org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable)3 AnnotationMirror (javax.lang.model.element.AnnotationMirror)2 Element (javax.lang.model.element.Element)2 Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)2 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)2 ClassTree (com.sun.source.tree.ClassTree)1 MethodTree (com.sun.source.tree.MethodTree)1 Tree (com.sun.source.tree.Tree)1 VariableTree (com.sun.source.tree.VariableTree)1 ClassType (com.sun.tools.javac.code.Type.ClassType)1 ExecutableElement (javax.lang.model.element.ExecutableElement)1 TypeElement (javax.lang.model.element.TypeElement)1 DeclaredType (javax.lang.model.type.DeclaredType)1 MethodCall (org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall)1 CFAbstractStore (org.checkerframework.framework.flow.CFAbstractStore)1