import type { CompilationUnit } from "../compilationUnit.js"; import { AgencyConfig } from "../config.js"; import { AgencyProgram, VariableType } from "../types.js"; import { TypeCheckError, TypeCheckResult } from "./types.js"; export type { TypeCheckError, TypeCheckResult } from "./types.js"; export declare class TypeChecker { private program; private config; private scopedTypeAliases; private currentScopeKey; private functionDefs; private nodeDefs; private importedFunctions; private jsImportedNames; private interruptEffectsByFunction; private symbolTable?; private currentFile?; private errors; private inferredReturnTypes; private inferringReturnType; private sourceText; constructor(program: AgencyProgram, config?: AgencyConfig, info?: CompilationUnit); private get typeAliases(); private withScope; private makeContext; check(): TypeCheckResult; /** Validated params let a function short-circuit with a failure before * the body runs. An explicit non-Result return type contradicts that. * (Unannotated returns are auto-wrapped during inference instead.) */ private checkValidatedParamReturns; /** Doc strings must not interpolate function/node parameters. The * description is built when the tool object is constructed at module * load time — long before the function is ever called — so parameter * values are simply not bound yet. Catch the obvious case here: * `${param}` as a top-level interpolation expression. */ private checkDocStringParams; /** Locations of locally-declared type aliases, for diagnostics raised * from the alias TABLE (which carries no locs). Imported aliases are not * in program.nodes and resolve to null (file-level diagnostic). Keyed by * bare name: a same-named alias in another scope wins last-visited, so a * diagnostic can anchor on the wrong (same-file) declaration — accepted * imprecision, still strictly better than no location. */ private collectAliasDeclLocs; /** Stamp the source file onto every diagnostic, once. One checker instance * checks exactly one file (ctx.currentFile), so a single pass here beats * threading the file through every push site. */ private stampFileOnErrors; private applySuppressions; private deduplicateErrors; /** Delegating method preserved for test compatibility. */ isAssignable(source: VariableType, target: VariableType): boolean; } export declare function typeCheck(program: AgencyProgram, config?: AgencyConfig, info?: CompilationUnit): TypeCheckResult; /** * Drop exact duplicates: same code, same rendered message, and same position. * The message stays in the key deliberately — one code can render different * params at one position (e.g. two assignability checks against different * expected types), and both must survive. This is the emit-once band-aid * until synth becomes pure (issue: emit-once follow-up); the key just must * never be LOSSIER than code+message+position. */ export declare function dedupeErrors(errors: TypeCheckError[]): TypeCheckError[]; export declare function formatErrors(errors: TypeCheckError[]): string; /** * One-line discovery hint printed AFTER the error block, naming the first * error-severity diagnostic. Returns null when no error-severity diagnostic * is present (warnings-only output gets no hint). Kept OUT of formatErrors * so programmatic consumers (compile.ts, serve.ts) are untouched — only the * human/agent-facing print sites append it. */ export declare function formatDiagnosticsHint(errors: TypeCheckError[]): string | null;