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