@optave/codegraph 3.11.2 → 3.13.0

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 (236) hide show
  1. package/README.md +73 -37
  2. package/dist/cli/commands/audit.d.ts.map +1 -1
  3. package/dist/cli/commands/audit.js +2 -1
  4. package/dist/cli/commands/audit.js.map +1 -1
  5. package/dist/cli/commands/batch.d.ts.map +1 -1
  6. package/dist/cli/commands/batch.js +1 -0
  7. package/dist/cli/commands/batch.js.map +1 -1
  8. package/dist/cli/commands/build.d.ts.map +1 -1
  9. package/dist/cli/commands/build.js +6 -1
  10. package/dist/cli/commands/build.js.map +1 -1
  11. package/dist/cli/commands/config.d.ts +3 -0
  12. package/dist/cli/commands/config.d.ts.map +1 -0
  13. package/dist/cli/commands/config.js +272 -0
  14. package/dist/cli/commands/config.js.map +1 -0
  15. package/dist/cli/commands/triage.js +1 -1
  16. package/dist/cli/commands/triage.js.map +1 -1
  17. package/dist/cli/index.d.ts.map +1 -1
  18. package/dist/cli/index.js +10 -0
  19. package/dist/cli/index.js.map +1 -1
  20. package/dist/cli/shared/options.d.ts +2 -1
  21. package/dist/cli/shared/options.d.ts.map +1 -1
  22. package/dist/cli/shared/options.js +11 -1
  23. package/dist/cli/shared/options.js.map +1 -1
  24. package/dist/cli/types.d.ts +2 -0
  25. package/dist/cli/types.d.ts.map +1 -1
  26. package/dist/db/migrations.d.ts.map +1 -1
  27. package/dist/db/migrations.js +8 -1
  28. package/dist/db/migrations.js.map +1 -1
  29. package/dist/domain/analysis/module-map.d.ts +2 -0
  30. package/dist/domain/analysis/module-map.d.ts.map +1 -1
  31. package/dist/domain/analysis/module-map.js +24 -2
  32. package/dist/domain/analysis/module-map.js.map +1 -1
  33. package/dist/domain/graph/builder/call-resolver.d.ts +16 -10
  34. package/dist/domain/graph/builder/call-resolver.d.ts.map +1 -1
  35. package/dist/domain/graph/builder/call-resolver.js +251 -34
  36. package/dist/domain/graph/builder/call-resolver.js.map +1 -1
  37. package/dist/domain/graph/builder/cha.d.ts +69 -0
  38. package/dist/domain/graph/builder/cha.d.ts.map +1 -0
  39. package/dist/domain/graph/builder/cha.js +158 -0
  40. package/dist/domain/graph/builder/cha.js.map +1 -0
  41. package/dist/domain/graph/builder/context.d.ts +3 -0
  42. package/dist/domain/graph/builder/context.d.ts.map +1 -1
  43. package/dist/domain/graph/builder/context.js +2 -0
  44. package/dist/domain/graph/builder/context.js.map +1 -1
  45. package/dist/domain/graph/builder/helpers.d.ts +25 -1
  46. package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
  47. package/dist/domain/graph/builder/helpers.js +178 -5
  48. package/dist/domain/graph/builder/helpers.js.map +1 -1
  49. package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
  50. package/dist/domain/graph/builder/incremental.js +74 -2
  51. package/dist/domain/graph/builder/incremental.js.map +1 -1
  52. package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
  53. package/dist/domain/graph/builder/pipeline.js +37 -2
  54. package/dist/domain/graph/builder/pipeline.js.map +1 -1
  55. package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
  56. package/dist/domain/graph/builder/stages/build-edges.js +704 -34
  57. package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
  58. package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
  59. package/dist/domain/graph/builder/stages/detect-changes.js +3 -2
  60. package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
  61. package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
  62. package/dist/domain/graph/builder/stages/finalize.js +4 -0
  63. package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
  64. package/dist/domain/graph/builder/stages/native-orchestrator.d.ts.map +1 -1
  65. package/dist/domain/graph/builder/stages/native-orchestrator.js +783 -37
  66. package/dist/domain/graph/builder/stages/native-orchestrator.js.map +1 -1
  67. package/dist/domain/graph/builder/stages/resolve-imports.d.ts +1 -0
  68. package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
  69. package/dist/domain/graph/builder/stages/resolve-imports.js +10 -1
  70. package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
  71. package/dist/domain/graph/journal.js +1 -1
  72. package/dist/domain/graph/journal.js.map +1 -1
  73. package/dist/domain/graph/resolver/points-to.d.ts +53 -0
  74. package/dist/domain/graph/resolver/points-to.d.ts.map +1 -0
  75. package/dist/domain/graph/resolver/points-to.js +213 -0
  76. package/dist/domain/graph/resolver/points-to.js.map +1 -0
  77. package/dist/domain/graph/resolver/ts-resolver.d.ts +9 -0
  78. package/dist/domain/graph/resolver/ts-resolver.d.ts.map +1 -0
  79. package/dist/domain/graph/resolver/ts-resolver.js +476 -0
  80. package/dist/domain/graph/resolver/ts-resolver.js.map +1 -0
  81. package/dist/domain/parser.d.ts +12 -4
  82. package/dist/domain/parser.d.ts.map +1 -1
  83. package/dist/domain/parser.js +83 -20
  84. package/dist/domain/parser.js.map +1 -1
  85. package/dist/domain/wasm-worker-entry.js +35 -2
  86. package/dist/domain/wasm-worker-entry.js.map +1 -1
  87. package/dist/domain/wasm-worker-pool.d.ts.map +1 -1
  88. package/dist/domain/wasm-worker-pool.js +34 -0
  89. package/dist/domain/wasm-worker-pool.js.map +1 -1
  90. package/dist/domain/wasm-worker-protocol.d.ts +15 -1
  91. package/dist/domain/wasm-worker-protocol.d.ts.map +1 -1
  92. package/dist/extractors/c.js +3 -3
  93. package/dist/extractors/c.js.map +1 -1
  94. package/dist/extractors/clojure.js +1 -1
  95. package/dist/extractors/clojure.js.map +1 -1
  96. package/dist/extractors/cpp.d.ts.map +1 -1
  97. package/dist/extractors/cpp.js +45 -4
  98. package/dist/extractors/cpp.js.map +1 -1
  99. package/dist/extractors/csharp.d.ts.map +1 -1
  100. package/dist/extractors/csharp.js +37 -8
  101. package/dist/extractors/csharp.js.map +1 -1
  102. package/dist/extractors/cuda.d.ts.map +1 -1
  103. package/dist/extractors/cuda.js +45 -4
  104. package/dist/extractors/cuda.js.map +1 -1
  105. package/dist/extractors/elixir.js +6 -6
  106. package/dist/extractors/elixir.js.map +1 -1
  107. package/dist/extractors/fsharp.js +1 -1
  108. package/dist/extractors/fsharp.js.map +1 -1
  109. package/dist/extractors/go.js +5 -5
  110. package/dist/extractors/go.js.map +1 -1
  111. package/dist/extractors/haskell.js +1 -1
  112. package/dist/extractors/haskell.js.map +1 -1
  113. package/dist/extractors/helpers.d.ts +11 -0
  114. package/dist/extractors/helpers.d.ts.map +1 -1
  115. package/dist/extractors/helpers.js +40 -0
  116. package/dist/extractors/helpers.js.map +1 -1
  117. package/dist/extractors/java.d.ts.map +1 -1
  118. package/dist/extractors/java.js +10 -9
  119. package/dist/extractors/java.js.map +1 -1
  120. package/dist/extractors/javascript.d.ts +2 -0
  121. package/dist/extractors/javascript.d.ts.map +1 -1
  122. package/dist/extractors/javascript.js +1812 -71
  123. package/dist/extractors/javascript.js.map +1 -1
  124. package/dist/extractors/kotlin.js +5 -5
  125. package/dist/extractors/kotlin.js.map +1 -1
  126. package/dist/extractors/lua.js +1 -1
  127. package/dist/extractors/lua.js.map +1 -1
  128. package/dist/extractors/objc.js +3 -3
  129. package/dist/extractors/objc.js.map +1 -1
  130. package/dist/extractors/ocaml.js +1 -1
  131. package/dist/extractors/ocaml.js.map +1 -1
  132. package/dist/extractors/php.js +2 -2
  133. package/dist/extractors/php.js.map +1 -1
  134. package/dist/extractors/python.js +7 -7
  135. package/dist/extractors/python.js.map +1 -1
  136. package/dist/extractors/ruby.js +2 -2
  137. package/dist/extractors/ruby.js.map +1 -1
  138. package/dist/extractors/scala.js +1 -1
  139. package/dist/extractors/scala.js.map +1 -1
  140. package/dist/extractors/solidity.js +1 -1
  141. package/dist/extractors/solidity.js.map +1 -1
  142. package/dist/extractors/swift.js +4 -4
  143. package/dist/extractors/swift.js.map +1 -1
  144. package/dist/extractors/zig.js +4 -4
  145. package/dist/extractors/zig.js.map +1 -1
  146. package/dist/features/structure-query.d.ts +1 -1
  147. package/dist/features/structure-query.d.ts.map +1 -1
  148. package/dist/features/structure-query.js +6 -6
  149. package/dist/features/structure-query.js.map +1 -1
  150. package/dist/index.d.ts +1 -1
  151. package/dist/index.d.ts.map +1 -1
  152. package/dist/index.js +1 -1
  153. package/dist/index.js.map +1 -1
  154. package/dist/infrastructure/config.d.ts +85 -2
  155. package/dist/infrastructure/config.d.ts.map +1 -1
  156. package/dist/infrastructure/config.js +408 -19
  157. package/dist/infrastructure/config.js.map +1 -1
  158. package/dist/infrastructure/native.d.ts +11 -0
  159. package/dist/infrastructure/native.d.ts.map +1 -1
  160. package/dist/infrastructure/native.js +78 -5
  161. package/dist/infrastructure/native.js.map +1 -1
  162. package/dist/infrastructure/registry.d.ts +27 -0
  163. package/dist/infrastructure/registry.d.ts.map +1 -1
  164. package/dist/infrastructure/registry.js +59 -1
  165. package/dist/infrastructure/registry.js.map +1 -1
  166. package/dist/presentation/queries-cli/overview.d.ts.map +1 -1
  167. package/dist/presentation/queries-cli/overview.js +5 -0
  168. package/dist/presentation/queries-cli/overview.js.map +1 -1
  169. package/dist/presentation/structure.d.ts +1 -1
  170. package/dist/presentation/structure.d.ts.map +1 -1
  171. package/dist/presentation/structure.js +2 -2
  172. package/dist/presentation/structure.js.map +1 -1
  173. package/dist/types.d.ts +221 -0
  174. package/dist/types.d.ts.map +1 -1
  175. package/grammars/tree-sitter-gleam.wasm +0 -0
  176. package/package.json +7 -8
  177. package/src/cli/commands/audit.ts +2 -1
  178. package/src/cli/commands/batch.ts +1 -0
  179. package/src/cli/commands/build.ts +6 -1
  180. package/src/cli/commands/config.ts +353 -0
  181. package/src/cli/commands/triage.ts +1 -1
  182. package/src/cli/index.ts +10 -0
  183. package/src/cli/shared/options.ts +11 -1
  184. package/src/cli/types.ts +2 -0
  185. package/src/db/migrations.ts +8 -1
  186. package/src/domain/analysis/module-map.ts +29 -1
  187. package/src/domain/graph/builder/call-resolver.ts +263 -35
  188. package/src/domain/graph/builder/cha.ts +192 -0
  189. package/src/domain/graph/builder/context.ts +3 -0
  190. package/src/domain/graph/builder/helpers.ts +195 -5
  191. package/src/domain/graph/builder/incremental.ts +80 -1
  192. package/src/domain/graph/builder/pipeline.ts +49 -2
  193. package/src/domain/graph/builder/stages/build-edges.ts +867 -32
  194. package/src/domain/graph/builder/stages/detect-changes.ts +4 -2
  195. package/src/domain/graph/builder/stages/finalize.ts +4 -0
  196. package/src/domain/graph/builder/stages/native-orchestrator.ts +910 -43
  197. package/src/domain/graph/builder/stages/resolve-imports.ts +15 -1
  198. package/src/domain/graph/journal.ts +1 -1
  199. package/src/domain/graph/resolver/points-to.ts +254 -0
  200. package/src/domain/graph/resolver/ts-resolver.ts +536 -0
  201. package/src/domain/parser.ts +86 -17
  202. package/src/domain/wasm-worker-entry.ts +35 -2
  203. package/src/domain/wasm-worker-pool.ts +22 -0
  204. package/src/domain/wasm-worker-protocol.ts +15 -0
  205. package/src/extractors/c.ts +3 -3
  206. package/src/extractors/clojure.ts +1 -1
  207. package/src/extractors/cpp.ts +47 -4
  208. package/src/extractors/csharp.ts +33 -9
  209. package/src/extractors/cuda.ts +47 -4
  210. package/src/extractors/elixir.ts +6 -6
  211. package/src/extractors/fsharp.ts +1 -1
  212. package/src/extractors/go.ts +5 -5
  213. package/src/extractors/haskell.ts +1 -1
  214. package/src/extractors/helpers.ts +43 -0
  215. package/src/extractors/java.ts +10 -9
  216. package/src/extractors/javascript.ts +1929 -72
  217. package/src/extractors/kotlin.ts +5 -5
  218. package/src/extractors/lua.ts +1 -1
  219. package/src/extractors/objc.ts +3 -3
  220. package/src/extractors/ocaml.ts +1 -1
  221. package/src/extractors/php.ts +2 -2
  222. package/src/extractors/python.ts +7 -7
  223. package/src/extractors/ruby.ts +2 -2
  224. package/src/extractors/scala.ts +1 -1
  225. package/src/extractors/solidity.ts +1 -1
  226. package/src/extractors/swift.ts +4 -4
  227. package/src/extractors/zig.ts +4 -4
  228. package/src/features/structure-query.ts +7 -7
  229. package/src/index.ts +5 -1
  230. package/src/infrastructure/config.ts +494 -20
  231. package/src/infrastructure/native.ts +87 -5
  232. package/src/infrastructure/registry.ts +82 -1
  233. package/src/presentation/queries-cli/overview.ts +15 -1
  234. package/src/presentation/structure.ts +3 -3
  235. package/src/types.ts +235 -0
  236. package/grammars/tree-sitter-erlang.wasm +0 -0
@@ -8,50 +8,265 @@
8
8
  */
9
9
  import { computeConfidence } from '../resolve.js';
10
10
  export const RECEIVER_KINDS = new Set(['class', 'struct', 'interface', 'type', 'module']);
11
+ /**
12
+ * Languages where bare `foo()` calls inside a class method are lexically scoped
13
+ * to the module, not the class — there is no implicit this/class binding.
14
+ * For these languages, the same-class fallback must not run for bare (no-receiver)
15
+ * calls that found no exact same-file match.
16
+ */
17
+ const MODULE_SCOPED_BARE_CALL_EXTENSIONS = new Set([
18
+ '.js',
19
+ '.mjs',
20
+ '.cjs',
21
+ '.jsx',
22
+ '.ts',
23
+ '.tsx',
24
+ '.mts',
25
+ '.cts',
26
+ ]);
27
+ export function isModuleScopedLanguage(relPath) {
28
+ const ext = relPath.slice(relPath.lastIndexOf('.'));
29
+ return MODULE_SCOPED_BARE_CALL_EXTENSIONS.has(ext);
30
+ }
11
31
  // ── Shared resolution functions ──────────────────────────────────────────
32
+ /**
33
+ * Callable definition kinds — variable/constant bindings are NOT callable
34
+ * in the function-as-enclosing-scope sense (they are local declarations, not
35
+ * function bodies). Top-level variable bindings (e.g. Haskell `main = do …`)
36
+ * are handled separately as a fallback tier.
37
+ */
38
+ const CALLABLE_KINDS = new Set(['function', 'method']);
39
+ /**
40
+ * Variable-like binding kinds that may act as top-level callers when no
41
+ * enclosing function/method exists (e.g. Haskell top-level `main` is a
42
+ * `bind` node → kind `variable`). Local variable declarations inside a
43
+ * function body must NOT win over the enclosing function.
44
+ */
45
+ const TOP_LEVEL_BINDING_KINDS = new Set(['variable', 'constant']);
12
46
  export function findCaller(lookup, call, definitions, relPath, fileNodeRow) {
13
- let caller = null;
14
- let callerSpan = Infinity;
47
+ // Pass 1: find the narrowest enclosing function/method.
48
+ let fnCaller = null;
49
+ let fnCallerName = null;
50
+ let fnCallerSpan = Infinity;
51
+ // Pass 2: find the widest (outermost) enclosing variable/constant binding.
52
+ // Used as fallback when no function/method encloses the call site
53
+ // (e.g. Haskell `main = do …` is a `bind` node with kind `variable`).
54
+ // We pick the WIDEST span (outermost binding), not the narrowest, so that
55
+ // nested `let` bindings inside `main`'s do-block do not shadow `main`
56
+ // itself as the attributing caller. The outermost enclosing variable is
57
+ // the "function-like" top-level binding.
58
+ let varCaller = null;
59
+ let varCallerName = null;
60
+ let varCallerSpan = -1; // looking for WIDEST span, so start at -1
15
61
  for (const def of definitions) {
16
62
  if (def.line <= call.line) {
17
- const end = def.endLine || Infinity;
63
+ const end = def.endLine ?? Infinity;
18
64
  if (call.line <= end) {
19
- const span = end - def.line;
20
- if (span < callerSpan) {
21
- const row = lookup.nodeId(def.name, def.kind, relPath, def.line);
22
- if (row) {
23
- caller = row;
24
- callerSpan = span;
65
+ const span = end === Infinity ? Infinity : end - def.line;
66
+ if (CALLABLE_KINDS.has(def.kind)) {
67
+ if (span < fnCallerSpan) {
68
+ const row = lookup.nodeId(def.name, def.kind, relPath, def.line);
69
+ if (row) {
70
+ fnCaller = row;
71
+ fnCallerName = def.name;
72
+ fnCallerSpan = span;
73
+ }
74
+ }
75
+ }
76
+ else if (TOP_LEVEL_BINDING_KINDS.has(def.kind)) {
77
+ if (span > varCallerSpan) {
78
+ const row = lookup.nodeId(def.name, def.kind, relPath, def.line);
79
+ if (row) {
80
+ varCaller = row;
81
+ varCallerName = def.name;
82
+ varCallerSpan = span;
83
+ }
25
84
  }
26
85
  }
27
86
  }
28
87
  }
29
88
  }
30
- return caller ?? fileNodeRow;
89
+ // Prefer function/method enclosing scope over variable binding.
90
+ // If a function/method encloses the call, use it — local variable
91
+ // declarations inside the function body must not shadow it.
92
+ // Only fall back to a variable/constant binding when the call is at
93
+ // top-level scope (no enclosing function/method found), which handles
94
+ // languages like Haskell where `main` is a top-level `bind` node.
95
+ if (fnCaller) {
96
+ return { ...fnCaller, callerName: fnCallerName };
97
+ }
98
+ if (varCaller) {
99
+ return { ...varCaller, callerName: varCallerName };
100
+ }
101
+ return { ...fileNodeRow, callerName: null };
31
102
  }
32
- export function resolveByMethodOrGlobal(lookup, call, relPath, typeMap) {
103
+ export function resolveByMethodOrGlobal(lookup, call, relPath, typeMap, callerName) {
33
104
  if (call.receiver) {
34
- const typeEntry = typeMap.get(call.receiver);
35
- const typeName = typeEntry
105
+ // Strip "this." so `this.repo.method()` resolves via typeMap["repo"]
106
+ // (or the "this.repo" key seeded directly by the TSC property-declaration enricher).
107
+ const effectiveReceiver = call.receiver.startsWith('this.')
108
+ ? call.receiver.slice('this.'.length)
109
+ : call.receiver;
110
+ // For this.prop receivers, prefer the class-scoped key (ClassName.prop) seeded by
111
+ // handlePropWriteTypeMap / handleFieldDefTypeMap — prevents false edges when multiple
112
+ // classes define the same property name (issues #1323, #1458).
113
+ // Class-scoped lookup runs first so bare fallback keys (confidence 0.6) don't shadow
114
+ // the correct per-class entry when callerName is available.
115
+ let typeEntry;
116
+ if (call.receiver.startsWith('this.') && callerName) {
117
+ const dotIdx = callerName.lastIndexOf('.');
118
+ if (dotIdx > -1) {
119
+ const callerClass = callerName.slice(0, dotIdx);
120
+ typeEntry = typeMap.get(`${callerClass}.${effectiveReceiver}`);
121
+ }
122
+ }
123
+ typeEntry ??=
124
+ typeMap.get(effectiveReceiver) ??
125
+ typeMap.get(call.receiver) ??
126
+ // Phase 8.3f: callee-scoped rest-param key (`callee::restName`) to avoid
127
+ // same-name rest-binding collision across functions in the same file (#1358).
128
+ (callerName ? typeMap.get(`${callerName}::${effectiveReceiver}`) : undefined);
129
+ let typeName = typeEntry
36
130
  ? typeof typeEntry === 'string'
37
131
  ? typeEntry
38
132
  : typeEntry.type
39
133
  : null;
134
+ // Belt-and-suspenders fallback for inline new-expression receivers that
135
+ // extractReceiverName did not normalise (e.g. raw text leaked from an
136
+ // unhandled AST node type). extractReceiverName already handles the common
137
+ // `new_expression` / `parenthesized_expression(new_expression)` shapes by
138
+ // returning the constructor name directly, so this branch is exercised only
139
+ // by future node types or constructs that fall through to the raw-text path.
140
+ // The uppercase-initial restriction ([A-Z_$]) is a heuristic to distinguish
141
+ // constructors (PascalCase) from regular functions and avoids false positives
142
+ // on `(new xmlParser()).parse()` style calls.
143
+ if (!typeName && call.receiver) {
144
+ const m = /^\(?\s*new\s+([A-Z_$][A-Za-z0-9_$]*)/.exec(call.receiver);
145
+ if (m?.[1])
146
+ typeName = m[1];
147
+ }
40
148
  if (typeName) {
41
- const typed = lookup.byName(`${typeName}.${call.name}`).filter((n) => n.kind === 'method');
149
+ const typed = lookup
150
+ .byName(`${typeName}.${call.name}`)
151
+ .filter((n) => n.kind === 'method' && computeConfidence(relPath, n.file, null) >= 0.5);
42
152
  if (typed.length > 0)
43
153
  return typed;
154
+ // Prototype alias: `Foo.prototype.bar = identifier` seeds typeMap['Foo.bar'] = { type: identifier }.
155
+ // Checked after the symbol-DB lookup so an actual method definition always wins.
156
+ const protoEntry = typeMap.get(`${typeName}.${call.name}`);
157
+ const protoTarget = protoEntry
158
+ ? typeof protoEntry === 'string'
159
+ ? protoEntry
160
+ : protoEntry.type
161
+ : null;
162
+ if (protoTarget) {
163
+ const resolved = lookup
164
+ .byName(protoTarget)
165
+ .filter((t) => computeConfidence(relPath, t.file, null) >= 0.5);
166
+ if (resolved.length > 0)
167
+ return resolved;
168
+ }
169
+ }
170
+ // Direct qualified method lookup: ClassName.staticMethod() or ClassName.instanceMethod()
171
+ // when the receiver is a class name with no typeMap entry. Handles static method calls
172
+ // like `C6.staticMethod()` or `D.d()` where the receiver IS the class.
173
+ // Matches both 'method' and 'function' kinds to cover field-initializer synthetic defs.
174
+ if (!typeName) {
175
+ const qualifiedName = `${effectiveReceiver}.${call.name}`;
176
+ const direct = lookup
177
+ .byName(qualifiedName)
178
+ .filter((n) => (n.kind === 'method' || n.kind === 'function') &&
179
+ computeConfidence(relPath, n.file, null) >= 0.5);
180
+ if (direct.length > 0)
181
+ return direct;
182
+ }
183
+ // Phase 8.3d: composite pts key — `obj.prop = fn` seeds typeMap['obj.prop'] = { type: 'fn' }.
184
+ // When a call site references `obj.prop` as a callback, resolve directly to the target fn.
185
+ const compositeEntry = typeMap.get(`${call.receiver}.${call.name}`);
186
+ const ptsTarget = compositeEntry
187
+ ? typeof compositeEntry === 'string'
188
+ ? compositeEntry
189
+ : compositeEntry.type
190
+ : null;
191
+ if (ptsTarget) {
192
+ const resolved = lookup
193
+ .byName(ptsTarget)
194
+ .filter((t) => computeConfidence(relPath, t.file, null) >= 0.5);
195
+ if (resolved.length > 0)
196
+ return resolved;
44
197
  }
45
198
  }
46
199
  if (!call.receiver ||
47
200
  call.receiver === 'this' ||
48
201
  call.receiver === 'self' ||
49
202
  call.receiver === 'super') {
50
- return lookup.byName(call.name).filter((t) => computeConfidence(relPath, t.file, null) >= 0.5);
203
+ // Phase 8.3f: accessor this-dispatch via Object.defineProperty.
204
+ // When a plain function (no class prefix) is registered as a get/set accessor for `obj`
205
+ // via Object.defineProperty, typeMap seeds 'callerName:this' = 'obj'.
206
+ // We then resolve this.method() → typeMap['obj.method'] → the concrete definition.
207
+ // This runs before the broad exact-name lookup to avoid false positives from
208
+ // unrelated same-file definitions.
209
+ if (call.receiver === 'this' && callerName && !callerName.includes('.')) {
210
+ const accessorThisEntry = typeMap.get(`${callerName}:this`);
211
+ const objName = accessorThisEntry
212
+ ? typeof accessorThisEntry === 'string'
213
+ ? accessorThisEntry
214
+ : accessorThisEntry.type
215
+ : null;
216
+ if (objName) {
217
+ const objMethodEntry = typeMap.get(`${objName}.${call.name}`);
218
+ const targetFn = objMethodEntry
219
+ ? typeof objMethodEntry === 'string'
220
+ ? objMethodEntry
221
+ : objMethodEntry.type
222
+ : null;
223
+ if (targetFn) {
224
+ const resolved = lookup
225
+ .byName(targetFn)
226
+ .filter((t) => computeConfidence(relPath, t.file, null) >= 0.5);
227
+ if (resolved.length > 0)
228
+ return resolved;
229
+ }
230
+ }
231
+ }
232
+ const exact = lookup
233
+ .byName(call.name)
234
+ .filter((t) => computeConfidence(relPath, t.file, null) >= 0.5);
235
+ if (exact.length > 0)
236
+ return exact;
237
+ // Try same-class method lookup via callerName.
238
+ // e.g. `this.area()` inside `Shape.describe` → try `Shape.area`.
239
+ // Also covers no-receiver calls inside class methods, e.g. `IsValidEmail(x)` inside
240
+ // `Validators.ValidateUser` → try `Validators.IsValidEmail` (C#/Java static siblings).
241
+ // This seeds the initial edge that runChaPostPass later expands to subclass overrides.
242
+ //
243
+ // For JS/TS, bare (no-receiver) calls are module-scoped — there is no implicit class
244
+ // binding. Skip the same-class fallback for bare calls in those languages to prevent
245
+ // false positives (e.g. `flush()` inside `Processor.run` must not resolve to
246
+ // `Processor.flush`). this.method() calls are unaffected: they still reach the fallback
247
+ // because `call.receiver === 'this'` is truthy, not a bare call.
248
+ const isBareCall = !call.receiver;
249
+ if (callerName && !(isBareCall && isModuleScopedLanguage(relPath))) {
250
+ const dotIdx = callerName.lastIndexOf('.');
251
+ if (dotIdx > -1) {
252
+ // Extract only the segment immediately before the method name so that
253
+ // 'Namespace.ClassName.method' yields 'ClassName', not 'Namespace.ClassName'.
254
+ // Symbols are stored under their bare class name, not their qualified path.
255
+ const prevDot = callerName.lastIndexOf('.', dotIdx - 1);
256
+ const callerClass = callerName.slice(prevDot + 1, dotIdx);
257
+ const qualifiedName = `${callerClass}.${call.name}`;
258
+ const sameClass = lookup
259
+ .byName(qualifiedName)
260
+ .filter((t) => t.kind === 'method' && computeConfidence(relPath, t.file, null) >= 0.5);
261
+ if (sameClass.length > 0)
262
+ return sameClass;
263
+ }
264
+ }
265
+ return exact; // empty
51
266
  }
52
267
  return [];
53
268
  }
54
- export function resolveCallTargets(lookup, call, relPath, importedNames, typeMap) {
269
+ export function resolveCallTargets(lookup, call, relPath, importedNames, typeMap, callerName) {
55
270
  const importedFrom = importedNames.get(call.name);
56
271
  let targets;
57
272
  if (importedFrom) {
@@ -66,7 +281,7 @@ export function resolveCallTargets(lookup, call, relPath, importedNames, typeMap
66
281
  if (!targets || targets.length === 0) {
67
282
  targets = lookup.byNameAndFile(call.name, relPath);
68
283
  if (targets.length === 0) {
69
- targets = resolveByMethodOrGlobal(lookup, call, relPath, typeMap);
284
+ targets = resolveByMethodOrGlobal(lookup, call, relPath, typeMap, callerName);
70
285
  }
71
286
  }
72
287
  const resolved = [...(targets ?? [])];
@@ -84,15 +299,19 @@ export function resolveCallTargets(lookup, call, relPath, importedNames, typeMap
84
299
  * Returns the edge tuple to insert, or null if nothing matched or the edge
85
300
  * was already seen. Callers are responsible for the actual DB/array insert.
86
301
  *
87
- * Receiver resolution collects all same-file candidates first (no kind
88
- * filter), falls back to global candidates only when the same-file set is
89
- * entirely empty, then filters the chosen set by RECEIVER_KINDS. This
90
- * matches the native Rust build path: if a file imports a name that happens
91
- * to be emitted as `kind='function'` in the importer, the same-file set is
92
- * non-empty and blocks the global fallback, so no receiver edge is emitted.
93
- * Keeping this behaviour identical to the Rust path maintains engine parity.
302
+ * Receiver resolution:
303
+ * 1. Look up same-file nodes for `effectiveReceiver` (unfiltered by kind).
304
+ * 2. If any same-file node exists AND `effectiveReceiver` is not in `importedNames`
305
+ * (i.e. it is a locally-defined symbol, not an import artifact), apply
306
+ * RECEIVER_KINDS and return the filtered set no global fallback.
307
+ * A local `function C(){}` means this file owns `C`; no cross-file class
308
+ * should win over it (issue #1539).
309
+ * 3. If the same-file node IS an import artifact (e.g. destructured require),
310
+ * or no same-file node exists at all, fall back to global candidates filtered
311
+ * by RECEIVER_KINDS. This preserves the pre-#1539 behaviour for cases where
312
+ * an imported name appears as kind='function' in the importer file.
94
313
  */
95
- export function resolveReceiverEdge(lookup, call, caller, relPath, typeMap, seenCallEdges) {
314
+ export function resolveReceiverEdge(lookup, call, caller, relPath, typeMap, seenCallEdges, importedNames) {
96
315
  const typeEntry = typeMap.get(call.receiver);
97
316
  const typeName = typeEntry
98
317
  ? typeof typeEntry === 'string'
@@ -103,15 +322,13 @@ export function resolveReceiverEdge(lookup, call, caller, relPath, typeMap, seen
103
322
  ? (typeEntry.confidence ?? null)
104
323
  : null;
105
324
  const effectiveReceiver = typeName || call.receiver;
106
- // Filter-before: apply RECEIVER_KINDS to same-file candidates first, then
107
- // fall back to global candidates (also filtered) only when same-file yields
108
- // nothing. This prevents an imported name emitted as kind='function' in the
109
- // importing file from blocking the fallback to the actual class/struct/etc.
110
- // node in the defining file.
111
- const sameFileCandidates = lookup
112
- .byNameAndFile(effectiveReceiver, relPath)
113
- .filter((n) => RECEIVER_KINDS.has(n.kind ?? ''));
114
- const candidates = sameFileCandidates.length > 0
325
+ // Block global fallback only when the same-file node is a local definition,
326
+ // not when it's an import artifact (e.g. `const { C } = require(…)` seeds a
327
+ // kind='function' node in the importer but the real class lives elsewhere).
328
+ const sameFileAll = lookup.byNameAndFile(effectiveReceiver, relPath);
329
+ const isLocalDefinition = sameFileAll.length > 0 && !importedNames?.has(effectiveReceiver);
330
+ const sameFileCandidates = sameFileAll.filter((n) => RECEIVER_KINDS.has(n.kind ?? ''));
331
+ const candidates = isLocalDefinition
115
332
  ? sameFileCandidates
116
333
  : lookup.byName(effectiveReceiver).filter((n) => RECEIVER_KINDS.has(n.kind ?? ''));
117
334
  if (candidates.length === 0)
@@ -1 +1 @@
1
- {"version":3,"file":"call-resolver.js","sourceRoot":"","sources":["../../../../src/domain/graph/builder/call-resolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"call-resolver.js","sourceRoot":"","sources":["../../../../src/domain/graph/builder/call-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Phase 8.5: Class Hierarchy Analysis (CHA) + Rapid Type Analysis (RTA)
3
+ *
4
+ * CHA resolves virtual/interface method dispatch to all known concrete
5
+ * implementations. RTA refines the CHA set by filtering out types that are
6
+ * never instantiated in the program (no `new X()` anywhere in the codebase).
7
+ *
8
+ * Used by:
9
+ * - buildFileCallEdges (WASM/JS path) — inline during per-file edge building
10
+ * - buildChaPostPass (native path) — JS post-pass on top of native edges
11
+ */
12
+ import type { ExtractorOutput } from '../../../types.js';
13
+ import type { CallNodeLookup } from './call-resolver.js';
14
+ export interface ChaContext {
15
+ /** interface/class name → concrete classes that implement or extend it */
16
+ readonly implementors: ReadonlyMap<string, readonly string[]>;
17
+ /** class name → direct parent class name (from `extends`) */
18
+ readonly parents: ReadonlyMap<string, string>;
19
+ /** RTA: class names that appear in `new X()` anywhere in the project */
20
+ readonly instantiatedTypes: ReadonlySet<string>;
21
+ }
22
+ export declare const EMPTY_CHA_CONTEXT: ChaContext;
23
+ /**
24
+ * Build the CHA context from all parsed file symbols.
25
+ *
26
+ * Must be called AFTER cross-file return-type propagation so that typeMap
27
+ * confidence values reflect propagated types (used for RTA seeding).
28
+ */
29
+ export declare function buildChaContext(fileSymbols: ReadonlyMap<string, ExtractorOutput>): ChaContext;
30
+ /**
31
+ * Resolve `this.method()`, `self.method()`, or `super.method()` through the
32
+ * class hierarchy of the calling method.
33
+ *
34
+ * callerName must be a qualified method name ("ClassName.callerFn") for the
35
+ * class context to be determinable. Returns [] for plain functions.
36
+ *
37
+ * For `super`, resolution starts from the parent of the caller's class.
38
+ * For `this`/`self`, resolution starts from the caller's own class and walks
39
+ * up the inheritance chain (supporting inherited method lookup).
40
+ *
41
+ * When `callerFile` is provided, same-file method nodes are preferred: if the
42
+ * hierarchy walk finds a qualified method that exists in both the caller's own
43
+ * file AND in unrelated files (e.g. a class named `A` that appears in multiple
44
+ * fixture files), only the same-file nodes are returned. This prevents
45
+ * cross-fixture false edges caused by accidental name collisions across
46
+ * unrelated files in the same project build. When no same-file nodes exist,
47
+ * all found nodes are returned as before.
48
+ */
49
+ export declare function resolveThisDispatch(methodName: string, callerName: string | null, receiver: 'this' | 'self' | 'super', chaCtx: ChaContext, lookup: CallNodeLookup, callerFile?: string | null): ReadonlyArray<{
50
+ id: number;
51
+ file: string;
52
+ }>;
53
+ /**
54
+ * CHA + RTA: given a receiver type (class or interface), return all concrete
55
+ * method implementations reachable via the class hierarchy.
56
+ *
57
+ * Only returns methods on types that are actually instantiated somewhere in
58
+ * the project (RTA filter). Returns [] when no concrete instantiated type
59
+ * overrides the given method.
60
+ *
61
+ * BFS over the implementors map handles multi-level hierarchies (e.g.
62
+ * IFoo → AbstractFoo → ConcreteFoo) so that abstract intermediate classes
63
+ * are transparently skipped while their concrete subclasses are still reached.
64
+ */
65
+ export declare function resolveChaTargets(typeName: string, methodName: string, chaCtx: ChaContext, lookup: CallNodeLookup): ReadonlyArray<{
66
+ id: number;
67
+ file: string;
68
+ }>;
69
+ //# sourceMappingURL=cha.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cha.d.ts","sourceRoot":"","sources":["../../../../src/domain/graph/builder/cha.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAIzD,MAAM,WAAW,UAAU;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IAC9D,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,wEAAwE;IACxE,QAAQ,CAAC,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACjD;AAED,eAAO,MAAM,iBAAiB,EAAE,UAI/B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,UAAU,CA8C7F;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EACnC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,cAAc,EACtB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GACzB,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA4B7C;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,cAAc,GACrB,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA4B7C"}
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Phase 8.5: Class Hierarchy Analysis (CHA) + Rapid Type Analysis (RTA)
3
+ *
4
+ * CHA resolves virtual/interface method dispatch to all known concrete
5
+ * implementations. RTA refines the CHA set by filtering out types that are
6
+ * never instantiated in the program (no `new X()` anywhere in the codebase).
7
+ *
8
+ * Used by:
9
+ * - buildFileCallEdges (WASM/JS path) — inline during per-file edge building
10
+ * - buildChaPostPass (native path) — JS post-pass on top of native edges
11
+ */
12
+ export const EMPTY_CHA_CONTEXT = {
13
+ implementors: new Map(),
14
+ parents: new Map(),
15
+ instantiatedTypes: new Set(),
16
+ };
17
+ /**
18
+ * Build the CHA context from all parsed file symbols.
19
+ *
20
+ * Must be called AFTER cross-file return-type propagation so that typeMap
21
+ * confidence values reflect propagated types (used for RTA seeding).
22
+ */
23
+ export function buildChaContext(fileSymbols) {
24
+ const implementors = new Map();
25
+ const parents = new Map();
26
+ const instantiatedTypes = new Set();
27
+ for (const symbols of fileSymbols.values()) {
28
+ for (const cls of symbols.classes) {
29
+ if (cls.implements) {
30
+ let list = implementors.get(cls.implements);
31
+ if (!list) {
32
+ list = [];
33
+ implementors.set(cls.implements, list);
34
+ }
35
+ if (!list.includes(cls.name))
36
+ list.push(cls.name);
37
+ }
38
+ if (cls.extends) {
39
+ // child → parent (for this/super hierarchy walking)
40
+ if (!parents.has(cls.name))
41
+ parents.set(cls.name, cls.extends);
42
+ // parent → children (for CHA dispatch expansion via extends)
43
+ let list = implementors.get(cls.extends);
44
+ if (!list) {
45
+ list = [];
46
+ implementors.set(cls.extends, list);
47
+ }
48
+ if (!list.includes(cls.name))
49
+ list.push(cls.name);
50
+ }
51
+ }
52
+ // RTA: Phase 8.5 dedicated newExpressions list (all `new X()` in the file)
53
+ if (symbols.newExpressions) {
54
+ for (const typeName of symbols.newExpressions) {
55
+ instantiatedTypes.add(typeName);
56
+ }
57
+ }
58
+ // RTA fallback: constructor-confidence typeMap entries (confidence >= 0.9)
59
+ // covers codebases that haven't been re-parsed since Phase 8.5 was added.
60
+ if (symbols.typeMap instanceof Map) {
61
+ for (const entry of symbols.typeMap.values()) {
62
+ if (typeof entry !== 'string' && entry.confidence >= 0.9) {
63
+ instantiatedTypes.add(entry.type);
64
+ }
65
+ }
66
+ }
67
+ }
68
+ return { implementors, parents, instantiatedTypes };
69
+ }
70
+ // ── this / self / super resolution ──────────────────────────────────────────
71
+ /**
72
+ * Resolve `this.method()`, `self.method()`, or `super.method()` through the
73
+ * class hierarchy of the calling method.
74
+ *
75
+ * callerName must be a qualified method name ("ClassName.callerFn") for the
76
+ * class context to be determinable. Returns [] for plain functions.
77
+ *
78
+ * For `super`, resolution starts from the parent of the caller's class.
79
+ * For `this`/`self`, resolution starts from the caller's own class and walks
80
+ * up the inheritance chain (supporting inherited method lookup).
81
+ *
82
+ * When `callerFile` is provided, same-file method nodes are preferred: if the
83
+ * hierarchy walk finds a qualified method that exists in both the caller's own
84
+ * file AND in unrelated files (e.g. a class named `A` that appears in multiple
85
+ * fixture files), only the same-file nodes are returned. This prevents
86
+ * cross-fixture false edges caused by accidental name collisions across
87
+ * unrelated files in the same project build. When no same-file nodes exist,
88
+ * all found nodes are returned as before.
89
+ */
90
+ export function resolveThisDispatch(methodName, callerName, receiver, chaCtx, lookup, callerFile) {
91
+ if (!callerName)
92
+ return [];
93
+ const dotIdx = callerName.indexOf('.');
94
+ if (dotIdx === -1)
95
+ return [];
96
+ const callerClass = callerName.slice(0, dotIdx);
97
+ const startClass = receiver === 'super' ? chaCtx.parents.get(callerClass) : callerClass;
98
+ if (!startClass)
99
+ return [];
100
+ // Walk up the hierarchy; the visited set guards against cycles in malformed data.
101
+ let current = startClass;
102
+ const visited = new Set();
103
+ while (current && !visited.has(current)) {
104
+ visited.add(current);
105
+ const qualified = `${current}.${methodName}`;
106
+ const found = lookup.byName(qualified).filter((n) => n.kind === 'method');
107
+ if (found.length > 0) {
108
+ // When the caller's file is known, prefer same-file nodes to avoid
109
+ // emitting cross-file edges to identically-named methods in unrelated
110
+ // files. Only fall back to the full set when no same-file node exists.
111
+ if (callerFile && found.some((n) => n.file === callerFile)) {
112
+ return found.filter((n) => n.file === callerFile);
113
+ }
114
+ return found;
115
+ }
116
+ current = chaCtx.parents.get(current);
117
+ }
118
+ return [];
119
+ }
120
+ // ── CHA dispatch expansion ───────────────────────────────────────────────────
121
+ /**
122
+ * CHA + RTA: given a receiver type (class or interface), return all concrete
123
+ * method implementations reachable via the class hierarchy.
124
+ *
125
+ * Only returns methods on types that are actually instantiated somewhere in
126
+ * the project (RTA filter). Returns [] when no concrete instantiated type
127
+ * overrides the given method.
128
+ *
129
+ * BFS over the implementors map handles multi-level hierarchies (e.g.
130
+ * IFoo → AbstractFoo → ConcreteFoo) so that abstract intermediate classes
131
+ * are transparently skipped while their concrete subclasses are still reached.
132
+ */
133
+ export function resolveChaTargets(typeName, methodName, chaCtx, lookup) {
134
+ const results = [];
135
+ const queue = [typeName];
136
+ const visited = new Set();
137
+ visited.add(typeName);
138
+ while (queue.length > 0) {
139
+ const current = queue.shift();
140
+ const children = chaCtx.implementors.get(current);
141
+ if (!children?.length)
142
+ continue;
143
+ for (const cls of children) {
144
+ if (visited.has(cls))
145
+ continue;
146
+ visited.add(cls);
147
+ if (chaCtx.instantiatedTypes.has(cls)) {
148
+ const qualified = `${cls}.${methodName}`;
149
+ const found = lookup.byName(qualified).filter((n) => n.kind === 'method');
150
+ results.push(...found);
151
+ }
152
+ // Traverse even non-instantiated classes — they may have instantiated subclasses.
153
+ queue.push(cls);
154
+ }
155
+ }
156
+ return results;
157
+ }
158
+ //# sourceMappingURL=cha.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cha.js","sourceRoot":"","sources":["../../../../src/domain/graph/builder/cha.ts"],"names":[],"mappings":"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"}
@@ -46,6 +46,8 @@ export declare class PipelineContext {
46
46
  batchResolved: Map<string, string> | null;
47
47
  reexportMap: Map<string, unknown[]>;
48
48
  barrelOnlyFiles: Set<string>;
49
+ /** Phase 8.4: cache for resolveBarrelExport results keyed as "barrelPath|symbolName". */
50
+ barrelExportCache: Map<string, string | null>;
49
51
  nodesByName: Map<string, NodeRow[]>;
50
52
  nodesByNameAndFile: Map<string, NodeRow[]>;
51
53
  /**
@@ -62,6 +64,7 @@ export declare class PipelineContext {
62
64
  edgeKind: string;
63
65
  confidence: number;
64
66
  dynamic: number;
67
+ technique: string | null;
65
68
  }>;
66
69
  hasEmbeddings: boolean;
67
70
  lineCountMap: Map<string, number>;