@scriptc/compiler 0.2.6 → 0.2.8
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 -18
- package/dist/backend/cycle-analysis.d.ts +21 -9
- package/dist/backend/cycle-analysis.js +139 -67
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/cycle-analysis.test.js +283 -3
- package/dist/backend/cycle-analysis.test.js.map +1 -1
- package/dist/backend/cycle-mutability.d.ts +39 -0
- package/dist/backend/cycle-mutability.js +205 -0
- package/dist/backend/cycle-mutability.js.map +1 -0
- package/dist/backend/link-plan-core.d.ts +2 -1
- package/dist/backend/link-plan-core.js +15 -3
- package/dist/backend/link-plan-core.js.map +1 -1
- package/dist/backend/link-plan.d.ts +2 -1
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/llvm/alloc.d.ts +43 -0
- package/dist/backend/llvm/alloc.js +246 -0
- package/dist/backend/llvm/alloc.js.map +1 -0
- package/dist/backend/llvm/alloc.test.d.ts +1 -0
- package/dist/backend/llvm/alloc.test.js +102 -0
- package/dist/backend/llvm/alloc.test.js.map +1 -0
- package/dist/backend/llvm/blocks.d.ts +9 -0
- package/dist/backend/llvm/blocks.js +9 -0
- package/dist/backend/llvm/blocks.js.map +1 -1
- package/dist/backend/llvm/borrowed-receivers.d.ts +7 -0
- package/dist/backend/llvm/borrowed-receivers.js +39 -0
- package/dist/backend/llvm/borrowed-receivers.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.d.ts +18 -3
- package/dist/backend/llvm/call-lifetimes.js +54 -19
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +178 -3
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/checked-narrows.d.ts +24 -0
- package/dist/backend/llvm/checked-narrows.js +108 -0
- package/dist/backend/llvm/checked-narrows.js.map +1 -0
- package/dist/backend/llvm/checked-narrows.test.d.ts +1 -0
- package/dist/backend/llvm/checked-narrows.test.js +208 -0
- package/dist/backend/llvm/checked-narrows.test.js.map +1 -0
- package/dist/backend/llvm/classes.d.ts +16 -1
- package/dist/backend/llvm/classes.js +60 -49
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +68 -6
- package/dist/backend/llvm/classes.test.js.map +1 -1
- package/dist/backend/llvm/common.d.ts +13 -0
- package/dist/backend/llvm/common.js +30 -0
- package/dist/backend/llvm/common.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.d.ts +19 -3
- package/dist/backend/llvm/constant-callbacks.js +289 -52
- package/dist/backend/llvm/constant-callbacks.js.map +1 -1
- package/dist/backend/llvm/constant-callbacks.test.js +140 -3
- package/dist/backend/llvm/constant-callbacks.test.js.map +1 -1
- package/dist/backend/llvm/debug-info.d.ts +6 -2
- package/dist/backend/llvm/debug-info.js +11 -1
- package/dist/backend/llvm/debug-info.js.map +1 -1
- package/dist/backend/llvm/dense-array-access.d.ts +29 -0
- package/dist/backend/llvm/dense-array-access.js +335 -0
- package/dist/backend/llvm/dense-array-access.js.map +1 -0
- package/dist/backend/llvm/dense-array-access.test.d.ts +1 -0
- package/dist/backend/llvm/dense-array-access.test.js +238 -0
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +38 -0
- package/dist/backend/llvm/dyn.js +213 -14
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +308 -15
- package/dist/backend/llvm/emitter.js +1788 -206
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +89 -7
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +62 -8
- package/dist/backend/llvm/expr-async.js.map +1 -1
- package/dist/backend/llvm/expr-async.test.d.ts +1 -0
- package/dist/backend/llvm/expr-async.test.js +62 -0
- package/dist/backend/llvm/expr-async.test.js.map +1 -0
- package/dist/backend/llvm/expr-bytes.d.ts +1 -1
- package/dist/backend/llvm/expr-bytes.js +85 -8
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.js +29 -21
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-calls.d.ts +5 -0
- package/dist/backend/llvm/expr-calls.js +118 -15
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +7 -1
- package/dist/backend/llvm/expr-containers.js +246 -32
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +113 -8
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dispatch.js +2 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +244 -44
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-island.js +3 -8
- package/dist/backend/llvm/expr-island.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +93 -36
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +51 -3
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -1
- package/dist/backend/llvm/expr-records.js +31 -17
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +96 -29
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
- package/dist/backend/llvm/expr-stream-callbacks.js +6 -3
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/integer-remainder.d.ts +11 -0
- package/dist/backend/llvm/integer-remainder.js +91 -0
- package/dist/backend/llvm/integer-remainder.js.map +1 -1
- package/dist/backend/llvm/layouts.d.ts +3 -1
- package/dist/backend/llvm/layouts.js +3 -2
- package/dist/backend/llvm/layouts.js.map +1 -1
- package/dist/backend/llvm/lazy-captures.d.ts +16 -0
- package/dist/backend/llvm/lazy-captures.js +96 -0
- package/dist/backend/llvm/lazy-captures.js.map +1 -0
- package/dist/backend/llvm/lazy-captures.test.d.ts +1 -0
- package/dist/backend/llvm/lazy-captures.test.js +78 -0
- package/dist/backend/llvm/lazy-captures.test.js.map +1 -0
- package/dist/backend/llvm/lib-abi.js +10 -0
- package/dist/backend/llvm/lib-abi.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +10 -15
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +8 -8
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +1 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.d.ts +5 -1
- package/dist/backend/llvm/local-array-reads.js +147 -26
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +85 -4
- package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.d.ts +5 -1
- package/dist/backend/llvm/local-union-storage.js +54 -8
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +94 -6
- package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
- package/dist/backend/llvm/map-number-lookup.d.ts +18 -0
- package/dist/backend/llvm/map-number-lookup.js +62 -0
- package/dist/backend/llvm/map-number-lookup.js.map +1 -0
- package/dist/backend/llvm/map-read-lifetimes.d.ts +6 -0
- package/dist/backend/llvm/map-read-lifetimes.js +24 -3
- package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.test.js +39 -20
- package/dist/backend/llvm/map-read-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/nullable-fields.d.ts +28 -0
- package/dist/backend/llvm/nullable-fields.js +45 -0
- package/dist/backend/llvm/nullable-fields.js.map +1 -0
- package/dist/backend/llvm/nullable-fields.test.d.ts +1 -0
- package/dist/backend/llvm/nullable-fields.test.js +48 -0
- package/dist/backend/llvm/nullable-fields.test.js.map +1 -0
- package/dist/backend/llvm/nullable-unions.d.ts +68 -0
- package/dist/backend/llvm/nullable-unions.js +132 -0
- package/dist/backend/llvm/nullable-unions.js.map +1 -0
- package/dist/backend/llvm/publish.d.ts +58 -0
- package/dist/backend/llvm/publish.js +286 -0
- package/dist/backend/llvm/publish.js.map +1 -0
- package/dist/backend/llvm/rebound-parameters.d.ts +12 -0
- package/dist/backend/llvm/rebound-parameters.js +72 -0
- package/dist/backend/llvm/rebound-parameters.js.map +1 -0
- package/dist/backend/llvm/rebound-parameters.test.d.ts +1 -0
- package/dist/backend/llvm/rebound-parameters.test.js +67 -0
- package/dist/backend/llvm/rebound-parameters.test.js.map +1 -0
- package/dist/backend/llvm/reference-effects.d.ts +18 -2
- package/dist/backend/llvm/reference-effects.js +106 -16
- package/dist/backend/llvm/reference-effects.js.map +1 -1
- package/dist/backend/llvm/reference-effects.test.js +52 -1
- package/dist/backend/llvm/reference-effects.test.js.map +1 -1
- package/dist/backend/llvm/serialized-ir-emission.test.d.ts +1 -0
- package/dist/backend/llvm/serialized-ir-emission.test.js +52 -0
- package/dist/backend/llvm/serialized-ir-emission.test.js.map +1 -0
- package/dist/backend/llvm/shapes.d.ts +104 -9
- package/dist/backend/llvm/shapes.js +356 -46
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +139 -5
- package/dist/backend/llvm/shapes.test.js.map +1 -1
- package/dist/backend/llvm/stack-callbacks.js +2 -3
- package/dist/backend/llvm/stack-callbacks.js.map +1 -1
- package/dist/backend/llvm/stack-captures.d.ts +3 -1
- package/dist/backend/llvm/stack-captures.js +5 -3
- package/dist/backend/llvm/stack-captures.js.map +1 -1
- package/dist/backend/llvm/stack-unions.test.js +43 -3
- package/dist/backend/llvm/stack-unions.test.js.map +1 -1
- package/dist/backend/llvm/string-construction.d.ts +10 -0
- package/dist/backend/llvm/string-construction.js +42 -0
- package/dist/backend/llvm/string-construction.js.map +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-key-hash.d.ts +15 -0
- package/dist/backend/llvm/string-key-hash.js +76 -0
- package/dist/backend/llvm/string-key-hash.js.map +1 -0
- package/dist/backend/llvm/string-key-hash.test.d.ts +1 -0
- package/dist/backend/llvm/string-key-hash.test.js +45 -0
- package/dist/backend/llvm/string-key-hash.test.js.map +1 -0
- package/dist/backend/llvm/string-lifetimes.test.js +65 -15
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/string-reads.d.ts +7 -0
- package/dist/backend/llvm/string-reads.js +76 -0
- package/dist/backend/llvm/string-reads.js.map +1 -0
- package/dist/backend/llvm/switch-dispatch.js +1 -1
- package/dist/backend/llvm/switch-dispatch.js.map +1 -1
- package/dist/backend/llvm/switch-dispatch.test.js +3 -3
- package/dist/backend/llvm/switch-dispatch.test.js.map +1 -1
- package/dist/backend/llvm/test-boxed-unions.d.ts +5 -0
- package/dist/backend/llvm/test-boxed-unions.js +13 -0
- package/dist/backend/llvm/test-boxed-unions.js.map +1 -0
- package/dist/backend/llvm/union-repr.d.ts +15 -0
- package/dist/backend/llvm/union-repr.js +89 -0
- package/dist/backend/llvm/union-repr.js.map +1 -0
- package/dist/backend/llvm/virtual-borrows.d.ts +31 -0
- package/dist/backend/llvm/virtual-borrows.js +82 -0
- package/dist/backend/llvm/virtual-borrows.js.map +1 -0
- package/dist/backend/llvm/walk-borrows.d.ts +43 -0
- package/dist/backend/llvm/walk-borrows.js +150 -0
- package/dist/backend/llvm/walk-borrows.js.map +1 -0
- package/dist/backend/llvm/walk-borrows.test.d.ts +1 -0
- package/dist/backend/llvm/walk-borrows.test.js +119 -0
- package/dist/backend/llvm/walk-borrows.test.js.map +1 -0
- package/dist/backend/llvm/walkers.d.ts +5 -1
- package/dist/backend/llvm/walkers.js +24 -21
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/backend/may-throw.d.ts +29 -1
- package/dist/backend/may-throw.js +349 -3
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +114 -2
- package/dist/backend/may-throw.test.js.map +1 -1
- package/dist/backend/native/cache-warm.d.ts +2 -1
- package/dist/backend/native/cache-warm.js.map +1 -1
- package/dist/backend/native/contracts.d.ts +3 -2
- package/dist/backend/native/contracts.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-codegen-core.d.ts +7 -4
- package/dist/backend/native-codegen-core.js +14 -9
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +9 -0
- package/dist/backend/native-codegen.js +53 -2
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +64 -10
- package/dist/backend/native-codegen.test.js.map +1 -1
- package/dist/backend/native-link-info-core.d.ts +3 -2
- package/dist/backend/native-link-info-core.js.map +1 -1
- package/dist/backend/native-link-info.d.ts +2 -1
- package/dist/backend/native-link-info.js.map +1 -1
- package/dist/backend/native-link-info.test.js +2 -2
- package/dist/backend/native-link-info.test.js.map +1 -1
- package/dist/backend/native-tools.d.ts +5 -1
- package/dist/backend/native-tools.js +3 -1
- package/dist/backend/native-tools.js.map +1 -1
- package/dist/backend/optimization.d.ts +25 -0
- package/dist/backend/optimization.js +21 -0
- package/dist/backend/optimization.js.map +1 -0
- package/dist/backend/optimization.test.d.ts +1 -0
- package/dist/backend/optimization.test.js +24 -0
- package/dist/backend/optimization.test.js.map +1 -0
- package/dist/backend/publication.d.ts +28 -0
- package/dist/backend/publication.js +155 -0
- package/dist/backend/publication.js.map +1 -0
- package/dist/backend/publication.test.d.ts +1 -0
- package/dist/backend/publication.test.js +72 -0
- package/dist/backend/publication.test.js.map +1 -0
- 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 +15 -4
- package/dist/backend/runtime-pack-core.js +23 -12
- package/dist/backend/runtime-pack-core.js.map +1 -1
- package/dist/backend/runtime-pack-native.d.ts +7 -3
- package/dist/backend/runtime-pack-native.js +0 -3
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack.d.ts +20 -2
- package/dist/backend/runtime-pack.js +23 -0
- package/dist/backend/runtime-pack.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +115 -2
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/target-diagnostics.test.js +1 -1
- package/dist/backend/targets.d.ts +2 -1
- package/dist/backend/targets.js +1 -1
- package/dist/backend/targets.js.map +1 -1
- package/dist/cli/command.js +75 -11
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/host.d.ts +2 -1
- package/dist/cli/usage.d.ts +4 -1
- package/dist/cli/usage.js +13 -3
- package/dist/cli/usage.js.map +1 -1
- package/dist/compile-types.d.ts +17 -5
- package/dist/coverage/report.d.ts +25 -2
- package/dist/coverage/report.js +161 -33
- package/dist/coverage/report.js.map +1 -1
- package/dist/coverage/verdict-cache.d.ts +63 -0
- package/dist/coverage/verdict-cache.js +193 -0
- package/dist/coverage/verdict-cache.js.map +1 -0
- package/dist/coverage/verdict-cache.test.d.ts +1 -0
- package/dist/coverage/verdict-cache.test.js +52 -0
- package/dist/coverage/verdict-cache.test.js.map +1 -0
- package/dist/coverage/verdict-semantic.d.ts +2 -0
- package/dist/coverage/verdict-semantic.js +24 -0
- package/dist/coverage/verdict-semantic.js.map +1 -0
- package/dist/coverage/verdict-startup.d.ts +15 -0
- package/dist/coverage/verdict-startup.js +66 -0
- package/dist/coverage/verdict-startup.js.map +1 -0
- package/dist/diagnostics/diagnostic.d.ts +29 -1
- package/dist/diagnostics/diagnostic.js +84 -12
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/diagnostics/envelope.d.ts +130 -0
- package/dist/diagnostics/envelope.js +257 -0
- package/dist/diagnostics/envelope.js.map +1 -0
- package/dist/diagnostics/envelope.test.d.ts +1 -0
- package/dist/diagnostics/envelope.test.js +91 -0
- package/dist/diagnostics/envelope.test.js.map +1 -0
- package/dist/diagnostics/render.d.ts +3 -0
- package/dist/diagnostics/render.js +13 -2
- package/dist/diagnostics/render.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +2 -2
- package/dist/executable/executable-cache.js +7 -4
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +20 -0
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/executable/prepare.d.ts +4 -0
- package/dist/executable/prepare.js +7 -1
- package/dist/executable/prepare.js.map +1 -1
- package/dist/frontend/analysis.js +1 -0
- package/dist/frontend/analysis.js.map +1 -1
- package/dist/frontend/lowering/abstract-equality.js +5 -49
- package/dist/frontend/lowering/abstract-equality.js.map +1 -1
- package/dist/frontend/lowering/array-values.d.ts +30 -0
- package/dist/frontend/lowering/array-values.js +246 -1
- package/dist/frontend/lowering/array-values.js.map +1 -1
- package/dist/frontend/lowering/builtins/errors.js +17 -2
- package/dist/frontend/lowering/builtins/errors.js.map +1 -1
- package/dist/frontend/lowering/builtins/numbers.js +29 -1
- package/dist/frontend/lowering/builtins/numbers.js.map +1 -1
- package/dist/frontend/lowering/builtins/process.d.ts +10 -17
- package/dist/frontend/lowering/builtins/process.js +66 -29
- package/dist/frontend/lowering/builtins/process.js.map +1 -1
- package/dist/frontend/lowering/builtins/workers.js +4 -2
- package/dist/frontend/lowering/builtins/workers.js.map +1 -1
- package/dist/frontend/lowering/caught-value-dispatch.d.ts +11 -0
- package/dist/frontend/lowering/caught-value-dispatch.js +87 -0
- package/dist/frontend/lowering/caught-value-dispatch.js.map +1 -0
- package/dist/frontend/lowering/class-assertions.d.ts +12 -0
- package/dist/frontend/lowering/class-assertions.js +229 -5
- package/dist/frontend/lowering/class-assertions.js.map +1 -1
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -3
- package/dist/frontend/lowering/class-callbacks.js +18 -5
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +1 -0
- package/dist/frontend/lowering/class-dynamic-dispatch.js +12 -6
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-method-mutations.d.ts +5 -0
- package/dist/frontend/lowering/class-method-mutations.js +472 -0
- package/dist/frontend/lowering/class-method-mutations.js.map +1 -0
- package/dist/frontend/lowering/class-method-values.js +25 -5
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.js +8 -2
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-unions.d.ts +16 -0
- package/dist/frontend/lowering/class-unions.js +127 -0
- package/dist/frontend/lowering/class-unions.js.map +1 -0
- package/dist/frontend/lowering/coercions/builders.js +8 -1
- package/dist/frontend/lowering/coercions/builders.js.map +1 -1
- package/dist/frontend/lowering/coercions/function-adapters.js +2 -0
- package/dist/frontend/lowering/coercions/function-adapters.js.map +1 -1
- package/dist/frontend/lowering/coercions/identity.d.ts +7 -0
- package/dist/frontend/lowering/coercions/identity.js +26 -0
- package/dist/frontend/lowering/coercions/identity.js.map +1 -0
- package/dist/frontend/lowering/coercions/state.d.ts +6 -0
- package/dist/frontend/lowering/coercions/state.js +2 -0
- package/dist/frontend/lowering/coercions/state.js.map +1 -1
- package/dist/frontend/lowering/coercions/structural.js +9 -6
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- package/dist/frontend/lowering/coercions/unions.d.ts +8 -0
- package/dist/frontend/lowering/coercions/unions.js +67 -2
- package/dist/frontend/lowering/coercions/unions.js.map +1 -1
- package/dist/frontend/lowering/collation-repertoire.d.ts +1 -0
- package/dist/frontend/lowering/collation-repertoire.js +19 -0
- package/dist/frontend/lowering/collation-repertoire.js.map +1 -0
- package/dist/frontend/lowering/collection-narrowing.d.ts +6 -0
- package/dist/frontend/lowering/collection-narrowing.js +31 -0
- package/dist/frontend/lowering/collection-narrowing.js.map +1 -0
- package/dist/frontend/lowering/construction-escapes.d.ts +38 -0
- package/dist/frontend/lowering/construction-escapes.js +146 -0
- package/dist/frontend/lowering/construction-escapes.js.map +1 -0
- package/dist/frontend/lowering/construction-escapes.test.d.ts +1 -0
- package/dist/frontend/lowering/construction-escapes.test.js +150 -0
- package/dist/frontend/lowering/construction-escapes.test.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callback-call.d.ts +7 -0
- package/dist/frontend/lowering/containers/array-callback-call.js +52 -0
- package/dist/frontend/lowering/containers/array-callback-call.js.map +1 -0
- package/dist/frontend/lowering/containers/array-callbacks.d.ts +1 -1
- package/dist/frontend/lowering/containers/array-callbacks.js +416 -65
- package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
- package/dist/frontend/lowering/containers/array-concat.d.ts +7 -0
- package/dist/frontend/lowering/containers/array-concat.js +130 -0
- package/dist/frontend/lowering/containers/array-concat.js.map +1 -0
- package/dist/frontend/lowering/containers/array-construction.d.ts +2 -0
- package/dist/frontend/lowering/containers/array-construction.js +110 -5
- package/dist/frontend/lowering/containers/array-construction.js.map +1 -1
- package/dist/frontend/lowering/containers/array-methods.d.ts +1 -11
- package/dist/frontend/lowering/containers/array-methods.js +274 -144
- package/dist/frontend/lowering/containers/array-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/callback-arguments.js +43 -1
- package/dist/frontend/lowering/containers/callback-arguments.js.map +1 -1
- package/dist/frontend/lowering/containers/collection-methods.js +10 -1
- package/dist/frontend/lowering/containers/collection-methods.js.map +1 -1
- package/dist/frontend/lowering/containers/indexed-objects.js +56 -70
- package/dist/frontend/lowering/containers/indexed-objects.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js +7 -63
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/cycle-initialization.d.ts +46 -0
- package/dist/frontend/lowering/cycle-initialization.js +303 -0
- package/dist/frontend/lowering/cycle-initialization.js.map +1 -0
- package/dist/frontend/lowering/divergences.d.ts +9 -0
- package/dist/frontend/lowering/divergences.js +630 -0
- package/dist/frontend/lowering/divergences.js.map +1 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js +4 -0
- package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +178 -34
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/union-field-write.d.ts +4 -4
- package/dist/frontend/lowering/expressions/union-field-write.js +54 -44
- package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -1
- package/dist/frontend/lowering/iterator-adapters.d.ts +20 -0
- package/dist/frontend/lowering/iterator-adapters.js +605 -0
- package/dist/frontend/lowering/iterator-adapters.js.map +1 -0
- package/dist/frontend/lowering/lower-array-sort.d.ts +1 -1
- package/dist/frontend/lowering/lower-array-sort.js +44 -5
- package/dist/frontend/lowering/lower-array-sort.js.map +1 -1
- package/dist/frontend/lowering/lower-array-sort.test.d.ts +1 -0
- package/dist/frontend/lowering/lower-array-sort.test.js +31 -0
- package/dist/frontend/lowering/lower-array-sort.test.js.map +1 -0
- package/dist/frontend/lowering/lower-assert.js +7 -0
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.js +1 -0
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +8 -3
- package/dist/frontend/lowering/lower-calls.js +388 -278
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +6 -0
- package/dist/frontend/lowering/lower-classes.js +117 -65
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +22 -2
- package/dist/frontend/lowering/lower-exprs.js +811 -254
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-functions.js +32 -19
- package/dist/frontend/lowering/lower-functions.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.d.ts +19 -13
- package/dist/frontend/lowering/lower-generators.js +67 -44
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +29 -4
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +1 -1
- package/dist/frontend/lowering/lower-island.js +24 -7
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +100 -3
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +82 -64
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +115 -2
- package/dist/frontend/lowering/lowerer.js +1266 -88
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/native-ffi.js +3 -1
- package/dist/frontend/lowering/native-ffi.js.map +1 -1
- package/dist/frontend/lowering/runtime-optional-bounds.d.ts +19 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js +354 -0
- package/dist/frontend/lowering/runtime-optional-bounds.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.test.d.ts +1 -0
- package/dist/frontend/lowering/runtime-optional-bounds.test.js +66 -0
- package/dist/frontend/lowering/runtime-optional-bounds.test.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-elements.d.ts +117 -0
- package/dist/frontend/lowering/runtime-optional-elements.js +738 -0
- package/dist/frontend/lowering/runtime-optional-elements.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-guards.d.ts +36 -0
- package/dist/frontend/lowering/runtime-optional-guards.js +375 -0
- package/dist/frontend/lowering/runtime-optional-guards.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-guards.test.d.ts +1 -0
- package/dist/frontend/lowering/runtime-optional-guards.test.js +92 -0
- package/dist/frontend/lowering/runtime-optional-guards.test.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-ownership.d.ts +63 -0
- package/dist/frontend/lowering/runtime-optional-ownership.js +382 -0
- package/dist/frontend/lowering/runtime-optional-ownership.js.map +1 -0
- package/dist/frontend/lowering/runtime-optional-provenance.d.ts +16 -0
- package/dist/frontend/lowering/runtime-optional-provenance.js +41 -0
- package/dist/frontend/lowering/runtime-optional-provenance.js.map +1 -0
- package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
- package/dist/frontend/lowering/strict-equality.d.ts +9 -0
- package/dist/frontend/lowering/strict-equality.js +116 -0
- package/dist/frontend/lowering/strict-equality.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.d.ts +36 -0
- package/dist/frontend/lowering/string-index-bounds.js +537 -0
- package/dist/frontend/lowering/string-index-bounds.js.map +1 -0
- package/dist/frontend/lowering/string-index-bounds.test.d.ts +1 -0
- package/dist/frontend/lowering/string-index-bounds.test.js +223 -0
- package/dist/frontend/lowering/string-index-bounds.test.js.map +1 -0
- package/dist/frontend/lowering/surfaces.js +3 -0
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/union-comparison.d.ts +5 -0
- package/dist/frontend/lowering/union-comparison.js +47 -0
- package/dist/frontend/lowering/union-comparison.js.map +1 -0
- package/dist/frontend/lowering/union-narrow.d.ts +2 -0
- package/dist/frontend/lowering/union-narrow.js +10 -6
- package/dist/frontend/lowering/union-narrow.js.map +1 -1
- package/dist/frontend/program-analysis.d.ts +10 -0
- package/dist/frontend/program-analysis.js +7 -0
- package/dist/frontend/program-analysis.js.map +1 -1
- package/dist/frontend/program.d.ts +63 -2
- package/dist/frontend/program.js +1038 -61
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +122 -6
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/resolve.d.ts +6 -0
- package/dist/frontend/resolve.js +14 -0
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/threads-import.d.ts +5 -0
- package/dist/frontend/threads-import.js +21 -0
- package/dist/frontend/threads-import.js.map +1 -0
- package/dist/frontend/type-mapper.d.ts +4 -1
- package/dist/frontend/type-mapper.js +161 -20
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-mapper.test.js +15 -3
- package/dist/frontend/type-mapper.test.js.map +1 -1
- package/dist/frontend/worker-target.d.ts +4 -0
- package/dist/frontend/worker-target.js +8 -1
- package/dist/frontend/worker-target.js.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +70 -16
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +3 -1
- package/dist/ir/analysis.js +4 -0
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/build.d.ts +5 -0
- package/dist/ir/build.js +7 -0
- package/dist/ir/build.js.map +1 -1
- package/dist/ir/builtin-signatures.d.ts +1 -1
- package/dist/ir/builtin-signatures.js +5 -3
- package/dist/ir/builtin-signatures.js.map +1 -1
- package/dist/ir/constant-tables.test.js +1 -1
- package/dist/ir/initializer-bindings.test.js +1 -1
- package/dist/ir/int32-slots.d.ts +72 -0
- package/dist/ir/int32-slots.js +837 -0
- package/dist/ir/int32-slots.js.map +1 -0
- package/dist/ir/int32-slots.test.d.ts +1 -0
- package/dist/ir/int32-slots.test.js +222 -0
- package/dist/ir/int32-slots.test.js.map +1 -0
- package/dist/ir/integer-ranges.d.ts +19 -3
- package/dist/ir/integer-ranges.js +168 -23
- package/dist/ir/integer-ranges.js.map +1 -1
- package/dist/ir/integer-ranges.test.js +74 -2
- package/dist/ir/integer-ranges.test.js.map +1 -1
- package/dist/ir/ir.d.ts +101 -20
- package/dist/ir/ir.js +20 -6
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/scalar-records.test.js +1 -1
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +3 -3
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/traverse.js +8 -0
- package/dist/ir/traverse.js.map +1 -1
- package/dist/ir/validate.js +139 -22
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +308 -8
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/library/fence-eval.test.js +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/library-cache.test.js +5 -5
- package/dist/library/library-profile.d.ts +2 -1
- package/dist/library/library-profile.js +4 -3
- package/dist/library/library-profile.js.map +1 -1
- package/dist/native/cache.d.ts +3 -0
- package/dist/native/cache.js +49 -1
- package/dist/native/cache.js.map +1 -1
- package/dist/native/cache.test.js +21 -1
- package/dist/native/cache.test.js.map +1 -1
- package/dist/native/cli.js +1 -1
- package/dist/native/cli.js.map +1 -1
- package/dist/native/compiler.d.ts +5 -0
- package/dist/native/compiler.js +51 -4
- package/dist/native/compiler.js.map +1 -1
- package/dist/native/compiler.test.js +2 -2
- package/dist/native/library.d.ts +2 -1
- package/dist/native/library.js.map +1 -1
- package/dist/native/prepare.d.ts +4 -0
- package/dist/native/prepare.js +28 -3
- package/dist/native/prepare.js.map +1 -1
- package/dist/native/sanitizer.d.ts +3 -2
- package/dist/native/sanitizer.js +3 -13
- package/dist/native/sanitizer.js.map +1 -1
- package/dist/startup-cache.d.ts +2 -0
- package/dist/startup-cache.js +2 -0
- package/dist/startup-cache.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +8 -2
package/dist/frontend/program.js
CHANGED
|
@@ -201,11 +201,24 @@ function adoptProjectConfig7(host, entryPath) {
|
|
|
201
201
|
adopted["paths"] = paths;
|
|
202
202
|
}
|
|
203
203
|
const nullChecks = adopted["strictNullChecks"] ?? adopted["strict"] ?? false;
|
|
204
|
-
|
|
204
|
+
const forcedStrictNullChecks = nullChecks !== true;
|
|
205
|
+
if (forcedStrictNullChecks) {
|
|
205
206
|
diags.push(strictNullChecksFloorDiag(configFile));
|
|
206
207
|
adopted["strictNullChecks"] = true;
|
|
207
208
|
}
|
|
208
|
-
|
|
209
|
+
// The project's own library selection, kept only to explain errors: the
|
|
210
|
+
// checker always uses scriptc's fixed library set (FORCED_OPTIONS).
|
|
211
|
+
const rawLib = parsed.options["lib"];
|
|
212
|
+
const projectLib = Array.isArray(rawLib)
|
|
213
|
+
? rawLib.filter((entry) => typeof entry === "string")
|
|
214
|
+
: undefined;
|
|
215
|
+
return {
|
|
216
|
+
configFile,
|
|
217
|
+
options: { ...BASE_OPTIONS, ...adopted, ...FORCED_OPTIONS },
|
|
218
|
+
diags,
|
|
219
|
+
...(projectLib === undefined ? {} : { projectLib }),
|
|
220
|
+
forcedStrictNullChecks,
|
|
221
|
+
};
|
|
209
222
|
}
|
|
210
223
|
/** The target project's @types/node, resolved with the OWN resolver's
|
|
211
224
|
* type-directive lookup anchored at the ENTRY (typeRoots-free — exactly the
|
|
@@ -538,6 +551,11 @@ function loadProgram7(host, entryPath, externalTypes = new Map()) {
|
|
|
538
551
|
entry,
|
|
539
552
|
moduleOrder: [],
|
|
540
553
|
configDiags: config.diags,
|
|
554
|
+
typeWorld: {
|
|
555
|
+
nodeFallback: nodeTypes === null,
|
|
556
|
+
projectLib: config.projectLib ?? null,
|
|
557
|
+
forcedStrictNullChecks: config.forcedStrictNullChecks ?? false,
|
|
558
|
+
},
|
|
541
559
|
externalTypes,
|
|
542
560
|
externalTypeSpecifiersByFile,
|
|
543
561
|
projectWorld: () => (projectWorld ??= host.createProgram(programRoots, options)),
|
|
@@ -1611,6 +1629,18 @@ function inTypePosition7(node) {
|
|
|
1611
1629
|
* callback-invoking builtin, a getter, an iterator, or an implicit
|
|
1612
1630
|
* coercion of a user object) disqualifies the module's cycles. */
|
|
1613
1631
|
function nonInertTopLevel7(program, sf) {
|
|
1632
|
+
const nonInert = topLevelInertness7(program);
|
|
1633
|
+
for (const stmt of sf.statements) {
|
|
1634
|
+
const offence = nonInert(stmt);
|
|
1635
|
+
if (offence !== null)
|
|
1636
|
+
return offence;
|
|
1637
|
+
}
|
|
1638
|
+
return null;
|
|
1639
|
+
}
|
|
1640
|
+
/** The per-statement form of nonInertTopLevel7: answers, for one
|
|
1641
|
+
* top-level statement, the first construct that could execute user code
|
|
1642
|
+
* while the statement runs, or null when the statement is inert. */
|
|
1643
|
+
function topLevelInertness7(program) {
|
|
1614
1644
|
const checker = program.getTypeChecker();
|
|
1615
1645
|
const PRIM = ts.TypeFlags.StringLike |
|
|
1616
1646
|
ts.TypeFlags.NumberLike |
|
|
@@ -1779,7 +1809,7 @@ function nonInertTopLevel7(program, sf) {
|
|
|
1779
1809
|
}
|
|
1780
1810
|
return false;
|
|
1781
1811
|
};
|
|
1782
|
-
|
|
1812
|
+
return (stmt) => {
|
|
1783
1813
|
if (ts.isImportDeclaration(stmt) ||
|
|
1784
1814
|
ts.isExportDeclaration(stmt) ||
|
|
1785
1815
|
ts.isImportEqualsDeclaration(stmt) ||
|
|
@@ -1790,20 +1820,13 @@ function nonInertTopLevel7(program, sf) {
|
|
|
1790
1820
|
(ts.getCombinedModifierFlags(stmt) &
|
|
1791
1821
|
ts.ModifierFlags.Ambient) !==
|
|
1792
1822
|
0) {
|
|
1793
|
-
|
|
1823
|
+
return null;
|
|
1794
1824
|
}
|
|
1795
1825
|
if (ts.isEnumDeclaration(stmt)) {
|
|
1796
|
-
|
|
1797
|
-
if (bad !== undefined)
|
|
1798
|
-
return bad;
|
|
1799
|
-
continue;
|
|
1800
|
-
}
|
|
1801
|
-
if (ts.isClassDeclaration(stmt)) {
|
|
1802
|
-
const bad = inertClass(stmt);
|
|
1803
|
-
if (bad !== null)
|
|
1804
|
-
return bad;
|
|
1805
|
-
continue;
|
|
1826
|
+
return stmt.members.find((m) => m.initializer !== undefined && !inert(m.initializer)) ?? null;
|
|
1806
1827
|
}
|
|
1828
|
+
if (ts.isClassDeclaration(stmt))
|
|
1829
|
+
return inertClass(stmt);
|
|
1807
1830
|
if (ts.isVariableStatement(stmt)) {
|
|
1808
1831
|
for (const d of stmt.declarationList.declarations) {
|
|
1809
1832
|
if (!ts.isIdentifier(d.name))
|
|
@@ -1811,21 +1834,15 @@ function nonInertTopLevel7(program, sf) {
|
|
|
1811
1834
|
if (d.initializer !== undefined && !inert(d.initializer))
|
|
1812
1835
|
return d.initializer;
|
|
1813
1836
|
}
|
|
1814
|
-
|
|
1815
|
-
}
|
|
1816
|
-
if (ts.isExpressionStatement(stmt)) {
|
|
1817
|
-
if (!inert(stmt.expression))
|
|
1818
|
-
return stmt;
|
|
1819
|
-
continue;
|
|
1837
|
+
return null;
|
|
1820
1838
|
}
|
|
1839
|
+
if (ts.isExpressionStatement(stmt))
|
|
1840
|
+
return inert(stmt.expression) ? null : stmt;
|
|
1821
1841
|
if (ts.isExportAssignment(stmt) && !stmt.isExportEquals) {
|
|
1822
|
-
|
|
1823
|
-
return stmt;
|
|
1824
|
-
continue;
|
|
1842
|
+
return inert(stmt.expression) ? null : stmt;
|
|
1825
1843
|
}
|
|
1826
1844
|
return stmt;
|
|
1827
|
-
}
|
|
1828
|
-
return null;
|
|
1845
|
+
};
|
|
1829
1846
|
}
|
|
1830
1847
|
/** The head of a property/element-access chain. */
|
|
1831
1848
|
function chainRoot7(e) {
|
|
@@ -1891,13 +1908,16 @@ function backEdgeUseOffence7(program, stmt, occurrences) {
|
|
|
1891
1908
|
* e.dep already mid-initialization in a depth-first walk), answers null
|
|
1892
1909
|
* to ADMIT the cycle — the guarded %init calls reproduce Node's cache-hit
|
|
1893
1910
|
* order and nothing can observe the partial initialization — or the
|
|
1894
|
-
* human-readable reason it keeps the SC1016 fence.
|
|
1911
|
+
* human-readable reason it keeps the SC1016 fence. Three admission chances:
|
|
1895
1912
|
* - the CHEAP PER-EDGE rule: the closing statement binds nothing (a
|
|
1896
1913
|
* side-effect import) or binds only namespace objects whose every use
|
|
1897
1914
|
* is a bare expression statement — no read crosses the edge at all;
|
|
1898
1915
|
* - the DECLARATION-ONLY INIT WINDOW rule (the admission block above):
|
|
1899
1916
|
* every cluster member is an ES module with an inert top level, and
|
|
1900
|
-
* the closing edge's bindings are used only in deferred positions
|
|
1917
|
+
* the closing edge's bindings are used only in deferred positions;
|
|
1918
|
+
* - the EXACT INITIALIZATION rule (exactCycleRefusal7): partial
|
|
1919
|
+
* initialization is observable, but every observation is modeled —
|
|
1920
|
+
* the lowering checks each binding cycleEarlyBindings reports.
|
|
1901
1921
|
* Tarjan SCCs (lazy, rooted at each queried importer) and cluster
|
|
1902
1922
|
* verdicts are memoized across calls, so `edgesOf` must answer the same
|
|
1903
1923
|
* edges for the same file every time. */
|
|
@@ -1948,10 +1968,11 @@ export function makeCycleAdmission(program, edgesOf) {
|
|
|
1948
1968
|
const nsf = node.getSourceFile();
|
|
1949
1969
|
return `${nsf.fileName}:${ts.getLineAndCharacterOfPosition(nsf, node.getStart(nsf)).line + 1}`;
|
|
1950
1970
|
};
|
|
1951
|
-
// Cluster verdict memo (keyed by the component array identity):
|
|
1952
|
-
//
|
|
1953
|
-
// member passes the inert-top-level bar.
|
|
1971
|
+
// Cluster verdict memo (keyed by the component array identity): true
|
|
1972
|
+
// when every member is an ES module passing the inert-top-level bar.
|
|
1954
1973
|
const sccVerdict = new Map();
|
|
1974
|
+
// The exact-initialization verdict, same keying (exactCycleRefusal7).
|
|
1975
|
+
const exactVerdict = new Map();
|
|
1955
1976
|
// A module can close many cycle edges, each importing many bindings.
|
|
1956
1977
|
// Index its identifiers once for this admission pass. ASTs are immutable;
|
|
1957
1978
|
// the pass owns the index so it cannot retain a disposed program.
|
|
@@ -1997,31 +2018,860 @@ export function makeCycleAdmission(program, edgesOf) {
|
|
|
1997
2018
|
return "the cycle's module cluster could not be analyzed";
|
|
1998
2019
|
}
|
|
1999
2020
|
if (!sccVerdict.has(comp)) {
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2021
|
+
sccVerdict.set(comp, comp.every((m) => !isCjsJsFile7(m, program) && nonInertTopLevel7(program, m) === null));
|
|
2022
|
+
}
|
|
2023
|
+
if (sccVerdict.get(comp) === true &&
|
|
2024
|
+
backEdgeUseOffence7(program, e.stmt, usesOf(importer)) === null) {
|
|
2025
|
+
return null;
|
|
2026
|
+
}
|
|
2027
|
+
// The EXACT INITIALIZATION rule: the cycle runs in Node's evaluation
|
|
2028
|
+
// order and every binding that can be observed before its declaration
|
|
2029
|
+
// runs carries an initialization check (cycleEarlyBindings).
|
|
2030
|
+
if (!exactVerdict.has(comp)) {
|
|
2031
|
+
const reason = exactCycleRefusal7(program, comp, lineOf);
|
|
2032
|
+
exactVerdict.set(comp, reason);
|
|
2033
|
+
if (reason === null) {
|
|
2034
|
+
const members = program.analysis.exactCycleMembers;
|
|
2035
|
+
for (const m of comp)
|
|
2036
|
+
members.add(m);
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
return exactVerdict.get(comp) ?? null;
|
|
2040
|
+
};
|
|
2041
|
+
}
|
|
2042
|
+
/* ── exact cyclic initialization ─────────────────────────────────────────
|
|
2043
|
+
* Cycles that fail the declaration-only rule still evaluate exactly like
|
|
2044
|
+
* Node when their shape is representable: the guarded %init calls already
|
|
2045
|
+
* run every module body in ES evaluation order (depth-first postorder,
|
|
2046
|
+
* a module mid-evaluation answered from the cache), function declarations
|
|
2047
|
+
* are callable from the start, and live bindings are shared globals. What
|
|
2048
|
+
* remains is the temporal dead zone: a let/const binding read before its
|
|
2049
|
+
* declaration ran throws ReferenceError. cycleEarlyBindings finds every
|
|
2050
|
+
* such binding whose read CAN run early; the lowering gives each one an
|
|
2051
|
+
* initialization flag and checks it at every read or write that can run
|
|
2052
|
+
* before the declaration. The shapes below have no such representation
|
|
2053
|
+
* and keep the SC1016 fence. */
|
|
2054
|
+
/** The modules of `program` whose import cycles were admitted by the
|
|
2055
|
+
* exact initialization rule (not the declaration-only rule). */
|
|
2056
|
+
export function exactCycleMembers(program) {
|
|
2057
|
+
return program.analysis.exactCycleMembers;
|
|
2058
|
+
}
|
|
2059
|
+
/** True when the module's top level (outside every function-like body)
|
|
2060
|
+
* contains `await` or `for await`. */
|
|
2061
|
+
function hasTopLevelAwait7(sf) {
|
|
2062
|
+
let found = false;
|
|
2063
|
+
ts.walkPreorder(sf, (node) => {
|
|
2064
|
+
if (found)
|
|
2065
|
+
return "stop";
|
|
2066
|
+
if (node !== sf && ts.isFunctionLike(node))
|
|
2067
|
+
return "skip";
|
|
2068
|
+
if (ts.isAwaitExpression(node) ||
|
|
2069
|
+
(ts.isForOfStatement(node) && node.awaitModifier !== undefined)) {
|
|
2070
|
+
found = true;
|
|
2071
|
+
return "stop";
|
|
2072
|
+
}
|
|
2073
|
+
return undefined;
|
|
2074
|
+
});
|
|
2075
|
+
return found;
|
|
2076
|
+
}
|
|
2077
|
+
/** The reason a strongly-connected module cluster cannot be initialized
|
|
2078
|
+
* exactly, or null when it can. */
|
|
2079
|
+
function exactCycleRefusal7(program, comp, lineOf) {
|
|
2080
|
+
const members = new Set(comp);
|
|
2081
|
+
const targetOf = (stmt) => {
|
|
2082
|
+
const spec = stmt.moduleSpecifier;
|
|
2083
|
+
if (spec === undefined || !ts.isStringLiteral(spec))
|
|
2084
|
+
return null;
|
|
2085
|
+
const sf = stmt.getSourceFile();
|
|
2086
|
+
return resolveImport7(program, sf, spec.text) ?? npmStaticDepSf7(program, sf, spec.text);
|
|
2087
|
+
};
|
|
2088
|
+
for (const m of comp) {
|
|
2089
|
+
if (isCjsJsFile7(m, program) || /\.c[jt]s$/.test(m.fileName)) {
|
|
2090
|
+
return `${m.fileName} is a CommonJS module — cyclic initialization covers ES modules only`;
|
|
2091
|
+
}
|
|
2092
|
+
if (hasTopLevelAwait7(m)) {
|
|
2093
|
+
return `${m.fileName} uses top-level await inside the cycle`;
|
|
2094
|
+
}
|
|
2095
|
+
for (const stmt of m.statements) {
|
|
2096
|
+
if (ts.isExportAssignment(stmt) && !stmt.isExportEquals) {
|
|
2097
|
+
return `the default export expression at ${lineOf(stmt)} has no initialization state inside the cycle`;
|
|
2098
|
+
}
|
|
2099
|
+
if (ts.isExportDeclaration(stmt) &&
|
|
2100
|
+
!stmt.isTypeOnly &&
|
|
2101
|
+
(stmt.exportClause === undefined || ts.isNamespaceExport(stmt.exportClause))) {
|
|
2102
|
+
const dep = targetOf(stmt);
|
|
2103
|
+
if (dep !== null && members.has(dep)) {
|
|
2104
|
+
return `the namespace re-export at ${lineOf(stmt)} names a module of the cycle`;
|
|
2005
2105
|
}
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2106
|
+
}
|
|
2107
|
+
if (ts.isImportDeclaration(stmt) &&
|
|
2108
|
+
stmt.importClause !== undefined &&
|
|
2109
|
+
!stmt.importClause.isTypeOnly &&
|
|
2110
|
+
stmt.importClause.namedBindings !== undefined &&
|
|
2111
|
+
ts.isNamespaceImport(stmt.importClause.namedBindings)) {
|
|
2112
|
+
const dep = targetOf(stmt);
|
|
2113
|
+
const nsName = stmt.importClause.namedBindings.name;
|
|
2114
|
+
if (dep !== null &&
|
|
2115
|
+
members.has(dep) &&
|
|
2116
|
+
!nsBindingUsesAreBareStatements7(program, m, nsName)) {
|
|
2117
|
+
return `the namespace import '${nsName.text}' at ${lineOf(stmt)} names a module of the cycle`;
|
|
2010
2118
|
}
|
|
2011
2119
|
}
|
|
2012
|
-
|
|
2120
|
+
if (ts.isClassDeclaration(stmt) && stmt.name === undefined) {
|
|
2121
|
+
return `the anonymous default class at ${lineOf(stmt)} has no initialization state inside the cycle`;
|
|
2122
|
+
}
|
|
2123
|
+
const ambient = (ts.getCombinedModifierFlags(stmt) &
|
|
2124
|
+
ts.ModifierFlags.Ambient) !==
|
|
2125
|
+
0;
|
|
2126
|
+
if (ambient)
|
|
2127
|
+
continue;
|
|
2128
|
+
if (ts.isEnumDeclaration(stmt) &&
|
|
2129
|
+
(ts.getCombinedModifierFlags(stmt) & ts.ModifierFlags.Const) === 0) {
|
|
2130
|
+
return `the enum '${stmt.name.text}' at ${lineOf(stmt)} has no initialization state inside the cycle`;
|
|
2131
|
+
}
|
|
2132
|
+
if (ts.isModuleDeclaration(stmt) && !typeOnlyNamespace7(stmt)) {
|
|
2133
|
+
return `the namespace at ${lineOf(stmt)} has no initialization state inside the cycle`;
|
|
2134
|
+
}
|
|
2013
2135
|
}
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2136
|
+
}
|
|
2137
|
+
return null;
|
|
2138
|
+
}
|
|
2139
|
+
/** Every binding of the program's exactly-initialized cycles that can be
|
|
2140
|
+
* observed before its declaration executes. `order` is the compiled module
|
|
2141
|
+
* order; `singleRoot` is false when more than one module graph root runs
|
|
2142
|
+
* (fork or worker entries), so a cycle can be entered at different
|
|
2143
|
+
* members. With one root and a purely ES-module graph the evaluation order
|
|
2144
|
+
* is static and the analysis is precise up to "user code may run": a
|
|
2145
|
+
* binding needs its check when its declaration completes after some
|
|
2146
|
+
* top-level code that can call user functions and a deferred position
|
|
2147
|
+
* (function body, parameter default, instance field) references it, or
|
|
2148
|
+
* when the top level of a cycle member evaluated before it reads it.
|
|
2149
|
+
* Otherwise every deferred reference and every top-level reference from
|
|
2150
|
+
* another member counts. */
|
|
2151
|
+
export function cycleEarlyBindings(program, entry, order, singleRoot) {
|
|
2152
|
+
const exact = program.analysis.exactCycleMembers;
|
|
2153
|
+
if (exact.size === 0)
|
|
2154
|
+
return [];
|
|
2155
|
+
// Every lowering pass of one compile asks with the same inputs.
|
|
2156
|
+
const key = `${entry.fileName}\0${order.map((sf) => sf.fileName).join("\0")}\0${singleRoot}`;
|
|
2157
|
+
const memo = program.analysis.cycleEarlyBindings;
|
|
2158
|
+
if (memo !== null && memo.key === key)
|
|
2159
|
+
return memo.bindings;
|
|
2160
|
+
const bindings = computeCycleEarlyBindings7(program, entry, order, singleRoot, exact);
|
|
2161
|
+
program.analysis.cycleEarlyBindings = { key, bindings };
|
|
2162
|
+
return bindings;
|
|
2163
|
+
}
|
|
2164
|
+
function computeCycleEarlyBindings7(program, entry, order, singleRoot, exact) {
|
|
2165
|
+
const inOrder = new Set(order);
|
|
2166
|
+
const members = [...exact].filter((m) => inOrder.has(m));
|
|
2167
|
+
if (members.length === 0)
|
|
2168
|
+
return [];
|
|
2169
|
+
const memberSet = new Set(members);
|
|
2170
|
+
const depsOf = (sf) => orderedImportsOf(program, sf).flatMap(({ dep }) => dep !== null && dep !== sf && inOrder.has(dep) ? [dep] : []);
|
|
2171
|
+
// Strongly-connected components among the exactly-initialized members.
|
|
2172
|
+
const comps = [];
|
|
2173
|
+
{
|
|
2174
|
+
const index = new Map();
|
|
2175
|
+
const low = new Map();
|
|
2176
|
+
const onStack = new Set();
|
|
2177
|
+
const stack = [];
|
|
2178
|
+
let next = 0;
|
|
2179
|
+
const connect = (v) => {
|
|
2180
|
+
index.set(v, next);
|
|
2181
|
+
low.set(v, next);
|
|
2182
|
+
next++;
|
|
2183
|
+
stack.push(v);
|
|
2184
|
+
onStack.add(v);
|
|
2185
|
+
for (const w of depsOf(v)) {
|
|
2186
|
+
if (!memberSet.has(w))
|
|
2187
|
+
continue;
|
|
2188
|
+
if (!index.has(w)) {
|
|
2189
|
+
connect(w);
|
|
2190
|
+
low.set(v, Math.min(low.get(v), low.get(w)));
|
|
2191
|
+
}
|
|
2192
|
+
else if (onStack.has(w)) {
|
|
2193
|
+
low.set(v, Math.min(low.get(v), index.get(w)));
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
if (low.get(v) === index.get(v)) {
|
|
2197
|
+
const comp = [];
|
|
2198
|
+
for (;;) {
|
|
2199
|
+
const w = stack.pop();
|
|
2200
|
+
onStack.delete(w);
|
|
2201
|
+
comp.push(w);
|
|
2202
|
+
if (w === v)
|
|
2203
|
+
break;
|
|
2204
|
+
}
|
|
2205
|
+
if (comp.length > 1)
|
|
2206
|
+
comps.push(comp);
|
|
2207
|
+
}
|
|
2208
|
+
};
|
|
2209
|
+
for (const m of members)
|
|
2210
|
+
if (!index.has(m))
|
|
2211
|
+
connect(m);
|
|
2212
|
+
}
|
|
2213
|
+
if (comps.length === 0)
|
|
2214
|
+
return [];
|
|
2215
|
+
// The static evaluation order: Node's depth-first postorder from the
|
|
2216
|
+
// entry over ES import edges. Known only for one root and a graph with
|
|
2217
|
+
// no CommonJS module (a require() evaluates its target mid-body).
|
|
2218
|
+
const position = new Map();
|
|
2219
|
+
if (singleRoot &&
|
|
2220
|
+
!order.some((sf) => isCjsJsFile7(sf, program) || /\.c[jt]s$/.test(sf.fileName))) {
|
|
2221
|
+
const seen = new Set();
|
|
2222
|
+
const visit = (sf) => {
|
|
2223
|
+
seen.add(sf);
|
|
2224
|
+
for (const dep of depsOf(sf))
|
|
2225
|
+
if (!seen.has(dep))
|
|
2226
|
+
visit(dep);
|
|
2227
|
+
position.set(sf, position.size);
|
|
2228
|
+
};
|
|
2229
|
+
visit(entry);
|
|
2230
|
+
}
|
|
2231
|
+
const checker = program.getTypeChecker();
|
|
2232
|
+
const nonInert = topLevelInertness7(program);
|
|
2233
|
+
const out = [];
|
|
2234
|
+
for (const comp of comps) {
|
|
2235
|
+
const known = comp.every((m) => position.has(m));
|
|
2236
|
+
const evaluation = known
|
|
2237
|
+
? comp.slice().sort((a, b) => position.get(a) - position.get(b))
|
|
2238
|
+
: comp.slice();
|
|
2239
|
+
const candidates = new Map();
|
|
2240
|
+
const names = new Set();
|
|
2241
|
+
let dirty = !known;
|
|
2242
|
+
evaluation.forEach((m, rank) => {
|
|
2243
|
+
for (const stmt of m.statements) {
|
|
2244
|
+
const offence = nonInert(stmt);
|
|
2245
|
+
const exposed = dirty || offence !== null;
|
|
2246
|
+
const declared = [];
|
|
2247
|
+
if (ts.isVariableStatement(stmt) &&
|
|
2248
|
+
(ts.getCombinedModifierFlags(stmt) &
|
|
2249
|
+
ts.ModifierFlags.Ambient) ===
|
|
2250
|
+
0) {
|
|
2251
|
+
const lexical = (stmt.declarationList.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) !== 0;
|
|
2252
|
+
for (const d of stmt.declarationList.declarations) {
|
|
2253
|
+
for (const name of boundNames7(d.name)) {
|
|
2254
|
+
declared.push({ name, kind: lexical ? "lexical" : "var" });
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
}
|
|
2258
|
+
else if (ts.isClassDeclaration(stmt) && stmt.name !== undefined) {
|
|
2259
|
+
declared.push({ name: stmt.name, kind: "class" });
|
|
2260
|
+
}
|
|
2261
|
+
for (const { name, kind } of declared) {
|
|
2262
|
+
const symbol = checker.getSymbolAtLocation(name);
|
|
2263
|
+
if (symbol === undefined)
|
|
2264
|
+
continue;
|
|
2265
|
+
candidates.set(symbol, {
|
|
2266
|
+
symbol,
|
|
2267
|
+
name,
|
|
2268
|
+
kind,
|
|
2269
|
+
module: m,
|
|
2270
|
+
exposed,
|
|
2271
|
+
rank,
|
|
2272
|
+
start: stmt.getStart(m),
|
|
2273
|
+
end: stmt.getEnd(),
|
|
2274
|
+
reference: null,
|
|
2275
|
+
folded: null,
|
|
2276
|
+
});
|
|
2277
|
+
names.add(name.text);
|
|
2278
|
+
}
|
|
2279
|
+
if (offence !== null)
|
|
2280
|
+
dirty = true;
|
|
2281
|
+
}
|
|
2282
|
+
});
|
|
2283
|
+
if (candidates.size === 0)
|
|
2284
|
+
continue;
|
|
2285
|
+
const rankOf = new Map(evaluation.map((m, i) => [m, i]));
|
|
2286
|
+
// References: every identifier spelled like a candidate, resolved
|
|
2287
|
+
// through import aliases to the declaration's symbol.
|
|
2288
|
+
for (const sf of order) {
|
|
2289
|
+
const refs = [];
|
|
2290
|
+
ts.walkPreorder(sf, (node) => {
|
|
2291
|
+
if (ts.isImportDeclaration(node))
|
|
2292
|
+
return "skip";
|
|
2293
|
+
if (ts.isIdentifier(node) && names.has(node.text))
|
|
2294
|
+
refs.push(node);
|
|
2295
|
+
return undefined;
|
|
2296
|
+
});
|
|
2297
|
+
if (refs.length === 0)
|
|
2298
|
+
continue;
|
|
2299
|
+
checker.prefetchSymbolNodesExact(refs);
|
|
2300
|
+
for (const ref of refs) {
|
|
2301
|
+
const parent = ref.parent;
|
|
2302
|
+
if (parent !== undefined && ts.isExportSpecifier(parent))
|
|
2303
|
+
continue;
|
|
2304
|
+
if (inTypePosition7(ref))
|
|
2305
|
+
continue;
|
|
2306
|
+
let symbol = checker.getSymbolAtLocation(ref);
|
|
2307
|
+
if (parent !== undefined &&
|
|
2308
|
+
ts.isShorthandPropertyAssignment(parent) &&
|
|
2309
|
+
parent.name === ref) {
|
|
2310
|
+
symbol = checker.getShorthandAssignmentValueSymbol(parent) ?? symbol;
|
|
2311
|
+
}
|
|
2312
|
+
if (symbol !== undefined && symbol.flags & ts.SymbolFlags.Alias) {
|
|
2313
|
+
symbol = checker.getAliasedSymbol(symbol);
|
|
2314
|
+
}
|
|
2315
|
+
const c = symbol === undefined ? undefined : candidates.get(symbol);
|
|
2316
|
+
if (c === undefined || ref === c.name)
|
|
2317
|
+
continue;
|
|
2318
|
+
if (c.folded === null && foldablePosition7(ref))
|
|
2319
|
+
c.folded = ref;
|
|
2320
|
+
if (c.reference !== null)
|
|
2321
|
+
continue;
|
|
2322
|
+
// A class body names its own inner binding, initialized throughout.
|
|
2323
|
+
if (c.kind === "class" &&
|
|
2324
|
+
sf === c.module &&
|
|
2325
|
+
ref.getStart(sf) >= c.start &&
|
|
2326
|
+
ref.getEnd() <= c.end)
|
|
2327
|
+
continue;
|
|
2328
|
+
let early;
|
|
2329
|
+
if (inDeferredPosition7(ref))
|
|
2330
|
+
early = c.exposed;
|
|
2331
|
+
else if (sf === c.module)
|
|
2332
|
+
early = ref.getStart(sf) < c.start;
|
|
2333
|
+
else if (!memberSet.has(sf) || !rankOf.has(sf))
|
|
2334
|
+
early = false;
|
|
2335
|
+
else
|
|
2336
|
+
early = !known || rankOf.get(sf) < c.rank;
|
|
2337
|
+
if (early)
|
|
2338
|
+
c.reference = ref;
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
for (const c of candidates.values()) {
|
|
2342
|
+
if (c.reference === null)
|
|
2343
|
+
continue;
|
|
2344
|
+
const settled = new Set(order.filter((sf) => !rankOf.has(sf)));
|
|
2345
|
+
if (known)
|
|
2346
|
+
for (const m of evaluation.slice(c.rank + 1))
|
|
2347
|
+
settled.add(m);
|
|
2348
|
+
out.push({
|
|
2349
|
+
symbol: c.symbol,
|
|
2350
|
+
name: c.name,
|
|
2351
|
+
kind: c.kind,
|
|
2352
|
+
module: c.module,
|
|
2353
|
+
reference: c.reference,
|
|
2354
|
+
...(c.folded !== null ? { folded: c.folded } : {}),
|
|
2355
|
+
settled,
|
|
2356
|
+
});
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
return out;
|
|
2360
|
+
}
|
|
2361
|
+
/** Top-level let/const bindings, in modules outside the exactly-initialized
|
|
2362
|
+
* cycles, that code running before their declaration completes can read.
|
|
2363
|
+
* Function declarations are callable from the module's start, so a call
|
|
2364
|
+
* made by earlier top-level code (or by the declaration's own initializer)
|
|
2365
|
+
* can observe the temporal dead zone. Reachability is syntactic: a stored
|
|
2366
|
+
* callable (a function or class declaration, or a function, class or
|
|
2367
|
+
* object-literal method stored by a variable initializer) becomes reachable
|
|
2368
|
+
* once reachable code names its binding, and every other function-like in
|
|
2369
|
+
* reachable code counts as reachable because it may be handed to a callee.
|
|
2370
|
+
* A binding is reported only when one of its references in a deferred
|
|
2371
|
+
* position is reachable before the declaration ran, so modules that call
|
|
2372
|
+
* nothing early report nothing. Bindings of exactly-initialized cycles are
|
|
2373
|
+
* covered by cycleEarlyBindings. */
|
|
2374
|
+
export function moduleEarlyBindings(program, order) {
|
|
2375
|
+
const key = order.map((sf) => sf.fileName).join("\0");
|
|
2376
|
+
const memo = program.analysis.moduleEarlyBindings;
|
|
2377
|
+
if (memo !== null && memo.key === key)
|
|
2378
|
+
return memo.bindings;
|
|
2379
|
+
const exact = program.analysis.exactCycleMembers;
|
|
2380
|
+
const out = [];
|
|
2381
|
+
for (const sf of order) {
|
|
2382
|
+
if (sf.isDeclarationFile || exact.has(sf))
|
|
2383
|
+
continue;
|
|
2384
|
+
out.push(...moduleEarlyBindingsOf7(program, sf, order));
|
|
2385
|
+
}
|
|
2386
|
+
program.analysis.moduleEarlyBindings = { key, bindings: out };
|
|
2387
|
+
return out;
|
|
2388
|
+
}
|
|
2389
|
+
function moduleEarlyBindingsOf7(program, sf, order) {
|
|
2390
|
+
const ambient = (stmt) => (ts.getCombinedModifierFlags(stmt) & ts.ModifierFlags.Ambient) !==
|
|
2391
|
+
0;
|
|
2392
|
+
const candidates = [];
|
|
2393
|
+
const candidateNames = new Set();
|
|
2394
|
+
// Stored callables, by the name of the binding that stores them.
|
|
2395
|
+
const stored = new Set();
|
|
2396
|
+
const storedBy = new Map();
|
|
2397
|
+
// Parts of a stored node that run where it is evaluated: a class's
|
|
2398
|
+
// heritage, computed keys, decorators and static initializers, and a
|
|
2399
|
+
// stored method's computed key.
|
|
2400
|
+
const immediate = new Map();
|
|
2401
|
+
const store = (name, units) => {
|
|
2402
|
+
if (units.length === 0)
|
|
2403
|
+
return;
|
|
2404
|
+
for (const u of units)
|
|
2405
|
+
stored.add(u);
|
|
2406
|
+
const list = storedBy.get(name.text) ?? [];
|
|
2407
|
+
list.push({ name, units });
|
|
2408
|
+
storedBy.set(name.text, list);
|
|
2409
|
+
};
|
|
2410
|
+
const checker = program.getTypeChecker();
|
|
2411
|
+
const storedIn = (e, units) => {
|
|
2412
|
+
while (ts.isParenthesizedExpression(e) ||
|
|
2413
|
+
ts.isAsExpression(e) ||
|
|
2414
|
+
ts.isSatisfiesExpression(e) ||
|
|
2415
|
+
ts.isNonNullExpression(e))
|
|
2416
|
+
e = e.expression;
|
|
2417
|
+
if (ts.isArrowFunction(e) || ts.isFunctionExpression(e)) {
|
|
2418
|
+
units.push(e);
|
|
2419
|
+
}
|
|
2420
|
+
else if (ts.isClassExpression(e)) {
|
|
2421
|
+
units.push(e);
|
|
2422
|
+
immediate.set(e, classSyncParts7(e));
|
|
2423
|
+
}
|
|
2424
|
+
else if (ts.isObjectLiteralExpression(e)) {
|
|
2425
|
+
for (const p of e.properties) {
|
|
2426
|
+
if (ts.isMethodDeclaration(p) ||
|
|
2427
|
+
ts.isGetAccessorDeclaration(p) ||
|
|
2428
|
+
ts.isSetAccessorDeclaration(p)) {
|
|
2429
|
+
// A computed key evaluates where the literal does; a plain
|
|
2430
|
+
// member-chain key (`[Equal.symbol]`) runs no user code.
|
|
2431
|
+
if (!ts.isComputedPropertyName(p.name))
|
|
2432
|
+
units.push(p);
|
|
2433
|
+
else if (memberChainKey7(p.name.expression)) {
|
|
2434
|
+
units.push(p);
|
|
2435
|
+
immediate.set(p, [p.name]);
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
else if (ts.isPropertyAssignment(p))
|
|
2439
|
+
storedIn(p.initializer, units);
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
else if (ts.isArrayLiteralExpression(e)) {
|
|
2443
|
+
for (const el of e.elements)
|
|
2444
|
+
if (!ts.isSpreadElement(el))
|
|
2445
|
+
storedIn(el, units);
|
|
2446
|
+
}
|
|
2447
|
+
else if (ts.isCallExpression(e)) {
|
|
2448
|
+
// `const f = wrap(callback)` where wrap only returns closures over
|
|
2449
|
+
// the callback: it runs when the stored result is called.
|
|
2450
|
+
e.arguments.forEach((arg, index) => {
|
|
2451
|
+
let fn = arg;
|
|
2452
|
+
while (ts.isParenthesizedExpression(fn))
|
|
2453
|
+
fn = fn.expression;
|
|
2454
|
+
if ((ts.isArrowFunction(fn) || ts.isFunctionExpression(fn)) &&
|
|
2455
|
+
returnsOnlyClosuresOver7(checker, e.expression, index))
|
|
2456
|
+
units.push(fn);
|
|
2457
|
+
});
|
|
2022
2458
|
}
|
|
2023
|
-
return null;
|
|
2024
2459
|
};
|
|
2460
|
+
sf.statements.forEach((stmt, index) => {
|
|
2461
|
+
if (ambient(stmt))
|
|
2462
|
+
return;
|
|
2463
|
+
if (ts.isFunctionDeclaration(stmt) && stmt.name !== undefined && stmt.body !== undefined) {
|
|
2464
|
+
store(stmt.name, [stmt]);
|
|
2465
|
+
}
|
|
2466
|
+
else if (ts.isClassDeclaration(stmt) && stmt.name !== undefined) {
|
|
2467
|
+
store(stmt.name, [stmt]);
|
|
2468
|
+
}
|
|
2469
|
+
else if (ts.isVariableStatement(stmt)) {
|
|
2470
|
+
const lexical = (stmt.declarationList.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) !== 0;
|
|
2471
|
+
for (const d of stmt.declarationList.declarations) {
|
|
2472
|
+
if (ts.isIdentifier(d.name) && d.initializer !== undefined) {
|
|
2473
|
+
const units = [];
|
|
2474
|
+
storedIn(d.initializer, units);
|
|
2475
|
+
store(d.name, units);
|
|
2476
|
+
}
|
|
2477
|
+
if (!lexical)
|
|
2478
|
+
continue;
|
|
2479
|
+
for (const name of boundNames7(d.name)) {
|
|
2480
|
+
candidates.push({ name, index, start: stmt.getStart(sf) });
|
|
2481
|
+
candidateNames.add(name.text);
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
});
|
|
2486
|
+
if (candidates.length === 0)
|
|
2487
|
+
return [];
|
|
2488
|
+
// Resolve every identifier that could name a candidate or a stored
|
|
2489
|
+
// callable in one batch.
|
|
2490
|
+
const idents = [];
|
|
2491
|
+
ts.walkPreorder(sf, (node) => {
|
|
2492
|
+
if (ts.isImportDeclaration(node))
|
|
2493
|
+
return "skip";
|
|
2494
|
+
if (ts.isIdentifier(node) && (candidateNames.has(node.text) || storedBy.has(node.text)))
|
|
2495
|
+
idents.push(node);
|
|
2496
|
+
return undefined;
|
|
2497
|
+
});
|
|
2498
|
+
checker.prefetchSymbolNodesExact(idents);
|
|
2499
|
+
const symbolOf = (id) => {
|
|
2500
|
+
const parent = id.parent;
|
|
2501
|
+
let symbol = checker.getSymbolAtLocation(id);
|
|
2502
|
+
if (parent !== undefined && ts.isShorthandPropertyAssignment(parent) && parent.name === id) {
|
|
2503
|
+
symbol = checker.getShorthandAssignmentValueSymbol(parent) ?? symbol;
|
|
2504
|
+
}
|
|
2505
|
+
if (symbol !== undefined && symbol.flags & ts.SymbolFlags.Alias) {
|
|
2506
|
+
symbol = checker.getAliasedSymbol(symbol);
|
|
2507
|
+
}
|
|
2508
|
+
return symbol;
|
|
2509
|
+
};
|
|
2510
|
+
// A callback handed to a timer, a microtask queue, a promise reaction or
|
|
2511
|
+
// a host (Node) API runs as a later job or event. Without top-level await
|
|
2512
|
+
// the module's body completes before any job runs, so such a callback is
|
|
2513
|
+
// never early. JavaScript builtins (array callbacks, the promise
|
|
2514
|
+
// executor, replacers) and the host APIs that call back synchronously
|
|
2515
|
+
// keep the conservative rule.
|
|
2516
|
+
if (!hasTopLevelAwait7(sf)) {
|
|
2517
|
+
const callbacks = (e) => {
|
|
2518
|
+
while (ts.isParenthesizedExpression(e))
|
|
2519
|
+
e = e.expression;
|
|
2520
|
+
if (ts.isArrowFunction(e) || ts.isFunctionExpression(e))
|
|
2521
|
+
stored.add(e);
|
|
2522
|
+
else if (ts.isObjectLiteralExpression(e)) {
|
|
2523
|
+
for (const p of e.properties) {
|
|
2524
|
+
if (ts.isMethodDeclaration(p))
|
|
2525
|
+
stored.add(p);
|
|
2526
|
+
else if (ts.isPropertyAssignment(p))
|
|
2527
|
+
callbacks(p.initializer);
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
};
|
|
2531
|
+
ts.walkPreorder(sf, (node) => {
|
|
2532
|
+
if ((ts.isCallExpression(node) || ts.isNewExpression(node)) &&
|
|
2533
|
+
laterJobCallee7(checker, node.expression)) {
|
|
2534
|
+
for (const arg of node.arguments ?? [])
|
|
2535
|
+
callbacks(arg);
|
|
2536
|
+
}
|
|
2537
|
+
return undefined;
|
|
2538
|
+
});
|
|
2539
|
+
}
|
|
2540
|
+
const unitsBySymbol = new Map();
|
|
2541
|
+
for (const list of storedBy.values()) {
|
|
2542
|
+
for (const { name, units } of list) {
|
|
2543
|
+
const symbol = checker.getSymbolAtLocation(name);
|
|
2544
|
+
if (symbol === undefined)
|
|
2545
|
+
continue;
|
|
2546
|
+
unitsBySymbol.set(symbol, [...(unitsBySymbol.get(symbol) ?? []), ...units]);
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
const candidateSymbols = new Map();
|
|
2550
|
+
for (const c of candidates) {
|
|
2551
|
+
const symbol = checker.getSymbolAtLocation(c.name);
|
|
2552
|
+
if (symbol !== undefined)
|
|
2553
|
+
candidateSymbols.set(symbol, c);
|
|
2554
|
+
}
|
|
2555
|
+
// Walk reachable code, collecting the candidate references it holds.
|
|
2556
|
+
const reachedUnits = new Set();
|
|
2557
|
+
const reachedRefs = new Map();
|
|
2558
|
+
const work = [];
|
|
2559
|
+
const visit = (root) => {
|
|
2560
|
+
ts.walkPreorder(root, (node) => {
|
|
2561
|
+
if (node !== root && stored.has(node)) {
|
|
2562
|
+
for (const part of immediate.get(node) ?? [])
|
|
2563
|
+
visit(part);
|
|
2564
|
+
return "skip";
|
|
2565
|
+
}
|
|
2566
|
+
if (ts.isImportDeclaration(node))
|
|
2567
|
+
return "skip";
|
|
2568
|
+
if (!ts.isIdentifier(node))
|
|
2569
|
+
return undefined;
|
|
2570
|
+
if (!candidateNames.has(node.text) && !storedBy.has(node.text))
|
|
2571
|
+
return undefined;
|
|
2572
|
+
if (inTypePosition7(node))
|
|
2573
|
+
return undefined;
|
|
2574
|
+
const parent = node.parent;
|
|
2575
|
+
if (parent !== undefined && ts.isExportSpecifier(parent))
|
|
2576
|
+
return undefined;
|
|
2577
|
+
if (parent !== undefined && declaredName7(parent) === node)
|
|
2578
|
+
return undefined;
|
|
2579
|
+
const symbol = symbolOf(node);
|
|
2580
|
+
if (symbol === undefined)
|
|
2581
|
+
return undefined;
|
|
2582
|
+
const c = candidateSymbols.get(symbol);
|
|
2583
|
+
if (c !== undefined && node !== c.name && !reachedRefs.has(symbol)) {
|
|
2584
|
+
if (inDeferredPosition7(node) || node.getStart(sf) < c.start)
|
|
2585
|
+
reachedRefs.set(symbol, node);
|
|
2586
|
+
}
|
|
2587
|
+
for (const unit of unitsBySymbol.get(symbol) ?? []) {
|
|
2588
|
+
if (reachedUnits.has(unit))
|
|
2589
|
+
continue;
|
|
2590
|
+
reachedUnits.add(unit);
|
|
2591
|
+
work.push(unit);
|
|
2592
|
+
}
|
|
2593
|
+
return undefined;
|
|
2594
|
+
});
|
|
2595
|
+
};
|
|
2596
|
+
const drain = () => {
|
|
2597
|
+
while (work.length > 0)
|
|
2598
|
+
visit(work.pop());
|
|
2599
|
+
};
|
|
2600
|
+
const out = [];
|
|
2601
|
+
const settled = new Set(order.filter((m) => m !== sf));
|
|
2602
|
+
let next = 0;
|
|
2603
|
+
const report = (declaration) => {
|
|
2604
|
+
while (next < candidates.length &&
|
|
2605
|
+
candidates[next].name.getStart(sf) >= declaration.getStart(sf) &&
|
|
2606
|
+
candidates[next].name.getEnd() <= declaration.getEnd()) {
|
|
2607
|
+
const c = candidates[next++];
|
|
2608
|
+
const symbol = checker.getSymbolAtLocation(c.name);
|
|
2609
|
+
const reference = symbol === undefined ? undefined : reachedRefs.get(symbol);
|
|
2610
|
+
if (symbol === undefined || reference === undefined)
|
|
2611
|
+
continue;
|
|
2612
|
+
out.push({ symbol, name: c.name, kind: "lexical", module: sf, reference, settled });
|
|
2613
|
+
}
|
|
2614
|
+
};
|
|
2615
|
+
for (const stmt of sf.statements) {
|
|
2616
|
+
if (ts.isClassDeclaration(stmt))
|
|
2617
|
+
for (const part of classSyncParts7(stmt))
|
|
2618
|
+
visit(part);
|
|
2619
|
+
else if (ts.isVariableStatement(stmt)) {
|
|
2620
|
+
// Declarators run in order: a later declarator's initializer cannot
|
|
2621
|
+
// observe an earlier binding before it was initialized.
|
|
2622
|
+
for (const d of stmt.declarationList.declarations) {
|
|
2623
|
+
visit(d);
|
|
2624
|
+
drain();
|
|
2625
|
+
report(d);
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
else if (!ts.isFunctionDeclaration(stmt))
|
|
2629
|
+
visit(stmt);
|
|
2630
|
+
drain();
|
|
2631
|
+
}
|
|
2632
|
+
return out;
|
|
2633
|
+
}
|
|
2634
|
+
/** True when the program function `callee` names reads its parameter
|
|
2635
|
+
* `index` only inside function expressions it returns directly, and never
|
|
2636
|
+
* through `arguments` in its own body: calling it cannot run that argument
|
|
2637
|
+
* before the returned closure is called. */
|
|
2638
|
+
function returnsOnlyClosuresOver7(checker, callee, index) {
|
|
2639
|
+
while (ts.isParenthesizedExpression(callee))
|
|
2640
|
+
callee = callee.expression;
|
|
2641
|
+
const name = ts.isIdentifier(callee)
|
|
2642
|
+
? callee
|
|
2643
|
+
: ts.isPropertyAccessExpression(callee) && ts.isIdentifier(callee.name)
|
|
2644
|
+
? callee.name
|
|
2645
|
+
: undefined;
|
|
2646
|
+
if (name === undefined)
|
|
2647
|
+
return false;
|
|
2648
|
+
let symbol = checker.getSymbolAtLocation(name);
|
|
2649
|
+
if (symbol !== undefined && symbol.flags & ts.SymbolFlags.Alias) {
|
|
2650
|
+
symbol = checker.getAliasedSymbol(symbol);
|
|
2651
|
+
}
|
|
2652
|
+
const decls = symbol === undefined ? [] : checker.declarationsOf(symbol);
|
|
2653
|
+
if (decls.length !== 1)
|
|
2654
|
+
return false;
|
|
2655
|
+
const decl = decls[0];
|
|
2656
|
+
if (decl.getSourceFile().isDeclarationFile)
|
|
2657
|
+
return false;
|
|
2658
|
+
let fn;
|
|
2659
|
+
if (ts.isFunctionDeclaration(decl))
|
|
2660
|
+
fn = decl;
|
|
2661
|
+
else if (ts.isVariableDeclaration(decl) && decl.initializer !== undefined) {
|
|
2662
|
+
let init = decl.initializer;
|
|
2663
|
+
while (ts.isParenthesizedExpression(init))
|
|
2664
|
+
init = init.expression;
|
|
2665
|
+
if (ts.isFunctionExpression(init) || ts.isArrowFunction(init))
|
|
2666
|
+
fn = init;
|
|
2667
|
+
}
|
|
2668
|
+
if (fn === undefined)
|
|
2669
|
+
return false;
|
|
2670
|
+
const like = fn;
|
|
2671
|
+
const body = like.body;
|
|
2672
|
+
const param = like.parameters[index];
|
|
2673
|
+
if (body === undefined || !ts.isBlock(body) || param === undefined)
|
|
2674
|
+
return false;
|
|
2675
|
+
if (!ts.isIdentifier(param.name) || param.dotDotDotToken !== undefined)
|
|
2676
|
+
return false;
|
|
2677
|
+
if (like.parameters.slice(0, index).some((p) => p.dotDotDotToken !== undefined))
|
|
2678
|
+
return false;
|
|
2679
|
+
const paramName = param.name.text;
|
|
2680
|
+
let deferred = true;
|
|
2681
|
+
ts.walkPreorder(body, (node) => {
|
|
2682
|
+
if (!deferred)
|
|
2683
|
+
return "stop";
|
|
2684
|
+
if (ts.isFunctionLike(node) || ts.isClassExpression(node) || ts.isClassDeclaration(node)) {
|
|
2685
|
+
let child = node;
|
|
2686
|
+
while (ts.isParenthesizedExpression(child.parent))
|
|
2687
|
+
child = child.parent;
|
|
2688
|
+
const returned = ts.isReturnStatement(child.parent) && child.parent.expression === child;
|
|
2689
|
+
const uses = (part) => {
|
|
2690
|
+
let found = false;
|
|
2691
|
+
ts.walkPreorder(part, (inner) => {
|
|
2692
|
+
if (ts.isIdentifier(inner) && inner.text === paramName)
|
|
2693
|
+
found = true;
|
|
2694
|
+
return found ? "stop" : undefined;
|
|
2695
|
+
});
|
|
2696
|
+
return found;
|
|
2697
|
+
};
|
|
2698
|
+
// A returned closure may use the parameter; any other nested
|
|
2699
|
+
// function could escape and run before the result is called. A
|
|
2700
|
+
// returned class still evaluates its heritage, computed keys,
|
|
2701
|
+
// decorators and static initializers when the callee runs.
|
|
2702
|
+
if (returned) {
|
|
2703
|
+
if ((ts.isClassExpression(node) || ts.isClassDeclaration(node)) &&
|
|
2704
|
+
classSyncParts7(node).some(uses))
|
|
2705
|
+
deferred = false;
|
|
2706
|
+
return "skip";
|
|
2707
|
+
}
|
|
2708
|
+
if (uses(node))
|
|
2709
|
+
deferred = false;
|
|
2710
|
+
return "skip";
|
|
2711
|
+
}
|
|
2712
|
+
if (ts.isIdentifier(node) && (node.text === paramName || node.text === "arguments")) {
|
|
2713
|
+
if (node !== param.name)
|
|
2714
|
+
deferred = false;
|
|
2715
|
+
}
|
|
2716
|
+
return undefined;
|
|
2717
|
+
});
|
|
2718
|
+
return deferred;
|
|
2719
|
+
}
|
|
2720
|
+
/** The parts of a class that run where the class is evaluated: heritage
|
|
2721
|
+
* expressions, decorators, computed member keys, static field
|
|
2722
|
+
* initializers and static blocks. Methods and instance fields wait for a
|
|
2723
|
+
* call or a construction. */
|
|
2724
|
+
function classSyncParts7(c) {
|
|
2725
|
+
const decorators = (n) => (n.modifiers ?? []).filter((m) => m.kind === ts.SyntaxKind.Decorator);
|
|
2726
|
+
const parts = [...decorators(c), ...(c.heritageClauses ?? [])];
|
|
2727
|
+
for (const m of c.members) {
|
|
2728
|
+
parts.push(...decorators(m));
|
|
2729
|
+
const memberName = m.name;
|
|
2730
|
+
if (memberName !== undefined && ts.isComputedPropertyName(memberName))
|
|
2731
|
+
parts.push(memberName);
|
|
2732
|
+
if (ts.isClassStaticBlockDeclaration(m))
|
|
2733
|
+
parts.push(m);
|
|
2734
|
+
else if (ts.isPropertyDeclaration(m) &&
|
|
2735
|
+
m.initializer !== undefined &&
|
|
2736
|
+
(ts.getCombinedModifierFlags(m) & ts.ModifierFlags.Static) !== 0)
|
|
2737
|
+
parts.push(m.initializer);
|
|
2738
|
+
}
|
|
2739
|
+
return parts;
|
|
2740
|
+
}
|
|
2741
|
+
/** An identifier or a chain of plain property reads. */
|
|
2742
|
+
function memberChainKey7(e) {
|
|
2743
|
+
while (ts.isPropertyAccessExpression(e))
|
|
2744
|
+
e = e.expression;
|
|
2745
|
+
return ts.isIdentifier(e);
|
|
2746
|
+
}
|
|
2747
|
+
/** The name a declaration node binds, if any. */
|
|
2748
|
+
function declaredName7(node) {
|
|
2749
|
+
if (ts.isVariableDeclaration(node) ||
|
|
2750
|
+
ts.isFunctionDeclaration(node) ||
|
|
2751
|
+
ts.isFunctionExpression(node) ||
|
|
2752
|
+
ts.isClassDeclaration(node) ||
|
|
2753
|
+
ts.isClassExpression(node) ||
|
|
2754
|
+
ts.isBindingElement(node) ||
|
|
2755
|
+
ts.isParameter(node))
|
|
2756
|
+
return node.name;
|
|
2757
|
+
return undefined;
|
|
2758
|
+
}
|
|
2759
|
+
/** A declared builtin whose callback arguments run only as later jobs or
|
|
2760
|
+
* events: the timers, queueMicrotask, promise reactions, and Node APIs
|
|
2761
|
+
* other than the ones that call back before returning. */
|
|
2762
|
+
function laterJobCallee7(checker, callee) {
|
|
2763
|
+
while (ts.isParenthesizedExpression(callee))
|
|
2764
|
+
callee = callee.expression;
|
|
2765
|
+
let name;
|
|
2766
|
+
if (ts.isIdentifier(callee))
|
|
2767
|
+
name = callee;
|
|
2768
|
+
else if (ts.isPropertyAccessExpression(callee) && ts.isIdentifier(callee.name)) {
|
|
2769
|
+
name = callee.name;
|
|
2770
|
+
}
|
|
2771
|
+
else
|
|
2772
|
+
return false;
|
|
2773
|
+
if (SYNC_CALLBACK_HOST_APIS7.has(name.text))
|
|
2774
|
+
return false;
|
|
2775
|
+
let root = callee;
|
|
2776
|
+
while (ts.isPropertyAccessExpression(root))
|
|
2777
|
+
root = root.expression;
|
|
2778
|
+
if (ts.isIdentifier(root) && root.text === "assert")
|
|
2779
|
+
return false;
|
|
2780
|
+
let symbol = checker.getSymbolAtLocation(name);
|
|
2781
|
+
if (symbol !== undefined && symbol.flags & ts.SymbolFlags.Alias) {
|
|
2782
|
+
symbol = checker.getAliasedSymbol(symbol);
|
|
2783
|
+
}
|
|
2784
|
+
if (symbol === undefined)
|
|
2785
|
+
return false;
|
|
2786
|
+
const decls = checker.declarationsOf(symbol);
|
|
2787
|
+
if (decls.length === 0 || !decls.every((d) => d.getSourceFile().isDeclarationFile))
|
|
2788
|
+
return false;
|
|
2789
|
+
if (LATER_JOB_BUILTINS7.has(name.text))
|
|
2790
|
+
return true;
|
|
2791
|
+
// The JavaScript standard library's callbacks mostly run synchronously;
|
|
2792
|
+
// package declarations describe user code.
|
|
2793
|
+
return decls.every((d) => {
|
|
2794
|
+
const file = d.getSourceFile().fileName;
|
|
2795
|
+
return isNodeTypesPath(file) || file === fallbackDtsPath();
|
|
2796
|
+
});
|
|
2797
|
+
}
|
|
2798
|
+
/** Standard-library functions whose callbacks run as later jobs. */
|
|
2799
|
+
const LATER_JOB_BUILTINS7 = new Set([
|
|
2800
|
+
"setTimeout",
|
|
2801
|
+
"setInterval",
|
|
2802
|
+
"setImmediate",
|
|
2803
|
+
"queueMicrotask",
|
|
2804
|
+
"then",
|
|
2805
|
+
"catch",
|
|
2806
|
+
"finally",
|
|
2807
|
+
]);
|
|
2808
|
+
/** Host APIs that can invoke a callback argument before returning. */
|
|
2809
|
+
const SYNC_CALLBACK_HOST_APIS7 = new Set([
|
|
2810
|
+
"apply",
|
|
2811
|
+
"bind",
|
|
2812
|
+
"call",
|
|
2813
|
+
"doesNotReject",
|
|
2814
|
+
"doesNotThrow",
|
|
2815
|
+
"emit",
|
|
2816
|
+
"enterWith",
|
|
2817
|
+
"exit",
|
|
2818
|
+
"rejects",
|
|
2819
|
+
"run",
|
|
2820
|
+
"runInAsyncScope",
|
|
2821
|
+
"throws",
|
|
2822
|
+
]);
|
|
2823
|
+
/** True for a reference whose value the lowering can take from the
|
|
2824
|
+
* binding's checker type instead of its storage: a property key (element
|
|
2825
|
+
* access argument, computed name, `in` operand, through parentheses,
|
|
2826
|
+
* casts and template spans) or a `typeof` operand. */
|
|
2827
|
+
function foldablePosition7(ref) {
|
|
2828
|
+
let child = ref;
|
|
2829
|
+
for (let p = ref.parent; p !== undefined; p = p.parent) {
|
|
2830
|
+
if (ts.isParenthesizedExpression(p) ||
|
|
2831
|
+
ts.isAsExpression(p) ||
|
|
2832
|
+
ts.isSatisfiesExpression(p) ||
|
|
2833
|
+
ts.isNonNullExpression(p) ||
|
|
2834
|
+
ts.isTemplateSpan(p) ||
|
|
2835
|
+
ts.isTemplateExpression(p)) {
|
|
2836
|
+
child = p;
|
|
2837
|
+
continue;
|
|
2838
|
+
}
|
|
2839
|
+
if (ts.isTypeOfExpression(p))
|
|
2840
|
+
return true;
|
|
2841
|
+
if (ts.isElementAccessExpression(p))
|
|
2842
|
+
return p.argumentExpression === child;
|
|
2843
|
+
if (ts.isComputedPropertyName(p))
|
|
2844
|
+
return true;
|
|
2845
|
+
if (ts.isBinaryExpression(p))
|
|
2846
|
+
return p.operatorToken.kind === ts.SyntaxKind.InKeyword && p.left === child;
|
|
2847
|
+
return false;
|
|
2848
|
+
}
|
|
2849
|
+
return false;
|
|
2850
|
+
}
|
|
2851
|
+
/** The identifiers a binding name (identifier or destructuring pattern)
|
|
2852
|
+
* declares. */
|
|
2853
|
+
function boundNames7(name) {
|
|
2854
|
+
if (ts.isIdentifier(name))
|
|
2855
|
+
return [name];
|
|
2856
|
+
const out = [];
|
|
2857
|
+
for (const el of name.elements) {
|
|
2858
|
+
if (ts.isOmittedExpression(el) || el.name === undefined)
|
|
2859
|
+
continue;
|
|
2860
|
+
out.push(...boundNames7(el.name));
|
|
2861
|
+
}
|
|
2862
|
+
return out;
|
|
2863
|
+
}
|
|
2864
|
+
/** A namespace declaration whose body holds only types (interfaces, type
|
|
2865
|
+
* aliases, nested type-only namespaces) — no runtime object exists. */
|
|
2866
|
+
function typeOnlyNamespace7(decl) {
|
|
2867
|
+
let body = decl.body;
|
|
2868
|
+
while (body !== undefined && ts.isModuleDeclaration(body))
|
|
2869
|
+
body = body.body;
|
|
2870
|
+
if (body === undefined || !ts.isModuleBlock(body))
|
|
2871
|
+
return true;
|
|
2872
|
+
return body.statements.every((s) => ts.isInterfaceDeclaration(s) ||
|
|
2873
|
+
ts.isTypeAliasDeclaration(s) ||
|
|
2874
|
+
(ts.isModuleDeclaration(s) && typeOnlyNamespace7(s)));
|
|
2025
2875
|
}
|
|
2026
2876
|
/** Resolves an import specifier from `from` to a source file of the
|
|
2027
2877
|
* program, or null (unresolvable / outside the program). Exported (as
|
|
@@ -2191,7 +3041,13 @@ function preflight7(load) {
|
|
|
2191
3041
|
const file = d.fileName ?? entry.fileName;
|
|
2192
3042
|
const start = d.fileName !== undefined ? d.pos : 0;
|
|
2193
3043
|
const end = d.fileName !== undefined ? d.end : 0;
|
|
2194
|
-
|
|
3044
|
+
const diag = tscPassthroughDiag(message, { file, start, end });
|
|
3045
|
+
const hint = typeWorldHint(d, message, load);
|
|
3046
|
+
if (hint !== null) {
|
|
3047
|
+
diag.typeWorld = true;
|
|
3048
|
+
diag.hint = hint;
|
|
3049
|
+
}
|
|
3050
|
+
return diag;
|
|
2195
3051
|
};
|
|
2196
3052
|
/* TS7 checker change (not finding 5, same discipline): tsgo types a
|
|
2197
3053
|
* NAMESPACE import as the spec's non-callable module namespace object
|
|
@@ -2450,10 +3306,9 @@ function preflight7(load) {
|
|
|
2450
3306
|
// benign-cycle admission block above). Node evaluates such cycles
|
|
2451
3307
|
// benignly (the revisited module is a cache hit, and no binding read
|
|
2452
3308
|
// can hit TDZ or a stale slot), so the guarded %init calls reproduce
|
|
2453
|
-
// its order exactly. Cycles that fail both
|
|
2454
|
-
//
|
|
2455
|
-
//
|
|
2456
|
-
// static story does not model.
|
|
3309
|
+
// its order exactly. Cycles that fail both are judged by the exact
|
|
3310
|
+
// initialization rule: admitted when every early read is modeled by an
|
|
3311
|
+
// initialization check, fenced with SC1016 otherwise.
|
|
2457
3312
|
const edges = new Map();
|
|
2458
3313
|
const refusals = new Map();
|
|
2459
3314
|
const depPositions = new Map();
|
|
@@ -2927,9 +3782,10 @@ function preflight7(load) {
|
|
|
2927
3782
|
// Node's evaluation order: depth-first postorder from the entry, each
|
|
2928
3783
|
// module once, back-edges answered from the cache (a module already
|
|
2929
3784
|
// evaluating is skipped) — which the guarded %init calls reproduce
|
|
2930
|
-
// exactly. Cycles are admitted
|
|
2931
|
-
// semantics are UNOBSERVABLE (JS's partial
|
|
2932
|
-
// silent-misbehavior trap, so SC1016
|
|
3785
|
+
// exactly. Cycles are admitted where Node's partially-initialized
|
|
3786
|
+
// semantics are UNOBSERVABLE or exactly modeled (JS's partial
|
|
3787
|
+
// initialization is otherwise a silent-misbehavior trap, so SC1016
|
|
3788
|
+
// stays for the rest):
|
|
2933
3789
|
// - a DIRECT SELF-IMPORT (the package self-name reference resolving to
|
|
2934
3790
|
// the importing module itself — Node's self-reference rule): the
|
|
2935
3791
|
// imported bindings alias the module's OWN top-level bindings with
|
|
@@ -2941,7 +3797,11 @@ function preflight7(load) {
|
|
|
2941
3797
|
// benign-cycle admission block: every module of the cycle's
|
|
2942
3798
|
// strongly-connected component has an inert top level and the
|
|
2943
3799
|
// closing edge's bindings are used only in deferred positions, so no
|
|
2944
|
-
// read can execute before every member initialized)
|
|
3800
|
+
// read can execute before every member initialized);
|
|
3801
|
+
// - the EXACT INITIALIZATION rule: an ES-module cluster whose early
|
|
3802
|
+
// reads are all let/const bindings with module storage — the
|
|
3803
|
+
// lowering checks each one (cycleEarlyBindings) and throws Node's
|
|
3804
|
+
// ReferenceError on a read before the declaration ran.
|
|
2945
3805
|
const cycleAdmissionReason = makeCycleAdmission(program, (sf) => edges.get(sf) ?? []);
|
|
2946
3806
|
const order = [];
|
|
2947
3807
|
const state = new Map();
|
|
@@ -2957,9 +3817,9 @@ function preflight7(load) {
|
|
|
2957
3817
|
continue;
|
|
2958
3818
|
if (s === "visiting") {
|
|
2959
3819
|
// A back-edge: Node answers it from the cache (the module is
|
|
2960
|
-
// already evaluating) —
|
|
2961
|
-
//
|
|
2962
|
-
//
|
|
3820
|
+
// already evaluating) — admitted by the cheap per-edge rule, the
|
|
3821
|
+
// declaration-only init window rule, or the exact initialization
|
|
3822
|
+
// rule.
|
|
2963
3823
|
const reason = cycleAdmissionReason(sf, e);
|
|
2964
3824
|
if (reason !== null) {
|
|
2965
3825
|
const cycleStart = stack.indexOf(e.dep.fileName);
|
|
@@ -3768,4 +4628,121 @@ export function isCjsExportTableLiteral(obj) {
|
|
|
3768
4628
|
}
|
|
3769
4629
|
return false;
|
|
3770
4630
|
}
|
|
4631
|
+
/** Names other runtimes and the DOM declare that scriptc's type world
|
|
4632
|
+
* (the ES2025 library plus Node types) does not. */
|
|
4633
|
+
const FOREIGN_RUNTIME_GLOBALS = new Set(["Deno", "Bun"]);
|
|
4634
|
+
const DOM_GLOBALS = new Set([
|
|
4635
|
+
"window",
|
|
4636
|
+
"document",
|
|
4637
|
+
"navigator",
|
|
4638
|
+
"location",
|
|
4639
|
+
"localStorage",
|
|
4640
|
+
"sessionStorage",
|
|
4641
|
+
"HTMLElement",
|
|
4642
|
+
"Element",
|
|
4643
|
+
"Document",
|
|
4644
|
+
"Window",
|
|
4645
|
+
"BodyInit",
|
|
4646
|
+
"HeadersInit",
|
|
4647
|
+
"RequestInfo",
|
|
4648
|
+
"XMLHttpRequest",
|
|
4649
|
+
"requestAnimationFrame",
|
|
4650
|
+
]);
|
|
4651
|
+
/** Root identifiers whose members the bundled Node fallback declares. */
|
|
4652
|
+
const NODE_GLOBAL_ROOTS = new Set(["process", "Buffer", "console", "globalThis"]);
|
|
4653
|
+
/** A hint when a TypeScript error comes from scriptc's own type world rather
|
|
4654
|
+
* than from the project: a library member newer than ES2025, a global of
|
|
4655
|
+
* another runtime or of the DOM, a Node member the bundled fallback types
|
|
4656
|
+
* leave out, or the strictNullChecks scriptc enforces. Null otherwise. */
|
|
4657
|
+
function typeWorldHint(d, message, load) {
|
|
4658
|
+
const world = load.typeWorld;
|
|
4659
|
+
if (world === undefined)
|
|
4660
|
+
return null;
|
|
4661
|
+
const quoted = /'([^']+)'/.exec(message)?.[1];
|
|
4662
|
+
// TS2304/TS2552: Cannot find name; TS2580/TS2591/TS2592: missing type
|
|
4663
|
+
// packages; TS2583: needs a newer library.
|
|
4664
|
+
if (d.code === 2304 || d.code === 2552 || d.code === 2583) {
|
|
4665
|
+
if (quoted !== undefined && FOREIGN_RUNTIME_GLOBALS.has(quoted)) {
|
|
4666
|
+
return `'${quoted}' is another runtime's global; scriptc's type world declares the ES2025 library and Node only — feature-test it through globalThis instead, e.g. '(globalThis as { ${quoted}?: unknown }).${quoted}' (the native program runs as Node would, where it is undefined)`;
|
|
4667
|
+
}
|
|
4668
|
+
if (quoted !== undefined && DOM_GLOBALS.has(quoted)) {
|
|
4669
|
+
return `'${quoted}' comes from the DOM library, which scriptc's type world does not include (it checks with the ES2025 library and Node types regardless of the project's "lib") — declare the shape you need locally, or move browser-only code out of the program`;
|
|
4670
|
+
}
|
|
4671
|
+
if (d.code === 2583) {
|
|
4672
|
+
return `scriptc checks with the ES2025 library regardless of the project's "lib" setting, and '${quoted ?? "this name"}' comes from a newer library that does not compile yet`;
|
|
4673
|
+
}
|
|
4674
|
+
}
|
|
4675
|
+
// TS2339/TS2550/TS2551: property does not exist (2550: on this lib).
|
|
4676
|
+
if (d.code === 2339 || d.code === 2550 || d.code === 2551) {
|
|
4677
|
+
const typeText = /on type '([^']+)'/.exec(message)?.[1] ?? "";
|
|
4678
|
+
const newerLib = world.projectLib !== null &&
|
|
4679
|
+
world.projectLib.some((lib) => /esnext|es202[6-9]|es20[3-9]\d/i.test(lib));
|
|
4680
|
+
if (d.code === 2550 || (newerLib && /^[A-Z][A-Za-z0-9]*(?:Constructor)?$/.test(typeText))) {
|
|
4681
|
+
return `scriptc checks with the ES2025 library regardless of the project's "lib" setting, and '${quoted ?? "this member"}' comes from a newer library that does not compile yet — use an ES2025 equivalent here`;
|
|
4682
|
+
}
|
|
4683
|
+
if (world.nodeFallback && d.fileName !== undefined) {
|
|
4684
|
+
const root = receiverRoot(load.program.getSourceFile(d.fileName)?.text ?? "", d.pos);
|
|
4685
|
+
if (root !== null &&
|
|
4686
|
+
(NODE_GLOBAL_ROOTS.has(root) || importsNodeBuiltin(load, d.fileName, root))) {
|
|
4687
|
+
return `the project has no @types/node, so scriptc types Node with its bundled declarations, which list only the members that compile natively — '${quoted ?? "this member"}' does not compile natively yet (https://scriptc.dev/limitations); installing @types/node turns this into a located refusal with a hint`;
|
|
4688
|
+
}
|
|
4689
|
+
}
|
|
4690
|
+
}
|
|
4691
|
+
if (world.forcedStrictNullChecks && /\b(?:null|undefined)\b/.test(message)) {
|
|
4692
|
+
return `the project disables strictNullChecks, which scriptc always enables — this error appears only under strict null checks; narrow the value (or enable "strictNullChecks" in the project to see the same errors from its own tsc)`;
|
|
4693
|
+
}
|
|
4694
|
+
return null;
|
|
4695
|
+
}
|
|
4696
|
+
/** The root identifier of the property access whose member name starts at
|
|
4697
|
+
* `pos` (`process.version` → `process`), or null. */
|
|
4698
|
+
function receiverRoot(text, pos) {
|
|
4699
|
+
let i = pos - 1;
|
|
4700
|
+
while (i >= 0 && /\s/.test(text[i]))
|
|
4701
|
+
i--;
|
|
4702
|
+
if (text[i] !== ".")
|
|
4703
|
+
return null;
|
|
4704
|
+
i--;
|
|
4705
|
+
if (text[i] === "?")
|
|
4706
|
+
i--;
|
|
4707
|
+
let root = null;
|
|
4708
|
+
for (;;) {
|
|
4709
|
+
while (i >= 0 && /\s/.test(text[i]))
|
|
4710
|
+
i--;
|
|
4711
|
+
let j = i;
|
|
4712
|
+
while (j >= 0 && /[\w$]/.test(text[j]))
|
|
4713
|
+
j--;
|
|
4714
|
+
if (j === i)
|
|
4715
|
+
return root;
|
|
4716
|
+
root = text.slice(j + 1, i + 1);
|
|
4717
|
+
i = j;
|
|
4718
|
+
while (i >= 0 && /\s/.test(text[i]))
|
|
4719
|
+
i--;
|
|
4720
|
+
if (text[i] !== ".")
|
|
4721
|
+
return root;
|
|
4722
|
+
i--;
|
|
4723
|
+
if (text[i] === "?")
|
|
4724
|
+
i--;
|
|
4725
|
+
}
|
|
4726
|
+
}
|
|
4727
|
+
/** Whether `name` is bound in `fileName` by an import of a Node builtin. */
|
|
4728
|
+
function importsNodeBuiltin(load, fileName, name) {
|
|
4729
|
+
const sf = load.program.getSourceFile(fileName);
|
|
4730
|
+
for (const stmt of sf?.statements ?? []) {
|
|
4731
|
+
if (!ts.isImportDeclaration(stmt) || !ts.isStringLiteral(stmt.moduleSpecifier))
|
|
4732
|
+
continue;
|
|
4733
|
+
if (canonicalBuiltinModule(stmt.moduleSpecifier.text) === null)
|
|
4734
|
+
continue;
|
|
4735
|
+
const clause = stmt.importClause;
|
|
4736
|
+
if (clause?.name?.text === name)
|
|
4737
|
+
return true;
|
|
4738
|
+
const bindings = clause?.namedBindings;
|
|
4739
|
+
if (bindings && ts.isNamespaceImport(bindings) && bindings.name.text === name)
|
|
4740
|
+
return true;
|
|
4741
|
+
if (bindings &&
|
|
4742
|
+
ts.isNamedImports(bindings) &&
|
|
4743
|
+
bindings.elements.some((e) => e.name.text === name))
|
|
4744
|
+
return true;
|
|
4745
|
+
}
|
|
4746
|
+
return false;
|
|
4747
|
+
}
|
|
3771
4748
|
//# sourceMappingURL=program.js.map
|