All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.checkerframework.dataflow.livevariable.LiveVarStore Maven / Gradle / Ivy

Go to download

dataflow-shaded is a dataflow framework based on the javac compiler. It differs from the org.checkerframework:dataflow artifact in two ways. First, the packages in this artifact have been renamed to org.checkerframework.shaded.*. Second, unlike the dataflow artifact, this artifact contains the dependencies it requires.

There is a newer version: 3.42.0-eisop5
Show newest version
package org.checkerframework.dataflow.livevariable;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.analysis.Store;
import org.checkerframework.dataflow.cfg.node.BinaryOperationNode;
import org.checkerframework.dataflow.cfg.node.FieldAccessNode;
import org.checkerframework.dataflow.cfg.node.InstanceOfNode;
import org.checkerframework.dataflow.cfg.node.LocalVariableNode;
import org.checkerframework.dataflow.cfg.node.Node;
import org.checkerframework.dataflow.cfg.node.TernaryExpressionNode;
import org.checkerframework.dataflow.cfg.node.TypeCastNode;
import org.checkerframework.dataflow.cfg.node.UnaryOperationNode;
import org.checkerframework.dataflow.cfg.visualize.CFGVisualizer;
import org.checkerframework.dataflow.expression.JavaExpression;
import org.checkerframework.javacutil.BugInCF;
import org.plumelib.util.ArraySet;

import java.util.LinkedHashSet;
import java.util.Set;
import java.util.StringJoiner;

/** A live variable store contains a set of live variables represented by nodes. */
public class LiveVarStore implements Store {

    /** The set of live variables in this store */
    private final Set liveVarNodeSet;

    /** Create a new LiveVarStore. */
    public LiveVarStore() {
        liveVarNodeSet = new LinkedHashSet<>();
    }

    /**
     * Create a new LiveVarStore.
     *
     * @param liveVarNodeSet the set of live variable nodes. The parameter is captured and the
     *     caller should not retain an alias.
     */
    public LiveVarStore(Set liveVarNodeSet) {
        this.liveVarNodeSet = liveVarNodeSet;
    }

    /**
     * Add the information of a live variable into the live variable set.
     *
     * @param variable a live variable
     */
    public void putLiveVar(LiveVarNode variable) {
        liveVarNodeSet.add(variable);
    }

    /**
     * Remove the information of a live variable from the live variable set.
     *
     * @param variable a live variable
     */
    public void killLiveVar(LiveVarNode variable) {
        liveVarNodeSet.remove(variable);
    }

    /**
     * Add the information of live variables in an expression to the live variable set.
     *
     * @param expression a node
     */
    public void addUseInExpression(Node expression) {
        // TODO Do we need a AbstractNodeScanner to do the following job?
        if (expression instanceof LocalVariableNode || expression instanceof FieldAccessNode) {
            LiveVarNode liveVarValue = new LiveVarNode(expression);
            putLiveVar(liveVarValue);
        } else if (expression instanceof UnaryOperationNode) {
            UnaryOperationNode unaryNode = (UnaryOperationNode) expression;
            addUseInExpression(unaryNode.getOperand());
        } else if (expression instanceof TernaryExpressionNode) {
            TernaryExpressionNode ternaryNode = (TernaryExpressionNode) expression;
            addUseInExpression(ternaryNode.getConditionOperand());
            addUseInExpression(ternaryNode.getThenOperand());
            addUseInExpression(ternaryNode.getElseOperand());
        } else if (expression instanceof TypeCastNode) {
            TypeCastNode typeCastNode = (TypeCastNode) expression;
            addUseInExpression(typeCastNode.getOperand());
        } else if (expression instanceof InstanceOfNode) {
            InstanceOfNode instanceOfNode = (InstanceOfNode) expression;
            addUseInExpression(instanceOfNode.getOperand());
        } else if (expression instanceof BinaryOperationNode) {
            BinaryOperationNode binaryNode = (BinaryOperationNode) expression;
            addUseInExpression(binaryNode.getLeftOperand());
            addUseInExpression(binaryNode.getRightOperand());
        }
    }

    @Override
    public boolean equals(@Nullable Object obj) {
        if (!(obj instanceof LiveVarStore)) {
            return false;
        }
        LiveVarStore other = (LiveVarStore) obj;
        return other.liveVarNodeSet.equals(this.liveVarNodeSet);
    }

    @Override
    public int hashCode() {
        return this.liveVarNodeSet.hashCode();
    }

    @Override
    public LiveVarStore copy() {
        return new LiveVarStore(new LinkedHashSet<>(liveVarNodeSet));
    }

    @Override
    public LiveVarStore leastUpperBound(LiveVarStore other) {
        Set liveVarNodeSetLub =
                ArraySet.newArraySetOrLinkedHashSet(
                        this.liveVarNodeSet.size() + other.liveVarNodeSet.size());
        liveVarNodeSetLub.addAll(this.liveVarNodeSet);
        liveVarNodeSetLub.addAll(other.liveVarNodeSet);
        return new LiveVarStore(liveVarNodeSetLub);
    }

    /** It should not be called since it is not used by the backward analysis. */
    @Override
    public LiveVarStore widenedUpperBound(LiveVarStore previous) {
        throw new BugInCF("wub of LiveVarStore get called!");
    }

    @Override
    public boolean canAlias(JavaExpression a, JavaExpression b) {
        return true;
    }

    @Override
    public String visualize(CFGVisualizer viz) {
        String key = "live variables";
        if (liveVarNodeSet.isEmpty()) {
            return viz.visualizeStoreKeyVal(key, "none");
        }
        StringJoiner sjStoreVal = new StringJoiner(", ");
        for (LiveVarNode liveVar : liveVarNodeSet) {
            sjStoreVal.add(liveVar.toString());
        }
        return viz.visualizeStoreKeyVal(key, sjStoreVal.toString());
    }

    @Override
    public String toString() {
        return liveVarNodeSet.toString();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy