blob: 92b5e9e8b1617d3f58d0a41185df297299c3f188 [file] [log] [blame]
package org.checkerframework.dataflow.analysis;
import com.sun.source.tree.Tree;
import java.util.IdentityHashMap;
import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.dataflow.cfg.ControlFlowGraph;
import org.checkerframework.dataflow.cfg.block.Block;
import org.checkerframework.dataflow.cfg.node.Node;
/**
* This interface defines a dataflow analysis, given a control flow graph and a transfer function. A
* dataflow analysis has a direction, either forward or backward. The direction of corresponding
* transfer function is consistent with the analysis, i.e. a forward analysis has a forward transfer
* function, and a backward analysis has a backward transfer function.
*
* @param <V> the abstract value type to be tracked by the analysis
* @param <S> the store type used in the analysis
* @param <T> the transfer function type that is used to approximated runtime behavior
*/
public interface Analysis<
V extends AbstractValue<V>, S extends Store<S>, T extends TransferFunction<V, S>> {
/** The direction of an analysis instance. */
enum Direction {
/** The forward direction. */
FORWARD,
/** The backward direction. */
BACKWARD
}
/**
* In calls to {@code Analysis#runAnalysisFor}, whether to return the store before or after the
* given node.
*/
public static enum BeforeOrAfter {
/** Return the pre-store. */
BEFORE,
/** Return the post-store. */
AFTER
}
/**
* Get the direction of this analysis.
*
* @return the direction of this analysis
*/
Direction getDirection();
/**
* Is the analysis currently running?
*
* @return true if the analysis is running currently, else false
*/
boolean isRunning();
/**
* Perform the actual analysis.
*
* @param cfg the control flow graph
*/
void performAnalysis(ControlFlowGraph cfg);
/**
* Perform the actual analysis on one block.
*
* @param b the block to analyze
*/
void performAnalysisBlock(Block b);
/**
* 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 immediately after {@code node} is returned. If
* {@code analysisCaches} is not null, this method uses a cache. {@code analysisCaches} is a map
* of a block of node to the cached analysis result. If the cache for {@code transferInput} is not
* in {@code analysisCaches}, this method creates new cache and stores it in {@code
* analysisCaches}. The cache is a map of nodes to the analysis results of the nodes.
*
* @param node the node to analyze
* @param preOrPost which store to return: the store immediately before {@code node} or the store
* after {@code node}
* @param blockTransferInput the transfer input of the block of this node
* @param nodeValues abstract values of nodes
* @param analysisCaches caches of analysis results
* @return the store before or after {@code node} (depends on the value of {@code before}) after
* running the analysis
*/
S runAnalysisFor(
Node node,
Analysis.BeforeOrAfter preOrPost,
TransferInput<V, S> blockTransferInput,
IdentityHashMap<Node, V> nodeValues,
Map<TransferInput<V, S>, IdentityHashMap<Node, TransferResult<V, S>>> analysisCaches);
/**
* The result of running the analysis. This is only available once the analysis finished running.
*
* @return the result of running the analysis
*/
AnalysisResult<V, S> getResult();
/**
* Get the transfer function of this analysis.
*
* @return the transfer function of this analysis
*/
@Nullable T getTransferFunction();
/**
* Get the transfer input of a given {@link Block} b.
*
* @param b a given Block
* @return the transfer input of this Block
*/
@Nullable TransferInput<V, S> getInput(Block b);
/**
* Returns the abstract value for {@link Node} {@code n}, or {@code null} if no information is
* available. Note that if the analysis has not finished yet, this value might not represent the
* final value for this node.
*
* @param n n a node
* @return the abstract value for node {@code n}, or {@code null} if no information is available
*/
@Nullable V getValue(Node n);
/**
* Return the abstract value for {@link Tree} {@code t}, or {@code null} if no information is
* available. Note that if the analysis has not finished yet, this value might not represent the
* final value for this node.
*
* @param t the given tree
* @return the abstract value for the given tree
*/
@Nullable V getValue(Tree t);
/**
* Returns the regular exit store, or {@code null}, if there is no such store (because the method
* cannot exit through the regular exit block).
*
* @return the regular exit store, or {@code null}, if there is no such store (because the method
* cannot exit through the regular exit block)
*/
@Nullable S getRegularExitStore();
/**
* Returns the exceptional exit store.
*
* @return the exceptional exit store
*/
@Nullable S getExceptionalExitStore();
}