xbintsc 0.5.6 → 0.5.21

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 (490) hide show
  1. package/AGENTS.md +20 -10
  2. package/README.md +8 -7
  3. package/README.zh-CN.md +6 -6
  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 +11 -2
  14. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  15. package/dist/src/codegen/generator/calls/closures.js +12 -4
  16. package/dist/src/codegen/generator/calls/closures.js.map +1 -1
  17. package/dist/src/codegen/generator/context.d.ts +8 -0
  18. package/dist/src/codegen/generator/context.js +22 -3
  19. package/dist/src/codegen/generator/context.js.map +1 -1
  20. package/dist/src/codegen/generator/expressions/operators.js +17 -15
  21. package/dist/src/codegen/generator/expressions/operators.js.map +1 -1
  22. package/dist/src/codegen/generator/expressions/primary.js +5 -0
  23. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  24. package/dist/src/codegen/generator/module.js +0 -7
  25. package/dist/src/codegen/generator/module.js.map +1 -1
  26. package/dist/src/codegen/generator/numeric.d.ts +6 -3
  27. package/dist/src/codegen/generator/numeric.js +54 -11
  28. package/dist/src/codegen/generator/numeric.js.map +1 -1
  29. package/dist/src/codegen/generator/state.js +23 -0
  30. package/dist/src/codegen/generator/state.js.map +1 -1
  31. package/dist/src/codegen/generator/statements/control-flow.js +1 -4
  32. package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
  33. package/dist/src/codegen/generator/statements/loops.js +48 -16
  34. package/dist/src/codegen/generator/statements/loops.js.map +1 -1
  35. package/dist/src/codegen/generator/tables.js +26 -1
  36. package/dist/src/codegen/generator/tables.js.map +1 -1
  37. package/dist/src/diagnostics/diagnostic.d.ts +3 -1
  38. package/dist/src/diagnostics/diagnostic.js +23 -3
  39. package/dist/src/diagnostics/diagnostic.js.map +1 -1
  40. package/dist/src/driver/app-artifacts.d.ts +42 -0
  41. package/dist/src/driver/app-artifacts.js +53 -0
  42. package/dist/src/driver/app-artifacts.js.map +1 -0
  43. package/dist/src/driver/build-key.d.ts +29 -0
  44. package/dist/src/driver/build-key.js +35 -0
  45. package/dist/src/driver/build-key.js.map +1 -0
  46. package/dist/src/driver/bundler/graph.js +61 -12
  47. package/dist/src/driver/bundler/graph.js.map +1 -1
  48. package/dist/src/driver/bundler/merge.js +7 -1
  49. package/dist/src/driver/bundler/merge.js.map +1 -1
  50. package/dist/src/driver/compiler.d.ts +10 -67
  51. package/dist/src/driver/compiler.js +95 -234
  52. package/dist/src/driver/compiler.js.map +1 -1
  53. package/dist/src/driver/config.d.ts +3 -0
  54. package/dist/src/driver/config.js +8 -0
  55. package/dist/src/driver/config.js.map +1 -1
  56. package/dist/src/driver/frontend.d.ts +37 -0
  57. package/dist/src/driver/frontend.js +92 -0
  58. package/dist/src/driver/frontend.js.map +1 -0
  59. package/dist/src/driver/index.d.ts +1 -1
  60. package/dist/src/driver/index.js.map +1 -1
  61. package/dist/src/driver/options.d.ts +64 -0
  62. package/dist/src/driver/options.js +9 -0
  63. package/dist/src/driver/options.js.map +1 -0
  64. package/dist/src/driver/runtime-objects.d.ts +38 -0
  65. package/dist/src/driver/runtime-objects.js +112 -0
  66. package/dist/src/driver/runtime-objects.js.map +1 -0
  67. package/dist/src/driver/toolchain-provider.d.ts +4 -0
  68. package/dist/src/driver/toolchain-provider.js +4 -0
  69. package/dist/src/driver/toolchain-provider.js.map +1 -1
  70. package/dist/src/driver/toolchain.d.ts +32 -1
  71. package/dist/src/driver/toolchain.js +115 -11
  72. package/dist/src/driver/toolchain.js.map +1 -1
  73. package/dist/src/driver/version.d.ts +12 -0
  74. package/dist/src/driver/version.js +13 -0
  75. package/dist/src/driver/version.js.map +1 -0
  76. package/dist/src/driver/win-icon.d.ts +7 -9
  77. package/dist/src/driver/win-icon.js +37 -35
  78. package/dist/src/driver/win-icon.js.map +1 -1
  79. package/dist/src/extensions/node/fs/index.d.ts +4 -3
  80. package/dist/src/extensions/node/fs/index.js +12 -3
  81. package/dist/src/extensions/node/fs/index.js.map +1 -1
  82. package/dist/src/extensions/node/fs-promises/index.d.ts +5 -5
  83. package/dist/src/extensions/node/fs-promises/index.js +15 -6
  84. package/dist/src/extensions/node/fs-promises/index.js.map +1 -1
  85. package/dist/src/parser/declarations/classes.js +5 -0
  86. package/dist/src/parser/declarations/classes.js.map +1 -1
  87. package/dist/src/parser/declarations/functions.js +13 -1
  88. package/dist/src/parser/declarations/functions.js.map +1 -1
  89. package/dist/src/parser/modules.js +8 -3
  90. package/dist/src/parser/modules.js.map +1 -1
  91. package/dist/src/parser/parser.d.ts +1 -0
  92. package/dist/src/parser/parser.js +23 -0
  93. package/dist/src/parser/parser.js.map +1 -1
  94. package/dist/tests/cli/check.test.d.ts +6 -0
  95. package/dist/tests/cli/check.test.js +68 -0
  96. package/dist/tests/cli/check.test.js.map +1 -0
  97. package/dist/tests/cli/main.test.js +19 -0
  98. package/dist/tests/cli/main.test.js.map +1 -1
  99. package/dist/tests/cli/watch.test.d.ts +6 -0
  100. package/dist/tests/cli/watch.test.js +72 -0
  101. package/dist/tests/cli/watch.test.js.map +1 -0
  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.js +1 -1
  136. package/dist/tests/e2e/async-fs.test.d.ts +9 -0
  137. package/dist/tests/e2e/async-fs.test.js +119 -0
  138. package/dist/tests/e2e/async-fs.test.js.map +1 -0
  139. package/dist/tests/e2e/async-generators.test.d.ts +1 -0
  140. package/dist/tests/e2e/async-generators.test.js +154 -0
  141. package/dist/tests/e2e/async-generators.test.js.map +1 -0
  142. package/dist/tests/e2e/await-ordering.test.d.ts +5 -0
  143. package/dist/tests/e2e/await-ordering.test.js +37 -0
  144. package/dist/tests/e2e/await-ordering.test.js.map +1 -0
  145. package/dist/tests/e2e/compile-builtins.test.js +1 -1
  146. package/dist/tests/e2e/compile-modules.test.js +7 -0
  147. package/dist/tests/e2e/compile-modules.test.js.map +1 -1
  148. package/dist/tests/e2e/date-parse.test.d.ts +8 -0
  149. package/dist/tests/e2e/date-parse.test.js +38 -0
  150. package/dist/tests/e2e/date-parse.test.js.map +1 -0
  151. package/dist/tests/e2e/default-anonymous-exports.test.d.ts +7 -0
  152. package/dist/tests/e2e/default-anonymous-exports.test.js +23 -0
  153. package/dist/tests/e2e/default-anonymous-exports.test.js.map +1 -0
  154. package/dist/tests/e2e/fetch.test.js +24 -0
  155. package/dist/tests/e2e/fetch.test.js.map +1 -1
  156. package/dist/tests/e2e/globals-microtask.test.d.ts +9 -0
  157. package/dist/tests/e2e/globals-microtask.test.js +37 -0
  158. package/dist/tests/e2e/globals-microtask.test.js.map +1 -0
  159. package/dist/tests/e2e/gui-inline-svg.test.d.ts +11 -0
  160. package/dist/tests/e2e/gui-inline-svg.test.js +160 -0
  161. package/dist/tests/e2e/gui-inline-svg.test.js.map +1 -0
  162. package/dist/tests/e2e/gui-media.test.js +8 -1
  163. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  164. package/dist/tests/e2e/inspect-builtins.test.d.ts +10 -0
  165. package/dist/tests/e2e/inspect-builtins.test.js +43 -0
  166. package/dist/tests/e2e/inspect-builtins.test.js.map +1 -0
  167. package/dist/tests/e2e/json-builtin-objects.test.d.ts +9 -0
  168. package/dist/tests/e2e/json-builtin-objects.test.js +23 -0
  169. package/dist/tests/e2e/json-builtin-objects.test.js.map +1 -0
  170. package/dist/tests/e2e/json-circular.test.d.ts +6 -0
  171. package/dist/tests/e2e/json-circular.test.js +43 -0
  172. package/dist/tests/e2e/json-circular.test.js.map +1 -0
  173. package/dist/tests/e2e/json-parse-reviver.test.d.ts +6 -0
  174. package/dist/tests/e2e/json-parse-reviver.test.js +29 -0
  175. package/dist/tests/e2e/json-parse-reviver.test.js.map +1 -0
  176. package/dist/tests/e2e/json-stringify-replacer.test.d.ts +6 -0
  177. package/dist/tests/e2e/json-stringify-replacer.test.js +27 -0
  178. package/dist/tests/e2e/json-stringify-replacer.test.js.map +1 -0
  179. package/dist/tests/e2e/json-stringify-space.test.d.ts +6 -0
  180. package/dist/tests/e2e/json-stringify-space.test.js +23 -0
  181. package/dist/tests/e2e/json-stringify-space.test.js.map +1 -0
  182. package/dist/tests/e2e/method-dispatch-errors.test.d.ts +9 -0
  183. package/dist/tests/e2e/method-dispatch-errors.test.js +38 -0
  184. package/dist/tests/e2e/method-dispatch-errors.test.js.map +1 -0
  185. package/dist/tests/e2e/native-extensions.test.js +1 -1
  186. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  187. package/dist/tests/e2e/promise-with-resolvers.test.d.ts +5 -0
  188. package/dist/tests/e2e/promise-with-resolvers.test.js +20 -0
  189. package/dist/tests/e2e/promise-with-resolvers.test.js.map +1 -0
  190. package/dist/tests/e2e/property-descriptors.test.d.ts +5 -0
  191. package/dist/tests/e2e/property-descriptors.test.js +25 -0
  192. package/dist/tests/e2e/property-descriptors.test.js.map +1 -0
  193. package/dist/tests/e2e/property-ic.test.d.ts +1 -0
  194. package/dist/tests/e2e/property-ic.test.js +55 -0
  195. package/dist/tests/e2e/property-ic.test.js.map +1 -0
  196. package/dist/tests/e2e/runtime-errors.test.d.ts +10 -0
  197. package/dist/tests/e2e/runtime-errors.test.js +52 -0
  198. package/dist/tests/e2e/runtime-errors.test.js.map +1 -0
  199. package/dist/tests/e2e/structured-clone.test.d.ts +6 -0
  200. package/dist/tests/e2e/structured-clone.test.js +49 -0
  201. package/dist/tests/e2e/structured-clone.test.js.map +1 -0
  202. package/dist/tests/e2e/text-codec.test.d.ts +6 -0
  203. package/dist/tests/e2e/text-codec.test.js +24 -0
  204. package/dist/tests/e2e/text-codec.test.js.map +1 -0
  205. package/dist/tests/e2e/typed-array-views.test.d.ts +6 -0
  206. package/dist/tests/e2e/typed-array-views.test.js +39 -0
  207. package/dist/tests/e2e/typed-array-views.test.js.map +1 -0
  208. package/dist/tests/e2e/url-search-params.test.d.ts +5 -0
  209. package/dist/tests/e2e/url-search-params.test.js +30 -0
  210. package/dist/tests/e2e/url-search-params.test.js.map +1 -0
  211. package/dist/tests/e2e/weak-collections.test.d.ts +1 -0
  212. package/dist/tests/e2e/weak-collections.test.js +88 -0
  213. package/dist/tests/e2e/weak-collections.test.js.map +1 -0
  214. package/dist/tests/parser/declarations.test.js +12 -0
  215. package/dist/tests/parser/declarations.test.js.map +1 -1
  216. package/dist/tests/parser/module-syntax.test.js +9 -0
  217. package/dist/tests/parser/module-syntax.test.js.map +1 -1
  218. package/dist/tests/parser/parser.test.js +7 -0
  219. package/dist/tests/parser/parser.test.js.map +1 -1
  220. package/dist/tests/version.test.js +5 -1
  221. package/dist/tests/version.test.js.map +1 -1
  222. package/doc/ai/README.md +4 -3
  223. package/doc/ai/cli.md +41 -0
  224. package/doc/ai/contributing.md +20 -16
  225. package/doc/ai/extensions.md +13 -10
  226. package/doc/ai/language-support.md +19 -14
  227. package/doc/ai/troubleshooting.md +11 -9
  228. package/doc/ai/zh-CN/README.md +3 -2
  229. package/doc/ai/zh-CN/cli.md +35 -0
  230. package/doc/ai/zh-CN/contributing.md +16 -15
  231. package/doc/ai/zh-CN/extensions.md +12 -9
  232. package/doc/ai/zh-CN/language-support.md +19 -15
  233. package/doc/ai/zh-CN/troubleshooting.md +9 -8
  234. package/doc/gui/api.md +8 -0
  235. package/doc/gui/build.md +13 -4
  236. package/doc/gui/known-issues.md +19 -14
  237. package/doc/gui/media.md +32 -3
  238. package/doc/gui/rendering.md +3 -1
  239. package/doc/gui.md +28 -5
  240. package/doc/icon.md +5 -4
  241. package/doc/implemented/async.md +51 -0
  242. package/doc/implemented/binder.md +13 -0
  243. package/doc/implemented/cli.md +47 -0
  244. package/doc/implemented/codegen.md +33 -0
  245. package/doc/implemented/collections.md +26 -0
  246. package/doc/implemented/driver.md +19 -0
  247. package/doc/implemented/extensions.md +19 -0
  248. package/doc/implemented/fetch.md +44 -0
  249. package/doc/implemented/lexer.md +23 -0
  250. package/doc/implemented/modules.md +28 -0
  251. package/doc/implemented/node/assert.md +17 -0
  252. package/doc/implemented/node/buffer.md +29 -0
  253. package/doc/implemented/node/child-process.md +29 -0
  254. package/doc/implemented/node/crypto.md +9 -0
  255. package/doc/implemented/node/dgram.md +15 -0
  256. package/doc/implemented/node/events.md +37 -0
  257. package/doc/implemented/node/fs-promises.md +49 -0
  258. package/doc/implemented/node/fs.md +112 -0
  259. package/doc/implemented/node/http.md +21 -0
  260. package/doc/implemented/node/net.md +17 -0
  261. package/doc/implemented/node/os.md +22 -0
  262. package/doc/implemented/node/path.md +33 -0
  263. package/doc/implemented/node/process.md +23 -0
  264. package/doc/implemented/node/querystring.md +20 -0
  265. package/doc/implemented/node/stream-promises.md +8 -0
  266. package/doc/implemented/node/stream.md +19 -0
  267. package/doc/implemented/node/test.md +10 -0
  268. package/doc/implemented/node/url.md +8 -0
  269. package/doc/implemented/node/util.md +25 -0
  270. package/doc/implemented/node/worker-threads.md +10 -0
  271. package/doc/implemented/node/zlib.md +8 -0
  272. package/doc/implemented/node.md +48 -0
  273. package/doc/implemented/operators.md +38 -0
  274. package/doc/implemented/parser.md +58 -0
  275. package/doc/implemented/pipeline.md +28 -0
  276. package/doc/implemented/runtime-core.md +32 -0
  277. package/doc/implemented/stdlib.md +78 -0
  278. package/doc/implemented/strings.md +27 -0
  279. package/doc/implemented/tests.md +10 -0
  280. package/doc/implemented/typed-arrays.md +26 -0
  281. package/doc/implemented/value-model.md +18 -0
  282. package/doc/implemented.md +54 -355
  283. package/doc/node-implemented.md +3 -585
  284. package/doc/node-unimplemented.md +3 -164
  285. package/doc/requirements.md +23 -8
  286. package/doc/unimplemented/classes.md +22 -0
  287. package/doc/unimplemented/deviations.md +27 -0
  288. package/doc/unimplemented/expressions.md +26 -0
  289. package/doc/unimplemented/functions.md +21 -0
  290. package/doc/unimplemented/modules.md +22 -0
  291. package/doc/unimplemented/node/async.md +20 -0
  292. package/doc/unimplemented/node/bun.md +9 -0
  293. package/doc/unimplemented/node/fs-promises.md +20 -0
  294. package/doc/unimplemented/node/fs.md +30 -0
  295. package/doc/unimplemented/node/globals.md +23 -0
  296. package/doc/unimplemented/node/modules.md +21 -0
  297. package/doc/unimplemented/node.md +21 -0
  298. package/doc/unimplemented/statements.md +18 -0
  299. package/doc/unimplemented/stdlib.md +54 -0
  300. package/doc/unimplemented/toolchain.md +14 -0
  301. package/doc/unimplemented/types.md +12 -0
  302. package/doc/unimplemented.md +18 -275
  303. package/doc/xbintsc.config.schema.json +12 -0
  304. package/doc/zh-CN/gui/api.md +7 -0
  305. package/doc/zh-CN/gui/build.md +11 -3
  306. package/doc/zh-CN/gui/known-issues.md +17 -11
  307. package/doc/zh-CN/gui/media.md +26 -2
  308. package/doc/zh-CN/gui/rendering.md +2 -1
  309. package/doc/zh-CN/gui.md +21 -3
  310. package/doc/zh-CN/icon.md +5 -4
  311. package/doc/zh-CN/implemented/async.md +49 -0
  312. package/doc/zh-CN/implemented/binder.md +13 -0
  313. package/doc/zh-CN/implemented/cli.md +46 -0
  314. package/doc/zh-CN/implemented/codegen.md +33 -0
  315. package/doc/zh-CN/implemented/collections.md +26 -0
  316. package/doc/zh-CN/implemented/driver.md +19 -0
  317. package/doc/zh-CN/implemented/extensions.md +19 -0
  318. package/doc/zh-CN/implemented/fetch.md +31 -0
  319. package/doc/zh-CN/implemented/lexer.md +23 -0
  320. package/doc/zh-CN/implemented/modules.md +28 -0
  321. package/doc/zh-CN/implemented/node/assert.md +17 -0
  322. package/doc/zh-CN/implemented/node/buffer.md +25 -0
  323. package/doc/zh-CN/implemented/node/child-process.md +27 -0
  324. package/doc/zh-CN/implemented/node/crypto.md +9 -0
  325. package/doc/zh-CN/implemented/node/dgram.md +15 -0
  326. package/doc/zh-CN/implemented/node/events.md +36 -0
  327. package/doc/zh-CN/implemented/node/fs-promises.md +30 -0
  328. package/doc/zh-CN/implemented/node/fs.md +105 -0
  329. package/doc/zh-CN/implemented/node/http.md +17 -0
  330. package/doc/zh-CN/implemented/node/net.md +17 -0
  331. package/doc/zh-CN/implemented/node/os.md +21 -0
  332. package/doc/zh-CN/implemented/node/path.md +26 -0
  333. package/doc/zh-CN/implemented/node/process.md +23 -0
  334. package/doc/zh-CN/implemented/node/querystring.md +20 -0
  335. package/doc/zh-CN/implemented/node/stream-promises.md +8 -0
  336. package/doc/zh-CN/implemented/node/stream.md +15 -0
  337. package/doc/zh-CN/implemented/node/test.md +10 -0
  338. package/doc/zh-CN/implemented/node/url.md +8 -0
  339. package/doc/zh-CN/implemented/node/util.md +25 -0
  340. package/doc/zh-CN/implemented/node/worker-threads.md +9 -0
  341. package/doc/zh-CN/implemented/node/zlib.md +8 -0
  342. package/doc/zh-CN/implemented/node.md +45 -0
  343. package/doc/zh-CN/implemented/operators.md +38 -0
  344. package/doc/zh-CN/implemented/parser.md +58 -0
  345. package/doc/zh-CN/implemented/pipeline.md +25 -0
  346. package/doc/zh-CN/implemented/runtime-core.md +31 -0
  347. package/doc/zh-CN/implemented/stdlib.md +76 -0
  348. package/doc/zh-CN/implemented/strings.md +27 -0
  349. package/doc/zh-CN/implemented/tests.md +10 -0
  350. package/doc/zh-CN/implemented/typed-arrays.md +26 -0
  351. package/doc/zh-CN/implemented/value-model.md +18 -0
  352. package/doc/zh-CN/implemented.md +50 -350
  353. package/doc/zh-CN/node-implemented.md +4 -531
  354. package/doc/zh-CN/node-unimplemented.md +4 -139
  355. package/doc/zh-CN/plan-require-node-modules.md +4 -4
  356. package/doc/zh-CN/requirements.md +20 -6
  357. package/doc/zh-CN/unimplemented/classes.md +22 -0
  358. package/doc/zh-CN/unimplemented/deviations.md +24 -0
  359. package/doc/zh-CN/unimplemented/expressions.md +24 -0
  360. package/doc/zh-CN/unimplemented/functions.md +21 -0
  361. package/doc/zh-CN/unimplemented/modules.md +19 -0
  362. package/doc/zh-CN/unimplemented/node/async.md +20 -0
  363. package/doc/zh-CN/unimplemented/node/bun.md +8 -0
  364. package/doc/zh-CN/unimplemented/node/fs-promises.md +12 -0
  365. package/doc/zh-CN/unimplemented/node/fs.md +24 -0
  366. package/doc/zh-CN/unimplemented/node/globals.md +14 -0
  367. package/doc/zh-CN/unimplemented/node/modules.md +15 -0
  368. package/doc/zh-CN/unimplemented/node.md +18 -0
  369. package/doc/zh-CN/unimplemented/statements.md +15 -0
  370. package/doc/zh-CN/unimplemented/stdlib.md +54 -0
  371. package/doc/zh-CN/unimplemented/toolchain.md +14 -0
  372. package/doc/zh-CN/unimplemented/types.md +11 -0
  373. package/doc/zh-CN/unimplemented.md +14 -237
  374. package/llms.txt +32 -4
  375. package/package.json +1 -1
  376. package/runtime/ext_gui/inline_svg.cpp +219 -0
  377. package/runtime/ext_gui/inline_svg.h +41 -0
  378. package/runtime/ext_gui/layout.cpp +18 -0
  379. package/runtime/ext_gui/layout.h +7 -0
  380. package/runtime/ext_gui/layout_flow.cpp +4 -3
  381. package/runtime/ext_gui/paint.cpp +14 -0
  382. package/runtime/ext_gui/paint.h +5 -1
  383. package/runtime/ext_gui/renderer_image.cpp +53 -25
  384. package/runtime/ext_gui/renderer_shaders.h +2 -2
  385. package/runtime/ext_gui/stb_image.h +1 -17
  386. package/runtime/ext_gui/style_ua.cpp +3 -0
  387. package/runtime/ext_gui/svg.cpp +122 -39
  388. package/runtime/ext_gui/svg.h +14 -3
  389. package/runtime/ext_gui/window.cpp +28 -0
  390. package/runtime/ext_node/child_process/child_process.c +173 -73
  391. package/runtime/ext_node/fs/async_api.c +314 -0
  392. package/runtime/ext_node/fs/async_complete.c +99 -0
  393. package/runtime/ext_node/fs/async_fh.c +206 -0
  394. package/runtime/ext_node/fs/async_job.c +81 -0
  395. package/runtime/ext_node/fs/async_job.h +132 -0
  396. package/runtime/ext_node/fs/async_worker.c +534 -0
  397. package/runtime/ext_node/fs/async_worker_dir.c +439 -0
  398. package/runtime/ext_node/fs/async_worker_dir.h +33 -0
  399. package/runtime/ext_node/fs/async_worker_fd.c +74 -0
  400. package/runtime/ext_node/fs/dir.c +60 -15
  401. package/runtime/ext_node/fs/fs_common.h +9 -0
  402. package/runtime/ext_node/fs/fs_ops.c +18 -29
  403. package/runtime/ext_node/fs/parts/builtins.inc +34 -0
  404. package/runtime/ext_node/fs/parts/platform.inc +66 -0
  405. package/runtime/ext_node/fs/promises.c +44 -234
  406. package/runtime/rt.h +15 -0
  407. package/runtime/rt_internal.h +108 -0
  408. package/runtime/xt_alloc.c +43 -7
  409. package/runtime/xt_array_buffer.c +284 -0
  410. package/runtime/xt_async.c +46 -21
  411. package/runtime/xt_async_io.c +333 -0
  412. package/runtime/xt_async_io.h +47 -0
  413. package/runtime/xt_bigint/helpers.inc +3 -3
  414. package/runtime/xt_builtins.c +21 -17
  415. package/runtime/xt_constructors.c +12 -2
  416. package/runtime/xt_containers/access.inc +148 -3
  417. package/runtime/xt_containers/objects.inc +26 -2
  418. package/runtime/xt_containers/shapes.inc +71 -0
  419. package/runtime/xt_containers.c +1 -0
  420. package/runtime/xt_coroutine.c +17 -0
  421. package/runtime/xt_fetch/async.inc +295 -0
  422. package/runtime/xt_fetch/request.inc +6 -183
  423. package/runtime/xt_fetch/socket.inc +5 -4
  424. package/runtime/xt_fetch.c +6 -4
  425. package/runtime/xt_generator.c +299 -10
  426. package/runtime/xt_io/inspect.inc +112 -0
  427. package/runtime/xt_loop.c +79 -7
  428. package/runtime/xt_performance.c +37 -0
  429. package/runtime/xt_promise.c +63 -1
  430. package/runtime/xt_stdlib/arrays.inc +1 -1
  431. package/runtime/xt_stdlib/dispatch.inc +46 -11
  432. package/runtime/xt_stdlib/strings.inc +1 -1
  433. package/runtime/xt_stdlib2/array-statics.inc +25 -0
  434. package/runtime/xt_stdlib2/arrays.inc +5 -3
  435. package/runtime/xt_stdlib2/container.inc +5 -0
  436. package/runtime/xt_stdlib2/date.inc +111 -3
  437. package/runtime/xt_stdlib2/error.inc +24 -0
  438. package/runtime/xt_stdlib2/json.inc +310 -19
  439. package/runtime/xt_stdlib2/number-string-statics.inc +1 -1
  440. package/runtime/xt_stdlib2/objects.inc +122 -0
  441. package/runtime/xt_stdlib2/set.inc +1 -1
  442. package/runtime/xt_structured_clone.c +159 -0
  443. package/runtime/xt_symbol.c +2 -2
  444. package/runtime/xt_text_codec.c +69 -0
  445. package/runtime/xt_typed_array/construction.inc +35 -5
  446. package/runtime/xt_typed_array/elements.inc +159 -0
  447. package/runtime/xt_typed_array/methods.inc +21 -5
  448. package/runtime/xt_typed_array.c +7 -10
  449. package/runtime/xt_url.c +375 -0
  450. package/runtime/xt_values/arithmetic.inc +2 -2
  451. package/runtime/xt_values/conversions.inc +1 -1
  452. package/runtime/xt_weak.c +281 -0
  453. package/scripts/build-gui.ts +133 -60
  454. package/scripts/check-version.ts +3 -3
  455. package/src/binder/declarations.ts +14 -3
  456. package/src/cli/hints.ts +8 -1
  457. package/src/cli/main.ts +119 -18
  458. package/src/cli/watch.ts +101 -0
  459. package/src/codegen/generator/calls/access.ts +10 -2
  460. package/src/codegen/generator/calls/closures.ts +12 -4
  461. package/src/codegen/generator/context.ts +23 -3
  462. package/src/codegen/generator/expressions/operators.ts +27 -13
  463. package/src/codegen/generator/expressions/primary.ts +4 -0
  464. package/src/codegen/generator/module.ts +0 -7
  465. package/src/codegen/generator/numeric.ts +85 -11
  466. package/src/codegen/generator/state.ts +23 -0
  467. package/src/codegen/generator/statements/control-flow.ts +1 -4
  468. package/src/codegen/generator/statements/loops.ts +50 -16
  469. package/src/codegen/generator/tables.ts +26 -1
  470. package/src/diagnostics/diagnostic.ts +23 -3
  471. package/src/driver/app-artifacts.ts +77 -0
  472. package/src/driver/build-key.ts +55 -0
  473. package/src/driver/bundler/graph.ts +63 -13
  474. package/src/driver/bundler/merge.ts +4 -1
  475. package/src/driver/compiler.ts +94 -328
  476. package/src/driver/config.ts +11 -0
  477. package/src/driver/frontend.ts +120 -0
  478. package/src/driver/index.ts +0 -1
  479. package/src/driver/options.ts +70 -0
  480. package/src/driver/runtime-objects.ts +134 -0
  481. package/src/driver/toolchain-provider.ts +4 -0
  482. package/src/driver/toolchain.ts +154 -10
  483. package/src/driver/version.ts +12 -0
  484. package/src/driver/win-icon.ts +36 -36
  485. package/src/extensions/node/fs/index.ts +12 -3
  486. package/src/extensions/node/fs-promises/index.ts +15 -6
  487. package/src/parser/declarations/classes.ts +4 -0
  488. package/src/parser/declarations/functions.ts +12 -1
  489. package/src/parser/modules.ts +8 -4
  490. package/src/parser/parser.ts +28 -0
@@ -0,0 +1,281 @@
1
+ /*
2
+ * xbintsc runtime — weak collections.
3
+ *
4
+ * `WeakMap`, `WeakSet` and `WeakRef` are the only values whose references the
5
+ * mark-sweep collector must *not* follow unconditionally. Their keys (and the
6
+ * target of a WeakRef) are excluded from the ordinary trace; instead the
7
+ * collector runs an ephemeron fixed point after marking:
8
+ *
9
+ * repeat
10
+ * for every live WeakMap entry whose key is marked:
11
+ * mark the value
12
+ * until nothing new is marked
13
+ *
14
+ * A value is therefore retained only while its key is otherwise reachable, and
15
+ * a key/value cycle that is only reachable through the WeakMap is collected.
16
+ * WeakRef targets that stay unmarked after that fixed point are cleared.
17
+ *
18
+ * WeakMap/WeakSet entries are removed at sweep time, so a later `has()` never
19
+ * observes a key whose object has been collected.
20
+ */
21
+
22
+ #include "rt_internal.h"
23
+
24
+ #include <stdlib.h>
25
+ #include <string.h>
26
+
27
+ static int xt_is_weak_target(xt_value value) {
28
+ return XT_IS_OBJECT(value) || XT_IS_ARRAY(value) || XT_IS_FUNCTION(value);
29
+ }
30
+
31
+ static void xt_weak_key_error(void) {
32
+ xt_throw(xt_error_from_message("TypeError: Invalid value used as weak map key"));
33
+ }
34
+
35
+ int xt_is_weak_map(xt_value value) {
36
+ return XT_IS_OBJECT(value) &&
37
+ ((xt_header *)XT_GET_PTR(value))->kind == XT_OBJECT_KIND_WEAK_MAP;
38
+ }
39
+
40
+ int xt_is_weak_set(xt_value value) {
41
+ return XT_IS_OBJECT(value) &&
42
+ ((xt_header *)XT_GET_PTR(value))->kind == XT_OBJECT_KIND_WEAK_SET;
43
+ }
44
+
45
+ int xt_is_weak_ref(xt_value value) {
46
+ return XT_IS_OBJECT(value) &&
47
+ ((xt_header *)XT_GET_PTR(value))->kind == XT_OBJECT_KIND_WEAK_REF;
48
+ }
49
+
50
+ /* -- WeakMap -------------------------------------------------------------- */
51
+
52
+ static int32_t xt_weak_map_index(xt_weak_map *map, xt_value key) {
53
+ for (uint32_t i = 0; i < map->count; i++) {
54
+ if (xt_value_equals(map->keys[i], key)) return (int32_t)i;
55
+ }
56
+ return -1;
57
+ }
58
+
59
+ static void xt_weak_map_set(xt_weak_map *map, xt_value key, xt_value value) {
60
+ int32_t index = xt_weak_map_index(map, key);
61
+ if (index >= 0) {
62
+ map->values[index] = value;
63
+ return;
64
+ }
65
+ if (map->count >= map->capacity) {
66
+ uint32_t capacity = map->capacity == 0 ? 8 : map->capacity * 2;
67
+ map->keys = (xt_value *)realloc(map->keys, sizeof(xt_value) * capacity);
68
+ map->values = (xt_value *)realloc(map->values, sizeof(xt_value) * capacity);
69
+ if (!map->keys || !map->values) abort();
70
+ map->capacity = capacity;
71
+ }
72
+ map->keys[map->count] = key;
73
+ map->values[map->count] = value;
74
+ map->count++;
75
+ }
76
+
77
+ static int xt_weak_map_delete(xt_weak_map *map, xt_value key) {
78
+ int32_t index = xt_weak_map_index(map, key);
79
+ if (index < 0) return 0;
80
+ for (uint32_t i = (uint32_t)index + 1; i < map->count; i++) {
81
+ map->keys[i - 1] = map->keys[i];
82
+ map->values[i - 1] = map->values[i];
83
+ }
84
+ map->count--;
85
+ return 1;
86
+ }
87
+
88
+ xt_value xt_weak_map_ctor(int32_t argc, xt_value *argv) {
89
+ xt_weak_map *map = (xt_weak_map *)xt_alloc(sizeof(xt_weak_map), XT_OBJECT_KIND_WEAK_MAP);
90
+ map->keys = NULL;
91
+ map->values = NULL;
92
+ map->count = 0;
93
+ map->capacity = 0;
94
+ xt_value iterable = xt_arg_at(argc, argv, 0);
95
+ if (XT_IS_ARRAY(iterable)) {
96
+ xt_array *array = (xt_array *)XT_GET_PTR(iterable);
97
+ for (uint32_t i = 0; i < array->length; i++) {
98
+ xt_array *pair = xt_as_array(array->items[i]);
99
+ if (!pair || pair->length < 2) {
100
+ xt_throw(xt_error_from_message("TypeError: Iterator value is not an entry object"));
101
+ return XT_UNDEFINED;
102
+ }
103
+ if (!xt_is_weak_target(pair->items[0])) {
104
+ xt_weak_key_error();
105
+ return XT_UNDEFINED;
106
+ }
107
+ xt_weak_map_set(map, pair->items[0], pair->items[1]);
108
+ }
109
+ }
110
+ return XT_FROM_PTR(XT_TAG_OBJECT, map);
111
+ }
112
+
113
+ /* -- WeakSet -------------------------------------------------------------- */
114
+
115
+ static int32_t xt_weak_set_index(xt_weak_set *set, xt_value value) {
116
+ for (uint32_t i = 0; i < set->count; i++) {
117
+ if (xt_value_equals(set->values[i], value)) return (int32_t)i;
118
+ }
119
+ return -1;
120
+ }
121
+
122
+ static void xt_weak_set_add(xt_weak_set *set, xt_value value) {
123
+ if (xt_weak_set_index(set, value) >= 0) return;
124
+ if (set->count >= set->capacity) {
125
+ uint32_t capacity = set->capacity == 0 ? 8 : set->capacity * 2;
126
+ set->values = (xt_value *)realloc(set->values, sizeof(xt_value) * capacity);
127
+ if (!set->values) abort();
128
+ set->capacity = capacity;
129
+ }
130
+ set->values[set->count++] = value;
131
+ }
132
+
133
+ static int xt_weak_set_delete(xt_weak_set *set, xt_value value) {
134
+ int32_t index = xt_weak_set_index(set, value);
135
+ if (index < 0) return 0;
136
+ for (uint32_t i = (uint32_t)index + 1; i < set->count; i++) {
137
+ set->values[i - 1] = set->values[i];
138
+ }
139
+ set->count--;
140
+ return 1;
141
+ }
142
+
143
+ xt_value xt_weak_set_ctor(int32_t argc, xt_value *argv) {
144
+ xt_weak_set *set = (xt_weak_set *)xt_alloc(sizeof(xt_weak_set), XT_OBJECT_KIND_WEAK_SET);
145
+ set->values = NULL;
146
+ set->count = 0;
147
+ set->capacity = 0;
148
+ xt_value iterable = xt_arg_at(argc, argv, 0);
149
+ if (XT_IS_ARRAY(iterable)) {
150
+ xt_array *array = (xt_array *)XT_GET_PTR(iterable);
151
+ for (uint32_t i = 0; i < array->length; i++) {
152
+ if (!xt_is_weak_target(array->items[i])) {
153
+ xt_weak_key_error();
154
+ return XT_UNDEFINED;
155
+ }
156
+ xt_weak_set_add(set, array->items[i]);
157
+ }
158
+ }
159
+ return XT_FROM_PTR(XT_TAG_OBJECT, set);
160
+ }
161
+
162
+ /* -- WeakRef -------------------------------------------------------------- */
163
+
164
+ xt_value xt_weak_ref_ctor(int32_t argc, xt_value *argv) {
165
+ xt_value target = xt_arg_at(argc, argv, 0);
166
+ if (!xt_is_weak_target(target)) {
167
+ xt_throw(xt_error_from_message("TypeError: WeakRef target must be an object"));
168
+ return XT_UNDEFINED;
169
+ }
170
+ xt_weak_ref *ref = (xt_weak_ref *)xt_alloc(sizeof(xt_weak_ref), XT_OBJECT_KIND_WEAK_REF);
171
+ ref->target = target;
172
+ return XT_FROM_PTR(XT_TAG_OBJECT, ref);
173
+ }
174
+
175
+ xt_value xt_weak_method(xt_value target, const char *method, int32_t argc, xt_value *argv,
176
+ int *handled) {
177
+ *handled = 1;
178
+ if (xt_is_weak_map(target)) {
179
+ xt_weak_map *map = (xt_weak_map *)XT_GET_PTR(target);
180
+ xt_value key = xt_arg_at(argc, argv, 0);
181
+ if (strcmp(method, "set") == 0) {
182
+ if (!xt_is_weak_target(key)) {
183
+ xt_weak_key_error();
184
+ return XT_UNDEFINED;
185
+ }
186
+ xt_weak_map_set(map, key, xt_arg_at(argc, argv, 1));
187
+ return target;
188
+ }
189
+ if (strcmp(method, "get") == 0) {
190
+ if (!xt_is_weak_target(key)) return XT_UNDEFINED;
191
+ int32_t index = xt_weak_map_index(map, key);
192
+ return index >= 0 ? map->values[index] : XT_UNDEFINED;
193
+ }
194
+ if (strcmp(method, "has") == 0) {
195
+ return xt_bool(xt_is_weak_target(key) && xt_weak_map_index(map, key) >= 0);
196
+ }
197
+ if (strcmp(method, "delete") == 0) {
198
+ return xt_bool(xt_is_weak_target(key) && xt_weak_map_delete(map, key));
199
+ }
200
+ } else if (xt_is_weak_set(target)) {
201
+ xt_weak_set *set = (xt_weak_set *)XT_GET_PTR(target);
202
+ xt_value value = xt_arg_at(argc, argv, 0);
203
+ if (strcmp(method, "add") == 0) {
204
+ if (!xt_is_weak_target(value)) {
205
+ xt_weak_key_error();
206
+ return XT_UNDEFINED;
207
+ }
208
+ xt_weak_set_add(set, value);
209
+ return target;
210
+ }
211
+ if (strcmp(method, "has") == 0) {
212
+ return xt_bool(xt_is_weak_target(value) && xt_weak_set_index(set, value) >= 0);
213
+ }
214
+ if (strcmp(method, "delete") == 0) {
215
+ return xt_bool(xt_is_weak_target(value) && xt_weak_set_delete(set, value));
216
+ }
217
+ } else if (xt_is_weak_ref(target)) {
218
+ if (strcmp(method, "deref") == 0) return ((xt_weak_ref *)XT_GET_PTR(target))->target;
219
+ }
220
+ *handled = 0;
221
+ return XT_UNDEFINED;
222
+ }
223
+
224
+ /* -- collector integration ------------------------------------------------ */
225
+
226
+ static int xt_weak_heap_value(xt_value value) {
227
+ return XT_IS_STRING(value) || XT_IS_OBJECT(value) || XT_IS_ARRAY(value) ||
228
+ XT_IS_FUNCTION(value) || XT_IS_BIGINT(value);
229
+ }
230
+
231
+ int xt_weak_gc_process_once(void) {
232
+ int changed = 0;
233
+ for (xt_header *header = xt_gc_heap_head(); header; header = header->gc_next) {
234
+ if ((header->flags & XT_GC_MARK) == 0) continue;
235
+ if (header->kind != XT_OBJECT_KIND_WEAK_MAP) continue;
236
+ xt_weak_map *map = (xt_weak_map *)header;
237
+ for (uint32_t i = 0; i < map->count; i++) {
238
+ if (!xt_gc_value_is_marked(map->keys[i])) continue;
239
+ xt_value value = map->values[i];
240
+ if (!xt_weak_heap_value(value)) continue;
241
+ if (xt_gc_value_is_marked(value)) continue;
242
+ xt_gc_mark_value(value);
243
+ changed = 1;
244
+ }
245
+ }
246
+ return changed;
247
+ }
248
+
249
+ void xt_weak_gc_clear(void) {
250
+ for (xt_header *header = xt_gc_heap_head(); header; header = header->gc_next) {
251
+ if ((header->flags & XT_GC_MARK) == 0) continue;
252
+ if (header->kind != XT_OBJECT_KIND_WEAK_REF) continue;
253
+ xt_weak_ref *ref = (xt_weak_ref *)header;
254
+ if (!xt_gc_value_is_marked(ref->target)) ref->target = XT_UNDEFINED;
255
+ }
256
+ }
257
+
258
+ void xt_weak_gc_compact(void) {
259
+ for (xt_header *header = xt_gc_heap_head(); header; header = header->gc_next) {
260
+ if ((header->flags & XT_GC_MARK) == 0) continue;
261
+ if (header->kind == XT_OBJECT_KIND_WEAK_MAP) {
262
+ xt_weak_map *map = (xt_weak_map *)header;
263
+ uint32_t write = 0;
264
+ for (uint32_t read = 0; read < map->count; read++) {
265
+ if (!xt_gc_value_is_marked(map->keys[read])) continue;
266
+ map->keys[write] = map->keys[read];
267
+ map->values[write] = map->values[read];
268
+ write++;
269
+ }
270
+ map->count = write;
271
+ } else if (header->kind == XT_OBJECT_KIND_WEAK_SET) {
272
+ xt_weak_set *set = (xt_weak_set *)header;
273
+ uint32_t write = 0;
274
+ for (uint32_t read = 0; read < set->count; read++) {
275
+ if (!xt_gc_value_is_marked(set->values[read])) continue;
276
+ set->values[write++] = set->values[read];
277
+ }
278
+ set->count = write;
279
+ }
280
+ }
281
+ }
@@ -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: