Search in sources :

Example 1 with MethodCall

use of org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall in project checker-framework by typetools.

the class CFAbstractStore method clearValue.

/**
 * Remove any knowledge about the expression {@code r} (correctly deciding where to remove the
 * information depending on the type of the expression {@code r}).
 */
public void clearValue(FlowExpressions.Receiver r) {
    if (r.containsUnknown()) {
        // Expressions containing unknown expressions are not stored.
        return;
    }
    if (r instanceof FlowExpressions.LocalVariable) {
        FlowExpressions.LocalVariable localVar = (FlowExpressions.LocalVariable) r;
        localVariableValues.remove(localVar);
    } else if (r instanceof FlowExpressions.FieldAccess) {
        FlowExpressions.FieldAccess fieldAcc = (FlowExpressions.FieldAccess) r;
        fieldValues.remove(fieldAcc);
    } else if (r instanceof FlowExpressions.MethodCall) {
        MethodCall method = (MethodCall) r;
        methodValues.remove(method);
    } else if (r instanceof FlowExpressions.ArrayAccess) {
        ArrayAccess a = (ArrayAccess) r;
        arrayValues.remove(a);
    } else if (r instanceof FlowExpressions.ClassName) {
        FlowExpressions.ClassName c = (FlowExpressions.ClassName) r;
        classValues.remove(c);
    } else {
    // thisValue ...
    // No other types of expressions are stored.
    }
}
Also used : FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) ArrayAccess(org.checkerframework.dataflow.analysis.FlowExpressions.ArrayAccess) ArrayAccess(org.checkerframework.dataflow.analysis.FlowExpressions.ArrayAccess) LocalVariable(org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable) LocalVariable(org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) FlowExpressions(org.checkerframework.dataflow.analysis.FlowExpressions) FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess) MethodCall(org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall)

Example 2 with MethodCall

use of org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall in project checker-framework by typetools.

the class FlowExpressionParseUtil method parseMethod.

private static Receiver parseMethod(String s, FlowExpressionContext context, TreePath path, ProcessingEnvironment env) throws FlowExpressionParseException {
    Pair<Pair<String, String>, String> method = parseMethod(s);
    if (method == null) {
        return null;
    }
    String methodName = method.first.first;
    // parse parameter list
    String parameterList = method.first.second;
    List<Receiver> parameters = ParameterListParser.parseParameterList(parameterList, true, context.copyAndUseOuterReceiver(), path);
    // get types for parameters
    List<TypeMirror> parameterTypes = new ArrayList<>();
    for (Receiver p : parameters) {
        parameterTypes.add(p.getType());
    }
    ExecutableElement methodElement = null;
    try {
        Element element = null;
        // try to find the correct method
        Resolver resolver = new Resolver(env);
        TypeMirror receiverType = context.receiver.getType();
        if (receiverType.getKind() == TypeKind.ARRAY) {
            element = resolver.findMethod(methodName, receiverType, path, parameterTypes);
        }
        // Search for method in each enclosing class.
        while (receiverType.getKind() == TypeKind.DECLARED) {
            element = resolver.findMethod(methodName, receiverType, path, parameterTypes);
            if (element.getKind() == ElementKind.METHOD) {
                break;
            }
            receiverType = getTypeOfEnclosingClass((DeclaredType) receiverType);
        }
        if (element == null) {
            throw constructParserException(s, "element==null");
        }
        if (element.getKind() != ElementKind.METHOD) {
            throw constructParserException(s, "element.getKind()==" + element.getKind());
        }
        methodElement = (ExecutableElement) element;
        for (int i = 0; i < parameters.size(); i++) {
            VariableElement formal = methodElement.getParameters().get(i);
            TypeMirror formalType = formal.asType();
            Receiver actual = parameters.get(i);
            TypeMirror actualType = actual.getType();
            // boxing necessary
            if (TypesUtils.isBoxedPrimitive(formalType) && TypesUtils.isPrimitive(actualType)) {
                MethodSymbol valueOfMethod = TreeBuilder.getValueOfMethod(env, formalType);
                List<Receiver> p = new ArrayList<>();
                p.add(actual);
                Receiver boxedParam = new MethodCall(formalType, valueOfMethod, new ClassName(formalType), p);
                parameters.set(i, boxedParam);
            }
        }
    } catch (Throwable t) {
        throw constructParserException(s, t);
    }
    assert methodElement != null;
    /*if (!PurityUtils.isDeterministic(context.checkerContext.getAnnotationProvider(),
                methodElement)) {
            throw new FlowExpressionParseException(Result.failure(
                    "flowexpr.method.not.deterministic",
                    methodElement.getSimpleName()));
        }*/
    if (ElementUtils.isStatic(methodElement)) {
        Element classElem = methodElement.getEnclosingElement();
        Receiver staticClassReceiver = new ClassName(ElementUtils.getType(classElem));
        return new MethodCall(ElementUtils.getType(methodElement), methodElement, staticClassReceiver, parameters);
    } else {
        if (context.receiver instanceof ClassName) {
            throw constructParserException(s, "a non-static method call cannot have a class name as a receiver.");
        }
        TypeMirror methodType = TypesUtils.substituteMethodReturnType(methodElement, context.receiver.getType(), env);
        return new MethodCall(methodType, methodElement, context.receiver, parameters);
    }
}
Also used : Resolver(org.checkerframework.javacutil.Resolver) ExecutableElement(javax.lang.model.element.ExecutableElement) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) VariableElement(javax.lang.model.element.VariableElement) MethodCall(org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) TypeMirror(javax.lang.model.type.TypeMirror) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) Pair(org.checkerframework.javacutil.Pair) DeclaredType(javax.lang.model.type.DeclaredType)

Example 3 with MethodCall

use of org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall in project checker-framework by typetools.

the class LockAnnotatedTypeFactory method isExpressionEffectivelyFinal.

/**
 * Returns whether or not the expression is effectively final.
 *
 * <p>This method returns true in the following cases when expr is:
 *
 * <p>1. a field access and the field is final and the field access expression is effectively
 * final as specified by this method.
 *
 * <p>2. an effectively final local variable.
 *
 * <p>3. a deterministic method call whose arguments and receiver expression are effectively
 * final as specified by this method.
 *
 * <p>4. a this reference or a class literal
 *
 * @param expr expression
 * @return whether or not the expression is effectively final
 */
boolean isExpressionEffectivelyFinal(Receiver expr) {
    if (expr instanceof FieldAccess) {
        FieldAccess fieldAccess = (FieldAccess) expr;
        Receiver recv = fieldAccess.getReceiver();
        // Don't call fieldAccess
        return fieldAccess.isFinal() && isExpressionEffectivelyFinal(recv);
    } else if (expr instanceof LocalVariable) {
        return ElementUtils.isEffectivelyFinal(((LocalVariable) expr).getElement());
    } else if (expr instanceof MethodCall) {
        MethodCall methodCall = (MethodCall) expr;
        for (Receiver param : methodCall.getParameters()) {
            if (!isExpressionEffectivelyFinal(param)) {
                return false;
            }
        }
        return PurityUtils.isDeterministic(this, methodCall.getElement()) && isExpressionEffectivelyFinal(methodCall.getReceiver());
    } else if (expr instanceof ThisReference || expr instanceof ClassName) {
        // final too.
        return true;
    } else {
        // type of 'expr' is not supported in @GuardedBy(...) lock expressions
        return false;
    }
}
Also used : LocalVariable(org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable) ClassName(org.checkerframework.dataflow.analysis.FlowExpressions.ClassName) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) FieldAccess(org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess) ThisReference(org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference) MethodCall(org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall)

Aggregations

ClassName (org.checkerframework.dataflow.analysis.FlowExpressions.ClassName)3 MethodCall (org.checkerframework.dataflow.analysis.FlowExpressions.MethodCall)3 FieldAccess (org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess)2 LocalVariable (org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable)2 Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)2 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)1 ArrayList (java.util.ArrayList)1 Element (javax.lang.model.element.Element)1 ExecutableElement (javax.lang.model.element.ExecutableElement)1 TypeElement (javax.lang.model.element.TypeElement)1 VariableElement (javax.lang.model.element.VariableElement)1 DeclaredType (javax.lang.model.type.DeclaredType)1 TypeMirror (javax.lang.model.type.TypeMirror)1 FlowExpressions (org.checkerframework.dataflow.analysis.FlowExpressions)1 ArrayAccess (org.checkerframework.dataflow.analysis.FlowExpressions.ArrayAccess)1 ThisReference (org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference)1 Pair (org.checkerframework.javacutil.Pair)1 Resolver (org.checkerframework.javacutil.Resolver)1