xbintsc 0.3.87 → 0.5.20

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 (458) hide show
  1. package/AGENTS.md +23 -11
  2. package/README.md +11 -9
  3. package/README.zh-CN.md +7 -7
  4. package/dist/src/binder/declarations.js +14 -3
  5. package/dist/src/binder/declarations.js.map +1 -1
  6. package/dist/src/cli/hints.js +7 -1
  7. package/dist/src/cli/hints.js.map +1 -1
  8. package/dist/src/cli/main.js +115 -15
  9. package/dist/src/cli/main.js.map +1 -1
  10. package/dist/src/cli/watch.d.ts +25 -0
  11. package/dist/src/cli/watch.js +93 -0
  12. package/dist/src/cli/watch.js.map +1 -0
  13. package/dist/src/codegen/generator/calls/access.js +17 -4
  14. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  15. package/dist/src/codegen/generator/calls/closures.js +13 -1
  16. package/dist/src/codegen/generator/calls/closures.js.map +1 -1
  17. package/dist/src/codegen/generator/calls/invocation.js +4 -3
  18. package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
  19. package/dist/src/codegen/generator/context.d.ts +8 -0
  20. package/dist/src/codegen/generator/context.js +22 -3
  21. package/dist/src/codegen/generator/context.js.map +1 -1
  22. package/dist/src/codegen/generator/expressions/operators.js +17 -15
  23. package/dist/src/codegen/generator/expressions/operators.js.map +1 -1
  24. package/dist/src/codegen/generator/expressions/primary.js +11 -1
  25. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  26. package/dist/src/codegen/generator/module.d.ts +0 -1
  27. package/dist/src/codegen/generator/module.js +10 -17
  28. package/dist/src/codegen/generator/module.js.map +1 -1
  29. package/dist/src/codegen/generator/numeric.d.ts +6 -3
  30. package/dist/src/codegen/generator/numeric.js +54 -11
  31. package/dist/src/codegen/generator/numeric.js.map +1 -1
  32. package/dist/src/codegen/generator/state.js +27 -0
  33. package/dist/src/codegen/generator/state.js.map +1 -1
  34. package/dist/src/codegen/generator/statements/control-flow.js +2 -7
  35. package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
  36. package/dist/src/codegen/generator/statements/loops.js +48 -16
  37. package/dist/src/codegen/generator/statements/loops.js.map +1 -1
  38. package/dist/src/codegen/generator/tables.d.ts +9 -0
  39. package/dist/src/codegen/generator/tables.js +100 -3
  40. package/dist/src/codegen/generator/tables.js.map +1 -1
  41. package/dist/src/diagnostics/diagnostic.d.ts +3 -1
  42. package/dist/src/diagnostics/diagnostic.js +23 -3
  43. package/dist/src/diagnostics/diagnostic.js.map +1 -1
  44. package/dist/src/driver/app-artifacts.d.ts +42 -0
  45. package/dist/src/driver/app-artifacts.js +53 -0
  46. package/dist/src/driver/app-artifacts.js.map +1 -0
  47. package/dist/src/driver/build-key.d.ts +29 -0
  48. package/dist/src/driver/build-key.js +35 -0
  49. package/dist/src/driver/build-key.js.map +1 -0
  50. package/dist/src/driver/bundler/graph.js +61 -12
  51. package/dist/src/driver/bundler/graph.js.map +1 -1
  52. package/dist/src/driver/bundler/merge.js +7 -1
  53. package/dist/src/driver/bundler/merge.js.map +1 -1
  54. package/dist/src/driver/compiler.d.ts +10 -67
  55. package/dist/src/driver/compiler.js +94 -230
  56. package/dist/src/driver/compiler.js.map +1 -1
  57. package/dist/src/driver/config.d.ts +3 -0
  58. package/dist/src/driver/config.js +8 -0
  59. package/dist/src/driver/config.js.map +1 -1
  60. package/dist/src/driver/frontend.d.ts +37 -0
  61. package/dist/src/driver/frontend.js +92 -0
  62. package/dist/src/driver/frontend.js.map +1 -0
  63. package/dist/src/driver/index.d.ts +1 -1
  64. package/dist/src/driver/index.js.map +1 -1
  65. package/dist/src/driver/options.d.ts +64 -0
  66. package/dist/src/driver/options.js +9 -0
  67. package/dist/src/driver/options.js.map +1 -0
  68. package/dist/src/driver/runtime-objects.d.ts +38 -0
  69. package/dist/src/driver/runtime-objects.js +111 -0
  70. package/dist/src/driver/runtime-objects.js.map +1 -0
  71. package/dist/src/driver/toolchain-provider.d.ts +4 -0
  72. package/dist/src/driver/toolchain-provider.js +4 -0
  73. package/dist/src/driver/toolchain-provider.js.map +1 -1
  74. package/dist/src/driver/toolchain.d.ts +32 -1
  75. package/dist/src/driver/toolchain.js +115 -11
  76. package/dist/src/driver/toolchain.js.map +1 -1
  77. package/dist/src/driver/version.d.ts +12 -0
  78. package/dist/src/driver/version.js +13 -0
  79. package/dist/src/driver/version.js.map +1 -0
  80. package/dist/src/driver/win-icon.d.ts +7 -9
  81. package/dist/src/driver/win-icon.js +37 -35
  82. package/dist/src/driver/win-icon.js.map +1 -1
  83. package/dist/src/parser/declarations/classes.js +5 -0
  84. package/dist/src/parser/declarations/classes.js.map +1 -1
  85. package/dist/src/parser/declarations/functions.js +13 -1
  86. package/dist/src/parser/declarations/functions.js.map +1 -1
  87. package/dist/src/parser/modules.js +8 -3
  88. package/dist/src/parser/modules.js.map +1 -1
  89. package/dist/src/parser/parser.d.ts +1 -0
  90. package/dist/src/parser/parser.js +23 -0
  91. package/dist/src/parser/parser.js.map +1 -1
  92. package/dist/tests/cli/check.test.d.ts +6 -0
  93. package/dist/tests/cli/check.test.js +68 -0
  94. package/dist/tests/cli/check.test.js.map +1 -0
  95. package/dist/tests/cli/main.test.js +19 -0
  96. package/dist/tests/cli/main.test.js.map +1 -1
  97. package/dist/tests/cli/watch.test.d.ts +6 -0
  98. package/dist/tests/cli/watch.test.js +72 -0
  99. package/dist/tests/cli/watch.test.js.map +1 -0
  100. package/dist/tests/codegen/closures.test.js +8 -0
  101. package/dist/tests/codegen/closures.test.js.map +1 -1
  102. package/dist/tests/codegen/expressions.test.js +15 -3
  103. package/dist/tests/codegen/expressions.test.js.map +1 -1
  104. package/dist/tests/codegen/llvm.test.js +16 -0
  105. package/dist/tests/codegen/llvm.test.js.map +1 -1
  106. package/dist/tests/diagnostics/diagnostic.test.js +8 -0
  107. package/dist/tests/diagnostics/diagnostic.test.js.map +1 -1
  108. package/dist/tests/docs/structure.test.d.ts +1 -0
  109. package/dist/tests/docs/structure.test.js +92 -0
  110. package/dist/tests/docs/structure.test.js.map +1 -0
  111. package/dist/tests/driver/compiler.test.js +6 -0
  112. package/dist/tests/driver/compiler.test.js.map +1 -1
  113. package/dist/tests/driver/config.test.js +9 -0
  114. package/dist/tests/driver/config.test.js.map +1 -1
  115. package/dist/tests/driver/icon.test.js +19 -32
  116. package/dist/tests/driver/icon.test.js.map +1 -1
  117. package/dist/tests/driver/invalid-input.test.d.ts +10 -0
  118. package/dist/tests/driver/invalid-input.test.js +29 -0
  119. package/dist/tests/driver/invalid-input.test.js.map +1 -0
  120. package/dist/tests/driver/modules.test.js +42 -3
  121. package/dist/tests/driver/modules.test.js.map +1 -1
  122. package/dist/tests/driver/toolchain-provider.test.js +27 -1
  123. package/dist/tests/driver/toolchain-provider.test.js.map +1 -1
  124. package/dist/tests/driver/toolchain.test.js +60 -2
  125. package/dist/tests/driver/toolchain.test.js.map +1 -1
  126. package/dist/tests/e2e/array-buffer.test.d.ts +5 -0
  127. package/dist/tests/e2e/array-buffer.test.js +38 -0
  128. package/dist/tests/e2e/array-buffer.test.js.map +1 -0
  129. package/dist/tests/e2e/array-from-iterables.test.d.ts +7 -0
  130. package/dist/tests/e2e/array-from-iterables.test.js +34 -0
  131. package/dist/tests/e2e/array-from-iterables.test.js.map +1 -0
  132. package/dist/tests/e2e/array-symbol-iterator.test.d.ts +8 -0
  133. package/dist/tests/e2e/array-symbol-iterator.test.js +42 -0
  134. package/dist/tests/e2e/array-symbol-iterator.test.js.map +1 -0
  135. package/dist/tests/e2e/async-await.test.d.ts +10 -0
  136. package/dist/tests/e2e/async-await.test.js +247 -0
  137. package/dist/tests/e2e/async-await.test.js.map +1 -0
  138. package/dist/tests/e2e/async-generators.test.d.ts +1 -0
  139. package/dist/tests/e2e/async-generators.test.js +154 -0
  140. package/dist/tests/e2e/async-generators.test.js.map +1 -0
  141. package/dist/tests/e2e/await-ordering.test.d.ts +5 -0
  142. package/dist/tests/e2e/await-ordering.test.js +37 -0
  143. package/dist/tests/e2e/await-ordering.test.js.map +1 -0
  144. package/dist/tests/e2e/compile-builtins.test.js +1 -1
  145. package/dist/tests/e2e/compile-modules.test.js +7 -0
  146. package/dist/tests/e2e/compile-modules.test.js.map +1 -1
  147. package/dist/tests/e2e/date-parse.test.d.ts +8 -0
  148. package/dist/tests/e2e/date-parse.test.js +38 -0
  149. package/dist/tests/e2e/date-parse.test.js.map +1 -0
  150. package/dist/tests/e2e/default-anonymous-exports.test.d.ts +7 -0
  151. package/dist/tests/e2e/default-anonymous-exports.test.js +23 -0
  152. package/dist/tests/e2e/default-anonymous-exports.test.js.map +1 -0
  153. package/dist/tests/e2e/globals-microtask.test.d.ts +9 -0
  154. package/dist/tests/e2e/globals-microtask.test.js +37 -0
  155. package/dist/tests/e2e/globals-microtask.test.js.map +1 -0
  156. package/dist/tests/e2e/gui-media.test.js +8 -1
  157. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  158. package/dist/tests/e2e/inspect-builtins.test.d.ts +10 -0
  159. package/dist/tests/e2e/inspect-builtins.test.js +43 -0
  160. package/dist/tests/e2e/inspect-builtins.test.js.map +1 -0
  161. package/dist/tests/e2e/json-builtin-objects.test.d.ts +9 -0
  162. package/dist/tests/e2e/json-builtin-objects.test.js +23 -0
  163. package/dist/tests/e2e/json-builtin-objects.test.js.map +1 -0
  164. package/dist/tests/e2e/json-circular.test.d.ts +6 -0
  165. package/dist/tests/e2e/json-circular.test.js +43 -0
  166. package/dist/tests/e2e/json-circular.test.js.map +1 -0
  167. package/dist/tests/e2e/json-parse-reviver.test.d.ts +6 -0
  168. package/dist/tests/e2e/json-parse-reviver.test.js +29 -0
  169. package/dist/tests/e2e/json-parse-reviver.test.js.map +1 -0
  170. package/dist/tests/e2e/json-stringify-replacer.test.d.ts +6 -0
  171. package/dist/tests/e2e/json-stringify-replacer.test.js +27 -0
  172. package/dist/tests/e2e/json-stringify-replacer.test.js.map +1 -0
  173. package/dist/tests/e2e/json-stringify-space.test.d.ts +6 -0
  174. package/dist/tests/e2e/json-stringify-space.test.js +23 -0
  175. package/dist/tests/e2e/json-stringify-space.test.js.map +1 -0
  176. package/dist/tests/e2e/method-dispatch-errors.test.d.ts +9 -0
  177. package/dist/tests/e2e/method-dispatch-errors.test.js +38 -0
  178. package/dist/tests/e2e/method-dispatch-errors.test.js.map +1 -0
  179. package/dist/tests/e2e/native-extensions.test.js +1 -1
  180. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  181. package/dist/tests/e2e/promise-with-resolvers.test.d.ts +5 -0
  182. package/dist/tests/e2e/promise-with-resolvers.test.js +20 -0
  183. package/dist/tests/e2e/promise-with-resolvers.test.js.map +1 -0
  184. package/dist/tests/e2e/property-descriptors.test.d.ts +5 -0
  185. package/dist/tests/e2e/property-descriptors.test.js +25 -0
  186. package/dist/tests/e2e/property-descriptors.test.js.map +1 -0
  187. package/dist/tests/e2e/property-ic.test.d.ts +1 -0
  188. package/dist/tests/e2e/property-ic.test.js +55 -0
  189. package/dist/tests/e2e/property-ic.test.js.map +1 -0
  190. package/dist/tests/e2e/runtime-coverage-globals.test.js +46 -0
  191. package/dist/tests/e2e/runtime-coverage-globals.test.js.map +1 -1
  192. package/dist/tests/e2e/runtime-errors.test.d.ts +10 -0
  193. package/dist/tests/e2e/runtime-errors.test.js +52 -0
  194. package/dist/tests/e2e/runtime-errors.test.js.map +1 -0
  195. package/dist/tests/e2e/string-utf16.test.d.ts +6 -0
  196. package/dist/tests/e2e/string-utf16.test.js +133 -0
  197. package/dist/tests/e2e/string-utf16.test.js.map +1 -0
  198. package/dist/tests/e2e/structured-clone.test.d.ts +6 -0
  199. package/dist/tests/e2e/structured-clone.test.js +49 -0
  200. package/dist/tests/e2e/structured-clone.test.js.map +1 -0
  201. package/dist/tests/e2e/text-codec.test.d.ts +6 -0
  202. package/dist/tests/e2e/text-codec.test.js +24 -0
  203. package/dist/tests/e2e/text-codec.test.js.map +1 -0
  204. package/dist/tests/e2e/typed-array-views.test.d.ts +6 -0
  205. package/dist/tests/e2e/typed-array-views.test.js +39 -0
  206. package/dist/tests/e2e/typed-array-views.test.js.map +1 -0
  207. package/dist/tests/e2e/url-search-params.test.d.ts +5 -0
  208. package/dist/tests/e2e/url-search-params.test.js +30 -0
  209. package/dist/tests/e2e/url-search-params.test.js.map +1 -0
  210. package/dist/tests/e2e/weak-collections.test.d.ts +1 -0
  211. package/dist/tests/e2e/weak-collections.test.js +88 -0
  212. package/dist/tests/e2e/weak-collections.test.js.map +1 -0
  213. package/dist/tests/parser/declarations.test.js +12 -0
  214. package/dist/tests/parser/declarations.test.js.map +1 -1
  215. package/dist/tests/parser/module-syntax.test.js +9 -0
  216. package/dist/tests/parser/module-syntax.test.js.map +1 -1
  217. package/dist/tests/parser/parser.test.js +7 -0
  218. package/dist/tests/parser/parser.test.js.map +1 -1
  219. package/dist/tests/version.test.js +5 -1
  220. package/dist/tests/version.test.js.map +1 -1
  221. package/doc/ai/README.md +4 -3
  222. package/doc/ai/cli.md +41 -0
  223. package/doc/ai/contributing.md +26 -21
  224. package/doc/ai/extensions.md +12 -9
  225. package/doc/ai/language-support.md +26 -19
  226. package/doc/ai/troubleshooting.md +15 -12
  227. package/doc/ai/zh-CN/README.md +3 -2
  228. package/doc/ai/zh-CN/cli.md +35 -0
  229. package/doc/ai/zh-CN/contributing.md +19 -18
  230. package/doc/ai/zh-CN/extensions.md +10 -7
  231. package/doc/ai/zh-CN/language-support.md +26 -20
  232. package/doc/ai/zh-CN/troubleshooting.md +12 -10
  233. package/doc/gui/build.md +13 -4
  234. package/doc/gui/known-issues.md +9 -5
  235. package/doc/gui/rendering.md +3 -1
  236. package/doc/gui.md +4 -3
  237. package/doc/icon.md +5 -4
  238. package/doc/implemented/async.md +38 -0
  239. package/doc/implemented/binder.md +13 -0
  240. package/doc/implemented/cli.md +47 -0
  241. package/doc/implemented/codegen.md +33 -0
  242. package/doc/implemented/collections.md +26 -0
  243. package/doc/implemented/driver.md +19 -0
  244. package/doc/implemented/extensions.md +19 -0
  245. package/doc/implemented/fetch.md +12 -0
  246. package/doc/implemented/lexer.md +23 -0
  247. package/doc/implemented/modules.md +28 -0
  248. package/doc/implemented/node/assert.md +17 -0
  249. package/doc/implemented/node/buffer.md +29 -0
  250. package/doc/implemented/node/child-process.md +29 -0
  251. package/doc/implemented/node/crypto.md +9 -0
  252. package/doc/implemented/node/dgram.md +15 -0
  253. package/doc/implemented/node/events.md +37 -0
  254. package/doc/implemented/node/fs-promises.md +38 -0
  255. package/doc/implemented/node/fs.md +112 -0
  256. package/doc/implemented/node/http.md +21 -0
  257. package/doc/implemented/node/net.md +17 -0
  258. package/doc/implemented/node/os.md +22 -0
  259. package/doc/implemented/node/path.md +33 -0
  260. package/doc/implemented/node/process.md +23 -0
  261. package/doc/implemented/node/querystring.md +20 -0
  262. package/doc/implemented/node/stream-promises.md +8 -0
  263. package/doc/implemented/node/stream.md +19 -0
  264. package/doc/implemented/node/test.md +10 -0
  265. package/doc/implemented/node/url.md +8 -0
  266. package/doc/implemented/node/util.md +25 -0
  267. package/doc/implemented/node/worker-threads.md +10 -0
  268. package/doc/implemented/node/zlib.md +8 -0
  269. package/doc/implemented/node.md +48 -0
  270. package/doc/implemented/operators.md +38 -0
  271. package/doc/implemented/parser.md +58 -0
  272. package/doc/implemented/pipeline.md +28 -0
  273. package/doc/implemented/runtime-core.md +32 -0
  274. package/doc/implemented/stdlib.md +78 -0
  275. package/doc/implemented/strings.md +27 -0
  276. package/doc/implemented/tests.md +10 -0
  277. package/doc/implemented/typed-arrays.md +26 -0
  278. package/doc/implemented/value-model.md +18 -0
  279. package/doc/implemented.md +54 -352
  280. package/doc/node-implemented.md +3 -585
  281. package/doc/node-unimplemented.md +3 -164
  282. package/doc/requirements.md +23 -8
  283. package/doc/unimplemented/classes.md +22 -0
  284. package/doc/unimplemented/deviations.md +27 -0
  285. package/doc/unimplemented/expressions.md +26 -0
  286. package/doc/unimplemented/functions.md +21 -0
  287. package/doc/unimplemented/modules.md +22 -0
  288. package/doc/unimplemented/node/async.md +17 -0
  289. package/doc/unimplemented/node/bun.md +9 -0
  290. package/doc/unimplemented/node/fs-promises.md +16 -0
  291. package/doc/unimplemented/node/fs.md +31 -0
  292. package/doc/unimplemented/node/globals.md +23 -0
  293. package/doc/unimplemented/node/modules.md +21 -0
  294. package/doc/unimplemented/node.md +21 -0
  295. package/doc/unimplemented/statements.md +18 -0
  296. package/doc/unimplemented/stdlib.md +54 -0
  297. package/doc/unimplemented/toolchain.md +14 -0
  298. package/doc/unimplemented/types.md +12 -0
  299. package/doc/unimplemented.md +18 -274
  300. package/doc/xbintsc.config.schema.json +12 -0
  301. package/doc/zh-CN/gui/build.md +11 -3
  302. package/doc/zh-CN/gui/known-issues.md +9 -4
  303. package/doc/zh-CN/gui/rendering.md +2 -1
  304. package/doc/zh-CN/gui.md +3 -2
  305. package/doc/zh-CN/icon.md +5 -4
  306. package/doc/zh-CN/implemented/async.md +38 -0
  307. package/doc/zh-CN/implemented/binder.md +13 -0
  308. package/doc/zh-CN/implemented/cli.md +46 -0
  309. package/doc/zh-CN/implemented/codegen.md +33 -0
  310. package/doc/zh-CN/implemented/collections.md +26 -0
  311. package/doc/zh-CN/implemented/driver.md +19 -0
  312. package/doc/zh-CN/implemented/extensions.md +19 -0
  313. package/doc/zh-CN/implemented/fetch.md +12 -0
  314. package/doc/zh-CN/implemented/lexer.md +23 -0
  315. package/doc/zh-CN/implemented/modules.md +28 -0
  316. package/doc/zh-CN/implemented/node/assert.md +17 -0
  317. package/doc/zh-CN/implemented/node/buffer.md +25 -0
  318. package/doc/zh-CN/implemented/node/child-process.md +27 -0
  319. package/doc/zh-CN/implemented/node/crypto.md +9 -0
  320. package/doc/zh-CN/implemented/node/dgram.md +15 -0
  321. package/doc/zh-CN/implemented/node/events.md +36 -0
  322. package/doc/zh-CN/implemented/node/fs-promises.md +27 -0
  323. package/doc/zh-CN/implemented/node/fs.md +105 -0
  324. package/doc/zh-CN/implemented/node/http.md +17 -0
  325. package/doc/zh-CN/implemented/node/net.md +17 -0
  326. package/doc/zh-CN/implemented/node/os.md +21 -0
  327. package/doc/zh-CN/implemented/node/path.md +26 -0
  328. package/doc/zh-CN/implemented/node/process.md +23 -0
  329. package/doc/zh-CN/implemented/node/querystring.md +20 -0
  330. package/doc/zh-CN/implemented/node/stream-promises.md +8 -0
  331. package/doc/zh-CN/implemented/node/stream.md +15 -0
  332. package/doc/zh-CN/implemented/node/test.md +10 -0
  333. package/doc/zh-CN/implemented/node/url.md +8 -0
  334. package/doc/zh-CN/implemented/node/util.md +25 -0
  335. package/doc/zh-CN/implemented/node/worker-threads.md +9 -0
  336. package/doc/zh-CN/implemented/node/zlib.md +8 -0
  337. package/doc/zh-CN/implemented/node.md +45 -0
  338. package/doc/zh-CN/implemented/operators.md +38 -0
  339. package/doc/zh-CN/implemented/parser.md +58 -0
  340. package/doc/zh-CN/implemented/pipeline.md +25 -0
  341. package/doc/zh-CN/implemented/runtime-core.md +31 -0
  342. package/doc/zh-CN/implemented/stdlib.md +76 -0
  343. package/doc/zh-CN/implemented/strings.md +27 -0
  344. package/doc/zh-CN/implemented/tests.md +10 -0
  345. package/doc/zh-CN/implemented/typed-arrays.md +26 -0
  346. package/doc/zh-CN/implemented/value-model.md +18 -0
  347. package/doc/zh-CN/implemented.md +50 -347
  348. package/doc/zh-CN/node-implemented.md +4 -531
  349. package/doc/zh-CN/node-unimplemented.md +4 -139
  350. package/doc/zh-CN/plan-require-node-modules.md +4 -4
  351. package/doc/zh-CN/requirements.md +20 -6
  352. package/doc/zh-CN/unimplemented/classes.md +22 -0
  353. package/doc/zh-CN/unimplemented/deviations.md +24 -0
  354. package/doc/zh-CN/unimplemented/expressions.md +24 -0
  355. package/doc/zh-CN/unimplemented/functions.md +21 -0
  356. package/doc/zh-CN/unimplemented/modules.md +19 -0
  357. package/doc/zh-CN/unimplemented/node/async.md +17 -0
  358. package/doc/zh-CN/unimplemented/node/bun.md +8 -0
  359. package/doc/zh-CN/unimplemented/node/fs-promises.md +12 -0
  360. package/doc/zh-CN/unimplemented/node/fs.md +24 -0
  361. package/doc/zh-CN/unimplemented/node/globals.md +14 -0
  362. package/doc/zh-CN/unimplemented/node/modules.md +15 -0
  363. package/doc/zh-CN/unimplemented/node.md +18 -0
  364. package/doc/zh-CN/unimplemented/statements.md +15 -0
  365. package/doc/zh-CN/unimplemented/stdlib.md +54 -0
  366. package/doc/zh-CN/unimplemented/toolchain.md +14 -0
  367. package/doc/zh-CN/unimplemented/types.md +11 -0
  368. package/doc/zh-CN/unimplemented.md +14 -236
  369. package/llms.txt +32 -4
  370. package/package.json +1 -1
  371. package/runtime/ext_gui/renderer_shaders.h +2 -2
  372. package/runtime/ext_gui/stb_image.h +1 -17
  373. package/runtime/ext_node/child_process/child_process.c +173 -73
  374. package/runtime/rt.h +47 -0
  375. package/runtime/rt_internal.h +205 -10
  376. package/runtime/xt_alloc.c +49 -7
  377. package/runtime/xt_array_buffer.c +284 -0
  378. package/runtime/xt_async.c +222 -0
  379. package/runtime/xt_bigint/helpers.inc +3 -3
  380. package/runtime/xt_builtins.c +59 -51
  381. package/runtime/xt_constructors.c +399 -0
  382. package/runtime/xt_containers/access.inc +195 -14
  383. package/runtime/xt_containers/arrays.inc +26 -2
  384. package/runtime/xt_containers/objects.inc +226 -5
  385. package/runtime/xt_containers/shapes.inc +71 -0
  386. package/runtime/xt_containers.c +1 -0
  387. package/runtime/xt_coroutine.c +229 -0
  388. package/runtime/xt_generator.c +325 -167
  389. package/runtime/xt_io/inspect.inc +147 -2
  390. package/runtime/xt_loop.c +35 -4
  391. package/runtime/xt_performance.c +37 -0
  392. package/runtime/xt_promise.c +125 -18
  393. package/runtime/xt_stdlib/arrays.inc +1 -1
  394. package/runtime/xt_stdlib/dispatch.inc +64 -13
  395. package/runtime/xt_stdlib/strings.inc +74 -17
  396. package/runtime/xt_stdlib2/array-statics.inc +28 -3
  397. package/runtime/xt_stdlib2/arrays.inc +5 -3
  398. package/runtime/xt_stdlib2/container.inc +5 -0
  399. package/runtime/xt_stdlib2/date.inc +111 -3
  400. package/runtime/xt_stdlib2/error.inc +35 -0
  401. package/runtime/xt_stdlib2/json.inc +353 -33
  402. package/runtime/xt_stdlib2/number-string-statics.inc +24 -15
  403. package/runtime/xt_stdlib2/objects.inc +123 -1
  404. package/runtime/xt_stdlib2/regexp-match.inc +2 -2
  405. package/runtime/xt_stdlib2/set.inc +7 -1
  406. package/runtime/xt_stdlib2/strings.inc +70 -40
  407. package/runtime/xt_structured_clone.c +159 -0
  408. package/runtime/xt_symbol.c +2 -2
  409. package/runtime/xt_text_codec.c +69 -0
  410. package/runtime/xt_typed_array/construction.inc +78 -7
  411. package/runtime/xt_typed_array/elements.inc +159 -0
  412. package/runtime/xt_typed_array/methods.inc +21 -5
  413. package/runtime/xt_typed_array.c +11 -10
  414. package/runtime/xt_url.c +375 -0
  415. package/runtime/xt_values/arithmetic.inc +2 -2
  416. package/runtime/xt_values/constructors.inc +8 -0
  417. package/runtime/xt_values/conversions.inc +1 -1
  418. package/runtime/xt_values/strings.inc +19 -3
  419. package/runtime/xt_values/utf16.inc +340 -0
  420. package/runtime/xt_values.c +1 -0
  421. package/runtime/xt_weak.c +281 -0
  422. package/scripts/build-gui.ts +133 -60
  423. package/scripts/check-version.ts +3 -3
  424. package/src/binder/declarations.ts +14 -3
  425. package/src/cli/hints.ts +8 -1
  426. package/src/cli/main.ts +119 -18
  427. package/src/cli/watch.ts +101 -0
  428. package/src/codegen/generator/calls/access.ts +17 -4
  429. package/src/codegen/generator/calls/closures.ts +12 -1
  430. package/src/codegen/generator/calls/invocation.ts +4 -3
  431. package/src/codegen/generator/context.ts +23 -3
  432. package/src/codegen/generator/expressions/operators.ts +27 -13
  433. package/src/codegen/generator/expressions/primary.ts +10 -1
  434. package/src/codegen/generator/module.ts +10 -19
  435. package/src/codegen/generator/numeric.ts +85 -11
  436. package/src/codegen/generator/state.ts +27 -0
  437. package/src/codegen/generator/statements/control-flow.ts +2 -6
  438. package/src/codegen/generator/statements/loops.ts +50 -16
  439. package/src/codegen/generator/tables.ts +110 -3
  440. package/src/diagnostics/diagnostic.ts +23 -3
  441. package/src/driver/app-artifacts.ts +77 -0
  442. package/src/driver/build-key.ts +55 -0
  443. package/src/driver/bundler/graph.ts +63 -13
  444. package/src/driver/bundler/merge.ts +4 -1
  445. package/src/driver/compiler.ts +93 -324
  446. package/src/driver/config.ts +11 -0
  447. package/src/driver/frontend.ts +120 -0
  448. package/src/driver/index.ts +0 -1
  449. package/src/driver/options.ts +70 -0
  450. package/src/driver/runtime-objects.ts +133 -0
  451. package/src/driver/toolchain-provider.ts +4 -0
  452. package/src/driver/toolchain.ts +154 -10
  453. package/src/driver/version.ts +12 -0
  454. package/src/driver/win-icon.ts +36 -36
  455. package/src/parser/declarations/classes.ts +4 -0
  456. package/src/parser/declarations/functions.ts +12 -1
  457. package/src/parser/modules.ts +8 -4
  458. package/src/parser/parser.ts +28 -0
@@ -20,24 +20,28 @@
20
20
  * `gui.lib` on Windows, built from MSVC-compatible COFF objects).
21
21
  *
22
22
  * Environment:
23
- * xbintsc_CXX C++ compiler override (default: clang++/c++/g++)
23
+ * xbintsc_CXX C++ compiler override (default: clang++ next to the resolved clang)
24
24
  * xbintsc_CMAKE CMake override (default: a vendored CMake, then `cmake`)
25
- * xbintsc_AR archiver override (default: llvm-ar, then ar)
25
+ * xbintsc_AR archiver override (default: llvm-ar next to clang, then llvm-ar)
26
26
  * SDL3_TAG SDL3 git tag to check out (default: release-3.2.10)
27
27
  * FREETYPE_VERSION FreeType version (default: 2.13.3)
28
28
  * HARFBUZZ_VERSION HarfBuzz version (default: 10.1.0)
29
29
  *
30
- * On Windows the engine is compiled with `clang++` against the MSVC ABI (run
31
- * from a Visual Studio developer prompt so `INCLUDE`/`LIB` are set) and merged
32
- * into a COFF `gui.lib` with `llvm-ar`.
30
+ * The C/C++ compiler is the same clang the driver resolves (see
31
+ * `src/driver/toolchain-provider.ts`), so the archive always matches the ABI of
32
+ * the runtime and emitted objects. On Windows that is an MSVC-targeting clang,
33
+ * normally the LLVM bundled with Visual Studio, and the result is a COFF
34
+ * `gui.lib`.
33
35
  */
34
36
 
35
- import { existsSync, mkdirSync, readdirSync, renameSync, rmSync } from "node:fs";
37
+ import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync } from "node:fs";
36
38
  import { availableParallelism } from "node:os";
37
39
  import { spawnSync, type SpawnSyncReturns } from "node:child_process";
38
40
  import { dirname, join, resolve } from "node:path";
39
41
  import { fileURLToPath } from "node:url";
40
42
  import { platformSlug } from "../src/driver/paths.js";
43
+ import { isMsvcTarget, probeClang, realRunner } from "../src/driver/toolchain.js";
44
+ import { resolveToolchain } from "../src/driver/toolchain-provider.js";
41
45
 
42
46
  const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
43
47
  const runtimeDir = join(root, "runtime");
@@ -81,18 +85,27 @@ const output = join(outDir, isWindows ? "gui.lib" : "gui.a");
81
85
  * `LNK2038: mismatch detected for 'RuntimeLibrary'`. The variable only takes
82
86
  * effect when policy CMP0091 is NEW, but FreeType and HarfBuzz declare
83
87
  * `cmake_minimum_required` below 3.15, which defaults the policy to OLD and
84
- * silently ignores it — hence `CMAKE_POLICY_DEFAULT_CMP0091`. The C/C++ compilers
85
- * are pinned to the same clang the engine is compiled with, so every object in
86
- * `gui.a` shares one ABI and optimization behaviour. */
87
- const cmakeGeneratorArgs: readonly string[] = isWindows
88
- ? [
89
- "-G", "Ninja",
90
- "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded",
91
- "-DCMAKE_POLICY_DEFAULT_CMP0091=NEW",
92
- "-DCMAKE_C_COMPILER=clang",
93
- "-DCMAKE_CXX_COMPILER=clang++",
94
- ]
95
- : [];
88
+ * silently ignores it — hence `CMAKE_POLICY_DEFAULT_CMP0091`.
89
+ *
90
+ * The tool paths are absolute and come from the same clang the driver resolves
91
+ * (on Windows, the LLVM bundled with Visual Studio when no newer one is on
92
+ * `PATH`), so every object merged into the archive shares one ABI and one
93
+ * optimization behaviour. Never leave these as bare `clang`/`clang++`: an older
94
+ * compiler earlier on `PATH` may be picked up at build time. */
95
+ function cmakeToolchainArgs(): string[] {
96
+ const compilers = [
97
+ `-DCMAKE_C_COMPILER=${clang}`,
98
+ `-DCMAKE_CXX_COMPILER=${clangxx}`,
99
+ ];
100
+ if (!isWindows) return compilers;
101
+ return [
102
+ "-G", "Ninja",
103
+ "-DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded",
104
+ "-DCMAKE_POLICY_DEFAULT_CMP0091=NEW",
105
+ ...compilers,
106
+ `-DCMAKE_AR=${llvmAr}`,
107
+ ];
108
+ }
96
109
 
97
110
  const SDL_TAG = process.env.SDL3_TAG || "release-3.2.10";
98
111
  const FREETYPE_VERSION = process.env.FREETYPE_VERSION || "2.13.3";
@@ -168,27 +181,103 @@ function findCmake(): string {
168
181
  return cmake;
169
182
  }
170
183
 
171
- function findCxx(): string {
172
- const cxx = firstAvailable([process.env.xbintsc_CXX, "clang++", "c++", "g++"]);
173
- if (!cxx) fail("no C++ compiler found; install clang++ or set xbintsc_CXX");
174
- return cxx;
184
+ /** The tool that sits next to `clang` in the same LLVM installation. */
185
+ function siblingTool(clangPath: string, name: string): string | undefined {
186
+ if (!clangPath.includes("/") && !clangPath.includes("\\")) return undefined;
187
+ const candidate = join(dirname(clangPath), `${name}${isWindows ? ".exe" : ""}`);
188
+ return existsSync(candidate) ? candidate : undefined;
175
189
  }
176
190
 
177
- function findCc(): string {
178
- const cc = firstAvailable([process.env.xbintsc_CC, process.env.CC, "clang", "cc", "gcc"]);
179
- if (!cc) fail("no C compiler found; install clang or set xbintsc_CC");
180
- return cc;
191
+ /** Resolve `clang++` from the same LLVM as the driver's clang. */
192
+ function findClangxx(clangPath: string): string {
193
+ const override = process.env.xbintsc_CXX;
194
+ if (override) {
195
+ const probe = probeClang(realRunner, override);
196
+ if (!probe.responds) fail(`xbintsc_CXX ${override} does not respond to --version`);
197
+ if (isWindows && (probe.version === undefined || (probe.target !== undefined && !isMsvcTarget(probe.target)))) {
198
+ fail(
199
+ `xbintsc_CXX ${override} is not an MSVC-targeting clang++ ` +
200
+ `(target ${probe.target ?? "unknown"}); the Windows GUI build requires one, for example ` +
201
+ "x86_64-pc-windows-msvc.",
202
+ );
203
+ }
204
+ return override;
205
+ }
206
+ const sibling = siblingTool(clangPath, "clang++");
207
+ if (sibling) return sibling;
208
+ const onPath = firstAvailable(["clang++"]);
209
+ if (onPath) return onPath;
210
+ fail("no clang++ found next to the resolved clang or on PATH; install LLVM or set xbintsc_CXX");
211
+ }
212
+
213
+ /** Resolve the archiver that matches the compiler, preferring LLVM's own. */
214
+ function findArchiver(clangPath: string): string {
215
+ const sibling = siblingTool(clangPath, "llvm-ar");
216
+ const archiver = firstAvailable([process.env.xbintsc_AR, sibling, "llvm-ar", isWindows ? undefined : "ar"]);
217
+ if (!archiver) fail("no archiver found; install llvm-ar or set xbintsc_AR");
218
+ return archiver;
181
219
  }
182
220
 
183
- function findArchiver(): string {
184
- const ar = firstAvailable([process.env.xbintsc_AR, "llvm-ar", "ar"]);
185
- if (!ar) fail("no archiver found; set xbintsc_AR to llvm-ar or ar");
186
- return ar;
221
+ /* One toolchain for the whole archive: the same clang the driver uses, its
222
+ * sibling clang++, and the matching llvm-ar. No `gcc`/`g++` fallbacks, and
223
+ * Windows never falls back to a non-LLVM archiver — mixing another C++ runtime
224
+ * or object format would break the final link. */
225
+ function driverClang(): string {
226
+ try {
227
+ return resolveToolchain().clang;
228
+ } catch (error) {
229
+ fail(error instanceof Error ? error.message : String(error));
230
+ }
231
+ }
232
+
233
+ const clang = driverClang();
234
+ const clangxx = findClangxx(clang);
235
+ const llvmAr = findArchiver(clang);
236
+
237
+
238
+ /** The compiler a previous CMake configure recorded for `buildDir`. */
239
+ function cachedCompiler(buildDir: string, variable: string): string | undefined {
240
+ const cache = join(buildDir, "CMakeCache.txt");
241
+ if (!existsSync(cache)) return undefined;
242
+ const match = new RegExp(`^${variable}:[^=]*=(.*)$`, "m").exec(readFileSync(cache, "utf8"));
243
+ return match?.[1]?.trim();
244
+ }
245
+
246
+ function sameToolPath(a: string, b: string): boolean {
247
+ const normalize = (value: string): string => value.replace(/\\/g, "/").replace(/\/+$/, "");
248
+ return process.platform === "win32"
249
+ ? normalize(a).toLowerCase() === normalize(b).toLowerCase()
250
+ : normalize(a) === normalize(b);
251
+ }
252
+
253
+ /**
254
+ * Configure a vendored CMake project, discarding a build tree whose cached
255
+ * compiler no longer matches the resolved toolchain. CMake refuses to switch
256
+ * compilers in place, and a tree configured by another clang would mix ABIs in
257
+ * the final archive.
258
+ */
259
+ function configureCmake(
260
+ name: string,
261
+ source: string,
262
+ build: string,
263
+ extraArgs: readonly string[],
264
+ ): string {
265
+ const cachedC = cachedCompiler(build, "CMAKE_C_COMPILER");
266
+ const cachedCxx = cachedCompiler(build, "CMAKE_CXX_COMPILER");
267
+ const stale =
268
+ (cachedC !== undefined && !sameToolPath(cachedC, clang)) ||
269
+ (cachedCxx !== undefined && !sameToolPath(cachedCxx, clangxx));
270
+ if (stale) {
271
+ console.log(`xbintsc: toolchain changed; reconfiguring ${name}`);
272
+ rmSync(build, { recursive: true, force: true });
273
+ }
274
+ const cmake = findCmake();
275
+ run(cmake, ["-S", source, "-B", build, ...cmakeToolchainArgs(), ...extraArgs]);
276
+ return cmake;
187
277
  }
188
278
 
189
279
  /** Directories a CMake `find_path` would search, relative to the filesystem
190
- * root, used to check that a development package is installed. */
191
- const HEADER_PREFIXES = ["/usr/include", "/usr/local/include", "/opt/homebrew/include"];
280
+ * root, used to check that a development package is installed. */const HEADER_PREFIXES = ["/usr/include", "/usr/local/include", "/opt/homebrew/include"];
192
281
 
193
282
  /** True on Debian and its derivatives, where the message below can name the
194
283
  * packages to install. Anywhere else the headers may well live under a prefix
@@ -300,19 +389,14 @@ if (!existingSdlArchive) {
300
389
  requireHeaders("SDL3's Wayland video driver", ["wayland-client-core.h"],
301
390
  "libwayland-dev libxkbcommon-dev libdecor-0-dev");
302
391
 
303
- const cmake = findCmake();
304
- console.log(`xbintsc: building static SDL3 with ${cmake}`);
305
- const configureArgs = [
306
- "-S", sdlSrc,
307
- "-B", sdlBuild,
308
- ...cmakeGeneratorArgs,
392
+ const cmake = configureCmake("SDL3", sdlSrc, sdlBuild, [
309
393
  "-DCMAKE_BUILD_TYPE=Release",
310
394
  "-DSDL_SHARED=OFF",
311
395
  "-DSDL_STATIC=ON",
312
396
  "-DSDL_TESTS=OFF",
313
397
  "-DSDL_EXAMPLES=OFF",
314
- ];
315
- run(cmake, configureArgs);
398
+ ]);
399
+ console.log(`xbintsc: building static SDL3 with ${cmake}`);
316
400
  run(cmake, ["--build", sdlBuild, "--config", "Release", "--target", "SDL3-static", "--parallel"]);
317
401
  } else {
318
402
  console.log(`xbintsc: reusing existing ${existingSdlArchive}`);
@@ -345,12 +429,7 @@ ensureTarballSource("freetype", FREETYPE_URL, `freetype-${FREETYPE_VERSION}`);
345
429
  ensureTarballSource("harfbuzz", HARFBUZZ_URL, `harfbuzz-${HARFBUZZ_VERSION}`);
346
430
 
347
431
  if (!existsSync(freetypeArchive() ?? "")) {
348
- const cmake = findCmake();
349
- console.log("xbintsc: building static FreeType");
350
- run(cmake, [
351
- "-S", freetypeSrc,
352
- "-B", freetypeBuild,
353
- ...cmakeGeneratorArgs,
432
+ const cmake = configureCmake("FreeType", freetypeSrc, freetypeBuild, [
354
433
  "-DCMAKE_BUILD_TYPE=Release",
355
434
  "-DBUILD_SHARED_LIBS=OFF",
356
435
  /* We only need TrueType/OpenType outlines; skip the optional codecs. */
@@ -360,18 +439,14 @@ if (!existsSync(freetypeArchive() ?? "")) {
360
439
  "-DFT_DISABLE_HARFBUZZ=TRUE",
361
440
  "-DFT_DISABLE_BROTLI=TRUE",
362
441
  ]);
442
+ console.log("xbintsc: building static FreeType");
363
443
  run(cmake, ["--build", freetypeBuild, "--config", "Release", "--parallel"]);
364
444
  } else {
365
445
  console.log(`xbintsc: reusing existing ${freetypeArchive()}`);
366
446
  }
367
447
 
368
448
  if (!existsSync(harfbuzzArchive() ?? "")) {
369
- const cmake = findCmake();
370
- console.log("xbintsc: building static HarfBuzz");
371
- run(cmake, [
372
- "-S", harfbuzzSrc,
373
- "-B", harfbuzzBuild,
374
- ...cmakeGeneratorArgs,
449
+ const cmake = configureCmake("HarfBuzz", harfbuzzSrc, harfbuzzBuild, [
375
450
  "-DCMAKE_BUILD_TYPE=Release",
376
451
  "-DBUILD_SHARED_LIBS=OFF",
377
452
  "-DHB_BUILD_UTILS=OFF",
@@ -382,6 +457,7 @@ if (!existsSync(harfbuzzArchive() ?? "")) {
382
457
  "-DHB_HAVE_ICU=OFF",
383
458
  "-DHB_HAVE_GRAPHITE2=OFF",
384
459
  ]);
460
+ console.log("xbintsc: building static HarfBuzz");
385
461
  run(cmake, ["--build", harfbuzzBuild, "--config", "Release", "--parallel"]);
386
462
  } else {
387
463
  console.log(`xbintsc: reusing existing ${harfbuzzArchive()}`);
@@ -398,9 +474,7 @@ if (isWindows) {
398
474
  ensureTarballSource("ffmpeg", FFMPEG_URL, `ffmpeg-${FFMPEG_VERSION}`, "configure");
399
475
  ffmpegLibraries = ffmpegStaticLibraries();
400
476
  if (!ffmpegLibraries) {
401
- const cc = findCc();
402
- const ccxx = findCxx();
403
- console.log(`xbintsc: building minimal static FFmpeg ${FFMPEG_VERSION} with ${cc}`);
477
+ console.log(`xbintsc: building minimal static FFmpeg ${FFMPEG_VERSION} with ${clang}`);
404
478
  mkdirSync(ffmpegBuild, { recursive: true });
405
479
  run(join(ffmpegSrc, "configure"), [
406
480
  `--prefix=${ffmpegInstall}`,
@@ -411,8 +485,8 @@ if (isWindows) {
411
485
  "--disable-everything",
412
486
  "--enable-avformat", "--enable-avcodec", "--enable-avutil", "--enable-swscale", "--enable-swresample",
413
487
  "--disable-network", "--disable-autodetect", "--disable-x86asm", "--disable-debug", "--enable-pic",
414
- `--cc=${cc}`,
415
- `--cxx=${ccxx}`,
488
+ `--cc=${clang}`,
489
+ `--cxx=${clangxx}`,
416
490
  ...FFMPEG_COMPONENTS,
417
491
  ], { cwd: ffmpegBuild });
418
492
  run("make", ["-j", String(availableParallelism())], { cwd: ffmpegBuild });
@@ -426,7 +500,6 @@ if (isWindows) {
426
500
 
427
501
  /* -- 3. engine objects ---------------------------------------------------- */
428
502
 
429
- const cxx = findCxx();
430
503
  mkdirSync(objDir, { recursive: true });
431
504
  const includeFlags = [
432
505
  "-I", runtimeDir,
@@ -454,7 +527,7 @@ if (!isWindows) cxxFlags.splice(3, 0, "-fPIC");
454
527
  for (const source of sources) {
455
528
  const object = join(objDir, source.replace(/\.cpp$/, objectSuffix));
456
529
  console.log(`xbintsc: compiling ${source}`);
457
- run(cxx, [...cxxFlags, "-c", join(engineDir, source), "-o", object]);
530
+ run(clangxx, [...cxxFlags, "-c", join(engineDir, source), "-o", object]);
458
531
  objects.push(object);
459
532
  }
460
533
 
@@ -480,7 +553,7 @@ if (process.platform === "darwin") {
480
553
  /* `ar -M` (GNU/LLVM) merges archives through an MRI script. Windows paths are
481
554
  * normalised to `/` so the MRI parser does not read `\` as an escape. */
482
555
  const mri = (path: string): string => path.replace(/\\/g, "/");
483
- const ar = findArchiver();
556
+ const ar = llvmAr;
484
557
  const script = [
485
558
  `create ${mri(output)}`,
486
559
  ...objects.map((object) => `addmod ${mri(object)}`),
@@ -15,9 +15,9 @@ import { fileURLToPath, pathToFileURL } from "node:url";
15
15
 
16
16
  /** Read the version literal from the compiler source. */
17
17
  export function compilerVersionOf(root: string): string {
18
- const text = readFileSync(join(root, "src", "driver", "compiler.ts"), "utf8");
18
+ const text = readFileSync(join(root, "src", "driver", "version.ts"), "utf8");
19
19
  const match = /export const COMPILER_VERSION = "([^"]+)"/.exec(text);
20
- if (!match) throw new Error("COMPILER_VERSION is not declared in src/driver/compiler.ts");
20
+ if (!match) throw new Error("COMPILER_VERSION is not declared in src/driver/version.ts");
21
21
  return match[1]!;
22
22
  }
23
23
 
@@ -35,7 +35,7 @@ export function checkCompilerVersion(root: string): string | undefined {
35
35
  if (packageVersion === compilerVersion) return undefined;
36
36
  return (
37
37
  `COMPILER_VERSION is "${compilerVersion}" but package.json is "${packageVersion}".\n` +
38
- 'Update COMPILER_VERSION in src/driver/compiler.ts (it keys the incremental cache), or fix package.json.'
38
+ 'Update COMPILER_VERSION in src/driver/version.ts (it keys the incremental cache), or fix package.json.'
39
39
  );
40
40
  }
41
41
 
@@ -98,9 +98,15 @@ export const declarationMethods: DeclarationMethods = {
98
98
  case SyntaxKind.FunctionDeclaration:
99
99
  this.declare((statement as FunctionDeclaration).name?.text ?? "(anonymous)", SymbolKind.Function, statement, scope, true);
100
100
  break;
101
- case SyntaxKind.ClassDeclaration:
102
- this.declare((statement as { name: Identifier }).name.text, SymbolKind.Class, statement, scope, false);
101
+ case SyntaxKind.ClassDeclaration: {
102
+ /* `export default class {}` has no binding name; the bundler maps the
103
+ * default export, so there is nothing to pre-declare. */
104
+ const className = (statement as { name?: Identifier }).name?.text;
105
+ if (className !== undefined) {
106
+ this.declare(className, SymbolKind.Class, statement, scope, false);
107
+ }
103
108
  break;
109
+ }
104
110
  case SyntaxKind.InterfaceDeclaration:
105
111
  this.declare((statement as { name: Identifier }).name.text, SymbolKind.Interface, statement, scope, false);
106
112
  break;
@@ -191,7 +197,12 @@ export const declarationMethods: DeclarationMethods = {
191
197
  statement.kind === SyntaxKind.FunctionDeclaration ||
192
198
  statement.kind === SyntaxKind.ClassDeclaration
193
199
  ) {
194
- const name = (statement as { name: Identifier }).name.text;
200
+ const name = (statement as { name?: Identifier }).name?.text;
201
+ if (name === undefined) {
202
+ /* `export default function () {}` / `export default class {}` have no
203
+ * binding name; the default export is handled by the bundler. */
204
+ continue;
205
+ }
195
206
  if (!fn.scope.symbols.has(name)) {
196
207
  this.declare(name, statement.kind === SyntaxKind.FunctionDeclaration ? SymbolKind.Function : SymbolKind.Class, statement, fn.scope, statement.kind === SyntaxKind.FunctionDeclaration);
197
208
  }
package/src/cli/hints.ts CHANGED
@@ -122,6 +122,7 @@ export function documentationFor(diagnostic: Diagnostic): DocumentationPointer |
122
122
  case DiagnosticCode.InvalidAssignmentTarget:
123
123
  case DiagnosticCode.DuplicateDefault:
124
124
  case DiagnosticCode.InvalidTypeSyntax:
125
+ case DiagnosticCode.NestingTooDeep:
125
126
  case DiagnosticCode.DuplicateIdentifier:
126
127
  case DiagnosticCode.CannotFindName:
127
128
  case DiagnosticCode.IllegalRedeclaration:
@@ -136,7 +137,7 @@ export function documentationFor(diagnostic: Diagnostic): DocumentationPointer |
136
137
 
137
138
  case DiagnosticCode.ModuleNotFound:
138
139
  return {
139
- text: "Node modules need the `node` extension (`--ext node`); third-party npm packages are not supported",
140
+ text: "Node built-ins need the `node` extension (`--ext node`); a package in `node_modules` is bundled at build time — check its name and exports map",
140
141
  path: DOC_EXTENSIONS,
141
142
  };
142
143
 
@@ -155,6 +156,12 @@ export function documentationFor(diagnostic: Diagnostic): DocumentationPointer |
155
156
  path: DOC_CLI,
156
157
  };
157
158
 
159
+ case DiagnosticCode.CircularDependency:
160
+ return {
161
+ text: "xbintsc does not support circular imports; move the shared binding into a third module",
162
+ path: "doc/unimplemented/modules.md",
163
+ };
164
+
158
165
  // The checker codes are defined but never emitted today.
159
166
  case DiagnosticCode.TypeMismatch:
160
167
  case DiagnosticCode.NotCallable:
package/src/cli/main.ts CHANGED
@@ -30,7 +30,6 @@ import {
30
30
  thrownFailure,
31
31
  toolchainPointer,
32
32
  UNEXPECTED_FAILURE_HINT,
33
- type DocumentationPointer,
34
33
  } from "./hints.js";
35
34
  import { createDefaultRegistry, type ExtensionRegistry } from "../extensions/registry.js";
36
35
  import { bundledExtensions } from "../extensions/catalog.js";
@@ -44,6 +43,10 @@ import {
44
43
  type AppConfig,
45
44
  type ProjectConfig,
46
45
  } from "../driver/config.js";
46
+ import { fingerprintTree, startWatching } from "./watch.js";
47
+
48
+ /** Sentinel: watch mode keeps the process alive instead of exiting. */
49
+ const KEEP_RUNNING = -1;
47
50
 
48
51
  export interface CliIo {
49
52
  readonly stdout: (text: string) => void;
@@ -80,6 +83,8 @@ const VALUE_FLAGS = new Set([
80
83
  "icon",
81
84
  "app-id",
82
85
  "app-name",
86
+ "pgo-generate",
87
+ "pgo-use",
83
88
  ]);
84
89
 
85
90
  function parseArgs(argv: readonly string[]): ParsedArgs {
@@ -200,22 +205,29 @@ function emitHint(io: CliIo, line: string): void {
200
205
  * the question.
201
206
  */
202
207
  function reportThrown(error: unknown, io: CliIo): number {
203
- const message =
204
- error instanceof ToolchainError
205
- ? `xbintsc: ${error.message}`
206
- : `xbintsc: ${error instanceof Error ? error.message : String(error)}`;
207
- io.stderr(`${message.trimEnd()}\n`);
208
- const text = error instanceof ToolchainError ? error.message : message;
209
- const pointer = error instanceof ToolchainError ? toolchainPointer(text) : thrownPointer(text);
210
- emitHint(io, `hint: ${pointer.text} — see ${pointer.path}`);
208
+ if (error instanceof ToolchainError) {
209
+ io.stderr(`xbintsc: ${error.message.trimEnd()}\n`);
210
+ const pointer = toolchainPointer(error.message);
211
+ emitHint(io, `hint: ${pointer.text} — see ${pointer.path}`);
212
+ return 1;
213
+ }
214
+ const message = error instanceof Error ? error.message : String(error);
215
+ const failure = thrownFailure(message);
216
+ if (failure === undefined) {
217
+ /* An uncaught exception that is not a known toolchain/setup failure is a
218
+ * compiler bug: say so instead of blaming the user's source or toolchain. */
219
+ io.stderr(`xbintsc: internal error: ${message.trimEnd()}\n`);
220
+ emitHint(
221
+ io,
222
+ `hint: this is a bug in xbintsc, not in your program — please report it with the input that triggered it — see ${UNEXPECTED_FAILURE_HINT.path}`,
223
+ );
224
+ return 1;
225
+ }
226
+ io.stderr(`xbintsc: ${message.trimEnd()}\n`);
227
+ emitHint(io, `hint: ${failure.pointer.text} — see ${failure.pointer.path}`);
211
228
  return 1;
212
229
  }
213
230
 
214
- /** The document that explains a failure the CLI reports as a plain message. */
215
- function thrownPointer(message: string): DocumentationPointer {
216
- return thrownFailure(message)?.pointer ?? UNEXPECTED_FAILURE_HINT;
217
- }
218
-
219
231
  /** Report a project-config failure, which never becomes a diagnostic bag. */
220
232
  function reportConfigError(error: string, io: CliIo): number {
221
233
  io.stderr(`xbintsc: ${error}\n`);
@@ -231,6 +243,8 @@ const HELP = `xbintsc ${COMPILER_VERSION} - TypeScript binary compiler
231
243
  Usage:
232
244
  xbintsc build <file.ts> [options] Compile to a native binary
233
245
  xbintsc run <file.ts> [-- args] Compile and execute
246
+ xbintsc check <file.ts> Parse and bind without linking
247
+ xbintsc watch <file.ts> [options] Rebuild whenever the source tree changes
234
248
  xbintsc emit <file.ts> Print LLVM IR
235
249
  xbintsc doctor Report the resolved toolchain
236
250
  xbintsc version Print the version
@@ -255,11 +269,15 @@ Options:
255
269
  --verbose Print progress information
256
270
  --time Print per-phase build timings
257
271
  --debug Emit debug info (DWARF/CodeView) and keep frame pointers
272
+ --lto Compile program and runtime to LTO bitcode; link with lld
273
+ --pgo-generate [dir] Build an instrumented binary writing profiles to dir
274
+ --pgo-use [dir] Build with the profiles collected from --pgo-generate
275
+ --json Print diagnostics as a JSON array on stdout
258
276
  --no-hints Do not append the "hint: … see <doc>" line to failures
259
277
 
260
278
  xbintsc compiles a subset of TypeScript to a native binary. Types are erased
261
- (never checked), Node modules need --ext node, third-party npm imports are not
262
- supported, and clang 16+ is required to link.
279
+ (never checked), Node built-ins need --ext node, packages in node_modules are
280
+ bundled at build time, and clang 16+ is required to link.
263
281
 
264
282
  Docs: doc/ai/README.md (task guide) - doc/ai/language-support.md (subset) -
265
283
  doc/ai/troubleshooting.md (failures) - llms.txt (index of every document)
@@ -323,7 +341,7 @@ function doctor(io: CliIo): number {
323
341
  try {
324
342
  if (!toolchain) throw new Error("no toolchain");
325
343
  const resource = resolveResourceCompiler(realRunner, toolchain.clang);
326
- io.stdout(`icon res : ${resource ? `${resource.tool} (${resource.kind})` : "none (.exe icon disabled)"}\n`);
344
+ io.stdout(`icon res : ${resource ? resource.tool : "none (.exe icon disabled)"}\n`);
327
345
  } catch {
328
346
  io.stdout("icon res : unknown\n");
329
347
  }
@@ -414,6 +432,57 @@ function dispatch(argv: readonly string[], io: CliIo): number {
414
432
  return 0;
415
433
  }
416
434
 
435
+ if (command === "check") {
436
+ const cliEntry = args.positionals[0];
437
+ const resolved = resolveProjectConfig(args.flags, cliEntry);
438
+ if (!resolved.ok) return reportConfigError(resolved.error, io);
439
+ const entry = cliEntry ?? resolved.config.entry;
440
+ if (!entry) {
441
+ io.stderr(`xbintsc: check requires a source file (or 'entry' in ${CONFIG_FILE_NAME})\n`);
442
+ emitHint(io, `hint: pass the entry file, or set 'entry' in ${CONFIG_FILE_NAME} — see ${DOC_CLI}`);
443
+ return 1;
444
+ }
445
+ const extNames = listFlag(args.flags, "ext") ?? resolved.config.extensions ?? [];
446
+ const nativeManifests = listFlag(args.flags, "ext-native") ?? resolved.config.extNative ?? [];
447
+ const registry = buildRegistry(extNames, nativeManifests);
448
+ /* Front-end only: parse, bundle and lower far enough to report binder /
449
+ * unsupported-feature diagnostics, but never invoke clang or write output. */
450
+ const { diagnostics } = compileEntry(entry, registry);
451
+ const failed = diagnostics.some((diagnostic) => diagnostic.category === "error");
452
+ if (args.flags.has("json")) {
453
+ io.stdout(`${JSON.stringify(diagnostics)}\n`);
454
+ } else if (failed) {
455
+ printDiagnostics(diagnostics, entry, io);
456
+ }
457
+ return failed ? 1 : 0;
458
+ }
459
+
460
+ if (command === "watch") {
461
+ const cliEntry = args.positionals[0];
462
+ const resolved = resolveProjectConfig(args.flags, cliEntry);
463
+ if (!resolved.ok) return reportConfigError(resolved.error, io);
464
+ const entry = cliEntry ?? resolved.config.entry;
465
+ if (!entry) {
466
+ io.stderr(`xbintsc: watch requires a source file (or 'entry' in ${CONFIG_FILE_NAME})\n`);
467
+ emitHint(io, `hint: pass the entry file, or set 'entry' in ${CONFIG_FILE_NAME} — see ${DOC_CLI}`);
468
+ return 1;
469
+ }
470
+ /* Re-enter the normal build path with the same flags, exactly as if the
471
+ * user had typed `build`; the config is re-read on every rebuild too. */
472
+ const forwarded = ["build", ...argv.slice(1)];
473
+ run(forwarded, io);
474
+ const root = dirname(resolve(entry));
475
+ startWatching({
476
+ scan: () => fingerprintTree(root),
477
+ onRebuild: () => {
478
+ io.stdout("\n");
479
+ run(forwarded, io);
480
+ },
481
+ });
482
+ io.stdout(`xbintsc: watching ${root} for changes (Ctrl+C to stop)\n`);
483
+ return KEEP_RUNNING;
484
+ }
485
+
417
486
  if (command === "emit") {
418
487
  const cliEntry = args.positionals[0];
419
488
  const resolved = resolveProjectConfig(args.flags, cliEntry);
@@ -429,6 +498,10 @@ function dispatch(argv: readonly string[], io: CliIo): number {
429
498
  const registry = buildRegistry(extNames, nativeManifests);
430
499
  const { ir, diagnostics } = compileEntry(entry, registry, { debug: Boolean(args.flags.get("debug")) });
431
500
  if (diagnostics.some((d) => d.category === "error")) {
501
+ if (args.flags.has("json")) {
502
+ io.stdout(`${JSON.stringify(diagnostics)}\n`);
503
+ return 1;
504
+ }
432
505
  printDiagnostics(diagnostics, entry, io);
433
506
  return 1;
434
507
  }
@@ -452,6 +525,24 @@ function dispatch(argv: readonly string[], io: CliIo): number {
452
525
  const extNames = listFlag(args.flags, "ext") ?? config.extensions ?? [];
453
526
  const nativeManifests = listFlag(args.flags, "ext-native") ?? config.extNative ?? [];
454
527
  const registry = buildRegistry(extNames, nativeManifests);
528
+ const pgoGenerate = args.flags.get("pgo-generate");
529
+ const pgoUse = args.flags.get("pgo-use");
530
+ if (pgoGenerate !== undefined && pgoUse !== undefined) {
531
+ io.stderr("xbintsc: --pgo-generate and --pgo-use are mutually exclusive\n");
532
+ return 1;
533
+ }
534
+ const pgo =
535
+ pgoGenerate !== undefined
536
+ ? ("generate" as const)
537
+ : pgoUse !== undefined
538
+ ? ("use" as const)
539
+ : config.pgo;
540
+ const pgoDir =
541
+ typeof pgoGenerate === "string"
542
+ ? pgoGenerate
543
+ : typeof pgoUse === "string"
544
+ ? pgoUse
545
+ : config.pgoDir;
455
546
 
456
547
  const result = build(entry, {
457
548
  output: typeof args.flags.get("output") === "string" ? (args.flags.get("output") as string) : config.output,
@@ -463,9 +554,16 @@ function dispatch(argv: readonly string[], io: CliIo): number {
463
554
  extensions: registry,
464
555
  app: mergeAppConfig(args.flags, config),
465
556
  debug: Boolean(args.flags.get("debug")),
557
+ lto: Boolean(args.flags.get("lto")) || config.lto === true,
558
+ ...(pgo ? { pgo } : {}),
559
+ ...(pgoDir ? { pgoDir } : {}),
466
560
  });
467
561
 
468
562
  if (result.diagnostics.some((d) => d.category === "error")) {
563
+ if (args.flags.has("json")) {
564
+ io.stdout(`${JSON.stringify(result.diagnostics)}\n`);
565
+ return 1;
566
+ }
469
567
  printDiagnostics(result.diagnostics, entry, io);
470
568
  return 1;
471
569
  }
@@ -493,5 +591,8 @@ function dispatch(argv: readonly string[], io: CliIo): number {
493
591
  const isMain =
494
592
  process.argv[1] !== undefined && import.meta.url === pathToFileURL(process.argv[1]).href;
495
593
  if (isMain) {
496
- process.exit(run(process.argv.slice(2)));
594
+ const status = run(process.argv.slice(2));
595
+ /* Watch mode returns KEEP_RUNNING; the polling interval keeps the process
596
+ * alive, so calling process.exit here would stop it immediately. */
597
+ if (status !== KEEP_RUNNING) process.exit(status);
497
598
  }