UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

98 lines (97 loc) 4.68 kB
/** * The decoration module is tasked with taking an R-ast given by a {@link RNode} and * * 1. assigning a unique id to each node (see {@link IdGenerator}) * 2. transforming the AST into a doubly linked tree using the ids (so it stays serializable) * * The main entry point is {@link decorateAst}. * * @module */ import type { NoInfo, RNode } from '../model'; import type { SourceRange } from '../../../../../util/range'; import { BiMap } from '../../../../../util/bimap'; import type { MergeableRecord } from '../../../../../util/objects'; import { RoleInParent } from './role'; import type { NodeId } from './node-id'; import type { RDelimiter } from '../nodes/info/r-delimiter'; /** * A function that given an RNode returns a (guaranteed) unique id for it * @param data - the node to generate an id for * * @returns a unique id for the given node */ export type IdGenerator<OtherInfo> = (data: RNode<OtherInfo>) => NodeId; /** * The simplest id generator which just increments a number on each call. */ export declare function deterministicCountingIdGenerator(id?: number): () => NodeId; export declare function deterministicPrefixIdGenerator(prefix: string, id?: number): () => NodeId; export declare function sourcedDeterministicCountingIdGenerator(path: string, location: SourceRange, start?: number): () => NodeId; /** * Generates the location id, used by {@link deterministicLocationIdGenerator}. * * @param data - the node to generate an id for, must have location information */ export declare function nodeToLocationId<OtherInfo>(data: RNode<OtherInfo> | RDelimiter): NodeId; /** * Generates unique ids based on the locations of the node (see {@link nodeToLocationId}). * If a node has no location information, it will be assigned a unique counter-value. * * @param start - the start value for the counter, in case nodes do not have location information */ export declare function deterministicLocationIdGenerator<OtherInfo>(start?: number): IdGenerator<OtherInfo>; export interface ParentContextInfo extends MergeableRecord { role: RoleInParent; /** * The nesting of the node in the AST * * The root node has a nesting of 0, nested function calls, loops etc. will increase the nesting */ nesting: number; /** * 0-based index of the child in the parent (code semantics, e.g., for an if-then-else, the condition will be 0, the then-case will be 1, ...) * * The index is adaptive, that means that if the name of an argument exists, it will have index 0, and the value will have index 1. * But if the argument is unnamed, its value will get the index 0 instead. */ index: number; } export interface ParentInformation extends ParentContextInfo { /** uniquely identifies an AST-Node */ id: NodeId; /** Links to the parent node, using an id so that the AST stays serializable */ parent: NodeId | undefined; } export type RNodeWithParent<OtherInfo = NoInfo> = RNode<OtherInfo & ParentInformation>; export type AstIdMap<OtherInfo = NoInfo> = BiMap<NodeId, RNodeWithParent<OtherInfo>>; /** * Contains the normalized AST as a doubly linked tree * and a map from ids to nodes so that parent links can be chased easily. */ export interface NormalizedAst<OtherInfo = ParentInformation, Node = RNode<OtherInfo & ParentInformation>> { /** Bidirectional mapping of ids to the corresponding nodes and the other way */ idMap: AstIdMap<OtherInfo>; /** The root of the AST with parent information */ ast: Node; /** marks whether the AST contains potential syntax errors */ hasError?: boolean; } export interface NormalizedAstDecorationConfiguration<OtherInfo> { /** The id generator: must generate a unique id für each passed node */ getId?: IdGenerator<OtherInfo>; /** the path to the file this AST was extracted from will be added to the nodes */ file?: string; } /** * Covert the given AST into a doubly linked tree while assigning ids (so it stays serializable). * * @param ast - The root of the AST to convert * @param getId - The id generator: must generate a unique id für each passed node * @param file - the path to the file this AST was extracted from will be added to the nodes * * @typeParam OtherInfo - The original decoration of the ast nodes (probably is nothing as the id decoration is most likely the first step to be performed after extraction) * * @returns A decorated AST based on the input and the id provider. */ export declare function decorateAst<OtherInfo = NoInfo>(ast: RNode<OtherInfo>, { getId, file }: NormalizedAstDecorationConfiguration<OtherInfo>): NormalizedAst<OtherInfo & ParentInformation>;