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

org.checkerframework.dataflow.analysis.Analysis Maven / Gradle / Ivy

Go to download

The Checker Framework enhances Java's type system to make it more powerful and useful. This lets software developers detect and prevent errors in their Java programs. The Checker Framework includes compiler plug-ins ("checkers") that find bugs or verify their absence. It also permits you to write your own compiler plug-ins.

The newest version!
package org.checkerframework.dataflow.analysis;

import com.sun.source.tree.Tree;

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;

import java.util.IdentityHashMap;
import java.util.Map;

/**
 * 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  the abstract value type to be tracked by the analysis
 * @param  the store type used in the analysis
 * @param  the transfer function type that is used to approximated runtime behavior
 */
public interface Analysis<
        V extends AbstractValue, S extends Store, T extends TransferFunction> {

    /** 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.
     */
    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 blockTransferInput,
            IdentityHashMap nodeValues,
            @Nullable Map, IdentityHashMap>>
                    analysisCaches);

    /**
     * The result of running the analysis. This is only available once the analysis finished
     * running.
     *
     * @return the result of running the analysis
     */
    AnalysisResult 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 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();
}