Search in sources :

Example 1 with Contract

use of org.checkerframework.framework.util.ContractsUtils.Contract in project checker-framework by typetools.

the class CFAbstractTransfer method processPostconditionsAndConditionalPostconditions.

private void processPostconditionsAndConditionalPostconditions(MethodInvocationNode n, Tree tree, S thenStore, S elseStore, Set<? extends Contract> postconditions) {
    FlowExpressionContext flowExprContext = null;
    for (Contract p : postconditions) {
        String expression = p.expression;
        AnnotationMirror anno = p.annotation;
        if (flowExprContext == null) {
            flowExprContext = FlowExpressionContext.buildContextForMethodUse(n, analysis.checker.getContext());
        }
        TreePath localScope = analysis.atypeFactory.getPath(tree);
        anno = standardizeAnnotationFromContract(anno, flowExprContext, localScope);
        try {
            FlowExpressions.Receiver r = FlowExpressionParseUtil.parse(expression, flowExprContext, localScope, false);
            if (p.kind == Contract.Kind.CONDITIONALPOSTCONDTION) {
                if (((ConditionalPostcondition) p).annoResult) {
                    thenStore.insertValue(r, anno);
                } else {
                    elseStore.insertValue(r, anno);
                }
            } else {
                thenStore.insertValue(r, anno);
            }
        } catch (FlowExpressionParseException e) {
            Result result;
            if (e.isFlowParseError()) {
                Object[] args = new Object[e.args.length + 1];
                args[0] = ElementUtils.getVerboseName(TreeUtils.elementFromUse(n.getTree()));
                System.arraycopy(e.args, 0, args, 1, e.args.length);
                result = Result.failure("flowexpr.parse.error.postcondition", args);
            } else {
                result = e.getResult();
            }
            // report errors here
            analysis.checker.report(result, tree);
        }
    }
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) TreePath(com.sun.source.util.TreePath) 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) ConditionalPostcondition(org.checkerframework.framework.util.ContractsUtils.ConditionalPostcondition) Contract(org.checkerframework.framework.util.ContractsUtils.Contract) TransferResult(org.checkerframework.dataflow.analysis.TransferResult) Result(org.checkerframework.framework.source.Result) RegularTransferResult(org.checkerframework.dataflow.analysis.RegularTransferResult) ConditionalTransferResult(org.checkerframework.dataflow.analysis.ConditionalTransferResult)

Example 2 with Contract

use of org.checkerframework.framework.util.ContractsUtils.Contract 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 3 with Contract

use of org.checkerframework.framework.util.ContractsUtils.Contract 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

AnnotationMirror (javax.lang.model.element.AnnotationMirror)3 FlowExpressions (org.checkerframework.dataflow.analysis.FlowExpressions)3 Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)3 Contract (org.checkerframework.framework.util.ContractsUtils.Contract)3 FlowExpressionContext (org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionContext)3 FlowExpressionParseException (org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionParseException)3 TreePath (com.sun.source.util.TreePath)2 MethodTree (com.sun.source.tree.MethodTree)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1 CompilerMessageKey (org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey)1 ConditionalTransferResult (org.checkerframework.dataflow.analysis.ConditionalTransferResult)1 RegularTransferResult (org.checkerframework.dataflow.analysis.RegularTransferResult)1 TransferResult (org.checkerframework.dataflow.analysis.TransferResult)1 Result (org.checkerframework.framework.source.Result)1 ConditionalPostcondition (org.checkerframework.framework.util.ContractsUtils.ConditionalPostcondition)1 Pair (org.checkerframework.javacutil.Pair)1