@backbencher/brain 0.0.0-stage → 0.1.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 (319) hide show
  1. package/CHANGELOG.md +298 -0
  2. package/EMBEDDINGS.md +355 -0
  3. package/LICENSE +21 -0
  4. package/README.md +415 -2
  5. package/bin/bb +13 -0
  6. package/dist/analysis-exclusions-7ZJDXOVZ.js +35 -0
  7. package/dist/brain-index-health-KY7K552E.js +17 -0
  8. package/dist/brain-relationship-enrichment-QH7OOHUF.js +558 -0
  9. package/dist/brain.sql-EIM4WS4D.js +29 -0
  10. package/dist/chunk-2BSKD7O3.js +40 -0
  11. package/dist/chunk-2DE27DVC.js +1314 -0
  12. package/dist/chunk-2RRBMNBQ.js +322 -0
  13. package/dist/chunk-2RTN2DFU.js +711 -0
  14. package/dist/chunk-2WXYNLBA.js +29 -0
  15. package/dist/chunk-3CTFIJJB.js +17 -0
  16. package/dist/chunk-3LFTSMIV.js +174 -0
  17. package/dist/chunk-47HKX4AJ.js +930 -0
  18. package/dist/chunk-4H22TLOT.js +543 -0
  19. package/dist/chunk-5SD45FLC.js +818 -0
  20. package/dist/chunk-66A5ZFYA.js +1758 -0
  21. package/dist/chunk-6AIRWAO2.js +247 -0
  22. package/dist/chunk-6WNGD3NN.js +196 -0
  23. package/dist/chunk-7AN7U5IZ.js +371 -0
  24. package/dist/chunk-BHB7BYYI.js +626 -0
  25. package/dist/chunk-BQ3OVQ3P.js +125 -0
  26. package/dist/chunk-CW4XXSNN.js +1479 -0
  27. package/dist/chunk-D2Q4Y47A.js +53 -0
  28. package/dist/chunk-DIYAGQJL.js +34 -0
  29. package/dist/chunk-DYM4FQEE.js +90 -0
  30. package/dist/chunk-EWMWK7WN.js +75 -0
  31. package/dist/chunk-FVVQTSIM.js +3427 -0
  32. package/dist/chunk-FWSL4VG6.js +1290 -0
  33. package/dist/chunk-GBI7V7KY.js +69 -0
  34. package/dist/chunk-GEFFO6O2.js +152 -0
  35. package/dist/chunk-HOWAQXJO.js +236 -0
  36. package/dist/chunk-HQSPJDHI.js +613 -0
  37. package/dist/chunk-IFZNR5UJ.js +2863 -0
  38. package/dist/chunk-J4PMBXQQ.js +336 -0
  39. package/dist/chunk-KAET47ZL.js +125 -0
  40. package/dist/chunk-KCDECRJY.js +440 -0
  41. package/dist/chunk-KLK3PBTO.js +1119 -0
  42. package/dist/chunk-L5TDYKYK.js +76 -0
  43. package/dist/chunk-MLKGABMK.js +9 -0
  44. package/dist/chunk-OWISBAOF.js +61 -0
  45. package/dist/chunk-PJTNGD3Z.js +6924 -0
  46. package/dist/chunk-QLK6ED4Q.js +235 -0
  47. package/dist/chunk-R2GW4F6R.js +19 -0
  48. package/dist/chunk-RCMTFSEF.js +87 -0
  49. package/dist/chunk-RH7KC5HU.js +12050 -0
  50. package/dist/chunk-RM3PY6TG.js +376 -0
  51. package/dist/chunk-ROMM6KMC.js +433 -0
  52. package/dist/chunk-SK6YVHFZ.js +211 -0
  53. package/dist/chunk-SM7RFQRO.js +214 -0
  54. package/dist/chunk-UFE77L67.js +782 -0
  55. package/dist/chunk-UGR4QIGS.js +67 -0
  56. package/dist/chunk-UUNHHX4M.js +13 -0
  57. package/dist/chunk-V44PGPA6.js +2104 -0
  58. package/dist/chunk-VL52PL2T.js +71 -0
  59. package/dist/chunk-VURYFIHW.js +201 -0
  60. package/dist/chunk-XJKJYIPP.js +7436 -0
  61. package/dist/chunk-YI6FF2ZR.js +340 -0
  62. package/dist/cli/index.js +37 -0
  63. package/dist/config-HZAAYDP3.js +10 -0
  64. package/dist/content-search-642F7E5V.js +593 -0
  65. package/dist/database-TCTZDLE5.js +9 -0
  66. package/dist/doctor-GXCKSJOX.js +395 -0
  67. package/dist/edit-engine-KM7MPFEC.js +51 -0
  68. package/dist/engine-42TZFNIZ.js +11 -0
  69. package/dist/engine-LO6L4JLQ.js +18 -0
  70. package/dist/fingerprint-XDXFRWO6.js +33 -0
  71. package/dist/framework-intelligence-DWFCKV44.js +860 -0
  72. package/dist/freshness-3K6VU5OT.js +174 -0
  73. package/dist/graph-engine-PL5YA7BA.js +21 -0
  74. package/dist/graph_request-MM4REP6H.js +350 -0
  75. package/dist/impact_request-WDE47IZ5.js +68 -0
  76. package/dist/index-space-IUUN5WYV.js +15 -0
  77. package/dist/index-status-6BD7UBHR.js +34 -0
  78. package/dist/index.js +159 -0
  79. package/dist/instance-FO6QZRLH.js +19 -0
  80. package/dist/language-detection-DFCAU5DZ.js +11 -0
  81. package/dist/lsp/server.js +4301 -0
  82. package/dist/mcp/server.js +132 -0
  83. package/dist/onboard-DIQZV2NW.js +161 -0
  84. package/dist/override-companion-pass-XR7MHTP7.js +117 -0
  85. package/dist/parallel-indexer-4PW3AFXP.js +88 -0
  86. package/dist/pool-worker.js +1153 -0
  87. package/dist/project-health-ZS5TS2Z6.js +94 -0
  88. package/dist/project-index-5SDPHITE.js +57 -0
  89. package/dist/project-registry-DGZBIZS7.js +355 -0
  90. package/dist/real-bash-analyzer-SXSV67E2.js +2201 -0
  91. package/dist/real-c-analyzer-SY7FTZ6W.js +5942 -0
  92. package/dist/real-clean-analyzer-IGDHHLZK.js +3470 -0
  93. package/dist/real-clojure-analyzer-4OH7IWLB.js +2818 -0
  94. package/dist/real-cpp-analyzer-7LTDRJRJ.js +4101 -0
  95. package/dist/real-csharp-analyzer-KICU3TLH.js +3298 -0
  96. package/dist/real-css-analyzer-HPU277Q6.js +15 -0
  97. package/dist/real-dart-analyzer-7LZ5LCMW.js +3944 -0
  98. package/dist/real-elixir-analyzer-BE3MEVZO.js +2192 -0
  99. package/dist/real-erlang-analyzer-BZMAKYBK.js +1731 -0
  100. package/dist/real-fsharp-analyzer-5QLTOV3E.js +2390 -0
  101. package/dist/real-go-analyzer-POD7MZQR.js +4126 -0
  102. package/dist/real-graphql-analyzer-MAQRZ6QW.js +1442 -0
  103. package/dist/real-groovy-analyzer-MEWSUPMJ.js +2285 -0
  104. package/dist/real-haskell-analyzer-I5L2GR3Y.js +2533 -0
  105. package/dist/real-hcl-analyzer-DBOPXSWJ.js +725 -0
  106. package/dist/real-html-analyzer-O63XZLZD.js +1759 -0
  107. package/dist/real-java-analyzer-CHCW3EKA.js +4677 -0
  108. package/dist/real-javascript-analyzer-QAAJQYZE.js +14 -0
  109. package/dist/real-json-analyzer-UGBR7YQN.js +1640 -0
  110. package/dist/real-julia-analyzer-35Q4GHOZ.js +2085 -0
  111. package/dist/real-kotlin-analyzer-GRAYCWW2.js +3956 -0
  112. package/dist/real-lua-analyzer-5BAPDZDF.js +1957 -0
  113. package/dist/real-makefile-analyzer-YJKAHNAS.js +920 -0
  114. package/dist/real-markdown-analyzer-UKUQZO4F.js +1215 -0
  115. package/dist/real-matlab-analyzer-FVIKQZKG.js +480 -0
  116. package/dist/real-nim-analyzer-M7FAIABG.js +3603 -0
  117. package/dist/real-objective-c-analyzer-XMYQIGQI.js +1518 -0
  118. package/dist/real-perl-analyzer-ZLY6M2DZ.js +1865 -0
  119. package/dist/real-php-analyzer-KI2ZAM7X.js +9368 -0
  120. package/dist/real-powershell-analyzer-B3T5ZP6U.js +2915 -0
  121. package/dist/real-protobuf-analyzer-23OZ75XV.js +867 -0
  122. package/dist/real-python-analyzer-I4TIUB6D.js +4880 -0
  123. package/dist/real-r-analyzer-FJZJXXS6.js +2596 -0
  124. package/dist/real-ruby-analyzer-M3UFIVTQ.js +2429 -0
  125. package/dist/real-rust-analyzer-LVSONPAN.js +3359 -0
  126. package/dist/real-scala-analyzer-CWPI33Q2.js +3293 -0
  127. package/dist/real-scss-analyzer-TGRJQ7TH.js +1515 -0
  128. package/dist/real-solidity-analyzer-4P2VBVWA.js +2608 -0
  129. package/dist/real-sql-analyzer-J7DYZOZR.js +3840 -0
  130. package/dist/real-svelte-analyzer-NHEN2SX5.js +2532 -0
  131. package/dist/real-swift-analyzer-2NSYULWI.js +2311 -0
  132. package/dist/real-toml-analyzer-L3C66L7Q.js +929 -0
  133. package/dist/real-typescript-analyzer-FTC6ETRQ.js +14 -0
  134. package/dist/real-vb-analyzer-ORY7LAQS.js +3145 -0
  135. package/dist/real-vba-analyzer-JH2TTUFI.js +466 -0
  136. package/dist/real-vue-analyzer-OO4FUGBV.js +2680 -0
  137. package/dist/real-xml-analyzer-6CQVR477.js +2405 -0
  138. package/dist/real-yaml-analyzer-J6MQG3YX.js +3528 -0
  139. package/dist/real-zig-analyzer-EFKCPJNU.js +2430 -0
  140. package/dist/regex-search-OPTLKUN5.js +239 -0
  141. package/dist/rules-I453JTRC.js +152 -0
  142. package/dist/scoped-path-MJYWJZQX.js +11 -0
  143. package/dist/setup-show-Y5GB5KXA.js +15 -0
  144. package/dist/setup-wizard-G5YYR5T6.js +24 -0
  145. package/dist/symbol-search-KB4MU4SI.js +16 -0
  146. package/dist/taint-YOTN5X55.js +202 -0
  147. package/dist/taint-analyzer-N7YLZU3N.js +163 -0
  148. package/dist/tool-handlers-G4NAGJIH.js +72 -0
  149. package/dist/tool-registry-BPEJNSZG.js +17 -0
  150. package/dist/tool-validation-RF675A3C.js +32 -0
  151. package/dist/type-inference-4Y7WTMFE.js +13 -0
  152. package/dist/vector-binary-LMY4QGAN.js +19 -0
  153. package/dist/version-LXGNFO37.js +9 -0
  154. package/dist/wasm-NMWO3WXY.js +16 -0
  155. package/docs/EMBEDDINGS.md +132 -0
  156. package/docs/README.md +178 -0
  157. package/docs/data/m10-baseline.json +602 -0
  158. package/docs/data/m10-benchmark-baseline.json +57 -0
  159. package/docs/data/m10-benchmark-last-run.json +127 -0
  160. package/docs/data/m10-final-audit.json +215 -0
  161. package/docs/data/m12-final-audit.json +138 -0
  162. package/docs/data/m12-surface-matrix.json +50 -0
  163. package/docs/data/public-tools.json +1902 -0
  164. package/docs/indexing/DEAD-ASSETS.md +88 -0
  165. package/docs/indexing/INDEXER-REVIEW.md +634 -0
  166. package/docs/indexing/PERFORMANCE-FINDINGS.md +106 -0
  167. package/docs/indexing/README.md +427 -0
  168. package/docs/indexing/discovery-matrix.md +41 -0
  169. package/docs/indexing/embeddings.md +325 -0
  170. package/docs/indexing/environment-variables.md +77 -0
  171. package/docs/indexing/performance.md +323 -0
  172. package/docs/indexing/resume.md +345 -0
  173. package/docs/indexing/troubleshooting.md +391 -0
  174. package/docs/man/bb.1 +190 -0
  175. package/docs/tools/bb_analyze.md +147 -0
  176. package/docs/tools/bb_annotate.md +110 -0
  177. package/docs/tools/bb_annotations.md +106 -0
  178. package/docs/tools/bb_ask.md +101 -0
  179. package/docs/tools/bb_cross_language.md +103 -0
  180. package/docs/tools/bb_doc.md +169 -0
  181. package/docs/tools/bb_edit.md +185 -0
  182. package/docs/tools/bb_graph.md +169 -0
  183. package/docs/tools/bb_health.md +156 -0
  184. package/docs/tools/bb_impact.md +117 -0
  185. package/docs/tools/bb_index.md +108 -0
  186. package/docs/tools/bb_migrate.md +135 -0
  187. package/docs/tools/bb_patterns.md +140 -0
  188. package/docs/tools/bb_search.md +150 -0
  189. package/docs/tools/bb_security.md +100 -0
  190. package/docs/tools/bb_visualize.md +184 -0
  191. package/grammars/README.md +57 -0
  192. package/grammars/THIRD-PARTY-NOTICES.md +50 -0
  193. package/grammars/tree-sitter-c/LICENSE +21 -0
  194. package/grammars/tree-sitter-clojure/LICENSE.md +21 -0
  195. package/grammars/tree-sitter-cpp/LICENSE +21 -0
  196. package/grammars/tree-sitter-csharp/LICENSE +21 -0
  197. package/grammars/tree-sitter-css/LICENSE +21 -0
  198. package/grammars/tree-sitter-css/README.md +21 -0
  199. package/grammars/tree-sitter-dart/LICENSE +20 -0
  200. package/grammars/tree-sitter-dart-upstream/LICENSE +20 -0
  201. package/grammars/tree-sitter-dart-upstream/README.md +18 -0
  202. package/grammars/tree-sitter-elixir/LICENSE +176 -0
  203. package/grammars/tree-sitter-elixir/README.md +11 -0
  204. package/grammars/tree-sitter-fsharp/LICENSE +21 -0
  205. package/grammars/tree-sitter-fsharp/README.md +45 -0
  206. package/grammars/tree-sitter-graphql/LICENSE +21 -0
  207. package/grammars/tree-sitter-graphql/README.md +106 -0
  208. package/grammars/tree-sitter-groovy/LICENSE +21 -0
  209. package/grammars/tree-sitter-groovy/README.md +4 -0
  210. package/grammars/tree-sitter-haskell/LICENSE +21 -0
  211. package/grammars/tree-sitter-haskell/README.md +394 -0
  212. package/grammars/tree-sitter-hcl/CHANGELOG.md +102 -0
  213. package/grammars/tree-sitter-hcl/LICENSE +201 -0
  214. package/grammars/tree-sitter-hcl/README.md +39 -0
  215. package/grammars/tree-sitter-html/LICENSE +21 -0
  216. package/grammars/tree-sitter-html/README.md +21 -0
  217. package/grammars/tree-sitter-julia/LICENSE +21 -0
  218. package/grammars/tree-sitter-julia/README.md +24 -0
  219. package/grammars/tree-sitter-kotlin/LICENSE +9 -0
  220. package/grammars/tree-sitter-lua/LICENSE.md +21 -0
  221. package/grammars/tree-sitter-lua/README.md +29 -0
  222. package/grammars/tree-sitter-make/LICENSE +21 -0
  223. package/grammars/tree-sitter-matlab/LICENSE +19 -0
  224. package/grammars/tree-sitter-matlab/README.md +99 -0
  225. package/grammars/tree-sitter-nim/LICENSE +373 -0
  226. package/grammars/tree-sitter-nim/README.md +46 -0
  227. package/grammars/tree-sitter-objc/LICENSE +21 -0
  228. package/grammars/tree-sitter-objc/README.md +20 -0
  229. package/grammars/tree-sitter-perl/LICENSE +7 -0
  230. package/grammars/tree-sitter-perl/README.md +100 -0
  231. package/grammars/tree-sitter-powershell/LICENSE +21 -0
  232. package/grammars/tree-sitter-powershell/README.md +7 -0
  233. package/grammars/tree-sitter-proto/LICENSE +21 -0
  234. package/grammars/tree-sitter-proto/README.md +105 -0
  235. package/grammars/tree-sitter-r/LICENSE +9 -0
  236. package/grammars/tree-sitter-r/README.md +66 -0
  237. package/grammars/tree-sitter-ruby/LICENSE +22 -0
  238. package/grammars/tree-sitter-scss/LICENSE +21 -0
  239. package/grammars/tree-sitter-scss/README.md +17 -0
  240. package/grammars/tree-sitter-solidity/LICENSE +7 -0
  241. package/grammars/tree-sitter-sql/LICENSE +21 -0
  242. package/grammars/tree-sitter-typescript/LICENSE +21 -0
  243. package/grammars/tree-sitter-vba/LICENSE +21 -0
  244. package/grammars/tree-sitter-vba/README.md +738 -0
  245. package/grammars/tree-sitter-vbnet/LICENSE +21 -0
  246. package/grammars/tree-sitter-vbnet/README.md +322 -0
  247. package/grammars/tree-sitter-xml/LICENSE +19 -0
  248. package/grammars/tree-sitter-yaml/LICENSE +20 -0
  249. package/grammars/tree-sitter-yaml/README.md +21 -0
  250. package/package.json +184 -4
  251. package/wasm/dart.wasm +0 -0
  252. package/wasm/tree-sitter-bash.wasm +0 -0
  253. package/wasm/tree-sitter-c.wasm +0 -0
  254. package/wasm/tree-sitter-c_sharp.wasm +0 -0
  255. package/wasm/tree-sitter-clean.wasm +0 -0
  256. package/wasm/tree-sitter-clojure.wasm +0 -0
  257. package/wasm/tree-sitter-core_schema.wasm +0 -0
  258. package/wasm/tree-sitter-cpp.wasm +0 -0
  259. package/wasm/tree-sitter-css.wasm +0 -0
  260. package/wasm/tree-sitter-dart.wasm +0 -0
  261. package/wasm/tree-sitter-elisp.wasm +0 -0
  262. package/wasm/tree-sitter-elixir.wasm +0 -0
  263. package/wasm/tree-sitter-elm.wasm +0 -0
  264. package/wasm/tree-sitter-embedded_template.wasm +0 -0
  265. package/wasm/tree-sitter-erlang.wasm +0 -0
  266. package/wasm/tree-sitter-fsharp.wasm +0 -0
  267. package/wasm/tree-sitter-fsharp_signature.wasm +0 -0
  268. package/wasm/tree-sitter-go.wasm +0 -0
  269. package/wasm/tree-sitter-graphql.wasm +0 -0
  270. package/wasm/tree-sitter-groovy.wasm +0 -0
  271. package/wasm/tree-sitter-haskell.wasm +0 -0
  272. package/wasm/tree-sitter-hcl.wasm +0 -0
  273. package/wasm/tree-sitter-html.wasm +0 -0
  274. package/wasm/tree-sitter-java.wasm +0 -0
  275. package/wasm/tree-sitter-javascript.wasm +0 -0
  276. package/wasm/tree-sitter-json.wasm +0 -0
  277. package/wasm/tree-sitter-json_schema.wasm +0 -0
  278. package/wasm/tree-sitter-julia.wasm +0 -0
  279. package/wasm/tree-sitter-kotlin.wasm +0 -0
  280. package/wasm/tree-sitter-lua.wasm +0 -0
  281. package/wasm/tree-sitter-make.wasm +0 -0
  282. package/wasm/tree-sitter-markdown.wasm +0 -0
  283. package/wasm/tree-sitter-markdown_inline.wasm +0 -0
  284. package/wasm/tree-sitter-matlab.wasm +0 -0
  285. package/wasm/tree-sitter-nim.wasm +0 -0
  286. package/wasm/tree-sitter-objc.wasm +0 -0
  287. package/wasm/tree-sitter-ocaml.wasm +0 -0
  288. package/wasm/tree-sitter-perl.wasm +0 -0
  289. package/wasm/tree-sitter-php.wasm +0 -0
  290. package/wasm/tree-sitter-php_only.wasm +0 -0
  291. package/wasm/tree-sitter-powershell.wasm +0 -0
  292. package/wasm/tree-sitter-protobuf.wasm +0 -0
  293. package/wasm/tree-sitter-python.wasm +0 -0
  294. package/wasm/tree-sitter-ql.wasm +0 -0
  295. package/wasm/tree-sitter-r.wasm +0 -0
  296. package/wasm/tree-sitter-rescript.wasm +0 -0
  297. package/wasm/tree-sitter-ruby.wasm +0 -0
  298. package/wasm/tree-sitter-rust.wasm +0 -0
  299. package/wasm/tree-sitter-scala.wasm +0 -0
  300. package/wasm/tree-sitter-scss.wasm +0 -0
  301. package/wasm/tree-sitter-solidity.wasm +0 -0
  302. package/wasm/tree-sitter-sql.wasm +0 -0
  303. package/wasm/tree-sitter-svelte.wasm +0 -0
  304. package/wasm/tree-sitter-swift.wasm +0 -0
  305. package/wasm/tree-sitter-systemrdl.wasm +0 -0
  306. package/wasm/tree-sitter-terraform.wasm +0 -0
  307. package/wasm/tree-sitter-tlaplus.wasm +0 -0
  308. package/wasm/tree-sitter-toml.wasm +0 -0
  309. package/wasm/tree-sitter-tsx.wasm +0 -0
  310. package/wasm/tree-sitter-typescript.wasm +0 -0
  311. package/wasm/tree-sitter-vba.wasm +0 -0
  312. package/wasm/tree-sitter-vbnet.wasm +0 -0
  313. package/wasm/tree-sitter-vue.wasm +0 -0
  314. package/wasm/tree-sitter-xml.wasm +0 -0
  315. package/wasm/tree-sitter-yaml.wasm +0 -0
  316. package/wasm/tree-sitter-zig.wasm +0 -0
  317. package/wasm/tree-sitter.wasm +0 -0
  318. package/wasm/tsx.wasm +0 -0
  319. package/wasm/typescript.wasm +0 -0
@@ -0,0 +1,1314 @@
1
+ // src/ast/project-index.ts
2
+ import * as fs from "fs";
3
+ var SOLIDITY_DECLARATION_SPEC = {
4
+ typeNodes: {
5
+ contract_declaration: "contract",
6
+ interface_declaration: "interface",
7
+ library_declaration: "library"
8
+ },
9
+ memberNodes: [
10
+ "function_definition",
11
+ "modifier_definition",
12
+ "constructor_definition",
13
+ "fallback_receive_definition",
14
+ "state_variable_declaration",
15
+ "struct_declaration",
16
+ "enum_declaration",
17
+ "event_definition",
18
+ "error_declaration"
19
+ ],
20
+ baseNodes: ["inheritance_specifier"]
21
+ };
22
+ var CPP_IDENT_RE = /^[A-Za-z_$][\w$]*$/;
23
+ var cppLeafOfPath = (text) => {
24
+ let s = text.trim();
25
+ const lt = s.indexOf("<");
26
+ if (lt > 0) s = s.slice(0, lt);
27
+ const cut = s.lastIndexOf("::");
28
+ const leaf = (cut >= 0 ? s.slice(cut + 2) : s).replace(/^[*&~\s]+/, "");
29
+ return CPP_IDENT_RE.test(leaf) ? leaf : "";
30
+ };
31
+ var cppDeclaratorName = (n, depth = 0) => {
32
+ if (!n || depth > 10) return "";
33
+ const t = n.type;
34
+ if (t === "identifier" || t === "field_identifier" || t === "type_identifier") return n.text.trim();
35
+ if (t === "qualified_identifier") return cppLeafOfPath(n.text);
36
+ if (t === "function_declarator" || t === "abstract_function_declarator" || t === "pointer_declarator" || t === "reference_declarator" || t === "array_declarator" || t === "init_declarator" || t === "parenthesized_declarator" || t === "attributed_declarator") {
37
+ return cppDeclaratorName(n.childForFieldName("declarator"), depth + 1);
38
+ }
39
+ if (t === "template_function" || t === "template_method") {
40
+ return cppDeclaratorName(n.childForFieldName("name"), depth + 1);
41
+ }
42
+ return "";
43
+ };
44
+ var cppDeclaredName = (n) => {
45
+ const t = n.type;
46
+ if (t === "class_specifier" || t === "struct_specifier" || t === "union_specifier" || t === "enum_specifier") {
47
+ const nameField = n.childForFieldName("name");
48
+ if (nameField) {
49
+ const direct = nameField.text.trim();
50
+ if (CPP_IDENT_RE.test(direct)) return direct;
51
+ const leaf = cppLeafOfPath(nameField.text);
52
+ if (leaf !== "") return leaf;
53
+ }
54
+ for (let i = 0; i < n.namedChildCount; i++) {
55
+ const c = n.namedChild(i);
56
+ if (c && (c.type === "type_identifier" || c.type === "identifier")) return c.text.trim();
57
+ }
58
+ return "";
59
+ }
60
+ if (t === "enumerator") {
61
+ const id = n.childForFieldName("name") ?? n.namedChild(0);
62
+ const name = id?.text.trim() ?? "";
63
+ return CPP_IDENT_RE.test(name) ? name : "";
64
+ }
65
+ if (t === "preproc_def" || t === "preproc_function_def") {
66
+ const id = n.childForFieldName("name") ?? n.namedChild(0);
67
+ const name = id?.text.trim() ?? "";
68
+ return CPP_IDENT_RE.test(name) ? name : "";
69
+ }
70
+ if (t === "alias_declaration" || t === "type_definition") {
71
+ return cppDeclaratorName(n.childForFieldName("declarator"));
72
+ }
73
+ return cppDeclaratorName(n.childForFieldName("declarator"));
74
+ };
75
+ var cppBaseNames = (n) => {
76
+ let clause = null;
77
+ for (let i = 0; i < n.namedChildCount; i++) {
78
+ const c = n.namedChild(i);
79
+ if (c && c.type === "base_class_clause") {
80
+ clause = c;
81
+ break;
82
+ }
83
+ }
84
+ if (!clause) return [];
85
+ const out = [];
86
+ for (let i = 0; i < clause.namedChildCount; i++) {
87
+ const c = clause.namedChild(i);
88
+ if (!c) continue;
89
+ const t = c.type;
90
+ if (t === "access_specifier" || t === "virtual") continue;
91
+ const leaf = t === "type_identifier" ? c.text.trim() : cppLeafOfPath(c.text);
92
+ if (leaf !== "") out.push(leaf);
93
+ }
94
+ return out;
95
+ };
96
+ var CPP_DECLARATION_SPEC = {
97
+ typeNodes: {
98
+ class_specifier: "class",
99
+ struct_specifier: "struct",
100
+ union_specifier: "union",
101
+ enum_specifier: "enum"
102
+ },
103
+ memberNodes: ["field_declaration", "function_definition", "declaration", "enumerator"],
104
+ // NO `baseNodes`: the cpp grammar's `base_class_clause` carries no `ancestor` field, so the
105
+ // baseNodes path reads nothing; `baseResolver` (called on the TYPE node) is the working half.
106
+ // A FUNCTION BODY IS A SCOPE. Without this, a local declared inside a body would be recorded as a
107
+ // PROJECT declaration — the fleet rule is that a local is not a project declaration (PY-7's closure
108
+ // correction). `function_definition` is also a member/nameOnly node: the node's OWN name is read
109
+ // with the OUTER scope count and only its children see the increment, which is exactly the
110
+ // behaviour `indexTree` documents for python.
111
+ scopeNodes: ["function_definition", "lambda_expression"],
112
+ // Free functions/prototypes and aliases are NAMES the index must carry; they get no DeclarationKind
113
+ // (the union has no "function" kind and inventing one is a vocabulary decision, not this patch).
114
+ nameOnlyNodes: ["function_definition", "declaration", "alias_declaration", "type_definition"],
115
+ nameOnlyIdentifierShaped: true,
116
+ nameResolver: cppDeclaredName,
117
+ baseResolver: cppBaseNames
118
+ };
119
+ function staticRubyConstantPath(n) {
120
+ if (!n) return null;
121
+ if (n.type === "constant") return n.text;
122
+ if (n.type === "scope_resolution") {
123
+ const scope = n.childForFieldName("scope");
124
+ const name = n.childForFieldName("name");
125
+ const left = staticRubyConstantPath(scope);
126
+ const right = name ? name.text : null;
127
+ if (left && right) return `${left}::${right}`;
128
+ return right ?? left ?? null;
129
+ }
130
+ return null;
131
+ }
132
+ var RUBY_DECLARATION_SPEC = {
133
+ typeNodes: { class: "class", module: "module" },
134
+ // `call` is listed for attr_*/alias_method/define_method ONLY; nameResolver returns "" for every other
135
+ // call, so a call that names nothing is not a member.
136
+ memberNodes: ["method", "singleton_method", "alias", "call"],
137
+ scopeNodes: ["method", "singleton_method", "block", "do_block", "lambda"],
138
+ nameOnlyNodes: ["assignment"],
139
+ mergeSameKindTypeDecls: true,
140
+ nameResolver: (node) => {
141
+ const t = node.type;
142
+ if (t === "class" || t === "module" || t === "method" || t === "singleton_method") {
143
+ return node.childForFieldName("name")?.text ?? "";
144
+ }
145
+ if (t === "alias") {
146
+ for (let i = 0; i < node.namedChildCount; i++) {
147
+ const c = node.namedChild(i);
148
+ if (c && (c.type === "identifier" || c.type === "method_identifier")) return c.text;
149
+ }
150
+ return "";
151
+ }
152
+ if (t === "assignment") {
153
+ const left = node.childForFieldName("left");
154
+ if (!left) return "";
155
+ const text = left.text;
156
+ if (text.length === 0) return "";
157
+ const c0 = text.charCodeAt(0);
158
+ return c0 >= 65 && c0 <= 90 ? text : "";
159
+ }
160
+ if (t === "call") {
161
+ const m = node.childForFieldName("method")?.text ?? "";
162
+ const args = node.childForFieldName("arguments");
163
+ const firstLiteral = () => {
164
+ if (!args || args.namedChildCount === 0) return "";
165
+ const a = args.namedChild(0);
166
+ if (!a) return "";
167
+ if (a.type === "simple_symbol") {
168
+ const t2 = a.text;
169
+ let k = 0;
170
+ while (k < t2.length && t2[k] === ":") k++;
171
+ return t2.slice(k);
172
+ }
173
+ if (a.type === "string") {
174
+ const t2 = a.text;
175
+ return t2.length >= 2 ? t2.slice(1, t2.length - 1) : "";
176
+ }
177
+ return "";
178
+ };
179
+ if (m === "attr_reader" || m === "attr_writer" || m === "attr_accessor" || m === "attr" || m === "alias_method" || m === "define_method") return firstLiteral();
180
+ return "";
181
+ }
182
+ return "";
183
+ },
184
+ baseResolver: (node) => {
185
+ if (node.type !== "class") return [];
186
+ const sup = node.childForFieldName("superclass");
187
+ const inner = sup ? sup.namedChild(0) : null;
188
+ const path = staticRubyConstantPath(inner);
189
+ return path ? [path] : [];
190
+ }
191
+ };
192
+ var TYPESCRIPT_DECLARATION_SPEC = {
193
+ typeNodes: {
194
+ class_declaration: "class",
195
+ interface_declaration: "interface",
196
+ enum_declaration: "enum",
197
+ type_alias_declaration: "class"
198
+ },
199
+ memberNodes: ["method_definition", "public_field_definition", "method_signature", "property_signature"],
200
+ memberNodesCallable: ["method_definition", "method_signature"],
201
+ // FS-P17's name-only channel, applied to the TS declarations whose names a TARGET WRITES but
202
+ // whose kind this index has no use for: a module-level function, a module/namespace header, and a
203
+ // top-level binding (`const cloneVNode = …`). The measured gap this closes: a workspace-package
204
+ // import (`import { cloneVNode } from "@scope/utils"`) names a free FUNCTION in another project
205
+ // file, and without these names the analyzer can prove the module is the project's own code but
206
+ // cannot prove the ITEM is declared — the handoff's B-class (55 edges at cap 50, more over the
207
+ // whole population) stayed unresolved on exactly that. `variable_declarator` brings the
208
+ // destructuring shapes with it, which is why the identifier-shape guard exists.
209
+ nameOnlyNodes: [
210
+ "function_declaration",
211
+ "generator_function_declaration",
212
+ "internal_module",
213
+ "module",
214
+ "variable_declarator"
215
+ ],
216
+ nameOnlyIdentifierShaped: true,
217
+ scopeNodes: ["function_declaration", "method_definition", "arrow_function", "function_expression"],
218
+ baseResolver: (node) => {
219
+ const out = [];
220
+ let heritage = null;
221
+ for (let i = 0; i < node.namedChildCount; i++) {
222
+ const c = node.namedChild(i);
223
+ if (c && c.type === "class_heritage") {
224
+ heritage = c;
225
+ break;
226
+ }
227
+ }
228
+ if (!heritage) return out;
229
+ const walk = (n) => {
230
+ if (n.type === "extends_clause") {
231
+ for (let i = 0; i < n.namedChildCount; i++) {
232
+ const c = n.namedChild(i);
233
+ if (!c) continue;
234
+ if (c.type === "identifier" || c.type === "type_identifier") out.push(c.text);
235
+ else if (c.type === "member_expression" || c.type === "nested_type_identifier") {
236
+ const leaf = c.childForFieldName("property") ?? c.namedChild(c.namedChildCount - 1);
237
+ if (leaf && leaf.text) out.push(leaf.text);
238
+ }
239
+ }
240
+ return;
241
+ }
242
+ for (let i = 0; i < n.namedChildCount; i++) {
243
+ const c = n.namedChild(i);
244
+ if (c) walk(c);
245
+ }
246
+ };
247
+ walk(heritage);
248
+ return out;
249
+ }
250
+ };
251
+ var JAVASCRIPT_DECLARATION_SPEC = {
252
+ typeNodes: {
253
+ class_declaration: "class"
254
+ },
255
+ memberNodes: ["method_definition", "field_definition"],
256
+ memberNodesCallable: ["method_definition"],
257
+ nameOnlyNodes: [
258
+ "function_declaration",
259
+ "generator_function_declaration",
260
+ "variable_declarator"
261
+ ],
262
+ nameOnlyIdentifierShaped: true,
263
+ // THE JS GRAMMAR NAMES A FIELD BY `property`, NOT BY `name` (`class C { x = 1 }` is
264
+ // field_definition { property: (property_identifier) }), so the generic `childForFieldName("name")`
265
+ // reads "" for every class field and the index held NO field members. Probed: `Panel => render` only,
266
+ // with `template` missing. Method names use `name`, so both fields are tried in that order.
267
+ nameResolver: (node) => node.childForFieldName("name")?.text ?? node.childForFieldName("property")?.text ?? "",
268
+ scopeNodes: [
269
+ "function_declaration",
270
+ "generator_function_declaration",
271
+ "method_definition",
272
+ "arrow_function",
273
+ "function_expression"
274
+ ],
275
+ baseResolver: (node) => {
276
+ const out = [];
277
+ let heritage = null;
278
+ for (let i = 0; i < node.namedChildCount; i++) {
279
+ const c = node.namedChild(i);
280
+ if (c && c.type === "class_heritage") {
281
+ heritage = c;
282
+ break;
283
+ }
284
+ }
285
+ if (!heritage) return out;
286
+ const walk = (n) => {
287
+ if (n.type === "class_heritage" || n.type === "extends_clause") {
288
+ for (let i = 0; i < n.namedChildCount; i++) {
289
+ const c = n.namedChild(i);
290
+ if (!c) continue;
291
+ if (c.type === "identifier" || c.type === "nested_identifier") out.push(c.text);
292
+ else if (c.type === "member_expression") {
293
+ const leaf = c.childForFieldName("property") ?? c.namedChild(c.namedChildCount - 1);
294
+ if (leaf && leaf.text) out.push(leaf.text);
295
+ } else if (c.type === "call_expression") {
296
+ const fn = c.childForFieldName("function");
297
+ if (fn && (fn.type === "identifier" || fn.type === "member_expression")) {
298
+ const leaf = fn.type === "member_expression" ? fn.childForFieldName("property") ?? fn.namedChild(fn.namedChildCount - 1) : fn;
299
+ if (leaf && leaf.text) out.push(leaf.text);
300
+ }
301
+ }
302
+ }
303
+ return;
304
+ }
305
+ for (let i = 0; i < n.namedChildCount; i++) {
306
+ const c = n.namedChild(i);
307
+ if (c) walk(c);
308
+ }
309
+ };
310
+ walk(heritage);
311
+ return out;
312
+ }
313
+ };
314
+ var PYTHON_DECLARATION_SPEC = {
315
+ typeNodes: {
316
+ class_definition: "class"
317
+ },
318
+ // Only functions are members. A class-level ASSIGNMENT is a member too, but it is not
319
+ // inheritable in the sense `overrides` describes — a class variable is not a method, and
320
+ // indexing it as one repeats PY-21 defect 4, where a base's class variable satisfied the
321
+ // "base declares this name" test and published fabricated overrides at 0.95. `memberNodesCallable`
322
+ // is left unset for the same reason: only callable members answer the question.
323
+ memberNodes: ["function_definition"],
324
+ scopeNodes: ["function_definition", "lambda"],
325
+ baseResolver: (node) => {
326
+ const out = [];
327
+ const sup = node.childForFieldName("superclasses");
328
+ if (!sup) return out;
329
+ for (let i = 0; i < sup.namedChildCount; i++) {
330
+ const c = sup.namedChild(i);
331
+ if (!c) continue;
332
+ if (c.type === "identifier") {
333
+ out.push(c.text);
334
+ } else if (c.type === "attribute") {
335
+ const leaf = c.childForFieldName("attribute") ?? c.namedChild(c.namedChildCount - 1);
336
+ if (leaf && leaf.text) out.push(leaf.text);
337
+ }
338
+ }
339
+ return out;
340
+ }
341
+ };
342
+ var DART_DECLARATION_SPEC = {
343
+ typeNodes: {
344
+ class_definition: "class",
345
+ mixin_declaration: "mixin",
346
+ extension_declaration: "extension",
347
+ extension_type_declaration: "extension_type",
348
+ enum_declaration: "enum",
349
+ // A `type_alias` IS A TYPE DECLARATION IN DART — `typedef ListMixin<E> = ListBase<E>;`
350
+ // DECLARES the name `ListMixin` for the whole library. The SDK's own `ListMixin` and
351
+ // `SetMixin` are exactly this (`sdk/lib/collection/list.dart:586` and `set.dart:322`).
352
+ //
353
+ // WITHOUT THIS ENTRY THE INDEX HOLDS NOTHING FOR AN ALIAS, and the failure is a REFUTED
354
+ // CLAIM, not a missing row: a class that applies the alias (`class _BoolArrayList with
355
+ // ListMixin<bool>`) asks the index whether the base declares the member, the index says
356
+ // "no such base", the analyzer's first-parent fallback publishes "this base is OUTSIDE the
357
+ // project", and the arbiter REFUTES it because the project DOES publish the name — as an
358
+ // alias. MEASURED on the fixed production arm (2026-10-20): 25 refuted rows over 11
359
+ // distinct targets, every one of them a `ListMixin.*` or `SetMixin.*` member.
360
+ type_alias: "typedef"
361
+ },
362
+ // DART'S MIXIN NAMES LIVE IN A DIRECT `identifier` CHILD, NOT IN A `name` FIELD.
363
+ //
364
+ // MEASURED (dart-http, whole project, `--index` arm; the dart lane's diagnosis): the index's
365
+ // `typeKinds` census was `class 524 · extension_type 278 · extension 183 · enum 16 · unknown 11`
366
+ // — **mixin 0** — and `typeKinds.has("TerminatableMixin") === false`. The generic
367
+ // `childForFieldName("name")` reads "" for a `mixin_declaration`, because the grammar puts the
368
+ // name in a direct `identifier` child (`(mixin_declaration (mixin) (identifier) (class_body))`,
369
+ // probed). So the spec indexed the right SHAPE and held NOTHING for the name — the failure mode
370
+ // this file's own header names for a spec that does not match the grammar.
371
+ //
372
+ // THE COST WAS A CLAUSE-4 RED, and the arbiter was right: the analyzer's 0.8 first-parent
373
+ // fallback named the FIRST mixin in a `with A, B` clause, and `isExternalBase` ("the project does
374
+ // not publish this base") was REFUTED for every row whose base the project does publish. Measured
375
+ // 5 refuted rows on dart-http (all `TerminatableMixin.*`, whose member is declared by
376
+ // `ClosableMixin` — the SECOND mixin), and 86 on the whole-population `--index` arm.
377
+ //
378
+ // The other Dart declarations DO have a `name` field, so the resolver returns it for them and
379
+ // changes nothing about them. This is the same `nameResolver` hook the ruby, F#, C++ and protobuf
380
+ // specs use for exactly this reason.
381
+ nameResolver: (node) => {
382
+ if (node.type === "mixin_declaration") {
383
+ for (let i = 0; i < node.namedChildCount; i++) {
384
+ const c = node.namedChild(i);
385
+ if (c && c.type === "identifier") return c.text;
386
+ }
387
+ return "";
388
+ }
389
+ if (node.type === "type_alias") {
390
+ let first = null;
391
+ for (let i = 0; i < node.namedChildCount; i++) {
392
+ const c = node.namedChild(i);
393
+ if (c && c.type === "type_identifier") {
394
+ first = c;
395
+ break;
396
+ }
397
+ }
398
+ return first ? first.text : "";
399
+ }
400
+ if (node.type === "operator_signature") {
401
+ const m = /operator\s*([^\s(]+)/.exec(node.text);
402
+ return m ? `operator ${m[1]}` : "operator";
403
+ }
404
+ return node.childForFieldName("name")?.text ?? "";
405
+ },
406
+ // Methods and accessors only. `getter_signature` and `setter_signature` count
407
+ // (Dart overrides both); constructors and fields do not.
408
+ memberNodes: [
409
+ "method_signature",
410
+ "function_signature",
411
+ "getter_signature",
412
+ "setter_signature",
413
+ "operator_signature"
414
+ ],
415
+ // NOT the class body. `typeNodes` already resets the member scope when it enters a
416
+ // declaration, so listing `class_body` here would put every direct member one scope
417
+ // deep and exclude precisely the members the index exists to record — measured: a
418
+ // Dart spec with `class_body` in scopeNodes indexed 9 types and ZERO members.
419
+ // What must be scopes are the BODIES a local function can hide inside, or a local
420
+ // `function_signature` would be indexed as a member of the enclosing class.
421
+ scopeNodes: ["function_body", "function_expression_body", "block"],
422
+ baseResolver: (node) => {
423
+ const out = [];
424
+ if (node.type === "type_alias") {
425
+ let last = null;
426
+ for (let i = 0; i < node.namedChildCount; i++) {
427
+ const c = node.namedChild(i);
428
+ if (c && c.type === "type_identifier") last = c;
429
+ }
430
+ if (last && last.text) out.push(last.text);
431
+ return out;
432
+ }
433
+ const pushLeaf = (group) => {
434
+ if (!group) return;
435
+ let last = null;
436
+ for (let i = 0; i < group.namedChildCount; i++) {
437
+ const c = group.namedChild(i);
438
+ if (c && c.type === "type_identifier") last = c;
439
+ }
440
+ if (last && last.text) out.push(last.text);
441
+ };
442
+ for (const c of node.namedChildren) {
443
+ if (!c) continue;
444
+ if (c.type === "superclass") {
445
+ for (const g of c.namedChildren) {
446
+ if (!g) continue;
447
+ if (g.type === "type_identifier") out.push(g.text);
448
+ else if (g.type === "superclass" || g.type === "mixin" || g.type === "interfaces") pushLeaf(g);
449
+ }
450
+ continue;
451
+ }
452
+ if (c.type === "type_identifier") {
453
+ out.push(c.text);
454
+ continue;
455
+ }
456
+ if (c.type === "interfaces" || c.type === "mixin_on_clause") pushLeaf(c);
457
+ }
458
+ return out;
459
+ }
460
+ };
461
+ var FSHARP_TYPE_NODES = {
462
+ // `anon_type_defn` is BOTH a class and an interface — see FSHARP_KIND_RESOLVER below, which is
463
+ // the whole reason the hook exists. The static entry is the CLASS reading, because a clause
464
+ // with a constructor is the shape that cannot be an interface, and it is what an index build
465
+ // with no resolver falls back to.
466
+ anon_type_defn: "class",
467
+ record_type_defn: "record",
468
+ union_type_defn: "union",
469
+ interface_type_defn: "interface",
470
+ enum_type_defn: "enum",
471
+ // An abbreviation (`type Address = int64<address>`) declares a NAME and no kind of its own —
472
+ // it IS whatever it aliases, which this index cannot see. `unknown` is therefore the accurate
473
+ // answer here rather than the evasive one it would be for a record.
474
+ type_abbrev_defn: "unknown",
475
+ delegate_type_defn: "unknown"
476
+ };
477
+ function fsharpKindResolver(node) {
478
+ if (node.type !== "anon_type_defn") return void 0;
479
+ let members = 0;
480
+ let sawBody = false;
481
+ const visit = (n) => {
482
+ for (const c of n.namedChildren) {
483
+ if (!c) continue;
484
+ if (FSHARP_TYPE_NODES[c.type] !== void 0) continue;
485
+ if (c.type === "member_defn") {
486
+ members++;
487
+ let abstract = false;
488
+ for (const inner of c.namedChildren) if (inner?.type === "member_signature") abstract = true;
489
+ if (!abstract) sawBody = true;
490
+ continue;
491
+ }
492
+ visit(c);
493
+ }
494
+ };
495
+ visit(node);
496
+ if (members === 0 || sawBody) return void 0;
497
+ for (const c of node.namedChildren) if (c?.type === "primary_constr_args") return void 0;
498
+ const parent = node.parent;
499
+ if (parent) {
500
+ for (const c of parent.namedChildren) {
501
+ if (c?.type === "attributes" && /\bAbstractClass\b/.test(c.text)) return void 0;
502
+ }
503
+ }
504
+ return "interface";
505
+ }
506
+ var SCSS_DECLARATION_SPEC = {
507
+ // The stylesheet root node IS the module declaration, and its name is the file's basename —
508
+ // which is what `nameFromFile` now makes true. The sentence that used to stand here said
509
+ // "(handled by the caller via file path)" and NO CALLER EVER PASSED IT, so the extraction was
510
+ // empty and this spec indexed nothing.
511
+ nameFromFile: true,
512
+ typeNodes: {
513
+ stylesheet: "module"
514
+ },
515
+ // Modules are the "types" — the file IS the module
516
+ nameOnlyNodes: ["use_statement", "forward_statement"],
517
+ // A Sass module's public surface is EXACTLY its top-level `$variables`, `@mixin`s and
518
+ // `@function`s — that is what `@use` binds. `declaration` is listed so a top-level `$x: …`
519
+ // becomes a member; the `nameResolver` below returns "" for any declaration whose
520
+ // property_name is not `$`-prefixed, so a plain `color: red` at the root is NOT a member.
521
+ // MEASURED before this list carried `declaration`: `bulma/sass/utilities/initial-variables.scss`
522
+ // has 65 top-level `$` declarations and the index recorded ZERO members for it, because a
523
+ // variable is a `declaration` node and no member channel named it.
524
+ memberNodes: ["mixin_statement", "function_statement", "declaration"],
525
+ memberNodesCallable: ["mixin_statement", "function_statement"],
526
+ // Scope nodes: a declaration inside a rule, a mixin/function body, or a control-flow block is
527
+ // LOCAL to that scope and is not part of the module's surface. `@media` is deliberately ABSENT
528
+ // for the reason the analyzer records: Sass gives a media query no new variable scope, so a
529
+ // root-level `@media { $x: 1 }` still assigns the module-level `$x`.
530
+ scopeNodes: ["mixin_statement", "function_statement", "if_statement", "each_statement", "for_statement", "while_statement", "rule_set"],
531
+ /**
532
+ * Read the member name in the spelling the analyzer PUBLISHES, so a cross-file consumer looks up
533
+ * the same string the declaring file would have published:
534
+ * `@mixin button` -> `button` (the analyzer's `mixinNames` key is the BARE name, and
535
+ * `@include ns.button` splits on the dot to reach it)
536
+ * `@function double`-> `double`
537
+ * `$brand: …` -> `$brand` (the analyzer publishes a variable as `$brand`, and a
538
+ * read edge targets `$brand`, so the `$` is load-bearing)
539
+ * Anything else (a plain `color: red` declaration, a selector) returns "" and is not a member.
540
+ */
541
+ nameResolver: (node) => {
542
+ const isPrivate = (published) => {
543
+ const bare = published.startsWith("$") ? published.slice(1) : published;
544
+ return bare.startsWith("-") || bare.startsWith("_");
545
+ };
546
+ if (node.type === "mixin_statement" || node.type === "function_statement") {
547
+ let bare = "";
548
+ const viaField = node.childForFieldName("name");
549
+ if (viaField) bare = viaField.text;
550
+ else {
551
+ for (let i = 0; i < node.namedChildCount; i++) {
552
+ const c = node.namedChild(i);
553
+ if (c && c.type === "identifier") {
554
+ bare = c.text;
555
+ break;
556
+ }
557
+ }
558
+ }
559
+ return bare !== "" && !isPrivate(bare) ? bare : "";
560
+ }
561
+ if (node.type === "declaration") {
562
+ for (let i = 0; i < node.namedChildCount; i++) {
563
+ const c = node.namedChild(i);
564
+ if (c && c.type === "property_name") {
565
+ if (!c.text.startsWith("$")) return "";
566
+ return isPrivate(c.text) ? "" : c.text;
567
+ }
568
+ }
569
+ return "";
570
+ }
571
+ return node.childForFieldName("name")?.text ?? "";
572
+ }
573
+ };
574
+ var javaTypeOwnName = (n) => {
575
+ if (n.type === "type_identifier") return n.text.trim();
576
+ let last = "";
577
+ const walk = (x) => {
578
+ if (x.type === "type_arguments") return;
579
+ if (x.type === "type_identifier") {
580
+ last = x.text.trim();
581
+ return;
582
+ }
583
+ for (let i = 0; i < x.namedChildCount; i++) {
584
+ const c = x.namedChild(i);
585
+ if (c) walk(c);
586
+ }
587
+ };
588
+ walk(n);
589
+ return last;
590
+ };
591
+ var javaBaseNames = (n) => {
592
+ const out = [];
593
+ const push = (name) => {
594
+ if (name === "" || out.includes(name)) return;
595
+ out.push(name);
596
+ };
597
+ for (let i = 0; i < n.childCount; i++) {
598
+ const clause = n.child(i);
599
+ if (!clause) continue;
600
+ if (clause.type === "superclass") {
601
+ for (let j = 0; j < clause.childCount; j++) {
602
+ const c = clause.child(j);
603
+ if (!c || c.type === "extends" || c.type === "implements") continue;
604
+ push(javaTypeOwnName(c));
605
+ }
606
+ continue;
607
+ }
608
+ if (clause.type === "super_interfaces" || clause.type === "extends_interfaces") {
609
+ for (let j = 0; j < clause.childCount; j++) {
610
+ const c = clause.child(j);
611
+ if (!c || c.type === "implements" || c.type === "extends") continue;
612
+ if (c.type === "type_list") {
613
+ for (let k = 0; k < c.namedChildCount; k++) {
614
+ const t = c.namedChild(k);
615
+ if (t) push(javaTypeOwnName(t));
616
+ }
617
+ continue;
618
+ }
619
+ push(javaTypeOwnName(c));
620
+ }
621
+ }
622
+ }
623
+ return out;
624
+ };
625
+ var JAVA_DECLARATION_SPEC = {
626
+ typeNodes: {
627
+ class_declaration: "class",
628
+ interface_declaration: "interface",
629
+ enum_declaration: "enum",
630
+ annotation_type_declaration: "interface",
631
+ record_declaration: "record"
632
+ },
633
+ memberNodes: ["method_declaration", "field_declaration", "constructor_declaration", "enum_constant", "annotation_type_element_declaration"],
634
+ memberNodesCallable: ["method_declaration", "constructor_declaration"],
635
+ // NO `baseNodes`: tree-sitter-java's `superclass` node carries the base as an UNLABELLED child and
636
+ // has no `ancestor` field, so the baseNodes path read nothing and java's `typeBases` was EMPTY
637
+ // (measured: 0 over clojure's 190 files and grails-core's 1,942). `baseResolver` — called on the
638
+ // TYPE node — is the working half, exactly as it is for cpp.
639
+ baseResolver: javaBaseNames,
640
+ qualifyTypeWithFile: true
641
+ };
642
+ var FSHARP_DECLARATION_SPEC = {
643
+ typeNodes: FSHARP_TYPE_NODES,
644
+ kindResolver: fsharpKindResolver,
645
+ // FS-P17, the two named channels. `function_or_value_defn` is F#'s binding node (`let f x = …`,
646
+ // `let value = 3`) and its identity is the name the analyzer already PUBLISHES for a top-level
647
+ // binding; `module_defn` and `namespace` are the scope headers, and the analyzer publishes those
648
+ // as the whole dotted header too (`module Fixture.Project.Domain` names its symbol
649
+ // `Fixture.Project.Domain`). Both are recorded WITHOUT a kind — see `nameOnlyNodes`.
650
+ // `named_module` is the FILE-HEADER form (`module Alpha.Beta.Gamma` as the first line) and it is
651
+ // a DIFFERENT node from `module_defn` entirely — found by dumping the tree, not by reading the
652
+ // grammar's docs. It is also the most important entry in this list: it is how most F# files
653
+ // declare their module, and its name is what another file writes targets against.
654
+ nameOnlyNodes: ["function_or_value_defn", "module_defn", "namespace", "named_module"],
655
+ // `member this.Speak() = …`, `override this.Speak() = …` and `abstract member Tag : …` are all
656
+ // `member_defn` — which is exactly the callable surface `overrides` reads. F# properties are
657
+ // accessors and ARE overridable, so a `member this.Tag` counts; fields are not listed because
658
+ // they cannot be overridden, the same reasoning PY-21 and DARTD16 record for their grammars.
659
+ memberNodes: ["member_defn"],
660
+ memberNodesCallable: ["member_defn"],
661
+ // A member inside an OBJECT EXPRESSION belongs to the anonymous implementation, not to the
662
+ // function that encloses it. The fixture has the shape: `let mock = { new System.IDisposable
663
+ // with override this.Dispose() = () … }` — without this, `Dispose` and `Tag` are published as
664
+ // members of whatever type the `let` sits in.
665
+ // FS-P17 adds TWO scope nodes to the object expression, and the second one is a defect the first
666
+ // draft of this channel shipped rather than a refinement of it. Measured on the lane's own twelve
667
+ // fixtures (`/tmp/fs-names.mts`): with only `function_or_value_defn` as a scope, the NAME-ONLY
668
+ // list contained `local` (declared at `call-ownership.fs:67` inside a member body) and `built`
669
+ // (`call-target-spelling.fs:63`, the same shape) — a local declared in a project DECLARATION, so
670
+ // every bare call to a name that happens to match a local anywhere in the corpus would be
671
+ // refined to `in-project-name`. The reason the first draft missed it: a scope node suppresses its
672
+ // CHILDREN, and a `let` directly inside a member body has no `function_or_value_defn` ABOVE it —
673
+ // the binding IS the node being visited, so `scopes` was still 0. `member_defn` is what starts
674
+ // the scope where a body begins.
675
+ //
676
+ // Both are scopes for MEMBERS as well as for names: a member inside a nested binding belongs to
677
+ // the nested binding's object expression, not to the type around it. Neither changes the member
678
+ // attribution of the member itself — `scopes` is tested BEFORE this increment — which the spec
679
+ // fixture confirms by reading 22 types-with-members and the same member sets after the change.
680
+ scopeNodes: ["object_expression", "function_or_value_defn", "member_defn"],
681
+ nameResolver: (node) => {
682
+ if (node.type === "namespace" || node.type === "named_module") {
683
+ for (const c of node.namedChildren) {
684
+ if (c?.type === "long_identifier" || c?.type === "identifier") return c.text;
685
+ }
686
+ return "";
687
+ }
688
+ if (node.type === "module_defn") {
689
+ const ownName = (n) => {
690
+ const parts = [];
691
+ for (const c of n.namedChildren) {
692
+ if (c?.type === "identifier" || c?.type === "long_identifier") parts.push(c.text);
693
+ }
694
+ return parts.join(".");
695
+ };
696
+ const own = ownName(node);
697
+ if (own === "") return "";
698
+ const chain = [own];
699
+ let p = node.parent;
700
+ while (p) {
701
+ if (p.type === "module_defn") {
702
+ const outer = ownName(p);
703
+ if (outer !== "") chain.unshift(outer);
704
+ } else if (p.type === "namespace" || p.type === "named_module") {
705
+ for (const c of p.namedChildren) {
706
+ if (c?.type === "long_identifier" || c?.type === "identifier") {
707
+ chain.unshift(c.text);
708
+ break;
709
+ }
710
+ }
711
+ break;
712
+ }
713
+ p = p.parent;
714
+ }
715
+ return chain.join(".");
716
+ }
717
+ if (node.type === "function_or_value_defn") {
718
+ for (const c of node.namedChildren) {
719
+ if (c?.type !== "function_declaration_left" && c?.type !== "value_declaration_left") continue;
720
+ const idents = [];
721
+ const stack = [c];
722
+ while (stack.length > 0) {
723
+ const n = stack.shift();
724
+ if (n.type === "identifier" && n.text) idents.push(n.text);
725
+ for (const inner of n.namedChildren) if (inner) stack.push(inner);
726
+ }
727
+ if (idents.length > 0) return idents[0];
728
+ }
729
+ return "";
730
+ }
731
+ for (const c of node.namedChildren) {
732
+ if (!c) continue;
733
+ if (c.type === "type_name") return c.childForFieldName("type_name")?.text ?? c.text;
734
+ if (c.type === "method_or_prop_defn") {
735
+ const method = c.childForFieldName("name")?.childForFieldName("method");
736
+ if (method?.text) return method.text;
737
+ }
738
+ if (c.type === "member_signature") {
739
+ for (const inner of c.namedChildren) {
740
+ if (inner && inner.type === "identifier" && inner.text) return inner.text;
741
+ }
742
+ }
743
+ }
744
+ return node.childForFieldName("name")?.text ?? "";
745
+ },
746
+ baseResolver: (node) => {
747
+ const out = [];
748
+ const pushLeaf = (n) => {
749
+ let written = "";
750
+ for (const c of n.namedChildren) {
751
+ if (!c) continue;
752
+ if (c.type === "long_identifier" || c.type === "identifier") {
753
+ written = c.text;
754
+ break;
755
+ }
756
+ }
757
+ if (written === "") written = n.text;
758
+ const segment = written.split(".").filter((s) => s.length > 0).pop() ?? "";
759
+ const clean = segment.replace(/[<(].*$/, "");
760
+ if (clean !== "") out.push(clean);
761
+ };
762
+ const visit = (n, isRoot) => {
763
+ for (const c of n.namedChildren) {
764
+ if (!c) continue;
765
+ if (c.type === "member_defn" || c.type === "object_expression") continue;
766
+ if (!isRoot && FSHARP_TYPE_NODES[c.type] !== void 0) continue;
767
+ if (c.type === "class_inherits_decl" || c.type === "interface_implementation") {
768
+ for (const inner of c.namedChildren) {
769
+ if (inner && inner.type === "simple_type") pushLeaf(inner);
770
+ }
771
+ continue;
772
+ }
773
+ visit(c, false);
774
+ }
775
+ };
776
+ visit(node, true);
777
+ return out;
778
+ }
779
+ };
780
+ var clojureExecutionHead = (list) => {
781
+ for (let i = 0; i < list.namedChildCount; i++) {
782
+ const child = list.namedChild(i);
783
+ if (child && child.type !== "comment" && child.type !== "dis_expr" && child.type !== "meta_lit") return child;
784
+ }
785
+ return null;
786
+ };
787
+ var clojureSymName = (node) => {
788
+ if (!node) return "";
789
+ if (node.type === "sym_lit") {
790
+ const name = node.childForFieldName("name");
791
+ const ns = node.childForFieldName("namespace");
792
+ const nsText = ns && (ns.text ?? "").startsWith("^{") ? ns.childForFieldName("name")?.text ?? ns.text : ns?.text ?? "";
793
+ if (name && nsText) return `${nsText}/${name.text}`;
794
+ if (name) return name.text;
795
+ return node.text;
796
+ }
797
+ return node.text;
798
+ };
799
+ var CLOJURE_DECLARATION_FORMS = /* @__PURE__ */ new Set([
800
+ "def",
801
+ "defn",
802
+ "defn-",
803
+ "defmacro",
804
+ "defonce",
805
+ "defmulti",
806
+ "defmethod",
807
+ "definterface",
808
+ "definline",
809
+ "defprotocol",
810
+ "defrecord",
811
+ "deftype",
812
+ "defstruct",
813
+ "declare",
814
+ "defvar"
815
+ ]);
816
+ var CLOJURE_TYPE_FORMS = /* @__PURE__ */ new Set([
817
+ "defprotocol",
818
+ "defrecord",
819
+ "deftype",
820
+ "definterface"
821
+ ]);
822
+ var clojureExecutableAfter = (list, after) => {
823
+ let seen = false;
824
+ for (let i = 0; i < list.namedChildCount; i++) {
825
+ const child = list.namedChild(i);
826
+ if (!child) continue;
827
+ if (child.type === "comment" || child.type === "dis_expr" || child.type === "meta_lit") continue;
828
+ if (!seen) {
829
+ if (child.id === after.id) seen = true;
830
+ continue;
831
+ }
832
+ return child;
833
+ }
834
+ return null;
835
+ };
836
+ var clojureFileNamespace = (node) => {
837
+ let root = node;
838
+ while (root.parent) root = root.parent;
839
+ for (let i = 0; i < root.namedChildCount; i++) {
840
+ const child = root.namedChild(i);
841
+ if (!child || child.type !== "list_lit") continue;
842
+ const head = clojureExecutionHead(child);
843
+ if (!head || head.type !== "sym_lit" || clojureSymName(head) !== "ns") continue;
844
+ const nameNode = clojureExecutableAfter(child, head);
845
+ if (!nameNode || nameNode.type !== "sym_lit") return "";
846
+ return clojureSymName(nameNode);
847
+ }
848
+ return "";
849
+ };
850
+ var clojureDeclarationName = (node, _fileName) => {
851
+ if (node.type !== "list_lit") return "";
852
+ const head = clojureExecutionHead(node);
853
+ if (!head || head.type !== "sym_lit") return "";
854
+ const ns = clojureFileNamespace(node);
855
+ const parent = node.parent;
856
+ if (parent && parent.type === "list_lit") {
857
+ const parentHead = clojureExecutionHead(parent);
858
+ if (parentHead && parentHead.type === "sym_lit" && CLOJURE_TYPE_FORMS.has(clojureSymName(parentHead))) {
859
+ const typeNode = clojureExecutableAfter(parent, parentHead);
860
+ const typeName = typeNode && typeNode.type === "sym_lit" ? clojureSymName(typeNode) : "";
861
+ const method = clojureSymName(head);
862
+ if (typeName === "" || method === "") return "";
863
+ return ns === "" ? method : `${ns}.${typeName}/${method}`;
864
+ }
865
+ }
866
+ if (!CLOJURE_DECLARATION_FORMS.has(clojureSymName(head))) return "";
867
+ const nameNode = clojureExecutableAfter(node, head);
868
+ if (!nameNode || nameNode.type !== "sym_lit") return "";
869
+ const name = clojureSymName(nameNode);
870
+ if (name === "") return "";
871
+ if (ns === "") return name;
872
+ const slash = name.lastIndexOf("/");
873
+ if (slash > 0) return `${ns}.${name.slice(0, slash)}/${name.slice(slash + 1)}`;
874
+ return `${ns}/${name}`;
875
+ };
876
+ var CLOJURE_DECLARATION_SPEC = {
877
+ typeNodes: {},
878
+ memberNodes: [],
879
+ nameOnlyNodes: ["list_lit"],
880
+ nameResolver: clojureDeclarationName
881
+ };
882
+ function addTo(map, key, value) {
883
+ let set = map.get(key);
884
+ if (!set) {
885
+ set = /* @__PURE__ */ new Set();
886
+ map.set(key, set);
887
+ }
888
+ set.add(value);
889
+ }
890
+ function indexTree(root, index, spec, fileName) {
891
+ const stack = [
892
+ { node: root, owner: null, scopes: 0 }
893
+ ];
894
+ const nameOf = (n) => spec.nameResolver !== void 0 ? spec.nameResolver(n, fileName) : n.childForFieldName("name")?.text ?? "";
895
+ while (stack.length > 0) {
896
+ const { node, owner, scopes } = stack.pop();
897
+ let nextOwner = owner;
898
+ let nextScopes = scopes + (spec.scopeNodes?.includes(node.type) ? 1 : 0);
899
+ const staticKind = spec.typeNodes[node.type];
900
+ let kind = staticKind;
901
+ if (staticKind !== void 0 && spec.kindResolver !== void 0) {
902
+ const resolved = spec.kindResolver(node);
903
+ if (resolved !== void 0) kind = resolved;
904
+ }
905
+ if (kind !== void 0) {
906
+ let name = nameOf(node);
907
+ if (name === "" && spec.nameFromFile === true && fileName !== void 0 && fileName !== "") {
908
+ name = fileName.split(/[\\/]/).pop() ?? "";
909
+ }
910
+ if (name !== "") {
911
+ if (spec.qualifyTypeWithFile === true && fileName !== void 0 && fileName !== "") {
912
+ const rel = fileName.split(/[\\/]/).filter((seg) => seg.length > 0);
913
+ rel.pop();
914
+ for (let i = 0; i < rel.length; i++) {
915
+ const prefix = rel.slice(i).join(".");
916
+ if (prefix === "") continue;
917
+ const qualified = `${prefix}.${name}`;
918
+ if (!index.typeKinds.has(qualified)) index.typeKinds.set(qualified, kind);
919
+ index.symbolNames.add(qualified);
920
+ index.symbolCounts.set(qualified, (index.symbolCounts.get(qualified) ?? 0) + 1);
921
+ }
922
+ }
923
+ const prior = index.typeKinds.get(name);
924
+ const reopened = prior !== void 0 && prior === kind && spec.mergeSameKindTypeDecls === true;
925
+ if (prior === void 0) index.typeKinds.set(name, kind);
926
+ else if (prior !== kind) index.typeKinds.set(name, "unknown");
927
+ index.symbolNames.add(name);
928
+ if (!reopened) index.symbolCounts.set(name, (index.symbolCounts.get(name) ?? 0) + 1);
929
+ nextOwner = name;
930
+ nextScopes = 0;
931
+ }
932
+ }
933
+ if (spec.nameOnlyNodes !== void 0 && scopes === 0 && spec.typeNodes[node.type] === void 0 && spec.nameOnlyNodes.includes(node.type)) {
934
+ const name = nameOf(node);
935
+ const identifierShaped = !spec.nameOnlyIdentifierShaped || /^[A-Za-z_$][A-Za-z0-9_$]*(\.[A-Za-z_$][A-Za-z0-9_$]*)*$/.test(name);
936
+ if (name !== "" && identifierShaped) {
937
+ index.symbolNames.add(name);
938
+ index.symbolCounts.set(name, (index.symbolCounts.get(name) ?? 0) + 1);
939
+ const dot = name.lastIndexOf(".");
940
+ if (dot > 0) {
941
+ const leaf = name.slice(dot + 1);
942
+ index.symbolNames.add(leaf);
943
+ index.symbolCounts.set(leaf, (index.symbolCounts.get(leaf) ?? 0) + 1);
944
+ }
945
+ }
946
+ }
947
+ if (owner !== null && scopes === 0 && spec.memberNodes.includes(node.type)) {
948
+ const name = nameOf(node);
949
+ if (name !== "") {
950
+ addTo(index.typeMembers, owner, name);
951
+ index.symbolNames.add(name);
952
+ }
953
+ }
954
+ if (owner !== null && spec.baseNodes?.includes(node.type)) {
955
+ const ownerName = index.typeKinds.has(owner) ? owner : null;
956
+ if (ownerName !== null) {
957
+ const anc = node.childForFieldName("ancestor");
958
+ let baseName = "";
959
+ if (anc) {
960
+ const stack2 = [anc];
961
+ let last = "";
962
+ while (stack2.length > 0) {
963
+ const n = stack2.pop();
964
+ if (n.type === "identifier") last = n.text;
965
+ for (let i = 0; i < n.namedChildCount; i++) {
966
+ const c = n.namedChild(i);
967
+ if (c) stack2.push(c);
968
+ }
969
+ }
970
+ baseName = last;
971
+ }
972
+ if (baseName !== "") {
973
+ let list = index.typeBases.get(ownerName);
974
+ if (!list) {
975
+ list = [];
976
+ index.typeBases.set(ownerName, list);
977
+ }
978
+ if (!list.includes(baseName)) list.push(baseName);
979
+ }
980
+ }
981
+ }
982
+ if (spec.baseResolver !== void 0 && kind !== void 0) {
983
+ const ownerName = nameOf(node);
984
+ if (ownerName !== "") {
985
+ for (const baseName of spec.baseResolver(node)) {
986
+ if (baseName === "") continue;
987
+ let list = index.typeBases.get(ownerName);
988
+ if (!list) {
989
+ list = [];
990
+ index.typeBases.set(ownerName, list);
991
+ }
992
+ if (!list.includes(baseName)) list.push(baseName);
993
+ }
994
+ }
995
+ }
996
+ for (let i = 0; i < node.namedChildCount; i++) {
997
+ const c = node.namedChild(i);
998
+ if (c) stack.push({ node: c, owner: nextOwner, scopes: nextScopes });
999
+ }
1000
+ }
1001
+ }
1002
+ function emptyProjectIndex() {
1003
+ return {
1004
+ typeKinds: /* @__PURE__ */ new Map(),
1005
+ typeMembers: /* @__PURE__ */ new Map(),
1006
+ typeBases: /* @__PURE__ */ new Map(),
1007
+ symbolNames: /* @__PURE__ */ new Set(),
1008
+ modules: /* @__PURE__ */ new Set(),
1009
+ symbolCounts: /* @__PURE__ */ new Map(),
1010
+ damagedFiles: /* @__PURE__ */ new Set(),
1011
+ stats: { files: 0, damaged: 0 },
1012
+ // FALSE, NOT undefined: an empty index is the least complete index there is, and a reader that
1013
+ // trusts it would certify every bare name in the corpus as external.
1014
+ complete: false
1015
+ };
1016
+ }
1017
+ function buildProjectIndex(files, spec = SOLIDITY_DECLARATION_SPEC) {
1018
+ const index = emptyProjectIndex();
1019
+ for (const f of files) {
1020
+ index.stats.files++;
1021
+ index.modules.add(f.path);
1022
+ {
1023
+ const base = f.path.split(/[\\/]/).pop() ?? "";
1024
+ if (base !== "") {
1025
+ index.modules.add(base);
1026
+ const stem = base.replace(/\.[^.]+$/, "");
1027
+ if (stem !== "") index.modules.add(stem);
1028
+ }
1029
+ }
1030
+ if (f.tree.hasError) {
1031
+ index.stats.damaged++;
1032
+ index.damagedFiles.add(f.path);
1033
+ }
1034
+ indexTree(f.tree.rootNode, index, spec, f.path);
1035
+ }
1036
+ return index;
1037
+ }
1038
+ async function buildProjectIndexFromDisk(wasmPath, files, spec = SOLIDITY_DECLARATION_SPEC) {
1039
+ const WTS = await import("web-tree-sitter");
1040
+ await WTS.Parser.init();
1041
+ const language = await WTS.Language.load(fs.readFileSync(wasmPath));
1042
+ const parser = new WTS.Parser();
1043
+ parser.setLanguage(language);
1044
+ const parsed = [];
1045
+ for (const f of files) {
1046
+ const text = fs.readFileSync(f, "utf8");
1047
+ const tree = parser.parse(text);
1048
+ if (tree === null) throw new Error(`project index: ${f} produced no parse tree`);
1049
+ parsed.push({ path: f, tree });
1050
+ }
1051
+ return buildProjectIndex(parsed, spec);
1052
+ }
1053
+ async function buildProjectIndexStreaming(wasmPath, files, spec = SOLIDITY_DECLARATION_SPEC, onProgress) {
1054
+ const WTS = await import("web-tree-sitter");
1055
+ await WTS.Parser.init();
1056
+ const language = await WTS.Language.load(fs.readFileSync(wasmPath));
1057
+ const parser = new WTS.Parser();
1058
+ parser.setLanguage(language);
1059
+ const index = emptyProjectIndex();
1060
+ let done = 0;
1061
+ let damaged = 0;
1062
+ const addModuleIdentity = (path) => {
1063
+ index.modules.add(path);
1064
+ const base = path.split(/[\\/]/).pop() ?? "";
1065
+ if (base !== "") {
1066
+ index.modules.add(base);
1067
+ const stem = base.replace(/\.[^.]+$/, "");
1068
+ if (stem !== "") index.modules.add(stem);
1069
+ }
1070
+ };
1071
+ for (const f of files) {
1072
+ let text;
1073
+ try {
1074
+ text = fs.readFileSync(f, "utf8");
1075
+ } catch {
1076
+ damaged++;
1077
+ index.damagedFiles.add(f);
1078
+ done++;
1079
+ continue;
1080
+ }
1081
+ addModuleIdentity(f);
1082
+ let tree = null;
1083
+ try {
1084
+ tree = parser.parse(text);
1085
+ if (tree?.rootNode) {
1086
+ indexTree(tree.rootNode, index, spec, f);
1087
+ if (tree.rootNode.hasError) index.damagedFiles.add(f);
1088
+ } else {
1089
+ damaged++;
1090
+ index.damagedFiles.add(f);
1091
+ }
1092
+ } catch {
1093
+ damaged++;
1094
+ index.damagedFiles.add(f);
1095
+ } finally {
1096
+ try {
1097
+ tree?.delete?.();
1098
+ } catch {
1099
+ }
1100
+ }
1101
+ done++;
1102
+ if (onProgress && done % 500 === 0) onProgress(done, files.length);
1103
+ }
1104
+ index.stats = { files: done - damaged, damaged };
1105
+ return index;
1106
+ }
1107
+ function buildResolutionTables(index) {
1108
+ const allMembers = /* @__PURE__ */ new Map();
1109
+ const memberOwners = /* @__PURE__ */ new Map();
1110
+ const memberDeclarer = /* @__PURE__ */ new Map();
1111
+ const memberDeclarers = /* @__PURE__ */ new Map();
1112
+ const closure = (typeName, seen = /* @__PURE__ */ new Set()) => {
1113
+ const cached = allMembers.get(typeName);
1114
+ if (cached) return cached;
1115
+ if (seen.has(typeName)) return /* @__PURE__ */ new Set();
1116
+ seen.add(typeName);
1117
+ const out = new Set(index.typeMembers.get(typeName) ?? []);
1118
+ for (const b of index.typeBases.get(typeName) ?? []) {
1119
+ for (const m of closure(b, seen)) out.add(m);
1120
+ }
1121
+ allMembers.set(typeName, out);
1122
+ return out;
1123
+ };
1124
+ const lineage = (typeName, seen = /* @__PURE__ */ new Set()) => {
1125
+ const out = /* @__PURE__ */ new Set();
1126
+ if (seen.has(typeName)) return out;
1127
+ seen.add(typeName);
1128
+ out.add(typeName);
1129
+ for (const b of index.typeBases.get(typeName) ?? []) {
1130
+ for (const t of lineage(b, seen)) out.add(t);
1131
+ }
1132
+ return out;
1133
+ };
1134
+ for (const typeName of index.typeKinds.keys()) {
1135
+ for (const m of closure(typeName)) addTo(memberOwners, m, typeName);
1136
+ }
1137
+ for (const [typeName, members] of index.typeMembers) {
1138
+ for (const m of members) memberDeclarers.set(m, (memberDeclarers.get(m) ?? 0) + 1);
1139
+ }
1140
+ for (const typeName of index.typeKinds.keys()) {
1141
+ const byName = /* @__PURE__ */ new Map();
1142
+ const line = lineage(typeName);
1143
+ for (const m of closure(typeName)) {
1144
+ let declarer = null;
1145
+ for (const t of line) {
1146
+ if (!(index.typeMembers.get(t)?.has(m) ?? false)) continue;
1147
+ if (declarer === null) declarer = t;
1148
+ else if (declarer !== t) {
1149
+ declarer = null;
1150
+ break;
1151
+ }
1152
+ }
1153
+ byName.set(m, declarer);
1154
+ }
1155
+ memberDeclarer.set(typeName, byName);
1156
+ }
1157
+ ;
1158
+ index.__closedMembers = allMembers;
1159
+ return { memberOwners, allMembers, memberDeclarer, memberDeclarers };
1160
+ }
1161
+ async function enrichWithProjectIndex(files, parse, spec = SOLIDITY_DECLARATION_SPEC, wasmPath) {
1162
+ let index;
1163
+ if (wasmPath) {
1164
+ index = await buildProjectIndexFromDisk(wasmPath, files, spec);
1165
+ } else {
1166
+ throw new Error(
1167
+ "enrichWithProjectIndex needs a wasmPath, or a caller-supplied index. Building the index requires a parser, and this module deliberately does not create one."
1168
+ );
1169
+ }
1170
+ buildResolutionTables(index);
1171
+ const results = [];
1172
+ for (const file of files) {
1173
+ results.push(await parse(file, { projectIndex: index }));
1174
+ }
1175
+ return { results, index };
1176
+ }
1177
+ function serializeProjectIndex(index) {
1178
+ if (index.__closedMembers === void 0) buildResolutionTables(index);
1179
+ return {
1180
+ version: 1,
1181
+ typeKinds: [...index.typeKinds.entries()],
1182
+ typeMembers: [...index.typeMembers.entries()].map(([k, v]) => [k, [...v]]),
1183
+ typeBases: [...index.typeBases.entries()].map(([k, v]) => [k, [...v]]),
1184
+ // A FIELD THE ANALYZER READS MUST SURVIVE THE WIRE. The index is built in the parent and
1185
+ // deserialised in every worker, so anything omitted here reads `undefined` at the only place it is
1186
+ // used -- the defect this file already records for `__closedMembers`.
1187
+ modules: [...index.modules],
1188
+ symbolCounts: [...index.symbolCounts.entries()],
1189
+ symbolNames: [...index.symbolNames],
1190
+ damagedFiles: [...index.damagedFiles],
1191
+ stats: { ...index.stats },
1192
+ // `=== true` rather than a truthy pass-through: nothing but the literal boolean true may
1193
+ // serialize as complete.
1194
+ complete: index.complete === true,
1195
+ closedMembers: [...index.__closedMembers?.entries() ?? []].map(([k, v]) => [k, [...v]])
1196
+ };
1197
+ }
1198
+ function deserializeProjectIndex(raw) {
1199
+ if (raw === null || typeof raw !== "object") return null;
1200
+ const r = raw;
1201
+ if (r.version !== 1) return null;
1202
+ if (!Array.isArray(r.typeKinds) || !Array.isArray(r.typeMembers) || !Array.isArray(r.typeBases) || !Array.isArray(r.symbolNames)) return null;
1203
+ const index = emptyProjectIndex();
1204
+ for (const [k, v] of r.typeKinds) index.typeKinds.set(k, v);
1205
+ for (const [k, v] of r.typeMembers) index.typeMembers.set(k, new Set(v));
1206
+ for (const [k, v] of r.typeBases) index.typeBases.set(k, [...v]);
1207
+ for (const n of r.symbolNames) index.symbolNames.add(n);
1208
+ for (const m of r.modules ?? []) index.modules.add(m);
1209
+ for (const [k, v] of r.symbolCounts ?? []) index.symbolCounts.set(k, v);
1210
+ for (const f of r.damagedFiles ?? []) index.damagedFiles.add(f);
1211
+ index.stats = { files: r.stats?.files ?? 0, damaged: r.stats?.damaged ?? 0 };
1212
+ index.complete = r.complete === true;
1213
+ if (Array.isArray(r.closedMembers)) {
1214
+ ;
1215
+ index.__closedMembers = new Map(r.closedMembers.map(([k, v]) => [k, new Set(v)]));
1216
+ }
1217
+ return index;
1218
+ }
1219
+ function roundTripProjectIndex(index) {
1220
+ const problems = [];
1221
+ const wire = JSON.parse(JSON.stringify(serializeProjectIndex(index)));
1222
+ const back = deserializeProjectIndex(wire);
1223
+ if (back === null) {
1224
+ problems.push("deserializeProjectIndex returned null for a well-formed payload");
1225
+ return problems;
1226
+ }
1227
+ if (back.typeKinds.size !== index.typeKinds.size) {
1228
+ problems.push(`typeKinds: ${back.typeKinds.size} of ${index.typeKinds.size}`);
1229
+ }
1230
+ if (back.symbolNames.size !== index.symbolNames.size) {
1231
+ problems.push(`symbolNames: ${back.symbolNames.size} of ${index.symbolNames.size}`);
1232
+ }
1233
+ if (back.typeMembers.size !== index.typeMembers.size) {
1234
+ problems.push(`typeMembers: ${back.typeMembers.size} of ${index.typeMembers.size}`);
1235
+ }
1236
+ if (back.typeBases.size !== index.typeBases.size) {
1237
+ problems.push(`typeBases: ${back.typeBases.size} of ${index.typeBases.size}`);
1238
+ }
1239
+ let memberTotal = 0;
1240
+ for (const [k, v] of index.typeMembers) {
1241
+ const got = back.typeMembers.get(k);
1242
+ if (got === void 0) {
1243
+ problems.push(`typeMembers lost the key ${k}`);
1244
+ continue;
1245
+ }
1246
+ if (got.size !== v.size) problems.push(`typeMembers[${k}]: ${got.size} of ${v.size}`);
1247
+ memberTotal += v.size;
1248
+ }
1249
+ for (const [k, v] of index.typeBases) {
1250
+ const got = back.typeBases.get(k);
1251
+ if (got === void 0) {
1252
+ problems.push(`typeBases lost the key ${k}`);
1253
+ continue;
1254
+ }
1255
+ if (got.length !== v.length) problems.push(`typeBases[${k}]: ${got.length} of ${v.length}`);
1256
+ }
1257
+ if (back.stats.files !== index.stats.files) problems.push("stats.files");
1258
+ if (back.stats.damaged !== index.stats.damaged) problems.push("stats.damaged");
1259
+ if (back.damagedFiles.size !== index.damagedFiles.size) problems.push("damagedFiles");
1260
+ {
1261
+ const before = index.__closedMembers;
1262
+ const after = back.__closedMembers;
1263
+ if ((before?.size ?? 0) !== (after?.size ?? 0)) {
1264
+ problems.push(`__closedMembers: ${after?.size ?? 0} of ${before?.size ?? 0}`);
1265
+ } else if (before !== void 0 && after !== void 0) {
1266
+ for (const [k, v] of before) {
1267
+ const got = after.get(k);
1268
+ if (got === void 0) {
1269
+ problems.push(`__closedMembers lost the key ${k}`);
1270
+ continue;
1271
+ }
1272
+ if (got.size !== v.size) problems.push(`__closedMembers[${k}]: ${got.size} of ${v.size}`);
1273
+ }
1274
+ }
1275
+ }
1276
+ const probe = index.typeMembers.keys().next().value;
1277
+ if (probe !== void 0) {
1278
+ const before = [...index.typeMembers.get(probe) ?? []].sort();
1279
+ const after = [...back.typeMembers.get(probe) ?? []].sort();
1280
+ if (JSON.stringify(before) !== JSON.stringify(after)) {
1281
+ problems.push(`typeMembers[${probe}] contents differ after the round trip`);
1282
+ }
1283
+ }
1284
+ return problems;
1285
+ }
1286
+
1287
+ export {
1288
+ SOLIDITY_DECLARATION_SPEC,
1289
+ CPP_DECLARATION_SPEC,
1290
+ RUBY_DECLARATION_SPEC,
1291
+ TYPESCRIPT_DECLARATION_SPEC,
1292
+ JAVASCRIPT_DECLARATION_SPEC,
1293
+ PYTHON_DECLARATION_SPEC,
1294
+ DART_DECLARATION_SPEC,
1295
+ SCSS_DECLARATION_SPEC,
1296
+ JAVA_DECLARATION_SPEC,
1297
+ FSHARP_DECLARATION_SPEC,
1298
+ clojureExecutionHead,
1299
+ clojureSymName,
1300
+ CLOJURE_DECLARATION_FORMS,
1301
+ clojureFileNamespace,
1302
+ clojureDeclarationName,
1303
+ CLOJURE_DECLARATION_SPEC,
1304
+ indexTree,
1305
+ emptyProjectIndex,
1306
+ buildProjectIndex,
1307
+ buildProjectIndexFromDisk,
1308
+ buildProjectIndexStreaming,
1309
+ buildResolutionTables,
1310
+ enrichWithProjectIndex,
1311
+ serializeProjectIndex,
1312
+ deserializeProjectIndex,
1313
+ roundTripProjectIndex
1314
+ };