Search in sources :

Example 6 with FlowExpressionParseException

use of org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException in project checker-framework by typetools.

the class LockVisitor method parseExpressionString.

private LockExpression parseExpressionString(String expression, FlowExpressionContext flowExprContext, TreePath path, Receiver itself) {
    LockExpression lockExpression = new LockExpression(expression);
    if (DependentTypesError.isExpressionError(expression)) {
        lockExpression.error = new DependentTypesError(expression);
        return lockExpression;
    }
    Matcher selfReceiverMatcher = selfReceiverPattern.matcher(expression);
    try {
        if (selfReceiverMatcher.matches()) {
            String remainingExpression = selfReceiverMatcher.group(2);
            if (remainingExpression == null || remainingExpression.isEmpty()) {
                lockExpression.lockExpression = itself;
                if (!atypeFactory.isExpressionEffectivelyFinal(lockExpression.lockExpression)) {
                    checker.report(Result.failure("lock.expression.not.final", lockExpression.lockExpression), path.getLeaf());
                }
                return lockExpression;
            } else {
                // TODO: The proper way to do this is to call
                // flowExprContext.copyChangeToParsingMemberOfReceiver to set the receiver to
                // the <self> expression, and then call FlowExpressionParseUtil.parse on the
                // remaining expression string with the new flow expression context. However,
                // this currently results in a FlowExpressions.Receiver that has a different
                // hash code than if the following flow expression is parsed directly, which
                // results in our inability to check that a lock expression is held as it does
                // not match anything in the store due to the hash code mismatch.  For now,
                // convert the "<self>" portion to the node's string representation, and parse
                // the entire string:
                lockExpression.lockExpression = FlowExpressionParseUtil.parse(itself.toString() + "." + remainingExpression, flowExprContext, path, true);
                if (!atypeFactory.isExpressionEffectivelyFinal(lockExpression.lockExpression)) {
                    checker.report(Result.failure("lock.expression.not.final", lockExpression.lockExpression), path.getLeaf());
                }
                return lockExpression;
            }
        } else {
            lockExpression.lockExpression = FlowExpressionParseUtil.parse(expression, flowExprContext, path, true);
            return lockExpression;
        }
    } catch (FlowExpressionParseException ex) {
        lockExpression.error = new DependentTypesError(expression, ex);
        return lockExpression;
    }
}
Also used : Matcher(java.util.regex.Matcher) DependentTypesError(org.checkerframework.framework.util.dependenttypes.DependentTypesError) FlowExpressionParseException(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException)

Example 7 with FlowExpressionParseException

use of org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException in project checker-framework by typetools.

the class SameLenAnnotatedTypeFactory method getAnnotatedTypeLhs.

/**
 * Handles case 2.
 */
@Override
public AnnotatedTypeMirror getAnnotatedTypeLhs(Tree tree) {
    AnnotatedTypeMirror atm = super.getAnnotatedTypeLhs(tree);
    if (tree.getKind() == Tree.Kind.VARIABLE) {
        Receiver r;
        try {
            r = FlowExpressionParseUtil.internalReprOfVariable(this, (VariableTree) tree);
        } catch (FlowExpressionParseException ex) {
            r = null;
        }
        if (r != null) {
            String varName = r.toString();
            AnnotationMirror anm = atm.getAnnotation(SameLen.class);
            if (anm != null) {
                List<String> slArrays = IndexUtil.getValueOfAnnotationWithStringArgument(anm);
                if (slArrays.contains(varName)) {
                    slArrays.remove(varName);
                }
                if (slArrays.size() == 0) {
                    atm.replaceAnnotation(UNKNOWN);
                } else {
                    atm.replaceAnnotation(createSameLen(slArrays.toArray(new String[0])));
                }
            }
        }
    }
    return atm;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) VariableTree(com.sun.source.tree.VariableTree) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) FlowExpressionParseException(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 8 with FlowExpressionParseException

use of org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException in project checker-framework by typetools.

the class BaseTypeVisitor method resolveContracts.

/**
 * Takes a set of contracts identified by their expression and annotation strings and resolves
 * them to the correct {@link Receiver} and {@link AnnotationMirror}.
 */
private Set<Pair<Receiver, AnnotationMirror>> resolveContracts(Set<? extends Contract> contractSet, AnnotatedExecutableType method) {
    Set<Pair<Receiver, AnnotationMirror>> result = new HashSet<>();
    MethodTree methodTree = visitorState.getMethodTree();
    TreePath path = atypeFactory.getPath(methodTree);
    FlowExpressionContext flowExprContext = null;
    for (Contract p : contractSet) {
        String expression = p.expression;
        AnnotationMirror annotation = p.annotation;
        if (flowExprContext == null) {
            flowExprContext = FlowExpressionContext.buildContextForMethodDeclaration(methodTree, method.getReceiverType().getUnderlyingType(), checker.getContext());
        }
        annotation = standardizeAnnotationFromContract(annotation, flowExprContext, path);
        try {
            // TODO: currently, these expressions are parsed many times.
            // this could
            // be optimized to store the result the first time.
            // (same for other annotations)
            FlowExpressions.Receiver expr = FlowExpressionParseUtil.parse(expression, flowExprContext, path, false);
            result.add(Pair.of(expr, annotation));
        } catch (FlowExpressionParseException e) {
            // report errors here
            checker.report(e.getResult(), methodTree);
        }
    }
    return result;
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) FlowExpressionContext(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionContext) FlowExpressions(org.checkerframework.dataflow.analysis.FlowExpressions) FlowExpressionParseException(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) Contract(org.checkerframework.framework.util.ContractsUtils.Contract) Pair(org.checkerframework.javacutil.Pair) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet)

Example 9 with FlowExpressionParseException

use of org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException in project checker-framework by typetools.

the class BaseTypeVisitor method checkPreconditions.

/**
 * Checks that all the given {@code preconditions} hold true immediately prior to the method
 * invocation or variable access at {@code tree}.
 *
 * @param tree the Tree immediately prior to which the preconditions must hold true
 * @param preconditions the preconditions to be checked
 */
protected void checkPreconditions(MethodInvocationTree tree, Set<Precondition> preconditions) {
    // TODO: Remove this check and investigate the root cause.
    if (preconditions.isEmpty()) {
        return;
    }
    FlowExpressionContext flowExprContext = FlowExpressionContext.buildContextForMethodUse(tree, checker.getContext());
    if (flowExprContext == null) {
        checker.report(Result.failure("flowexpr.parse.context.not.determined", tree), tree);
        return;
    }
    for (Precondition p : preconditions) {
        String expression = p.expression;
        AnnotationMirror anno = p.annotation;
        anno = standardizeAnnotationFromContract(anno, flowExprContext, getCurrentPath());
        try {
            FlowExpressions.Receiver expr = FlowExpressionParseUtil.parse(expression, flowExprContext, getCurrentPath(), false);
            CFAbstractStore<?, ?> store = atypeFactory.getStoreBefore(tree);
            CFAbstractValue<?> value = store.getValue(expr);
            AnnotationMirror inferredAnno = null;
            if (value != null) {
                QualifierHierarchy hierarchy = atypeFactory.getQualifierHierarchy();
                Set<AnnotationMirror> annos = value.getAnnotations();
                inferredAnno = hierarchy.findAnnotationInSameHierarchy(annos, anno);
            }
            if (!checkContract(expr, anno, inferredAnno, store)) {
                checker.report(Result.failure("contracts.precondition.not.satisfied", tree.toString(), expr == null ? expression : expr.toString()), tree);
            }
        } catch (FlowExpressionParseException e) {
            // report errors here
            checker.report(e.getResult(), tree);
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) FlowExpressionContext(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionContext) Precondition(org.checkerframework.framework.util.ContractsUtils.Precondition) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) FlowExpressions(org.checkerframework.dataflow.analysis.FlowExpressions) FlowExpressionParseException(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Example 10 with FlowExpressionParseException

use of org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException in project checker-framework by typetools.

the class BaseTypeVisitor method checkContractsAtMethodDeclaration.

private void checkContractsAtMethodDeclaration(MethodTree node, ExecutableElement methodElement, List<String> formalParamNames, boolean abstractMethod) {
    FlowExpressionContext flowExprContext = null;
    List<Contract> contracts = contractsUtils.getContracts(methodElement);
    for (Contract contract : contracts) {
        String expression = contract.expression;
        AnnotationMirror annotation = contract.annotation;
        if (flowExprContext == null) {
            flowExprContext = FlowExpressionContext.buildContextForMethodDeclaration(node, getCurrentPath(), checker.getContext());
        }
        annotation = standardizeAnnotationFromContract(annotation, flowExprContext, getCurrentPath());
        FlowExpressions.Receiver expr = null;
        try {
            expr = FlowExpressionParseUtil.parse(expression, flowExprContext, getCurrentPath(), false);
        } catch (FlowExpressionParseException e) {
            checker.report(e.getResult(), node);
        }
        if (expr != null && !abstractMethod) {
            switch(contract.kind) {
                case POSTCONDTION:
                    checkPostcondition(node, annotation, expr);
                    break;
                case CONDITIONALPOSTCONDTION:
                    checkConditionalPostcondition(node, annotation, expr, ((ConditionalPostcondition) contract).annoResult);
                    break;
                case PRECONDITION:
                    // Preconditions are checked at method invocations, not declarations
                    break;
            }
        }
        if (formalParamNames != null && formalParamNames.contains(expression)) {
            @SuppressWarnings("CompilerMessages") @CompilerMessageKey String key = "contracts." + contract.kind.errorKey + ".expression.parameter.name";
            checker.report(Result.warning(key, node.getName().toString(), expression, formalParamNames.indexOf(expression) + 1, expression), node);
        }
        checkParametersAreEffectivelyFinal(node, methodElement, expression);
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) CompilerMessageKey(org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey) FlowExpressionContext(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionContext) FlowExpressions(org.checkerframework.dataflow.analysis.FlowExpressions) FlowExpressionParseException(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) Contract(org.checkerframework.framework.util.ContractsUtils.Contract)

Aggregations

FlowExpressionParseException (org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException)10 AnnotationMirror (javax.lang.model.element.AnnotationMirror)8 FlowExpressions (org.checkerframework.dataflow.analysis.FlowExpressions)7 Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)6 FlowExpressionContext (org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionContext)5 TreePath (com.sun.source.util.TreePath)3 Contract (org.checkerframework.framework.util.ContractsUtils.Contract)3 Precondition (org.checkerframework.framework.util.ContractsUtils.Precondition)2 MethodTree (com.sun.source.tree.MethodTree)1 VariableTree (com.sun.source.tree.VariableTree)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 Matcher (java.util.regex.Matcher)1 CompilerMessageKey (org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey)1 ArrayLen (org.checkerframework.common.value.qual.ArrayLen)1 ArrayLenRange (org.checkerframework.common.value.qual.ArrayLenRange)1 IntRange (org.checkerframework.common.value.qual.IntRange)1 IntVal (org.checkerframework.common.value.qual.IntVal)1 StringVal (org.checkerframework.common.value.qual.StringVal)1 ConditionalTransferResult (org.checkerframework.dataflow.analysis.ConditionalTransferResult)1