import { SyntaxNode } from '../ast';
import { PartialDeep } from 'type-fest';
export type TraverseMatchFilter<N extends SyntaxNode = SyntaxNode> = PartialDeep<N>;
export interface TraversePath<N extends SyntaxNode = SyntaxNode> {
    /**
     * The key of the node
     * @example "SourceUnit.ContractDefinition"
     */
    path: string;
    /**
     * The depth of the AST, starting from 0
     */
    depth: number;
    /**
     * Syntax Node form AST
     */
    node: N;
    /**
     * The parent path
     */
    parentPath: TraversePath | null;
    /**
     * Stop traversing
     */
    stop: () => void;
    /**
     * Rewrite the current node
     * @param value The new value to replace the current node
     */
    rewrite: (value: SyntaxNode | any) => void;
    /**
     * Is the current node matches the filter
     * @param filter The filter to match
     */
    matches: (filter: TraverseMatchFilter<N>) => boolean;
    /**
     * Check if the current node contains the offset
     * @param offset
     * @returns
     */
    checkOffset: (offset?: number) => boolean;
    /**
     * Get the flatten node list
     */
    getFlattenParents: (maxDepth?: number) => N[];
}
export type TraverseCallback = (path: TraversePath) => void | (() => void);
/**
 * Traverse
 * @param ast SyntaxNode Tree
 * @param callback like Array.map, but it will traverse the tree
 * @returns The new AST, the original AST will not be modified
 */
export declare function traverse<T extends SyntaxNode>(ast: T | TraversePath<T>, callback: TraverseCallback): T;
