Search in sources :

Example 1 with FieldAccessNode

use of org.checkerframework.dataflow.cfg.node.FieldAccessNode in project bazel by bazelbuild.

the class FlowExpressions method internalReprOf.

/**
     * We ignore operations such as widening and
     * narrowing when computing the internal representation.
     *
     * @return The internal representation (as {@link Receiver}) of any
     *         {@link Node}. Might contain {@link Unknown}.
     */
public static Receiver internalReprOf(AnnotationProvider provider, Node receiverNode, boolean allowNonDeterminitic) {
    Receiver receiver = null;
    if (receiverNode instanceof FieldAccessNode) {
        FieldAccessNode fan = (FieldAccessNode) receiverNode;
        if (fan.getFieldName().equals("this")) {
            // For some reason, "className.this" is considered a field access.
            // We right this wrong here.
            receiver = new ThisReference(fan.getReceiver().getType());
        } else {
            receiver = internalReprOfFieldAccess(provider, fan);
        }
    } else if (receiverNode instanceof ExplicitThisLiteralNode) {
        receiver = new ThisReference(receiverNode.getType());
    } else if (receiverNode instanceof ThisLiteralNode) {
        receiver = new ThisReference(receiverNode.getType());
    } else if (receiverNode instanceof SuperNode) {
        receiver = new ThisReference(receiverNode.getType());
    } else if (receiverNode instanceof LocalVariableNode) {
        LocalVariableNode lv = (LocalVariableNode) receiverNode;
        receiver = new LocalVariable(lv);
    } else if (receiverNode instanceof ArrayAccessNode) {
        ArrayAccessNode a = (ArrayAccessNode) receiverNode;
        receiver = internalReprOfArrayAccess(provider, a);
    } else if (receiverNode instanceof StringConversionNode) {
        // ignore string conversion
        return internalReprOf(provider, ((StringConversionNode) receiverNode).getOperand());
    } else if (receiverNode instanceof WideningConversionNode) {
        // ignore widening
        return internalReprOf(provider, ((WideningConversionNode) receiverNode).getOperand());
    } else if (receiverNode instanceof NarrowingConversionNode) {
        // ignore narrowing
        return internalReprOf(provider, ((NarrowingConversionNode) receiverNode).getOperand());
    } else if (receiverNode instanceof ClassNameNode) {
        ClassNameNode cn = (ClassNameNode) receiverNode;
        receiver = new ClassName(cn.getType());
    } else if (receiverNode instanceof ValueLiteralNode) {
        ValueLiteralNode vn = (ValueLiteralNode) receiverNode;
        receiver = new ValueLiteral(vn.getType(), vn);
    } else if (receiverNode instanceof MethodInvocationNode) {
        MethodInvocationNode mn = (MethodInvocationNode) receiverNode;
        ExecutableElement invokedMethod = TreeUtils.elementFromUse(mn.getTree());
        // check if this represents a boxing operation of a constant, in which
        // case we treat the method call as deterministic, because there is no way
        // to behave differently in two executions where two constants are being used.
        boolean considerDeterministic = false;
        if (invokedMethod.toString().equals("valueOf(long)") && mn.getTarget().getReceiver().toString().equals("Long")) {
            Node arg = mn.getArgument(0);
            if (arg instanceof ValueLiteralNode) {
                considerDeterministic = true;
            }
        }
        if (PurityUtils.isDeterministic(provider, invokedMethod) || allowNonDeterminitic || considerDeterministic) {
            List<Receiver> parameters = new ArrayList<>();
            for (Node p : mn.getArguments()) {
                parameters.add(internalReprOf(provider, p));
            }
            Receiver methodReceiver;
            if (ElementUtils.isStatic(invokedMethod)) {
                methodReceiver = new ClassName(mn.getTarget().getReceiver().getType());
            } else {
                methodReceiver = internalReprOf(provider, mn.getTarget().getReceiver());
            }
            receiver = new PureMethodCall(mn.getType(), invokedMethod, methodReceiver, parameters);
        }
    }
    if (receiver == null) {
        receiver = new Unknown(receiverNode.getType());
    }
    return receiver;
}
Also used : MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) SuperNode(org.checkerframework.dataflow.cfg.node.SuperNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) ExecutableElement(javax.lang.model.element.ExecutableElement) ThisLiteralNode(org.checkerframework.dataflow.cfg.node.ThisLiteralNode) ValueLiteralNode(org.checkerframework.dataflow.cfg.node.ValueLiteralNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) WideningConversionNode(org.checkerframework.dataflow.cfg.node.WideningConversionNode) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) SuperNode(org.checkerframework.dataflow.cfg.node.SuperNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) NarrowingConversionNode(org.checkerframework.dataflow.cfg.node.NarrowingConversionNode) ExplicitThisLiteralNode(org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode) Node(org.checkerframework.dataflow.cfg.node.Node) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) ExplicitThisLiteralNode(org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) ValueLiteralNode(org.checkerframework.dataflow.cfg.node.ValueLiteralNode) WideningConversionNode(org.checkerframework.dataflow.cfg.node.WideningConversionNode) NarrowingConversionNode(org.checkerframework.dataflow.cfg.node.NarrowingConversionNode) ThisLiteralNode(org.checkerframework.dataflow.cfg.node.ThisLiteralNode) ExplicitThisLiteralNode(org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode) ArrayList(java.util.ArrayList) List(java.util.List)

Example 2 with FieldAccessNode

use of org.checkerframework.dataflow.cfg.node.FieldAccessNode in project bazel by bazelbuild.

the class FlowExpressions method internalReprOfFieldAccess.

/**
     * @return The internal representation (as {@link FieldAccess}) of a
     *         {@link FieldAccessNode}. Can contain {@link Unknown} as receiver.
     */
public static FieldAccess internalReprOfFieldAccess(AnnotationProvider provider, FieldAccessNode node) {
    Receiver receiver;
    Node receiverNode = node.getReceiver();
    if (node.isStatic()) {
        receiver = new ClassName(receiverNode.getType());
    } else {
        receiver = internalReprOf(provider, receiverNode);
    }
    return new FieldAccess(receiver, node);
}
Also used : ThisLiteralNode(org.checkerframework.dataflow.cfg.node.ThisLiteralNode) ValueLiteralNode(org.checkerframework.dataflow.cfg.node.ValueLiteralNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) WideningConversionNode(org.checkerframework.dataflow.cfg.node.WideningConversionNode) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) SuperNode(org.checkerframework.dataflow.cfg.node.SuperNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) NarrowingConversionNode(org.checkerframework.dataflow.cfg.node.NarrowingConversionNode) ExplicitThisLiteralNode(org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode) Node(org.checkerframework.dataflow.cfg.node.Node)

Example 3 with FieldAccessNode

use of org.checkerframework.dataflow.cfg.node.FieldAccessNode in project error-prone by google.

the class NullnessPropagationTransfer method visitAssignment.

@Override
Nullness visitAssignment(AssignmentNode node, SubNodeValues inputs, LocalVariableUpdates updates) {
    Nullness value = inputs.valueOfSubNode(node.getExpression());
    Node target = node.getTarget();
    if (target instanceof LocalVariableNode) {
        updates.set((LocalVariableNode) target, value);
    }
    if (target instanceof ArrayAccessNode) {
        setNonnullIfLocalVariable(updates, ((ArrayAccessNode) target).getArray());
    }
    if (target instanceof FieldAccessNode) {
        FieldAccessNode fieldAccess = (FieldAccessNode) target;
        ClassAndField targetField = tryGetFieldSymbol(target.getTree());
        setReceiverNonnull(updates, fieldAccess.getReceiver(), targetField);
    }
    /*
     * We propagate the value of the target to the value of the assignment expressions as a whole.
     * We do this regardless of whether the target is a local variable. For example:
     *
     * String s = object.field = "foo"; // Now |s| is non-null.
     *
     * It's not clear to me that this is technically correct, but it works in practice with the
     * bytecode generated by both javac and ecj.
     *
     * http://stackoverflow.com/q/12850676/28465
     */
    return value;
}
Also used : TypeCastNode(org.checkerframework.dataflow.cfg.node.TypeCastNode) ArrayCreationNode(org.checkerframework.dataflow.cfg.node.ArrayCreationNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) EqualToNode(org.checkerframework.dataflow.cfg.node.EqualToNode) VariableDeclarationNode(org.checkerframework.dataflow.cfg.node.VariableDeclarationNode) InstanceOfNode(org.checkerframework.dataflow.cfg.node.InstanceOfNode) AssignmentNode(org.checkerframework.dataflow.cfg.node.AssignmentNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) NotEqualNode(org.checkerframework.dataflow.cfg.node.NotEqualNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) FunctionalInterfaceNode(org.checkerframework.dataflow.cfg.node.FunctionalInterfaceNode) Node(org.checkerframework.dataflow.cfg.node.Node) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode)

Aggregations

ArrayAccessNode (org.checkerframework.dataflow.cfg.node.ArrayAccessNode)3 FieldAccessNode (org.checkerframework.dataflow.cfg.node.FieldAccessNode)3 LocalVariableNode (org.checkerframework.dataflow.cfg.node.LocalVariableNode)3 MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)3 Node (org.checkerframework.dataflow.cfg.node.Node)3 ClassNameNode (org.checkerframework.dataflow.cfg.node.ClassNameNode)2 ExplicitThisLiteralNode (org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode)2 NarrowingConversionNode (org.checkerframework.dataflow.cfg.node.NarrowingConversionNode)2 StringConversionNode (org.checkerframework.dataflow.cfg.node.StringConversionNode)2 SuperNode (org.checkerframework.dataflow.cfg.node.SuperNode)2 ThisLiteralNode (org.checkerframework.dataflow.cfg.node.ThisLiteralNode)2 ValueLiteralNode (org.checkerframework.dataflow.cfg.node.ValueLiteralNode)2 WideningConversionNode (org.checkerframework.dataflow.cfg.node.WideningConversionNode)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 ExecutableElement (javax.lang.model.element.ExecutableElement)1 ArrayCreationNode (org.checkerframework.dataflow.cfg.node.ArrayCreationNode)1 AssignmentNode (org.checkerframework.dataflow.cfg.node.AssignmentNode)1 EqualToNode (org.checkerframework.dataflow.cfg.node.EqualToNode)1 FunctionalInterfaceNode (org.checkerframework.dataflow.cfg.node.FunctionalInterfaceNode)1