@scriptc/compiler 0.3.0 → 0.3.2
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 +346 -17
- package/dist/backend/executable-features.js +1 -0
- package/dist/backend/executable-features.js.map +1 -1
- package/dist/backend/literals.d.ts +7 -0
- package/dist/backend/literals.js +32 -0
- package/dist/backend/literals.js.map +1 -1
- package/dist/backend/literals.test.js +17 -1
- package/dist/backend/literals.test.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +15 -4
- package/dist/backend/llvm/alloc.js +39 -15
- package/dist/backend/llvm/alloc.js.map +1 -1
- package/dist/backend/llvm/alloc.test.js +15 -1
- package/dist/backend/llvm/alloc.test.js.map +1 -1
- package/dist/backend/llvm/appended-array-literals.d.ts +2 -0
- package/dist/backend/llvm/appended-array-literals.js +109 -0
- package/dist/backend/llvm/appended-array-literals.js.map +1 -0
- package/dist/backend/llvm/appended-array-literals.test.d.ts +1 -0
- package/dist/backend/llvm/appended-array-literals.test.js +90 -0
- package/dist/backend/llvm/appended-array-literals.test.js.map +1 -0
- package/dist/backend/llvm/bigint-wrap.d.ts +4 -0
- package/dist/backend/llvm/bigint-wrap.js +590 -0
- package/dist/backend/llvm/bigint-wrap.js.map +1 -0
- package/dist/backend/llvm/blocks.d.ts +2 -0
- package/dist/backend/llvm/blocks.js +4 -0
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.d.ts +4 -1
- package/dist/backend/llvm/call-lifetimes.js +66 -7
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +14 -3
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.test.js +1 -1
- package/dist/backend/llvm/checked-narrows.test.js.map +1 -1
- package/dist/backend/llvm/classes.js +67 -14
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +6 -6
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +7 -5
- package/dist/backend/llvm/common.js +7 -5
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.js +10 -28
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.js +146 -53
- package/dist/backend/llvm/dense-array-access.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.test.js +68 -3
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +4 -0
- package/dist/backend/llvm/dyn.js +15 -2
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +163 -8
- package/dist/backend/llvm/emitter.js +973 -100
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +14 -7
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +242 -49
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.js +1 -1
- package/dist/backend/llvm/expr-async.test.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.js +51 -36
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +8 -0
- package/dist/backend/llvm/expr-callbacks.js +153 -4
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +12 -1
- package/dist/backend/llvm/expr-calls.js +279 -78
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-calls.test.d.ts +1 -0
- package/dist/backend/llvm/expr-calls.test.js +132 -0
- package/dist/backend/llvm/expr-calls.test.js.map +1 -0
- package/dist/backend/llvm/expr-containers.d.ts +7 -0
- package/dist/backend/llvm/expr-containers.js +49 -5
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +4 -0
- package/dist/backend/llvm/expr-control.d.ts +8 -0
- package/dist/backend/llvm/expr-control.js +103 -69
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.js +3 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +28 -6
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +14 -0
- package/dist/backend/llvm/expr-primitives.js +110 -48
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +95 -5
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.d.ts +9 -0
- package/dist/backend/llvm/expr-records.js +144 -16
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.d.ts +9 -1
- package/dist/backend/llvm/expr-stream-bridges.js +152 -4
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +98 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -1
- package/dist/backend/llvm/int32-abi.d.ts +47 -0
- package/dist/backend/llvm/int32-abi.js +83 -0
- package/dist/backend/llvm/int32-abi.js.map +1 -0
- package/dist/backend/llvm/int32-abi.test.d.ts +1 -0
- package/dist/backend/llvm/int32-abi.test.js +181 -0
- package/dist/backend/llvm/int32-abi.test.js.map +1 -0
- package/dist/backend/llvm/int32-locals.d.ts +30 -0
- package/dist/backend/llvm/int32-locals.js +95 -0
- package/dist/backend/llvm/int32-locals.js.map +1 -0
- package/dist/backend/llvm/integer-values.d.ts +4 -0
- package/dist/backend/llvm/integer-values.js +30 -1
- package/dist/backend/llvm/integer-values.js.map +1 -1
- package/dist/backend/llvm/integer-views.d.ts +8 -1
- package/dist/backend/llvm/integer-views.js +47 -2
- package/dist/backend/llvm/integer-views.js.map +1 -1
- package/dist/backend/llvm/lazy-captures.d.ts +16 -0
- package/dist/backend/llvm/lazy-captures.js +88 -2
- package/dist/backend/llvm/lazy-captures.js.map +1 -1
- package/dist/backend/llvm/lazy-captures.test.js +48 -0
- package/dist/backend/llvm/lazy-captures.test.js.map +1 -1
- package/dist/backend/llvm/lib-dispatch.js +21 -0
- package/dist/backend/llvm/lib-dispatch.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +61 -0
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +83 -9
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.js +26 -5
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +3 -2
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.d.ts +24 -2
- package/dist/backend/llvm/local-union-storage.js +127 -12
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +108 -3
- package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.test.js +2 -2
- package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/record-results.d.ts +26 -0
- package/dist/backend/llvm/record-results.js +252 -0
- package/dist/backend/llvm/record-results.js.map +1 -0
- package/dist/backend/llvm/reference-effects.js +4 -0
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-writes.d.ts +3 -0
- package/dist/backend/llvm/reference-writes.js +25 -11
- package/dist/backend/llvm/reference-writes.js.map +1 -1
- package/dist/backend/llvm/regex-matchers.d.ts +39 -0
- package/dist/backend/llvm/regex-matchers.js +1649 -0
- package/dist/backend/llvm/regex-matchers.js.map +1 -0
- package/dist/backend/llvm/regex-matchers.test.d.ts +1 -0
- package/dist/backend/llvm/regex-matchers.test.js +96 -0
- package/dist/backend/llvm/regex-matchers.test.js.map +1 -0
- package/dist/backend/llvm/regions.d.ts +67 -0
- package/dist/backend/llvm/regions.js +309 -0
- package/dist/backend/llvm/regions.js.map +1 -0
- package/dist/backend/llvm/regions.test.d.ts +1 -0
- package/dist/backend/llvm/regions.test.js +173 -0
- package/dist/backend/llvm/regions.test.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +70 -8
- package/dist/backend/llvm/shapes.js +157 -29
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +7 -6
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/split-loops.js +1 -1
- package/dist/backend/llvm/split-loops.js.map +1 -1
- package/dist/backend/llvm/stack-objects.d.ts +29 -0
- package/dist/backend/llvm/stack-objects.js +130 -0
- package/dist/backend/llvm/stack-objects.js.map +1 -0
- package/dist/backend/llvm/stack-objects.test.d.ts +1 -0
- package/dist/backend/llvm/stack-objects.test.js +252 -0
- package/dist/backend/llvm/stack-objects.test.js.map +1 -0
- package/dist/backend/llvm/stack-unions.test.js +1 -1
- package/dist/backend/llvm/stack-unions.test.js.map +1 -1
- package/dist/backend/llvm/string-construction.test.js +2 -2
- package/dist/backend/llvm/string-construction.test.js.map +1 -1
- package/dist/backend/llvm/string-lifetimes.test.js +5 -5
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-literal-equality.d.ts +22 -0
- package/dist/backend/llvm/string-literal-equality.js +78 -0
- package/dist/backend/llvm/string-literal-equality.js.map +1 -0
- package/dist/backend/llvm/string-reads.d.ts +4 -1
- package/dist/backend/llvm/string-reads.js +89 -9
- package/dist/backend/llvm/string-reads.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.js +60 -13
- package/dist/backend/llvm/switch-dispatch.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +71 -6
- package/dist/backend/llvm/switch-dispatch.test.js.map +1 -1
- package/dist/backend/llvm/union-retype.test.d.ts +1 -0
- package/dist/backend/llvm/union-retype.test.js +229 -0
- package/dist/backend/llvm/union-retype.test.js.map +1 -0
- package/dist/backend/llvm/walkers.d.ts +2 -0
- package/dist/backend/llvm/walkers.js +4 -2
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/llvm/wrapping-sums.d.ts +17 -0
- package/dist/backend/llvm/wrapping-sums.js +113 -0
- package/dist/backend/llvm/wrapping-sums.js.map +1 -0
- package/dist/backend/loop-polls.js +1 -0
- package/dist/backend/loop-polls.js.map +1 -1
- package/dist/backend/mangle.d.ts +9 -0
- package/dist/backend/mangle.js +15 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/backend/may-throw.js +7 -3
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +5 -0
- package/dist/backend/native/executable.js +16 -1
- package/dist/backend/native/executable.js.map +1 -1
- package/dist/backend/native/library.js +1 -1
- package/dist/backend/native/library.js.map +1 -1
- package/dist/backend/native/runtime-inputs.d.ts +1 -1
- package/dist/backend/native/runtime-inputs.js +2 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +1 -0
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-core.d.ts +1 -0
- package/dist/backend/runtime-pack-core.js +1 -0
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack.test.js +1 -1
- package/dist/backend/target-diagnostics.js +14 -0
- package/dist/backend/target-diagnostics.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +13 -0
- package/dist/backend/target-diagnostics.test.js.map +1 -1
- package/dist/contracts/check.js +4 -0
- package/dist/contracts/check.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +1 -0
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/frontend/experimental-import.d.ts +12 -0
- package/dist/frontend/experimental-import.js +63 -0
- package/dist/frontend/experimental-import.js.map +1 -0
- package/dist/frontend/lowering/array-values.d.ts +14 -0
- package/dist/frontend/lowering/array-values.js +29 -0
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/builtin-calls.d.ts +6 -1
- package/dist/frontend/lowering/builtin-calls.js +36 -0
- package/dist/frontend/lowering/builtin-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/console.d.ts +16 -6
- package/dist/frontend/lowering/builtins/console.js +33 -9
- package/dist/frontend/lowering/builtins/console.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.js +20 -0
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/json.d.ts +2 -2
- package/dist/frontend/lowering/builtins/json.js +13 -4
- package/dist/frontend/lowering/builtins/json.js.map +1 -1
- package/dist/frontend/lowering/builtins/module-calls.js +16 -1
- package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
- package/dist/frontend/lowering/builtins/numbers.d.ts +1 -0
- package/dist/frontend/lowering/builtins/numbers.js +17 -0
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/operating-system.d.ts +18 -0
- package/dist/frontend/lowering/builtins/operating-system.js +361 -1
- package/dist/frontend/lowering/builtins/operating-system.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.js +15 -3
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/promises.js +109 -2
- package/dist/frontend/lowering/builtins/promises.js.map +1 -1
- package/dist/frontend/lowering/builtins/text-codecs.d.ts +3 -4
- package/dist/frontend/lowering/builtins/text-codecs.js +3 -4
- package/dist/frontend/lowering/builtins/text-codecs.js.map +1 -1
- package/dist/frontend/lowering/checked-promise-all.d.ts +10 -3
- package/dist/frontend/lowering/checked-promise-all.js +52 -6
- package/dist/frontend/lowering/checked-promise-all.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +6 -3
- package/dist/frontend/lowering/class-dynamic-dispatch.js +54 -31
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.js +74 -4
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-construction.js +8 -4
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-pipelines.d.ts +54 -0
- package/dist/frontend/lowering/containers/array-pipelines.js +1827 -0
- package/dist/frontend/lowering/containers/array-pipelines.js.map +1 -0
- package/dist/frontend/lowering/containers/exec-result-uses.d.ts +10 -0
- package/dist/frontend/lowering/containers/exec-result-uses.js +88 -0
- package/dist/frontend/lowering/containers/exec-result-uses.js.map +1 -0
- package/dist/frontend/lowering/containers/string-and-regexp.js +106 -7
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/containers/string-replacement.d.ts +2 -1
- package/dist/frontend/lowering/containers/string-replacement.js +32 -136
- package/dist/frontend/lowering/containers/string-replacement.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +18 -2
- package/dist/frontend/lowering/cycle-initialization.js +166 -12
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.js +7 -2
- package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -1
- package/dist/frontend/lowering/deferred-module-initializers.test.js +28 -0
- package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -1
- package/dist/frontend/lowering/devirtualize.d.ts +33 -0
- package/dist/frontend/lowering/devirtualize.js +199 -0
- package/dist/frontend/lowering/devirtualize.js.map +1 -0
- package/dist/frontend/lowering/expressions/nullish-assignment.js +55 -7
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +5 -56
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/generator-delegation.d.ts +8 -0
- package/dist/frontend/lowering/generator-delegation.js +231 -10
- package/dist/frontend/lowering/generator-delegation.js.map +1 -1
- package/dist/frontend/lowering/identifier-uses.d.ts +7 -0
- package/dist/frontend/lowering/identifier-uses.js +23 -0
- package/dist/frontend/lowering/identifier-uses.js.map +1 -0
- package/dist/frontend/lowering/iterator-adapters.js +51 -3
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -1
- package/dist/frontend/lowering/lifetime-regions.d.ts +11 -0
- package/dist/frontend/lowering/lifetime-regions.js +216 -0
- package/dist/frontend/lowering/lifetime-regions.js.map +1 -0
- package/dist/frontend/lowering/lower-array-sort.d.ts +28 -2
- package/dist/frontend/lowering/lower-array-sort.js +112 -2
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.test.js +99 -2
- package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +135 -131
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +4 -3
- package/dist/frontend/lowering/lower-classes.js +117 -13
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-console.d.ts +27 -0
- package/dist/frontend/lowering/lower-console.js +651 -0
- package/dist/frontend/lowering/lower-console.js.map +1 -0
- package/dist/frontend/lowering/lower-event-emitter.d.ts +6 -0
- package/dist/frontend/lowering/lower-event-emitter.js +124 -38
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +272 -25
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +7 -3
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +25 -7
- package/dist/frontend/lowering/lower-generators.js +264 -113
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +8 -1
- package/dist/frontend/lowering/lower-inspect.js +119 -18
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +24 -14
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stdlib.d.ts +4 -0
- package/dist/frontend/lowering/lower-stdlib.js +35 -1
- package/dist/frontend/lowering/lower-stdlib.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +66 -11
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +13 -10
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +47 -5
- package/dist/frontend/lowering/lowerer.js +235 -54
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/nan-coded-reads.d.ts +16 -0
- package/dist/frontend/lowering/nan-coded-reads.js +108 -1
- package/dist/frontend/lowering/nan-coded-reads.js.map +1 -1
- package/dist/frontend/lowering/regex-span-reads.d.ts +12 -0
- package/dist/frontend/lowering/regex-span-reads.js +164 -0
- package/dist/frontend/lowering/regex-span-reads.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.d.ts +4 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +2 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-bounds.test.js +27 -0
- package/dist/frontend/lowering/runtime-optional-bounds.test.js.map +1 -1
- package/dist/frontend/lowering/split-consumers.js +2 -18
- package/dist/frontend/lowering/split-consumers.js.map +1 -1
- package/dist/frontend/lowering/surfaces.js +115 -18
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/union-retag.d.ts +6 -1
- package/dist/frontend/lowering/union-retag.js +64 -1
- package/dist/frontend/lowering/union-retag.js.map +1 -1
- package/dist/frontend/lowering/union-retag.test.js +46 -0
- package/dist/frontend/lowering/union-retag.test.js.map +1 -1
- package/dist/frontend/lowering/var-hoisting.d.ts +3 -0
- package/dist/frontend/lowering/var-hoisting.js +261 -0
- package/dist/frontend/lowering/var-hoisting.js.map +1 -0
- package/dist/frontend/pipeline.js +5 -3
- package/dist/frontend/pipeline.js.map +1 -1
- package/dist/frontend/program.d.ts +3 -2
- package/dist/frontend/program.js +23 -5
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +13 -0
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +13 -1
- package/dist/frontend/type-mapper.js +160 -14
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/ir/builtin-effects.js +31 -2
- package/dist/ir/builtin-effects.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +157 -16
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/function-references.d.ts +12 -0
- package/dist/ir/function-references.js +29 -0
- package/dist/ir/function-references.js.map +1 -0
- package/dist/ir/function-references.test.d.ts +1 -0
- package/dist/ir/function-references.test.js +277 -0
- package/dist/ir/function-references.test.js.map +1 -0
- package/dist/ir/int32-slots.d.ts +7 -4
- package/dist/ir/int32-slots.js +215 -49
- package/dist/ir/int32-slots.js.map +1 -1
- package/dist/ir/int32-slots.test.js +38 -1
- package/dist/ir/int32-slots.test.js.map +1 -1
- package/dist/ir/integer-ranges.d.ts +4 -4
- package/dist/ir/integer-ranges.js +89 -64
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +71 -9
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/intrinsic-signatures.js +3 -0
- package/dist/ir/intrinsic-signatures.js.map +1 -1
- package/dist/ir/ir.d.ts +111 -20
- package/dist/ir/ir.js +6 -0
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/runtime-features.d.ts +1 -0
- package/dist/ir/runtime-features.js +38 -3
- package/dist/ir/runtime-features.js.map +1 -1
- package/dist/ir/scalar-records.js +1 -2
- package/dist/ir/scalar-records.js.map +1 -1
- package/dist/ir/traverse.js +4 -0
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/validate.js +201 -25
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +90 -7
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/ir-policy.js +1 -0
- package/dist/library/ir-policy.js.map +1 -1
- package/dist/native/sanitizer.test.js +1 -0
- package/dist/native/sanitizer.test.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +159 -17
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as ts from "../ts7/adapter.js";
|
|
2
|
+
import { type IrExpr, type SrcLoc } from "../../ir/ir.js";
|
|
3
|
+
import { type ConsoleMethodMember } from "./builtins/console.js";
|
|
4
|
+
import { type Lowerer } from "./lowerer.js";
|
|
5
|
+
/** `new Console(stdout[, stderr][, ignoreErrors])` and `new
|
|
6
|
+
* Console({ stdout, stderr, ignoreErrors })`. Arguments and option
|
|
7
|
+
* initializers evaluate in source order into hidden locals before the
|
|
8
|
+
* handle exists (Node evaluates them before the constructor body); an
|
|
9
|
+
* absent stderr shares stdout's target. */
|
|
10
|
+
export declare function lowerConsoleNew(lowerer: Lowerer, expr: ts.NewExpression): IrExpr | null;
|
|
11
|
+
/** `c.log(...)` and the other output members on a stdlib-Console-typed
|
|
12
|
+
* receiver that is not the global console itself (that path keeps its
|
|
13
|
+
* direct console lowering): the receiver evaluates first, then the
|
|
14
|
+
* util.format rendering of the arguments, then one native write. */
|
|
15
|
+
export declare function lowerConsoleInstanceCall(lowerer: Lowerer, call: ts.CallExpression, loc: SrcLoc): IrExpr | null;
|
|
16
|
+
/** One console argument, already lowered, in the shape the console
|
|
17
|
+
* intrinsics take: Node's formatter (formatWithOptions) prints strings
|
|
18
|
+
* verbatim, numbers and booleans directly, and everything else through
|
|
19
|
+
* util.inspect at the rest-args depth 2. */
|
|
20
|
+
export declare function lowerConsoleArg(lowerer: Lowerer, node: ts.Expression, lowered: IrExpr, surface: string, loc: SrcLoc): IrExpr;
|
|
21
|
+
/** console.log/info/debug (stdout) and console.error/warn (stderr), and
|
|
22
|
+
* the members Node defines as log (dirxml, group's label line): one
|
|
23
|
+
* formatted line through the console intrinsic. */
|
|
24
|
+
export declare function lowerConsoleOutput(lowerer: Lowerer, expr: ts.CallExpression, stdout: boolean, surface: string, loc: SrcLoc): IrExpr;
|
|
25
|
+
/** console.<member>(...) on the global console for the members past the
|
|
26
|
+
* output set. */
|
|
27
|
+
export declare function lowerConsoleMethodCall(lowerer: Lowerer, expr: ts.CallExpression, member: ConsoleMethodMember, loc: SrcLoc): IrExpr;
|
|
@@ -0,0 +1,651 @@
|
|
|
1
|
+
import * as ts from "../ts7/adapter.js";
|
|
2
|
+
import { BOOL, DYN, STRING, VOID, canBoxFuncIntoDyn, } from "../../ir/ir.js";
|
|
3
|
+
import { boolLit, dynUndefinedExpr, numLit, strLit, varRef } from "../../ir/build.js";
|
|
4
|
+
import { locOf } from "../program.js";
|
|
5
|
+
import {} from "./builtins/console.js";
|
|
6
|
+
import { jsFuncNameOf } from "./lowerer.js";
|
|
7
|
+
import { lowerConsoleInspectArg, lowerFormatCall, lowerInspectValue } from "./lower-inspect.js";
|
|
8
|
+
import { streamSidesOf } from "./lower-stream.js";
|
|
9
|
+
/** node:console Console instances: a native handle (the checked-dynamic
|
|
10
|
+
* representation the stdlib Console type maps to) over two output
|
|
11
|
+
* targets — process.stdout/process.stderr, or writable streams — plus
|
|
12
|
+
* the ignoreErrors flag. The log/info/debug (stdout) and error/warn
|
|
13
|
+
* (stderr) members lower through util.format into ONE write of the
|
|
14
|
+
* formatted line, exactly Node's kWriteToConsole; the remaining Console
|
|
15
|
+
* surface stays fenced like the global console's. */
|
|
16
|
+
const OUTPUT_MEMBERS = new Map([
|
|
17
|
+
["log", false],
|
|
18
|
+
["info", false],
|
|
19
|
+
["debug", false],
|
|
20
|
+
["error", true],
|
|
21
|
+
["warn", true],
|
|
22
|
+
]);
|
|
23
|
+
const OPTION_KEYS = new Set(["stdout", "stderr", "ignoreErrors"]);
|
|
24
|
+
function isConsoleCtor(lowerer, callee) {
|
|
25
|
+
if (ts.isIdentifier(callee)) {
|
|
26
|
+
const bi = lowerer.builtinImportOf(callee);
|
|
27
|
+
return bi?.module === "console" && bi.member === "Console";
|
|
28
|
+
}
|
|
29
|
+
if (!ts.isPropertyAccessExpression(callee) || callee.name.text !== "Console")
|
|
30
|
+
return false;
|
|
31
|
+
return (lowerer.isStdlibGlobal(callee.expression, "console") ||
|
|
32
|
+
lowerer.builtinNamespaceModuleOf(callee.expression) === "console");
|
|
33
|
+
}
|
|
34
|
+
function isUndefinedArg(node) {
|
|
35
|
+
return (node === undefined ||
|
|
36
|
+
(ts.isIdentifier(node) && node.text === "undefined") ||
|
|
37
|
+
ts.isVoidExpression(node));
|
|
38
|
+
}
|
|
39
|
+
/** `new Console(stdout[, stderr][, ignoreErrors])` and `new
|
|
40
|
+
* Console({ stdout, stderr, ignoreErrors })`. Arguments and option
|
|
41
|
+
* initializers evaluate in source order into hidden locals before the
|
|
42
|
+
* handle exists (Node evaluates them before the constructor body); an
|
|
43
|
+
* absent stderr shares stdout's target. */
|
|
44
|
+
export function lowerConsoleNew(lowerer, expr) {
|
|
45
|
+
if (!isConsoleCtor(lowerer, expr.expression))
|
|
46
|
+
return null;
|
|
47
|
+
const loc = locOf(expr);
|
|
48
|
+
const args = expr.arguments ?? [];
|
|
49
|
+
const entries = [];
|
|
50
|
+
const first = args[0];
|
|
51
|
+
if (first && ts.isObjectLiteralExpression(first)) {
|
|
52
|
+
for (const prop of first.properties) {
|
|
53
|
+
let name = null;
|
|
54
|
+
let value = null;
|
|
55
|
+
if (ts.isPropertyAssignment(prop) &&
|
|
56
|
+
(ts.isIdentifier(prop.name) || ts.isStringLiteral(prop.name))) {
|
|
57
|
+
name = prop.name.text;
|
|
58
|
+
value = prop.initializer;
|
|
59
|
+
}
|
|
60
|
+
else if (ts.isShorthandPropertyAssignment(prop)) {
|
|
61
|
+
name = prop.name.text;
|
|
62
|
+
value = prop.name;
|
|
63
|
+
}
|
|
64
|
+
if (name === null || value === null || !OPTION_KEYS.has(name)) {
|
|
65
|
+
lowerer.noLowering("Console options other than stdout, stderr, and ignoreErrors", prop, "colorMode, inspectOptions, and groupIndentation have no lowering yet");
|
|
66
|
+
}
|
|
67
|
+
entries.push({ role: name, node: value });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
entries.push({ role: "stdout", node: args[0] });
|
|
72
|
+
entries.push({ role: "stderr", node: args[1] });
|
|
73
|
+
entries.push({ role: "ignoreErrors", node: args[2] });
|
|
74
|
+
}
|
|
75
|
+
const stmts = [];
|
|
76
|
+
const target = (node, role) => {
|
|
77
|
+
if (ts.isPropertyAccessExpression(node)) {
|
|
78
|
+
const member = lowerer.stdlibGlobalMember(node, "process");
|
|
79
|
+
if (member === "stdout")
|
|
80
|
+
return { fd: 1 };
|
|
81
|
+
if (member === "stderr")
|
|
82
|
+
return { fd: 2 };
|
|
83
|
+
}
|
|
84
|
+
const value = lowerer.lowerExpr(node);
|
|
85
|
+
const info = value.type.kind === "object" ? lowerer.classes.get(value.type.className) : undefined;
|
|
86
|
+
const sides = streamSidesOf(lowerer, info);
|
|
87
|
+
if (sides !== "w" && sides !== "rw") {
|
|
88
|
+
lowerer.noLowering(`a Console ${role} of type '${lowerer.fmt(value.type)}'`, node, "process.stdout, process.stderr, and node:stream writables (Writable, Duplex, Transform, PassThrough, and their subclasses) are the supported Console streams");
|
|
89
|
+
}
|
|
90
|
+
const local = lowerer.declareHiddenLocal(`%console${role}`, value.type);
|
|
91
|
+
stmts.push({ kind: "varDecl", localId: local.id, init: value, loc });
|
|
92
|
+
return { local: local.id, type: value.type };
|
|
93
|
+
};
|
|
94
|
+
let out = null;
|
|
95
|
+
let err = null;
|
|
96
|
+
let ignore = null;
|
|
97
|
+
for (const entry of entries) {
|
|
98
|
+
const node = entry.node;
|
|
99
|
+
if (isUndefinedArg(node)) {
|
|
100
|
+
// `void expr` still evaluates its operand.
|
|
101
|
+
if (node !== undefined && ts.isVoidExpression(node)) {
|
|
102
|
+
stmts.push({ kind: "exprStmt", expr: lowerer.lowerExpr(node), loc });
|
|
103
|
+
}
|
|
104
|
+
if (entry.role === "stdout")
|
|
105
|
+
out = null;
|
|
106
|
+
else if (entry.role === "stderr")
|
|
107
|
+
err = null;
|
|
108
|
+
else
|
|
109
|
+
ignore = null;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (entry.role === "stdout") {
|
|
113
|
+
out = target(node, "stdout");
|
|
114
|
+
}
|
|
115
|
+
else if (entry.role === "stderr") {
|
|
116
|
+
err = target(node, "stderr");
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
const value = lowerer.lowerExpr(node);
|
|
120
|
+
if (value.type.kind !== "bool") {
|
|
121
|
+
lowerer.noLowering(`ignoreErrors of type '${lowerer.fmt(value.type)}'`, node, "pass a boolean");
|
|
122
|
+
}
|
|
123
|
+
const local = lowerer.declareHiddenLocal("%consoleIgnoreErrors", BOOL);
|
|
124
|
+
stmts.push({ kind: "varDecl", localId: local.id, init: value, loc });
|
|
125
|
+
ignore = varRef(local.id, BOOL, loc);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (out === null) {
|
|
129
|
+
return lowerer.noLowering("new Console without a stdout stream", expr, "pass the stdout stream");
|
|
130
|
+
}
|
|
131
|
+
const stdoutTarget = out;
|
|
132
|
+
const stderrTarget = err ?? stdoutTarget;
|
|
133
|
+
const handle = lowerer.declareHiddenLocal("%console", DYN);
|
|
134
|
+
const fdOf = (t) => numLit("fd" in t ? t.fd : 0, loc);
|
|
135
|
+
stmts.push({
|
|
136
|
+
kind: "varDecl",
|
|
137
|
+
localId: handle.id,
|
|
138
|
+
init: {
|
|
139
|
+
kind: "libCall",
|
|
140
|
+
fn: "console.new",
|
|
141
|
+
args: [fdOf(stdoutTarget), fdOf(stderrTarget), ignore ?? boolLit(true, loc)],
|
|
142
|
+
type: DYN,
|
|
143
|
+
loc,
|
|
144
|
+
},
|
|
145
|
+
loc,
|
|
146
|
+
});
|
|
147
|
+
const targets = [stdoutTarget, stderrTarget];
|
|
148
|
+
for (let which = 0; which < targets.length; which++) {
|
|
149
|
+
const t = targets[which];
|
|
150
|
+
if (!("local" in t))
|
|
151
|
+
continue;
|
|
152
|
+
stmts.push({
|
|
153
|
+
kind: "exprStmt",
|
|
154
|
+
expr: {
|
|
155
|
+
kind: "libCall",
|
|
156
|
+
fn: "console.bind",
|
|
157
|
+
args: [varRef(handle.id, DYN, loc), numLit(which, loc), varRef(t.local, t.type, loc)],
|
|
158
|
+
type: VOID,
|
|
159
|
+
loc,
|
|
160
|
+
},
|
|
161
|
+
loc,
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
return { kind: "seqExpr", stmts, result: varRef(handle.id, DYN, loc), type: DYN, loc };
|
|
165
|
+
}
|
|
166
|
+
/** `c.log(...)` and the other output members on a stdlib-Console-typed
|
|
167
|
+
* receiver that is not the global console itself (that path keeps its
|
|
168
|
+
* direct console lowering): the receiver evaluates first, then the
|
|
169
|
+
* util.format rendering of the arguments, then one native write. */
|
|
170
|
+
export function lowerConsoleInstanceCall(lowerer, call, loc) {
|
|
171
|
+
if (call.questionDotToken || !ts.isPropertyAccessExpression(call.expression))
|
|
172
|
+
return null;
|
|
173
|
+
const access = call.expression;
|
|
174
|
+
if (access.questionDotToken)
|
|
175
|
+
return null;
|
|
176
|
+
const recvType = lowerer.typeOf(access.expression);
|
|
177
|
+
const sym = recvType.getAliasSymbol() ?? recvType.getSymbol();
|
|
178
|
+
if (!sym || sym.name !== "Console" || !lowerer.isStdlibSymbol(sym))
|
|
179
|
+
return null;
|
|
180
|
+
const toStderr = OUTPUT_MEMBERS.get(access.name.text);
|
|
181
|
+
if (toStderr === undefined) {
|
|
182
|
+
lowerer.noLowering(`Console.${access.name.text}`, call, "log, info, debug, error, and warn are the lowered Console members");
|
|
183
|
+
}
|
|
184
|
+
const receiver = lowerer.lowerExpr(access.expression);
|
|
185
|
+
if (receiver.type.kind !== "dyn")
|
|
186
|
+
return null;
|
|
187
|
+
const formatted = lowerFormatCall(lowerer, call, loc, false);
|
|
188
|
+
return {
|
|
189
|
+
kind: "libCall",
|
|
190
|
+
fn: "console.write",
|
|
191
|
+
args: [receiver, formatted, boolLit(toStderr, loc)],
|
|
192
|
+
type: VOID,
|
|
193
|
+
loc,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
/* ── the global console's output members ─────────────────────────────── */
|
|
197
|
+
/** One console argument, already lowered, in the shape the console
|
|
198
|
+
* intrinsics take: Node's formatter (formatWithOptions) prints strings
|
|
199
|
+
* verbatim, numbers and booleans directly, and everything else through
|
|
200
|
+
* util.inspect at the rest-args depth 2. */
|
|
201
|
+
export function lowerConsoleArg(lowerer, node, lowered, surface, loc) {
|
|
202
|
+
// Checked-dynamic values carry their own shape, so the runtime
|
|
203
|
+
// renders them exactly like Node's console formatter renders a
|
|
204
|
+
// non-format argument: strings VERBATIM, everything else through
|
|
205
|
+
// inspect at the rest-args depth 2 (formatWithOptions) — scalar
|
|
206
|
+
// kinds byte-exactly, boxed functions as [Function: name] /
|
|
207
|
+
// [Function (anonymous)], composites through the dyn walk
|
|
208
|
+
// (insp.dyn). Never throws — Node's console.log never does.
|
|
209
|
+
if (lowered.type.kind === "dyn") {
|
|
210
|
+
return {
|
|
211
|
+
kind: "libCall",
|
|
212
|
+
fn: "insp.dynS",
|
|
213
|
+
args: [lowered, numLit(2, loc)],
|
|
214
|
+
type: STRING,
|
|
215
|
+
loc,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
// A function VALUE prints Node's [Function: name] form by boxing
|
|
219
|
+
// across the checked-dynamic boundary (the box carries the
|
|
220
|
+
// best-effort reference-site name — the documented naming stance)
|
|
221
|
+
// and rendering through the same dyn arm.
|
|
222
|
+
if (lowered.type.kind === "func" &&
|
|
223
|
+
canBoxFuncIntoDyn(lowered.type, (id) => lowerer.shapes.get(id), (id) => lowerer.unions.get(id))) {
|
|
224
|
+
const name = jsFuncNameOf(node);
|
|
225
|
+
const boxed = {
|
|
226
|
+
kind: "dynFrom",
|
|
227
|
+
value: lowered,
|
|
228
|
+
type: DYN,
|
|
229
|
+
...(name !== null ? { fnName: name } : {}),
|
|
230
|
+
loc,
|
|
231
|
+
};
|
|
232
|
+
return {
|
|
233
|
+
kind: "libCall",
|
|
234
|
+
fn: "insp.dynS",
|
|
235
|
+
args: [boxed, numLit(2, loc)],
|
|
236
|
+
type: STRING,
|
|
237
|
+
loc,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
// number/string/boolean ride the ScrLogArg protocol directly (the
|
|
241
|
+
// runtime formats them Node-exactly — including -0).
|
|
242
|
+
if (lowered.type.kind === "f64" ||
|
|
243
|
+
lowered.type.kind === "string" ||
|
|
244
|
+
lowered.type.kind === "bool") {
|
|
245
|
+
return lowered;
|
|
246
|
+
}
|
|
247
|
+
// Everything else renders through the static inspect machinery at
|
|
248
|
+
// the rest-args depth 2 (formatWithOptions): arrays, records,
|
|
249
|
+
// unions (a string arm prints VERBATIM — the console.log vs
|
|
250
|
+
// inspect distinction, per arm), Maps/Sets, plain undefined/null,
|
|
251
|
+
// regexes, symbols, error values, Buffers. Shapes inspect cannot
|
|
252
|
+
// render fence honestly with the reason.
|
|
253
|
+
return lowerConsoleInspectArg(lowerer, node, lowerer.deferredFieldSlot(lowered) ?? lowered, surface, loc);
|
|
254
|
+
}
|
|
255
|
+
function consoleWrite(stdout, args, loc) {
|
|
256
|
+
return {
|
|
257
|
+
kind: "intrinsic",
|
|
258
|
+
name: stdout ? "console.log" : "console.error",
|
|
259
|
+
args,
|
|
260
|
+
type: VOID,
|
|
261
|
+
loc,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function hasFormatSpecifier(text) {
|
|
265
|
+
return /%[sdifjoOc%]/.test(text);
|
|
266
|
+
}
|
|
267
|
+
function isStringLiteralLike(node) {
|
|
268
|
+
return (node !== undefined && (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)));
|
|
269
|
+
}
|
|
270
|
+
/** console.log/info/debug (stdout) and console.error/warn (stderr), and
|
|
271
|
+
* the members Node defines as log (dirxml, group's label line): one
|
|
272
|
+
* formatted line through the console intrinsic. */
|
|
273
|
+
export function lowerConsoleOutput(lowerer, expr, stdout, surface, loc) {
|
|
274
|
+
// A LITERAL format string with %-specifiers and further arguments
|
|
275
|
+
// (`console.log('Mismatched %s function calls. Expected %s, actual
|
|
276
|
+
// %d.', name, seg, n)` — test/common's exit report): Node's console
|
|
277
|
+
// formatter IS util.format — route through the format lowering and
|
|
278
|
+
// print its one string. Specifier-free first strings keep the
|
|
279
|
+
// plain space-joined path below (identical output, cheaper).
|
|
280
|
+
const first = expr.arguments[0];
|
|
281
|
+
if (expr.arguments.length > 1 && isStringLiteralLike(first) && hasFormatSpecifier(first.text)) {
|
|
282
|
+
return consoleWrite(stdout, [lowerFormatCall(lowerer, expr, loc, false)], loc);
|
|
283
|
+
}
|
|
284
|
+
const args = expr.arguments.map((a) => lowerConsoleArg(lowerer, a, lowerer.lowerExpr(a), surface, loc));
|
|
285
|
+
return consoleWrite(stdout, args, loc);
|
|
286
|
+
}
|
|
287
|
+
/* ── the rest of the global console ──────────────────────────────────── */
|
|
288
|
+
function isUndefinedLiteral(node) {
|
|
289
|
+
return ts.isIdentifier(node) && node.text === "undefined";
|
|
290
|
+
}
|
|
291
|
+
/** Literals and identifier reads: evaluating one later, or not at all,
|
|
292
|
+
* is unobservable. */
|
|
293
|
+
function isPureArgument(node) {
|
|
294
|
+
return (ts.isIdentifier(node) ||
|
|
295
|
+
ts.isStringLiteral(node) ||
|
|
296
|
+
ts.isNoSubstitutionTemplateLiteral(node) ||
|
|
297
|
+
ts.isNumericLiteral(node) ||
|
|
298
|
+
node.kind === ts.SyntaxKind.TrueKeyword ||
|
|
299
|
+
node.kind === ts.SyntaxKind.FalseKeyword ||
|
|
300
|
+
node.kind === ts.SyntaxKind.NullKeyword);
|
|
301
|
+
}
|
|
302
|
+
/** Evaluate `value` into a fresh hidden local (Node evaluates every call
|
|
303
|
+
* argument before the method body runs) and answer a read of it. Unit
|
|
304
|
+
* values have no local: their effects run here and a literal stands in;
|
|
305
|
+
* void values pass through for the consumer's fence. */
|
|
306
|
+
function hoist(lowerer, stmts, name, value, loc) {
|
|
307
|
+
const k = value.type.kind;
|
|
308
|
+
if (k === "void")
|
|
309
|
+
return value;
|
|
310
|
+
if (k === "undefinedT" || k === "nullT") {
|
|
311
|
+
if (value.kind !== "unitLit")
|
|
312
|
+
stmts.push({ kind: "exprStmt", expr: value, loc });
|
|
313
|
+
return { kind: "unitLit", unit: k === "nullT" ? "null" : "undefined", type: value.type, loc };
|
|
314
|
+
}
|
|
315
|
+
const local = lowerer.declareHiddenLocal(name, value.type);
|
|
316
|
+
stmts.push({ kind: "varDecl", localId: local.id, init: value, loc });
|
|
317
|
+
return varRef(local.id, value.type, loc);
|
|
318
|
+
}
|
|
319
|
+
function seq(stmts, result, loc) {
|
|
320
|
+
return stmts.length === 0 ? result : { kind: "seqExpr", stmts, result, type: result.type, loc };
|
|
321
|
+
}
|
|
322
|
+
/** The tail of a lowering whose effects all sit in its statements. */
|
|
323
|
+
function noop(loc) {
|
|
324
|
+
return { kind: "libCall", fn: "console.noop", args: [], type: VOID, loc };
|
|
325
|
+
}
|
|
326
|
+
/** Arguments Node ignores still evaluate, in order. */
|
|
327
|
+
function evaluateIgnored(lowerer, args, stmts, loc) {
|
|
328
|
+
for (const arg of args) {
|
|
329
|
+
const value = lowerer.lowerExpr(arg);
|
|
330
|
+
if (value.kind !== "unitLit")
|
|
331
|
+
stmts.push({ kind: "exprStmt", expr: value, loc });
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
/** A label argument's value before coercion (`label = 'default'`):
|
|
335
|
+
* null when absent or the literal undefined. */
|
|
336
|
+
function rawLabel(lowerer, member, node) {
|
|
337
|
+
if (node === undefined || isUndefinedLiteral(node))
|
|
338
|
+
return null;
|
|
339
|
+
const value = lowerer.lowerExpr(node);
|
|
340
|
+
const t = value.type;
|
|
341
|
+
if (t.kind === "string" || t.kind === "dyn" || lowerer.dynConvertible(t)) {
|
|
342
|
+
if (t.kind !== "func" && t.kind !== "bytes")
|
|
343
|
+
return value;
|
|
344
|
+
}
|
|
345
|
+
return lowerer.noLowering(`console.${member} with a '${lowerer.fmt(t)}' label`, node, "labels are strings, numbers, booleans, null, or undefined");
|
|
346
|
+
}
|
|
347
|
+
/** Node's `${label}` over the defaulted label. */
|
|
348
|
+
function labelText(raw, loc) {
|
|
349
|
+
if (raw === null)
|
|
350
|
+
return strLit("default", loc);
|
|
351
|
+
if (raw.type.kind === "string")
|
|
352
|
+
return raw;
|
|
353
|
+
const boxed = raw.type.kind === "dyn" ? raw : { kind: "dynFrom", value: raw, type: DYN, loc };
|
|
354
|
+
return { kind: "libCall", fn: "console.label", args: [boxed], type: STRING, loc };
|
|
355
|
+
}
|
|
356
|
+
/** process.emitWarning(message) with Node's default type; an empty
|
|
357
|
+
* message (the runtime's "no warning applies" answer) emits nothing. */
|
|
358
|
+
function emitWarning(message, loc) {
|
|
359
|
+
return { kind: "libCall", fn: "process.emitWarningText", args: [message], type: VOID, loc };
|
|
360
|
+
}
|
|
361
|
+
function concat(parts, loc) {
|
|
362
|
+
return parts.reduce((left, right) => ({
|
|
363
|
+
kind: "strConcat",
|
|
364
|
+
left,
|
|
365
|
+
right,
|
|
366
|
+
type: STRING,
|
|
367
|
+
loc,
|
|
368
|
+
}));
|
|
369
|
+
}
|
|
370
|
+
/** console.timeEnd/timeLog: the label's elapsed time, Node's
|
|
371
|
+
* `${label}: ${formatTime(ms)}` line (timeLog appends its data the way
|
|
372
|
+
* log appends arguments after a format string), or the "No such label"
|
|
373
|
+
* warning. Every argument evaluates before the timer is read. */
|
|
374
|
+
function lowerConsoleTimeLog(lowerer, expr, member, loc) {
|
|
375
|
+
const stmts = [];
|
|
376
|
+
const raw = rawLabel(lowerer, member, expr.arguments[0]);
|
|
377
|
+
const rawRef = raw === null ? null : hoist(lowerer, stmts, "%consoleLabel", raw, loc);
|
|
378
|
+
const data = expr.arguments.slice(1);
|
|
379
|
+
const dataRefs = [];
|
|
380
|
+
if (member === "timeLog") {
|
|
381
|
+
for (const node of data) {
|
|
382
|
+
dataRefs.push({
|
|
383
|
+
node,
|
|
384
|
+
value: hoist(lowerer, stmts, "%consoleData", lowerer.lowerExpr(node), loc),
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
evaluateIgnored(lowerer, data, stmts, loc);
|
|
390
|
+
}
|
|
391
|
+
const label = hoist(lowerer, stmts, "%consoleLabelText", labelText(rawRef, loc), loc);
|
|
392
|
+
const elapsed = hoist(lowerer, stmts, "%consoleElapsed", {
|
|
393
|
+
kind: "libCall",
|
|
394
|
+
fn: member === "timeEnd" ? "console.timeEnd" : "console.timeLog",
|
|
395
|
+
args: [label],
|
|
396
|
+
type: STRING,
|
|
397
|
+
loc,
|
|
398
|
+
}, loc);
|
|
399
|
+
const line = concat([label, strLit(": ", loc), elapsed], loc);
|
|
400
|
+
const rendered = dataRefs.map(({ node, value }) => lowerConsoleArg(lowerer, node, value, `console.${member}`, loc));
|
|
401
|
+
const missing = {
|
|
402
|
+
kind: "strEq",
|
|
403
|
+
negated: false,
|
|
404
|
+
left: elapsed,
|
|
405
|
+
right: strLit("", loc),
|
|
406
|
+
type: BOOL,
|
|
407
|
+
loc,
|
|
408
|
+
};
|
|
409
|
+
stmts.push({
|
|
410
|
+
kind: "if",
|
|
411
|
+
cond: { kind: "unary", op: "!", operand: missing, type: BOOL, loc },
|
|
412
|
+
then: [{ kind: "exprStmt", expr: consoleWrite(true, [line, ...rendered], loc), loc }],
|
|
413
|
+
else_: null,
|
|
414
|
+
loc,
|
|
415
|
+
});
|
|
416
|
+
const warning = {
|
|
417
|
+
kind: "ternary",
|
|
418
|
+
cond: missing,
|
|
419
|
+
then: concat([strLit("No such label '", loc), label, strLit(`' for console.${member}()`, loc)], loc),
|
|
420
|
+
else_: strLit("", loc),
|
|
421
|
+
type: STRING,
|
|
422
|
+
loc,
|
|
423
|
+
};
|
|
424
|
+
return seq(stmts, emitWarning(warning, loc), loc);
|
|
425
|
+
}
|
|
426
|
+
/** console.assert(value, ...message): on a falsy value, Node prefixes a
|
|
427
|
+
* string first argument with "Assertion failed: " (or inserts
|
|
428
|
+
* "Assertion failed" before a non-string one) and prints through warn —
|
|
429
|
+
* so a format string still formats. */
|
|
430
|
+
function lowerConsoleAssert(lowerer, expr, loc) {
|
|
431
|
+
const stmts = [];
|
|
432
|
+
const [valueNode, ...args] = expr.arguments;
|
|
433
|
+
const ok = valueNode === undefined
|
|
434
|
+
? boolLit(false, loc)
|
|
435
|
+
: hoist(lowerer, stmts, "%consoleAssert", lowerer.lowerCondition(valueNode), loc);
|
|
436
|
+
const first = args[0];
|
|
437
|
+
let failed;
|
|
438
|
+
if (isStringLiteralLike(first) && args.length > 1 && hasFormatSpecifier(first.text)) {
|
|
439
|
+
// The format path lowers its arguments inside the failing branch;
|
|
440
|
+
// that is only exact when skipping their evaluation is unobservable.
|
|
441
|
+
const effectful = args.find((a) => !isPureArgument(a));
|
|
442
|
+
if (effectful !== undefined) {
|
|
443
|
+
lowerer.noLowering("console.assert with a format string and computed arguments", effectful, "evaluate the argument first (const v = ...) and pass the binding");
|
|
444
|
+
}
|
|
445
|
+
failed = consoleWrite(false, [lowerFormatCall(lowerer, expr, loc, false, args, "Assertion failed: ")], loc);
|
|
446
|
+
}
|
|
447
|
+
else {
|
|
448
|
+
const values = args.map((node) => ({
|
|
449
|
+
node,
|
|
450
|
+
value: hoist(lowerer, stmts, "%consoleData", lowerer.lowerExpr(node), loc),
|
|
451
|
+
}));
|
|
452
|
+
const head = values[0];
|
|
453
|
+
let rendered;
|
|
454
|
+
if (head !== undefined && head.value.type.kind === "string") {
|
|
455
|
+
if (values.length > 1 && !isStringLiteralLike(head.node)) {
|
|
456
|
+
lowerer.noLowering("console.assert with a runtime format string and further arguments", head.node, "the %-substitution positions are runtime-dependent — use a string literal");
|
|
457
|
+
}
|
|
458
|
+
rendered = [
|
|
459
|
+
concat([strLit("Assertion failed: ", loc), head.value], loc),
|
|
460
|
+
...values
|
|
461
|
+
.slice(1)
|
|
462
|
+
.map(({ node, value }) => lowerConsoleArg(lowerer, node, value, "console.assert", loc)),
|
|
463
|
+
];
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
if (head !== undefined && head.value.type.kind !== "dyn") {
|
|
467
|
+
const t = head.value.type;
|
|
468
|
+
if (t.kind === "union") {
|
|
469
|
+
const def = lowerer.unions.get(t.unionId);
|
|
470
|
+
if (def?.arms.some((arm) => arm.kind === "string")) {
|
|
471
|
+
lowerer.noLowering("console.assert with a first message argument that may be a string", head.node, "Node prefixes string messages and inserts a separate prefix otherwise — narrow the message type");
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
if (head !== undefined && head.value.type.kind === "dyn") {
|
|
476
|
+
lowerer.noLowering("console.assert with an untyped first message argument", head.node, "Node prefixes string messages and inserts a separate prefix otherwise — narrow the message type");
|
|
477
|
+
}
|
|
478
|
+
rendered = [
|
|
479
|
+
strLit("Assertion failed", loc),
|
|
480
|
+
...values.map(({ node, value }) => lowerConsoleArg(lowerer, node, value, "console.assert", loc)),
|
|
481
|
+
];
|
|
482
|
+
}
|
|
483
|
+
failed = consoleWrite(false, rendered, loc);
|
|
484
|
+
}
|
|
485
|
+
stmts.push({
|
|
486
|
+
kind: "if",
|
|
487
|
+
cond: { kind: "unary", op: "!", operand: ok, type: BOOL, loc },
|
|
488
|
+
then: [{ kind: "exprStmt", expr: failed, loc }],
|
|
489
|
+
else_: null,
|
|
490
|
+
loc,
|
|
491
|
+
});
|
|
492
|
+
return seq(stmts, noop(loc), loc);
|
|
493
|
+
}
|
|
494
|
+
/** console.table(tabularData[, properties]): primitives print like
|
|
495
|
+
* log; objects, arrays, and checked-dynamic values render Node's table
|
|
496
|
+
* in the runtime (cli_table's layout over util.inspect cells). */
|
|
497
|
+
function lowerConsoleTable(lowerer, expr, loc) {
|
|
498
|
+
const stmts = [];
|
|
499
|
+
const [dataNode, propsNode, ...rest] = expr.arguments;
|
|
500
|
+
if (dataNode === undefined)
|
|
501
|
+
return consoleWrite(true, [strLit("undefined", loc)], loc);
|
|
502
|
+
let data = lowerer.lowerExpr(dataNode);
|
|
503
|
+
let props = propsNode === undefined || isUndefinedLiteral(propsNode) ? null : lowerer.lowerExpr(propsNode);
|
|
504
|
+
if (rest.length > 0) {
|
|
505
|
+
// The ignored arguments evaluate after the two the table reads.
|
|
506
|
+
data = hoist(lowerer, stmts, "%consoleTable", data, loc);
|
|
507
|
+
if (props !== null)
|
|
508
|
+
props = hoist(lowerer, stmts, "%consoleTableProps", props, loc);
|
|
509
|
+
evaluateIgnored(lowerer, rest, stmts, loc);
|
|
510
|
+
}
|
|
511
|
+
const t = data.type;
|
|
512
|
+
if (props === null &&
|
|
513
|
+
(t.kind === "f64" ||
|
|
514
|
+
t.kind === "string" ||
|
|
515
|
+
t.kind === "bool" ||
|
|
516
|
+
t.kind === "undefinedT" ||
|
|
517
|
+
t.kind === "nullT")) {
|
|
518
|
+
// Node: `if (tabularData === null || typeof tabularData !== 'object')
|
|
519
|
+
// return this.log(tabularData)`.
|
|
520
|
+
return seq(stmts, consoleWrite(true, [lowerConsoleArg(lowerer, dataNode, data, "console.table", loc)], loc), loc);
|
|
521
|
+
}
|
|
522
|
+
const boxable = t.kind === "dyn" ||
|
|
523
|
+
(t.kind !== "func" &&
|
|
524
|
+
t.kind !== "bytes" &&
|
|
525
|
+
t.kind !== "map" &&
|
|
526
|
+
t.kind !== "set" &&
|
|
527
|
+
lowerer.dynConvertible(t));
|
|
528
|
+
if (!boxable) {
|
|
529
|
+
lowerer.noLowering(`console.table of '${lowerer.fmt(t)}' values`, dataNode, "arrays, plain objects, and their JSON-shaped contents are the lowered tables");
|
|
530
|
+
}
|
|
531
|
+
if (props !== null) {
|
|
532
|
+
const pt = props.type;
|
|
533
|
+
if (!(pt.kind === "array" && pt.elem.kind === "string")) {
|
|
534
|
+
lowerer.noLowering(`console.table with a '${lowerer.fmt(pt)}' properties argument`, propsNode, "pass an array of property names");
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
const box = (v) => v.type.kind === "dyn" ? v : { kind: "dynFrom", value: v, type: DYN, loc };
|
|
538
|
+
const call = {
|
|
539
|
+
kind: "libCall",
|
|
540
|
+
fn: "console.table",
|
|
541
|
+
args: [box(data), props === null ? dynUndefinedExpr(loc) : box(props)],
|
|
542
|
+
type: VOID,
|
|
543
|
+
loc,
|
|
544
|
+
};
|
|
545
|
+
return seq(stmts, call, loc);
|
|
546
|
+
}
|
|
547
|
+
/** console.<member>(...) on the global console for the members past the
|
|
548
|
+
* output set. */
|
|
549
|
+
export function lowerConsoleMethodCall(lowerer, expr, member, loc) {
|
|
550
|
+
const args = expr.arguments;
|
|
551
|
+
switch (member) {
|
|
552
|
+
case "dirxml":
|
|
553
|
+
return lowerConsoleOutput(lowerer, expr, true, "console.dirxml", loc);
|
|
554
|
+
case "group":
|
|
555
|
+
case "groupCollapsed": {
|
|
556
|
+
const indent = {
|
|
557
|
+
kind: "libCall",
|
|
558
|
+
fn: "console.group",
|
|
559
|
+
args: [numLit(1, loc)],
|
|
560
|
+
type: VOID,
|
|
561
|
+
loc,
|
|
562
|
+
};
|
|
563
|
+
if (args.length === 0)
|
|
564
|
+
return indent;
|
|
565
|
+
const label = lowerConsoleOutput(lowerer, expr, true, `console.${member}`, loc);
|
|
566
|
+
return seq([{ kind: "exprStmt", expr: label, loc }], indent, loc);
|
|
567
|
+
}
|
|
568
|
+
case "groupEnd": {
|
|
569
|
+
const stmts = [];
|
|
570
|
+
evaluateIgnored(lowerer, args, stmts, loc);
|
|
571
|
+
return seq(stmts, { kind: "libCall", fn: "console.group", args: [numLit(-1, loc)], type: VOID, loc }, loc);
|
|
572
|
+
}
|
|
573
|
+
case "count": {
|
|
574
|
+
const stmts = [];
|
|
575
|
+
const raw = rawLabel(lowerer, member, args[0]);
|
|
576
|
+
const rawRef = raw === null ? null : hoist(lowerer, stmts, "%consoleLabel", raw, loc);
|
|
577
|
+
evaluateIgnored(lowerer, args.slice(1), stmts, loc);
|
|
578
|
+
return seq(stmts, { kind: "libCall", fn: "console.count", args: [labelText(rawRef, loc)], type: VOID, loc }, loc);
|
|
579
|
+
}
|
|
580
|
+
case "countReset": {
|
|
581
|
+
const stmts = [];
|
|
582
|
+
const raw = rawLabel(lowerer, member, args[0]);
|
|
583
|
+
const rawRef = raw === null ? null : hoist(lowerer, stmts, "%consoleLabel", raw, loc);
|
|
584
|
+
evaluateIgnored(lowerer, args.slice(1), stmts, loc);
|
|
585
|
+
// Node looks the RAW label up (`counts.has(label)`) and deletes its
|
|
586
|
+
// string form: only string labels (and the default) ever reset.
|
|
587
|
+
const boxed = rawRef === null
|
|
588
|
+
? dynUndefinedExpr(loc)
|
|
589
|
+
: rawRef.type.kind === "dyn"
|
|
590
|
+
? rawRef
|
|
591
|
+
: { kind: "dynFrom", value: rawRef, type: DYN, loc };
|
|
592
|
+
return seq(stmts, emitWarning({ kind: "libCall", fn: "console.countReset", args: [boxed], type: STRING, loc }, loc), loc);
|
|
593
|
+
}
|
|
594
|
+
case "time": {
|
|
595
|
+
const stmts = [];
|
|
596
|
+
const raw = rawLabel(lowerer, member, args[0]);
|
|
597
|
+
const rawRef = raw === null ? null : hoist(lowerer, stmts, "%consoleLabel", raw, loc);
|
|
598
|
+
evaluateIgnored(lowerer, args.slice(1), stmts, loc);
|
|
599
|
+
return seq(stmts, emitWarning({
|
|
600
|
+
kind: "libCall",
|
|
601
|
+
fn: "console.time",
|
|
602
|
+
args: [labelText(rawRef, loc)],
|
|
603
|
+
type: STRING,
|
|
604
|
+
loc,
|
|
605
|
+
}, loc), loc);
|
|
606
|
+
}
|
|
607
|
+
case "timeEnd":
|
|
608
|
+
case "timeLog":
|
|
609
|
+
return lowerConsoleTimeLog(lowerer, expr, member, loc);
|
|
610
|
+
case "assert":
|
|
611
|
+
return lowerConsoleAssert(lowerer, expr, loc);
|
|
612
|
+
case "dir": {
|
|
613
|
+
const stmts = [];
|
|
614
|
+
const [valueNode, optionsNode, ...rest] = args;
|
|
615
|
+
const rendered = valueNode === undefined
|
|
616
|
+
? strLit("undefined", loc)
|
|
617
|
+
: lowerInspectValue(lowerer, valueNode, optionsNode, loc, true);
|
|
618
|
+
if (rest.length === 0)
|
|
619
|
+
return consoleWrite(true, [rendered], loc);
|
|
620
|
+
const text = hoist(lowerer, stmts, "%consoleDir", rendered, loc);
|
|
621
|
+
evaluateIgnored(lowerer, rest, stmts, loc);
|
|
622
|
+
return seq(stmts, consoleWrite(true, [text], loc), loc);
|
|
623
|
+
}
|
|
624
|
+
case "table":
|
|
625
|
+
return lowerConsoleTable(lowerer, expr, loc);
|
|
626
|
+
case "clear": {
|
|
627
|
+
const stmts = [];
|
|
628
|
+
evaluateIgnored(lowerer, args, stmts, loc);
|
|
629
|
+
return seq(stmts, { kind: "libCall", fn: "console.clear", args: [], type: VOID, loc }, loc);
|
|
630
|
+
}
|
|
631
|
+
case "profile":
|
|
632
|
+
case "profileEnd":
|
|
633
|
+
case "timeStamp": {
|
|
634
|
+
// Inspector-only: without an attached session these print nothing.
|
|
635
|
+
// V8 still converts the first argument to a string, so only
|
|
636
|
+
// primitive arguments lower.
|
|
637
|
+
const stmts = [];
|
|
638
|
+
for (const arg of args) {
|
|
639
|
+
const value = lowerer.lowerExpr(arg);
|
|
640
|
+
const k = value.type.kind;
|
|
641
|
+
if (k !== "string" && k !== "f64" && k !== "bool" && k !== "undefinedT" && k !== "nullT") {
|
|
642
|
+
lowerer.noLowering(`console.${member} with a '${lowerer.fmt(value.type)}' argument`, arg, "pass a string label");
|
|
643
|
+
}
|
|
644
|
+
if (value.kind !== "unitLit")
|
|
645
|
+
stmts.push({ kind: "exprStmt", expr: value, loc });
|
|
646
|
+
}
|
|
647
|
+
return seq(stmts, noop(loc), loc);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
//# sourceMappingURL=lower-console.js.map
|