import type { BindingElem, BindingPattern, Decl, ParameterDecl, VariableDecl, VariableDeclList } from "./declaration";
import { Assertion, AssertionToInstance } from "./ensure";
import type { Err } from "./error";
import type { Expr, ImportKeyword, QuasiString, SuperKeyword } from "./expression";
import type { NodeCtor } from "./node-ctor";
import { NodeKind, NodeKindName } from "./node-kind";
import type { BlockStmt, CatchClause, Stmt } from "./statement";
export declare type FunctionlessNode = Decl | Expr | Stmt | Err | SuperKeyword | ImportKeyword | BindingPattern | VariableDeclList | QuasiString;
export interface HasParent<Parent extends FunctionlessNode> {
    get parent(): Parent;
    set parent(parent: Parent);
}
declare type BindingDecl = VariableDecl | ParameterDecl | BindingElem;
export declare abstract class BaseNode<Kind extends NodeKind, Parent extends FunctionlessNode | undefined = FunctionlessNode | undefined> {
    readonly kind: Kind;
    abstract readonly nodeKind: "Err" | "Expr" | "Stmt" | "Decl" | "Node";
    readonly parent: Parent;
    /**
     * The immediate Child nodes contained within this Node.
     */
    readonly children: FunctionlessNode[];
    readonly _arguments: ConstructorParameters<NodeCtor<this["kind"]>>;
    constructor(kind: Kind, _arguments: IArguments);
    get kindName(): NodeKindName<Kind>;
    toSExpr(): [kind: this["kind"], ...args: any[]];
    /**
     * Forks the tree starting from `this` node with {@link node} as its child
     *
     * This function simply sets the {@link node}'s parent and returns it.
     */
    fork<N extends this["parent"]>(node: N): N;
    protected ensureArrayOf<Assert extends Assertion>(arr: any[], fieldName: string, assertion: Assert[] | readonly Assert[]): asserts arr is AssertionToInstance<Assert>[];
    protected ensure<Assert extends Assertion>(item: any, fieldName: string, assertion: Assert[] | readonly Assert[]): asserts item is AssertionToInstance<Assert>;
    as<T>(guard: (a: any) => a is T): T | undefined;
    is<N extends this>(is: (node: this) => node is N): this is N;
    findChildren<N extends FunctionlessNode>(is: (node: FunctionlessNode) => node is N): N[];
    collectChildren<T>(f: (node: FunctionlessNode) => T[]): T[];
    findParent<N extends FunctionlessNode>(is: (node: FunctionlessNode) => node is N): N | undefined;
    hasOnlyAncestors(cont: (node: FunctionlessNode) => boolean, stop?: (node: FunctionlessNode) => boolean): boolean;
    /**
     * Finds the {@link CatchClause} that this Node should throw to.
     */
    findCatchClause(): CatchClause | undefined;
    contains(node: FunctionlessNode, alg?: "dfs" | "bfs"): boolean;
    /**
     * @returns the {@link Stmt} that will be run immediately after this Node.
     */
    step(): Stmt | undefined;
    /**
     * @returns the {@link Stmt} that will be run after exiting the scope of this Node.
     */
    exit(): Stmt | undefined;
    /**
     * @returns the {@link Stmt} that will be run if an error was raised from this Node.
     */
    throw(): CatchClause | BlockStmt | undefined;
    /**
     * @returns an array of all the visible names in this node's scope.
     */
    getVisibleNames(): string[];
    /**
     * @returns a mapping of name to the node visible in this node's scope.
     */
    getLexicalScope(): Map<string, BindingDecl>;
    /**
     * @returns checks if this Node is terminal - meaning all branches explicitly return a value
     */
    isTerminal(): boolean;
}
export declare const deploymentOnlyModule = true;
export {};
//# sourceMappingURL=node.d.ts.map