@scriptc/compiler 0.0.35 → 0.0.36
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/ambient/scriptc-node-fallback.d.ts +7 -6
- package/dist/backend/build-cache.d.ts +44 -0
- package/dist/backend/build-cache.js +241 -0
- package/dist/backend/build-cache.js.map +1 -0
- package/dist/backend/{emission/emit-async.d.ts → c/async.d.ts} +21 -30
- package/dist/backend/{emission/emit-async.js → c/async.js} +270 -286
- package/dist/backend/c/async.js.map +1 -0
- package/dist/backend/{emission/emitter.d.ts → c/c-emitter.d.ts} +6 -23
- package/dist/backend/{emission/emitter.js → c/c-emitter.js} +53 -107
- package/dist/backend/c/c-emitter.js.map +1 -0
- package/dist/backend/c/exprs.d.ts +8 -0
- package/dist/backend/c/exprs.js +7913 -0
- package/dist/backend/c/exprs.js.map +1 -0
- package/dist/backend/{emission/emit-island.d.ts → c/island.d.ts} +5 -5
- package/dist/backend/{emission/emit-island.js → c/island.js} +24 -22
- package/dist/backend/c/island.js.map +1 -0
- package/dist/backend/{emission → c}/may-throw.d.ts +1 -1
- package/dist/backend/{emission → c}/may-throw.js +1 -1
- package/dist/backend/c/may-throw.js.map +1 -0
- package/dist/backend/{emission/emit-shapes.d.ts → c/shapes.d.ts} +19 -19
- package/dist/backend/{emission/emit-shapes.js → c/shapes.js} +78 -87
- package/dist/backend/c/shapes.js.map +1 -0
- package/dist/backend/{emission/emit-stmts.d.ts → c/stmts.d.ts} +12 -12
- package/dist/backend/{emission/emit-stmts.js → c/stmts.js} +377 -343
- package/dist/backend/c/stmts.js.map +1 -0
- package/dist/backend/{emission/emit-types.d.ts → c/types.d.ts} +1 -1
- package/dist/backend/{emission/emit-types.js → c/types.js} +42 -286
- package/dist/backend/c/types.js.map +1 -0
- package/dist/backend/c/types.test.js +25 -0
- package/dist/backend/c/types.test.js.map +1 -0
- package/dist/backend/{emission/emit-walkers.d.ts → c/walkers.d.ts} +19 -41
- package/dist/backend/{emission/emit-walkers.js → c/walkers.js} +238 -298
- package/dist/backend/c/walkers.js.map +1 -0
- package/dist/backend/ffi-callbacks.d.ts +1 -1
- package/dist/backend/ffi-callbacks.js +4 -3
- package/dist/backend/ffi-callbacks.js.map +1 -1
- package/dist/backend/{library-identity.d.ts → library-identity-markers.d.ts} +0 -4
- package/dist/backend/{library-identity.js → library-identity-markers.js} +10 -9
- package/dist/backend/library-identity-markers.js.map +1 -0
- package/dist/backend/llvm/blocks.d.ts +4 -0
- package/dist/backend/llvm/blocks.js +29 -0
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +2 -19
- package/dist/backend/llvm/classes.js +20 -52
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +4 -0
- package/dist/backend/llvm/common.js +27 -0
- package/dist/backend/llvm/common.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +3 -8
- package/dist/backend/llvm/dyn.js +152 -224
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +4 -1
- package/dist/backend/llvm/emitter.js +514 -9981
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-async.d.ts +4 -0
- package/dist/backend/llvm/expr-async.js +726 -0
- package/dist/backend/llvm/expr-async.js.map +1 -0
- package/dist/backend/llvm/expr-bytes.d.ts +13 -0
- package/dist/backend/llvm/expr-bytes.js +456 -0
- package/dist/backend/llvm/expr-bytes.js.map +1 -0
- package/dist/backend/llvm/expr-callbacks.d.ts +22 -0
- package/dist/backend/llvm/expr-callbacks.js +520 -0
- package/dist/backend/llvm/expr-callbacks.js.map +1 -0
- package/dist/backend/llvm/expr-calls.d.ts +2 -0
- package/dist/backend/llvm/expr-calls.js +618 -0
- package/dist/backend/llvm/expr-calls.js.map +1 -0
- package/dist/backend/llvm/expr-containers.d.ts +25 -0
- package/dist/backend/llvm/expr-containers.js +623 -0
- package/dist/backend/llvm/expr-containers.js.map +1 -0
- package/dist/backend/llvm/expr-context.d.ts +255 -0
- package/dist/backend/llvm/expr-context.js +2 -0
- package/dist/backend/llvm/expr-context.js.map +1 -0
- package/dist/backend/llvm/expr-control.d.ts +2 -0
- package/dist/backend/llvm/expr-control.js +473 -0
- package/dist/backend/llvm/expr-control.js.map +1 -0
- package/dist/backend/llvm/expr-dispatch.d.ts +4 -0
- package/dist/backend/llvm/expr-dispatch.js +151 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -0
- package/dist/backend/llvm/expr-dynamic.d.ts +2 -0
- package/dist/backend/llvm/expr-dynamic.js +810 -0
- package/dist/backend/llvm/expr-dynamic.js.map +1 -0
- package/dist/backend/llvm/expr-island.d.ts +15 -0
- package/dist/backend/llvm/expr-island.js +690 -0
- package/dist/backend/llvm/expr-island.js.map +1 -0
- package/dist/backend/llvm/expr-primitives.d.ts +6 -0
- package/dist/backend/llvm/expr-primitives.js +622 -0
- package/dist/backend/llvm/expr-primitives.js.map +1 -0
- package/dist/backend/llvm/expr-records.d.ts +9 -0
- package/dist/backend/llvm/expr-records.js +299 -0
- package/dist/backend/llvm/expr-records.js.map +1 -0
- package/dist/backend/llvm/expr-stream-bridges.d.ts +13 -0
- package/dist/backend/llvm/expr-stream-bridges.js +396 -0
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -0
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +12 -0
- package/dist/backend/llvm/expr-stream-callbacks.js +360 -0
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -0
- package/dist/backend/llvm/lib-dispatch.d.ts +5 -0
- package/dist/backend/llvm/lib-dispatch.js +267 -0
- package/dist/backend/llvm/lib-dispatch.js.map +1 -0
- package/dist/backend/llvm/lib-filesystem.d.ts +6 -0
- package/dist/backend/llvm/lib-filesystem.js +594 -0
- package/dist/backend/llvm/lib-filesystem.js.map +1 -0
- package/dist/backend/llvm/lib-network.d.ts +2 -0
- package/dist/backend/llvm/lib-network.js +429 -0
- package/dist/backend/llvm/lib-network.js.map +1 -0
- package/dist/backend/llvm/lib-process.d.ts +5 -0
- package/dist/backend/llvm/lib-process.js +585 -0
- package/dist/backend/llvm/lib-process.js.map +1 -0
- package/dist/backend/llvm/lib-shared.d.ts +6 -0
- package/dist/backend/llvm/lib-shared.js +687 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -0
- package/dist/backend/llvm/lib-stream.d.ts +2 -0
- package/dist/backend/llvm/lib-stream.js +470 -0
- package/dist/backend/llvm/lib-stream.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +12 -2
- package/dist/backend/llvm/shapes.js +66 -307
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +52 -0
- package/dist/backend/llvm/shapes.test.js.map +1 -0
- package/dist/backend/llvm/unsupported.d.ts +1 -1
- package/dist/backend/llvm/walkers.d.ts +2 -3
- package/dist/backend/llvm/walkers.js +164 -218
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +38 -0
- package/dist/backend/native-codegen.js +261 -0
- package/dist/backend/native-codegen.js.map +1 -0
- package/dist/backend/native-codegen.test.js +188 -0
- package/dist/backend/native-codegen.test.js.map +1 -0
- package/dist/backend/native-link-info.d.ts +96 -0
- package/dist/backend/native-link-info.js +219 -0
- package/dist/backend/native-link-info.js.map +1 -0
- package/dist/backend/native-link-info.test.d.ts +1 -0
- package/dist/backend/native-link-info.test.js +134 -0
- package/dist/backend/native-link-info.test.js.map +1 -0
- package/dist/backend/{cc.d.ts → native-toolchain.d.ts} +54 -34
- package/dist/backend/{cc.js → native-toolchain.js} +231 -810
- package/dist/backend/native-toolchain.js.map +1 -0
- package/dist/backend/native-toolchain.test.d.ts +1 -0
- package/dist/backend/{cc-cache.test.js → native-toolchain.test.js} +214 -6
- package/dist/backend/native-toolchain.test.js.map +1 -0
- package/dist/backend/object-localize.js +1 -1
- package/dist/backend/runtime-abi.d.ts +10 -0
- package/dist/backend/runtime-abi.js +11 -0
- package/dist/backend/runtime-abi.js.map +1 -0
- package/dist/backend/runtime-pack.d.ts +137 -0
- package/dist/backend/runtime-pack.js +400 -0
- package/dist/backend/runtime-pack.js.map +1 -0
- package/dist/backend/runtime-pack.test.d.ts +1 -0
- package/dist/backend/runtime-pack.test.js +438 -0
- package/dist/backend/runtime-pack.test.js.map +1 -0
- package/dist/backend/targets.d.ts +30 -0
- package/dist/backend/targets.js +46 -0
- package/dist/backend/targets.js.map +1 -0
- package/dist/backend/targets.test.d.ts +1 -0
- package/dist/backend/targets.test.js +19 -0
- package/dist/backend/targets.test.js.map +1 -0
- package/dist/backend/vendor-archives.d.ts +41 -0
- package/dist/backend/vendor-archives.js +462 -0
- package/dist/backend/vendor-archives.js.map +1 -0
- package/dist/compat/fetch-profile.d.ts +0 -1
- package/dist/compat/fetch-profile.js +0 -1
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/coverage/report.js +3 -3
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/surface-manifest.js +25 -32
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +11 -12
- package/dist/diagnostics/diagnostic.js +19 -17
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/render.d.ts +1 -1
- package/dist/diagnostics/render.js +1 -1
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +9 -0
- package/dist/errors.js.map +1 -0
- package/dist/executable/{early-cache.d.ts → executable-cache.d.ts} +2 -2
- package/dist/executable/{early-cache.js → executable-cache.js} +36 -98
- package/dist/executable/executable-cache.js.map +1 -0
- package/dist/executable/executable-cache.test.d.ts +1 -0
- package/dist/executable/{early-cache.test.js → executable-cache.test.js} +3 -3
- package/dist/executable/executable-cache.test.js.map +1 -0
- package/dist/ffi/{profile.js → ffi-manifest.js} +1 -1
- package/dist/ffi/ffi-manifest.js.map +1 -0
- package/dist/frontend/builtin-modules.d.ts +21 -0
- package/dist/frontend/builtin-modules.js +82 -0
- package/dist/frontend/builtin-modules.js.map +1 -0
- package/dist/frontend/cjs-lexer.d.ts +7 -0
- package/dist/frontend/cjs-lexer.js +15 -17
- package/dist/frontend/cjs-lexer.js.map +1 -1
- package/dist/frontend/dts-paths.d.ts +26 -0
- package/dist/frontend/dts-paths.js +41 -0
- package/dist/frontend/dts-paths.js.map +1 -0
- package/dist/frontend/input-tracker.d.ts +0 -2
- package/dist/frontend/input-tracker.js +1 -4
- package/dist/frontend/input-tracker.js.map +1 -1
- package/dist/frontend/lib-contract.d.ts +1 -5
- package/dist/frontend/lib-contract.js +1 -1
- package/dist/frontend/lib-contract.js.map +1 -1
- package/dist/frontend/lib-exports.d.ts +1 -1
- package/dist/frontend/lowering/call-position.d.ts +4 -0
- package/dist/frontend/lowering/call-position.js +7 -0
- package/dist/frontend/lowering/call-position.js.map +1 -0
- package/dist/frontend/lowering/callback-arg.d.ts +20 -0
- package/dist/frontend/lowering/callback-arg.js +44 -0
- package/dist/frontend/lowering/callback-arg.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.d.ts +1 -1
- package/dist/frontend/lowering/lib-boundary.js +34 -34
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.d.ts +3 -3
- package/dist/frontend/lowering/lower-assert.js +214 -241
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +74 -146
- package/dist/frontend/lowering/lower-builtins.js +1124 -1232
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +56 -188
- package/dist/frontend/lowering/lower-calls.js +1397 -1492
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +62 -125
- package/dist/frontend/lowering/lower-classes.js +832 -866
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-comptime.d.ts +5 -12
- package/dist/frontend/lowering/lower-comptime.js +32 -31
- package/dist/frontend/lowering/lower-comptime.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +35 -135
- package/dist/frontend/lowering/lower-containers.js +1384 -1700
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.d.ts +3 -7
- package/dist/frontend/lowering/lower-dgram.js +97 -111
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-enums.d.ts +4 -4
- package/dist/frontend/lowering/lower-enums.js +30 -30
- package/dist/frontend/lowering/lower-enums.js.map +1 -1
- package/dist/frontend/lowering/{lower-emitter.d.ts → lower-event-emitter.d.ts} +7 -18
- package/dist/frontend/lowering/{lower-emitter.js → lower-event-emitter.js} +172 -174
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -0
- package/dist/frontend/lowering/lower-expando.d.ts +5 -5
- package/dist/frontend/lowering/lower-expando.js +40 -40
- package/dist/frontend/lowering/lower-expando.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +56 -264
- package/dist/frontend/lowering/lower-exprs.js +1624 -1696
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +6 -6
- package/dist/frontend/lowering/lower-generators.js +73 -72
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +5 -17
- package/dist/frontend/lowering/lower-inspect.js +236 -238
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +34 -45
- package/dist/frontend/lowering/lower-island.js +437 -508
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-mixins.d.ts +7 -10
- package/dist/frontend/lowering/lower-mixins.js +85 -85
- package/dist/frontend/lowering/lower-mixins.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +12 -18
- package/dist/frontend/lowering/lower-modules.js +284 -283
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +23 -49
- package/dist/frontend/lowering/lower-namespaces.js +123 -115
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +18 -25
- package/dist/frontend/lowering/lower-server.js +899 -899
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +30 -149
- package/dist/frontend/lowering/lower-stmts.js +1175 -1228
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +12 -12
- package/dist/frontend/lowering/lower-stream.js +300 -301
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lower-test.d.ts +5 -5
- package/dist/frontend/lowering/lower-test.js +82 -82
- package/dist/frontend/lowering/lower-test.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +60 -20
- package/dist/frontend/lowering/lowerer.js +191 -117
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/pairs-snapshot.d.ts +11 -0
- package/dist/frontend/lowering/pairs-snapshot.js +85 -0
- package/dist/frontend/lowering/pairs-snapshot.js.map +1 -0
- package/dist/frontend/lowering/static-this.d.ts +6 -0
- package/dist/frontend/lowering/static-this.js +24 -0
- package/dist/frontend/lowering/static-this.js.map +1 -0
- package/dist/frontend/lowering/surfaces.d.ts +14 -33
- package/dist/frontend/lowering/surfaces.js +63 -63
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm-static-rewrite.js +6 -28
- package/dist/frontend/npm-static-rewrite.js.map +1 -1
- package/dist/frontend/npm-static.d.ts +0 -10
- package/dist/frontend/npm-static.js +4 -7
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +0 -24
- package/dist/frontend/npm.js +11 -85
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/program.d.ts +3 -1
- package/dist/frontend/program.js +9 -4
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/provenance-registry.d.ts +0 -2
- package/dist/frontend/provenance-registry.js +0 -10
- package/dist/frontend/provenance-registry.js.map +1 -1
- package/dist/frontend/provenance.js +4 -7
- package/dist/frontend/provenance.js.map +1 -1
- package/dist/frontend/resolve.d.ts +7 -2
- package/dist/frontend/resolve.js +12 -17
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/resolve.test.d.ts +1 -0
- package/dist/frontend/resolve.test.js +29 -0
- package/dist/frontend/resolve.test.js.map +1 -0
- package/dist/frontend/ts7/adapter.d.ts +2 -2
- package/dist/frontend/ts7/adapter.js +1 -1
- package/dist/frontend/ts7/adapter.js.map +1 -1
- package/dist/frontend/ts7/checker.js +2 -36
- package/dist/frontend/ts7/checker.js.map +1 -1
- package/dist/frontend/ts7/enums.js +2 -1
- package/dist/frontend/ts7/enums.js.map +1 -1
- package/dist/frontend/ts7/{program.js → program-adapter.js} +7 -6
- package/dist/frontend/ts7/program-adapter.js.map +1 -0
- package/dist/frontend/ts7/world-check.d.ts +1 -3
- package/dist/frontend/ts7/world-check.js +3 -1
- package/dist/frontend/ts7/world-check.js.map +1 -1
- package/dist/frontend/tsc-codes.d.ts +8 -0
- package/dist/frontend/tsc-codes.js +109 -0
- package/dist/frontend/tsc-codes.js.map +1 -0
- package/dist/frontend/{types.d.ts → type-mapper.d.ts} +2 -25
- package/dist/frontend/{types.js → type-mapper.js} +12 -11
- package/dist/frontend/type-mapper.js.map +1 -0
- package/dist/frontend/workspace-registry.d.ts +26 -0
- package/dist/frontend/workspace-registry.js +71 -0
- package/dist/frontend/workspace-registry.js.map +1 -0
- package/dist/index.d.ts +112 -30
- package/dist/index.js +512 -126
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +37 -0
- package/dist/ir/analysis.js +118 -0
- package/dist/ir/analysis.js.map +1 -0
- package/dist/ir/analysis.test.d.ts +1 -0
- package/dist/ir/analysis.test.js +21 -0
- package/dist/ir/analysis.test.js.map +1 -0
- package/dist/ir/build.d.ts +9 -0
- package/dist/ir/build.js +33 -0
- package/dist/ir/build.js.map +1 -0
- package/dist/ir/integer-loops.d.ts +1 -1
- package/dist/ir/{nodes.d.ts → ir.d.ts} +54 -26
- package/dist/ir/{nodes.js → ir.js} +145 -141
- package/dist/ir/ir.js.map +1 -0
- package/dist/ir/ir.test.d.ts +1 -0
- package/dist/ir/ir.test.js +17 -0
- package/dist/ir/ir.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +2 -1
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/validate.d.ts +1 -1
- package/dist/ir/validate.js +10 -5
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/cache-primitives.d.ts +24 -0
- package/dist/library/cache-primitives.js +83 -0
- package/dist/library/cache-primitives.js.map +1 -0
- package/dist/library/cache-reset.test.d.ts +1 -0
- package/dist/library/cache-reset.test.js +47 -0
- package/dist/library/cache-reset.test.js.map +1 -0
- package/dist/library/{implementation-identity.js → compiler-self-identity.js} +1 -1
- package/dist/library/compiler-self-identity.js.map +1 -0
- package/dist/library/fence-eval.d.ts +3 -1
- package/dist/library/fence-eval.js +5 -1
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/int-infer.d.ts +1 -36
- package/dist/library/int-infer.js +17 -17
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/{early-cache.d.ts → library-cache.d.ts} +1 -1
- package/dist/library/{early-cache.js → library-cache.js} +34 -89
- package/dist/library/library-cache.js.map +1 -0
- package/dist/library/library-cache.test.d.ts +1 -0
- package/dist/library/{early-cache.test.js → library-cache.test.js} +2 -2
- package/dist/library/library-cache.test.js.map +1 -0
- package/dist/library/{profile.d.ts → library-profile.d.ts} +4 -7
- package/dist/library/{profile.js → library-profile.js} +18 -11
- package/dist/library/library-profile.js.map +1 -0
- package/dist/library/semantic-source.js +2 -1
- package/dist/library/semantic-source.js.map +1 -1
- package/dist/library/sidecar.d.ts +5 -2
- package/dist/library/sidecar.js +11 -5
- package/dist/library/sidecar.js.map +1 -1
- package/dist/startup-cache.d.ts +3 -3
- package/dist/startup-cache.js +2 -2
- package/dist/startup-cache.js.map +1 -1
- package/package.json +6 -2
- package/surface-manifest.json +1 -1
- package/dist/backend/cc-cache.test.js.map +0 -1
- package/dist/backend/cc.js.map +0 -1
- package/dist/backend/emission/emit-async.js.map +0 -1
- package/dist/backend/emission/emit-exprs.d.ts +0 -13
- package/dist/backend/emission/emit-exprs.js +0 -7407
- package/dist/backend/emission/emit-exprs.js.map +0 -1
- package/dist/backend/emission/emit-island.js.map +0 -1
- package/dist/backend/emission/emit-shapes.js.map +0 -1
- package/dist/backend/emission/emit-stmts.js.map +0 -1
- package/dist/backend/emission/emit-types.js.map +0 -1
- package/dist/backend/emission/emit-walkers.js.map +0 -1
- package/dist/backend/emission/emitter.js.map +0 -1
- package/dist/backend/emission/may-throw.js.map +0 -1
- package/dist/backend/library-identity.js.map +0 -1
- package/dist/executable/early-cache.js.map +0 -1
- package/dist/executable/early-cache.test.js.map +0 -1
- package/dist/ffi/profile.js.map +0 -1
- package/dist/frontend/lowering/lower-emitter.js.map +0 -1
- package/dist/frontend/shared.d.ts +0 -82
- package/dist/frontend/shared.js +0 -308
- package/dist/frontend/shared.js.map +0 -1
- package/dist/frontend/ts7/program.js.map +0 -1
- package/dist/frontend/types.js.map +0 -1
- package/dist/ir/nodes.js.map +0 -1
- package/dist/library/early-cache.js.map +0 -1
- package/dist/library/early-cache.test.js.map +0 -1
- package/dist/library/implementation-identity.js.map +0 -1
- package/dist/library/profile.js.map +0 -1
- /package/dist/backend/{cc-cache.test.d.ts → c/types.test.d.ts} +0 -0
- /package/dist/{executable/early-cache.test.d.ts → backend/llvm/shapes.test.d.ts} +0 -0
- /package/dist/{library/early-cache.test.d.ts → backend/native-codegen.test.d.ts} +0 -0
- /package/dist/ffi/{profile.d.ts → ffi-manifest.d.ts} +0 -0
- /package/dist/frontend/ts7/{program.d.ts → program-adapter.d.ts} +0 -0
- /package/dist/library/{implementation-identity.d.ts → compiler-self-identity.d.ts} +0 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { InternalCompilerError } from "../../errors.js";
|
|
1
2
|
/* The node:util inspect/format lowering (a spoke module like
|
|
2
3
|
* lower-assert.ts): STATIC util.inspect — one synthesized traversal
|
|
3
4
|
* helper per argument type (the deepStrictEqual precedent, interned per
|
|
@@ -35,15 +36,13 @@
|
|
|
35
36
|
* 36's existing stance). */
|
|
36
37
|
import * as ts from "../ts7/adapter.js";
|
|
37
38
|
import { isJsSourceFile } from "../program.js";
|
|
38
|
-
import { BOOL, DYN, F64, RUNTIME_ERROR_CLASSES, STRING, canConvertToDyn, canDynCheckTo, shapeHasAccessorSlots, typeKey } from "../../ir/
|
|
39
|
+
import { BOOL, DYN, F64, RUNTIME_ERROR_CLASSES, STRING, canConvertToDyn, canDynCheckTo, shapeHasAccessorSlots, typeKey } from "../../ir/ir.js";
|
|
39
40
|
import { pureReemittable } from "./lower-exprs.js";
|
|
41
|
+
import { boolLit, numLit, strLit, varRef } from "../../ir/build.js";
|
|
40
42
|
/* ── IR construction shorthand ───────────────────────────────────────── */
|
|
41
|
-
const str = (value, loc) => ({ kind: "strLit", value, type: STRING, loc });
|
|
42
|
-
const num = (value, loc) => ({ kind: "numLit", value, type: F64, loc });
|
|
43
|
-
const boolLit = (value, loc) => ({ kind: "boolLit", value, type: BOOL, loc });
|
|
44
43
|
function concatAll(parts, loc) {
|
|
45
44
|
if (parts.length === 0)
|
|
46
|
-
return
|
|
45
|
+
return strLit("", loc);
|
|
47
46
|
let out = parts[0];
|
|
48
47
|
for (let i = 1; i < parts.length; i++) {
|
|
49
48
|
out = { kind: "strConcat", left: out, right: parts[i], type: STRING, loc };
|
|
@@ -54,7 +53,7 @@ function concatAll(parts, loc) {
|
|
|
54
53
|
/** strEscape's quote ladder over a COMPILE-TIME string (record field
|
|
55
54
|
* names, format-string chunks never pass through here — only keys).
|
|
56
55
|
* Mirrors scr_inspect.c's insp_quote_into byte-for-byte. */
|
|
57
|
-
|
|
56
|
+
function inspectQuote(s) {
|
|
58
57
|
const hasSingle = s.includes("'");
|
|
59
58
|
const quote = !hasSingle ? "'" : !s.includes('"') ? '"' : !s.includes("`") && !s.includes("${") ? "`" : "'";
|
|
60
59
|
let body = "";
|
|
@@ -111,15 +110,15 @@ function errorRenderable(info) {
|
|
|
111
110
|
return false;
|
|
112
111
|
return info.subclasses.every((s) => errorRenderable(s));
|
|
113
112
|
}
|
|
114
|
-
function isErrorClass(
|
|
113
|
+
function isErrorClass(lowerer, className) {
|
|
115
114
|
if (RUNTIME_ERROR_CLASSES.has(className))
|
|
116
115
|
return true;
|
|
117
|
-
return
|
|
116
|
+
return lowerer.isSubclassOf(className, "%Error");
|
|
118
117
|
}
|
|
119
118
|
/** inspUnsupportedReason: the deepUnsupportedReason twin. Fences name the
|
|
120
119
|
* FIRST unsupported constituent. `visiting` terminates recursive shapes
|
|
121
120
|
* and records their existence (the depth-null gate). */
|
|
122
|
-
function inspectSupport(
|
|
121
|
+
function inspectSupport(lowerer, t, visiting, out) {
|
|
123
122
|
switch (t.kind) {
|
|
124
123
|
case "f64":
|
|
125
124
|
case "string":
|
|
@@ -132,7 +131,7 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
132
131
|
case "jsval":
|
|
133
132
|
return null;
|
|
134
133
|
case "array":
|
|
135
|
-
return inspectSupport(
|
|
134
|
+
return inspectSupport(lowerer, t.elem, visiting, out);
|
|
136
135
|
case "bytes":
|
|
137
136
|
return "typed arrays inside composites have no inspect lowering yet (Buffer's <Buffer ..> form vs Uint8Array's is not recorded in the static type here)";
|
|
138
137
|
case "record": {
|
|
@@ -141,7 +140,7 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
141
140
|
return null;
|
|
142
141
|
}
|
|
143
142
|
visiting.add(t.shapeId);
|
|
144
|
-
const shape =
|
|
143
|
+
const shape = lowerer.shapes.get(t.shapeId);
|
|
145
144
|
if (!shape)
|
|
146
145
|
return "this record shape has no inspect lowering";
|
|
147
146
|
// Accessor-carrying shapes: Node prints the accessor names as
|
|
@@ -161,14 +160,14 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
161
160
|
if (shape.fields.length > 0) {
|
|
162
161
|
return "index-signature records with declared fields have no inspect lowering yet (JS interleaves integer keys across the declared and dynamic key sets)";
|
|
163
162
|
}
|
|
164
|
-
const why = inspectSupport(
|
|
163
|
+
const why = inspectSupport(lowerer, shape.indexValue, visiting, out);
|
|
165
164
|
if (why !== null)
|
|
166
165
|
return why;
|
|
167
166
|
visiting.delete(t.shapeId);
|
|
168
167
|
return null;
|
|
169
168
|
}
|
|
170
169
|
for (const f of shape.fields) {
|
|
171
|
-
const why = inspectSupport(
|
|
170
|
+
const why = inspectSupport(lowerer, f.type, visiting, out);
|
|
172
171
|
if (why !== null)
|
|
173
172
|
return why;
|
|
174
173
|
}
|
|
@@ -176,15 +175,15 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
176
175
|
return null;
|
|
177
176
|
}
|
|
178
177
|
case "map": {
|
|
179
|
-
const keyWhy = inspectSupport(
|
|
178
|
+
const keyWhy = inspectSupport(lowerer, t.key, visiting, out);
|
|
180
179
|
if (keyWhy !== null)
|
|
181
180
|
return keyWhy;
|
|
182
|
-
return inspectSupport(
|
|
181
|
+
return inspectSupport(lowerer, t.value, visiting, out);
|
|
183
182
|
}
|
|
184
183
|
case "set":
|
|
185
|
-
return inspectSupport(
|
|
184
|
+
return inspectSupport(lowerer, t.elem, visiting, out);
|
|
186
185
|
case "union": {
|
|
187
|
-
const def =
|
|
186
|
+
const def = lowerer.unions.get(t.unionId);
|
|
188
187
|
if (!def)
|
|
189
188
|
return "this union has no inspect lowering";
|
|
190
189
|
if (visiting.has(t.unionId)) {
|
|
@@ -193,7 +192,7 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
193
192
|
}
|
|
194
193
|
visiting.add(t.unionId);
|
|
195
194
|
for (const arm of def.arms) {
|
|
196
|
-
const why = inspectSupport(
|
|
195
|
+
const why = inspectSupport(lowerer, arm, visiting, out);
|
|
197
196
|
if (why !== null)
|
|
198
197
|
return why;
|
|
199
198
|
}
|
|
@@ -203,10 +202,10 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
203
202
|
case "func":
|
|
204
203
|
return "function values have no inspect lowering (no runtime name exists — Node prints '[Function: name]'; pass the function's declared identifier directly to util.inspect for the baked form)";
|
|
205
204
|
case "object": {
|
|
206
|
-
const info =
|
|
205
|
+
const info = lowerer.classes.get(t.className);
|
|
207
206
|
if (!info)
|
|
208
207
|
return `class '${t.className}' has no inspect lowering`;
|
|
209
|
-
if (isErrorClass(
|
|
208
|
+
if (isErrorClass(lowerer, t.className)) {
|
|
210
209
|
return errorRenderable(info)
|
|
211
210
|
? null
|
|
212
211
|
: "error subclasses with declared fields have no inspect lowering yet (the extra own properties are runtime-dynamic)";
|
|
@@ -224,7 +223,7 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
224
223
|
for (const f of info.def.fields) {
|
|
225
224
|
if (f.name.startsWith("#"))
|
|
226
225
|
continue;
|
|
227
|
-
const why = inspectSupport(
|
|
226
|
+
const why = inspectSupport(lowerer, f.type, visiting, out);
|
|
228
227
|
if (why !== null)
|
|
229
228
|
return why;
|
|
230
229
|
}
|
|
@@ -232,17 +231,17 @@ function inspectSupport(L, t, visiting, out) {
|
|
|
232
231
|
return null;
|
|
233
232
|
}
|
|
234
233
|
default:
|
|
235
|
-
return `'${
|
|
234
|
+
return `'${lowerer.fmt(t)}' values have no inspect lowering`;
|
|
236
235
|
}
|
|
237
236
|
}
|
|
238
237
|
/* ── the per-type rendering expression ───────────────────────────────── */
|
|
239
238
|
/** True when a runtime value of `t` at index expr `v` answers
|
|
240
239
|
* `typeof v === 'number'` — the grid-grouping order flag. */
|
|
241
|
-
function isNumberFlag(
|
|
240
|
+
function isNumberFlag(lowerer, t, v, loc) {
|
|
242
241
|
if (t.kind === "f64")
|
|
243
242
|
return boolLit(true, loc);
|
|
244
243
|
if (t.kind === "union") {
|
|
245
|
-
const def =
|
|
244
|
+
const def = lowerer.unions.get(t.unionId);
|
|
246
245
|
const tag = def ? def.arms.findIndex((a) => a.kind === "f64") : -1;
|
|
247
246
|
if (tag >= 0) {
|
|
248
247
|
return { kind: "unionIsTag", unionId: t.unionId, tag, negated: false, value: v(), type: BOOL, loc };
|
|
@@ -253,7 +252,7 @@ function isNumberFlag(L, t, v, loc) {
|
|
|
253
252
|
/** The rendering of one value of type `t` at runtime depth `recurse`
|
|
254
253
|
* with the depth budget `depth` — a direct scalar libCall or a call of
|
|
255
254
|
* the interned per-type helper. */
|
|
256
|
-
function inspectExpr(
|
|
255
|
+
function inspectExpr(lowerer, t, value, recurse, depth, loc) {
|
|
257
256
|
switch (t.kind) {
|
|
258
257
|
case "f64":
|
|
259
258
|
return { kind: "libCall", fn: "insp.f64", args: [value], type: STRING, loc };
|
|
@@ -262,9 +261,9 @@ function inspectExpr(L, t, value, recurse, depth, loc) {
|
|
|
262
261
|
case "bool":
|
|
263
262
|
return { kind: "toString", operand: value, type: STRING, loc };
|
|
264
263
|
case "undefinedT":
|
|
265
|
-
return
|
|
264
|
+
return strLit("undefined", loc);
|
|
266
265
|
case "nullT":
|
|
267
|
-
return
|
|
266
|
+
return strLit("null", loc);
|
|
268
267
|
case "regex":
|
|
269
268
|
return { kind: "libCall", fn: "insp.regex", args: [value], type: STRING, loc };
|
|
270
269
|
case "symbol":
|
|
@@ -278,12 +277,12 @@ function inspectExpr(L, t, value, recurse, depth, loc) {
|
|
|
278
277
|
case "jsval":
|
|
279
278
|
return { kind: "libCall", fn: "insp.jsval", args: [value, recurse, depth], type: STRING, loc };
|
|
280
279
|
case "object":
|
|
281
|
-
if (isErrorClass(
|
|
280
|
+
if (isErrorClass(lowerer, t.className)) {
|
|
282
281
|
return { kind: "libCall", fn: "insp.error", args: [value, recurse, depth], type: STRING, loc };
|
|
283
282
|
}
|
|
284
|
-
return { kind: "call", callee: inspectHelper(
|
|
283
|
+
return { kind: "call", callee: inspectHelper(lowerer, t, loc), args: [value, recurse, depth], type: STRING, loc };
|
|
285
284
|
default:
|
|
286
|
-
return { kind: "call", callee: inspectHelper(
|
|
285
|
+
return { kind: "call", callee: inspectHelper(lowerer, t, loc), args: [value, recurse, depth], type: STRING, loc };
|
|
287
286
|
}
|
|
288
287
|
}
|
|
289
288
|
/** True when a VALUE of `t` can contain itself — t's type graph reaches t
|
|
@@ -292,14 +291,14 @@ function inspectExpr(L, t, value, recurse, depth, loc) {
|
|
|
292
291
|
* helpers over such types run Node's circular machinery (seen stack +
|
|
293
292
|
* <ref *N>/[Circular *N]); everything acyclic keeps the zero-cost path
|
|
294
293
|
* (a value of an acyclic type can never repeat on its own path). */
|
|
295
|
-
export function typeReachesItself(
|
|
294
|
+
export function typeReachesItself(lowerer, t) {
|
|
296
295
|
const root = typeKey(t);
|
|
297
296
|
const seen = new Set();
|
|
298
297
|
const walk = (u) => {
|
|
299
298
|
const constituents = [];
|
|
300
299
|
switch (u.kind) {
|
|
301
300
|
case "record": {
|
|
302
|
-
const shape =
|
|
301
|
+
const shape = lowerer.shapes.get(u.shapeId);
|
|
303
302
|
if (!shape)
|
|
304
303
|
return false;
|
|
305
304
|
constituents.push(...shape.fields.map((f) => f.type));
|
|
@@ -315,13 +314,13 @@ export function typeReachesItself(L, t) {
|
|
|
315
314
|
constituents.push(u.key, u.value);
|
|
316
315
|
break;
|
|
317
316
|
case "union": {
|
|
318
|
-
const def =
|
|
317
|
+
const def = lowerer.unions.get(u.unionId);
|
|
319
318
|
if (def)
|
|
320
319
|
constituents.push(...def.arms);
|
|
321
320
|
break;
|
|
322
321
|
}
|
|
323
322
|
case "object": {
|
|
324
|
-
const info =
|
|
323
|
+
const info = lowerer.classes.get(u.className);
|
|
325
324
|
if (info)
|
|
326
325
|
constituents.push(...info.def.fields.map((f) => f.type));
|
|
327
326
|
break;
|
|
@@ -350,18 +349,17 @@ export function typeReachesItself(L, t) {
|
|
|
350
349
|
* `[Set]`/`[ClassName]`, and non-empty composites drive the runtime
|
|
351
350
|
* frame engine (begin / entry / end). Registered in the cache BEFORE the
|
|
352
351
|
* body builds, so recursive shapes call themselves by name. */
|
|
353
|
-
function inspectHelper(
|
|
352
|
+
function inspectHelper(lowerer, t, loc) {
|
|
354
353
|
const key = `insp:${typeKey(t)}`;
|
|
355
|
-
const existing =
|
|
354
|
+
const existing = lowerer.inspectHelpers.get(key);
|
|
356
355
|
if (existing)
|
|
357
356
|
return existing;
|
|
358
|
-
const name = `%util.insp.${
|
|
359
|
-
|
|
360
|
-
const
|
|
361
|
-
const
|
|
362
|
-
const
|
|
363
|
-
const
|
|
364
|
-
const rPlus1 = () => ({ kind: "bin", op: "+", left: r(), right: num(1, loc), type: F64, loc });
|
|
357
|
+
const name = `%util.insp.${lowerer.inspectHelpers.size}`;
|
|
358
|
+
lowerer.inspectHelpers.set(key, name);
|
|
359
|
+
const v = () => varRef("v.0", t, loc);
|
|
360
|
+
const r = () => varRef("r.0", F64, loc);
|
|
361
|
+
const d = () => varRef("d.0", F64, loc);
|
|
362
|
+
const rPlus1 = () => ({ kind: "bin", op: "+", left: r(), right: numLit(1, loc), type: F64, loc });
|
|
365
363
|
const ret = (value) => ({ kind: "return", value, loc });
|
|
366
364
|
const exprStmt = (expr) => ({ kind: "exprStmt", expr, loc });
|
|
367
365
|
// CYCLE-CAPABLE composites (typeReachesItself) run Node's circular
|
|
@@ -371,7 +369,7 @@ function inspectHelper(L, t, loc) {
|
|
|
371
369
|
// <ref *N> prefix on values the walk found circular). Acyclic types
|
|
372
370
|
// keep the zero-cost path.
|
|
373
371
|
const onCycle = (t.kind === "record" || t.kind === "array" || t.kind === "map" || t.kind === "object") &&
|
|
374
|
-
typeReachesItself(
|
|
372
|
+
typeReachesItself(lowerer, t);
|
|
375
373
|
const begin = () => [
|
|
376
374
|
exprStmt({ kind: "libCall", fn: "insp.begin", args: [rPlus1()], type: { kind: "void" }, loc }),
|
|
377
375
|
...(onCycle
|
|
@@ -395,11 +393,11 @@ function inspectHelper(L, t, loc) {
|
|
|
395
393
|
const depthGate = (placeholder) => ({
|
|
396
394
|
kind: "if",
|
|
397
395
|
cond: { kind: "bin", op: ">", left: r(), right: d(), type: BOOL, loc },
|
|
398
|
-
then: [ret(
|
|
396
|
+
then: [ret(strLit(placeholder, loc))],
|
|
399
397
|
else_: null,
|
|
400
398
|
loc,
|
|
401
399
|
});
|
|
402
|
-
const child = (elemT, value) => inspectExpr(
|
|
400
|
+
const child = (elemT, value) => inspectExpr(lowerer, elemT, value, rPlus1(), d(), loc);
|
|
403
401
|
const locals = [
|
|
404
402
|
{ id: "v.0", name: "v", type: t, mutable: false },
|
|
405
403
|
{ id: "r.0", name: "r", type: F64, mutable: false },
|
|
@@ -412,28 +410,28 @@ function inspectHelper(L, t, loc) {
|
|
|
412
410
|
const len = () => ({ kind: "arrIntrinsic", method: "length", receiver: v(), args: [], type: F64, loc });
|
|
413
411
|
const at = (i) => ({ kind: "arrayGet", arr: v(), index: i, type: t.elem, loc });
|
|
414
412
|
locals.push({ id: "n.0", name: "n", type: F64, mutable: false }, { id: "s.0", name: "s", type: F64, mutable: false }, { id: "i.0", name: "i", type: F64, mutable: true });
|
|
415
|
-
const n = () =>
|
|
416
|
-
const shown = () =>
|
|
417
|
-
const i = () =>
|
|
418
|
-
const hasMore = () => ({ kind: "bin", op: ">", left: n(), right:
|
|
413
|
+
const n = () => varRef("n.0", F64, loc);
|
|
414
|
+
const shown = () => varRef("s.0", F64, loc);
|
|
415
|
+
const i = () => varRef("i.0", F64, loc);
|
|
416
|
+
const hasMore = () => ({ kind: "bin", op: ">", left: n(), right: numLit(100, loc), type: BOOL, loc });
|
|
419
417
|
body = [
|
|
420
418
|
{ kind: "varDecl", localId: "n.0", init: len(), loc },
|
|
421
419
|
{
|
|
422
420
|
kind: "if",
|
|
423
|
-
cond: { kind: "bin", op: "===", left: n(), right:
|
|
424
|
-
then: [ret(
|
|
421
|
+
cond: { kind: "bin", op: "===", left: n(), right: numLit(0, loc), type: BOOL, loc },
|
|
422
|
+
then: [ret(strLit("[]", loc))],
|
|
425
423
|
else_: null,
|
|
426
424
|
loc,
|
|
427
425
|
},
|
|
428
426
|
depthGate("[Array]"),
|
|
429
|
-
{ kind: "varDecl", localId: "s.0", init: { kind: "ternary", cond: hasMore(), then:
|
|
427
|
+
{ kind: "varDecl", localId: "s.0", init: { kind: "ternary", cond: hasMore(), then: numLit(100, loc), else_: n(), type: F64, loc }, loc },
|
|
430
428
|
...begin(),
|
|
431
429
|
{
|
|
432
430
|
kind: "for",
|
|
433
|
-
init: { kind: "varDecl", localId: "i.0", init:
|
|
431
|
+
init: { kind: "varDecl", localId: "i.0", init: numLit(0, loc), loc },
|
|
434
432
|
cond: { kind: "bin", op: "<", left: i(), right: shown(), type: BOOL, loc },
|
|
435
|
-
update: { kind: "assign", localId: "i.0", value: { kind: "bin", op: "+", left: i(), right:
|
|
436
|
-
body: [entry(child(t.elem, at(i())), isNumberFlag(
|
|
433
|
+
update: { kind: "assign", localId: "i.0", value: { kind: "bin", op: "+", left: i(), right: numLit(1, loc), type: F64, loc }, loc },
|
|
434
|
+
body: [entry(child(t.elem, at(i())), isNumberFlag(lowerer, t.elem, () => at(i()), loc))],
|
|
437
435
|
loc,
|
|
438
436
|
},
|
|
439
437
|
{
|
|
@@ -443,34 +441,34 @@ function inspectHelper(L, t, loc) {
|
|
|
443
441
|
entry({
|
|
444
442
|
kind: "libCall",
|
|
445
443
|
fn: "insp.moreItems",
|
|
446
|
-
args: [{ kind: "bin", op: "-", left: n(), right:
|
|
444
|
+
args: [{ kind: "bin", op: "-", left: n(), right: numLit(100, loc), type: F64, loc }],
|
|
447
445
|
type: STRING,
|
|
448
446
|
loc,
|
|
449
|
-
}, isNumberFlag(
|
|
447
|
+
}, isNumberFlag(lowerer, t.elem, () => at(numLit(100, loc)), loc)),
|
|
450
448
|
],
|
|
451
449
|
else_: null,
|
|
452
450
|
loc,
|
|
453
451
|
},
|
|
454
|
-
ret(end(
|
|
452
|
+
ret(end(strLit("", loc), strLit("[", loc), strLit("]", loc), true, hasMore())),
|
|
455
453
|
];
|
|
456
454
|
break;
|
|
457
455
|
}
|
|
458
456
|
case "record": {
|
|
459
|
-
const shape =
|
|
457
|
+
const shape = lowerer.shapes.get(t.shapeId);
|
|
460
458
|
if (!shape)
|
|
461
|
-
throw new
|
|
459
|
+
throw new InternalCompilerError(`inspect of unknown shape ${t.shapeId}`);
|
|
462
460
|
const get = (field, type) => ({ kind: "recordGet", obj: v(), shapeId: t.shapeId, field, type, loc });
|
|
463
461
|
if (shape.tuple) {
|
|
464
462
|
// Tuples ARE arrays to Node: bracket form, array-extras grouping.
|
|
465
463
|
if (shape.fields.length === 0) {
|
|
466
|
-
body = [ret(
|
|
464
|
+
body = [ret(strLit("[]", loc))];
|
|
467
465
|
break;
|
|
468
466
|
}
|
|
469
467
|
body = [depthGate("[Array]"), ...begin()];
|
|
470
468
|
for (const f of shape.fields) {
|
|
471
|
-
body.push(entry(child(f.type, get(f.name, f.type)), isNumberFlag(
|
|
469
|
+
body.push(entry(child(f.type, get(f.name, f.type)), isNumberFlag(lowerer, f.type, () => get(f.name, f.type), loc)));
|
|
472
470
|
}
|
|
473
|
-
body.push(ret(end(
|
|
471
|
+
body.push(ret(end(strLit("", loc), strLit("[", loc), strLit("]", loc), true, boolLit(false, loc))));
|
|
474
472
|
break;
|
|
475
473
|
}
|
|
476
474
|
if (shape.indexValue && shape.fields.length === 0) {
|
|
@@ -483,18 +481,18 @@ function inspectHelper(L, t, loc) {
|
|
|
483
481
|
const iv = shape.indexValue;
|
|
484
482
|
const ksT = { kind: "array", elem: STRING };
|
|
485
483
|
locals.push({ id: "ks.0", name: "ks", type: ksT, mutable: false }, { id: "n.0", name: "n", type: F64, mutable: false }, { id: "i.0", name: "i", type: F64, mutable: true }, { id: "k.0", name: "k", type: STRING, mutable: false });
|
|
486
|
-
const ks = () =>
|
|
487
|
-
const n = () =>
|
|
488
|
-
const i = () =>
|
|
489
|
-
const k = () =>
|
|
484
|
+
const ks = () => varRef("ks.0", ksT, loc);
|
|
485
|
+
const n = () => varRef("n.0", F64, loc);
|
|
486
|
+
const i = () => varRef("i.0", F64, loc);
|
|
487
|
+
const k = () => varRef("k.0", STRING, loc);
|
|
490
488
|
const keyedRead = () => ({ kind: "recordKeyGet", obj: v(), shapeId: t.shapeId, key: k(), overflowOnly: true, type: iv, loc });
|
|
491
489
|
body = [
|
|
492
490
|
{ kind: "varDecl", localId: "ks.0", init: { kind: "recordOvfKeys", obj: v(), shapeId: t.shapeId, type: ksT, loc }, loc },
|
|
493
491
|
{ kind: "varDecl", localId: "n.0", init: { kind: "arrIntrinsic", method: "length", receiver: ks(), args: [], type: F64, loc }, loc },
|
|
494
492
|
{
|
|
495
493
|
kind: "if",
|
|
496
|
-
cond: { kind: "bin", op: "===", left: n(), right:
|
|
497
|
-
then: [ret(
|
|
494
|
+
cond: { kind: "bin", op: "===", left: n(), right: numLit(0, loc), type: BOOL, loc },
|
|
495
|
+
then: [ret(strLit("{}", loc))],
|
|
498
496
|
else_: null,
|
|
499
497
|
loc,
|
|
500
498
|
},
|
|
@@ -502,32 +500,32 @@ function inspectHelper(L, t, loc) {
|
|
|
502
500
|
...begin(),
|
|
503
501
|
{
|
|
504
502
|
kind: "for",
|
|
505
|
-
init: { kind: "varDecl", localId: "i.0", init:
|
|
503
|
+
init: { kind: "varDecl", localId: "i.0", init: numLit(0, loc), loc },
|
|
506
504
|
cond: { kind: "bin", op: "<", left: i(), right: n(), type: BOOL, loc },
|
|
507
|
-
update: { kind: "assign", localId: "i.0", value: { kind: "bin", op: "+", left: i(), right:
|
|
505
|
+
update: { kind: "assign", localId: "i.0", value: { kind: "bin", op: "+", left: i(), right: numLit(1, loc), type: F64, loc }, loc },
|
|
508
506
|
body: [
|
|
509
507
|
{ kind: "varDecl", localId: "k.0", init: { kind: "arrayGet", arr: ks(), index: i(), type: STRING, loc }, loc },
|
|
510
508
|
entry(concatAll([
|
|
511
509
|
{ kind: "libCall", fn: "insp.key", args: [k()], type: STRING, loc },
|
|
512
|
-
|
|
510
|
+
strLit(": ", loc),
|
|
513
511
|
child(iv, keyedRead()),
|
|
514
512
|
], loc), boolLit(false, loc)),
|
|
515
513
|
],
|
|
516
514
|
loc,
|
|
517
515
|
},
|
|
518
|
-
ret(end(
|
|
516
|
+
ret(end(strLit("", loc), strLit("{", loc), strLit("}", loc), false, boolLit(false, loc))),
|
|
519
517
|
];
|
|
520
518
|
break;
|
|
521
519
|
}
|
|
522
520
|
if (shape.fields.length === 0) {
|
|
523
|
-
body = [ret(
|
|
521
|
+
body = [ret(strLit("{}", loc))];
|
|
524
522
|
break;
|
|
525
523
|
}
|
|
526
524
|
// Object.keys' declared order (SEMANTICS.md 36's stance). Retained
|
|
527
525
|
// reachability can settle this shape after the helper is first
|
|
528
526
|
// interned, so rebuild the field walk once metadata is final.
|
|
529
527
|
rebuildShapeOrderBody = () => {
|
|
530
|
-
const current =
|
|
528
|
+
const current = lowerer.shapes.get(t.shapeId) ?? shape;
|
|
531
529
|
const order = current.declaredOrder ?? current.fields.map((f) => f.name);
|
|
532
530
|
const byName = new Map(current.fields.map((f) => [f.name, f.type]));
|
|
533
531
|
body = [depthGate("[Object]"), ...begin()];
|
|
@@ -535,9 +533,9 @@ function inspectHelper(L, t, loc) {
|
|
|
535
533
|
const ft = byName.get(fname);
|
|
536
534
|
if (!ft)
|
|
537
535
|
continue;
|
|
538
|
-
body.push(entry(concatAll([
|
|
536
|
+
body.push(entry(concatAll([strLit(`${inspectKey(fname)}: `, loc), child(ft, get(fname, ft))], loc), boolLit(false, loc)));
|
|
539
537
|
}
|
|
540
|
-
body.push(ret(end(
|
|
538
|
+
body.push(ret(end(strLit("", loc), strLit("{", loc), strLit("}", loc), false, boolLit(false, loc))));
|
|
541
539
|
};
|
|
542
540
|
rebuildShapeOrderBody();
|
|
543
541
|
break;
|
|
@@ -549,36 +547,36 @@ function inspectHelper(L, t, loc) {
|
|
|
549
547
|
? { kind: "mapIntrinsic", method: method, receiver: v(), args, type, loc }
|
|
550
548
|
: { kind: "setIntrinsic", method: method, receiver: v(), args, type, loc };
|
|
551
549
|
locals.push({ id: "n.0", name: "n", type: F64, mutable: false }, { id: "i.0", name: "i", type: F64, mutable: true }, { id: "c.0", name: "c", type: F64, mutable: true });
|
|
552
|
-
const n = () =>
|
|
553
|
-
const i = () =>
|
|
554
|
-
const c = () =>
|
|
550
|
+
const n = () => varRef("n.0", F64, loc);
|
|
551
|
+
const i = () => varRef("i.0", F64, loc);
|
|
552
|
+
const c = () => varRef("c.0", F64, loc);
|
|
555
553
|
const label = isMap ? "Map" : "Set";
|
|
556
554
|
const keyT = isMap ? t.key : t.elem;
|
|
557
|
-
const hasMore = () => ({ kind: "bin", op: ">", left: n(), right:
|
|
555
|
+
const hasMore = () => ({ kind: "bin", op: ">", left: n(), right: numLit(100, loc), type: BOOL, loc });
|
|
558
556
|
const entryValue = () => {
|
|
559
557
|
const k = child(keyT, mi("iterKey", [i()], keyT));
|
|
560
558
|
if (!isMap)
|
|
561
559
|
return k;
|
|
562
560
|
const valueT = t.value;
|
|
563
|
-
return concatAll([k,
|
|
561
|
+
return concatAll([k, strLit(" => ", loc), child(valueT, mi("iterValue", [i()], valueT))], loc);
|
|
564
562
|
};
|
|
565
563
|
body = [
|
|
566
564
|
{ kind: "varDecl", localId: "n.0", init: mi("size", [], F64), loc },
|
|
567
565
|
{
|
|
568
566
|
kind: "if",
|
|
569
|
-
cond: { kind: "bin", op: "===", left: n(), right:
|
|
570
|
-
then: [ret(
|
|
567
|
+
cond: { kind: "bin", op: "===", left: n(), right: numLit(0, loc), type: BOOL, loc },
|
|
568
|
+
then: [ret(strLit(`${label}(0) {}`, loc))],
|
|
571
569
|
else_: null,
|
|
572
570
|
loc,
|
|
573
571
|
},
|
|
574
572
|
depthGate(`[${label}]`),
|
|
575
573
|
...begin(),
|
|
576
|
-
{ kind: "varDecl", localId: "c.0", init:
|
|
574
|
+
{ kind: "varDecl", localId: "c.0", init: numLit(0, loc), loc },
|
|
577
575
|
{
|
|
578
576
|
kind: "for",
|
|
579
|
-
init: { kind: "varDecl", localId: "i.0", init:
|
|
577
|
+
init: { kind: "varDecl", localId: "i.0", init: numLit(0, loc), loc },
|
|
580
578
|
cond: { kind: "bin", op: "<", left: i(), right: mi("iterCount", [], F64), type: BOOL, loc },
|
|
581
|
-
update: { kind: "assign", localId: "i.0", value: { kind: "bin", op: "+", left: i(), right:
|
|
579
|
+
update: { kind: "assign", localId: "i.0", value: { kind: "bin", op: "+", left: i(), right: numLit(1, loc), type: F64, loc }, loc },
|
|
582
580
|
body: [
|
|
583
581
|
{
|
|
584
582
|
kind: "if",
|
|
@@ -589,13 +587,13 @@ function inspectHelper(L, t, loc) {
|
|
|
589
587
|
},
|
|
590
588
|
{
|
|
591
589
|
kind: "if",
|
|
592
|
-
cond: { kind: "bin", op: "===", left: c(), right:
|
|
590
|
+
cond: { kind: "bin", op: "===", left: c(), right: numLit(100, loc), type: BOOL, loc },
|
|
593
591
|
then: [{ kind: "break", loc }],
|
|
594
592
|
else_: null,
|
|
595
593
|
loc,
|
|
596
594
|
},
|
|
597
595
|
entry(entryValue(), boolLit(false, loc)),
|
|
598
|
-
{ kind: "assign", localId: "c.0", value: { kind: "bin", op: "+", left: c(), right:
|
|
596
|
+
{ kind: "assign", localId: "c.0", value: { kind: "bin", op: "+", left: c(), right: numLit(1, loc), type: F64, loc }, loc },
|
|
599
597
|
],
|
|
600
598
|
loc,
|
|
601
599
|
},
|
|
@@ -606,7 +604,7 @@ function inspectHelper(L, t, loc) {
|
|
|
606
604
|
entry({
|
|
607
605
|
kind: "libCall",
|
|
608
606
|
fn: "insp.moreItems",
|
|
609
|
-
args: [{ kind: "bin", op: "-", left: n(), right:
|
|
607
|
+
args: [{ kind: "bin", op: "-", left: n(), right: numLit(100, loc), type: F64, loc }],
|
|
610
608
|
type: STRING,
|
|
611
609
|
loc,
|
|
612
610
|
}, boolLit(false, loc)),
|
|
@@ -614,14 +612,14 @@ function inspectHelper(L, t, loc) {
|
|
|
614
612
|
else_: null,
|
|
615
613
|
loc,
|
|
616
614
|
},
|
|
617
|
-
ret(end(
|
|
615
|
+
ret(end(strLit("", loc), concatAll([strLit(`${label}(`, loc), { kind: "toString", operand: n(), type: STRING, loc }, strLit(") {", loc)], loc), strLit("}", loc), false, hasMore())),
|
|
618
616
|
];
|
|
619
617
|
break;
|
|
620
618
|
}
|
|
621
619
|
case "union": {
|
|
622
|
-
const def =
|
|
620
|
+
const def = lowerer.unions.get(t.unionId);
|
|
623
621
|
if (!def)
|
|
624
|
-
throw new
|
|
622
|
+
throw new InternalCompilerError(`inspect of unknown union ${t.unionId}`);
|
|
625
623
|
body = [];
|
|
626
624
|
def.arms.forEach((arm, tag) => {
|
|
627
625
|
// The union wrapper is not a nesting level: arms render at the
|
|
@@ -630,18 +628,18 @@ function inspectHelper(L, t, loc) {
|
|
|
630
628
|
body.push({
|
|
631
629
|
kind: "if",
|
|
632
630
|
cond: { kind: "unionIsTag", unionId: t.unionId, tag, negated: false, value: v(), type: BOOL, loc },
|
|
633
|
-
then: [ret(inspectExpr(
|
|
631
|
+
then: [ret(inspectExpr(lowerer, arm, narrowed, r(), d(), loc))],
|
|
634
632
|
else_: null,
|
|
635
633
|
loc,
|
|
636
634
|
});
|
|
637
635
|
});
|
|
638
|
-
body.push(ret(
|
|
636
|
+
body.push(ret(strLit("", loc))); // unreachable: some arm always matches
|
|
639
637
|
break;
|
|
640
638
|
}
|
|
641
639
|
case "object": {
|
|
642
|
-
const info =
|
|
640
|
+
const info = lowerer.classes.get(t.className);
|
|
643
641
|
if (!info)
|
|
644
|
-
throw new
|
|
642
|
+
throw new InternalCompilerError(`inspect of unknown class ${t.className}`);
|
|
645
643
|
// Node prints the class's OWN name — the declaration's, never the
|
|
646
644
|
// IR name's module qualifier (`m0.Timer` is the frontend's spelling
|
|
647
645
|
// for a class declared in a non-entry module).
|
|
@@ -651,7 +649,7 @@ function inspectHelper(L, t, loc) {
|
|
|
651
649
|
// so a class whose only fields are private prints as `C {}`.
|
|
652
650
|
const visible = info.def.fields.filter((f) => !f.name.startsWith("#"));
|
|
653
651
|
if (visible.length === 0) {
|
|
654
|
-
body = [ret(
|
|
652
|
+
body = [ret(strLit(`${display} {}`, loc))];
|
|
655
653
|
break;
|
|
656
654
|
}
|
|
657
655
|
const get = (field, type) => ({ kind: "fieldGet", obj: v(), className: t.className, field, type, loc });
|
|
@@ -670,13 +668,13 @@ function inspectHelper(L, t, loc) {
|
|
|
670
668
|
];
|
|
671
669
|
for (const f of ordered) {
|
|
672
670
|
const key = symNames.has(f.name) ? f.name : inspectKey(f.name);
|
|
673
|
-
body.push(entry(concatAll([
|
|
671
|
+
body.push(entry(concatAll([strLit(`${key}: `, loc), child(f.type, get(f.name, f.type))], loc), boolLit(false, loc)));
|
|
674
672
|
}
|
|
675
|
-
body.push(ret(end(
|
|
673
|
+
body.push(ret(end(strLit("", loc), strLit(`${display} {`, loc), strLit("}", loc), false, boolLit(false, loc))));
|
|
676
674
|
break;
|
|
677
675
|
}
|
|
678
676
|
default:
|
|
679
|
-
throw new
|
|
677
|
+
throw new InternalCompilerError(`inspect helper over unexpected type ${typeKey(t)}`);
|
|
680
678
|
}
|
|
681
679
|
let prependCycleGuard = null;
|
|
682
680
|
if (onCycle) {
|
|
@@ -685,7 +683,7 @@ function inspectHelper(L, t, loc) {
|
|
|
685
683
|
// [Circular *N] and descends no further — Node's formatValue order
|
|
686
684
|
// (a circular target beyond the depth budget still says Circular).
|
|
687
685
|
locals.push({ id: "cc.0", name: "cc", type: F64, mutable: false });
|
|
688
|
-
const cc = () =>
|
|
686
|
+
const cc = () => varRef("cc.0", F64, loc);
|
|
689
687
|
prependCycleGuard = () => {
|
|
690
688
|
body.unshift({
|
|
691
689
|
kind: "varDecl",
|
|
@@ -694,7 +692,7 @@ function inspectHelper(L, t, loc) {
|
|
|
694
692
|
loc,
|
|
695
693
|
}, {
|
|
696
694
|
kind: "if",
|
|
697
|
-
cond: { kind: "bin", op: ">", left: cc(), right:
|
|
695
|
+
cond: { kind: "bin", op: ">", left: cc(), right: numLit(0, loc), type: BOOL, loc },
|
|
698
696
|
then: [ret({ kind: "libCall", fn: "insp.circular", args: [cc()], type: STRING, loc })],
|
|
699
697
|
else_: null,
|
|
700
698
|
loc,
|
|
@@ -715,13 +713,13 @@ function inspectHelper(L, t, loc) {
|
|
|
715
713
|
loc,
|
|
716
714
|
};
|
|
717
715
|
if (rebuildShapeOrderBody !== null) {
|
|
718
|
-
|
|
716
|
+
lowerer.shapeOrderHelperFinalizers.push(() => {
|
|
719
717
|
rebuildShapeOrderBody();
|
|
720
718
|
prependCycleGuard?.();
|
|
721
719
|
fn.body = body;
|
|
722
720
|
});
|
|
723
721
|
}
|
|
724
|
-
|
|
722
|
+
lowerer.liftedFns.push(fn);
|
|
725
723
|
return name;
|
|
726
724
|
}
|
|
727
725
|
/* ── the console/format top-level value rendering ────────────────────── */
|
|
@@ -732,7 +730,7 @@ function inspectHelper(L, t, loc) {
|
|
|
732
730
|
* exactly as inspect at the given depth. Unions dispatch per arm AT
|
|
733
731
|
* RUNTIME through an interned helper, so a string arm stays verbatim
|
|
734
732
|
* while its sibling arms inspect. Callers check inspectSupport first. */
|
|
735
|
-
|
|
733
|
+
function formatValueExpr(lowerer, t, value, depth, loc) {
|
|
736
734
|
switch (t.kind) {
|
|
737
735
|
case "string":
|
|
738
736
|
return value;
|
|
@@ -741,33 +739,33 @@ export function formatValueExpr(L, t, value, depth, loc) {
|
|
|
741
739
|
case "bool":
|
|
742
740
|
return { kind: "toString", operand: value, type: STRING, loc };
|
|
743
741
|
case "undefinedT":
|
|
744
|
-
return
|
|
742
|
+
return strLit("undefined", loc);
|
|
745
743
|
case "nullT":
|
|
746
|
-
return
|
|
744
|
+
return strLit("null", loc);
|
|
747
745
|
case "symbol":
|
|
748
746
|
return { kind: "libCall", fn: "sym.toString", args: [value], type: STRING, loc };
|
|
749
747
|
case "dyn":
|
|
750
|
-
return { kind: "libCall", fn: "insp.dynS", args: [value,
|
|
748
|
+
return { kind: "libCall", fn: "insp.dynS", args: [value, numLit(depth, loc)], type: STRING, loc };
|
|
751
749
|
case "union":
|
|
752
|
-
return { kind: "call", callee: formatUnionHelper(
|
|
750
|
+
return { kind: "call", callee: formatUnionHelper(lowerer, t, depth, loc), args: [value], type: STRING, loc };
|
|
753
751
|
default:
|
|
754
|
-
return inspectExpr(
|
|
752
|
+
return inspectExpr(lowerer, t, value, numLit(0, loc), numLit(depth, loc), loc);
|
|
755
753
|
}
|
|
756
754
|
}
|
|
757
755
|
/** `%util.fmtv.<n>(v): string` — formatValueExpr's runtime dispatch over a
|
|
758
756
|
* union's arms (interned per union + depth, the inspectHelper pattern).
|
|
759
757
|
* The TOP-LEVEL union rule only: nested unions inside composites keep
|
|
760
758
|
* inspect's own rendering, where string arms quote — exactly Node. */
|
|
761
|
-
function formatUnionHelper(
|
|
759
|
+
function formatUnionHelper(lowerer, t, depth, loc) {
|
|
762
760
|
const key = `fmtv:${typeKey(t)}:${depth}`;
|
|
763
|
-
const existing =
|
|
761
|
+
const existing = lowerer.inspectHelpers.get(key);
|
|
764
762
|
if (existing)
|
|
765
763
|
return existing;
|
|
766
|
-
const name = `%util.fmtv.${
|
|
767
|
-
|
|
768
|
-
const def =
|
|
764
|
+
const name = `%util.fmtv.${lowerer.inspectHelpers.size}`;
|
|
765
|
+
lowerer.inspectHelpers.set(key, name);
|
|
766
|
+
const def = lowerer.unions.get(t.unionId);
|
|
769
767
|
if (!def)
|
|
770
|
-
throw new
|
|
768
|
+
throw new InternalCompilerError(`format value over unknown union ${t.unionId}`);
|
|
771
769
|
const v = () => ({ kind: "varRef", localId: "v.0", type: t, loc });
|
|
772
770
|
const body = [];
|
|
773
771
|
def.arms.forEach((arm, tag) => {
|
|
@@ -775,13 +773,13 @@ function formatUnionHelper(L, t, depth, loc) {
|
|
|
775
773
|
body.push({
|
|
776
774
|
kind: "if",
|
|
777
775
|
cond: { kind: "unionIsTag", unionId: t.unionId, tag, negated: false, value: v(), type: BOOL, loc },
|
|
778
|
-
then: [{ kind: "return", value: formatValueExpr(
|
|
776
|
+
then: [{ kind: "return", value: formatValueExpr(lowerer, arm, narrowed, depth, loc), loc }],
|
|
779
777
|
else_: null,
|
|
780
778
|
loc,
|
|
781
779
|
});
|
|
782
780
|
});
|
|
783
|
-
body.push({ kind: "return", value:
|
|
784
|
-
|
|
781
|
+
body.push({ kind: "return", value: strLit("", loc), loc }); // unreachable: some arm always matches
|
|
782
|
+
lowerer.liftedFns.push({
|
|
785
783
|
name,
|
|
786
784
|
params: [{ localId: "v.0", name: "v", type: t }],
|
|
787
785
|
returnType: STRING,
|
|
@@ -797,53 +795,53 @@ function formatUnionHelper(L, t, depth, loc) {
|
|
|
797
795
|
* site): the rendered STRING under Node's console semantics — inspect at
|
|
798
796
|
* the rest-args depth 2 — or the honest fence naming the first
|
|
799
797
|
* unsupported constituent. */
|
|
800
|
-
export function lowerConsoleInspectArg(
|
|
798
|
+
export function lowerConsoleInspectArg(lowerer, node, value, surface, loc) {
|
|
801
799
|
const t = value.type;
|
|
802
800
|
if (t.kind === "undefinedT" || t.kind === "nullT") {
|
|
803
801
|
// The baked text ("undefined"/"null"): the operand is a literal or a
|
|
804
802
|
// pure read, so dropping its evaluation loses nothing. Effectful
|
|
805
803
|
// unit-typed operands keep a fence — a silent skip is banned.
|
|
806
804
|
if (value.kind !== "unitLit" && !pureReemittable(value)) {
|
|
807
|
-
|
|
805
|
+
lowerer.unsupported("SC1090", node, `${surface} of an effectful '${lowerer.fmt(t)}'-typed expression (evaluate it first: const v = ...; ${surface}(v))`);
|
|
808
806
|
}
|
|
809
|
-
return
|
|
807
|
+
return strLit(t.kind === "undefinedT" ? "undefined" : "null", loc);
|
|
810
808
|
}
|
|
811
809
|
if (t.kind === "bytes") {
|
|
812
810
|
// One runtime representation serves Buffer AND Uint8Array; their
|
|
813
811
|
// renderings differ, so the argument's checker type picks — and only
|
|
814
812
|
// Buffer lowers (lowerInspectCall's stance).
|
|
815
|
-
const tname =
|
|
813
|
+
const tname = lowerer.checker.typeToString(lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(node)));
|
|
816
814
|
const isBuffer = tname === "Buffer" || tname === "NonSharedBuffer" || tname.startsWith("Buffer<") || tname.startsWith("NonSharedBuffer<");
|
|
817
815
|
if (t.elem !== "u8" || !isBuffer) {
|
|
818
|
-
|
|
816
|
+
lowerer.unsupported("SC1090", node, `${surface} of '${tname}' values (Buffer's <Buffer ..> form is the lowered typed-array rendering; other typed arrays fence)`);
|
|
819
817
|
}
|
|
820
|
-
return inspectExpr(
|
|
818
|
+
return inspectExpr(lowerer, t, value, numLit(0, loc), numLit(2, loc), loc);
|
|
821
819
|
}
|
|
822
820
|
if (t.kind === "void") {
|
|
823
821
|
// Node prints "undefined" for a void call's result; a void expression
|
|
824
822
|
// is not a value here, so the composition fences with the rewrite.
|
|
825
|
-
|
|
823
|
+
lowerer.unsupported("SC1090", node, `${surface} of a void call result (call it as its own statement, then ${surface}(undefined))`);
|
|
826
824
|
}
|
|
827
825
|
const walk = { recursive: false };
|
|
828
|
-
const reason = inspectSupport(
|
|
826
|
+
const reason = inspectSupport(lowerer, t, new Set(), walk);
|
|
829
827
|
if (reason !== null) {
|
|
830
|
-
|
|
828
|
+
lowerer.unsupported("SC1090", node, `${surface} of '${lowerer.fmt(t)}' values (${reason})`);
|
|
831
829
|
}
|
|
832
|
-
return formatValueExpr(
|
|
830
|
+
return formatValueExpr(lowerer, t, value, 2, loc);
|
|
833
831
|
}
|
|
834
832
|
/* ── the callsite: options, direct function/class names ──────────────── */
|
|
835
833
|
/** The parsed options literal: the resolved depth (numeric; Infinity for
|
|
836
834
|
* `null`), with every non-default knob fenced by name. */
|
|
837
|
-
function parseInspectOptions(
|
|
835
|
+
function parseInspectOptions(lowerer, node, recursive) {
|
|
838
836
|
if (!node || (ts.isIdentifier(node) && node.text === "undefined"))
|
|
839
837
|
return 2;
|
|
840
838
|
if (!ts.isObjectLiteralExpression(node)) {
|
|
841
|
-
|
|
839
|
+
lowerer.noLowering("util.inspect with a non-literal options argument", node, "the options must be an object literal ({ depth, colors: false, ... }) so the knobs resolve at compile time");
|
|
842
840
|
}
|
|
843
841
|
let depth = 2;
|
|
844
842
|
for (const prop of node.properties) {
|
|
845
843
|
if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name)) {
|
|
846
|
-
|
|
844
|
+
lowerer.noLowering("util.inspect options in this form", prop, "plain `key: literal` entries are the lowered options");
|
|
847
845
|
}
|
|
848
846
|
const key = prop.name.text;
|
|
849
847
|
const value = prop.initializer;
|
|
@@ -866,28 +864,28 @@ function parseInspectOptions(L, node, recursive) {
|
|
|
866
864
|
else if (!(ts.isIdentifier(value) && value.text === "undefined")) {
|
|
867
865
|
const n = numeric();
|
|
868
866
|
if (n === null) {
|
|
869
|
-
|
|
867
|
+
lowerer.noLowering("util.inspect with a non-literal depth option", value, "depth must be a numeric literal (or null)");
|
|
870
868
|
}
|
|
871
869
|
depth = n;
|
|
872
870
|
}
|
|
873
871
|
}
|
|
874
872
|
else if (key === "colors") {
|
|
875
873
|
if (value.kind !== ts.SyntaxKind.FalseKeyword) {
|
|
876
|
-
|
|
874
|
+
lowerer.noLowering("util.inspect with colors: true", value, "ANSI styling has no lowering — only colors: false");
|
|
877
875
|
}
|
|
878
876
|
}
|
|
879
877
|
else if (key === "compact") {
|
|
880
878
|
if (numeric() !== 3) {
|
|
881
|
-
|
|
879
|
+
lowerer.noLowering("util.inspect with a non-default compact option", value, "only the default compact: 3 is lowered");
|
|
882
880
|
}
|
|
883
881
|
}
|
|
884
882
|
else if (key === "breakLength") {
|
|
885
883
|
if (numeric() !== 80) {
|
|
886
|
-
|
|
884
|
+
lowerer.noLowering("util.inspect with a non-default breakLength option", value, "only the default breakLength: 80 is lowered");
|
|
887
885
|
}
|
|
888
886
|
}
|
|
889
887
|
else {
|
|
890
|
-
|
|
888
|
+
lowerer.noLowering(`util.inspect with the '${key}' option`, prop, "the lowered options are depth (numeric literal or null), colors: false, compact: 3, and breakLength: 80");
|
|
891
889
|
}
|
|
892
890
|
}
|
|
893
891
|
return depth;
|
|
@@ -896,13 +894,13 @@ function parseInspectOptions(L, node, recursive) {
|
|
|
896
894
|
* naming a declared function or class: the name is compile-time truth,
|
|
897
895
|
* so `[Function: name]` / `[class X extends Y]` bake as literals. Null
|
|
898
896
|
* when the identifier is not such a declaration. */
|
|
899
|
-
function directCallableInspect(
|
|
897
|
+
function directCallableInspect(lowerer, node, loc) {
|
|
900
898
|
if (!ts.isIdentifier(node))
|
|
901
899
|
return null;
|
|
902
|
-
const sym =
|
|
900
|
+
const sym = lowerer.resolveValueSymbol(node);
|
|
903
901
|
if (!sym)
|
|
904
902
|
return null;
|
|
905
|
-
const cls =
|
|
903
|
+
const cls = lowerer.classBySymbol.get(sym) ?? lowerer.builtinErrorInfoOf(sym);
|
|
906
904
|
// A rebindable decorated name is not compile-time truth — the binding
|
|
907
905
|
// holds the decoration result; no literal folds.
|
|
908
906
|
if (cls?.classDecorators?.valueGlobalId !== undefined)
|
|
@@ -910,16 +908,16 @@ function directCallableInspect(L, node, loc) {
|
|
|
910
908
|
if (cls) {
|
|
911
909
|
if (cls.builtinError) {
|
|
912
910
|
// Node's Error constructors are native functions, not classes.
|
|
913
|
-
return
|
|
911
|
+
return strLit(`[Function: ${cls.def.name.replace(/^%/, "")}]`, loc);
|
|
914
912
|
}
|
|
915
913
|
const base = cls.base ? ` extends ${cls.base.def.name.replace(/^%/, "")}` : "";
|
|
916
|
-
return
|
|
914
|
+
return strLit(`[class ${cls.def.name}${base}]`, loc);
|
|
917
915
|
}
|
|
918
|
-
const decl =
|
|
916
|
+
const decl = lowerer.checker.declarationsOf(sym)[0];
|
|
919
917
|
if (!decl)
|
|
920
918
|
return null;
|
|
921
919
|
if (ts.isFunctionDeclaration(decl) && decl.name) {
|
|
922
|
-
return
|
|
920
|
+
return strLit(`[Function: ${decl.name.text}]`, loc);
|
|
923
921
|
}
|
|
924
922
|
if (ts.isVariableDeclaration(decl) &&
|
|
925
923
|
ts.isIdentifier(decl.name) &&
|
|
@@ -928,57 +926,57 @@ function directCallableInspect(L, node, loc) {
|
|
|
928
926
|
// JS name inference: the binding names the function value — unless
|
|
929
927
|
// the function expression carries its OWN name, which wins.
|
|
930
928
|
const own = ts.isFunctionExpression(decl.initializer) ? decl.initializer.name?.text : undefined;
|
|
931
|
-
return
|
|
929
|
+
return strLit(`[Function: ${own ?? decl.name.text}]`, loc);
|
|
932
930
|
}
|
|
933
931
|
return null;
|
|
934
932
|
}
|
|
935
933
|
/** util.inspect(value[, options]) — the spoke's inspect entry. */
|
|
936
|
-
function lowerInspectCall(
|
|
934
|
+
function lowerInspectCall(lowerer, expr, loc) {
|
|
937
935
|
if (expr.arguments.length < 1 || expr.arguments.length > 2) {
|
|
938
|
-
|
|
936
|
+
lowerer.noLowering(`util.inspect with ${expr.arguments.length} arguments`, expr, "the supported forms are inspect(value) and inspect(value, options)");
|
|
939
937
|
}
|
|
940
938
|
const valueNode = expr.arguments[0];
|
|
941
939
|
// Inline function/class literals and direct declared names render as
|
|
942
940
|
// their baked forms; other function-typed values fence below.
|
|
943
|
-
const direct = directCallableInspect(
|
|
941
|
+
const direct = directCallableInspect(lowerer, valueNode, loc);
|
|
944
942
|
if (direct) {
|
|
945
|
-
parseInspectOptions(
|
|
943
|
+
parseInspectOptions(lowerer, expr.arguments[1], false);
|
|
946
944
|
return direct;
|
|
947
945
|
}
|
|
948
946
|
if (ts.isArrowFunction(valueNode) || ts.isFunctionExpression(valueNode)) {
|
|
949
|
-
parseInspectOptions(
|
|
950
|
-
return
|
|
947
|
+
parseInspectOptions(lowerer, expr.arguments[1], false);
|
|
948
|
+
return strLit(valueNode.kind === ts.SyntaxKind.FunctionExpression && valueNode.name ? `[Function: ${valueNode.name.text}]` : "[Function (anonymous)]", loc);
|
|
951
949
|
}
|
|
952
|
-
const value =
|
|
950
|
+
const value = lowerer.lowerExpr(valueNode);
|
|
953
951
|
if (value.type.kind === "bytes") {
|
|
954
952
|
// One runtime representation serves Buffer AND Uint8Array; their
|
|
955
953
|
// renderings differ (<Buffer aa> vs Uint8Array(1) [ 170 ]), so the
|
|
956
954
|
// TOP-LEVEL argument's checker type picks — and only Buffer lowers.
|
|
957
955
|
// Nested bytes fence in inspectSupport (no checker type survives
|
|
958
956
|
// into shapes).
|
|
959
|
-
const tname =
|
|
957
|
+
const tname = lowerer.checker.typeToString(lowerer.checker.getBaseTypeOfLiteralType(lowerer.typeOf(valueNode)));
|
|
960
958
|
const isBuffer = tname === "Buffer" || tname === "NonSharedBuffer" || tname.startsWith("Buffer<") || tname.startsWith("NonSharedBuffer<");
|
|
961
959
|
if (value.type.elem !== "u8" || !isBuffer) {
|
|
962
|
-
|
|
960
|
+
lowerer.noLowering(`util.inspect of '${tname}' values`, valueNode, "Buffer's <Buffer ..> form is the lowered typed-array rendering; other typed arrays fence");
|
|
963
961
|
}
|
|
964
|
-
const bufDepth = parseInspectOptions(
|
|
962
|
+
const bufDepth = parseInspectOptions(lowerer, expr.arguments[1], false);
|
|
965
963
|
void bufDepth; // Buffers render fully at any depth (custom inspect)
|
|
966
|
-
return inspectExpr(
|
|
964
|
+
return inspectExpr(lowerer, value.type, value, numLit(0, loc), numLit(2, loc), loc);
|
|
967
965
|
}
|
|
968
966
|
const walk = { recursive: false };
|
|
969
|
-
const reason = inspectSupport(
|
|
967
|
+
const reason = inspectSupport(lowerer, value.type, new Set(), walk);
|
|
970
968
|
if (reason !== null) {
|
|
971
|
-
|
|
969
|
+
lowerer.noLowering(`util.inspect of '${lowerer.fmt(value.type)}' values`, valueNode, reason);
|
|
972
970
|
}
|
|
973
|
-
const depth = parseInspectOptions(
|
|
974
|
-
return inspectExpr(
|
|
971
|
+
const depth = parseInspectOptions(lowerer, expr.arguments[1], walk.recursive);
|
|
972
|
+
return inspectExpr(lowerer, value.type, value, numLit(0, loc), numLit(depth, loc), loc);
|
|
975
973
|
}
|
|
976
974
|
/* ── util.format / util.formatWithOptions ────────────────────────────── */
|
|
977
975
|
/** One argument as format's %s conversion (Node: numbers via
|
|
978
976
|
* formatNumber, strings verbatim, objects through inspect at the given
|
|
979
977
|
* depth). Null = fence with the given reason. */
|
|
980
|
-
function formatSArg(
|
|
981
|
-
const value =
|
|
978
|
+
function formatSArg(lowerer, node, depth, loc) {
|
|
979
|
+
const value = lowerer.lowerExpr(node);
|
|
982
980
|
const t = value.type;
|
|
983
981
|
if (t.kind === "string")
|
|
984
982
|
return value;
|
|
@@ -987,91 +985,91 @@ function formatSArg(L, node, depth, loc) {
|
|
|
987
985
|
if (t.kind === "bool")
|
|
988
986
|
return { kind: "toString", operand: value, type: STRING, loc };
|
|
989
987
|
if (t.kind === "undefinedT")
|
|
990
|
-
return
|
|
988
|
+
return strLit("undefined", loc);
|
|
991
989
|
if (t.kind === "nullT")
|
|
992
|
-
return
|
|
990
|
+
return strLit("null", loc);
|
|
993
991
|
// %s of a symbol prints inspect's text ("Symbol(foo)") — String(sym)'s
|
|
994
992
|
// answer too, one runtime call either way.
|
|
995
993
|
if (t.kind === "symbol")
|
|
996
994
|
return { kind: "libCall", fn: "sym.toString", args: [value], type: STRING, loc };
|
|
997
995
|
if (t.kind === "dyn") {
|
|
998
|
-
return { kind: "libCall", fn: "insp.dynS", args: [value,
|
|
996
|
+
return { kind: "libCall", fn: "insp.dynS", args: [value, numLit(depth, loc)], type: STRING, loc };
|
|
999
997
|
}
|
|
1000
998
|
// A UNION argument dispatches per arm at runtime: a string arm prints
|
|
1001
999
|
// VERBATIM (typeof arg === 'string' in Node's formatter — inspect's
|
|
1002
1000
|
// quoting never applies at the top level), every other arm inspects.
|
|
1003
1001
|
if (t.kind === "union") {
|
|
1004
1002
|
const walk = { recursive: false };
|
|
1005
|
-
const reason = inspectSupport(
|
|
1003
|
+
const reason = inspectSupport(lowerer, t, new Set(), walk);
|
|
1006
1004
|
if (reason !== null)
|
|
1007
|
-
|
|
1008
|
-
return formatValueExpr(
|
|
1005
|
+
lowerer.noLowering(`util.format %s of '${lowerer.fmt(t)}' values`, node, reason);
|
|
1006
|
+
return formatValueExpr(lowerer, t, value, depth, loc);
|
|
1009
1007
|
}
|
|
1010
|
-
if (t.kind === "object" && !isErrorClass(
|
|
1008
|
+
if (t.kind === "object" && !isErrorClass(lowerer, t.className)) {
|
|
1011
1009
|
// hasBuiltInToString: a class with its OWN toString goes through
|
|
1012
1010
|
// String(arg) in Node, not inspect — call it explicitly instead.
|
|
1013
|
-
for (let info =
|
|
1011
|
+
for (let info = lowerer.classes.get(t.className) ?? null; info; info = info.base) {
|
|
1014
1012
|
if (info.methods.has("toString")) {
|
|
1015
|
-
|
|
1013
|
+
lowerer.noLowering("util.format %s over a class with its own toString", node, "Node calls the override (String(arg)) — call it explicitly");
|
|
1016
1014
|
}
|
|
1017
1015
|
}
|
|
1018
1016
|
}
|
|
1019
1017
|
if (t.kind === "bytes") {
|
|
1020
|
-
|
|
1018
|
+
lowerer.noLowering(`util.format %s of typed-array values`, node, "pass util.inspect(buf) explicitly");
|
|
1021
1019
|
}
|
|
1022
1020
|
const walk = { recursive: false };
|
|
1023
|
-
const reason = inspectSupport(
|
|
1021
|
+
const reason = inspectSupport(lowerer, t, new Set(), walk);
|
|
1024
1022
|
if (reason !== null)
|
|
1025
|
-
|
|
1026
|
-
return inspectExpr(
|
|
1023
|
+
lowerer.noLowering(`util.format %s of '${lowerer.fmt(t)}' values`, node, reason);
|
|
1024
|
+
return inspectExpr(lowerer, t, value, numLit(0, loc), numLit(depth, loc), loc);
|
|
1027
1025
|
}
|
|
1028
1026
|
/** %O (depth 2) / %o (showHidden, depth 4) — inspect with the spec's
|
|
1029
1027
|
* option deltas; %o fences over arrays (showHidden adds their hidden
|
|
1030
1028
|
* [length] entry, which has no lowering). */
|
|
1031
|
-
function formatOArg(
|
|
1032
|
-
const value =
|
|
1029
|
+
function formatOArg(lowerer, node, depth, loc) {
|
|
1030
|
+
const value = lowerer.lowerExpr(node);
|
|
1033
1031
|
if (value.type.kind === "bytes") {
|
|
1034
|
-
|
|
1032
|
+
lowerer.noLowering(`util.format %${depth === 4 ? "o" : "O"} of typed-array values`, node, "pass util.inspect(buf) explicitly");
|
|
1035
1033
|
}
|
|
1036
1034
|
const walk = { recursive: false };
|
|
1037
|
-
const reason = inspectSupport(
|
|
1035
|
+
const reason = inspectSupport(lowerer, value.type, new Set(), walk);
|
|
1038
1036
|
if (reason !== null)
|
|
1039
|
-
|
|
1040
|
-
if (depth === 4 && typeTreeHasArray(
|
|
1041
|
-
|
|
1037
|
+
lowerer.noLowering(`util.format %${depth === 4 ? "o" : "O"} of '${lowerer.fmt(value.type)}' values`, node, reason);
|
|
1038
|
+
if (depth === 4 && typeTreeHasArray(lowerer, value.type, new Set())) {
|
|
1039
|
+
lowerer.noLowering("util.format %o over arrays", node, "%o renders with showHidden (arrays gain a hidden [length] entry) — use %O for the default rendering");
|
|
1042
1040
|
}
|
|
1043
|
-
return inspectExpr(
|
|
1041
|
+
return inspectExpr(lowerer, value.type, value, numLit(0, loc), numLit(depth, loc), loc);
|
|
1044
1042
|
}
|
|
1045
1043
|
/** util.format(...) / util.formatWithOptions({}, ...): the compile-time
|
|
1046
1044
|
* %-substitution over a literal format string (formatWithOptionsInternal
|
|
1047
1045
|
* ported exactly — the arg cursor, the args-exhausted guard, %c's
|
|
1048
1046
|
* consume-and-drop), with per-static-type conversions. Non-literal
|
|
1049
1047
|
* format strings lower only in the substitution-free shapes. */
|
|
1050
|
-
export function lowerFormatCall(
|
|
1048
|
+
export function lowerFormatCall(lowerer, expr, loc, withOptions) {
|
|
1051
1049
|
const argNodes = [...expr.arguments];
|
|
1052
1050
|
if (withOptions) {
|
|
1053
1051
|
const opts = argNodes.shift();
|
|
1054
1052
|
if (!opts || !ts.isObjectLiteralExpression(opts) || opts.properties.length > 0) {
|
|
1055
|
-
|
|
1053
|
+
lowerer.noLowering("util.formatWithOptions with a non-empty options literal", opts ?? expr, "only the empty literal {} (the defaults — exactly util.format) is lowered");
|
|
1056
1054
|
}
|
|
1057
1055
|
}
|
|
1058
1056
|
if (argNodes.length === 0)
|
|
1059
|
-
return
|
|
1057
|
+
return strLit("", loc);
|
|
1060
1058
|
const first = argNodes[0];
|
|
1061
1059
|
const firstIsLiteral = ts.isStringLiteral(first) || ts.isNoSubstitutionTemplateLiteral(first);
|
|
1062
1060
|
/** The rest-args tail: ` ` + (strings verbatim, everything else
|
|
1063
1061
|
* inspected at the default depth). */
|
|
1064
|
-
const restArg = (node) => formatSArg(
|
|
1062
|
+
const restArg = (node) => formatSArg(lowerer, node, 2, loc);
|
|
1065
1063
|
if (!firstIsLiteral) {
|
|
1066
|
-
const firstT =
|
|
1064
|
+
const firstT = lowerer.mapTypeOf(lowerer.typeOf(first));
|
|
1067
1065
|
if (firstT?.kind === "string" && argNodes.length > 1) {
|
|
1068
|
-
|
|
1066
|
+
lowerer.noLowering("util.format with a runtime format string and further arguments", first, "the %-substitution positions are runtime-dependent — use a string literal");
|
|
1069
1067
|
}
|
|
1070
1068
|
// No substitutions possible: every argument joins with spaces.
|
|
1071
1069
|
const parts = [];
|
|
1072
1070
|
for (let i = 0; i < argNodes.length; i++) {
|
|
1073
1071
|
if (i > 0)
|
|
1074
|
-
parts.push(
|
|
1072
|
+
parts.push(strLit(" ", loc));
|
|
1075
1073
|
parts.push(restArg(argNodes[i]));
|
|
1076
1074
|
}
|
|
1077
1075
|
return concatAll(parts, loc);
|
|
@@ -1080,7 +1078,7 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1080
1078
|
// Node's early return: a lone string first argument passes VERBATIM —
|
|
1081
1079
|
// no substitution runs, "%%" stays "%%".
|
|
1082
1080
|
if (argNodes.length === 1)
|
|
1083
|
-
return
|
|
1081
|
+
return strLit(fmt, loc);
|
|
1084
1082
|
const parts = [];
|
|
1085
1083
|
let a = 0; // the arg cursor over argNodes (0 = the format string)
|
|
1086
1084
|
let lastPos = 0;
|
|
@@ -1088,12 +1086,12 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1088
1086
|
const convert = (spec, node) => {
|
|
1089
1087
|
switch (spec) {
|
|
1090
1088
|
case 115: // %s
|
|
1091
|
-
return formatSArg(
|
|
1089
|
+
return formatSArg(lowerer, node, 0, loc);
|
|
1092
1090
|
case 100: {
|
|
1093
1091
|
// %d — Number(arg) formatted: numbers as-is, booleans 1/0,
|
|
1094
1092
|
// strings through the runtime's ECMA-exact StringToNumber
|
|
1095
1093
|
// (num.fromString — the same lowering Number(aString) takes).
|
|
1096
|
-
const value =
|
|
1094
|
+
const value = lowerer.lowerExpr(node);
|
|
1097
1095
|
if (value.type.kind === "f64")
|
|
1098
1096
|
return { kind: "libCall", fn: "insp.f64", args: [value], type: STRING, loc };
|
|
1099
1097
|
if (value.type.kind === "string") {
|
|
@@ -1104,7 +1102,7 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1104
1102
|
return {
|
|
1105
1103
|
kind: "libCall",
|
|
1106
1104
|
fn: "insp.f64",
|
|
1107
|
-
args: [{ kind: "ternary", cond: value, then:
|
|
1105
|
+
args: [{ kind: "ternary", cond: value, then: numLit(1, loc), else_: numLit(0, loc), type: F64, loc }],
|
|
1108
1106
|
type: STRING,
|
|
1109
1107
|
loc,
|
|
1110
1108
|
};
|
|
@@ -1123,34 +1121,34 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1123
1121
|
loc,
|
|
1124
1122
|
};
|
|
1125
1123
|
}
|
|
1126
|
-
|
|
1124
|
+
lowerer.noLowering(`util.format %d of '${lowerer.fmt(value.type)}' values`, node, "numbers, booleans, and strings lower; ToNumber over other types has no static lowering");
|
|
1127
1125
|
break;
|
|
1128
1126
|
}
|
|
1129
1127
|
case 105: {
|
|
1130
1128
|
// %i — parseInt(ToString(arg)): the spec-exact composition.
|
|
1131
|
-
const value =
|
|
1129
|
+
const value = lowerer.lowerExpr(node);
|
|
1132
1130
|
if (value.type.kind === "f64" || value.type.kind === "bool" || value.type.kind === "string") {
|
|
1133
1131
|
const text = value.type.kind === "string" ? value : { kind: "toString", operand: value, type: STRING, loc };
|
|
1134
|
-
const parsed = { kind: "libCall", fn: "num.parseInt", args: [text,
|
|
1132
|
+
const parsed = { kind: "libCall", fn: "num.parseInt", args: [text, numLit(0, loc)], type: F64, loc };
|
|
1135
1133
|
return { kind: "libCall", fn: "insp.f64", args: [parsed], type: STRING, loc };
|
|
1136
1134
|
}
|
|
1137
|
-
|
|
1135
|
+
lowerer.noLowering(`util.format %i of '${lowerer.fmt(value.type)}' values`, node);
|
|
1138
1136
|
break;
|
|
1139
1137
|
}
|
|
1140
1138
|
case 106: {
|
|
1141
1139
|
// %j — JSON.stringify; undefined-valued args print "undefined"
|
|
1142
1140
|
// (Node appends the non-string result of tryStringify).
|
|
1143
|
-
const value =
|
|
1141
|
+
const value = lowerer.lowerExpr(node);
|
|
1144
1142
|
if (value.type.kind === "undefinedT")
|
|
1145
|
-
return
|
|
1143
|
+
return strLit("undefined", loc);
|
|
1146
1144
|
// JSON.stringify(sym) is undefined in Node — %j prints the
|
|
1147
1145
|
// "undefined" text. Folding drops the operand, so only
|
|
1148
1146
|
// side-effect-free reads compose (the typeof-fold stance).
|
|
1149
1147
|
if (value.type.kind === "symbol") {
|
|
1150
1148
|
if (!pureReemittable(value)) {
|
|
1151
|
-
|
|
1149
|
+
lowerer.noLowering(`util.format %j of computed symbol values`, node, "bind the symbol to a const first (the %j text is always \"undefined\")");
|
|
1152
1150
|
}
|
|
1153
|
-
return
|
|
1151
|
+
return strLit("undefined", loc);
|
|
1154
1152
|
}
|
|
1155
1153
|
// A checked-dynamic argument (`console.error('headers: %j',
|
|
1156
1154
|
// headers)` — the suite's http logging idiom): the runtime dyn
|
|
@@ -1159,17 +1157,17 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1159
1157
|
if (value.type.kind === "dyn") {
|
|
1160
1158
|
return { kind: "libCall", fn: "insp.jsonDyn", args: [value], type: STRING, loc };
|
|
1161
1159
|
}
|
|
1162
|
-
if (!
|
|
1163
|
-
|
|
1160
|
+
if (!lowerer.jsonSafe(value.type)) {
|
|
1161
|
+
lowerer.noLowering(`util.format %j of '${lowerer.fmt(value.type)}' values`, node, "only JSON-safe static types lower");
|
|
1164
1162
|
}
|
|
1165
1163
|
return { kind: "jsonStringify", value, type: STRING, loc };
|
|
1166
1164
|
}
|
|
1167
1165
|
case 79: // %O — inspect at the defaults
|
|
1168
|
-
return formatOArg(
|
|
1166
|
+
return formatOArg(lowerer, node, 2, loc);
|
|
1169
1167
|
case 111: // %o — showHidden semantics; depth 4
|
|
1170
|
-
return formatOArg(
|
|
1168
|
+
return formatOArg(lowerer, node, 4, loc);
|
|
1171
1169
|
}
|
|
1172
|
-
throw new
|
|
1170
|
+
throw new InternalCompilerError("unreachable format spec");
|
|
1173
1171
|
};
|
|
1174
1172
|
for (let i = 0; i < fmt.length - 1; i++) {
|
|
1175
1173
|
if (fmt.charCodeAt(i) === 37 /* % */) {
|
|
@@ -1184,22 +1182,22 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1184
1182
|
case 105: { // i
|
|
1185
1183
|
const node = args[++a];
|
|
1186
1184
|
if (lastPos !== i - 1)
|
|
1187
|
-
parts.push(
|
|
1185
|
+
parts.push(strLit(fmt.slice(lastPos, i - 1), loc));
|
|
1188
1186
|
parts.push(convert(nextChar, node));
|
|
1189
1187
|
lastPos = i + 1;
|
|
1190
1188
|
continue;
|
|
1191
1189
|
}
|
|
1192
1190
|
case 102: // f — parseFloat's full grammar has no static lowering
|
|
1193
|
-
|
|
1191
|
+
lowerer.noLowering("util.format %f", expr, "parseFloat has no static lowering (it runs with --dynamic)");
|
|
1194
1192
|
break;
|
|
1195
1193
|
case 99: // c — consumes its argument, contributes nothing
|
|
1196
1194
|
a += 1;
|
|
1197
1195
|
if (lastPos !== i - 1)
|
|
1198
|
-
parts.push(
|
|
1196
|
+
parts.push(strLit(fmt.slice(lastPos, i - 1), loc));
|
|
1199
1197
|
lastPos = i + 1;
|
|
1200
1198
|
continue;
|
|
1201
1199
|
case 37: // %%
|
|
1202
|
-
parts.push(
|
|
1200
|
+
parts.push(strLit(fmt.slice(lastPos, i), loc));
|
|
1203
1201
|
lastPos = i + 1;
|
|
1204
1202
|
continue;
|
|
1205
1203
|
default:
|
|
@@ -1207,7 +1205,7 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1207
1205
|
}
|
|
1208
1206
|
}
|
|
1209
1207
|
else if (nextChar === 37) {
|
|
1210
|
-
parts.push(
|
|
1208
|
+
parts.push(strLit(fmt.slice(lastPos, i), loc));
|
|
1211
1209
|
lastPos = i + 1;
|
|
1212
1210
|
}
|
|
1213
1211
|
}
|
|
@@ -1215,22 +1213,22 @@ export function lowerFormatCall(L, expr, loc, withOptions) {
|
|
|
1215
1213
|
if (lastPos !== 0) {
|
|
1216
1214
|
a++;
|
|
1217
1215
|
if (lastPos < fmt.length)
|
|
1218
|
-
parts.push(
|
|
1216
|
+
parts.push(strLit(fmt.slice(lastPos), loc));
|
|
1219
1217
|
}
|
|
1220
1218
|
else {
|
|
1221
1219
|
// No substitution touched the format string: it joins verbatim, and
|
|
1222
1220
|
// the cursor advances past it.
|
|
1223
|
-
parts.push(
|
|
1221
|
+
parts.push(strLit(fmt, loc));
|
|
1224
1222
|
a++;
|
|
1225
1223
|
}
|
|
1226
1224
|
for (; a < args.length; a++) {
|
|
1227
|
-
parts.push(
|
|
1225
|
+
parts.push(strLit(" ", loc));
|
|
1228
1226
|
parts.push(restArg(args[a]));
|
|
1229
1227
|
}
|
|
1230
1228
|
return concatAll(parts, loc);
|
|
1231
1229
|
}
|
|
1232
1230
|
/** Arrays anywhere in the tree — the %o (showHidden) gate. */
|
|
1233
|
-
function typeTreeHasArray(
|
|
1231
|
+
function typeTreeHasArray(lowerer, t, visiting) {
|
|
1234
1232
|
switch (t.kind) {
|
|
1235
1233
|
case "array":
|
|
1236
1234
|
return true;
|
|
@@ -1238,26 +1236,26 @@ function typeTreeHasArray(L, t, visiting) {
|
|
|
1238
1236
|
if (visiting.has(t.shapeId))
|
|
1239
1237
|
return false;
|
|
1240
1238
|
visiting.add(t.shapeId);
|
|
1241
|
-
const shape =
|
|
1239
|
+
const shape = lowerer.shapes.get(t.shapeId);
|
|
1242
1240
|
if (shape?.tuple)
|
|
1243
1241
|
return true;
|
|
1244
|
-
return (shape?.fields ?? []).some((f) => typeTreeHasArray(
|
|
1242
|
+
return (shape?.fields ?? []).some((f) => typeTreeHasArray(lowerer, f.type, visiting));
|
|
1245
1243
|
}
|
|
1246
1244
|
case "map":
|
|
1247
|
-
return typeTreeHasArray(
|
|
1245
|
+
return typeTreeHasArray(lowerer, t.key, visiting) || typeTreeHasArray(lowerer, t.value, visiting);
|
|
1248
1246
|
case "set":
|
|
1249
|
-
return typeTreeHasArray(
|
|
1247
|
+
return typeTreeHasArray(lowerer, t.elem, visiting);
|
|
1250
1248
|
case "union": {
|
|
1251
1249
|
if (visiting.has(t.unionId))
|
|
1252
1250
|
return false;
|
|
1253
1251
|
visiting.add(t.unionId);
|
|
1254
|
-
return (
|
|
1252
|
+
return (lowerer.unions.get(t.unionId)?.arms ?? []).some((a) => typeTreeHasArray(lowerer, a, visiting));
|
|
1255
1253
|
}
|
|
1256
1254
|
case "object": {
|
|
1257
1255
|
if (visiting.has(t.className))
|
|
1258
1256
|
return false;
|
|
1259
1257
|
visiting.add(t.className);
|
|
1260
|
-
return (
|
|
1258
|
+
return (lowerer.classes.get(t.className)?.def.fields ?? []).some((f) => typeTreeHasArray(lowerer, f.type, visiting));
|
|
1261
1259
|
}
|
|
1262
1260
|
case "bytes":
|
|
1263
1261
|
return true;
|
|
@@ -1269,20 +1267,20 @@ function typeTreeHasArray(L, t, visiting) {
|
|
|
1269
1267
|
/** The spoke's entry, called from both the named-import and namespace/
|
|
1270
1268
|
* default-import call paths. Null for other modules and members (the
|
|
1271
1269
|
* module tables' fence takes over). */
|
|
1272
|
-
export function lowerUtilModuleCall(
|
|
1270
|
+
export function lowerUtilModuleCall(lowerer, expr, bi, loc) {
|
|
1273
1271
|
if (bi.module !== "util")
|
|
1274
1272
|
return null;
|
|
1275
1273
|
switch (bi.member) {
|
|
1276
1274
|
case "inspect":
|
|
1277
|
-
return lowerInspectCall(
|
|
1275
|
+
return lowerInspectCall(lowerer, expr, loc);
|
|
1278
1276
|
case "format":
|
|
1279
|
-
return lowerFormatCall(
|
|
1277
|
+
return lowerFormatCall(lowerer, expr, loc, false);
|
|
1280
1278
|
case "formatWithOptions":
|
|
1281
|
-
return lowerFormatCall(
|
|
1279
|
+
return lowerFormatCall(lowerer, expr, loc, true);
|
|
1282
1280
|
case "parseArgs":
|
|
1283
|
-
return lowerParseArgsCall(
|
|
1281
|
+
return lowerParseArgsCall(lowerer, expr, loc);
|
|
1284
1282
|
case "getCallSites":
|
|
1285
|
-
return lowerGetCallSitesCall(
|
|
1283
|
+
return lowerGetCallSitesCall(lowerer, expr, loc);
|
|
1286
1284
|
default:
|
|
1287
1285
|
return null;
|
|
1288
1286
|
}
|
|
@@ -1292,9 +1290,9 @@ export function lowerUtilModuleCall(L, expr, bi, loc) {
|
|
|
1292
1290
|
* parser returns the same tree-shaped result Node does (including token
|
|
1293
1291
|
* variants and a null-prototype values object); statically typed member
|
|
1294
1292
|
* reads leave that tree through the ordinary dyn checks. */
|
|
1295
|
-
function lowerParseArgsCall(
|
|
1293
|
+
function lowerParseArgsCall(lowerer, expr, loc) {
|
|
1296
1294
|
if (expr.arguments.length > 1 || expr.arguments.some(ts.isSpreadElement)) {
|
|
1297
|
-
|
|
1295
|
+
lowerer.noLowering(`util.parseArgs with ${expr.arguments.length} arguments`, expr, "the lowered form is parseArgs() or parseArgs(config)");
|
|
1298
1296
|
}
|
|
1299
1297
|
let config;
|
|
1300
1298
|
const configNode = expr.arguments[0];
|
|
@@ -1302,14 +1300,14 @@ function lowerParseArgsCall(L, expr, loc) {
|
|
|
1302
1300
|
config = { kind: "dynObjLit", fields: [], type: DYN, loc };
|
|
1303
1301
|
}
|
|
1304
1302
|
else {
|
|
1305
|
-
const raw =
|
|
1303
|
+
const raw = lowerer.lowerExpr(configNode);
|
|
1306
1304
|
if (raw.type.kind === "dyn") {
|
|
1307
1305
|
config = raw;
|
|
1308
1306
|
}
|
|
1309
1307
|
else if (raw.type.kind === "jsval") {
|
|
1310
1308
|
config = { kind: "dynFromJsval", value: raw, type: DYN, loc };
|
|
1311
1309
|
}
|
|
1312
|
-
else if (canConvertToDyn(raw.type, (id) =>
|
|
1310
|
+
else if (canConvertToDyn(raw.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
1313
1311
|
// parseArgs assigns descriptor default arrays directly into the
|
|
1314
1312
|
// returned values object. Keep mutable config composites in typed-ref
|
|
1315
1313
|
// capsules so that default arrays can leave the dyn result as the
|
|
@@ -1326,7 +1324,7 @@ function lowerParseArgsCall(L, expr, loc) {
|
|
|
1326
1324
|
};
|
|
1327
1325
|
}
|
|
1328
1326
|
else {
|
|
1329
|
-
|
|
1327
|
+
lowerer.noLowering(`util.parseArgs with a '${lowerer.fmt(raw.type)}' configuration`, configNode, "pass the documented JSON-safe config object (args/options and boolean flags)");
|
|
1330
1328
|
}
|
|
1331
1329
|
}
|
|
1332
1330
|
const parsed = {
|
|
@@ -1336,9 +1334,9 @@ function lowerParseArgsCall(L, expr, loc) {
|
|
|
1336
1334
|
type: DYN,
|
|
1337
1335
|
loc,
|
|
1338
1336
|
};
|
|
1339
|
-
const result =
|
|
1337
|
+
const result = lowerer.mapTypeOf(lowerer.typeOf(expr));
|
|
1340
1338
|
if (result !== null && result.kind !== "dyn" && result.kind !== "jsval" && result.kind !== "void" &&
|
|
1341
|
-
canDynCheckTo(result, (id) =>
|
|
1339
|
+
canDynCheckTo(result, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
1342
1340
|
return { kind: "dynCheck", value: parsed, type: result, loc };
|
|
1343
1341
|
}
|
|
1344
1342
|
return parsed;
|
|
@@ -1352,7 +1350,7 @@ function lowerParseArgsCall(L, expr, loc) {
|
|
|
1352
1350
|
* failure text — read a printable value instead of throwing). Argument
|
|
1353
1351
|
* forms and TypeScript keep the SC2020 fence: a typed consumer asserting
|
|
1354
1352
|
* real frames must fail loudly at compile time, not read placeholders. */
|
|
1355
|
-
function lowerGetCallSitesCall(
|
|
1353
|
+
function lowerGetCallSitesCall(lowerer, expr, loc) {
|
|
1356
1354
|
if (expr.arguments.length !== 0)
|
|
1357
1355
|
return null;
|
|
1358
1356
|
if (!isJsSourceFile(expr.getSourceFile()))
|