import type { RNamedFunctionCall } from '../../../r-bridge/lang-4.x/ast/model/nodes/r-function-call';
import type { RNode } from '../../../r-bridge/lang-4.x/ast/model/model';
import type { BuiltInEvalHandlerArgs } from '../../environments/built-in';
import { PkgName } from '../../environments/identifier';
import { type Value } from '../values/r-value';
/** everything after the last separator, with trailing separators dropped first (`a/b/` is `b`, `/` is the empty string) */
declare function basename(path: string): string;
/** everything before the last separator, `.` if there is none and `/` if only the root remains */
declare function dirname(path: string): string;
/**
 * One entry of the {@link StringFns} registry: the parameters R declares, in order, and how to fold them.
 *
 * `fold` receives them in that order, so a parameter R gives a default is an optional parameter of `fold`,
 * and a `...` parameter arrives as the array of everything it collected. Whatever `fold` cannot answer it
 * returns `undefined` for, which keeps the call `Top`.
 */
export interface StringFn {
    /** the package declaring it, so another package's function of that name does not fold */
    readonly pkg: PkgName;
    /** the parameter names, in the order R declares them; `...` collects the arguments naming no other parameter */
    readonly params: readonly string[];
    /** what a parameter R gives a default stands for, so `paste(a, b)` folds like `paste(a, b, sep = ' ')` */
    readonly defaults?: Readonly<Record<string, string>>;
    /** parameters a call may supply that change nothing for the single strings we fold, like `paste`'s `collapse` */
    readonly ignored?: readonly string[];
    /** the fold over the supplied arguments, in declaration order */
    readonly fold: (...args: any[]) => string | number | undefined;
}
/**
 * Every string built-in the value solver folds, the joining ones included: `paste` is an entry like `toupper`
 * is, and both are reached through {@link resolveAsStringFn}. Teaching flowR one more is a line here plus the
 * matching `evalHandler` in the built-in configuration -- a test checks that the two agree.
 *
 * An entry with a `...` parameter joins what it collected, which is why its separator is just another
 * parameter with a default. The rest take a fixed number of arguments under the names R documents.
 */
export declare const StringFns: {
    readonly paste: {
        readonly pkg: PkgName.Base;
        readonly params: readonly ["...", "sep"];
        readonly defaults: {
            readonly sep: " ";
        };
        readonly ignored: readonly ["collapse"];
        readonly fold: (parts: string[], sep: string) => string;
    };
    readonly paste0: {
        readonly pkg: PkgName.Base;
        readonly params: readonly ["...", "sep"];
        readonly defaults: {
            readonly sep: "";
        };
        readonly ignored: readonly ["collapse"];
        readonly fold: (parts: string[], sep: string) => string;
    };
    readonly 'file.path': {
        readonly pkg: PkgName.Base;
        readonly params: readonly ["...", "fsep"];
        readonly defaults: {
            readonly fsep: "/";
        };
        readonly fold: (parts: string[], fsep: string) => string;
    };
    readonly here: {
        readonly pkg: PkgName.Here;
        readonly params: readonly ["..."];
        readonly fold: (parts: string[]) => string;
    };
    readonly basename: {
        readonly pkg: PkgName.Base;
        readonly params: readonly ["path"];
        readonly fold: typeof basename;
    };
    readonly dirname: {
        readonly pkg: PkgName.Base;
        readonly params: readonly ["path"];
        readonly fold: typeof dirname;
    };
    readonly toupper: {
        readonly pkg: PkgName.Base;
        readonly params: readonly ["x"];
        readonly fold: (s: string) => string;
    };
    readonly tolower: {
        readonly pkg: PkgName.Base;
        readonly params: readonly ["x"];
        readonly fold: (s: string) => string;
    };
    readonly trimws: {
        readonly pkg: PkgName.Base;
        readonly params: readonly ["x"];
        readonly fold: (s: string) => string;
    };
    /** R counts characters, so we count code points rather than UTF-16 units */
    readonly nchar: {
        readonly pkg: PkgName.Base;
        readonly params: readonly ["x"];
        readonly fold: (s: string) => number;
    };
};
/** the entries that join what they are handed, the ones a name at construction time may be built from */
export declare const PasteLikeCalls: ReadonlySet<string>;
/**
 * Folds a named {@link StringFns} call to its result, resolving each argument with `resolveArg`. `undefined`
 * when the name is not one of them, an argument does not resolve, or the call does not match what the entry
 * declares. Shared by the value solver ({@link resolveAsStringFn}) and construction-time name resolution.
 */
export declare function foldStringCall<Info>(node: RNamedFunctionCall<Info>, resolveArg: (arg: RNode<Info>) => string | undefined): string | number | undefined;
/**
 * Resolves any call of a {@link StringFns} entry to a {@link Value}, with its arguments in any order R accepts:
 * a join like `paste0("cfg_", k)` when every part resolves to a single string constant, and a transformation
 * like `basename(p)` when its argument does. Anything that does not resolve stays `Top`.
 */
export declare function resolveAsStringFn(args: BuiltInEvalHandlerArgs): Value;
export {};
