use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class StringToJavaExpression method atLambdaParameter.
/**
* Parses a string as if it were written at one of the parameters of {@code lambdaTree}.
* Parameters of the lambda are expressed as {@link LocalVariable}s.
*
* @param expression a Java expression to parse
* @param lambdaTree the lambda tree
* @param parentPath path to the parent of {@code lambdaTree}; required because the expression can
* reference final local variables of the enclosing method
* @param checker checker used to get the {@link
* javax.annotation.processing.ProcessingEnvironment} and current {@link
* com.sun.source.tree.CompilationUnitTree}
* @return a {@code JavaExpression} for {@code expression}
* @throws JavaExpressionParseException if {@code expression} cannot be parsed
*/
static JavaExpression atLambdaParameter(String expression, LambdaExpressionTree lambdaTree, TreePath parentPath, SourceChecker checker) throws JavaExpressionParseException {
TypeMirror enclosingType = TreeUtils.typeOf(TreePathUtil.enclosingClass(parentPath));
JavaExpression receiver = JavaExpression.getPseudoReceiver(parentPath, enclosingType);
// If receiver isn't a ThisReference, then the lambda is in a static context and "this"
// cannot be referenced in the expression.
ThisReference thisReference = receiver instanceof ThisReference ? (ThisReference) receiver : null;
List<JavaExpression> paramsAsLocals = new ArrayList<>(lambdaTree.getParameters().size());
List<FormalParameter> parameters = new ArrayList<>(lambdaTree.getParameters().size());
int oneBasedIndex = 1;
for (VariableTree arg : lambdaTree.getParameters()) {
LocalVariable param = (LocalVariable) JavaExpression.fromVariableTree(arg);
paramsAsLocals.add(param);
parameters.add(new FormalParameter(oneBasedIndex, (VariableElement) param.getElement()));
oneBasedIndex++;
}
JavaExpression javaExpr = JavaExpressionParseUtil.parse(expression, enclosingType, thisReference, parameters, parentPath, checker.getPathToCompilationUnit(), checker.getProcessingEnvironment());
return ViewpointAdaptJavaExpression.viewpointAdapt(javaExpr, paramsAsLocals);
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class StringToJavaExpression method atMethodBody.
/**
* Parses a string to a {@link JavaExpression} as if it were written at {@code methodTree}. The
* returned {@code JavaExpression} uses {@link LocalVariable}s to represent parameters. Use {@link
* #atMethodDecl(String, ExecutableElement, SourceChecker)} if parameters should be {@link
* FormalParameter}s instead.
*
* @param expression a Java expression to parse
* @param methodTree method declaration tree at which {@code expression} is parsed
* @param checker checker used to get the {@link
* javax.annotation.processing.ProcessingEnvironment} and current {@link
* com.sun.source.tree.CompilationUnitTree}
* @return a {@code JavaExpression} for {@code expression}
* @throws JavaExpressionParseException if {@code expression} cannot be parsed
*/
static JavaExpression atMethodBody(String expression, MethodTree methodTree, SourceChecker checker) throws JavaExpressionParseException {
ExecutableElement ee = TreeUtils.elementFromDeclaration(methodTree);
JavaExpression javaExpr = StringToJavaExpression.atMethodDecl(expression, ee, checker);
return javaExpr.atMethodBody(methodTree);
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class ValueAnnotatedTypeFactory method getMinLenFromString.
/**
* Returns the minimum length of an array expression or 0 if the min length is unknown.
*
* @param sequenceExpression Java expression
* @param tree expression tree or variable declaration
* @param currentPath path to local scope
* @return min length of sequenceExpression or 0
*/
public int getMinLenFromString(String sequenceExpression, Tree tree, TreePath currentPath) {
AnnotationMirror lengthAnno;
JavaExpression expressionObj;
try {
expressionObj = parseJavaExpressionString(sequenceExpression, currentPath);
} catch (JavaExpressionParseException e) {
// ignore parse errors and return 0.
return 0;
}
if (expressionObj instanceof ValueLiteral) {
ValueLiteral sequenceLiteral = (ValueLiteral) expressionObj;
Object sequenceLiteralValue = sequenceLiteral.getValue();
if (sequenceLiteralValue instanceof String) {
return ((String) sequenceLiteralValue).length();
}
} else if (expressionObj instanceof ArrayCreation) {
ArrayCreation arrayCreation = (ArrayCreation) expressionObj;
// This is only expected to support array creations in varargs methods
return arrayCreation.getInitializers().size();
} else if (expressionObj instanceof ArrayAccess) {
List<? extends AnnotationMirror> annoList = expressionObj.getType().getAnnotationMirrors();
for (AnnotationMirror anno : annoList) {
String ANNO_NAME = AnnotationUtils.annotationName(anno);
if (ANNO_NAME.equals(MINLEN_NAME)) {
return getMinLenValue(canonicalAnnotation(anno));
} else if (ANNO_NAME.equals(ARRAYLEN_NAME) || ANNO_NAME.equals(ARRAYLENRANGE_NAME)) {
return getMinLenValue(anno);
}
}
}
lengthAnno = getAnnotationFromJavaExpression(expressionObj, tree, ArrayLenRange.class);
if (lengthAnno == null) {
lengthAnno = getAnnotationFromJavaExpression(expressionObj, tree, ArrayLen.class);
}
if (lengthAnno == null) {
lengthAnno = getAnnotationFromJavaExpression(expressionObj, tree, StringVal.class);
}
if (lengthAnno == null) {
// Could not find a more precise type, so return 0;
return 0;
}
return getMinLenValue(lengthAnno);
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class ValueTransfer method addAnnotationToStore.
private void addAnnotationToStore(CFStore store, AnnotationMirror anno, Node node) {
// If node is assignment, iterate over lhs and rhs; otherwise, iterator contains just node.
for (Node internal : splitAssignments(node)) {
JavaExpression je = JavaExpression.fromNode(internal);
CFValue currentValueFromStore;
if (CFAbstractStore.canInsertJavaExpression(je)) {
currentValueFromStore = store.getValue(je);
} else {
// Don't just `continue;` which would skip the calls to refine{Array,String}...
currentValueFromStore = null;
}
AnnotationMirror currentAnno = (currentValueFromStore == null ? atypeFactory.UNKNOWNVAL : getValueAnnotation(currentValueFromStore));
// Combine the new annotations based on the results of the comparison with the existing type.
AnnotationMirror newAnno = hierarchy.greatestLowerBound(anno, currentAnno);
store.insertValue(je, newAnno);
if (node instanceof FieldAccessNode) {
refineArrayAtLengthAccess((FieldAccessNode) internal, store);
} else if (node instanceof MethodInvocationNode) {
MethodInvocationNode miNode = (MethodInvocationNode) node;
refineAtLengthInvocation(miNode, store);
}
}
}
use of org.checkerframework.dataflow.expression.JavaExpression in project checker-framework by typetools.
the class JavaExpressionOptimizer method visitMethodCall.
@Override
protected JavaExpression visitMethodCall(MethodCall methodCallExpr, Void unused) {
JavaExpression optReceiver = convert(methodCallExpr.getReceiver());
List<JavaExpression> optArguments = convert(methodCallExpr.getArguments());
// Length of string literal: convert it to an integer literal.
if (methodCallExpr.getElement().getSimpleName().contentEquals("length") && optReceiver instanceof ValueLiteral) {
Object value = ((ValueLiteral) optReceiver).getValue();
if (value instanceof String) {
return new ValueLiteral(factory.types.getPrimitiveType(TypeKind.INT), ((String) value).length());
}
}
return new MethodCall(methodCallExpr.getType(), methodCallExpr.getElement(), optReceiver, optArguments);
}
Aggregations