xbintsc 0.3.46 → 0.3.49

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 (91) hide show
  1. package/AGENTS.md +95 -0
  2. package/README.md +25 -0
  3. package/README.zh-CN.md +23 -0
  4. package/dist/src/cli/hints.d.ts +54 -0
  5. package/dist/src/cli/hints.js +165 -0
  6. package/dist/src/cli/hints.js.map +1 -0
  7. package/dist/src/cli/main.js +73 -9
  8. package/dist/src/cli/main.js.map +1 -1
  9. package/dist/src/codegen/generator/tables.d.ts +26 -0
  10. package/dist/src/codegen/generator/tables.js +64 -12
  11. package/dist/src/codegen/generator/tables.js.map +1 -1
  12. package/dist/src/diagnostics/source-text.d.ts +22 -0
  13. package/dist/src/diagnostics/source-text.js +76 -0
  14. package/dist/src/diagnostics/source-text.js.map +1 -0
  15. package/dist/src/driver/bundler/graph.js +2 -1
  16. package/dist/src/driver/bundler/graph.js.map +1 -1
  17. package/dist/src/driver/compiler.js +3 -2
  18. package/dist/src/driver/compiler.js.map +1 -1
  19. package/dist/src/lexer/scanner/strings.js +16 -3
  20. package/dist/src/lexer/scanner/strings.js.map +1 -1
  21. package/dist/tests/cli/hints.test.d.ts +9 -0
  22. package/dist/tests/cli/hints.test.js +143 -0
  23. package/dist/tests/cli/hints.test.js.map +1 -0
  24. package/dist/tests/cli/main.test.js +6 -4
  25. package/dist/tests/cli/main.test.js.map +1 -1
  26. package/dist/tests/codegen/llvm.test.js +17 -2
  27. package/dist/tests/codegen/llvm.test.js.map +1 -1
  28. package/dist/tests/helpers.js +3 -2
  29. package/dist/tests/helpers.js.map +1 -1
  30. package/dist/tests/lexer/strings.test.js +14 -2
  31. package/dist/tests/lexer/strings.test.js.map +1 -1
  32. package/doc/DESIGN.md +117 -0
  33. package/doc/ai/README.md +63 -0
  34. package/doc/ai/build-recipe.md +137 -0
  35. package/doc/ai/cli.md +142 -0
  36. package/doc/ai/contributing.md +196 -0
  37. package/doc/ai/extensions.md +148 -0
  38. package/doc/ai/language-support.md +152 -0
  39. package/doc/ai/troubleshooting.md +163 -0
  40. package/doc/ai/zh-CN/README.md +56 -0
  41. package/doc/ai/zh-CN/build-recipe.md +132 -0
  42. package/doc/ai/zh-CN/cli.md +127 -0
  43. package/doc/ai/zh-CN/contributing.md +173 -0
  44. package/doc/ai/zh-CN/extensions.md +139 -0
  45. package/doc/ai/zh-CN/language-support.md +147 -0
  46. package/doc/ai/zh-CN/troubleshooting.md +150 -0
  47. package/doc/gui-scripts.md +350 -0
  48. package/doc/gui.md +646 -0
  49. package/doc/icon.md +265 -0
  50. package/doc/implemented.md +373 -0
  51. package/doc/node-implemented.md +588 -0
  52. package/doc/node-unimplemented.md +167 -0
  53. package/doc/post/announce.md +43 -0
  54. package/doc/requirements.md +145 -0
  55. package/doc/unimplemented.md +286 -0
  56. package/doc/xbintsc.config.schema.json +67 -0
  57. package/doc/zh-CN/DESIGN.md +104 -0
  58. package/doc/zh-CN/gui-scripts.md +329 -0
  59. package/doc/zh-CN/gui.md +588 -0
  60. package/doc/zh-CN/icon.md +241 -0
  61. package/doc/zh-CN/implemented.md +365 -0
  62. package/doc/zh-CN/node-implemented.md +533 -0
  63. package/doc/zh-CN/node-unimplemented.md +141 -0
  64. package/doc/zh-CN/plan-require-node-modules.md +284 -0
  65. package/doc/zh-CN/post/announce.md +47 -0
  66. package/doc/zh-CN/requirements.md +134 -0
  67. package/doc/zh-CN/unimplemented.md +247 -0
  68. package/llms.txt +45 -0
  69. package/package.json +4 -1
  70. package/runtime/ext_gui/gui.cpp +3 -1
  71. package/runtime/ext_gui/renderer.cpp +13 -11
  72. package/runtime/ext_gui/renderer_image.cpp +12 -8
  73. package/runtime/ext_gui/renderer_shaders.h +131 -4
  74. package/runtime/ext_gui/renderer_shaders_data.h +1809 -0
  75. package/runtime/ext_gui/renderer_text.cpp +12 -8
  76. package/runtime/ext_gui/shaders.hlsl +98 -0
  77. package/runtime/ext_gui/spirv/fill.frag +19 -0
  78. package/runtime/ext_gui/spirv/fill.vert +42 -0
  79. package/runtime/ext_gui/spirv/image.frag +16 -0
  80. package/runtime/ext_gui/spirv/quad.vert +30 -0
  81. package/runtime/ext_gui/spirv/text.frag +16 -0
  82. package/scripts/build-gui-shaders.mjs +204 -0
  83. package/scripts/build-gui.ts +35 -0
  84. package/scripts/check-file-length.ts +5 -1
  85. package/src/cli/hints.ts +194 -0
  86. package/src/cli/main.ts +82 -9
  87. package/src/codegen/generator/tables.ts +60 -14
  88. package/src/diagnostics/source-text.ts +78 -0
  89. package/src/driver/bundler/graph.ts +2 -1
  90. package/src/driver/compiler.ts +3 -2
  91. package/src/lexer/scanner/strings.ts +16 -3
@@ -0,0 +1,139 @@
1
+ # 扩展:Node 模块、GUI、C++/Rust 库
2
+
3
+ 编译器核心与平台无关。任何与平台相关的东西——Node 的 `fs`、一个 HTML/CSS 渲染器、
4
+ 你自己的 C++ 库——都以**扩展**的形式接入:它既贡献模块绑定,也贡献要一起编译/链接的
5
+ C/C++ 源码或目标文件。
6
+
7
+ ## 最容易踩的规则
8
+
9
+ **只要扩展没开启,import 它提供的模块就会失败。** xbintsc 知道该模块存在,并明确
10
+ 告诉你要传什么:
11
+
12
+ ```bash
13
+ $ xbintsc run app.ts # app.ts: import { readFileSync } from "fs";
14
+ error TS6001: module 'fs' is provided by the 'node' extension; pass --ext node
15
+ ```
16
+
17
+ ```bash
18
+ xbintsc run app.ts --ext node
19
+ ```
20
+
21
+ 多个扩展用逗号分隔一次开启:`--ext node,gui`。在项目里写进
22
+ `xbintsc.config.json` 就不需要每次带参数:
23
+
24
+ ```json
25
+ { "entry": "src/app.ts", "outDir": "build", "extensions": ["node"] }
26
+ ```
27
+
28
+ ## 内置扩展
29
+
30
+ ### `node` —— Node 内置模块
31
+
32
+ 用 `--ext node` 开启。可以用裸名或 `node:` 前缀导入(`import { readFileSync } from
33
+ "node:fs"`),两种写法解析到同一实现。
34
+
35
+ | 模块 | 说明 |
36
+ | --- | --- |
37
+ | `fs` | **仅同步 API**(`readFileSync`、`writeFileSync` 等);`fs/promises` 是独立模块 |
38
+ | `fs/promises` | 基于 Promise 的文件 API |
39
+ | `path` | 同时接入命名空间分发,`path.join(...)` 可用 |
40
+ | `os` | |
41
+ | `process` | `process.cwd()`、`argv`、`env` 等;也接入命名空间分发 |
42
+ | `buffer` | |
43
+ | `crypto` | |
44
+ | `stream`、`stream/promises` | |
45
+ | `events` | |
46
+ | `net`、`dgram`、`http` | 跑在 xbintsc 事件循环上的套接字与服务端(注意下面的异步限制) |
47
+ | `child_process` | |
48
+ | `worker_threads` | |
49
+ | `util`、`querystring`、`url`、`assert`、`test`、`zlib` | |
50
+
51
+ 各模块的具体覆盖(确切函数与选项)见
52
+ [../../zh-CN/node-implemented.md](../../zh-CN/node-implemented.md),缺失项见
53
+ [../../zh-CN/node-unimplemented.md](../../zh-CN/node-unimplemented.md)。
54
+
55
+ 在 `net`/`http` 上搭东西之前,先记住运行时模型:事件循环在**程序主体之后**才运行,
56
+ 而 `async`/`await` 是同步微任务模型。见 [language-support.md](./language-support.md)。
57
+
58
+ ### `gui` —— HTML/CSS 窗口
59
+
60
+ 用 `--ext gui` 开启并导入 `gui` 模块:
61
+
62
+ ```ts
63
+ import { createWindow, run } from "gui";
64
+ ```
65
+
66
+ 它是自带渲染引擎的 GPU 加速实现(自己的 HTML 解析器、CSS 级联、布局与合成器),不是
67
+ 系统 WebView。因为主体是 C++,它以各平台预编译的 `gui.a`/`gui.lib` 形式分发。如果该
68
+ 平台的归档不存在,构建会以明确的提示失败;设计与路线图见 [../../zh-CN/gui.md](../../zh-CN/gui.md),
69
+ 脚本接口见 [../../zh-CN/gui-scripts.md](../../zh-CN/gui-scripts.md)。
70
+
71
+ ## 第三方 npm 包
72
+
73
+ 没有被已启用扩展认领的裸说明符,会在 `node_modules` 里查找并**作为源码**打包。不是
74
+ 纯 ESM TypeScript/JavaScript 的包——或依赖 CommonJS、`require`、`__dirname`、循环
75
+ 依赖的包——都不会工作。`require()` 会被拒绝并提示改用 `import`。
76
+
77
+ 实践结论:写 Node 程序时,正确做法通常就是开 `--ext node`;只有确实必要时才去依赖
78
+ npm 包。
79
+
80
+ ## 原生扩展(C++ / Rust,无需改编译器)
81
+
82
+ 任何暴露了运行时 ABI 的 `extern "C"` 入口的代码都能被链接进来:
83
+
84
+ ```c
85
+ xt_value my_fn(int32_t argc, xt_value *argv);
86
+ ```
87
+
88
+ 用**外部**工具链(clang++ 或 cargo)构建它,把产物写进一个 JSON 清单,然后传清单:
89
+
90
+ ```bash
91
+ xbintsc build demo.ts --ext-native ./xbintsc.manifest.json
92
+ xbintsc build demo.ts --ext-native a.json,b.json # 多个
93
+ ```
94
+
95
+ ```jsonc
96
+ {
97
+ "name": "mathx-cpp", // 必填,唯一
98
+ "objects": ["build/mathx.o"], // .o / .a / .lib,相对本文件
99
+ "linkerFlagsByPlatform": { // C++/Rust 运行时
100
+ "linux": ["-lstdc++", "-lm"],
101
+ "darwin": ["-lc++"],
102
+ "win32": ["-lmsvcprt"]
103
+ },
104
+ "builtins": { "cppClamp": { "symbol": "mathx_clamp" } }, // 无需 import
105
+ "modules": {
106
+ "mathx": { "exports": { "add": { "symbol": "mathx_add" } } }
107
+ }
108
+ }
109
+ ```
110
+
111
+ 之后 `import { add } from "mathx"` 会像 C 运行时绑定一样降级到原生符号;`builtins`
112
+ 无需导入即可全局调用。
113
+
114
+ 编写辅助头:`runtime/xt_ext.h`(C/C++)与 `runtime/xt_ext.rs`(Rust),它们封装了参数
115
+ 与值的辅助函数。关键 ABI 事实:值是 64 位 NaN-boxed 字;字符串**不**以 NUL 结尾,
116
+ 所以要把 `xt_string_data` 与 `xt_string_length_value` 配对使用;运行时交给你的内存
117
+ 不会被移动或释放。请使用与 xbintsc 解析到的同一个 clang/ABI 构建(`xbintsc doctor`
118
+ 会打印它);在 Windows 上要在 **x64/ARM64 Native Tools 命令提示符**里构建。
119
+
120
+ 可直接照抄的工程:[`examples/extensions/cpp`](../../../examples/extensions/cpp) 与
121
+ [`examples/extensions/rust`](../../../examples/extensions/rust);完整指南见
122
+ [../../../examples/extensions/README.md](../../../examples/extensions/README.md)。
123
+
124
+ ## 编程式注册
125
+
126
+ ```ts
127
+ import { build, createDefaultRegistry, nativeExtensionFromManifest, nodeExtension } from "xbintsc";
128
+
129
+ const extensions = createDefaultRegistry()
130
+ .register(nodeExtension)
131
+ .register(nativeExtensionFromManifest("./xbintsc.manifest.json"));
132
+
133
+ build("demo.ts", { extensions });
134
+ ```
135
+
136
+ 注册表也是宿主工具提示"某扩展未开启"的机制,正是它把错误变成了可操作的
137
+ "pass `--ext node`",而不是下游令人困惑的报错
138
+ ([../../../src/extensions/catalog.ts](../../../src/extensions/catalog.ts))。内置扩展
139
+ 列表由 `bundledExtensions()` 提供。
@@ -0,0 +1,147 @@
1
+ # 语言支持范围:什么能编译,什么行为不同
2
+
3
+ xbintsc 编译 TypeScript 的一个**实用子集**。本页用来判断你能写什么;要精确措辞请
4
+ 点开链接。
5
+
6
+ 权威细节(始终最新、篇幅长得多):
7
+
8
+ - [../../zh-CN/implemented.md](../../zh-CN/implemented.md) —— 所有已实现能力,按编译器阶段组织
9
+ - [../../zh-CN/unimplemented.md](../../zh-CN/unimplemented.md) —— 不支持的语法、行为偏差、速查表
10
+ - [../../zh-CN/node-implemented.md](../../zh-CN/node-implemented.md) / [../../zh-CN/node-unimplemented.md](../../zh-CN/node-unimplemented.md) —— Node 扩展
11
+
12
+ ## 图例
13
+
14
+ | 标记 | 含义 |
15
+ | --- | --- |
16
+ | ✅ | 与 Node/TypeScript 一致 |
17
+ | ⚠️ | 可用,但与标准行为有偏差 |
18
+ | 🚫 | 被拒绝——语法错误或 `UnsupportedFeature` |
19
+ | — | 被解析后擦除,运行时无任何作用 |
20
+
21
+ ## 语句与声明
22
+
23
+ | 特性 | 状态 | 说明 |
24
+ | --- | --- | --- |
25
+ | `var`/`let`/`const`、块、`if`、`for`、`for...of`、`for...in`、`while`、`do...while` | ✅ | `for...in` 只枚举自有键(不含原型链) |
26
+ | `switch`、`break`、`continue`、标签 | ✅ | 含带标签的 `break`/`continue` |
27
+ | `try`/`catch`/`finally`、`throw` | ✅ | 提前 `return`/`break`/`continue` 时 `finally` 仍会执行 |
28
+ | `function`、箭头函数、默认参数/剩余参数 | ✅ | |
29
+ | `namespace`/`module` 声明 | 🚫 | 解析 ✓,代码生成 ✗ |
30
+ | `with`、`debugger` | 🚫 | 不支持 |
31
+ | 顶层 `await` | 🚫 | 请包进 `async` 函数 |
32
+
33
+ ## 表达式与运算符
34
+
35
+ | 特性 | 状态 | 说明 |
36
+ | --- | --- | --- |
37
+ | 算术、位运算、逻辑、比较、赋值运算符 | ✅ | `+` 与 `ToPrimitive` 强转与 Node 一致 |
38
+ | `===`/`!==`/`==`/`!=` | ✅ | 宽松相等与 Node 一致 |
39
+ | 可选链 `?.`、空值合并 `??`、逻辑赋值 `??=` | ✅ | 整条链的短路都已实现 |
40
+ | 模板字符串、标签模板 | ✅ | 标签模板提供 `raw` 与 `String.raw` |
41
+ | 调用/数组/对象字面量中的展开与剩余 | ✅ | |
42
+ | 解构(绑定、参数、嵌套) | ✅ | 支持默认值与剩余 |
43
+ | `delete`、`in`、`instanceof`、`typeof` | ✅ | |
44
+ | 逗号运算符、`void` | ✅ | |
45
+ | `new.target` | 🚫 | 未实现 |
46
+ | `import.meta` | 🚫 | 能解析,但没有值 |
47
+ | `super` | ⚠️ | 单层继承正确;继承深度 > 1 可能不准 |
48
+
49
+ ## 函数、类与对象
50
+
51
+ | 特性 | 状态 | 说明 |
52
+ | --- | --- | --- |
53
+ | 闭包(通过 box 按引用捕获) | ✅ | 直接调用与闭包调用共用一条 ABI |
54
+ | `this`、方法调用、箭头函数词法 `this` | ✅ | 与 JS 不同:箭头函数有自己的 `arguments` |
55
+ | `call`/`apply`/`bind`、`fn.name`/`fn.length` | ✅ | bind 出的闭包不跟踪部分应用后的 `length` |
56
+ | 一等内置方法(把 `arr.map` 当值用) | ✅ | 暴露为*未绑定*方法值;脱离接收者调用时与 JS 一样抛错 |
57
+ | `fn.toString()` | ⚠️ | 返回 `function name() { [native code] }`,不是源码 |
58
+ | 类:字段、方法、静态成员、getter/setter、`extends`/`super`、`instanceof` | ✅ | |
59
+ | 构造器参数属性 `constructor(public x: T)` | ✅ | |
60
+ | `#private` 字段/方法/静态成员 | ⚠️ | 以字面量 `#x` 键存储;不做访问控制;父子类同名可能互相覆盖 |
61
+ | `enum`/`const enum` | ✅ | 正向 + 反向映射 |
62
+ | `private`/`protected`/`public`/`readonly`/`abstract`/`implements` | — | 被擦除,无访问控制 |
63
+ | 生成器 `function*`、`yield`、`yield*` | ✅ | 不支持 `async` 生成器 |
64
+ | `arguments` 对象 | ✅ | 隐式提供;箭头函数看到的是自己的参数 |
65
+ | 参数个数校验 | 🚫 | 从不校验,虽然 `fn.length` 会报声明元数 |
66
+
67
+ ## 异步、Promise 与事件循环
68
+
69
+ | 特性 | 状态 | 说明 |
70
+ | --- | --- | --- |
71
+ | `async`/`await`、`Promise`、`Promise.all` | ⚠️ | **同步微任务模型**——`await` 一个已敲定的 Promise 会同步继续 |
72
+ | `setTimeout` 与回调 | ⚠️ | 事件循环在**程序主体之后**才运行,因此定时器里敲定的 Promise 无法被 await |
73
+ | 套接字/服务端(`http`、`net`、`dgram`) | ⚠️ | 同一模型:回调在程序主体之后的循环里执行 |
74
+ | 真正的异步事件循环、worker 线程 | 🚫 | 未实现 |
75
+
76
+ ## 类型:解析后擦除
77
+
78
+ **不做任何类型检查。** 类型语法被解析进 AST,随后在绑定/代码生成阶段擦除:
79
+
80
+ | 构造 | 状态 |
81
+ | --- | --- |
82
+ | 类型注解、返回类型、类型别名、接口 | — 解析后擦除,从不检查 |
83
+ | 泛型参数与约束 | — 运行时无实例化 |
84
+ | `as`、`satisfies`、非空断言 `!` | — 擦除,无断言语义 |
85
+ | 可选链的类型收窄 | 🚫 |
86
+ | 诊断码 `TS4001`–`TS4004`(`TypeMismatch`、`NotCallable`、`PropertyNotFound`、`ArgumentCountMismatch`) | 🚫 有定义但从不发出 |
87
+
88
+ 因此源码里的类型错误**不是**编译错误——只有运行时行为会被检查。你想跑出什么行为,
89
+ 就写什么代码。
90
+
91
+ ## 标准库
92
+
93
+ 已实现:`Math`、`JSON`、`Date`、`RegExp`、`Map`、`Set`、`WeakMap`/`WeakSet`、
94
+ `Symbol`、`Error` 家族、`BigInt`、`Array`/`String`/`Number`/`Object` 方法、TypedArray、
95
+ 带捕获组的 `String.prototype.match`/`split`/`replace`、不可变数组方法
96
+ (`toReversed`、`toSorted`、`toSpliced`、`with`)、全局 URI 函数。
97
+
98
+ | 缺失或行为不同 | 状态 |
99
+ | --- | --- |
100
+ | `String.prototype.normalize`、`structuredClone` | 🚫 |
101
+ | `Error.stack` 采集 | 🚫(不采集) |
102
+ | `Object.getPrototypeOf({})` | ⚠️ 返回 `undefined`,而非 `Object.prototype` |
103
+ | 全局 RegExp `lastIndex` | ⚠️ `/g`、`/y` 下 `test`/`exec` 忽略它 |
104
+ | 稀疏数组空洞、数组越界 | ⚠️ 不区分空洞;越界读得 `undefined` |
105
+
106
+ 完整列表见 [../../zh-CN/unimplemented.md](../../zh-CN/unimplemented.md) 第 3 节。
107
+
108
+ ## 模块
109
+
110
+ | 特性 | 状态 | 说明 |
111
+ | --- | --- | --- |
112
+ | ESM `import`/`export` | ✅ | |
113
+ | 相对路径多文件打包 | ✅ | `./helper.js` 会解析到 `helper.ts` |
114
+ | `import * as ns`、默认导入与具名导入 | ✅ | |
115
+ | Node 内置模块 | ✅ | 仅在 `--ext node` 下——见 [extensions.md](./extensions.md) |
116
+ | 裸第三方 npm 包 | 🚫 | 只有当没有扩展认领该说明符时,`node_modules` 的 ESM 包才会作为源码打包 |
117
+ | `require()` / CommonJS | 🚫 | 被拒绝,并提示改用 `import` |
118
+ | 循环依赖 | 🚫 | |
119
+ | 实时绑定 | ⚠️ | 导入与命名空间成员都是快照 |
120
+ | `import.meta`、`__dirname`、`__filename` | 🚫 | |
121
+
122
+ ## 字符串、数字与内存
123
+
124
+ | 项目 | 行为 |
125
+ | --- | --- |
126
+ | `String.prototype.length` | ⚠️ 按 **UTF-8 字节**计,不是 UTF-16 码元:`"é".length === 1`,`"😀".length === 4`;`codePointAt` 相应不同 |
127
+ | 数字格式化与强转 | ✅ 与 Node 一致(`toFixed`、`toPrecision`、十六/八/二进制解析) |
128
+ | `BigInt` | ✅ 已实现 |
129
+ | 垃圾回收 | ✅ 非移动标记清扫;显式根 + C 栈保守扫描;单线程、stop-the-world;无弱引用 |
130
+ | 线程 | 🚫 单线程;`worker_threads` 只存在于 Node 扩展中 |
131
+
132
+ ## 平台
133
+
134
+ 构建目标覆盖 macOS、Linux、Windows 的 x64 与 arm64。Windows 上是 **MSVC ABI**,
135
+ clang 需要 MSVC/SDK 环境——见 [../../zh-CN/requirements.md](../../zh-CN/requirements.md)。
136
+ 需要 clang **16 或更新**。
137
+
138
+ ## 写大程序之前
139
+
140
+ 1. 扫一眼你要用的特性所在的行;凡标 ⚠️ 或 🚫 的,打开
141
+ [../../zh-CN/unimplemented.md](../../zh-CN/unimplemented.md) 确认。
142
+ 2. 用 `xbintsc emit app.ts` 做原型验证——这是确认某构造是否被支持最便宜的方式,
143
+ 不需要 clang。
144
+ 3. 用 `xbintsc run app.ts` 跑真实程序;构建失败就去
145
+ [troubleshooting.md](./troubleshooting.md)。
146
+ 4. 需要精确对齐 Node 行为时,把同一程序在 Node 下跑一遍对比输出;项目自带测试套件
147
+ 就是这么做的差分验证。
@@ -0,0 +1,150 @@
1
+ # 排错指南
2
+
3
+ 先跑这条命令,看 xbintsc 到底解析到了什么:
4
+
5
+ ```bash
6
+ xbintsc doctor
7
+ ```
8
+
9
+ 它会打印平台、将要使用的工具链(以及来源)、编译器版本、运行时目录、运行时库目录
10
+ 与图标资源编译器。绝大多数"跑不起来"的答案都在这里。
11
+
12
+ ## 首先确认:clang 够新吗?
13
+
14
+ **需要 clang/LLVM 16 或更新。** 更老的 clang 会以有类型指针(typed pointer)错误
15
+ 拒绝生成的 IR:
16
+
17
+ ```
18
+ D:\...\build\app.ll:382:37: error: '@.str.0' defined with type '[6 x i8]*' but expected 'i8*'
19
+ %r0 = call i64 @xt_string_new(i8* @.str.0, i64 5)
20
+ ```
21
+
22
+ 编译器生成的 LLVM IR 依赖不透明指针(opaque pointers),而有类型指针在 LLVM 16
23
+ 中被移除([LLVM 发布说明](https://github.com/llvm/llvm-project/blob/release/15.x/llvm/docs/ReleaseNotes.rst#changes-to-the-llvm-ir))。
24
+ 用 `clang --version` 确认;如果机器上的系统 clang 太旧,装一个新版 LLVM 并让 xbintsc
25
+ 用它:
26
+
27
+ ```powershell
28
+ $env:xbintsc_CLANG = "C:\Program Files\LLVM\bin\clang.exe"
29
+ ```
30
+
31
+ ```bash
32
+ export xbintsc_CLANG=/usr/lib/llvm-18/bin/clang
33
+ ```
34
+
35
+ 注意:只做前端工作(`xbintsc emit`)完全不需要 clang,所以在旧工具链上它照常可用。
36
+
37
+ ## 报错信息对照
38
+
39
+ ### `module '…' is provided by the 'node' extension; pass --ext node`
40
+
41
+ 程序导入了 Node 模块但扩展没开。加上参数,或写进 `xbintsc.config.json` 让它始终生效:
42
+
43
+ ```bash
44
+ xbintsc run app.ts --ext node
45
+ ```
46
+
47
+ ### `module '<pkg>' is not supported: xbintsc can import built-in platform modules, relative '.ts' files and ESM packages under node_modules; CommonJS packages are not supported`
48
+
49
+ 一个没人认领、也链不进来的裸第三方导入。要么该包是 CommonJS(不支持),要么它是
50
+ 打包失败的 ESM 包。优先改用 `node` 扩展提供的 Node 内置模块;可打包的范围见
51
+ [extensions.md](./extensions.md)。
52
+
53
+ ### ``CommonJS `require()` is not supported``
54
+
55
+ 改写为 ESM:`const fs = require("fs")` 变成 `import fs from "fs"`(并加
56
+ `--ext node`)。`node_modules` 包内部的 `require` 由打包器处理;只有你自己的源码里
57
+ 会被拒绝。`require(<非常量表达式>)` 永远不支持。
58
+
59
+ ### `error TS4005: xbintsc does not yet support this <construct>`
60
+
61
+ 语法解析通过了,但代码生成没实现。查 [language-support.md](./language-support.md) 与
62
+ [../../zh-CN/unimplemented.md](../../zh-CN/unimplemented.md),然后改写该构造(或者
63
+ 贡献实现)。常见的是 `namespace` 声明与 `new.target`。
64
+
65
+ ### `error TS2xxx`(语法分析)或 `error TS1xxx`(词法分析)
66
+
67
+ 源码语法错误。诊断会打印文件、行、列、出错的那一行以及插入符。注意 xbintsc 的
68
+ 解析器接受绝大多数 TypeScript,所以语法错误通常意味着语法真的坏了,而不是"不支持"。
69
+
70
+ ### `error TS6001: Cannot resolve module './x' from '<file>'` / `Cannot find module`
71
+
72
+ 相对导入解析不到。`./helper.js` 说明符会映射到 `helper.ts`,所以要按你实际写的
73
+ TypeScript 运行时路径导入。
74
+
75
+ ### `Cannot resolve module '…' required from '<file>'`
76
+
77
+ 被打包的 `node_modules` 包内部的 `require(...)` 无法解析。该包不能直接用;请优先
78
+ 使用内置模块或换一个依赖。
79
+
80
+ ### `xbintsc: <config path>: invalid JSON (…)` / `Unable to read …`
81
+
82
+ 项目配置或原生扩展清单格式错误或不存在。修好 JSON,或用 `--no-config` /
83
+ `--config <path>` 绕开自动发现。
84
+
85
+ ### `error TS6003` / `Command failed (N): clang …`
86
+
87
+ clang 自身失败。抛出的消息包含完整的 clang 命令与 stderr——请读 stderr,不要只看
88
+ 第一行。常见原因:
89
+
90
+ - 工具链太旧(见上文);
91
+ - Windows 上 clang 因为环境没导入而找不到 MSVC/SDK 头文件或库。请在
92
+ **x64 Native Tools Command Prompt for VS 2022**(ARM64 机器上是 **ARM64 Native
93
+ Tools**)里运行,或先导入环境:
94
+ ```powershell
95
+ & "$env:ProgramFiles\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x64
96
+ ```
97
+ - Linux 上链接器不对——设置 `xbintsc_CLANG`,并/或传
98
+ `xbintsc_LINKER_ARGS=-fuse-ld=lld`;
99
+ - `No C compiler found. Set xbintsc_CLANG to a clang binary.` —— `PATH` 里完全没有
100
+ clang。
101
+
102
+ ### `GUI native library not found at …`
103
+
104
+ `gui` 扩展需要各平台预编译的 `gui.a`/`gui.lib`,普通源码检出并没有构建它。去掉
105
+ `--ext gui`,或按 [../../zh-CN/gui.md](../../zh-CN/gui.md) 构建该归档。
106
+
107
+ ### `Icon file not found` / 图标工具缺失
108
+
109
+ `--icon`/`app.icon` 的路径相对配置文件目录解析。Windows 上嵌入 PE 图标需要
110
+ `llvm-rc` 或 `windres`;`doctor` 会报告找到了哪个,只有在确实请求了图标时缺失才是
111
+ 致命错误。
112
+
113
+ ## 看起来不对、其实正常的构建行为
114
+
115
+ ### 构建打印了 `(cached)` 并什么都没做
116
+
117
+ 增量缓存命中了:源码哈希、编译器版本、选项、平台与扩展集合都没变,且所有产物都还在。
118
+ 这正是设计目标。要强制重建就用 `--force`。
119
+
120
+ ### 改了参数后产物是旧的
121
+
122
+ 对象缓存的键刻意不含编译参数,这正是那些会改参数的脚本(如运行时覆盖率)使用独立
123
+ `xbintsc_CACHE_DIR` 的原因。如果怀疑产物过期,传 `--force` 或删掉 `.xbintsc/`。
124
+
125
+ ### `run` 返回非零但没有错误信息
126
+
127
+ `run` 透传的是**被运行程序**的退出码,编译器本身成功了。直接跑 `./build/app` 看程序
128
+ 自己的输出。
129
+
130
+ ### `xbintsc: run requires --emit exe`
131
+
132
+ `run` 只能执行可执行文件。要看 IR 请用 `build --emit ir` 或 `emit`。
133
+
134
+ ### 程序输出顺序出乎意料
135
+
136
+ `async`/`await` 是同步微任务模型,且事件循环只在程序主体之后运行,所以定时器和套接字
137
+ 回调会晚触发;见 [language-support.md](./language-support.md)。
138
+
139
+ ## 该去源码哪里看
140
+
141
+ | 症状 | 源码 |
142
+ | --- | --- |
143
+ | 某条诊断文本或代码 | [../../../src/diagnostics/diagnostic.ts](../../../src/diagnostics/diagnostic.ts),以及 `src/` 下的发出点 |
144
+ | 某个特性缺失 | [../../../src/codegen/](../../../src/codegen/) —— `UnsupportedFeature` 在那里抛出 |
145
+ | 导入解析不了 | [../../../src/driver/bundler/](../../../src/driver/bundler/) |
146
+ | clang 调用、链接参数 | [../../../src/driver/toolchain.ts](../../../src/driver/toolchain.ts)、[../../../src/driver/toolchain-provider.ts](../../../src/driver/toolchain-provider.ts) |
147
+ | 缓存行为 | [../../../src/driver/cache.ts](../../../src/driver/cache.ts) |
148
+ | 运行时崩溃、GC、值 | `runtime/*.c`、`runtime/rt.h` |
149
+
150
+ 如果你要改的是编译器本身而不是用它,接着读 [contributing.md](./contributing.md)。