Search in sources :

Example 71 with JavaExpression

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

the class NullnessTransfer method strengthenAnnotationOfEqualTo.

/**
 * {@inheritDoc}
 *
 * <p>Furthermore, this method refines the type to {@code NonNull} for the appropriate branch if
 * an expression is compared to the {@code null} literal (listed as case 1 in the class
 * description).
 */
@Override
protected TransferResult<NullnessValue, NullnessStore> strengthenAnnotationOfEqualTo(TransferResult<NullnessValue, NullnessStore> res, Node firstNode, Node secondNode, NullnessValue firstValue, NullnessValue secondValue, boolean notEqualTo) {
    res = super.strengthenAnnotationOfEqualTo(res, firstNode, secondNode, firstValue, secondValue, notEqualTo);
    if (firstNode instanceof NullLiteralNode) {
        NullnessStore thenStore = res.getThenStore();
        NullnessStore elseStore = res.getElseStore();
        List<Node> secondParts = splitAssignments(secondNode);
        for (Node secondPart : secondParts) {
            JavaExpression secondInternal = JavaExpression.fromNode(secondPart);
            if (CFAbstractStore.canInsertJavaExpression(secondInternal)) {
                thenStore = thenStore == null ? res.getThenStore() : thenStore;
                elseStore = elseStore == null ? res.getElseStore() : elseStore;
                if (notEqualTo) {
                    thenStore.insertValue(secondInternal, NONNULL);
                } else {
                    elseStore.insertValue(secondInternal, NONNULL);
                }
            }
        }
        Set<AnnotationMirror> secondAnnos = secondValue != null ? secondValue.getAnnotations() : AnnotationUtils.createAnnotationSet();
        if (nullnessTypeFactory.containsSameByClass(secondAnnos, PolyNull.class)) {
            thenStore = thenStore == null ? res.getThenStore() : thenStore;
            elseStore = elseStore == null ? res.getElseStore() : elseStore;
            // TODO: methodTree is null for lambdas.  Handle that case.  See Issue3850.java.
            MethodTree methodTree = analysis.getContainingMethod(secondNode.getTree());
            ExecutableElement methodElem = methodTree == null ? null : TreeUtils.elementFromDeclaration(methodTree);
            if (notEqualTo) {
                elseStore.setPolyNullNull(true);
                if (methodElem != null && polyNullIsNonNull(methodElem, thenStore)) {
                    thenStore.setPolyNullNonNull(true);
                }
            } else {
                thenStore.setPolyNullNull(true);
                if (methodElem != null && polyNullIsNonNull(methodElem, elseStore)) {
                    elseStore.setPolyNullNonNull(true);
                }
            }
        }
        if (thenStore != null) {
            return new ConditionalTransferResult<>(res.getResultValue(), thenStore, elseStore);
        }
    }
    return res;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) MethodTree(com.sun.source.tree.MethodTree) ConditionalTransferResult(org.checkerframework.dataflow.analysis.ConditionalTransferResult) InstanceOfNode(org.checkerframework.dataflow.cfg.node.InstanceOfNode) MethodAccessNode(org.checkerframework.dataflow.cfg.node.MethodAccessNode) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) ThrowNode(org.checkerframework.dataflow.cfg.node.ThrowNode) Node(org.checkerframework.dataflow.cfg.node.Node) ExecutableElement(javax.lang.model.element.ExecutableElement) NullLiteralNode(org.checkerframework.dataflow.cfg.node.NullLiteralNode)

Example 72 with JavaExpression

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

the class SameLenTransfer method propagateCombinedSameLen.

/**
 * Insert a @SameLen annotation into the store as the SameLen type of each array listed in it.
 *
 * @param sameLenAnno a {@code @SameLen} annotation. Not just an annotation in the SameLen
 *     hierarchy; this annotation must be {@code @SameLen(...)}.
 * @param node the node in the tree where the combination is happening. Used for context.
 * @param store the store to modify
 */
private void propagateCombinedSameLen(AnnotationMirror sameLenAnno, Node node, CFStore store) {
    TreePath currentPath = aTypeFactory.getPath(node.getTree());
    if (currentPath == null) {
        return;
    }
    for (String exprString : AnnotationUtils.getElementValueArray(sameLenAnno, aTypeFactory.sameLenValueElement, String.class)) {
        JavaExpression je;
        try {
            je = aTypeFactory.parseJavaExpressionString(exprString, currentPath);
        } catch (JavaExpressionParseUtil.JavaExpressionParseException e) {
            continue;
        }
        store.clearValue(je);
        store.insertValue(je, sameLenAnno);
    }
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) TreePath(com.sun.source.util.TreePath) JavaExpressionParseUtil(org.checkerframework.framework.util.JavaExpressionParseUtil)

Example 73 with JavaExpression

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

the class UpperBoundVisitor method checkEffectivelyFinalAndParsable.

/**
 * Reports an error if the Java expression named by s is not effectively final when parsed at the
 * declaration of the given class.
 *
 * @param s a Java expression
 * @param classTree the expression is parsed with respect to this class
 * @param whereToReportError the tree at which to possibly report an error
 */
private void checkEffectivelyFinalAndParsable(String s, ClassTree classTree, Tree whereToReportError) {
    JavaExpression je;
    try {
        je = StringToJavaExpression.atTypeDecl(s, TreeUtils.elementFromDeclaration(classTree), checker);
    } catch (JavaExpressionParseException e) {
        checker.report(whereToReportError, e.getDiagMessage());
        return;
    }
    Element element = null;
    if (je instanceof LocalVariable) {
        element = ((LocalVariable) je).getElement();
    } else if (je instanceof FieldAccess) {
        element = ((FieldAccess) je).getField();
    } else if (je instanceof ThisReference || je instanceof ValueLiteral) {
        return;
    }
    if (element == null || !ElementUtils.isEffectivelyFinal(element)) {
        checker.reportError(whereToReportError, NOT_FINAL, je);
    }
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) Element(javax.lang.model.element.Element) JavaExpressionParseException(org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException) LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) ValueLiteral(org.checkerframework.dataflow.expression.ValueLiteral) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) ThisReference(org.checkerframework.dataflow.expression.ThisReference)

Example 74 with JavaExpression

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

the class LockAnnotatedTypeFactory method isExpressionEffectivelyFinal.

/**
 * Returns whether or not the expression is effectively final.
 *
 * <p>This method returns true in the following cases when expr is:
 *
 * <p>1. a field access and the field is final and the field access expression is effectively
 * final as specified by this method.
 *
 * <p>2. an effectively final local variable.
 *
 * <p>3. a deterministic method call whose arguments and receiver expression are effectively final
 * as specified by this method.
 *
 * <p>4. a this reference or a class literal
 *
 * @param expr expression
 * @return whether or not the expression is effectively final
 */
boolean isExpressionEffectivelyFinal(JavaExpression expr) {
    if (expr instanceof FieldAccess) {
        FieldAccess fieldAccess = (FieldAccess) expr;
        JavaExpression receiver = fieldAccess.getReceiver();
        // Don't call fieldAccess
        return fieldAccess.isFinal() && isExpressionEffectivelyFinal(receiver);
    } else if (expr instanceof LocalVariable) {
        return ElementUtils.isEffectivelyFinal(((LocalVariable) expr).getElement());
    } else if (expr instanceof MethodCall) {
        MethodCall methodCall = (MethodCall) expr;
        for (JavaExpression arg : methodCall.getArguments()) {
            if (!isExpressionEffectivelyFinal(arg)) {
                return false;
            }
        }
        return PurityUtils.isDeterministic(this, methodCall.getElement()) && isExpressionEffectivelyFinal(methodCall.getReceiver());
    } else if (expr instanceof ThisReference || expr instanceof ClassName) {
        // too.
        return true;
    } else {
        // type of 'expr' is not supported in @GuardedBy(...) lock expressions
        return false;
    }
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) ClassName(org.checkerframework.dataflow.expression.ClassName) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) ThisReference(org.checkerframework.dataflow.expression.ThisReference) MethodCall(org.checkerframework.dataflow.expression.MethodCall)

Example 75 with JavaExpression

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

the class LockAnnotatedTypeFactory method createDependentTypesHelper.

@Override
protected DependentTypesHelper createDependentTypesHelper() {
    return new DependentTypesHelper(this) {

        @Override
        protected void reportErrors(Tree errorTree, List<DependentTypesError> errors) {
            // If the error message is NOT_EFFECTIVELY_FINAL, then report
            // lock.expression.not.final instead of expression.unparsable .
            List<DependentTypesError> superErrors = new ArrayList<>(errors.size());
            for (DependentTypesError error : errors) {
                if (error.error.equals(NOT_EFFECTIVELY_FINAL)) {
                    checker.reportError(errorTree, "lock.expression.not.final", error.expression);
                } else {
                    superErrors.add(error);
                }
            }
            super.reportErrors(errorTree, superErrors);
        }

        @Override
        protected boolean shouldPassThroughExpression(String expression) {
            // There is no expression to use to replace <self> here, so just pass the expression along.
            return super.shouldPassThroughExpression(expression) || LockVisitor.SELF_RECEIVER_PATTERN.matcher(expression).matches();
        }

        @Override
        @Nullable
        protected JavaExpression transform(JavaExpression javaExpr) {
            if (javaExpr instanceof Unknown || isExpressionEffectivelyFinal(javaExpr)) {
                return javaExpr;
            }
            // string.
            return createError(javaExpr.toString(), NOT_EFFECTIVELY_FINAL);
        }
    };
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) Unknown(org.checkerframework.dataflow.expression.Unknown) GuardedByUnknown(org.checkerframework.checker.lock.qual.GuardedByUnknown) DependentTypesError(org.checkerframework.framework.util.dependenttypes.DependentTypesError) DependentTypesHelper(org.checkerframework.framework.util.dependenttypes.DependentTypesHelper) ArrayList(java.util.ArrayList) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) VariableTree(com.sun.source.tree.VariableTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) List(java.util.List) ArrayList(java.util.ArrayList)

Aggregations

JavaExpression (org.checkerframework.dataflow.expression.JavaExpression)87 AnnotationMirror (javax.lang.model.element.AnnotationMirror)39 Node (org.checkerframework.dataflow.cfg.node.Node)23 StringToJavaExpression (org.checkerframework.framework.util.StringToJavaExpression)21 CFValue (org.checkerframework.framework.flow.CFValue)20 ExecutableElement (javax.lang.model.element.ExecutableElement)19 MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)19 ArrayList (java.util.ArrayList)15 CFStore (org.checkerframework.framework.flow.CFStore)15 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)13 JavaExpressionParseException (org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException)13 Tree (com.sun.source.tree.Tree)12 List (java.util.List)11 FieldAccess (org.checkerframework.dataflow.expression.FieldAccess)11 MethodTree (com.sun.source.tree.MethodTree)10 TreePath (com.sun.source.util.TreePath)10 HashMap (java.util.HashMap)10 Map (java.util.Map)9 Element (javax.lang.model.element.Element)9 VariableElement (javax.lang.model.element.VariableElement)9