@scriptc/compiler 0.2.6 → 0.2.7
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 +5 -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 +40 -0
- package/dist/backend/llvm/alloc.js +205 -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/call-lifetimes.d.ts +15 -3
- package/dist/backend/llvm/call-lifetimes.js +42 -18
- package/dist/backend/llvm/call-lifetimes.js.map +1 -1
- package/dist/backend/llvm/call-lifetimes.test.js +170 -0
- package/dist/backend/llvm/call-lifetimes.test.js.map +1 -1
- package/dist/backend/llvm/classes.d.ts +4 -1
- package/dist/backend/llvm/classes.js +35 -32
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/classes.test.js +36 -3
- 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/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 +149 -0
- package/dist/backend/llvm/dense-array-access.test.js.map +1 -0
- package/dist/backend/llvm/dyn.d.ts +34 -0
- package/dist/backend/llvm/dyn.js +189 -1
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +124 -4
- package/dist/backend/llvm/emitter.js +623 -105
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.test.js +68 -6
- package/dist/backend/llvm/emitter.test.js.map +1 -1
- package/dist/backend/llvm/expr-async.js +58 -4
- 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-calls.js +64 -6
- package/dist/backend/llvm/expr-calls.js.map +1 -1
- package/dist/backend/llvm/expr-containers.js +16 -5
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +92 -2
- 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 +174 -25
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +52 -24
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.js +1 -1
- package/dist/backend/llvm/expr-records.js +3 -3
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +59 -2
- 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/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 +2 -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-filesystem.js +3 -4
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.d.ts +5 -1
- package/dist/backend/llvm/local-array-reads.js +78 -17
- package/dist/backend/llvm/local-array-reads.js.map +1 -1
- package/dist/backend/llvm/local-array-reads.test.js +78 -1
- 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 +48 -6
- package/dist/backend/llvm/local-union-storage.js.map +1 -1
- package/dist/backend/llvm/local-union-storage.test.js +91 -4
- package/dist/backend/llvm/local-union-storage.test.js.map +1 -1
- package/dist/backend/llvm/map-read-lifetimes.test.js +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/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 +69 -2
- package/dist/backend/llvm/shapes.js +259 -27
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/llvm/shapes.test.js +114 -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 +38 -1
- package/dist/backend/llvm/stack-unions.test.js.map +1 -1
- package/dist/backend/llvm/string-construction.test.js +1 -1
- package/dist/backend/llvm/string-key-hash.d.ts +8 -0
- package/dist/backend/llvm/string-key-hash.js +59 -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 +34 -0
- package/dist/backend/llvm/string-key-hash.test.js.map +1 -0
- package/dist/backend/llvm/string-lifetimes.test.js +41 -4
- package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
- 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 +2 -2
- package/dist/backend/llvm/switch-dispatch.test.js.map +1 -1
- package/dist/backend/may-throw.js +3 -0
- package/dist/backend/may-throw.js.map +1 -1
- package/dist/backend/may-throw.test.js +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 +1 -0
- package/dist/backend/native/runtime-inputs.js.map +1 -1
- package/dist/backend/native-codegen-core.d.ts +2 -1
- package/dist/backend/native-codegen-core.js.map +1 -1
- package/dist/backend/native-codegen.d.ts +5 -0
- package/dist/backend/native-codegen.js +4 -0
- package/dist/backend/native-codegen.js.map +1 -1
- package/dist/backend/native-codegen.test.js +23 -0
- 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 +3 -1
- package/dist/backend/native-tools.js +0 -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/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 +5 -4
- package/dist/cli/command.js.map +1 -1
- package/dist/cli/host.d.ts +2 -1
- package/dist/cli/usage.d.ts +1 -1
- package/dist/cli/usage.js +5 -2
- package/dist/cli/usage.js.map +1 -1
- package/dist/compile-types.d.ts +5 -2
- package/dist/diagnostics/diagnostic.js +10 -8
- package/dist/diagnostics/diagnostic.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/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 +23 -0
- package/dist/frontend/lowering/array-values.js +129 -0
- 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/process.d.ts +6 -17
- package/dist/frontend/lowering/builtins/process.js +56 -29
- package/dist/frontend/lowering/builtins/process.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 +4 -0
- package/dist/frontend/lowering/class-assertions.js +12 -4
- 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 +4 -1
- 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/structural.js +9 -6
- package/dist/frontend/lowering/coercions/structural.js.map +1 -1
- 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/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 +363 -49
- 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 +95 -3
- 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 +43 -132
- package/dist/frontend/lowering/containers/array-methods.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/cycle-initialization.d.ts +41 -0
- package/dist/frontend/lowering/cycle-initialization.js +277 -0
- package/dist/frontend/lowering/cycle-initialization.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 +138 -32
- 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 +3 -3
- package/dist/frontend/lowering/lower-calls.js +162 -121
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +2 -0
- package/dist/frontend/lowering/lower-classes.js +45 -43
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +9 -2
- package/dist/frontend/lowering/lower-exprs.js +390 -157
- 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-inspect.js +26 -2
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +10 -2
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +46 -58
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +37 -0
- package/dist/frontend/lowering/lowerer.js +283 -18
- 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-provenance.d.ts +15 -0
- package/dist/frontend/lowering/runtime-optional-provenance.js +40 -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/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/program.d.ts +38 -2
- package/dist/frontend/program.js +440 -59
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +59 -6
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +1 -1
- package/dist/frontend/type-mapper.js +89 -14
- 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/index.js +25 -9
- 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/builtin-signatures.js +2 -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/ir.d.ts +78 -15
- 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 +118 -20
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +269 -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/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.js +27 -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/package.json +20 -20
- package/surface-manifest.json +8 -2
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
import { checkCycleBindingAccesses, refuseUncheckedCycleReads, } from "./cycle-initialization.js";
|
|
2
|
+
import { identityPreservingWidening } from "./coercions/identity.js";
|
|
3
|
+
import { checkedClassAssertion } from "./class-assertions.js";
|
|
4
|
+
import { narrowStoredClassValue, narrowGenericClassValue } from "./class-unions.js";
|
|
5
|
+
import { isOptionalProcessStreamProperty } from "./builtins/process.js";
|
|
6
|
+
import { concreteCollectionNarrow } from "./collection-narrowing.js";
|
|
1
7
|
import { lowerWorkerMetadata } from "./builtins/workers.js";
|
|
2
8
|
import { dynUndefinedExpr, nodeThrowExpr, numLit, varRef } from "../../ir/build.js";
|
|
9
|
+
import { iteratorSlotAdapter } from "./iterator-adapters.js";
|
|
3
10
|
import { lowerBuiltinCall } from "./builtin-calls.js";
|
|
4
11
|
import { CoercionState } from "./coercions/state.js";
|
|
5
12
|
import { widthLiftPlan, unitOnlyElem, recordWidthPlan, describeRecordWidthBlocker, objToRecordPlan, recordToClassPlan, } from "./coercions/structural-plans.js";
|
|
@@ -9,6 +16,7 @@ import { unionRetagMappable, narrowedRetagHelper, strandedUnitTrap, strandedCoer
|
|
|
9
16
|
import { jsvalLiftable, jsvalLiftExpr, unionToJsvalHelper, recordToJsvalHelper, arrayToJsvalHelper, arrayToJsvalArrayHelper, } from "./coercions/island.js";
|
|
10
17
|
import { lowerUtilTypeValue, pathModuleValue, utilTypesModuleValue, } from "./lower-builtin-values.js";
|
|
11
18
|
import { everyExprChild, everyStmtChild, transformStmtList } from "../../ir/traverse.js";
|
|
19
|
+
import { RuntimeOptionalProvenance } from "./runtime-optional-provenance.js";
|
|
12
20
|
import { RuntimeOptionalLocals } from "./runtime-optional-locals.js";
|
|
13
21
|
import { sanitizeUnregisteredClassTypes } from "./sanitize-class-types.js";
|
|
14
22
|
import { UnregisteredClassTypes } from "./unregistered-class-types.js";
|
|
@@ -1358,7 +1366,16 @@ export class Lowerer {
|
|
|
1358
1366
|
runtimeOptionalWidening(actual, expected) {
|
|
1359
1367
|
if (actual.kind !== "union" || this.armTag(actual.unionId, UNDEFINED_T) < 0)
|
|
1360
1368
|
return null;
|
|
1361
|
-
|
|
1369
|
+
const present = this.stripUndefinedArm(actual);
|
|
1370
|
+
if (typeEquals(present, expected))
|
|
1371
|
+
return actual;
|
|
1372
|
+
// Only a bare expected arm gains runtime-optional storage. A slot that
|
|
1373
|
+
// already admits undefined keeps its own checked representation.
|
|
1374
|
+
if (expected.kind === "union" && this.armTag(expected.unionId, UNDEFINED_T) >= 0)
|
|
1375
|
+
return null;
|
|
1376
|
+
return identityPreservingWidening(this, present, expected)
|
|
1377
|
+
? this.runtimeOptionalType(expected)
|
|
1378
|
+
: null;
|
|
1362
1379
|
}
|
|
1363
1380
|
runtimeOptionalType(t) {
|
|
1364
1381
|
if (t.kind === "union")
|
|
@@ -1427,6 +1444,8 @@ export class Lowerer {
|
|
|
1427
1444
|
/** True while re-lowering a base function's 2nd+ instance: the same source
|
|
1428
1445
|
* statements were already counted for the first instance. */
|
|
1429
1446
|
suppressStats = false;
|
|
1447
|
+
/** Comparisons interned by operand representations and equality semantics. */
|
|
1448
|
+
equalityHelpers = new Map();
|
|
1430
1449
|
/** Synthetic array-HOF loop functions (map/filter/forEach desugar),
|
|
1431
1450
|
* interned per method + element/callback-result type: key → fn name. */
|
|
1432
1451
|
arrHofHelpers = new Map();
|
|
@@ -1518,6 +1537,10 @@ export class Lowerer {
|
|
|
1518
1537
|
* node carrying the ?. token is marked handled so the receiver-typed
|
|
1519
1538
|
* lowerings stop declining it (chainBlocked). */
|
|
1520
1539
|
chainRecvByNode = new Map();
|
|
1540
|
+
/** Lowered void calls whose checked type is `never` (they throw or exit).
|
|
1541
|
+
* TypeScript lets such a call stand where any value is expected;
|
|
1542
|
+
* coerceToExpected turns them into diverging sequences. */
|
|
1543
|
+
neverValued = new Set();
|
|
1521
1544
|
chainNarrowedType = new Map();
|
|
1522
1545
|
chainHandled = new Set();
|
|
1523
1546
|
/** for-of-over-matchAll bindings whose `.index` reads the companion-index
|
|
@@ -1549,6 +1572,8 @@ export class Lowerer {
|
|
|
1549
1572
|
/** Named method slots observed before class collection need a callable
|
|
1550
1573
|
* ABI and shared prototype descriptors instead of call-site specialization. */
|
|
1551
1574
|
prototypeMethodAccesses = new Map();
|
|
1575
|
+
/** Field names whose complete source census stores only lexical arrows. */
|
|
1576
|
+
receiverFreeCallbackFields = new Set();
|
|
1552
1577
|
/** Inferred JS methods participating in an override chain keep a vtable
|
|
1553
1578
|
* ABI instead of call-site specialization. Filled before class collection. */
|
|
1554
1579
|
virtualJsMethods = new Set();
|
|
@@ -1726,6 +1751,10 @@ export class Lowerer {
|
|
|
1726
1751
|
* function called above the declaration statement reads that, never a
|
|
1727
1752
|
* NULL slot. Filled by collectGlobals. */
|
|
1728
1753
|
varGlobalEntryInits = new Map();
|
|
1754
|
+
/** Import-cycle bindings with an initialization flag, by global id, and
|
|
1755
|
+
* the top-level statements declaring them (cycle-initialization.ts). */
|
|
1756
|
+
cycleInitFlags = new Map();
|
|
1757
|
+
cycleInitDeclarations = new Map();
|
|
1729
1758
|
get ctx() {
|
|
1730
1759
|
const top = this.fnStack[this.fnStack.length - 1];
|
|
1731
1760
|
if (!top)
|
|
@@ -2874,9 +2903,13 @@ export class Lowerer {
|
|
|
2874
2903
|
* but it is not a runtime proof; promoting only the affected slots keeps
|
|
2875
2904
|
* the rest of the dense ABI unchanged. */
|
|
2876
2905
|
analyzeRuntimeOptionalArrayReads(parts) {
|
|
2906
|
+
const provenance = RuntimeOptionalProvenance.fromEnvironment();
|
|
2907
|
+
// The site whose value the current promotion follows (debug only).
|
|
2908
|
+
let provenanceSite;
|
|
2877
2909
|
const optionalSymbols = new Set();
|
|
2878
2910
|
const optionalReturns = new Set();
|
|
2879
2911
|
const arithmeticReturns = new Map();
|
|
2912
|
+
const primitiveBindings = new Map();
|
|
2880
2913
|
const optionalParams = new Map();
|
|
2881
2914
|
const optionalFields = new Map();
|
|
2882
2915
|
const dynamicObjectEntryRows = new Set();
|
|
@@ -2903,6 +2936,17 @@ export class Lowerer {
|
|
|
2903
2936
|
(projection?.kind === "declared-function" ? projection.signature : null));
|
|
2904
2937
|
};
|
|
2905
2938
|
const functionDeclBySymbol = new Map();
|
|
2939
|
+
const staticFieldsBySymbol = new Map();
|
|
2940
|
+
for (const info of this.classes.values()) {
|
|
2941
|
+
for (const field of info.staticFields) {
|
|
2942
|
+
const declaration = field.initializer.parent;
|
|
2943
|
+
if (!ts.isPropertyDeclaration(declaration))
|
|
2944
|
+
continue;
|
|
2945
|
+
const symbol = symbolOf(declaration.name);
|
|
2946
|
+
if (symbol)
|
|
2947
|
+
staticFieldsBySymbol.set(symbol, field);
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2906
2950
|
const signatureBySymbol = new Map();
|
|
2907
2951
|
const methodFamilies = new Map();
|
|
2908
2952
|
const familyBySymbol = new Map();
|
|
@@ -2999,11 +3043,12 @@ export class Lowerer {
|
|
|
2999
3043
|
}
|
|
3000
3044
|
return false;
|
|
3001
3045
|
};
|
|
3002
|
-
const
|
|
3046
|
+
const isIndexedRead = (node) => {
|
|
3003
3047
|
const e = peel(node);
|
|
3004
3048
|
if (!ts.isElementAccessExpression(e))
|
|
3005
3049
|
return false;
|
|
3006
|
-
|
|
3050
|
+
const kind = this.mapTypeOf(this.typeOf(e.expression))?.kind;
|
|
3051
|
+
return kind === "array" || kind === "string";
|
|
3007
3052
|
};
|
|
3008
3053
|
const isDynamicObjectEntryRead = (node) => {
|
|
3009
3054
|
const read = peel(node);
|
|
@@ -3038,7 +3083,9 @@ export class Lowerer {
|
|
|
3038
3083
|
if (explicitlyNonNull(node))
|
|
3039
3084
|
return false;
|
|
3040
3085
|
const e = peel(node);
|
|
3041
|
-
if (
|
|
3086
|
+
if (isIndexedRead(e))
|
|
3087
|
+
return true;
|
|
3088
|
+
if (ts.isPropertyAccessExpression(e) && isOptionalProcessStreamProperty(this, e))
|
|
3042
3089
|
return true;
|
|
3043
3090
|
if (ts.isCallExpression(e) && this.runtimeOptionalReduceTypes.has(e))
|
|
3044
3091
|
return true;
|
|
@@ -3058,6 +3105,11 @@ export class Lowerer {
|
|
|
3058
3105
|
const symbol = symbolOf(e);
|
|
3059
3106
|
return symbol !== null && optionalSymbols.has(symbol);
|
|
3060
3107
|
}
|
|
3108
|
+
if (ts.isPropertyAccessExpression(e)) {
|
|
3109
|
+
const symbol = symbolOf(e.name);
|
|
3110
|
+
if (symbol && optionalSymbols.has(symbol))
|
|
3111
|
+
return true;
|
|
3112
|
+
}
|
|
3061
3113
|
if (ts.isCallExpression(e) && ts.isIdentifier(e.expression)) {
|
|
3062
3114
|
const symbol = callableSymbolOf(e.expression);
|
|
3063
3115
|
return symbol !== null && optionalReturns.has(symbol);
|
|
@@ -3085,11 +3137,31 @@ export class Lowerer {
|
|
|
3085
3137
|
}
|
|
3086
3138
|
return false;
|
|
3087
3139
|
};
|
|
3088
|
-
const
|
|
3140
|
+
const optionalPrimitiveResultType = (node) => {
|
|
3089
3141
|
const e = peel(node);
|
|
3090
|
-
if (
|
|
3142
|
+
if (ts.isIdentifier(e)) {
|
|
3143
|
+
const symbol = symbolOf(e);
|
|
3144
|
+
return symbol ? (primitiveBindings.get(symbol) ?? null) : null;
|
|
3145
|
+
}
|
|
3146
|
+
if (ts.isCallExpression(e)) {
|
|
3147
|
+
const symbol = callableSymbolOf(e.expression);
|
|
3148
|
+
return symbol ? (arithmeticReturns.get(symbol) ?? null) : null;
|
|
3149
|
+
}
|
|
3150
|
+
if (!ts.isBinaryExpression(e))
|
|
3151
|
+
return null;
|
|
3152
|
+
if (e.operatorToken.kind === ts.SyntaxKind.QuestionQuestionToken && mayBeOptional(e.left)) {
|
|
3153
|
+
const left = this.mapTypeOf(this.typeOf(e.left));
|
|
3154
|
+
const right = this.mapTypeOf(this.typeOf(e.right));
|
|
3155
|
+
const primitive = (t) => t?.kind === "f64" || t?.kind === "string" || t?.kind === "bool";
|
|
3156
|
+
if (primitive(left) && primitive(right) && !typeEquals(left, right)) {
|
|
3157
|
+
const arms = [left, right].sort((a, b) => (typeKey(a) < typeKey(b) ? -1 : 1));
|
|
3158
|
+
return { kind: "union", unionId: this.unions.intern(arms) };
|
|
3159
|
+
}
|
|
3091
3160
|
return null;
|
|
3092
|
-
|
|
3161
|
+
}
|
|
3162
|
+
if (e.operatorToken.kind !== ts.SyntaxKind.PlusToken)
|
|
3163
|
+
return null;
|
|
3164
|
+
const stringRead = (part) => {
|
|
3093
3165
|
const p = peel(part);
|
|
3094
3166
|
if (!ts.isElementAccessExpression(p))
|
|
3095
3167
|
return false;
|
|
@@ -3097,16 +3169,15 @@ export class Lowerer {
|
|
|
3097
3169
|
if (t?.kind !== "string")
|
|
3098
3170
|
return false;
|
|
3099
3171
|
const recv = this.mapTypeOf(this.typeOf(p.expression));
|
|
3100
|
-
return recv?.kind === "array" && recv.elem.kind === "string";
|
|
3172
|
+
return recv?.kind === "string" || (recv?.kind === "array" && recv.elem.kind === "string");
|
|
3101
3173
|
};
|
|
3102
3174
|
const primitive = (part) => {
|
|
3103
3175
|
const t = this.mapTypeOf(this.typeOf(part));
|
|
3104
3176
|
return t?.kind === "f64" || t?.kind === "string";
|
|
3105
3177
|
};
|
|
3106
|
-
if (!
|
|
3178
|
+
if (!stringRead(e.left) && !stringRead(e.right))
|
|
3107
3179
|
return null;
|
|
3108
|
-
if (!
|
|
3109
|
-
!(primitive(e.right) || stringArrayRead(e.right)))
|
|
3180
|
+
if (!primitive(e.left) || !primitive(e.right))
|
|
3110
3181
|
return null;
|
|
3111
3182
|
return { kind: "union", unionId: this.unions.intern([F64, STRING]) };
|
|
3112
3183
|
};
|
|
@@ -3139,6 +3210,7 @@ export class Lowerer {
|
|
|
3139
3210
|
const symbol = symbolOf(el.name);
|
|
3140
3211
|
if (symbol && !el.initializer && !optionalSymbols.has(symbol)) {
|
|
3141
3212
|
optionalSymbols.add(symbol);
|
|
3213
|
+
provenance?.note("pattern-binding", el.name, init);
|
|
3142
3214
|
// Indexed flow facts can survive a mutating method call in the
|
|
3143
3215
|
// checker. The array's element ABI describes every value a
|
|
3144
3216
|
// position may hold after that call, so bind from that type.
|
|
@@ -3282,6 +3354,7 @@ export class Lowerer {
|
|
|
3282
3354
|
const widened = this.runtimeOptionalType(current);
|
|
3283
3355
|
const previous = this.runtimeOptionalBindingTypes.get(symbol);
|
|
3284
3356
|
this.runtimeOptionalBindingTypes.set(symbol, widened);
|
|
3357
|
+
provenance?.note("callback-parameter", parameter.name, provenanceSite);
|
|
3285
3358
|
if (!previous || !typeEquals(previous, widened))
|
|
3286
3359
|
changed = true;
|
|
3287
3360
|
if (!optionalSymbols.has(symbol)) {
|
|
@@ -3293,6 +3366,7 @@ export class Lowerer {
|
|
|
3293
3366
|
const fnType = this.mapTypeOf(this.typeOf(fn));
|
|
3294
3367
|
if (fnType?.kind === "func" && bodyReturnsOptional(fn)) {
|
|
3295
3368
|
const widenedReturn = this.runtimeOptionalType(fnType.ret);
|
|
3369
|
+
provenance?.note("callback-return", fn, provenanceSite);
|
|
3296
3370
|
const previousReturn = this.runtimeOptionalFunctionReturnType(fn, fnType.ret);
|
|
3297
3371
|
this.runtimeOptionalFunctionReturns.set(fn, widenedReturn);
|
|
3298
3372
|
if (!typeEquals(previousReturn, widenedReturn))
|
|
@@ -3425,6 +3499,16 @@ export class Lowerer {
|
|
|
3425
3499
|
const scan = (node) => {
|
|
3426
3500
|
if (ts.isVariableDeclaration(node)) {
|
|
3427
3501
|
if (node.initializer) {
|
|
3502
|
+
const result = optionalPrimitiveResultType(node.initializer);
|
|
3503
|
+
const symbol = ts.isIdentifier(node.name) ? symbolOf(node.name) : null;
|
|
3504
|
+
if (result?.kind === "union" && symbol) {
|
|
3505
|
+
const before = primitiveBindings.get(symbol);
|
|
3506
|
+
if (!before || !typeEquals(before, result)) {
|
|
3507
|
+
primitiveBindings.set(symbol, result);
|
|
3508
|
+
this.runtimeOptionalBindingTypes.set(symbol, result);
|
|
3509
|
+
changed = true;
|
|
3510
|
+
}
|
|
3511
|
+
}
|
|
3428
3512
|
if (ts.isIdentifier(node.name) && isDynamicObjectEntryRead(node.initializer)) {
|
|
3429
3513
|
const symbol = symbolOf(node.name);
|
|
3430
3514
|
if (symbol && !dynamicObjectEntryRows.has(symbol)) {
|
|
@@ -3436,6 +3520,7 @@ export class Lowerer {
|
|
|
3436
3520
|
const symbol = symbolOf(node.name);
|
|
3437
3521
|
if (symbol && !optionalSymbols.has(symbol)) {
|
|
3438
3522
|
optionalSymbols.add(symbol);
|
|
3523
|
+
provenance?.note("binding", node.name, node.initializer);
|
|
3439
3524
|
changed = true;
|
|
3440
3525
|
}
|
|
3441
3526
|
}
|
|
@@ -3456,6 +3541,8 @@ export class Lowerer {
|
|
|
3456
3541
|
const aliasNew = !optionalReturns.has(symbol);
|
|
3457
3542
|
if (aliasNew)
|
|
3458
3543
|
optionalReturns.add(symbol);
|
|
3544
|
+
if (aliasNew)
|
|
3545
|
+
provenance?.note("function-alias", node.name, node.initializer);
|
|
3459
3546
|
if (aliasNew)
|
|
3460
3547
|
changed = true;
|
|
3461
3548
|
const valueType = this.mapTypeOf(this.typeOf(node.name));
|
|
@@ -3491,8 +3578,10 @@ export class Lowerer {
|
|
|
3491
3578
|
const value = ts.isPropertyAssignment(prop)
|
|
3492
3579
|
? prop.initializer
|
|
3493
3580
|
: prop.name;
|
|
3494
|
-
if (mayBeOptional(value) && noteField(node, name.text))
|
|
3581
|
+
if (mayBeOptional(value) && noteField(node, name.text)) {
|
|
3582
|
+
provenance?.note("literal-field", name, value);
|
|
3495
3583
|
changed = true;
|
|
3584
|
+
}
|
|
3496
3585
|
}
|
|
3497
3586
|
}
|
|
3498
3587
|
}
|
|
@@ -3507,14 +3596,24 @@ export class Lowerer {
|
|
|
3507
3596
|
const symbol = symbolOf(node.left);
|
|
3508
3597
|
if (symbol && !optionalSymbols.has(symbol)) {
|
|
3509
3598
|
optionalSymbols.add(symbol);
|
|
3599
|
+
provenance?.note("assigned-binding", node.left, node.right);
|
|
3510
3600
|
changed = true;
|
|
3511
3601
|
}
|
|
3512
3602
|
}
|
|
3513
|
-
else if (ts.isPropertyAccessExpression(node.left)
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3603
|
+
else if (ts.isPropertyAccessExpression(node.left)) {
|
|
3604
|
+
const field = symbolOf(node.left.name);
|
|
3605
|
+
if (field && staticFieldsBySymbol.has(field) && !optionalSymbols.has(field)) {
|
|
3606
|
+
optionalSymbols.add(field);
|
|
3607
|
+
provenance?.note("static-field", node.left, node.right);
|
|
3517
3608
|
changed = true;
|
|
3609
|
+
}
|
|
3610
|
+
else if (ts.isIdentifier(node.left.expression)) {
|
|
3611
|
+
const symbol = symbolOf(node.left.expression);
|
|
3612
|
+
if (symbol && noteFieldSymbol(symbol, node.left.name.text)) {
|
|
3613
|
+
provenance?.note("assigned-field", node.left, node.right);
|
|
3614
|
+
changed = true;
|
|
3615
|
+
}
|
|
3616
|
+
}
|
|
3518
3617
|
}
|
|
3519
3618
|
}
|
|
3520
3619
|
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
@@ -3555,6 +3654,7 @@ export class Lowerer {
|
|
|
3555
3654
|
}
|
|
3556
3655
|
}
|
|
3557
3656
|
if (nativeArrayReceiver) {
|
|
3657
|
+
provenanceSite = node;
|
|
3558
3658
|
if (promoteHofCallback(callback, callbackIndices))
|
|
3559
3659
|
changed = true;
|
|
3560
3660
|
const method = node.expression.name.text;
|
|
@@ -3605,6 +3705,7 @@ export class Lowerer {
|
|
|
3605
3705
|
continue;
|
|
3606
3706
|
shape.type = widened;
|
|
3607
3707
|
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
3708
|
+
provenance?.note("parameter", parameter, node, "(omitted or undefined argument)");
|
|
3608
3709
|
if (parameter) {
|
|
3609
3710
|
for (const bound of boundIdentifiersOf(parameter.name)) {
|
|
3610
3711
|
const boundSymbol = symbolOf(bound);
|
|
@@ -3629,6 +3730,7 @@ export class Lowerer {
|
|
|
3629
3730
|
const callbackSlot = shape?.type;
|
|
3630
3731
|
if (callbackSlot?.kind === "func" && !ts.isSpreadElement(arg)) {
|
|
3631
3732
|
const optionalCallbackParams = callbackSlot.params.flatMap((type, index) => type.kind === "union" && this.armTag(type.unionId, UNDEFINED_T) >= 0 ? [index] : []);
|
|
3733
|
+
provenanceSite = node;
|
|
3632
3734
|
if (optionalCallbackParams.length > 0 &&
|
|
3633
3735
|
promoteHofCallback(arg, optionalCallbackParams)) {
|
|
3634
3736
|
changed = true;
|
|
@@ -3649,6 +3751,7 @@ export class Lowerer {
|
|
|
3649
3751
|
continue;
|
|
3650
3752
|
rest.type = widened;
|
|
3651
3753
|
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
3754
|
+
provenance?.note("rest-parameter", parameter, arg);
|
|
3652
3755
|
if (parameter && ts.isIdentifier(parameter.name)) {
|
|
3653
3756
|
const bound = symbolOf(parameter.name);
|
|
3654
3757
|
if (bound)
|
|
@@ -3677,6 +3780,7 @@ export class Lowerer {
|
|
|
3677
3780
|
if (set.size !== before) {
|
|
3678
3781
|
changed = true;
|
|
3679
3782
|
const parameter = functionDeclBySymbol.get(target)?.parameters[i];
|
|
3783
|
+
provenance?.note("parameter", parameter, arg, target === symbol ? "" : "(override)");
|
|
3680
3784
|
if (parameter) {
|
|
3681
3785
|
for (const bound of boundIdentifiersOf(parameter.name)) {
|
|
3682
3786
|
const boundSymbol = symbolOf(bound);
|
|
@@ -3700,9 +3804,10 @@ export class Lowerer {
|
|
|
3700
3804
|
for (const expression of returnsOf(decl)) {
|
|
3701
3805
|
if (mayBeOptional(expression) && !optionalReturns.has(symbol)) {
|
|
3702
3806
|
optionalReturns.add(symbol);
|
|
3807
|
+
provenance?.note("return", decl.name ?? decl, expression);
|
|
3703
3808
|
changed = true;
|
|
3704
3809
|
}
|
|
3705
|
-
const arithmetic =
|
|
3810
|
+
const arithmetic = optionalPrimitiveResultType(expression);
|
|
3706
3811
|
if (arithmetic && !arithmeticReturns.has(symbol)) {
|
|
3707
3812
|
arithmeticReturns.set(symbol, arithmetic);
|
|
3708
3813
|
changed = true;
|
|
@@ -3713,6 +3818,13 @@ export class Lowerer {
|
|
|
3713
3818
|
let changed = true;
|
|
3714
3819
|
while (changed) {
|
|
3715
3820
|
changed = false;
|
|
3821
|
+
for (const [symbol, field] of staticFieldsBySymbol) {
|
|
3822
|
+
if (!optionalSymbols.has(symbol) && mayBeOptional(field.initializer)) {
|
|
3823
|
+
optionalSymbols.add(symbol);
|
|
3824
|
+
provenance?.note("static-field", field.initializer.parent, field.initializer);
|
|
3825
|
+
changed = true;
|
|
3826
|
+
}
|
|
3827
|
+
}
|
|
3716
3828
|
for (const sf of sourceFiles)
|
|
3717
3829
|
if (scanFile(sf))
|
|
3718
3830
|
changed = true;
|
|
@@ -3744,11 +3856,27 @@ export class Lowerer {
|
|
|
3744
3856
|
for (const symbol of family) {
|
|
3745
3857
|
if (!optionalReturns.has(symbol)) {
|
|
3746
3858
|
optionalReturns.add(symbol);
|
|
3859
|
+
provenance?.note("return", functionDeclBySymbol.get(symbol), undefined, "(override family)");
|
|
3747
3860
|
changed = true;
|
|
3748
3861
|
}
|
|
3749
3862
|
}
|
|
3750
3863
|
}
|
|
3751
3864
|
}
|
|
3865
|
+
const globalsById = new Map(this.globalsList.map((global) => [global.id, global]));
|
|
3866
|
+
for (const [symbol, field] of staticFieldsBySymbol) {
|
|
3867
|
+
if (!optionalSymbols.has(symbol))
|
|
3868
|
+
continue;
|
|
3869
|
+
const promoted = addUndefined(field.type);
|
|
3870
|
+
// An explicit optional annotation already has the right layout, but
|
|
3871
|
+
// an indexed assignment still invalidates the checker's presence fact.
|
|
3872
|
+
field.type = promoted;
|
|
3873
|
+
field.runtimeOptional = true;
|
|
3874
|
+
const global = globalsById.get(field.globalId);
|
|
3875
|
+
if (global) {
|
|
3876
|
+
global.type = promoted;
|
|
3877
|
+
this.runtimeOptionalGlobals.add(global);
|
|
3878
|
+
}
|
|
3879
|
+
}
|
|
3752
3880
|
for (const [symbol, sig] of signatureBySymbol) {
|
|
3753
3881
|
const params = optionalParams.get(symbol);
|
|
3754
3882
|
if (params) {
|
|
@@ -3880,6 +4008,7 @@ export class Lowerer {
|
|
|
3880
4008
|
}
|
|
3881
4009
|
});
|
|
3882
4010
|
}
|
|
4011
|
+
provenance?.flush();
|
|
3883
4012
|
}
|
|
3884
4013
|
run() {
|
|
3885
4014
|
const parts = this.splitFiles();
|
|
@@ -4123,6 +4252,7 @@ export class Lowerer {
|
|
|
4123
4252
|
// the emitted program references, flushing deferred class diagnostics
|
|
4124
4253
|
// that a reached type makes relevant.
|
|
4125
4254
|
const artifacts = this.moduleArtifacts(functions);
|
|
4255
|
+
refuseUncheckedCycleReads(this, artifacts.classes ?? []);
|
|
4126
4256
|
// Types still naming a class that never REGISTERED after retention's
|
|
4127
4257
|
// flush (JS graphs whose class fences deferred to runtime — the
|
|
4128
4258
|
// sentence-walker's path params, printer tables whose func-typed
|
|
@@ -4137,7 +4267,7 @@ export class Lowerer {
|
|
|
4137
4267
|
const module = this.diags.length > 0
|
|
4138
4268
|
? null
|
|
4139
4269
|
: {
|
|
4140
|
-
irVersion:
|
|
4270
|
+
irVersion: 15,
|
|
4141
4271
|
sourceFile: this.entry.fileName,
|
|
4142
4272
|
functions,
|
|
4143
4273
|
classes: artifacts.classes,
|
|
@@ -4151,6 +4281,8 @@ export class Lowerer {
|
|
|
4151
4281
|
};
|
|
4152
4282
|
if (module)
|
|
4153
4283
|
sanitizeUnregisteredClassTypes(module, (name) => this.classes.has(name));
|
|
4284
|
+
if (module)
|
|
4285
|
+
checkCycleBindingAccesses(this, module);
|
|
4154
4286
|
return {
|
|
4155
4287
|
module,
|
|
4156
4288
|
diagnostics: this.diags,
|
|
@@ -5060,6 +5192,9 @@ export class Lowerer {
|
|
|
5060
5192
|
if (arm !== undefined)
|
|
5061
5193
|
return arm;
|
|
5062
5194
|
}
|
|
5195
|
+
const collection = concreteCollectionNarrow(this, node, t);
|
|
5196
|
+
if (collection)
|
|
5197
|
+
return collection;
|
|
5063
5198
|
// IMPLICIT-ANY instance bodies: an identifier reference to a BOUND
|
|
5064
5199
|
// param answers the call site's concrete type wherever the checker
|
|
5065
5200
|
// still says `any` (there is no `T` for mapType to substitute — the
|
|
@@ -5383,6 +5518,11 @@ export class Lowerer {
|
|
|
5383
5518
|
this.pushDiag(recordShapeMismatchDiag(this.fmt(expected), this.fmt(actual), locOf(node), detail));
|
|
5384
5519
|
throw new PoisonError();
|
|
5385
5520
|
}
|
|
5521
|
+
// Iterator-typed slots hold generators and built-in collection
|
|
5522
|
+
// iterators; any other iterator object (a user class) stays fenced.
|
|
5523
|
+
if (expected.kind === "generator" && actual.kind !== "generator") {
|
|
5524
|
+
this.unsupported("SC1090", node, `'${this.fmt(actual)}' values in an iterator-typed slot (Iterator and IterableIterator slots hold generators and built-in collection iterators)`);
|
|
5525
|
+
}
|
|
5386
5526
|
// Everything else — a plain-kind mismatch like a string flowing into a
|
|
5387
5527
|
// class-instance slot — is tsc-rejected in the lowering world and only
|
|
5388
5528
|
// reaches here through preflight's project-world second chance (e.g. a
|
|
@@ -5438,6 +5578,21 @@ export class Lowerer {
|
|
|
5438
5578
|
}
|
|
5439
5579
|
return literalUnionArm(def, values, (id) => this.shapes.get(id), cached.owners);
|
|
5440
5580
|
}
|
|
5581
|
+
/** Widen only the result view; identical parameter ABIs preserve closure identity. */
|
|
5582
|
+
coerceCovariantFunction(expr, expected) {
|
|
5583
|
+
if (expr.type.kind === "func" &&
|
|
5584
|
+
expected.kind === "func" &&
|
|
5585
|
+
expr.type.rest === expected.rest &&
|
|
5586
|
+
expr.type.restAbi === expected.restAbi &&
|
|
5587
|
+
expr.type.argumentsAll === expected.argumentsAll &&
|
|
5588
|
+
expr.type.params.length === expected.params.length &&
|
|
5589
|
+
expr.type.params.every((type, i) => typeEquals(type, expected.params[i])) &&
|
|
5590
|
+
expr.type.ret.kind === "object" &&
|
|
5591
|
+
expected.ret.kind === "object" &&
|
|
5592
|
+
this.isSubclassOf(expr.type.ret.className, expected.ret.className))
|
|
5593
|
+
return { kind: "upcast", value: expr, type: expected, loc: expr.loc };
|
|
5594
|
+
return null;
|
|
5595
|
+
}
|
|
5441
5596
|
/** Implicit union construction. Wherever a value flows into a typed slot
|
|
5442
5597
|
* (initializer, assignment, call argument, return, field write, record
|
|
5443
5598
|
* literal field, ternary arm) whose expected type is a union and the
|
|
@@ -5446,6 +5601,15 @@ export class Lowerer {
|
|
|
5446
5601
|
* else (including a DIFFERENT union) is left for requireExactShape, which
|
|
5447
5602
|
* rejects union mismatches with SC2003. */
|
|
5448
5603
|
coerceToExpected(expr, expected) {
|
|
5604
|
+
if (expr.type.kind === "void" && expected.kind !== "void" && this.neverValued.has(expr))
|
|
5605
|
+
return this.divergentValue(expr, expected);
|
|
5606
|
+
// Iterator-typed slots: native iterators and differently typed
|
|
5607
|
+
// generators step through an adapter generator.
|
|
5608
|
+
if (expected.kind === "generator" && !typeEquals(expr.type, expected)) {
|
|
5609
|
+
const adapted = iteratorSlotAdapter(this, expr, expected);
|
|
5610
|
+
if (adapted)
|
|
5611
|
+
return adapted;
|
|
5612
|
+
}
|
|
5449
5613
|
// Island boundary, both directions. IN: any static value flowing into
|
|
5450
5614
|
// an any-typed slot marshals implicitly (tsc allows the assignment;
|
|
5451
5615
|
// the marshal is where its semantics live). OUT: an 'any' value
|
|
@@ -5705,6 +5869,9 @@ export class Lowerer {
|
|
|
5705
5869
|
return { kind: "call", callee: adapter, args: [expr], type: expected, loc: expr.loc };
|
|
5706
5870
|
}
|
|
5707
5871
|
}
|
|
5872
|
+
const covariant = this.coerceCovariantFunction(expr, expected);
|
|
5873
|
+
if (covariant)
|
|
5874
|
+
return covariant;
|
|
5708
5875
|
// The GENERAL function-value adapter (funcCoerceAdapter): a function
|
|
5709
5876
|
// whose signature differs from the slot's only by coercible pieces —
|
|
5710
5877
|
// fewer parameters (JS ignores extras: `load(function () {})` into an
|
|
@@ -5728,6 +5895,31 @@ export class Lowerer {
|
|
|
5728
5895
|
this.isSubclassOf(expr.type.className, expected.className)) {
|
|
5729
5896
|
return { kind: "upcast", value: expr, type: expected, loc: expr.loc };
|
|
5730
5897
|
}
|
|
5898
|
+
// Optional subclass storage still has the same object payload. Extract
|
|
5899
|
+
// it with a checked tag test, then widen the class view without copying.
|
|
5900
|
+
if (expected.kind === "object" && expr.type.kind === "union") {
|
|
5901
|
+
const arms = this.unions.get(expr.type.unionId)?.arms;
|
|
5902
|
+
const present = arms?.filter((arm) => !isUnitType(arm)) ?? [];
|
|
5903
|
+
if (present.length === 1 &&
|
|
5904
|
+
present[0].kind === "object" &&
|
|
5905
|
+
present[0].className !== expected.className &&
|
|
5906
|
+
this.isSubclassOf(present[0].className, expected.className)) {
|
|
5907
|
+
// One class arm: the ordinary checked narrow reports a missing value
|
|
5908
|
+
// exactly like same-class storage before the prefix view widens it.
|
|
5909
|
+
return {
|
|
5910
|
+
kind: "upcast",
|
|
5911
|
+
value: this.coerceToExpected(expr, present[0]),
|
|
5912
|
+
type: expected,
|
|
5913
|
+
loc: expr.loc,
|
|
5914
|
+
};
|
|
5915
|
+
}
|
|
5916
|
+
if (present.length > 1 &&
|
|
5917
|
+
present.every((arm) => identityPreservingWidening(this, arm, expected))) {
|
|
5918
|
+
const view = checkedClassAssertion(this, expr, expected, expr.loc);
|
|
5919
|
+
if (view)
|
|
5920
|
+
return view;
|
|
5921
|
+
}
|
|
5922
|
+
}
|
|
5731
5923
|
// CLASS-VALUE widening (classval:D into a classval:C slot): the same
|
|
5732
5924
|
// pointer with only the static type changing — legal exactly when D
|
|
5733
5925
|
// strictly descends from C AND the two completed constructor ABIs
|
|
@@ -6110,6 +6302,17 @@ export class Lowerer {
|
|
|
6110
6302
|
loc: expr.loc,
|
|
6111
6303
|
}
|
|
6112
6304
|
: this.coerceToExpected(expr, expected);
|
|
6305
|
+
// Keep storage intact when ordinary widening already accepts it. Only
|
|
6306
|
+
// a destination needing a more specific class layout uses the site's
|
|
6307
|
+
// refinement and checked extraction.
|
|
6308
|
+
if (!typeEquals(e.type, expected) &&
|
|
6309
|
+
(expected.kind === "object" || expected.kind === "union")) {
|
|
6310
|
+
const site = e.type.kind === "union" ? this.mapTypeOf(this.typeOf(node)) : null;
|
|
6311
|
+
const narrowed = (site && narrowStoredClassValue(this, e, site)) ??
|
|
6312
|
+
narrowGenericClassValue(this, e, expected);
|
|
6313
|
+
if (narrowed)
|
|
6314
|
+
e = this.coerceToExpected(narrowed, expected);
|
|
6315
|
+
}
|
|
6113
6316
|
// Existing JavaScript arrays retain mutations and identity across checked
|
|
6114
6317
|
// slots. Fresh literals have no prior identity and use checked storage
|
|
6115
6318
|
// directly, so later writes can change their inferred element type.
|
|
@@ -6698,6 +6901,42 @@ export class Lowerer {
|
|
|
6698
6901
|
wrappedUndefined(type, loc) {
|
|
6699
6902
|
return wrappedUndefined(this, type, loc);
|
|
6700
6903
|
}
|
|
6904
|
+
/** The value an OMITTED or deleted property leaves in a record field
|
|
6905
|
+
* slot of `type`: the ABSENT state for undefined-armed unions (the slot
|
|
6906
|
+
* reads as undefined but the property does not exist), the dyn
|
|
6907
|
+
* undefined for 'unknown' slots, and null when the slot cannot be
|
|
6908
|
+
* missing. Only legal as a direct field-slot write (IR fieldAbsent). */
|
|
6909
|
+
absentFieldValue(type, loc) {
|
|
6910
|
+
if (type.kind === "union" && this.armTag(type.unionId, UNDEFINED_T) >= 0) {
|
|
6911
|
+
return { kind: "fieldAbsent", unionId: type.unionId, type, loc };
|
|
6912
|
+
}
|
|
6913
|
+
return this.wrappedUndefined(type, loc);
|
|
6914
|
+
}
|
|
6915
|
+
/** A field copy that keeps absence: `value` (the converted read of
|
|
6916
|
+
* `field` from record `obj`, which must be repeatable) when the source
|
|
6917
|
+
* property exists, else the target slot's ABSENT state. Fields that are
|
|
6918
|
+
* always present, and targets that cannot be absent, copy `value`
|
|
6919
|
+
* as-is. Only legal as a direct field-slot write. */
|
|
6920
|
+
presenceKeepingCopy(obj, shapeId, field, value, loc) {
|
|
6921
|
+
const present = this.recordFieldPresent(obj, shapeId, field, loc);
|
|
6922
|
+
if (present.kind !== "recordHas")
|
|
6923
|
+
return value;
|
|
6924
|
+
const absent = this.absentFieldValue(value.type, loc);
|
|
6925
|
+
if (absent?.kind !== "fieldAbsent")
|
|
6926
|
+
return value;
|
|
6927
|
+
return { kind: "ternary", cond: present, then: value, else_: absent, type: value.type, loc };
|
|
6928
|
+
}
|
|
6929
|
+
/** Own-property presence of declared field `field` on record `obj`
|
|
6930
|
+
* (borrowed — callers pass a repeatable receiver): a runtime test for
|
|
6931
|
+
* undefined-armed union fields, which can be absent, and `true` for
|
|
6932
|
+
* every other declared field. */
|
|
6933
|
+
recordFieldPresent(obj, shapeId, field, loc) {
|
|
6934
|
+
const f = this.shapes.get(shapeId)?.fields.find((x) => x.name === field);
|
|
6935
|
+
if (f && f.type.kind === "union" && this.armTag(f.type.unionId, UNDEFINED_T) >= 0) {
|
|
6936
|
+
return { kind: "recordHas", obj, shapeId, field, type: BOOL, loc };
|
|
6937
|
+
}
|
|
6938
|
+
return { kind: "boolLit", value: true, type: BOOL, loc };
|
|
6939
|
+
}
|
|
6701
6940
|
/** The entry value of a binding JS initializes to `undefined` (an
|
|
6702
6941
|
* initializer-less declaration, a hoisted `var` before its statement):
|
|
6703
6942
|
* undefined-armed unions hold the interned undefined arm, and 'any'
|
|
@@ -7102,6 +7341,32 @@ export class Lowerer {
|
|
|
7102
7341
|
declareLocal(nameNode, name, type, mutable) {
|
|
7103
7342
|
return declareContextLocal(this.ctx, name, type, mutable, this.checker.getSymbolAtLocation(nameNode), bindingSource(nameNode));
|
|
7104
7343
|
}
|
|
7344
|
+
/** A never-returning call in a value position of type `expected`: the
|
|
7345
|
+
* call runs for its effects (it throws or exits), and the expression ends
|
|
7346
|
+
* in an unreachable trap instead of producing a value. The result reads an
|
|
7347
|
+
* uninitialized hidden local that control never reaches. */
|
|
7348
|
+
divergentValue(call, expected) {
|
|
7349
|
+
const loc = call.loc;
|
|
7350
|
+
const slot = this.declareHiddenLocal("%never", expected);
|
|
7351
|
+
slot.mutable = true;
|
|
7352
|
+
return {
|
|
7353
|
+
kind: "seqExpr",
|
|
7354
|
+
stmts: [
|
|
7355
|
+
{ kind: "exprStmt", expr: call, loc },
|
|
7356
|
+
{ kind: "varDecl", localId: slot.id, init: null, loc },
|
|
7357
|
+
{
|
|
7358
|
+
kind: "runtimeFence",
|
|
7359
|
+
code: "SC9002",
|
|
7360
|
+
message: "unreachable: a 'never' call returned — please report this",
|
|
7361
|
+
loc,
|
|
7362
|
+
},
|
|
7363
|
+
],
|
|
7364
|
+
result: varRef(slot.id, expected, loc),
|
|
7365
|
+
diverges: true,
|
|
7366
|
+
type: expected,
|
|
7367
|
+
loc,
|
|
7368
|
+
};
|
|
7369
|
+
}
|
|
7105
7370
|
/** A function-scope local bound to NO ts.Symbol — the hidden ABI slot of a
|
|
7106
7371
|
* defaulted parameter (the parameter's symbol binds to the separately-
|
|
7107
7372
|
* declared body local; nothing in the source can name this one). */
|