gitnexus 1.6.3-rc.2 → 1.6.3-rc.21

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.
Files changed (130) hide show
  1. package/dist/_shared/graph/types.d.ts +16 -0
  2. package/dist/_shared/graph/types.d.ts.map +1 -1
  3. package/dist/_shared/index.d.ts +41 -1
  4. package/dist/_shared/index.d.ts.map +1 -1
  5. package/dist/_shared/index.js +28 -0
  6. package/dist/_shared/index.js.map +1 -1
  7. package/dist/_shared/scope-resolution/def-index.d.ts +36 -0
  8. package/dist/_shared/scope-resolution/def-index.d.ts.map +1 -0
  9. package/dist/_shared/scope-resolution/def-index.js +51 -0
  10. package/dist/_shared/scope-resolution/def-index.js.map +1 -0
  11. package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +139 -0
  12. package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -0
  13. package/dist/_shared/scope-resolution/finalize-algorithm.js +479 -0
  14. package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -0
  15. package/dist/_shared/scope-resolution/method-dispatch-index.d.ts +80 -0
  16. package/dist/_shared/scope-resolution/method-dispatch-index.d.ts.map +1 -0
  17. package/dist/_shared/scope-resolution/method-dispatch-index.js +79 -0
  18. package/dist/_shared/scope-resolution/method-dispatch-index.js.map +1 -0
  19. package/dist/_shared/scope-resolution/module-scope-index.d.ts +46 -0
  20. package/dist/_shared/scope-resolution/module-scope-index.d.ts.map +1 -0
  21. package/dist/_shared/scope-resolution/module-scope-index.js +58 -0
  22. package/dist/_shared/scope-resolution/module-scope-index.js.map +1 -0
  23. package/dist/_shared/scope-resolution/parsed-file.d.ts +64 -0
  24. package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -0
  25. package/dist/_shared/scope-resolution/parsed-file.js +42 -0
  26. package/dist/_shared/scope-resolution/parsed-file.js.map +1 -0
  27. package/dist/_shared/scope-resolution/position-index.d.ts +62 -0
  28. package/dist/_shared/scope-resolution/position-index.d.ts.map +1 -0
  29. package/dist/_shared/scope-resolution/position-index.js +134 -0
  30. package/dist/_shared/scope-resolution/position-index.js.map +1 -0
  31. package/dist/_shared/scope-resolution/qualified-name-index.d.ts +44 -0
  32. package/dist/_shared/scope-resolution/qualified-name-index.d.ts.map +1 -0
  33. package/dist/_shared/scope-resolution/qualified-name-index.js +75 -0
  34. package/dist/_shared/scope-resolution/qualified-name-index.js.map +1 -0
  35. package/dist/_shared/scope-resolution/reference-site.d.ts +67 -0
  36. package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -0
  37. package/dist/_shared/scope-resolution/reference-site.js +24 -0
  38. package/dist/_shared/scope-resolution/reference-site.js.map +1 -0
  39. package/dist/_shared/scope-resolution/registries/class-registry.d.ts +27 -0
  40. package/dist/_shared/scope-resolution/registries/class-registry.d.ts.map +1 -0
  41. package/dist/_shared/scope-resolution/registries/class-registry.js +30 -0
  42. package/dist/_shared/scope-resolution/registries/class-registry.js.map +1 -0
  43. package/dist/_shared/scope-resolution/registries/context.d.ts +69 -0
  44. package/dist/_shared/scope-resolution/registries/context.d.ts.map +1 -0
  45. package/dist/_shared/scope-resolution/registries/context.js +44 -0
  46. package/dist/_shared/scope-resolution/registries/context.js.map +1 -0
  47. package/dist/_shared/scope-resolution/registries/evidence.d.ts +56 -0
  48. package/dist/_shared/scope-resolution/registries/evidence.d.ts.map +1 -0
  49. package/dist/_shared/scope-resolution/registries/evidence.js +150 -0
  50. package/dist/_shared/scope-resolution/registries/evidence.js.map +1 -0
  51. package/dist/_shared/scope-resolution/registries/field-registry.d.ts +26 -0
  52. package/dist/_shared/scope-resolution/registries/field-registry.d.ts.map +1 -0
  53. package/dist/_shared/scope-resolution/registries/field-registry.js +31 -0
  54. package/dist/_shared/scope-resolution/registries/field-registry.js.map +1 -0
  55. package/dist/_shared/scope-resolution/registries/lookup-core.d.ts +81 -0
  56. package/dist/_shared/scope-resolution/registries/lookup-core.d.ts.map +1 -0
  57. package/dist/_shared/scope-resolution/registries/lookup-core.js +332 -0
  58. package/dist/_shared/scope-resolution/registries/lookup-core.js.map +1 -0
  59. package/dist/_shared/scope-resolution/registries/lookup-qualified.d.ts +33 -0
  60. package/dist/_shared/scope-resolution/registries/lookup-qualified.d.ts.map +1 -0
  61. package/dist/_shared/scope-resolution/registries/lookup-qualified.js +56 -0
  62. package/dist/_shared/scope-resolution/registries/lookup-qualified.js.map +1 -0
  63. package/dist/_shared/scope-resolution/registries/method-registry.d.ts +36 -0
  64. package/dist/_shared/scope-resolution/registries/method-registry.d.ts.map +1 -0
  65. package/dist/_shared/scope-resolution/registries/method-registry.js +32 -0
  66. package/dist/_shared/scope-resolution/registries/method-registry.js.map +1 -0
  67. package/dist/_shared/scope-resolution/registries/tie-breaks.d.ts +43 -0
  68. package/dist/_shared/scope-resolution/registries/tie-breaks.d.ts.map +1 -0
  69. package/dist/_shared/scope-resolution/registries/tie-breaks.js +60 -0
  70. package/dist/_shared/scope-resolution/registries/tie-breaks.js.map +1 -0
  71. package/dist/_shared/scope-resolution/resolve-type-ref.d.ts +53 -0
  72. package/dist/_shared/scope-resolution/resolve-type-ref.d.ts.map +1 -0
  73. package/dist/_shared/scope-resolution/resolve-type-ref.js +126 -0
  74. package/dist/_shared/scope-resolution/resolve-type-ref.js.map +1 -0
  75. package/dist/_shared/scope-resolution/scope-id.d.ts +43 -0
  76. package/dist/_shared/scope-resolution/scope-id.d.ts.map +1 -0
  77. package/dist/_shared/scope-resolution/scope-id.js +46 -0
  78. package/dist/_shared/scope-resolution/scope-id.js.map +1 -0
  79. package/dist/_shared/scope-resolution/scope-tree.d.ts +61 -0
  80. package/dist/_shared/scope-resolution/scope-tree.d.ts.map +1 -0
  81. package/dist/_shared/scope-resolution/scope-tree.js +186 -0
  82. package/dist/_shared/scope-resolution/scope-tree.js.map +1 -0
  83. package/dist/_shared/scope-resolution/shadow/aggregate.d.ts +63 -0
  84. package/dist/_shared/scope-resolution/shadow/aggregate.d.ts.map +1 -0
  85. package/dist/_shared/scope-resolution/shadow/aggregate.js +122 -0
  86. package/dist/_shared/scope-resolution/shadow/aggregate.js.map +1 -0
  87. package/dist/_shared/scope-resolution/shadow/diff.d.ts +59 -0
  88. package/dist/_shared/scope-resolution/shadow/diff.d.ts.map +1 -0
  89. package/dist/_shared/scope-resolution/shadow/diff.js +79 -0
  90. package/dist/_shared/scope-resolution/shadow/diff.js.map +1 -0
  91. package/dist/_shared/scope-resolution/types.d.ts +156 -0
  92. package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
  93. package/dist/cli/analyze.d.ts +15 -0
  94. package/dist/cli/analyze.js +22 -1
  95. package/dist/cli/index.js +4 -0
  96. package/dist/cli/list.js +11 -1
  97. package/dist/core/ingestion/emit-references.d.ts +88 -0
  98. package/dist/core/ingestion/emit-references.js +229 -0
  99. package/dist/core/ingestion/finalize-orchestrator.d.ts +63 -0
  100. package/dist/core/ingestion/finalize-orchestrator.js +139 -0
  101. package/dist/core/ingestion/framework-detection.js +6 -2
  102. package/dist/core/ingestion/import-target-adapter.d.ts +73 -0
  103. package/dist/core/ingestion/import-target-adapter.js +95 -0
  104. package/dist/core/ingestion/language-provider.d.ts +187 -1
  105. package/dist/core/ingestion/model/scope-resolution-indexes.d.ts +59 -0
  106. package/dist/core/ingestion/model/scope-resolution-indexes.js +42 -0
  107. package/dist/core/ingestion/model/semantic-model.d.ts +25 -0
  108. package/dist/core/ingestion/model/semantic-model.js +16 -0
  109. package/dist/core/ingestion/parsing-processor.d.ts +9 -0
  110. package/dist/core/ingestion/parsing-processor.js +10 -0
  111. package/dist/core/ingestion/registry-primary-flag.d.ts +59 -0
  112. package/dist/core/ingestion/registry-primary-flag.js +78 -0
  113. package/dist/core/ingestion/scope-extractor-bridge.d.ts +32 -0
  114. package/dist/core/ingestion/scope-extractor-bridge.js +44 -0
  115. package/dist/core/ingestion/scope-extractor.d.ts +87 -0
  116. package/dist/core/ingestion/scope-extractor.js +603 -0
  117. package/dist/core/ingestion/shadow-harness.d.ts +113 -0
  118. package/dist/core/ingestion/shadow-harness.js +148 -0
  119. package/dist/core/ingestion/workers/parse-worker.d.ts +9 -0
  120. package/dist/core/ingestion/workers/parse-worker.js +20 -1
  121. package/dist/core/run-analyze.d.ts +21 -0
  122. package/dist/core/run-analyze.js +15 -4
  123. package/dist/core/search/phase-timer.d.ts +72 -0
  124. package/dist/core/search/phase-timer.js +106 -0
  125. package/dist/mcp/local/local-backend.js +70 -8
  126. package/dist/storage/git.d.ts +25 -0
  127. package/dist/storage/git.js +52 -0
  128. package/dist/storage/repo-manager.d.ts +70 -1
  129. package/dist/storage/repo-manager.js +107 -5
  130. package/package.json +1 -1
@@ -0,0 +1,479 @@
1
+ /**
2
+ * `finalize` — cross-file finalize algorithm for the SemanticModel
3
+ * (RFC §3.2 Phase 2; Ring 2 SHARED #915).
4
+ *
5
+ * Pure logic that takes per-file parse output (`ParsedImport[]` +
6
+ * `SymbolDefinition[]`) and returns:
7
+ *
8
+ * - Linked `ImportEdge[]` per module scope, with `targetModuleScope` and
9
+ * `targetDefId` filled where resolvable; edges that could not be
10
+ * resolved within the hard fixpoint cap are marked
11
+ * `linkStatus: 'unresolved'`.
12
+ * - Materialized `bindings` per module scope — local defs merged with
13
+ * imported / wildcard-expanded / re-exported names via the provider's
14
+ * `mergeBindings` precedence.
15
+ * - The SCC condensation of the import graph, exposed so disjoint SCCs
16
+ * can be processed in parallel by callers that want that.
17
+ *
18
+ * The algorithm is **SCC-aware**: it runs Tarjan SCC over the file-level
19
+ * import graph, processes SCCs in reverse-topological order (leaves
20
+ * first), and within each SCC runs a bounded fixpoint link pass capped at
21
+ * `N = |edges in SCC|`. Cyclic imports finalize without hanging; malformed
22
+ * inputs are bounded by the cap.
23
+ *
24
+ * **No language-specific logic.** Target resolution, wildcard expansion,
25
+ * and binding precedence all go through caller-supplied hooks
26
+ * (`resolveImportTarget`, `expandsWildcardTo`, `mergeBindings`) that
27
+ * match the LanguageProvider surface from #911.
28
+ *
29
+ * **Dynamic imports rule.** `kind === 'dynamic-unresolved'` passes through
30
+ * as an `ImportEdge { kind: 'dynamic-unresolved', targetFile: null }`
31
+ * with no `BindingRef`. They are parse-time signals, not linkable targets.
32
+ */
33
+ // ─── Entry point ───────────────────────────────────────────────────────────
34
+ export function finalize(input, hooks) {
35
+ const byFilePath = new Map();
36
+ for (const f of input.files)
37
+ byFilePath.set(f.filePath, f);
38
+ // ── Phase 0: pre-resolve raw import targets (one syscall-equivalent per
39
+ // (file, parsedImport)). Edges with no resolvable target become
40
+ // `linkStatus: 'unresolved'` or, for dynamic-unresolved, pass through
41
+ // with `targetFile: null`.
42
+ const edgeIndex = new Map(); // filePath → drafts
43
+ let totalEdges = 0;
44
+ for (const file of input.files) {
45
+ const drafts = [];
46
+ for (const parsed of file.parsedImports) {
47
+ const draft = makeEdgeDraft(parsed, file, hooks, input.workspaceIndex);
48
+ drafts.push(draft);
49
+ totalEdges++;
50
+ }
51
+ edgeIndex.set(file.filePath, drafts);
52
+ }
53
+ // ── Phase 1: build file-level import graph (only resolvable edges form
54
+ // graph edges; unresolvable ones are terminal and contribute no
55
+ // fixpoint obligation).
56
+ const graph = new Map();
57
+ for (const file of input.files) {
58
+ graph.set(file.filePath, new Set());
59
+ }
60
+ for (const [fromFile, drafts] of edgeIndex) {
61
+ const edges = graph.get(fromFile);
62
+ for (const d of drafts) {
63
+ if (d.targetFile !== null && byFilePath.has(d.targetFile)) {
64
+ edges.add(d.targetFile);
65
+ }
66
+ }
67
+ }
68
+ // ── Phase 2: Tarjan SCC → reverse-topological list of SCCs.
69
+ const sccs = tarjanSccs(graph);
70
+ // ── Phase 3: process SCCs in reverse-topological order (leaves first).
71
+ // Within each SCC, run a bounded fixpoint that resolves intra-SCC edges.
72
+ // Edges leaving the SCC are already resolved (their target SCC is
73
+ // already finalized); edges inside the SCC may need multiple passes.
74
+ const linkedByScope = new Map();
75
+ let linkedEdges = 0;
76
+ for (const scc of sccs) {
77
+ const sccFiles = new Set(scc.files);
78
+ const capacity = countEdgesWithin(edgeIndex, sccFiles);
79
+ // Run the fixpoint up to `capacity` iterations. Each iteration tries to
80
+ // resolve every still-unlinked edge in the SCC; stops early if a pass
81
+ // makes no progress.
82
+ let progressed = true;
83
+ let iterations = 0;
84
+ while (progressed && iterations < capacity) {
85
+ progressed = false;
86
+ iterations++;
87
+ for (const filePath of scc.files) {
88
+ const drafts = edgeIndex.get(filePath);
89
+ for (const draft of drafts) {
90
+ if (draft.finalized !== null)
91
+ continue;
92
+ const finalized = tryFinalize(draft, byFilePath);
93
+ if (finalized !== null) {
94
+ draft.finalized = finalized;
95
+ progressed = true;
96
+ }
97
+ }
98
+ }
99
+ }
100
+ // Any drafts still not finalized within this SCC hit the cap → unresolved.
101
+ for (const filePath of scc.files) {
102
+ const drafts = edgeIndex.get(filePath);
103
+ for (const draft of drafts) {
104
+ if (draft.finalized !== null)
105
+ continue;
106
+ draft.finalized = {
107
+ ...draft.base,
108
+ linkStatus: 'unresolved',
109
+ };
110
+ }
111
+ }
112
+ }
113
+ // ── Phase 4: collect finalized `ImportEdge[]` per module scope, preserving
114
+ // input order within each file, and wildcard-expand where applicable.
115
+ for (const file of input.files) {
116
+ const drafts = edgeIndex.get(file.filePath);
117
+ const finalized = [];
118
+ for (const d of drafts) {
119
+ const edge = d.finalized;
120
+ if (d.source.kind === 'wildcard' && edge.linkStatus !== 'unresolved') {
121
+ // Produce one `wildcard-expanded` ImportEdge per exported name.
122
+ const expanded = expandWildcard(edge, byFilePath, hooks, input.workspaceIndex);
123
+ for (const e of expanded)
124
+ finalized.push(e);
125
+ }
126
+ else {
127
+ finalized.push(edge);
128
+ }
129
+ if (edge.linkStatus !== 'unresolved')
130
+ linkedEdges++;
131
+ }
132
+ linkedByScope.set(file.moduleScope, Object.freeze(finalized));
133
+ }
134
+ // ── Phase 5: materialize module-scope bindings (local + imports + wildcards),
135
+ // delegating precedence to `provider.mergeBindings`.
136
+ const bindingsByScope = materializeBindings(input.files, linkedByScope, hooks);
137
+ // ── Stats.
138
+ const sccCount = sccs.length;
139
+ let largestSccSize = 0;
140
+ for (const scc of sccs) {
141
+ if (scc.files.length > largestSccSize)
142
+ largestSccSize = scc.files.length;
143
+ }
144
+ const stats = {
145
+ totalFiles: input.files.length,
146
+ totalEdges,
147
+ linkedEdges,
148
+ unresolvedEdges: totalEdges - linkedEdges,
149
+ sccCount,
150
+ largestSccSize,
151
+ };
152
+ return Object.freeze({
153
+ imports: linkedByScope,
154
+ bindings: bindingsByScope,
155
+ sccs,
156
+ stats,
157
+ });
158
+ }
159
+ function makeEdgeDraft(parsed, file, hooks, workspace) {
160
+ // Dynamic-unresolved passes through — no `BindingRef`, no target file.
161
+ if (parsed.kind === 'dynamic-unresolved') {
162
+ const base = {
163
+ localName: parsed.localName,
164
+ targetFile: null,
165
+ targetExportedName: '',
166
+ kind: 'dynamic-unresolved',
167
+ };
168
+ return {
169
+ source: parsed,
170
+ fromFile: file.filePath,
171
+ fromScope: file.moduleScope,
172
+ targetFile: null,
173
+ base,
174
+ finalized: base, // already fully finalized
175
+ };
176
+ }
177
+ const targetFile = hooks.resolveImportTarget(parsed.targetRaw ?? '', file.filePath, workspace);
178
+ // Edge is unresolvable at the file level — mark unresolved now.
179
+ if (targetFile === null) {
180
+ const edgeKind = parsed.kind === 'wildcard' ? 'wildcard-expanded' : parsed.kind;
181
+ const localName = parsed.kind === 'wildcard' ? '' : parsed.localName;
182
+ const targetExportedName = extractExportedName(parsed);
183
+ const base = {
184
+ localName,
185
+ targetFile: null,
186
+ targetExportedName,
187
+ kind: edgeKind,
188
+ linkStatus: 'unresolved',
189
+ };
190
+ return {
191
+ source: parsed,
192
+ fromFile: file.filePath,
193
+ fromScope: file.moduleScope,
194
+ targetFile: null,
195
+ base,
196
+ finalized: base,
197
+ };
198
+ }
199
+ // Resolvable at the file level; intra-SCC fixpoint may still fail to fill
200
+ // in `targetDefId` (e.g., symbol not exported from target).
201
+ const edgeKind = parsed.kind === 'wildcard' ? 'wildcard-expanded' : parsed.kind;
202
+ const localName = parsed.kind === 'wildcard' ? '' : parsed.localName;
203
+ const targetExportedName = extractExportedName(parsed);
204
+ const base = {
205
+ localName,
206
+ targetFile,
207
+ targetExportedName,
208
+ kind: edgeKind,
209
+ };
210
+ return {
211
+ source: parsed,
212
+ fromFile: file.filePath,
213
+ fromScope: file.moduleScope,
214
+ targetFile,
215
+ base,
216
+ finalized: null,
217
+ };
218
+ }
219
+ function extractExportedName(parsed) {
220
+ switch (parsed.kind) {
221
+ case 'named':
222
+ case 'alias':
223
+ case 'namespace':
224
+ case 'reexport':
225
+ return parsed.importedName;
226
+ case 'wildcard':
227
+ case 'dynamic-unresolved':
228
+ return '';
229
+ }
230
+ }
231
+ // ─── Internal: per-edge finalization (phase 3) ─────────────────────────────
232
+ function tryFinalize(draft, byFilePath) {
233
+ const targetFile = draft.targetFile;
234
+ if (targetFile === null)
235
+ return draft.base; // already terminal
236
+ const targetModule = byFilePath.get(targetFile);
237
+ if (targetModule === undefined)
238
+ return draft.base; // external target — leave as-is
239
+ // Wildcards finalize at the file level; their per-name expansion happens
240
+ // in phase 4. At this stage we just record the target module scope.
241
+ if (draft.source.kind === 'wildcard') {
242
+ return {
243
+ ...draft.base,
244
+ targetModuleScope: targetModule.moduleScope,
245
+ };
246
+ }
247
+ // Namespace imports alias the target *module*; they don't name a
248
+ // specific export. Link the module scope unconditionally. If the target
249
+ // also exposes a def whose simple name matches `importedName` (some
250
+ // languages emit a synthetic module-def), pick it up as the `targetDefId`
251
+ // so consumers can reach the module as a symbol — but its absence is not
252
+ // a failure.
253
+ if (draft.source.kind === 'namespace') {
254
+ const moduleDef = findExportByName(targetModule.localDefs, extractExportedName(draft.source));
255
+ return {
256
+ ...draft.base,
257
+ targetModuleScope: targetModule.moduleScope,
258
+ ...(moduleDef !== undefined ? { targetDefId: moduleDef.nodeId } : {}),
259
+ };
260
+ }
261
+ // named / alias / reexport: look up the imported name in the target's
262
+ // local defs. Multi-hop re-export chains settle iteratively — each hop
263
+ // resolves once its prior hop is finalized.
264
+ const importedName = extractExportedName(draft.source);
265
+ const exported = findExportByName(targetModule.localDefs, importedName);
266
+ if (exported === undefined) {
267
+ // Target resolvable but the name isn't exported — keep trying in case a
268
+ // re-export inside the target's SCC surfaces it in a later iteration.
269
+ return null;
270
+ }
271
+ const transitiveVia = draft.source.kind === 'reexport' ? Object.freeze([targetFile]) : undefined;
272
+ return {
273
+ ...draft.base,
274
+ targetModuleScope: targetModule.moduleScope,
275
+ targetDefId: exported.nodeId,
276
+ ...(transitiveVia !== undefined ? { transitiveVia } : {}),
277
+ };
278
+ }
279
+ /**
280
+ * The "simple" (unqualified) name of a def, for import-name matching.
281
+ *
282
+ * Canonical source: `def.qualifiedName` — the tail after the last `.` (or
283
+ * the whole string if no dot). Defs without a qualifiedName can't be
284
+ * resolved by name here and return `null`; callers treat that as "name
285
+ * not exported" and either retry in a later fixpoint iteration or mark
286
+ * the edge unresolved.
287
+ */
288
+ function deriveSimpleName(def) {
289
+ const q = def.qualifiedName;
290
+ if (q === undefined || q.length === 0)
291
+ return null;
292
+ const dot = q.lastIndexOf('.');
293
+ return dot === -1 ? q : q.slice(dot + 1);
294
+ }
295
+ function findExportByName(defs, name) {
296
+ for (const d of defs) {
297
+ if (deriveSimpleName(d) === name)
298
+ return d;
299
+ }
300
+ return undefined;
301
+ }
302
+ function countEdgesWithin(edgeIndex, files) {
303
+ let n = 0;
304
+ for (const filePath of files) {
305
+ const drafts = edgeIndex.get(filePath);
306
+ if (drafts === undefined)
307
+ continue;
308
+ for (const d of drafts) {
309
+ if (d.targetFile !== null && files.has(d.targetFile))
310
+ n++;
311
+ }
312
+ }
313
+ // Guarantee at least one pass even for a trivial SCC (ensures deterministic
314
+ // fixpoint termination even when a single-file SCC has zero intra-SCC edges
315
+ // but still needs one settle pass).
316
+ return Math.max(n, 1);
317
+ }
318
+ // ─── Internal: wildcard expansion (phase 4) ────────────────────────────────
319
+ function expandWildcard(edge, byFilePath, hooks, workspace) {
320
+ if (edge.targetModuleScope === undefined || edge.targetFile === null) {
321
+ return [edge]; // unresolvable wildcard survives as a single unlinked edge
322
+ }
323
+ const target = byFilePath.get(edge.targetFile);
324
+ if (target === undefined)
325
+ return [edge];
326
+ const names = hooks.expandsWildcardTo(edge.targetModuleScope, workspace);
327
+ if (names.length === 0)
328
+ return [];
329
+ const expanded = [];
330
+ for (const name of names) {
331
+ const def = findExportByName(target.localDefs, name);
332
+ if (def === undefined)
333
+ continue;
334
+ expanded.push({
335
+ localName: name,
336
+ targetFile: edge.targetFile,
337
+ targetExportedName: name,
338
+ kind: 'wildcard-expanded',
339
+ targetModuleScope: edge.targetModuleScope,
340
+ targetDefId: def.nodeId,
341
+ });
342
+ }
343
+ return expanded;
344
+ }
345
+ // ─── Internal: bindings materialization (phase 5) ───────────────────────────
346
+ function materializeBindings(files, linkedByScope, hooks) {
347
+ const out = new Map();
348
+ for (const file of files) {
349
+ const scopeBindings = new Map();
350
+ // Start with local defs as `origin: 'local'` bindings.
351
+ for (const def of file.localDefs) {
352
+ const name = deriveSimpleName(def);
353
+ if (name === null)
354
+ continue;
355
+ const incoming = [{ def, origin: 'local' }];
356
+ const existing = scopeBindings.get(name) ?? [];
357
+ scopeBindings.set(name, hooks.mergeBindings(existing, incoming, file.moduleScope));
358
+ }
359
+ // Layer in finalized imports.
360
+ const imports = linkedByScope.get(file.moduleScope) ?? [];
361
+ for (const edge of imports) {
362
+ if (edge.targetDefId === undefined || edge.linkStatus === 'unresolved')
363
+ continue;
364
+ // Every def the importing file needs to reach is in some other file's
365
+ // `localDefs`; walk all files to find it. In practice we could index
366
+ // this, but at finalize-time N(files) is small per workspace pass.
367
+ const def = findDefById(files, edge.targetDefId);
368
+ if (def === undefined)
369
+ continue;
370
+ const origin = edge.kind === 'namespace'
371
+ ? 'namespace'
372
+ : edge.kind === 'wildcard-expanded'
373
+ ? 'wildcard'
374
+ : edge.kind === 'reexport'
375
+ ? 'reexport'
376
+ : 'import';
377
+ const fallback = deriveSimpleName(def);
378
+ const name = edge.localName.length > 0 ? edge.localName : fallback;
379
+ if (name === null)
380
+ continue;
381
+ const incoming = [{ def, origin, via: edge }];
382
+ const existing = scopeBindings.get(name) ?? [];
383
+ scopeBindings.set(name, hooks.mergeBindings(existing, incoming, file.moduleScope));
384
+ }
385
+ // Freeze nested buckets for immutability.
386
+ const frozen = new Map();
387
+ for (const [name, refs] of scopeBindings) {
388
+ frozen.set(name, Object.freeze(refs.slice()));
389
+ }
390
+ out.set(file.moduleScope, frozen);
391
+ }
392
+ return out;
393
+ }
394
+ function findDefById(files, defId) {
395
+ for (const f of files) {
396
+ for (const d of f.localDefs) {
397
+ if (d.nodeId === defId)
398
+ return d;
399
+ }
400
+ }
401
+ return undefined;
402
+ }
403
+ // ─── Internal: Tarjan SCC ──────────────────────────────────────────────────
404
+ /**
405
+ * Iterative Tarjan SCC. Returns SCCs in **reverse-topological** order
406
+ * (leaves first — a property Tarjan gives for free, and the order
407
+ * `finalize` wants so leaves are fully resolved before their dependents).
408
+ */
409
+ function tarjanSccs(graph) {
410
+ const index = new Map();
411
+ const lowlink = new Map();
412
+ const onStack = new Set();
413
+ const stack = [];
414
+ const sccs = [];
415
+ let idx = 0;
416
+ // Iterative DFS to avoid stack overflow on deep import chains.
417
+ const allNodes = Array.from(graph.keys()).sort(); // deterministic order
418
+ const iterStack = [];
419
+ for (const root of allNodes) {
420
+ if (index.has(root))
421
+ continue;
422
+ iterStack.push({
423
+ node: root,
424
+ children: (graph.get(root) ?? new Set()).values(),
425
+ entered: false,
426
+ });
427
+ while (iterStack.length > 0) {
428
+ const frame = iterStack[iterStack.length - 1];
429
+ if (!frame.entered) {
430
+ frame.entered = true;
431
+ index.set(frame.node, idx);
432
+ lowlink.set(frame.node, idx);
433
+ idx++;
434
+ stack.push(frame.node);
435
+ onStack.add(frame.node);
436
+ }
437
+ const nextChild = frame.children.next();
438
+ if (nextChild.done) {
439
+ // Post-visit: compute SCC membership if frame.node is a root.
440
+ if (lowlink.get(frame.node) === index.get(frame.node)) {
441
+ const scc = [];
442
+ let selfInCycle = false;
443
+ while (true) {
444
+ const w = stack.pop();
445
+ onStack.delete(w);
446
+ scc.push(w);
447
+ // A single-file self-loop counts as a cycle.
448
+ if (w === frame.node) {
449
+ selfInCycle = (graph.get(w) ?? new Set()).has(w);
450
+ break;
451
+ }
452
+ }
453
+ const isCycle = scc.length > 1 || selfInCycle;
454
+ sccs.push({ files: Object.freeze(scc), isCycle });
455
+ }
456
+ iterStack.pop();
457
+ // Propagate lowlink to parent.
458
+ if (iterStack.length > 0) {
459
+ const parent = iterStack[iterStack.length - 1];
460
+ lowlink.set(parent.node, Math.min(lowlink.get(parent.node), lowlink.get(frame.node)));
461
+ }
462
+ continue;
463
+ }
464
+ const child = nextChild.value;
465
+ if (!index.has(child)) {
466
+ iterStack.push({
467
+ node: child,
468
+ children: (graph.get(child) ?? new Set()).values(),
469
+ entered: false,
470
+ });
471
+ }
472
+ else if (onStack.has(child)) {
473
+ lowlink.set(frame.node, Math.min(lowlink.get(frame.node), index.get(child)));
474
+ }
475
+ }
476
+ }
477
+ return sccs;
478
+ }
479
+ //# sourceMappingURL=finalize-algorithm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finalize-algorithm.js","sourceRoot":"","sources":["../../src/scope-resolution/finalize-algorithm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * `MethodDispatchIndex` — materialized view of class hierarchies keyed by
3
+ * `DefId` (RFC §3.1; Ring 2 SHARED #914).
4
+ *
5
+ * Two O(1)-access maps used by `Registry.lookupMethod` and interface-
6
+ * dispatch callers:
7
+ *
8
+ * - `mroByOwnerDefId` : owner class → full MRO ancestor chain
9
+ * (excludes the owner itself, in per-language
10
+ * strategy order).
11
+ * - `implsByInterfaceDefId` : interface/trait → classes that implement it.
12
+ *
13
+ * **Not an MRO implementation.** The build function is a pure aggregator: it
14
+ * asks the caller (via `computeMro` and `implementsOf` callbacks) for the
15
+ * per-language answers and materializes the two-way index. MRO strategies
16
+ * live where they already do today (`model/resolve.ts § c3Linearize`,
17
+ * `languages/ruby.ts § selectDispatch`, etc.) — this index does not
18
+ * reimplement them.
19
+ *
20
+ * Why callbacks and not a shared strategy registry: the five strategies
21
+ * (Python C3, Ruby kind-aware, Java/Kotlin linear, Rust qualified-syntax,
22
+ * COBOL none) already exist in the CLI package and depend on the CLI's
23
+ * `HeritageMap` + `SemanticModel`. Pulling them into `gitnexus-shared` would
24
+ * require migrating both — out of scope for #914. Callbacks let the shared
25
+ * build stay pure while honoring existing strategies verbatim.
26
+ *
27
+ * Consumed by: #917 (`Registry.lookupMethod` MRO fast path, interface
28
+ * dispatch resolver).
29
+ */
30
+ import type { DefId } from './types.js';
31
+ export interface MethodDispatchIndex {
32
+ /**
33
+ * Full MRO ancestor chain per owner class (excludes the owner itself).
34
+ * Order reflects the per-language strategy used by `computeMro`.
35
+ */
36
+ readonly mroByOwnerDefId: ReadonlyMap<DefId, readonly DefId[]>;
37
+ /** Interfaces / traits → classes that implement them. */
38
+ readonly implsByInterfaceDefId: ReadonlyMap<DefId, readonly DefId[]>;
39
+ /** `mroByOwnerDefId.get`, with an empty frozen array on miss. */
40
+ mroFor(ownerDefId: DefId): readonly DefId[];
41
+ /** `implsByInterfaceDefId.get`, with an empty frozen array on miss. */
42
+ implementorsOf(interfaceDefId: DefId): readonly DefId[];
43
+ }
44
+ export interface MethodDispatchInput {
45
+ /**
46
+ * Owner defs to index (classes, structs, traits, interfaces — any kind
47
+ * that can appear on the owner side of a method-dispatch graph).
48
+ */
49
+ readonly owners: readonly DefId[];
50
+ /**
51
+ * Return the full MRO ancestor chain for `ownerDefId`, **excluding the
52
+ * owner itself**, in the order dictated by the owner's language-specific
53
+ * MRO strategy.
54
+ *
55
+ * Contract:
56
+ * - Pure (no side effects).
57
+ * - Deterministic per input.
58
+ * - `undefined` not allowed — return `[]` when the owner has no parents.
59
+ */
60
+ readonly computeMro: (ownerDefId: DefId) => readonly DefId[];
61
+ /**
62
+ * Return the set of interface/trait defs that `ownerDefId` implements.
63
+ * Transitive inclusion (e.g., `implements` on a parent class) is the
64
+ * caller's choice — the build function simply inverts whatever is
65
+ * returned.
66
+ *
67
+ * Repeated IDs in the output are deduplicated automatically.
68
+ *
69
+ * **Call-count contract.** `implementsOf` is invoked **once per
70
+ * occurrence** of an owner in `input.owners`, not once per unique
71
+ * owner. Duplicate owners therefore re-invoke it; dedup happens at
72
+ * the bucket layer (after the callback returns). Callers with
73
+ * expensive `implementsOf` implementations should pass a deduplicated
74
+ * `owners` list. `computeMro`, by contrast, is memoized by the first-
75
+ * write-wins policy and fires at most once per unique owner.
76
+ */
77
+ readonly implementsOf: (ownerDefId: DefId) => readonly DefId[];
78
+ }
79
+ export declare function buildMethodDispatchIndex(input: MethodDispatchInput): MethodDispatchIndex;
80
+ //# sourceMappingURL=method-dispatch-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"method-dispatch-index.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/method-dispatch-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAIxC,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,KAAK,EAAE,SAAS,KAAK,EAAE,CAAC,CAAC;IAC/D,yDAAyD;IACzD,QAAQ,CAAC,qBAAqB,EAAE,WAAW,CAAC,KAAK,EAAE,SAAS,KAAK,EAAE,CAAC,CAAC;IAErE,iEAAiE;IACjE,MAAM,CAAC,UAAU,EAAE,KAAK,GAAG,SAAS,KAAK,EAAE,CAAC;IAC5C,uEAAuE;IACvE,cAAc,CAAC,cAAc,EAAE,KAAK,GAAG,SAAS,KAAK,EAAE,CAAC;CACzD;AAED,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;IAClC;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,UAAU,EAAE,KAAK,KAAK,SAAS,KAAK,EAAE,CAAC;IAC7D;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,KAAK,KAAK,SAAS,KAAK,EAAE,CAAC;CAChE;AAID,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,mBAAmB,GAAG,mBAAmB,CAqCxF"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * `MethodDispatchIndex` — materialized view of class hierarchies keyed by
3
+ * `DefId` (RFC §3.1; Ring 2 SHARED #914).
4
+ *
5
+ * Two O(1)-access maps used by `Registry.lookupMethod` and interface-
6
+ * dispatch callers:
7
+ *
8
+ * - `mroByOwnerDefId` : owner class → full MRO ancestor chain
9
+ * (excludes the owner itself, in per-language
10
+ * strategy order).
11
+ * - `implsByInterfaceDefId` : interface/trait → classes that implement it.
12
+ *
13
+ * **Not an MRO implementation.** The build function is a pure aggregator: it
14
+ * asks the caller (via `computeMro` and `implementsOf` callbacks) for the
15
+ * per-language answers and materializes the two-way index. MRO strategies
16
+ * live where they already do today (`model/resolve.ts § c3Linearize`,
17
+ * `languages/ruby.ts § selectDispatch`, etc.) — this index does not
18
+ * reimplement them.
19
+ *
20
+ * Why callbacks and not a shared strategy registry: the five strategies
21
+ * (Python C3, Ruby kind-aware, Java/Kotlin linear, Rust qualified-syntax,
22
+ * COBOL none) already exist in the CLI package and depend on the CLI's
23
+ * `HeritageMap` + `SemanticModel`. Pulling them into `gitnexus-shared` would
24
+ * require migrating both — out of scope for #914. Callbacks let the shared
25
+ * build stay pure while honoring existing strategies verbatim.
26
+ *
27
+ * Consumed by: #917 (`Registry.lookupMethod` MRO fast path, interface
28
+ * dispatch resolver).
29
+ */
30
+ // ─── Builder ────────────────────────────────────────────────────────────────
31
+ export function buildMethodDispatchIndex(input) {
32
+ const mroByOwnerDefId = new Map();
33
+ const implsBuilding = new Map();
34
+ const implsSeen = new Map();
35
+ for (const ownerId of input.owners) {
36
+ // First-write-wins on duplicate owner ids: a stable policy consistent
37
+ // with sibling indexes (#913 DefIndex / ModuleScopeIndex).
38
+ if (!mroByOwnerDefId.has(ownerId)) {
39
+ const chain = input.computeMro(ownerId);
40
+ mroByOwnerDefId.set(ownerId, Object.freeze(chain.slice()));
41
+ }
42
+ for (const ifaceId of input.implementsOf(ownerId)) {
43
+ let seen = implsSeen.get(ifaceId);
44
+ if (seen === undefined) {
45
+ seen = new Set();
46
+ implsSeen.set(ifaceId, seen);
47
+ }
48
+ if (seen.has(ownerId))
49
+ continue;
50
+ seen.add(ownerId);
51
+ let bucket = implsBuilding.get(ifaceId);
52
+ if (bucket === undefined) {
53
+ bucket = [];
54
+ implsBuilding.set(ifaceId, bucket);
55
+ }
56
+ bucket.push(ownerId);
57
+ }
58
+ }
59
+ const implsByInterfaceDefId = new Map();
60
+ for (const [ifaceId, owners] of implsBuilding) {
61
+ implsByInterfaceDefId.set(ifaceId, Object.freeze(owners.slice()));
62
+ }
63
+ return wrapIndex(mroByOwnerDefId, implsByInterfaceDefId);
64
+ }
65
+ // ─── Internal ───────────────────────────────────────────────────────────────
66
+ const EMPTY = Object.freeze([]);
67
+ function wrapIndex(mroByOwnerDefId, implsByInterfaceDefId) {
68
+ return {
69
+ mroByOwnerDefId,
70
+ implsByInterfaceDefId,
71
+ mroFor(ownerDefId) {
72
+ return mroByOwnerDefId.get(ownerDefId) ?? EMPTY;
73
+ },
74
+ implementorsOf(interfaceDefId) {
75
+ return implsByInterfaceDefId.get(interfaceDefId) ?? EMPTY;
76
+ },
77
+ };
78
+ }
79
+ //# sourceMappingURL=method-dispatch-index.js.map