xbintsc 0.5.22 → 0.5.31

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 (391) hide show
  1. package/AGENTS.md +12 -3
  2. package/README.md +46 -11
  3. package/README.zh-CN.md +32 -6
  4. package/dist/scripts/support-matrix.d.ts +18 -0
  5. package/dist/scripts/support-matrix.js +141 -0
  6. package/dist/scripts/support-matrix.js.map +1 -0
  7. package/dist/src/ast/common.d.ts +2 -2
  8. package/dist/src/ast/declarations.d.ts +7 -1
  9. package/dist/src/ast/expressions.d.ts +5 -0
  10. package/dist/src/ast/kinds.d.ts +2 -0
  11. package/dist/src/ast/kinds.js +2 -0
  12. package/dist/src/ast/kinds.js.map +1 -1
  13. package/dist/src/binder/binder.d.ts +2 -1
  14. package/dist/src/binder/binder.js +2 -0
  15. package/dist/src/binder/binder.js.map +1 -1
  16. package/dist/src/binder/declarations.d.ts +9 -0
  17. package/dist/src/binder/declarations.js +64 -0
  18. package/dist/src/binder/declarations.js.map +1 -1
  19. package/dist/src/binder/references.js +85 -3
  20. package/dist/src/binder/references.js.map +1 -1
  21. package/dist/src/binder/types.d.ts +32 -0
  22. package/dist/src/binder/types.js.map +1 -1
  23. package/dist/src/canonical.d.ts +29 -0
  24. package/dist/src/canonical.js +35 -0
  25. package/dist/src/canonical.js.map +1 -0
  26. package/dist/src/checker/assignability.d.ts +13 -0
  27. package/dist/src/checker/assignability.js +146 -0
  28. package/dist/src/checker/assignability.js.map +1 -0
  29. package/dist/src/checker/calls.d.ts +13 -0
  30. package/dist/src/checker/calls.js +127 -0
  31. package/dist/src/checker/calls.js.map +1 -0
  32. package/dist/src/checker/checker.d.ts +26 -0
  33. package/dist/src/checker/checker.js +31 -0
  34. package/dist/src/checker/checker.js.map +1 -0
  35. package/dist/src/checker/declarations.d.ts +9 -0
  36. package/dist/src/checker/declarations.js +15 -0
  37. package/dist/src/checker/declarations.js.map +1 -0
  38. package/dist/src/checker/flow.d.ts +21 -0
  39. package/dist/src/checker/flow.js +241 -0
  40. package/dist/src/checker/flow.js.map +1 -0
  41. package/dist/src/checker/globals.d.ts +9 -0
  42. package/dist/src/checker/globals.js +29 -0
  43. package/dist/src/checker/globals.js.map +1 -0
  44. package/dist/src/checker/source.d.ts +38 -0
  45. package/dist/src/checker/source.js +48 -0
  46. package/dist/src/checker/source.js.map +1 -0
  47. package/dist/src/checker/type-infer.d.ts +18 -0
  48. package/dist/src/checker/type-infer.js +173 -0
  49. package/dist/src/checker/type-infer.js.map +1 -0
  50. package/dist/src/checker/type-model.d.ts +73 -0
  51. package/dist/src/checker/type-model.js +151 -0
  52. package/dist/src/checker/type-model.js.map +1 -0
  53. package/dist/src/checker/type-system.d.ts +58 -0
  54. package/dist/src/checker/type-system.js +569 -0
  55. package/dist/src/checker/type-system.js.map +1 -0
  56. package/dist/src/checker/typecheck-types.d.ts +22 -0
  57. package/dist/src/checker/typecheck-types.js +109 -0
  58. package/dist/src/checker/typecheck-types.js.map +1 -0
  59. package/dist/src/checker/typecheck.d.ts +62 -0
  60. package/dist/src/checker/typecheck.js +574 -0
  61. package/dist/src/checker/typecheck.js.map +1 -0
  62. package/dist/src/checker/undefined.d.ts +14 -0
  63. package/dist/src/checker/undefined.js +32 -0
  64. package/dist/src/checker/undefined.js.map +1 -0
  65. package/dist/src/checker/walk.d.ts +10 -0
  66. package/dist/src/checker/walk.js +15 -0
  67. package/dist/src/checker/walk.js.map +1 -0
  68. package/dist/src/cli/help.d.ts +7 -0
  69. package/dist/src/cli/help.js +64 -0
  70. package/dist/src/cli/help.js.map +1 -0
  71. package/dist/src/cli/hints.js +13 -1
  72. package/dist/src/cli/hints.js.map +1 -1
  73. package/dist/src/cli/main.js +12 -48
  74. package/dist/src/cli/main.js.map +1 -1
  75. package/dist/src/codegen/generator/calls/access.js +8 -8
  76. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  77. package/dist/src/codegen/generator/calls/invocation.js +9 -4
  78. package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
  79. package/dist/src/codegen/generator/calls/super.d.ts +9 -1
  80. package/dist/src/codegen/generator/calls/super.js +56 -5
  81. package/dist/src/codegen/generator/calls/super.js.map +1 -1
  82. package/dist/src/codegen/generator/context.d.ts +13 -2
  83. package/dist/src/codegen/generator/context.js +25 -19
  84. package/dist/src/codegen/generator/context.js.map +1 -1
  85. package/dist/src/codegen/generator/debug.js +2 -1
  86. package/dist/src/codegen/generator/debug.js.map +1 -1
  87. package/dist/src/codegen/generator/expressions/primary.d.ts +4 -1
  88. package/dist/src/codegen/generator/expressions/primary.js +68 -8
  89. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  90. package/dist/src/codegen/generator/generator.js +11 -1
  91. package/dist/src/codegen/generator/generator.js.map +1 -1
  92. package/dist/src/codegen/generator/module.d.ts +2 -0
  93. package/dist/src/codegen/generator/module.js +62 -26
  94. package/dist/src/codegen/generator/module.js.map +1 -1
  95. package/dist/src/codegen/generator/state.d.ts +11 -1
  96. package/dist/src/codegen/generator/state.js.map +1 -1
  97. package/dist/src/codegen/generator/statements/variables.js +20 -3
  98. package/dist/src/codegen/generator/statements/variables.js.map +1 -1
  99. package/dist/src/codegen/generator/tables.d.ts +2 -0
  100. package/dist/src/codegen/generator/tables.js +4 -0
  101. package/dist/src/codegen/generator/tables.js.map +1 -1
  102. package/dist/src/driver/build-key.d.ts +2 -0
  103. package/dist/src/driver/build-key.js +1 -0
  104. package/dist/src/driver/build-key.js.map +1 -1
  105. package/dist/src/driver/bundler/graph.js +5 -1
  106. package/dist/src/driver/bundler/graph.js.map +1 -1
  107. package/dist/src/driver/bundler/merge.js +16 -1
  108. package/dist/src/driver/bundler/merge.js.map +1 -1
  109. package/dist/src/driver/bundler/types.d.ts +12 -0
  110. package/dist/src/driver/compiler.d.ts +1 -1
  111. package/dist/src/driver/compiler.js +4 -0
  112. package/dist/src/driver/compiler.js.map +1 -1
  113. package/dist/src/driver/fingerprint.js +2 -1
  114. package/dist/src/driver/fingerprint.js.map +1 -1
  115. package/dist/src/driver/frontend.d.ts +8 -6
  116. package/dist/src/driver/frontend.js +4 -0
  117. package/dist/src/driver/frontend.js.map +1 -1
  118. package/dist/src/driver/options.d.ts +6 -0
  119. package/dist/src/driver/version.d.ts +1 -1
  120. package/dist/src/driver/version.js +1 -1
  121. package/dist/src/extensions/catalog.js +2 -1
  122. package/dist/src/extensions/catalog.js.map +1 -1
  123. package/dist/src/extensions/gui/html.js +20 -6
  124. package/dist/src/extensions/gui/html.js.map +1 -1
  125. package/dist/src/extensions/gui/index.js +63 -0
  126. package/dist/src/extensions/gui/index.js.map +1 -1
  127. package/dist/src/extensions/media/index.d.ts +27 -0
  128. package/dist/src/extensions/media/index.js +60 -0
  129. package/dist/src/extensions/media/index.js.map +1 -0
  130. package/dist/src/extensions/registry.d.ts +50 -0
  131. package/dist/src/extensions/registry.js +26 -0
  132. package/dist/src/extensions/registry.js.map +1 -1
  133. package/dist/src/index.d.ts +2 -0
  134. package/dist/src/index.js +2 -0
  135. package/dist/src/index.js.map +1 -1
  136. package/dist/src/parser/declarations/classes.js +7 -0
  137. package/dist/src/parser/declarations/classes.js.map +1 -1
  138. package/dist/src/parser/expressions.js +14 -1
  139. package/dist/src/parser/expressions.js.map +1 -1
  140. package/dist/src/parser/literals.js +6 -2
  141. package/dist/src/parser/literals.js.map +1 -1
  142. package/dist/tests/binder/binder.test.js +29 -0
  143. package/dist/tests/binder/binder.test.js.map +1 -1
  144. package/dist/tests/canonical.test.d.ts +1 -0
  145. package/dist/tests/canonical.test.js +19 -0
  146. package/dist/tests/canonical.test.js.map +1 -0
  147. package/dist/tests/checker/checker.test.d.ts +1 -0
  148. package/dist/tests/checker/checker.test.js +245 -0
  149. package/dist/tests/checker/checker.test.js.map +1 -0
  150. package/dist/tests/cli/check.test.js +20 -0
  151. package/dist/tests/cli/check.test.js.map +1 -1
  152. package/dist/tests/cli/hints.test.js +15 -0
  153. package/dist/tests/cli/hints.test.js.map +1 -1
  154. package/dist/tests/cli/process.test.js +12 -0
  155. package/dist/tests/cli/process.test.js.map +1 -1
  156. package/dist/tests/conformance/matrix.test.d.ts +6 -0
  157. package/dist/tests/conformance/matrix.test.js +23 -0
  158. package/dist/tests/conformance/matrix.test.js.map +1 -0
  159. package/dist/tests/conformance/test262/manifest.d.ts +115 -0
  160. package/dist/tests/conformance/test262/manifest.js +257 -0
  161. package/dist/tests/conformance/test262/manifest.js.map +1 -0
  162. package/dist/tests/conformance/test262.test.d.ts +11 -0
  163. package/dist/tests/conformance/test262.test.js +74 -0
  164. package/dist/tests/conformance/test262.test.js.map +1 -0
  165. package/dist/tests/docs/structure.test.js +9 -11
  166. package/dist/tests/docs/structure.test.js.map +1 -1
  167. package/dist/tests/e2e/child-process.test.js +3 -2
  168. package/dist/tests/e2e/child-process.test.js.map +1 -1
  169. package/dist/tests/e2e/compile-builtins.test.js +21 -0
  170. package/dist/tests/e2e/compile-builtins.test.js.map +1 -1
  171. package/dist/tests/e2e/compile-objects-classes.test.js +54 -0
  172. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
  173. package/dist/tests/e2e/differential-syntax.test.d.ts +5 -0
  174. package/dist/tests/e2e/differential-syntax.test.js +95 -0
  175. package/dist/tests/e2e/differential-syntax.test.js.map +1 -0
  176. package/dist/tests/e2e/differential-values.test.js +15 -0
  177. package/dist/tests/e2e/differential-values.test.js.map +1 -1
  178. package/dist/tests/e2e/gui-browser.test.d.ts +13 -0
  179. package/dist/tests/e2e/gui-browser.test.js +163 -0
  180. package/dist/tests/e2e/gui-browser.test.js.map +1 -0
  181. package/dist/tests/e2e/gui-example-browser.test.js +2 -2
  182. package/dist/tests/e2e/gui-example-browser.test.js.map +1 -1
  183. package/dist/tests/e2e/gui-example-canvas.test.js +8 -5
  184. package/dist/tests/e2e/gui-example-canvas.test.js.map +1 -1
  185. package/dist/tests/e2e/gui-example-svg.test.js +4 -3
  186. package/dist/tests/e2e/gui-example-svg.test.js.map +1 -1
  187. package/dist/tests/e2e/gui-example.test.js +4 -3
  188. package/dist/tests/e2e/gui-example.test.js.map +1 -1
  189. package/dist/tests/e2e/gui-helpers.d.ts +3 -0
  190. package/dist/tests/e2e/gui-helpers.js +6 -3
  191. package/dist/tests/e2e/gui-helpers.js.map +1 -1
  192. package/dist/tests/e2e/gui-media-disabled.test.d.ts +9 -0
  193. package/dist/tests/e2e/gui-media-disabled.test.js +42 -0
  194. package/dist/tests/e2e/gui-media-disabled.test.js.map +1 -0
  195. package/dist/tests/e2e/gui-media.test.d.ts +6 -4
  196. package/dist/tests/e2e/gui-media.test.js +20 -16
  197. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  198. package/dist/tests/e2e/harness.d.ts +9 -0
  199. package/dist/tests/e2e/harness.js +14 -2
  200. package/dist/tests/e2e/harness.js.map +1 -1
  201. package/dist/tests/e2e/native-extensions.test.js +2 -1
  202. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  203. package/dist/tests/e2e/property-descriptors.test.js +20 -0
  204. package/dist/tests/e2e/property-descriptors.test.js.map +1 -1
  205. package/dist/tests/e2e/unicode-output.test.d.ts +16 -0
  206. package/dist/tests/e2e/unicode-output.test.js +67 -0
  207. package/dist/tests/e2e/unicode-output.test.js.map +1 -0
  208. package/dist/tests/e2e/weak-collections.test.js +16 -2
  209. package/dist/tests/e2e/weak-collections.test.js.map +1 -1
  210. package/dist/tests/extensions/media.test.d.ts +1 -0
  211. package/dist/tests/extensions/media.test.js +58 -0
  212. package/dist/tests/extensions/media.test.js.map +1 -0
  213. package/dist/tests/extensions/registry.test.js +8 -0
  214. package/dist/tests/extensions/registry.test.js.map +1 -1
  215. package/dist/tests/helpers.d.ts +1 -0
  216. package/dist/tests/helpers.js +1 -0
  217. package/dist/tests/helpers.js.map +1 -1
  218. package/dist/tests/lexer/identifiers.test.js +12 -0
  219. package/dist/tests/lexer/identifiers.test.js.map +1 -1
  220. package/dist/tests/lexer/scanner.test.js +8 -0
  221. package/dist/tests/lexer/scanner.test.js.map +1 -1
  222. package/dist/tests/lexer/strings.test.js +30 -0
  223. package/dist/tests/lexer/strings.test.js.map +1 -1
  224. package/dist/tests/parser/declarations.test.js +20 -0
  225. package/dist/tests/parser/declarations.test.js.map +1 -1
  226. package/dist/tests/parser/expressions.test.js +36 -0
  227. package/dist/tests/parser/expressions.test.js.map +1 -1
  228. package/dist/tests/platform.d.ts +32 -0
  229. package/dist/tests/platform.js +40 -0
  230. package/dist/tests/platform.js.map +1 -0
  231. package/dist/tests/platform.test.d.ts +12 -0
  232. package/dist/tests/platform.test.js +51 -0
  233. package/dist/tests/platform.test.js.map +1 -0
  234. package/dist/tests/version.test.js +4 -4
  235. package/dist/tests/version.test.js.map +1 -1
  236. package/doc/ai/README.md +10 -4
  237. package/doc/ai/build-recipe.md +1 -0
  238. package/doc/ai/cli.md +18 -6
  239. package/doc/ai/contributing.md +59 -2
  240. package/doc/ai/extensions.md +46 -23
  241. package/doc/ai/language-support.md +25 -16
  242. package/doc/ai/troubleshooting.md +9 -0
  243. package/doc/ai/zh-CN/README.md +9 -4
  244. package/doc/ai/zh-CN/build-recipe.md +1 -0
  245. package/doc/ai/zh-CN/cli.md +14 -4
  246. package/doc/ai/zh-CN/contributing.md +49 -3
  247. package/doc/ai/zh-CN/extensions.md +29 -8
  248. package/doc/ai/zh-CN/language-support.md +23 -14
  249. package/doc/ai/zh-CN/troubleshooting.md +8 -0
  250. package/doc/gui/api.md +45 -0
  251. package/doc/gui/build.md +37 -21
  252. package/doc/gui/known-issues.md +17 -6
  253. package/doc/gui/media.md +26 -11
  254. package/doc/gui/runtime.md +18 -0
  255. package/doc/gui-scripts.md +7 -0
  256. package/doc/gui.md +43 -33
  257. package/doc/implemented/binder.md +2 -0
  258. package/doc/implemented/checker.md +117 -0
  259. package/doc/implemented/cli.md +13 -1
  260. package/doc/implemented/codegen.md +3 -2
  261. package/doc/implemented/driver.md +2 -2
  262. package/doc/implemented/operators.md +2 -1
  263. package/doc/implemented/parser.md +3 -2
  264. package/doc/implemented/pipeline.md +8 -1
  265. package/doc/implemented/stdlib.md +2 -1
  266. package/doc/implemented/tests.md +3 -1
  267. package/doc/implemented.md +2 -0
  268. package/doc/npm-package.md +417 -0
  269. package/doc/requirements.md +4 -1
  270. package/doc/support-matrix.md +83 -0
  271. package/doc/unimplemented/classes.md +3 -0
  272. package/doc/unimplemented/deviations.md +3 -2
  273. package/doc/unimplemented/toolchain.md +1 -1
  274. package/doc/unimplemented/types.md +24 -8
  275. package/doc/unimplemented.md +1 -1
  276. package/doc/zh-CN/gui/api.md +41 -0
  277. package/doc/zh-CN/gui/build.md +28 -16
  278. package/doc/zh-CN/gui/known-issues.md +13 -5
  279. package/doc/zh-CN/gui/media.md +21 -10
  280. package/doc/zh-CN/gui/runtime.md +16 -0
  281. package/doc/zh-CN/gui-scripts.md +5 -0
  282. package/doc/zh-CN/gui.md +37 -32
  283. package/doc/zh-CN/implemented/binder.md +2 -0
  284. package/doc/zh-CN/implemented/checker.md +99 -0
  285. package/doc/zh-CN/implemented/cli.md +12 -1
  286. package/doc/zh-CN/implemented/codegen.md +3 -2
  287. package/doc/zh-CN/implemented/driver.md +2 -2
  288. package/doc/zh-CN/implemented/operators.md +1 -1
  289. package/doc/zh-CN/implemented/parser.md +3 -2
  290. package/doc/zh-CN/implemented/pipeline.md +3 -1
  291. package/doc/zh-CN/implemented/stdlib.md +2 -1
  292. package/doc/zh-CN/implemented/tests.md +3 -1
  293. package/doc/zh-CN/implemented.md +2 -0
  294. package/doc/zh-CN/npm-package.md +391 -0
  295. package/doc/zh-CN/post/announce.md +47 -47
  296. package/doc/zh-CN/requirements.md +4 -1
  297. package/doc/zh-CN/support-matrix.md +82 -0
  298. package/doc/zh-CN/unimplemented/classes.md +3 -0
  299. package/doc/zh-CN/unimplemented/deviations.md +3 -2
  300. package/doc/zh-CN/unimplemented/toolchain.md +1 -1
  301. package/doc/zh-CN/unimplemented/types.md +16 -6
  302. package/doc/zh-CN/unimplemented.md +1 -1
  303. package/llms.txt +4 -1
  304. package/package.json +3 -1
  305. package/runtime/ext_gui/audio.cpp +316 -0
  306. package/runtime/ext_gui/browser.cpp +547 -0
  307. package/runtime/ext_gui/browser_escape.cpp +85 -0
  308. package/runtime/ext_gui/browser_loop.cpp +83 -0
  309. package/runtime/ext_gui/canvas.cpp +9 -3
  310. package/runtime/ext_gui/canvas_raster.cpp +19 -1
  311. package/runtime/ext_gui/dom_api.cpp +36 -0
  312. package/runtime/ext_gui/dom_api_document.cpp +96 -5
  313. package/runtime/ext_gui/dom_api_events.cpp +20 -0
  314. package/runtime/ext_gui/dom_api_internal.h +19 -0
  315. package/runtime/ext_gui/dom_api_proto.cpp +6 -0
  316. package/runtime/ext_gui/gui.cpp +90 -23
  317. package/runtime/ext_gui/gui_engine.h +44 -0
  318. package/runtime/ext_gui/gui_media.cpp +69 -2
  319. package/runtime/ext_gui/media.cpp +34 -488
  320. package/runtime/ext_gui/media.h +54 -19
  321. package/runtime/ext_gui/media_api.h +65 -0
  322. package/runtime/ext_gui/window.cpp +9 -0
  323. package/runtime/ext_media/media.cpp +507 -0
  324. package/runtime/ext_media/media_bridge.c +35 -0
  325. package/runtime/ext_node/path/path.c +7 -7
  326. package/runtime/ext_node/url/url.c +4 -2
  327. package/runtime/rt.h +15 -0
  328. package/runtime/xt_constructors.c +2 -1
  329. package/runtime/xt_containers/objects.inc +22 -2
  330. package/runtime/xt_io/exception.inc +4 -2
  331. package/runtime/xt_stdlib/math.inc +62 -0
  332. package/runtime/xt_stdlib2/date.inc +7 -1
  333. package/runtime/xt_stdlib2/objects.inc +14 -0
  334. package/scripts/build-gui.ts +6 -72
  335. package/scripts/build-media.ts +245 -0
  336. package/scripts/support-matrix.ts +167 -0
  337. package/src/ast/common.ts +2 -0
  338. package/src/ast/declarations.ts +12 -1
  339. package/src/ast/expressions.ts +6 -0
  340. package/src/ast/kinds.ts +2 -0
  341. package/src/binder/binder.ts +3 -0
  342. package/src/binder/declarations.ts +70 -0
  343. package/src/binder/references.ts +84 -3
  344. package/src/binder/types.ts +30 -0
  345. package/src/canonical.ts +37 -0
  346. package/src/checker/assignability.ts +134 -0
  347. package/src/checker/calls.ts +135 -0
  348. package/src/checker/checker.ts +47 -0
  349. package/src/checker/declarations.ts +26 -0
  350. package/src/checker/flow.ts +236 -0
  351. package/src/checker/globals.ts +40 -0
  352. package/src/checker/source.ts +53 -0
  353. package/src/checker/type-infer.ts +185 -0
  354. package/src/checker/type-model.ts +212 -0
  355. package/src/checker/type-system.ts +578 -0
  356. package/src/checker/typecheck-types.ts +112 -0
  357. package/src/checker/typecheck.ts +586 -0
  358. package/src/checker/undefined.ts +43 -0
  359. package/src/checker/walk.ts +16 -0
  360. package/src/cli/help.ts +65 -0
  361. package/src/cli/hints.ts +13 -1
  362. package/src/cli/main.ts +12 -49
  363. package/src/codegen/generator/calls/access.ts +8 -8
  364. package/src/codegen/generator/calls/invocation.ts +8 -5
  365. package/src/codegen/generator/calls/super.ts +67 -5
  366. package/src/codegen/generator/context.ts +31 -19
  367. package/src/codegen/generator/debug.ts +2 -1
  368. package/src/codegen/generator/expressions/primary.ts +84 -13
  369. package/src/codegen/generator/generator.ts +11 -1
  370. package/src/codegen/generator/module.ts +65 -24
  371. package/src/codegen/generator/state.ts +11 -1
  372. package/src/codegen/generator/statements/variables.ts +20 -3
  373. package/src/codegen/generator/tables.ts +5 -0
  374. package/src/driver/build-key.ts +3 -0
  375. package/src/driver/bundler/graph.ts +6 -2
  376. package/src/driver/bundler/merge.ts +14 -1
  377. package/src/driver/bundler/types.ts +13 -0
  378. package/src/driver/compiler.ts +5 -1
  379. package/src/driver/fingerprint.ts +2 -1
  380. package/src/driver/frontend.ts +13 -2
  381. package/src/driver/options.ts +6 -0
  382. package/src/driver/version.ts +1 -1
  383. package/src/extensions/catalog.ts +2 -1
  384. package/src/extensions/gui/html.ts +23 -10
  385. package/src/extensions/gui/index.ts +65 -0
  386. package/src/extensions/media/index.ts +67 -0
  387. package/src/extensions/registry.ts +72 -0
  388. package/src/index.ts +2 -0
  389. package/src/parser/declarations/classes.ts +7 -0
  390. package/src/parser/expressions.ts +13 -1
  391. package/src/parser/literals.ts +6 -2
@@ -0,0 +1,167 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Render `doc/support-matrix.md` and its Chinese mirror from the vendored
4
+ * test262 catalogue.
5
+ *
6
+ * The catalogue is executable evidence: `tests/conformance/test262.test.ts`
7
+ * compiles and runs every supported case (unmodified test262 files) and
8
+ * requires every unsupported case to fail with the listed diagnostic code.
9
+ * This script turns the same catalogue into the human-readable table, so the
10
+ * document cannot claim a feature the compiler does not exercise.
11
+ *
12
+ * Usage: npm run docs:matrix
13
+ */
14
+
15
+ import { writeFileSync } from "node:fs";
16
+ import { dirname, resolve } from "node:path";
17
+ import { fileURLToPath, pathToFileURL } from "node:url";
18
+ import {
19
+ SUPPORT_AREAS,
20
+ SUPPORTED_CASES,
21
+ UNSUPPORTED_CASES,
22
+ type SupportArea,
23
+ } from "../tests/conformance/test262/manifest.js";
24
+
25
+ const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
26
+
27
+ type Language = "en" | "zh";
28
+
29
+ export const MATRIX_FILES: Readonly<Record<Language, string>> = {
30
+ en: "doc/support-matrix.md",
31
+ zh: "doc/zh-CN/support-matrix.md",
32
+ };
33
+
34
+ export const TEST262_COMMIT = "d53ebc8b1931d9f1541e43d59650776e4b766248";
35
+
36
+ function docLink(area: SupportArea, language: Language): string {
37
+ const relative = area.doc.startsWith("doc/") ? area.doc.slice("doc/".length) : area.doc;
38
+ return language === "en" ? relative : `../${relative}`;
39
+ }
40
+
41
+ function areaTitle(area: SupportArea, language: Language): string {
42
+ return language === "en" ? area.title : area.titleZh;
43
+ }
44
+
45
+ function count(area: SupportArea, cases: readonly { readonly area: string }[]): number {
46
+ return cases.filter((testCase) => testCase.area === area.id).length;
47
+ }
48
+
49
+ function rowsFor(language: Language): string {
50
+ return SUPPORT_AREAS.map((area) => {
51
+ const supported = count(area, SUPPORTED_CASES);
52
+ const unsupported = count(area, UNSUPPORTED_CASES);
53
+ return `| ${areaTitle(area, language)} | ${supported} | ${unsupported} | [${language === "en" ? "reference" : "参考"}](${docLink(area, language)}) |`;
54
+ }).join("\n");
55
+ }
56
+
57
+ function supportedTable(language: Language): string {
58
+ const header =
59
+ language === "en"
60
+ ? "| test262 case | Area | What it pins down |\n| --- | --- | --- |"
61
+ : "| test262 用例 | 领域 | 固化的行为 |\n| --- | --- | --- |";
62
+ const rows = SUPPORTED_CASES.map((testCase) => {
63
+ const area = SUPPORT_AREAS.find((candidate) => candidate.id === testCase.area)!;
64
+ const claim = language === "en" ? testCase.claim : testCase.claimZh;
65
+ return `| \`${testCase.path}\` | ${areaTitle(area, language)} | ${claim} |`;
66
+ });
67
+ return [header, ...rows].join("\n");
68
+ }
69
+
70
+ function unsupportedTable(language: Language): string {
71
+ const header =
72
+ language === "en"
73
+ ? "| test262 case | Area | Diagnostic | Why |\n| --- | --- | ---: | --- |"
74
+ : "| test262 用例 | 领域 | 诊断码 | 原因 |\n| --- | --- | ---: | --- |";
75
+ const rows = UNSUPPORTED_CASES.map((testCase) => {
76
+ const area = SUPPORT_AREAS.find((candidate) => candidate.id === testCase.area)!;
77
+ const claim = language === "en" ? testCase.claim : testCase.claimZh;
78
+ return `| \`${testCase.path}\` | ${areaTitle(area, language)} | TS${testCase.code} | ${claim} |`;
79
+ });
80
+ return [header, ...rows].join("\n");
81
+ }
82
+
83
+ export function renderSupportMatrix(language: Language): string {
84
+ const corpusLink =
85
+ language === "en" ? "../tests/conformance/test262/manifest.ts" : "../../tests/conformance/test262/manifest.ts";
86
+ const testLink =
87
+ language === "en" ? "../tests/conformance/test262.test.ts" : "../../tests/conformance/test262.test.ts";
88
+ const sourceLink =
89
+ language === "en" ? "../tests/conformance/test262/SOURCE.md" : "../../tests/conformance/test262/SOURCE.md";
90
+
91
+ if (language === "en") {
92
+ return `# Support matrix
93
+
94
+ > Language: **English** | [简体中文](./zh-CN/support-matrix.md)
95
+
96
+ > **Generated** by \`npm run docs:matrix\` from the executable catalogue in
97
+ > [\`tests/conformance/test262/manifest.ts\`](${corpusLink}). Do not edit this
98
+ > file by hand: change a case and regenerate.
99
+
100
+ Every supported case is an unmodified [test262](https://github.com/tc39/test262)
101
+ file (pinned at \`${TEST262_COMMIT}\`) that xbintsc compiles **and runs**; the
102
+ [test262 suite](${testLink}) fails if one stops passing. The corpus is a
103
+ representative subset, not a full test262 run. Every unsupported case
104
+ is valid JavaScript that xbintsc currently rejects, pinned with the diagnostic
105
+ code it produces. See [\`SOURCE.md\`](${sourceLink}) for the harness adaptation.
106
+ Because the suite runs on every CI platform, this table cannot claim more than
107
+ the compiler does.
108
+
109
+ ## Coverage by area
110
+
111
+ | Area | Supported | Unsupported | Reference |
112
+ | --- | ---: | ---: | --- |
113
+ ${rowsFor(language)}
114
+
115
+ ## Supported cases (test262, compiled and executed)
116
+
117
+ ${supportedTable(language)}
118
+
119
+ ## Unsupported cases (valid JavaScript, expected diagnostics)
120
+
121
+ ${unsupportedTable(language)}
122
+ `;
123
+ }
124
+
125
+ return `# 支持矩阵
126
+
127
+ > 语言:[English](../support-matrix.md) | **简体中文**
128
+
129
+ > 本文件由 \`npm run docs:matrix\` 根据可执行语料
130
+ > [\`tests/conformance/test262/manifest.ts\`](${corpusLink}) 生成,请勿手工编辑:
131
+ > 修改用例后重新生成。
132
+
133
+ 每个“支持”用例都是 [test262](https://github.com/tc39/test262) 的原始文件
134
+ (固定版本 \`${TEST262_COMMIT}\`),由 xbintsc 编译**并执行**;
135
+ [test262 测试套件](${testLink}) 会在用例回归时失败。该语料是代表性
136
+ 子集,不是完整的 test262 全量运行。每个“不支持”用例都是
137
+ xbintsc 目前会拒绝的合法 JavaScript,并以实际产生的诊断码固定下来。
138
+ harness 的适配说明见 [\`SOURCE.md\`](${sourceLink})。该套件在 CI 的每个平台
139
+ 运行,因此本表不会声称编译器做不到的能力。
140
+
141
+ ## 各领域覆盖
142
+
143
+ | 领域 | 支持 | 不支持 | 参考 |
144
+ | --- | ---: | ---: | --- |
145
+ ${rowsFor(language)}
146
+
147
+ ## 支持的用例(test262,编译并执行)
148
+
149
+ ${supportedTable(language)}
150
+
151
+ ## 不支持的用例(合法 JavaScript,预期诊断)
152
+
153
+ ${unsupportedTable(language)}
154
+ `;
155
+ }
156
+
157
+ function main(): void {
158
+ for (const language of ["en", "zh"] as const) {
159
+ const path = resolve(root, MATRIX_FILES[language]);
160
+ writeFileSync(path, renderSupportMatrix(language));
161
+ process.stdout.write(`xbintsc: wrote ${MATRIX_FILES[language]}\n`);
162
+ }
163
+ }
164
+
165
+ if (process.argv[1] !== undefined && pathToFileURL(resolve(process.argv[1])).href === import.meta.url) {
166
+ main();
167
+ }
package/src/ast/common.ts CHANGED
@@ -33,6 +33,7 @@ import type {
33
33
  PropertyAccessExpression,
34
34
  RegularExpressionLiteral,
35
35
  SatisfiesExpression,
36
+ SequenceExpression,
36
37
  SpreadElement,
37
38
  StringLiteral,
38
39
  TaggedTemplateExpression,
@@ -143,6 +144,7 @@ export type Expression =
143
144
  | ConditionalExpression
144
145
  | AsExpression
145
146
  | SatisfiesExpression
147
+ | SequenceExpression
146
148
  | NonNullExpression
147
149
  | TypeOfExpression
148
150
  | VoidExpression
@@ -75,7 +75,11 @@ export interface ExpressionWithTypeArguments extends Node {
75
75
  readonly typeArguments: TypeNode[];
76
76
  }
77
77
 
78
- export type ClassElement = PropertyDeclaration | MethodDeclaration | ConstructorDeclaration;
78
+ export type ClassElement =
79
+ | PropertyDeclaration
80
+ | MethodDeclaration
81
+ | ConstructorDeclaration
82
+ | ClassStaticBlockDeclaration;
79
83
 
80
84
  export interface PropertyDeclaration extends Node {
81
85
  readonly kind: SyntaxKind.PropertyDeclaration;
@@ -108,6 +112,13 @@ export interface ConstructorDeclaration extends Node {
108
112
  readonly body?: Block;
109
113
  }
110
114
 
115
+ /** `static { ... }`: runs once, while the class is being defined. */
116
+ export interface ClassStaticBlockDeclaration extends Node {
117
+ readonly kind: SyntaxKind.ClassStaticBlockDeclaration;
118
+ readonly modifiers: Modifier[];
119
+ readonly body: Block;
120
+ }
121
+
111
122
  export interface ClassDeclaration extends Node {
112
123
  readonly kind: SyntaxKind.ClassDeclaration;
113
124
  readonly name?: Identifier;
@@ -206,6 +206,12 @@ export interface ParenthesizedExpression extends Node {
206
206
  readonly expression: Expression;
207
207
  }
208
208
 
209
+ /** `a, b, c`: evaluates every operand left to right, yields the last value. */
210
+ export interface SequenceExpression extends Node {
211
+ readonly kind: SyntaxKind.SequenceExpression;
212
+ readonly expressions: Expression[];
213
+ }
214
+
209
215
  export interface PrefixUnaryExpression extends Node {
210
216
  readonly kind: SyntaxKind.PrefixUnaryExpression;
211
217
  readonly operator: PrefixUnaryOperator;
package/src/ast/kinds.ts CHANGED
@@ -63,6 +63,7 @@ export const enum SyntaxKind {
63
63
  ObjectBindingPattern = 47,
64
64
  BindingElement = 48,
65
65
  ComputedPropertyName = 49,
66
+ SequenceExpression = 50,
66
67
 
67
68
  // Statements
68
69
  ExpressionStatement = 60,
@@ -112,6 +113,7 @@ export const enum SyntaxKind {
112
113
  ExportAssignment = 119,
113
114
  NamedExports = 120,
114
115
  ExportSpecifier = 121,
116
+ ClassStaticBlockDeclaration = 122,
115
117
 
116
118
  // Types
117
119
  TypeReference = 200,
@@ -20,6 +20,7 @@ import type { Identifier, Node, SourceFileNode } from "../ast/nodes.js";
20
20
  import {
21
21
  ScopeKind,
22
22
  type ClassInfo,
23
+ type DeclarationConflict,
23
24
  type FunctionInfo,
24
25
  type MutableFunction,
25
26
  type Scope,
@@ -45,6 +46,7 @@ export class Binder {
45
46
  readonly symbolOfIdentifier = new Map<Identifier, SymbolInfo>();
46
47
  readonly scopes = new Map<Node, Scope>();
47
48
  readonly unresolved: Identifier[] = [];
49
+ readonly conflicts: DeclarationConflict[] = [];
48
50
  nextSymbolId = 1;
49
51
  nextFunctionId = 1;
50
52
  nextClassId = 1;
@@ -83,6 +85,7 @@ export class Binder {
83
85
  symbolOfIdentifier: this.symbolOfIdentifier,
84
86
  scopes: this.scopes,
85
87
  unresolved: this.unresolved,
88
+ conflicts: this.conflicts,
86
89
  };
87
90
  }
88
91
 
@@ -20,6 +20,71 @@ import { SymbolKind, type MutableFunction, type Scope, type SymbolInfo } from ".
20
20
  import { childNodes } from "./helpers.js";
21
21
  import type { Binder } from "./binder.js";
22
22
 
23
+ /** Kinds that only introduce a type name, never a runtime binding. */
24
+ const TYPE_ONLY_KINDS: ReadonlySet<SymbolKind> = new Set([
25
+ SymbolKind.Interface,
26
+ SymbolKind.TypeAlias,
27
+ ]);
28
+
29
+ function isVarLike(kind: SymbolKind): boolean {
30
+ return kind === SymbolKind.Var || kind === SymbolKind.Function;
31
+ }
32
+
33
+ /**
34
+ * Whether a declaration of `next` may legally share a scope with `existing`.
35
+ *
36
+ * This is JavaScript's redeclaration rules plus TypeScript's declaration
37
+ * merging, kept deliberately explicit: a wrong `true` would hide a real bug, a
38
+ * wrong `false` would make valid code fail to compile. Only the cases this
39
+ * compiler can actually see are covered; anything unknown is treated as legal.
40
+ */
41
+ export function declarationsCanMerge(existing: SymbolKind, next: SymbolKind): boolean {
42
+ if (existing === next) {
43
+ /* Repeated `var` / `function` / `interface` / `enum` declarations merge.
44
+ * Two imports may also share a name: bundling merges every module into one
45
+ * scope, and separate modules routinely import the same builtin
46
+ * (`readFileSync` from `node:fs`, `dirname` from `node:path`). The import
47
+ * map is keyed by symbol id, so keeping the first declaration is enough.
48
+ * `let`, `const`, `class` and parameters do not merge. */
49
+ return (
50
+ existing === SymbolKind.Var ||
51
+ existing === SymbolKind.Function ||
52
+ existing === SymbolKind.Interface ||
53
+ existing === SymbolKind.Namespace ||
54
+ existing === SymbolKind.Enum ||
55
+ existing === SymbolKind.Import
56
+ );
57
+ }
58
+ // `var` and `function` are both function-scoped and may coexist in any order.
59
+ if (isVarLike(existing) && isVarLike(next)) return true;
60
+ // `var` may redeclare a parameter; `let`/`const` may not.
61
+ if (
62
+ (existing === SymbolKind.Parameter && next === SymbolKind.Var) ||
63
+ (existing === SymbolKind.Var && next === SymbolKind.Parameter)
64
+ ) {
65
+ return true;
66
+ }
67
+ // Namespaces merge with classes, functions, enums and each other.
68
+ if (existing === SymbolKind.Namespace || next === SymbolKind.Namespace) return true;
69
+ // A class and an interface merge their instance shape.
70
+ if (
71
+ (existing === SymbolKind.Class && next === SymbolKind.Interface) ||
72
+ (existing === SymbolKind.Interface && next === SymbolKind.Class)
73
+ ) {
74
+ return true;
75
+ }
76
+ // An import binds both a value and a type name, so it conflicts with any
77
+ // same-name local declaration.
78
+ if (existing === SymbolKind.Import || next === SymbolKind.Import) return false;
79
+ // Value and type names live in separate declaration spaces, except classes
80
+ // and enums, which declare a type as well as a value.
81
+ if (TYPE_ONLY_KINDS.has(existing) !== TYPE_ONLY_KINDS.has(next)) {
82
+ const valueKind = TYPE_ONLY_KINDS.has(existing) ? next : existing;
83
+ return valueKind !== SymbolKind.Class && valueKind !== SymbolKind.Enum;
84
+ }
85
+ return false;
86
+ }
87
+
23
88
  export interface DeclarationMethods {
24
89
  declareBinding(this: Binder, name: BindingName, kind: SymbolKind, declaration: Node, scope: Scope, mutable: boolean): SymbolInfo | undefined;
25
90
  declare(this: Binder, name: string, kind: SymbolKind, node: Node, scope: Scope, mutable: boolean): SymbolInfo;
@@ -60,6 +125,11 @@ export const declarationMethods: DeclarationMethods = {
60
125
  ): SymbolInfo {
61
126
  const existing = scope.symbols.get(name);
62
127
  if (existing) {
128
+ // `(anonymous)` is the binder's placeholder for `export default
129
+ // function () {}`; those have no user-visible name to collide.
130
+ if (name !== "(anonymous)" && !declarationsCanMerge(existing.kind, kind)) {
131
+ this.conflicts.push({ name, existing, kind, node });
132
+ }
63
133
  // `var` redeclarations and duplicate functions merge into one symbol.
64
134
  if (
65
135
  (kind === SymbolKind.Var && existing.kind === SymbolKind.Var) ||
@@ -33,7 +33,9 @@ import type { ArrayBindingPattern, ObjectBindingPattern, Parameter } from "../as
33
33
  import {
34
34
  ScopeKind,
35
35
  SymbolKind,
36
+ type ClassFieldInfo,
36
37
  type ClassInfo,
38
+ type ClassStaticInit,
37
39
  type FunctionInfo,
38
40
  type FunctionNode,
39
41
  type MutableFunction,
@@ -136,6 +138,23 @@ export const referenceMethods: ReferenceMethods = {
136
138
  case SyntaxKind.LabeledStatement:
137
139
  this.bindNode((node as unknown as { statement: Node }).statement, scope);
138
140
  return;
141
+ case SyntaxKind.SwitchStatement: {
142
+ const statement = node as unknown as {
143
+ expression: Expression;
144
+ clauses: { expression?: Expression; statements: Statement[] }[];
145
+ };
146
+ this.bindNode(statement.expression, scope);
147
+ /* Every `case` body shares the switch's block scope, so the
148
+ * declarations they contain have to be pre-declared before any clause
149
+ * is bound. Without this a `const` declared directly in a `case`
150
+ * clause had no symbol and later phases crashed on it. */
151
+ for (const clause of statement.clauses) {
152
+ this.bindNode(clause.expression, scope);
153
+ this.predeclareStatements(clause.statements, scope);
154
+ }
155
+ for (const clause of statement.clauses) this.bindStatements(clause.statements, scope);
156
+ return;
157
+ }
139
158
  case SyntaxKind.BreakStatement:
140
159
  case SyntaxKind.ContinueStatement:
141
160
  return;
@@ -150,6 +169,15 @@ export const referenceMethods: ReferenceMethods = {
150
169
  case SyntaxKind.TypeAliasDeclaration:
151
170
  // Type-only: skip the body entirely.
152
171
  return;
172
+ case SyntaxKind.EnumDeclaration: {
173
+ /* Member names are keys of the generated object, not bindings; only an
174
+ * initializer (`A = foo()`) contains runtime references. */
175
+ const members = (node as unknown as { members: { initializer?: Expression }[] }).members;
176
+ for (const member of members) {
177
+ if (member.initializer) this.bindNode(member.initializer, scope);
178
+ }
179
+ return;
180
+ }
153
181
  case SyntaxKind.ImportDeclaration:
154
182
  return;
155
183
  case SyntaxKind.ExportDeclaration: {
@@ -204,6 +232,22 @@ export const referenceMethods: ReferenceMethods = {
204
232
  this.bindBlock(clause.block, catchScope);
205
233
  return;
206
234
  }
235
+ /* Type positions are erased, so their identifiers are not runtime
236
+ * references. Walking them would put `Foo` from `x as Foo` or the type
237
+ * arguments of `f<Foo>()` into `unresolved`, and the checker would then
238
+ * report a value that never exists. */
239
+ case SyntaxKind.AsExpression:
240
+ case SyntaxKind.SatisfiesExpression:
241
+ case SyntaxKind.NonNullExpression:
242
+ this.bindNode((node as unknown as { expression: Expression }).expression, scope);
243
+ return;
244
+ case SyntaxKind.CallExpression:
245
+ case SyntaxKind.NewExpression: {
246
+ const call = node as unknown as { expression: Expression; arguments: Expression[] };
247
+ this.bindNode(call.expression, scope);
248
+ for (const argument of call.arguments) this.bindNode(argument, scope);
249
+ return;
250
+ }
207
251
  default:
208
252
  break;
209
253
  }
@@ -211,10 +255,24 @@ export const referenceMethods: ReferenceMethods = {
211
255
  },
212
256
 
213
257
  bindVariableList(list: VariableDeclarationList, scope: Scope): void {
258
+ const declarationKind =
259
+ list.declarationKind === "const"
260
+ ? SymbolKind.Const
261
+ : list.declarationKind === "var"
262
+ ? SymbolKind.Var
263
+ : SymbolKind.Let;
214
264
  for (const declaration of list.declarations) {
215
- const symbol = this.symbolOfDeclaration.get(declaration);
216
265
  if (declaration.name.kind === SyntaxKind.Identifier) {
217
- this.symbolOfDeclaration.set(declaration.name, symbol ?? this.symbolOfDeclaration.get(declaration) as SymbolInfo);
266
+ /* Normally the declaration was pre-declared; if it was not (a code
267
+ * path that binds statements without pre-declaring them), declare it
268
+ * here rather than storing an empty entry that later phases would
269
+ * dereference. */
270
+ const name = declaration.name as Identifier;
271
+ const symbol =
272
+ this.symbolOfDeclaration.get(declaration) ??
273
+ this.symbolOfDeclaration.get(name) ??
274
+ this.declareBinding(name, declarationKind, declaration, scope, declarationKind !== SymbolKind.Const);
275
+ if (symbol) this.symbolOfDeclaration.set(name, symbol);
218
276
  } else {
219
277
  this.bindBindingPattern(declaration.name, scope);
220
278
  }
@@ -329,6 +387,8 @@ export const referenceMethods: ReferenceMethods = {
329
387
  fields: [],
330
388
  methods: [],
331
389
  statics: [],
390
+ staticBlocks: [],
391
+ staticInit: [],
332
392
  };
333
393
  this.classes.push(info);
334
394
  this.classOfNode.set(node, info);
@@ -337,6 +397,9 @@ export const referenceMethods: ReferenceMethods = {
337
397
  this.scopes.set(node, classScope);
338
398
 
339
399
  let constructor: FunctionInfo | undefined;
400
+ /* `static { ... }` functions, so the field pass below can interleave them
401
+ * with static fields in declaration order. */
402
+ const staticBlockFns = new Map<Node, FunctionInfo>();
340
403
  for (const member of node.members) {
341
404
  if (member.kind === SyntaxKind.ConstructorDeclaration) {
342
405
  const ctor = member as ConstructorDeclaration;
@@ -354,6 +417,14 @@ export const referenceMethods: ReferenceMethods = {
354
417
  }
355
418
  if (isStatic) (info.statics as FunctionInfo[]).push(fn);
356
419
  else (info.methods as FunctionInfo[]).push(fn);
420
+ } else if (member.kind === SyntaxKind.ClassStaticBlockDeclaration) {
421
+ /* A static block is a function-like body: it runs once with `this`
422
+ * bound to the class, so it is bound like a static method and called
423
+ * right after the class value is built. */
424
+ const block = member as unknown as { body: Block };
425
+ const fn = this.createClassFunction(member, "static", [], block.body, classScope, info, true, false);
426
+ (info.staticBlocks as FunctionInfo[]).push(fn);
427
+ staticBlockFns.set(member, fn);
357
428
  }
358
429
  }
359
430
  if (!constructor) {
@@ -371,7 +442,17 @@ export const referenceMethods: ReferenceMethods = {
371
442
  this.current = constructor as MutableFunction;
372
443
  if (property.initializer) this.bindNode(property.initializer, classScope);
373
444
  this.current = owner;
374
- info.fields.push({ name: classMemberName(property.name), initializer: property.initializer, fn: constructor, isStatic });
445
+ const field: ClassFieldInfo = {
446
+ name: classMemberName(property.name),
447
+ initializer: property.initializer,
448
+ fn: constructor,
449
+ isStatic,
450
+ };
451
+ (info.fields as ClassFieldInfo[]).push(field);
452
+ if (isStatic) (info.staticInit as ClassStaticInit[]).push({ kind: "field", field });
453
+ } else if (member.kind === SyntaxKind.ClassStaticBlockDeclaration) {
454
+ const fn = staticBlockFns.get(member);
455
+ if (fn) (info.staticInit as ClassStaticInit[]).push({ kind: "block", fn });
375
456
  }
376
457
  }
377
458
 
@@ -43,6 +43,24 @@ export interface SymbolInfo {
43
43
  boxed: boolean;
44
44
  }
45
45
 
46
+ /**
47
+ * A same-scope declaration that cannot legally merge with the symbol already
48
+ * bound to that name (`let x` twice, `function f` then `const f`, ...).
49
+ *
50
+ * The binder records the conflict instead of reporting it: whether it is an
51
+ * error is checker policy (`--no-check` keeps the old, permissive behaviour),
52
+ * while the fact itself is cheap to capture during the one declaration pass.
53
+ */
54
+ export interface DeclarationConflict {
55
+ readonly name: string;
56
+ /** The symbol the name was already bound to. */
57
+ readonly existing: SymbolInfo;
58
+ /** The kind of the offending declaration. */
59
+ readonly kind: SymbolKind;
60
+ /** The offending declaration node (the second one to use the name). */
61
+ readonly node: Node;
62
+ }
63
+
46
64
  export type FunctionNode = SourceFileNode | FunctionDeclaration | FunctionExpression | ArrowFunction;
47
65
 
48
66
  export interface FunctionInfo {
@@ -88,10 +106,20 @@ export interface ClassInfo {
88
106
  readonly fields: ClassFieldInfo[];
89
107
  readonly methods: FunctionInfo[];
90
108
  readonly statics: FunctionInfo[];
109
+ /** `static { ... }` blocks, in declaration order. */
110
+ readonly staticBlocks: FunctionInfo[];
111
+ /** Static fields and static blocks, interleaved in declaration order: they
112
+ * run in source order, while static methods are installed before both. */
113
+ readonly staticInit: ClassStaticInit[];
91
114
  ctor?: FunctionInfo;
92
115
  /** The symbol the class name binds to, when there is one. */
93
116
  }
94
117
 
118
+ /** One static element evaluated at class-definition time, in source order. */
119
+ export type ClassStaticInit =
120
+ | { readonly kind: "field"; readonly field: ClassFieldInfo }
121
+ | { readonly kind: "block"; readonly fn: FunctionInfo };
122
+
95
123
  export interface ClassFieldInfo {
96
124
  readonly name: string;
97
125
  readonly initializer: Expression | undefined;
@@ -129,6 +157,8 @@ export interface BindResult {
129
157
  readonly scopes: Map<Node, Scope>;
130
158
  /** Identifier references that could not be resolved in user code. */
131
159
  readonly unresolved: Identifier[];
160
+ /** Same-scope declarations that cannot merge (see {@link DeclarationConflict}). */
161
+ readonly conflicts: readonly DeclarationConflict[];
132
162
  }
133
163
 
134
164
  export interface MutableFunction extends FunctionInfo {
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Canonical bytes for compiler-emitted artifacts.
3
+ *
4
+ * The compiler runs on Windows, macOS and Linux, and can be compiled by
5
+ * itself. Anything it writes into a byte-compared artifact — LLVM IR, debug
6
+ * metadata, the compiler fingerprint, the bundled module text and the `path`
7
+ * module's results — has to use the same representation on every host. These
8
+ * constants are that representation: do not spell `"/"` or `"\n"` in code that
9
+ * emits an artifact.
10
+ *
11
+ * Native paths are deliberately different. Diagnostics, `import.meta.filename`
12
+ * and `process.cwd()` keep the host separator, exactly like Node. Convert a
13
+ * native path with {@link artifactPath} only when it enters an artifact.
14
+ */
15
+
16
+ /** Separator between path segments in a compiler artifact. Deliberately not
17
+ * selected by `process.platform`: every host writes `/`, so the same source
18
+ * produces the same bytes (and Windows accepts `/` in every API). */
19
+ export const ARTIFACT_PATH_SEPARATOR = "/";
20
+
21
+ /** Line ending between records in a compiler artifact. Deliberately not
22
+ * `os.EOL`/`"\r\n"` on Windows: the runtime opens stdout/stderr in binary
23
+ * mode, and CRLF would make IR, fingerprints and documentation differ per
24
+ * host. */
25
+ export const ARTIFACT_LINE_ENDING = "\n";
26
+
27
+ /**
28
+ * Rewrite a native path for an artifact: `C:\dir\file.ts` becomes
29
+ * `C:/dir/file.ts`. A backslash is always a separator here, matching how the
30
+ * runtime and Node treat Windows paths.
31
+ */
32
+ export function artifactPath(path: string): string {
33
+ // `split`/`join` is measurably faster than a regex or `replaceAll` for the
34
+ // short paths this sees (it runs once per emitted stack frame), and it is the
35
+ // exact transform the compiler used before it was centralised.
36
+ return path.split("\\").join(ARTIFACT_PATH_SEPARATOR);
37
+ }