import type { DecodedFunction } from '../../project/sigdb/decode';
/**
 * What a single argument of a call is used for, as a bitmask.
 * @see {@link BuiltInFnInfo#sig}
 */
export declare enum ArgProp {
    /** the result is this argument, handed back unchanged, like `x` in `identity(x)`; this is what draws the `Returns` edge */
    Alias = 1,
    /** the result is computed from the argument's value, like `x` in `sum(x)` */
    Value = 2,
    /** only the shape is used (length, dimensions, names, other attributes), like `x` in `nrow(x)` */
    Shape = 4,
    /** selects a behavior instead of carrying data, like `na.rm` in `sum(x, na.rm = TRUE)` */
    Flag = 8,
    /** names the resource the call reads or writes, like `file` in `write.csv(x, file)` */
    Resource = 16,
    /** what it refers to may be modified, like `envir` in `assign(x, v, envir = e)` */
    Written = 32,
    /** evaluated whenever the call happens, even if the result goes unused, like `x` in `force(x)` */
    Forced = 64,
    /** quoted or evaluated in another frame, like `expr` in `quote(expr)` */
    Nse = 128,
    /** called as a function, like `FUN` in `lapply(x, FUN)` */
    Callee = 256,
    /** only whether it was supplied matters, as with `missing()` */
    Presence = 512,
    /**
     * the result is one of this argument's values, like `choices` in `match.arg(arg, choices)`. The bounding
     * argument of a {@link CallProp.Narrows} call; without one such a call yields a value of its own making.
     */
    Bounds = 1024,
    /**
     * only atomic data works here, never a closure, as with `e1` in `e1 > e2`. A bare symbol in such an
     * argument therefore names a variable even when a function of that name is in scope.
     */
    Atomic = 2048,
    /** the open handle the call acts on, like `con` in `close(con)` */
    Handle = 4096
}
/**
 * What the call as a whole does, as a bitmask. The resource bits ({@link CallProp.File} and its neighbors)
 * say where the call gets its data from, which is what {@link InputProps} collects.
 * @see {@link BuiltInFnInfo#props}
 */
export declare enum CallProp {
    /** computes a result and nothing else, the positive counterpart of `hasUnknownSideEffects` (excludes {@link ImpureProps}) */
    Pure = 1,
    /**
     * pure on its own, but it runs code it is handed, so whatever that code does happens too.
     * The parameter it runs is marked {@link ArgProp.Callee} or {@link ArgProp.Nse}, as with `lapply(x, f)`.
     */
    MayPure = 2,
    /** may signal an error, like `stop()` (see {@link SigDbInferable}) */
    Throws = 4,
    /** returns invisibly, so the result is not auto-printed */
    Invisible = 8,
    /** dispatches on the class of an argument (S3, S4, or S7), a group generic like `+` on either operand */
    Generic = 16,
    /** a method that is reached by dispatch, like `print.foo` (see {@link SigDbInferable}) */
    Method = 32,
    /** binds, rebinds, or removes names outside of its own frame, like `assign` or `library` */
    Scope = 64,
    /** the result may differ between two identical calls for a reason neither `Random` nor `Ambient` covers (see {@link SigDbInferable}) */
    NonDet = 128,
    /** draws from the random number generator, or sets its state (stated instead of `NonDet`) */
    Random = 256,
    /** depends on ambient state like the clock, the locale, environment variables, or global options (stated instead of `NonDet`) */
    Ambient = 512,
    /** touches the file system */
    File = 1024,
    /** produces a temporary path; on its own this touches no file system, so a call that also does states `File` too */
    TempFile = 2048,
    /**
     * always reaches the network, like `curl::curl_download`. Calls that only do so for some arguments, like
     * `read.csv` of a URL, are left to the `network-functions` rule, which decides that per call site.
     */
    Network = 4096,
    /** runs a system command */
    Process = 8192,
    /** calls native code through the foreign function interface, like `.Call` */
    Ffi = 16384,
    /** produces a language object, like `quote` or `deparse` */
    Lang = 32768,
    /** asks the user, like `readline` or a file chooser */
    User = 65536,
    /** draws on a graphics device */
    Graphics = 131072,
    /** talks to a database */
    Database = 262144,
    /** reads the resource its `Resource` arguments name */
    Reads = 524288,
    /** writes the resource its `Resource` arguments name */
    Writes = 1048576,
    /** may emit to standard output, like `print` or a `cat` without a `file`, and follows a `sink` when one is active */
    Prints = 2097152,
    /**
     * the result is bounded no matter what flows in: a count, an index, a logical, or one of the values of the
     * argument marked {@link ArgProp.Bounds}. So nothing an argument carries reaches the result, which is what
     * lets the input-sources query stop tracing at `length(x)` or `match.arg(arg, choices)`.
     */
    Narrows = 4194304,
    /**
     * sets ambient state later calls read back: the working directory, environment variables, options, the
     * locale, the RNG seed. The counterpart of {@link CallProp.Ambient}; a call doing both states both.
     */
    Configures = 8388608,
    /** ends what an opener started: a graphics device, a connection, a sink. Narrower than {@link CallProp.Graphics}. */
    Closes = 16777216,
    /** yields the paths it matches at run time rather than one it was handed (`list.files`, `Sys.glob`); empty is an answer */
    Glob = 33554432,
    /** hands back what the program was invoked with, as `commandArgs` and the option parsers built on it do */
    CommandLine = 67108864,
    /** hands back a handle the program is expected to close again, like `file` or `DBI::dbConnect` */
    Opens = 134217728
}
/**
 * The {@link CallProp} bits that state an effect beyond computing a result, so no {@link CallProp.Pure}
 * definition may carry any of them.
 */
export declare const ImpureProps: number;
/**
 * Which {@link CallProp} bits rule each other out, as `[bit, everything stating it forbids]`. A definition
 * that carries the left bit must carry none of the right ones; a test checks the {@link DefaultBuiltinConfig}
 * (and any configured built-ins) against this. Every other pair of bits combines freely.
 */
export declare const ExclusiveCallProps: readonly (readonly [bit: CallProp, forbidden: CallProps])[];
/**
 * The {@link CallProp} bits of calls that bring in data of their own. A function that states its props and
 * carries none of these derives its result from its arguments, which is what {@link BuiltInIndex#without}
 * looks for.
 */
export declare const InputProps: number;
/**
 * The {@link CallProp} bits the signature database states itself, so {@link fnInfoFromSignature} can read them
 * off any package function without anyone writing them down.
 */
export declare const SigDbInferable: number;
/**
 * The {@link CallProp} bits that say a call takes its data from a file, as {@link CallProp.File} alone also
 * covers the calls that only write one.
 */
export declare const FileInputProps: number;
/**
 * The {@link CallProp} bits that carry over from a callee to its caller: what the called function does, the
 * calling one does too. Purity does not travel this way, which is why it is not in here.
 */
export declare const PropagatedProps: number;
/** a bitfield of {@link ArgProp} */
export type ArgProps = number;
/** a bitfield of {@link CallProp} */
export type CallProps = number;
/**
 * The formals of a built-in, in the order they are declared in, each with what its argument is used for.
 * A `...` entry stands for every argument from the position it appears at, and the entries behind it are matched
 * by their full name only.
 */
export type FnSig = [name: string, props: ArgProps][];
/**
 * Utility functions for {@link FnSig|function signatures}.
 */
export declare const FnSig: {
    readonly name: "FnSig";
    /** The positional view of a signature; see {@link sigLayout}. */
    readonly layout: typeof sigLayout;
    /** The roles of the argument at a position; see {@link argProp}. */
    readonly propAt: typeof argProp;
    /** The positions carrying any of the given roles; see {@link argsWith}. */
    readonly posWith: typeof argsWith;
};
/** What a call states about itself, as words rather than as a bit mask, for anything showing it to a reader. */
export declare function callPropWords(props: CallProps | undefined): string[];
/**
 * Semantics of a built-in that hold no matter which processor handles the call. The remaining facts already
 * have a home: the exit behavior in `cfg`, whether flowR can fold the call in the `evalHandler` of the
 * definition, and the fallback for everything unmodelled in `hasUnknownSideEffects`.
 */
export interface BuiltInFnInfo {
    /** the parameters and what each of their arguments is used for */
    readonly sig?: FnSig;
    /** bitfield of {@link CallProp} */
    readonly props?: CallProps;
    /** keep the environment on the call vertex, for a later pass to look names up in */
    readonly keepEnvironment?: boolean;
}
/** A {@link FnSig} in the form the call processors use it, see {@link sigLayout}. */
export interface SigLayout {
    /** the props of each declared parameter, in order */
    readonly props: readonly ArgProps[];
    /** the position of the `...` parameter, `-1` if there is none */
    readonly rest: number;
    /** every bit some parameter carries, so a call can skip the bits nobody uses */
    readonly any: ArgProps;
    /** the position of the {@link ArgProp.Alias} argument, handed back as the result, `-1` if there is none */
    readonly alias: number;
}
/**
 * The positional view of a {@link FnSig}, computed on first use and cached per signature object,
 * so declaring a signature costs nothing until a call actually needs it.
 */
declare function sigLayout(this: void, sig: FnSig): SigLayout;
/** The {@link ArgProp} bits of the argument at `index`, with `...` covering every position from where it appears. */
declare function argProp(this: void, { props, rest }: SigLayout, index: number): ArgProps;
/** The positions of the first `count` arguments that carry any of `prop`. */
declare function argsWith(this: void, layout: SigLayout, count: number, prop: ArgProps): number[];
/** the callees that make the calling function itself a generic ({@link CallProp.Generic}) */
export declare const DispatchCallees: ReadonlySet<string>;
/**
 * The part of a {@link BuiltInFnInfo} that the signature database already knows: the parameter names in order
 * (`...` included) with the ones R always forces, plus the properties listed in {@link SigDbProps}. Everything
 * else the database records (`higher-order`, `deprecated`, `recursive`, ...) has no counterpart here and is
 * dropped, and anything it cannot see (purity, resources, what an argument is used for) stays unset.
 */
export declare function fnInfoFromSignature(fn: DecodedFunction): BuiltInFnInfo;
export {};
