@lzehrung/codegraph 2.3.30 → 2.4.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 (416) hide show
  1. package/README.md +30 -137
  2. package/codegraph-skill/codegraph/SKILL.md +5 -3
  3. package/dist/agent/artifact.d.ts +2 -0
  4. package/dist/agent/artifact.d.ts.map +1 -1
  5. package/dist/agent/artifact.js.map +1 -1
  6. package/dist/agent/search.d.ts.map +1 -1
  7. package/dist/agent/search.js +3 -0
  8. package/dist/agent/search.js.map +1 -1
  9. package/dist/agent/session.d.ts +3 -0
  10. package/dist/agent/session.d.ts.map +1 -1
  11. package/dist/agent/session.js +10 -2
  12. package/dist/agent/session.js.map +1 -1
  13. package/dist/bin/cli.js +42229 -28876
  14. package/dist/bin/query-index-worker.js +73 -11
  15. package/dist/cli/affected.d.ts.map +1 -1
  16. package/dist/cli/affected.js +4 -1
  17. package/dist/cli/affected.js.map +1 -1
  18. package/dist/cli/command-catalog.js +1 -1
  19. package/dist/cli/command-catalog.js.map +1 -1
  20. package/dist/cli/graph-queries.d.ts.map +1 -1
  21. package/dist/cli/graph-queries.js +27 -1
  22. package/dist/cli/graph-queries.js.map +1 -1
  23. package/dist/cli/help.d.ts +2 -2
  24. package/dist/cli/help.d.ts.map +1 -1
  25. package/dist/cli/help.js +4 -2
  26. package/dist/cli/help.js.map +1 -1
  27. package/dist/cli/options.js +2 -2
  28. package/dist/cli/options.js.map +1 -1
  29. package/dist/drift/artifact.d.ts.map +1 -1
  30. package/dist/drift/artifact.js +15 -18
  31. package/dist/drift/artifact.js.map +1 -1
  32. package/dist/drift/compare.js +1 -1
  33. package/dist/drift/compare.js.map +1 -1
  34. package/dist/drift/snapshot.d.ts.map +1 -1
  35. package/dist/drift/snapshot.js +5 -6
  36. package/dist/drift/snapshot.js.map +1 -1
  37. package/dist/drift/types.d.ts +2 -0
  38. package/dist/drift/types.d.ts.map +1 -1
  39. package/dist/drift/types.js.map +1 -1
  40. package/dist/graph-builder.d.ts.map +1 -1
  41. package/dist/graph-builder.js +4 -6
  42. package/dist/graph-builder.js.map +1 -1
  43. package/dist/graph-edge-collector.d.ts +3 -0
  44. package/dist/graph-edge-collector.d.ts.map +1 -1
  45. package/dist/graph-edge-collector.js +8 -5
  46. package/dist/graph-edge-collector.js.map +1 -1
  47. package/dist/graphs/angularjs.d.ts.map +1 -1
  48. package/dist/graphs/angularjs.js +2 -1
  49. package/dist/graphs/angularjs.js.map +1 -1
  50. package/dist/graphs/edge-resolution.d.ts +4 -1
  51. package/dist/graphs/edge-resolution.d.ts.map +1 -1
  52. package/dist/graphs/edge-resolution.js +26 -2
  53. package/dist/graphs/edge-resolution.js.map +1 -1
  54. package/dist/graphs/specifiers.d.ts.map +1 -1
  55. package/dist/graphs/specifiers.js +6 -2
  56. package/dist/graphs/specifiers.js.map +1 -1
  57. package/dist/graphs/symbol-graph-detailed/ast.d.ts +20 -0
  58. package/dist/graphs/symbol-graph-detailed/ast.d.ts.map +1 -1
  59. package/dist/graphs/symbol-graph-detailed/ast.js +154 -15
  60. package/dist/graphs/symbol-graph-detailed/ast.js.map +1 -1
  61. package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts +51 -8
  62. package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts.map +1 -1
  63. package/dist/graphs/symbol-graph-detailed/edge-passes.js +823 -132
  64. package/dist/graphs/symbol-graph-detailed/edge-passes.js.map +1 -1
  65. package/dist/graphs/symbol-graph-detailed/import-aliases.d.ts +2 -1
  66. package/dist/graphs/symbol-graph-detailed/import-aliases.d.ts.map +1 -1
  67. package/dist/graphs/symbol-graph-detailed/import-aliases.js +139 -7
  68. package/dist/graphs/symbol-graph-detailed/import-aliases.js.map +1 -1
  69. package/dist/graphs/symbol-graph-detailed/member-chains.d.ts +1 -0
  70. package/dist/graphs/symbol-graph-detailed/member-chains.d.ts.map +1 -1
  71. package/dist/graphs/symbol-graph-detailed/member-chains.js +3 -1
  72. package/dist/graphs/symbol-graph-detailed/member-chains.js.map +1 -1
  73. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts +128 -22
  74. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts.map +1 -1
  75. package/dist/graphs/symbol-graph-detailed/receiver-calls.js +872 -125
  76. package/dist/graphs/symbol-graph-detailed/receiver-calls.js.map +1 -1
  77. package/dist/graphs/symbol-graph-detailed.d.ts.map +1 -1
  78. package/dist/graphs/symbol-graph-detailed.js +434 -40
  79. package/dist/graphs/symbol-graph-detailed.js.map +1 -1
  80. package/dist/graphs/symbol-graph.d.ts +2 -0
  81. package/dist/graphs/symbol-graph.d.ts.map +1 -1
  82. package/dist/graphs/symbol-graph.js +34 -16
  83. package/dist/graphs/symbol-graph.js.map +1 -1
  84. package/dist/impact/call-compatibility/providers/index.d.ts +12 -0
  85. package/dist/impact/call-compatibility/providers/index.d.ts.map +1 -1
  86. package/dist/impact/call-compatibility/providers/index.js +16 -22
  87. package/dist/impact/call-compatibility/providers/index.js.map +1 -1
  88. package/dist/impact/call-compatibility/providers/types.d.ts +2 -0
  89. package/dist/impact/call-compatibility/providers/types.d.ts.map +1 -1
  90. package/dist/impact/call-compatibility/types.d.ts +6 -0
  91. package/dist/impact/call-compatibility/types.d.ts.map +1 -1
  92. package/dist/impact/call-compatibility.d.ts.map +1 -1
  93. package/dist/impact/call-compatibility.js +316 -552
  94. package/dist/impact/call-compatibility.js.map +1 -1
  95. package/dist/impact/map.js +1 -0
  96. package/dist/impact/map.js.map +1 -1
  97. package/dist/impact/member-resolution-coverage.d.ts.map +1 -1
  98. package/dist/impact/member-resolution-coverage.js +1 -1
  99. package/dist/impact/member-resolution-coverage.js.map +1 -1
  100. package/dist/impact/reference-cache.d.ts.map +1 -1
  101. package/dist/impact/reference-cache.js +2 -2
  102. package/dist/impact/reference-cache.js.map +1 -1
  103. package/dist/index.d.ts +1 -1
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/index.js +1 -1
  106. package/dist/index.js.map +1 -1
  107. package/dist/indexer/ambiguous-resolution.d.ts +11 -0
  108. package/dist/indexer/ambiguous-resolution.d.ts.map +1 -0
  109. package/dist/indexer/ambiguous-resolution.js +19 -0
  110. package/dist/indexer/ambiguous-resolution.js.map +1 -0
  111. package/dist/indexer/build-cache/module-cache.d.ts +38 -0
  112. package/dist/indexer/build-cache/module-cache.d.ts.map +1 -1
  113. package/dist/indexer/build-cache/module-cache.js +151 -9
  114. package/dist/indexer/build-cache/module-cache.js.map +1 -1
  115. package/dist/indexer/build-cache/options.d.ts +16 -43
  116. package/dist/indexer/build-cache/options.d.ts.map +1 -1
  117. package/dist/indexer/build-cache/options.js +16 -43
  118. package/dist/indexer/build-cache/options.js.map +1 -1
  119. package/dist/indexer/build-cache/project-snapshot.d.ts +1 -0
  120. package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
  121. package/dist/indexer/build-cache/project-snapshot.js +117 -24
  122. package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
  123. package/dist/indexer/build-cache/resolver-environment.d.ts.map +1 -1
  124. package/dist/indexer/build-cache/resolver-environment.js +32 -2
  125. package/dist/indexer/build-cache/resolver-environment.js.map +1 -1
  126. package/dist/indexer/build-cache.d.ts +1 -1
  127. package/dist/indexer/build-cache.d.ts.map +1 -1
  128. package/dist/indexer/build-cache.js +1 -1
  129. package/dist/indexer/build-cache.js.map +1 -1
  130. package/dist/indexer/build-index.d.ts.map +1 -1
  131. package/dist/indexer/build-index.js +593 -22
  132. package/dist/indexer/build-index.js.map +1 -1
  133. package/dist/indexer/call-hierarchy.js +1 -1
  134. package/dist/indexer/call-hierarchy.js.map +1 -1
  135. package/dist/indexer/compilation-units.d.ts +101 -0
  136. package/dist/indexer/compilation-units.d.ts.map +1 -0
  137. package/dist/indexer/compilation-units.js +605 -0
  138. package/dist/indexer/compilation-units.js.map +1 -0
  139. package/dist/indexer/cpp-callables.d.ts +20 -0
  140. package/dist/indexer/cpp-callables.d.ts.map +1 -0
  141. package/dist/indexer/cpp-callables.js +554 -0
  142. package/dist/indexer/cpp-callables.js.map +1 -0
  143. package/dist/indexer/declaration-visibility.d.ts +36 -2
  144. package/dist/indexer/declaration-visibility.d.ts.map +1 -1
  145. package/dist/indexer/declaration-visibility.js +136 -2
  146. package/dist/indexer/declaration-visibility.js.map +1 -1
  147. package/dist/indexer/expand-star-imports.d.ts.map +1 -1
  148. package/dist/indexer/expand-star-imports.js +28 -6
  149. package/dist/indexer/expand-star-imports.js.map +1 -1
  150. package/dist/indexer/import-types.d.ts +37 -0
  151. package/dist/indexer/import-types.d.ts.map +1 -1
  152. package/dist/indexer/import-types.js +24 -1
  153. package/dist/indexer/import-types.js.map +1 -1
  154. package/dist/indexer/imports/binding-ranges.d.ts +1 -1
  155. package/dist/indexer/imports/binding-ranges.d.ts.map +1 -1
  156. package/dist/indexer/imports/context.d.ts +11 -1
  157. package/dist/indexer/imports/context.d.ts.map +1 -1
  158. package/dist/indexer/imports/import-binding-tables.d.ts +75 -0
  159. package/dist/indexer/imports/import-binding-tables.d.ts.map +1 -0
  160. package/dist/indexer/imports/import-binding-tables.js +544 -0
  161. package/dist/indexer/imports/import-binding-tables.js.map +1 -0
  162. package/dist/indexer/imports/js-text-imports.js +4 -4
  163. package/dist/indexer/imports/js-text-imports.js.map +1 -1
  164. package/dist/indexer/imports/language-specific.d.ts +3 -22
  165. package/dist/indexer/imports/language-specific.d.ts.map +1 -1
  166. package/dist/indexer/imports/language-specific.js +29 -362
  167. package/dist/indexer/imports/language-specific.js.map +1 -1
  168. package/dist/indexer/imports/native-captures.d.ts.map +1 -1
  169. package/dist/indexer/imports/native-captures.js +18 -6
  170. package/dist/indexer/imports/native-captures.js.map +1 -1
  171. package/dist/indexer/imports/python.d.ts +10 -2
  172. package/dist/indexer/imports/python.d.ts.map +1 -1
  173. package/dist/indexer/imports/python.js +91 -40
  174. package/dist/indexer/imports/python.js.map +1 -1
  175. package/dist/indexer/imports/text-import-extractors.d.ts.map +1 -1
  176. package/dist/indexer/imports/text-import-extractors.js +51 -12
  177. package/dist/indexer/imports/text-import-extractors.js.map +1 -1
  178. package/dist/indexer/imports.d.ts.map +1 -1
  179. package/dist/indexer/imports.js +25 -5
  180. package/dist/indexer/imports.js.map +1 -1
  181. package/dist/indexer/incremental-plan.d.ts +33 -0
  182. package/dist/indexer/incremental-plan.d.ts.map +1 -1
  183. package/dist/indexer/incremental-plan.js +187 -1
  184. package/dist/indexer/incremental-plan.js.map +1 -1
  185. package/dist/indexer/locals-and-exports.d.ts +2 -0
  186. package/dist/indexer/locals-and-exports.d.ts.map +1 -1
  187. package/dist/indexer/locals-and-exports.js +565 -54
  188. package/dist/indexer/locals-and-exports.js.map +1 -1
  189. package/dist/indexer/name-lookup-policies/c-family.d.ts +7 -0
  190. package/dist/indexer/name-lookup-policies/c-family.d.ts.map +1 -0
  191. package/dist/indexer/name-lookup-policies/c-family.js +117 -0
  192. package/dist/indexer/name-lookup-policies/c-family.js.map +1 -0
  193. package/dist/indexer/name-lookup-policies/csharp-using-static.d.ts +11 -0
  194. package/dist/indexer/name-lookup-policies/csharp-using-static.d.ts.map +1 -0
  195. package/dist/indexer/name-lookup-policies/csharp-using-static.js +136 -0
  196. package/dist/indexer/name-lookup-policies/csharp-using-static.js.map +1 -0
  197. package/dist/indexer/name-lookup-policies/implicit-self.d.ts +10 -0
  198. package/dist/indexer/name-lookup-policies/implicit-self.d.ts.map +1 -0
  199. package/dist/indexer/name-lookup-policies/implicit-self.js +113 -0
  200. package/dist/indexer/name-lookup-policies/implicit-self.js.map +1 -0
  201. package/dist/indexer/name-lookup-policies/index.d.ts +3 -0
  202. package/dist/indexer/name-lookup-policies/index.d.ts.map +1 -0
  203. package/dist/indexer/name-lookup-policies/index.js +106 -0
  204. package/dist/indexer/name-lookup-policies/index.js.map +1 -0
  205. package/dist/indexer/name-lookup-policies/php.d.ts +3 -0
  206. package/dist/indexer/name-lookup-policies/php.d.ts.map +1 -0
  207. package/dist/indexer/name-lookup-policies/php.js +75 -0
  208. package/dist/indexer/name-lookup-policies/php.js.map +1 -0
  209. package/dist/indexer/name-resolution-types.d.ts +99 -0
  210. package/dist/indexer/name-resolution-types.d.ts.map +1 -0
  211. package/dist/indexer/name-resolution-types.js +2 -0
  212. package/dist/indexer/name-resolution-types.js.map +1 -0
  213. package/dist/indexer/name-resolution.d.ts +52 -0
  214. package/dist/indexer/name-resolution.d.ts.map +1 -0
  215. package/dist/indexer/name-resolution.js +189 -0
  216. package/dist/indexer/name-resolution.js.map +1 -0
  217. package/dist/indexer/navigation-cpp.d.ts +50 -0
  218. package/dist/indexer/navigation-cpp.d.ts.map +1 -0
  219. package/dist/indexer/navigation-cpp.js +654 -0
  220. package/dist/indexer/navigation-cpp.js.map +1 -0
  221. package/dist/indexer/navigation-goto.d.ts +107 -4
  222. package/dist/indexer/navigation-goto.d.ts.map +1 -1
  223. package/dist/indexer/navigation-goto.js +2075 -137
  224. package/dist/indexer/navigation-goto.js.map +1 -1
  225. package/dist/indexer/navigation-local.d.ts +18 -2
  226. package/dist/indexer/navigation-local.d.ts.map +1 -1
  227. package/dist/indexer/navigation-local.js +498 -61
  228. package/dist/indexer/navigation-local.js.map +1 -1
  229. package/dist/indexer/navigation-php.d.ts +66 -0
  230. package/dist/indexer/navigation-php.d.ts.map +1 -1
  231. package/dist/indexer/navigation-php.js +287 -4
  232. package/dist/indexer/navigation-php.js.map +1 -1
  233. package/dist/indexer/navigation-references.d.ts +72 -5
  234. package/dist/indexer/navigation-references.d.ts.map +1 -1
  235. package/dist/indexer/navigation-references.js +620 -54
  236. package/dist/indexer/navigation-references.js.map +1 -1
  237. package/dist/indexer/navigation-resolve.d.ts +33 -2
  238. package/dist/indexer/navigation-resolve.d.ts.map +1 -1
  239. package/dist/indexer/navigation-resolve.js +446 -193
  240. package/dist/indexer/navigation-resolve.js.map +1 -1
  241. package/dist/indexer/navigation.d.ts +28 -2
  242. package/dist/indexer/navigation.d.ts.map +1 -1
  243. package/dist/indexer/navigation.js +1082 -151
  244. package/dist/indexer/navigation.js.map +1 -1
  245. package/dist/indexer/php-namespace-symbols.d.ts +66 -0
  246. package/dist/indexer/php-namespace-symbols.d.ts.map +1 -0
  247. package/dist/indexer/php-namespace-symbols.js +342 -0
  248. package/dist/indexer/php-namespace-symbols.js.map +1 -0
  249. package/dist/indexer/reference-context.d.ts +2 -0
  250. package/dist/indexer/reference-context.d.ts.map +1 -1
  251. package/dist/indexer/reference-context.js +4 -0
  252. package/dist/indexer/reference-context.js.map +1 -1
  253. package/dist/indexer/scope-nodes.d.ts +92 -13
  254. package/dist/indexer/scope-nodes.d.ts.map +1 -1
  255. package/dist/indexer/scope-nodes.js +212 -20
  256. package/dist/indexer/scope-nodes.js.map +1 -1
  257. package/dist/indexer/scope-types.d.ts +25 -1
  258. package/dist/indexer/scope-types.d.ts.map +1 -1
  259. package/dist/indexer/scope.d.ts.map +1 -1
  260. package/dist/indexer/scope.js +894 -45
  261. package/dist/indexer/scope.js.map +1 -1
  262. package/dist/indexer/shared-owner-identity.d.ts +53 -0
  263. package/dist/indexer/shared-owner-identity.d.ts.map +1 -0
  264. package/dist/indexer/shared-owner-identity.js +460 -0
  265. package/dist/indexer/shared-owner-identity.js.map +1 -0
  266. package/dist/indexer/shared.d.ts +1 -1
  267. package/dist/indexer/shared.d.ts.map +1 -1
  268. package/dist/indexer/shared.js +1 -1
  269. package/dist/indexer/shared.js.map +1 -1
  270. package/dist/indexer/star-import-precedence.d.ts +114 -0
  271. package/dist/indexer/star-import-precedence.d.ts.map +1 -0
  272. package/dist/indexer/star-import-precedence.js +396 -0
  273. package/dist/indexer/star-import-precedence.js.map +1 -0
  274. package/dist/indexer/symbols.d.ts +3 -1
  275. package/dist/indexer/symbols.d.ts.map +1 -1
  276. package/dist/indexer/symbols.js +58 -18
  277. package/dist/indexer/symbols.js.map +1 -1
  278. package/dist/indexer/ts-callables.d.ts +51 -0
  279. package/dist/indexer/ts-callables.d.ts.map +1 -0
  280. package/dist/indexer/ts-callables.js +264 -0
  281. package/dist/indexer/ts-callables.js.map +1 -0
  282. package/dist/indexer/types.d.ts +23 -1
  283. package/dist/indexer/types.d.ts.map +1 -1
  284. package/dist/indexer/unused-exports.d.ts +13 -0
  285. package/dist/indexer/unused-exports.d.ts.map +1 -0
  286. package/dist/indexer/unused-exports.js +159 -0
  287. package/dist/indexer/unused-exports.js.map +1 -0
  288. package/dist/indexer/workspace-symbols.d.ts.map +1 -1
  289. package/dist/indexer/workspace-symbols.js +3 -2
  290. package/dist/indexer/workspace-symbols.js.map +1 -1
  291. package/dist/indexer.d.ts +2 -2
  292. package/dist/indexer.d.ts.map +1 -1
  293. package/dist/indexer.js +1 -1
  294. package/dist/indexer.js.map +1 -1
  295. package/dist/languages/callable-arity.d.ts +202 -0
  296. package/dist/languages/callable-arity.d.ts.map +1 -0
  297. package/dist/languages/callable-arity.js +1182 -0
  298. package/dist/languages/callable-arity.js.map +1 -0
  299. package/dist/languages/definitions/c-family.d.ts.map +1 -1
  300. package/dist/languages/definitions/c-family.js +30 -1
  301. package/dist/languages/definitions/c-family.js.map +1 -1
  302. package/dist/languages/definitions/c.d.ts +4 -0
  303. package/dist/languages/definitions/c.d.ts.map +1 -1
  304. package/dist/languages/definitions/c.js +19 -0
  305. package/dist/languages/definitions/c.js.map +1 -1
  306. package/dist/languages/definitions/cpp.d.ts.map +1 -1
  307. package/dist/languages/definitions/cpp.js +12 -0
  308. package/dist/languages/definitions/cpp.js.map +1 -1
  309. package/dist/languages/definitions/csharp.d.ts.map +1 -1
  310. package/dist/languages/definitions/csharp.js +2 -8
  311. package/dist/languages/definitions/csharp.js.map +1 -1
  312. package/dist/languages/definitions/go.d.ts.map +1 -1
  313. package/dist/languages/definitions/go.js +3 -0
  314. package/dist/languages/definitions/go.js.map +1 -1
  315. package/dist/languages/definitions/javascript.d.ts.map +1 -1
  316. package/dist/languages/definitions/javascript.js +10 -1
  317. package/dist/languages/definitions/javascript.js.map +1 -1
  318. package/dist/languages/definitions/js-family.d.ts +1 -1
  319. package/dist/languages/definitions/js-family.d.ts.map +1 -1
  320. package/dist/languages/definitions/js-family.js +7 -1
  321. package/dist/languages/definitions/js-family.js.map +1 -1
  322. package/dist/languages/definitions/php.d.ts.map +1 -1
  323. package/dist/languages/definitions/php.js +5 -1
  324. package/dist/languages/definitions/php.js.map +1 -1
  325. package/dist/languages/definitions/typescript.d.ts.map +1 -1
  326. package/dist/languages/definitions/typescript.js +8 -1
  327. package/dist/languages/definitions/typescript.js.map +1 -1
  328. package/dist/languages/definitions/zig.d.ts.map +1 -1
  329. package/dist/languages/definitions/zig.js +2 -0
  330. package/dist/languages/definitions/zig.js.map +1 -1
  331. package/dist/mcp/handlers.js +14 -7
  332. package/dist/mcp/handlers.js.map +1 -1
  333. package/dist/review/candidates.d.ts.map +1 -1
  334. package/dist/review/candidates.js +1 -1
  335. package/dist/review/candidates.js.map +1 -1
  336. package/dist/review/deleted.d.ts +3 -3
  337. package/dist/review/deleted.d.ts.map +1 -1
  338. package/dist/review/deleted.js +82 -32
  339. package/dist/review/deleted.js.map +1 -1
  340. package/dist/review/report.d.ts +1 -0
  341. package/dist/review/report.d.ts.map +1 -1
  342. package/dist/review/report.js +1 -1
  343. package/dist/review/report.js.map +1 -1
  344. package/dist/review.d.ts.map +1 -1
  345. package/dist/review.js +1 -0
  346. package/dist/review.js.map +1 -1
  347. package/dist/sql/navigation.d.ts.map +1 -1
  348. package/dist/sql/navigation.js +1 -0
  349. package/dist/sql/navigation.js.map +1 -1
  350. package/dist/sql/source-graph.d.ts.map +1 -1
  351. package/dist/sql/source-graph.js +2 -2
  352. package/dist/sql/source-graph.js.map +1 -1
  353. package/dist/sqlite/schema.d.ts +1 -1
  354. package/dist/sqlite/schema.d.ts.map +1 -1
  355. package/dist/sqlite/schema.js +8 -2
  356. package/dist/sqlite/schema.js.map +1 -1
  357. package/dist/sqlite/write.js +2 -2
  358. package/dist/sqlite/write.js.map +1 -1
  359. package/dist/types.d.ts +2 -0
  360. package/dist/types.d.ts.map +1 -1
  361. package/dist/util/bloom-filter.d.ts +7 -1
  362. package/dist/util/bloom-filter.d.ts.map +1 -1
  363. package/dist/util/bloom-filter.js +12 -2
  364. package/dist/util/bloom-filter.js.map +1 -1
  365. package/dist/util/dynamic-import-tables.d.ts +88 -0
  366. package/dist/util/dynamic-import-tables.d.ts.map +1 -0
  367. package/dist/util/dynamic-import-tables.js +100 -0
  368. package/dist/util/dynamic-import-tables.js.map +1 -0
  369. package/dist/util/graph-edges.d.ts +19 -1
  370. package/dist/util/graph-edges.d.ts.map +1 -1
  371. package/dist/util/graph-edges.js +30 -4
  372. package/dist/util/graph-edges.js.map +1 -1
  373. package/dist/util/identifiers.d.ts +15 -0
  374. package/dist/util/identifiers.d.ts.map +1 -1
  375. package/dist/util/identifiers.js +35 -0
  376. package/dist/util/identifiers.js.map +1 -1
  377. package/dist/util/member-access-tables.d.ts +129 -0
  378. package/dist/util/member-access-tables.d.ts.map +1 -0
  379. package/dist/util/member-access-tables.js +285 -0
  380. package/dist/util/member-access-tables.js.map +1 -0
  381. package/dist/util/member-access.d.ts +17 -0
  382. package/dist/util/member-access.d.ts.map +1 -1
  383. package/dist/util/member-access.js +138 -93
  384. package/dist/util/member-access.js.map +1 -1
  385. package/dist/util/resolution/cargo-targets.d.ts +11 -0
  386. package/dist/util/resolution/cargo-targets.d.ts.map +1 -1
  387. package/dist/util/resolution/cargo-targets.js +174 -13
  388. package/dist/util/resolution/cargo-targets.js.map +1 -1
  389. package/dist/util/resolution/csharp.d.ts +33 -1
  390. package/dist/util/resolution/csharp.d.ts.map +1 -1
  391. package/dist/util/resolution/csharp.js +145 -30
  392. package/dist/util/resolution/csharp.js.map +1 -1
  393. package/dist/util/resolution/php.d.ts.map +1 -1
  394. package/dist/util/resolution/php.js +35 -8
  395. package/dist/util/resolution/php.js.map +1 -1
  396. package/dist/util/resolution/python.d.ts +9 -0
  397. package/dist/util/resolution/python.d.ts.map +1 -1
  398. package/dist/util/resolution/python.js +46 -0
  399. package/dist/util/resolution/python.js.map +1 -1
  400. package/dist/util/resolution/rust.d.ts.map +1 -1
  401. package/dist/util/resolution/rust.js +95 -26
  402. package/dist/util/resolution/rust.js.map +1 -1
  403. package/dist/util/resolution-candidates.d.ts +5 -0
  404. package/dist/util/resolution-candidates.d.ts.map +1 -1
  405. package/dist/util/resolution-candidates.js +16 -3
  406. package/dist/util/resolution-candidates.js.map +1 -1
  407. package/dist/util/resolution.d.ts +2 -1
  408. package/dist/util/resolution.d.ts.map +1 -1
  409. package/dist/util/resolution.js +96 -5
  410. package/dist/util/resolution.js.map +1 -1
  411. package/dist/util/specifiers.d.ts +20 -0
  412. package/dist/util/specifiers.d.ts.map +1 -1
  413. package/dist/util/specifiers.js +39 -93
  414. package/dist/util/specifiers.js.map +1 -1
  415. package/docs/mcp.md +3 -2
  416. package/package.json +3 -3
@@ -1,29 +1,18 @@
1
- import fs from "node:fs";
2
1
  import path from "node:path";
3
2
  import { supportForFileWithoutHeaderSample } from "../languages.js";
4
3
  import { languageHasDeclarationVisibility } from "./declaration-visibility.js";
5
- import { GO_IDENTIFIER_SOURCE, JAVA_IDENTIFIER_SOURCE, KOTLIN_IDENTIFIER_SOURCE } from "../util/identifiers.js";
4
+ import { foldPhpIdentifierCase, normalizeCsharpIdentifier, normalizeCsharpQualifiedName } from "../util/identifiers.js";
6
5
  import { fileIdentityKey, normalizePath } from "../util/paths.js";
6
+ import { getCompilationUnitPeers, IMPLICIT_UNIT_LANGUAGES, isUnitBareNameVisible } from "./compilation-units.js";
7
+ import { phpNamedImportRole } from "./import-types.js";
8
+ import { resolvePythonSubmoduleExact } from "../util/resolution/python.js";
9
+ import { PHP_CLASS_LIKE_KINDS } from "./php-namespace-symbols.js";
10
+ import { coalesceEquivalentCsharpPartialExports } from "./shared-owner-identity.js";
7
11
  import { SymbolKind, } from "./types.js";
8
- const GO_PACKAGE_PATTERN = new RegExp(String.raw `^\s*package\s+(${GO_IDENTIFIER_SOURCE})`, "mu");
9
- const JAVA_PACKAGE_NAME_PATTERN = new RegExp(String.raw `^\s*package\s+(${JAVA_IDENTIFIER_SOURCE}(?:\.${JAVA_IDENTIFIER_SOURCE})*)\s*;`, "mu");
10
- const KOTLIN_PACKAGE_NAME_PATTERN = new RegExp(String.raw `^\s*package\s+(${KOTLIN_IDENTIFIER_SOURCE}(?:\.${KOTLIN_IDENTIFIER_SOURCE})*)`, "mu");
11
- /**
12
- * Files that can carry the package declaration each lookup language searches for. Java and Kotlin
13
- * stay one group because they share a JVM package namespace and each pattern already accepts the
14
- * other's declaration; every other language is skipped instead of read for a keyword it never uses.
15
- */
16
- const PACKAGE_DECLARING_LANGUAGE_IDS = {
17
- go: new Set(["go"]),
18
- java: new Set(["java", "kotlin"]),
19
- kotlin: new Set(["java", "kotlin"]),
20
- };
21
12
  function cacheKey(file, canonicalName) {
22
13
  return `${fileIdentityKey(file)}::canonical::${canonicalName}`;
23
14
  }
24
15
  const moduleNameLookups = new WeakMap();
25
- const packageDirectoryLookups = new WeakMap();
26
- const packageNameCaches = new WeakMap();
27
16
  function moduleFor(index, file) {
28
17
  return index.byFile.get(fileIdentityKey(file));
29
18
  }
@@ -123,175 +112,155 @@ function sameResolvedExport(index, left, right) {
123
112
  }
124
113
  return false;
125
114
  }
126
- function packageNameCacheFor(index) {
127
- let caches = packageNameCaches.get(index);
128
- if (!caches) {
129
- caches = { go: new Map(), jvm: new Map() };
130
- packageNameCaches.set(index, caches);
131
- }
132
- return caches;
133
- }
134
115
  /**
135
- * Source to read a package declaration from: the text the index already parsed when it retained
136
- * one, and otherwise the file itself. Reusing the retained text keeps the package name consistent
137
- * with the symbols resolved from that same snapshot.
116
+ * Unique same-compilation-unit match for a bare name. Go, the JVM languages, C#, and Swift can
117
+ * name top-level declarations of their package, namespace, or module without an import;
118
+ * candidates come from the same proven unit relation used for reference-candidate discovery
119
+ * (`getCompilationUnitPeers`), never from a project-wide name scan. A name matching more than
120
+ * one unit declaration is ambiguous and stays unresolved, except proven-equivalent C# `partial`
121
+ * type parts, which collapse to one representative before uniqueness is judged. Members are
122
+ * excluded because they resolve through receiver/owner identity rather than as bare unit names.
138
123
  */
139
- function packageDeclarationSource(index, filePath, fileKey) {
140
- const retained = index.parsed?.get(fileKey)?.source;
141
- if (retained !== undefined)
142
- return retained;
143
- try {
144
- return fs.readFileSync(filePath, "utf8");
145
- }
146
- catch {
147
- return null;
148
- }
149
- }
150
- function readGoPackageName(index, filePath) {
151
- const cache = packageNameCacheFor(index).go;
152
- const key = fileIdentityKey(filePath);
153
- const cached = cache.get(key);
154
- if (cached !== undefined)
155
- return cached;
156
- const source = packageDeclarationSource(index, filePath, key);
157
- if (source === null) {
158
- cache.set(key, null);
159
- return null;
160
- }
161
- const packageName = GO_PACKAGE_PATTERN.exec(source)?.[1] ?? null;
162
- cache.set(key, packageName);
163
- return packageName;
164
- }
165
- function resolveGoPackageExport(index, file, exportedName) {
166
- if (supportForFileWithoutHeaderSample(file, index.languageExtensions)?.id !== "go")
124
+ function resolveImplicitUnitExport(index, file, exportedName, matchesOptions, namespace, useIndex, qualification) {
125
+ // Only the implicit compilation-unit languages have bare-name unit visibility. C and C++
126
+ // keep their include-scope tag precedence and PHP its case-folded namespaces; the unit
127
+ // lookup must not preempt those established fallbacks.
128
+ const languageId = supportForFileWithoutHeaderSample(file, index.languageExtensions)?.id;
129
+ if (!languageId || !IMPLICIT_UNIT_LANGUAGES[languageId])
167
130
  return null;
168
- const directory = packageDirectoryLookup(index, "go").get(fileIdentityKey(path.dirname(file)));
169
- if (!directory)
170
- return null;
171
- const sourcePackage = readGoPackageName(index, file);
172
- const candidates = sourcePackage ? (directory.byName.get(sourcePackage) ?? []) : directory.all;
173
131
  const matches = [];
174
- for (const moduleEntry of candidates) {
175
- const names = moduleNameLookup(index, moduleEntry.file);
132
+ const peers = getCompilationUnitPeers(index, file, languageId === "csharp" && qualification !== undefined ? { csharpQualifiedName: true } : undefined);
133
+ for (const peerFile of peers.files) {
134
+ const names = moduleNameLookup(index, peerFile);
176
135
  if (!names)
177
136
  continue;
178
137
  for (const target of names.localExports.get(names.normalizeIdentifier(exportedName)) ?? []) {
138
+ if (target.isMember || !matchesOptions(target, namespace))
139
+ continue;
140
+ if (!isUnitBareNameVisible({
141
+ index,
142
+ declarationFile: target.file,
143
+ declaration: target.range,
144
+ useFile: file,
145
+ ...(useIndex !== undefined ? { useIndex } : {}),
146
+ ...(qualification !== undefined ? { qualification } : {}),
147
+ })) {
148
+ continue;
149
+ }
179
150
  if (!matches.some((candidate) => sameSymbolDef(index, candidate, target))) {
180
151
  matches.push(target);
181
152
  }
182
153
  }
183
154
  }
184
- return matches.length === 1 ? (matches[0] ?? null) : null;
185
- }
186
- function readPackageNameForLanguage(index, filePath, languageId) {
187
- const cache = packageNameCacheFor(index).jvm;
188
- const fileKey = fileIdentityKey(filePath);
189
- const key = `${languageId}::${fileKey}`;
190
- const cached = cache.get(key);
191
- if (cached !== undefined)
192
- return cached;
193
- const source = packageDeclarationSource(index, filePath, fileKey);
194
- if (source === null) {
195
- cache.set(key, null);
196
- return null;
197
- }
198
- const pattern = languageId === "kotlin" ? KOTLIN_PACKAGE_NAME_PATTERN : JAVA_PACKAGE_NAME_PATTERN;
199
- const packageName = pattern.exec(source)?.[1] ?? null;
200
- cache.set(key, packageName);
201
- return packageName;
155
+ const unique = languageId === "csharp" ? coalesceEquivalentCsharpPartialExports(index, matches) : matches;
156
+ return unique.length === 1 ? (unique[0] ?? null) : null;
202
157
  }
203
- function packageDirectoryLookup(index, languageId) {
204
- let byLanguage = packageDirectoryLookups.get(index);
205
- if (!byLanguage) {
206
- byLanguage = new Map();
207
- packageDirectoryLookups.set(index, byLanguage);
208
- }
209
- const cached = byLanguage.get(languageId);
210
- if (cached)
211
- return cached;
212
- const directories = new Map();
213
- for (const moduleEntry of index.byFile.values()) {
214
- const directoryKey = fileIdentityKey(path.dirname(moduleEntry.file));
215
- let directory = directories.get(directoryKey);
216
- if (!directory) {
217
- directory = { all: [], byName: new Map() };
218
- directories.set(directoryKey, directory);
219
- }
220
- directory.all.push(moduleEntry);
221
- const moduleLanguageId = supportForFileWithoutHeaderSample(moduleEntry.file, index.languageExtensions)?.id;
222
- if (!moduleLanguageId || !PACKAGE_DECLARING_LANGUAGE_IDS[languageId].has(moduleLanguageId))
223
- continue;
224
- const packageName = languageId === "go"
225
- ? readGoPackageName(index, moduleEntry.file)
226
- : readPackageNameForLanguage(index, moduleEntry.file, languageId);
227
- if (!packageName)
228
- continue;
229
- const entries = directory.byName.get(packageName) ?? [];
230
- entries.push(moduleEntry);
231
- directory.byName.set(packageName, entries);
232
- }
233
- byLanguage.set(languageId, directories);
234
- return directories;
235
- }
236
- function resolveSiblingPackageExport(index, targetFile, exportedName, languageId) {
237
- const packageName = readPackageNameForLanguage(index, targetFile, languageId);
238
- if (!packageName)
239
- return null;
240
- const directory = packageDirectoryLookup(index, languageId).get(fileIdentityKey(path.dirname(targetFile)));
241
- if (!directory)
158
+ /**
159
+ * Same-package Java/Kotlin export that the bare-name unit scan does not answer (a member, for
160
+ * example). Peers come from `getCompilationUnitPeers`, so Java and Kotlin share one package
161
+ * rule. An incomplete set (an unreadable peer, or the same package outside this directory)
162
+ * is not a proven unique answer.
163
+ */
164
+ function resolveSiblingPackageExport(index, targetFile, exportedName) {
165
+ const peers = getCompilationUnitPeers(index, targetFile);
166
+ if (!peers.complete)
242
167
  return null;
243
168
  const targetFileKey = fileIdentityKey(targetFile);
244
169
  const matches = [];
245
- for (const moduleEntry of directory.byName.get(packageName) ?? []) {
246
- if (fileIdentityKey(moduleEntry.file) === targetFileKey)
170
+ for (const peerFile of peers.files) {
171
+ if (fileIdentityKey(peerFile) === targetFileKey)
247
172
  continue;
248
- const hit = resolveExport(index, moduleEntry.file, exportedName);
173
+ const hit = resolveExport(index, peerFile, exportedName);
249
174
  if (hit && !matches.some((candidate) => sameResolvedExport(index, candidate, hit))) {
250
175
  matches.push(hit);
251
176
  }
252
177
  }
253
178
  return matches.length === 1 ? (matches[0] ?? null) : null;
254
179
  }
255
- function resolvePythonSubmodule(targetFile, exportedName) {
256
- let baseDir;
257
- try {
258
- const targetStat = fs.statSync(targetFile);
259
- if (targetStat.isDirectory()) {
260
- baseDir = targetFile;
261
- }
262
- else if (path.basename(targetFile) === "__init__.py" || path.basename(targetFile) === "__init__.pyi") {
263
- baseDir = path.dirname(targetFile);
264
- }
265
- else {
266
- return null;
267
- }
180
+ function declaresMemberKind(def) {
181
+ return def.kind === SymbolKind.Class || def.kind === SymbolKind.Interface || def.kind === SymbolKind.TypeAlias;
182
+ }
183
+ /**
184
+ * A default-export wrapper keeps `SymbolKind.Default` so the export name stays `default`.
185
+ * Member lookup needs the class, interface, or type alias that wrapper was copied from.
186
+ */
187
+ export function memberContainerForDefinition(index, def) {
188
+ if (declaresMemberKind(def))
189
+ return def;
190
+ if (def.kind !== SymbolKind.Default)
191
+ return undefined;
192
+ const moduleEntry = index.byFile.get(fileIdentityKey(def.file));
193
+ if (!moduleEntry)
194
+ return undefined;
195
+ const sameRange = moduleEntry.locals.filter((local) => declaresMemberKind(local) &&
196
+ local.range.start.line === def.range.start.line &&
197
+ local.range.start.column === def.range.start.column);
198
+ if (sameRange.length === 1)
199
+ return sameRange[0];
200
+ }
201
+ /** The export entry that proves a direct CommonJS or TypeScript module value, whatever its public name. */
202
+ export function directModuleValueEntry(moduleEntry) {
203
+ return moduleEntry.exports.find((entry) => entry.type === "local" && (entry.mechanism === "cjs-module-value" || entry.mechanism === "ts-export-assignment"));
204
+ }
205
+ /**
206
+ * `require()` and `import x = require()` return a proven direct `module.exports = X` or
207
+ * TypeScript `export = X` value. A default export accompanied by named exports instead returns
208
+ * a namespace object, including non-local and star re-exports.
209
+ */
210
+ export function cjsRequireValueBinding(index, targetFile) {
211
+ const moduleEntry = index.byFile.get(fileIdentityKey(targetFile));
212
+ const directValue = moduleEntry && directModuleValueEntry(moduleEntry);
213
+ if (directValue)
214
+ return memberContainerForDefinition(index, directValue.target) ?? directValue.target;
215
+ const resolved = resolveExport(index, targetFile, "default");
216
+ if (resolved?.kind !== "resolved")
217
+ return undefined;
218
+ const hasNamedExport = moduleEntry?.exports.some((entry) => {
219
+ if (entry.type === "exportStar")
220
+ return !entry.typeOnly;
221
+ if (entry.type === "local")
222
+ return entry.exportedAs !== "default" && !entry.target.isMember;
223
+ return entry.exportedAs !== "default" && !entry.typeOnly;
224
+ });
225
+ if (hasNamedExport)
226
+ return undefined;
227
+ return memberContainerForDefinition(index, resolved.def) ?? resolved.def;
228
+ }
229
+ const fileEdgeTargetsCache = new WeakMap();
230
+ /** First resolved file target per importer and raw specifier; rebuilt when the edge list changes. */
231
+ function fileEdgeTargetsFor(index) {
232
+ const edges = index.graph.edges;
233
+ const cached = fileEdgeTargetsCache.get(index);
234
+ if (cached && cached.edges === edges && cached.length === edges.length)
235
+ return cached.targets;
236
+ const targets = new Map();
237
+ for (const edge of edges) {
238
+ if (edge.to.type !== "file")
239
+ continue;
240
+ const key = `${fileIdentityKey(edge.from)}\0${edge.raw}`;
241
+ if (!targets.has(key))
242
+ targets.set(key, edge.to.path);
268
243
  }
269
- catch {
244
+ fileEdgeTargetsCache.set(index, { edges, length: edges.length, targets });
245
+ return targets;
246
+ }
247
+ /**
248
+ * A member of the module a `typeof import("spec")` receiver holds, resolved through the file
249
+ * dependency edge the index recorded for that specifier.
250
+ */
251
+ export function resolveImportTypeMember(index, fromFile, specifier, member) {
252
+ const target = fileEdgeTargetsFor(index).get(`${fileIdentityKey(fromFile)}\0${specifier}`);
253
+ if (!target)
270
254
  return null;
271
- }
272
- const moduleFile = path.join(baseDir, `${exportedName}.py`);
273
- const stubModuleFile = path.join(baseDir, `${exportedName}.pyi`);
274
- const packageInit = path.join(baseDir, exportedName, "__init__.py");
275
- const stubPackageInit = path.join(baseDir, exportedName, "__init__.pyi");
276
- const namespacePackage = path.join(baseDir, exportedName);
277
- for (const candidate of [moduleFile, stubModuleFile, packageInit, stubPackageInit, namespacePackage]) {
278
- try {
279
- const candidateStat = fs.statSync(candidate);
280
- if (candidate === namespacePackage ? candidateStat.isDirectory() : candidateStat.isFile()) {
281
- return normalizePath(candidate);
282
- }
283
- }
284
- catch {
285
- // The next candidate can still be a real submodule.
286
- }
287
- }
288
- return null;
255
+ const hit = resolveExport(index, target, member);
256
+ return hit?.kind === "resolved" ? hit.def : null;
289
257
  }
290
258
  export function resolveExport(index, file, exportedName, opts) {
291
259
  const visited = new Set();
292
- const matchesPreferredKind = (def) => !opts?.preferredKind || def.kind === opts.preferredKind;
260
+ const matchesOptions = (def, namespace) => (!opts?.preferredKind || def.kind === opts.preferredKind) &&
261
+ (namespace === undefined || (def.cTag ? "tag" : "ordinary") === namespace);
293
262
  const allowLocalFallback = opts?.allowLocalFallback ?? true;
294
- function resolveFromFile(fileInner, name) {
263
+ function resolveFromFile(fileInner, name, namespace = opts?.cNamespace) {
295
264
  const moduleEntry = moduleFor(index, fileInner);
296
265
  if (!moduleEntry)
297
266
  return null;
@@ -299,29 +268,80 @@ export function resolveExport(index, file, exportedName, opts) {
299
268
  if (!names)
300
269
  return null;
301
270
  const normalizedFile = normalizePath(moduleEntry.file);
302
- const canonicalName = names.normalizeIdentifier(name);
303
- const key = opts?.preferredKind
304
- ? `${cacheKey(normalizedFile, canonicalName)}::${opts.preferredKind}::${allowLocalFallback ? "local" : "export"}`
305
- : `${cacheKey(normalizedFile, canonicalName)}::${allowLocalFallback ? "local" : "export"}`;
271
+ const referenceIndex = fileIdentityKey(fileInner) === fileIdentityKey(file) ? opts?.referenceIndex : undefined;
272
+ const csharpFile = supportForFileWithoutHeaderSample(normalizedFile, index.languageExtensions)?.id === "csharp";
273
+ // A dotted name is a namespace path even when the caller has no source position
274
+ // (`using PT = N.Inner.Point` resolves through the bound file, not a use site).
275
+ // A bare name still needs a source position before namespace visibility applies.
276
+ const filtersUseNamespace = csharpFile && (referenceIndex !== undefined || name.includes(".") || name.startsWith("global::"));
277
+ const separator = filtersUseNamespace ? name.lastIndexOf(".") : -1;
278
+ let qualification;
279
+ let unqualifiedName = name;
280
+ if (separator >= 0) {
281
+ // `@P.Target` and `P.Target` name the same namespace path.
282
+ qualification = normalizeCsharpQualifiedName(name.slice(0, separator));
283
+ unqualifiedName = name.slice(separator + 1);
284
+ }
285
+ else if (filtersUseNamespace && name.startsWith("global::")) {
286
+ qualification = "global::";
287
+ unqualifiedName = name.slice("global::".length);
288
+ }
289
+ const canonicalName = names.normalizeIdentifier(unqualifiedName);
290
+ const key = `${cacheKey(normalizedFile, names.normalizeIdentifier(name))}::${opts?.preferredKind ?? ""}::${namespace ?? ""}::${allowLocalFallback ? "local" : "export"}::${referenceIndex ?? ""}`;
306
291
  if (index.exportCache.has(key))
307
292
  return index.exportCache.get(key);
308
- const cycleKey = cacheKey(normalizedFile, canonicalName);
293
+ const cycleKey = `${cacheKey(normalizedFile, canonicalName)}::${namespace ?? ""}`;
309
294
  if (visited.has(cycleKey))
310
295
  return null;
311
296
  visited.add(cycleKey);
312
- const goPackageExport = resolveGoPackageExport(index, normalizedFile, canonicalName);
313
- if (goPackageExport && matchesPreferredKind(goPackageExport)) {
314
- const result = { kind: "resolved", def: goPackageExport };
297
+ const implicitUnitExport = resolveImplicitUnitExport(index, normalizedFile, canonicalName, matchesOptions, namespace, referenceIndex, qualification);
298
+ if (implicitUnitExport) {
299
+ const result = { kind: "resolved", def: implicitUnitExport };
315
300
  index.exportCache.set(key, result);
316
301
  return result;
317
302
  }
318
303
  const localCandidates = [];
319
304
  for (const target of names.localExports.get(canonicalName) ?? []) {
320
- if (matchesPreferredKind(target) &&
305
+ if (matchesOptions(target, namespace) &&
306
+ // Nested types resolve through their owner, not as bare namespace names.
307
+ (!filtersUseNamespace ||
308
+ (!target.isMember &&
309
+ isUnitBareNameVisible({
310
+ index,
311
+ declarationFile: target.file,
312
+ declaration: target.range,
313
+ useFile: file,
314
+ ...(referenceIndex !== undefined ? { useIndex: referenceIndex } : {}),
315
+ ...(qualification !== undefined ? { qualification } : {}),
316
+ }))) &&
321
317
  !localCandidates.some((candidate) => sameSymbolDef(index, candidate, target))) {
322
318
  localCandidates.push(target);
323
319
  }
324
320
  }
321
+ // A bodyless C tag use can introduce an incomplete tag, but must reuse a tag
322
+ // already brought into scope by an include. Do not let that use hide its header.
323
+ if (namespace &&
324
+ (!localCandidates.length ||
325
+ localCandidates.every((candidate) => candidate.cTag === "reference" || candidate.cTag === "forward"))) {
326
+ const included = [];
327
+ for (const imp of moduleEntry.imports) {
328
+ if (typeof imp.resolved !== "string")
329
+ continue;
330
+ if (imp.kind !== "star" && !(imp.kind === "named" && imp.local === name))
331
+ continue;
332
+ if (imp.kind === "named" && (imp.cNamespace ?? "ordinary") !== namespace)
333
+ continue;
334
+ const downstream = resolveFromFile(imp.resolved, imp.kind === "named" ? imp.imported : name, namespace);
335
+ if (downstream && !included.some((candidate) => sameResolvedExport(index, candidate, downstream))) {
336
+ included.push(downstream);
337
+ }
338
+ }
339
+ if (included.length) {
340
+ const result = included.length === 1 ? included[0] : null;
341
+ index.exportCache.set(key, result);
342
+ return result;
343
+ }
344
+ }
325
345
  if (localCandidates.length === 1) {
326
346
  const target = localCandidates[0];
327
347
  const result = { kind: "resolved", def: target };
@@ -348,8 +368,9 @@ export function resolveExport(index, file, exportedName, opts) {
348
368
  }
349
369
  const reexportCandidates = [];
350
370
  for (const entry of names.reexports.get(canonicalName) ?? []) {
351
- const downstream = resolveFromFile(entry.fromModule, entry.sourceSpecifier || canonicalName) ??
352
- resolveFromFile(entry.fromModule, canonicalName);
371
+ const downstream = resolveFromFile(entry.fromModule, entry.sourceSpecifier || canonicalName, namespace) ??
372
+ // A qualified using target cannot fall back to an unrelated bare export.
373
+ (entry.sourceSpecifier.includes("::") ? null : resolveFromFile(entry.fromModule, canonicalName, namespace));
353
374
  if (downstream && !reexportCandidates.some((candidate) => sameResolvedExport(index, candidate, downstream))) {
354
375
  reexportCandidates.push(downstream);
355
376
  }
@@ -367,7 +388,7 @@ export function resolveExport(index, file, exportedName, opts) {
367
388
  for (const entry of moduleEntry.exports) {
368
389
  if (entry.type !== "exportStar")
369
390
  continue;
370
- const downstream = resolveFromFile(entry.fromModule, canonicalName);
391
+ const downstream = resolveFromFile(entry.fromModule, canonicalName, namespace);
371
392
  if (downstream && !starCandidates.some((candidate) => sameResolvedExport(index, candidate, downstream))) {
372
393
  starCandidates.push(downstream);
373
394
  }
@@ -382,21 +403,44 @@ export function resolveExport(index, file, exportedName, opts) {
382
403
  return null;
383
404
  }
384
405
  const localFallbackCandidates = [];
385
- if (allowLocalFallback && !shouldSkipVisibilityLocalFallback(index, moduleEntry)) {
406
+ // C# lexical bindings have already been checked. Only namespace-level types
407
+ // can remain visible from another region without a shared lexical scope.
408
+ if (allowLocalFallback && (filtersUseNamespace || !shouldSkipVisibilityLocalFallback(index, moduleEntry))) {
386
409
  for (const local of names.locals.get(canonicalName) ?? []) {
387
- if (matchesPreferredKind(local) &&
410
+ if (filtersUseNamespace &&
411
+ (local.isMember ||
412
+ (local.kind !== SymbolKind.Class &&
413
+ local.kind !== SymbolKind.Interface &&
414
+ local.kind !== SymbolKind.TypeAlias) ||
415
+ !isUnitBareNameVisible({
416
+ index,
417
+ declarationFile: local.file,
418
+ declaration: local.range,
419
+ useFile: file,
420
+ ...(referenceIndex !== undefined ? { useIndex: referenceIndex } : {}),
421
+ ...(qualification !== undefined ? { qualification } : {}),
422
+ }))) {
423
+ continue;
424
+ }
425
+ if (matchesOptions(local, namespace) &&
388
426
  !localFallbackCandidates.some((candidate) => sameSymbolDef(index, candidate, local))) {
389
427
  localFallbackCandidates.push(local);
390
428
  }
391
429
  }
392
430
  }
393
- if (localFallbackCandidates.length === 1) {
394
- const local = localFallbackCandidates[0];
431
+ // Hidden same-file C# types are omitted from exports, so equivalent internal
432
+ // `partial` parts both land here. Collapse them with the same shared-owner
433
+ // identity used for exported candidates before uniqueness is judged.
434
+ const uniqueLocalFallback = filtersUseNamespace
435
+ ? coalesceEquivalentCsharpPartialExports(index, localFallbackCandidates)
436
+ : localFallbackCandidates;
437
+ if (uniqueLocalFallback.length === 1) {
438
+ const local = uniqueLocalFallback[0];
395
439
  const result = { kind: "resolved", def: local };
396
440
  index.exportCache.set(key, result);
397
441
  return result;
398
442
  }
399
- if (localFallbackCandidates.length) {
443
+ if (uniqueLocalFallback.length) {
400
444
  index.exportCache.set(key, null);
401
445
  return null;
402
446
  }
@@ -405,6 +449,63 @@ export function resolveExport(index, file, exportedName, opts) {
405
449
  }
406
450
  return resolveFromFile(file, exportedName);
407
451
  }
452
+ function resolvePhpCaseInsensitiveExport(index, targetFile, exportedName, preferredKind) {
453
+ const exactExport = resolveExport(index, targetFile, exportedName, { preferredKind, allowLocalFallback: false });
454
+ if (exactExport)
455
+ return exactExport;
456
+ const moduleEntry = moduleFor(index, targetFile);
457
+ if (!moduleEntry)
458
+ return null;
459
+ const foldedName = foldPhpIdentifierCase(exportedName);
460
+ const resolveUnique = (sourceSpellings, allowLocalFallback) => {
461
+ const matches = [];
462
+ for (const sourceSpelling of sourceSpellings) {
463
+ const hit = resolveExport(index, targetFile, sourceSpelling, { preferredKind, allowLocalFallback });
464
+ if (hit && !matches.some((candidate) => sameResolvedExport(index, candidate, hit))) {
465
+ matches.push(hit);
466
+ }
467
+ }
468
+ return matches.length === 1 ? matches[0] : null;
469
+ };
470
+ const exportSpellings = new Set();
471
+ for (const entry of moduleEntry.exports) {
472
+ if (entry.type === "local" &&
473
+ entry.target.kind === preferredKind &&
474
+ foldPhpIdentifierCase(entry.exportedAs) === foldedName) {
475
+ exportSpellings.add(entry.exportedAs);
476
+ }
477
+ }
478
+ if (exportSpellings.size)
479
+ return resolveUnique(exportSpellings, false);
480
+ const exactLocal = resolveExport(index, targetFile, exportedName, { preferredKind });
481
+ if (exactLocal)
482
+ return exactLocal;
483
+ const localSpellings = new Set();
484
+ for (const local of moduleEntry.locals) {
485
+ if (local.kind === preferredKind && foldPhpIdentifierCase(local.localName) === foldedName) {
486
+ localSpellings.add(local.localName);
487
+ }
488
+ }
489
+ return resolveUnique(localSpellings, true);
490
+ }
491
+ /** Resolves a PHP symbol through its separate class, function, or constant import namespace. */
492
+ export function resolvePhpExportByImportType(index, targetFile, exportedName, importType) {
493
+ if (importType === "class") {
494
+ for (const preferredKind of PHP_CLASS_LIKE_KINDS) {
495
+ const hit = resolvePhpCaseInsensitiveExport(index, targetFile, exportedName, preferredKind);
496
+ if (hit)
497
+ return hit;
498
+ }
499
+ return null;
500
+ }
501
+ if (importType === "function") {
502
+ return resolvePhpCaseInsensitiveExport(index, targetFile, exportedName, SymbolKind.Function);
503
+ }
504
+ if (importType === "const") {
505
+ return resolveExport(index, targetFile, exportedName, { preferredKind: SymbolKind.Variable });
506
+ }
507
+ return resolveExport(index, targetFile, exportedName);
508
+ }
408
509
  function collectExportedNames(index, file, includeLocalFallback, names, visited) {
409
510
  const fileKey = fileIdentityKey(file);
410
511
  if (visited.has(fileKey))
@@ -439,41 +540,193 @@ export function resolveModuleExports(index, file, opts) {
439
540
  }
440
541
  return resolved;
441
542
  }
442
- export function resolveImported(index, imp, exportedName) {
543
+ /**
544
+ * Qualified name a C# using-alias binds. `from` is either the namespace (`N.Inner`
545
+ * for `using PT = N.Inner.Point`) or the full dotted type when an earlier resolver
546
+ * already kept it (`Utils.UtilsClass`). A bare imported name must not be searched on
547
+ * its own: compilation-unit lookup would accept a same-named type in another namespace.
548
+ */
549
+ function csharpNamedImportLookupName(from, exportedName) {
550
+ if (!exportedName || exportedName.includes(".") || exportedName.startsWith("global::"))
551
+ return exportedName;
552
+ const normalizedFrom = from.trim();
553
+ if (!normalizedFrom)
554
+ return exportedName;
555
+ const parts = normalizedFrom.split(".").filter(Boolean);
556
+ const tail = parts[parts.length - 1];
557
+ if (!tail)
558
+ return exportedName;
559
+ if (normalizeCsharpIdentifier(tail) === normalizeCsharpIdentifier(exportedName))
560
+ return normalizedFrom;
561
+ return `${normalizedFrom}.${exportedName}`;
562
+ }
563
+ /**
564
+ * The name a C# binding looks up. A named binding qualifies with its alias target. A `using N;`
565
+ * star binding qualifies with `N`: its resolved file is one of the files that declare `N`, and
566
+ * the qualified lookup reaches exactly the types of `N` in every declaring file, not types of
567
+ * other namespaces the bound file also declares.
568
+ */
569
+ function csharpImportLookupName(imp, exportedName) {
570
+ if (imp.kind === "named")
571
+ return csharpNamedImportLookupName(imp.from, exportedName);
572
+ if (imp.kind !== "star" || imp.staticMembersOf)
573
+ return exportedName;
574
+ if (!exportedName || exportedName.includes(".") || exportedName.startsWith("global::"))
575
+ return exportedName;
576
+ const namespaceName = imp.from.trim();
577
+ return namespaceName ? `${namespaceName}.${exportedName}` : exportedName;
578
+ }
579
+ const csharpNamespaceImportDirectoryFiles = new WeakMap();
580
+ /**
581
+ * For each C# `using N;` binding, one declaring file per directory. The file graph links each
582
+ * directive to every file that declares `N` within the importer's own project, so the set is
583
+ * kept per binding: two importers in different projects never share one. A qualified lookup from
584
+ * one file reaches the rest of its directory, so one file per directory covers every declaration
585
+ * of `N`. Built once per index.
586
+ */
587
+ function csharpNamespaceImportDirectories(index) {
588
+ const cached = csharpNamespaceImportDirectoryFiles.get(index);
589
+ if (cached)
590
+ return cached;
591
+ const edgesByImporter = new Map();
592
+ for (const edge of index.graph.edges) {
593
+ if (edge.to.type !== "file")
594
+ continue;
595
+ if (supportForFileWithoutHeaderSample(edge.to.path, index.languageExtensions)?.id !== "csharp")
596
+ continue;
597
+ const importerKey = fileIdentityKey(edge.from);
598
+ let byRaw = edgesByImporter.get(importerKey);
599
+ if (!byRaw)
600
+ edgesByImporter.set(importerKey, (byRaw = new Map()));
601
+ const raw = normalizeCsharpQualifiedName(edge.raw);
602
+ let byDirectory = byRaw.get(raw);
603
+ if (!byDirectory)
604
+ byRaw.set(raw, (byDirectory = new Map()));
605
+ const directoryKey = fileIdentityKey(path.posix.dirname(normalizePath(edge.to.path)));
606
+ if (!byDirectory.has(directoryKey))
607
+ byDirectory.set(directoryKey, edge.to.path);
608
+ }
609
+ const result = new Map();
610
+ for (const mod of index.byFile.values()) {
611
+ for (const imp of mod.imports) {
612
+ if (imp.kind !== "star" || imp.staticMembersOf || typeof imp.resolved !== "string")
613
+ continue;
614
+ if (supportForFileWithoutHeaderSample(imp.resolved, index.languageExtensions)?.id !== "csharp")
615
+ continue;
616
+ const files = new Map([
617
+ [fileIdentityKey(path.posix.dirname(normalizePath(imp.resolved))), imp.resolved],
618
+ ]);
619
+ const targets = edgesByImporter.get(fileIdentityKey(mod.file))?.get(normalizeCsharpQualifiedName(imp.from));
620
+ for (const [directoryKey, file] of targets ?? [])
621
+ if (!files.has(directoryKey))
622
+ files.set(directoryKey, file);
623
+ result.set(imp, [...files.values()]);
624
+ }
625
+ }
626
+ csharpNamespaceImportDirectoryFiles.set(index, result);
627
+ return result;
628
+ }
629
+ /**
630
+ * A name imported by C# `using N;`, looked up as `N.Name` from one declaring file per
631
+ * directory. Distinct declarations (other than parts of one partial type) are ambiguous. Only
632
+ * exported types count: local fallback would expose an `internal` type the exports omit, for
633
+ * both the bare name and the qualified `N.Name` form.
634
+ */
635
+ function resolveCsharpNamespaceImport(index, imp, boundFile, lookupName, opts) {
636
+ // A binding that is not one of the index's own (a copy) falls back to the bound file's directory.
637
+ const files = csharpNamespaceImportDirectories(index).get(imp) ?? [boundFile];
638
+ const matches = [];
639
+ let namespaceHit;
640
+ for (const file of files) {
641
+ const hit = resolveExport(index, file, lookupName, { ...opts, allowLocalFallback: false });
642
+ if (hit?.kind === "namespace")
643
+ namespaceHit ??= hit.file;
644
+ if (hit?.kind !== "resolved" || matches.some((candidate) => sameSymbolDef(index, candidate, hit.def)))
645
+ continue;
646
+ matches.push(hit.def);
647
+ }
648
+ const unique = coalesceEquivalentCsharpPartialExports(index, matches);
649
+ if (unique.length === 1)
650
+ return unique[0];
651
+ if (unique.length)
652
+ return null;
653
+ return namespaceHit ? { namespace: namespaceHit } : null;
654
+ }
655
+ /**
656
+ * A C# namespace-qualified type name (`N.Type`) used in `mod`. Qualified export lookup from the
657
+ * use file covers its own directory; a `using N;` in the file also reaches every other directory
658
+ * that declares `N`, as the unqualified name does.
659
+ */
660
+ export function resolveCsharpQualifiedName(index, mod, qualifiedName, referenceIndex) {
661
+ const direct = resolveExport(index, mod.file, qualifiedName, { referenceIndex });
662
+ if (direct)
663
+ return direct;
664
+ const separator = qualifiedName.lastIndexOf(".");
665
+ if (separator <= 0)
666
+ return null;
667
+ const namespaceName = normalizeCsharpQualifiedName(qualifiedName.slice(0, separator)).replace(/^global::/u, "");
668
+ const typeName = qualifiedName.slice(separator + 1);
669
+ for (const imp of mod.imports) {
670
+ if (imp.kind !== "star" || imp.staticMembersOf || typeof imp.resolved !== "string")
671
+ continue;
672
+ if (normalizeCsharpQualifiedName(imp.from).replace(/^global::/u, "") !== namespaceName)
673
+ continue;
674
+ const hit = resolveImported(index, imp, typeName);
675
+ if (!hit)
676
+ return null;
677
+ return "namespace" in hit ? { kind: "namespace", file: hit.namespace } : { kind: "resolved", def: hit };
678
+ }
679
+ return null;
680
+ }
681
+ export function resolveImported(index, imp, exportedName, opts) {
443
682
  const targetFile = typeof imp.resolved === "string" ? imp.resolved : undefined;
444
683
  if (!targetFile)
445
684
  return null;
446
- let preferredKind;
447
- if (imp.kind === "named") {
448
- if (imp.phpImportType === "function") {
449
- preferredKind = SymbolKind.Function;
450
- }
451
- else if (imp.phpImportType === "class") {
452
- preferredKind = SymbolKind.Class;
453
- }
454
- else if (imp.phpImportType === "const") {
455
- preferredKind = SymbolKind.Variable;
456
- }
685
+ const namespace = opts?.cNamespace ?? (imp.kind === "named" ? imp.cNamespace : undefined);
686
+ if (opts?.cNamespace && imp.kind === "named" && (imp.cNamespace ?? "ordinary") !== opts.cNamespace)
687
+ return null;
688
+ const phpRole = phpNamedImportRole(imp);
689
+ // A C# `using PT = N.Inner.Point` stores the namespace in `from` and the type in
690
+ // `imported`. A bare `Point` lookup is an implicit compilation-unit search, so a peer
691
+ // `N.Point` is the only bare-visible match when this file also declares outer `N`.
692
+ // The alias names one namespace, and that qualified name is what every consumer resolves.
693
+ const support = supportForFileWithoutHeaderSample(targetFile, index.languageExtensions);
694
+ const lookupName = support?.id === "csharp" ? csharpImportLookupName(imp, exportedName) : exportedName;
695
+ if (support?.id === "csharp" && imp.kind === "star" && !imp.staticMembersOf) {
696
+ return resolveCsharpNamespaceImport(index, imp, targetFile, lookupName, {
697
+ ...opts,
698
+ ...(namespace ? { cNamespace: namespace } : {}),
699
+ });
457
700
  }
458
- const hit = resolveExport(index, targetFile, exportedName, {
459
- ...(preferredKind ? { preferredKind } : {}),
460
- });
701
+ const hit = phpRole
702
+ ? resolvePhpExportByImportType(index, targetFile, exportedName, phpRole)
703
+ : resolveExport(index, targetFile, lookupName, {
704
+ ...opts,
705
+ ...(namespace ? { cNamespace: namespace } : {}),
706
+ });
461
707
  if (hit?.kind === "resolved")
462
708
  return hit.def;
463
709
  if (hit?.kind === "namespace")
464
710
  return { namespace: hit.file };
711
+ if (imp.kind === "default" && exportedName === "default") {
712
+ const moduleEntry = moduleFor(index, targetFile);
713
+ const directValue = moduleEntry && directModuleValueEntry(moduleEntry);
714
+ if (directValue)
715
+ return directValue.target;
716
+ }
465
717
  // Only Java, Kotlin, and Python matter below, so a `.h` target never needs its sample read.
466
- const support = supportForFileWithoutHeaderSample(targetFile, index.languageExtensions);
467
718
  if (support?.id === "java" || support?.id === "kotlin") {
468
- const siblingHit = resolveSiblingPackageExport(index, targetFile, exportedName, support.id);
719
+ const siblingHit = resolveSiblingPackageExport(index, targetFile, exportedName);
469
720
  if (siblingHit?.kind === "resolved")
470
721
  return siblingHit.def;
471
722
  if (siblingHit?.kind === "namespace") {
472
723
  return { namespace: siblingHit.file };
473
724
  }
474
725
  }
475
- if (support?.id === "python") {
476
- const submodule = resolvePythonSubmodule(targetFile, exportedName);
726
+ // A named `from pkg import child` may load child as a submodule. A plain
727
+ // namespace import of pkg cannot gain child solely because child.py exists.
728
+ if (support?.id === "python" && imp.kind === "named" && imp.mechanism === "python") {
729
+ const submodule = resolvePythonSubmoduleExact(targetFile, exportedName);
477
730
  if (submodule)
478
731
  return { namespace: submodule };
479
732
  }