import type { AgencyConfig } from "./config.js"; import type { AgencyProgram, FunctionMarkers, FunctionParameter, Tag, TypeParam, ValueParam, VariableType } from "./types.js"; import type { SourceLocation } from "./types/base.js"; import type { ImportNodeStatement, ImportStatement } from "./types/importStatement.js"; import type { ExportFromStatement } from "./types/exportFromStatement.js"; import type { EffectDeclaration } from "./types/effectDeclaration.js"; export type InterruptEffect = { effect: string; }; /** Marker on a SymbolInfo that entered FileSymbols via an `export from` re-export. */ export type ReExportedFrom = { sourceFile: string; originalName: string; }; export type FunctionSymbol = { kind: "function"; name: string; loc?: SourceLocation; markers?: FunctionMarkers; exported: boolean; parameters: FunctionParameter[]; returnType: VariableType | null; returnTypeValidated?: boolean; interruptEffects?: InterruptEffect[]; reExportedFrom?: ReExportedFrom; }; export type NodeSymbol = { kind: "node"; name: string; loc?: SourceLocation; parameters: FunctionParameter[]; returnType: VariableType | null; returnTypeValidated?: boolean; exported?: boolean; interruptEffects?: InterruptEffect[]; reExportedFrom?: ReExportedFrom; }; export type TypeSymbol = { kind: "type"; name: string; loc?: SourceLocation; exported: boolean; aliasedType: VariableType; /** Type parameters for generic aliases (e.g., `T` in `type Container = ...`). */ typeParams?: TypeParam[]; /** Value parameters for value-parameterized aliases (e.g. `low` and `high` * in `type NumberInRange(low: number, high: number) = number`). * Carried through imports/re-exports alongside `typeParams`. */ valueParams?: ValueParam[]; /** `@validate(...)` / `@jsonSchema(...)` annotations declared above the alias. * Carried through imports/re-exports so annotation metadata flows across modules. */ tags?: Tag[]; /** True when declared via `effectSet` (not `type`). Carried through imports * so an imported effect set is recognized as one. */ isEffectSet?: boolean; reExportedFrom?: ReExportedFrom; }; export type ConstantSymbol = { kind: "constant"; name: string; loc?: SourceLocation; exported: boolean; reExportedFrom?: ReExportedFrom; }; export type SymbolInfo = FunctionSymbol | NodeSymbol | TypeSymbol | ConstantSymbol; export type SymbolKind = SymbolInfo["kind"]; /** Maps symbol name → info for a single file. */ export type FileSymbols = Record; export type ImportModuleResolution = { kind: "missing"; } | { kind: "notLoaded"; } | { kind: "loaded"; symbols: FileSymbols; }; /** * One named symbol resolved through an import: where it lives, what name * the importing file uses, and what it actually is. */ export type ResolvedImport = { file: string; originalName: string; localName: string; symbol: SymbolInfo; }; /** * Cross-file index of every declaration reachable from an entrypoint. * Built eagerly: parses every reachable .agency file, classifies its * top-level (and nested type-alias) declarations, and follows imports. */ export declare class SymbolTable { private readonly files; private readonly effectDecls; constructor(files?: Record, effectDecls?: Record); /** * @param overrides Maps an absolute file path to in-memory source that * replaces the on-disk contents for that file. The LSP passes the active * editor buffer here so an unsaved edit (e.g. a just-typed `import`) is * reflected in the symbol table without waiting for a save. Keyed by * `path.resolve`d absolute path to match how `visit` normalizes paths. */ static build(entrypoint: string | string[], config?: AgencyConfig, overrides?: Record): SymbolTable; has(absPath: string): boolean; getFile(absPath: string): FileSymbols | undefined; /** * Classify an import's target module for the strict-imports check. * - `missing` — the path resolves to nothing on disk, or resolution threw * (e.g. an unresolvable `pkg::`). * - `notLoaded` — the file exists on disk but was never crawled into this * table (a parse failure in it, or a partial single-file * check). The caller must stay silent: the view is incomplete. * - `loaded` — the file was crawled; `symbols` is its FileSymbols. */ resolveImportModule(modulePath: string, fromFile: string, config?: AgencyConfig): ImportModuleResolution; /** Every effect declaration reachable in the closure, tagged with its * source file. Includes duplicates so the typechecker can detect * same-file dups and cross-file conflicts. */ allEffectDeclarations(): { decl: EffectDeclaration; file: string; }[]; filePaths(): string[]; /** * Walk every file looking for a type alias with the given name. Returns * the first match in iteration order. Used to surface imported type * definitions for Zod schema generation. */ findTypeAcrossFiles(name: string): SymbolInfo | undefined; /** * Resolve every named symbol in an import statement to its source file * + SymbolInfo. Skips namespace and default imports. Returns [] for * non-Agency imports. */ resolveImport(stmt: ImportStatement, fromFile: string): ResolvedImport[]; resolveImportedNodes(stmt: ImportNodeStatement, fromFile: string): ResolvedImport[]; } /** * Walk the top-level program node list to find `@tag(...)` nodes * sitting directly above type aliases, returning a map from alias name * to its pending tag list. This mirrors what the TypescriptPreprocessor's * `attachTags` does later in the pipeline, but happens early so symbol * table consumers (other modules that import this alias) see annotations * attached to the TypeSymbol. * * Pre-pass only, no mutation: keeps SymbolTable.build idempotent and * decoupled from the preprocessor. */ export declare function collectTypeAliasTags(program: AgencyProgram): Record; /** * Classify symbols in a parsed Agency program. * Uses walkNodes to find symbols at all nesting levels (e.g. type aliases inside functions). */ export declare function classifySymbols(program: AgencyProgram): FileSymbols; export declare function isExportedSymbol(sym: SymbolInfo): boolean; /** * Merge symbols flowing through one `exportFromStatement` from `sourcePath` * into the re-exporter's `FileSymbols`. Hard errors on missing symbols, * non-exported sources, and collisions. */ export declare function mergeExportsFrom(files: Record, reExporterPath: string, sourcePath: string, stmt: ExportFromStatement): void;