Search in sources :

Example 36 with JavaExpression

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

the class UpperBoundVisitor method getExpressionAndOffsetFromJavaExpressionString.

/**
 * Fetches a receiver and an offset from a String using the passed type factory. Returns null if
 * there is a parse exception. This wraps GenericAnnotatedTypeFactory#parseJavaExpressionString.
 *
 * <p>This is useful for expressions like "n+1", for which {@link #parseJavaExpressionString}
 * returns null because the whole expression is not a receiver.
 */
static Pair<JavaExpression, String> getExpressionAndOffsetFromJavaExpressionString(String s, UpperBoundAnnotatedTypeFactory atypeFactory, TreePath currentPath) {
    Pair<String, String> p = AnnotatedTypeFactory.getExpressionAndOffset(s);
    JavaExpression je = parseJavaExpressionString(p.first, atypeFactory, currentPath);
    if (je == null) {
        return null;
    }
    return Pair.of(je, p.second);
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression)

Example 37 with JavaExpression

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

the class InitializationTransfer method visitAssignment.

@Override
public TransferResult<V, S> visitAssignment(AssignmentNode n, TransferInput<V, S> in) {
    TransferResult<V, S> result = super.visitAssignment(n, in);
    assert result instanceof RegularTransferResult;
    JavaExpression lhs = JavaExpression.fromNode(n.getTarget());
    // If this is an assignment to a field of 'this', then mark the field as initialized.
    if (!lhs.containsUnknown()) {
        if (lhs instanceof FieldAccess) {
            FieldAccess fa = (FieldAccess) lhs;
            result.getRegularStore().addInitializedField(fa);
        }
    }
    return result;
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) RegularTransferResult(org.checkerframework.dataflow.analysis.RegularTransferResult)

Example 38 with JavaExpression

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

the class CreatesMustCallForElementSupplier method getCreatesMustCallForExpressions.

/**
 * Returns the elements of the @CreatesMustCallFor annotation on the invoked method, as
 * JavaExpressions. Returns the empty set if the given method has no @CreatesMustCallFor
 * annotation.
 *
 * <p>If any expression is unparseable, this method reports an error and returns the empty set.
 *
 * @param n a method invocation
 * @param atypeFactory the type factory to report errors and parse the expression string
 * @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 arguments of the method's @CreatesMustCallFor annotation, or an empty list
 */
static List<JavaExpression> getCreatesMustCallForExpressions(MethodInvocationNode n, GenericAnnotatedTypeFactory<?, ?, ?, ?> atypeFactory, CreatesMustCallForElementSupplier supplier) {
    AnnotationMirror createsMustCallForList = atypeFactory.getDeclAnnotation(n.getTarget().getMethod(), CreatesMustCallFor.List.class);
    List<JavaExpression> results = new ArrayList<>(1);
    if (createsMustCallForList != null) {
        // Handle a set of CreatesMustCallFor annotations.
        List<AnnotationMirror> createsMustCallForAnnos = AnnotationUtils.getElementValueArray(createsMustCallForList, supplier.getCreatesMustCallForListValueElement(), AnnotationMirror.class);
        for (AnnotationMirror createsMustCallFor : createsMustCallForAnnos) {
            JavaExpression expr = getCreatesMustCallForExpression(createsMustCallFor, n, atypeFactory, supplier);
            if (expr != null && !results.contains(expr)) {
                results.add(expr);
            }
        }
    }
    AnnotationMirror createsMustCallFor = atypeFactory.getDeclAnnotation(n.getTarget().getMethod(), CreatesMustCallFor.class);
    if (createsMustCallFor != null) {
        JavaExpression expr = getCreatesMustCallForExpression(createsMustCallFor, n, atypeFactory, supplier);
        if (expr != null && !results.contains(expr)) {
            results.add(expr);
        }
    }
    return results;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) CreatesMustCallFor(org.checkerframework.checker.mustcall.qual.CreatesMustCallFor) ArrayList(java.util.ArrayList)

Example 39 with JavaExpression

use of org.checkerframework.dataflow.expression.JavaExpression 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 40 with JavaExpression

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

the class LessThanAnnotatedTypeFactory method getMinValueFromString.

/**
 * Returns the minimum value of {@code expression} at {@code tree}.
 *
 * @param expression the expression whose minimum value to retrieve
 * @param tree where to determine the value
 * @param path the path to {@code tree}
 * @return the minimum value of {@code expression} at {@code tree}
 */
private long getMinValueFromString(String expression, Tree tree, TreePath path) {
    ValueAnnotatedTypeFactory valueAtypeFactory = getValueAnnotatedTypeFactory();
    JavaExpression expressionJe;
    try {
        expressionJe = valueAtypeFactory.parseJavaExpressionString(expression, path);
    } catch (JavaExpressionParseException e) {
        return Long.MIN_VALUE;
    }
    AnnotationMirror intRange = valueAtypeFactory.getAnnotationFromJavaExpression(expressionJe, tree, IntRange.class);
    if (intRange != null) {
        return valueAtypeFactory.getRange(intRange).from;
    }
    AnnotationMirror intValue = valueAtypeFactory.getAnnotationFromJavaExpression(expressionJe, tree, IntVal.class);
    if (intValue != null) {
        List<Long> possibleValues = valueAtypeFactory.getIntValues(intValue);
        return Collections.min(possibleValues);
    }
    if (expressionJe instanceof FieldAccess) {
        FieldAccess fieldAccess = ((FieldAccess) expressionJe);
        if (fieldAccess.getReceiver().getType().getKind() == TypeKind.ARRAY) {
            // array.length might not be in the store, so check for the length of the array.
            AnnotationMirror arrayRange = valueAtypeFactory.getAnnotationFromJavaExpression(fieldAccess.getReceiver(), tree, ArrayLenRange.class);
            if (arrayRange != null) {
                return valueAtypeFactory.getRange(arrayRange).from;
            }
            AnnotationMirror arrayLen = valueAtypeFactory.getAnnotationFromJavaExpression(expressionJe, tree, ArrayLen.class);
            if (arrayLen != null) {
                List<Integer> possibleValues = valueAtypeFactory.getArrayLength(arrayLen);
                return Collections.min(possibleValues);
            }
            // Even arrays that we know nothing about must have at least zero length.
            return 0;
        }
    }
    return Long.MIN_VALUE;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) JavaExpressionParseException(org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException) FieldAccess(org.checkerframework.dataflow.expression.FieldAccess) ValueAnnotatedTypeFactory(org.checkerframework.common.value.ValueAnnotatedTypeFactory)

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