Search in sources :

Example 1 with ExplicitThisLiteralNode

use of org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode 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 ExplicitThisLiteralNode

use of org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode in project checker-framework by typetools.

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 allowNonDeterministic) {
    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 if (fan.getFieldName().equals("class")) {
            // "className.class" is considered a field access. This makes sense,
            // since .class is similar to a field access which is the equivalent
            // of a call to getClass(). However for the purposes of dataflow
            // analysis, and value stores, this is the equivalent of a ClassNameNode.
            receiver = new ClassName(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 ArrayCreationNode) {
        ArrayCreationNode an = (ArrayCreationNode) receiverNode;
        List<Receiver> dimensions = new ArrayList<>();
        for (Node dimension : an.getDimensions()) {
            dimensions.add(internalReprOf(provider, dimension, allowNonDeterministic));
        }
        List<Receiver> initializers = new ArrayList<>();
        for (Node initializer : an.getInitializers()) {
            initializers.add(internalReprOf(provider, initializer, allowNonDeterministic));
        }
        receiver = new ArrayCreation(an.getType(), dimensions, initializers);
    } 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 (isLongValueOf(mn, invokedMethod)) {
            Node arg = mn.getArgument(0);
            if (arg instanceof ValueLiteralNode) {
                considerDeterministic = true;
            }
        }
        if (PurityUtils.isDeterministic(provider, invokedMethod) || allowNonDeterministic || 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 MethodCall(mn.getType(), invokedMethod, methodReceiver, parameters);
        }
    }
    if (receiver == null) {
        receiver = new Unknown(receiverNode.getType());
    }
    return receiver;
}
Also used : ArrayCreationNode(org.checkerframework.dataflow.cfg.node.ArrayCreationNode) 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) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) ClassNameNode(org.checkerframework.dataflow.cfg.node.ClassNameNode) StringConversionNode(org.checkerframework.dataflow.cfg.node.StringConversionNode) ArrayCreationNode(org.checkerframework.dataflow.cfg.node.ArrayCreationNode) 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) MethodInvocationNode(org.checkerframework.dataflow.cfg.node.MethodInvocationNode) SuperNode(org.checkerframework.dataflow.cfg.node.SuperNode) ArrayAccessNode(org.checkerframework.dataflow.cfg.node.ArrayAccessNode) ExplicitThisLiteralNode(org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode) FieldAccessNode(org.checkerframework.dataflow.cfg.node.FieldAccessNode) LocalVariableNode(org.checkerframework.dataflow.cfg.node.LocalVariableNode) ValueLiteralNode(org.checkerframework.dataflow.cfg.node.ValueLiteralNode)

Aggregations

ArrayList (java.util.ArrayList)2 List (java.util.List)2 ExecutableElement (javax.lang.model.element.ExecutableElement)2 ArrayAccessNode (org.checkerframework.dataflow.cfg.node.ArrayAccessNode)2 ClassNameNode (org.checkerframework.dataflow.cfg.node.ClassNameNode)2 ExplicitThisLiteralNode (org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode)2 FieldAccessNode (org.checkerframework.dataflow.cfg.node.FieldAccessNode)2 LocalVariableNode (org.checkerframework.dataflow.cfg.node.LocalVariableNode)2 MethodInvocationNode (org.checkerframework.dataflow.cfg.node.MethodInvocationNode)2 NarrowingConversionNode (org.checkerframework.dataflow.cfg.node.NarrowingConversionNode)2 Node (org.checkerframework.dataflow.cfg.node.Node)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 ArrayCreationNode (org.checkerframework.dataflow.cfg.node.ArrayCreationNode)1