import type { ArgProps, BuiltInFnInfo, CallProps, FnSig } from './built-in-props';
import type { BuiltIns } from './built-in';
import type { BuiltInDefinition, BuiltInDefinitions } from './built-in-config';
import type { REnvironmentInformation } from './environment';
import { Identifier } from './identifier';
import { NodeId } from '../../r-bridge/lang-4.x/ast/model/processing/node-id';
import type { PackageSignatureSource } from '../../project/sigdb/reader';
import type { DataflowInformation } from '../info';
/**
 * Where to look up what flowR knows about a function, in that order:
 * the name as it resolves here, the built-in definitions, and the signature database for the rest.
 */
export interface FnPropsSource {
    /** resolve the name here first, so a definition in the analyzed code shadows the built-in as it does in R */
    readonly environment?: REnvironmentInformation;
    /** consulted when there is no environment at hand */
    readonly builtIns?: BuiltIns;
    /** fills in what the built-in definitions do not state, for namespaced names */
    readonly signatures?: PackageSignatureSource;
    /** the package version to ask the signature database for (its latest by default) */
    readonly version?: string;
}
/**
 * What flowR knows about the function `name`: what the built-in definitions state, filled up with what the
 * signature database knows (see {@link fnInfoFromSignature}). A declared signature wins, the properties of
 * both are joined. `undefined` if neither has anything to say, and also if the name resolves to a definition
 * in the analyzed code, which shadows any built-in.
 */
export declare function queryFnProps(name: Identifier, { environment, builtIns, signatures, version }: FnPropsSource): BuiltInFnInfo | undefined;
/** What flowR states about the call `id` makes, together with the name the call resolved to. */
export declare function callFnProps(id: NodeId, { graph, environment }: Pick<DataflowInformation, 'graph' | 'environment'>): (BuiltInFnInfo & {
    name: Identifier;
}) | undefined;
/**
 * What the signature database implies for a package function: what its own entry states
 * (see {@link fnInfoFromSignature}) plus the {@link PropagatedProps} of everything it calls, transitively.
 * A package function that ends up in `system()` runs a system command as well.
 */
export declare function inferFnProps(src: PackageSignatureSource, pkg: string, name: string, version?: string): BuiltInFnInfo | undefined;
/** The identifiers a definition registers, with the suffixes of a replacement spelled out. */
export declare function builtInNames(definition: BuiltInDefinition): Identifier[];
/** One built-in as the {@link BuiltInIndex} sees it: the name it is registered under and what flowR states about it. */
export interface BuiltInEntry {
    /** the identifier the built-in is registered under, with a replacement's suffix spelled out */
    readonly name: Identifier;
    /** the {@link CallProp} bits the definition states, `undefined` when it states none */
    readonly props?: CallProps;
    /** the declared parameters and what each of their arguments is used for */
    readonly sig?: FnSig;
    /** whether the value solver can fold a call of this built-in to a constant */
    readonly folds: boolean;
}
/** One parameter of a built-in, as {@link BuiltInIndex#params} reports it. */
export interface BuiltInParam {
    /** the built-in the parameter belongs to */
    readonly call: Identifier;
    /** the position it is declared at; a `...` parameter covers every position from here on */
    readonly index: number;
    readonly name: string;
    readonly props: ArgProps;
}
/**
 * The one place to ask what flowR's built-ins are: _every pure function_, _every call that reads a file_,
 * _every parameter that names a resource_, _everything the value solver can fold_. Each answer is derived
 * from the {@link BuiltInFnInfo} the definitions carry, so a built-in that states its {@link CallProp} bits and
 * its {@link FnSig} is found here without anything else being registered.
 *
 * Build one over the {@link DefaultBuiltinConfig} with {@link BuiltInIndex.default} (computed once and shared),
 * over your own definitions with {@link BuiltInIndex.of}, or over the built-ins an analysis actually registered
 * with {@link BuiltInIndex.ofEnvironment}, which reflects configured overrides. For a single name (where a
 * definition in the analyzed code shadows the built-in) use {@link queryFnProps} instead.
 */
export declare class BuiltInIndex {
    readonly entries: readonly BuiltInEntry[];
    private readonly byName;
    private readonly cache;
    private constructor();
    /** The index of flowR's own {@link DefaultBuiltinConfig}, computed on first use and shared from then on. */
    static default(): BuiltInIndex;
    /** The index of a set of built-in definitions, e.g. the ones a flowR config adds. */
    static of(definitions: BuiltInDefinitions): BuiltInIndex;
    /** The index of the built-ins an analysis registered, so a configured or overwritten built-in is what shows up. */
    static ofEnvironment(builtIns: BuiltIns): BuiltInIndex;
    /** answers are keyed by what was asked, as every caller asks the same handful of questions over and over */
    private cached;
    /** Every built-in whose props carry at least one bit of `props`, like {@link CallProp.File} for the file calls. */
    with(props: CallProps): readonly Identifier[];
    /**
     * Every built-in whose props carry *every* bit of `props`, for the questions a single bit cannot answer,
     * like {@link FileInputProps} for the calls that read a file rather than only write one.
     */
    withAll(props: CallProps): readonly Identifier[];
    /**
     * Every built-in that states its props but carries no bit of `props`. With {@link InputProps} this yields
     * the calls that derive their result from their arguments alone.
     */
    without(props: CallProps): readonly Identifier[];
    /** Every built-in flowR states computes a result and nothing else ({@link CallProp.Pure}). */
    get pure(): readonly Identifier[];
    /** Every built-in the value solver can fold to a constant (the ones with a `evalHandler`). */
    get folding(): readonly Identifier[];
    /** Every parameter whose argument carries at least one bit of `props`, like {@link ArgProp.Resource}. */
    params(props: ArgProps): BuiltInParam[];
    /** What the index states about `name`, ignoring any namespace (built-ins are registered by their bare name). */
    get(name: Identifier): BuiltInEntry | undefined;
    /** The {@link CallProp} bits of `name`, `undefined` when no built-in of that name states any. */
    propsOf(name: Identifier): CallProps | undefined;
}
