@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
186 lines (185 loc) • 7.55 kB
TypeScript
import type { MergeableRecord } from './util/objects';
import Joi from 'joi';
import type { BuiltInDefinitions } from './dataflow/environments/built-in-config';
import type { KnownParser } from './r-bridge/parser';
import type { DeepPartial } from 'ts-essentials';
export declare enum VariableResolve {
/** Don't resolve constants at all */
Disabled = "disabled",
/** Use alias tracking to resolve */
Alias = "alias",
/** Only resolve directly assigned builtin constants */
Builtin = "builtin"
}
/**
* How to infer the working directory from a script
*/
export declare enum InferWorkingDirectory {
/** Don't infer the working directory */
No = "no",
/** Infer the working directory from the main script */
MainScript = "main-script",
/** Infer the working directory from the active script */
ActiveScript = "active-script",
/** Infer the working directory from any script */
AnyScript = "any-script"
}
/**
* How to handle fixed strings in a source path
*/
export declare enum DropPathsOption {
/** Don't drop any parts of the sourced path */
No = "no",
/** try to drop everything but the filename */
Once = "once",
/** try to drop every folder of the path */
All = "all"
}
export interface FlowrLaxSourcingOptions extends MergeableRecord {
/**
* search for filenames matching in the lowercase
*/
readonly ignoreCapitalization: boolean;
/**
* try to infer the working directory from the main or any script to analyze.
*/
readonly inferWorkingDirectory: InferWorkingDirectory;
/**
* Additionally search in these paths
*/
readonly searchPath: readonly string[];
/**
* Allow to drop the first or all parts of the sourced path,
* if it is relative.
*/
readonly dropPaths: DropPathsOption;
/**
* How often the same file can be sourced within a single run?
* Please be aware: in case of cyclic sources this may not reach a fixpoint so give this a sensible limit.
*/
readonly repeatedSourceLimit?: number;
/**
* sometimes files may have a different name in the source call (e.g., due to later replacements),
* with this setting you can provide a list of replacements to apply for each sourced file.
* Every replacement consists of a record that maps a regex to a replacement string.
*
* @example
* ```ts
* [
* { }, // no replacement -> still try the original name/path
* { '.*\\.R$': 'main.R' }, // replace all .R files with main.R
* { '\s' : '_' }, // replace all spaces with underscores
* { '\s' : '-', 'oo': 'aa' }, // replace all spaces with dashes and oo with aa
* ]
* ```
*
* Given a `source("foo bar.R")` this configuration will search for (in this order):
* - `foo bar.R` (original name)
* - `main.R` (replaced with main.R)
* - `foo_bar.R` (replaced spaces)
* - `foo-bar.R` (replaced spaces and oo)
*/
readonly applyReplacements?: Record<string, string>[];
}
export interface FlowrConfigOptions extends MergeableRecord {
/**
* Whether source calls should be ignored, causing {@link processSourceCall}'s behavior to be skipped
*/
readonly ignoreSourceCalls: boolean;
/** Configure language semantics and how flowR handles them */
readonly semantics: {
/** Semantics regarding the handling of the environment */
readonly environment: {
/** Do you want to overwrite (parts) of the builtin definition? */
readonly overwriteBuiltIns: {
/** Should the default configuration still be loaded? */
readonly loadDefaults?: boolean;
/** The definitions to load */
readonly definitions: BuiltInDefinitions;
};
};
};
/**
* The engines to use for interacting with R code. Currently, supports {@link TreeSitterEngineConfig} and {@link RShellEngineConfig}.
* An empty array means all available engines will be used.
*/
readonly engines: readonly EngineConfig[];
/**
* The default engine to use for interacting with R code. If this is undefined, an arbitrary engine from {@link engines} will be used.
*/
readonly defaultEngine?: EngineConfig['type'];
/** How to resolve constants, constraints, cells, … */
readonly solver: {
/**
* How to resolve variables and their values
*/
readonly variables: VariableResolve;
/**
* Should we include eval(parse(text="...")) calls in the dataflow graph?
*/
readonly evalStrings: boolean;
/**
* Whether to track pointers in the dataflow graph,
* if not, the graph will be over-approximated wrt.
* containers and accesses
*/
readonly pointerTracking: boolean | {
/**
* The maximum number of indices tracked per obj with the pointer analysis (currently this focuses on initialization)
*/
readonly maxIndexCount: number;
};
/**
* If lax source calls are active, flowR searches for sourced files much more freely,
* based on the configurations you give it.
* This option is only in effect if {@link ignoreSourceCalls} is set to false.
*/
readonly resolveSource?: FlowrLaxSourcingOptions;
/**
* The configuration for flowR's slicer
*/
slicer?: {
/**
* The maximum number of iterations to perform on a single function call during slicing
*/
readonly threshold?: number;
};
};
}
export interface TreeSitterEngineConfig extends MergeableRecord {
readonly type: 'tree-sitter';
/**
* The path to the tree-sitter-r WASM binary to use. If this is undefined, {@link DEFAULT_TREE_SITTER_R_WASM_PATH} will be used.
*/
readonly wasmPath?: string;
/**
* The path to the tree-sitter WASM binary to use. If this is undefined, the path specified by the tree-sitter package will be used.
*/
readonly treeSitterWasmPath?: string;
/**
* Whether to use the lax parser for parsing R code (allowing for syntax errors). If this is undefined, the strict parser will be used.
*/
readonly lax?: boolean;
}
export interface RShellEngineConfig extends MergeableRecord {
readonly type: 'r-shell';
/**
* The path to the R executable to use. If this is undefined, {@link DEFAULT_R_PATH} will be used.
*/
readonly rPath?: string;
}
export type EngineConfig = TreeSitterEngineConfig | RShellEngineConfig;
export type KnownEngines = {
[T in EngineConfig['type']]?: KnownParser;
};
export declare const defaultConfigOptions: FlowrConfigOptions;
export declare const flowrConfigFileSchema: Joi.ObjectSchema<any>;
export declare function setConfigFile(file: string | undefined, workingDirectory?: string, forceLoad?: boolean): void;
export declare function parseConfig(jsonString: string): FlowrConfigOptions | undefined;
export declare function setConfig(config: FlowrConfigOptions): void;
export declare function amendConfig(amendment: DeepPartial<FlowrConfigOptions>): void;
export declare function getConfig(): FlowrConfigOptions;
export declare function getEngineConfig<T extends EngineConfig['type']>(engine: T): EngineConfig & {
type: T;
} | undefined;
export declare function isOverPointerAnalysisThreshold(count: number): boolean;