xbintsc 0.5.22 → 0.5.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (391) hide show
  1. package/AGENTS.md +12 -3
  2. package/README.md +46 -11
  3. package/README.zh-CN.md +32 -6
  4. package/dist/scripts/support-matrix.d.ts +18 -0
  5. package/dist/scripts/support-matrix.js +141 -0
  6. package/dist/scripts/support-matrix.js.map +1 -0
  7. package/dist/src/ast/common.d.ts +2 -2
  8. package/dist/src/ast/declarations.d.ts +7 -1
  9. package/dist/src/ast/expressions.d.ts +5 -0
  10. package/dist/src/ast/kinds.d.ts +2 -0
  11. package/dist/src/ast/kinds.js +2 -0
  12. package/dist/src/ast/kinds.js.map +1 -1
  13. package/dist/src/binder/binder.d.ts +2 -1
  14. package/dist/src/binder/binder.js +2 -0
  15. package/dist/src/binder/binder.js.map +1 -1
  16. package/dist/src/binder/declarations.d.ts +9 -0
  17. package/dist/src/binder/declarations.js +64 -0
  18. package/dist/src/binder/declarations.js.map +1 -1
  19. package/dist/src/binder/references.js +85 -3
  20. package/dist/src/binder/references.js.map +1 -1
  21. package/dist/src/binder/types.d.ts +32 -0
  22. package/dist/src/binder/types.js.map +1 -1
  23. package/dist/src/canonical.d.ts +29 -0
  24. package/dist/src/canonical.js +35 -0
  25. package/dist/src/canonical.js.map +1 -0
  26. package/dist/src/checker/assignability.d.ts +13 -0
  27. package/dist/src/checker/assignability.js +146 -0
  28. package/dist/src/checker/assignability.js.map +1 -0
  29. package/dist/src/checker/calls.d.ts +13 -0
  30. package/dist/src/checker/calls.js +127 -0
  31. package/dist/src/checker/calls.js.map +1 -0
  32. package/dist/src/checker/checker.d.ts +26 -0
  33. package/dist/src/checker/checker.js +31 -0
  34. package/dist/src/checker/checker.js.map +1 -0
  35. package/dist/src/checker/declarations.d.ts +9 -0
  36. package/dist/src/checker/declarations.js +15 -0
  37. package/dist/src/checker/declarations.js.map +1 -0
  38. package/dist/src/checker/flow.d.ts +21 -0
  39. package/dist/src/checker/flow.js +241 -0
  40. package/dist/src/checker/flow.js.map +1 -0
  41. package/dist/src/checker/globals.d.ts +9 -0
  42. package/dist/src/checker/globals.js +29 -0
  43. package/dist/src/checker/globals.js.map +1 -0
  44. package/dist/src/checker/source.d.ts +38 -0
  45. package/dist/src/checker/source.js +48 -0
  46. package/dist/src/checker/source.js.map +1 -0
  47. package/dist/src/checker/type-infer.d.ts +18 -0
  48. package/dist/src/checker/type-infer.js +173 -0
  49. package/dist/src/checker/type-infer.js.map +1 -0
  50. package/dist/src/checker/type-model.d.ts +73 -0
  51. package/dist/src/checker/type-model.js +151 -0
  52. package/dist/src/checker/type-model.js.map +1 -0
  53. package/dist/src/checker/type-system.d.ts +58 -0
  54. package/dist/src/checker/type-system.js +569 -0
  55. package/dist/src/checker/type-system.js.map +1 -0
  56. package/dist/src/checker/typecheck-types.d.ts +22 -0
  57. package/dist/src/checker/typecheck-types.js +109 -0
  58. package/dist/src/checker/typecheck-types.js.map +1 -0
  59. package/dist/src/checker/typecheck.d.ts +62 -0
  60. package/dist/src/checker/typecheck.js +574 -0
  61. package/dist/src/checker/typecheck.js.map +1 -0
  62. package/dist/src/checker/undefined.d.ts +14 -0
  63. package/dist/src/checker/undefined.js +32 -0
  64. package/dist/src/checker/undefined.js.map +1 -0
  65. package/dist/src/checker/walk.d.ts +10 -0
  66. package/dist/src/checker/walk.js +15 -0
  67. package/dist/src/checker/walk.js.map +1 -0
  68. package/dist/src/cli/help.d.ts +7 -0
  69. package/dist/src/cli/help.js +64 -0
  70. package/dist/src/cli/help.js.map +1 -0
  71. package/dist/src/cli/hints.js +13 -1
  72. package/dist/src/cli/hints.js.map +1 -1
  73. package/dist/src/cli/main.js +12 -48
  74. package/dist/src/cli/main.js.map +1 -1
  75. package/dist/src/codegen/generator/calls/access.js +8 -8
  76. package/dist/src/codegen/generator/calls/access.js.map +1 -1
  77. package/dist/src/codegen/generator/calls/invocation.js +9 -4
  78. package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
  79. package/dist/src/codegen/generator/calls/super.d.ts +9 -1
  80. package/dist/src/codegen/generator/calls/super.js +56 -5
  81. package/dist/src/codegen/generator/calls/super.js.map +1 -1
  82. package/dist/src/codegen/generator/context.d.ts +13 -2
  83. package/dist/src/codegen/generator/context.js +25 -19
  84. package/dist/src/codegen/generator/context.js.map +1 -1
  85. package/dist/src/codegen/generator/debug.js +2 -1
  86. package/dist/src/codegen/generator/debug.js.map +1 -1
  87. package/dist/src/codegen/generator/expressions/primary.d.ts +4 -1
  88. package/dist/src/codegen/generator/expressions/primary.js +68 -8
  89. package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
  90. package/dist/src/codegen/generator/generator.js +11 -1
  91. package/dist/src/codegen/generator/generator.js.map +1 -1
  92. package/dist/src/codegen/generator/module.d.ts +2 -0
  93. package/dist/src/codegen/generator/module.js +62 -26
  94. package/dist/src/codegen/generator/module.js.map +1 -1
  95. package/dist/src/codegen/generator/state.d.ts +11 -1
  96. package/dist/src/codegen/generator/state.js.map +1 -1
  97. package/dist/src/codegen/generator/statements/variables.js +20 -3
  98. package/dist/src/codegen/generator/statements/variables.js.map +1 -1
  99. package/dist/src/codegen/generator/tables.d.ts +2 -0
  100. package/dist/src/codegen/generator/tables.js +4 -0
  101. package/dist/src/codegen/generator/tables.js.map +1 -1
  102. package/dist/src/driver/build-key.d.ts +2 -0
  103. package/dist/src/driver/build-key.js +1 -0
  104. package/dist/src/driver/build-key.js.map +1 -1
  105. package/dist/src/driver/bundler/graph.js +5 -1
  106. package/dist/src/driver/bundler/graph.js.map +1 -1
  107. package/dist/src/driver/bundler/merge.js +16 -1
  108. package/dist/src/driver/bundler/merge.js.map +1 -1
  109. package/dist/src/driver/bundler/types.d.ts +12 -0
  110. package/dist/src/driver/compiler.d.ts +1 -1
  111. package/dist/src/driver/compiler.js +4 -0
  112. package/dist/src/driver/compiler.js.map +1 -1
  113. package/dist/src/driver/fingerprint.js +2 -1
  114. package/dist/src/driver/fingerprint.js.map +1 -1
  115. package/dist/src/driver/frontend.d.ts +8 -6
  116. package/dist/src/driver/frontend.js +4 -0
  117. package/dist/src/driver/frontend.js.map +1 -1
  118. package/dist/src/driver/options.d.ts +6 -0
  119. package/dist/src/driver/version.d.ts +1 -1
  120. package/dist/src/driver/version.js +1 -1
  121. package/dist/src/extensions/catalog.js +2 -1
  122. package/dist/src/extensions/catalog.js.map +1 -1
  123. package/dist/src/extensions/gui/html.js +20 -6
  124. package/dist/src/extensions/gui/html.js.map +1 -1
  125. package/dist/src/extensions/gui/index.js +63 -0
  126. package/dist/src/extensions/gui/index.js.map +1 -1
  127. package/dist/src/extensions/media/index.d.ts +27 -0
  128. package/dist/src/extensions/media/index.js +60 -0
  129. package/dist/src/extensions/media/index.js.map +1 -0
  130. package/dist/src/extensions/registry.d.ts +50 -0
  131. package/dist/src/extensions/registry.js +26 -0
  132. package/dist/src/extensions/registry.js.map +1 -1
  133. package/dist/src/index.d.ts +2 -0
  134. package/dist/src/index.js +2 -0
  135. package/dist/src/index.js.map +1 -1
  136. package/dist/src/parser/declarations/classes.js +7 -0
  137. package/dist/src/parser/declarations/classes.js.map +1 -1
  138. package/dist/src/parser/expressions.js +14 -1
  139. package/dist/src/parser/expressions.js.map +1 -1
  140. package/dist/src/parser/literals.js +6 -2
  141. package/dist/src/parser/literals.js.map +1 -1
  142. package/dist/tests/binder/binder.test.js +29 -0
  143. package/dist/tests/binder/binder.test.js.map +1 -1
  144. package/dist/tests/canonical.test.d.ts +1 -0
  145. package/dist/tests/canonical.test.js +19 -0
  146. package/dist/tests/canonical.test.js.map +1 -0
  147. package/dist/tests/checker/checker.test.d.ts +1 -0
  148. package/dist/tests/checker/checker.test.js +245 -0
  149. package/dist/tests/checker/checker.test.js.map +1 -0
  150. package/dist/tests/cli/check.test.js +20 -0
  151. package/dist/tests/cli/check.test.js.map +1 -1
  152. package/dist/tests/cli/hints.test.js +15 -0
  153. package/dist/tests/cli/hints.test.js.map +1 -1
  154. package/dist/tests/cli/process.test.js +12 -0
  155. package/dist/tests/cli/process.test.js.map +1 -1
  156. package/dist/tests/conformance/matrix.test.d.ts +6 -0
  157. package/dist/tests/conformance/matrix.test.js +23 -0
  158. package/dist/tests/conformance/matrix.test.js.map +1 -0
  159. package/dist/tests/conformance/test262/manifest.d.ts +115 -0
  160. package/dist/tests/conformance/test262/manifest.js +257 -0
  161. package/dist/tests/conformance/test262/manifest.js.map +1 -0
  162. package/dist/tests/conformance/test262.test.d.ts +11 -0
  163. package/dist/tests/conformance/test262.test.js +74 -0
  164. package/dist/tests/conformance/test262.test.js.map +1 -0
  165. package/dist/tests/docs/structure.test.js +9 -11
  166. package/dist/tests/docs/structure.test.js.map +1 -1
  167. package/dist/tests/e2e/child-process.test.js +3 -2
  168. package/dist/tests/e2e/child-process.test.js.map +1 -1
  169. package/dist/tests/e2e/compile-builtins.test.js +21 -0
  170. package/dist/tests/e2e/compile-builtins.test.js.map +1 -1
  171. package/dist/tests/e2e/compile-objects-classes.test.js +54 -0
  172. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
  173. package/dist/tests/e2e/differential-syntax.test.d.ts +5 -0
  174. package/dist/tests/e2e/differential-syntax.test.js +95 -0
  175. package/dist/tests/e2e/differential-syntax.test.js.map +1 -0
  176. package/dist/tests/e2e/differential-values.test.js +15 -0
  177. package/dist/tests/e2e/differential-values.test.js.map +1 -1
  178. package/dist/tests/e2e/gui-browser.test.d.ts +13 -0
  179. package/dist/tests/e2e/gui-browser.test.js +163 -0
  180. package/dist/tests/e2e/gui-browser.test.js.map +1 -0
  181. package/dist/tests/e2e/gui-example-browser.test.js +2 -2
  182. package/dist/tests/e2e/gui-example-browser.test.js.map +1 -1
  183. package/dist/tests/e2e/gui-example-canvas.test.js +8 -5
  184. package/dist/tests/e2e/gui-example-canvas.test.js.map +1 -1
  185. package/dist/tests/e2e/gui-example-svg.test.js +4 -3
  186. package/dist/tests/e2e/gui-example-svg.test.js.map +1 -1
  187. package/dist/tests/e2e/gui-example.test.js +4 -3
  188. package/dist/tests/e2e/gui-example.test.js.map +1 -1
  189. package/dist/tests/e2e/gui-helpers.d.ts +3 -0
  190. package/dist/tests/e2e/gui-helpers.js +6 -3
  191. package/dist/tests/e2e/gui-helpers.js.map +1 -1
  192. package/dist/tests/e2e/gui-media-disabled.test.d.ts +9 -0
  193. package/dist/tests/e2e/gui-media-disabled.test.js +42 -0
  194. package/dist/tests/e2e/gui-media-disabled.test.js.map +1 -0
  195. package/dist/tests/e2e/gui-media.test.d.ts +6 -4
  196. package/dist/tests/e2e/gui-media.test.js +20 -16
  197. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  198. package/dist/tests/e2e/harness.d.ts +9 -0
  199. package/dist/tests/e2e/harness.js +14 -2
  200. package/dist/tests/e2e/harness.js.map +1 -1
  201. package/dist/tests/e2e/native-extensions.test.js +2 -1
  202. package/dist/tests/e2e/native-extensions.test.js.map +1 -1
  203. package/dist/tests/e2e/property-descriptors.test.js +20 -0
  204. package/dist/tests/e2e/property-descriptors.test.js.map +1 -1
  205. package/dist/tests/e2e/unicode-output.test.d.ts +16 -0
  206. package/dist/tests/e2e/unicode-output.test.js +67 -0
  207. package/dist/tests/e2e/unicode-output.test.js.map +1 -0
  208. package/dist/tests/e2e/weak-collections.test.js +16 -2
  209. package/dist/tests/e2e/weak-collections.test.js.map +1 -1
  210. package/dist/tests/extensions/media.test.d.ts +1 -0
  211. package/dist/tests/extensions/media.test.js +58 -0
  212. package/dist/tests/extensions/media.test.js.map +1 -0
  213. package/dist/tests/extensions/registry.test.js +8 -0
  214. package/dist/tests/extensions/registry.test.js.map +1 -1
  215. package/dist/tests/helpers.d.ts +1 -0
  216. package/dist/tests/helpers.js +1 -0
  217. package/dist/tests/helpers.js.map +1 -1
  218. package/dist/tests/lexer/identifiers.test.js +12 -0
  219. package/dist/tests/lexer/identifiers.test.js.map +1 -1
  220. package/dist/tests/lexer/scanner.test.js +8 -0
  221. package/dist/tests/lexer/scanner.test.js.map +1 -1
  222. package/dist/tests/lexer/strings.test.js +30 -0
  223. package/dist/tests/lexer/strings.test.js.map +1 -1
  224. package/dist/tests/parser/declarations.test.js +20 -0
  225. package/dist/tests/parser/declarations.test.js.map +1 -1
  226. package/dist/tests/parser/expressions.test.js +36 -0
  227. package/dist/tests/parser/expressions.test.js.map +1 -1
  228. package/dist/tests/platform.d.ts +32 -0
  229. package/dist/tests/platform.js +40 -0
  230. package/dist/tests/platform.js.map +1 -0
  231. package/dist/tests/platform.test.d.ts +12 -0
  232. package/dist/tests/platform.test.js +51 -0
  233. package/dist/tests/platform.test.js.map +1 -0
  234. package/dist/tests/version.test.js +4 -4
  235. package/dist/tests/version.test.js.map +1 -1
  236. package/doc/ai/README.md +10 -4
  237. package/doc/ai/build-recipe.md +1 -0
  238. package/doc/ai/cli.md +18 -6
  239. package/doc/ai/contributing.md +59 -2
  240. package/doc/ai/extensions.md +46 -23
  241. package/doc/ai/language-support.md +25 -16
  242. package/doc/ai/troubleshooting.md +9 -0
  243. package/doc/ai/zh-CN/README.md +9 -4
  244. package/doc/ai/zh-CN/build-recipe.md +1 -0
  245. package/doc/ai/zh-CN/cli.md +14 -4
  246. package/doc/ai/zh-CN/contributing.md +49 -3
  247. package/doc/ai/zh-CN/extensions.md +29 -8
  248. package/doc/ai/zh-CN/language-support.md +23 -14
  249. package/doc/ai/zh-CN/troubleshooting.md +8 -0
  250. package/doc/gui/api.md +45 -0
  251. package/doc/gui/build.md +37 -21
  252. package/doc/gui/known-issues.md +17 -6
  253. package/doc/gui/media.md +26 -11
  254. package/doc/gui/runtime.md +18 -0
  255. package/doc/gui-scripts.md +7 -0
  256. package/doc/gui.md +43 -33
  257. package/doc/implemented/binder.md +2 -0
  258. package/doc/implemented/checker.md +117 -0
  259. package/doc/implemented/cli.md +13 -1
  260. package/doc/implemented/codegen.md +3 -2
  261. package/doc/implemented/driver.md +2 -2
  262. package/doc/implemented/operators.md +2 -1
  263. package/doc/implemented/parser.md +3 -2
  264. package/doc/implemented/pipeline.md +8 -1
  265. package/doc/implemented/stdlib.md +2 -1
  266. package/doc/implemented/tests.md +3 -1
  267. package/doc/implemented.md +2 -0
  268. package/doc/npm-package.md +417 -0
  269. package/doc/requirements.md +4 -1
  270. package/doc/support-matrix.md +83 -0
  271. package/doc/unimplemented/classes.md +3 -0
  272. package/doc/unimplemented/deviations.md +3 -2
  273. package/doc/unimplemented/toolchain.md +1 -1
  274. package/doc/unimplemented/types.md +24 -8
  275. package/doc/unimplemented.md +1 -1
  276. package/doc/zh-CN/gui/api.md +41 -0
  277. package/doc/zh-CN/gui/build.md +28 -16
  278. package/doc/zh-CN/gui/known-issues.md +13 -5
  279. package/doc/zh-CN/gui/media.md +21 -10
  280. package/doc/zh-CN/gui/runtime.md +16 -0
  281. package/doc/zh-CN/gui-scripts.md +5 -0
  282. package/doc/zh-CN/gui.md +37 -32
  283. package/doc/zh-CN/implemented/binder.md +2 -0
  284. package/doc/zh-CN/implemented/checker.md +99 -0
  285. package/doc/zh-CN/implemented/cli.md +12 -1
  286. package/doc/zh-CN/implemented/codegen.md +3 -2
  287. package/doc/zh-CN/implemented/driver.md +2 -2
  288. package/doc/zh-CN/implemented/operators.md +1 -1
  289. package/doc/zh-CN/implemented/parser.md +3 -2
  290. package/doc/zh-CN/implemented/pipeline.md +3 -1
  291. package/doc/zh-CN/implemented/stdlib.md +2 -1
  292. package/doc/zh-CN/implemented/tests.md +3 -1
  293. package/doc/zh-CN/implemented.md +2 -0
  294. package/doc/zh-CN/npm-package.md +391 -0
  295. package/doc/zh-CN/post/announce.md +47 -47
  296. package/doc/zh-CN/requirements.md +4 -1
  297. package/doc/zh-CN/support-matrix.md +82 -0
  298. package/doc/zh-CN/unimplemented/classes.md +3 -0
  299. package/doc/zh-CN/unimplemented/deviations.md +3 -2
  300. package/doc/zh-CN/unimplemented/toolchain.md +1 -1
  301. package/doc/zh-CN/unimplemented/types.md +16 -6
  302. package/doc/zh-CN/unimplemented.md +1 -1
  303. package/llms.txt +4 -1
  304. package/package.json +3 -1
  305. package/runtime/ext_gui/audio.cpp +316 -0
  306. package/runtime/ext_gui/browser.cpp +547 -0
  307. package/runtime/ext_gui/browser_escape.cpp +85 -0
  308. package/runtime/ext_gui/browser_loop.cpp +83 -0
  309. package/runtime/ext_gui/canvas.cpp +9 -3
  310. package/runtime/ext_gui/canvas_raster.cpp +19 -1
  311. package/runtime/ext_gui/dom_api.cpp +36 -0
  312. package/runtime/ext_gui/dom_api_document.cpp +96 -5
  313. package/runtime/ext_gui/dom_api_events.cpp +20 -0
  314. package/runtime/ext_gui/dom_api_internal.h +19 -0
  315. package/runtime/ext_gui/dom_api_proto.cpp +6 -0
  316. package/runtime/ext_gui/gui.cpp +90 -23
  317. package/runtime/ext_gui/gui_engine.h +44 -0
  318. package/runtime/ext_gui/gui_media.cpp +69 -2
  319. package/runtime/ext_gui/media.cpp +34 -488
  320. package/runtime/ext_gui/media.h +54 -19
  321. package/runtime/ext_gui/media_api.h +65 -0
  322. package/runtime/ext_gui/window.cpp +9 -0
  323. package/runtime/ext_media/media.cpp +507 -0
  324. package/runtime/ext_media/media_bridge.c +35 -0
  325. package/runtime/ext_node/path/path.c +7 -7
  326. package/runtime/ext_node/url/url.c +4 -2
  327. package/runtime/rt.h +15 -0
  328. package/runtime/xt_constructors.c +2 -1
  329. package/runtime/xt_containers/objects.inc +22 -2
  330. package/runtime/xt_io/exception.inc +4 -2
  331. package/runtime/xt_stdlib/math.inc +62 -0
  332. package/runtime/xt_stdlib2/date.inc +7 -1
  333. package/runtime/xt_stdlib2/objects.inc +14 -0
  334. package/scripts/build-gui.ts +6 -72
  335. package/scripts/build-media.ts +245 -0
  336. package/scripts/support-matrix.ts +167 -0
  337. package/src/ast/common.ts +2 -0
  338. package/src/ast/declarations.ts +12 -1
  339. package/src/ast/expressions.ts +6 -0
  340. package/src/ast/kinds.ts +2 -0
  341. package/src/binder/binder.ts +3 -0
  342. package/src/binder/declarations.ts +70 -0
  343. package/src/binder/references.ts +84 -3
  344. package/src/binder/types.ts +30 -0
  345. package/src/canonical.ts +37 -0
  346. package/src/checker/assignability.ts +134 -0
  347. package/src/checker/calls.ts +135 -0
  348. package/src/checker/checker.ts +47 -0
  349. package/src/checker/declarations.ts +26 -0
  350. package/src/checker/flow.ts +236 -0
  351. package/src/checker/globals.ts +40 -0
  352. package/src/checker/source.ts +53 -0
  353. package/src/checker/type-infer.ts +185 -0
  354. package/src/checker/type-model.ts +212 -0
  355. package/src/checker/type-system.ts +578 -0
  356. package/src/checker/typecheck-types.ts +112 -0
  357. package/src/checker/typecheck.ts +586 -0
  358. package/src/checker/undefined.ts +43 -0
  359. package/src/checker/walk.ts +16 -0
  360. package/src/cli/help.ts +65 -0
  361. package/src/cli/hints.ts +13 -1
  362. package/src/cli/main.ts +12 -49
  363. package/src/codegen/generator/calls/access.ts +8 -8
  364. package/src/codegen/generator/calls/invocation.ts +8 -5
  365. package/src/codegen/generator/calls/super.ts +67 -5
  366. package/src/codegen/generator/context.ts +31 -19
  367. package/src/codegen/generator/debug.ts +2 -1
  368. package/src/codegen/generator/expressions/primary.ts +84 -13
  369. package/src/codegen/generator/generator.ts +11 -1
  370. package/src/codegen/generator/module.ts +65 -24
  371. package/src/codegen/generator/state.ts +11 -1
  372. package/src/codegen/generator/statements/variables.ts +20 -3
  373. package/src/codegen/generator/tables.ts +5 -0
  374. package/src/driver/build-key.ts +3 -0
  375. package/src/driver/bundler/graph.ts +6 -2
  376. package/src/driver/bundler/merge.ts +14 -1
  377. package/src/driver/bundler/types.ts +13 -0
  378. package/src/driver/compiler.ts +5 -1
  379. package/src/driver/fingerprint.ts +2 -1
  380. package/src/driver/frontend.ts +13 -2
  381. package/src/driver/options.ts +6 -0
  382. package/src/driver/version.ts +1 -1
  383. package/src/extensions/catalog.ts +2 -1
  384. package/src/extensions/gui/html.ts +23 -10
  385. package/src/extensions/gui/index.ts +65 -0
  386. package/src/extensions/media/index.ts +67 -0
  387. package/src/extensions/registry.ts +72 -0
  388. package/src/index.ts +2 -0
  389. package/src/parser/declarations/classes.ts +7 -0
  390. package/src/parser/expressions.ts +13 -1
  391. package/src/parser/literals.ts +6 -2
@@ -0,0 +1,185 @@
1
+ /**
2
+ * Inference from expressions into the checker's type model.
3
+ *
4
+ * It is deliberately shallow: literals, object/array literals, `new`, function
5
+ * expressions and the obvious operators are inferred; calls, property reads and
6
+ * everything else are `any` here (the type-check walk refines them with flow).
7
+ */
8
+
9
+ import {
10
+ SyntaxKind,
11
+ type ArrowFunction,
12
+ type ArrayLiteralExpression,
13
+ type AsExpression,
14
+ type BinaryExpression,
15
+ type ClassDeclaration,
16
+ type ConditionalExpression,
17
+ type Expression,
18
+ type FunctionExpression,
19
+ type Identifier,
20
+ type NewExpression,
21
+ type ObjectLiteralExpression,
22
+ type Parameter,
23
+ type ShorthandPropertyAssignment,
24
+ type TypeNode,
25
+ } from "../ast/nodes.js";
26
+ import { SymbolKind, type BindResult, type SymbolInfo } from "../binder/binder.js";
27
+ import { classMemberName } from "../binder/helpers.js";
28
+ import { ASSIGNMENT_OPERATORS } from "../codegen/generator/tables.js";
29
+ import { ANY, isAny, isThisParameter, primitive, unionOf, widenType, type ParameterInfo, type PropertyInfo, type Type } from "./type-model.js";
30
+
31
+ export interface InferenceContext {
32
+ readonly binding: BindResult;
33
+ resolve(node: TypeNode | undefined, typeParams?: ReadonlyMap<string, Type>): Type;
34
+ typeOfSymbol(symbol: SymbolInfo): Type;
35
+ classInstanceType(node: ClassDeclaration): Type;
36
+ parameterInfo(parameter: Parameter, typeParams: ReadonlyMap<string, Type>): ParameterInfo;
37
+ }
38
+
39
+ export function inferTypeOfExpression(
40
+ context: InferenceContext,
41
+ expression: Expression,
42
+ lookup?: (symbol: SymbolInfo) => Type | undefined,
43
+ ): Type {
44
+ switch (expression.kind) {
45
+ case SyntaxKind.NumericLiteral:
46
+ return { kind: "literal", value: (expression as { value: number }).value, primitive: "number" };
47
+ case SyntaxKind.StringLiteral:
48
+ case SyntaxKind.NoSubstitutionTemplateLiteral:
49
+ return { kind: "literal", value: (expression as { value: string }).value, primitive: "string" };
50
+ case SyntaxKind.TrueKeyword:
51
+ return { kind: "literal", value: true, primitive: "boolean" };
52
+ case SyntaxKind.FalseKeyword:
53
+ return { kind: "literal", value: false, primitive: "boolean" };
54
+ case SyntaxKind.NullKeyword:
55
+ return primitive("null");
56
+ case SyntaxKind.UndefinedKeyword:
57
+ return primitive("undefined");
58
+ case SyntaxKind.BigIntLiteral:
59
+ return primitive("bigint");
60
+ case SyntaxKind.Identifier: {
61
+ const symbol = context.binding.symbolOfIdentifier.get(expression as Identifier);
62
+ if (!symbol) return ANY;
63
+ return lookup?.(symbol) ?? context.typeOfSymbol(symbol);
64
+ }
65
+ case SyntaxKind.ObjectLiteralExpression:
66
+ return objectLiteralType(context, expression as ObjectLiteralExpression);
67
+ case SyntaxKind.ArrayLiteralExpression: {
68
+ const elements = (expression as ArrayLiteralExpression).elements.map((element) => {
69
+ if (element.kind !== SyntaxKind.SpreadElement) return inferTypeOfExpression(context, element, lookup);
70
+ const spread = inferTypeOfExpression(context, (element as unknown as { expression: Expression }).expression, lookup);
71
+ return spread.kind === "array" ? spread.element : ANY;
72
+ });
73
+ return { kind: "array", element: widenType(unionOf(elements)) };
74
+ }
75
+ case SyntaxKind.NewExpression: {
76
+ const call = expression as NewExpression;
77
+ if (call.expression.kind !== SyntaxKind.Identifier) return ANY;
78
+ const symbol = context.binding.symbolOfIdentifier.get(call.expression as Identifier);
79
+ if (!symbol || symbol.kind !== SymbolKind.Class || symbol.declarations.length !== 1) return ANY;
80
+ const declaration = symbol.declarations[0]!;
81
+ if (declaration.kind !== SyntaxKind.ClassDeclaration) return ANY;
82
+ return context.classInstanceType(declaration as ClassDeclaration);
83
+ }
84
+ case SyntaxKind.ArrowFunction:
85
+ case SyntaxKind.FunctionExpression:
86
+ return functionExpressionType(context, expression as ArrowFunction | FunctionExpression);
87
+ case SyntaxKind.AsExpression:
88
+ return context.resolve((expression as AsExpression).type);
89
+ case SyntaxKind.SatisfiesExpression:
90
+ case SyntaxKind.ParenthesizedExpression:
91
+ case SyntaxKind.NonNullExpression:
92
+ return inferTypeOfExpression(context, (expression as unknown as { expression: Expression }).expression, lookup);
93
+ case SyntaxKind.TypeOfExpression:
94
+ return primitive("string");
95
+ case SyntaxKind.VoidExpression:
96
+ return primitive("undefined");
97
+ case SyntaxKind.TemplateLiteral:
98
+ return primitive("string");
99
+ case SyntaxKind.ConditionalExpression: {
100
+ const conditional = expression as ConditionalExpression;
101
+ return unionOf([inferTypeOfExpression(context, conditional.whenTrue, lookup), inferTypeOfExpression(context, conditional.whenFalse, lookup)]);
102
+ }
103
+ case SyntaxKind.SequenceExpression: {
104
+ const expressions = (expression as unknown as { expressions: Expression[] }).expressions;
105
+ return inferTypeOfExpression(context, expressions[expressions.length - 1]!, lookup);
106
+ }
107
+ case SyntaxKind.BinaryExpression: {
108
+ const binary = expression as BinaryExpression;
109
+ if (binary.operator === "+") {
110
+ const left = inferTypeOfExpression(context, binary.left, lookup);
111
+ const right = inferTypeOfExpression(context, binary.right, lookup);
112
+ if (isAny(left) || isAny(right)) return ANY;
113
+ if (isBigIntish(left) || isBigIntish(right)) return primitive("bigint");
114
+ if (isStringish(left) || isStringish(right)) return primitive("string");
115
+ return primitive("number");
116
+ }
117
+ if (ASSIGNMENT_OPERATORS.has(binary.operator)) return ANY;
118
+ if (["<", "<=", ">", ">=", "==", "!=", "===", "!==", "in", "instanceof"].includes(binary.operator)) return primitive("boolean");
119
+ if (binary.operator === "&&" || binary.operator === "||" || binary.operator === "??") {
120
+ return unionOf([inferTypeOfExpression(context, binary.left, lookup), inferTypeOfExpression(context, binary.right, lookup)]);
121
+ }
122
+ const left = inferTypeOfExpression(context, binary.left, lookup);
123
+ const right = inferTypeOfExpression(context, binary.right, lookup);
124
+ if (isAny(left) || isAny(right)) return ANY;
125
+ if (isBigIntish(left) || isBigIntish(right)) return primitive("bigint");
126
+ return primitive("number");
127
+ }
128
+ case SyntaxKind.PrefixUnaryExpression: {
129
+ const operator = (expression as { operator: string }).operator;
130
+ if (operator === "typeof") return primitive("string");
131
+ if (operator === "!") return primitive("boolean");
132
+ if (operator === "void") return primitive("undefined");
133
+ return primitive("number");
134
+ }
135
+ case SyntaxKind.PostfixUnaryExpression:
136
+ return primitive("number");
137
+ case SyntaxKind.CallExpression:
138
+ return ANY;
139
+ case SyntaxKind.PropertyAccessExpression:
140
+ return ANY;
141
+ default:
142
+ return ANY;
143
+ }
144
+ }
145
+
146
+ function objectLiteralType(context: InferenceContext, literal: ObjectLiteralExpression): Type {
147
+ const properties = new Map<string, PropertyInfo>();
148
+ for (const element of literal.properties) {
149
+ if (element.kind === SyntaxKind.PropertyAssignment) {
150
+ const property = element as { name: Parameters<typeof classMemberName>[0]; initializer: Expression; accessor?: "get" | "set" };
151
+ const name = classMemberName(property.name);
152
+ if (!name) return ANY;
153
+ // A getter/setter pair is a value property, not a function property;
154
+ // its exact type is not inferred here.
155
+ const type = property.accessor ? ANY : widenType(inferTypeOfExpression(context, property.initializer));
156
+ if (!(property.accessor === "set" && properties.has(name))) properties.set(name, { type, optional: false });
157
+ } else if (element.kind === SyntaxKind.ShorthandPropertyAssignment) {
158
+ const shorthand = element as ShorthandPropertyAssignment;
159
+ properties.set(shorthand.name.text, { type: inferTypeOfExpression(context, shorthand.name), optional: false });
160
+ } else {
161
+ return ANY; // spread: the shape is not static
162
+ }
163
+ }
164
+ return { kind: "object", properties, closed: true };
165
+ }
166
+
167
+ function functionExpressionType(context: InferenceContext, expression: ArrowFunction | FunctionExpression): Type {
168
+ const typeParams = new Map<string, Type>();
169
+ return {
170
+ kind: "function",
171
+ parameters: expression.parameters.filter((parameter) => !isThisParameter(parameter)).map((parameter) => context.parameterInfo(parameter, typeParams)),
172
+ returnType: context.resolve(expression.returnType, typeParams),
173
+ typeParameters: (expression.typeParameters ?? []).map((parameter) => ({ name: parameter.name.text })),
174
+ };
175
+ }
176
+
177
+ function isStringish(type: Type): boolean {
178
+ if (type.kind === "primitive") return type.name === "string";
179
+ if (type.kind === "literal") return type.primitive === "string";
180
+ return false;
181
+ }
182
+
183
+ function isBigIntish(type: Type): boolean {
184
+ return (type.kind === "primitive" && type.name === "bigint");
185
+ }
@@ -0,0 +1,212 @@
1
+ /**
2
+ * The value model used by the checker: a deliberately small structural type
3
+ * union plus the helpers shared by resolution and assignability.
4
+ */
5
+
6
+ import {
7
+ ModifierKind,
8
+ SyntaxKind,
9
+ type Expression,
10
+ type Identifier,
11
+ type Parameter,
12
+ } from "../ast/nodes.js";
13
+
14
+ export type PrimitiveName =
15
+ | "number"
16
+ | "string"
17
+ | "boolean"
18
+ | "bigint"
19
+ | "symbol"
20
+ | "null"
21
+ | "undefined"
22
+ | "void"
23
+ | "object";
24
+
25
+ export interface PropertyInfo {
26
+ readonly type: Type;
27
+ readonly optional: boolean;
28
+ }
29
+
30
+ export interface ParameterInfo {
31
+ readonly type: Type;
32
+ readonly optional: boolean;
33
+ readonly rest: boolean;
34
+ }
35
+
36
+ export interface TypeParameterInfo {
37
+ readonly name: string;
38
+ readonly constraint?: Type;
39
+ }
40
+
41
+ export type Type =
42
+ | { readonly kind: "any" }
43
+ | { readonly kind: "primitive"; readonly name: PrimitiveName }
44
+ | { readonly kind: "literal"; readonly value: string | number | boolean; readonly primitive: "string" | "number" | "boolean" }
45
+ | { readonly kind: "array"; readonly element: Type }
46
+ | { readonly kind: "tuple"; readonly elements: readonly Type[] }
47
+ | {
48
+ readonly kind: "object";
49
+ readonly properties: ReadonlyMap<string, PropertyInfo>;
50
+ readonly index?: Type;
51
+ /** False when the shape is open (index signature, `object`, ...). */
52
+ readonly closed: boolean;
53
+ readonly label?: string;
54
+ }
55
+ | {
56
+ readonly kind: "function";
57
+ readonly parameters: readonly ParameterInfo[];
58
+ readonly returnType: Type;
59
+ readonly typeParameters: readonly TypeParameterInfo[];
60
+ readonly label?: string;
61
+ }
62
+ | { readonly kind: "union"; readonly members: readonly Type[] }
63
+ | { readonly kind: "typeParam"; readonly name: string };
64
+
65
+ export const ANY: Type = { kind: "any" };
66
+ export const UNKNOWN: Type = { kind: "any" }; // no strict unknown mode: treat like any
67
+
68
+ /** Own properties every object inherits from `Object.prototype`. */
69
+ export const OBJECT_PROTOTYPE_NAMES: ReadonlySet<string> = new Set([
70
+ "constructor",
71
+ "hasOwnProperty",
72
+ "isPrototypeOf",
73
+ "propertyIsEnumerable",
74
+ "toLocaleString",
75
+ "toString",
76
+ "valueOf",
77
+ "__defineGetter__",
78
+ "__defineSetter__",
79
+ "__lookupGetter__",
80
+ "__lookupSetter__",
81
+ "__proto__",
82
+ ]);
83
+
84
+ export function isAny(type: Type): boolean {
85
+ return type.kind === "any" || type.kind === "typeParam";
86
+ }
87
+
88
+ export function primitive(name: PrimitiveName): Type {
89
+ return { kind: "primitive", name };
90
+ }
91
+
92
+ export function unionOf(members: readonly Type[]): Type {
93
+ const flattened: Type[] = [];
94
+ for (const member of members) {
95
+ if (member.kind === "any" || member.kind === "typeParam") return ANY;
96
+ if (member.kind === "union") flattened.push(...member.members);
97
+ else flattened.push(member);
98
+ }
99
+ const unique: Type[] = [];
100
+ for (const member of flattened) {
101
+ if (!unique.some((other) => sameType(member, other))) unique.push(member);
102
+ }
103
+ if (unique.length === 0) return ANY;
104
+ if (unique.length === 1) return unique[0]!;
105
+ return { kind: "union", members: unique };
106
+ }
107
+
108
+ export function unionMembers(type: Type): readonly Type[] {
109
+ return type.kind === "union" ? type.members : [type];
110
+ }
111
+
112
+ /**
113
+ * Widen the literal types TypeScript widens for a mutable position: `let x =
114
+ * 1` and object/array literal members are `number`, not the literal `1`.
115
+ * (`const x = 1` keeps the literal; the caller decides when to widen.)
116
+ */
117
+ export function widenType(type: Type): Type {
118
+ switch (type.kind) {
119
+ case "literal":
120
+ return primitive(type.primitive);
121
+ case "array":
122
+ return { kind: "array", element: widenType(type.element) };
123
+ case "tuple":
124
+ return { kind: "tuple", elements: type.elements.map((element) => widenType(element)) };
125
+ case "union":
126
+ return unionOf(type.members.map((member) => widenType(member)));
127
+ case "object": {
128
+ const properties = new Map<string, PropertyInfo>();
129
+ for (const [name, property] of type.properties) {
130
+ properties.set(name, { type: widenType(property.type), optional: property.optional });
131
+ }
132
+ return {
133
+ kind: "object",
134
+ properties,
135
+ ...(type.index ? { index: widenType(type.index) } : {}),
136
+ closed: type.closed,
137
+ ...(type.label ? { label: type.label } : {}),
138
+ };
139
+ }
140
+ default:
141
+ return type;
142
+ }
143
+ }
144
+
145
+ function sameType(a: Type, b: Type): boolean {
146
+ if (a.kind !== b.kind) return false;
147
+ if (a.kind === "primitive" && b.kind === "primitive") return a.name === b.name;
148
+ if (a.kind === "literal" && b.kind === "literal") return a.value === b.value;
149
+ if (a.kind === "typeParam" && b.kind === "typeParam") return a.name === b.name;
150
+ return false;
151
+ }
152
+
153
+ export function printType(type: Type, depth = 0): string {
154
+ if (depth > 3) return "...";
155
+ switch (type.kind) {
156
+ case "any":
157
+ return "any";
158
+ case "primitive":
159
+ return type.name;
160
+ case "literal":
161
+ return typeof type.value === "string" ? JSON.stringify(type.value) : String(type.value);
162
+ case "array":
163
+ return `${printType(type.element, depth + 1)}[]`;
164
+ case "tuple":
165
+ return `[${type.elements.map((element) => printType(element, depth + 1)).join(", ")}]`;
166
+ case "union":
167
+ return type.members.map((member) => printType(member, depth + 1)).join(" | ");
168
+ case "function": {
169
+ const params = type.parameters.map((parameter) => `${parameter.rest ? "..." : ""}${printType(parameter.type, depth + 1)}${parameter.optional ? "?" : ""}`);
170
+ return `(${params.join(", ")}) => ${printType(type.returnType, depth + 1)}`;
171
+ }
172
+ case "typeParam":
173
+ return type.name;
174
+ case "object": {
175
+ if (type.label) return type.label;
176
+ const entries = [...type.properties.entries()].slice(0, 6).map(([name, property]) => `${name}${property.optional ? "?" : ""}: ${printType(property.type, depth + 1)}`);
177
+ if (type.properties.size > 6) entries.push("...");
178
+ return `{ ${entries.join("; ")} }`;
179
+ }
180
+ }
181
+ }
182
+
183
+ /** Shared unwrapping for erased expression wrappers. */
184
+ export function unwrap(expression: Expression): Expression {
185
+ let current = expression;
186
+ for (;;) {
187
+ if (
188
+ current.kind === SyntaxKind.AsExpression ||
189
+ current.kind === SyntaxKind.SatisfiesExpression ||
190
+ current.kind === SyntaxKind.NonNullExpression ||
191
+ current.kind === SyntaxKind.ParenthesizedExpression
192
+ ) {
193
+ current = (current as unknown as { expression: Expression }).expression;
194
+ continue;
195
+ }
196
+ return current;
197
+ }
198
+ }
199
+
200
+ export function isThisParameter(parameter: Parameter): boolean {
201
+ return parameter.name.kind === SyntaxKind.Identifier && (parameter.name as Identifier).text === "this";
202
+ }
203
+
204
+ export function isParameterProperty(parameter: Parameter): boolean {
205
+ return parameter.modifiers.some(
206
+ (modifier) =>
207
+ modifier.modifierKind === ModifierKind.Public ||
208
+ modifier.modifierKind === ModifierKind.Private ||
209
+ modifier.modifierKind === ModifierKind.Protected ||
210
+ modifier.modifierKind === ModifierKind.Readonly,
211
+ );
212
+ }