Search in sources :

Example 6 with ClassName

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

the class CFAbstractStore method supersetOf.

/**
 * Returns true iff this {@link CFAbstractStore} contains a superset of the map entries of the
 * argument {@link CFAbstractStore}. Note that we test the entry keys and values by Java equality,
 * not by any subtype relationship. This method is used primarily to simplify the equals
 * predicate.
 */
protected boolean supersetOf(CFAbstractStore<V, S> other) {
    for (Map.Entry<LocalVariable, V> e : other.localVariableValues.entrySet()) {
        LocalVariable key = e.getKey();
        V value = localVariableValues.get(key);
        if (value == null || !value.equals(e.getValue())) {
            return false;
        }
    }
    if (!Objects.equals(thisValue, other.thisValue)) {
        return false;
    }
    for (Map.Entry<FieldAccess, V> e : other.fieldValues.entrySet()) {
        FieldAccess key = e.getKey();
        V value = fieldValues.get(key);
        if (value == null || !value.equals(e.getValue())) {
            return false;
        }
    }
    for (Map.Entry<ArrayAccess, V> e : other.arrayValues.entrySet()) {
        ArrayAccess key = e.getKey();
        V value = arrayValues.get(key);
        if (value == null || !value.equals(e.getValue())) {
            return false;
        }
    }
    for (Map.Entry<MethodCall, V> e : other.methodValues.entrySet()) {
        MethodCall key = e.getKey();
        V value = methodValues.get(key);
        if (value == null || !value.equals(e.getValue())) {
            return false;
        }
    }
    for (Map.Entry<ClassName, V> e : other.classValues.entrySet()) {
        ClassName key = e.getKey();
        V value = classValues.get(key);
        if (value == null || !value.equals(e.getValue())) {
            return false;
        }
    }
    return true;
}
Also used : ArrayAccess(org.checkerframework.dataflow.expression.ArrayAccess) LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) ClassName(org.checkerframework.dataflow.expression.ClassName) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) HashMap(java.util.HashMap) Map(java.util.Map) MethodCall(org.checkerframework.dataflow.expression.MethodCall)

Example 7 with ClassName

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

the class CFAbstractStore method upperBound.

private S upperBound(S other, boolean shouldWiden) {
    S newStore = analysis.createEmptyStore(sequentialSemantics);
    for (Map.Entry<LocalVariable, V> e : other.localVariableValues.entrySet()) {
        // local variables that are only part of one store, but not the other are discarded, as one of
        // store implicitly contains 'top' for that variable.
        LocalVariable localVar = e.getKey();
        V thisVal = localVariableValues.get(localVar);
        if (thisVal != null) {
            V otherVal = e.getValue();
            V mergedVal = upperBoundOfValues(otherVal, thisVal, shouldWiden);
            if (mergedVal != null) {
                newStore.localVariableValues.put(localVar, mergedVal);
            }
        }
    }
    // information about the current object
    {
        V otherVal = other.thisValue;
        V myVal = thisValue;
        V mergedVal = myVal == null ? null : upperBoundOfValues(otherVal, myVal, shouldWiden);
        if (mergedVal != null) {
            newStore.thisValue = mergedVal;
        }
    }
    for (Map.Entry<FieldAccess, V> e : other.fieldValues.entrySet()) {
        // information about fields that are only part of one store, but not the other are discarded,
        // as one store implicitly contains 'top' for that field.
        FieldAccess el = e.getKey();
        V thisVal = fieldValues.get(el);
        if (thisVal != null) {
            V otherVal = e.getValue();
            V mergedVal = upperBoundOfValues(otherVal, thisVal, shouldWiden);
            if (mergedVal != null) {
                newStore.fieldValues.put(el, mergedVal);
            }
        }
    }
    for (Map.Entry<ArrayAccess, V> e : other.arrayValues.entrySet()) {
        // information about arrays that are only part of one store, but not the other are discarded,
        // as one store implicitly contains 'top' for that array access.
        ArrayAccess el = e.getKey();
        V thisVal = arrayValues.get(el);
        if (thisVal != null) {
            V otherVal = e.getValue();
            V mergedVal = upperBoundOfValues(otherVal, thisVal, shouldWiden);
            if (mergedVal != null) {
                newStore.arrayValues.put(el, mergedVal);
            }
        }
    }
    for (Map.Entry<MethodCall, V> e : other.methodValues.entrySet()) {
        // information about methods that are only part of one store, but not the other are discarded,
        // as one store implicitly contains 'top' for that field.
        MethodCall el = e.getKey();
        V thisVal = methodValues.get(el);
        if (thisVal != null) {
            V otherVal = e.getValue();
            V mergedVal = upperBoundOfValues(otherVal, thisVal, shouldWiden);
            if (mergedVal != null) {
                newStore.methodValues.put(el, mergedVal);
            }
        }
    }
    for (Map.Entry<ClassName, V> e : other.classValues.entrySet()) {
        ClassName el = e.getKey();
        V thisVal = classValues.get(el);
        if (thisVal != null) {
            V otherVal = e.getValue();
            V mergedVal = upperBoundOfValues(otherVal, thisVal, shouldWiden);
            if (mergedVal != null) {
                newStore.classValues.put(el, mergedVal);
            }
        }
    }
    return newStore;
}
Also used : LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) MethodCall(org.checkerframework.dataflow.expression.MethodCall) ArrayAccess(org.checkerframework.dataflow.expression.ArrayAccess) ClassName(org.checkerframework.dataflow.expression.ClassName) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) HashMap(java.util.HashMap) Map(java.util.Map)

Example 8 with ClassName

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

the class WholeProgramInferenceImplementation method updateContracts.

@Override
public void updateContracts(Analysis.BeforeOrAfter preOrPost, ExecutableElement methodElt, CFAbstractStore<?, ?> store) {
    // Don't infer types for code that isn't presented as source.
    if (!ElementUtils.isElementFromSourceCode(methodElt)) {
        return;
    }
    if (store == null) {
        throw new BugInCF("updateContracts(%s, %s, null) for %s", preOrPost, methodElt, atypeFactory.getClass().getSimpleName());
    }
    if (!storage.hasStorageLocationForMethod(methodElt)) {
        return;
    }
    // TODO: Probably move some part of this into the AnnotatedTypeFactory.
    // This code handles fields of "this" and method parameters (including the receiver parameter
    // "this"), for now.  In the future, extend it to other expressions.
    TypeElement containingClass = (TypeElement) methodElt.getEnclosingElement();
    ThisReference thisReference = new ThisReference(containingClass.asType());
    ClassName classNameReceiver = new ClassName(containingClass.asType());
    // Fields of "this":
    for (VariableElement fieldElement : ElementFilter.fieldsIn(containingClass.getEnclosedElements())) {
        if (atypeFactory.wpiOutputFormat == OutputFormat.JAIF && containingClass.getNestingKind().isNested()) {
            // places the annotations incorrectly on the class declarations.
            continue;
        }
        FieldAccess fa = new FieldAccess((ElementUtils.isStatic(fieldElement) ? classNameReceiver : thisReference), fieldElement.asType(), fieldElement);
        CFAbstractValue<?> v = store.getFieldValue(fa);
        AnnotatedTypeMirror fieldDeclType = atypeFactory.getAnnotatedType(fieldElement);
        AnnotatedTypeMirror inferredType;
        if (v != null) {
            // This field is in the store.
            inferredType = convertCFAbstractValueToAnnotatedTypeMirror(v, fieldDeclType);
            atypeFactory.wpiAdjustForUpdateNonField(inferredType);
        } else {
            // This field is not in the store. Use the declared type.
            inferredType = fieldDeclType;
        }
        T preOrPostConditionAnnos = storage.getPreOrPostconditions(preOrPost, methodElt, fa.toString(), fieldDeclType, atypeFactory);
        if (preOrPostConditionAnnos == null) {
            continue;
        }
        String file = storage.getFileForElement(methodElt);
        updateAnnotationSet(preOrPostConditionAnnos, TypeUseLocation.FIELD, inferredType, fieldDeclType, file, false);
    }
    // This loop is 1-indexed to match the syntax used in annotation arguments.
    for (int index = 1; index <= methodElt.getParameters().size(); index++) {
        VariableElement paramElt = methodElt.getParameters().get(index - 1);
        // spurious flowexpr.parameter.not.final warnings.
        if (!ElementUtils.isEffectivelyFinal(paramElt)) {
            continue;
        }
        LocalVariable param = new LocalVariable(paramElt);
        CFAbstractValue<?> v = store.getValue(param);
        AnnotatedTypeMirror declType = atypeFactory.getAnnotatedType(paramElt);
        AnnotatedTypeMirror inferredType;
        if (v != null) {
            // This parameter is in the store.
            inferredType = convertCFAbstractValueToAnnotatedTypeMirror(v, declType);
            atypeFactory.wpiAdjustForUpdateNonField(inferredType);
        } else {
            // are supported for parameters.)
            continue;
        }
        T preOrPostConditionAnnos = storage.getPreOrPostconditions(preOrPost, methodElt, "#" + index, declType, atypeFactory);
        if (preOrPostConditionAnnos != null) {
            String file = storage.getFileForElement(methodElt);
            updateAnnotationSet(preOrPostConditionAnnos, TypeUseLocation.PARAMETER, inferredType, declType, file, false);
        }
    }
    // Receiver parameter ("this"):
    if (!ElementUtils.isStatic(methodElt)) {
        // Static methods do not have a receiver.
        CFAbstractValue<?> v = store.getValue(thisReference);
        if (v != null) {
            // This parameter is in the store.
            AnnotatedTypeMirror declaredType = atypeFactory.getAnnotatedType(methodElt).getReceiverType();
            if (declaredType == null) {
                // have a receiver).
                return;
            }
            AnnotatedTypeMirror inferredType = AnnotatedTypeMirror.createType(declaredType.getUnderlyingType(), atypeFactory, false);
            inferredType.replaceAnnotations(v.getAnnotations());
            atypeFactory.wpiAdjustForUpdateNonField(inferredType);
            T preOrPostConditionAnnos = storage.getPreOrPostconditions(preOrPost, methodElt, "this", declaredType, atypeFactory);
            if (preOrPostConditionAnnos != null) {
                String file = storage.getFileForElement(methodElt);
                updateAnnotationSet(preOrPostConditionAnnos, TypeUseLocation.PARAMETER, inferredType, declaredType, file, false);
            }
        }
    }
}
Also used : TypeElement(javax.lang.model.element.TypeElement) ClassName(org.checkerframework.dataflow.expression.ClassName) LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) VariableElement(javax.lang.model.element.VariableElement) BugInCF(org.checkerframework.javacutil.BugInCF) ThisReference(org.checkerframework.dataflow.expression.ThisReference) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 9 with ClassName

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

the class CFAbstractStore method clearValue.

/**
 * Remove any knowledge about the expression {@code expr} (correctly deciding where to remove the
 * information depending on the type of the expression {@code expr}).
 */
public void clearValue(JavaExpression expr) {
    if (expr.containsUnknown()) {
        // Expressions containing unknown expressions are not stored.
        return;
    }
    if (expr instanceof LocalVariable) {
        LocalVariable localVar = (LocalVariable) expr;
        localVariableValues.remove(localVar);
    } else if (expr instanceof FieldAccess) {
        FieldAccess fieldAcc = (FieldAccess) expr;
        fieldValues.remove(fieldAcc);
    } else if (expr instanceof MethodCall) {
        MethodCall method = (MethodCall) expr;
        methodValues.remove(method);
    } else if (expr instanceof ArrayAccess) {
        ArrayAccess a = (ArrayAccess) expr;
        arrayValues.remove(a);
    } else if (expr instanceof ClassName) {
        ClassName c = (ClassName) expr;
        classValues.remove(c);
    } else {
    // thisValue ...
    // No other types of expressions are stored.
    }
}
Also used : ArrayAccess(org.checkerframework.dataflow.expression.ArrayAccess) LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) ClassName(org.checkerframework.dataflow.expression.ClassName) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) MethodCall(org.checkerframework.dataflow.expression.MethodCall)

Example 10 with ClassName

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

the class LockTransfer method initialStore.

@Override
public LockStore initialStore(UnderlyingAST underlyingAST, List<LocalVariableNode> parameters) {
    LockStore store = super.initialStore(underlyingAST, parameters);
    Kind astKind = underlyingAST.getKind();
    // Handle synchronized methods and constructors.
    if (astKind == UnderlyingAST.Kind.METHOD) {
        CFGMethod method = (CFGMethod) underlyingAST;
        MethodTree methodTree = method.getMethod();
        ExecutableElement methodElement = TreeUtils.elementFromDeclaration(methodTree);
        if (methodElement.getModifiers().contains(Modifier.SYNCHRONIZED)) {
            final ClassTree classTree = method.getClassTree();
            TypeMirror classType = TreeUtils.typeOf(classTree);
            if (methodElement.getModifiers().contains(Modifier.STATIC)) {
                store.insertValue(new ClassName(classType), atypeFactory.LOCKHELD);
            } else {
                store.insertThisValue(atypeFactory.LOCKHELD, classType);
            }
        } else if (methodElement.getKind() == ElementKind.CONSTRUCTOR) {
            store.setInConstructorOrInitializer();
        }
    } else if (astKind == Kind.ARBITRARY_CODE) {
        // Handle initializers
        store.setInConstructorOrInitializer();
    }
    return store;
}
Also used : CFGMethod(org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod) MethodTree(com.sun.source.tree.MethodTree) TypeMirror(javax.lang.model.type.TypeMirror) ElementKind(javax.lang.model.element.ElementKind) Kind(org.checkerframework.dataflow.cfg.UnderlyingAST.Kind) ExecutableElement(javax.lang.model.element.ExecutableElement) ClassTree(com.sun.source.tree.ClassTree) ClassName(org.checkerframework.dataflow.expression.ClassName)

Aggregations

ClassName (org.checkerframework.dataflow.expression.ClassName)11 FieldAccess (org.checkerframework.dataflow.expression.FieldAccess)9 LocalVariable (org.checkerframework.dataflow.expression.LocalVariable)8 MethodCall (org.checkerframework.dataflow.expression.MethodCall)6 ThisReference (org.checkerframework.dataflow.expression.ThisReference)6 ArrayAccess (org.checkerframework.dataflow.expression.ArrayAccess)5 HashMap (java.util.HashMap)2 Map (java.util.Map)2 AnnotationMirror (javax.lang.model.element.AnnotationMirror)2 ExecutableElement (javax.lang.model.element.ExecutableElement)2 JavaExpression (org.checkerframework.dataflow.expression.JavaExpression)2 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)2 ParseProblemException (com.github.javaparser.ParseProblemException)1 LanguageLevel (com.github.javaparser.ParserConfiguration.LanguageLevel)1 Expression (com.github.javaparser.ast.expr.Expression)1 ClassTree (com.sun.source.tree.ClassTree)1 MethodTree (com.sun.source.tree.MethodTree)1 Element (javax.lang.model.element.Element)1 ElementKind (javax.lang.model.element.ElementKind)1 TypeElement (javax.lang.model.element.TypeElement)1