/**
 * 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>;
