Search in sources :

Example 1 with Unknown

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

the class LockVisitor method getLockExpressions.

private List<LockExpression> getLockExpressions(boolean implicitThis, AnnotationMirror gbAnno, Tree tree) {
    List<String> expressions = AnnotationUtils.getElementValueArray(gbAnno, atypeFactory.guardedByValueElement, String.class, Collections.emptyList());
    if (expressions.isEmpty()) {
        return Collections.emptyList();
    }
    TreePath currentPath = getCurrentPath();
    TypeMirror enclosingType = TreeUtils.typeOf(TreePathUtil.enclosingClass(currentPath));
    JavaExpression pseudoReceiver = JavaExpression.getPseudoReceiver(currentPath, enclosingType);
    JavaExpression self;
    if (implicitThis) {
        self = pseudoReceiver;
    } else if (TreeUtils.isExpressionTree(tree)) {
        self = JavaExpression.fromTree((ExpressionTree) tree);
    } else {
        self = new Unknown(tree);
    }
    return CollectionsPlume.mapList(expression -> parseExpressionString(expression, currentPath, self), expressions);
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) TreePath(com.sun.source.util.TreePath) Unknown(org.checkerframework.dataflow.expression.Unknown) GuardedByUnknown(org.checkerframework.checker.lock.qual.GuardedByUnknown) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror)

Example 2 with Unknown

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

the class CreatesMustCallForElementSupplier method getCreatesMustCallForExpression.

/**
 * Parses a single CreatesMustCallFor annotation. Clients should use {@link
 * #getCreatesMustCallForExpressions(MethodInvocationNode, GenericAnnotatedTypeFactory,
 * CreatesMustCallForElementSupplier)}, which handles the possibility of multiple such
 * annotations, instead.
 *
 * @param createsMustCallFor a @CreatesMustCallFor annotation
 * @param n the invocation of a reset method
 * @param atypeFactory the type factory
 * @param supplier a type factory that can supply the executable elements for CreatesMustCallFor
 *     and CreatesMustCallFor.List's value elements. Usually, you should just pass atypeFactory
 *     again. The arguments are different so that the given type factory's adherence to both
 *     protocols are checked by the type system.
 * @return the Java expression representing the target, or null if the target is unparseable
 */
@Nullable
static JavaExpression getCreatesMustCallForExpression(AnnotationMirror createsMustCallFor, MethodInvocationNode n, GenericAnnotatedTypeFactory<?, ?, ?, ?> atypeFactory, CreatesMustCallForElementSupplier supplier) {
    // Unfortunately, there is no way to avoid passing the default string "this" here. The default
    // must be hard-coded into the client, such as here. That is the price for the efficiency of not
    // having to query the annotation definition (such queries are expensive).
    String targetStrWithoutAdaptation = AnnotationUtils.getElementValue(createsMustCallFor, supplier.getCreatesMustCallForValueElement(), String.class, "this");
    // TODO: find a way to also check if the target is a known tempvar, and if so return that. That
    // should improve the quality of the error messages we give.
    JavaExpression targetExpr;
    try {
        targetExpr = StringToJavaExpression.atMethodInvocation(targetStrWithoutAdaptation, n, atypeFactory.getChecker());
        if (targetExpr instanceof Unknown) {
            issueUnparseableError(n, atypeFactory, targetStrWithoutAdaptation);
            return null;
        }
    } catch (JavaExpressionParseException e) {
        issueUnparseableError(n, atypeFactory, targetStrWithoutAdaptation);
        return null;
    }
    return targetExpr;
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) Unknown(org.checkerframework.dataflow.expression.Unknown) JavaExpressionParseException(org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException) Nullable(org.checkerframework.checker.nullness.qual.Nullable)

Example 3 with Unknown

use of org.checkerframework.dataflow.expression.Unknown 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)

Example 4 with Unknown

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

the class OffsetEquation method createOffsetFromNode.

/**
 * Updates an offset equation from a Node.
 *
 * @param node the Node from which to create an offset equation
 * @param factory an AnnotationTypeFactory
 * @param eq an OffsetEquation to update
 * @param op '+' or '-'
 */
private static void createOffsetFromNode(Node node, AnnotationProvider factory, OffsetEquation eq, char op) {
    JavaExpression je = JavaExpression.fromNode(node);
    if (je instanceof Unknown || je == null) {
        if (node instanceof NumericalAdditionNode) {
            createOffsetFromNode(((NumericalAdditionNode) node).getLeftOperand(), factory, eq, op);
            createOffsetFromNode(((NumericalAdditionNode) node).getRightOperand(), factory, eq, op);
        } else if (node instanceof NumericalSubtractionNode) {
            createOffsetFromNode(((NumericalSubtractionNode) node).getLeftOperand(), factory, eq, op);
            char other = op == '+' ? '-' : '+';
            createOffsetFromNode(((NumericalSubtractionNode) node).getRightOperand(), factory, eq, other);
        } else {
            eq.error = node.toString();
        }
    } else {
        eq.addTerm(op, je.toString());
    }
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) Unknown(org.checkerframework.dataflow.expression.Unknown) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode)

Example 5 with Unknown

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

the class ValueTransfer method refineAtLengthAccess.

/**
 * Transform @IntVal or @IntRange annotations of a array or string length into an @ArrayLen
 * or @ArrayLenRange annotation for the array or string.
 *
 * @param lengthNode an invocation of method {@code length} or an access of the {@code length}
 *     field
 * @param receiverNode the receiver of {@code lengthNode}
 * @param store the store to update
 */
private void refineAtLengthAccess(Node lengthNode, Node receiverNode, CFStore store) {
    JavaExpression lengthExpr = JavaExpression.fromNode(lengthNode);
    // not marked @Pure, then do not refine.
    if (lengthExpr instanceof Unknown) {
        return;
    }
    CFValue value = store.getValue(lengthExpr);
    if (value == null) {
        return;
    }
    AnnotationMirror lengthAnno = getValueAnnotation(value);
    if (lengthAnno == null) {
        return;
    }
    if (AnnotationUtils.areSameByName(lengthAnno, ValueAnnotatedTypeFactory.BOTTOMVAL_NAME)) {
        // If the length is bottom, then this is dead code, so the receiver type
        // should also be bottom.
        JavaExpression receiver = JavaExpression.fromNode(receiverNode);
        store.insertValue(receiver, lengthAnno);
        return;
    }
    RangeOrListOfValues rolv;
    if (atypeFactory.isIntRange(lengthAnno)) {
        rolv = new RangeOrListOfValues(atypeFactory.getRange(lengthAnno));
    } else if (AnnotationUtils.areSameByName(lengthAnno, ValueAnnotatedTypeFactory.INTVAL_NAME)) {
        List<Long> lengthValues = atypeFactory.getIntValues(lengthAnno);
        rolv = new RangeOrListOfValues(RangeOrListOfValues.convertLongsToInts(lengthValues));
    } else {
        return;
    }
    AnnotationMirror newRecAnno = rolv.createAnnotation(atypeFactory);
    AnnotationMirror oldRecAnno = getArrayOrStringAnnotation(receiverNode);
    AnnotationMirror combinedRecAnno;
    // with the facts known about its length using GLB.
    if (oldRecAnno == null) {
        combinedRecAnno = newRecAnno;
    } else {
        combinedRecAnno = hierarchy.greatestLowerBound(oldRecAnno, newRecAnno);
    }
    JavaExpression receiver = JavaExpression.fromNode(receiverNode);
    store.insertValue(receiver, combinedRecAnno);
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) AnnotationMirror(javax.lang.model.element.AnnotationMirror) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) Unknown(org.checkerframework.dataflow.expression.Unknown) List(java.util.List) ArrayList(java.util.ArrayList)

Aggregations

JavaExpression (org.checkerframework.dataflow.expression.JavaExpression)5 Unknown (org.checkerframework.dataflow.expression.Unknown)5 ArrayList (java.util.ArrayList)2 List (java.util.List)2 GuardedByUnknown (org.checkerframework.checker.lock.qual.GuardedByUnknown)2 StringToJavaExpression (org.checkerframework.framework.util.StringToJavaExpression)2 ExpressionTree (com.sun.source.tree.ExpressionTree)1 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)1 Tree (com.sun.source.tree.Tree)1 VariableTree (com.sun.source.tree.VariableTree)1 TreePath (com.sun.source.util.TreePath)1 AnnotationMirror (javax.lang.model.element.AnnotationMirror)1 TypeMirror (javax.lang.model.type.TypeMirror)1 Nullable (org.checkerframework.checker.nullness.qual.Nullable)1 NumericalAdditionNode (org.checkerframework.dataflow.cfg.node.NumericalAdditionNode)1 NumericalSubtractionNode (org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode)1 CFValue (org.checkerframework.framework.flow.CFValue)1 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)1 JavaExpressionParseException (org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException)1 DependentTypesError (org.checkerframework.framework.util.dependenttypes.DependentTypesError)1