/** * Syntactic (checker-free) edge resolver — the fast-tier resolver. * * Resolves a call site from two signals only, never the type checker: * 1. the callee's simple name (`foo` in `foo()`, the rightmost name in * `a.b.c()`, the tag in ``, etc.), extracted syntactically; * 2. the importing file's import graph — which module each name was * imported from — used to disambiguate same-named functions across * files. * * This generalizes the exact resolver's already-name-based * `resolveByCatalogFallback`: that seed resolves a unique name with no * file context; this adds import/same-file *pinning* to pick the right * occurrence when a name is ambiguous. * * Honest approximation (the core invariant in code): every verdict is * tagged `resolution: 'syntactic'` and confidence is CAPPED — `'medium'` * when the import graph (or a same-file definition) pinned the target * file, `'low'` otherwise. The fast path NEVER emits `'high'`; high * confidence is reserved for semantic resolution. */ import ts from 'typescript'; import type { Catalog, ResolverVerdict } from '@opensip-cli/graph'; /** * Per-file import index: imported binding name → resolved target file * (project-relative POSIX path), or `null` when the import resolves * outside the catalog (external/bare package, unresolvable relative * path). Built once per source file by {@link buildImportIndex}. */ export type ImportIndex = ReadonlyMap; /** Context for a single syntactic resolution — all checker-free. */ export interface SyntacticContext { readonly catalog: Catalog; /** Project-relative POSIX path of the file containing the call site. */ readonly currentFileRel: string; /** Import index for {@link currentFileRel}. */ readonly importIndex: ImportIndex; /** Import binding metadata used to translate caller-local named aliases. */ readonly importBindings?: ReadonlyMap; } /** * Collect the set of project-relative file paths the catalog knows about * (every occurrence carries one). Used to decide whether a resolved * import specifier lands inside the catalog. */ export declare function collectKnownFiles(catalog: Catalog): ReadonlySet; /** * Resolve a single walked call/new/jsx/value-reference node to a verdict * using only the callee name and the file's import graph. * * Returns `null` for a bare value reference / shorthand that resolves to * nothing (mirrors the exact resolver, which suppresses empty * value-reference verdicts rather than emitting a useless edge). A real * call/new/jsx site that doesn't resolve still returns a verdict (with * `to: []`) so it is counted as an unresolved call site. */ export declare function resolveSyntactic(node: ts.Node, ctx: SyntacticContext): ResolverVerdict | null; export interface Callee { readonly name: string; /** Imported receiver binding for a qualified/member call, when syntactically known. */ readonly bindingName?: string; /** 'call' = call/new/jsx (a real invocation); 'ref' = bare value reference. */ readonly shape: 'call' | 'ref'; } /** * Extract the callee's simple name from a walked resolver-candidate node, * purely syntactically. Returns `null` when no simple name is available * (e.g. an element-access call `a[b]()` or a computed tag). * * Exported so the cross-shard boundary extractor can identify a call * site's callee name without re-implementing the per-node-kind logic. */ export declare function calleeSimpleName(node: ts.Node): Callee | null; /** * The node whose start position anchors a call/new edge's `(line, column)` * identity — the CALLEE token, not the whole expression's start: * - `x.m()` → `m` (the method name) * - `f()` → `f` (the callee identifier — unchanged for plain calls) * - `new C()` → `C` (the class name, not the `new` keyword) * - `new ns.C()` → `C` * * WHY: a chained call `a().b()` (or `new A().b()`) has its inner CallExpression * `a()` and its outer CallExpression `a().b()` BOTH starting at `a`, so keying an * edge by the expression start collapses the two DISTINCT, REAL edges onto one * `(owner, line, column)` identity — one shadows the other, and the exact and * sharded engines keep different members of the pair (a spurious "conflict" * divergence; see ADR-0033 follow-up). Anchoring at the callee token gives every * call in a chain a distinct column, so both real edges survive in both engines. * Non-call/new nodes (JSX elements, identifiers) keep their own start. */ export declare function calleeAnchorNode(node: ts.Node): ts.Node; /** * Build the per-file import index by reading the file's `import` / * `import =` statements and resolving each specifier to a project file * (or `null` when it resolves outside the catalog). No type checker, no * `ts.Program` — relative specifiers are resolved against the known-file * set syntactically; bare specifiers are treated as external. */ export declare function buildImportIndex(sourceFile: ts.SourceFile, projectDirAbs: string, knownFilesRel: ReadonlySet): ImportIndex; /** * Build a per-file index of imported binding name → the RAW import * specifier it came from (`'./x.js'`, `'@scope/pkg'`). Distinct from * {@link buildImportIndex} (which resolves to a project file): the * cross-shard boundary pass needs the raw specifier to re-resolve against * the GLOBAL catalog, where the target file may live in another shard not * present in this file's known-file set. */ export declare function buildImportSpecifierIndex(sourceFile: ts.SourceFile): ReadonlyMap; /** Raw module source for one imported local binding. */ export interface ImportBindingSource { readonly specifier: string; /** * Source module's exported name when the local binding aliases a named import * (`source` in `import { source as local }`). Absent when no name translation * is required. */ readonly importedName?: string; } /** * Build the richer import-binding index used by cross-shard boundary * extraction. Unlike {@link buildImportSpecifierIndex}, it preserves the * exported/source name for aliased named imports so the engine does not try to * find the caller-local alias in the imported module. * * Default, namespace, and `import =` bindings intentionally carry only their * specifier: their local spelling has no named-export translation this model * can attest. */ export declare function buildImportBindingSourceIndex(sourceFile: ts.SourceFile): ReadonlyMap; //# sourceMappingURL=syntactic.d.ts.map