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

org.checkerframework.dataflow.reachingdef.ReachingDefinitionStore Maven / Gradle / Ivy

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

import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.analysis.Store;
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.Iterator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.StringJoiner;

/**
 * A reaching definition store contains a set of reaching definitions represented by
 * ReachingDefinitionNode
 */
public class ReachingDefinitionStore implements Store {

    /** The set of reaching definitions in this store */
    private final Set reachingDefSet;

    /** Create a new ReachDefinitionStore. */
    public ReachingDefinitionStore() {
        reachingDefSet = new LinkedHashSet<>();
    }

    /**
     * Create a new ReachDefinitionStore.
     *
     * @param reachingDefSet a set of reaching definition nodes. The parameter is captured and the
     *     caller should not retain an alias.
     */
    public ReachingDefinitionStore(Set reachingDefSet) {
        this.reachingDefSet = reachingDefSet;
    }

    /**
     * Remove the information of a reaching definition from the reaching definition set.
     *
     * @param defTarget target of a reaching definition
     */
    public void killDef(Node defTarget) {
        Iterator it = reachingDefSet.iterator();
        while (it.hasNext()) {
            // We use `.equals` instead of `==` here to compare value equality
            // rather than reference equality, because if two left-hand side node
            // have same values, we need to kill the old one and replace with the
            // new one.
            ReachingDefinitionNode generatedDefNode = it.next();
            if (generatedDefNode.def.getTarget().equals(defTarget)) {
                it.remove();
            }
        }
    }

    /**
     * Add a reaching definition to the reaching definition set.
     *
     * @param def a reaching definition
     */
    public void putDef(ReachingDefinitionNode def) {
        reachingDefSet.add(def);
    }

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

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

    @Override
    public ReachingDefinitionStore copy() {
        return new ReachingDefinitionStore(new LinkedHashSet<>(reachingDefSet));
    }

    @Override
    public ReachingDefinitionStore leastUpperBound(ReachingDefinitionStore other) {
        LinkedHashSet reachingDefSetLub =
                new LinkedHashSet<>(this.reachingDefSet.size() + other.reachingDefSet.size());
        reachingDefSetLub.addAll(this.reachingDefSet);
        reachingDefSetLub.addAll(other.reachingDefSet);
        return new ReachingDefinitionStore(reachingDefSetLub);
    }

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

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

    @Override
    public String visualize(CFGVisualizer viz) {
        String key = "reaching definitions";
        if (reachingDefSet.isEmpty()) {
            return viz.visualizeStoreKeyVal(key, "none");
        }
        StringJoiner sjStoreVal = new StringJoiner(", ", "{ ", " }");
        for (ReachingDefinitionNode reachDefNode : reachingDefSet) {
            sjStoreVal.add(reachDefNode.toString());
        }
        return viz.visualizeStoreKeyVal(key, sjStoreVal.toString());
    }

    @Override
    public String toString() {
        return "ReachingDefinitionStore: " + reachingDefSet.toString();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy