xbintsc 0.5.23 → 0.5.32

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 (481) hide show
  1. package/AGENTS.md +11 -2
  2. package/README.md +47 -16
  3. package/README.zh-CN.md +21 -2
  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 +99 -4
  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 +2 -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 +3 -0
  93. package/dist/src/codegen/generator/module.js +116 -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 +26 -7
  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 +3 -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/gui/css.d.ts +26 -0
  122. package/dist/src/extensions/gui/css.js +100 -0
  123. package/dist/src/extensions/gui/css.js.map +1 -0
  124. package/dist/src/extensions/gui/html.js +28 -7
  125. package/dist/src/extensions/gui/html.js.map +1 -1
  126. package/dist/src/extensions/gui/index.js +79 -2
  127. package/dist/src/extensions/gui/index.js.map +1 -1
  128. package/dist/src/extensions/gui/three.d.ts +16 -0
  129. package/dist/src/extensions/gui/three.js +22 -0
  130. package/dist/src/extensions/gui/three.js.map +1 -0
  131. package/dist/src/extensions/media/index.d.ts +6 -5
  132. package/dist/src/extensions/media/index.js +12 -14
  133. package/dist/src/extensions/media/index.js.map +1 -1
  134. package/dist/src/extensions/registry.d.ts +38 -0
  135. package/dist/src/extensions/registry.js +10 -0
  136. package/dist/src/extensions/registry.js.map +1 -1
  137. package/dist/src/index.d.ts +1 -0
  138. package/dist/src/index.js +1 -0
  139. package/dist/src/index.js.map +1 -1
  140. package/dist/src/parser/declarations/classes.js +7 -0
  141. package/dist/src/parser/declarations/classes.js.map +1 -1
  142. package/dist/src/parser/expressions.js +14 -1
  143. package/dist/src/parser/expressions.js.map +1 -1
  144. package/dist/src/parser/literals.js +6 -2
  145. package/dist/src/parser/literals.js.map +1 -1
  146. package/dist/tests/binder/binder.test.js +29 -0
  147. package/dist/tests/binder/binder.test.js.map +1 -1
  148. package/dist/tests/canonical.test.d.ts +1 -0
  149. package/dist/tests/canonical.test.js +19 -0
  150. package/dist/tests/canonical.test.js.map +1 -0
  151. package/dist/tests/checker/checker.test.d.ts +1 -0
  152. package/dist/tests/checker/checker.test.js +245 -0
  153. package/dist/tests/checker/checker.test.js.map +1 -0
  154. package/dist/tests/cli/check.test.js +20 -0
  155. package/dist/tests/cli/check.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 +45 -0
  170. package/dist/tests/e2e/compile-builtins.test.js.map +1 -1
  171. package/dist/tests/e2e/compile-objects-classes.test.js +77 -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-effects.test.d.ts +6 -0
  182. package/dist/tests/e2e/gui-effects.test.js +262 -0
  183. package/dist/tests/e2e/gui-effects.test.js.map +1 -0
  184. package/dist/tests/e2e/gui-example-browser.test.js +2 -2
  185. package/dist/tests/e2e/gui-example-browser.test.js.map +1 -1
  186. package/dist/tests/e2e/gui-example-canvas.test.js +5 -4
  187. package/dist/tests/e2e/gui-example-canvas.test.js.map +1 -1
  188. package/dist/tests/e2e/gui-example-svg.test.js +4 -3
  189. package/dist/tests/e2e/gui-example-svg.test.js.map +1 -1
  190. package/dist/tests/e2e/gui-example-webgl.test.d.ts +10 -0
  191. package/dist/tests/e2e/gui-example-webgl.test.js +75 -0
  192. package/dist/tests/e2e/gui-example-webgl.test.js.map +1 -0
  193. package/dist/tests/e2e/gui-example-webgl2.test.d.ts +8 -0
  194. package/dist/tests/e2e/gui-example-webgl2.test.js +72 -0
  195. package/dist/tests/e2e/gui-example-webgl2.test.js.map +1 -0
  196. package/dist/tests/e2e/gui-example.test.js +4 -3
  197. package/dist/tests/e2e/gui-example.test.js.map +1 -1
  198. package/dist/tests/e2e/gui-helpers.js +4 -3
  199. package/dist/tests/e2e/gui-helpers.js.map +1 -1
  200. package/dist/tests/e2e/gui-layout.test.js +48 -0
  201. package/dist/tests/e2e/gui-layout.test.js.map +1 -1
  202. package/dist/tests/e2e/gui-media.test.js +10 -8
  203. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  204. package/dist/tests/e2e/gui-webgl.test.d.ts +11 -0
  205. package/dist/tests/e2e/gui-webgl.test.js +179 -0
  206. package/dist/tests/e2e/gui-webgl.test.js.map +1 -0
  207. package/dist/tests/e2e/gui-webgl2.test.d.ts +10 -0
  208. package/dist/tests/e2e/gui-webgl2.test.js +238 -0
  209. package/dist/tests/e2e/gui-webgl2.test.js.map +1 -0
  210. package/dist/tests/e2e/harness.d.ts +9 -0
  211. package/dist/tests/e2e/harness.js +14 -2
  212. package/dist/tests/e2e/harness.js.map +1 -1
  213. package/dist/tests/e2e/native-extensions.test.js +2 -1
  214. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  215. package/dist/tests/e2e/property-descriptors.test.js +20 -0
  216. package/dist/tests/e2e/property-descriptors.test.js.map +1 -1
  217. package/dist/tests/e2e/unicode-output.test.js +5 -3
  218. package/dist/tests/e2e/unicode-output.test.js.map +1 -1
  219. package/dist/tests/e2e/weak-collections.test.js +16 -2
  220. package/dist/tests/e2e/weak-collections.test.js.map +1 -1
  221. package/dist/tests/extensions/gui.test.js +41 -0
  222. package/dist/tests/extensions/gui.test.js.map +1 -1
  223. package/dist/tests/extensions/media.test.js +7 -3
  224. package/dist/tests/extensions/media.test.js.map +1 -1
  225. package/dist/tests/helpers.d.ts +1 -0
  226. package/dist/tests/helpers.js +1 -0
  227. package/dist/tests/helpers.js.map +1 -1
  228. package/dist/tests/parser/declarations.test.js +20 -0
  229. package/dist/tests/parser/declarations.test.js.map +1 -1
  230. package/dist/tests/parser/expressions.test.js +36 -0
  231. package/dist/tests/parser/expressions.test.js.map +1 -1
  232. package/dist/tests/platform.d.ts +32 -0
  233. package/dist/tests/platform.js +40 -0
  234. package/dist/tests/platform.js.map +1 -0
  235. package/dist/tests/platform.test.d.ts +12 -0
  236. package/dist/tests/platform.test.js +51 -0
  237. package/dist/tests/platform.test.js.map +1 -0
  238. package/dist/tests/version.test.js +4 -4
  239. package/dist/tests/version.test.js.map +1 -1
  240. package/doc/ai/README.md +10 -4
  241. package/doc/ai/build-recipe.md +1 -0
  242. package/doc/ai/cli.md +17 -5
  243. package/doc/ai/contributing.md +59 -2
  244. package/doc/ai/extensions.md +38 -7
  245. package/doc/ai/language-support.md +25 -16
  246. package/doc/ai/troubleshooting.md +12 -8
  247. package/doc/ai/zh-CN/README.md +9 -4
  248. package/doc/ai/zh-CN/build-recipe.md +1 -0
  249. package/doc/ai/zh-CN/cli.md +13 -3
  250. package/doc/ai/zh-CN/contributing.md +49 -3
  251. package/doc/ai/zh-CN/extensions.md +33 -6
  252. package/doc/ai/zh-CN/language-support.md +23 -14
  253. package/doc/ai/zh-CN/troubleshooting.md +10 -6
  254. package/doc/gui/api.md +47 -1
  255. package/doc/gui/build.md +72 -16
  256. package/doc/gui/canvas.md +11 -3
  257. package/doc/gui/dom.md +33 -18
  258. package/doc/gui/known-issues.md +58 -15
  259. package/doc/gui/layout.md +18 -0
  260. package/doc/gui/media.md +17 -13
  261. package/doc/gui/rendering.md +50 -3
  262. package/doc/gui/runtime.md +18 -0
  263. package/doc/gui/webgl.md +256 -0
  264. package/doc/gui-scripts.md +7 -0
  265. package/doc/gui.md +108 -17
  266. package/doc/implemented/binder.md +2 -0
  267. package/doc/implemented/checker.md +117 -0
  268. package/doc/implemented/cli.md +13 -1
  269. package/doc/implemented/codegen.md +3 -2
  270. package/doc/implemented/driver.md +2 -2
  271. package/doc/implemented/operators.md +2 -1
  272. package/doc/implemented/parser.md +3 -2
  273. package/doc/implemented/pipeline.md +8 -1
  274. package/doc/implemented/stdlib.md +2 -1
  275. package/doc/implemented/tests.md +3 -1
  276. package/doc/implemented.md +2 -0
  277. package/doc/npm-package.md +419 -0
  278. package/doc/requirements.md +22 -10
  279. package/doc/support-matrix.md +83 -0
  280. package/doc/unimplemented/classes.md +3 -0
  281. package/doc/unimplemented/deviations.md +3 -2
  282. package/doc/unimplemented/toolchain.md +1 -1
  283. package/doc/unimplemented/types.md +24 -8
  284. package/doc/unimplemented.md +1 -1
  285. package/doc/zh-CN/gui/api.md +43 -1
  286. package/doc/zh-CN/gui/build.md +64 -15
  287. package/doc/zh-CN/gui/canvas.md +9 -2
  288. package/doc/zh-CN/gui/dom.md +20 -7
  289. package/doc/zh-CN/gui/known-issues.md +46 -13
  290. package/doc/zh-CN/gui/layout.md +14 -0
  291. package/doc/zh-CN/gui/media.md +15 -11
  292. package/doc/zh-CN/gui/rendering.md +41 -4
  293. package/doc/zh-CN/gui/runtime.md +16 -0
  294. package/doc/zh-CN/gui/webgl.md +115 -0
  295. package/doc/zh-CN/gui-scripts.md +5 -0
  296. package/doc/zh-CN/gui.md +89 -14
  297. package/doc/zh-CN/implemented/binder.md +2 -0
  298. package/doc/zh-CN/implemented/checker.md +99 -0
  299. package/doc/zh-CN/implemented/cli.md +12 -1
  300. package/doc/zh-CN/implemented/codegen.md +3 -2
  301. package/doc/zh-CN/implemented/driver.md +2 -2
  302. package/doc/zh-CN/implemented/operators.md +1 -1
  303. package/doc/zh-CN/implemented/parser.md +3 -2
  304. package/doc/zh-CN/implemented/pipeline.md +3 -1
  305. package/doc/zh-CN/implemented/stdlib.md +2 -1
  306. package/doc/zh-CN/implemented/tests.md +3 -1
  307. package/doc/zh-CN/implemented.md +2 -0
  308. package/doc/zh-CN/npm-package.md +394 -0
  309. package/doc/zh-CN/post/announce.md +47 -47
  310. package/doc/zh-CN/requirements.md +16 -7
  311. package/doc/zh-CN/support-matrix.md +82 -0
  312. package/doc/zh-CN/unimplemented/classes.md +3 -0
  313. package/doc/zh-CN/unimplemented/deviations.md +3 -2
  314. package/doc/zh-CN/unimplemented/toolchain.md +1 -1
  315. package/doc/zh-CN/unimplemented/types.md +16 -6
  316. package/doc/zh-CN/unimplemented.md +1 -1
  317. package/llms.txt +6 -1
  318. package/package.json +2 -1
  319. package/runtime/ext_gui/audio.cpp +316 -0
  320. package/runtime/ext_gui/browser.cpp +573 -0
  321. package/runtime/ext_gui/browser_escape.cpp +85 -0
  322. package/runtime/ext_gui/browser_loop.cpp +83 -0
  323. package/runtime/ext_gui/canvas.cpp +12 -21
  324. package/runtime/ext_gui/canvas_internal.h +10 -0
  325. package/runtime/ext_gui/canvas_raster.cpp +79 -1
  326. package/runtime/ext_gui/clip_values.cpp +246 -0
  327. package/runtime/ext_gui/css.cpp +94 -0
  328. package/runtime/ext_gui/css.h +22 -1
  329. package/runtime/ext_gui/css_match.cpp +3 -0
  330. package/runtime/ext_gui/css_selector.cpp +9 -0
  331. package/runtime/ext_gui/css_sheet.cpp +89 -45
  332. package/runtime/ext_gui/document.cpp +4 -1
  333. package/runtime/ext_gui/document.h +2 -0
  334. package/runtime/ext_gui/dom.h +16 -0
  335. package/runtime/ext_gui/dom_api.cpp +37 -0
  336. package/runtime/ext_gui/dom_api_canvas.cpp +17 -80
  337. package/runtime/ext_gui/dom_api_canvas_extra.cpp +130 -1
  338. package/runtime/ext_gui/dom_api_canvas_pending.cpp +41 -0
  339. package/runtime/ext_gui/dom_api_document.cpp +96 -5
  340. package/runtime/ext_gui/dom_api_events.cpp +20 -0
  341. package/runtime/ext_gui/dom_api_internal.h +278 -0
  342. package/runtime/ext_gui/dom_api_proto.cpp +6 -0
  343. package/runtime/ext_gui/dom_api_webgl.cpp +376 -0
  344. package/runtime/ext_gui/dom_api_webgl2.cpp +434 -0
  345. package/runtime/ext_gui/dom_api_webgl2_draw.cpp +269 -0
  346. package/runtime/ext_gui/dom_api_webgl_buffer.cpp +212 -0
  347. package/runtime/ext_gui/dom_api_webgl_rt.h +30 -0
  348. package/runtime/ext_gui/dom_api_webgl_shader.cpp +443 -0
  349. package/runtime/ext_gui/dom_api_webgl_state.cpp +444 -0
  350. package/runtime/ext_gui/dom_api_webgl_texture.cpp +445 -0
  351. package/runtime/ext_gui/effect_values.cpp +312 -0
  352. package/runtime/ext_gui/gradient_values.cpp +476 -0
  353. package/runtime/ext_gui/grid_values.cpp +230 -0
  354. package/runtime/ext_gui/gui.cpp +90 -23
  355. package/runtime/ext_gui/gui_canvas.cpp +50 -2
  356. package/runtime/ext_gui/gui_engine.h +71 -0
  357. package/runtime/ext_gui/gui_events.cpp +4 -1
  358. package/runtime/ext_gui/gui_media.cpp +1 -1
  359. package/runtime/ext_gui/gui_webgl.cpp +83 -0
  360. package/runtime/ext_gui/layout.cpp +21 -0
  361. package/runtime/ext_gui/layout_flow.cpp +81 -4
  362. package/runtime/ext_gui/layout_flow_internal.h +31 -0
  363. package/runtime/ext_gui/layout_grid.cpp +374 -0
  364. package/runtime/ext_gui/media.h +1 -1
  365. package/runtime/ext_gui/media_api.h +2 -2
  366. package/runtime/ext_gui/media_query.cpp +211 -0
  367. package/runtime/ext_gui/paint.cpp +111 -77
  368. package/runtime/ext_gui/paint.h +33 -3
  369. package/runtime/ext_gui/paint_background.cpp +229 -0
  370. package/runtime/ext_gui/paint_clip.cpp +268 -0
  371. package/runtime/ext_gui/paint_effects.cpp +324 -0
  372. package/runtime/ext_gui/paint_internal.h +85 -0
  373. package/runtime/ext_gui/renderer.cpp +8 -31
  374. package/runtime/ext_gui/renderer_clip.cpp +196 -0
  375. package/runtime/ext_gui/renderer_image.cpp +13 -8
  376. package/runtime/ext_gui/renderer_internal.h +15 -8
  377. package/runtime/ext_gui/renderer_text.cpp +6 -31
  378. package/runtime/ext_gui/style.cpp +343 -20
  379. package/runtime/ext_gui/style.h +144 -3
  380. package/runtime/ext_gui/style_print.cpp +134 -1
  381. package/runtime/ext_gui/style_values.cpp +152 -126
  382. package/runtime/ext_gui/style_values_internal.h +35 -0
  383. package/runtime/ext_gui/webgl.h +466 -0
  384. package/runtime/ext_gui/webgl2_constants.h +274 -0
  385. package/runtime/ext_gui/webgl_buffer.cpp +565 -0
  386. package/runtime/ext_gui/webgl_constants.h +317 -0
  387. package/runtime/ext_gui/webgl_context.cpp +466 -0
  388. package/runtime/ext_gui/webgl_draw.cpp +495 -0
  389. package/runtime/ext_gui/webgl_glsl.h +125 -0
  390. package/runtime/ext_gui/webgl_glsl_compile.cpp +431 -0
  391. package/runtime/ext_gui/webgl_glsl_rewrite.cpp +349 -0
  392. package/runtime/ext_gui/webgl_glsl_scan.cpp +581 -0
  393. package/runtime/ext_gui/webgl_msl.cpp +62 -0
  394. package/runtime/ext_gui/webgl_msl.h +33 -0
  395. package/runtime/ext_gui/webgl_pipeline.cpp +274 -0
  396. package/runtime/ext_gui/webgl_program_internal.h +18 -0
  397. package/runtime/ext_gui/webgl_shader.cpp +582 -0
  398. package/runtime/ext_gui/webgl_texture.cpp +293 -0
  399. package/runtime/ext_gui/webgl_uniform.cpp +167 -0
  400. package/runtime/ext_gui/webgl_webgl2.cpp +224 -0
  401. package/runtime/ext_gui/window.cpp +9 -0
  402. package/runtime/ext_media/media.cpp +1 -1
  403. package/runtime/ext_media/media_bridge.c +9 -3
  404. package/runtime/ext_node/path/path.c +7 -7
  405. package/runtime/ext_node/url/url.c +4 -2
  406. package/runtime/rt.h +15 -0
  407. package/runtime/rt_internal.h +1 -0
  408. package/runtime/xt_constructors.c +2 -1
  409. package/runtime/xt_containers/access.inc +8 -0
  410. package/runtime/xt_containers/objects.inc +22 -2
  411. package/runtime/xt_io/exception.inc +4 -2
  412. package/runtime/xt_regex/api.inc +2 -0
  413. package/runtime/xt_regex/matcher.inc +16 -3
  414. package/runtime/xt_regex/parser.inc +8 -2
  415. package/runtime/xt_regex/types.inc +3 -0
  416. package/runtime/xt_stdlib/math.inc +62 -0
  417. package/runtime/xt_stdlib2/date.inc +7 -1
  418. package/runtime/xt_stdlib2/objects.inc +14 -0
  419. package/runtime/xt_stdlib2/regexp-match.inc +60 -21
  420. package/runtime/xt_stdlib2/regexp.inc +1 -0
  421. package/runtime/xt_typed_array.c +1 -1
  422. package/scripts/build-gui.ts +90 -3
  423. package/scripts/build-media.ts +323 -58
  424. package/scripts/setup-vs-toolchain.ps1 +152 -0
  425. package/scripts/support-matrix.ts +167 -0
  426. package/src/ast/common.ts +2 -0
  427. package/src/ast/declarations.ts +12 -1
  428. package/src/ast/expressions.ts +6 -0
  429. package/src/ast/kinds.ts +2 -0
  430. package/src/binder/binder.ts +3 -0
  431. package/src/binder/declarations.ts +70 -0
  432. package/src/binder/references.ts +97 -4
  433. package/src/binder/types.ts +30 -0
  434. package/src/canonical.ts +37 -0
  435. package/src/checker/assignability.ts +134 -0
  436. package/src/checker/calls.ts +135 -0
  437. package/src/checker/checker.ts +47 -0
  438. package/src/checker/declarations.ts +26 -0
  439. package/src/checker/flow.ts +236 -0
  440. package/src/checker/globals.ts +40 -0
  441. package/src/checker/source.ts +53 -0
  442. package/src/checker/type-infer.ts +185 -0
  443. package/src/checker/type-model.ts +212 -0
  444. package/src/checker/type-system.ts +578 -0
  445. package/src/checker/typecheck-types.ts +112 -0
  446. package/src/checker/typecheck.ts +586 -0
  447. package/src/checker/undefined.ts +43 -0
  448. package/src/checker/walk.ts +16 -0
  449. package/src/cli/help.ts +65 -0
  450. package/src/cli/hints.ts +2 -1
  451. package/src/cli/main.ts +12 -49
  452. package/src/codegen/generator/calls/access.ts +8 -8
  453. package/src/codegen/generator/calls/invocation.ts +8 -5
  454. package/src/codegen/generator/calls/super.ts +67 -5
  455. package/src/codegen/generator/context.ts +31 -19
  456. package/src/codegen/generator/debug.ts +2 -1
  457. package/src/codegen/generator/expressions/primary.ts +84 -13
  458. package/src/codegen/generator/generator.ts +11 -1
  459. package/src/codegen/generator/module.ts +115 -24
  460. package/src/codegen/generator/state.ts +11 -1
  461. package/src/codegen/generator/statements/variables.ts +26 -6
  462. package/src/codegen/generator/tables.ts +5 -0
  463. package/src/driver/build-key.ts +3 -0
  464. package/src/driver/bundler/graph.ts +6 -2
  465. package/src/driver/bundler/merge.ts +14 -1
  466. package/src/driver/bundler/types.ts +13 -0
  467. package/src/driver/compiler.ts +4 -1
  468. package/src/driver/fingerprint.ts +2 -1
  469. package/src/driver/frontend.ts +13 -2
  470. package/src/driver/options.ts +6 -0
  471. package/src/driver/version.ts +1 -1
  472. package/src/extensions/gui/css.ts +113 -0
  473. package/src/extensions/gui/html.ts +31 -11
  474. package/src/extensions/gui/index.ts +81 -2
  475. package/src/extensions/gui/three.ts +25 -0
  476. package/src/extensions/media/index.ts +13 -16
  477. package/src/extensions/registry.ts +48 -0
  478. package/src/index.ts +1 -0
  479. package/src/parser/declarations/classes.ts +7 -0
  480. package/src/parser/expressions.ts +13 -1
  481. package/src/parser/literals.ts +6 -2
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env pwsh
2
+ <#
3
+ .SYNOPSIS
4
+ Select the Visual Studio MSVC + LLVM toolchain for a Windows build.
5
+
6
+ .DESCRIPTION
7
+ Finds the Visual Studio installation that owns the C++ build tools, imports
8
+ its `vcvarsall` environment (INCLUDE, LIB, PATH, ...), verifies the LLVM
9
+ bundled with that same installation (`clang`, `clang++`, `clang-cl`,
10
+ `llvm-ar`, `llvm-rc`) and exposes it as `xbintsc_CLANG`.
11
+
12
+ This is the toolchain a local build resolves and the one the prebuilt
13
+ `gui.lib` / `media.lib` archives are compiled with. GitHub Actions calls this
14
+ script from `.github/actions/vs-toolchain` instead of installing a separate
15
+ LLVM, so CI and local builds share one compiler chain.
16
+
17
+ Run it directly from a PowerShell prompt to use the same environment
18
+ interactively:
19
+
20
+ pwsh -File scripts/setup-vs-toolchain.ps1
21
+
22
+ In GitHub Actions it also appends the environment to `GITHUB_ENV` and the
23
+ LLVM bin directory to `GITHUB_PATH`, so later steps see it.
24
+
25
+ .PARAMETER InstallMake
26
+ Install GNU make through Chocolatey (the FFmpeg media build needs it). Only
27
+ used by CI; a local developer already has a native GNU make on PATH.
28
+ #>
29
+ [CmdletBinding()]
30
+ param(
31
+ [switch]$InstallMake
32
+ )
33
+
34
+ $ErrorActionPreference = "Stop"
35
+
36
+ function Write-GitHubEnv([string]$name, [string]$value) {
37
+ if ($env:GITHUB_ENV) {
38
+ "$name=$value" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
39
+ }
40
+ }
41
+
42
+ function Write-GitHubPath([string]$path) {
43
+ if ($env:GITHUB_PATH) {
44
+ $path | Out-File -FilePath $env:GITHUB_PATH -Append -Encoding utf8
45
+ }
46
+ }
47
+
48
+ # 1. Find Visual Studio with the C++ tools for this machine's architecture.
49
+ $arch = if ($env:RUNNER_ARCH -eq "ARM64" -or $env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "arm64" } else { "x64" }
50
+ $llvmArch = if ($arch -eq "arm64") { "ARM64" } else { "x64" }
51
+ $component = if ($arch -eq "arm64") {
52
+ "Microsoft.VisualStudio.Component.VC.Tools.arm64"
53
+ } else {
54
+ "Microsoft.VisualStudio.Component.VC.Tools.x86.x64"
55
+ }
56
+
57
+ $programFilesX86 = [Environment]::GetFolderPath("ProgramFilesX86")
58
+ $vswhere = Join-Path $programFilesX86 "Microsoft Visual Studio\Installer\vswhere.exe"
59
+ if (-not (Test-Path $vswhere)) {
60
+ $vswhere = Join-Path $env:ProgramFiles "Microsoft Visual Studio\Installer\vswhere.exe"
61
+ }
62
+ if (-not (Test-Path $vswhere)) {
63
+ throw "vswhere.exe not found; install Visual Studio with the C++ build tools."
64
+ }
65
+
66
+ $vsPath = (& $vswhere -latest -products * -requires $component -property installationPath |
67
+ Select-Object -First 1)
68
+ if ($vsPath) { $vsPath = $vsPath.Trim() }
69
+ if (-not $vsPath -or -not (Test-Path $vsPath)) {
70
+ throw "Visual Studio C++ build tools ($component) were not found."
71
+ }
72
+
73
+ # 2. Import the vcvarsall environment into this process and, in CI, the rest of
74
+ # the job. vcvarsall is locale-independent for KEY=VALUE output.
75
+ $vcvars = Join-Path $vsPath "VC\Auxiliary\Build\vcvarsall.bat"
76
+ if (-not (Test-Path $vcvars)) { throw "vcvarsall.bat not found at $vcvars" }
77
+ foreach ($line in (cmd /c "`"$vcvars`" $arch && set")) {
78
+ if ($line -match "^([^=]+)=(.*)$") {
79
+ $name = $matches[1]
80
+ $value = $matches[2]
81
+ Set-Item -Path "Env:$name" -Value $value
82
+ Write-GitHubEnv $name $value
83
+ }
84
+ }
85
+
86
+ # 3. Use the LLVM bundled with that Visual Studio installation. This is the
87
+ # same compiler the driver and the build scripts resolve locally; the
88
+ # fallback handles installations that put LLVM at the VC\Tools\Llvm root.
89
+ $llvmBin = Join-Path $vsPath "VC\Tools\Llvm\$llvmArch\bin"
90
+ if (-not (Test-Path (Join-Path $llvmBin "clang.exe"))) {
91
+ $llvmBin = Join-Path $vsPath "VC\Tools\Llvm\bin"
92
+ }
93
+ $clang = Join-Path $llvmBin "clang.exe"
94
+ if (-not (Test-Path $clang)) {
95
+ throw @"
96
+ Visual Studio at $vsPath has no LLVM at $llvmBin.
97
+ Install the "C++ Clang tools for Windows" component (Microsoft.VisualStudio.Component.VC.Llvm.Clang).
98
+ "@
99
+ }
100
+
101
+ $versionOutput = & $clang --version
102
+ if ($LASTEXITCODE -ne 0) { throw "$clang --version failed." }
103
+ $versionLine = ($versionOutput | Select-Object -First 1).Trim()
104
+ if ($versionLine -notmatch "clang version (\d+)\.") {
105
+ throw "$clang did not report a clang version: $versionLine"
106
+ }
107
+ $major = [int]$matches[1]
108
+ if ($major -lt 16) {
109
+ throw "Visual Studio's clang is $versionLine; xbintsc requires clang 16 or newer."
110
+ }
111
+ $targetLine = $versionOutput | Where-Object { $_ -match "^Target:" } | Select-Object -First 1
112
+ if (-not $targetLine -or $targetLine -notmatch "windows-msvc") {
113
+ throw "Visual Studio's clang targets '$targetLine', not the MSVC ABI."
114
+ }
115
+ $expectedTarget = if ($arch -eq "arm64") { "aarch64-pc-windows-msvc" } else { "x86_64-pc-windows-msvc" }
116
+ if ($targetLine -notmatch [regex]::Escape($expectedTarget)) {
117
+ throw "Visual Studio's clang targets '$targetLine'; this runner is $arch (expected $expectedTarget)."
118
+ }
119
+
120
+ # 4. Put it in front of PATH and tell the driver exactly which clang to use.
121
+ $env:xbintsc_CLANG = $clang
122
+ $env:Path = "$llvmBin;$env:Path"
123
+ Write-GitHubEnv "xbintsc_CLANG" $clang
124
+ Write-GitHubPath $llvmBin
125
+
126
+ # 5. Optional: GNU make for FFmpeg's configure (media archive only).
127
+ if ($InstallMake) {
128
+ if ($env:GITHUB_ACTIONS) {
129
+ choco install make --no-progress -y
130
+ if ($LASTEXITCODE -ne 0) { throw "choco install make failed" }
131
+ $makePath = "C:\ProgramData\chocolatey\bin\make.exe"
132
+ if (-not (Test-Path $makePath)) { throw "GNU make was not installed at $makePath" }
133
+ } else {
134
+ $makeCommand = Get-Command make -ErrorAction SilentlyContinue
135
+ if (-not $makeCommand) {
136
+ throw "GNU make not found; install it (choco install make) or run without -InstallMake."
137
+ }
138
+ $makePath = $makeCommand.Source
139
+ }
140
+ $env:xbintsc_MAKE = $makePath
141
+ Write-GitHubEnv "xbintsc_MAKE" $makePath
142
+ $makeVersion = (& $makePath --version | Select-Object -First 1).Trim()
143
+ if ($makeVersion -notmatch "GNU Make") {
144
+ throw "$makePath is not GNU make: $makeVersion"
145
+ }
146
+ Write-Host "make : $makePath ($makeVersion)"
147
+ }
148
+
149
+ Write-Host "Visual Studio: $vsPath"
150
+ Write-Host "MSVC arch : $arch"
151
+ Write-Host "clang : $clang ($versionLine)"
152
+ Write-Host "target : $targetLine"
@@ -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
 
@@ -429,7 +510,19 @@ export const referenceMethods: ReferenceMethods = {
429
510
  this.symbolOfIdentifier.set(identifier, symbol);
430
511
  // Functions, classes and type-only names are resolved to their
431
512
  // declaration sites by codegen; they are never captured as values.
432
- if (symbol.fn !== this.current && isCapturable(symbol.kind)) this.markCaptured(symbol);
513
+ // A *function declaration* reached from a nested function is the
514
+ // exception: the closure value belongs to the declaring function's
515
+ // frame (it may itself capture parameters), so thread it through the
516
+ // environment instead of rebuilding it at the call site with the
517
+ // caller's slots. Module-scope functions keep their global handling.
518
+ if (symbol.kind === SymbolKind.Function) {
519
+ /* Module-scope functions are reached through their globals; a
520
+ * function declared inside a function travels with the closure
521
+ * environment because its own captures belong to that frame. */
522
+ if (symbol.fn !== this.current && !symbol.fn.isModule) this.markCaptured(symbol);
523
+ } else if (symbol.fn !== this.current && isCapturable(symbol.kind)) {
524
+ this.markCaptured(symbol);
525
+ }
433
526
  return;
434
527
  }
435
528
  current = current.parent;