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

org.checkerframework.dataflow.busyexpr.BusyExprStore 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.busyexpr;

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.Node;
import org.checkerframework.dataflow.cfg.visualize.CFGVisualizer;
import org.checkerframework.dataflow.expression.JavaExpression;
import org.checkerframework.javacutil.BugInCF;

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

/** A busy expression store contains a set of busy expressions represented by nodes. */
public class BusyExprStore implements Store {

    /** A set of busy expression abstract values. */
    private final Set busyExprValueSet;

    /**
     * Create a new BusyExprStore.
     *
     * @param busyExprValueSet a set of busy expression abstract values. The parameter is captured
     *     and the caller should not retain an alias.
     */
    public BusyExprStore(Set busyExprValueSet) {
        this.busyExprValueSet = busyExprValueSet;
    }

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

    /**
     * Kill expressions if they contain variable var.
     *
     * @param var a variable
     */
    public void killBusyExpr(Node var) {
        busyExprValueSet.removeIf(
                busyExprValue -> exprContainsVariable(busyExprValue.busyExpression, var));
    }

    /**
     * Return true if the expression contains variable var. Note that {@code .equals} is used in the
     * return statement to verify value equality, as the statement decides whether the two nodes
     * have the same value, not represent the same CFG node.
     *
     * @param expr the expression checked
     * @param var the variable
     * @return true if the expression contains the variable
     */
    public boolean exprContainsVariable(Node expr, Node var) {
        if (expr instanceof BinaryOperationNode) {
            BinaryOperationNode binaryNode = (BinaryOperationNode) expr;
            return exprContainsVariable(binaryNode.getLeftOperand(), var)
                    || exprContainsVariable(binaryNode.getRightOperand(), var);
        }

        return expr.equals(var);
    }

    /**
     * Add busy expression e to busy expression value set.
     *
     * @param e the busy expression to be added
     */
    public void putBusyExpr(BusyExprValue e) {
        busyExprValueSet.add(e);
    }

    /**
     * Add expressions to the store, add sub-expressions to the store recursively
     *
     * @param e the expression to be added
     */
    public void addUseInExpression(Node e) {
        if (e instanceof BinaryOperationNode) {
            BinaryOperationNode binaryNode = (BinaryOperationNode) e;
            putBusyExpr(new BusyExprValue(binaryNode));
            // recursively add expressions
            addUseInExpression(binaryNode.getLeftOperand());
            addUseInExpression(binaryNode.getRightOperand());
        }
    }

    @Override
    public BusyExprStore copy() {
        return new BusyExprStore(new LinkedHashSet<>(busyExprValueSet));
    }

    @Override
    public BusyExprStore leastUpperBound(BusyExprStore other) {
        Set busyExprValueSetLub = new LinkedHashSet<>(this.busyExprValueSet);
        busyExprValueSetLub.retainAll(other.busyExprValueSet);

        return new BusyExprStore(busyExprValueSetLub);
    }

    @Override
    public BusyExprStore widenedUpperBound(BusyExprStore previous) {
        throw new BugInCF("BusyExprStore.widenedUpperBound was called!");
    }

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

    @Override
    public String visualize(CFGVisualizer viz) {
        String key = "busy expressions";
        if (busyExprValueSet.isEmpty()) {
            return viz.visualizeStoreKeyVal(key, "none");
        }
        StringJoiner sjStoreVal = new StringJoiner(", ");
        for (BusyExprValue busyExprValue : busyExprValueSet) {
            sjStoreVal.add(busyExprValue.toString());
        }
        return viz.visualizeStoreKeyVal(key, sjStoreVal.toString());
    }

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

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

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




© 2015 - 2025 Weber Informatics LLC | Privacy Policy