@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,198 @@
1
+ /** Scope-, Namens-, Signatur- und Dokumentationsregeln des Tabellenprofils. */
2
+ import type { SourceRange } from "@untangle-code/domain";
3
+
4
+ import type { FileTextContext } from "./node-utils.js";
5
+ import { commentRangeOf, unionRange, unquote } from "./node-utils.js";
6
+ import type { ScopeSignature } from "./profile.js";
7
+ import type { ScopeNode } from "./scope-model.js";
8
+ import { normalizeSpacing } from "./signature.js";
9
+ import type { SyntaxNode } from "./syntax.js";
10
+ import {
11
+ firstChildOfKind,
12
+ firstChildOfKinds,
13
+ firstDescendantOfKinds,
14
+ setOf,
15
+ } from "./table-profile-queries.js";
16
+ import type { LanguageKindTable, ScopeRule } from "./table-profile.js";
17
+
18
+ const ANONYMOUS_NAME = "<anonymous>";
19
+ const MAX_DOC_GAP_LINES = 1;
20
+ const MAX_NAME_FIELD_DESCENT = 16;
21
+
22
+ /**
23
+ * Kompiliert nur die Scope-Seite einer Sprachtabelle. Der vereinheitlichte
24
+ * Walk kennt dadurch weder Namenspfade noch Sichtbarkeits- oder Doc-Regeln.
25
+ */
26
+ export class TableScopeResolver {
27
+ readonly functionLikeKinds = new Set<string>();
28
+ readonly nodeKinds: ReadonlySet<string>;
29
+
30
+ private readonly ruleByNodeKind = new Map<string, ScopeRule>();
31
+ private readonly visibilityKinds: ReadonlySet<string>;
32
+ private readonly visibilityWords: ReadonlySet<string>;
33
+ private readonly bodyField: string;
34
+
35
+ constructor(
36
+ private readonly table: LanguageKindTable,
37
+ private readonly commentKinds: ReadonlySet<string>,
38
+ ) {
39
+ this.visibilityKinds = setOf(table.visibilityKinds);
40
+ this.visibilityWords = setOf(table.visibilityWords);
41
+ this.bodyField = table.bodyField ?? "body";
42
+ for (const rule of table.scopes) this.registerRule(rule);
43
+ this.nodeKinds = new Set(this.ruleByNodeKind.keys());
44
+ }
45
+
46
+ private registerRule(rule: ScopeRule): void {
47
+ for (const kind of rule.kinds) {
48
+ this.ruleByNodeKind.set(kind, rule);
49
+ if (rule.scopeKind === "function" || rule.scopeKind === "method") {
50
+ this.functionLikeKinds.add(kind);
51
+ }
52
+ }
53
+ }
54
+
55
+ /** Einem Feldpfad und optional der wiederholten letzten Kante folgen. */
56
+ private resolveNameField(node: SyntaxNode, rule: ScopeRule): SyntaxNode | null {
57
+ let base: SyntaxNode | null = node;
58
+ for (const kind of rule.nameKindPath ?? []) {
59
+ base = firstChildOfKind(base, kind);
60
+ if (base === null) return null;
61
+ }
62
+
63
+ const path = (rule.nameField ?? "name").split(".");
64
+ let found: SyntaxNode | null = base;
65
+ for (const field of path) {
66
+ found = found.childForFieldName(field);
67
+ if (found === null) return this.nameKindFallback(base, rule);
68
+ }
69
+ return rule.nameDescend === true
70
+ ? this.descendRepeatedNameField(found, path.at(-1) as string)
71
+ : found;
72
+ }
73
+
74
+ private nameKindFallback(base: SyntaxNode, rule: ScopeRule): SyntaxNode | null {
75
+ return rule.nameKinds === undefined ? null : firstChildOfKinds(base, setOf(rule.nameKinds));
76
+ }
77
+
78
+ private descendRepeatedNameField(start: SyntaxNode, field: string): SyntaxNode {
79
+ let current = start;
80
+ for (let depth = 0; depth < MAX_NAME_FIELD_DESCENT; depth += 1) {
81
+ const next = current.childForFieldName(field);
82
+ if (next === null) return current;
83
+ current = next;
84
+ }
85
+ return current;
86
+ }
87
+
88
+ nameOf(node: SyntaxNode): string {
89
+ const rule = this.ruleByNodeKind.get(node.type);
90
+ if (rule === undefined) return ANONYMOUS_NAME;
91
+ const byField = this.resolveNameField(node, rule);
92
+ if (byField !== null) return unquote(byField.text);
93
+ const byKind = this.nameKindFallback(node, rule);
94
+ return byKind === null ? ANONYMOUS_NAME : unquote(byKind.text);
95
+ }
96
+
97
+ /** Struktureller Traegername fuer Go-Methoden (WP-237). */
98
+ qualifierOf(node: SyntaxNode): string | undefined {
99
+ const rule = this.ruleByNodeKind.get(node.type);
100
+ if (rule?.qualifierField === undefined || rule.qualifierNameKinds === undefined) {
101
+ return undefined;
102
+ }
103
+ const field = node.childForFieldName(rule.qualifierField);
104
+ if (field === null) return undefined;
105
+ const qualifier = firstDescendantOfKinds(field, setOf(rule.qualifierNameKinds));
106
+ return qualifier === null ? undefined : unquote(qualifier.text);
107
+ }
108
+
109
+ kindOf(node: SyntaxNode): ScopeNode["kind"] | null {
110
+ const rule = this.ruleByNodeKind.get(node.type);
111
+ if (
112
+ rule === undefined ||
113
+ !this.hasAllowedParent(node, rule) ||
114
+ !this.hasAllowedAncestor(node, rule)
115
+ ) {
116
+ return null;
117
+ }
118
+ if (rule.constructorNames?.includes(this.nameOf(node)) === true) return "constructor";
119
+ return this.refinedKindOf(node, rule) ?? rule.scopeKind;
120
+ }
121
+
122
+ private hasAllowedParent(node: SyntaxNode, rule: ScopeRule): boolean {
123
+ if (rule.parentKinds === undefined) return true;
124
+ const parentKind = node.parent?.type;
125
+ return parentKind !== undefined && rule.parentKinds.includes(parentKind);
126
+ }
127
+
128
+ private hasAllowedAncestor(node: SyntaxNode, rule: ScopeRule): boolean {
129
+ if (rule.ancestorKinds === undefined) return true;
130
+ let ancestor = node.parent;
131
+ while (ancestor !== null) {
132
+ if (rule.ancestorKinds.includes(ancestor.type)) return true;
133
+ ancestor = ancestor.parent;
134
+ }
135
+ return false;
136
+ }
137
+
138
+ private refinedKindOf(node: SyntaxNode, rule: ScopeRule): ScopeNode["kind"] | undefined {
139
+ for (const refinement of rule.refine ?? []) {
140
+ if (firstChildOfKinds(node, setOf(refinement.childKinds)) !== null) {
141
+ return refinement.scopeKind;
142
+ }
143
+ }
144
+ return undefined;
145
+ }
146
+
147
+ signatureOf(node: SyntaxNode): ScopeSignature {
148
+ const body = node.childForFieldName(this.bodyField);
149
+ const raw =
150
+ body === null
151
+ ? (node.text.split("\n")[0]?.trim() ?? node.text)
152
+ : node.text.slice(0, Math.max(0, body.startIndex - node.startIndex)).trimEnd();
153
+ return { raw, normalized: normalizeSpacing(raw) };
154
+ }
155
+
156
+ /** Der unmittelbar vorangehende Kommentarblock eines Symbols. */
157
+ docRangeOf(node: SyntaxNode, ctx: FileTextContext): SourceRange | undefined {
158
+ const anchor = this.docAnchorOf(node);
159
+ let boundary: SyntaxNode = anchor;
160
+ let previous = anchor.previousSibling;
161
+ let docRange: SourceRange | undefined;
162
+ while (previous !== null && this.commentKinds.has(previous.type)) {
163
+ const commentRange = commentRangeOf(previous, ctx);
164
+ const gap = boundary.startPosition.row + 1 - commentRange.endLine;
165
+ if (gap > MAX_DOC_GAP_LINES) break;
166
+ docRange = docRange === undefined ? commentRange : unionRange(commentRange, docRange);
167
+ boundary = previous;
168
+ previous = previous.previousSibling;
169
+ }
170
+ return docRange;
171
+ }
172
+
173
+ /**
174
+ * Go legt Kommentare vor `type_declaration`, den Scope aber unter
175
+ * `type_spec` ab. Solange ein Knoten das einzige benannte Kind ist, steht
176
+ * deshalb seine Huelle fuer ihn; die Wurzel wird nie zum Anker.
177
+ */
178
+ private docAnchorOf(node: SyntaxNode): SyntaxNode {
179
+ let anchor = node;
180
+ for (;;) {
181
+ const parent = anchor.parent;
182
+ if (parent === null || parent.parent === null || parent.namedChildCount !== 1) return anchor;
183
+ anchor = parent;
184
+ }
185
+ }
186
+
187
+ visibilityOf(node: SyntaxNode): string | undefined {
188
+ if (this.visibilityKinds.size === 0) return undefined;
189
+ const modifier = firstChildOfKinds(node, this.visibilityKinds);
190
+ if (modifier === null) return undefined;
191
+ if (this.visibilityWords.size === 0) return modifier.text;
192
+ return modifier.text.split(/\s+/).find((word) => this.visibilityWords.has(word));
193
+ }
194
+
195
+ exportedNamesOf(node: SyntaxNode, name: string): string[] {
196
+ return this.table.isExported?.(name, node) === true ? [name] : [];
197
+ }
198
+ }
@@ -0,0 +1,427 @@
1
+ /**
2
+ * Das TABELLENGETRIEBENE Sprachprofil: eine Sprache kostet eine Tabelle,
3
+ * keinen Motor.
4
+ *
5
+ * Wofuer es da ist (WP-220): fuer jede Sprache, fuer die wir KEINE eigene
6
+ * Grammatik und keine handgeschriebenen Detektoren pflegen wollen. Der
7
+ * vereinheitlichte Walk (`engine.ts`) bleibt derselbe; nur die Bedeutung der
8
+ * Knotenarten kommt aus {@link LanguageKindTable} statt aus Fallunterscheidungen
9
+ * im Motor.
10
+ *
11
+ * WAS DIESE FASSUNG LEISTET — und was nicht. Sie deckt Symbole, Kommentare,
12
+ * Entscheidungen, Nesting, Halstead-Token, Importe und Aufrufe ab. Sie ist
13
+ * damit ausdruecklich SCHWAECHER als die handgeschriebene JS/TS-Fassung
14
+ * (`js-family-profile.ts`), und das steht hier, damit es niemand aus der
15
+ * Ausgabe erraten muss:
16
+ *
17
+ * - Importbindungen (`RawImport.bindings`) liefert sie nur, wo die Tabelle
18
+ * ein Aliasfeld nennt. Sonst FEHLT das Feld, statt eine Zuordnung zu
19
+ * erfinden — der Vertrag in domain `analysis.ts` sagt ausdruecklich, dass
20
+ * ein fehlendes Feld "unbekannt" heisst und Namensgleichheit kein Beweis ist.
21
+ * - Der Aufrufqualifizierer kommt aus der Form des Aufrufziels, nicht aus
22
+ * einer Namensaufloesung. `a.b.c()` liefert Qualifizierer `a.b`.
23
+ * - `normalizedSignature` ist der Kopf bis zum Rumpf, mit den
24
+ * Leerraumregeln aus `signature.ts`. Vorgabewerte werden NICHT entfernt
25
+ * (das ist eine JS/TS-Regel und waere anderswo geraten).
26
+ *
27
+ * Wer eine dieser Grenzen fuer eine Sprache nicht hinnehmen will, schreibt fuer
28
+ * sie ein eigenes Profil — der Vertrag dafuer ist `profile.ts`, und der Motor
29
+ * merkt den Unterschied nicht.
30
+ */
31
+ import type { LiteralFact, SupportLevel } from "@untangle-code/domain";
32
+
33
+ import type { LanguageProfile } from "./profile.js";
34
+ import type { ScopeNode } from "./scope-model.js";
35
+ import type { SyntaxNode } from "./syntax.js";
36
+ import { TableDecisionDetector } from "./table-profile-decisions.js";
37
+ import { TableModuleFactCollector } from "./table-profile-module-facts.js";
38
+ import { setOf } from "./table-profile-queries.js";
39
+ import { TableScopeResolver } from "./table-profile-scopes.js";
40
+
41
+ /** Wie eine Knotenart zu einem Symbolscope wird. */
42
+ export interface ScopeRule {
43
+ /** Knotenarten, die diesen Scope oeffnen. */
44
+ kinds: readonly string[];
45
+ scopeKind: ScopeNode["kind"];
46
+ /**
47
+ * Feld, das den Namen traegt (Vorgabe: `name`). Ein PUNKT trennt einen
48
+ * Feldpfad: Javas `field_declaration` fuehrt seinen Namen unter
49
+ * `declarator.name`, nicht unter `name`.
50
+ */
51
+ nameField?: string;
52
+ /**
53
+ * Feld mit dem TRAEGER, wenn die Sprache ihn nicht als Elternknoten fuehrt
54
+ * (WP-237). Gos `method_declaration` traegt `(a *A)` unter `receiver`; ohne
55
+ * diesen Zusatz heissen `(*A).Run` und `(*B).Run` beide `Run`.
56
+ */
57
+ qualifierField?: string;
58
+ /**
59
+ * Knotenarten, die im Traegerfeld den eigentlichen Namen tragen. Der erste
60
+ * Treffer in Quelltextreihenfolge gewinnt. Go nennt den Typ eines
61
+ * Empfaengers `type_identifier`; so bleibt auch `Pair[A, B]` strukturell
62
+ * `Pair`, ohne den Quelltext an Leerzeichen oder Klammern zu zerlegen.
63
+ */
64
+ qualifierNameKinds?: readonly string[];
65
+ /**
66
+ * Dem Namensfeld so lange weiter folgen, wie es weiterfuehrt. C schreibt
67
+ * `ring_t *ring_new(size_t)` als
68
+ * `function_definition.declarator -> pointer_declarator.declarator ->
69
+ * function_declarator.declarator -> identifier`; ohne diesen Abstieg hiesse
70
+ * jede zeigerwertige Funktion `*ring_new(...)`.
71
+ */
72
+ nameDescend?: boolean;
73
+ /**
74
+ * Kette von KINDKNOTENARTEN, die vor der Namenssuche abgestiegen wird.
75
+ * C# schreibt ein Feld als `field_declaration > variable_declaration >
76
+ * variable_declarator.name`, PHP als `property_declaration >
77
+ * property_element.name`. Ohne den Abstieg stuende der ganze Text im
78
+ * Namen (`"Dictionary<string, string> _items = new()"`).
79
+ */
80
+ nameKindPath?: readonly string[];
81
+ /** Ersatzweise: Kindknotenarten, deren Text der Name ist (erste Fundstelle). */
82
+ nameKinds?: readonly string[];
83
+ /**
84
+ * Nur dann ein Scope, wenn der ELTERNKNOTEN von dieser Art ist.
85
+ *
86
+ * WOFUER: Kotlin und Swift benutzen `property_declaration` sowohl fuer ein
87
+ * Klassenfeld als auch fuer eine LOKALE Variable in einem Funktionsrumpf.
88
+ * Ohne diese Schranke wuerde `var i = 0` mitten in einer Methode als Symbol
89
+ * gemeldet — eine falsche Aussage ueber die Datei, die in Hotspots,
90
+ * Ratsche und Risikobewertung einflosse.
91
+ */
92
+ parentKinds?: readonly string[];
93
+ /**
94
+ * Mindestens ein VORFAHRE muss von einer dieser Arten sein. Das grenzt
95
+ * syntaktisch identische Deklarationen nach ihrem Kontext ab: Rust verwendet
96
+ * `function_signature_item` sowohl in Traits als auch in `extern`-Bloecken,
97
+ * aber nur die Trait-Signatur ist eine Methode des analysierten Codes.
98
+ */
99
+ ancestorKinds?: readonly string[];
100
+ /**
101
+ * Namen, die diesen Scope zu einem Konstruktor machen (Java `<init>`,
102
+ * Rust `new`, ...). Leer heisst: nie ein Konstruktor.
103
+ */
104
+ constructorNames?: readonly string[];
105
+ /**
106
+ * Verfeinerung nach einem Kindknoten. Go kennt nur `type_spec`; ob daraus
107
+ * eine Klasse (`struct_type`), eine Schnittstelle (`interface_type`) oder ein
108
+ * Typalias wird, steht erst im Kind. Ohne diese Regel muesste die Tabelle
109
+ * luegen oder alles zu `type` einebnen.
110
+ */
111
+ refine?: readonly { childKinds: readonly string[]; scopeKind: ScopeNode["kind"] }[];
112
+ }
113
+
114
+ /** Entscheidungs- und Nesting-Regeln (spec.md §16.2–§16.4). */
115
+ export interface DecisionRules {
116
+ ifKinds: readonly string[];
117
+ /**
118
+ * Elternknotenarten, die ein `if` zu einem `else if` machen (JS/Rust:
119
+ * `else_clause`, Go: `if_statement` selbst). Ohne Eintrag gibt es kein
120
+ * `else_if` — und die Zaehlung sagt das dann auch nicht.
121
+ */
122
+ elseIfParentKinds?: readonly string[];
123
+ /**
124
+ * Huellen, unter denen ein `if` nur dann eine Fortsetzung ist, wenn die
125
+ * Huelle unmittelbar auf ein anonymes `else`-Geschwister folgt. Kotlin
126
+ * bildet `else if` als `else > control_structure_body > if_expression` ab;
127
+ * ein `if` im Dann-Rumpf hat dieselbe Huelle, aber kein `else` davor.
128
+ */
129
+ elseIfWrapperKinds?: readonly string[];
130
+ /**
131
+ * Bereichssichere Korrektur fuer Grammatiken, die ein gueltiges
132
+ * `else /* Kommentar *\/ if` in Geschwister zerlegen und dabei das anonyme
133
+ * `else`-Token aus dem Baum verlieren. Aktiviert wird sie nur fuer die
134
+ * betroffene Sprache; erkannt wird ausschliesslich ein exaktes `else` im
135
+ * begrenzten Quelltextspalt zwischen zwei AST-Geschwistern.
136
+ */
137
+ recoverDetachedElseIfAfterComments?: boolean;
138
+ /**
139
+ * Knotenarten, die SELBST ein `else if` sind (Ruby `elsif`, PHP
140
+ * `else_if_clause`, Bash `elif_clause`). Anders als
141
+ * {@link DecisionRules.elseIfParentKinds} braucht es dafuer keinen Blick auf
142
+ * den Elternknoten — die Grammatik sagt es schon.
143
+ */
144
+ elseIfKinds?: readonly string[];
145
+ loopKinds: readonly string[];
146
+ catchKinds?: readonly string[];
147
+ /**
148
+ * Knotenarten, die eine vorzeitige Rueckkehr SIND (Swift `guard`). Die
149
+ * Guard-Erkennung ueber `consequenceField`/`jumpKinds` findet nur die
150
+ * `if`-Form; wo die Sprache ein eigenes Schluesselwort hat, steht es hier.
151
+ */
152
+ guardKinds?: readonly string[];
153
+ /**
154
+ * Musteralternativen (`Some(1) | Some(2)` in Rust) — `DecisionKind`
155
+ * `pattern_alternative`.
156
+ */
157
+ patternAlternativeKinds?: readonly string[];
158
+ /**
159
+ * Knotenarten, die einen KURZSCHLUSS darstellen, ohne ein Operatorfeld zu
160
+ * haben: Rusts `try_expression` (der `?`-Operator). Sie zaehlen wie ein
161
+ * logischer Operator NUR erweitert (spec.md §16.3), nie klassisch.
162
+ */
163
+ shortCircuitKinds?: readonly string[];
164
+ ternaryKinds?: readonly string[];
165
+ switchKinds?: readonly string[];
166
+ caseKinds?: readonly string[];
167
+ /**
168
+ * Ein `case`-Knoten mit einem DIREKTEN Kind dieser Art ist der
169
+ * Auffangzweig (`default:`) und zaehlt NICHT. Java und C fuehren `case X:`
170
+ * und `default:` unter DERSELBEN Knotenart; ohne diese Ausnahme bekaeme
171
+ * jeder `switch` eine Entscheidung zu viel.
172
+ */
173
+ caseExcludeChildKinds?: readonly string[];
174
+ /** Dasselbe ueber den Text des ersten Kindes (Bashs Auffangmuster `*)`). */
175
+ caseExcludeFirstChildText?: string;
176
+ /** Binaerausdruecke, deren Operator ueber `operatorField` erreichbar ist. */
177
+ binaryKinds?: readonly string[];
178
+ /**
179
+ * Knotenarten, deren Operator KEIN Feld ist, sondern das erste anonyme Kind.
180
+ * Kotlin (`conjunction_expression`), Swift (`disjunction_expression`) und
181
+ * Bash (`list` mit `&&`/`||`) vergeben dort keine Feldnamen.
182
+ */
183
+ anonymousOperatorKinds?: readonly string[];
184
+ operatorField?: string;
185
+ logicalAndOperators?: readonly string[];
186
+ logicalOrOperators?: readonly string[];
187
+ shortCircuitOperators?: readonly string[];
188
+ /** Sprunganweisungen fuer die Guard-Clause-Erkennung. */
189
+ jumpKinds?: readonly string[];
190
+ /** Rumpfhuellen, die fuer die Guard-Erkennung durchsichtig sind (Go: `block`+`statement_list`). */
191
+ blockKinds?: readonly string[];
192
+ consequenceField?: string;
193
+ alternativeField?: string;
194
+ }
195
+
196
+ /** Importregeln. */
197
+ export interface ImportRules {
198
+ /** Anweisungsarten, die einen Import darstellen. */
199
+ kinds: readonly string[];
200
+ /** Untereintraege innerhalb der Anweisung (Go: `import_spec`). Leer: die Anweisung selbst. */
201
+ specKinds?: readonly string[];
202
+ /** Feld mit dem Pfad/Ziel (Go `path`, Rust `argument`). */
203
+ pathField?: string;
204
+ /** Ersatzweise: Knotenarten, deren Text der Pfad ist. */
205
+ pathKinds?: readonly string[];
206
+ /** Feld mit dem lokalen Namen (Alias), wenn die Sprache eines hat. */
207
+ aliasField?: string;
208
+ /**
209
+ * Auspacken zusammengesetzter Ziele. Rust schreibt
210
+ * `use a::b as c` (`use_as_clause`) und `use a::{b, c}` (`scoped_use_list`);
211
+ * ohne diese Regel stuende der ganze Ausdruck als "Pfad" im Ergebnis.
212
+ */
213
+ unwrap?: readonly {
214
+ kinds: readonly string[];
215
+ pathField: string;
216
+ aliasField?: string;
217
+ /** Feld mit der Namensliste; ihre BENANNTEN Kinder werden zu `importedNames`. */
218
+ namesField?: string;
219
+ }[];
220
+ }
221
+
222
+ /** Aufrufregeln. */
223
+ export interface CallRules {
224
+ kinds: readonly string[];
225
+ /** Feld mit dem Aufrufziel (Vorgabe: `function`). */
226
+ functionField?: string;
227
+ /** Feld mit der Argumentliste (Vorgabe: `arguments`). */
228
+ argumentsField?: string;
229
+ /** Zugriffsformen `a.b` / `a::b`, aus denen Qualifizierer und Name entstehen. */
230
+ memberKinds?: readonly string[];
231
+ /**
232
+ * Feld mit dem EMPFAENGER, wenn die Sprache ihn getrennt fuehrt statt in
233
+ * einem Zugriffsknoten: Javas `method_invocation` hat `object` und `name`
234
+ * nebeneinander, Rubys `call` hat `receiver` und `method`. Ohne dieses Feld
235
+ * ginge der Qualifizierer dort verloren.
236
+ */
237
+ receiverField?: string;
238
+ /** Konstruktoraufrufe (`new X()`), falls die Sprache eine eigene Knotenart hat. */
239
+ constructionKinds?: readonly string[];
240
+ /** Feld mit dem Typ eines Konstruktoraufrufs. */
241
+ constructedTypeField?: string;
242
+ /**
243
+ * Zusaetzliche Bedingung, die ein Kandidat erfuellen muss.
244
+ *
245
+ * WOFUER: Swift benutzt `call_expression` AUCH fuer Indexzugriffe
246
+ * (`items["a"]`). Ohne Filter meldete der Adapter `items` als Aufrufziel —
247
+ * ein Aufruf, den es nicht gibt.
248
+ */
249
+ acceptCall?: (node: SyntaxNode) => boolean;
250
+ }
251
+
252
+ /** Die vollstaendige Tabelle einer Sprache. */
253
+ export interface LanguageKindTable {
254
+ languageId: string;
255
+ extensions: readonly string[];
256
+ supportLevel: SupportLevel;
257
+ commentKinds: readonly string[];
258
+ /** Knoten, deren Teilbaum EIN Operand ist (Zeichenkettenliterale). */
259
+ stringContainerKinds: readonly string[];
260
+ identifierLeafKinds: readonly string[];
261
+ numberLeafKinds?: readonly string[];
262
+ booleanLeafKinds?: readonly string[];
263
+ nullLeafKinds?: readonly string[];
264
+ /** Satzzeichen, die weder Operator noch Operand sind (Vorgabe: {@link DEFAULT_PUNCTUATION}). */
265
+ punctuationKinds?: readonly string[];
266
+ scopes: readonly ScopeRule[];
267
+ decisions: DecisionRules;
268
+ imports: ImportRules;
269
+ calls: CallRules;
270
+ /** Elternknotenarten, in denen ein Bezeichner im Namensfeld eine Deklaration ist. */
271
+ declarationParentKinds: readonly string[];
272
+ /** Knotenarten, deren Text die Sichtbarkeit angibt (Rust `visibility_modifier`). */
273
+ visibilityKinds?: readonly string[];
274
+ /**
275
+ * Wenn der Sichtbarkeitsknoten ein SACK von Modifikatoren ist (Javas
276
+ * `modifiers` traegt `private final static` in EINEM Knoten): das erste
277
+ * Wort daraus, das in dieser Liste steht, ist die Sichtbarkeit. Ohne die
278
+ * Liste stuende `"private final"` im Ergebnis — eine Angabe, die kein
279
+ * Verbraucher vergleichen kann.
280
+ */
281
+ visibilityWords?: readonly string[];
282
+ /** Feld mit dem Rumpf — alles davor ist die Signatur (Vorgabe: `body`). */
283
+ bodyField?: string;
284
+ /**
285
+ * Ist dieser Name aus der Datei heraus sichtbar? Go entscheidet das am
286
+ * Grossbuchstaben, Rust am `pub`. Fehlt der Haken, meldet das Profil KEINE
287
+ * exportierten Namen — lieber nichts als eine erfundene Sichtbarkeit.
288
+ */
289
+ isExported?: (name: string, node: SyntaxNode) => boolean;
290
+ /**
291
+ * Feldnamen, die der ast-grep-Cursor am Elternknoten abfragen darf, um
292
+ * `currentFieldName` zu bestimmen (ast-grep kennt keine Umkehrrichtung,
293
+ * siehe `languages/astgrep-backend/syntax.ts`). Vorgabe: `["name"]`.
294
+ */
295
+ fieldNames?: readonly string[];
296
+ }
297
+
298
+ /** Satzzeichen, die in fast jeder Sprache reine Struktur sind. */
299
+ export const DEFAULT_PUNCTUATION: readonly string[] = [
300
+ "(",
301
+ ")",
302
+ "{",
303
+ "}",
304
+ "[",
305
+ "]",
306
+ ",",
307
+ ";",
308
+ ".",
309
+ ":",
310
+ ];
311
+ /**
312
+ * Die Blattklassifikation ist eine eigene Verantwortung: Sie kennt weder
313
+ * Scopes noch Kontrollfluss, Importe oder Aufrufe.
314
+ */
315
+ class TableTokenClassifier {
316
+ readonly commentKinds: ReadonlySet<string>;
317
+ readonly literalContainerKinds: ReadonlySet<string>;
318
+ readonly identifierLeafKinds: ReadonlySet<string>;
319
+ readonly simpleLiteralLeafKinds: ReadonlySet<string>;
320
+ readonly punctuationKinds: ReadonlySet<string>;
321
+
322
+ private readonly numberKinds: ReadonlySet<string>;
323
+ private readonly booleanKinds: ReadonlySet<string>;
324
+ private readonly nullKinds: ReadonlySet<string>;
325
+ private readonly declarationParentKinds: ReadonlySet<string>;
326
+
327
+ constructor(table: LanguageKindTable) {
328
+ this.commentKinds = setOf(table.commentKinds);
329
+ this.literalContainerKinds = setOf(table.stringContainerKinds);
330
+ this.identifierLeafKinds = setOf(table.identifierLeafKinds);
331
+ this.numberKinds = setOf(table.numberLeafKinds);
332
+ this.booleanKinds = setOf(table.booleanLeafKinds);
333
+ this.nullKinds = setOf(table.nullLeafKinds);
334
+ this.simpleLiteralLeafKinds = new Set([
335
+ ...this.numberKinds,
336
+ ...this.booleanKinds,
337
+ ...this.nullKinds,
338
+ ]);
339
+ this.punctuationKinds = setOf(table.punctuationKinds ?? DEFAULT_PUNCTUATION);
340
+ this.declarationParentKinds = setOf(table.declarationParentKinds);
341
+ }
342
+
343
+ literalKindOf(kind: string): LiteralFact["literalKind"] {
344
+ if (this.numberKinds.has(kind)) return "number";
345
+ if (this.booleanKinds.has(kind)) return "boolean";
346
+ if (this.nullKinds.has(kind)) return "null";
347
+ return "other";
348
+ }
349
+
350
+ identifierRoleOf(fieldName: string | undefined, parentKind: string): "declaration" | "reference" {
351
+ return fieldName === "name" && this.declarationParentKinds.has(parentKind)
352
+ ? "declaration"
353
+ : "reference";
354
+ }
355
+ }
356
+
357
+ function stringLiteralKind(): LiteralFact["literalKind"] {
358
+ return "string";
359
+ }
360
+
361
+ function neverSuppressScope(): boolean {
362
+ return false;
363
+ }
364
+
365
+ function noMemberRegions(): [] {
366
+ return [];
367
+ }
368
+
369
+ /**
370
+ * Baut ein Profil aus vier kompilierten, unabhaengigen Verantwortungen.
371
+ *
372
+ * WP-239: Diese Funktion verdrahtet nur noch Tokens, Scopes, Entscheidungen
373
+ * und Modul-Fakten. Die jeweiligen Regeln leben in kleinen Resolvern mit
374
+ * eigener Zustandsmenge; der vorherige 500-Zeilen-Abschluss ist verschwunden.
375
+ */
376
+ export function createTableProfile(table: LanguageKindTable): LanguageProfile {
377
+ const tokens = new TableTokenClassifier(table);
378
+ const scopes = new TableScopeResolver(table, tokens.commentKinds);
379
+ const decisions = new TableDecisionDetector(table.decisions, tokens.commentKinds);
380
+ const moduleFacts = new TableModuleFactCollector(table.imports, table.calls);
381
+ const needsNodeKinds = new Set([
382
+ ...scopes.nodeKinds,
383
+ ...decisions.nodeKinds,
384
+ ...moduleFacts.nodeKinds,
385
+ ]);
386
+
387
+ return {
388
+ languageId: table.languageId,
389
+ extensions: table.extensions,
390
+ supportLevel: table.supportLevel,
391
+
392
+ commentKinds: tokens.commentKinds,
393
+ literalContainerKinds: tokens.literalContainerKinds,
394
+ identifierLeafKinds: tokens.identifierLeafKinds,
395
+ simpleLiteralLeafKinds: tokens.simpleLiteralLeafKinds,
396
+ templateTextLeafKinds: new Set<string>(),
397
+ ignoredPunctuationKinds: tokens.punctuationKinds,
398
+ typeKeywordParentKinds: new Set<string>(),
399
+ functionLikeKinds: scopes.functionLikeKinds,
400
+ exportWrapperKinds: new Set<string>(),
401
+
402
+ containerLiteralKind: stringLiteralKind,
403
+ simpleLiteralKind: tokens.literalKindOf.bind(tokens),
404
+ identifierRole: tokens.identifierRoleOf.bind(tokens),
405
+ needsNode: needsNodeKinds.has.bind(needsNodeKinds),
406
+
407
+ scopeKindOf: scopes.kindOf.bind(scopes),
408
+ suppressesScope: neverSuppressScope,
409
+ scopeName: scopes.nameOf.bind(scopes),
410
+ scopeQualifier: scopes.qualifierOf.bind(scopes),
411
+ scopeSignature: scopes.signatureOf.bind(scopes),
412
+ docRange: scopes.docRangeOf.bind(scopes),
413
+ visibility: scopes.visibilityOf.bind(scopes),
414
+ exportedNames: scopes.exportedNamesOf.bind(scopes),
415
+
416
+ detectDecisionAndNesting: decisions.detect.bind(decisions),
417
+ collectModuleFacts: moduleFacts.collect.bind(moduleFacts),
418
+ memberRegions: noMemberRegions,
419
+ };
420
+ }
421
+
422
+ /** Die Feldnamen, die ein Backend ohne Feldnamen-Rueckrichtung abfragen muss. */
423
+ export function fieldNamesOf(table: LanguageKindTable): readonly string[] {
424
+ const names = new Set<string>(table.fieldNames ?? ["name"]);
425
+ for (const rule of table.scopes) names.add(rule.nameField ?? "name");
426
+ return [...names];
427
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Thin type-only surface over the `tree-sitter` native binding.
3
+ *
4
+ * We import only types here (`import type`) — the actual native module is
5
+ * loaded lazily and dynamically at runtime via `grammar-loader.ts` using
6
+ * `createRequire`, never through a static `import` statement. That is what
7
+ * makes grammar loading lazy: requiring this file costs nothing at the
8
+ * native-addon level, only `loadGrammar()` does, and only for languages
9
+ * actually used.
10
+ */
11
+ import type Parser from "tree-sitter";
12
+
13
+ import type { SyntaxCursor, SyntaxNode } from "./syntax.js";
14
+
15
+ export type TsSyntaxNode = Parser.SyntaxNode;
16
+ /** Eine Parserinstanz mit gesetzter Grammatik (siehe `parse-limits.ts#parseWithBuffer`). */
17
+ export type TsParser = Parser;
18
+ export type TsTree = Parser.Tree;
19
+ /**
20
+ * Der native Baumcursor (`tree.walk()` / `node.walk()`). Er haelt die
21
+ * Position IN der nativen Bibliothek; `gotoFirstChild`/`gotoNextSibling`/
22
+ * `gotoParent` verschieben sie, ohne je einen JS-Knotenwrapper zu bauen.
23
+ * Genau darum ist er der Traversierungsweg dieses Pakets (WP-95) — `.children`
24
+ * materialisiert je Knoten ein Array aus Wrappern.
25
+ */
26
+ export type TsTreeCursor = Parser.TreeCursor;
27
+ export type TsPoint = Parser.Point;
28
+ export type TsParserCtor = typeof Parser;
29
+
30
+ /** Opaque tree-sitter `Language` handle, as accepted by `Parser#setLanguage`. */
31
+ export type TsLanguage = unknown;
32
+
33
+ /**
34
+ * Die Zusage aus `syntax.ts`, hier festgenagelt: die NATIVEN tree-sitter-Formen
35
+ * erfuellen den backend-neutralen Baumvertrag STRUKTURELL. Kein Wrapper, kein
36
+ * Adapterobjekt, keine zusaetzliche Grenzueberquerung je Knoten — der Weg, den
37
+ * WP-95 saniert hat, bleibt genau so teuer wie vorher.
38
+ *
39
+ * Diese beiden Zuweisungen sind reine Typaussagen (`never` zur Laufzeit
40
+ * unbenutzt). Bricht eine kuenftige Aenderung an `syntax.ts` die Vertraglichkeit,
41
+ * scheitert der Typcheck HIER — und nicht erst an der Aufrufstelle, an der
42
+ * jemand versucht waere, sie mit einer Umtypung zu erschlagen.
43
+ */
44
+ type AssertAssignable<Target, Source extends Target> = [Target, Source];
45
+ export type TreeSitterSatisfiesSyntaxNode = AssertAssignable<SyntaxNode, TsSyntaxNode>;
46
+ export type TreeSitterSatisfiesSyntaxCursor = AssertAssignable<SyntaxCursor, TsTreeCursor>;