gitnexus 1.6.6-rc.70 → 1.6.6-rc.72

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 (43) hide show
  1. package/dist/core/ingestion/languages/cobol/captures.d.ts +13 -0
  2. package/dist/core/ingestion/languages/cobol/captures.js +227 -0
  3. package/dist/core/ingestion/languages/cobol/index.d.ts +14 -0
  4. package/dist/core/ingestion/languages/cobol/index.js +14 -0
  5. package/dist/core/ingestion/languages/cobol/interpret.d.ts +46 -0
  6. package/dist/core/ingestion/languages/cobol/interpret.js +79 -0
  7. package/dist/core/ingestion/languages/cobol/scope-resolver.d.ts +13 -0
  8. package/dist/core/ingestion/languages/cobol/scope-resolver.js +69 -0
  9. package/dist/core/ingestion/languages/cobol.js +9 -2
  10. package/dist/core/ingestion/languages/typescript/import-target.d.ts +3 -0
  11. package/dist/core/ingestion/languages/typescript/import-target.js +1 -1
  12. package/dist/core/ingestion/languages/typescript/scope-resolver.js +5 -1
  13. package/dist/core/ingestion/registry-primary-flag.d.ts +3 -2
  14. package/dist/core/ingestion/registry-primary-flag.js +3 -2
  15. package/dist/core/ingestion/scope-resolution/pipeline/registry.js +2 -0
  16. package/package.json +1 -1
  17. package/web/assets/{agent-BNViyptx.js → agent-ztCmSzAP.js} +55 -55
  18. package/web/assets/{architectureDiagram-UL44E2DR-DO5inHmm.js → architectureDiagram-UL44E2DR-UbBGKtKc.js} +1 -1
  19. package/web/assets/{chunk-LCXTWHL2-DhdrdQ7D.js → chunk-LCXTWHL2-CNag8uwS.js} +1 -1
  20. package/web/assets/{chunk-RG4AUYOV-DBj3-_VI.js → chunk-RG4AUYOV-BsPxAzSB.js} +1 -1
  21. package/web/assets/{classDiagram-KGZ6W3CR-BTB1tQAy.js → classDiagram-KGZ6W3CR-hyXalbgI.js} +1 -1
  22. package/web/assets/{classDiagram-v2-72OJOZXJ-V77T4eMR.js → classDiagram-v2-72OJOZXJ-BZvBt1Jw.js} +1 -1
  23. package/web/assets/{diagram-3NCE3AQN-4wwT76SR.js → diagram-3NCE3AQN-BPy1qvxM.js} +1 -1
  24. package/web/assets/{diagram-GF46GFSD-1KA4CdVb.js → diagram-GF46GFSD-DHZvmDr6.js} +1 -1
  25. package/web/assets/{diagram-QXG6HAR7-DyJXA8oH.js → diagram-QXG6HAR7-h2JaRLwM.js} +1 -1
  26. package/web/assets/{diagram-WEQXMOUZ-SaMOxwEm.js → diagram-WEQXMOUZ-BQasYj8c.js} +1 -1
  27. package/web/assets/{erDiagram-L5TCEMPS-CQrHY5G4.js → erDiagram-L5TCEMPS-CKNmoGli.js} +1 -1
  28. package/web/assets/{flowDiagram-H6V6AXG4-D76sobt4.js → flowDiagram-H6V6AXG4-BUtBrFuB.js} +1 -1
  29. package/web/assets/{index-C0tkkul6.js → index-BTynj0rU.js} +6 -6
  30. package/web/assets/{infoDiagram-3YFTVSEB-DSjuC3eN.js → infoDiagram-3YFTVSEB-FmBeKKHR.js} +1 -1
  31. package/web/assets/{ishikawaDiagram-BNXS4ZKH-BRvPjFcQ.js → ishikawaDiagram-BNXS4ZKH-CBIehaQ8.js} +1 -1
  32. package/web/assets/{kanban-definition-75IXJCU3-CvhjvMdi.js → kanban-definition-75IXJCU3-BkQHGPDZ.js} +1 -1
  33. package/web/assets/{mindmap-definition-2TDM6QVE-DAt0LLtT.js → mindmap-definition-2TDM6QVE-CtjovahQ.js} +1 -1
  34. package/web/assets/{pieDiagram-CU6KROY3-wcL42rsj.js → pieDiagram-CU6KROY3-DJ7mL2OO.js} +1 -1
  35. package/web/assets/{requirementDiagram-JXO7QTGE-6rMJxIMd.js → requirementDiagram-JXO7QTGE-BQ-a2UHa.js} +1 -1
  36. package/web/assets/{sequenceDiagram-VS2MUI6T-Qxw2CKq9.js → sequenceDiagram-VS2MUI6T-Dq-E41TD.js} +1 -1
  37. package/web/assets/{stateDiagram-7D4R322I-59Ejn7s2.js → stateDiagram-7D4R322I-DyXkAThk.js} +1 -1
  38. package/web/assets/{stateDiagram-v2-36443NZ5-DuJ-XKAm.js → stateDiagram-v2-36443NZ5-x6kVl63Y.js} +1 -1
  39. package/web/assets/{timeline-definition-O6YCAMPW-31ZPtVTp.js → timeline-definition-O6YCAMPW-CnIsqFeF.js} +1 -1
  40. package/web/assets/{vennDiagram-MWXL3ELB-DF2g9kQO.js → vennDiagram-MWXL3ELB-Ce24QI5i.js} +1 -1
  41. package/web/assets/{wardleyDiagram-CUQ6CDDI-DEhL8j4N.js → wardleyDiagram-CUQ6CDDI-BFmc79Jd.js} +1 -1
  42. package/web/assets/{xychartDiagram-N2JHSOCM-BhcF9p43.js → xychartDiagram-N2JHSOCM-CIcd2MDJ.js} +1 -1
  43. package/web/index.html +1 -1
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `emitScopeCaptures` for COBOL.
3
+ *
4
+ * Wraps the existing regex tagger (`extractCobolSymbolsWithRegex`) and
5
+ * produces parser-agnostic `CaptureMatch[]` matching the RFC §5.1
6
+ * vocabulary. The central `ScopeExtractor` consumes these captures
7
+ * without knowing whether they came from tree-sitter or regex.
8
+ *
9
+ * Pure given the input source text. No I/O, no globals consulted.
10
+ * The regex tagger is synchronous — no async needed.
11
+ */
12
+ import type { CaptureMatch } from '../../../../_shared/index.js';
13
+ export declare function emitCobolScopeCaptures(sourceText: string, _filePath: string, _cachedTree?: unknown): readonly CaptureMatch[];
@@ -0,0 +1,227 @@
1
+ /**
2
+ * `emitScopeCaptures` for COBOL.
3
+ *
4
+ * Wraps the existing regex tagger (`extractCobolSymbolsWithRegex`) and
5
+ * produces parser-agnostic `CaptureMatch[]` matching the RFC §5.1
6
+ * vocabulary. The central `ScopeExtractor` consumes these captures
7
+ * without knowing whether they came from tree-sitter or regex.
8
+ *
9
+ * Pure given the input source text. No I/O, no globals consulted.
10
+ * The regex tagger is synchronous — no async needed.
11
+ */
12
+ import { extractCobolSymbolsWithRegex, preprocessCobolSource, } from '../../cobol/cobol-preprocessor.js';
13
+ // ---------------------------------------------------------------------------
14
+ // Capture building helpers
15
+ // ---------------------------------------------------------------------------
16
+ function capture(name, range, text) {
17
+ return { name, range, text };
18
+ }
19
+ function rangeOf(startLine, startCol, endLine, endCol) {
20
+ return { startLine, startCol, endLine, endCol };
21
+ }
22
+ /**
23
+ * Build a single CaptureMatch from a record of captures.
24
+ * Returns null if the record is empty.
25
+ */
26
+ function matchFrom(grouped) {
27
+ if (Object.keys(grouped).length === 0)
28
+ return null;
29
+ return Object.freeze(grouped);
30
+ }
31
+ /**
32
+ * Compute end column for a single-line capture from the source lines array.
33
+ */
34
+ function endColFrom(line) {
35
+ return line.length > 0 ? line.length - 1 : 0;
36
+ }
37
+ // ---------------------------------------------------------------------------
38
+ // Main entry point
39
+ // ---------------------------------------------------------------------------
40
+ export function emitCobolScopeCaptures(sourceText, _filePath, _cachedTree) {
41
+ const lines = sourceText.split(/\r?\n/);
42
+ // Preprocess: strip patch markers from columns 1-6
43
+ const cleaned = preprocessCobolSource(sourceText);
44
+ // Run the regex tagger on the preprocessed source
45
+ const extracted = extractCobolSymbolsWithRegex(cleaned, _filePath);
46
+ const out = [];
47
+ // ── 1. PROGRAM-ID → @scope.module ───────────────────────────────────
48
+ // The primary program name (first PROGRAM-ID encountered)
49
+ if (extracted.programName) {
50
+ const name = extracted.programName;
51
+ const lastLine = lines.length;
52
+ const progDef = extracted.programs.find((p) => p.name.toUpperCase() === name.toUpperCase());
53
+ const startLine = progDef?.startLine ?? 1;
54
+ const endLine = progDef?.endLine ?? lastLine;
55
+ const startCol = 0;
56
+ const endCol = endColFrom(lines[Math.min(endLine, lines.length) - 1] ?? '');
57
+ const progIdLine = findProgramIdLine(cleaned, name);
58
+ const nameRange = progIdLine !== -1
59
+ ? rangeOf(progIdLine, 7, progIdLine, lines[progIdLine - 1]?.length ?? endCol)
60
+ : rangeOf(startLine, startCol, endLine, endCol);
61
+ const grouped = {
62
+ '@scope.module': capture('@scope.module', nameRange, name),
63
+ '@declaration.program': capture('@declaration.program', rangeOf(startLine, startCol, endLine, endCol), name),
64
+ '@declaration.name': capture('@declaration.name', nameRange, name),
65
+ };
66
+ if (progDef?.procedureUsing && progDef.procedureUsing.length > 0) {
67
+ grouped['@declaration.parameter-count'] = capture('@declaration.parameter-count', nameRange, String(progDef.procedureUsing.length));
68
+ }
69
+ const m = matchFrom(grouped);
70
+ if (m !== null)
71
+ out.push(m);
72
+ }
73
+ // ── 2. Nested / additional programs → @scope.module ──────────────
74
+ for (const prog of extracted.programs) {
75
+ if (extracted.programName && prog.name.toUpperCase() === extracted.programName.toUpperCase())
76
+ continue;
77
+ const startLine = prog.startLine;
78
+ const endLine = prog.endLine;
79
+ const startCol = 0;
80
+ const endCol = endColFrom(lines[Math.min(endLine, lines.length) - 1] ?? '');
81
+ const progIdLine = findProgramIdLine(cleaned, prog.name);
82
+ const nameRange = progIdLine !== -1
83
+ ? rangeOf(progIdLine, 7, progIdLine, lines[progIdLine - 1]?.length ?? endCol)
84
+ : rangeOf(startLine, startCol, endLine, endCol);
85
+ const grouped = {
86
+ '@scope.module': capture('@scope.module', nameRange, prog.name),
87
+ '@declaration.program': capture('@declaration.program', rangeOf(startLine, startCol, endLine, endCol), prog.name),
88
+ '@declaration.name': capture('@declaration.name', nameRange, prog.name),
89
+ };
90
+ if (prog.procedureUsing && prog.procedureUsing.length > 0) {
91
+ grouped['@declaration.parameter-count'] = capture('@declaration.parameter-count', nameRange, String(prog.procedureUsing.length));
92
+ }
93
+ const m = matchFrom(grouped);
94
+ if (m !== null)
95
+ out.push(m);
96
+ }
97
+ // ── 3. PROCEDURE DIVISION sections → @scope.function ─────────────
98
+ for (const section of extracted.sections) {
99
+ const lineIdx = section.line - 1;
100
+ if (lineIdx < 0 || lineIdx >= lines.length)
101
+ continue;
102
+ const sectionLine = lines[lineIdx];
103
+ const startCol = 0;
104
+ const endCol = endColFrom(sectionLine);
105
+ const nameRange = rangeOf(section.line, startCol, section.line, endCol);
106
+ const grouped = {
107
+ '@scope.function': capture('@scope.function', nameRange, section.name),
108
+ '@declaration.function': capture('@declaration.function', nameRange, section.name),
109
+ '@declaration.name': capture('@declaration.name', nameRange, section.name),
110
+ };
111
+ const m = matchFrom(grouped);
112
+ if (m !== null)
113
+ out.push(m);
114
+ }
115
+ // ── 4. Paragraphs → @scope.function ──────────────────────────────
116
+ for (const para of extracted.paragraphs) {
117
+ const lineIdx = para.line - 1;
118
+ if (lineIdx < 0 || lineIdx >= lines.length)
119
+ continue;
120
+ const paraLine = lines[lineIdx];
121
+ const startCol = 0;
122
+ const endCol = endColFrom(paraLine);
123
+ const nameRange = rangeOf(para.line, startCol, para.line, endCol);
124
+ const grouped = {
125
+ '@scope.function': capture('@scope.function', nameRange, para.name),
126
+ '@declaration.function': capture('@declaration.function', nameRange, para.name),
127
+ '@declaration.name': capture('@declaration.name', nameRange, para.name),
128
+ };
129
+ const m = matchFrom(grouped);
130
+ if (m !== null)
131
+ out.push(m);
132
+ }
133
+ // ── 5. COPY → @import.statement ──────────────────────────────────
134
+ for (const copy of extracted.copies) {
135
+ const lineIdx = copy.line - 1;
136
+ if (lineIdx < 0 || lineIdx >= lines.length)
137
+ continue;
138
+ const copyLine = lines[lineIdx];
139
+ const startCol = 0;
140
+ const endCol = endColFrom(copyLine);
141
+ const stmtRange = rangeOf(copy.line, startCol, copy.line, endCol);
142
+ const grouped = {
143
+ '@import.statement': capture('@import.statement', stmtRange, copy.target),
144
+ '@import.name': capture('@import.name', stmtRange, copy.target),
145
+ };
146
+ const m = matchFrom(grouped);
147
+ if (m !== null)
148
+ out.push(m);
149
+ }
150
+ // ── 6. CALL (quoted/referenced) → @reference.call ────────────────
151
+ for (const call of extracted.calls) {
152
+ const lineIdx = call.line - 1;
153
+ if (lineIdx < 0 || lineIdx >= lines.length)
154
+ continue;
155
+ const callLine = lines[lineIdx];
156
+ const startCol = 0;
157
+ const endCol = endColFrom(callLine);
158
+ const stmtRange = rangeOf(call.line, startCol, call.line, endCol);
159
+ const grouped = {
160
+ '@reference.call': capture('@reference.call', stmtRange, call.target),
161
+ '@reference.name': capture('@reference.name', stmtRange, call.target),
162
+ };
163
+ // Arity from CALL USING parameters
164
+ if (call.parameters && call.parameters.length > 0) {
165
+ grouped['@reference.arity'] = capture('@reference.arity', stmtRange, String(call.parameters.length));
166
+ }
167
+ const m = matchFrom(grouped);
168
+ if (m !== null)
169
+ out.push(m);
170
+ }
171
+ // ── 7. PERFORM → @reference.call ─────────────────────────────────
172
+ for (const perf of extracted.performs) {
173
+ const lineIdx = perf.line - 1;
174
+ if (lineIdx < 0 || lineIdx >= lines.length)
175
+ continue;
176
+ const perfLine = lines[lineIdx];
177
+ const startCol = 0;
178
+ const endCol = endColFrom(perfLine);
179
+ const stmtRange = rangeOf(perf.line, startCol, perf.line, endCol);
180
+ const grouped = {
181
+ '@reference.call': capture('@reference.call', stmtRange, perf.target),
182
+ '@reference.name': capture('@reference.name', stmtRange, perf.target),
183
+ };
184
+ const m = matchFrom(grouped);
185
+ if (m !== null)
186
+ out.push(m);
187
+ }
188
+ // ── 8. GO TO → @reference.call ───────────────────────────────────
189
+ for (const gt of extracted.gotos) {
190
+ const lineIdx = gt.line - 1;
191
+ if (lineIdx < 0 || lineIdx >= lines.length)
192
+ continue;
193
+ const gtLine = lines[lineIdx];
194
+ const startCol = 0;
195
+ const endCol = endColFrom(gtLine);
196
+ const stmtRange = rangeOf(gt.line, startCol, gt.line, endCol);
197
+ const grouped = {
198
+ '@reference.call': capture('@reference.call', stmtRange, gt.target),
199
+ '@reference.name': capture('@reference.name', stmtRange, gt.target),
200
+ };
201
+ const m = matchFrom(grouped);
202
+ if (m !== null)
203
+ out.push(m);
204
+ }
205
+ return out;
206
+ }
207
+ // ---------------------------------------------------------------------------
208
+ // Helpers
209
+ // ---------------------------------------------------------------------------
210
+ /**
211
+ * Find the PROGRAM-ID. line for a given program name in the cleaned source.
212
+ * Returns 1-based line number, or -1 if not found.
213
+ */
214
+ function findProgramIdLine(cleanedSource, programName) {
215
+ const lines = cleanedSource.split(/\r?\n/);
216
+ const upper = programName.toUpperCase();
217
+ const re = new RegExp(`\\bPROGRAM-ID\\.\\s*${escapeRegex(upper)}\\b`, 'i');
218
+ for (let i = 0; i < lines.length; i++) {
219
+ if (re.test(lines[i]))
220
+ return i + 1; // 1-based
221
+ }
222
+ return -1;
223
+ }
224
+ /** Simple regex escape for special chars. */
225
+ function escapeRegex(s) {
226
+ return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
227
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * COBOL scope-resolution public API barrel.
3
+ *
4
+ * Consumers should import from this file rather than the individual
5
+ * modules — that keeps the per-hook organization an implementation
6
+ * detail we can refactor without touching the provider wiring.
7
+ *
8
+ * Module layout:
9
+ *
10
+ * - `captures.ts` — `emitCobolScopeCaptures` (wraps the regex tagger)
11
+ * - `interpret.ts` — import/type-binding/receiver hooks
12
+ */
13
+ export { emitCobolScopeCaptures } from './captures.js';
14
+ export { interpretCobolImport, interpretCobolTypeBinding, cobolImportOwningScope, cobolReceiverBinding, } from './interpret.js';
@@ -0,0 +1,14 @@
1
+ /**
2
+ * COBOL scope-resolution public API barrel.
3
+ *
4
+ * Consumers should import from this file rather than the individual
5
+ * modules — that keeps the per-hook organization an implementation
6
+ * detail we can refactor without touching the provider wiring.
7
+ *
8
+ * Module layout:
9
+ *
10
+ * - `captures.ts` — `emitCobolScopeCaptures` (wraps the regex tagger)
11
+ * - `interpret.ts` — import/type-binding/receiver hooks
12
+ */
13
+ export { emitCobolScopeCaptures } from './captures.js';
14
+ export { interpretCobolImport, interpretCobolTypeBinding, cobolImportOwningScope, cobolReceiverBinding, } from './interpret.js';
@@ -0,0 +1,46 @@
1
+ /**
2
+ * COBOL scope-resolution interpret hooks.
3
+ *
4
+ * Interprets raw `@import.statement` capture matches (from COPY statements)
5
+ * into `ParsedImport` for the central finalize algorithm.
6
+ *
7
+ * COBOL's import semantic is simple: `COPY bookname` means the copybook's
8
+ * content is inlined at compile time. There is no module-system equivalent
9
+ * of `export` — everything is text-inclusion. The scope-resolution pipeline
10
+ * models this as a `'named'` import where the imported name is the copybook
11
+ * name and the target is the copybook file path.
12
+ */
13
+ import type { CaptureMatch, ParsedImport, ParsedTypeBinding, ScopeId, ScopeTree, Scope, TypeRef } from '../../../../_shared/index.js';
14
+ /**
15
+ * Interpret a COPY statement as a `ParsedImport`.
16
+ *
17
+ * The `@import.name` capture contains the copybook target name (e.g.,
18
+ * `CPSESP` from `COPY CPSESP.`). Returns a `'named'` import with the
19
+ * copybook name as both `localName` and `importedName`.
20
+ *
21
+ * Returns `null` for any match that doesn't carry an `@import.name` (e.g.,
22
+ * malformed COPY statements the regex tagger might emit).
23
+ */
24
+ export declare function interpretCobolImport(match: CaptureMatch): ParsedImport | null;
25
+ /**
26
+ * COBOL has no type system — no type bindings to interpret.
27
+ * Always returns `null`.
28
+ */
29
+ export declare function interpretCobolTypeBinding(_match: CaptureMatch): ParsedTypeBinding | null;
30
+ /**
31
+ * COPY statements in COBOL are module-level — they expand inline at
32
+ * compile time and their bindings belong to the enclosing PROGRAM-ID
33
+ * (Module) scope. Walk up from the innermost scope through ancestors
34
+ * to find the enclosing Module scope.
35
+ *
36
+ * For the edge case of a COPY inside a paragraph (unusual but possible
37
+ * with some vendors), we walk the scope tree to ensure the import is
38
+ * attached to the program scope, not the paragraph Function scope.
39
+ */
40
+ export declare function cobolImportOwningScope(_imp: ParsedImport, innermost: Scope, tree: ScopeTree): ScopeId | null;
41
+ /**
42
+ * COBOL has no implicit receiver (no `self`, `this`, or equivalent).
43
+ * All function calls are explicit CALL statements or PERFORM/GO TO
44
+ * control flow. Always returns `null`.
45
+ */
46
+ export declare function cobolReceiverBinding(_functionScope: Scope): TypeRef | null;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * COBOL scope-resolution interpret hooks.
3
+ *
4
+ * Interprets raw `@import.statement` capture matches (from COPY statements)
5
+ * into `ParsedImport` for the central finalize algorithm.
6
+ *
7
+ * COBOL's import semantic is simple: `COPY bookname` means the copybook's
8
+ * content is inlined at compile time. There is no module-system equivalent
9
+ * of `export` — everything is text-inclusion. The scope-resolution pipeline
10
+ * models this as a `'named'` import where the imported name is the copybook
11
+ * name and the target is the copybook file path.
12
+ */
13
+ // ─── interpretImport ──────────────────────────────────────────────────────
14
+ /**
15
+ * Interpret a COPY statement as a `ParsedImport`.
16
+ *
17
+ * The `@import.name` capture contains the copybook target name (e.g.,
18
+ * `CPSESP` from `COPY CPSESP.`). Returns a `'named'` import with the
19
+ * copybook name as both `localName` and `importedName`.
20
+ *
21
+ * Returns `null` for any match that doesn't carry an `@import.name` (e.g.,
22
+ * malformed COPY statements the regex tagger might emit).
23
+ */
24
+ export function interpretCobolImport(match) {
25
+ const nameCap = match['@import.name'];
26
+ if (nameCap === undefined)
27
+ return null;
28
+ const name = nameCap.text;
29
+ if (name === '')
30
+ return null;
31
+ return {
32
+ kind: 'named',
33
+ localName: name,
34
+ importedName: name,
35
+ targetRaw: name,
36
+ };
37
+ }
38
+ // ─── interpretTypeBinding ─────────────────────────────────────────────────
39
+ /**
40
+ * COBOL has no type system — no type bindings to interpret.
41
+ * Always returns `null`.
42
+ */
43
+ export function interpretCobolTypeBinding(_match) {
44
+ return null;
45
+ }
46
+ // ─── importOwningScope ────────────────────────────────────────────────────
47
+ /**
48
+ * COPY statements in COBOL are module-level — they expand inline at
49
+ * compile time and their bindings belong to the enclosing PROGRAM-ID
50
+ * (Module) scope. Walk up from the innermost scope through ancestors
51
+ * to find the enclosing Module scope.
52
+ *
53
+ * For the edge case of a COPY inside a paragraph (unusual but possible
54
+ * with some vendors), we walk the scope tree to ensure the import is
55
+ * attached to the program scope, not the paragraph Function scope.
56
+ */
57
+ export function cobolImportOwningScope(_imp, innermost, tree) {
58
+ // If already in a Module scope, use it directly.
59
+ if (innermost.kind === 'Module')
60
+ return innermost.id;
61
+ // Walk through ancestors to find the enclosing Module.
62
+ const ancestors = tree.getAncestors(innermost.id);
63
+ for (const ancId of ancestors) {
64
+ const anc = tree.getScope(ancId);
65
+ if (anc !== undefined && anc.kind === 'Module')
66
+ return ancId;
67
+ }
68
+ // Fallback: delegate to central default.
69
+ return null;
70
+ }
71
+ // ─── receiverBinding ──────────────────────────────────────────────────────
72
+ /**
73
+ * COBOL has no implicit receiver (no `self`, `this`, or equivalent).
74
+ * All function calls are explicit CALL statements or PERFORM/GO TO
75
+ * control flow. Always returns `null`.
76
+ */
77
+ export function cobolReceiverBinding(_functionScope) {
78
+ return null;
79
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * COBOL `ScopeResolver` registered in `SCOPE_RESOLVERS` and consumed
3
+ * by the generic `runScopeResolution` orchestrator.
4
+ *
5
+ * The provider is a thin wiring object — COBOL's simple scope model
6
+ * (Module + Function only, no inheritance, no type system) plugs into
7
+ * `runScopeResolution` with minimal configuration.
8
+ *
9
+ * Reference: `languages/python/scope-resolver.ts`.
10
+ */
11
+ import type { ScopeResolver } from '../../scope-resolution/contract/scope-resolver.js';
12
+ declare const cobolScopeResolver: ScopeResolver;
13
+ export { cobolScopeResolver };
@@ -0,0 +1,69 @@
1
+ /**
2
+ * COBOL `ScopeResolver` registered in `SCOPE_RESOLVERS` and consumed
3
+ * by the generic `runScopeResolution` orchestrator.
4
+ *
5
+ * The provider is a thin wiring object — COBOL's simple scope model
6
+ * (Module + Function only, no inheritance, no type system) plugs into
7
+ * `runScopeResolution` with minimal configuration.
8
+ *
9
+ * Reference: `languages/python/scope-resolver.ts`.
10
+ */
11
+ import path from 'node:path';
12
+ import { SupportedLanguages } from '../../../../_shared/index.js';
13
+ import { populateClassOwnedMembers } from '../../scope-resolution/scope/walkers.js';
14
+ import { cobolProvider } from '../cobol.js';
15
+ // Copybook file extensions for COPY name resolution
16
+ const COPYBOOK_EXTENSIONS = new Set(['.cpy', '.copybook']);
17
+ const cobolScopeResolver = {
18
+ language: SupportedLanguages.Cobol,
19
+ languageProvider: cobolProvider,
20
+ importEdgeReason: 'cobol-scope: copy',
21
+ // ── Resolve COPY bookname to file path ─────────────────────────────
22
+ resolveImportTarget: (targetRaw, _fromFile, allFilePaths) => {
23
+ const upper = targetRaw.toUpperCase();
24
+ // Check copybook files first
25
+ for (const fp of allFilePaths) {
26
+ const ext = path.extname(fp).toLowerCase();
27
+ if (!COPYBOOK_EXTENSIONS.has(ext))
28
+ continue;
29
+ const basename = path.basename(fp, ext).toUpperCase();
30
+ if (basename === upper)
31
+ return fp;
32
+ }
33
+ // Also search COBOL source files (.cbl, .cob, .cobol)
34
+ const COBOL_SOURCE_EXTS = new Set(['.cbl', '.cob', '.cobol']);
35
+ for (const fp of allFilePaths) {
36
+ const ext = path.extname(fp).toLowerCase();
37
+ if (!COBOL_SOURCE_EXTS.has(ext))
38
+ continue;
39
+ const basename = path.basename(fp, ext).toUpperCase();
40
+ if (basename === upper)
41
+ return fp;
42
+ }
43
+ return null;
44
+ },
45
+ // COBOL has no binding-merge rules beyond the default (local-first-then-imports).
46
+ mergeBindings: (existing) => [...existing],
47
+ // COBOL arity: compare CALL USING param count against def's parameterCount.
48
+ // COBOL requires exact arity match for CALL USING.
49
+ arityCompatibility: (callsite, def) => {
50
+ if (callsite.arity === undefined)
51
+ return 'unknown';
52
+ const defParamCount = def.parameterCount;
53
+ if (defParamCount === undefined)
54
+ return 'unknown';
55
+ if (callsite.arity === defParamCount)
56
+ return 'compatible';
57
+ return 'incompatible';
58
+ },
59
+ // No inheritance in COBOL — empty MRO map.
60
+ buildMro: () => new Map(),
61
+ // Everything lives under the PROGRAM-ID Module scope.
62
+ populateOwners: (parsed) => populateClassOwnedMembers(parsed),
63
+ // COBOL has no super calls.
64
+ isSuperReceiver: () => false,
65
+ // ── Optional toggles ─────────────────────────────────────────────
66
+ fieldFallbackOnMethodLookup: false,
67
+ propagatesReturnTypesAcrossImports: false,
68
+ };
69
+ export { cobolScopeResolver };
@@ -6,11 +6,13 @@
6
6
  * processed by cobol-processor.ts in pipeline Phase 2.6, not by the
7
7
  * tree-sitter pipeline.
8
8
  *
9
- * This provider exists to satisfy the SupportedLanguages exhaustiveness
10
- * checks and to declare parseStrategy: 'standalone'.
9
+ * This provider supports scope-based resolution (RFC #909 Ring 3) via
10
+ * `emitScopeCaptures` which wraps the regex tagger. COPY statements are
11
+ * interpreted as imports; there is no type system and no implicit receiver.
11
12
  */
12
13
  import { SupportedLanguages } from '../../../_shared/index.js';
13
14
  import { defineLanguage } from '../language-provider.js';
15
+ import { emitCobolScopeCaptures, interpretCobolImport, cobolImportOwningScope, cobolReceiverBinding, } from './cobol/index.js';
14
16
  export const cobolProvider = defineLanguage({
15
17
  id: SupportedLanguages.Cobol,
16
18
  parseStrategy: 'standalone',
@@ -25,4 +27,9 @@ export const cobolProvider = defineLanguage({
25
27
  },
26
28
  exportChecker: () => false,
27
29
  importResolver: () => null,
30
+ // ── Scope-resolution hooks ───────────────────────────────────────
31
+ emitScopeCaptures: emitCobolScopeCaptures,
32
+ interpretImport: interpretCobolImport,
33
+ importOwningScope: cobolImportOwningScope,
34
+ receiverBinding: cobolReceiverBinding,
28
35
  });
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import type { ParsedImport, WorkspaceIndex } from '../../../../_shared/index.js';
17
17
  import { SupportedLanguages } from '../../../../_shared/index.js';
18
+ import type { SuffixIndex } from '../../import-resolvers/utils.js';
18
19
  import type { TsconfigPaths } from '../../language-config.js';
19
20
  export interface TsResolveContext {
20
21
  readonly fromFile: string;
@@ -28,6 +29,8 @@ export interface TsResolveContext {
28
29
  readonly normalizedFileList?: readonly string[];
29
30
  /** Per-call resolution cache to dedupe repeated lookups. */
30
31
  readonly resolveCache?: Map<string, string | null>;
32
+ /** Prebuilt suffix index for O(1)-style package/absolute import matching. */
33
+ readonly index?: SuffixIndex;
31
34
  /** Parsed tsconfig path-aliases. `null` = no aliases configured. */
32
35
  readonly tsconfigPaths?: TsconfigPaths | null;
33
36
  /** JavaScript vs TypeScript switch — affects the extensions the
@@ -48,7 +48,7 @@ export function resolveTsTarget(targetRaw, ctx) {
48
48
  const allFileList = ctx.allFileList ?? Array.from(ctx.allFilePaths);
49
49
  const normalizedFileList = ctx.normalizedFileList ?? allFileList.map((f) => f.toLowerCase());
50
50
  const resolveCache = ctx.resolveCache ?? new Map();
51
- return resolveImportPath(ctx.fromFile, targetRaw, ctx.allFilePaths, allFileList, normalizedFileList, resolveCache, language, ctx.tsconfigPaths ?? null);
51
+ return resolveImportPath(ctx.fromFile, targetRaw, ctx.allFilePaths, allFileList, normalizedFileList, resolveCache, language, ctx.tsconfigPaths ?? null, ctx.index);
52
52
  }
53
53
  function narrowTsContext(workspaceIndex) {
54
54
  const ctx = workspaceIndex;
@@ -16,6 +16,7 @@ import { buildMro, defaultLinearize } from '../../scope-resolution/passes/mro.js
16
16
  import { populateClassOwnedMembers } from '../../scope-resolution/scope/walkers.js';
17
17
  import { typescriptProvider } from '../typescript.js';
18
18
  import { loadTsconfigPaths } from '../../language-config.js';
19
+ import { buildSuffixIndex } from '../../import-resolvers/utils.js';
19
20
  import { typescriptArityCompatibility, typescriptMergeBindings, resolveTsTarget, } from './index.js';
20
21
  /**
21
22
  * Build a `resolveImportTarget` adapter that memoizes the workspace
@@ -35,11 +36,13 @@ function makeTsResolveImportTarget() {
35
36
  return (targetRaw, fromFile, allFilePaths, resolutionConfig) => {
36
37
  if (cached === null || cached.key !== allFilePaths) {
37
38
  const allFileList = Array.from(allFilePaths);
39
+ const normalizedFileList = allFileList.map((f) => f.toLowerCase());
38
40
  cached = {
39
41
  key: allFilePaths,
40
42
  allFilePaths: new Set(allFilePaths),
41
43
  allFileList,
42
- normalizedFileList: allFileList.map((f) => f.toLowerCase()),
44
+ normalizedFileList,
45
+ index: buildSuffixIndex(normalizedFileList, allFileList),
43
46
  resolveCache: new Map(),
44
47
  };
45
48
  }
@@ -49,6 +52,7 @@ function makeTsResolveImportTarget() {
49
52
  allFilePaths: cached.allFilePaths,
50
53
  allFileList: cached.allFileList,
51
54
  normalizedFileList: cached.normalizedFileList,
55
+ index: cached.index,
52
56
  resolveCache: cached.resolveCache,
53
57
  tsconfigPaths: cfg?.tsconfigPaths ?? null,
54
58
  };
@@ -11,8 +11,9 @@
11
11
  * ## Contract
12
12
  *
13
13
  * - Env-var name per language: `REGISTRY_PRIMARY_<UPPER(enum-value)>`.
14
- * Example: `SupportedLanguages.Python` → `REGISTRY_PRIMARY_PYTHON`;
15
- * `SupportedLanguages.CPlusPlus` (value `'cpp'`) → `REGISTRY_PRIMARY_CPP`.
14
+ * Example: `SupportedLanguages.Python` → `REGISTRY_PRIMARY_PYTHON`;
15
+ * `SupportedLanguages.CPlusPlus` (value `'cpp'`) → `REGISTRY_PRIMARY_CPP`.
16
+ * `SupportedLanguages.Cobol` (value `'cobol'`) → `REGISTRY_PRIMARY_COBOL`.
16
17
  * - Truthy values: `'true'`, `'1'`, `'yes'` (case-insensitive,
17
18
  * whitespace-trimmed). Anything else — including `undefined`, empty
18
19
  * string, or unknown tokens — is `false`.
@@ -11,8 +11,9 @@
11
11
  * ## Contract
12
12
  *
13
13
  * - Env-var name per language: `REGISTRY_PRIMARY_<UPPER(enum-value)>`.
14
- * Example: `SupportedLanguages.Python` → `REGISTRY_PRIMARY_PYTHON`;
15
- * `SupportedLanguages.CPlusPlus` (value `'cpp'`) → `REGISTRY_PRIMARY_CPP`.
14
+ * Example: `SupportedLanguages.Python` → `REGISTRY_PRIMARY_PYTHON`;
15
+ * `SupportedLanguages.CPlusPlus` (value `'cpp'`) → `REGISTRY_PRIMARY_CPP`.
16
+ * `SupportedLanguages.Cobol` (value `'cobol'`) → `REGISTRY_PRIMARY_COBOL`.
16
17
  * - Truthy values: `'true'`, `'1'`, `'yes'` (case-insensitive,
17
18
  * whitespace-trimmed). Anything else — including `undefined`, empty
18
19
  * string, or unknown tokens — is `false`.
@@ -21,6 +21,7 @@ import { rustScopeResolver } from '../../languages/rust/scope-resolver.js';
21
21
  import { javascriptScopeResolver } from '../../languages/javascript/scope-resolver.js';
22
22
  import { kotlinScopeResolver } from '../../languages/kotlin/scope-resolver.js';
23
23
  import { rubyScopeResolver } from '../../languages/ruby/scope-resolver.js';
24
+ import { cobolScopeResolver } from '../../languages/cobol/scope-resolver.js';
24
25
  /** Map of `SupportedLanguages` → `ScopeResolver`. The phase iterates
25
26
  * this map intersected with `MIGRATED_LANGUAGES` (the per-language
26
27
  * flag set) so adding a resolver here without flipping the flag is
@@ -38,4 +39,5 @@ export const SCOPE_RESOLVERS = new Map([
38
39
  [SupportedLanguages.JavaScript, javascriptScopeResolver],
39
40
  [SupportedLanguages.Kotlin, kotlinScopeResolver],
40
41
  [SupportedLanguages.Ruby, rubyScopeResolver],
42
+ [SupportedLanguages.Cobol, cobolScopeResolver],
41
43
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.6-rc.70",
3
+ "version": "1.6.6-rc.72",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",