@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
58 lines (57 loc) • 3.83 kB
TypeScript
import { RNode } from '../../../../../r-bridge/lang-4.x/ast/model/model';
import type { NodeId } from '../../../../../r-bridge/lang-4.x/ast/model/processing/node-id';
import type { ParentInformation } from '../../../../../r-bridge/lang-4.x/ast/model/processing/decorate';
import { Identifier } from '../../../../environments/identifier';
import { type DataflowGraph } from '../../../../graph/graph';
import { type DataflowGraphVertexInfo } from '../../../../graph/vertex';
/** The escape a quoting function offers, a property of the function: `quote(!!x)` negates, `expr(!!x)` splices. */
export declare enum Unquote {
/** no escape at all, everything within the argument stays unevaluated */
None = "none",
/** rlang's `!!` and `!!!` splice in the value of their operand */
Rlang = "rlang",
/** `bquote`'s `.(x)` evaluates its operand */
Bquote = "bquote"
}
/**
* A call that hands its arguments a data mask, with the names in that mask the caller binds itself.
* Those mean the column as much as the binding, so {@link Nse.linkMasksToData} links them to the data too.
*/
export interface MaskingCall {
readonly id: NodeId;
readonly bound: readonly NodeId[];
}
/** The parts of a call R does not evaluate the standard way. */
export declare const Nse: {
readonly name: "Nse";
/** The ids an {@link Unquote} escape hands back to standard evaluation, the markers themselves excluded. */
readonly unquoted: <Info extends ParentInformation>(this: void, root: RNode<Info> | undefined, style: Unquote) => ReadonlySet<NodeId> | undefined;
/** Whether everything below `node` is unquoted. */
readonly isUnquote: <Info>(this: void, node: RNode<Info>, style: Unquote) => boolean;
/**
* Drops the mask mark from names the caller binds to a value: while `filter(d, k)` is processed `k` has no
* read yet. A name bound to a function keeps its mark, as `filter(d, id > 2)` next to `id <- function(...)`
* still means the column. Hands back the masking call and the names it just unmarked, `undefined` when
* `name` does not mask at all, so {@link linkMasksToData} need not ask a second time.
*/
readonly dropResolvedMask: (this: void, graph: DataflowGraph, id: NodeId, name: Identifier) => MaskingCall | undefined;
/** Drops the non-standard-evaluation mark from the outgoing edges of `id` that `which` accepts, and reports them. */
readonly unmark: (this: void, graph: DataflowGraph, id: NodeId, which?: (target: NodeId) => boolean) => NodeId[];
/** Whether the vertex is a name a data mask may supply, which is every name appearing in the mask. */
readonly maskCandidate: (this: void, vertex: DataflowGraphVertexInfo | undefined) => boolean;
/** Whether `id` is a name the data mask supplies, i.e. a use the caller does not bind itself. */
readonly suppliedByMask: (this: void, graph: DataflowGraph, id: NodeId, vertex?: DataflowGraphVertexInfo | undefined) => boolean;
/**
* Whether `id` is a name a data mask supplied, which the mark the masking call carries is what records.
* Unlike {@link suppliedByMask} this survives {@link linkMasksToData}, so ask this one after the dataflow
* is complete and that one while a call is still being processed.
*/
readonly maskedName: (this: void, graph: DataflowGraph, id: NodeId) => boolean;
/**
* Links every name the data masks of `calls` supply to the data it comes from: `id` in `filter(df, id > 2)`
* is a column of `df`, so it reads `df`. Run once every mark has settled, as adding the read makes
* {@link suppliedByMask} false for the name; a call whose first argument is masked too has no data to link
* against.
*/
readonly linkMasksToData: (this: void, graph: DataflowGraph, calls: readonly MaskingCall[]) => void;
};