UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

70 lines (69 loc) 4.34 kB
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;