@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
88 lines (87 loc) • 5.21 kB
TypeScript
/**
* Provides an environment structure similar to R.
* This allows the dataflow to hold current definition locations for variables, based on the current scope.
*
* @module
*/
import type { Identifier, IdentifierDefinition, IdentifierReference } from './identifier';
import type { DataflowGraph } from '../graph/graph';
import type { ControlDependency } from '../info';
/**
* Marks the reference as maybe (i.e., as controlled by a set of {@link IdentifierReference#controlDependencies|control dependencies}).
*/
export declare function makeReferenceMaybe(ref: IdentifierReference, graph: DataflowGraph, environments: REnvironmentInformation, includeDefs: boolean, defaultCd?: ControlDependency | undefined): IdentifierReference;
export declare function makeAllMaybe(references: readonly IdentifierReference[] | undefined, graph: DataflowGraph, environments: REnvironmentInformation, includeDefs: boolean, defaultCd?: ControlDependency | undefined): IdentifierReference[];
export type EnvironmentMemory = Map<Identifier, IdentifierDefinition[]>;
/** A single entry/scope within an {@link REnvironmentInformation} */
export interface IEnvironment {
/** Unique and internally generated identifier -- will not be used for comparison but helps with debugging for tracking identities */
readonly id: number;
/** Lexical parent of the environment, if any (can be manipulated by R code) */
parent: IEnvironment;
/** Maps to exactly one definition of an identifier if the source is known, otherwise to a list of all possible definitions */
memory: EnvironmentMemory;
}
/** @see REnvironmentInformation */
export declare class Environment implements IEnvironment {
readonly id: number;
parent: IEnvironment;
memory: Map<Identifier, IdentifierDefinition[]>;
constructor(parent: IEnvironment);
}
export interface WorkingDirectoryReference {
readonly path: string;
readonly controlDependencies: ControlDependency[] | undefined;
}
/**
* An environment describes a ({@link IEnvironment#parent|scoped}) mapping of names to their definitions ({@link EnvironmentMemory}).
*
* First, yes, R stores its environments differently, potentially even with another differentiation between
* the `baseenv`, the `emptyenv`, and other default environments (see https://adv-r.hadley.nz/environments.html).
* Yet, during the dataflow analysis, we want sometimes to know more (static {@link IdentifierDefinition|reference information})
* and sometimes know less (to be honest, we do not want that,
* but statically determining all attached environments is theoretically impossible --- consider attachments by user input).
*
* One important environment is the {@link BuiltInEnvironment} which contains the default definitions for R's built-in functions and constants.
* Please use {@link initializeCleanEnvironments} to initialize the environments (which includes the built-ins).
* During serialization, you may want to rely on the {@link builtInEnvJsonReplacer} to avoid the huge built-in environment.
*
*
* @see {@link define} - to define a new {@link IdentifierDefinition|identifier definition} within an environment
* @see {@link resolveByName} - to resolve an {@link Identifier|identifier/name} to its {@link IdentifierDefinition|definitions} within an environment
* @see {@link makeReferenceMaybe} - to attach control dependencies to a reference
* @see {@link pushLocalEnvironment} - to create a new local scope
* @see {@link popLocalEnvironment} - to remove the current local scope
* @see {@link appendEnvironment} - to append an environment to the current one
* @see {@link overwriteEnvironment} - to overwrite the definitions in the current environment with those of another one
*/
export interface REnvironmentInformation {
/** The currently active environment (the stack is represented by the currently active {@link IEnvironment#parent}). Environments are maintained within the dataflow graph. */
readonly current: IEnvironment;
/** nesting level of the environment, will be `0` for the global/root environment */
readonly level: number;
}
/**
* The built-in {@link REnvironmentInformation|environment} is the root of all environments.
*
* For its default content (when not overwritten by a flowR config),
* see the {@link DefaultBuiltinConfig}.
*/
export declare const BuiltInEnvironment: Environment;
/**
* The twin of the {@link BuiltInEnvironment} but with less built ins defined for
* cases in which we want some commonly overwritten variables to remain open.
* If you do not know if you need the empty environment, you do not need the empty environment (right now).
*
* @see {@link BuiltInEnvironment}
*/
export declare const EmptyBuiltInEnvironment: IEnvironment;
/**
* Initialize a new {@link REnvironmentInformation|environment} with the built-ins.
* See {@link EmptyBuiltInEnvironment} for the case `fullBuiltIns = false`.
*/
export declare function initializeCleanEnvironments(fullBuiltIns?: boolean): REnvironmentInformation;
/**
* Helps to serialize an environment, but replaces the built-in environment with a placeholder.
*/
export declare function builtInEnvJsonReplacer(k: unknown, v: unknown): unknown;