import type { NoInfo, RNode } from '../r-bridge/lang-4.x/ast/model/model';
import type { RExpressionList } from '../r-bridge/lang-4.x/ast/model/nodes/r-expression-list';
import type { RFunctionCall } from '../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
import { EmptyArgument } from '../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
import type { RFunctionDefinition } from '../r-bridge/lang-4.x/ast/model/nodes/r-function-definition';
import { RType } from '../r-bridge/lang-4.x/ast/model/type';
import type { RForLoop } from '../r-bridge/lang-4.x/ast/model/nodes/r-for-loop';
import type { RWhileLoop } from '../r-bridge/lang-4.x/ast/model/nodes/r-while-loop';
import type { RRepeatLoop } from '../r-bridge/lang-4.x/ast/model/nodes/r-repeat-loop';
import type { RIfThenElse } from '../r-bridge/lang-4.x/ast/model/nodes/r-if-then-else';
import type { RBinaryOp } from '../r-bridge/lang-4.x/ast/model/nodes/r-binary-op';
import type { RPipe } from '../r-bridge/lang-4.x/ast/model/nodes/r-pipe';
import type { RUnaryOp } from '../r-bridge/lang-4.x/ast/model/nodes/r-unary-op';
import type { RParameter } from '../r-bridge/lang-4.x/ast/model/nodes/r-parameter';
import type { RArgument } from '../r-bridge/lang-4.x/ast/model/nodes/r-argument';
import type { RAccess } from '../r-bridge/lang-4.x/ast/model/nodes/r-access';
import type { RLogical } from '../r-bridge/lang-4.x/ast/model/nodes/r-logical';
import type { RBreak } from '../r-bridge/lang-4.x/ast/model/nodes/r-break';
import type { RComment } from '../r-bridge/lang-4.x/ast/model/nodes/r-comment';
import type { RNext } from '../r-bridge/lang-4.x/ast/model/nodes/r-next';
import type { RNumber } from '../r-bridge/lang-4.x/ast/model/nodes/r-number';
import type { RLineDirective } from '../r-bridge/lang-4.x/ast/model/nodes/r-line-directive';
import type { RString } from '../r-bridge/lang-4.x/ast/model/nodes/r-string';
import type { RSymbol } from '../r-bridge/lang-4.x/ast/model/nodes/r-symbol';
type FoldOfType<T extends RType, Returns = void, Info = NoInfo> = (node: Extract<RNode<Info>, {
    type: T;
}>) => Returns;
/** explicitly excludes types that are not visitable */
export type FoldableRType = Exclude<RType, RType.Delimiter>;
/**
 * Describes the fold functions for each node type.
 */
export type NormalizedAstFold<Returns = void, Info = NoInfo> = {
    [K in FoldableRType as `fold${Capitalize<K>}`]: FoldOfType<K, Returns, Info>;
};
/**
 * Describes the type of a mapping object,
 * which maps the type of the normalized AST node to the corresponding fold function.
 */
export type FittingNormalizedAstFold<Returns = void, Info = NoInfo> = Readonly<{
    [K in FoldableRType]: FoldOfType<K, Returns, Info>;
}>;
export type SingleOrArrayOrNothing<T> = T | readonly (T | null | undefined)[] | null | undefined;
export type EntryExitVisitor<Info> = ((node: RNode<Info>) => void) | undefined;
/**
 * Default implementation of a fold over the normalized AST (using the classic fold traversal).
 * To modify the behavior, please extend this class and overwrite the methods of interest.
 * You can control the value passing (`Returns` generic)
 * by providing sensible Monoid behavior overwriting the {@link DefaultNormalizedAstFold#concat|concat} method
 * and supplying the empty value in the constructor.
 *
 * @note By providing `entry` and `exit` you can use this as an extension to the simpler {@link visitAst} function but without
 *       the early termination within the visitors (for this, you can overwrite the respective `fold*` methods).
 *
 * @example First you want to create your own fold:
 *
 * ```ts
 * let marker = false;
 * class MyNumberFold<Info> extends DefaultNormalizedAstFold<void, Info> {
 *     override foldRNumber(node: RNumber<Info>) {
 *         super.foldRNumber(node);
 *         marker = true;
 *     }
 * }
 * ```
 * This one does explicitly not use the return functionality (and hence acts more as a conventional visitor).
 * Now let us suppose we have a normalized AST as an {@link RNode} in the variable `ast`
 * and want to check if the AST contains a number:
 *
 * ```ts
 * const result = new MyNumberFold().fold(ast);
 * ```
 *
 * Please take a look at the corresponding tests or the wiki pages for more information on how to use this fold.
 */
export declare class DefaultNormalizedAstFold<Returns = void, Info = NoInfo> implements NormalizedAstFold<Returns, Info> {
    protected readonly enter: EntryExitVisitor<Info>;
    protected readonly exit: EntryExitVisitor<Info>;
    protected readonly empty: Returns;
    /**
     * Empty must provide a sensible default whenever you want to have `Returns` as non-`void`
     * (e.g., whenever you want your visitors to be able to return a value).
     */
    constructor(empty: Returns, enter?: EntryExitVisitor<Info>, exit?: EntryExitVisitor<Info>);
    /**
     * Monoid::concat
     *
     *
     * @see {@link https://en.wikipedia.org/wiki/Monoid}
     * @see {@link DefaultNormalizedAstFold#concatAll|concatAll}
     */
    protected concat(_a: Returns, _b: Returns): Returns;
    /**
     * overwrite this method, if you have a faster way to concat multiple nodes
     *
     * @see {@link DefaultNormalizedAstFold#concatAll|concatAll}
     */
    protected concatAll(nodes: readonly Returns[]): Returns;
    fold(nodes: SingleOrArrayOrNothing<RNode<Info> | typeof EmptyArgument>): Returns;
    protected foldSingle(node: RNode<Info>): Returns;
    foldRAccess(access: RAccess<Info>): Returns;
    foldRArgument(argument: RArgument<Info>): Returns;
    foldRBinaryOp(binaryOp: RBinaryOp<Info>): Returns;
    foldRExpressionList(exprList: RExpressionList<Info>): Returns;
    foldRForLoop(loop: RForLoop<Info>): Returns;
    foldRFunctionCall(call: RFunctionCall<Info>): Returns;
    foldRFunctionDefinition(definition: RFunctionDefinition<Info>): Returns;
    foldRIfThenElse(ite: RIfThenElse<Info>): Returns;
    foldRParameter(parameter: RParameter<Info>): Returns;
    foldRPipe(pipe: RPipe<Info>): Returns;
    foldRRepeatLoop(loop: RRepeatLoop<Info>): Returns;
    foldRUnaryOp(unaryOp: RUnaryOp<Info>): Returns;
    foldRWhileLoop(loop: RWhileLoop<Info>): Returns;
    foldRBreak(_node: RBreak<Info>): Returns;
    foldRComment(_node: RComment<Info>): Returns;
    foldRLineDirective(_node: RLineDirective<Info>): Returns;
    foldRLogical(_node: RLogical<Info>): Returns;
    foldRNext(_node: RNext<Info>): Returns;
    foldRNumber(_node: RNumber<Info>): Returns;
    foldRString(_node: RString<Info>): Returns;
    foldRSymbol(_node: RSymbol<Info>): Returns;
    protected readonly folds: FittingNormalizedAstFold<Returns, Info>;
}
export {};
