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