@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
109 lines (108 loc) • 6.74 kB
TypeScript
import type { ArgProps, BuiltInFnInfo, CallProps, FnSig } from './built-in-props';
import type { BuiltIns } from './built-in';
import type { BuiltInDefinition, BuiltInDefinitions } from './built-in-config';
import type { REnvironmentInformation } from './environment';
import { Identifier } from './identifier';
import { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
import type { PackageSignatureSource } from '../../project/sigdb/reader';
import type { DataflowInformation } from '../info';
/**
* Where to look up what flowR knows about a function, in that order:
* the name as it resolves here, the built-in definitions, and the signature database for the rest.
*/
export interface FnPropsSource {
/** resolve the name here first, so a definition in the analyzed code shadows the built-in as it does in R */
readonly environment?: REnvironmentInformation;
/** consulted when there is no environment at hand */
readonly builtIns?: BuiltIns;
/** fills in what the built-in definitions do not state, for namespaced names */
readonly signatures?: PackageSignatureSource;
/** the package version to ask the signature database for (its latest by default) */
readonly version?: string;
}
/**
* What flowR knows about the function `name`: what the built-in definitions state, filled up with what the
* signature database knows (see {@link fnInfoFromSignature}). A declared signature wins, the properties of
* both are joined. `undefined` if neither has anything to say, and also if the name resolves to a definition
* in the analyzed code, which shadows any built-in.
*/
export declare function queryFnProps(name: Identifier, { environment, builtIns, signatures, version }: FnPropsSource): BuiltInFnInfo | undefined;
/** What flowR states about the call `id` makes, together with the name the call resolved to. */
export declare function callFnProps(id: NodeId, { graph, environment }: Pick<DataflowInformation, 'graph' | 'environment'>): (BuiltInFnInfo & {
name: Identifier;
}) | undefined;
/**
* What the signature database implies for a package function: what its own entry states
* (see {@link fnInfoFromSignature}) plus the {@link PropagatedProps} of everything it calls, transitively.
* A package function that ends up in `system()` runs a system command as well.
*/
export declare function inferFnProps(src: PackageSignatureSource, pkg: string, name: string, version?: string): BuiltInFnInfo | undefined;
/** The identifiers a definition registers, with the suffixes of a replacement spelled out. */
export declare function builtInNames(definition: BuiltInDefinition): Identifier[];
/** One built-in as the {@link BuiltInIndex} sees it: the name it is registered under and what flowR states about it. */
export interface BuiltInEntry {
/** the identifier the built-in is registered under, with a replacement's suffix spelled out */
readonly name: Identifier;
/** the {@link CallProp} bits the definition states, `undefined` when it states none */
readonly props?: CallProps;
/** the declared parameters and what each of their arguments is used for */
readonly sig?: FnSig;
/** whether the value solver can fold a call of this built-in to a constant */
readonly folds: boolean;
}
/** One parameter of a built-in, as {@link BuiltInIndex#params} reports it. */
export interface BuiltInParam {
/** the built-in the parameter belongs to */
readonly call: Identifier;
/** the position it is declared at; a `...` parameter covers every position from here on */
readonly index: number;
readonly name: string;
readonly props: ArgProps;
}
/**
* The one place to ask what flowR's built-ins are: _every pure function_, _every call that reads a file_,
* _every parameter that names a resource_, _everything the value solver can fold_. Each answer is derived
* from the {@link BuiltInFnInfo} the definitions carry, so a built-in that states its {@link CallProp} bits and
* its {@link FnSig} is found here without anything else being registered.
*
* Build one over the {@link DefaultBuiltinConfig} with {@link BuiltInIndex.default} (computed once and shared),
* over your own definitions with {@link BuiltInIndex.of}, or over the built-ins an analysis actually registered
* with {@link BuiltInIndex.ofEnvironment}, which reflects configured overrides. For a single name (where a
* definition in the analyzed code shadows the built-in) use {@link queryFnProps} instead.
*/
export declare class BuiltInIndex {
readonly entries: readonly BuiltInEntry[];
private readonly byName;
private readonly cache;
private constructor();
/** The index of flowR's own {@link DefaultBuiltinConfig}, computed on first use and shared from then on. */
static default(): BuiltInIndex;
/** The index of a set of built-in definitions, e.g. the ones a flowR config adds. */
static of(definitions: BuiltInDefinitions): BuiltInIndex;
/** The index of the built-ins an analysis registered, so a configured or overwritten built-in is what shows up. */
static ofEnvironment(builtIns: BuiltIns): BuiltInIndex;
/** answers are keyed by what was asked, as every caller asks the same handful of questions over and over */
private cached;
/** Every built-in whose props carry at least one bit of `props`, like {@link CallProp.File} for the file calls. */
with(props: CallProps): readonly Identifier[];
/**
* Every built-in whose props carry *every* bit of `props`, for the questions a single bit cannot answer,
* like {@link FileInputProps} for the calls that read a file rather than only write one.
*/
withAll(props: CallProps): readonly Identifier[];
/**
* Every built-in that states its props but carries no bit of `props`. With {@link InputProps} this yields
* the calls that derive their result from their arguments alone.
*/
without(props: CallProps): readonly Identifier[];
/** Every built-in flowR states computes a result and nothing else ({@link CallProp.Pure}). */
get pure(): readonly Identifier[];
/** Every built-in the value solver can fold to a constant (the ones with a `evalHandler`). */
get folding(): readonly Identifier[];
/** Every parameter whose argument carries at least one bit of `props`, like {@link ArgProp.Resource}. */
params(props: ArgProps): BuiltInParam[];
/** What the index states about `name`, ignoring any namespace (built-ins are registered by their bare name). */
get(name: Identifier): BuiltInEntry | undefined;
/** The {@link CallProp} bits of `name`, `undefined` when no built-in of that name states any. */
propsOf(name: Identifier): CallProps | undefined;
}