Search in sources :

Example 16 with JavaExpression

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);
}
Also used : FormalParameter(org.checkerframework.dataflow.expression.FormalParameter) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) ViewpointAdaptJavaExpression(org.checkerframework.dataflow.expression.ViewpointAdaptJavaExpression) TypeMirror(javax.lang.model.type.TypeMirror) ArrayList(java.util.ArrayList) VariableTree(com.sun.source.tree.VariableTree) LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) VariableElement(javax.lang.model.element.VariableElement) ThisReference(org.checkerframework.dataflow.expression.ThisReference)

Example 17 with JavaExpression

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);
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) ViewpointAdaptJavaExpression(org.checkerframework.dataflow.expression.ViewpointAdaptJavaExpression) ExecutableElement(javax.lang.model.element.ExecutableElement)

Example 18 with JavaExpression

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);
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) ArrayAccess(org.checkerframework.dataflow.expression.ArrayAccess) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) ArrayLen(org.checkerframework.common.value.qual.ArrayLen) JavaExpressionParseException(org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException) ArrayCreation(org.checkerframework.dataflow.expression.ArrayCreation) ArrayLenRange(org.checkerframework.common.value.qual.ArrayLenRange) ValueLiteral(org.checkerframework.dataflow.expression.ValueLiteral) StringVal(org.checkerframework.common.value.qual.StringVal)

Example 19 with JavaExpression

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);
        }
    }
}
Also used : CFValue(org.checkerframework.framework.flow.CFValue) AnnotationMirror(javax.lang.model.element.AnnotationMirror) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) NumericalMultiplicationNode(org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode) MethodAccessNode(org.checkerframework.dataflow.cfg.node.MethodAccessNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) UnsignedRightShiftNode(org.checkerframework.dataflow.cfg.node.UnsignedRightShiftNode) LeftShiftNode(org.checkerframework.dataflow.cfg.node.LeftShiftNode) FloatingRemainderNode(org.checkerframework.dataflow.cfg.node.FloatingRemainderNode) LessThanNode(org.checkerframework.dataflow.cfg.node.LessThanNode) BitwiseOrNode(org.checkerframework.dataflow.cfg.node.BitwiseOrNode) SignedRightShiftNode(org.checkerframework.dataflow.cfg.node.SignedRightShiftNode) EqualToNode(org.checkerframework.dataflow.cfg.node.EqualToNode) NumericalPlusNode(org.checkerframework.dataflow.cfg.node.NumericalPlusNode) ConditionalAndNode(org.checkerframework.dataflow.cfg.node.ConditionalAndNode) GreaterThanOrEqualNode(org.checkerframework.dataflow.cfg.node.GreaterThanOrEqualNode) StringLiteralNode(org.checkerframework.dataflow.cfg.node.StringLiteralNode) BitwiseAndNode(org.checkerframework.dataflow.cfg.node.BitwiseAndNode) IntegerDivisionNode(org.checkerframework.dataflow.cfg.node.IntegerDivisionNode) IntegerRemainderNode(org.checkerframework.dataflow.cfg.node.IntegerRemainderNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) ConditionalOrNode(org.checkerframework.dataflow.cfg.node.ConditionalOrNode) NumericalAdditionNode(org.checkerframework.dataflow.cfg.node.NumericalAdditionNode) NotEqualNode(org.checkerframework.dataflow.cfg.node.NotEqualNode) NumericalSubtractionNode(org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode) BitwiseXorNode(org.checkerframework.dataflow.cfg.node.BitwiseXorNode) BitwiseComplementNode(org.checkerframework.dataflow.cfg.node.BitwiseComplementNode) ConditionalNotNode(org.checkerframework.dataflow.cfg.node.ConditionalNotNode) NumericalMinusNode(org.checkerframework.dataflow.cfg.node.NumericalMinusNode) StringConcatenateNode(org.checkerframework.dataflow.cfg.node.StringConcatenateNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) FloatingDivisionNode(org.checkerframework.dataflow.cfg.node.FloatingDivisionNode) GreaterThanNode(org.checkerframework.dataflow.cfg.node.GreaterThanNode) LessThanOrEqualNode(org.checkerframework.dataflow.cfg.node.LessThanOrEqualNode) StringConcatenateAssignmentNode(org.checkerframework.dataflow.cfg.node.StringConcatenateAssignmentNode) Node(org.checkerframework.dataflow.cfg.node.Node) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode)

Example 20 with JavaExpression

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);
}
Also used : JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) ValueLiteral(org.checkerframework.dataflow.expression.ValueLiteral) MethodCall(org.checkerframework.dataflow.expression.MethodCall)

Aggregations

JavaExpression (org.checkerframework.dataflow.expression.JavaExpression)87 AnnotationMirror (javax.lang.model.element.AnnotationMirror)39 Node (org.checkerframework.dataflow.cfg.node.Node)23 StringToJavaExpression (org.checkerframework.framework.util.StringToJavaExpression)21 CFValue (org.checkerframework.framework.flow.CFValue)20 ExecutableElement (javax.lang.model.element.ExecutableElement)19 MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)19 ArrayList (java.util.ArrayList)15 CFStore (org.checkerframework.framework.flow.CFStore)15 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)13 JavaExpressionParseException (org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException)13 Tree (com.sun.source.tree.Tree)12 List (java.util.List)11 FieldAccess (org.checkerframework.dataflow.expression.FieldAccess)11 MethodTree (com.sun.source.tree.MethodTree)10 TreePath (com.sun.source.util.TreePath)10 HashMap (java.util.HashMap)10 Map (java.util.Map)9 Element (javax.lang.model.element.Element)9 VariableElement (javax.lang.model.element.VariableElement)9