Search in sources :

Example 1 with ClassName

use of org.checkerframework.dataflow.analysis.FlowExpressions.ClassName 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 ClassName

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

the class FlowExpressionParseUtil method getReceiverField.

private static Receiver getReceiverField(String s, FlowExpressionContext context, boolean originalReceiver, VariableElement fieldElem) throws FlowExpressionParseException {
    TypeMirror receiverType = context.receiver.getType();
    TypeMirror fieldType = ElementUtils.getType(fieldElem);
    if (ElementUtils.isStatic(fieldElem)) {
        Element classElem = fieldElem.getEnclosingElement();
        Receiver staticClassReceiver = new ClassName(ElementUtils.getType(classElem));
        return new FieldAccess(staticClassReceiver, fieldType, fieldElem);
    }
    Receiver locationOfField;
    if (originalReceiver) {
        locationOfField = context.receiver;
    } else {
        locationOfField = FlowExpressions.internalReprOf(context.checkerContext.getAnnotationProvider(), new ImplicitThisLiteralNode(receiverType));
    }
    if (locationOfField instanceof ClassName) {
        throw constructParserException(s, "a non-static field cannot have a class name as a receiver.");
    }
    return new FieldAccess(locationOfField, fieldType, fieldElem);
}
Also used : ImplicitThisLiteralNode(org.checkerframework.dataflow.cfg.node.ImplicitThisLiteralNode) 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) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess)

Example 3 with ClassName

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

the class FlowExpressionParseUtil method parse.

/**
 * Parse a string and return its representation as a {@link Receiver}, or throw an {@link
 * FlowExpressionParseException}.
 *
 * @param expression flow expression to parse
 * @param context information about any receiver and arguments
 * @param localScope path to local scope to use
 * @param useLocalScope whether {@code localScope} should be used to resolve identifiers
 */
public static FlowExpressions.Receiver parse(String expression, FlowExpressionContext context, TreePath localScope, boolean useLocalScope) throws FlowExpressionParseException {
    context.useLocalScope = useLocalScope;
    FlowExpressions.Receiver result = parseHelper(expression, context, localScope);
    if (result instanceof ClassName && !expression.endsWith("class")) {
        throw constructParserException(expression, "a class name cannot terminate a flow expression string");
    }
    return result;
}
Also used : ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) FlowExpressions(org.checkerframework.dataflow.analysis.FlowExpressions) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Example 4 with ClassName

use of org.checkerframework.dataflow.analysis.FlowExpressions.ClassName 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 5 with ClassName

use of org.checkerframework.dataflow.analysis.FlowExpressions.ClassName 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)

Aggregations

ClassName (org.checkerframework.dataflow.analysis.FlowExpressions.ClassName)11 FieldAccess (org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess)6 Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)6 VariableElement (javax.lang.model.element.VariableElement)5 TypeMirror (javax.lang.model.type.TypeMirror)5 ThisReference (org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference)5 Element (javax.lang.model.element.Element)4 LocalVariable (org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable)4 ExecutableElement (javax.lang.model.element.ExecutableElement)3 TypeElement (javax.lang.model.element.TypeElement)3 FlowExpressions (org.checkerframework.dataflow.analysis.FlowExpressions)3 MethodCall (org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall)3 Resolver (org.checkerframework.javacutil.Resolver)3 AnnotationMirror (javax.lang.model.element.AnnotationMirror)2 DeclaredType (javax.lang.model.type.DeclaredType)2 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)2 Pair (org.checkerframework.javacutil.Pair)2 ClassTree (com.sun.source.tree.ClassTree)1 MethodTree (com.sun.source.tree.MethodTree)1 Tree (com.sun.source.tree.Tree)1