UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

137 lines (136 loc) 8.96 kB
import { DefaultMap } from '../../util/collections/defaultmap'; import type { BuiltIn } from '../../r-bridge/lang-4.x/ast/model/processing/node-id'; import { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id'; import { Identifier, type IdentifierReference } from '../environments/identifier'; import { type DataflowGraph, FunctionArgument } from '../graph/graph'; import type { RParameter } from '../../r-bridge/lang-4.x/ast/model/nodes/r-parameter'; import type { AstIdMap, ParentInformation } from '../../r-bridge/lang-4.x/ast/model/processing/decorate'; import { type DataflowGraphVertexFunctionCall, type DataflowGraphVertexFunctionDefinition, type DataflowGraphVertexInfo } from '../graph/vertex'; import type { REnvironmentInformation } from '../environments/environment'; import type { ExitPoint } from '../info'; export type NameIdMap = DefaultMap<Identifier, IdentifierReference[]>; /** * Find all reads within the graph that do not reference a local definition in the graph. */ export declare function findNonLocalReads(graph: DataflowGraph, ignores?: ReadonlySet<NodeId>): IdentifierReference[]; /** * Produces a map from names to all identifier references sharing that name. */ export declare function produceNameSharedIdMap(references: IdentifierReference[]): NameIdMap; /** * {@link matchArgumentsToParameters|Matches} the arguments to the parameters and links them in the graph, * returning the resolved map from argument ids to parameter ids. * If you just want to match by name, use {@link pMatch}. */ export declare function linkArgumentsOnCall(args: readonly FunctionArgument[], params: readonly RParameter<ParentInformation>[], graph: DataflowGraph): Map<NodeId, NodeId>; /** * {@link matchArgumentsToParameters|Matches} the arguments against a parameter specification, returning the * arguments bound to each target. Unlike {@link linkArgumentsOnCall} this touches no graph, so it also works * for a specification without parameters in the AST. * @example * ```ts * const parameterSpec = { * 'paramName': 'paramId', * 'anotherParamName': 'anotherParamId', * // we recommend to always add '...' to your specification * // this way you can collect all arguments that could not be matched! * '...': '...' * } as const; * * const match = pMatch(convertFnArguments(args), parameterSpec); * const addParam = match.get('paramId'); * ``` * @note * To obtain the arguments from a {@link RFunctionCall}[], either use {@link processAllArguments} (also available via {@link processKnownFunctionCall}) * or convert them with {@link convertFnArguments}. */ export declare function pMatch<Targets extends NodeId>(args: readonly FunctionArgument[], params: Record<string, Targets>): Map<Targets, NodeId[]>; /** * Links a function call with a single target function definition. */ export declare function linkFunctionCallWithSingleTarget(graph: DataflowGraph, { subflow: fnSubflow, exitPoints, id: fnId, params }: DataflowGraphVertexFunctionDefinition, info: DataflowGraphVertexFunctionCall, idMap: AstIdMap): ExitPoint[]; /** * Returns the called functions within the current graph, which can be used to merge the environments with the call. * Furthermore, it links the corresponding arguments. * @param graph - The graph to use for search and resolution traversals (ideally a superset of the `thisGraph`) * @param idMap - The map to resolve ids to names * @param thisGraph - The graph to search for function calls in */ export declare function linkFunctionCalls(graph: DataflowGraph, idMap: AstIdMap, thisGraph: DataflowGraph): { functionCall: NodeId; called: readonly DataflowGraphVertexInfo[]; propagateExitPoints: readonly ExitPoint[]; }[]; /** * convenience function returning all known call targets, as well as the name source which defines them */ export declare function getAllFunctionCallTargets(call: NodeId, graph: DataflowGraph, environment?: REnvironmentInformation): NodeId[]; /** * Finds all linked function definitions starting from the given set of read ids. * This is a complicated function, please only call it if you know what you are doing. * For example, if you are interested in the called functions of a function call, use {@link getAllFunctionCallTargets} instead. * This function here expects you to handle the accessed objects yourself (e.g,. already resolve the first layer of reads/returns/calls/... or resolve the identifier by name) * and then pass in the relevant read ids. * @example * Consider a scenario like this: * ```R * x <- function() 3 * x() * ``` * To resolve the call `x` in the second line, use {@link getAllFunctionCallTargets}! * To know what fdefs the definition of `x` in the first line links to, you can use {@link getAllLinkedFunctionDefinitions|this function}. */ export declare function getAllLinkedFunctionDefinitions(functionDefinitionReadIds: ReadonlySet<NodeId>, dataflowGraph: DataflowGraph): [Set<Required<DataflowGraphVertexFunctionDefinition>>, Set<BuiltIn>]; /** * This method links a set of read variables to definitions in an environment. * @param referencesToLinkAgainstEnvironment - The set of references to link against the environment * @param environmentInformation - The environment information to link against * @param givenInputs - The existing list of inputs that might be extended * @param graph - The graph to enter the found links * @param maybeForRemaining - Each input that can not be linked, will be added to `givenInputs`. If this flag is `true`, it will be marked as `maybe`. * @returns the given inputs, possibly extended with the remaining inputs (those of `referencesToLinkAgainstEnvironment` that could not be linked against the environment) */ /** * Links every name in the expression rooted at `expr` against `environment`, as if it were written there, and * hands back what stays unresolved. This is how an expression that was captured elsewhere is read here. * @useInstead {@link Quoted.evaluateIn} */ export declare function linkExpressionIn<Info>(this: void, graph: DataflowGraph, expr: NodeId, environment: REnvironmentInformation, idMap: AstIdMap<Info & ParentInformation>): readonly IdentifierReference[]; /** * This method links a set of read variables to definitions in an environment. * @param referencesToLinkAgainstEnvironment - The set of references to link against the environment * @param environmentInformation - The environment information to link against * @param givenInputs - The existing list of inputs that might be extended * @param graph - The graph to enter the found links * @param maybeForRemaining - Each input that can not be linked, will be added to `givenInputs`. If this flag is `true`, it will be marked as `maybe`. * @returns the given inputs, possibly extended with the remaining inputs (those of `referencesToLinkAgainstEnvironment` that could not be linked against the environment) */ export declare function linkInputs(referencesToLinkAgainstEnvironment: readonly IdentifierReference[], environmentInformation: REnvironmentInformation, givenInputs: IdentifierReference[], graph: DataflowGraph, maybeForRemaining: boolean): IdentifierReference[]; /** * all loops variables which are open read (not already bound by a redefinition within the loop) get a maybe read marker to their last definition within the loop * e.g. with: * ```R * for(i in 1:10) { * x_1 <- x_2 + 1 * } * ``` * `x_2` must get a read marker to `x_1` as `x_1` is the active redefinition in the second loop iteration. * * When `environment` is supplied the function uses it to discover ALL definitions that are still live at the * loop exit, so sequential overwrites contribute a single candidate while if-else branches contribute one * candidate per branch. */ export declare function linkCircularRedefinitionsWithinALoop(graph: DataflowGraph, openIns: NameIdMap, outgoing: readonly IdentifierReference[], environment?: REnvironmentInformation): void; /** * Reapplies the loop exit points' control dependencies to the given identifier references. */ export declare function reapplyLoopExitPoints(exits: readonly ExitPoint[], references: readonly IdentifierReference[], graph: DataflowGraph): void; /** The open references a function definition still carries into its closure. */ export declare const ClosureRefs: { readonly name: "ClosureRefs"; /** * Resolves the open ingoing references of a definition called anonymously at `callId` against `environment`, * links what resolves, and leaves only the references that stay open. */ readonly resolveOpenIngoing: (this: void, graph: DataflowGraph, callId: NodeId, definition: DataflowGraphVertexFunctionDefinition, environment: REnvironmentInformation) => void; };