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

org.checkerframework.dataflow.constantpropagation.ConstantPropagationStore 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.constantpropagation;

import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.analysis.Store;
import org.checkerframework.dataflow.cfg.node.IntegerLiteralNode;
import org.checkerframework.dataflow.cfg.node.LocalVariableNode;
import org.checkerframework.dataflow.cfg.node.Node;
import org.checkerframework.dataflow.cfg.visualize.CFGVisualizer;
import org.checkerframework.dataflow.expression.JavaExpression;
import org.plumelib.util.ArrayMap;
import org.plumelib.util.CollectionsPlume;

import java.util.LinkedHashMap;
import java.util.Map;

/** A store that records information about constant values. */
public class ConstantPropagationStore implements Store {

    /** Information about variables gathered so far. */
    private final Map contents;

    /** Creates a new ConstantPropagationStore. */
    public ConstantPropagationStore() {
        contents = new LinkedHashMap<>();
    }

    protected ConstantPropagationStore(Map contents) {
        this.contents = contents;
    }

    public Constant getInformation(Node n) {
        if (contents.containsKey(n)) {
            return contents.get(n);
        }
        return new Constant(Constant.Type.TOP);
    }

    public void mergeInformation(Node n, Constant val) {
        Constant value;
        if (contents.containsKey(n)) {
            value = val.leastUpperBound(contents.get(n));
        } else {
            value = val;
        }
        // TODO: remove (only two nodes supported atm)
        assert n instanceof IntegerLiteralNode || n instanceof LocalVariableNode;
        contents.put(n, value);
    }

    public void setInformation(Node n, Constant val) {
        // TODO: remove (only two nodes supported atm)
        assert n instanceof IntegerLiteralNode || n instanceof LocalVariableNode;
        contents.put(n, val);
    }

    @Override
    public ConstantPropagationStore copy() {
        return new ConstantPropagationStore(new LinkedHashMap<>(contents));
    }

    @Override
    public ConstantPropagationStore leastUpperBound(ConstantPropagationStore other) {
        Map newContents =
                ArrayMap.newArrayMapOrLinkedHashMap(contents.size() + other.contents.size());

        // go through all of the information of the other class
        for (Map.Entry e : other.contents.entrySet()) {
            Node n = e.getKey();
            Constant otherVal = e.getValue();
            if (contents.containsKey(n)) {
                // merge if both contain information about a variable
                newContents.put(n, otherVal.leastUpperBound(contents.get(n)));
            } else {
                // add new information
                newContents.put(n, otherVal);
            }
        }

        for (Map.Entry e : contents.entrySet()) {
            Node n = e.getKey();
            Constant thisVal = e.getValue();
            if (!other.contents.containsKey(n)) {
                // add new information
                newContents.put(n, thisVal);
            }
        }

        return new ConstantPropagationStore(newContents);
    }

    @Override
    public ConstantPropagationStore widenedUpperBound(ConstantPropagationStore previous) {
        return leastUpperBound(previous);
    }

    @Override
    public boolean equals(@Nullable Object o) {
        if (o == null) {
            return false;
        }
        if (!(o instanceof ConstantPropagationStore)) {
            return false;
        }
        ConstantPropagationStore other = (ConstantPropagationStore) o;
        // go through all of the information of the other object
        for (Map.Entry e : other.contents.entrySet()) {
            Node n = e.getKey();
            Constant otherVal = e.getValue();
            if (otherVal.isBottom()) {
                continue; // no information
            }
            if (contents.containsKey(n)) {
                if (!otherVal.equals(contents.get(n))) {
                    return false;
                }
            } else {
                return false;
            }
        }
        // go through all of the information of the this object
        for (Map.Entry e : contents.entrySet()) {
            Node n = e.getKey();
            Constant thisVal = e.getValue();
            if (thisVal.isBottom()) {
                continue; // no information
            }
            if (other.contents.containsKey(n)) {
                continue;
            } else {
                return false;
            }
        }
        return true;
    }

    @Override
    public int hashCode() {
        int s = 0;
        for (Map.Entry e : contents.entrySet()) {
            if (!e.getValue().isBottom()) {
                s += e.hashCode();
            }
        }
        return s;
    }

    @Override
    public String toString() {
        // Only output local variable information.
        // This output is very terse, so a CFG containing it fits well in the manual.
        Map contentsLocalVars =
                new LinkedHashMap<>(CollectionsPlume.mapCapacity(contents));
        for (Map.Entry e : contents.entrySet()) {
            if (e.getKey() instanceof LocalVariableNode) {
                contentsLocalVars.put(e.getKey(), e.getValue());
            }
        }
        return contentsLocalVars.toString();
    }

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

    @Override
    public String visualize(CFGVisualizer viz) {
        return viz.visualizeStoreKeyVal("constant propagation", toString());
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy