@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
70 lines (69 loc) • 4.34 kB
TypeScript
import type { SliceResult } from './slicer-types';
import type { Fingerprint } from './fingerprint';
import { VisitingQueue } from './visiting-queue';
import type { NormalizedAst } from '../../r-bridge/lang-4.x/ast/model/processing/decorate';
import type { REnvironmentInformation } from '../../dataflow/environments/environment';
import { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
import type { DataflowInformation } from '../../dataflow/info';
import type { DataflowGraph } from '../../dataflow/graph/graph';
import type { ReadOnlyFlowrAnalyzerContext } from '../../project/context/flowr-analyzer-context';
import { SliceDirection } from '../../util/slice-direction';
import type { GasOverrides } from '../../gas';
export declare const slicerLogger: import("tslog").Logger<import("tslog").ILogObj>;
/** Options for {@link staticSlice}. */
export interface StaticSliceOptions {
/** The analyzer context (environments, configuration). */
readonly ctx: ReadOnlyFlowrAnalyzerContext;
/** Dataflow information including the graph to traverse. */
readonly info: DataflowInformation;
/** Normalized AST, used for id resolution and nesting info. */
readonly ast: NormalizedAst;
/** Seed node ids to start the BFS from. At least one is required. */
readonly ids: readonly NodeId[];
/** Whether to slice forward or backward. Defaults to {@link SliceDirection.Backward}. */
readonly direction?: SliceDirection;
/**
* Maximum BFS visits before the algorithm switches to over-approximation (includes everything).
* Defaults to 75.
*/
readonly threshold?: number;
/** Memoization cache that can be shared across multiple slices on the same graph. */
readonly cache?: Map<Fingerprint, Set<NodeId>>;
/**
* Pre-built graph to use for BFS traversal instead of (possibly inverting) `info.graph`.
* `info.graph` is still consulted for function-call resolution, so it must remain the non-inverted original.
* Used by {@link staticDice} to pass a reduced-and-inverted graph in a single allocation.
*/
readonly sliceGraph?: DataflowGraph;
/**
* If set (and slicing backward), continue the slice past a function-definition boundary: whenever the
* slice reaches a node that lives inside a function definition, also include the vertex that binds/defines
* the function (e.g. `f <- function(...)`) as well as all of its call sites (and their arguments).
* Defaults to `false` (slicing stops at the function-definition boundary, the historic behavior).
*/
readonly includeCallees?: boolean;
/**
* Gas bounds for this slice (see {@link GasOverrides}), on top of the enclosing operation's.
* A slice always gets a contingent of its own, so it is never billed for the analysis or the slices before it.
*/
readonly gas?: GasOverrides;
}
/**
* Computes the node ids to include in a static slice, starting from the given seed ids.
* The returned ids can be used with {@link reconstructToCode} to reproduce executable R code.
*/
export declare function staticSlice(options: StaticSliceOptions): Readonly<SliceResult>;
/**
* Computes a program dice: only those nodes reachable forward from `startIds` that are also in the backward slice of `endIds`.
* This effectively selects all paths from the given start nodes that lead to the given end nodes.
*
* For performance, the backward slice is computed first (typically the smaller set), then the graph is
* reduced to that set and its edges are inverted in a single pass via {@link Dataflow.reduceAndInvertGraph}.
* The forward traversal then runs only within that subgraph, avoiding nodes that cannot contribute to the dice.
*/
export declare function staticDice(ctx: ReadOnlyFlowrAnalyzerContext, info: DataflowInformation, ast: NormalizedAst, startIds: readonly NodeId[], endIds: readonly NodeId[], threshold?: number, includeCallees?: boolean, gas?: GasOverrides): Readonly<SliceResult>;
/**
* Updates the potential addition for the given target node in the visiting queue.
* This describes vertices that might be added *if* another path reaches them.
*/
export declare function updatePotentialAddition(queue: VisitingQueue, id: NodeId, target: NodeId, baseEnvironment: REnvironmentInformation, envFingerprint: string): void;