UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

100 lines (99 loc) 4.9 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/collections/bimap'; import type { MergeableRecord } from '../../../../../util/objects'; import { RoleInParent } from './role'; import { RType } from '../type'; import type { NodeId } from './node-id'; import type { RDelimiter } from '../nodes/info/r-delimiter'; import type { RProject } from '../nodes/r-project'; /** * 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: RProject<OtherInfo> | RNode<OtherInfo>) => NodeId; /** * The simplest id generator which just increments a number on each call. */ export declare function deterministicCountingIdGenerator(id?: number): () => NodeId; /** * Generates ids with a fixed prefix and an incrementing counter. */ export declare function deterministicPrefixIdGenerator(prefix: string, id?: number): () => NodeId; /** * Generates ids with a fixed source path and location information as prefix and an incrementing counter. */ 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, contexts listed in ${@link nestForElement} 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 = RProject<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; } /** * Node types for which the nesting score will be increased */ export declare const nestForElement: ReadonlySet<RType>; export interface NormalizedAstDecorationConfiguration<OtherInfo> { /** The id generator: must generate a unique id für each passed node */ getId?: IdGenerator<OtherInfo>; } /** * Covert the given AST into a doubly linked tree while assigning ids (so it stays serializable). * @param project - The AST to decorate * @param getId - The id generator: must generate a unique id für each passed node * @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>(project: RProject<OtherInfo>, { getId }: NormalizedAstDecorationConfiguration<OtherInfo>): NormalizedAst<OtherInfo & ParentInformation>;