gitnexus 1.6.2 → 1.6.3-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_shared/index.d.ts +45 -0
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js +33 -0
- package/dist/_shared/index.js.map +1 -1
- package/dist/_shared/scope-resolution/def-index.d.ts +36 -0
- package/dist/_shared/scope-resolution/def-index.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/def-index.js +51 -0
- package/dist/_shared/scope-resolution/def-index.js.map +1 -0
- package/dist/_shared/scope-resolution/evidence-weights.d.ts +69 -0
- package/dist/_shared/scope-resolution/evidence-weights.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/evidence-weights.js +84 -0
- package/dist/_shared/scope-resolution/evidence-weights.js.map +1 -0
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +139 -0
- package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/finalize-algorithm.js +479 -0
- package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -0
- package/dist/_shared/scope-resolution/language-classification.d.ts +26 -0
- package/dist/_shared/scope-resolution/language-classification.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/language-classification.js +44 -0
- package/dist/_shared/scope-resolution/language-classification.js.map +1 -0
- package/dist/_shared/scope-resolution/method-dispatch-index.d.ts +80 -0
- package/dist/_shared/scope-resolution/method-dispatch-index.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/method-dispatch-index.js +79 -0
- package/dist/_shared/scope-resolution/method-dispatch-index.js.map +1 -0
- package/dist/_shared/scope-resolution/module-scope-index.d.ts +46 -0
- package/dist/_shared/scope-resolution/module-scope-index.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/module-scope-index.js +58 -0
- package/dist/_shared/scope-resolution/module-scope-index.js.map +1 -0
- package/dist/_shared/scope-resolution/origin-priority.d.ts +14 -0
- package/dist/_shared/scope-resolution/origin-priority.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/origin-priority.js +21 -0
- package/dist/_shared/scope-resolution/origin-priority.js.map +1 -0
- package/dist/_shared/scope-resolution/position-index.d.ts +62 -0
- package/dist/_shared/scope-resolution/position-index.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/position-index.js +134 -0
- package/dist/_shared/scope-resolution/position-index.js.map +1 -0
- package/dist/_shared/scope-resolution/qualified-name-index.d.ts +44 -0
- package/dist/_shared/scope-resolution/qualified-name-index.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/qualified-name-index.js +75 -0
- package/dist/_shared/scope-resolution/qualified-name-index.js.map +1 -0
- package/dist/_shared/scope-resolution/registries/class-registry.d.ts +27 -0
- package/dist/_shared/scope-resolution/registries/class-registry.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/registries/class-registry.js +30 -0
- package/dist/_shared/scope-resolution/registries/class-registry.js.map +1 -0
- package/dist/_shared/scope-resolution/registries/context.d.ts +69 -0
- package/dist/_shared/scope-resolution/registries/context.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/registries/context.js +44 -0
- package/dist/_shared/scope-resolution/registries/context.js.map +1 -0
- package/dist/_shared/scope-resolution/registries/evidence.d.ts +56 -0
- package/dist/_shared/scope-resolution/registries/evidence.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/registries/evidence.js +150 -0
- package/dist/_shared/scope-resolution/registries/evidence.js.map +1 -0
- package/dist/_shared/scope-resolution/registries/field-registry.d.ts +26 -0
- package/dist/_shared/scope-resolution/registries/field-registry.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/registries/field-registry.js +31 -0
- package/dist/_shared/scope-resolution/registries/field-registry.js.map +1 -0
- package/dist/_shared/scope-resolution/registries/lookup-core.d.ts +81 -0
- package/dist/_shared/scope-resolution/registries/lookup-core.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/registries/lookup-core.js +332 -0
- package/dist/_shared/scope-resolution/registries/lookup-core.js.map +1 -0
- package/dist/_shared/scope-resolution/registries/lookup-qualified.d.ts +33 -0
- package/dist/_shared/scope-resolution/registries/lookup-qualified.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/registries/lookup-qualified.js +56 -0
- package/dist/_shared/scope-resolution/registries/lookup-qualified.js.map +1 -0
- package/dist/_shared/scope-resolution/registries/method-registry.d.ts +36 -0
- package/dist/_shared/scope-resolution/registries/method-registry.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/registries/method-registry.js +32 -0
- package/dist/_shared/scope-resolution/registries/method-registry.js.map +1 -0
- package/dist/_shared/scope-resolution/registries/tie-breaks.d.ts +43 -0
- package/dist/_shared/scope-resolution/registries/tie-breaks.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/registries/tie-breaks.js +60 -0
- package/dist/_shared/scope-resolution/registries/tie-breaks.js.map +1 -0
- package/dist/_shared/scope-resolution/resolve-type-ref.d.ts +53 -0
- package/dist/_shared/scope-resolution/resolve-type-ref.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/resolve-type-ref.js +126 -0
- package/dist/_shared/scope-resolution/resolve-type-ref.js.map +1 -0
- package/dist/_shared/scope-resolution/scope-id.d.ts +43 -0
- package/dist/_shared/scope-resolution/scope-id.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/scope-id.js +46 -0
- package/dist/_shared/scope-resolution/scope-id.js.map +1 -0
- package/dist/_shared/scope-resolution/scope-tree.d.ts +61 -0
- package/dist/_shared/scope-resolution/scope-tree.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/scope-tree.js +186 -0
- package/dist/_shared/scope-resolution/scope-tree.js.map +1 -0
- package/dist/_shared/scope-resolution/shadow/aggregate.d.ts +63 -0
- package/dist/_shared/scope-resolution/shadow/aggregate.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/shadow/aggregate.js +122 -0
- package/dist/_shared/scope-resolution/shadow/aggregate.js.map +1 -0
- package/dist/_shared/scope-resolution/shadow/diff.d.ts +59 -0
- package/dist/_shared/scope-resolution/shadow/diff.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/shadow/diff.js +79 -0
- package/dist/_shared/scope-resolution/shadow/diff.js.map +1 -0
- package/dist/_shared/scope-resolution/symbol-definition.d.ts +34 -0
- package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/symbol-definition.js +12 -0
- package/dist/_shared/scope-resolution/symbol-definition.js.map +1 -0
- package/dist/_shared/scope-resolution/types.d.ts +356 -0
- package/dist/_shared/scope-resolution/types.d.ts.map +1 -0
- package/dist/_shared/scope-resolution/types.js +17 -0
- package/dist/_shared/scope-resolution/types.js.map +1 -0
- package/dist/core/ingestion/call-processor.d.ts +2 -1
- package/dist/core/ingestion/language-provider.d.ts +172 -1
- package/dist/core/ingestion/model/field-registry.d.ts +1 -1
- package/dist/core/ingestion/model/index.d.ts +1 -1
- package/dist/core/ingestion/model/index.js +2 -0
- package/dist/core/ingestion/model/method-registry.d.ts +1 -1
- package/dist/core/ingestion/model/registration-table.d.ts +1 -2
- package/dist/core/ingestion/model/resolution-context.d.ts +1 -1
- package/dist/core/ingestion/model/resolve.d.ts +1 -1
- package/dist/core/ingestion/model/symbol-table.d.ts +1 -23
- package/dist/core/ingestion/model/type-registry.d.ts +1 -1
- package/dist/core/search/phase-timer.d.ts +72 -0
- package/dist/core/search/phase-timer.js +106 -0
- package/dist/mcp/local/local-backend.d.ts +48 -1
- package/dist/mcp/local/local-backend.js +345 -135
- package/dist/mcp/tools.js +19 -1
- package/package.json +1 -1
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope-resolution type definitions — RFC §2 data model (authoritative source).
|
|
3
|
+
*
|
|
4
|
+
* See: https://www.notion.so/346dc50b6ed281cfaacbe480bf231d50
|
|
5
|
+
*
|
|
6
|
+
* Anti-drift rule: every type, interface, and enum defined here is the single
|
|
7
|
+
* source of truth. Later code that references these names must import them
|
|
8
|
+
* from `gitnexus-shared`; it must not re-define them locally.
|
|
9
|
+
*
|
|
10
|
+
* Lifecycle contract (RFC §2.8): scopes are **constructed during extraction,
|
|
11
|
+
* linked during finalize, immutable after finalize**. All fields are
|
|
12
|
+
* `readonly` at the type level; `Object.freeze` is applied at runtime in dev
|
|
13
|
+
* builds. `ReferenceIndex` is the sole structure populated after freeze — by
|
|
14
|
+
* resolution, before emission.
|
|
15
|
+
*/
|
|
16
|
+
import type { NodeLabel } from '../graph/types.js';
|
|
17
|
+
import type { SymbolDefinition } from './symbol-definition.js';
|
|
18
|
+
/** Stable per-(file, range, kind) scope identifier; interned for identity-fast equality. */
|
|
19
|
+
export type ScopeId = string;
|
|
20
|
+
/** Stable symbol-definition identifier (graph nodeId). */
|
|
21
|
+
export type DefId = string;
|
|
22
|
+
/** Kinds of lexical scope a `Scope` node can represent. */
|
|
23
|
+
export type ScopeKind = 'Module' | 'Namespace' | 'Class' | 'Function' | 'Block' | 'Expression';
|
|
24
|
+
/** Source-text range. 1-based `startLine`/`endLine`; 0-based `startCol`/`endCol`. */
|
|
25
|
+
export interface Range {
|
|
26
|
+
readonly startLine: number;
|
|
27
|
+
readonly startCol: number;
|
|
28
|
+
readonly endLine: number;
|
|
29
|
+
readonly endCol: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Tagged capture emitted by a LanguageProvider's `emitScopeCaptures` hook.
|
|
33
|
+
*
|
|
34
|
+
* Parser-agnostic: tree-sitter queries and COBOL's regex tagger both produce
|
|
35
|
+
* `Capture[]`. The central `ScopeExtractor` consumes captures without
|
|
36
|
+
* knowing which parser produced them.
|
|
37
|
+
*/
|
|
38
|
+
export interface Capture {
|
|
39
|
+
/** Capture name, including leading `@` (e.g., `'@scope.module'`, `'@declaration.class'`). */
|
|
40
|
+
readonly name: string;
|
|
41
|
+
readonly range: Range;
|
|
42
|
+
/** The captured source text. */
|
|
43
|
+
readonly text: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A grouping of `Capture`s that came from a single query match (e.g., one
|
|
47
|
+
* `@import.statement` match carries `@import.source`, `@import.name`,
|
|
48
|
+
* `@import.alias?` as child captures). Keyed by capture name for O(1)
|
|
49
|
+
* child access.
|
|
50
|
+
*/
|
|
51
|
+
export type CaptureMatch = Readonly<Record<string, Capture>>;
|
|
52
|
+
/**
|
|
53
|
+
* Provider-interpreted raw import, consumed by finalize (Phase 2) to produce
|
|
54
|
+
* linked `ImportEdge[]`. The provider's `interpretImport` hook turns a
|
|
55
|
+
* `CaptureMatch` for an `@import.statement` into one of these; the central
|
|
56
|
+
* finalize algorithm resolves `targetRaw` to a concrete file via
|
|
57
|
+
* `resolveImportTarget` and materializes the final `ImportEdge`.
|
|
58
|
+
*
|
|
59
|
+
* Discriminated union — each variant carries only the fields that make sense
|
|
60
|
+
* for its kind. Invalid shapes (e.g., a `namespace` import with an alias-like
|
|
61
|
+
* `importedName` mismatch) are compile errors, not latent bugs. `'wildcard-
|
|
62
|
+
* expanded'` is deliberately NOT a variant: that kind is finalize output only,
|
|
63
|
+
* produced when `expandsWildcardTo` materializes a wildcard against target
|
|
64
|
+
* exports — a provider must never emit it at parse time.
|
|
65
|
+
*/
|
|
66
|
+
export type ParsedImport =
|
|
67
|
+
/**
|
|
68
|
+
* Per-name import without rename.
|
|
69
|
+
*
|
|
70
|
+
* Examples:
|
|
71
|
+
* - Python `from foo import X` → `{ kind: 'named', localName: 'X', importedName: 'X', targetRaw: 'foo' }`
|
|
72
|
+
* - TS `import { X } from './foo'` → `{ kind: 'named', localName: 'X', importedName: 'X', targetRaw: './foo' }`
|
|
73
|
+
* - Java `import foo.bar.X` → `{ kind: 'named', localName: 'X', importedName: 'X', targetRaw: 'foo.bar' }`
|
|
74
|
+
*/
|
|
75
|
+
{
|
|
76
|
+
readonly kind: 'named';
|
|
77
|
+
readonly localName: string;
|
|
78
|
+
readonly importedName: string;
|
|
79
|
+
readonly targetRaw: string;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Per-name import with rename.
|
|
83
|
+
*
|
|
84
|
+
* Examples:
|
|
85
|
+
* - Python `from foo import X as Y` → `{ kind: 'alias', localName: 'Y', importedName: 'X', alias: 'Y', targetRaw: 'foo' }`
|
|
86
|
+
* - TS `import { X as Y } from './foo'` → `{ kind: 'alias', localName: 'Y', importedName: 'X', alias: 'Y', targetRaw: './foo' }`
|
|
87
|
+
*/
|
|
88
|
+
| {
|
|
89
|
+
readonly kind: 'alias';
|
|
90
|
+
readonly localName: string;
|
|
91
|
+
readonly importedName: string;
|
|
92
|
+
readonly alias: string;
|
|
93
|
+
readonly targetRaw: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Qualified module handle, with or without rename. `importedName` is the
|
|
97
|
+
* module being aliased; `localName` is the scope-visible handle (often the
|
|
98
|
+
* same unless renamed).
|
|
99
|
+
*
|
|
100
|
+
* Examples:
|
|
101
|
+
* - Python `import numpy` → `{ kind: 'namespace', localName: 'numpy', importedName: 'numpy', targetRaw: 'numpy' }`
|
|
102
|
+
* - Python `import numpy as np` → `{ kind: 'namespace', localName: 'np', importedName: 'numpy', targetRaw: 'numpy' }`
|
|
103
|
+
* - TS `import * as np from 'numpy'` → `{ kind: 'namespace', localName: 'np', importedName: 'numpy', targetRaw: 'numpy' }`
|
|
104
|
+
* - Go `import foo "pkg/bar"` → `{ kind: 'namespace', localName: 'foo', importedName: 'bar', targetRaw: 'pkg/bar' }`
|
|
105
|
+
*/
|
|
106
|
+
| {
|
|
107
|
+
readonly kind: 'namespace';
|
|
108
|
+
/** Scope-visible handle (e.g. `np` in `import numpy as np`; `numpy` when unaliased). */
|
|
109
|
+
readonly localName: string;
|
|
110
|
+
/** Module being aliased (e.g. `numpy` in `import numpy as np`). */
|
|
111
|
+
readonly importedName: string;
|
|
112
|
+
readonly targetRaw: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Syntactically-detectable parse-time re-export. Finalize may still produce
|
|
116
|
+
* `ImportEdge { kind: 'reexport', transitiveVia }` when flattening chains;
|
|
117
|
+
* this variant preserves the *parse-time* signal so finalize doesn't have
|
|
118
|
+
* to re-derive it from scratch.
|
|
119
|
+
*
|
|
120
|
+
* Examples:
|
|
121
|
+
* - TS `export { X } from './y'` → `{ kind: 'reexport', localName: 'X', importedName: 'X', targetRaw: './y' }`
|
|
122
|
+
* - TS `export { X as Y } from './y'` → `{ kind: 'reexport', localName: 'Y', importedName: 'X', alias: 'Y', targetRaw: './y' }`
|
|
123
|
+
* - Rust `pub use foo::bar` → `{ kind: 'reexport', localName: 'bar', importedName: 'bar', targetRaw: 'foo' }`
|
|
124
|
+
*/
|
|
125
|
+
| {
|
|
126
|
+
readonly kind: 'reexport';
|
|
127
|
+
/** Name as re-exported in the current module. */
|
|
128
|
+
readonly localName: string;
|
|
129
|
+
/** Name in the source module. */
|
|
130
|
+
readonly importedName: string;
|
|
131
|
+
readonly targetRaw: string;
|
|
132
|
+
/** Set when the re-export renames the symbol (e.g. `export { X as Y } from './y'`). */
|
|
133
|
+
readonly alias?: string;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Wildcard import — brings every exported name from the target module into
|
|
137
|
+
* the importing scope. The finalize algorithm expands this into one
|
|
138
|
+
* `BindingRef` per exported name via the provider's `expandsWildcardTo`
|
|
139
|
+
* hook, producing the finalize-only `ImportEdge` kind `'wildcard-expanded'`.
|
|
140
|
+
*
|
|
141
|
+
* Examples:
|
|
142
|
+
* - Python `from foo import *` → `{ kind: 'wildcard', targetRaw: 'foo' }`
|
|
143
|
+
* - JS `export * from './foo'` → `{ kind: 'wildcard', targetRaw: './foo' }`
|
|
144
|
+
* - Rust `pub use foo::*` → `{ kind: 'wildcard', targetRaw: 'foo' }`
|
|
145
|
+
*/
|
|
146
|
+
| {
|
|
147
|
+
readonly kind: 'wildcard';
|
|
148
|
+
readonly targetRaw: string;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Runtime-computed target — the import path is not a static literal at
|
|
152
|
+
* parse time. Providers SHOULD emit the unresolvable expression's source
|
|
153
|
+
* text as `targetRaw` to aid diagnostics; `null` only when no string form
|
|
154
|
+
* exists.
|
|
155
|
+
*
|
|
156
|
+
* Examples:
|
|
157
|
+
* - JS `await import(expr)` → `{ kind: 'dynamic-unresolved', localName: '', targetRaw: 'expr' }`
|
|
158
|
+
* - Python `importlib.import_module(f'pkg.{name}')` → `{ kind: 'dynamic-unresolved', localName: '', targetRaw: "f'pkg.{name}'" }`
|
|
159
|
+
*/
|
|
160
|
+
| {
|
|
161
|
+
readonly kind: 'dynamic-unresolved';
|
|
162
|
+
readonly localName: string;
|
|
163
|
+
/** Source text of the unresolved expression when available; `null` otherwise. */
|
|
164
|
+
readonly targetRaw: string | null;
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Provider-interpreted type binding. The provider's `interpretTypeBinding`
|
|
168
|
+
* hook turns a `CaptureMatch` (e.g., `@type-binding.parameter`) into one of
|
|
169
|
+
* these; the central extractor attaches the resulting `TypeRef` to the
|
|
170
|
+
* appropriate scope's `typeBindings` map.
|
|
171
|
+
*/
|
|
172
|
+
export interface ParsedTypeBinding {
|
|
173
|
+
/** The name being bound (parameter name, `self`, assignment LHS, …). */
|
|
174
|
+
readonly boundName: string;
|
|
175
|
+
/** The raw type name as written in source (`'User'`, `'models.User'`, …). */
|
|
176
|
+
readonly rawTypeName: string;
|
|
177
|
+
readonly source: TypeRef['source'];
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Cross-file workspace index consumed by finalize-phase hooks
|
|
181
|
+
* (`resolveImportTarget`, `expandsWildcardTo`). Opaque placeholder in Ring 1;
|
|
182
|
+
* concretely typed in Ring 2 SHARED (#915).
|
|
183
|
+
*/
|
|
184
|
+
export type WorkspaceIndex = unknown;
|
|
185
|
+
/**
|
|
186
|
+
* Minimal scope-lookup contract: map a `ScopeId` back to its `Scope` record.
|
|
187
|
+
*
|
|
188
|
+
* Lives in the data-model layer so both `ScopeTree` (§3.1) and
|
|
189
|
+
* `resolveTypeRef` / `Registry.lookup` (§4) can depend on it without
|
|
190
|
+
* inverting each other. `ScopeTree` is the canonical implementation;
|
|
191
|
+
* tests and future alternative containers may supply their own.
|
|
192
|
+
*/
|
|
193
|
+
export interface ScopeLookup {
|
|
194
|
+
getScope(id: ScopeId): Scope | undefined;
|
|
195
|
+
}
|
|
196
|
+
/** Call-site description passed to `arityCompatibility`. */
|
|
197
|
+
export interface Callsite {
|
|
198
|
+
/** Number of arguments at the call site. */
|
|
199
|
+
readonly arity: number;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* A cross-file import edge attached to a module/namespace scope.
|
|
203
|
+
*
|
|
204
|
+
* Raw (unlinked) edges are emitted during parse (Phase 1); `targetModuleScope`
|
|
205
|
+
* and `targetDefId` are filled in during finalize (Phase 2) via SCC-aware
|
|
206
|
+
* bounded-fixpoint linking (RFC §3.2).
|
|
207
|
+
*/
|
|
208
|
+
export interface ImportEdge {
|
|
209
|
+
/** How this scope sees the imported name (after alias). */
|
|
210
|
+
readonly localName: string;
|
|
211
|
+
/** Exporting file; `null` only when `kind === 'dynamic-unresolved'`. */
|
|
212
|
+
readonly targetFile: string | null;
|
|
213
|
+
/** The name under which the target exports this symbol. */
|
|
214
|
+
readonly targetExportedName: string;
|
|
215
|
+
/** Pre-resolved at finalize: the module scope of the exporting file. */
|
|
216
|
+
readonly targetModuleScope?: ScopeId;
|
|
217
|
+
/** Pre-resolved at finalize: the exported symbol's `DefId`. */
|
|
218
|
+
readonly targetDefId?: DefId;
|
|
219
|
+
readonly kind: 'named' | 'alias' | 'namespace' | 'wildcard-expanded' | 'reexport' | 'dynamic-unresolved';
|
|
220
|
+
/** Re-export chain, for provenance (e.g., `['./y']` when re-exported via `./y`). */
|
|
221
|
+
readonly transitiveVia?: readonly string[];
|
|
222
|
+
/** Set to `'unresolved'` when the SCC fixpoint could not link this edge. */
|
|
223
|
+
readonly linkStatus?: 'unresolved';
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* A name binding visible at a scope, with provenance.
|
|
227
|
+
*
|
|
228
|
+
* Provenance stays at the visibility layer — a name being visible because it
|
|
229
|
+
* is local vs imported vs wildcard-expanded vs re-exported is a property of
|
|
230
|
+
* the binding itself. This keeps evidence emission and `import-use` reference
|
|
231
|
+
* stamping first-class instead of reconstructing provenance from a side table.
|
|
232
|
+
*/
|
|
233
|
+
export interface BindingRef {
|
|
234
|
+
readonly def: SymbolDefinition;
|
|
235
|
+
readonly origin: 'local' | 'import' | 'namespace' | 'wildcard' | 'reexport';
|
|
236
|
+
/** Non-null for non-local origins; carries the `ImportEdge` that brought the name into this scope. */
|
|
237
|
+
readonly via?: ImportEdge;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* A reference to a named type, anchored at its declaration site.
|
|
241
|
+
*
|
|
242
|
+
* Design choice: raw name + declaration-site scope, resolved at lookup time.
|
|
243
|
+
* Pre-resolution would invert the extraction/resolution wall. Deferred thunks
|
|
244
|
+
* add no capability. Structured type systems are months of work per language.
|
|
245
|
+
* This shape keeps V1 tractable while preserving correctness for aliases,
|
|
246
|
+
* re-exports, and nested modules. Generics deferred to V2 via `typeArgs`.
|
|
247
|
+
*/
|
|
248
|
+
export interface TypeRef {
|
|
249
|
+
/** The name as written in source (e.g., `'User'`, `'models.User'`, `'List'`). */
|
|
250
|
+
readonly rawName: string;
|
|
251
|
+
/** Anchor for resolving `rawName` — the scope where the annotation/inference was written. */
|
|
252
|
+
readonly declaredAtScope: ScopeId;
|
|
253
|
+
readonly source: 'annotation' | 'parameter-annotation' | 'return-annotation' | 'self' | 'assignment-inferred' | 'constructor-inferred' | 'receiver-propagated';
|
|
254
|
+
/** Reserved for V2+: generic type arguments (`List<User>` → `[TypeRef('User')]`). V1 ignores. */
|
|
255
|
+
readonly typeArgs?: readonly TypeRef[];
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* The canonical lexical-scope node. Forms the spine of the SemanticModel.
|
|
259
|
+
*
|
|
260
|
+
* ScopeId shape (RFC §2.2): `scope:{filePath}#{startLine}:{startCol}-{endLine}:{endCol}:{kind}`
|
|
261
|
+
* — deterministic, stable across reparses of the same source, interned.
|
|
262
|
+
*/
|
|
263
|
+
export interface Scope {
|
|
264
|
+
readonly id: ScopeId;
|
|
265
|
+
readonly parent: ScopeId | null;
|
|
266
|
+
readonly kind: ScopeKind;
|
|
267
|
+
readonly range: Range;
|
|
268
|
+
readonly filePath: string;
|
|
269
|
+
/** Names visible from this scope. Provenance preserved via `BindingRef.origin`. */
|
|
270
|
+
readonly bindings: ReadonlyMap<string, readonly BindingRef[]>;
|
|
271
|
+
/** Defs structurally owned by this scope (e.g., methods owned by a class body scope). */
|
|
272
|
+
readonly ownedDefs: readonly SymbolDefinition[];
|
|
273
|
+
/** Import edges attached to this scope. Mostly module/namespace scopes, but some
|
|
274
|
+
* languages allow local imports (Python `def f(): from x import Y`, Rust
|
|
275
|
+
* fn-local `use`, TS dynamic `import()`). */
|
|
276
|
+
readonly imports: readonly ImportEdge[];
|
|
277
|
+
/** Local type facts visible from this scope (parameter annotations, `self` binding, etc.). */
|
|
278
|
+
readonly typeBindings: ReadonlyMap<string, TypeRef>;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* One piece of evidence for a `Resolution`. Multiple signals corroborate a
|
|
282
|
+
* single match; their weights compose additively to produce `confidence`.
|
|
283
|
+
*
|
|
284
|
+
* Weights come from `EvidenceWeights` (see `./evidence-weights.ts`).
|
|
285
|
+
*/
|
|
286
|
+
export interface ResolutionEvidence {
|
|
287
|
+
readonly kind: 'local' | 'scope-chain' | 'import' | 'type-binding' | 'owner-match' | 'kind-match' | 'arity-match' | 'global-name' | 'global-qualified' | 'dynamic-import-unresolved';
|
|
288
|
+
/** Signal weight, sourced from `EvidenceWeights`. Additive; sum capped at 1.0. */
|
|
289
|
+
readonly weight: number;
|
|
290
|
+
/** Optional debug annotation (e.g., `'matched via self: User'`). */
|
|
291
|
+
readonly note?: string;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* A ranked resolution candidate returned by `ClassRegistry.lookup` /
|
|
295
|
+
* `MethodRegistry.lookup` / `FieldRegistry.lookup`. Evidence composes
|
|
296
|
+
* additively; callers read `[0]` for the one-shot answer or inspect the
|
|
297
|
+
* evidence trace for debugging.
|
|
298
|
+
*/
|
|
299
|
+
export interface Resolution {
|
|
300
|
+
readonly def: SymbolDefinition;
|
|
301
|
+
/** Σ of `evidence[].weight`, capped at 1.0. */
|
|
302
|
+
readonly confidence: number;
|
|
303
|
+
readonly evidence: readonly ResolutionEvidence[];
|
|
304
|
+
/** Optional debug trace: scopes walked to reach `def`. */
|
|
305
|
+
readonly path?: readonly ScopeId[];
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* A post-resolution usage fact: some code at `atRange` inside `fromScope`
|
|
309
|
+
* references `toDef` with the given confidence/evidence. Materialized by the
|
|
310
|
+
* resolution phase; emitted as graph edges (`CALLS`/`READS`/`WRITES`/etc.)
|
|
311
|
+
* during the emit phase.
|
|
312
|
+
*/
|
|
313
|
+
export interface Reference {
|
|
314
|
+
/** Innermost lexical scope containing `atRange`. */
|
|
315
|
+
readonly fromScope: ScopeId;
|
|
316
|
+
readonly toDef: DefId;
|
|
317
|
+
/** Location of the reference in source. */
|
|
318
|
+
readonly atRange: Range;
|
|
319
|
+
readonly kind: 'call' | 'read' | 'write' | 'type-reference' | 'inherits' | 'import-use';
|
|
320
|
+
readonly confidence: number;
|
|
321
|
+
readonly evidence: readonly ResolutionEvidence[];
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Two-way index over `Reference` records, populated during the resolution
|
|
325
|
+
* phase. Scopes stay immutable after finalize; references accumulate here.
|
|
326
|
+
*/
|
|
327
|
+
export interface ReferenceIndex {
|
|
328
|
+
readonly bySourceScope: ReadonlyMap<ScopeId, readonly Reference[]>;
|
|
329
|
+
readonly byTargetDef: ReadonlyMap<DefId, readonly Reference[]>;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Opaque placeholder for the per-kind registry passed as the owner-scoped
|
|
333
|
+
* contributor. Typed concretely in Ring 2 SHARED (#917); kept as `unknown`
|
|
334
|
+
* here so Ring 1 can ship without pulling in the registry implementation.
|
|
335
|
+
*/
|
|
336
|
+
export type RegistryContributor = unknown;
|
|
337
|
+
/**
|
|
338
|
+
* Parameters accepted by `Registry.lookup`. Three registries (Class/Method/
|
|
339
|
+
* Field) run the same 7-step algorithm with different parameter tuples; see
|
|
340
|
+
* RFC §4.4 for per-registry specializations.
|
|
341
|
+
*/
|
|
342
|
+
export interface LookupParams {
|
|
343
|
+
readonly acceptedKinds: readonly NodeLabel[];
|
|
344
|
+
/** Class lookups: false. Method/Field lookups: true. */
|
|
345
|
+
readonly useReceiverTypeBinding: boolean;
|
|
346
|
+
readonly ownerScopedContributor: RegistryContributor | null;
|
|
347
|
+
/** Optional arity hint fed to `provider.arityCompatibility`. */
|
|
348
|
+
readonly arityHint?: number;
|
|
349
|
+
/** Explicit receiver name (e.g., `'user'` in `user.save()`). When present,
|
|
350
|
+
* the receiver's type binding at the callsite scope is used; otherwise
|
|
351
|
+
* the enclosing method's implicit `self`/`this` is consulted. See §4.1. */
|
|
352
|
+
readonly explicitReceiver?: {
|
|
353
|
+
readonly name: string;
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope-resolution type definitions — RFC §2 data model (authoritative source).
|
|
3
|
+
*
|
|
4
|
+
* See: https://www.notion.so/346dc50b6ed281cfaacbe480bf231d50
|
|
5
|
+
*
|
|
6
|
+
* Anti-drift rule: every type, interface, and enum defined here is the single
|
|
7
|
+
* source of truth. Later code that references these names must import them
|
|
8
|
+
* from `gitnexus-shared`; it must not re-define them locally.
|
|
9
|
+
*
|
|
10
|
+
* Lifecycle contract (RFC §2.8): scopes are **constructed during extraction,
|
|
11
|
+
* linked during finalize, immutable after finalize**. All fields are
|
|
12
|
+
* `readonly` at the type level; `Object.freeze` is applied at runtime in dev
|
|
13
|
+
* builds. `ReferenceIndex` is the sole structure populated after freeze — by
|
|
14
|
+
* resolution, before emission.
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/scope-resolution/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { KnowledgeGraph } from '../graph/types.js';
|
|
2
2
|
import { ASTCache } from './ast-cache.js';
|
|
3
|
-
import type { SymbolDefinition
|
|
3
|
+
import type { SymbolDefinition } from '../../_shared/index.js';
|
|
4
|
+
import type { SymbolTableReader, HeritageMap, ExtractedHeritage } from './model/index.js';
|
|
4
5
|
import type { ResolutionContext } from './model/resolution-context.js';
|
|
5
6
|
import type { TieredCandidates } from './model/resolution-context.js';
|
|
6
7
|
import type { TypeEnvironment } from './type-env.js';
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* The providers table in `languages/index.ts` uses `satisfies Record<SupportedLanguages, LanguageProvider>`
|
|
9
9
|
* so adding a language to the enum without creating a provider is a compiler error.
|
|
10
10
|
*/
|
|
11
|
-
import type { SupportedLanguages, MroStrategy } from '../../_shared/index.js';
|
|
11
|
+
import type { SupportedLanguages, MroStrategy, Capture, CaptureMatch, BindingRef, TypeRef, Scope, ScopeId, ScopeKind, ScopeTree, ParsedImport, ParsedTypeBinding, SymbolDefinition, Callsite, WorkspaceIndex } from '../../_shared/index.js';
|
|
12
12
|
import type { LanguageTypeConfig } from './type-extractors/types.js';
|
|
13
13
|
import type { CallRouter } from './call-routing.js';
|
|
14
14
|
import type { CallExtractor, DispatchDecision, ImplicitReceiverOverride, ReceiverEnriched } from './call-types.js';
|
|
@@ -222,6 +222,177 @@ interface LanguageProviderConfig {
|
|
|
222
222
|
/** Built-in/stdlib names that should be filtered from the call graph for this language.
|
|
223
223
|
* Default: undefined (no language-specific filtering). */
|
|
224
224
|
readonly builtInNames?: ReadonlySet<string>;
|
|
225
|
+
/**
|
|
226
|
+
* Emit scope captures from raw source. Tree-sitter-based providers run a
|
|
227
|
+
* `scopes.scm` query; standalone providers (COBOL) emit captures from a
|
|
228
|
+
* regex tagger. The return shape is parser-agnostic: the central
|
|
229
|
+
* `ScopeExtractor` consumes `Capture[]` without knowing which parser
|
|
230
|
+
* produced them.
|
|
231
|
+
*
|
|
232
|
+
* Required for any provider participating in scope-based resolution.
|
|
233
|
+
* Providers that have not yet migrated continue to run through the legacy
|
|
234
|
+
* DAG path (feature-flagged per `REGISTRY_PRIMARY_<LANG>`).
|
|
235
|
+
*
|
|
236
|
+
* Default: undefined (language continues to use legacy DAG).
|
|
237
|
+
*/
|
|
238
|
+
readonly emitScopeCaptures?: (sourceText: string, filePath: string) => Promise<readonly Capture[]>;
|
|
239
|
+
/**
|
|
240
|
+
* Interpret a raw `@import.statement` capture group into a `ParsedImport`.
|
|
241
|
+
* The central finalize algorithm resolves `ParsedImport.targetRaw` to a
|
|
242
|
+
* concrete file via `resolveImportTarget` and materializes the final
|
|
243
|
+
* `ImportEdge` with `targetModuleScope` / `targetDefId` filled in.
|
|
244
|
+
*
|
|
245
|
+
* Required when `emitScopeCaptures` is implemented.
|
|
246
|
+
*/
|
|
247
|
+
readonly interpretImport?: (captures: CaptureMatch) => ParsedImport | null;
|
|
248
|
+
/**
|
|
249
|
+
* What is the implicit receiver on a Function scope? For instance methods
|
|
250
|
+
* this is `self`/`this`; for standalone functions it is `null`. Consulted
|
|
251
|
+
* by `Registry.lookup` Step 2 via the `resolveTypeRef` helper.
|
|
252
|
+
*
|
|
253
|
+
* Required for any language with method dispatch (OO semantics).
|
|
254
|
+
*
|
|
255
|
+
* Default: undefined (treated as `null` — no implicit receiver).
|
|
256
|
+
*/
|
|
257
|
+
readonly receiverBinding?: (functionScope: Scope) => TypeRef | null;
|
|
258
|
+
/**
|
|
259
|
+
* Interpret a raw type-binding capture (parameter annotation, `self`,
|
|
260
|
+
* assignment with constructor RHS, …) into a `ParsedTypeBinding`. The
|
|
261
|
+
* central extractor attaches the resulting `TypeRef` to the appropriate
|
|
262
|
+
* scope's `typeBindings` map.
|
|
263
|
+
*
|
|
264
|
+
* Default: undefined (falls back to `{ boundName: captures.name, rawTypeName: captures.type, source: 'annotation' }`).
|
|
265
|
+
*/
|
|
266
|
+
readonly interpretTypeBinding?: (captures: CaptureMatch) => ParsedTypeBinding | null;
|
|
267
|
+
/**
|
|
268
|
+
* Override the `ScopeKind` assigned to a scope capture. Use when the
|
|
269
|
+
* capture name alone can't resolve the kind (e.g., tree-sitter captures
|
|
270
|
+
* a `block` that is semantically an `Expression` in this language).
|
|
271
|
+
*
|
|
272
|
+
* Default: undefined (the central extractor uses the capture name's
|
|
273
|
+
* suffix — `@scope.function` → `'Function'`, etc.).
|
|
274
|
+
*/
|
|
275
|
+
readonly resolveScopeKind?: (captures: CaptureMatch) => ScopeKind | null;
|
|
276
|
+
/**
|
|
277
|
+
* Should this scope capture materialize as a real `Scope` node? Return
|
|
278
|
+
* `false` to skip scope creation while still emitting declarations that
|
|
279
|
+
* would have gone inside (they attach to the enclosing real scope).
|
|
280
|
+
*
|
|
281
|
+
* Example: Python `if`/`for`/`while` bodies capture as `@scope.block` but
|
|
282
|
+
* Python has no block scope — hook returns `false` and child declarations
|
|
283
|
+
* lift to the enclosing function/module.
|
|
284
|
+
*
|
|
285
|
+
* Default: undefined (treated as `true` — always create).
|
|
286
|
+
*/
|
|
287
|
+
readonly shouldCreateScope?: (captures: CaptureMatch) => boolean;
|
|
288
|
+
/**
|
|
289
|
+
* Override where a declaration's name becomes visible. By default the name
|
|
290
|
+
* is bound in the innermost enclosing scope; return a different `ScopeId`
|
|
291
|
+
* to hoist it (JS `var` → enclosing function scope; Ruby `def` inside
|
|
292
|
+
* `begin` → enclosing class scope).
|
|
293
|
+
*
|
|
294
|
+
* Return `null` to delegate to the central default (innermost enclosing
|
|
295
|
+
* scope). This matches the `X | null` convention used by the other optional
|
|
296
|
+
* hooks and supports partial overrides — e.g., a JS provider can return a
|
|
297
|
+
* hoisted scope for `var` declarations and `null` for `let`/`const`, without
|
|
298
|
+
* re-implementing the default lookup.
|
|
299
|
+
*
|
|
300
|
+
* **Purity:** must be a pure function of its inputs — same parameters must
|
|
301
|
+
* yield the same `ScopeId` (or `null`) across invocations. No closure over
|
|
302
|
+
* mutable state. Required so scope-tree construction stays deterministic
|
|
303
|
+
* across re-parses.
|
|
304
|
+
*
|
|
305
|
+
* Default: undefined (the central extractor uses `innermostScope.id`).
|
|
306
|
+
*/
|
|
307
|
+
readonly bindingScopeFor?: (declCapture: CaptureMatch, innermostScope: Scope, scopeTree: ScopeTree) => ScopeId | null;
|
|
308
|
+
/**
|
|
309
|
+
* Resolve a `ParsedImport.targetRaw` expression to a concrete file path in
|
|
310
|
+
* the workspace. Language-specific resolution: Python relative imports,
|
|
311
|
+
* JS package.json + node_modules, Go module paths, Java classpath,
|
|
312
|
+
* COBOL COPY paths. Ports today's per-language import resolver.
|
|
313
|
+
*
|
|
314
|
+
* Required when `emitScopeCaptures` is implemented. Ring 2 PKG #922
|
|
315
|
+
* provides the adapter that bridges today's resolver shape to this hook.
|
|
316
|
+
*/
|
|
317
|
+
readonly resolveImportTarget?: (parsedImport: ParsedImport, workspaceIndex: WorkspaceIndex) => string | null;
|
|
318
|
+
/**
|
|
319
|
+
* Enumerate the exported names of a file — used by the finalize algorithm
|
|
320
|
+
* to expand `import * from M` into individual `BindingRef`s with
|
|
321
|
+
* `origin: 'wildcard'`.
|
|
322
|
+
*
|
|
323
|
+
* Default: undefined (central finalize walks the target file's
|
|
324
|
+
* `ExportMap.keys()`).
|
|
325
|
+
*/
|
|
326
|
+
readonly expandsWildcardTo?: (targetFile: string, workspaceIndex: WorkspaceIndex) => readonly string[];
|
|
327
|
+
/**
|
|
328
|
+
* Decide the scope to which a `ParsedImport` attaches. Most languages
|
|
329
|
+
* attach imports to the nearest enclosing `Module`/`Namespace` scope
|
|
330
|
+
* (the default); some languages allow local imports (Python function-local
|
|
331
|
+
* `from x import Y`, Rust fn-local `use`, TS dynamic `import()`) — return
|
|
332
|
+
* a `Function`/`Block` scope id instead.
|
|
333
|
+
*
|
|
334
|
+
* Return `null` to delegate to the central default (nearest enclosing
|
|
335
|
+
* `Module`/`Namespace`). This matches the `X | null` convention used by
|
|
336
|
+
* the other optional hooks and supports partial overrides — a provider
|
|
337
|
+
* that handles only specific import forms non-standardly can `return null`
|
|
338
|
+
* for the common cases and let the central walk handle them.
|
|
339
|
+
*
|
|
340
|
+
* **Purity:** must be a pure function of its inputs — same parameters must
|
|
341
|
+
* yield the same `ScopeId` (or `null`) across invocations. No closure over
|
|
342
|
+
* mutable state. Required so scope-tree construction stays deterministic
|
|
343
|
+
* across re-parses.
|
|
344
|
+
*
|
|
345
|
+
* Default: undefined (central finalize walks to the nearest enclosing
|
|
346
|
+
* `Module` or `Namespace` scope).
|
|
347
|
+
*/
|
|
348
|
+
readonly importOwningScope?: (parsedImport: ParsedImport, innermostScope: Scope, scopeTree: ScopeTree) => ScopeId | null;
|
|
349
|
+
/**
|
|
350
|
+
* Merge local declarations and imported bindings for a single (scope, name)
|
|
351
|
+
* during finalize materialization of a scope's binding table. Language-
|
|
352
|
+
* specific precedence: Python local hides import; TypeScript namespace
|
|
353
|
+
* merging keeps both; Ruby constant resolution has its own rules.
|
|
354
|
+
*
|
|
355
|
+
* Default: undefined (central finalize uses local-first-then-imports,
|
|
356
|
+
* deduping by `DefId`).
|
|
357
|
+
*/
|
|
358
|
+
readonly mergeBindings?: (scope: Scope, bindings: readonly BindingRef[]) => readonly BindingRef[];
|
|
359
|
+
/**
|
|
360
|
+
* Classify a `@reference.call` capture as free / member / constructor /
|
|
361
|
+
* index. Preferred path is declarative via capture sub-tags
|
|
362
|
+
* (`@reference.call.free`, etc.); this hook handles the languages where
|
|
363
|
+
* call form can't be decided statically (Ruby bare `foo(x)` is free-or-
|
|
364
|
+
* member until resolved).
|
|
365
|
+
*
|
|
366
|
+
* Default: undefined (central extractor reads capture sub-tag if present;
|
|
367
|
+
* else treats as `'free'`).
|
|
368
|
+
*/
|
|
369
|
+
readonly classifyCallForm?: (captures: CaptureMatch, enclosingScope: Scope) => 'free' | 'member' | 'constructor' | 'index';
|
|
370
|
+
/**
|
|
371
|
+
* Does a binding at this scope shadow bindings of the same name in outer
|
|
372
|
+
* scopes? Default: any binding shadows (standard lexical scoping). Return
|
|
373
|
+
* `false` for transparent-scope edge cases (Python `from x import *`
|
|
374
|
+
* contexts, JS `var` hoisting quirks, COBOL PARAGRAPH transparency).
|
|
375
|
+
*
|
|
376
|
+
* Consulted by `Registry.lookup` Step 1 and by `resolveTypeRef` for
|
|
377
|
+
* shadowing decisions during the lexical chain walk.
|
|
378
|
+
*
|
|
379
|
+
* Default: undefined (treated as `true` — any binding shadows).
|
|
380
|
+
*/
|
|
381
|
+
readonly shouldShadow?: (scope: Scope, bindings: readonly BindingRef[]) => boolean;
|
|
382
|
+
/**
|
|
383
|
+
* Is this callable definition compatible with the given call-site arity?
|
|
384
|
+
* Language-specific rules: Python `*args`/`**kwargs`/defaults, JS default
|
|
385
|
+
* params + rest, Kotlin vararg + defaults, Ruby optional/splat/block, Go
|
|
386
|
+
* straight counts, Rust no-variadic-no-defaults.
|
|
387
|
+
*
|
|
388
|
+
* `'incompatible'` is a soft penalty (−0.15 per EvidenceWeights) and is
|
|
389
|
+
* filtered only when at least one `'compatible'` candidate exists;
|
|
390
|
+
* otherwise the incompatible candidate is kept with the penalty so the
|
|
391
|
+
* call-site still links to a best-guess target.
|
|
392
|
+
*
|
|
393
|
+
* Default: undefined (treated as `'unknown'` — no signal either way).
|
|
394
|
+
*/
|
|
395
|
+
readonly arityCompatibility?: (def: SymbolDefinition, callsite: Callsite) => 'compatible' | 'unknown' | 'incompatible';
|
|
225
396
|
}
|
|
226
397
|
/** Runtime type — same as LanguageProviderConfig but with defaults guaranteed present. */
|
|
227
398
|
export interface LanguageProvider extends Omit<LanguageProviderConfig, 'importSemantics' | 'heritageDefaultEdge' | 'mroStrategy'> {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Owner-scoped field/property index extracted from SymbolTable.
|
|
5
5
|
* Stores Property symbols keyed by `ownerNodeId\0fieldName` for O(1) lookup.
|
|
6
6
|
*/
|
|
7
|
-
import type { SymbolDefinition } from '
|
|
7
|
+
import type { SymbolDefinition } from '../../../_shared/index.js';
|
|
8
8
|
export interface FieldRegistry {
|
|
9
9
|
/** Look up a field/property by its owning class nodeId and field name. */
|
|
10
10
|
lookupFieldByOwner(ownerNodeId: string, fieldName: string): SymbolDefinition | undefined;
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* `SymbolTable` by design.
|
|
11
11
|
*/
|
|
12
12
|
export { type SemanticModel, type MutableSemanticModel, createSemanticModel, } from './semantic-model.js';
|
|
13
|
-
export { type SymbolTableReader, type SymbolTableWriter, createSymbolTable, type
|
|
13
|
+
export { type SymbolTableReader, type SymbolTableWriter, createSymbolTable, type AddMetadata, CLASS_TYPES, CLASS_TYPES_TUPLE, type ClassLikeLabel, FREE_CALLABLE_TYPES, FREE_CALLABLE_TUPLE, type FreeCallableLabel, CALL_TARGET_TYPES, } from './symbol-table.js';
|
|
14
14
|
export { type TypeRegistry, type MutableTypeRegistry, createTypeRegistry, } from './type-registry.js';
|
|
15
15
|
export { type MethodRegistry, type MutableMethodRegistry, createMethodRegistry, } from './method-registry.js';
|
|
16
16
|
export { type FieldRegistry, type MutableFieldRegistry, createFieldRegistry, } from './field-registry.js';
|
|
@@ -17,6 +17,8 @@ export { createSemanticModel, } from './semantic-model.js';
|
|
|
17
17
|
// for the rare caller that needs the file/callable interface in
|
|
18
18
|
// isolation (e.g. tests).
|
|
19
19
|
export { createSymbolTable, CLASS_TYPES, CLASS_TYPES_TUPLE, FREE_CALLABLE_TYPES, FREE_CALLABLE_TUPLE, CALL_TARGET_TYPES, } from './symbol-table.js';
|
|
20
|
+
// `SymbolDefinition` moved to `gitnexus-shared` (RFC #909 Ring 1 #910).
|
|
21
|
+
// Consumers should import it directly from `gitnexus-shared`, not via this barrel.
|
|
20
22
|
// Type registry (classes, structs, interfaces, enums, records, impls)
|
|
21
23
|
export { createTypeRegistry, } from './type-registry.js';
|
|
22
24
|
// Method registry (owner-scoped methods with arity-aware overload lookup)
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* `ownerNodeId\0methodName` for O(1) lookup. Supports overloads
|
|
7
7
|
* (array values) and arity-based filtering.
|
|
8
8
|
*/
|
|
9
|
-
import type { SymbolDefinition } from '
|
|
9
|
+
import type { SymbolDefinition } from '../../../_shared/index.js';
|
|
10
10
|
export interface MethodRegistry {
|
|
11
11
|
/**
|
|
12
12
|
* Look up a method by owner class + name, optionally filtered by arity.
|
|
@@ -48,8 +48,7 @@
|
|
|
48
48
|
* The runtime exhaustiveness guard in `symbol-table.ts` will warn if a
|
|
49
49
|
* `NodeLabel` is missing from all three sets.
|
|
50
50
|
*/
|
|
51
|
-
import type { NodeLabel } from '../../../_shared/index.js';
|
|
52
|
-
import type { SymbolDefinition } from './symbol-table.js';
|
|
51
|
+
import type { NodeLabel, SymbolDefinition } from '../../../_shared/index.js';
|
|
53
52
|
import type { MutableTypeRegistry } from './type-registry.js';
|
|
54
53
|
import type { MutableMethodRegistry } from './method-registry.js';
|
|
55
54
|
import type { MutableFieldRegistry } from './field-registry.js';
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* - Tier 3 combines lookupClassByName + lookupImplByName + lookupCallableByName
|
|
18
18
|
* (three O(1) index lookups with a narrow, type-specific result set).
|
|
19
19
|
*/
|
|
20
|
-
import type { SymbolDefinition } from '
|
|
20
|
+
import type { SymbolDefinition } from '../../../_shared/index.js';
|
|
21
21
|
import type { MutableSemanticModel } from './semantic-model.js';
|
|
22
22
|
/**
|
|
23
23
|
* A single named binding in a source file (e.g. `import { User as U }`).
|