@lzehrung/codegraph 3.0.1 → 3.1.1

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 (684) hide show
  1. package/README.md +17 -17
  2. package/codegraph-skill/codegraph/SKILL.md +6 -2
  3. package/dist/agent/artifact.d.ts.map +1 -1
  4. package/dist/agent/artifact.js +4 -9
  5. package/dist/agent/artifact.js.map +1 -1
  6. package/dist/agent/call-hierarchy.d.ts +4 -2
  7. package/dist/agent/call-hierarchy.d.ts.map +1 -1
  8. package/dist/agent/call-hierarchy.js +20 -29
  9. package/dist/agent/call-hierarchy.js.map +1 -1
  10. package/dist/agent/explain.d.ts.map +1 -1
  11. package/dist/agent/explain.js +24 -18
  12. package/dist/agent/explain.js.map +1 -1
  13. package/dist/agent/explore.d.ts.map +1 -1
  14. package/dist/agent/explore.js +2 -11
  15. package/dist/agent/explore.js.map +1 -1
  16. package/dist/agent/file-view.d.ts.map +1 -1
  17. package/dist/agent/file-view.js +4 -12
  18. package/dist/agent/file-view.js.map +1 -1
  19. package/dist/agent/normalize.d.ts +0 -3
  20. package/dist/agent/normalize.d.ts.map +1 -1
  21. package/dist/agent/normalize.js +1 -7
  22. package/dist/agent/normalize.js.map +1 -1
  23. package/dist/agent/orient.d.ts.map +1 -1
  24. package/dist/agent/orient.js +2 -6
  25. package/dist/agent/orient.js.map +1 -1
  26. package/dist/agent/packet.d.ts.map +1 -1
  27. package/dist/agent/packet.js +2 -5
  28. package/dist/agent/packet.js.map +1 -1
  29. package/dist/agent/query-index/content.d.ts.map +1 -1
  30. package/dist/agent/query-index/content.js +2 -6
  31. package/dist/agent/query-index/content.js.map +1 -1
  32. package/dist/agent/query-index/update.d.ts.map +1 -1
  33. package/dist/agent/query-index/update.js +8 -45
  34. package/dist/agent/query-index/update.js.map +1 -1
  35. package/dist/agent/query-index/worker-pool.d.ts.map +1 -1
  36. package/dist/agent/query-index/worker-pool.js +2 -1
  37. package/dist/agent/query-index/worker-pool.js.map +1 -1
  38. package/dist/agent/refactor-plan.d.ts +2 -2
  39. package/dist/agent/refactor-plan.d.ts.map +1 -1
  40. package/dist/agent/refactor-plan.js +11 -57
  41. package/dist/agent/refactor-plan.js.map +1 -1
  42. package/dist/agent/rename-preview.d.ts.map +1 -1
  43. package/dist/agent/rename-preview.js +166 -23
  44. package/dist/agent/rename-preview.js.map +1 -1
  45. package/dist/agent/search.d.ts +13 -0
  46. package/dist/agent/search.d.ts.map +1 -1
  47. package/dist/agent/search.js +17 -26
  48. package/dist/agent/search.js.map +1 -1
  49. package/dist/agent/semantic-symbols.d.ts +1 -1
  50. package/dist/agent/semantic-symbols.d.ts.map +1 -1
  51. package/dist/agent/semantic-symbols.js +2 -5
  52. package/dist/agent/semantic-symbols.js.map +1 -1
  53. package/dist/agent/semantic.d.ts +5 -0
  54. package/dist/agent/semantic.d.ts.map +1 -1
  55. package/dist/agent/semantic.js +12 -1
  56. package/dist/agent/semantic.js.map +1 -1
  57. package/dist/agent/session.d.ts +9 -0
  58. package/dist/agent/session.d.ts.map +1 -1
  59. package/dist/agent/session.js +59 -41
  60. package/dist/agent/session.js.map +1 -1
  61. package/dist/agent/type-hierarchy.d.ts +4 -2
  62. package/dist/agent/type-hierarchy.d.ts.map +1 -1
  63. package/dist/agent/type-hierarchy.js +19 -31
  64. package/dist/agent/type-hierarchy.js.map +1 -1
  65. package/dist/agent/workspace-symbols.d.ts +1 -1
  66. package/dist/agent/workspace-symbols.d.ts.map +1 -1
  67. package/dist/agent/workspace-symbols.js +7 -15
  68. package/dist/agent/workspace-symbols.js.map +1 -1
  69. package/dist/analysis-summary.d.ts +1 -4
  70. package/dist/analysis-summary.d.ts.map +1 -1
  71. package/dist/analysis-summary.js +58 -19
  72. package/dist/analysis-summary.js.map +1 -1
  73. package/dist/bin/cli.js +41060 -27641
  74. package/dist/bin/query-index-worker.js +268 -241
  75. package/dist/bootstrap/tree-sitter-languages.d.ts +2 -0
  76. package/dist/bootstrap/tree-sitter-languages.d.ts.map +1 -1
  77. package/dist/bootstrap/tree-sitter-languages.js +6 -19
  78. package/dist/bootstrap/tree-sitter-languages.js.map +1 -1
  79. package/dist/chunking/chunk-matches.d.ts.map +1 -1
  80. package/dist/chunking/chunk-matches.js +6 -42
  81. package/dist/chunking/chunk-matches.js.map +1 -1
  82. package/dist/chunking/chunk-split.d.ts +7 -0
  83. package/dist/chunking/chunk-split.d.ts.map +1 -1
  84. package/dist/chunking/chunk-split.js +3 -3
  85. package/dist/chunking/chunk-split.js.map +1 -1
  86. package/dist/chunking/chunk-text-file.js +2 -30
  87. package/dist/chunking/chunk-text-file.js.map +1 -1
  88. package/dist/cli/affected.d.ts.map +1 -1
  89. package/dist/cli/affected.js +1 -9
  90. package/dist/cli/affected.js.map +1 -1
  91. package/dist/cli/call-hierarchy.js +3 -6
  92. package/dist/cli/call-hierarchy.js.map +1 -1
  93. package/dist/cli/chunk.d.ts.map +1 -1
  94. package/dist/cli/chunk.js +4 -11
  95. package/dist/cli/chunk.js.map +1 -1
  96. package/dist/cli/command-table.d.ts.map +1 -1
  97. package/dist/cli/command-table.js +7 -0
  98. package/dist/cli/command-table.js.map +1 -1
  99. package/dist/cli/context.d.ts +1 -0
  100. package/dist/cli/context.d.ts.map +1 -1
  101. package/dist/cli/context.js +1 -1
  102. package/dist/cli/context.js.map +1 -1
  103. package/dist/cli/doctor.d.ts.map +1 -1
  104. package/dist/cli/doctor.js +1 -11
  105. package/dist/cli/doctor.js.map +1 -1
  106. package/dist/cli/duplicates.d.ts +5 -0
  107. package/dist/cli/duplicates.d.ts.map +1 -1
  108. package/dist/cli/duplicates.js +15 -2
  109. package/dist/cli/duplicates.js.map +1 -1
  110. package/dist/cli/graph.d.ts +4 -12
  111. package/dist/cli/graph.d.ts.map +1 -1
  112. package/dist/cli/graph.js +17 -8
  113. package/dist/cli/graph.js.map +1 -1
  114. package/dist/cli/help.d.ts +4 -4
  115. package/dist/cli/help.d.ts.map +1 -1
  116. package/dist/cli/help.js +17 -9
  117. package/dist/cli/help.js.map +1 -1
  118. package/dist/cli/index.d.ts +2 -12
  119. package/dist/cli/index.d.ts.map +1 -1
  120. package/dist/cli/index.js +2 -5
  121. package/dist/cli/index.js.map +1 -1
  122. package/dist/cli/links.d.ts.map +1 -1
  123. package/dist/cli/links.js +4 -10
  124. package/dist/cli/links.js.map +1 -1
  125. package/dist/cli/mcp.d.ts.map +1 -1
  126. package/dist/cli/mcp.js +5 -0
  127. package/dist/cli/mcp.js.map +1 -1
  128. package/dist/cli/module-locals.d.ts +8 -0
  129. package/dist/cli/module-locals.d.ts.map +1 -0
  130. package/dist/cli/module-locals.js +9 -0
  131. package/dist/cli/module-locals.js.map +1 -0
  132. package/dist/cli/navigation.d.ts +2 -0
  133. package/dist/cli/navigation.d.ts.map +1 -1
  134. package/dist/cli/navigation.js +3 -5
  135. package/dist/cli/navigation.js.map +1 -1
  136. package/dist/cli/options.d.ts.map +1 -1
  137. package/dist/cli/options.js +6 -1
  138. package/dist/cli/options.js.map +1 -1
  139. package/dist/cli/pretty.d.ts +1 -0
  140. package/dist/cli/pretty.d.ts.map +1 -1
  141. package/dist/cli/pretty.js +6 -8
  142. package/dist/cli/pretty.js.map +1 -1
  143. package/dist/cli/progress.d.ts.map +1 -1
  144. package/dist/cli/progress.js +42 -16
  145. package/dist/cli/progress.js.map +1 -1
  146. package/dist/cli/refactor-plan.js +2 -5
  147. package/dist/cli/refactor-plan.js.map +1 -1
  148. package/dist/cli/rename-preview.js +2 -5
  149. package/dist/cli/rename-preview.js.map +1 -1
  150. package/dist/cli/review.d.ts +6 -16
  151. package/dist/cli/review.d.ts.map +1 -1
  152. package/dist/cli/review.js +2 -0
  153. package/dist/cli/review.js.map +1 -1
  154. package/dist/cli/server.d.ts.map +1 -1
  155. package/dist/cli/server.js +9 -10
  156. package/dist/cli/server.js.map +1 -1
  157. package/dist/cli/type-hierarchy.js +8 -8
  158. package/dist/cli/type-hierarchy.js.map +1 -1
  159. package/dist/cli/viewer.js +1 -1
  160. package/dist/cli/viewer.js.map +1 -1
  161. package/dist/document-links/asciidoc.d.ts.map +1 -1
  162. package/dist/document-links/asciidoc.js +4 -16
  163. package/dist/document-links/asciidoc.js.map +1 -1
  164. package/dist/document-links/check.d.ts.map +1 -1
  165. package/dist/document-links/check.js +1 -3
  166. package/dist/document-links/check.js.map +1 -1
  167. package/dist/document-links/html.d.ts.map +1 -1
  168. package/dist/document-links/html.js +6 -44
  169. package/dist/document-links/html.js.map +1 -1
  170. package/dist/document-links/markdown.d.ts.map +1 -1
  171. package/dist/document-links/markdown.js +4 -13
  172. package/dist/document-links/markdown.js.map +1 -1
  173. package/dist/document-links/rst.d.ts.map +1 -1
  174. package/dist/document-links/rst.js +7 -31
  175. package/dist/document-links/rst.js.map +1 -1
  176. package/dist/document-links/sfc.d.ts.map +1 -1
  177. package/dist/document-links/sfc.js +2 -5
  178. package/dist/document-links/sfc.js.map +1 -1
  179. package/dist/document-links/shared.d.ts +2 -0
  180. package/dist/document-links/shared.d.ts.map +1 -1
  181. package/dist/document-links/shared.js +13 -0
  182. package/dist/document-links/shared.js.map +1 -1
  183. package/dist/drift/artifact.d.ts.map +1 -1
  184. package/dist/drift/artifact.js +4 -27
  185. package/dist/drift/artifact.js.map +1 -1
  186. package/dist/drift/git.d.ts.map +1 -1
  187. package/dist/drift/git.js +10 -2
  188. package/dist/drift/git.js.map +1 -1
  189. package/dist/drift/graph-edges.d.ts +4 -0
  190. package/dist/drift/graph-edges.d.ts.map +1 -0
  191. package/dist/drift/graph-edges.js +15 -0
  192. package/dist/drift/graph-edges.js.map +1 -0
  193. package/dist/drift/snapshot.d.ts.map +1 -1
  194. package/dist/drift/snapshot.js +2 -17
  195. package/dist/drift/snapshot.js.map +1 -1
  196. package/dist/duplicates/candidates.d.ts +61 -0
  197. package/dist/duplicates/candidates.d.ts.map +1 -0
  198. package/dist/duplicates/candidates.js +873 -0
  199. package/dist/duplicates/candidates.js.map +1 -0
  200. package/dist/duplicates/progress.d.ts +17 -0
  201. package/dist/duplicates/progress.d.ts.map +1 -0
  202. package/dist/duplicates/progress.js +57 -0
  203. package/dist/duplicates/progress.js.map +1 -0
  204. package/dist/duplicates/scoring.d.ts +9 -40
  205. package/dist/duplicates/scoring.d.ts.map +1 -1
  206. package/dist/duplicates/scoring.js +34 -414
  207. package/dist/duplicates/scoring.js.map +1 -1
  208. package/dist/duplicates/types.d.ts +30 -1
  209. package/dist/duplicates/types.d.ts.map +1 -1
  210. package/dist/duplicates/unit-cache.d.ts +11 -1
  211. package/dist/duplicates/unit-cache.d.ts.map +1 -1
  212. package/dist/duplicates/unit-cache.js +20 -2
  213. package/dist/duplicates/unit-cache.js.map +1 -1
  214. package/dist/duplicates/units.d.ts +4 -2
  215. package/dist/duplicates/units.d.ts.map +1 -1
  216. package/dist/duplicates/units.js +47 -25
  217. package/dist/duplicates/units.js.map +1 -1
  218. package/dist/duplicates.d.ts +1 -0
  219. package/dist/duplicates.d.ts.map +1 -1
  220. package/dist/duplicates.js +116 -62
  221. package/dist/duplicates.js.map +1 -1
  222. package/dist/graph-builder.d.ts +1 -1
  223. package/dist/graph-builder.d.ts.map +1 -1
  224. package/dist/graph-builder.js +3 -2
  225. package/dist/graph-builder.js.map +1 -1
  226. package/dist/graph-edge-collector.d.ts +3 -1
  227. package/dist/graph-edge-collector.d.ts.map +1 -1
  228. package/dist/graph-edge-collector.js +38 -6
  229. package/dist/graph-edge-collector.js.map +1 -1
  230. package/dist/graphs/angularjs.d.ts.map +1 -1
  231. package/dist/graphs/angularjs.js +2 -9
  232. package/dist/graphs/angularjs.js.map +1 -1
  233. package/dist/graphs/edge-resolution.d.ts +4 -0
  234. package/dist/graphs/edge-resolution.d.ts.map +1 -1
  235. package/dist/graphs/edge-resolution.js +2 -0
  236. package/dist/graphs/edge-resolution.js.map +1 -1
  237. package/dist/graphs/external/manifests.d.ts.map +1 -1
  238. package/dist/graphs/external/manifests.js +1 -6
  239. package/dist/graphs/external/manifests.js.map +1 -1
  240. package/dist/graphs/specifiers.d.ts.map +1 -1
  241. package/dist/graphs/specifiers.js +47 -26
  242. package/dist/graphs/specifiers.js.map +1 -1
  243. package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts +2 -0
  244. package/dist/graphs/symbol-graph-detailed/edge-passes.d.ts.map +1 -1
  245. package/dist/graphs/symbol-graph-detailed/edge-passes.js +9 -3
  246. package/dist/graphs/symbol-graph-detailed/edge-passes.js.map +1 -1
  247. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts +3 -3
  248. package/dist/graphs/symbol-graph-detailed/receiver-calls.d.ts.map +1 -1
  249. package/dist/graphs/symbol-graph-detailed/receiver-calls.js +2 -26
  250. package/dist/graphs/symbol-graph-detailed/receiver-calls.js.map +1 -1
  251. package/dist/graphs/symbol-graph-detailed.d.ts.map +1 -1
  252. package/dist/graphs/symbol-graph-detailed.js +38 -1
  253. package/dist/graphs/symbol-graph-detailed.js.map +1 -1
  254. package/dist/impact/analyzer.d.ts.map +1 -1
  255. package/dist/impact/analyzer.js +23 -17
  256. package/dist/impact/analyzer.js.map +1 -1
  257. package/dist/impact/budgets.d.ts.map +1 -1
  258. package/dist/impact/budgets.js +3 -9
  259. package/dist/impact/budgets.js.map +1 -1
  260. package/dist/impact/call-compatibility.d.ts.map +1 -1
  261. package/dist/impact/call-compatibility.js +3 -12
  262. package/dist/impact/call-compatibility.js.map +1 -1
  263. package/dist/impact/context.d.ts +6 -0
  264. package/dist/impact/context.d.ts.map +1 -1
  265. package/dist/impact/context.js +2 -2
  266. package/dist/impact/context.js.map +1 -1
  267. package/dist/impact/direct.d.ts.map +1 -1
  268. package/dist/impact/direct.js +2 -6
  269. package/dist/impact/direct.js.map +1 -1
  270. package/dist/impact/map.d.ts +3 -1
  271. package/dist/impact/map.d.ts.map +1 -1
  272. package/dist/impact/map.js +12 -5
  273. package/dist/impact/map.js.map +1 -1
  274. package/dist/impact/providers/base.js +1 -1
  275. package/dist/impact/providers/base.js.map +1 -1
  276. package/dist/impact/reference-cache.d.ts.map +1 -1
  277. package/dist/impact/reference-cache.js +1 -24
  278. package/dist/impact/reference-cache.js.map +1 -1
  279. package/dist/impact/report-shared.d.ts +2 -1
  280. package/dist/impact/report-shared.d.ts.map +1 -1
  281. package/dist/impact/report-shared.js +10 -0
  282. package/dist/impact/report-shared.js.map +1 -1
  283. package/dist/impact/report-suggestions.d.ts.map +1 -1
  284. package/dist/impact/report-suggestions.js +2 -8
  285. package/dist/impact/report-suggestions.js.map +1 -1
  286. package/dist/impact/report.d.ts.map +1 -1
  287. package/dist/impact/report.js +2 -8
  288. package/dist/impact/report.js.map +1 -1
  289. package/dist/impact/streaming.d.ts.map +1 -1
  290. package/dist/impact/streaming.js +3 -8
  291. package/dist/impact/streaming.js.map +1 -1
  292. package/dist/indexer/build-cache/manifest.d.ts.map +1 -1
  293. package/dist/indexer/build-cache/manifest.js +10 -108
  294. package/dist/indexer/build-cache/manifest.js.map +1 -1
  295. package/dist/indexer/build-cache/module-cache.d.ts +6 -1
  296. package/dist/indexer/build-cache/module-cache.d.ts.map +1 -1
  297. package/dist/indexer/build-cache/module-cache.js +25 -2
  298. package/dist/indexer/build-cache/module-cache.js.map +1 -1
  299. package/dist/indexer/build-cache/options.d.ts +38 -1
  300. package/dist/indexer/build-cache/options.d.ts.map +1 -1
  301. package/dist/indexer/build-cache/options.js +38 -1
  302. package/dist/indexer/build-cache/options.js.map +1 -1
  303. package/dist/indexer/build-cache/project-snapshot.d.ts.map +1 -1
  304. package/dist/indexer/build-cache/project-snapshot.js +48 -99
  305. package/dist/indexer/build-cache/project-snapshot.js.map +1 -1
  306. package/dist/indexer/build-cache/reports.d.ts +1 -0
  307. package/dist/indexer/build-cache/reports.d.ts.map +1 -1
  308. package/dist/indexer/build-cache/reports.js +10 -0
  309. package/dist/indexer/build-cache/reports.js.map +1 -1
  310. package/dist/indexer/build-index.d.ts +2 -0
  311. package/dist/indexer/build-index.d.ts.map +1 -1
  312. package/dist/indexer/build-index.js +187 -57
  313. package/dist/indexer/build-index.js.map +1 -1
  314. package/dist/indexer/build-workers.d.ts +7 -1
  315. package/dist/indexer/build-workers.d.ts.map +1 -1
  316. package/dist/indexer/build-workers.js +12 -0
  317. package/dist/indexer/build-workers.js.map +1 -1
  318. package/dist/indexer/call-hierarchy.d.ts.map +1 -1
  319. package/dist/indexer/call-hierarchy.js +5 -17
  320. package/dist/indexer/call-hierarchy.js.map +1 -1
  321. package/dist/indexer/compilation-units.d.ts +32 -20
  322. package/dist/indexer/compilation-units.d.ts.map +1 -1
  323. package/dist/indexer/compilation-units.js +139 -145
  324. package/dist/indexer/compilation-units.js.map +1 -1
  325. package/dist/indexer/cpp-callables.d.ts.map +1 -1
  326. package/dist/indexer/cpp-callables.js +2 -7
  327. package/dist/indexer/cpp-callables.js.map +1 -1
  328. package/dist/indexer/import-types.d.ts +5 -0
  329. package/dist/indexer/import-types.d.ts.map +1 -1
  330. package/dist/indexer/import-types.js.map +1 -1
  331. package/dist/indexer/imports/binding-ranges.d.ts +5 -12
  332. package/dist/indexer/imports/binding-ranges.d.ts.map +1 -1
  333. package/dist/indexer/imports/binding-ranges.js +13 -19
  334. package/dist/indexer/imports/binding-ranges.js.map +1 -1
  335. package/dist/indexer/imports/context.d.ts +6 -0
  336. package/dist/indexer/imports/context.d.ts.map +1 -1
  337. package/dist/indexer/imports/import-binding-tables.d.ts +28 -13
  338. package/dist/indexer/imports/import-binding-tables.d.ts.map +1 -1
  339. package/dist/indexer/imports/import-binding-tables.js +179 -178
  340. package/dist/indexer/imports/import-binding-tables.js.map +1 -1
  341. package/dist/indexer/imports/js-text-imports.d.ts +0 -1
  342. package/dist/indexer/imports/js-text-imports.d.ts.map +1 -1
  343. package/dist/indexer/imports/js-text-imports.js +0 -176
  344. package/dist/indexer/imports/js-text-imports.js.map +1 -1
  345. package/dist/indexer/imports/language-specific.d.ts.map +1 -1
  346. package/dist/indexer/imports/language-specific.js +4 -8
  347. package/dist/indexer/imports/language-specific.js.map +1 -1
  348. package/dist/indexer/imports/python.d.ts +0 -1
  349. package/dist/indexer/imports/python.d.ts.map +1 -1
  350. package/dist/indexer/imports/python.js +1 -29
  351. package/dist/indexer/imports/python.js.map +1 -1
  352. package/dist/indexer/imports/text-import-extractors.d.ts +2 -9
  353. package/dist/indexer/imports/text-import-extractors.d.ts.map +1 -1
  354. package/dist/indexer/imports/text-import-extractors.js +0 -284
  355. package/dist/indexer/imports/text-import-extractors.js.map +1 -1
  356. package/dist/indexer/imports.d.ts +15 -0
  357. package/dist/indexer/imports.d.ts.map +1 -1
  358. package/dist/indexer/imports.js +82 -44
  359. package/dist/indexer/imports.js.map +1 -1
  360. package/dist/indexer/incremental-plan.d.ts +0 -1
  361. package/dist/indexer/incremental-plan.d.ts.map +1 -1
  362. package/dist/indexer/incremental-plan.js +6 -12
  363. package/dist/indexer/incremental-plan.js.map +1 -1
  364. package/dist/indexer/name-lookup-policies/implicit-self.d.ts.map +1 -1
  365. package/dist/indexer/name-lookup-policies/implicit-self.js +25 -4
  366. package/dist/indexer/name-lookup-policies/implicit-self.js.map +1 -1
  367. package/dist/indexer/name-resolution-types.d.ts +5 -0
  368. package/dist/indexer/name-resolution-types.d.ts.map +1 -1
  369. package/dist/indexer/name-resolution.d.ts.map +1 -1
  370. package/dist/indexer/name-resolution.js +2 -0
  371. package/dist/indexer/name-resolution.js.map +1 -1
  372. package/dist/indexer/navigation-cpp.d.ts.map +1 -1
  373. package/dist/indexer/navigation-cpp.js +3 -5
  374. package/dist/indexer/navigation-cpp.js.map +1 -1
  375. package/dist/indexer/navigation-goto.d.ts +49 -3
  376. package/dist/indexer/navigation-goto.d.ts.map +1 -1
  377. package/dist/indexer/navigation-goto.js +500 -106
  378. package/dist/indexer/navigation-goto.js.map +1 -1
  379. package/dist/indexer/navigation-local.d.ts +7 -0
  380. package/dist/indexer/navigation-local.d.ts.map +1 -1
  381. package/dist/indexer/navigation-local.js +22 -2
  382. package/dist/indexer/navigation-local.js.map +1 -1
  383. package/dist/indexer/navigation-php.d.ts +0 -1
  384. package/dist/indexer/navigation-php.d.ts.map +1 -1
  385. package/dist/indexer/navigation-php.js +1 -7
  386. package/dist/indexer/navigation-php.js.map +1 -1
  387. package/dist/indexer/navigation-references.d.ts +1 -0
  388. package/dist/indexer/navigation-references.d.ts.map +1 -1
  389. package/dist/indexer/navigation-references.js +134 -23
  390. package/dist/indexer/navigation-references.js.map +1 -1
  391. package/dist/indexer/navigation-resolve.d.ts +22 -0
  392. package/dist/indexer/navigation-resolve.d.ts.map +1 -1
  393. package/dist/indexer/navigation-resolve.js +73 -8
  394. package/dist/indexer/navigation-resolve.js.map +1 -1
  395. package/dist/indexer/navigation.d.ts +4 -1
  396. package/dist/indexer/navigation.d.ts.map +1 -1
  397. package/dist/indexer/navigation.js +398 -95
  398. package/dist/indexer/navigation.js.map +1 -1
  399. package/dist/indexer/python-property-decorator.d.ts +11 -0
  400. package/dist/indexer/python-property-decorator.d.ts.map +1 -0
  401. package/dist/indexer/python-property-decorator.js +30 -0
  402. package/dist/indexer/python-property-decorator.js.map +1 -0
  403. package/dist/indexer/shared-owner-identity.d.ts +3 -1
  404. package/dist/indexer/shared-owner-identity.d.ts.map +1 -1
  405. package/dist/indexer/shared-owner-identity.js +40 -12
  406. package/dist/indexer/shared-owner-identity.js.map +1 -1
  407. package/dist/indexer/shared.d.ts +10 -0
  408. package/dist/indexer/shared.d.ts.map +1 -1
  409. package/dist/indexer/shared.js +8 -0
  410. package/dist/indexer/shared.js.map +1 -1
  411. package/dist/indexer/star-import-precedence.d.ts +5 -1
  412. package/dist/indexer/star-import-precedence.d.ts.map +1 -1
  413. package/dist/indexer/star-import-precedence.js +12 -19
  414. package/dist/indexer/star-import-precedence.js.map +1 -1
  415. package/dist/indexer/type-hierarchy.d.ts.map +1 -1
  416. package/dist/indexer/type-hierarchy.js +8 -9
  417. package/dist/indexer/type-hierarchy.js.map +1 -1
  418. package/dist/indexer/types.d.ts +49 -1
  419. package/dist/indexer/types.d.ts.map +1 -1
  420. package/dist/indexer/types.js.map +1 -1
  421. package/dist/indexer/workspace-symbols.d.ts.map +1 -1
  422. package/dist/indexer/workspace-symbols.js +3 -13
  423. package/dist/indexer/workspace-symbols.js.map +1 -1
  424. package/dist/installer/locks.d.ts +1 -0
  425. package/dist/installer/locks.d.ts.map +1 -1
  426. package/dist/installer/locks.js +4 -8
  427. package/dist/installer/locks.js.map +1 -1
  428. package/dist/installer/registry.d.ts.map +1 -1
  429. package/dist/installer/registry.js +9 -15
  430. package/dist/installer/registry.js.map +1 -1
  431. package/dist/languages/callable-arity.d.ts.map +1 -1
  432. package/dist/languages/callable-arity.js +1 -38
  433. package/dist/languages/callable-arity.js.map +1 -1
  434. package/dist/languages/definitions/csharp.d.ts.map +1 -1
  435. package/dist/languages/definitions/csharp.js +5 -13
  436. package/dist/languages/definitions/csharp.js.map +1 -1
  437. package/dist/languages/definitions/java.d.ts.map +1 -1
  438. package/dist/languages/definitions/java.js +4 -13
  439. package/dist/languages/definitions/java.js.map +1 -1
  440. package/dist/languages/definitions/kotlin.d.ts.map +1 -1
  441. package/dist/languages/definitions/kotlin.js +4 -8
  442. package/dist/languages/definitions/kotlin.js.map +1 -1
  443. package/dist/languages/definitions/python.d.ts.map +1 -1
  444. package/dist/languages/definitions/python.js +5 -3
  445. package/dist/languages/definitions/python.js.map +1 -1
  446. package/dist/languages/import-statement-parsers.d.ts +0 -30
  447. package/dist/languages/import-statement-parsers.d.ts.map +1 -1
  448. package/dist/languages/import-statement-parsers.js +1 -81
  449. package/dist/languages/import-statement-parsers.js.map +1 -1
  450. package/dist/languages/sfc.d.ts.map +1 -1
  451. package/dist/languages/sfc.js +8 -43
  452. package/dist/languages/sfc.js.map +1 -1
  453. package/dist/lifecycle/manifest.d.ts.map +1 -1
  454. package/dist/lifecycle/manifest.js +11 -29
  455. package/dist/lifecycle/manifest.js.map +1 -1
  456. package/dist/mcp/cancellation.d.ts +6 -0
  457. package/dist/mcp/cancellation.d.ts.map +1 -0
  458. package/dist/mcp/cancellation.js +11 -0
  459. package/dist/mcp/cancellation.js.map +1 -0
  460. package/dist/mcp/handlers.d.ts +54 -3
  461. package/dist/mcp/handlers.d.ts.map +1 -1
  462. package/dist/mcp/handlers.js +186 -42
  463. package/dist/mcp/handlers.js.map +1 -1
  464. package/dist/mcp/http-transport.d.ts.map +1 -1
  465. package/dist/mcp/http-transport.js +9 -2
  466. package/dist/mcp/http-transport.js.map +1 -1
  467. package/dist/mcp/index-readiness.d.ts +114 -0
  468. package/dist/mcp/index-readiness.d.ts.map +1 -0
  469. package/dist/mcp/index-readiness.js +264 -0
  470. package/dist/mcp/index-readiness.js.map +1 -0
  471. package/dist/mcp/project-watcher.d.ts +125 -0
  472. package/dist/mcp/project-watcher.d.ts.map +1 -0
  473. package/dist/mcp/project-watcher.js +643 -0
  474. package/dist/mcp/project-watcher.js.map +1 -0
  475. package/dist/mcp/protocol.d.ts.map +1 -1
  476. package/dist/mcp/protocol.js +23 -10
  477. package/dist/mcp/protocol.js.map +1 -1
  478. package/dist/mcp/server.d.ts +2 -0
  479. package/dist/mcp/server.d.ts.map +1 -1
  480. package/dist/mcp/server.js +11 -2
  481. package/dist/mcp/server.js.map +1 -1
  482. package/dist/mcp/stale-install.d.ts +13 -0
  483. package/dist/mcp/stale-install.d.ts.map +1 -0
  484. package/dist/mcp/stale-install.js +30 -0
  485. package/dist/mcp/stale-install.js.map +1 -0
  486. package/dist/native/byte-index.d.ts +1 -0
  487. package/dist/native/byte-index.d.ts.map +1 -1
  488. package/dist/native/byte-index.js +1 -1
  489. package/dist/native/byte-index.js.map +1 -1
  490. package/dist/native/contracts.d.ts +1 -0
  491. package/dist/native/contracts.d.ts.map +1 -1
  492. package/dist/native/native-backend-report.d.ts +2 -1
  493. package/dist/native/native-backend-report.d.ts.map +1 -1
  494. package/dist/native/native-backend-report.js +23 -0
  495. package/dist/native/native-backend-report.js.map +1 -1
  496. package/dist/native/tree-shape.d.ts +5 -7
  497. package/dist/native/tree-shape.d.ts.map +1 -1
  498. package/dist/native/tree-shape.js +11 -10
  499. package/dist/native/tree-shape.js.map +1 -1
  500. package/dist/presentation/bounds.d.ts +2 -0
  501. package/dist/presentation/bounds.d.ts.map +1 -1
  502. package/dist/presentation/bounds.js +8 -0
  503. package/dist/presentation/bounds.js.map +1 -1
  504. package/dist/review/candidates.d.ts.map +1 -1
  505. package/dist/review/candidates.js +4 -25
  506. package/dist/review/candidates.js.map +1 -1
  507. package/dist/review/deleted.js +1 -1
  508. package/dist/review/deleted.js.map +1 -1
  509. package/dist/review/report.d.ts.map +1 -1
  510. package/dist/review/report.js +4 -2
  511. package/dist/review/report.js.map +1 -1
  512. package/dist/review/summaries.d.ts.map +1 -1
  513. package/dist/review/summaries.js +14 -35
  514. package/dist/review/summaries.js.map +1 -1
  515. package/dist/review.d.ts +6 -0
  516. package/dist/review.d.ts.map +1 -1
  517. package/dist/review.js +5 -6
  518. package/dist/review.js.map +1 -1
  519. package/dist/scss/navigation.d.ts +13 -0
  520. package/dist/scss/navigation.d.ts.map +1 -0
  521. package/dist/scss/navigation.js +150 -0
  522. package/dist/scss/navigation.js.map +1 -0
  523. package/dist/scss/resolution.d.ts +190 -0
  524. package/dist/scss/resolution.d.ts.map +1 -0
  525. package/dist/scss/resolution.js +1802 -0
  526. package/dist/scss/resolution.js.map +1 -0
  527. package/dist/scss/syntax.d.ts +181 -0
  528. package/dist/scss/syntax.d.ts.map +1 -0
  529. package/dist/scss/syntax.js +1436 -0
  530. package/dist/scss/syntax.js.map +1 -0
  531. package/dist/sql/classify-sql-file.d.ts +7 -0
  532. package/dist/sql/classify-sql-file.d.ts.map +1 -1
  533. package/dist/sql/classify-sql-file.js +9 -0
  534. package/dist/sql/classify-sql-file.js.map +1 -1
  535. package/dist/sql/extract-facts.d.ts.map +1 -1
  536. package/dist/sql/extract-facts.js +517 -77
  537. package/dist/sql/extract-facts.js.map +1 -1
  538. package/dist/sql/lex.d.ts +100 -1
  539. package/dist/sql/lex.d.ts.map +1 -1
  540. package/dist/sql/lex.js +473 -11
  541. package/dist/sql/lex.js.map +1 -1
  542. package/dist/sql/lookup.d.ts +17 -0
  543. package/dist/sql/lookup.d.ts.map +1 -1
  544. package/dist/sql/lookup.js +21 -0
  545. package/dist/sql/lookup.js.map +1 -1
  546. package/dist/sql/navigation.d.ts +28 -1
  547. package/dist/sql/navigation.d.ts.map +1 -1
  548. package/dist/sql/navigation.js +474 -84
  549. package/dist/sql/navigation.js.map +1 -1
  550. package/dist/sql/object-mentions.d.ts +24 -0
  551. package/dist/sql/object-mentions.d.ts.map +1 -0
  552. package/dist/sql/object-mentions.js +233 -0
  553. package/dist/sql/object-mentions.js.map +1 -0
  554. package/dist/sql/review.d.ts +3 -0
  555. package/dist/sql/review.d.ts.map +1 -1
  556. package/dist/sql/review.js +15 -14
  557. package/dist/sql/review.js.map +1 -1
  558. package/dist/sql/routine-mentions.d.ts +61 -0
  559. package/dist/sql/routine-mentions.d.ts.map +1 -0
  560. package/dist/sql/routine-mentions.js +868 -0
  561. package/dist/sql/routine-mentions.js.map +1 -0
  562. package/dist/sql/source-graph.d.ts +18 -3
  563. package/dist/sql/source-graph.d.ts.map +1 -1
  564. package/dist/sql/source-graph.js +109 -32
  565. package/dist/sql/source-graph.js.map +1 -1
  566. package/dist/sqlite/raw-query-worker-pool.d.ts.map +1 -1
  567. package/dist/sqlite/raw-query-worker-pool.js +2 -0
  568. package/dist/sqlite/raw-query-worker-pool.js.map +1 -1
  569. package/dist/sqlite/types.d.ts +6 -5
  570. package/dist/sqlite/types.d.ts.map +1 -1
  571. package/dist/sqlite/write.d.ts.map +1 -1
  572. package/dist/sqlite/write.js.map +1 -1
  573. package/dist/sqlite-driver.d.ts +0 -1
  574. package/dist/sqlite-driver.d.ts.map +1 -1
  575. package/dist/sqlite-driver.js +0 -11
  576. package/dist/sqlite-driver.js.map +1 -1
  577. package/dist/terraform/navigation.d.ts.map +1 -1
  578. package/dist/terraform/navigation.js +1 -3
  579. package/dist/terraform/navigation.js.map +1 -1
  580. package/dist/terraform/syntax.d.ts.map +1 -1
  581. package/dist/terraform/syntax.js +1 -4
  582. package/dist/terraform/syntax.js.map +1 -1
  583. package/dist/types.d.ts +2 -0
  584. package/dist/types.d.ts.map +1 -1
  585. package/dist/util/ast.d.ts +5 -0
  586. package/dist/util/ast.d.ts.map +1 -1
  587. package/dist/util/ast.js +10 -0
  588. package/dist/util/ast.js.map +1 -1
  589. package/dist/util/atomic-file.d.ts +22 -0
  590. package/dist/util/atomic-file.d.ts.map +1 -0
  591. package/dist/util/atomic-file.js +106 -0
  592. package/dist/util/atomic-file.js.map +1 -0
  593. package/dist/util/collections.d.ts +5 -0
  594. package/dist/util/collections.d.ts.map +1 -1
  595. package/dist/util/collections.js +26 -0
  596. package/dist/util/collections.js.map +1 -1
  597. package/dist/util/concurrency.d.ts +8 -0
  598. package/dist/util/concurrency.d.ts.map +1 -1
  599. package/dist/util/concurrency.js +16 -0
  600. package/dist/util/concurrency.js.map +1 -1
  601. package/dist/util/confined-file.d.ts.map +1 -1
  602. package/dist/util/confined-file.js +1 -3
  603. package/dist/util/confined-file.js.map +1 -1
  604. package/dist/util/csharp-tree.d.ts +65 -0
  605. package/dist/util/csharp-tree.d.ts.map +1 -0
  606. package/dist/util/csharp-tree.js +266 -0
  607. package/dist/util/csharp-tree.js.map +1 -0
  608. package/dist/util/errors.d.ts +1 -0
  609. package/dist/util/errors.d.ts.map +1 -1
  610. package/dist/util/errors.js +3 -0
  611. package/dist/util/errors.js.map +1 -1
  612. package/dist/util/graph-edges.d.ts +2 -0
  613. package/dist/util/graph-edges.d.ts.map +1 -1
  614. package/dist/util/graph-edges.js +11 -0
  615. package/dist/util/graph-edges.js.map +1 -1
  616. package/dist/util/guards.d.ts +1 -0
  617. package/dist/util/guards.d.ts.map +1 -1
  618. package/dist/util/guards.js +6 -0
  619. package/dist/util/guards.js.map +1 -1
  620. package/dist/util/identifiers.d.ts +0 -24
  621. package/dist/util/identifiers.d.ts.map +1 -1
  622. package/dist/util/identifiers.js +0 -24
  623. package/dist/util/identifiers.js.map +1 -1
  624. package/dist/util/jvm-tree.d.ts +58 -0
  625. package/dist/util/jvm-tree.d.ts.map +1 -0
  626. package/dist/util/jvm-tree.js +153 -0
  627. package/dist/util/jvm-tree.js.map +1 -0
  628. package/dist/util/package-exports.d.ts +0 -22
  629. package/dist/util/package-exports.d.ts.map +1 -1
  630. package/dist/util/package-exports.js +25 -5
  631. package/dist/util/package-exports.js.map +1 -1
  632. package/dist/util/paths.d.ts +1 -0
  633. package/dist/util/paths.d.ts.map +1 -1
  634. package/dist/util/paths.js +10 -4
  635. package/dist/util/paths.js.map +1 -1
  636. package/dist/util/resolution/csharp.d.ts +20 -8
  637. package/dist/util/resolution/csharp.d.ts.map +1 -1
  638. package/dist/util/resolution/csharp.js +126 -127
  639. package/dist/util/resolution/csharp.js.map +1 -1
  640. package/dist/util/resolution/files.d.ts +6 -0
  641. package/dist/util/resolution/files.d.ts.map +1 -1
  642. package/dist/util/resolution/files.js +74 -21
  643. package/dist/util/resolution/files.js.map +1 -1
  644. package/dist/util/resolution/jvm.d.ts +21 -1
  645. package/dist/util/resolution/jvm.d.ts.map +1 -1
  646. package/dist/util/resolution/jvm.js +168 -100
  647. package/dist/util/resolution/jvm.js.map +1 -1
  648. package/dist/util/resolution/project-symbols.d.ts +1 -1
  649. package/dist/util/resolution/project-symbols.d.ts.map +1 -1
  650. package/dist/util/resolution/project-symbols.js.map +1 -1
  651. package/dist/util/resolution/specifier-targets.d.ts +4 -0
  652. package/dist/util/resolution/specifier-targets.d.ts.map +1 -1
  653. package/dist/util/resolution/specifier-targets.js +11 -3
  654. package/dist/util/resolution/specifier-targets.js.map +1 -1
  655. package/dist/util/resolution.d.ts.map +1 -1
  656. package/dist/util/resolution.js +21 -7
  657. package/dist/util/resolution.js.map +1 -1
  658. package/dist/util/syntax-tree.d.ts +16 -0
  659. package/dist/util/syntax-tree.d.ts.map +1 -0
  660. package/dist/util/syntax-tree.js +34 -0
  661. package/dist/util/syntax-tree.js.map +1 -0
  662. package/dist/util/text-scanning.d.ts +6 -0
  663. package/dist/util/text-scanning.d.ts.map +1 -0
  664. package/dist/util/text-scanning.js +35 -0
  665. package/dist/util/text-scanning.js.map +1 -0
  666. package/dist/util/trivia-tables.d.ts +13 -8
  667. package/dist/util/trivia-tables.d.ts.map +1 -1
  668. package/dist/util/trivia-tables.js +13 -72
  669. package/dist/util/trivia-tables.js.map +1 -1
  670. package/dist/util/trivia.d.ts +10 -3
  671. package/dist/util/trivia.d.ts.map +1 -1
  672. package/dist/util/trivia.js +209 -79
  673. package/dist/util/trivia.js.map +1 -1
  674. package/dist/util/windows-process-drain.d.ts.map +1 -1
  675. package/dist/util/windows-process-drain.js.map +1 -1
  676. package/dist/util/worker-threads.d.ts +16 -0
  677. package/dist/util/worker-threads.d.ts.map +1 -1
  678. package/dist/util/worker-threads.js +118 -0
  679. package/dist/util/worker-threads.js.map +1 -1
  680. package/dist/worker/native-worker-pool.d.ts.map +1 -1
  681. package/dist/worker/native-worker-pool.js +2 -1
  682. package/dist/worker/native-worker-pool.js.map +1 -1
  683. package/docs/mcp.md +82 -8
  684. package/package.json +7 -7
@@ -1,16 +1,20 @@
1
1
  import { CSHARP_SUPPORT, supportForFileWithoutHeaderSample } from "../languages.js";
2
+ import { pythonPropertyDecorator } from "./python-property-decorator.js";
2
3
  import { isJsTsLanguage } from "../languages/js-family.js";
3
4
  import { isPythonReceiverAttributeAssignmentName } from "../languages/definitions/python.js";
4
5
  import { sliceText } from "../util/ast.js";
5
6
  import { foldPhpIdentifierCase } from "../util/identifiers.js";
7
+ import { csharpNamespaceAtIndex, csharpNamespaceRegionAtIndex, } from "../util/csharp-tree.js";
6
8
  import { fileIdentityKey } from "../util/paths.js";
7
9
  import { collectMemberAccessChain, getMemberAccessParts, getNavigationExpressionProperty, isMemberAccessNode, isReceiverNameNode, memberAccessTraversalTypes, } from "../util/member-access.js";
10
+ import { definitionIdentityKey } from "./reference-context.js";
11
+ import { toTreeSitterPosition } from "./shared.js";
8
12
  import { MEMBER_ACCESS_ROWS, supportsReceiverMemberNavigation } from "../util/member-access-tables.js";
9
13
  import { typescriptCallableContainerKey, typescriptMergedNamespaceContainers } from "./ts-callables.js";
10
14
  import { effectiveExplicitBinding, isExpandedStarBinding, resolveStarImportedName, resolveStarImportedNamespace, starImportPrecedence, } from "./star-import-precedence.js";
11
15
  import { classifyReceiver, cppOutOfLineOwnerPath, cppQualifiedNameSegments, declarationIsStaticEquivalent, declarationNodeIsStatic, declaredTypeNameNode, declaresMembers, hasStaticMemberDistinction, memberContainerDef, nearestMemberContainer, isUnprovenHeritageExpression, kotlinExtensionReceiverTypeNode, csharpDottedNameRoot, nodeInStaticMemberContext, importTypeQuerySpecifier, rustImplSelfTypeNode, supportsStaticMemberScope, TRANSPARENT_MEMBER_CONTAINER_TYPES, unwrapNamedType, } from "../graphs/symbol-graph-detailed/receiver-calls.js";
12
16
  import { getCallArgumentCount, memberLookupBinding } from "../languages/callable-arity.js";
13
- import { getCompilationUnitPeers, getPackageDeclarationName } from "./compilation-units.js";
17
+ import { csharpNamespaceChainDeclares, csharpProjectDeclarationsUnknown, csharpUsingTargetShadowed, getCompilationUnitPeers, getPackageDeclarationName, } from "./compilation-units.js";
14
18
  import { isExportedDeclaration, isJvmPackageSymbolVisible, isPrivateDeclaration, isGoExportedMemberName, isSwiftCrossFileHiddenSharedOwnerMember, } from "./declaration-visibility.js";
15
19
  import { ensureParsedContext } from "./parse-context.js";
16
20
  import { csharpLookupName, csharpQualifiedNameNode, findClosestScopeBinding, getOrBuildScopeIndex, resolveNamedDefinition, } from "./navigation-local.js";
@@ -18,7 +22,7 @@ import { resolveCppQualifiedMemberContainer, cppFunctionHasImplicitThis } from "
18
22
  import { okGoToResult } from "./navigation-provenance.js";
19
23
  import { comparePhpReferenceNames, findPhpImportAlias } from "./navigation-php.js";
20
24
  import { resolveIndexedPhpClassReference, resolvePhpNamespaceSymbol } from "./php-namespace-symbols.js";
21
- import { cjsRequireValueBinding, memberContainerForDefinition, resolveCsharpQualifiedName, resolveExport, resolveImported, resolvePhpExportByImportType, resolveImportTypeMember, } from "./navigation-resolve.js";
25
+ import { cjsRequireValueBinding, csharpShadowedStarsMayHold, memberContainerForDefinition, resolveCsharpQualifiedName, resolveExport, resolveImported, resolvePhpExportByImportType, resolveImportTypeMember, } from "./navigation-resolve.js";
22
26
  import { CSHARP_PARTIAL_CONTAINER_TYPES, getSharedOwnerIdentity, isSwiftExtensionContainer, sharedOwnerCanUseMembers, } from "./shared-owner-identity.js";
23
27
  import { hasSeparateMemberScopes, inheritsMemberOverloads, selectMember, } from "./member-selection.js";
24
28
  import { SymbolKind, } from "./types.js";
@@ -237,7 +241,7 @@ export async function findCsharpPartialTypeEquivalents(index, def) {
237
241
  if (context.sup.id !== "csharp")
238
242
  return [];
239
243
  const start = def.range.start;
240
- const nameNode = context.tree.rootNode.descendantForPosition({ row: start.line - 1, column: start.column - 1 }, { row: start.line - 1, column: start.column - 1 });
244
+ const nameNode = context.tree.rootNode.descendantForPosition(toTreeSitterPosition(start), toTreeSitterPosition(start));
241
245
  const container = nearestMemberContainer(nameNode);
242
246
  if (!container)
243
247
  return [];
@@ -286,7 +290,7 @@ function nameNodeForDef(context, def) {
286
290
  const index = start.index;
287
291
  if (index !== undefined)
288
292
  return context.tree.rootNode.descendantForIndex(index, index);
289
- const position = { row: start.line - 1, column: start.column - 1 };
293
+ const position = toTreeSitterPosition(start);
290
294
  return context.tree.rootNode.descendantForPosition(position, position);
291
295
  }
292
296
  function enclosingImportScope(declarationName) {
@@ -296,41 +300,181 @@ function enclosingImportScope(declarationName) {
296
300
  }
297
301
  return current?.parent ?? null;
298
302
  }
303
+ /** The scope of the import whose local name token starts at `start`, found by descending from `root`. */
304
+ function importScopeAt(root, start) {
305
+ let nameNode = root;
306
+ for (;;) {
307
+ const child = nameNode.namedChildren.find((candidate) => candidate.startIndex <= start && start < candidate.endIndex);
308
+ if (!child)
309
+ break;
310
+ nameNode = child;
311
+ }
312
+ return enclosingImportScope(nameNode);
313
+ }
314
+ const CSHARP_SHADOWED_ALIAS_REASON = "C# alias is shadowed by an enclosing namespace member";
315
+ const CSHARP_SHADOWED_TARGET_REASON = "C# alias target is shadowed by a member of an enclosing namespace";
316
+ const CSHARP_INCOMPLETE_ALIAS_REASON = "C# namespace alias may name a type in a project file that could not be read";
317
+ const CSHARP_SHADOWED_USING_REASON = "C# using directive is shadowed by an enclosing namespace that may declare the name";
318
+ /** The leading name `X` of a C# dotted or alias-qualified name (`X.Y.Z`, `X::Y`) and the names it qualifies. */
319
+ export function csharpChainQualifier(chainNode, source) {
320
+ const chain = collectMemberAccessChain({ sup: CSHARP_SUPPORT, source, chainNode });
321
+ if (!chain || !isReceiverNameNode(CSHARP_SUPPORT, chain.base.type))
322
+ return null;
323
+ return { qualifier: chain.base, names: chain.names };
324
+ }
325
+ /**
326
+ * Whether a nearer namespace shadows the namespace alias that `qualifier` (the `X` of `X.Type`) names. C# searches
327
+ * each enclosing namespace together with its own aliases before the next one out, so a namespace or type `X` in a
328
+ * namespace deeper than the alias's own comes before the alias. The answer comes from the index's own C# declarations
329
+ * when the lookup runs, never from the alias binding a cached module holds. An alias under `#if`, `#elif`, or
330
+ * `#else` belongs to the namespace that contains the conditional block. `X::Type` binds only aliases.
331
+ */
332
+ function csharpAliasShadowedAt(index, mod, qualifier, source) {
333
+ if (qualifier.parent?.type === "alias_qualified_name")
334
+ return false;
335
+ const name = sliceText(qualifier, source);
336
+ const alias = innermostNamespaceImport(mod.imports, name, qualifier, CSHARP_SUPPORT.normalizeIdentifier);
337
+ const aliasStart = alias?.kind === "namespace" ? alias.localRange?.start.index : undefined;
338
+ const regions = mod.csharpNamespaceFacts?.regions;
339
+ if (aliasStart === undefined || !regions)
340
+ return false;
341
+ const enclosing = csharpNamespaceAtIndex(regions, qualifier.startIndex);
342
+ return (!!enclosing &&
343
+ csharpNamespaceChainDeclares(index, mod, enclosing, CSHARP_SUPPORT.normalizeIdentifier(name), csharpNamespaceAtIndex(regions, aliasStart)));
344
+ }
345
+ /**
346
+ * Why a use led by the namespace alias `qualifier` names (`X.Type`, `X::Type`) is unproven, or `null` when the alias
347
+ * stands. A nearer namespace can shadow the alias, and an enclosing namespace of the alias's own directive can shadow
348
+ * the first segment of its target. A project file whose declarations are unknown (no syntax tree) may declare the
349
+ * same type name as one the alias reaches, so no type found through a namespace alias is proven to be the only one.
350
+ * All three answers come from the index's own C# declarations when the lookup runs, never from a flag a cached
351
+ * module holds.
352
+ */
353
+ export function csharpAliasUnprovenReason(index, mod, qualifier, source) {
354
+ if (csharpAliasShadowedAt(index, mod, qualifier, source))
355
+ return CSHARP_SHADOWED_ALIAS_REASON;
356
+ const alias = innermostNamespaceImport(mod.imports, sliceText(qualifier, source), qualifier, CSHARP_SUPPORT.normalizeIdentifier);
357
+ if (alias?.kind !== "namespace")
358
+ return null;
359
+ // An incomplete scan is the reason when it is the only one, and a declaration that was read names the shadowing one.
360
+ if (csharpProjectDeclarationsUnknown(index, mod))
361
+ return CSHARP_INCOMPLETE_ALIAS_REASON;
362
+ return csharpUsingTargetShadowed(index, mod, alias.localRange?.start.index, alias.from)
363
+ ? CSHARP_SHADOWED_TARGET_REASON
364
+ : null;
365
+ }
366
+ /**
367
+ * Why a dotted name led by `qualifier` (`B` of `B.Type`) is unproven because a `using N;` may bring `B` in, or `null`.
368
+ * An enclosing namespace shadows such a directive, so no lookup resolves it, and a namespace named `B` that the project
369
+ * declares must not stand in for what `B` may name there. An alias in scope binds the name first, and `B::Type` reaches
370
+ * aliases only, so neither is this reason.
371
+ */
372
+ export function csharpShadowedUsingReason(index, mod, qualifier, source) {
373
+ if (qualifier.parent?.type === "alias_qualified_name")
374
+ return null;
375
+ const name = sliceText(qualifier, source);
376
+ if (!csharpShadowedStarsMayHold(index, mod, name) || csharpAliasAt(mod, name, qualifier))
377
+ return null;
378
+ return CSHARP_SHADOWED_USING_REASON;
379
+ }
380
+ /**
381
+ * The namespace block whose directives include the alias `binding`, read from the file's own namespace regions, so an
382
+ * alias under `#if` keeps the scope of the block around it. `undefined` for the compilation unit, and for a binding or
383
+ * file with no recorded position.
384
+ */
385
+ function csharpAliasRegion(mod, binding) {
386
+ const aliasStart = binding.kind === "named" || binding.kind === "namespace" ? binding.localRange?.start.index : undefined;
387
+ const regions = mod.csharpNamespaceFacts?.regions;
388
+ return regions ? csharpNamespaceRegionAtIndex(regions, aliasStart) : undefined;
389
+ }
390
+ /**
391
+ * The alias of `candidates` that C# finds first for a use at `useIndex`. An alias binds only inside the block of the
392
+ * namespace its directive sits in (a directive before every namespace belongs to the whole file), and the aliases of a
393
+ * block come before those of the blocks around it, so of the aliases in scope the one in the smallest block wins. A
394
+ * binding or file with no recorded position counts as in scope and as outermost. Aliases of one block can only differ
395
+ * under conditional compilation, and the first stays.
396
+ */
397
+ function nearestCsharpAlias(mod, candidates, useIndex) {
398
+ let nearest;
399
+ let nearestSpan = Number.POSITIVE_INFINITY;
400
+ for (const candidate of candidates) {
401
+ const region = csharpAliasRegion(mod, candidate);
402
+ if (region && (useIndex < region.start || useIndex >= region.end))
403
+ continue;
404
+ const span = region ? region.end - region.start : Number.POSITIVE_INFINITY;
405
+ if (!nearest || span < nearestSpan) {
406
+ nearest = candidate;
407
+ nearestSpan = span;
408
+ }
409
+ }
410
+ return nearest;
411
+ }
412
+ const csharpAliasTables = new WeakMap();
413
+ /** The explicit aliases of a C# file by name, read from its import list once. A star import's expanded copies are no aliases. */
414
+ function csharpAliasTable(mod) {
415
+ const cached = csharpAliasTables.get(mod.imports);
416
+ if (cached?.size === mod.imports.length)
417
+ return cached;
418
+ const table = { size: mod.imports.length, types: new Map(), namespaces: new Map() };
419
+ const add = (aliases, name, binding) => {
420
+ const named = aliases.get(name);
421
+ if (named)
422
+ named.push(binding);
423
+ else
424
+ aliases.set(name, [binding]);
425
+ };
426
+ for (const imp of mod.imports) {
427
+ if (imp.kind === "namespace") {
428
+ add(table.namespaces, CSHARP_SUPPORT.normalizeIdentifier(imp.localNS), imp);
429
+ }
430
+ else if ((imp.kind === "named" || imp.kind === "default") && !isExpandedStarBinding(imp, mod.imports)) {
431
+ add(table.types, imp.local, imp);
432
+ }
433
+ }
434
+ csharpAliasTables.set(mod.imports, table);
435
+ return table;
436
+ }
299
437
  /**
300
- * Rewrites a valid C# `using X = Namespace; X::Target` lookup into the dotted form
301
- * export resolution already understands. `global::` and ordinary dotted names keep
302
- * their source spelling; an unknown alias stays `X::Target` instead of a bare name.
438
+ * The alias, namespace or type, that C# binds the name `name` to at `useNode`: the one declared in the nearest namespace
439
+ * block that contains the use. `undefined` when no alias is in scope there.
440
+ */
441
+ export function csharpAliasAt(mod, name, useNode) {
442
+ const namespaceAlias = innermostNamespaceImport(mod.imports, name, useNode, CSHARP_SUPPORT.normalizeIdentifier);
443
+ const typeAliases = csharpAliasTable(mod).types.get(name) ?? [];
444
+ return nearestCsharpAlias(mod, namespaceAlias ? [namespaceAlias, ...typeAliases] : typeAliases, useNode.startIndex);
445
+ }
446
+ /**
447
+ * Whether a table of the file's imports keyed by name, built once for the whole file, answers for `name` at `useNode`.
448
+ * C# aliases bind only inside the block of their directive, so the table is right only for a name that no alias
449
+ * declares, or whose single alias is the one in scope at the use. A name that two aliases share, or whose alias sits in
450
+ * another block, has no answer a whole-file table can give.
451
+ */
452
+ export function csharpAliasTableAnswers(mod, name, useNode) {
453
+ const table = csharpAliasTable(mod);
454
+ const types = table.types.get(name);
455
+ const namespaces = table.namespaces.get(CSHARP_SUPPORT.normalizeIdentifier(name));
456
+ const declared = (types?.length ?? 0) + (namespaces?.length ?? 0);
457
+ if (!declared)
458
+ return true;
459
+ return declared === 1 && csharpAliasAt(mod, name, useNode) === (types?.[0] ?? namespaces?.[0]);
460
+ }
461
+ /**
462
+ * Rewrites a valid C# `using X = Namespace;` lookup (`X.Target` or `X::Target`) into the
463
+ * dotted form export resolution understands. `global::` and unknown aliases keep their source spelling.
303
464
  */
304
465
  export function csharpAliasQualifiedLookupName(node, source, fallback, imports) {
305
466
  const raw = csharpLookupName(node, source, fallback);
306
467
  if (raw.startsWith("global::"))
307
468
  return raw;
308
469
  const chainNode = csharpQualifiedNameNode(node);
309
- if (!chainNode || !raw.includes("::"))
470
+ const lead = chainNode && csharpChainQualifier(chainNode, source);
471
+ if (!lead)
310
472
  return raw;
311
- const names = [];
312
- let current = chainNode;
313
- let base = null;
314
- while (current && (current.type === "qualified_name" || current.type === "alias_qualified_name")) {
315
- const parts = getMemberAccessParts(CSHARP_SUPPORT, current);
316
- base = parts.object ?? base;
317
- let property = parts.property;
318
- if (property?.type === "generic_name") {
319
- property = property.childForFieldName("name") ?? property.namedChildren[0] ?? property;
320
- }
321
- if (property?.type === "identifier")
322
- names.push(sliceText(property, source));
323
- current = base;
324
- }
325
- if (!base || !isReceiverNameNode(CSHARP_SUPPORT, base.type) || !names.length)
326
- return raw;
327
- const alias = sliceText(base, source);
473
+ const alias = sliceText(lead.qualifier, source);
328
474
  if (alias === "global")
329
475
  return raw;
330
- const imported = innermostNamespaceImport(imports, alias, base, CSHARP_SUPPORT.normalizeIdentifier);
331
- if (!imported)
332
- return raw;
333
- return `${imported.from}.${[...names].reverse().join(".")}`;
476
+ const imported = innermostNamespaceImport(imports, alias, lead.qualifier, CSHARP_SUPPORT.normalizeIdentifier);
477
+ return imported ? `${imported.from}.${lead.names.toReversed().join(".")}` : raw;
334
478
  }
335
479
  /**
336
480
  * Innermost in-scope namespace import bound to `alias`. `normalize` applies the language's
@@ -351,14 +495,7 @@ export function innermostNamespaceImport(imports, alias, useNode, normalize = (n
351
495
  const start = match.localRange?.start.index;
352
496
  if (start === undefined)
353
497
  continue;
354
- let nameNode = root;
355
- for (;;) {
356
- const child = nameNode.namedChildren.find((candidate) => candidate.startIndex <= start && start < candidate.endIndex);
357
- if (!child)
358
- break;
359
- nameNode = child;
360
- }
361
- const scope = enclosingImportScope(nameNode);
498
+ const scope = importScopeAt(root, start);
362
499
  if (!scope)
363
500
  continue;
364
501
  if (start > useNode.startIndex && scope.parent)
@@ -506,7 +643,7 @@ function resolveJvmPackageExpression(index, sup, source, expr, resolveLexicalBin
506
643
  return target ? { kind: "resolved", def: target } : null;
507
644
  }
508
645
  export async function resolveMemberAccessDefinition(params) {
509
- const { index, mod, node, source, tree, sup, resolveLexicalBinding } = params;
646
+ const { index, mod, node, source, tree, sup, resolveLexicalBinding, loadParsedFile, pythonReceiverResolutionCache } = params;
510
647
  if (sup.id === "ruby") {
511
648
  const qualified = resolveRubyQualifiedConstantDefinition(index, mod, node, source);
512
649
  if (qualified)
@@ -525,6 +662,19 @@ export async function resolveMemberAccessDefinition(params) {
525
662
  }
526
663
  if (!memberNode)
527
664
  return null;
665
+ if (sup.id === "csharp") {
666
+ const lead = csharpChainQualifier(memberNode, source);
667
+ const reason = lead ? csharpAliasUnprovenReason(index, mod, lead.qualifier, source) : null;
668
+ if (lead && reason) {
669
+ // A parameter, local, or member named like the alias is a value that C# binds before any alias,
670
+ // except after `::`, which reaches aliases only.
671
+ const scopeIndex = getOrBuildScopeIndex(index, mod.file, source, sup, mod, tree);
672
+ const closest = findClosestScopeBinding(scopeIndex, sliceText(lead.qualifier, source), lead.qualifier, sup);
673
+ const aliasQualified = lead.qualifier.parent?.type === "alias_qualified_name";
674
+ if (aliasQualified || !closest || closest.import)
675
+ return { status: "not_found", reason };
676
+ }
677
+ }
528
678
  const { object: obj, property: prop } = getMemberAccessParts(sup, memberNode);
529
679
  const optionalMemberTypes = memberAccessTraversalTypes(sup);
530
680
  // Only the outermost access is the callee; an inner hop (`A.B` in `A.B.C()`) is not called.
@@ -561,12 +711,7 @@ export async function resolveMemberAccessDefinition(params) {
561
711
  return null;
562
712
  }
563
713
  else {
564
- imp = innermostNamespaceImport(mod.imports, exprName, expr, sup.normalizeIdentifier);
565
- if (!imp) {
566
- imp = mod.imports.find((candidate) => (candidate.kind === "named" || candidate.kind === "default") &&
567
- candidate.local === exprName &&
568
- !isExpandedStarBinding(candidate, mod.imports));
569
- }
714
+ imp = csharpAliasAt(mod, exprName, expr);
570
715
  }
571
716
  }
572
717
  else {
@@ -615,6 +760,10 @@ export async function resolveMemberAccessDefinition(params) {
615
760
  const local = resolveExport(index, mod.file, exprName, { referenceIndex: expr.startIndex });
616
761
  if (local)
617
762
  return local;
763
+ // An explicit alias in scope binds before any type a `using N;` imports, so one that names no indexed type stays
764
+ // unresolved. An alias in another namespace block is not selected above and leaves the imported type to answer.
765
+ if (imp)
766
+ return null;
618
767
  }
619
768
  else {
620
769
  const local = mod.locals.find((candidate) => {
@@ -685,9 +834,13 @@ export async function resolveMemberAccessDefinition(params) {
685
834
  const memberName = sliceText(subProp, source);
686
835
  // `P.Mix` in `P.Mix.M()`: when the leftmost name binds nothing, a C# dotted name is a
687
836
  // namespace-qualified type, which qualified export lookup resolves across every file that
688
- // declares the namespace.
837
+ // declares the namespace. An alias in scope binds the name, resolved or not, and so may a
838
+ // `using N;` that an enclosing namespace shadows, so neither falls back to a namespace of that name.
689
839
  const dottedRoot = !base && sup.id === "csharp" ? csharpDottedNameRoot(expr) : null;
690
- if (dottedRoot && !resolveLexicalBinding?.(dottedRoot)) {
840
+ if (dottedRoot &&
841
+ !resolveLexicalBinding?.(dottedRoot) &&
842
+ !csharpAliasAt(mod, sliceText(dottedRoot, source), dottedRoot) &&
843
+ !csharpShadowedUsingReason(index, mod, dottedRoot, source)) {
691
844
  return resolveCsharpQualifiedName(index, mod, sliceText(expr, source).replace(/\s+/gu, ""), expr.startIndex);
692
845
  }
693
846
  if (base?.kind === "namespace") {
@@ -768,9 +921,12 @@ export async function resolveMemberAccessDefinition(params) {
768
921
  return null;
769
922
  })
770
923
  : null;
924
+ const pythonInstanceReceiver = sup.id === "python" &&
925
+ ((receiverProof?.kind === "own-type" && obj?.type === "identifier" && sliceText(obj, source) === "self") ||
926
+ (receiverProof?.kind === "named-type" && receiverProof.proof !== "static-type"));
771
927
  const chain = await resolveExpression(memberNode);
772
928
  if (chain && prop && node.id === prop.id) {
773
- if (chain.kind === "resolved") {
929
+ if (chain.kind === "resolved" && !pythonInstanceReceiver) {
774
930
  return okGoToResult(index, chain.def, {
775
931
  via: { exportedName: sliceText(prop, source) },
776
932
  resolution: "member-access",
@@ -792,7 +948,7 @@ export async function resolveMemberAccessDefinition(params) {
792
948
  if (obj && prop && node.id === prop.id && supportsReceiverMemberNavigation(sup.id)) {
793
949
  const member = sliceText(prop, source);
794
950
  if (sup.id === "python") {
795
- const memberDef = await resolvePythonReceiverMember(index, mod, node, obj, member, source, sup, resolveExpression, receiverProof);
951
+ const memberDef = await resolvePythonReceiverMember(index, mod, node, obj, member, source, sup, resolveExpression, receiverProof, loadParsedFile, pythonReceiverResolutionCache);
796
952
  if (!memberDef)
797
953
  return null;
798
954
  return okGoToResult(index, memberDef, {
@@ -962,10 +1118,6 @@ export async function resolveMemberAccessDefinition(params) {
962
1118
  function findEnclosingClassContainer(node) {
963
1119
  return nearestMemberContainer(node);
964
1120
  }
965
- function keywordClassKey(def) {
966
- const start = def.range.start;
967
- return `${fileIdentityKey(def.file)}:${start.index ?? `${start.line}:${start.column}`}`;
968
- }
969
1121
  function keywordContainerKey(file, container) {
970
1122
  return `${fileIdentityKey(file)}:${container.startIndex}:${container.endIndex}`;
971
1123
  }
@@ -1378,7 +1530,7 @@ function crossFilePeerMemberHidden(useFile, memberDef, targetContext) {
1378
1530
  if (languageId !== "java" && languageId !== "kotlin" && languageId !== "swift")
1379
1531
  return false;
1380
1532
  const start = memberDef.range.start;
1381
- const position = { row: Math.max(0, start.line - 1), column: Math.max(0, start.column - 1) };
1533
+ const position = toTreeSitterPosition(start);
1382
1534
  const nameNode = targetContext.tree.rootNode.descendantForPosition(position, position);
1383
1535
  if (!nameNode)
1384
1536
  return false;
@@ -1428,7 +1580,7 @@ async function baseRefsFromContainer(index, mod, container, source, sup, supercl
1428
1580
  // unresolved, while an own receiver can inherit their default members.
1429
1581
  if (superclassOnly && sup.id === "kotlin" && !base.invoked)
1430
1582
  continue;
1431
- const key = keywordClassKey(def);
1583
+ const key = definitionIdentityKey(def);
1432
1584
  if (seen.has(key))
1433
1585
  continue;
1434
1586
  seen.add(key);
@@ -2340,11 +2492,11 @@ function receiverMemberAcceptsArgumentCount(index, def, argumentCount) {
2340
2492
  /** Indexed owner membership and callable facts for direct and merged-owner lookup. */
2341
2493
  function indexedMemberModel(index, members, languageId) {
2342
2494
  return {
2343
- ownerKey: keywordClassKey,
2495
+ ownerKey: definitionIdentityKey,
2344
2496
  members: () => members,
2345
2497
  supertypes: () => [],
2346
2498
  name: (def) => def.localName,
2347
- key: (def) => def.callable?.key ?? keywordClassKey(def),
2499
+ key: (def) => def.callable?.key ?? definitionIdentityKey(def),
2348
2500
  callable: (def) => {
2349
2501
  const facts = def.callable ??
2350
2502
  index.byFile
@@ -2600,7 +2752,7 @@ async function selectRustReceiverMember(index, receiverDef, member, context, loc
2600
2752
  const ref = await keywordClassRefFromDef(index, traitDef);
2601
2753
  if (!ref || ref.container.type !== "trait_item")
2602
2754
  continue;
2603
- const key = keywordClassKey(traitDef);
2755
+ const key = definitionIdentityKey(traitDef);
2604
2756
  if (traitMembers.has(key))
2605
2757
  continue;
2606
2758
  const matches = [];
@@ -2625,7 +2777,7 @@ async function selectRustReceiverMember(index, receiverDef, member, context, loc
2625
2777
  return owner === "implemented" ? traitOwners : [];
2626
2778
  },
2627
2779
  name: (def) => context.sup.normalizeIdentifier(def.localName),
2628
- key: (def) => def.callable?.key ?? keywordClassKey(def),
2780
+ key: (def) => def.callable?.key ?? definitionIdentityKey(def),
2629
2781
  callable: (def) => def.callable,
2630
2782
  scope: () => "any",
2631
2783
  visible: () => true,
@@ -2785,7 +2937,7 @@ async function selectGoReceiverMember(index, receiverDef, member, normalizeIdent
2785
2937
  members: (owner) => members.get(owner) ?? [],
2786
2938
  supertypes: (owner) => embedded.get(owner) ?? [],
2787
2939
  name: (def) => normalizeIdentifier(def.localName),
2788
- key: (def) => def.callable?.key ?? keywordClassKey(def),
2940
+ key: (def) => def.callable?.key ?? definitionIdentityKey(def),
2789
2941
  callable: (def) => def.callable,
2790
2942
  scope: () => "any",
2791
2943
  visible: () => true,
@@ -2799,17 +2951,16 @@ async function selectGoReceiverMember(index, receiverDef, member, normalizeIdent
2799
2951
  });
2800
2952
  return selected.status === "unique" ? selected.member : undefined;
2801
2953
  }
2802
- function pythonClassKey(def) {
2803
- const start = def.range.start;
2804
- return `${fileIdentityKey(def.file)}:${start.index ?? `${start.line}:${start.column}`}`;
2954
+ export function createPythonReceiverResolutionCache() {
2955
+ return { classRefs: new Map(), members: new Map() };
2805
2956
  }
2806
- async function resolvePythonReceiverMember(index, mod, node, obj, member, source, sup, resolveExpression, proof) {
2807
- const classRef = await pythonReceiverClassRef(index, mod, node, obj, source, sup, resolveExpression, proof);
2957
+ async function resolvePythonReceiverMember(index, mod, node, obj, member, source, sup, resolveExpression, proof, loadParsedFile, cache) {
2958
+ const classRef = await pythonReceiverClassRef(index, mod, node, obj, source, sup, resolveExpression, proof, loadParsedFile, cache);
2808
2959
  if (!classRef)
2809
2960
  return undefined;
2810
- return lookupPythonClassMember(index, classRef.ref, member, classRef.startAtSupertype);
2961
+ return lookupPythonClassMember(index, classRef.ref, member, classRef.startAtSupertype, classRef.preferInstanceAttributes, loadParsedFile, cache);
2811
2962
  }
2812
- async function pythonReceiverClassRef(index, mod, node, obj, source, sup, resolveExpression, proof) {
2963
+ async function pythonReceiverClassRef(index, mod, node, obj, source, sup, resolveExpression, proof, loadParsedFile, cache) {
2813
2964
  const receiver = proof ?? classifyReceiver(sup, obj, source, null, 0, obj.parent ?? obj, noLexicalBinding);
2814
2965
  if (receiver.kind === "own-type" || receiver.kind === "supertype") {
2815
2966
  const container = findEnclosingClassContainer(node);
@@ -2831,11 +2982,13 @@ async function pythonReceiverClassRef(index, mod, node, obj, source, sup, resolv
2831
2982
  });
2832
2983
  if (!def)
2833
2984
  return null;
2834
- const ref = await pythonClassRefFromDef(index, def);
2835
- return ref ? { ref, startAtSupertype: receiver.kind === "supertype" } : null;
2985
+ const ref = await pythonClassRefFromDef(index, def, loadParsedFile, cache);
2986
+ const preferInstanceAttributes = receiver.kind === "own-type" && sliceText(obj, source) === "self";
2987
+ return ref ? { ref, startAtSupertype: receiver.kind === "supertype", preferInstanceAttributes } : null;
2836
2988
  }
2837
2989
  let classDef;
2838
2990
  const constructor = receiver.kind === "named-type" && receiver.proof !== "static-type" ? receiver.typeNode : null;
2991
+ const preferInstanceAttributes = receiver.kind === "named-type" && receiver.proof !== "static-type";
2839
2992
  if (constructor) {
2840
2993
  const result = await resolveExpression(constructor);
2841
2994
  if (result?.kind === "resolved" && result.def.kind === SymbolKind.Class) {
@@ -2850,35 +3003,140 @@ async function pythonReceiverClassRef(index, mod, node, obj, source, sup, resolv
2850
3003
  }
2851
3004
  if (!classDef)
2852
3005
  return null;
2853
- const ref = await pythonClassRefFromDef(index, classDef);
2854
- return ref ? { ref, startAtSupertype: false } : null;
3006
+ const ref = await pythonClassRefFromDef(index, classDef, loadParsedFile, cache);
3007
+ return ref ? { ref, startAtSupertype: false, preferInstanceAttributes } : null;
2855
3008
  }
2856
- async function pythonClassRefFromDef(index, def) {
2857
- const module = index.byFile.get(fileIdentityKey(def.file));
2858
- if (!module)
2859
- return null;
2860
- const context = await ensureParsedContext(def.file, undefined, index.languageExtensions);
2861
- const start = def.range.start;
2862
- const position = {
2863
- row: start.line - 1,
2864
- column: start.column - 1,
2865
- };
2866
- let current = context.tree.rootNode.descendantForPosition(position, position);
2867
- while (current && current.type !== "class_definition") {
2868
- current = current.parent;
2869
- }
2870
- if (!current)
2871
- return null;
2872
- return { def, container: current, context, module };
3009
+ async function pythonClassRefFromDef(index, def, loadParsedFile, cache) {
3010
+ const key = definitionIdentityKey(def);
3011
+ const cached = cache?.classRefs.get(key);
3012
+ if (cached)
3013
+ return cached;
3014
+ const pending = (async () => {
3015
+ const module = index.byFile.get(fileIdentityKey(def.file));
3016
+ if (!module)
3017
+ return null;
3018
+ const context = loadParsedFile
3019
+ ? await loadParsedFile(def.file)
3020
+ : await ensureParsedContext(def.file, undefined, index.languageExtensions);
3021
+ if (!context || context.sup.id !== "python")
3022
+ return null;
3023
+ const start = def.range.start;
3024
+ const position = {
3025
+ row: start.line - 1,
3026
+ column: start.column - 1,
3027
+ };
3028
+ let current = context.tree.rootNode.descendantForPosition(position, position);
3029
+ while (current && current.type !== "class_definition") {
3030
+ current = current.parent;
3031
+ }
3032
+ if (!current)
3033
+ return null;
3034
+ return { def, container: current, context, module };
3035
+ })();
3036
+ cache?.classRefs.set(key, pending);
3037
+ return pending;
3038
+ }
3039
+ /** Whether `nameNode` names a class-level annotation without a value (`count: int`), which declares a type and binds nothing. */
3040
+ function isPythonValuelessAnnotation(nameNode) {
3041
+ const assignment = nameNode.parent;
3042
+ return (assignment?.type === "assignment" &&
3043
+ assignment.childForFieldName("left")?.id === nameNode.id &&
3044
+ !assignment.childForFieldName("right"));
3045
+ }
3046
+ /** The `locals` of `classRef` that bind their name in the class namespace: every one but an annotation without a value. */
3047
+ function pythonBindingLocals(classRef, locals) {
3048
+ return locals.filter((local) => {
3049
+ const nameNode = nameNodeForDef(classRef.context, local);
3050
+ return !nameNode || !isPythonValuelessAnnotation(nameNode);
3051
+ });
2873
3052
  }
2874
- function pythonMembersOnClass(classRef, member) {
3053
+ /**
3054
+ * The members of one class named `member`. `prefer` (`self` and constructed receivers) lets a property decide first and
3055
+ * then an instance attribute beat a class attribute of the same class; `fallback` reaches instance attributes only
3056
+ * when the class has no class-level member.
3057
+ */
3058
+ function pythonMembersOnClass(classRef, member, instanceAttributes = "fallback") {
2875
3059
  const normalizeIdentifier = classRef.context.sup.normalizeIdentifier;
2876
- const direct = findDirectLocalsWithinNode(classRef.module.locals, member, classRef.container, classRef.context, normalizeIdentifier);
3060
+ let direct;
3061
+ if (instanceAttributes === "prefer") {
3062
+ direct = findDirectLocalsWithinNode(classRef.module.locals, member, classRef.container, classRef.context, normalizeIdentifier);
3063
+ const propertyMembers = pythonPropertyDescriptorMembers(classRef, member, direct);
3064
+ if (propertyMembers)
3065
+ return propertyMembers;
3066
+ const instanceAttributeMembers = findPythonInstanceAttributesWithinClass(classRef.module.locals, member, classRef.container, classRef.context, normalizeIdentifier, "self");
3067
+ const selectedInstanceAttribute = preferredPythonInstanceAttribute(instanceAttributeMembers, classRef.container, classRef.context);
3068
+ if (selectedInstanceAttribute)
3069
+ return [selectedInstanceAttribute];
3070
+ }
3071
+ direct ??= findDirectLocalsWithinNode(classRef.module.locals, member, classRef.container, classRef.context, normalizeIdentifier);
2877
3072
  if (direct.length)
2878
3073
  return direct;
2879
3074
  return findPythonInstanceAttributesWithinClass(classRef.module.locals, member, classRef.container, classRef.context, normalizeIdentifier);
2880
3075
  }
2881
- function findPythonInstanceAttributesWithinClass(locals, member, container, targetContext, normalizeIdentifier) {
3076
+ /** What a function definition does to the property `member`: the role its decorators give it, `null` for a plain one. */
3077
+ function pythonPropertyRole(decorators, member) {
3078
+ for (const decorator of decorators) {
3079
+ if (decorator?.kind === "property")
3080
+ return "getter";
3081
+ if (decorator?.kind === "accessor" && decorator.propertyName === member)
3082
+ return decorator.accessor;
3083
+ }
3084
+ return null;
3085
+ }
3086
+ /**
3087
+ * What the class-level binding that `nameNode` names does to the property `member` holds: `property` makes a new one whose
3088
+ * getter is the binding (`property(...)`, `@property`, a replacing `@member.getter`), `update` changes the one an
3089
+ * earlier binding made (`@member.setter`, `@member.deleter`), `plain` replaces it with something else, and `annotation`
3090
+ * (`member: int`) binds nothing.
3091
+ */
3092
+ function pythonPropertyBinding(classRef, nameNode, member) {
3093
+ if (isPythonValuelessAnnotation(nameNode))
3094
+ return "annotation";
3095
+ const assignment = nameNode.parent;
3096
+ if (assignment?.type === "assignment" && assignment.childForFieldName("left")?.id === nameNode.id) {
3097
+ const value = assignment.childForFieldName("right");
3098
+ const callee = value?.type === "call" ? value.childForFieldName("function") : null;
3099
+ const argumentsNode = value?.childForFieldName("arguments");
3100
+ return callee?.text === "property" && (argumentsNode?.namedChildren.length ?? 0) >= 1 ? "property" : "plain";
3101
+ }
3102
+ let functionNode = nameNode;
3103
+ while (functionNode && functionNode.id !== classRef.container.id && functionNode.type !== "function_definition") {
3104
+ functionNode = functionNode.parent;
3105
+ }
3106
+ const decorated = functionNode?.type === "function_definition" ? functionNode.parent : null;
3107
+ const decorators = decorated?.type === "decorated_definition"
3108
+ ? decorated.namedChildren.filter((child) => child.type === "decorator")
3109
+ : [];
3110
+ const role = pythonPropertyRole(decorators.map(pythonPropertyDecorator), member);
3111
+ if (role === "getter")
3112
+ return "property";
3113
+ return role ? "update" : "plain";
3114
+ }
3115
+ /**
3116
+ * The property descriptor that `member` is in `classRef`, or `null` when it is not one. The class-level bindings of the
3117
+ * name run in source order and the last one decides what the name holds: `property(...)`, `@property`, and a replacing
3118
+ * `@member.getter` each make a new property whose getter is that definition, `@member.setter` and `@member.deleter` keep
3119
+ * the property an earlier binding made, so its getter stays the target, and any other binding replaces the property
3120
+ * (`count = 0` after `@property def count`). An annotation without a value binds nothing.
3121
+ */
3122
+ function pythonPropertyDescriptorMembers(classRef, member, directMembers) {
3123
+ let descriptor;
3124
+ const inSourceOrder = [...directMembers].sort((left, right) => (left.range.start.index ?? 0) - (right.range.start.index ?? 0));
3125
+ for (const local of inSourceOrder) {
3126
+ const nameNode = nameNodeForDef(classRef.context, local);
3127
+ if (!nameNode)
3128
+ continue;
3129
+ const binding = pythonPropertyBinding(classRef, nameNode, member);
3130
+ if (binding === "property")
3131
+ descriptor = local;
3132
+ else if (binding === "update")
3133
+ descriptor ??= local;
3134
+ else if (binding === "plain")
3135
+ descriptor = undefined;
3136
+ }
3137
+ return descriptor ? [descriptor] : null;
3138
+ }
3139
+ function findPythonInstanceAttributesWithinClass(locals, member, container, targetContext, normalizeIdentifier, receiver) {
2882
3140
  const matches = [];
2883
3141
  const containerStart = container.startIndex;
2884
3142
  const containerEnd = container.endIndex;
@@ -2899,11 +3157,61 @@ function findPythonInstanceAttributesWithinClass(locals, member, container, targ
2899
3157
  column: start.column - 1,
2900
3158
  };
2901
3159
  const nameNode = targetContext.tree.rootNode.descendantForPosition(position, position);
2902
- if (isPythonReceiverAttributeAssignmentName(nameNode))
2903
- matches.push(local);
3160
+ if (!isPythonReceiverAttributeAssignmentName(nameNode))
3161
+ continue;
3162
+ const object = nameNode.parent?.childForFieldName("object");
3163
+ if (receiver && object?.text !== receiver)
3164
+ continue;
3165
+ matches.push(local);
2904
3166
  }
2905
3167
  return matches;
2906
3168
  }
3169
+ function preferredPythonInstanceAttribute(attributes, container, context) {
3170
+ let firstMethodAssignment;
3171
+ let firstMethodStartIndex;
3172
+ let initializerAssignment;
3173
+ let initializerStartIndex;
3174
+ for (const attribute of attributes) {
3175
+ const startIndex = attribute.range.start.index;
3176
+ if (startIndex === undefined)
3177
+ continue;
3178
+ const start = attribute.range.start;
3179
+ const position = {
3180
+ row: start.line - 1,
3181
+ column: start.column - 1,
3182
+ };
3183
+ let current = context.tree.rootNode.descendantForPosition(position, position);
3184
+ let method = null;
3185
+ let invalidMethodScope = false;
3186
+ while (current && current.id !== container.id) {
3187
+ if (current.type === "class_definition") {
3188
+ invalidMethodScope = true;
3189
+ break;
3190
+ }
3191
+ if (current.type === "function_definition") {
3192
+ if (method) {
3193
+ invalidMethodScope = true;
3194
+ break;
3195
+ }
3196
+ method = current;
3197
+ }
3198
+ current = current.parent;
3199
+ }
3200
+ if (invalidMethodScope || current?.id !== container.id || !method)
3201
+ continue;
3202
+ if (firstMethodStartIndex === undefined || startIndex < firstMethodStartIndex) {
3203
+ firstMethodAssignment = attribute;
3204
+ firstMethodStartIndex = startIndex;
3205
+ }
3206
+ if (method.childForFieldName("name")?.text !== "__init__")
3207
+ continue;
3208
+ if (initializerStartIndex === undefined || startIndex < initializerStartIndex) {
3209
+ initializerAssignment = attribute;
3210
+ initializerStartIndex = startIndex;
3211
+ }
3212
+ }
3213
+ return initializerAssignment ?? firstMethodAssignment;
3214
+ }
2907
3215
  function pythonBaseIdentifierNodes(classNode) {
2908
3216
  const bases = classNode.childForFieldName("superclasses") ??
2909
3217
  (classNode.namedChildren ?? []).find((child) => child.type === "argument_list");
@@ -2953,7 +3261,7 @@ function resolvePythonNamedClass(index, mod, name) {
2953
3261
  return exported.def;
2954
3262
  return undefined;
2955
3263
  }
2956
- async function pythonBaseClassRefs(index, classRef) {
3264
+ async function pythonBaseClassRefs(index, classRef, loadParsedFile, cache) {
2957
3265
  const names = pythonBaseIdentifierNodes(classRef.container);
2958
3266
  const refs = [];
2959
3267
  const seen = new Set();
@@ -2961,26 +3269,112 @@ async function pythonBaseClassRefs(index, classRef) {
2961
3269
  const def = resolvePythonNamedClass(index, classRef.module, sliceText(nameNode, classRef.context.source));
2962
3270
  if (!def)
2963
3271
  continue;
2964
- const key = pythonClassKey(def);
3272
+ const key = definitionIdentityKey(def);
2965
3273
  if (seen.has(key))
2966
3274
  continue;
2967
3275
  seen.add(key);
2968
- const ref = await pythonClassRefFromDef(index, def);
3276
+ const ref = await pythonClassRefFromDef(index, def, loadParsedFile, cache);
2969
3277
  if (ref)
2970
3278
  refs.push(ref);
2971
3279
  }
2972
3280
  return refs;
2973
3281
  }
2974
- async function lookupPythonClassMember(index, start, member, startAtSupertype = false) {
3282
+ /**
3283
+ * What decides `self.member` in `start`'s hierarchy: `property` when the first class that binds `member` at class level
3284
+ * binds a property, `attribute` when it binds anything else or no class binds it, and `unproven` when the method
3285
+ * resolution order would have to say. An annotation without a value (`member: int`) binds nothing. Python gives a
3286
+ * property (a data descriptor) precedence over the instance dictionary, so `self.member = value` writes through it
3287
+ * instead of declaring an attribute, while a plain class-level binding found first leaves the instance attribute in
3288
+ * charge. Along one chain of single bases the nearest binding is first. With several bases the order is not rebuilt: a
3289
+ * subclass always comes before its bases, so a binding class that no other binding class derives from comes first when
3290
+ * it is the only one, and with several of them it is not proven which does. A property is first only as that one class,
3291
+ * wherever it sits in the hierarchy, and it is the one whose getter answers.
3292
+ */
3293
+ async function pythonPropertyPrecedence(index, start, member, loadParsedFile, cache) {
3294
+ // The classes that bind `member`, each with the property its bindings make, or `null` when they make none.
3295
+ const declarations = new Map();
3296
+ const baseKeys = new Map();
3297
+ const visited = new Set([definitionIdentityKey(start.def)]);
3298
+ let level = [start];
3299
+ let singleChain = true;
3300
+ for (let depth = 0; depth < RECEIVER_HIERARCHY_DEPTH && level.length; depth += 1) {
3301
+ if (level.length > 1)
3302
+ singleChain = false;
3303
+ const next = [];
3304
+ for (const ref of level) {
3305
+ const key = definitionIdentityKey(ref.def);
3306
+ const bindings = pythonBindingLocals(ref, findDirectLocalsWithinNode(ref.module.locals, member, ref.container, ref.context, ref.context.sup.normalizeIdentifier));
3307
+ if (bindings.length)
3308
+ declarations.set(key, pythonPropertyDescriptorMembers(ref, member, bindings)?.[0] ?? null);
3309
+ const bases = await pythonBaseClassRefs(index, ref, loadParsedFile, cache);
3310
+ baseKeys.set(key, bases.map((base) => definitionIdentityKey(base.def)));
3311
+ for (const base of bases) {
3312
+ const baseKey = definitionIdentityKey(base.def);
3313
+ if (visited.has(baseKey))
3314
+ continue;
3315
+ visited.add(baseKey);
3316
+ next.push(base);
3317
+ }
3318
+ }
3319
+ // On one chain of single bases the nearest declaration is first, so the walk ends at it.
3320
+ if (singleChain && declarations.size)
3321
+ break;
3322
+ level = next;
3323
+ }
3324
+ if (!declarations.size)
3325
+ return { kind: "attribute" };
3326
+ // A declaring class that another declaring class extends comes later in every order, so only the others can be first.
3327
+ const dominated = new Set();
3328
+ for (const declaring of declarations.keys()) {
3329
+ const seen = new Set();
3330
+ const pending = [...(baseKeys.get(declaring) ?? [])];
3331
+ while (pending.length) {
3332
+ const ancestor = pending.pop();
3333
+ if (seen.has(ancestor))
3334
+ continue;
3335
+ seen.add(ancestor);
3336
+ if (declarations.has(ancestor))
3337
+ dominated.add(ancestor);
3338
+ pending.push(...(baseKeys.get(ancestor) ?? []));
3339
+ }
3340
+ }
3341
+ const nearest = [...declarations].filter(([key]) => !dominated.has(key)).map(([, getter]) => getter);
3342
+ if (!nearest.length)
3343
+ return { kind: "unproven" };
3344
+ if (nearest.every((getter) => !getter))
3345
+ return { kind: "attribute" };
3346
+ const [getter] = nearest;
3347
+ return nearest.length === 1 && getter ? { kind: "property", getter } : { kind: "unproven" };
3348
+ }
3349
+ async function lookupPythonClassMember(index, start, member, startAtSupertype = false, preferInstanceAttributes = false, loadParsedFile, cache) {
3350
+ const key = `${definitionIdentityKey(start.def)}:${member}:${startAtSupertype}:${preferInstanceAttributes}`;
3351
+ const cached = cache?.members.get(key);
3352
+ if (cached)
3353
+ return cached;
3354
+ const pending = lookupPythonClassMemberUncached(index, start, member, startAtSupertype, preferInstanceAttributes, loadParsedFile, cache);
3355
+ cache?.members.set(key, pending);
3356
+ return pending;
3357
+ }
3358
+ async function lookupPythonClassMemberUncached(index, start, member, startAtSupertype, preferInstanceAttributes, loadParsedFile, cache) {
3359
+ const instanceAttributes = preferInstanceAttributes ? "prefer" : "fallback";
3360
+ if (preferInstanceAttributes) {
3361
+ // An inherited property takes the write `self.x = value` and the read after it, so no instance attribute shadows it,
3362
+ // and the class that binds it first answers, whichever level of the hierarchy it sits on.
3363
+ const precedence = await pythonPropertyPrecedence(index, start, member, loadParsedFile, cache);
3364
+ if (precedence.kind === "unproven")
3365
+ return undefined;
3366
+ if (precedence.kind === "property")
3367
+ return precedence.getter;
3368
+ }
2975
3369
  const membersByOwner = new Map();
2976
3370
  const parentsByOwner = new Map();
2977
- const visited = new Set([pythonClassKey(start.def)]);
3371
+ const visited = new Set([definitionIdentityKey(start.def)]);
2978
3372
  let level = [start];
2979
3373
  for (let depth = 0; depth < RECEIVER_HIERARCHY_DEPTH && level.length; depth += 1) {
2980
3374
  let named = false;
2981
3375
  for (const ref of level) {
2982
- const members = startAtSupertype && !depth ? [] : pythonMembersOnClass(ref, member);
2983
- membersByOwner.set(pythonClassKey(ref.def), members);
3376
+ const members = startAtSupertype && !depth ? [] : pythonMembersOnClass(ref, member, instanceAttributes);
3377
+ membersByOwner.set(definitionIdentityKey(ref.def), members);
2984
3378
  if (members.length)
2985
3379
  named = true;
2986
3380
  }
@@ -2988,10 +3382,10 @@ async function lookupPythonClassMember(index, start, member, startAtSupertype =
2988
3382
  break;
2989
3383
  const next = [];
2990
3384
  for (const ref of level) {
2991
- const parents = await pythonBaseClassRefs(index, ref);
2992
- parentsByOwner.set(pythonClassKey(ref.def), parents);
3385
+ const parents = await pythonBaseClassRefs(index, ref, loadParsedFile, cache);
3386
+ parentsByOwner.set(definitionIdentityKey(ref.def), parents);
2993
3387
  for (const parent of parents) {
2994
- const key = pythonClassKey(parent.def);
3388
+ const key = definitionIdentityKey(parent.def);
2995
3389
  if (visited.has(key))
2996
3390
  continue;
2997
3391
  visited.add(key);
@@ -3001,11 +3395,11 @@ async function lookupPythonClassMember(index, start, member, startAtSupertype =
3001
3395
  level = next;
3002
3396
  }
3003
3397
  const model = {
3004
- ownerKey: (ref) => pythonClassKey(ref.def),
3005
- members: (ref) => membersByOwner.get(pythonClassKey(ref.def)) ?? [],
3006
- supertypes: (ref) => parentsByOwner.get(pythonClassKey(ref.def)) ?? [],
3398
+ ownerKey: (ref) => definitionIdentityKey(ref.def),
3399
+ members: (ref) => membersByOwner.get(definitionIdentityKey(ref.def)) ?? [],
3400
+ supertypes: (ref) => parentsByOwner.get(definitionIdentityKey(ref.def)) ?? [],
3007
3401
  name: (def) => def.localName,
3008
- key: (def) => def.callable?.key ?? pythonClassKey(def),
3402
+ key: (def) => def.callable?.key ?? definitionIdentityKey(def),
3009
3403
  callable: (def) => def.callable,
3010
3404
  scope: () => "any",
3011
3405
  visible: () => true,