import type { ParserDef } from '../types.ts'; /** * Per-node children/fields/raw/trivia/state capture is dead work when the build * never declares the corresponding formal param. This module derives a build's * *confirmed* formal-parameter arity so the compiler and macro can elide their * direct-AST-only CST collectors without changing structural/CST output. * * Conservative by construction: any source we can't confidently parse — rest params, * destructuring, `arguments`, an unrecognized shape — yields `null` (arity unknown), * and callers KEEP full capture. We only ever return a number when the parameter list * is a plain comma-separated list of simple identifiers. */ type NodeDef = Extract; /** * Is a positioned-CST host installed for this parse? * * `cstBuildHost` (and the language-service hosts) mark themselves with * `_parsemanCstOutput`. That flag is what re-routes a node with its OWN direct builder * through the host — and therefore what makes the direct builder's formal arity the * WRONG basis for eliding capture, since the consumer is no longer that builder. * * The COMPILED engine answers this at compile time (`hostMode`, 0.37.0). The interpreter * has no compile step, so it asks per parse. */ export declare function cstOutputHost(build: unknown): boolean; /** * Confirmed count of simple formal parameters the build declares, or `null` when the * source can't be parsed into a plain identifier list (→ caller keeps full capture). */ export declare function confirmedBuildArity(src: string): number | null; /** * Prove that one simple positional formal is never referenced by a reducer. * * This deliberately answers a BOOLEAN rather than `boolean | null`: `false` means * either "used" OR "not provably unused", and callers keep capture in both cases. * The proof accepts only the same plain-parameter shapes as arity analysis and then * counts exact identifier tokens across the whole source. The declaration is the one * permitted occurrence; any second occurrence — including a comment, string, shadowed * binding, or nested closure — conservatively keeps the value. * * Dynamic name lookup is an unconditional refusal. `eval`, `Function`, `with`, and * `arguments` can observe a value without leaving a statically attributable identifier * read. False positives merely retain work; a false negative would change a builder's * input, so there is no speculative branch here. */ export declare function confirmedBuildParamUnused(src: string, index: number): boolean; /** * The source a def's arity/shape analysis must read. * * `buildSrc` is the source text of the EXPRESSION written at the `node(...)` call * site. When the reducer is passed as a bare identifier — `node('Foo', p, { build: * foldOperation })` — that text is just `"foldOperation"`, which matches no parameter * list and used to fail open into all five capture tiers, silently. The macro plugin * already holds the whole module's AST, so it resolves such an identifier to its * module-scope declaration and parks that declaration's source here. `buildSigSrc` is * ANALYSIS-ONLY: it is never emitted, so the generated builder reference is unchanged. */ export declare function buildAnalysisSrc(def: NodeDef): string; /** * Confirmed formal arity for a node def, reporting once when it cannot be confirmed. * * Order of authority: * 1. `node(..., { buildArity })` — the author DECLARED it. Nothing overrides that. * 2. `def.buildArity` as resolved by the macro's reducer resolver (real scope analysis * and cross-module import following). * 3. Reading the parameter list out of whatever source we have. * * Fail-open is the correct BEHAVIOR — capturing too much is safe, capturing too little * is a correctness bug. Fail-open with no diagnostic was the defect. But a diagnostic is * the right answer only for the genuinely undecidable; for everything a static analysis * can decide, the right answer is to decide it, which is why (2) exists and why (1) gives * the author a way out of (3) entirely. */ export declare function confirmedArityForDef(def: NodeDef): number | null; /** Build reads its 1st (`children`) arg? Unknown/unparseable → true (keep capture). */ export declare function buildReadsChildren(def: NodeDef): boolean; /** Build reads its 4th (`rawChildren`) arg? Unknown/unparseable → true (keep capture). */ export declare function buildReadsRaw(def: NodeDef): boolean; /** Build reads the 5th (triviaLog) arg? Unknown/unparseable → true (keep capture). */ export declare function buildReadsTrivia(def: NodeDef): boolean; /** Build reads the 6th (state) arg? Unknown/unparseable → true (keep state clone). */ export declare function buildReadsState(def: NodeDef): boolean; export {}; //# sourceMappingURL=build-arity.d.ts.map