@untangle-code/parser-registry 0.0.0-stage → 0.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 (345) hide show
  1. package/LICENSE +661 -0
  2. package/NOTICE +90 -0
  3. package/README.md +352 -2
  4. package/THIRD_PARTY_LICENSES.md +91 -0
  5. package/dist/boundaries/expression.d.ts +10 -0
  6. package/dist/boundaries/expression.d.ts.map +1 -0
  7. package/dist/boundaries/expression.js +95 -0
  8. package/dist/boundaries/expression.js.map +1 -0
  9. package/dist/boundaries/extract.d.ts +12 -0
  10. package/dist/boundaries/extract.d.ts.map +1 -0
  11. package/dist/boundaries/extract.js +259 -0
  12. package/dist/boundaries/extract.js.map +1 -0
  13. package/dist/boundaries/python.d.ts +6 -0
  14. package/dist/boundaries/python.d.ts.map +1 -0
  15. package/dist/boundaries/python.js +154 -0
  16. package/dist/boundaries/python.js.map +1 -0
  17. package/dist/index.d.ts +26 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +19 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/languages/astgrep-backend/adapter.d.ts +101 -0
  22. package/dist/languages/astgrep-backend/adapter.d.ts.map +1 -0
  23. package/dist/languages/astgrep-backend/adapter.js +130 -0
  24. package/dist/languages/astgrep-backend/adapter.js.map +1 -0
  25. package/dist/languages/astgrep-backend/index.d.ts +29 -0
  26. package/dist/languages/astgrep-backend/index.d.ts.map +1 -0
  27. package/dist/languages/astgrep-backend/index.js +28 -0
  28. package/dist/languages/astgrep-backend/index.js.map +1 -0
  29. package/dist/languages/astgrep-backend/lang/bash.d.ts +38 -0
  30. package/dist/languages/astgrep-backend/lang/bash.d.ts.map +1 -0
  31. package/dist/languages/astgrep-backend/lang/bash.js +42 -0
  32. package/dist/languages/astgrep-backend/lang/bash.js.map +1 -0
  33. package/dist/languages/astgrep-backend/lang/c.d.ts +33 -0
  34. package/dist/languages/astgrep-backend/lang/c.d.ts.map +1 -0
  35. package/dist/languages/astgrep-backend/lang/c.js +85 -0
  36. package/dist/languages/astgrep-backend/lang/c.js.map +1 -0
  37. package/dist/languages/astgrep-backend/lang/cpp.d.ts +27 -0
  38. package/dist/languages/astgrep-backend/lang/cpp.d.ts.map +1 -0
  39. package/dist/languages/astgrep-backend/lang/cpp.js +38 -0
  40. package/dist/languages/astgrep-backend/lang/cpp.js.map +1 -0
  41. package/dist/languages/astgrep-backend/lang/csharp.d.ts +24 -0
  42. package/dist/languages/astgrep-backend/lang/csharp.d.ts.map +1 -0
  43. package/dist/languages/astgrep-backend/lang/csharp.js +102 -0
  44. package/dist/languages/astgrep-backend/lang/csharp.js.map +1 -0
  45. package/dist/languages/astgrep-backend/lang/index.d.ts +29 -0
  46. package/dist/languages/astgrep-backend/lang/index.d.ts.map +1 -0
  47. package/dist/languages/astgrep-backend/lang/index.js +22 -0
  48. package/dist/languages/astgrep-backend/lang/index.js.map +1 -0
  49. package/dist/languages/astgrep-backend/lang/java.d.ts +26 -0
  50. package/dist/languages/astgrep-backend/lang/java.d.ts.map +1 -0
  51. package/dist/languages/astgrep-backend/lang/java.js +89 -0
  52. package/dist/languages/astgrep-backend/lang/java.js.map +1 -0
  53. package/dist/languages/astgrep-backend/lang/kotlin.d.ts +44 -0
  54. package/dist/languages/astgrep-backend/lang/kotlin.d.ts.map +1 -0
  55. package/dist/languages/astgrep-backend/lang/kotlin.js +94 -0
  56. package/dist/languages/astgrep-backend/lang/kotlin.js.map +1 -0
  57. package/dist/languages/astgrep-backend/lang/php.d.ts +23 -0
  58. package/dist/languages/astgrep-backend/lang/php.d.ts.map +1 -0
  59. package/dist/languages/astgrep-backend/lang/php.js +80 -0
  60. package/dist/languages/astgrep-backend/lang/php.js.map +1 -0
  61. package/dist/languages/astgrep-backend/lang/ruby.d.ts +37 -0
  62. package/dist/languages/astgrep-backend/lang/ruby.d.ts.map +1 -0
  63. package/dist/languages/astgrep-backend/lang/ruby.js +70 -0
  64. package/dist/languages/astgrep-backend/lang/ruby.js.map +1 -0
  65. package/dist/languages/astgrep-backend/lang/swift.d.ts +34 -0
  66. package/dist/languages/astgrep-backend/lang/swift.d.ts.map +1 -0
  67. package/dist/languages/astgrep-backend/lang/swift.js +86 -0
  68. package/dist/languages/astgrep-backend/lang/swift.js.map +1 -0
  69. package/dist/languages/astgrep-backend/languages.d.ts +55 -0
  70. package/dist/languages/astgrep-backend/languages.d.ts.map +1 -0
  71. package/dist/languages/astgrep-backend/languages.js +214 -0
  72. package/dist/languages/astgrep-backend/languages.js.map +1 -0
  73. package/dist/languages/astgrep-backend/napi.d.ts +71 -0
  74. package/dist/languages/astgrep-backend/napi.d.ts.map +1 -0
  75. package/dist/languages/astgrep-backend/napi.js +176 -0
  76. package/dist/languages/astgrep-backend/napi.js.map +1 -0
  77. package/dist/languages/astgrep-backend/syntax.d.ts +88 -0
  78. package/dist/languages/astgrep-backend/syntax.d.ts.map +1 -0
  79. package/dist/languages/astgrep-backend/syntax.js +180 -0
  80. package/dist/languages/astgrep-backend/syntax.js.map +1 -0
  81. package/dist/languages/index.d.ts +14 -0
  82. package/dist/languages/index.d.ts.map +1 -0
  83. package/dist/languages/index.js +37 -0
  84. package/dist/languages/index.js.map +1 -0
  85. package/dist/languages/javascript/index.d.ts +4 -0
  86. package/dist/languages/javascript/index.d.ts.map +1 -0
  87. package/dist/languages/javascript/index.js +7 -0
  88. package/dist/languages/javascript/index.js.map +1 -0
  89. package/dist/languages/jsx/index.d.ts +4 -0
  90. package/dist/languages/jsx/index.d.ts.map +1 -0
  91. package/dist/languages/jsx/index.js +7 -0
  92. package/dist/languages/jsx/index.js.map +1 -0
  93. package/dist/languages/prose/index.d.ts +53 -0
  94. package/dist/languages/prose/index.d.ts.map +1 -0
  95. package/dist/languages/prose/index.js +172 -0
  96. package/dist/languages/prose/index.js.map +1 -0
  97. package/dist/languages/prose/line-bytes.d.ts +31 -0
  98. package/dist/languages/prose/line-bytes.d.ts.map +1 -0
  99. package/dist/languages/prose/line-bytes.js +39 -0
  100. package/dist/languages/prose/line-bytes.js.map +1 -0
  101. package/dist/languages/python/create-adapter.d.ts +20 -0
  102. package/dist/languages/python/create-adapter.d.ts.map +1 -0
  103. package/dist/languages/python/create-adapter.js +9 -0
  104. package/dist/languages/python/create-adapter.js.map +1 -0
  105. package/dist/languages/python/index.d.ts +4 -0
  106. package/dist/languages/python/index.d.ts.map +1 -0
  107. package/dist/languages/python/index.js +6 -0
  108. package/dist/languages/python/index.js.map +1 -0
  109. package/dist/languages/python/profile.d.ts +36 -0
  110. package/dist/languages/python/profile.d.ts.map +1 -0
  111. package/dist/languages/python/profile.js +282 -0
  112. package/dist/languages/python/profile.js.map +1 -0
  113. package/dist/languages/python/signature.d.ts +53 -0
  114. package/dist/languages/python/signature.d.ts.map +1 -0
  115. package/dist/languages/python/signature.js +188 -0
  116. package/dist/languages/python/signature.js.map +1 -0
  117. package/dist/languages/python/table.d.ts +46 -0
  118. package/dist/languages/python/table.d.ts.map +1 -0
  119. package/dist/languages/python/table.js +88 -0
  120. package/dist/languages/python/table.js.map +1 -0
  121. package/dist/languages/shared/call-detection.d.ts +17 -0
  122. package/dist/languages/shared/call-detection.d.ts.map +1 -0
  123. package/dist/languages/shared/call-detection.js +86 -0
  124. package/dist/languages/shared/call-detection.js.map +1 -0
  125. package/dist/languages/shared/chunks.d.ts +28 -0
  126. package/dist/languages/shared/chunks.d.ts.map +1 -0
  127. package/dist/languages/shared/chunks.js +181 -0
  128. package/dist/languages/shared/chunks.js.map +1 -0
  129. package/dist/languages/shared/create-adapter.d.ts +11 -0
  130. package/dist/languages/shared/create-adapter.d.ts.map +1 -0
  131. package/dist/languages/shared/create-adapter.js +90 -0
  132. package/dist/languages/shared/create-adapter.js.map +1 -0
  133. package/dist/languages/shared/decisions.d.ts +45 -0
  134. package/dist/languages/shared/decisions.d.ts.map +1 -0
  135. package/dist/languages/shared/decisions.js +141 -0
  136. package/dist/languages/shared/decisions.js.map +1 -0
  137. package/dist/languages/shared/dialect.d.ts +18 -0
  138. package/dist/languages/shared/dialect.d.ts.map +1 -0
  139. package/dist/languages/shared/dialect.js +37 -0
  140. package/dist/languages/shared/dialect.js.map +1 -0
  141. package/dist/languages/shared/doc-binding.d.ts +26 -0
  142. package/dist/languages/shared/doc-binding.d.ts.map +1 -0
  143. package/dist/languages/shared/doc-binding.js +50 -0
  144. package/dist/languages/shared/doc-binding.js.map +1 -0
  145. package/dist/languages/shared/engine.d.ts +49 -0
  146. package/dist/languages/shared/engine.d.ts.map +1 -0
  147. package/dist/languages/shared/engine.js +317 -0
  148. package/dist/languages/shared/engine.js.map +1 -0
  149. package/dist/languages/shared/extract-symbols.d.ts +5 -0
  150. package/dist/languages/shared/extract-symbols.d.ts.map +1 -0
  151. package/dist/languages/shared/extract-symbols.js +31 -0
  152. package/dist/languages/shared/extract-symbols.js.map +1 -0
  153. package/dist/languages/shared/fingerprint.d.ts +7 -0
  154. package/dist/languages/shared/fingerprint.d.ts.map +1 -0
  155. package/dist/languages/shared/fingerprint.js +95 -0
  156. package/dist/languages/shared/fingerprint.js.map +1 -0
  157. package/dist/languages/shared/grammar-loader.d.ts +15 -0
  158. package/dist/languages/shared/grammar-loader.d.ts.map +1 -0
  159. package/dist/languages/shared/grammar-loader.js +48 -0
  160. package/dist/languages/shared/grammar-loader.js.map +1 -0
  161. package/dist/languages/shared/import-detection.d.ts +24 -0
  162. package/dist/languages/shared/import-detection.d.ts.map +1 -0
  163. package/dist/languages/shared/import-detection.js +138 -0
  164. package/dist/languages/shared/import-detection.js.map +1 -0
  165. package/dist/languages/shared/js-family-profile.d.ts +5 -0
  166. package/dist/languages/shared/js-family-profile.d.ts.map +1 -0
  167. package/dist/languages/shared/js-family-profile.js +179 -0
  168. package/dist/languages/shared/js-family-profile.js.map +1 -0
  169. package/dist/languages/shared/node-kinds.d.ts +78 -0
  170. package/dist/languages/shared/node-kinds.d.ts.map +1 -0
  171. package/dist/languages/shared/node-kinds.js +141 -0
  172. package/dist/languages/shared/node-kinds.js.map +1 -0
  173. package/dist/languages/shared/node-utils.d.ts +31 -0
  174. package/dist/languages/shared/node-utils.d.ts.map +1 -0
  175. package/dist/languages/shared/node-utils.js +89 -0
  176. package/dist/languages/shared/node-utils.js.map +1 -0
  177. package/dist/languages/shared/parse-diagnostics.d.ts +44 -0
  178. package/dist/languages/shared/parse-diagnostics.d.ts.map +1 -0
  179. package/dist/languages/shared/parse-diagnostics.js +64 -0
  180. package/dist/languages/shared/parse-diagnostics.js.map +1 -0
  181. package/dist/languages/shared/parse-limits.d.ts +24 -0
  182. package/dist/languages/shared/parse-limits.d.ts.map +1 -0
  183. package/dist/languages/shared/parse-limits.js +134 -0
  184. package/dist/languages/shared/parse-limits.js.map +1 -0
  185. package/dist/languages/shared/profile.d.ts +149 -0
  186. package/dist/languages/shared/profile.d.ts.map +1 -0
  187. package/dist/languages/shared/profile.js +9 -0
  188. package/dist/languages/shared/profile.js.map +1 -0
  189. package/dist/languages/shared/scope-model.d.ts +32 -0
  190. package/dist/languages/shared/scope-model.d.ts.map +1 -0
  191. package/dist/languages/shared/scope-model.js +2 -0
  192. package/dist/languages/shared/scope-model.js.map +1 -0
  193. package/dist/languages/shared/scope-naming.d.ts +20 -0
  194. package/dist/languages/shared/scope-naming.d.ts.map +1 -0
  195. package/dist/languages/shared/scope-naming.js +118 -0
  196. package/dist/languages/shared/scope-naming.js.map +1 -0
  197. package/dist/languages/shared/scope-signature.d.ts +14 -0
  198. package/dist/languages/shared/scope-signature.d.ts.map +1 -0
  199. package/dist/languages/shared/scope-signature.js +82 -0
  200. package/dist/languages/shared/scope-signature.js.map +1 -0
  201. package/dist/languages/shared/signature.d.ts +55 -0
  202. package/dist/languages/shared/signature.d.ts.map +1 -0
  203. package/dist/languages/shared/signature.js +147 -0
  204. package/dist/languages/shared/signature.js.map +1 -0
  205. package/dist/languages/shared/syntax.d.ts +115 -0
  206. package/dist/languages/shared/syntax.d.ts.map +1 -0
  207. package/dist/languages/shared/syntax.js +2 -0
  208. package/dist/languages/shared/syntax.js.map +1 -0
  209. package/dist/languages/shared/table-profile-decisions.d.ts +54 -0
  210. package/dist/languages/shared/table-profile-decisions.d.ts.map +1 -0
  211. package/dist/languages/shared/table-profile-decisions.js +245 -0
  212. package/dist/languages/shared/table-profile-decisions.js.map +1 -0
  213. package/dist/languages/shared/table-profile-module-facts.d.ts +29 -0
  214. package/dist/languages/shared/table-profile-module-facts.d.ts.map +1 -0
  215. package/dist/languages/shared/table-profile-module-facts.js +139 -0
  216. package/dist/languages/shared/table-profile-module-facts.js.map +1 -0
  217. package/dist/languages/shared/table-profile-queries.d.ts +27 -0
  218. package/dist/languages/shared/table-profile-queries.d.ts.map +1 -0
  219. package/dist/languages/shared/table-profile-queries.js +70 -0
  220. package/dist/languages/shared/table-profile-queries.js.map +1 -0
  221. package/dist/languages/shared/table-profile-scopes.d.ts +46 -0
  222. package/dist/languages/shared/table-profile-scopes.d.ts.map +1 -0
  223. package/dist/languages/shared/table-profile-scopes.js +180 -0
  224. package/dist/languages/shared/table-profile-scopes.js.map +1 -0
  225. package/dist/languages/shared/table-profile.d.ts +302 -0
  226. package/dist/languages/shared/table-profile.d.ts.map +1 -0
  227. package/dist/languages/shared/table-profile.js +125 -0
  228. package/dist/languages/shared/table-profile.js.map +1 -0
  229. package/dist/languages/shared/tree-sitter-types.d.ts +44 -0
  230. package/dist/languages/shared/tree-sitter-types.d.ts.map +1 -0
  231. package/dist/languages/shared/tree-sitter-types.js +2 -0
  232. package/dist/languages/shared/tree-sitter-types.js.map +1 -0
  233. package/dist/languages/structured-text/index.d.ts +48 -0
  234. package/dist/languages/structured-text/index.d.ts.map +1 -0
  235. package/dist/languages/structured-text/index.js +120 -0
  236. package/dist/languages/structured-text/index.js.map +1 -0
  237. package/dist/languages/tsx/index.d.ts +4 -0
  238. package/dist/languages/tsx/index.d.ts.map +1 -0
  239. package/dist/languages/tsx/index.js +7 -0
  240. package/dist/languages/tsx/index.js.map +1 -0
  241. package/dist/languages/typescript/index.d.ts +4 -0
  242. package/dist/languages/typescript/index.d.ts.map +1 -0
  243. package/dist/languages/typescript/index.js +7 -0
  244. package/dist/languages/typescript/index.js.map +1 -0
  245. package/dist/languages/vue/index.d.ts +21 -0
  246. package/dist/languages/vue/index.d.ts.map +1 -0
  247. package/dist/languages/vue/index.js +234 -0
  248. package/dist/languages/vue/index.js.map +1 -0
  249. package/dist/languages/vue/mapping.d.ts +11 -0
  250. package/dist/languages/vue/mapping.d.ts.map +1 -0
  251. package/dist/languages/vue/mapping.js +77 -0
  252. package/dist/languages/vue/mapping.js.map +1 -0
  253. package/dist/registry.d.ts +24 -0
  254. package/dist/registry.d.ts.map +1 -0
  255. package/dist/registry.js +42 -0
  256. package/dist/registry.js.map +1 -0
  257. package/dist/text/byte-offset-table.d.ts +27 -0
  258. package/dist/text/byte-offset-table.d.ts.map +1 -0
  259. package/dist/text/byte-offset-table.js +39 -0
  260. package/dist/text/byte-offset-table.js.map +1 -0
  261. package/package.json +125 -3
  262. package/src/boundaries/expression.ts +95 -0
  263. package/src/boundaries/extract.ts +307 -0
  264. package/src/boundaries/python.ts +181 -0
  265. package/src/index.ts +51 -0
  266. package/src/languages/__golden__/javascript-basic.json +32 -0
  267. package/src/languages/__golden__/tsx-basic.json +19 -0
  268. package/src/languages/__golden__/typescript-basic.json +37 -0
  269. package/src/languages/astgrep-backend/GRAMMARS.md +86 -0
  270. package/src/languages/astgrep-backend/README.md +112 -0
  271. package/src/languages/astgrep-backend/__golden__/bash-basic.sh +53 -0
  272. package/src/languages/astgrep-backend/__golden__/c-basic.c +64 -0
  273. package/src/languages/astgrep-backend/__golden__/cpp-basic.cpp +65 -0
  274. package/src/languages/astgrep-backend/__golden__/csharp-basic.cs +73 -0
  275. package/src/languages/astgrep-backend/__golden__/go-basic.go +93 -0
  276. package/src/languages/astgrep-backend/__golden__/java-basic.java +62 -0
  277. package/src/languages/astgrep-backend/__golden__/kotlin-basic.kt +58 -0
  278. package/src/languages/astgrep-backend/__golden__/php-basic.php +72 -0
  279. package/src/languages/astgrep-backend/__golden__/ruby-basic.rb +62 -0
  280. package/src/languages/astgrep-backend/__golden__/rust-basic.rs +82 -0
  281. package/src/languages/astgrep-backend/__golden__/swift-basic.swift +73 -0
  282. package/src/languages/astgrep-backend/adapter.ts +240 -0
  283. package/src/languages/astgrep-backend/index.ts +44 -0
  284. package/src/languages/astgrep-backend/lang/README.md +115 -0
  285. package/src/languages/astgrep-backend/lang/bash.ts +78 -0
  286. package/src/languages/astgrep-backend/lang/c.ts +119 -0
  287. package/src/languages/astgrep-backend/lang/cpp.ts +65 -0
  288. package/src/languages/astgrep-backend/lang/csharp.ts +125 -0
  289. package/src/languages/astgrep-backend/lang/index.ts +61 -0
  290. package/src/languages/astgrep-backend/lang/java.ts +115 -0
  291. package/src/languages/astgrep-backend/lang/kotlin.ts +136 -0
  292. package/src/languages/astgrep-backend/lang/php.ts +105 -0
  293. package/src/languages/astgrep-backend/lang/ruby.ts +105 -0
  294. package/src/languages/astgrep-backend/lang/swift.ts +118 -0
  295. package/src/languages/astgrep-backend/languages.ts +238 -0
  296. package/src/languages/astgrep-backend/napi.ts +261 -0
  297. package/src/languages/astgrep-backend/syntax.ts +242 -0
  298. package/src/languages/index.ts +53 -0
  299. package/src/languages/javascript/index.ts +9 -0
  300. package/src/languages/jsx/index.ts +9 -0
  301. package/src/languages/prose/index.ts +270 -0
  302. package/src/languages/prose/line-bytes.ts +52 -0
  303. package/src/languages/python/README.md +246 -0
  304. package/src/languages/python/__golden__/python-basic.json +44 -0
  305. package/src/languages/python/create-adapter.ts +29 -0
  306. package/src/languages/python/index.ts +8 -0
  307. package/src/languages/python/profile.ts +341 -0
  308. package/src/languages/python/signature.ts +183 -0
  309. package/src/languages/python/table.ts +135 -0
  310. package/src/languages/shared/__fixtures__/large-over-32kib.ts.txt +1207 -0
  311. package/src/languages/shared/call-detection.ts +112 -0
  312. package/src/languages/shared/chunks.ts +255 -0
  313. package/src/languages/shared/create-adapter.ts +136 -0
  314. package/src/languages/shared/decisions.ts +204 -0
  315. package/src/languages/shared/dialect.ts +55 -0
  316. package/src/languages/shared/doc-binding.ts +78 -0
  317. package/src/languages/shared/engine.ts +461 -0
  318. package/src/languages/shared/extract-symbols.ts +35 -0
  319. package/src/languages/shared/fingerprint.ts +99 -0
  320. package/src/languages/shared/grammar-loader.ts +67 -0
  321. package/src/languages/shared/import-detection.ts +154 -0
  322. package/src/languages/shared/js-family-profile.ts +246 -0
  323. package/src/languages/shared/node-kinds.ts +153 -0
  324. package/src/languages/shared/node-utils.ts +120 -0
  325. package/src/languages/shared/parse-diagnostics.ts +125 -0
  326. package/src/languages/shared/parse-limits.ts +147 -0
  327. package/src/languages/shared/profile.ts +184 -0
  328. package/src/languages/shared/scope-model.ts +43 -0
  329. package/src/languages/shared/scope-naming.ts +124 -0
  330. package/src/languages/shared/scope-signature.ts +108 -0
  331. package/src/languages/shared/signature.ts +149 -0
  332. package/src/languages/shared/syntax.ts +116 -0
  333. package/src/languages/shared/table-profile-decisions.ts +251 -0
  334. package/src/languages/shared/table-profile-module-facts.ts +177 -0
  335. package/src/languages/shared/table-profile-queries.ts +85 -0
  336. package/src/languages/shared/table-profile-scopes.ts +198 -0
  337. package/src/languages/shared/table-profile.ts +427 -0
  338. package/src/languages/shared/tree-sitter-types.ts +46 -0
  339. package/src/languages/structured-text/index.ts +192 -0
  340. package/src/languages/tsx/index.ts +9 -0
  341. package/src/languages/typescript/index.ts +9 -0
  342. package/src/languages/vue/index.ts +312 -0
  343. package/src/languages/vue/mapping.ts +93 -0
  344. package/src/registry.ts +61 -0
  345. package/src/text/byte-offset-table.ts +63 -0
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Swift (WP-86).
3
+ *
4
+ * WIE KOTLIN OHNE FELDNAMEN — mit denselben zwei Folgen (Signatur = erste
5
+ * Zeile, `IdentifierFact.role` immer `reference`); die Begruendung steht im
6
+ * Kopf von `kotlin.ts` und wird hier nicht wiederholt.
7
+ *
8
+ * ABBILDUNGEN: `class_declaration` traegt in Swift AUCH `struct`, `enum`,
9
+ * `actor` und `extension` — unterschieden ueber das Schluesselwortkind.
10
+ * `extension` -> `namespace`: eine Erweiterung ist kein neuer Typ, sondern ein
11
+ * benannter Ort fuer weitere Mitglieder eines bestehenden.
12
+ * `protocol_declaration` -> `interface`.
13
+ *
14
+ * ENTSCHEIDUNGSPUNKTE (spec.md §16.2/§16.3):
15
+ * - `guard_statement` zaehlt als `guard` — es IST die vorzeitige Rueckkehr,
16
+ * fuer die die Art gedacht ist (`guardKinds`).
17
+ * - `switch_entry` ist ein `case`; der `default`-Arm zaehlt nicht
18
+ * (`caseExcludeChildKinds: ["default_keyword"]`).
19
+ * - `catch_block` zaehlt als `catch`.
20
+ * - `??` zaehlt als `short_circuit`, nur erweitert.
21
+ * - `try?`/`try!` zaehlen NICHT: anders als Rusts `?` kehren sie nicht
22
+ * zurueck, sondern liefern `nil` beziehungsweise brechen ab. Der Zweig
23
+ * entsteht am `catch_block`, und der wird gezaehlt.
24
+ *
25
+ * EINE MESSGRENZE, AUSDRUECKLICH: `@ast-grep/lang-swift` steht bei Version
26
+ * 0.0.8. Geprueft ist die Grammatik an der Golden-Datei dieses Pakets
27
+ * (0 Fehlerknoten); an grossen echten Swift-Projekten ist sie hier NICHT
28
+ * erprobt.
29
+ */
30
+ import type { LanguageKindTable } from "../../shared/table-profile.js";
31
+ import type { AstGrepLanguageSource } from "../adapter.js";
32
+
33
+ export const SWIFT_SOURCE: AstGrepLanguageSource = {
34
+ languageName: "swift",
35
+ moduleName: "@ast-grep/lang-swift",
36
+ };
37
+
38
+ export const SWIFT_TABLE: LanguageKindTable = {
39
+ languageId: "swift",
40
+ extensions: [".swift"],
41
+ supportLevel: "deep",
42
+ commentKinds: ["comment", "multiline_comment"],
43
+ stringContainerKinds: ["line_string_literal", "multi_line_string_literal", "raw_string_literal"],
44
+ identifierLeafKinds: ["simple_identifier", "type_identifier", "self_expression"],
45
+ numberLeafKinds: ["integer_literal", "hex_literal", "oct_literal", "bin_literal", "real_literal"],
46
+ booleanLeafKinds: ["boolean_literal"],
47
+ nullLeafKinds: ["nil"],
48
+ scopes: [
49
+ {
50
+ kinds: ["class_declaration"],
51
+ scopeKind: "class",
52
+ nameKinds: ["type_identifier", "user_type"],
53
+ refine: [
54
+ { childKinds: ["enum"], scopeKind: "enum" },
55
+ { childKinds: ["extension"], scopeKind: "namespace" },
56
+ ],
57
+ },
58
+ {
59
+ kinds: ["protocol_declaration"],
60
+ scopeKind: "interface",
61
+ nameKinds: ["type_identifier"],
62
+ },
63
+ {
64
+ kinds: ["function_declaration", "protocol_function_declaration"],
65
+ scopeKind: "function",
66
+ nameKinds: ["simple_identifier"],
67
+ },
68
+ { kinds: ["init_declaration"], scopeKind: "constructor", nameKinds: ["init"] },
69
+ {
70
+ kinds: ["property_declaration"],
71
+ scopeKind: "property",
72
+ nameKindPath: ["pattern"],
73
+ nameKinds: ["simple_identifier"],
74
+ // Wie in Kotlin: `var i = 0` in einem Funktionsrumpf ist kein Symbol.
75
+ parentKinds: ["class_body", "protocol_body", "enum_class_body", "source_file"],
76
+ },
77
+ ],
78
+ decisions: {
79
+ ifKinds: ["if_statement"],
80
+ elseIfParentKinds: ["if_statement"],
81
+ guardKinds: ["guard_statement"],
82
+ loopKinds: ["for_statement", "while_statement", "repeat_while_statement"],
83
+ catchKinds: ["catch_block"],
84
+ ternaryKinds: ["ternary_expression"],
85
+ switchKinds: ["switch_statement"],
86
+ caseKinds: ["switch_entry"],
87
+ caseExcludeChildKinds: ["default_keyword"],
88
+ anonymousOperatorKinds: [
89
+ "conjunction_expression",
90
+ "disjunction_expression",
91
+ "nil_coalescing_expression",
92
+ ],
93
+ logicalAndOperators: ["&&"],
94
+ logicalOrOperators: ["||"],
95
+ shortCircuitOperators: ["??"],
96
+ jumpKinds: ["control_transfer_statement"],
97
+ blockKinds: ["statements"],
98
+ },
99
+ imports: {
100
+ kinds: ["import_declaration"],
101
+ pathKinds: ["identifier"],
102
+ },
103
+ calls: {
104
+ kinds: ["call_expression"],
105
+ memberKinds: ["navigation_expression"],
106
+ // Swift benutzt `call_expression` AUCH fuer Indexzugriffe: `items["a"]`
107
+ // waere sonst ein Aufruf von `items`. Nur ein Anhang, der mit `(` beginnt,
108
+ // ist ein Aufruf.
109
+ acceptCall: (node) => {
110
+ const last = node.children[node.children.length - 1];
111
+ return last !== undefined && last.text.trimStart().startsWith("(");
112
+ },
113
+ },
114
+ declarationParentKinds: [],
115
+ visibilityKinds: ["modifiers"],
116
+ visibilityWords: ["public", "internal", "fileprivate", "private", "open"],
117
+ fieldNames: ["name"],
118
+ };
@@ -0,0 +1,238 @@
1
+ /**
2
+ * Die Sprachtabellen des ast-grep-Backends.
3
+ *
4
+ * Jede Sprache ist EINE Tabelle (`shared/table-profile.ts`) plus die Angabe,
5
+ * aus welchem npm-Paket ihre Grammatik kommt. Kein Motor, keine
6
+ * Fallunterscheidung, keine zweite Traversierung. Wer eine Sprache
7
+ * hinzufuegt, schreibt eine Tabelle wie die beiden hier und eine
8
+ * Registrierungszeile in `languages/index.ts` — sonst nichts.
9
+ *
10
+ * DIE KNOTENARTEN SIND NACHGESEHEN, NICHT GERATEN: jede Zeichenkette hier
11
+ * stammt aus einem echten Baum, den `adapter.test.ts` mit demselben Quelltext
12
+ * wieder erzeugt. Wer eine Art aendert, ohne den Test zu bewegen, sieht es
13
+ * sofort.
14
+ *
15
+ * SPRACHPAKETE WERDEN EINZELN AUFGENOMMEN. Die 22 Sprachpakete von ast-grep
16
+ * belegen zusammen 450 MB; eine Sammelabhaengigkeit waere respektlos gegen
17
+ * jeden, der nur Go analysieren will.
18
+ */
19
+ import type { LanguageKindTable } from "../shared/table-profile.js";
20
+
21
+ import type { AstGrepLanguageSource } from "./adapter.js";
22
+
23
+ /** Sprachpakete, wie ast-grep sie kennt (Name) und npm sie liefert (Paket). */
24
+ export const GO_SOURCE: AstGrepLanguageSource = {
25
+ languageName: "go",
26
+ moduleName: "@ast-grep/lang-go",
27
+ };
28
+
29
+ export const RUST_SOURCE: AstGrepLanguageSource = {
30
+ languageName: "rust",
31
+ moduleName: "@ast-grep/lang-rust",
32
+ };
33
+
34
+ /**
35
+ * Go.
36
+ *
37
+ * Zwei Eigenheiten stehen in der Tabelle statt in einer Sonderbehandlung:
38
+ * - `else if` ist in Go ein `if_statement` DIREKT unter einem `if_statement`
39
+ * (kein `else_clause` wie in JS/Rust) — `elseIfParentKinds` sagt das.
40
+ * - Ein Rumpf ist `block > statement_list`; die Guard-Clause-Erkennung muss
41
+ * durch BEIDE Huellen hindurch (`blockKinds`).
42
+ * - Sichtbarkeit steht nicht im Baum, sondern im Namen: Go exportiert, was
43
+ * mit einem Grossbuchstaben beginnt.
44
+ */
45
+ export const GO_TABLE: LanguageKindTable = {
46
+ languageId: "go",
47
+ extensions: [".go"],
48
+ supportLevel: "deep",
49
+ commentKinds: ["comment"],
50
+ stringContainerKinds: ["interpreted_string_literal", "raw_string_literal", "rune_literal"],
51
+ identifierLeafKinds: [
52
+ "identifier",
53
+ "field_identifier",
54
+ "package_identifier",
55
+ "type_identifier",
56
+ "label_name",
57
+ ],
58
+ numberLeafKinds: ["int_literal", "float_literal", "imaginary_literal"],
59
+ booleanLeafKinds: ["true", "false"],
60
+ nullLeafKinds: ["nil"],
61
+ scopes: [
62
+ { kinds: ["function_declaration"], scopeKind: "function" },
63
+ {
64
+ kinds: ["method_declaration"],
65
+ scopeKind: "method",
66
+ qualifierField: "receiver",
67
+ qualifierNameKinds: ["type_identifier"],
68
+ },
69
+ { kinds: ["method_elem"], scopeKind: "method" },
70
+ {
71
+ kinds: ["type_spec"],
72
+ scopeKind: "type",
73
+ refine: [
74
+ { childKinds: ["struct_type"], scopeKind: "class" },
75
+ { childKinds: ["interface_type"], scopeKind: "interface" },
76
+ ],
77
+ },
78
+ ],
79
+ decisions: {
80
+ ifKinds: ["if_statement"],
81
+ elseIfParentKinds: ["if_statement"],
82
+ loopKinds: ["for_statement"],
83
+ switchKinds: ["expression_switch_statement", "type_switch_statement", "select_statement"],
84
+ // WP-86: `default_case` steht hier NICHT mehr. Gos `select` ist zwar kein
85
+ // C-`switch` — jeder `communication_case` ist ein echter, zur Laufzeit
86
+ // gewaehlter Zweig und zaehlt deshalb —, aber der `default`-Zweig ist in
87
+ // beiden Formen der Fall, der uebrig bleibt. Er eroeffnet keinen
88
+ // zusaetzlichen unabhaengigen Pfad: ein `switch` mit drei `case` und einem
89
+ // `default` hat DREI Entscheidungen, nicht vier. Vorher zaehlte er mit und
90
+ // jede Go-Datei mit `default` bekam eine zyklomatische Zahl zu viel.
91
+ caseKinds: ["expression_case", "type_case", "communication_case"],
92
+ binaryKinds: ["binary_expression"],
93
+ operatorField: "operator",
94
+ logicalAndOperators: ["&&"],
95
+ logicalOrOperators: ["||"],
96
+ jumpKinds: ["return_statement", "break_statement", "continue_statement", "goto_statement"],
97
+ blockKinds: ["block", "statement_list"],
98
+ consequenceField: "consequence",
99
+ alternativeField: "alternative",
100
+ },
101
+ imports: {
102
+ kinds: ["import_declaration"],
103
+ specKinds: ["import_spec"],
104
+ pathField: "path",
105
+ aliasField: "name",
106
+ },
107
+ calls: {
108
+ kinds: ["call_expression"],
109
+ functionField: "function",
110
+ argumentsField: "arguments",
111
+ memberKinds: ["selector_expression"],
112
+ },
113
+ declarationParentKinds: [
114
+ "function_declaration",
115
+ "method_declaration",
116
+ "method_elem",
117
+ "type_spec",
118
+ "const_spec",
119
+ "var_spec",
120
+ "import_spec",
121
+ "field_declaration",
122
+ ],
123
+ bodyField: "body",
124
+ isExported: (name) => /^\p{Lu}/u.test(name),
125
+ fieldNames: ["name"],
126
+ };
127
+
128
+ /**
129
+ * Rust.
130
+ *
131
+ * Auch hier stehen die Eigenheiten in der Tabelle:
132
+ * - Sichtbarkeit ist ein Knoten (`visibility_modifier`), kein Namensmuster.
133
+ * - `use a::b as c` und `use a::{b, c}` werden ausgepackt, sonst stuende der
134
+ * ganze Ausdruck als "Pfad" im Ergebnis.
135
+ * - `impl Counter { ... }` oeffnet einen Scope der Art `class`, damit
136
+ * Methoden `Counter.bump` heissen statt bloss `bump`. Dass eine Datei
137
+ * dadurch `Counter` zweimal fuehren kann (einmal `struct_item`, einmal
138
+ * `impl_item`), ist gewollt: es sind zwei Quelltextstellen, und die
139
+ * Scope-Kennungen unterscheiden sich ueber die Ordnungszahl.
140
+ *
141
+ * BEKANNTE GRENZE: eine `fn` in einem `impl`-Block wird als `function`
142
+ * gefuehrt, nicht als `method` — die Knotenart ist in beiden Faellen
143
+ * `function_item`, und die Tabelle entscheidet nach Knotenart. Das ist eine
144
+ * Ungenauigkeit in der Symbolart, keine im Bereich oder in der Metrik.
145
+ */
146
+ export const RUST_TABLE: LanguageKindTable = {
147
+ languageId: "rust",
148
+ extensions: [".rs"],
149
+ supportLevel: "deep",
150
+ commentKinds: ["line_comment", "block_comment"],
151
+ stringContainerKinds: ["string_literal", "raw_string_literal", "char_literal"],
152
+ identifierLeafKinds: [
153
+ "identifier",
154
+ "type_identifier",
155
+ "field_identifier",
156
+ "primitive_type",
157
+ "self",
158
+ "shorthand_field_identifier",
159
+ ],
160
+ numberLeafKinds: ["integer_literal", "float_literal"],
161
+ booleanLeafKinds: ["true", "false"],
162
+ scopes: [
163
+ { kinds: ["function_item"], scopeKind: "function" },
164
+ {
165
+ kinds: ["function_signature_item"],
166
+ scopeKind: "method",
167
+ ancestorKinds: ["trait_item"],
168
+ },
169
+ { kinds: ["struct_item", "union_item"], scopeKind: "class" },
170
+ { kinds: ["impl_item"], scopeKind: "class", nameField: "type" },
171
+ { kinds: ["trait_item"], scopeKind: "interface" },
172
+ { kinds: ["enum_item"], scopeKind: "enum" },
173
+ { kinds: ["type_item"], scopeKind: "type" },
174
+ { kinds: ["mod_item"], scopeKind: "namespace" },
175
+ ],
176
+ decisions: {
177
+ ifKinds: ["if_expression"],
178
+ elseIfParentKinds: ["else_clause"],
179
+ loopKinds: ["for_expression", "while_expression", "loop_expression"],
180
+ switchKinds: ["match_expression"],
181
+ // WP-86: gezaehlt wird das MUSTER, nicht der Arm — nur so ist der
182
+ // Auffangarm `_ => ...` zu erkennen (sein `match_pattern` besteht genau
183
+ // aus dem `_`). Er ist Rusts `default` und zaehlt nicht;
184
+ // `Some(_) => ...` zaehlt dagegen, weil es wirklich nur EINEN Fall abdeckt.
185
+ caseKinds: ["match_pattern"],
186
+ caseExcludeFirstChildText: "_",
187
+ // `Some(1) | Some(2)` ist eine Musteralternative — `DecisionKind`
188
+ // `pattern_alternative` existiert genau dafuer.
189
+ patternAlternativeKinds: ["or_pattern"],
190
+ // WP-86: der `?`-OPERATOR IST KONTROLLFLUSS — er kehrt bei `Err` sofort
191
+ // zurueck. Gezaehlt wird er KONSERVATIV als `short_circuit`, also nur
192
+ // ERWEITERT (spec.md §16.3), nicht klassisch (§16.2): `?` ist in
193
+ // idiomatischem Rust so haeufig wie ein Semikolon, und klassisch
194
+ // mitgezaehlt bekaeme jede Funktion, die drei Aufrufe weiterreicht,
195
+ // dieselbe Zahl wie eine mit drei `if`. Verschwiegen wird er nicht — die
196
+ // erweiterte Zahl zeigt ihn.
197
+ shortCircuitKinds: ["try_expression"],
198
+ binaryKinds: ["binary_expression"],
199
+ operatorField: "operator",
200
+ logicalAndOperators: ["&&"],
201
+ logicalOrOperators: ["||"],
202
+ jumpKinds: ["return_expression", "break_expression", "continue_expression"],
203
+ blockKinds: ["block"],
204
+ consequenceField: "consequence",
205
+ alternativeField: "alternative",
206
+ },
207
+ imports: {
208
+ kinds: ["use_declaration"],
209
+ pathField: "argument",
210
+ unwrap: [
211
+ { kinds: ["use_as_clause"], pathField: "path", aliasField: "alias" },
212
+ { kinds: ["scoped_use_list"], pathField: "path", namesField: "list" },
213
+ ],
214
+ },
215
+ calls: {
216
+ kinds: ["call_expression", "macro_invocation"],
217
+ functionField: "function",
218
+ argumentsField: "arguments",
219
+ memberKinds: ["field_expression", "scoped_identifier"],
220
+ },
221
+ declarationParentKinds: [
222
+ "function_item",
223
+ "function_signature_item",
224
+ "struct_item",
225
+ "enum_item",
226
+ "trait_item",
227
+ "mod_item",
228
+ "type_item",
229
+ "const_item",
230
+ "static_item",
231
+ "field_declaration",
232
+ "parameter",
233
+ ],
234
+ visibilityKinds: ["visibility_modifier"],
235
+ bodyField: "body",
236
+ isExported: (_name, node) => node.children.some((child) => child.type === "visibility_modifier"),
237
+ fieldNames: ["name", "type"],
238
+ };
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Der Zugang zu `@ast-grep/napi` — traege geladen, EINMAL registriert, und
3
+ * ohne stillen Ausfall.
4
+ *
5
+ * DREI EIGENHEITEN DIESER BIBLIOTHEK BESTIMMEN DIESE DATEI:
6
+ *
7
+ * 1. `registerDynamicLanguage` WIRKT GENAU EINMAL. Der zweite Aufruf wirft
8
+ * nicht — er registriert schweigend nichts, und jeder spaetere
9
+ * `parse("<sprache>", ...)` scheitert dann mit "not supported in napi".
10
+ * Also: EINE Registrierung, aufgeschoben bis zum ersten Parse einer
11
+ * dynamischen Sprache, mit ALLEN Sprachen, deren Adapter bis dahin
12
+ * angemeldet wurden. Wer danach noch eine Sprache anmeldet, bekommt einen
13
+ * Fehler statt einer stillen Wirkungslosigkeit ({@link registerAstGrepLanguage}).
14
+ *
15
+ * 2. EIN FEHLENDER PREBUILD SCHEITERT BEI DER INSTALLATION STILL. Die
16
+ * `postinstall` der `@ast-grep/lang-*`-Pakete faengt den Baufehler und
17
+ * endet mit Exit 0; npm/pnpm melden Erfolg. Erst `require("<paket>")
18
+ * .libraryPath` wirft — ein Getter. Die Sprachpakete liefern Prebuilds nur
19
+ * fuer macOS x64/arm64, Linux x64/arm64 (glibc) und Windows x64: auf
20
+ * Alpine (musl), Windows ARM64 und Windows ia32 gibt es KEINEN. Deshalb
21
+ * wird jede Sprache einzeln geprueft, der Ausfall benannt festgehalten
22
+ * ({@link astGrepLanguageStatus}) und beim Parsen als
23
+ * `grammar_unavailable` gemeldet — woraus der Aufrufer einen
24
+ * Skip-Ledger-Eintrag mit Grund baut (E4). Kein Adapter tut so, als haette
25
+ * er geparst.
26
+ *
27
+ * 3. `SgNode#id()` IST ADRESSABGELEITET. Innerhalb eines Prozesses taugt es
28
+ * zum Vergleich zweier Knoten, ueber Prozesse hinweg zu gar nichts. Es
29
+ * darf deshalb NIE in Ergebnisdaten stehen; genutzt wird es einzig in
30
+ * `syntax.ts`, um den Feldnamen des aktuellen Knotens zu bestimmen.
31
+ *
32
+ * Der Kern (`@ast-grep/napi`) bringt TypeScript, TSX, JavaScript, HTML und CSS
33
+ * fest eingebaut mit. Wir benutzen davon NICHTS: die JS/TS-Familie laeuft
34
+ * weiter ueber tree-sitter (Begruendung in `README.md` dieses Verzeichnisses).
35
+ */
36
+ import { createRequire } from "node:module";
37
+
38
+ import { AdapterParseError } from "@untangle-code/domain";
39
+
40
+ const require = createRequire(import.meta.url);
41
+
42
+ /** Die Knotenform von ast-grep, auf die Teilmenge reduziert, die wir benutzen. */
43
+ export interface SgNode {
44
+ id(): number;
45
+ kind(): string;
46
+ text(): string;
47
+ range(): { start: SgPos; end: SgPos };
48
+ isLeaf(): boolean;
49
+ isNamed(): boolean;
50
+ children(): SgNode[];
51
+ namedChildren(): SgNode[];
52
+ parent(): SgNode | null;
53
+ prev(): SgNode | null;
54
+ field(name: string): SgNode | null;
55
+ }
56
+
57
+ export interface SgPos {
58
+ /** 0-basierte Zeile. */
59
+ line: number;
60
+ /** 0-basierte Spalte, in UTF-16-Einheiten. */
61
+ column: number;
62
+ /**
63
+ * ENTGEGEN der Typdefinition von ast-grep ("byte offset") ein
64
+ * UTF-16-Offset — nachgemessen an Umlauten und Emoji. Die Umrechnung in
65
+ * Bytes macht ausschliesslich die `ByteOffsetTable`.
66
+ */
67
+ index: number;
68
+ }
69
+
70
+ export interface SgRoot {
71
+ root(): SgNode;
72
+ }
73
+
74
+ interface AstGrepModule {
75
+ parse(lang: string, source: string): SgRoot;
76
+ registerDynamicLanguage(langs: Record<string, LanguageRegistration>): void;
77
+ }
78
+
79
+ interface LanguageRegistration {
80
+ libraryPath: string;
81
+ extensions: string[];
82
+ languageSymbol?: string;
83
+ metaVarChar?: string;
84
+ expandoChar?: string;
85
+ }
86
+
87
+ /** Wie es einer angemeldeten Sprache ergangen ist. */
88
+ export type AstGrepLanguageStatus =
89
+ | { readonly state: "pending" }
90
+ | { readonly state: "available" }
91
+ | { readonly state: "unavailable"; readonly reason: string };
92
+
93
+ interface PendingLanguage {
94
+ /** Name, unter dem ast-grep die Sprache kennt (auch der `parse`-Parameter). */
95
+ languageName: string;
96
+ /** npm-Paket mit Prebuild und Registrierungsangaben. */
97
+ moduleName: string;
98
+ }
99
+
100
+ const pending = new Map<string, PendingLanguage>();
101
+ const status = new Map<string, AstGrepLanguageStatus>();
102
+ let registrationDone = false;
103
+ let cachedModule: AstGrepModule | undefined;
104
+
105
+ /**
106
+ * Meldet eine Sprache fuer die EINE spaetere Registrierung an. Kostet nichts:
107
+ * kein `require`, kein Laden einer Grammatik — genau wie die traege
108
+ * Registrierung der tree-sitter-Adapter (`registry.ts`).
109
+ */
110
+ export function registerAstGrepLanguage(languageName: string, moduleName: string): void {
111
+ const already = pending.get(languageName);
112
+ if (already !== undefined && already.moduleName === moduleName) {
113
+ // DIESELBE Sprache aus DEMSELBEN Paket ein zweites Mal anzumelden ist
114
+ // harmlos und passiert im Normalbetrieb: `createParserRegistry()` baut
115
+ // jedes Mal frische Adapter, und ein Prozess darf mehr als eine Registry
116
+ // haben (die CLI tut es je Befehl). Der Eintrag ist bereits da, die
117
+ // Registrierung enthaelt die Sprache also — hier ist NICHTS zu tun und
118
+ // nichts zu melden. Ohne diese Ausnahme warf die zweite Registry, obwohl
119
+ // ihre Sprachen samt und sonders verfuegbar waren (WP-86).
120
+ return;
121
+ }
122
+ if (registrationDone) {
123
+ // Nach der Registrierung ist die Liste unveraenderlich (Eigenheit 1 im
124
+ // Modulkopf). Ein spaeterer Eintrag waere wirkungslos — und wirkungslos
125
+ // und unbemerkt ist genau das, was E4 verbietet.
126
+ throw new AdapterParseError(
127
+ "grammar_unavailable",
128
+ `Sprache "${languageName}" was registered after the one-time ast-grep registration. ` +
129
+ `registerDynamicLanguage only takes effect on its first call; the language would silently remain unavailable.`,
130
+ );
131
+ }
132
+ pending.set(languageName, { languageName, moduleName });
133
+ status.set(languageName, { state: "pending" });
134
+ }
135
+
136
+ function loadModule(): AstGrepModule {
137
+ if (cachedModule === undefined) {
138
+ cachedModule = require("@ast-grep/napi") as AstGrepModule;
139
+ }
140
+ return cachedModule;
141
+ }
142
+
143
+ /**
144
+ * Fuehrt die EINE Registrierung aus (idempotent). Jede Sprache, deren Paket
145
+ * fehlt oder deren Prebuild nicht gebaut wurde, faellt hier mit BENANNTEM
146
+ * Grund heraus, statt erst beim Parsen unverstaendlich zu scheitern.
147
+ */
148
+ function ensureRegistered(): AstGrepModule {
149
+ const napi = loadModule();
150
+ if (registrationDone) return napi;
151
+ registrationDone = true;
152
+
153
+ const registrations: Record<string, LanguageRegistration> = {};
154
+ for (const language of pending.values()) {
155
+ try {
156
+ const registration = require(language.moduleName) as LanguageRegistration;
157
+ // `libraryPath` ist ein GETTER, der genau dann wirft, wenn weder ein
158
+ // Prebuild noch ein selbst gebauter Parser da ist. Der Zugriff hier ist
159
+ // die Pruefung, nicht ein beilaeufiges Lesen.
160
+ const libraryPath = registration.libraryPath;
161
+ registrations[language.languageName] = { ...registration, libraryPath };
162
+ } catch (error) {
163
+ status.set(language.languageName, {
164
+ state: "unavailable",
165
+ reason: `Package "${language.moduleName}" could not be loaded or has no built parser for ${process.platform}/${process.arch}: ${errorText(error)}`,
166
+ });
167
+ }
168
+ }
169
+
170
+ if (Object.keys(registrations).length > 0) {
171
+ try {
172
+ napi.registerDynamicLanguage(registrations);
173
+ for (const name of Object.keys(registrations)) {
174
+ status.set(name, { state: "available" });
175
+ }
176
+ } catch (error) {
177
+ for (const name of Object.keys(registrations)) {
178
+ status.set(name, {
179
+ state: "unavailable",
180
+ reason: `registerDynamicLanguage failed: ${errorText(error)}`,
181
+ });
182
+ }
183
+ }
184
+ }
185
+
186
+ return napi;
187
+ }
188
+
189
+ function errorText(error: unknown): string {
190
+ return error instanceof Error ? error.message : String(error);
191
+ }
192
+
193
+ /**
194
+ * Zustand einer angemeldeten Sprache — fuer `doctor` und fuer Tests. Loest die
195
+ * Registrierung NICHT aus: wer nur fragt, soll keine Grammatik laden.
196
+ */
197
+ export function astGrepLanguageStatus(languageName: string): AstGrepLanguageStatus | null {
198
+ return status.get(languageName) ?? null;
199
+ }
200
+
201
+ /** Alle angemeldeten Sprachen mit ihrem Zustand (Reihenfolge der Anmeldung). */
202
+ export function astGrepLanguageStates(): { languageName: string; status: AstGrepLanguageStatus }[] {
203
+ return [...pending.keys()].map((languageName) => ({
204
+ languageName,
205
+ status: status.get(languageName) ?? { state: "pending" },
206
+ }));
207
+ }
208
+
209
+ /**
210
+ * Parst Quelltext mit ast-grep. Loest beim ERSTEN Aufruf die einmalige
211
+ * Registrierung aus (siehe Modulkopf) und wirft einen benannten
212
+ * `AdapterParseError`, wenn genau diese Sprache nicht verfuegbar ist.
213
+ */
214
+ export function astGrepParse(languageName: string, source: string): SgNode {
215
+ let napi: AstGrepModule;
216
+ try {
217
+ napi = ensureRegistered();
218
+ } catch (error) {
219
+ throw new AdapterParseError(
220
+ "grammar_unavailable",
221
+ `Could not load @ast-grep/napi: ${errorText(error)}`,
222
+ { cause: error },
223
+ );
224
+ }
225
+
226
+ const languageStatus = status.get(languageName);
227
+ if (languageStatus === undefined) {
228
+ throw new AdapterParseError(
229
+ "grammar_unavailable",
230
+ `Sprache "${languageName}" is not registered with this ast-grep backend.`,
231
+ );
232
+ }
233
+ if (languageStatus.state === "unavailable") {
234
+ throw new AdapterParseError(
235
+ "grammar_unavailable",
236
+ `Sprache "${languageName}" is unavailable: ${languageStatus.reason}`,
237
+ );
238
+ }
239
+
240
+ try {
241
+ return napi.parse(languageName, source).root();
242
+ } catch (error) {
243
+ throw new AdapterParseError(
244
+ "parser_internal_error",
245
+ `ast-grep could not parse "${languageName}" could not be parsed: ${errorText(error)}`,
246
+ { cause: error },
247
+ );
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Nur fuer Tests: setzt Anmeldungen und Registrierungszustand zurueck. Der
253
+ * NATIVE Zustand laesst sich damit NICHT zuruecksetzen — `registerDynamicLanguage`
254
+ * bleibt im Prozess wirksam. Ein Test, der eine zweite, andere Registrierung
255
+ * erzwingen will, braucht einen eigenen Prozess.
256
+ */
257
+ export function resetAstGrepRegistrationForTests(): void {
258
+ pending.clear();
259
+ status.clear();
260
+ registrationDone = false;
261
+ }