Search in sources :

Example 1 with LocalVariable

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

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

the class CFAbstractTransfer method addFinalLocalValues.

private void addFinalLocalValues(S info, Element enclosingElement) {
    // add information about effectively final variables (from outer scopes)
    for (Entry<Element, V> e : analysis.atypeFactory.getFinalLocalValues().entrySet()) {
        Element elem = e.getKey();
        // TODO: There is a design flaw where the values of final local values leaks
        // into other methods of the same class. For example, in
        // class a { void b() {...} void c() {...} }
        // final local values from b() would be visible in the store for c(),
        // even though they should only be visible in b() and in classes
        // defined inside the method body of b().
        // This is partly because GenericAnnotatedTypeFactory.performFlowAnalysis
        // does not call itself recursively to analyze inner classes, but instead
        // pops classes off of a queue, and the information about known final local
        // values is stored by GenericAnnotatedTypeFactory.analyze in
        // GenericAnnotatedTypeFactory.flowResult, which is visible to all classes
        // in the queue regardless of their level of recursion.
        // We work around this here by ensuring that we only add a final
        // local value to a method's store if that method is enclosed by
        // the method where the local variables were declared.
        // Find the enclosing method of the element
        Element enclosingMethodOfVariableDeclaration = elem.getEnclosingElement();
        if (enclosingMethodOfVariableDeclaration != null) {
            // Now find all the enclosing methods of the code we are analyzing. If any one of
            // them matches the above, then the final local variable value applies.
            Element enclosingMethodOfCurrentMethod = enclosingElement;
            while (enclosingMethodOfCurrentMethod != null) {
                if (enclosingMethodOfVariableDeclaration.equals(enclosingMethodOfCurrentMethod)) {
                    LocalVariable l = new LocalVariable(elem);
                    info.insertValue(l, e.getValue());
                    break;
                }
                enclosingMethodOfCurrentMethod = enclosingMethodOfCurrentMethod.getEnclosingElement();
            }
        }
    }
}
Also used : 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)

Example 3 with LocalVariable

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

the class GenericAnnotatedTypeFactory method getAnnotationFromReceiver.

/**
 * Returns the primary annotation on a receiver.
 *
 * @param receiver the receiver for which the annotation is returned
 * @param tree current tree
 * @param clazz the Class of the annotation
 * @return the annotation on expression or null if one does not exist
 * @throws FlowExpressionParseException thrown if the expression cannot be parsed
 */
public AnnotationMirror getAnnotationFromReceiver(FlowExpressions.Receiver receiver, Tree tree, Class<? extends Annotation> clazz) throws FlowExpressionParseException {
    AnnotationMirror annotationMirror = null;
    if (CFAbstractStore.canInsertReceiver(receiver)) {
        Store store = getStoreBefore(tree);
        if (store != null) {
            Value value = store.getValue(receiver);
            if (value != null) {
                annotationMirror = AnnotationUtils.getAnnotationByClass(value.getAnnotations(), clazz);
            }
        }
    }
    if (annotationMirror == null) {
        if (receiver instanceof LocalVariable) {
            Element ele = ((LocalVariable) receiver).getElement();
            annotationMirror = getAnnotatedType(ele).getAnnotation(clazz);
        } else if (receiver instanceof FieldAccess) {
            Element ele = ((FieldAccess) receiver).getField();
            annotationMirror = getAnnotatedType(ele).getAnnotation(clazz);
        }
    }
    return annotationMirror;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) CFAbstractValue(org.checkerframework.framework.flow.CFAbstractValue) CFValue(org.checkerframework.framework.flow.CFValue) LocalVariable(org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable) CFStore(org.checkerframework.framework.flow.CFStore) CFAbstractStore(org.checkerframework.framework.flow.CFAbstractStore) FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess)

Example 4 with LocalVariable

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

Example 5 with LocalVariable

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

the class FlowExpressionParseUtil method internalReprOfVariable.

public static Receiver internalReprOfVariable(AnnotatedTypeFactory provider, VariableTree tree) throws FlowExpressionParseException {
    Element elt = TreeUtils.elementFromDeclaration(tree);
    if (elt.getKind() == ElementKind.LOCAL_VARIABLE || elt.getKind() == ElementKind.RESOURCE_VARIABLE || elt.getKind() == ElementKind.EXCEPTION_PARAMETER || elt.getKind() == ElementKind.PARAMETER) {
        return new LocalVariable(elt);
    }
    Receiver receiverF = FlowExpressions.internalReprOfImplicitReceiver(elt);
    FlowExpressionParseUtil.FlowExpressionContext context = new FlowExpressionParseUtil.FlowExpressionContext(receiverF, null, provider.getContext());
    return FlowExpressionParseUtil.parse(tree.getName().toString(), context, provider.getPath(tree), false);
}
Also used : 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) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Aggregations

LocalVariable (org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable)7 Element (javax.lang.model.element.Element)5 VariableElement (javax.lang.model.element.VariableElement)5 ExecutableElement (javax.lang.model.element.ExecutableElement)4 FieldAccess (org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess)4 TypeElement (javax.lang.model.element.TypeElement)3 ClassName (org.checkerframework.dataflow.analysis.FlowExpressions.ClassName)3 ThisReference (org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference)3 AnnotationMirror (javax.lang.model.element.AnnotationMirror)2 Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)2 CFAbstractStore (org.checkerframework.framework.flow.CFAbstractStore)2 CFAbstractValue (org.checkerframework.framework.flow.CFAbstractValue)2 CFValue (org.checkerframework.framework.flow.CFValue)2 ArrayList (java.util.ArrayList)1 DeclaredType (javax.lang.model.type.DeclaredType)1 TypeMirror (javax.lang.model.type.TypeMirror)1 MethodCall (org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall)1 CFStore (org.checkerframework.framework.flow.CFStore)1 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)1 Resolver (org.checkerframework.javacutil.Resolver)1