gitnexus 1.6.3-rc.4 → 1.6.3-rc.6

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 (26) hide show
  1. package/dist/_shared/index.d.ts +10 -0
  2. package/dist/_shared/index.d.ts.map +1 -1
  3. package/dist/_shared/index.js +8 -0
  4. package/dist/_shared/index.js.map +1 -1
  5. package/dist/_shared/scope-resolution/def-index.d.ts +36 -0
  6. package/dist/_shared/scope-resolution/def-index.d.ts.map +1 -0
  7. package/dist/_shared/scope-resolution/def-index.js +51 -0
  8. package/dist/_shared/scope-resolution/def-index.js.map +1 -0
  9. package/dist/_shared/scope-resolution/method-dispatch-index.d.ts +72 -0
  10. package/dist/_shared/scope-resolution/method-dispatch-index.d.ts.map +1 -0
  11. package/dist/_shared/scope-resolution/method-dispatch-index.js +79 -0
  12. package/dist/_shared/scope-resolution/method-dispatch-index.js.map +1 -0
  13. package/dist/_shared/scope-resolution/module-scope-index.d.ts +38 -0
  14. package/dist/_shared/scope-resolution/module-scope-index.d.ts.map +1 -0
  15. package/dist/_shared/scope-resolution/module-scope-index.js +50 -0
  16. package/dist/_shared/scope-resolution/module-scope-index.js.map +1 -0
  17. package/dist/_shared/scope-resolution/qualified-name-index.d.ts +44 -0
  18. package/dist/_shared/scope-resolution/qualified-name-index.d.ts.map +1 -0
  19. package/dist/_shared/scope-resolution/qualified-name-index.js +75 -0
  20. package/dist/_shared/scope-resolution/qualified-name-index.js.map +1 -0
  21. package/dist/_shared/scope-resolution/resolve-type-ref.d.ts +62 -0
  22. package/dist/_shared/scope-resolution/resolve-type-ref.d.ts.map +1 -0
  23. package/dist/_shared/scope-resolution/resolve-type-ref.js +120 -0
  24. package/dist/_shared/scope-resolution/resolve-type-ref.js.map +1 -0
  25. package/dist/mcp/local/local-backend.js +10 -1
  26. package/package.json +1 -1
@@ -12,6 +12,16 @@ export { ORIGIN_PRIORITY } from './scope-resolution/origin-priority.js';
12
12
  export type { OriginForTieBreak } from './scope-resolution/origin-priority.js';
13
13
  export { LanguageClassifications, isProductionLanguage, } from './scope-resolution/language-classification.js';
14
14
  export type { LanguageClassification } from './scope-resolution/language-classification.js';
15
+ export { buildDefIndex } from './scope-resolution/def-index.js';
16
+ export type { DefIndex } from './scope-resolution/def-index.js';
17
+ export { buildModuleScopeIndex } from './scope-resolution/module-scope-index.js';
18
+ export type { ModuleScopeIndex, ModuleScopeEntry } from './scope-resolution/module-scope-index.js';
19
+ export { buildQualifiedNameIndex } from './scope-resolution/qualified-name-index.js';
20
+ export type { QualifiedNameIndex } from './scope-resolution/qualified-name-index.js';
21
+ export { resolveTypeRef } from './scope-resolution/resolve-type-ref.js';
22
+ export type { ResolveTypeRefContext, ScopeLookup } from './scope-resolution/resolve-type-ref.js';
23
+ export { buildMethodDispatchIndex } from './scope-resolution/method-dispatch-index.js';
24
+ export type { MethodDispatchIndex, MethodDispatchInput, } from './scope-resolution/method-dispatch-index.js';
15
25
  export { diffResolutions } from './scope-resolution/shadow/diff.js';
16
26
  export type { ShadowAgreement, ShadowCallsite, ShadowDiff, } from './scope-resolution/shadow/diff.js';
17
27
  export { aggregateDiffs } from './scope-resolution/shadow/aggregate.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAGzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACjG,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIrE,YAAY,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,YAAY,EACV,OAAO,EACP,KAAK,EACL,SAAS,EACT,KAAK,EACL,OAAO,EACP,YAAY,EACZ,UAAU,EACV,UAAU,EACV,OAAO,EACP,KAAK,EACL,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,QAAQ,GACT,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAG/E,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,+CAA+C,CAAC;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC;AAG5F,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,YAAY,EACV,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AACxE,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAGzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACjG,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIrE,YAAY,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,YAAY,EACV,OAAO,EACP,KAAK,EACL,SAAS,EACT,KAAK,EACL,OAAO,EACP,YAAY,EACZ,UAAU,EACV,UAAU,EACV,OAAO,EACP,KAAK,EACL,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,QAAQ,GACT,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAG/E,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,+CAA+C,CAAC;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC;AAG5F,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,YAAY,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACjF,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AACnG,OAAO,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AACrF,YAAY,EAAE,kBAAkB,EAAE,MAAM,4CAA4C,CAAC;AAGrF,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AACxE,YAAY,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAGjG,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AACvF,YAAY,EACV,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,6CAA6C,CAAC;AAGrD,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,YAAY,EACV,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AACxE,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC"}
@@ -8,6 +8,14 @@ export { EvidenceWeights, typeBindingWeightAtDepth } from './scope-resolution/ev
8
8
  export { ORIGIN_PRIORITY } from './scope-resolution/origin-priority.js';
9
9
  // Language classification (RFC §6.1 Ring 3/4 governance)
10
10
  export { LanguageClassifications, isProductionLanguage, } from './scope-resolution/language-classification.js';
11
+ // Core indexes over per-file artifacts (RFC §3.1; Ring 2 SHARED #913)
12
+ export { buildDefIndex } from './scope-resolution/def-index.js';
13
+ export { buildModuleScopeIndex } from './scope-resolution/module-scope-index.js';
14
+ export { buildQualifiedNameIndex } from './scope-resolution/qualified-name-index.js';
15
+ // Strict type-reference resolver (RFC §4.6; Ring 2 SHARED #916)
16
+ export { resolveTypeRef } from './scope-resolution/resolve-type-ref.js';
17
+ // Method-dispatch materialized view over HeritageMap (RFC §3.1; Ring 2 SHARED #914)
18
+ export { buildMethodDispatchIndex } from './scope-resolution/method-dispatch-index.js';
11
19
  // Shadow-mode diff + aggregation (RFC §6.3; Ring 2 SHARED #918)
12
20
  export { diffResolutions } from './scope-resolution/shadow/diff.js';
13
21
  export { aggregateDiffs } from './scope-resolution/shadow/aggregate.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAGpC,mBAAmB;AACnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAiCjG,8DAA8D;AAC9D,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAGxE,yDAAyD;AACzD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,+CAA+C,CAAC;AAGvD,gEAAgE;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAMpE,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAGpC,mBAAmB;AACnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAiCjG,8DAA8D;AAC9D,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAGxE,yDAAyD;AACzD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,+CAA+C,CAAC;AAGvD,sEAAsE;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAEjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AAGrF,gEAAgE;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAGxE,oFAAoF;AACpF,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AAMvF,gEAAgE;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAMpE,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * `DefIndex` — O(1) `DefId → SymbolDefinition` materialization.
3
+ *
4
+ * The global "what is this id?" lookup. Every per-kind registry (ClassRegistry,
5
+ * MethodRegistry, FieldRegistry) returns `DefId[]` and resolves them back to
6
+ * full `SymbolDefinition` records through this index — one central hash map,
7
+ * one allocation per def.
8
+ *
9
+ * Part of RFC #909 Ring 2 SHARED — #913.
10
+ *
11
+ * Consumed by: #917 (`Registry.lookup` implementations), #915 (SCC finalize).
12
+ */
13
+ import type { SymbolDefinition } from './symbol-definition.js';
14
+ import type { DefId } from './types.js';
15
+ export interface DefIndex {
16
+ readonly byId: ReadonlyMap<DefId, SymbolDefinition>;
17
+ readonly size: number;
18
+ get(id: DefId): SymbolDefinition | undefined;
19
+ has(id: DefId): boolean;
20
+ }
21
+ /**
22
+ * Build a `DefIndex` from a flat list of `SymbolDefinition` records.
23
+ *
24
+ * **Collision policy: first-write-wins.** `DefId` is meant to be unique
25
+ * (`nodeId` is the stable graph identifier), so a collision indicates an
26
+ * upstream bug — most likely the same symbol parsed twice or a duplicate
27
+ * commit into the pipeline. Rather than silently overwriting with a later
28
+ * definition that may be partial or wrong, the first record wins and
29
+ * subsequent records for the same id are dropped. Pipeline bugs surface
30
+ * later as `has(id) === true` but the def looking older than expected,
31
+ * which is easier to debug than a silent overwrite.
32
+ *
33
+ * Pure function — safe to call repeatedly; no side effects.
34
+ */
35
+ export declare function buildDefIndex(defs: readonly SymbolDefinition[]): DefIndex;
36
+ //# sourceMappingURL=def-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"def-index.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/def-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,EAAE,KAAK,GAAG,gBAAgB,GAAG,SAAS,CAAC;IAC7C,GAAG,CAAC,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,GAAG,QAAQ,CAOzE"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * `DefIndex` — O(1) `DefId → SymbolDefinition` materialization.
3
+ *
4
+ * The global "what is this id?" lookup. Every per-kind registry (ClassRegistry,
5
+ * MethodRegistry, FieldRegistry) returns `DefId[]` and resolves them back to
6
+ * full `SymbolDefinition` records through this index — one central hash map,
7
+ * one allocation per def.
8
+ *
9
+ * Part of RFC #909 Ring 2 SHARED — #913.
10
+ *
11
+ * Consumed by: #917 (`Registry.lookup` implementations), #915 (SCC finalize).
12
+ */
13
+ /**
14
+ * Build a `DefIndex` from a flat list of `SymbolDefinition` records.
15
+ *
16
+ * **Collision policy: first-write-wins.** `DefId` is meant to be unique
17
+ * (`nodeId` is the stable graph identifier), so a collision indicates an
18
+ * upstream bug — most likely the same symbol parsed twice or a duplicate
19
+ * commit into the pipeline. Rather than silently overwriting with a later
20
+ * definition that may be partial or wrong, the first record wins and
21
+ * subsequent records for the same id are dropped. Pipeline bugs surface
22
+ * later as `has(id) === true` but the def looking older than expected,
23
+ * which is easier to debug than a silent overwrite.
24
+ *
25
+ * Pure function — safe to call repeatedly; no side effects.
26
+ */
27
+ export function buildDefIndex(defs) {
28
+ const byId = new Map();
29
+ for (const def of defs) {
30
+ if (byId.has(def.nodeId))
31
+ continue; // first-write-wins
32
+ byId.set(def.nodeId, def);
33
+ }
34
+ return freezeIndex(byId);
35
+ }
36
+ // ─── Internal ───────────────────────────────────────────────────────────────
37
+ function freezeIndex(byId) {
38
+ return {
39
+ byId,
40
+ get size() {
41
+ return byId.size;
42
+ },
43
+ get(id) {
44
+ return byId.get(id);
45
+ },
46
+ has(id) {
47
+ return byId.has(id);
48
+ },
49
+ };
50
+ }
51
+ //# sourceMappingURL=def-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"def-index.js","sourceRoot":"","sources":["../../src/scope-resolution/def-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,IAAiC;IAC7D,MAAM,IAAI,GAAG,IAAI,GAAG,EAA2B,CAAC;IAChD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,SAAS,CAAC,mBAAmB;QACvD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,+EAA+E;AAE/E,SAAS,WAAW,CAAC,IAAkC;IACrD,OAAO;QACL,IAAI;QACJ,IAAI,IAAI;YACN,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,CAAC;QACD,GAAG,CAAC,EAAS;YACX,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtB,CAAC;QACD,GAAG,CAAC,EAAS;YACX,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,72 @@
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
+ readonly implementsOf: (ownerDefId: DefId) => readonly DefId[];
70
+ }
71
+ export declare function buildMethodDispatchIndex(input: MethodDispatchInput): MethodDispatchIndex;
72
+ //# 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;;;;;;;OAOG;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 freezeIndex(mroByOwnerDefId, implsByInterfaceDefId);
64
+ }
65
+ // ─── Internal ───────────────────────────────────────────────────────────────
66
+ const EMPTY = Object.freeze([]);
67
+ function freezeIndex(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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"method-dispatch-index.js","sourceRoot":"","sources":["../../src/scope-resolution/method-dispatch-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAiDH,+EAA+E;AAE/E,MAAM,UAAU,wBAAwB,CAAC,KAA0B;IACjE,MAAM,eAAe,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC3D,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAqB,CAAC;IAE/C,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACnC,sEAAsE;QACtE,2DAA2D;QAC3D,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACxC,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC7D,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,IAAI,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACvB,IAAI,GAAG,IAAI,GAAG,EAAS,CAAC;gBACxB,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAC/B,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,SAAS;YAChC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAElB,IAAI,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM,GAAG,EAAE,CAAC;gBACZ,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACrC,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAA2B,CAAC;IACjE,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;QAC9C,qBAAqB,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,WAAW,CAAC,eAAe,EAAE,qBAAqB,CAAC,CAAC;AAC7D,CAAC;AAED,+EAA+E;AAE/E,MAAM,KAAK,GAAqB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAElD,SAAS,WAAW,CAClB,eAA6C,EAC7C,qBAAmD;IAEnD,OAAO;QACL,eAAe;QACf,qBAAqB;QACrB,MAAM,CAAC,UAAiB;YACtB,OAAO,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC;QAClD,CAAC;QACD,cAAc,CAAC,cAAqB;YAClC,OAAO,qBAAqB,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,KAAK,CAAC;QAC5D,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * `ModuleScopeIndex` — O(1) `filePath → moduleScopeId` lookup.
3
+ *
4
+ * Every file parsed produces exactly one `Module` scope at its root. The
5
+ * finalize algorithm needs to resolve `ImportEdge.targetFile` to a concrete
6
+ * module scope id in constant time during the link pass; this index is that
7
+ * mapping.
8
+ *
9
+ * Part of RFC #909 Ring 2 SHARED — #913.
10
+ *
11
+ * Consumed by: #915 (SCC finalize link pass), #923 (shadow harness when
12
+ * resolving callsite file → enclosing module).
13
+ */
14
+ import type { ScopeId } from './types.js';
15
+ export interface ModuleScopeIndex {
16
+ readonly byFilePath: ReadonlyMap<string, ScopeId>;
17
+ readonly size: number;
18
+ get(filePath: string): ScopeId | undefined;
19
+ has(filePath: string): boolean;
20
+ }
21
+ export interface ModuleScopeEntry {
22
+ readonly filePath: string;
23
+ readonly moduleScopeId: ScopeId;
24
+ }
25
+ /**
26
+ * Build a `ModuleScopeIndex` from a flat list of `{ filePath, moduleScopeId }`
27
+ * pairs.
28
+ *
29
+ * **Collision policy: first-write-wins.** A file should appear exactly once
30
+ * in a single ingestion run; collisions indicate the same file was parsed
31
+ * twice or a `filePath` normalization bug upstream. Dropping the later
32
+ * entry preserves the first-stable id the rest of the pipeline may already
33
+ * have registered against.
34
+ *
35
+ * Pure function — safe to call repeatedly; no side effects.
36
+ */
37
+ export declare function buildModuleScopeIndex(entries: readonly ModuleScopeEntry[]): ModuleScopeIndex;
38
+ //# sourceMappingURL=module-scope-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-scope-index.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/module-scope-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC3C,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,GAAG,gBAAgB,CAO5F"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * `ModuleScopeIndex` — O(1) `filePath → moduleScopeId` lookup.
3
+ *
4
+ * Every file parsed produces exactly one `Module` scope at its root. The
5
+ * finalize algorithm needs to resolve `ImportEdge.targetFile` to a concrete
6
+ * module scope id in constant time during the link pass; this index is that
7
+ * mapping.
8
+ *
9
+ * Part of RFC #909 Ring 2 SHARED — #913.
10
+ *
11
+ * Consumed by: #915 (SCC finalize link pass), #923 (shadow harness when
12
+ * resolving callsite file → enclosing module).
13
+ */
14
+ /**
15
+ * Build a `ModuleScopeIndex` from a flat list of `{ filePath, moduleScopeId }`
16
+ * pairs.
17
+ *
18
+ * **Collision policy: first-write-wins.** A file should appear exactly once
19
+ * in a single ingestion run; collisions indicate the same file was parsed
20
+ * twice or a `filePath` normalization bug upstream. Dropping the later
21
+ * entry preserves the first-stable id the rest of the pipeline may already
22
+ * have registered against.
23
+ *
24
+ * Pure function — safe to call repeatedly; no side effects.
25
+ */
26
+ export function buildModuleScopeIndex(entries) {
27
+ const byFilePath = new Map();
28
+ for (const { filePath, moduleScopeId } of entries) {
29
+ if (byFilePath.has(filePath))
30
+ continue; // first-write-wins
31
+ byFilePath.set(filePath, moduleScopeId);
32
+ }
33
+ return freezeIndex(byFilePath);
34
+ }
35
+ // ─── Internal ───────────────────────────────────────────────────────────────
36
+ function freezeIndex(byFilePath) {
37
+ return {
38
+ byFilePath,
39
+ get size() {
40
+ return byFilePath.size;
41
+ },
42
+ get(filePath) {
43
+ return byFilePath.get(filePath);
44
+ },
45
+ has(filePath) {
46
+ return byFilePath.has(filePath);
47
+ },
48
+ };
49
+ }
50
+ //# sourceMappingURL=module-scope-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-scope-index.js","sourceRoot":"","sources":["../../src/scope-resolution/module-scope-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAgBH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAoC;IACxE,MAAM,UAAU,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC9C,KAAK,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,IAAI,OAAO,EAAE,CAAC;QAClD,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAS,CAAC,mBAAmB;QAC3D,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC;AACjC,CAAC;AAED,+EAA+E;AAE/E,SAAS,WAAW,CAAC,UAAgC;IACnD,OAAO;QACL,UAAU;QACV,IAAI,IAAI;YACN,OAAO,UAAU,CAAC,IAAI,CAAC;QACzB,CAAC;QACD,GAAG,CAAC,QAAgB;YAClB,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC;QACD,GAAG,CAAC,QAAgB;YAClB,OAAO,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * `QualifiedNameIndex` — O(1) `qualifiedName → DefId[]` lookup across all kinds.
3
+ *
4
+ * Cross-kind fast path for qualified-name resolution
5
+ * (`lookupQualified(qname, scope, params)` in RFC §4.5). Class, method,
6
+ * field, and namespace defs all contribute to a single index here; consumers
7
+ * filter the returned `DefId[]` by `p.acceptedKinds` at the call site.
8
+ *
9
+ * Returns `DefId[]` (not a single `DefId`) because multiple defs can legally
10
+ * share a qualified name — partial classes in C#, method overloads, or
11
+ * accidental cross-kind collisions. The lookup caller filters to the expected
12
+ * kind(s) and ranks the survivors.
13
+ *
14
+ * Part of RFC #909 Ring 2 SHARED — #913.
15
+ *
16
+ * Consumed by: #917 (`Registry.lookup` qualified fast path, `resolveTypeRef`
17
+ * dotted fallback via #916).
18
+ */
19
+ import type { SymbolDefinition } from './symbol-definition.js';
20
+ import type { DefId } from './types.js';
21
+ export interface QualifiedNameIndex {
22
+ readonly byQualifiedName: ReadonlyMap<string, readonly DefId[]>;
23
+ readonly size: number;
24
+ /** Returns all `DefId`s registered under this qualified name; empty frozen
25
+ * array on miss so callers can iterate without null checks. */
26
+ get(qualifiedName: string): readonly DefId[];
27
+ has(qualifiedName: string): boolean;
28
+ }
29
+ /**
30
+ * Build a `QualifiedNameIndex` from a flat list of `SymbolDefinition` records.
31
+ *
32
+ * Only defs with a non-empty `qualifiedName` contribute; defs without one are
33
+ * silently skipped (not every kind carries a qualified name — anonymous or
34
+ * top-level symbols, dynamic-unresolved imports, etc.).
35
+ *
36
+ * **Duplicate policy: appended in input order.** Each unique `(qname, DefId)`
37
+ * pair contributes at most once — repeated entries for the same pair are
38
+ * deduplicated. Distinct `DefId`s sharing a `qname` accumulate in insertion
39
+ * order (stable output for deterministic lookup ranking at the call site).
40
+ *
41
+ * Pure function — safe to call repeatedly; no side effects.
42
+ */
43
+ export declare function buildQualifiedNameIndex(defs: readonly SymbolDefinition[]): QualifiedNameIndex;
44
+ //# sourceMappingURL=qualified-name-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qualified-name-index.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/qualified-name-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC,CAAC;IAChE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;oEACgE;IAChE,GAAG,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,KAAK,EAAE,CAAC;IAC7C,GAAG,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;CACrC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,GAAG,kBAAkB,CA2B7F"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * `QualifiedNameIndex` — O(1) `qualifiedName → DefId[]` lookup across all kinds.
3
+ *
4
+ * Cross-kind fast path for qualified-name resolution
5
+ * (`lookupQualified(qname, scope, params)` in RFC §4.5). Class, method,
6
+ * field, and namespace defs all contribute to a single index here; consumers
7
+ * filter the returned `DefId[]` by `p.acceptedKinds` at the call site.
8
+ *
9
+ * Returns `DefId[]` (not a single `DefId`) because multiple defs can legally
10
+ * share a qualified name — partial classes in C#, method overloads, or
11
+ * accidental cross-kind collisions. The lookup caller filters to the expected
12
+ * kind(s) and ranks the survivors.
13
+ *
14
+ * Part of RFC #909 Ring 2 SHARED — #913.
15
+ *
16
+ * Consumed by: #917 (`Registry.lookup` qualified fast path, `resolveTypeRef`
17
+ * dotted fallback via #916).
18
+ */
19
+ /**
20
+ * Build a `QualifiedNameIndex` from a flat list of `SymbolDefinition` records.
21
+ *
22
+ * Only defs with a non-empty `qualifiedName` contribute; defs without one are
23
+ * silently skipped (not every kind carries a qualified name — anonymous or
24
+ * top-level symbols, dynamic-unresolved imports, etc.).
25
+ *
26
+ * **Duplicate policy: appended in input order.** Each unique `(qname, DefId)`
27
+ * pair contributes at most once — repeated entries for the same pair are
28
+ * deduplicated. Distinct `DefId`s sharing a `qname` accumulate in insertion
29
+ * order (stable output for deterministic lookup ranking at the call site).
30
+ *
31
+ * Pure function — safe to call repeatedly; no side effects.
32
+ */
33
+ export function buildQualifiedNameIndex(defs) {
34
+ const byQualifiedName = new Map();
35
+ const seenPairs = new Set();
36
+ for (const def of defs) {
37
+ const qname = def.qualifiedName;
38
+ if (qname === undefined || qname.length === 0)
39
+ continue;
40
+ const pairKey = `${qname}\0${def.nodeId}`;
41
+ if (seenPairs.has(pairKey))
42
+ continue;
43
+ seenPairs.add(pairKey);
44
+ const bucket = byQualifiedName.get(qname);
45
+ if (bucket === undefined) {
46
+ byQualifiedName.set(qname, [def.nodeId]);
47
+ }
48
+ else {
49
+ bucket.push(def.nodeId);
50
+ }
51
+ }
52
+ // Freeze bucket arrays so consumers can't mutate the index.
53
+ const frozen = new Map();
54
+ for (const [k, v] of byQualifiedName) {
55
+ frozen.set(k, Object.freeze(v.slice()));
56
+ }
57
+ return freezeIndex(frozen);
58
+ }
59
+ // ─── Internal ───────────────────────────────────────────────────────────────
60
+ const EMPTY = Object.freeze([]);
61
+ function freezeIndex(byQualifiedName) {
62
+ return {
63
+ byQualifiedName,
64
+ get size() {
65
+ return byQualifiedName.size;
66
+ },
67
+ get(qualifiedName) {
68
+ return byQualifiedName.get(qualifiedName) ?? EMPTY;
69
+ },
70
+ has(qualifiedName) {
71
+ return byQualifiedName.has(qualifiedName);
72
+ },
73
+ };
74
+ }
75
+ //# sourceMappingURL=qualified-name-index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qualified-name-index.js","sourceRoot":"","sources":["../../src/scope-resolution/qualified-name-index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAcH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAiC;IACvE,MAAM,eAAe,GAAG,IAAI,GAAG,EAAmB,CAAC;IACnD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAExD,MAAM,OAAO,GAAG,GAAG,KAAK,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;QAC1C,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,SAAS;QACrC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAEvB,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,eAAe,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3C,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,4DAA4D;IAC5D,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IACnD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,eAAe,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC;AAED,+EAA+E;AAE/E,MAAM,KAAK,GAAqB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAElD,SAAS,WAAW,CAAC,eAA8C;IACjE,OAAO;QACL,eAAe;QACf,IAAI,IAAI;YACN,OAAO,eAAe,CAAC,IAAI,CAAC;QAC9B,CAAC;QACD,GAAG,CAAC,aAAqB;YACvB,OAAO,eAAe,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC;QACrD,CAAC;QACD,GAAG,CAAC,aAAqB;YACvB,OAAO,eAAe,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC5C,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * `resolveTypeRef` — strict single-return resolver for `TypeRef`s
3
+ * (RFC §4.6; Ring 2 SHARED #916).
4
+ *
5
+ * Narrower contract than `Registry.lookup`: no name-only global fallback, no
6
+ * confidence ranking, no arity check. Used by `Registry.lookup` Step 2 (type-
7
+ * binding propagation) and by any caller that wants the single best type-
8
+ * target for an annotation without paying for the full evidence pipeline.
9
+ *
10
+ * **Algorithm (strict).** Walk the scope chain from `ref.declaredAtScope`:
11
+ *
12
+ * 1. At each scope, inspect `bindings.get(ref.rawName)`:
13
+ * - If one of the bindings is a **type-kind** def with a **strict origin**
14
+ * (`'local' | 'import' | 'namespace' | 'reexport'`), return it.
15
+ * - If any binding for this name exists at this scope but none qualifies
16
+ * (e.g., a local variable named `User` shadows an outer import of class
17
+ * `User`), return `null`. The nearer binding shadows; we do NOT fall
18
+ * through to the global qualified-name index.
19
+ * - Otherwise continue to the parent scope.
20
+ * 2. If the raw name is a dotted path (e.g., `'models.User'`) and the scope
21
+ * walk produced no match, consult `QualifiedNameIndex.byQualifiedName`.
22
+ * Only accept **exactly one** type-kind hit — anything ambiguous returns
23
+ * `null` rather than a guess.
24
+ * 3. Return `null`.
25
+ *
26
+ * **What `'strict' origins' means.** `'wildcard'` is intentionally excluded.
27
+ * A wildcard-expanded name (`from x import *`) is too loose to use as an
28
+ * anchor for type resolution — it gives no signal about whether the name was
29
+ * actually imported. `Registry.lookup` may accept wildcard bindings at its
30
+ * own discretion (with lower evidence weight); `resolveTypeRef` does not.
31
+ *
32
+ * **What 'type-kind' means.** The subset of `NodeLabel` that a type annotation
33
+ * may legitimately reference: class-like, interface-like, enum-like, and
34
+ * alias-like kinds. See `TYPE_KINDS` below.
35
+ *
36
+ * Pure function — safe to call repeatedly; no side effects.
37
+ */
38
+ import type { SymbolDefinition } from './symbol-definition.js';
39
+ import type { Scope, ScopeId, TypeRef } from './types.js';
40
+ import type { DefIndex } from './def-index.js';
41
+ import type { QualifiedNameIndex } from './qualified-name-index.js';
42
+ /**
43
+ * Minimal scope-lookup contract required by `resolveTypeRef`. Implemented by
44
+ * the `ScopeTree` from #912; declared here so #916 can ship as a standalone
45
+ * piece without a hard dependency on the full scope-tree implementation. Any
46
+ * structure that hands back a `Scope` by `ScopeId` satisfies this contract.
47
+ */
48
+ export interface ScopeLookup {
49
+ getScope(id: ScopeId): Scope | undefined;
50
+ }
51
+ /**
52
+ * All inputs `resolveTypeRef` needs from the semantic model. Bundled into a
53
+ * context object so the call site stays short and the interface is stable as
54
+ * additional indexes get threaded through in later rings.
55
+ */
56
+ export interface ResolveTypeRefContext {
57
+ readonly scopes: ScopeLookup;
58
+ readonly defIndex: DefIndex;
59
+ readonly qualifiedNameIndex: QualifiedNameIndex;
60
+ }
61
+ export declare function resolveTypeRef(ref: TypeRef, ctx: ResolveTypeRefContext): SymbolDefinition | null;
62
+ //# sourceMappingURL=resolve-type-ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-type-ref.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/resolve-type-ref.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAc,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAIpE;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,OAAO,GAAG,KAAK,GAAG,SAAS,CAAC;CAC1C;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;CACjD;AAsCD,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,qBAAqB,GAAG,gBAAgB,GAAG,IAAI,CAgDhG"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * `resolveTypeRef` — strict single-return resolver for `TypeRef`s
3
+ * (RFC §4.6; Ring 2 SHARED #916).
4
+ *
5
+ * Narrower contract than `Registry.lookup`: no name-only global fallback, no
6
+ * confidence ranking, no arity check. Used by `Registry.lookup` Step 2 (type-
7
+ * binding propagation) and by any caller that wants the single best type-
8
+ * target for an annotation without paying for the full evidence pipeline.
9
+ *
10
+ * **Algorithm (strict).** Walk the scope chain from `ref.declaredAtScope`:
11
+ *
12
+ * 1. At each scope, inspect `bindings.get(ref.rawName)`:
13
+ * - If one of the bindings is a **type-kind** def with a **strict origin**
14
+ * (`'local' | 'import' | 'namespace' | 'reexport'`), return it.
15
+ * - If any binding for this name exists at this scope but none qualifies
16
+ * (e.g., a local variable named `User` shadows an outer import of class
17
+ * `User`), return `null`. The nearer binding shadows; we do NOT fall
18
+ * through to the global qualified-name index.
19
+ * - Otherwise continue to the parent scope.
20
+ * 2. If the raw name is a dotted path (e.g., `'models.User'`) and the scope
21
+ * walk produced no match, consult `QualifiedNameIndex.byQualifiedName`.
22
+ * Only accept **exactly one** type-kind hit — anything ambiguous returns
23
+ * `null` rather than a guess.
24
+ * 3. Return `null`.
25
+ *
26
+ * **What `'strict' origins' means.** `'wildcard'` is intentionally excluded.
27
+ * A wildcard-expanded name (`from x import *`) is too loose to use as an
28
+ * anchor for type resolution — it gives no signal about whether the name was
29
+ * actually imported. `Registry.lookup` may accept wildcard bindings at its
30
+ * own discretion (with lower evidence weight); `resolveTypeRef` does not.
31
+ *
32
+ * **What 'type-kind' means.** The subset of `NodeLabel` that a type annotation
33
+ * may legitimately reference: class-like, interface-like, enum-like, and
34
+ * alias-like kinds. See `TYPE_KINDS` below.
35
+ *
36
+ * Pure function — safe to call repeatedly; no side effects.
37
+ */
38
+ // ─── Strict policy constants ────────────────────────────────────────────────
39
+ /** `'wildcard'` is deliberately absent. See file header. */
40
+ const STRICT_ORIGINS = new Set([
41
+ 'local',
42
+ 'import',
43
+ 'namespace',
44
+ 'reexport',
45
+ ]);
46
+ /**
47
+ * `NodeLabel` values that may appear on the RHS of a type annotation.
48
+ *
49
+ * Includes the usual class-like and interface-like kinds plus the alias-like
50
+ * ones (`TypeAlias`, `Typedef`). `Namespace` is excluded — it is a scope
51
+ * container, not a value type. `Function` / `Method` / `Variable` are
52
+ * excluded by design: a `rawName` bound to them at a strict origin is a
53
+ * *shadowing* binding, which the algorithm short-circuits to `null`.
54
+ */
55
+ const TYPE_KINDS = new Set([
56
+ 'Class',
57
+ 'Interface',
58
+ 'Enum',
59
+ 'Struct',
60
+ 'Union',
61
+ 'Trait',
62
+ 'TypeAlias',
63
+ 'Typedef',
64
+ 'Record',
65
+ 'Delegate',
66
+ 'Annotation',
67
+ 'Template',
68
+ ]);
69
+ // ─── Main entry point ──────────────────────────────────────────────────────
70
+ export function resolveTypeRef(ref, ctx) {
71
+ // Phase 1: scope-chain walk anchored at the declaration site.
72
+ let currentId = ref.declaredAtScope;
73
+ const visited = new Set();
74
+ while (currentId !== null) {
75
+ // Cycle guard — a well-formed scope tree never loops, but a bug in the
76
+ // construction path should fail fast here rather than hanging.
77
+ if (visited.has(currentId))
78
+ return null;
79
+ visited.add(currentId);
80
+ const scope = ctx.scopes.getScope(currentId);
81
+ if (scope === undefined)
82
+ return null; // broken chain = unresolvable
83
+ const bindings = scope.bindings.get(ref.rawName);
84
+ if (bindings !== undefined && bindings.length > 0) {
85
+ // At least one binding exists at this scope → it is the shadowing site.
86
+ // Either one of them qualifies, or the name is shadowed by a non-type.
87
+ for (const binding of bindings) {
88
+ if (!STRICT_ORIGINS.has(binding.origin))
89
+ continue;
90
+ if (TYPE_KINDS.has(binding.def.type)) {
91
+ return binding.def;
92
+ }
93
+ }
94
+ // Shadowed by a non-type / non-strict-origin binding. Fail fast — no
95
+ // global fallback, no walk to the parent.
96
+ return null;
97
+ }
98
+ currentId = scope.parent;
99
+ }
100
+ // Phase 2: dotted fallback via `QualifiedNameIndex`. Only accept a unique
101
+ // type-kind hit; anything ambiguous returns null (strict: no guesses).
102
+ if (ref.rawName.includes('.')) {
103
+ const candidates = ctx.qualifiedNameIndex.get(ref.rawName);
104
+ let onlyTypeDef = null;
105
+ for (const defId of candidates) {
106
+ const def = ctx.defIndex.get(defId);
107
+ if (def === undefined)
108
+ continue;
109
+ if (!TYPE_KINDS.has(def.type))
110
+ continue;
111
+ if (onlyTypeDef !== null)
112
+ return null; // ambiguous
113
+ onlyTypeDef = def;
114
+ }
115
+ if (onlyTypeDef !== null)
116
+ return onlyTypeDef;
117
+ }
118
+ return null;
119
+ }
120
+ //# sourceMappingURL=resolve-type-ref.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-type-ref.js","sourceRoot":"","sources":["../../src/scope-resolution/resolve-type-ref.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AA+BH,+EAA+E;AAE/E,4DAA4D;AAC5D,MAAM,cAAc,GAAsC,IAAI,GAAG,CAAuB;IACtF,OAAO;IACP,QAAQ;IACR,WAAW;IACX,UAAU;CACX,CAAC,CAAC;AAEH;;;;;;;;GAQG;AACH,MAAM,UAAU,GAA2B,IAAI,GAAG,CAAY;IAC5D,OAAO;IACP,WAAW;IACX,MAAM;IACN,QAAQ;IACR,OAAO;IACP,OAAO;IACP,WAAW;IACX,SAAS;IACT,QAAQ;IACR,UAAU;IACV,YAAY;IACZ,UAAU;CACX,CAAC,CAAC;AAEH,8EAA8E;AAE9E,MAAM,UAAU,cAAc,CAAC,GAAY,EAAE,GAA0B;IACrE,8DAA8D;IAC9D,IAAI,SAAS,GAAmB,GAAG,CAAC,eAAe,CAAC;IACpD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAW,CAAC;IAEnC,OAAO,SAAS,KAAK,IAAI,EAAE,CAAC;QAC1B,uEAAuE;QACvE,+DAA+D;QAC/D,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,OAAO,IAAI,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAEvB,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC7C,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,CAAC,8BAA8B;QAEpE,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,wEAAwE;YACxE,uEAAuE;YACvE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;oBAAE,SAAS;gBAClD,IAAI,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrC,OAAO,OAAO,CAAC,GAAG,CAAC;gBACrB,CAAC;YACH,CAAC;YACD,qEAAqE;YACrE,0CAA0C;YAC1C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,0EAA0E;IAC1E,uEAAuE;IACvE,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9B,MAAM,UAAU,GAAG,GAAG,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC3D,IAAI,WAAW,GAA4B,IAAI,CAAC;QAChD,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,GAAG,KAAK,SAAS;gBAAE,SAAS;YAChC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YACxC,IAAI,WAAW,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC,CAAC,YAAY;YACnD,WAAW,GAAG,GAAG,CAAC;QACpB,CAAC;QACD,IAAI,WAAW,KAAK,IAAI;YAAE,OAAO,WAAW,CAAC;IAC/C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -1447,7 +1447,14 @@ export class LocalBackend {
1447
1447
  }
1448
1448
  let diffOutput;
1449
1449
  try {
1450
- diffOutput = execFileSync('git', diffArgs, { cwd: repo.repoPath, encoding: 'utf-8' });
1450
+ // maxBuffer raised from Node's 1MB default to 256MB to avoid ENOBUFS on
1451
+ // repos with large unstaged/untracked diffs (e.g. unignored build folders).
1452
+ // See issue: spawnSync git ENOBUFS in detect_changes(scope="unstaged").
1453
+ diffOutput = execFileSync('git', diffArgs, {
1454
+ cwd: repo.repoPath,
1455
+ encoding: 'utf-8',
1456
+ maxBuffer: 256 * 1024 * 1024,
1457
+ });
1451
1458
  }
1452
1459
  catch (err) {
1453
1460
  return { error: `Git diff failed: ${err.message}` };
@@ -1662,6 +1669,8 @@ export class LocalBackend {
1662
1669
  cwd: repo.repoPath,
1663
1670
  encoding: 'utf-8',
1664
1671
  timeout: 5000,
1672
+ // Avoid ENOBUFS on large repos: rg -l can list many files.
1673
+ maxBuffer: 256 * 1024 * 1024,
1665
1674
  });
1666
1675
  const files = output
1667
1676
  .trim()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.3-rc.4",
3
+ "version": "1.6.3-rc.6",
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",