xbintsc 0.3.87 → 0.5.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +23 -11
- package/README.md +11 -9
- package/README.zh-CN.md +7 -7
- package/dist/src/binder/declarations.js +14 -3
- package/dist/src/binder/declarations.js.map +1 -1
- package/dist/src/cli/hints.js +7 -1
- package/dist/src/cli/hints.js.map +1 -1
- package/dist/src/cli/main.js +115 -15
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/cli/watch.d.ts +25 -0
- package/dist/src/cli/watch.js +93 -0
- package/dist/src/cli/watch.js.map +1 -0
- package/dist/src/codegen/generator/calls/access.js +17 -4
- package/dist/src/codegen/generator/calls/access.js.map +1 -1
- package/dist/src/codegen/generator/calls/closures.js +13 -1
- package/dist/src/codegen/generator/calls/closures.js.map +1 -1
- package/dist/src/codegen/generator/calls/invocation.js +4 -3
- package/dist/src/codegen/generator/calls/invocation.js.map +1 -1
- package/dist/src/codegen/generator/context.d.ts +8 -0
- package/dist/src/codegen/generator/context.js +22 -3
- package/dist/src/codegen/generator/context.js.map +1 -1
- package/dist/src/codegen/generator/expressions/operators.js +17 -15
- package/dist/src/codegen/generator/expressions/operators.js.map +1 -1
- package/dist/src/codegen/generator/expressions/primary.js +11 -1
- package/dist/src/codegen/generator/expressions/primary.js.map +1 -1
- package/dist/src/codegen/generator/module.d.ts +0 -1
- package/dist/src/codegen/generator/module.js +10 -17
- package/dist/src/codegen/generator/module.js.map +1 -1
- package/dist/src/codegen/generator/numeric.d.ts +6 -3
- package/dist/src/codegen/generator/numeric.js +54 -11
- package/dist/src/codegen/generator/numeric.js.map +1 -1
- package/dist/src/codegen/generator/state.js +27 -0
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/statements/control-flow.js +2 -7
- package/dist/src/codegen/generator/statements/control-flow.js.map +1 -1
- package/dist/src/codegen/generator/statements/loops.js +48 -16
- package/dist/src/codegen/generator/statements/loops.js.map +1 -1
- package/dist/src/codegen/generator/tables.d.ts +9 -0
- package/dist/src/codegen/generator/tables.js +100 -3
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/diagnostics/diagnostic.d.ts +3 -1
- package/dist/src/diagnostics/diagnostic.js +23 -3
- package/dist/src/diagnostics/diagnostic.js.map +1 -1
- package/dist/src/driver/app-artifacts.d.ts +42 -0
- package/dist/src/driver/app-artifacts.js +53 -0
- package/dist/src/driver/app-artifacts.js.map +1 -0
- package/dist/src/driver/build-key.d.ts +29 -0
- package/dist/src/driver/build-key.js +35 -0
- package/dist/src/driver/build-key.js.map +1 -0
- package/dist/src/driver/bundler/graph.js +61 -12
- package/dist/src/driver/bundler/graph.js.map +1 -1
- package/dist/src/driver/bundler/merge.js +7 -1
- package/dist/src/driver/bundler/merge.js.map +1 -1
- package/dist/src/driver/compiler.d.ts +10 -67
- package/dist/src/driver/compiler.js +94 -230
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/config.d.ts +3 -0
- package/dist/src/driver/config.js +8 -0
- package/dist/src/driver/config.js.map +1 -1
- package/dist/src/driver/frontend.d.ts +37 -0
- package/dist/src/driver/frontend.js +92 -0
- package/dist/src/driver/frontend.js.map +1 -0
- package/dist/src/driver/index.d.ts +1 -1
- package/dist/src/driver/index.js.map +1 -1
- package/dist/src/driver/options.d.ts +64 -0
- package/dist/src/driver/options.js +9 -0
- package/dist/src/driver/options.js.map +1 -0
- package/dist/src/driver/runtime-objects.d.ts +38 -0
- package/dist/src/driver/runtime-objects.js +111 -0
- package/dist/src/driver/runtime-objects.js.map +1 -0
- package/dist/src/driver/toolchain-provider.d.ts +4 -0
- package/dist/src/driver/toolchain-provider.js +4 -0
- package/dist/src/driver/toolchain-provider.js.map +1 -1
- package/dist/src/driver/toolchain.d.ts +32 -1
- package/dist/src/driver/toolchain.js +115 -11
- package/dist/src/driver/toolchain.js.map +1 -1
- package/dist/src/driver/version.d.ts +12 -0
- package/dist/src/driver/version.js +13 -0
- package/dist/src/driver/version.js.map +1 -0
- package/dist/src/driver/win-icon.d.ts +7 -9
- package/dist/src/driver/win-icon.js +37 -35
- package/dist/src/driver/win-icon.js.map +1 -1
- package/dist/src/parser/declarations/classes.js +5 -0
- package/dist/src/parser/declarations/classes.js.map +1 -1
- package/dist/src/parser/declarations/functions.js +13 -1
- package/dist/src/parser/declarations/functions.js.map +1 -1
- package/dist/src/parser/modules.js +8 -3
- package/dist/src/parser/modules.js.map +1 -1
- package/dist/src/parser/parser.d.ts +1 -0
- package/dist/src/parser/parser.js +23 -0
- package/dist/src/parser/parser.js.map +1 -1
- package/dist/tests/cli/check.test.d.ts +6 -0
- package/dist/tests/cli/check.test.js +68 -0
- package/dist/tests/cli/check.test.js.map +1 -0
- package/dist/tests/cli/main.test.js +19 -0
- package/dist/tests/cli/main.test.js.map +1 -1
- package/dist/tests/cli/watch.test.d.ts +6 -0
- package/dist/tests/cli/watch.test.js +72 -0
- package/dist/tests/cli/watch.test.js.map +1 -0
- package/dist/tests/codegen/closures.test.js +8 -0
- package/dist/tests/codegen/closures.test.js.map +1 -1
- package/dist/tests/codegen/expressions.test.js +15 -3
- package/dist/tests/codegen/expressions.test.js.map +1 -1
- package/dist/tests/codegen/llvm.test.js +16 -0
- package/dist/tests/codegen/llvm.test.js.map +1 -1
- package/dist/tests/diagnostics/diagnostic.test.js +8 -0
- package/dist/tests/diagnostics/diagnostic.test.js.map +1 -1
- package/dist/tests/docs/structure.test.d.ts +1 -0
- package/dist/tests/docs/structure.test.js +92 -0
- package/dist/tests/docs/structure.test.js.map +1 -0
- package/dist/tests/driver/compiler.test.js +6 -0
- package/dist/tests/driver/compiler.test.js.map +1 -1
- package/dist/tests/driver/config.test.js +9 -0
- package/dist/tests/driver/config.test.js.map +1 -1
- package/dist/tests/driver/icon.test.js +19 -32
- package/dist/tests/driver/icon.test.js.map +1 -1
- package/dist/tests/driver/invalid-input.test.d.ts +10 -0
- package/dist/tests/driver/invalid-input.test.js +29 -0
- package/dist/tests/driver/invalid-input.test.js.map +1 -0
- package/dist/tests/driver/modules.test.js +42 -3
- package/dist/tests/driver/modules.test.js.map +1 -1
- package/dist/tests/driver/toolchain-provider.test.js +27 -1
- package/dist/tests/driver/toolchain-provider.test.js.map +1 -1
- package/dist/tests/driver/toolchain.test.js +60 -2
- package/dist/tests/driver/toolchain.test.js.map +1 -1
- package/dist/tests/e2e/array-buffer.test.d.ts +5 -0
- package/dist/tests/e2e/array-buffer.test.js +38 -0
- package/dist/tests/e2e/array-buffer.test.js.map +1 -0
- package/dist/tests/e2e/array-from-iterables.test.d.ts +7 -0
- package/dist/tests/e2e/array-from-iterables.test.js +34 -0
- package/dist/tests/e2e/array-from-iterables.test.js.map +1 -0
- package/dist/tests/e2e/array-symbol-iterator.test.d.ts +8 -0
- package/dist/tests/e2e/array-symbol-iterator.test.js +42 -0
- package/dist/tests/e2e/array-symbol-iterator.test.js.map +1 -0
- package/dist/tests/e2e/async-await.test.d.ts +10 -0
- package/dist/tests/e2e/async-await.test.js +247 -0
- package/dist/tests/e2e/async-await.test.js.map +1 -0
- package/dist/tests/e2e/async-generators.test.d.ts +1 -0
- package/dist/tests/e2e/async-generators.test.js +154 -0
- package/dist/tests/e2e/async-generators.test.js.map +1 -0
- package/dist/tests/e2e/await-ordering.test.d.ts +5 -0
- package/dist/tests/e2e/await-ordering.test.js +37 -0
- package/dist/tests/e2e/await-ordering.test.js.map +1 -0
- package/dist/tests/e2e/compile-builtins.test.js +1 -1
- package/dist/tests/e2e/compile-modules.test.js +7 -0
- package/dist/tests/e2e/compile-modules.test.js.map +1 -1
- package/dist/tests/e2e/date-parse.test.d.ts +8 -0
- package/dist/tests/e2e/date-parse.test.js +38 -0
- package/dist/tests/e2e/date-parse.test.js.map +1 -0
- package/dist/tests/e2e/default-anonymous-exports.test.d.ts +7 -0
- package/dist/tests/e2e/default-anonymous-exports.test.js +23 -0
- package/dist/tests/e2e/default-anonymous-exports.test.js.map +1 -0
- package/dist/tests/e2e/globals-microtask.test.d.ts +9 -0
- package/dist/tests/e2e/globals-microtask.test.js +37 -0
- package/dist/tests/e2e/globals-microtask.test.js.map +1 -0
- package/dist/tests/e2e/gui-media.test.js +8 -1
- package/dist/tests/e2e/gui-media.test.js.map +1 -1
- package/dist/tests/e2e/inspect-builtins.test.d.ts +10 -0
- package/dist/tests/e2e/inspect-builtins.test.js +43 -0
- package/dist/tests/e2e/inspect-builtins.test.js.map +1 -0
- package/dist/tests/e2e/json-builtin-objects.test.d.ts +9 -0
- package/dist/tests/e2e/json-builtin-objects.test.js +23 -0
- package/dist/tests/e2e/json-builtin-objects.test.js.map +1 -0
- package/dist/tests/e2e/json-circular.test.d.ts +6 -0
- package/dist/tests/e2e/json-circular.test.js +43 -0
- package/dist/tests/e2e/json-circular.test.js.map +1 -0
- package/dist/tests/e2e/json-parse-reviver.test.d.ts +6 -0
- package/dist/tests/e2e/json-parse-reviver.test.js +29 -0
- package/dist/tests/e2e/json-parse-reviver.test.js.map +1 -0
- package/dist/tests/e2e/json-stringify-replacer.test.d.ts +6 -0
- package/dist/tests/e2e/json-stringify-replacer.test.js +27 -0
- package/dist/tests/e2e/json-stringify-replacer.test.js.map +1 -0
- package/dist/tests/e2e/json-stringify-space.test.d.ts +6 -0
- package/dist/tests/e2e/json-stringify-space.test.js +23 -0
- package/dist/tests/e2e/json-stringify-space.test.js.map +1 -0
- package/dist/tests/e2e/method-dispatch-errors.test.d.ts +9 -0
- package/dist/tests/e2e/method-dispatch-errors.test.js +38 -0
- package/dist/tests/e2e/method-dispatch-errors.test.js.map +1 -0
- package/dist/tests/e2e/native-extensions.test.js +1 -1
- package/dist/tests/e2e/native-extensions.test.js.map +1 -1
- package/dist/tests/e2e/promise-with-resolvers.test.d.ts +5 -0
- package/dist/tests/e2e/promise-with-resolvers.test.js +20 -0
- package/dist/tests/e2e/promise-with-resolvers.test.js.map +1 -0
- package/dist/tests/e2e/property-descriptors.test.d.ts +5 -0
- package/dist/tests/e2e/property-descriptors.test.js +25 -0
- package/dist/tests/e2e/property-descriptors.test.js.map +1 -0
- package/dist/tests/e2e/property-ic.test.d.ts +1 -0
- package/dist/tests/e2e/property-ic.test.js +55 -0
- package/dist/tests/e2e/property-ic.test.js.map +1 -0
- package/dist/tests/e2e/runtime-coverage-globals.test.js +46 -0
- package/dist/tests/e2e/runtime-coverage-globals.test.js.map +1 -1
- package/dist/tests/e2e/runtime-errors.test.d.ts +10 -0
- package/dist/tests/e2e/runtime-errors.test.js +52 -0
- package/dist/tests/e2e/runtime-errors.test.js.map +1 -0
- package/dist/tests/e2e/string-utf16.test.d.ts +6 -0
- package/dist/tests/e2e/string-utf16.test.js +133 -0
- package/dist/tests/e2e/string-utf16.test.js.map +1 -0
- package/dist/tests/e2e/structured-clone.test.d.ts +6 -0
- package/dist/tests/e2e/structured-clone.test.js +49 -0
- package/dist/tests/e2e/structured-clone.test.js.map +1 -0
- package/dist/tests/e2e/text-codec.test.d.ts +6 -0
- package/dist/tests/e2e/text-codec.test.js +24 -0
- package/dist/tests/e2e/text-codec.test.js.map +1 -0
- package/dist/tests/e2e/typed-array-views.test.d.ts +6 -0
- package/dist/tests/e2e/typed-array-views.test.js +39 -0
- package/dist/tests/e2e/typed-array-views.test.js.map +1 -0
- package/dist/tests/e2e/url-search-params.test.d.ts +5 -0
- package/dist/tests/e2e/url-search-params.test.js +30 -0
- package/dist/tests/e2e/url-search-params.test.js.map +1 -0
- package/dist/tests/e2e/weak-collections.test.d.ts +1 -0
- package/dist/tests/e2e/weak-collections.test.js +88 -0
- package/dist/tests/e2e/weak-collections.test.js.map +1 -0
- package/dist/tests/parser/declarations.test.js +12 -0
- package/dist/tests/parser/declarations.test.js.map +1 -1
- package/dist/tests/parser/module-syntax.test.js +9 -0
- package/dist/tests/parser/module-syntax.test.js.map +1 -1
- package/dist/tests/parser/parser.test.js +7 -0
- package/dist/tests/parser/parser.test.js.map +1 -1
- package/dist/tests/version.test.js +5 -1
- package/dist/tests/version.test.js.map +1 -1
- package/doc/ai/README.md +4 -3
- package/doc/ai/cli.md +41 -0
- package/doc/ai/contributing.md +26 -21
- package/doc/ai/extensions.md +12 -9
- package/doc/ai/language-support.md +26 -19
- package/doc/ai/troubleshooting.md +15 -12
- package/doc/ai/zh-CN/README.md +3 -2
- package/doc/ai/zh-CN/cli.md +35 -0
- package/doc/ai/zh-CN/contributing.md +19 -18
- package/doc/ai/zh-CN/extensions.md +10 -7
- package/doc/ai/zh-CN/language-support.md +26 -20
- package/doc/ai/zh-CN/troubleshooting.md +12 -10
- package/doc/gui/build.md +13 -4
- package/doc/gui/known-issues.md +9 -5
- package/doc/gui/rendering.md +3 -1
- package/doc/gui.md +4 -3
- package/doc/icon.md +5 -4
- package/doc/implemented/async.md +38 -0
- package/doc/implemented/binder.md +13 -0
- package/doc/implemented/cli.md +47 -0
- package/doc/implemented/codegen.md +33 -0
- package/doc/implemented/collections.md +26 -0
- package/doc/implemented/driver.md +19 -0
- package/doc/implemented/extensions.md +19 -0
- package/doc/implemented/fetch.md +12 -0
- package/doc/implemented/lexer.md +23 -0
- package/doc/implemented/modules.md +28 -0
- package/doc/implemented/node/assert.md +17 -0
- package/doc/implemented/node/buffer.md +29 -0
- package/doc/implemented/node/child-process.md +29 -0
- package/doc/implemented/node/crypto.md +9 -0
- package/doc/implemented/node/dgram.md +15 -0
- package/doc/implemented/node/events.md +37 -0
- package/doc/implemented/node/fs-promises.md +38 -0
- package/doc/implemented/node/fs.md +112 -0
- package/doc/implemented/node/http.md +21 -0
- package/doc/implemented/node/net.md +17 -0
- package/doc/implemented/node/os.md +22 -0
- package/doc/implemented/node/path.md +33 -0
- package/doc/implemented/node/process.md +23 -0
- package/doc/implemented/node/querystring.md +20 -0
- package/doc/implemented/node/stream-promises.md +8 -0
- package/doc/implemented/node/stream.md +19 -0
- package/doc/implemented/node/test.md +10 -0
- package/doc/implemented/node/url.md +8 -0
- package/doc/implemented/node/util.md +25 -0
- package/doc/implemented/node/worker-threads.md +10 -0
- package/doc/implemented/node/zlib.md +8 -0
- package/doc/implemented/node.md +48 -0
- package/doc/implemented/operators.md +38 -0
- package/doc/implemented/parser.md +58 -0
- package/doc/implemented/pipeline.md +28 -0
- package/doc/implemented/runtime-core.md +32 -0
- package/doc/implemented/stdlib.md +78 -0
- package/doc/implemented/strings.md +27 -0
- package/doc/implemented/tests.md +10 -0
- package/doc/implemented/typed-arrays.md +26 -0
- package/doc/implemented/value-model.md +18 -0
- package/doc/implemented.md +54 -352
- package/doc/node-implemented.md +3 -585
- package/doc/node-unimplemented.md +3 -164
- package/doc/requirements.md +23 -8
- package/doc/unimplemented/classes.md +22 -0
- package/doc/unimplemented/deviations.md +27 -0
- package/doc/unimplemented/expressions.md +26 -0
- package/doc/unimplemented/functions.md +21 -0
- package/doc/unimplemented/modules.md +22 -0
- package/doc/unimplemented/node/async.md +17 -0
- package/doc/unimplemented/node/bun.md +9 -0
- package/doc/unimplemented/node/fs-promises.md +16 -0
- package/doc/unimplemented/node/fs.md +31 -0
- package/doc/unimplemented/node/globals.md +23 -0
- package/doc/unimplemented/node/modules.md +21 -0
- package/doc/unimplemented/node.md +21 -0
- package/doc/unimplemented/statements.md +18 -0
- package/doc/unimplemented/stdlib.md +54 -0
- package/doc/unimplemented/toolchain.md +14 -0
- package/doc/unimplemented/types.md +12 -0
- package/doc/unimplemented.md +18 -274
- package/doc/xbintsc.config.schema.json +12 -0
- package/doc/zh-CN/gui/build.md +11 -3
- package/doc/zh-CN/gui/known-issues.md +9 -4
- package/doc/zh-CN/gui/rendering.md +2 -1
- package/doc/zh-CN/gui.md +3 -2
- package/doc/zh-CN/icon.md +5 -4
- package/doc/zh-CN/implemented/async.md +38 -0
- package/doc/zh-CN/implemented/binder.md +13 -0
- package/doc/zh-CN/implemented/cli.md +46 -0
- package/doc/zh-CN/implemented/codegen.md +33 -0
- package/doc/zh-CN/implemented/collections.md +26 -0
- package/doc/zh-CN/implemented/driver.md +19 -0
- package/doc/zh-CN/implemented/extensions.md +19 -0
- package/doc/zh-CN/implemented/fetch.md +12 -0
- package/doc/zh-CN/implemented/lexer.md +23 -0
- package/doc/zh-CN/implemented/modules.md +28 -0
- package/doc/zh-CN/implemented/node/assert.md +17 -0
- package/doc/zh-CN/implemented/node/buffer.md +25 -0
- package/doc/zh-CN/implemented/node/child-process.md +27 -0
- package/doc/zh-CN/implemented/node/crypto.md +9 -0
- package/doc/zh-CN/implemented/node/dgram.md +15 -0
- package/doc/zh-CN/implemented/node/events.md +36 -0
- package/doc/zh-CN/implemented/node/fs-promises.md +27 -0
- package/doc/zh-CN/implemented/node/fs.md +105 -0
- package/doc/zh-CN/implemented/node/http.md +17 -0
- package/doc/zh-CN/implemented/node/net.md +17 -0
- package/doc/zh-CN/implemented/node/os.md +21 -0
- package/doc/zh-CN/implemented/node/path.md +26 -0
- package/doc/zh-CN/implemented/node/process.md +23 -0
- package/doc/zh-CN/implemented/node/querystring.md +20 -0
- package/doc/zh-CN/implemented/node/stream-promises.md +8 -0
- package/doc/zh-CN/implemented/node/stream.md +15 -0
- package/doc/zh-CN/implemented/node/test.md +10 -0
- package/doc/zh-CN/implemented/node/url.md +8 -0
- package/doc/zh-CN/implemented/node/util.md +25 -0
- package/doc/zh-CN/implemented/node/worker-threads.md +9 -0
- package/doc/zh-CN/implemented/node/zlib.md +8 -0
- package/doc/zh-CN/implemented/node.md +45 -0
- package/doc/zh-CN/implemented/operators.md +38 -0
- package/doc/zh-CN/implemented/parser.md +58 -0
- package/doc/zh-CN/implemented/pipeline.md +25 -0
- package/doc/zh-CN/implemented/runtime-core.md +31 -0
- package/doc/zh-CN/implemented/stdlib.md +76 -0
- package/doc/zh-CN/implemented/strings.md +27 -0
- package/doc/zh-CN/implemented/tests.md +10 -0
- package/doc/zh-CN/implemented/typed-arrays.md +26 -0
- package/doc/zh-CN/implemented/value-model.md +18 -0
- package/doc/zh-CN/implemented.md +50 -347
- package/doc/zh-CN/node-implemented.md +4 -531
- package/doc/zh-CN/node-unimplemented.md +4 -139
- package/doc/zh-CN/plan-require-node-modules.md +4 -4
- package/doc/zh-CN/requirements.md +20 -6
- package/doc/zh-CN/unimplemented/classes.md +22 -0
- package/doc/zh-CN/unimplemented/deviations.md +24 -0
- package/doc/zh-CN/unimplemented/expressions.md +24 -0
- package/doc/zh-CN/unimplemented/functions.md +21 -0
- package/doc/zh-CN/unimplemented/modules.md +19 -0
- package/doc/zh-CN/unimplemented/node/async.md +17 -0
- package/doc/zh-CN/unimplemented/node/bun.md +8 -0
- package/doc/zh-CN/unimplemented/node/fs-promises.md +12 -0
- package/doc/zh-CN/unimplemented/node/fs.md +24 -0
- package/doc/zh-CN/unimplemented/node/globals.md +14 -0
- package/doc/zh-CN/unimplemented/node/modules.md +15 -0
- package/doc/zh-CN/unimplemented/node.md +18 -0
- package/doc/zh-CN/unimplemented/statements.md +15 -0
- package/doc/zh-CN/unimplemented/stdlib.md +54 -0
- package/doc/zh-CN/unimplemented/toolchain.md +14 -0
- package/doc/zh-CN/unimplemented/types.md +11 -0
- package/doc/zh-CN/unimplemented.md +14 -236
- package/llms.txt +32 -4
- package/package.json +1 -1
- package/runtime/ext_gui/renderer_shaders.h +2 -2
- package/runtime/ext_gui/stb_image.h +1 -17
- package/runtime/ext_node/child_process/child_process.c +173 -73
- package/runtime/rt.h +47 -0
- package/runtime/rt_internal.h +205 -10
- package/runtime/xt_alloc.c +49 -7
- package/runtime/xt_array_buffer.c +284 -0
- package/runtime/xt_async.c +222 -0
- package/runtime/xt_bigint/helpers.inc +3 -3
- package/runtime/xt_builtins.c +59 -51
- package/runtime/xt_constructors.c +399 -0
- package/runtime/xt_containers/access.inc +195 -14
- package/runtime/xt_containers/arrays.inc +26 -2
- package/runtime/xt_containers/objects.inc +226 -5
- package/runtime/xt_containers/shapes.inc +71 -0
- package/runtime/xt_containers.c +1 -0
- package/runtime/xt_coroutine.c +229 -0
- package/runtime/xt_generator.c +325 -167
- package/runtime/xt_io/inspect.inc +147 -2
- package/runtime/xt_loop.c +35 -4
- package/runtime/xt_performance.c +37 -0
- package/runtime/xt_promise.c +125 -18
- package/runtime/xt_stdlib/arrays.inc +1 -1
- package/runtime/xt_stdlib/dispatch.inc +64 -13
- package/runtime/xt_stdlib/strings.inc +74 -17
- package/runtime/xt_stdlib2/array-statics.inc +28 -3
- package/runtime/xt_stdlib2/arrays.inc +5 -3
- package/runtime/xt_stdlib2/container.inc +5 -0
- package/runtime/xt_stdlib2/date.inc +111 -3
- package/runtime/xt_stdlib2/error.inc +35 -0
- package/runtime/xt_stdlib2/json.inc +353 -33
- package/runtime/xt_stdlib2/number-string-statics.inc +24 -15
- package/runtime/xt_stdlib2/objects.inc +123 -1
- package/runtime/xt_stdlib2/regexp-match.inc +2 -2
- package/runtime/xt_stdlib2/set.inc +7 -1
- package/runtime/xt_stdlib2/strings.inc +70 -40
- package/runtime/xt_structured_clone.c +159 -0
- package/runtime/xt_symbol.c +2 -2
- package/runtime/xt_text_codec.c +69 -0
- package/runtime/xt_typed_array/construction.inc +78 -7
- package/runtime/xt_typed_array/elements.inc +159 -0
- package/runtime/xt_typed_array/methods.inc +21 -5
- package/runtime/xt_typed_array.c +11 -10
- package/runtime/xt_url.c +375 -0
- package/runtime/xt_values/arithmetic.inc +2 -2
- package/runtime/xt_values/constructors.inc +8 -0
- package/runtime/xt_values/conversions.inc +1 -1
- package/runtime/xt_values/strings.inc +19 -3
- package/runtime/xt_values/utf16.inc +340 -0
- package/runtime/xt_values.c +1 -0
- package/runtime/xt_weak.c +281 -0
- package/scripts/build-gui.ts +133 -60
- package/scripts/check-version.ts +3 -3
- package/src/binder/declarations.ts +14 -3
- package/src/cli/hints.ts +8 -1
- package/src/cli/main.ts +119 -18
- package/src/cli/watch.ts +101 -0
- package/src/codegen/generator/calls/access.ts +17 -4
- package/src/codegen/generator/calls/closures.ts +12 -1
- package/src/codegen/generator/calls/invocation.ts +4 -3
- package/src/codegen/generator/context.ts +23 -3
- package/src/codegen/generator/expressions/operators.ts +27 -13
- package/src/codegen/generator/expressions/primary.ts +10 -1
- package/src/codegen/generator/module.ts +10 -19
- package/src/codegen/generator/numeric.ts +85 -11
- package/src/codegen/generator/state.ts +27 -0
- package/src/codegen/generator/statements/control-flow.ts +2 -6
- package/src/codegen/generator/statements/loops.ts +50 -16
- package/src/codegen/generator/tables.ts +110 -3
- package/src/diagnostics/diagnostic.ts +23 -3
- package/src/driver/app-artifacts.ts +77 -0
- package/src/driver/build-key.ts +55 -0
- package/src/driver/bundler/graph.ts +63 -13
- package/src/driver/bundler/merge.ts +4 -1
- package/src/driver/compiler.ts +93 -324
- package/src/driver/config.ts +11 -0
- package/src/driver/frontend.ts +120 -0
- package/src/driver/index.ts +0 -1
- package/src/driver/options.ts +70 -0
- package/src/driver/runtime-objects.ts +133 -0
- package/src/driver/toolchain-provider.ts +4 -0
- package/src/driver/toolchain.ts +154 -10
- package/src/driver/version.ts +12 -0
- package/src/driver/win-icon.ts +36 -36
- package/src/parser/declarations/classes.ts +4 -0
- package/src/parser/declarations/functions.ts +12 -1
- package/src/parser/modules.ts +8 -4
- package/src/parser/parser.ts +28 -0
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
type VariableDeclarationList,
|
|
13
13
|
type WhileStatement,
|
|
14
14
|
} from "../../../ast/nodes.js";
|
|
15
|
-
import { numberLiteral } from "../../values.js";
|
|
15
|
+
import { i64, numberLiteral, XT_TRUE } from "../../values.js";
|
|
16
16
|
import type { Generator } from "../generator.js";
|
|
17
17
|
import type { LoopLabels } from "../state.js";
|
|
18
18
|
|
|
@@ -48,10 +48,7 @@ export const loopStatementMethods: LoopStatementMethods = {
|
|
|
48
48
|
this.terminate(`br label %${condLabel}`);
|
|
49
49
|
this.startBlock(condLabel);
|
|
50
50
|
const condition = this.emitExpression(statement.condition);
|
|
51
|
-
const
|
|
52
|
-
this.emit(` ${truthy} = call i32 @xt_truthy(i64 ${condition})`);
|
|
53
|
-
const nonzero = this.reg();
|
|
54
|
-
this.emit(` ${nonzero} = icmp ne i32 ${truthy}, 0`);
|
|
51
|
+
const nonzero = this.emitTruthiness(condition, statement.condition);
|
|
55
52
|
this.terminate(`br i1 ${nonzero}, label %${bodyLabel}, label %${endLabel}`);
|
|
56
53
|
this.startBlock(bodyLabel);
|
|
57
54
|
this.current.loops.push({ breakLabel: endLabel, continueLabel: condLabel, tryDepth: this.current.tryFrames.length, labels: this.takePendingLabels() });
|
|
@@ -74,10 +71,7 @@ export const loopStatementMethods: LoopStatementMethods = {
|
|
|
74
71
|
|
|
75
72
|
this.startBlock(condLabel);
|
|
76
73
|
const condition = this.emitExpression(statement.condition);
|
|
77
|
-
const
|
|
78
|
-
this.emit(` ${truthy} = call i32 @xt_truthy(i64 ${condition})`);
|
|
79
|
-
const nonzero = this.reg();
|
|
80
|
-
this.emit(` ${nonzero} = icmp ne i32 ${truthy}, 0`);
|
|
74
|
+
const nonzero = this.emitTruthiness(condition, statement.condition);
|
|
81
75
|
this.terminate(`br i1 ${nonzero}, label %${bodyLabel}, label %${endLabel}`);
|
|
82
76
|
this.startBlock(endLabel);
|
|
83
77
|
},
|
|
@@ -103,10 +97,7 @@ export const loopStatementMethods: LoopStatementMethods = {
|
|
|
103
97
|
this.startBlock(condLabel);
|
|
104
98
|
if (statement.condition) {
|
|
105
99
|
const condition = this.emitExpression(statement.condition);
|
|
106
|
-
const
|
|
107
|
-
this.emit(` ${truthy} = call i32 @xt_truthy(i64 ${condition})`);
|
|
108
|
-
const nonzero = this.reg();
|
|
109
|
-
this.emit(` ${nonzero} = icmp ne i32 ${truthy}, 0`);
|
|
100
|
+
const nonzero = this.emitTruthiness(condition, statement.condition);
|
|
110
101
|
this.terminate(`br i1 ${nonzero}, label %${bodyLabel}, label %${endLabel}`);
|
|
111
102
|
} else {
|
|
112
103
|
this.terminate(`br label %${bodyLabel}`);
|
|
@@ -128,6 +119,50 @@ export const loopStatementMethods: LoopStatementMethods = {
|
|
|
128
119
|
emitForOf(statement: ForOfStatement | ForInStatement): void {
|
|
129
120
|
const source = this.emitExpression(statement.expression);
|
|
130
121
|
const isForIn = statement.kind === SyntaxKind.ForInStatement;
|
|
122
|
+
/* `for await (const x of xs)`: resolve the async iteration protocol once,
|
|
123
|
+
* await one step per iteration, then bind its `value`. Running the await
|
|
124
|
+
* inside the surrounding async coroutine is what makes the loop suspend
|
|
125
|
+
* between elements instead of blocking the event loop. */
|
|
126
|
+
if (!isForIn && (statement as ForOfStatement).awaitModifier) {
|
|
127
|
+
const iterable = this.runtimeCall("xt_async_iter_open", [source]);
|
|
128
|
+
const condLabel = this.label("forawait.cond");
|
|
129
|
+
const bodyLabel = this.label("forawait.body");
|
|
130
|
+
const updateLabel = this.label("forawait.update");
|
|
131
|
+
const endLabel = this.label("forawait.end");
|
|
132
|
+
this.terminate(`br label %${condLabel}`);
|
|
133
|
+
|
|
134
|
+
this.startBlock(condLabel);
|
|
135
|
+
const next = this.runtimeCall("xt_async_iter_next", [iterable]);
|
|
136
|
+
const step = this.runtimeCall("xt_await", [next]);
|
|
137
|
+
const doneKey = this.stringValue("done");
|
|
138
|
+
const done = this.runtimeCall("xt_get", [step, doneKey]);
|
|
139
|
+
/* `xt_truthy` returns i32, so it cannot go through `runtimeCall`
|
|
140
|
+
* (which types every result as i64). */
|
|
141
|
+
const truthy = this.reg();
|
|
142
|
+
this.emit(` ${truthy} = call i32 @xt_truthy(i64 ${done})`);
|
|
143
|
+
const nonzero = this.reg();
|
|
144
|
+
this.emit(` ${nonzero} = icmp ne i32 ${truthy}, 0`);
|
|
145
|
+
this.terminate(`br i1 ${nonzero}, label %${endLabel}, label %${bodyLabel}`);
|
|
146
|
+
|
|
147
|
+
this.startBlock(bodyLabel);
|
|
148
|
+
const valueKey = this.stringValue("value");
|
|
149
|
+
const element = this.runtimeCall("xt_get", [step, valueKey]);
|
|
150
|
+
this.bindLoopVariable(statement.initializer, element);
|
|
151
|
+
this.current.loops.push({
|
|
152
|
+
breakLabel: endLabel,
|
|
153
|
+
continueLabel: updateLabel,
|
|
154
|
+
tryDepth: this.current.tryFrames.length,
|
|
155
|
+
labels: this.takePendingLabels(),
|
|
156
|
+
});
|
|
157
|
+
this.emitStatement(statement.statement);
|
|
158
|
+
this.current.loops.pop();
|
|
159
|
+
if (!this.current.terminated) this.terminate(`br label %${updateLabel}`);
|
|
160
|
+
|
|
161
|
+
this.startBlock(updateLabel);
|
|
162
|
+
this.terminate(`br label %${condLabel}`);
|
|
163
|
+
this.startBlock(endLabel);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
131
166
|
// `for...in` iterates the enumerable keys (indices become strings);
|
|
132
167
|
// `for...of` resolves the iteration protocol once, then walks it.
|
|
133
168
|
const iterable = isForIn
|
|
@@ -148,10 +183,9 @@ export const loopStatementMethods: LoopStatementMethods = {
|
|
|
148
183
|
/* `xt_iter_has` covers generators too, which cannot be sized up front. */
|
|
149
184
|
const hasValue = this.reg();
|
|
150
185
|
this.emit(` ${hasValue} = call i64 @xt_iter_has(i64 ${iterable}, i64 ${index})`);
|
|
151
|
-
|
|
152
|
-
this.emit(` ${truthy} = call i32 @xt_truthy(i64 ${hasValue})`);
|
|
186
|
+
/* `xt_iter_has` always returns a boolean tag, so skip `xt_truthy`. */
|
|
153
187
|
const nonzero = this.reg();
|
|
154
|
-
this.emit(` ${nonzero} = icmp
|
|
188
|
+
this.emit(` ${nonzero} = icmp eq i64 ${hasValue}, ${i64(XT_TRUE)}`);
|
|
155
189
|
this.terminate(`br i1 ${nonzero}, label %${bodyLabel}, label %${endLabel}`);
|
|
156
190
|
|
|
157
191
|
this.startBlock(bodyLabel);
|
|
@@ -37,6 +37,9 @@ export const BUILTIN_INSTANCEOF: Readonly<Record<string, number>> = {
|
|
|
37
37
|
Date: 5,
|
|
38
38
|
RegExp: 6,
|
|
39
39
|
Promise: 7,
|
|
40
|
+
WeakMap: 8,
|
|
41
|
+
WeakSet: 9,
|
|
42
|
+
WeakRef: 10,
|
|
40
43
|
Uint8Array: 16,
|
|
41
44
|
Int8Array: 17,
|
|
42
45
|
Uint8ClampedArray: 18,
|
|
@@ -153,6 +156,10 @@ export const GLOBAL_FUNCTIONS: Record<string, string> = {
|
|
|
153
156
|
clearTimeout: "xt_clear_timeout",
|
|
154
157
|
setInterval: "xt_set_interval",
|
|
155
158
|
clearInterval: "xt_clear_interval",
|
|
159
|
+
setImmediate: "xt_set_immediate",
|
|
160
|
+
clearImmediate: "xt_clear_immediate",
|
|
161
|
+
queueMicrotask: "xt_queue_microtask",
|
|
162
|
+
structuredClone: "xt_structured_clone",
|
|
156
163
|
fetch: "xt_fetch",
|
|
157
164
|
Number: "xt_number_ctor",
|
|
158
165
|
String: "xt_string_ctor",
|
|
@@ -177,6 +184,10 @@ export const BUILTIN_FUNCTION_VALUES: Record<string, string> = {
|
|
|
177
184
|
clearTimeout: "xt_builtin_value_clearTimeout",
|
|
178
185
|
setInterval: "xt_builtin_value_setInterval",
|
|
179
186
|
clearInterval: "xt_builtin_value_clearInterval",
|
|
187
|
+
setImmediate: "xt_builtin_value_setImmediate",
|
|
188
|
+
clearImmediate: "xt_builtin_value_clearImmediate",
|
|
189
|
+
queueMicrotask: "xt_builtin_value_queueMicrotask",
|
|
190
|
+
structuredClone: "xt_builtin_value_structuredClone",
|
|
180
191
|
fetch: "xt_builtin_value_fetch",
|
|
181
192
|
Number: "xt_builtin_value_number",
|
|
182
193
|
String: "xt_builtin_value_string",
|
|
@@ -233,9 +244,11 @@ export const NAMESPACE_STATICS: Record<string, string> = {
|
|
|
233
244
|
Symbol: "xt_symbol_static",
|
|
234
245
|
Date: "xt_date_static",
|
|
235
246
|
Promise: "xt_promise_static",
|
|
247
|
+
ArrayBuffer: "xt_array_buffer_static",
|
|
236
248
|
path: "xt_path_static",
|
|
237
249
|
os: "xt_os_static",
|
|
238
250
|
process: "xt_process_call",
|
|
251
|
+
performance: "xt_performance_call",
|
|
239
252
|
Buffer: "xt_buffer_static",
|
|
240
253
|
stream: "xt_stream_static",
|
|
241
254
|
Readable: "xt_stream_static",
|
|
@@ -253,18 +266,39 @@ export const NAMESPACE_STATICS: Record<string, string> = {
|
|
|
253
266
|
...TYPED_ARRAY_STATICS,
|
|
254
267
|
};
|
|
255
268
|
|
|
269
|
+
/** The well-known symbols exposed as properties of the `Symbol` namespace. */
|
|
270
|
+
export const SYMBOL_WELL_KNOWN = new Set<string>([
|
|
271
|
+
"asyncIterator",
|
|
272
|
+
"hasInstance",
|
|
273
|
+
"isConcatSpreadable",
|
|
274
|
+
"iterator",
|
|
275
|
+
"match",
|
|
276
|
+
"matchAll",
|
|
277
|
+
"replace",
|
|
278
|
+
"search",
|
|
279
|
+
"species",
|
|
280
|
+
"split",
|
|
281
|
+
"toPrimitive",
|
|
282
|
+
"toStringTag",
|
|
283
|
+
"unscopables",
|
|
284
|
+
]);
|
|
285
|
+
|
|
256
286
|
/** Namespace identifiers whose property access maps to a runtime getter. */
|
|
257
287
|
export const NAMESPACE_PROPERTIES: Record<string, string> = {
|
|
258
288
|
process: "xt_process_get",
|
|
259
289
|
"import.meta": "xt_import_meta",
|
|
260
290
|
Symbol: "xt_symbol_get",
|
|
291
|
+
performance: "xt_performance_get",
|
|
261
292
|
};
|
|
262
293
|
|
|
263
294
|
/** Global constructors called as `new X(...)` (all have signature `(i32, i64*)`). */
|
|
264
295
|
export const CTOR_FUNCTIONS: Record<string, string> = {
|
|
265
|
-
Array: "
|
|
296
|
+
Array: "xt_array_ctor",
|
|
266
297
|
Map: "xt_map_ctor",
|
|
267
298
|
Set: "xt_set_ctor",
|
|
299
|
+
WeakMap: "xt_weak_map_ctor",
|
|
300
|
+
WeakSet: "xt_weak_set_ctor",
|
|
301
|
+
WeakRef: "xt_weak_ref_ctor",
|
|
268
302
|
Date: "xt_date_ctor",
|
|
269
303
|
RegExp: "xt_regexp_ctor",
|
|
270
304
|
Promise: "xt_promise_ctor",
|
|
@@ -277,10 +311,42 @@ export const CTOR_FUNCTIONS: Record<string, string> = {
|
|
|
277
311
|
Socket: "xt_net_socket_ctor",
|
|
278
312
|
Server: "xt_net_server_ctor",
|
|
279
313
|
EventEmitter: "xt_event_emitter_ctor",
|
|
314
|
+
URLSearchParams: "xt_url_search_params_ctor",
|
|
315
|
+
TextEncoder: "xt_text_encoder_ctor",
|
|
316
|
+
TextDecoder: "xt_text_decoder_ctor",
|
|
317
|
+
ArrayBuffer: "xt_array_buffer_ctor",
|
|
318
|
+
DataView: "xt_data_view_ctor",
|
|
280
319
|
...ERROR_CONSTRUCTORS,
|
|
281
320
|
...TYPED_ARRAY_CTORS,
|
|
282
321
|
};
|
|
283
322
|
|
|
323
|
+
/**
|
|
324
|
+
* Built-in constructors that are also ordinary first-class values. The codegen
|
|
325
|
+
* lowers a bare reference (`const A = Array`) to `xt_builtin_constructor`, which
|
|
326
|
+
* returns a cached function with `name`/`length`, a `prototype` and the
|
|
327
|
+
* constructor's statics (`A.isArray`, `A.from`, ...).
|
|
328
|
+
*/
|
|
329
|
+
export const FIRST_CLASS_CONSTRUCTORS = new Set<string>([
|
|
330
|
+
"Array",
|
|
331
|
+
"Object",
|
|
332
|
+
"Function",
|
|
333
|
+
"Map",
|
|
334
|
+
"Set",
|
|
335
|
+
"WeakMap",
|
|
336
|
+
"WeakSet",
|
|
337
|
+
"WeakRef",
|
|
338
|
+
"Date",
|
|
339
|
+
"RegExp",
|
|
340
|
+
"Promise",
|
|
341
|
+
...Object.keys(TYPED_ARRAYS),
|
|
342
|
+
...Object.keys(ERROR_CONSTRUCTORS),
|
|
343
|
+
"Number",
|
|
344
|
+
"String",
|
|
345
|
+
"Boolean",
|
|
346
|
+
"BigInt",
|
|
347
|
+
"Symbol",
|
|
348
|
+
]);
|
|
349
|
+
|
|
284
350
|
export const BUILTIN_METHODS = new Set<string>([
|
|
285
351
|
"push", "pop", "shift", "unshift", "join", "slice", "indexOf", "includes", "map", "forEach", "filter",
|
|
286
352
|
"reduce", "concat", "reverse", "charAt", "charCodeAt", "substring", "substr", "split", "toUpperCase",
|
|
@@ -350,7 +416,7 @@ export const KIND_NAMES = new Map<number, string>([
|
|
|
350
416
|
[SyntaxKind.DeleteExpression, "delete expression"],
|
|
351
417
|
[SyntaxKind.AwaitExpression, "await expression"],
|
|
352
418
|
[SyntaxKind.YieldExpression, "yield expression"],
|
|
353
|
-
[SyntaxKind.
|
|
419
|
+
[SyntaxKind.ModuleDeclaration, "namespace declaration"],
|
|
354
420
|
]);
|
|
355
421
|
|
|
356
422
|
/**
|
|
@@ -394,7 +460,7 @@ export function utf8Bytes(text: string): number[] {
|
|
|
394
460
|
if (!hasMultiByteUnit(text)) {
|
|
395
461
|
const bytes: number[] = [];
|
|
396
462
|
for (let index = 0; index < text.length; index++) bytes.push(text.charCodeAt(index) & 0xff);
|
|
397
|
-
return bytes;
|
|
463
|
+
return combineSurrogateBytes(bytes);
|
|
398
464
|
}
|
|
399
465
|
const bytes: number[] = [];
|
|
400
466
|
const length = text.length;
|
|
@@ -420,6 +486,47 @@ function hasMultiByteUnit(text: string): boolean {
|
|
|
420
486
|
return false;
|
|
421
487
|
}
|
|
422
488
|
|
|
489
|
+
/**
|
|
490
|
+
* Join adjacent WTF-8 surrogate halves into one four-byte sequence.
|
|
491
|
+
*
|
|
492
|
+
* A literal such as `"\uD83D\uDE00"` scans to two separate three-byte
|
|
493
|
+
* escapes. JavaScript's string value is one code point, so the emitted bytes
|
|
494
|
+
* must be the four-byte UTF-8 form (and a lone escape must stay three bytes,
|
|
495
|
+
* which is why this runs after scanning rather than per escape).
|
|
496
|
+
*/
|
|
497
|
+
function combineSurrogateBytes(bytes: number[]): number[] {
|
|
498
|
+
const out: number[] = [];
|
|
499
|
+
for (let index = 0; index < bytes.length; index++) {
|
|
500
|
+
if (
|
|
501
|
+
index + 5 < bytes.length &&
|
|
502
|
+
bytes[index] === 0xed &&
|
|
503
|
+
bytes[index + 1]! >= 0xa0 &&
|
|
504
|
+
bytes[index + 1]! <= 0xaf &&
|
|
505
|
+
bytes[index + 2]! >= 0x80 &&
|
|
506
|
+
bytes[index + 2]! <= 0xbf &&
|
|
507
|
+
bytes[index + 3] === 0xed &&
|
|
508
|
+
bytes[index + 4]! >= 0xb0 &&
|
|
509
|
+
bytes[index + 4]! <= 0xbf &&
|
|
510
|
+
bytes[index + 5]! >= 0x80 &&
|
|
511
|
+
bytes[index + 5]! <= 0xbf
|
|
512
|
+
) {
|
|
513
|
+
const high = ((bytes[index]! & 0x0f) << 12) | ((bytes[index + 1]! & 0x3f) << 6) | (bytes[index + 2]! & 0x3f);
|
|
514
|
+
const low = ((bytes[index + 3]! & 0x0f) << 12) | ((bytes[index + 4]! & 0x3f) << 6) | (bytes[index + 5]! & 0x3f);
|
|
515
|
+
const code = 0x10000 + ((high - 0xd800) << 10) + (low - 0xdc00);
|
|
516
|
+
out.push(
|
|
517
|
+
0xf0 | (code >> 18),
|
|
518
|
+
0x80 | ((code >> 12) & 0x3f),
|
|
519
|
+
0x80 | ((code >> 6) & 0x3f),
|
|
520
|
+
0x80 | (code & 0x3f),
|
|
521
|
+
);
|
|
522
|
+
index += 5;
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
out.push(bytes[index]!);
|
|
526
|
+
}
|
|
527
|
+
return out;
|
|
528
|
+
}
|
|
529
|
+
|
|
423
530
|
export function escapeBytes(bytes: readonly number[]): string {
|
|
424
531
|
return bytes
|
|
425
532
|
.map((byte) => {
|
|
@@ -20,6 +20,7 @@ export enum DiagnosticCode {
|
|
|
20
20
|
InvalidAssignmentTarget = 2005,
|
|
21
21
|
DuplicateDefault = 2006,
|
|
22
22
|
InvalidTypeSyntax = 2007,
|
|
23
|
+
NestingTooDeep = 2008,
|
|
23
24
|
|
|
24
25
|
// Binder 3xxx
|
|
25
26
|
DuplicateIdentifier = 3001,
|
|
@@ -42,6 +43,7 @@ export enum DiagnosticCode {
|
|
|
42
43
|
IOError = 6002,
|
|
43
44
|
ToolchainError = 6003,
|
|
44
45
|
IncrementalCacheError = 6004,
|
|
46
|
+
CircularDependency = 6005,
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
export interface Diagnostic {
|
|
@@ -119,9 +121,27 @@ export function formatDiagnostic(d: Diagnostic, source?: SourceFile): string {
|
|
|
119
121
|
const lineText = source.text.split("\n")[line - 1] ?? "";
|
|
120
122
|
const end = d.end ?? d.start;
|
|
121
123
|
const endCol = source.positionAt(end).column;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
|
|
125
|
+
/* Long lines (a minified bundle, a generated one-liner, deeply nested
|
|
126
|
+
* source) would otherwise print tens of thousands of characters and make
|
|
127
|
+
* the actual message impossible to find. Keep a window around the caret. */
|
|
128
|
+
const maxExcerpt = 160;
|
|
129
|
+
const caretIndex = Math.max(0, column - 1);
|
|
130
|
+
let windowStart = 0;
|
|
131
|
+
let windowEnd = lineText.length;
|
|
132
|
+
if (lineText.length > maxExcerpt) {
|
|
133
|
+
windowStart = Math.max(0, caretIndex - Math.floor(maxExcerpt / 2));
|
|
134
|
+
windowEnd = Math.min(lineText.length, windowStart + maxExcerpt);
|
|
135
|
+
if (windowEnd === lineText.length) windowStart = Math.max(0, windowEnd - maxExcerpt);
|
|
136
|
+
}
|
|
137
|
+
const prefix = windowStart > 0 ? "\u2026" : "";
|
|
138
|
+
const suffix = windowEnd < lineText.length ? "\u2026" : "";
|
|
139
|
+
const visible = lineText.slice(windowStart, windowEnd);
|
|
140
|
+
const visibleCaret = caretIndex - windowStart;
|
|
141
|
+
const caretWidth = Math.max(1, Math.min(endCol - column, visible.length - visibleCaret));
|
|
142
|
+
const caretPad = " ".repeat(prefix.length + Math.max(0, visibleCaret));
|
|
143
|
+
const caret = "^".repeat(caretWidth);
|
|
144
|
+
excerpt = `\n${prefix}${visible}${suffix}\n${caretPad}${caret}`;
|
|
125
145
|
}
|
|
126
146
|
return `${location} - ${severity} TS${d.code}: ${d.message}${excerpt}`;
|
|
127
147
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform artifacts that turn a linked program into a desktop application:
|
|
3
|
+
* the Windows-subystem entry shim, the embedded icon object and the Windows PE
|
|
4
|
+
* icon resource.
|
|
5
|
+
*
|
|
6
|
+
* They are collected separately from the link call so icon/GUI/package work
|
|
7
|
+
* has a home of its own instead of growing `build`.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { ExtensionRegistry } from "../extensions/registry.js";
|
|
11
|
+
import { ensureIconObject, EMPTY_ICON, IconError, type IconInfo } from "./icon.js";
|
|
12
|
+
import { ensureWindowsEntryObject } from "./win-entry.js";
|
|
13
|
+
import { ensureWindowsIconResource, resolveResourceCompiler } from "./win-icon.js";
|
|
14
|
+
import type { AppConfig } from "./config.js";
|
|
15
|
+
import type { Runner } from "./toolchain.js";
|
|
16
|
+
|
|
17
|
+
export interface AppArtifactRequest {
|
|
18
|
+
readonly runner: Runner;
|
|
19
|
+
readonly clang: string;
|
|
20
|
+
readonly cacheDir: string;
|
|
21
|
+
readonly registry: ExtensionRegistry;
|
|
22
|
+
readonly app: AppConfig;
|
|
23
|
+
readonly icon: IconInfo | undefined;
|
|
24
|
+
readonly env: Record<string, string>;
|
|
25
|
+
readonly verbose: boolean | undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface AppArtifacts {
|
|
29
|
+
/** Windows-subsystem entry shim, when the program is a GUI app. */
|
|
30
|
+
readonly entryObject?: string;
|
|
31
|
+
readonly iconObjects: readonly string[];
|
|
32
|
+
/** Extra linker flags implied by the subsystem (empty on other platforms). */
|
|
33
|
+
readonly linkerFlags: readonly string[];
|
|
34
|
+
/** Set when the icon could not be embedded; the caller reports it. */
|
|
35
|
+
readonly iconError?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Build the objects (and flags) that accompany the program object.
|
|
40
|
+
*
|
|
41
|
+
* On Windows a GUI program links as a **Windows-subsystem** executable, so
|
|
42
|
+
* launching it does not flash a console window. That subsystem's C runtime
|
|
43
|
+
* wants `WinMain`, so a tiny shim object bridges it to the runtime's `main`.
|
|
44
|
+
* `app.console: true` keeps the console subsystem instead (useful while
|
|
45
|
+
* debugging, because stdout and stderr only exist there). Other platforms have
|
|
46
|
+
* no equivalent.
|
|
47
|
+
*/
|
|
48
|
+
export function ensureAppArtifacts(request: AppArtifactRequest): AppArtifacts {
|
|
49
|
+
const { runner, clang, cacheDir, registry, app, icon, env, verbose } = request;
|
|
50
|
+
const windowsSubsystem = process.platform === "win32" && registry.has("gui") && app.console !== true;
|
|
51
|
+
const linkerFlags = windowsSubsystem ? ["-Wl,/SUBSYSTEM:WINDOWS"] : [];
|
|
52
|
+
const entryObject = windowsSubsystem
|
|
53
|
+
? ensureWindowsEntryObject(runner, clang, cacheDir, env)
|
|
54
|
+
: undefined;
|
|
55
|
+
|
|
56
|
+
const iconObjects: string[] = [];
|
|
57
|
+
// The GUI extension references the icon symbols unconditionally, so a GUI
|
|
58
|
+
// program gets an (empty) icon object even with no icon configured.
|
|
59
|
+
if (icon !== undefined || registry.has("gui")) {
|
|
60
|
+
try {
|
|
61
|
+
iconObjects.push(ensureIconObject(runner, clang, cacheDir, icon ?? EMPTY_ICON, env));
|
|
62
|
+
if (icon && process.platform === "win32") {
|
|
63
|
+
const resourceCompiler = resolveResourceCompiler(runner, clang);
|
|
64
|
+
if (resourceCompiler) {
|
|
65
|
+
iconObjects.push(ensureWindowsIconResource(runner, cacheDir, icon, resourceCompiler, env));
|
|
66
|
+
} else if (verbose) {
|
|
67
|
+
process.stderr.write("xbintsc: no llvm-rc found; skipping the embedded .exe icon\n");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
} catch (error) {
|
|
71
|
+
if (error instanceof IconError) return { entryObject, iconObjects, linkerFlags, iconError: error.message };
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return { entryObject, iconObjects, linkerFlags };
|
|
77
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The incremental-cache key.
|
|
3
|
+
*
|
|
4
|
+
* Everything that can change the produced binary belongs here: compiler
|
|
5
|
+
* version, source text, emit kind, optimization/LTO/PGO mode, platform,
|
|
6
|
+
* extension and runtime fingerprints, and the embedded application metadata.
|
|
7
|
+
* A feature that adds such an input edits this module (and the call site),
|
|
8
|
+
* not the build orchestration.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { ExtensionRegistry } from "../extensions/registry.js";
|
|
12
|
+
import { hashParts } from "./cache.js";
|
|
13
|
+
import type { AppConfig } from "./config.js";
|
|
14
|
+
import { compilerFingerprint, registryFingerprint, runtimeFingerprint } from "./fingerprint.js";
|
|
15
|
+
import { COMPILER_VERSION } from "./version.js";
|
|
16
|
+
import type { IconInfo } from "./icon.js";
|
|
17
|
+
import type { PgoMode } from "./toolchain.js";
|
|
18
|
+
|
|
19
|
+
export interface CacheKeyInput {
|
|
20
|
+
/** The text the build compiled: the entry source, or the bundled module text. */
|
|
21
|
+
readonly sourceText: string;
|
|
22
|
+
readonly emit: string;
|
|
23
|
+
readonly optimize: string;
|
|
24
|
+
readonly registry: ExtensionRegistry;
|
|
25
|
+
readonly runtimeDir: string;
|
|
26
|
+
readonly icon?: IconInfo;
|
|
27
|
+
readonly app: AppConfig;
|
|
28
|
+
readonly debug: boolean;
|
|
29
|
+
readonly lto: boolean;
|
|
30
|
+
readonly pgo?: PgoMode;
|
|
31
|
+
readonly pgoDir: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Hash every input that can change the produced binary. */
|
|
35
|
+
export function buildCacheKey(input: CacheKeyInput): string {
|
|
36
|
+
const { app, icon, pgo } = input;
|
|
37
|
+
return hashParts([
|
|
38
|
+
COMPILER_VERSION,
|
|
39
|
+
compilerFingerprint(),
|
|
40
|
+
input.sourceText,
|
|
41
|
+
input.emit,
|
|
42
|
+
input.optimize,
|
|
43
|
+
process.platform,
|
|
44
|
+
registryFingerprint(input.registry),
|
|
45
|
+
runtimeFingerprint(input.runtimeDir),
|
|
46
|
+
icon ? hashParts(["icon", icon.format, Buffer.from(icon.bytes).toString("base64")]) : "",
|
|
47
|
+
app.name ?? "",
|
|
48
|
+
String(app.bundle ?? false),
|
|
49
|
+
app.bundleId ?? "",
|
|
50
|
+
String(input.debug),
|
|
51
|
+
String(input.lto),
|
|
52
|
+
pgo ?? "",
|
|
53
|
+
pgo ? input.pgoDir : "",
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { existsSync, readFileSync } from "node:fs";
|
|
7
|
-
import { dirname, extname } from "node:path";
|
|
8
|
-
import { SyntaxKind, type ExportDeclaration, type ImportDeclaration, type Statement } from "../../ast/nodes.js";
|
|
7
|
+
import { dirname, extname, relative } from "node:path";
|
|
8
|
+
import { SyntaxKind, type ExportDeclaration, type ImportDeclaration, type NamedExports, type Statement } from "../../ast/nodes.js";
|
|
9
9
|
import { bind } from "../../binder/binder.js";
|
|
10
10
|
import { DiagnosticBag, DiagnosticCode } from "../../diagnostics/diagnostic.js";
|
|
11
11
|
import { SourceFile } from "../../diagnostics/source.js";
|
|
@@ -16,12 +16,47 @@ import { classifyDependency } from "./resolve.js";
|
|
|
16
16
|
import { collectRequireSites, isNodeModulesPath, usesCommonJS } from "./commonjs.js";
|
|
17
17
|
import type { ModuleRecord } from "./types.js";
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* True when an import has no runtime binding, so it is not a module edge:
|
|
21
|
+
* `import type { T } from "..."` or `import { type T } from "..."`. A
|
|
22
|
+
* side-effect-only import (`import "..."`) and an empty clause
|
|
23
|
+
* (`import {} from "..."`) both evaluate the module and *are* edges. Types are
|
|
24
|
+
* erased, so a type-only import must not pull the target into the bundle —
|
|
25
|
+
* and, in particular, must not turn the mutual `import type` references
|
|
26
|
+
* between source files into a circular-import error.
|
|
27
|
+
*/
|
|
28
|
+
function isTypeOnlyImport(declaration: ImportDeclaration): boolean {
|
|
29
|
+
const clause = declaration.importClause;
|
|
30
|
+
if (!clause) return false;
|
|
31
|
+
if (clause.isTypeOnly) return true;
|
|
32
|
+
if (clause.name) return false;
|
|
33
|
+
const bindings = clause.namedBindings;
|
|
34
|
+
if (!bindings) return true;
|
|
35
|
+
if (bindings.kind === SyntaxKind.NamespaceImport) return false;
|
|
36
|
+
// `import {} from "..."` is an empty clause but still evaluates the module.
|
|
37
|
+
return bindings.elements.length > 0 && bindings.elements.every((element) => element.isTypeOnly);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** True when an export declaration only re-exports types. */
|
|
41
|
+
function isTypeOnlyExport(declaration: ExportDeclaration): boolean {
|
|
42
|
+
if (declaration.isTypeOnly) return true;
|
|
43
|
+
const clause = declaration.exportClause;
|
|
44
|
+
if (!clause || clause.kind !== SyntaxKind.NamedExports) return false;
|
|
45
|
+
const elements = (clause as NamedExports).elements;
|
|
46
|
+
// `export {} from "..."` is a side-effect re-export, not a type-only one.
|
|
47
|
+
return elements.length > 0 && elements.every((element) => element.isTypeOnly);
|
|
48
|
+
}
|
|
49
|
+
|
|
19
50
|
function moduleSpecifierOf(statement: Statement): string | undefined {
|
|
20
51
|
if (statement.kind === SyntaxKind.ImportDeclaration) {
|
|
21
|
-
|
|
52
|
+
const declaration = statement as ImportDeclaration;
|
|
53
|
+
if (isTypeOnlyImport(declaration)) return undefined;
|
|
54
|
+
return declaration.moduleSpecifier.value;
|
|
22
55
|
}
|
|
23
56
|
if (statement.kind === SyntaxKind.ExportDeclaration) {
|
|
24
|
-
const
|
|
57
|
+
const declaration = statement as ExportDeclaration;
|
|
58
|
+
if (isTypeOnlyExport(declaration)) return undefined;
|
|
59
|
+
const specifier = declaration.moduleSpecifier;
|
|
25
60
|
if (specifier) return specifier.value;
|
|
26
61
|
}
|
|
27
62
|
return undefined;
|
|
@@ -36,15 +71,30 @@ export function loadGraph(
|
|
|
36
71
|
): ModuleRecord[] | undefined {
|
|
37
72
|
const records = new Map<string, ModuleRecord>();
|
|
38
73
|
const order: ModuleRecord[] = [];
|
|
39
|
-
|
|
74
|
+
/* Modules on the current depth-first path, for cycle reporting. A module is
|
|
75
|
+
* added to `records` only after its dependencies finish, so a back edge is
|
|
76
|
+
* still "visiting" when it is reached. */
|
|
77
|
+
const stack: string[] = [];
|
|
40
78
|
let counter = 0;
|
|
41
79
|
let failed = false;
|
|
42
80
|
|
|
43
|
-
const load = (
|
|
81
|
+
const load = (
|
|
82
|
+
path: string,
|
|
83
|
+
origin?: { readonly file: string; readonly statement: Statement },
|
|
84
|
+
): ModuleRecord | undefined => {
|
|
44
85
|
const existing = records.get(path);
|
|
45
86
|
if (existing) return existing;
|
|
46
|
-
if (
|
|
47
|
-
|
|
87
|
+
if (stack.includes(path)) {
|
|
88
|
+
const start = stack.indexOf(path);
|
|
89
|
+
const cycle = [...stack.slice(start), path]
|
|
90
|
+
.map((entry) => relative(dirname(entryPath), entry))
|
|
91
|
+
.join(" -> ");
|
|
92
|
+
diagnostics.error(
|
|
93
|
+
DiagnosticCode.CircularDependency,
|
|
94
|
+
`Circular import detected: ${cycle}`,
|
|
95
|
+
origin?.statement,
|
|
96
|
+
origin?.file,
|
|
97
|
+
);
|
|
48
98
|
failed = true;
|
|
49
99
|
return undefined;
|
|
50
100
|
}
|
|
@@ -53,7 +103,7 @@ export function loadGraph(
|
|
|
53
103
|
failed = true;
|
|
54
104
|
return undefined;
|
|
55
105
|
}
|
|
56
|
-
|
|
106
|
+
stack.push(path);
|
|
57
107
|
const raw = sourceTextBytes(readFileSync(path, "utf8"));
|
|
58
108
|
/* An extension may rewrite an imported asset (e.g. `.html`) into a TS
|
|
59
109
|
* module before it is parsed. The core only sees the transformed text. */
|
|
@@ -68,7 +118,7 @@ export function loadGraph(
|
|
|
68
118
|
error instanceof Error ? error.message : String(error),
|
|
69
119
|
);
|
|
70
120
|
failed = true;
|
|
71
|
-
|
|
121
|
+
stack.pop();
|
|
72
122
|
return undefined;
|
|
73
123
|
}
|
|
74
124
|
}
|
|
@@ -90,7 +140,6 @@ export function loadGraph(
|
|
|
90
140
|
// `require` / `module` / `exports` are only honoured inside `node_modules`,
|
|
91
141
|
// so user code keeps its ESM-only diagnostic.
|
|
92
142
|
record.commonjs = isNodeModulesPath(path) && usesCommonJS(bindResult);
|
|
93
|
-
records.set(path, record);
|
|
94
143
|
|
|
95
144
|
for (const statement of sourceFile.statements) {
|
|
96
145
|
const specifier = moduleSpecifierOf(statement);
|
|
@@ -107,7 +156,7 @@ export function loadGraph(
|
|
|
107
156
|
failed = true;
|
|
108
157
|
continue;
|
|
109
158
|
}
|
|
110
|
-
load(dependency.path);
|
|
159
|
+
load(dependency.path, { file: path, statement });
|
|
111
160
|
}
|
|
112
161
|
|
|
113
162
|
// A CommonJS module's `require("...")` calls are dynamic import edges: the
|
|
@@ -118,7 +167,8 @@ export function loadGraph(
|
|
|
118
167
|
if (dependency.kind === "file") load(dependency.path);
|
|
119
168
|
}
|
|
120
169
|
}
|
|
121
|
-
|
|
170
|
+
stack.pop();
|
|
171
|
+
records.set(path, record);
|
|
122
172
|
order.push(record);
|
|
123
173
|
return record;
|
|
124
174
|
};
|
|
@@ -77,8 +77,10 @@ export function bundleModules(
|
|
|
77
77
|
for (const statement of record.sourceFile.statements) {
|
|
78
78
|
if (statement.kind === SyntaxKind.ExportDeclaration) {
|
|
79
79
|
const declaration = statement as ExportDeclaration;
|
|
80
|
+
if (declaration.isTypeOnly) continue;
|
|
80
81
|
if (declaration.exportClause && declaration.exportClause.kind === SyntaxKind.NamedExports) {
|
|
81
82
|
for (const specifier of declaration.exportClause.elements) {
|
|
83
|
+
if (specifier.isTypeOnly) continue;
|
|
82
84
|
const localName = specifier.propertyName?.text ?? specifier.name.text;
|
|
83
85
|
const exportedName = specifier.name.text;
|
|
84
86
|
if (declaration.moduleSpecifier) {
|
|
@@ -144,7 +146,7 @@ export function bundleModules(
|
|
|
144
146
|
const declaration = statement as ImportDeclaration;
|
|
145
147
|
const dependency = dependencyOf(record, declaration.moduleSpecifier.value);
|
|
146
148
|
const clause = declaration.importClause;
|
|
147
|
-
if (!clause || !dependency) continue;
|
|
149
|
+
if (!clause || clause.isTypeOnly || !dependency) continue;
|
|
148
150
|
if (clause.name) {
|
|
149
151
|
const target = dependency.exports.get("default") ?? dependency.exports.get("default");
|
|
150
152
|
const local = scope.symbols.get(clause.name.text);
|
|
@@ -153,6 +155,7 @@ export function bundleModules(
|
|
|
153
155
|
const bindings = clause.namedBindings;
|
|
154
156
|
if (bindings && bindings.kind === SyntaxKind.NamedImports) {
|
|
155
157
|
for (const specifier of bindings.elements) {
|
|
158
|
+
if (specifier.isTypeOnly) continue;
|
|
156
159
|
const importedName = specifier.propertyName?.text ?? specifier.name.text;
|
|
157
160
|
const target = dependency.exports.get(importedName);
|
|
158
161
|
const local = scope.symbols.get(specifier.name.text);
|