UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

81 lines (80 loc) 3.63 kB
import type { MergeableRecord } from '../objects'; import type { QuadSerializationConfiguration } from '../quads'; import type { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id'; import type { NormalizedAst, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate'; import { RFalse, RTrue } from '../../r-bridge/lang-4.x/convert-values'; import type { DataflowGraph } from '../../dataflow/graph/graph'; export declare const enum CfgVertexType { /** Marks a break point in a construct (e.g., between the name and the value of an argument, or the formals and the body of a function) */ MidMarker = "mid-marker", /** The explicit exit-nodes to ensure the hammock property */ EndMarker = "end-marker", /** something like an if, assignment, ... even though in the classical sense of R they are still expressions */ Statement = "statement", /** something like an addition, ... */ Expression = "expression" } export interface CfgVertex { id: NodeId; type: CfgVertexType; name: string; /** in case of a function definition */ children?: NodeId[]; } interface CfgFlowDependencyEdge extends MergeableRecord { label: 'FD'; } interface CfgControlDependencyEdge extends MergeableRecord { label: 'CD'; /** the id which caused the control dependency */ caused: NodeId; when: typeof RTrue | typeof RFalse; } export type CfgEdge = CfgFlowDependencyEdge | CfgControlDependencyEdge; /** * This class represents the control flow graph of an R program. * The control flow may be hierarchical when confronted with function definitions (see {@link CfgVertex} and {@link CFG#rootVertexIds|rootVertexIds()}). */ export declare class ControlFlowGraph { private rootVertices; private vertexInformation; private edgeInformation; addVertex(vertex: CfgVertex, rootVertex?: boolean): this; addEdge(from: NodeId, to: NodeId, edge: CfgEdge): this; outgoing(node: NodeId): ReadonlyMap<NodeId, CfgEdge> | undefined; rootVertexIds(): ReadonlySet<NodeId>; vertices(): ReadonlyMap<NodeId, CfgVertex>; edges(): ReadonlyMap<NodeId, ReadonlyMap<NodeId, CfgEdge>>; merge(other: ControlFlowGraph, forceNested?: boolean): this; } export interface ControlFlowInformation extends MergeableRecord { returns: NodeId[]; breaks: NodeId[]; nexts: NodeId[]; /** intended to construct a hammock graph, with 0 exit points representing a block that should not be part of the CFG (like a comment) */ entryPoints: NodeId[]; /** See {@link ControlFlowInformation#entryPoints|entryPoints} */ exitPoints: NodeId[]; graph: ControlFlowGraph; } export declare function emptyControlFlowInformation(): ControlFlowInformation; /** * Given a normalized AST this approximates the control flow graph of the program. * This few is different from the computation of the dataflow graph and may differ, * especially because it focuses on intra-procedural analysis. * * @param ast - the normalized AST * @param graph - additional dataflow facts to consider by the control flow extraction */ export declare function extractCFG<Info = ParentInformation>(ast: NormalizedAst<Info>, graph?: DataflowGraph): ControlFlowInformation; /** * Returns true if the given CFG equals the other CFG. False otherwise. */ export declare function equalCfg(a: ControlFlowGraph | undefined, b: ControlFlowGraph | undefined): boolean; /** * @see df2quads * @see serialize2quads * @see graph2quads */ export declare function cfg2quads(cfg: ControlFlowInformation, config: QuadSerializationConfiguration): string; export {};