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);
}
}
}
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;
}
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);
}
}
Aggregations