diff options
Diffstat (limited to 'third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AnalysisResult.java')
-rw-r--r-- | third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AnalysisResult.java | 220 |
1 files changed, 0 insertions, 220 deletions
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AnalysisResult.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AnalysisResult.java deleted file mode 100644 index 48f376dbea..0000000000 --- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AnalysisResult.java +++ /dev/null @@ -1,220 +0,0 @@ -package org.checkerframework.dataflow.analysis; - -/*>>> -import org.checkerframework.checker.nullness.qual.Nullable; -*/ - -import com.sun.source.tree.Tree; -import java.util.HashMap; -import java.util.IdentityHashMap; -import java.util.Map; -import java.util.Map.Entry; -import javax.lang.model.element.Element; -import org.checkerframework.dataflow.cfg.block.Block; -import org.checkerframework.dataflow.cfg.block.ExceptionBlock; -import org.checkerframework.dataflow.cfg.block.RegularBlock; -import org.checkerframework.dataflow.cfg.node.Node; - -/** - * An {@link AnalysisResult} represents the result of a org.checkerframework.dataflow analysis by - * providing the abstract values given a node or a tree. Note that it does not keep track of custom - * results computed by some analysis. - * - * @author Stefan Heule - * @param <A> type of the abstract value that is tracked - */ -public class AnalysisResult<A extends AbstractValue<A>, S extends Store<S>> { - - /** Abstract values of nodes. */ - protected final IdentityHashMap<Node, A> nodeValues; - - /** Map from AST {@link Tree}s to {@link Node}s. */ - protected final IdentityHashMap<Tree, Node> treeLookup; - - /** Map from (effectively final) local variable elements to their abstract value. */ - protected final HashMap<Element, A> finalLocalValues; - - /** The stores before every method call. */ - protected final IdentityHashMap<Block, TransferInput<A, S>> stores; - - /** Initialize with a given node-value mapping. */ - public AnalysisResult( - Map<Node, A> nodeValues, - IdentityHashMap<Block, TransferInput<A, S>> stores, - IdentityHashMap<Tree, Node> treeLookup, - HashMap<Element, A> finalLocalValues) { - this.nodeValues = new IdentityHashMap<>(nodeValues); - this.treeLookup = new IdentityHashMap<>(treeLookup); - this.stores = stores; - this.finalLocalValues = finalLocalValues; - } - - /** Initialize empty result. */ - public AnalysisResult() { - nodeValues = new IdentityHashMap<>(); - treeLookup = new IdentityHashMap<>(); - stores = new IdentityHashMap<>(); - finalLocalValues = new HashMap<>(); - } - - /** Combine with another analysis result. */ - public void combine(AnalysisResult<A, S> other) { - for (Entry<Node, A> e : other.nodeValues.entrySet()) { - nodeValues.put(e.getKey(), e.getValue()); - } - for (Entry<Tree, Node> e : other.treeLookup.entrySet()) { - treeLookup.put(e.getKey(), e.getValue()); - } - for (Entry<Block, TransferInput<A, S>> e : other.stores.entrySet()) { - stores.put(e.getKey(), e.getValue()); - } - for (Entry<Element, A> e : other.finalLocalValues.entrySet()) { - finalLocalValues.put(e.getKey(), e.getValue()); - } - } - - /** @return the value of effectively final local variables */ - public HashMap<Element, A> getFinalLocalValues() { - return finalLocalValues; - } - - /** - * @return the abstract value for {@link Node} {@code n}, or {@code null} if no information is - * available. - */ - public /*@Nullable*/ A getValue(Node n) { - return nodeValues.get(n); - } - - /** - * @return the abstract value for {@link Tree} {@code t}, or {@code null} if no information is - * available. - */ - public /*@Nullable*/ A getValue(Tree t) { - A val = getValue(treeLookup.get(t)); - return val; - } - - /** @return the {@link Node} for a given {@link Tree}. */ - public /*@Nullable*/ Node getNodeForTree(Tree tree) { - return treeLookup.get(tree); - } - - /** @return the store immediately before a given {@link Tree}. */ - public S getStoreBefore(Tree tree) { - Node node = getNodeForTree(tree); - if (node == null) { - return null; - } - return getStoreBefore(node); - } - - /** @return the store immediately before a given {@link Node}. */ - public S getStoreBefore(Node node) { - return runAnalysisFor(node, true); - } - - /** @return the store immediately after a given {@link Tree}. */ - public S getStoreAfter(Tree tree) { - Node node = getNodeForTree(tree); - if (node == null) { - return null; - } - return getStoreAfter(node); - } - - /** @return the store immediately after a given {@link Node}. */ - public S getStoreAfter(Node node) { - return runAnalysisFor(node, false); - } - - /** - * Runs the analysis again within the block of {@code node} and returns the store at the - * location of {@code node}. If {@code before} is true, then the store immediately before the - * {@link Node} {@code node} is returned. Otherwise, the store after {@code node} is returned. - * - * <p>If the given {@link Node} cannot be reached (in the control flow graph), then {@code null} - * is returned. - */ - protected S runAnalysisFor(Node node, boolean before) { - Block block = node.getBlock(); - TransferInput<A, S> transferInput = stores.get(block); - if (transferInput == null) { - return null; - } - return runAnalysisFor(node, before, transferInput); - } - - /** - * Runs the analysis again within the block of {@code node} and returns the store at the - * location of {@code node}. If {@code before} is true, then the store immediately before the - * {@link Node} {@code node} is returned. Otherwise, the store after {@code node} is returned. - */ - public static <A extends AbstractValue<A>, S extends Store<S>> S runAnalysisFor( - Node node, boolean before, TransferInput<A, S> transferInput) { - assert node != null; - Block block = node.getBlock(); - assert transferInput != null; - Analysis<A, S, ?> analysis = transferInput.analysis; - Node oldCurrentNode = analysis.currentNode; - - if (analysis.isRunning) { - return analysis.currentInput.getRegularStore(); - } - analysis.isRunning = true; - try { - switch (block.getType()) { - case REGULAR_BLOCK: - { - RegularBlock rb = (RegularBlock) block; - - // Apply transfer function to contents until we found the node - // we - // are looking for. - TransferInput<A, S> store = transferInput; - TransferResult<A, S> transferResult = null; - for (Node n : rb.getContents()) { - analysis.currentNode = n; - if (n == node && before) { - return store.getRegularStore(); - } - transferResult = analysis.callTransferFunction(n, store); - if (n == node) { - return transferResult.getRegularStore(); - } - store = new TransferInput<>(n, analysis, transferResult); - } - // This point should never be reached. If the block of 'node' is - // 'block', then 'node' must be part of the contents of 'block'. - assert false; - return null; - } - - case EXCEPTION_BLOCK: - { - ExceptionBlock eb = (ExceptionBlock) block; - - // apply transfer function to content - assert eb.getNode() == node; - if (before) { - return transferInput.getRegularStore(); - } - analysis.currentNode = node; - TransferResult<A, S> transferResult = - analysis.callTransferFunction(node, transferInput); - return transferResult.getRegularStore(); - } - - default: - // Only regular blocks and exceptional blocks can hold nodes. - assert false; - break; - } - - return null; - } finally { - analysis.currentNode = oldCurrentNode; - analysis.isRunning = false; - } - } -} |