@tsonic/emitter 0.0.76 → 0.0.77
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/dist/.tsbuildinfo +1 -1
- package/dist/array.test.js +3 -3
- package/dist/array.test.js.map +1 -1
- package/dist/core/format/backend-ast/invariants.test.js +5 -0
- package/dist/core/format/backend-ast/invariants.test.js.map +1 -1
- package/dist/core/format/backend-ast/printer-colon-detection.d.ts.map +1 -1
- package/dist/core/format/backend-ast/printer-colon-detection.js +2 -0
- package/dist/core/format/backend-ast/printer-colon-detection.js.map +1 -1
- package/dist/core/format/backend-ast/printer-expressions.d.ts.map +1 -1
- package/dist/core/format/backend-ast/printer-expressions.js +4 -0
- package/dist/core/format/backend-ast/printer-expressions.js.map +1 -1
- package/dist/core/format/backend-ast/printer-precedence.d.ts.map +1 -1
- package/dist/core/format/backend-ast/printer-precedence.js +1 -0
- package/dist/core/format/backend-ast/printer-precedence.js.map +1 -1
- package/dist/core/format/backend-ast/types/expression-ast.d.ts +5 -1
- package/dist/core/format/backend-ast/types/expression-ast.d.ts.map +1 -1
- package/dist/core/format/backend-ast/utils.d.ts +3 -0
- package/dist/core/format/backend-ast/utils.d.ts.map +1 -1
- package/dist/core/format/backend-ast/utils.js +39 -0
- package/dist/core/format/backend-ast/utils.js.map +1 -1
- package/dist/core/format/backend-ast/utils.test.js +13 -1
- package/dist/core/format/backend-ast/utils.test.js.map +1 -1
- package/dist/core/format/local-names.d.ts.map +1 -1
- package/dist/core/format/local-names.js +3 -2
- package/dist/core/format/local-names.js.map +1 -1
- package/dist/core/format/local-names.test.js +7 -6
- package/dist/core/format/local-names.test.js.map +1 -1
- package/dist/core/format/module-emitter/orchestrator.d.ts.map +1 -1
- package/dist/core/format/module-emitter/orchestrator.js +3 -1
- package/dist/core/format/module-emitter/orchestrator.js.map +1 -1
- package/dist/core/format/module-emitter/static-container.d.ts.map +1 -1
- package/dist/core/format/module-emitter/static-container.js +2 -4
- package/dist/core/format/module-emitter/static-container.js.map +1 -1
- package/dist/core/module-emitter-cases/class-and-recursion.test.js +4 -1
- package/dist/core/module-emitter-cases/class-and-recursion.test.js.map +1 -1
- package/dist/core/module-emitter-cases/static-containers.test.js +111 -1
- package/dist/core/module-emitter-cases/static-containers.test.js.map +1 -1
- package/dist/core/semantic/adapt-result.d.ts +20 -0
- package/dist/core/semantic/adapt-result.d.ts.map +1 -0
- package/dist/core/semantic/adapt-result.js +30 -0
- package/dist/core/semantic/adapt-result.js.map +1 -0
- package/dist/core/semantic/array-expected-types.d.ts.map +1 -1
- package/dist/core/semantic/array-expected-types.js.map +1 -1
- package/dist/core/semantic/assignment-flow.d.ts.map +1 -1
- package/dist/core/semantic/assignment-flow.js +26 -3
- package/dist/core/semantic/assignment-flow.js.map +1 -1
- package/dist/core/semantic/async-wrapper-types.d.ts +1 -0
- package/dist/core/semantic/async-wrapper-types.d.ts.map +1 -1
- package/dist/core/semantic/async-wrapper-types.js +19 -1
- package/dist/core/semantic/async-wrapper-types.js.map +1 -1
- package/dist/core/semantic/boolean-condition-main.d.ts.map +1 -1
- package/dist/core/semantic/boolean-condition-main.js +6 -2
- package/dist/core/semantic/boolean-condition-main.js.map +1 -1
- package/dist/core/semantic/boolean-context.test.js +2 -1
- package/dist/core/semantic/boolean-context.test.js.map +1 -1
- package/dist/core/semantic/broad-array-storage.d.ts.map +1 -1
- package/dist/core/semantic/broad-array-storage.js +2 -5
- package/dist/core/semantic/broad-array-storage.js.map +1 -1
- package/dist/core/semantic/broad-object-types.d.ts +1 -0
- package/dist/core/semantic/broad-object-types.d.ts.map +1 -1
- package/dist/core/semantic/broad-object-types.js +39 -0
- package/dist/core/semantic/broad-object-types.js.map +1 -1
- package/dist/core/semantic/clr-type-identity.d.ts +1 -2
- package/dist/core/semantic/clr-type-identity.d.ts.map +1 -1
- package/dist/core/semantic/clr-type-identity.js +3 -65
- package/dist/core/semantic/clr-type-identity.js.map +1 -1
- package/dist/core/semantic/comparable-types.d.ts.map +1 -1
- package/dist/core/semantic/comparable-types.js +61 -27
- package/dist/core/semantic/comparable-types.js.map +1 -1
- package/dist/core/semantic/comparable-types.test.js.map +1 -1
- package/dist/core/semantic/deterministic-type-keys.d.ts.map +1 -1
- package/dist/core/semantic/deterministic-type-keys.js +90 -37
- package/dist/core/semantic/deterministic-type-keys.js.map +1 -1
- package/dist/core/semantic/deterministic-type-keys.test.d.ts +2 -0
- package/dist/core/semantic/deterministic-type-keys.test.d.ts.map +1 -0
- package/dist/core/semantic/deterministic-type-keys.test.js +38 -0
- package/dist/core/semantic/deterministic-type-keys.test.js.map +1 -0
- package/dist/core/semantic/direct-storage-ir-types.d.ts +1 -1
- package/dist/core/semantic/direct-storage-ir-types.d.ts.map +1 -1
- package/dist/core/semantic/direct-storage-ir-types.js +12 -3
- package/dist/core/semantic/direct-storage-ir-types.js.map +1 -1
- package/dist/core/semantic/direct-value-surfaces.d.ts.map +1 -1
- package/dist/core/semantic/direct-value-surfaces.js +165 -6
- package/dist/core/semantic/direct-value-surfaces.js.map +1 -1
- package/dist/core/semantic/direct-value-surfaces.test.js +69 -6
- package/dist/core/semantic/direct-value-surfaces.test.js.map +1 -1
- package/dist/core/semantic/expected-type-matching.d.ts.map +1 -1
- package/dist/core/semantic/expected-type-matching.js +4 -5
- package/dist/core/semantic/expected-type-matching.js.map +1 -1
- package/dist/core/semantic/implicit-interfaces.d.ts.map +1 -1
- package/dist/core/semantic/implicit-interfaces.js.map +1 -1
- package/dist/core/semantic/imports-cases/basic-and-local.test.js +8 -8
- package/dist/core/semantic/imports-cases/basic-and-local.test.js.map +1 -1
- package/dist/core/semantic/imports.js +3 -2
- package/dist/core/semantic/imports.js.map +1 -1
- package/dist/core/semantic/index.d.ts +1 -1
- package/dist/core/semantic/index.d.ts.map +1 -1
- package/dist/core/semantic/index.js +1 -1
- package/dist/core/semantic/index.js.map +1 -1
- package/dist/core/semantic/instanceof-predicate-refinements.d.ts.map +1 -1
- package/dist/core/semantic/instanceof-predicate-refinements.js +1 -9
- package/dist/core/semantic/instanceof-predicate-refinements.js.map +1 -1
- package/dist/core/semantic/js-array-surface-members.d.ts +4 -0
- package/dist/core/semantic/js-array-surface-members.d.ts.map +1 -0
- package/dist/core/semantic/js-array-surface-members.js +32 -0
- package/dist/core/semantic/js-array-surface-members.js.map +1 -0
- package/dist/core/semantic/materialized-narrowing.d.ts +1 -0
- package/dist/core/semantic/materialized-narrowing.d.ts.map +1 -1
- package/dist/core/semantic/materialized-narrowing.js +170 -34
- package/dist/core/semantic/materialized-narrowing.js.map +1 -1
- package/dist/core/semantic/materialized-narrowing.test.js +24 -6
- package/dist/core/semantic/materialized-narrowing.test.js.map +1 -1
- package/dist/core/semantic/module-map.d.ts.map +1 -1
- package/dist/core/semantic/module-map.js +4 -6
- package/dist/core/semantic/module-map.js.map +1 -1
- package/dist/core/semantic/module-type-collisions.d.ts +7 -0
- package/dist/core/semantic/module-type-collisions.d.ts.map +1 -0
- package/dist/core/semantic/module-type-collisions.js +24 -0
- package/dist/core/semantic/module-type-collisions.js.map +1 -0
- package/dist/core/semantic/mutable-storage-helpers.d.ts +1 -1
- package/dist/core/semantic/mutable-storage-helpers.d.ts.map +1 -1
- package/dist/core/semantic/mutable-storage-helpers.js +4 -12
- package/dist/core/semantic/mutable-storage-helpers.js.map +1 -1
- package/dist/core/semantic/naming-collisions.d.ts.map +1 -1
- package/dist/core/semantic/naming-collisions.js +13 -3
- package/dist/core/semantic/naming-collisions.js.map +1 -1
- package/dist/core/semantic/narrowed-expression-types.d.ts +3 -1
- package/dist/core/semantic/narrowed-expression-types.d.ts.map +1 -1
- package/dist/core/semantic/narrowed-expression-types.js +138 -16
- package/dist/core/semantic/narrowed-expression-types.js.map +1 -1
- package/dist/core/semantic/narrowed-union-resolution.d.ts.map +1 -1
- package/dist/core/semantic/narrowed-union-resolution.js +13 -2
- package/dist/core/semantic/narrowed-union-resolution.js.map +1 -1
- package/dist/core/semantic/narrowing-builder-core.d.ts +3 -2
- package/dist/core/semantic/narrowing-builder-core.d.ts.map +1 -1
- package/dist/core/semantic/narrowing-builder-core.js +85 -126
- package/dist/core/semantic/narrowing-builder-core.js.map +1 -1
- package/dist/core/semantic/narrowing-builder-core.test.js +3 -2
- package/dist/core/semantic/narrowing-builder-core.test.js.map +1 -1
- package/dist/core/semantic/narrowing-builder-unions.d.ts.map +1 -1
- package/dist/core/semantic/narrowing-builder-unions.js +43 -7
- package/dist/core/semantic/narrowing-builder-unions.js.map +1 -1
- package/dist/core/semantic/narrowing-builders.d.ts +1 -1
- package/dist/core/semantic/narrowing-builders.d.ts.map +1 -1
- package/dist/core/semantic/narrowing-builders.js +1 -1
- package/dist/core/semantic/narrowing-builders.js.map +1 -1
- package/dist/core/semantic/narrowing-refinements.d.ts +1 -1
- package/dist/core/semantic/narrowing-refinements.d.ts.map +1 -1
- package/dist/core/semantic/narrowing-refinements.js +1 -1
- package/dist/core/semantic/narrowing-refinements.js.map +1 -1
- package/dist/core/semantic/nullable-typeof-refinements.d.ts +1 -5
- package/dist/core/semantic/nullable-typeof-refinements.d.ts.map +1 -1
- package/dist/core/semantic/nullable-typeof-refinements.js +128 -57
- package/dist/core/semantic/nullable-typeof-refinements.js.map +1 -1
- package/dist/core/semantic/nullish-value-helpers.d.ts +1 -1
- package/dist/core/semantic/nullish-value-helpers.d.ts.map +1 -1
- package/dist/core/semantic/nullish-value-helpers.js +18 -9
- package/dist/core/semantic/nullish-value-helpers.js.map +1 -1
- package/dist/core/semantic/runtime-materialization-targets.js +1 -1
- package/dist/core/semantic/runtime-materialization-targets.js.map +1 -1
- package/dist/core/semantic/runtime-reification.d.ts +1 -0
- package/dist/core/semantic/runtime-reification.d.ts.map +1 -1
- package/dist/core/semantic/runtime-reification.js +141 -35
- package/dist/core/semantic/runtime-reification.js.map +1 -1
- package/dist/core/semantic/runtime-union-family-preservation.js +1 -1
- package/dist/core/semantic/runtime-union-family-preservation.js.map +1 -1
- package/dist/core/semantic/runtime-union-matching.d.ts.map +1 -1
- package/dist/core/semantic/runtime-union-matching.js +13 -0
- package/dist/core/semantic/runtime-union-matching.js.map +1 -1
- package/dist/core/semantic/runtime-union-member-mapping.test.js +1 -1
- package/dist/core/semantic/runtime-union-member-mapping.test.js.map +1 -1
- package/dist/core/semantic/runtime-union-ordering.d.ts.map +1 -1
- package/dist/core/semantic/runtime-union-ordering.js +10 -22
- package/dist/core/semantic/runtime-union-ordering.js.map +1 -1
- package/dist/core/semantic/runtime-union-projection.d.ts.map +1 -1
- package/dist/core/semantic/runtime-union-projection.js +23 -7
- package/dist/core/semantic/runtime-union-projection.js.map +1 -1
- package/dist/core/semantic/runtime-union-projection.test.js +19 -1
- package/dist/core/semantic/runtime-union-projection.test.js.map +1 -1
- package/dist/core/semantic/runtime-union-registry.js +13 -13
- package/dist/core/semantic/runtime-union-registry.js.map +1 -1
- package/dist/core/semantic/runtime-unions.d.ts.map +1 -1
- package/dist/core/semantic/runtime-unions.js +47 -21
- package/dist/core/semantic/runtime-unions.js.map +1 -1
- package/dist/core/semantic/runtime-unions.test.js +12 -7
- package/dist/core/semantic/runtime-unions.test.js.map +1 -1
- package/dist/core/semantic/semantic-union-members.d.ts.map +1 -1
- package/dist/core/semantic/semantic-union-members.js.map +1 -1
- package/dist/core/semantic/storage-erased-adaptation.d.ts.map +1 -1
- package/dist/core/semantic/storage-erased-adaptation.js +8 -11
- package/dist/core/semantic/storage-erased-adaptation.js.map +1 -1
- package/dist/core/semantic/storage-erased-adaptation.test.js +4 -1
- package/dist/core/semantic/storage-erased-adaptation.test.js.map +1 -1
- package/dist/core/semantic/storage-types.d.ts.map +1 -1
- package/dist/core/semantic/storage-types.js +4 -2
- package/dist/core/semantic/storage-types.js.map +1 -1
- package/dist/core/semantic/structural-shape-matching.d.ts +5 -1
- package/dist/core/semantic/structural-shape-matching.d.ts.map +1 -1
- package/dist/core/semantic/structural-shape-matching.js +29 -4
- package/dist/core/semantic/structural-shape-matching.js.map +1 -1
- package/dist/core/semantic/symbol-types.d.ts +2 -9
- package/dist/core/semantic/symbol-types.d.ts.map +1 -1
- package/dist/core/semantic/symbol-types.js +7 -11
- package/dist/core/semantic/symbol-types.js.map +1 -1
- package/dist/core/semantic/truthiness-evaluation.d.ts.map +1 -1
- package/dist/core/semantic/truthiness-evaluation.js +3 -3
- package/dist/core/semantic/truthiness-evaluation.js.map +1 -1
- package/dist/core/semantic/type-compatibility.d.ts +4 -2
- package/dist/core/semantic/type-compatibility.d.ts.map +1 -1
- package/dist/core/semantic/type-compatibility.js +62 -2
- package/dist/core/semantic/type-compatibility.js.map +1 -1
- package/dist/core/semantic/type-domains.d.ts +17 -0
- package/dist/core/semantic/type-domains.d.ts.map +1 -0
- package/dist/core/semantic/type-domains.js +7 -0
- package/dist/core/semantic/type-domains.js.map +1 -0
- package/dist/core/semantic/type-equivalence.d.ts.map +1 -1
- package/dist/core/semantic/type-equivalence.js +12 -7
- package/dist/core/semantic/type-equivalence.js.map +1 -1
- package/dist/core/semantic/type-equivalence.test.js +34 -0
- package/dist/core/semantic/type-equivalence.test.js.map +1 -1
- package/dist/core/semantic/type-resolution-cases/array-like-element.test.js +13 -4
- package/dist/core/semantic/type-resolution-cases/array-like-element.test.js.map +1 -1
- package/dist/core/semantic/type-resolution-cases/helpers.d.ts +2 -2
- package/dist/core/semantic/type-resolution-cases/helpers.d.ts.map +1 -1
- package/dist/core/semantic/type-resolution-cases/helpers.js +2 -2
- package/dist/core/semantic/type-resolution-cases/helpers.js.map +1 -1
- package/dist/core/semantic/type-resolution-cases/typeof-narrowing.test.d.ts +2 -0
- package/dist/core/semantic/type-resolution-cases/typeof-narrowing.test.d.ts.map +1 -0
- package/dist/core/semantic/type-resolution-cases/typeof-narrowing.test.js +36 -0
- package/dist/core/semantic/type-resolution-cases/typeof-narrowing.test.js.map +1 -0
- package/dist/core/semantic/type-resolution.test.d.ts +1 -1
- package/dist/core/semantic/type-resolution.test.d.ts.map +1 -1
- package/dist/core/semantic/type-resolution.test.js +1 -1
- package/dist/core/semantic/type-resolution.test.js.map +1 -1
- package/dist/core/semantic/type-substitution.d.ts.map +1 -1
- package/dist/core/semantic/type-substitution.js +2 -1
- package/dist/core/semantic/type-substitution.js.map +1 -1
- package/dist/core/semantic/union-predicate-matching.d.ts.map +1 -1
- package/dist/core/semantic/union-predicate-matching.js +1 -1
- package/dist/core/semantic/union-predicate-matching.js.map +1 -1
- package/dist/core/semantic/union-typeof-matching.d.ts.map +1 -1
- package/dist/core/semantic/union-typeof-matching.js +72 -22
- package/dist/core/semantic/union-typeof-matching.js.map +1 -1
- package/dist/core/semantic/variable-type-resolution.d.ts +1 -0
- package/dist/core/semantic/variable-type-resolution.d.ts.map +1 -1
- package/dist/core/semantic/variable-type-resolution.js +62 -6
- package/dist/core/semantic/variable-type-resolution.js.map +1 -1
- package/dist/duplicate-type-suppression.d.ts.map +1 -1
- package/dist/duplicate-type-suppression.js.map +1 -1
- package/dist/emitter-types/context.d.ts +1 -0
- package/dist/emitter-types/context.d.ts.map +1 -1
- package/dist/emitter-types/context.js +12 -1
- package/dist/emitter-types/context.js.map +1 -1
- package/dist/emitter-types/core.d.ts +10 -9
- package/dist/emitter-types/core.d.ts.map +1 -1
- package/dist/emitter-types/fqn.d.ts +0 -1
- package/dist/emitter-types/fqn.d.ts.map +1 -1
- package/dist/emitter-types/fqn.js +0 -1
- package/dist/emitter-types/fqn.js.map +1 -1
- package/dist/emitter-types/index.d.ts +1 -1
- package/dist/emitter-types/index.d.ts.map +1 -1
- package/dist/emitter-types/index.js +1 -1
- package/dist/emitter-types/index.js.map +1 -1
- package/dist/emitter.d.ts +3 -3
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +1 -7
- package/dist/emitter.js.map +1 -1
- package/dist/expression-emitter.d.ts.map +1 -1
- package/dist/expression-emitter.js +7 -2
- package/dist/expression-emitter.js.map +1 -1
- package/dist/expressions/access-binding.d.ts.map +1 -1
- package/dist/expressions/access-binding.js +32 -46
- package/dist/expressions/access-binding.js.map +1 -1
- package/dist/expressions/access-computed.d.ts.map +1 -1
- package/dist/expressions/access-computed.js +7 -8
- package/dist/expressions/access-computed.js.map +1 -1
- package/dist/expressions/access-length.d.ts +5 -9
- package/dist/expressions/access-length.d.ts.map +1 -1
- package/dist/expressions/access-length.js +17 -225
- package/dist/expressions/access-length.js.map +1 -1
- package/dist/expressions/access-property.d.ts +1 -2
- package/dist/expressions/access-property.d.ts.map +1 -1
- package/dist/expressions/access-property.js +20 -94
- package/dist/expressions/access-property.js.map +1 -1
- package/dist/expressions/access-resolution-receivers.d.ts.map +1 -1
- package/dist/expressions/access-resolution-receivers.js +14 -5
- package/dist/expressions/access-resolution-receivers.js.map +1 -1
- package/dist/expressions/access-resolution-types.d.ts.map +1 -1
- package/dist/expressions/access-resolution-types.js +7 -0
- package/dist/expressions/access-resolution-types.js.map +1 -1
- package/dist/expressions/access.d.ts +2 -2
- package/dist/expressions/access.d.ts.map +1 -1
- package/dist/expressions/access.js +6 -5
- package/dist/expressions/access.js.map +1 -1
- package/dist/expressions/architecture-invariants.test.js +18 -0
- package/dist/expressions/architecture-invariants.test.js.map +1 -1
- package/dist/expressions/await-normalization.d.ts.map +1 -1
- package/dist/expressions/await-normalization.js +53 -13
- package/dist/expressions/await-normalization.js.map +1 -1
- package/dist/expressions/calls/call-analysis.d.ts +0 -1
- package/dist/expressions/calls/call-analysis.d.ts.map +1 -1
- package/dist/expressions/calls/call-analysis.js +0 -7
- package/dist/expressions/calls/call-analysis.js.map +1 -1
- package/dist/expressions/calls/call-arguments-emit.d.ts.map +1 -1
- package/dist/expressions/calls/call-arguments-emit.js +219 -36
- package/dist/expressions/calls/call-arguments-emit.js.map +1 -1
- package/dist/expressions/calls/call-arguments-helpers.d.ts.map +1 -1
- package/dist/expressions/calls/call-arguments-helpers.js.map +1 -1
- package/dist/expressions/calls/call-array-mutation.d.ts.map +1 -1
- package/dist/expressions/calls/call-array-mutation.js +8 -33
- package/dist/expressions/calls/call-array-mutation.js.map +1 -1
- package/dist/expressions/calls/call-array-wrapper.d.ts.map +1 -1
- package/dist/expressions/calls/call-array-wrapper.js +6 -4
- package/dist/expressions/calls/call-array-wrapper.js.map +1 -1
- package/dist/expressions/calls/call-emitter.d.ts +1 -1
- package/dist/expressions/calls/call-emitter.d.ts.map +1 -1
- package/dist/expressions/calls/call-emitter.js +85 -7
- package/dist/expressions/calls/call-emitter.js.map +1 -1
- package/dist/expressions/calls/call-json.d.ts +1 -1
- package/dist/expressions/calls/call-json.d.ts.map +1 -1
- package/dist/expressions/calls/call-json.js +50 -84
- package/dist/expressions/calls/call-json.js.map +1 -1
- package/dist/expressions/calls/call-promise-ir-types.d.ts.map +1 -1
- package/dist/expressions/calls/call-promise-ir-types.js.map +1 -1
- package/dist/expressions/calls/call-runtime-union-guards.d.ts.map +1 -1
- package/dist/expressions/calls/call-runtime-union-guards.js +10 -1
- package/dist/expressions/calls/call-runtime-union-guards.js.map +1 -1
- package/dist/expressions/calls/new-emitter-collections.d.ts +7 -4
- package/dist/expressions/calls/new-emitter-collections.d.ts.map +1 -1
- package/dist/expressions/calls/new-emitter-collections.js +64 -25
- package/dist/expressions/calls/new-emitter-collections.js.map +1 -1
- package/dist/expressions/calls/new-emitter.d.ts.map +1 -1
- package/dist/expressions/calls/new-emitter.js +4 -5
- package/dist/expressions/calls/new-emitter.js.map +1 -1
- package/dist/expressions/direct-storage-types.d.ts.map +1 -1
- package/dist/expressions/direct-storage-types.js +76 -15
- package/dist/expressions/direct-storage-types.js.map +1 -1
- package/dist/expressions/exact-comparison.d.ts.map +1 -1
- package/dist/expressions/exact-comparison.js +3 -1
- package/dist/expressions/exact-comparison.js.map +1 -1
- package/dist/expressions/expected-type-adaptation.d.ts +1 -1
- package/dist/expressions/expected-type-adaptation.d.ts.map +1 -1
- package/dist/expressions/expected-type-adaptation.js +149 -29
- package/dist/expressions/expected-type-adaptation.js.map +1 -1
- package/dist/expressions/expected-type-adaptation.test.js +81 -26
- package/dist/expressions/expected-type-adaptation.test.js.map +1 -1
- package/dist/expressions/identifier-storage.d.ts +5 -0
- package/dist/expressions/identifier-storage.d.ts.map +1 -1
- package/dist/expressions/identifier-storage.js +200 -25
- package/dist/expressions/identifier-storage.js.map +1 -1
- package/dist/expressions/identifiers.d.ts.map +1 -1
- package/dist/expressions/identifiers.js +7 -16
- package/dist/expressions/identifiers.js.map +1 -1
- package/dist/expressions/index-cases/array-wrapper-recursion-b.test.js +3 -3
- package/dist/expressions/index-cases/array-wrapper-recursion-b.test.js.map +1 -1
- package/dist/expressions/index-cases/basic-literals-and-calls.test.js +3 -3
- package/dist/expressions/index-cases/basic-literals-and-calls.test.js.map +1 -1
- package/dist/expressions/index-cases/defaults-and-char-context.test.js +8 -2
- package/dist/expressions/index-cases/defaults-and-char-context.test.js.map +1 -1
- package/dist/expressions/index-cases/dictionary-and-object-initializers-a.test.js +17 -20
- package/dist/expressions/index-cases/dictionary-and-object-initializers-a.test.js.map +1 -1
- package/dist/expressions/index-cases/dictionary-and-object-initializers-b.test.js +7 -8
- package/dist/expressions/index-cases/dictionary-and-object-initializers-b.test.js.map +1 -1
- package/dist/expressions/index-cases/helpers.d.ts +5 -4
- package/dist/expressions/index-cases/helpers.d.ts.map +1 -1
- package/dist/expressions/index-cases/helpers.js +3 -2
- package/dist/expressions/index-cases/helpers.js.map +1 -1
- package/dist/expressions/index-cases/nullable-and-comparisons.test.js +9 -9
- package/dist/expressions/index-cases/nullable-and-comparisons.test.js.map +1 -1
- package/dist/expressions/index-cases/runtime-subset-and-assertions.test.js +3 -3
- package/dist/expressions/index-cases/runtime-subset-and-assertions.test.js.map +1 -1
- package/dist/expressions/index-cases/runtime-union-reification-b.test.js +19 -13
- package/dist/expressions/index-cases/runtime-union-reification-b.test.js.map +1 -1
- package/dist/expressions/index-cases/string-and-array-fallbacks-a.test.js +4 -4
- package/dist/expressions/index-cases/string-and-array-fallbacks-a.test.js.map +1 -1
- package/dist/expressions/lambda-parameters.d.ts.map +1 -1
- package/dist/expressions/lambda-parameters.js +97 -12
- package/dist/expressions/lambda-parameters.js.map +1 -1
- package/dist/expressions/object-literal.d.ts.map +1 -1
- package/dist/expressions/object-literal.js +48 -18
- package/dist/expressions/object-literal.js.map +1 -1
- package/dist/expressions/operators/binary-dispatch.d.ts +1 -1
- package/dist/expressions/operators/binary-dispatch.d.ts.map +1 -1
- package/dist/expressions/operators/binary-dispatch.js +52 -12
- package/dist/expressions/operators/binary-dispatch.js.map +1 -1
- package/dist/expressions/operators/binary-helpers.d.ts.map +1 -1
- package/dist/expressions/operators/binary-helpers.js +11 -1
- package/dist/expressions/operators/binary-helpers.js.map +1 -1
- package/dist/expressions/operators/binary-special-ops.d.ts +1 -11
- package/dist/expressions/operators/binary-special-ops.d.ts.map +1 -1
- package/dist/expressions/operators/binary-special-ops.js +217 -195
- package/dist/expressions/operators/binary-special-ops.js.map +1 -1
- package/dist/expressions/operators/conditional-emitter.d.ts.map +1 -1
- package/dist/expressions/operators/conditional-emitter.js +89 -19
- package/dist/expressions/operators/conditional-emitter.js.map +1 -1
- package/dist/expressions/operators/logical-emitter.js +1 -1
- package/dist/expressions/operators/logical-emitter.js.map +1 -1
- package/dist/expressions/operators/unary-emitter.d.ts.map +1 -1
- package/dist/expressions/operators/unary-emitter.js +7 -50
- package/dist/expressions/operators/unary-emitter.js.map +1 -1
- package/dist/expressions/other.d.ts +2 -6
- package/dist/expressions/other.d.ts.map +1 -1
- package/dist/expressions/other.js +6 -13
- package/dist/expressions/other.js.map +1 -1
- package/dist/expressions/post-emission-adaptation.d.ts +1 -1
- package/dist/expressions/post-emission-adaptation.d.ts.map +1 -1
- package/dist/expressions/post-emission-adaptation.js +55 -150
- package/dist/expressions/post-emission-adaptation.js.map +1 -1
- package/dist/expressions/precedence.test.js +5 -46
- package/dist/expressions/precedence.test.js.map +1 -1
- package/dist/expressions/runtime-union-adaptation-projection.d.ts.map +1 -1
- package/dist/expressions/runtime-union-adaptation-projection.js +25 -4
- package/dist/expressions/runtime-union-adaptation-projection.js.map +1 -1
- package/dist/expressions/runtime-union-adaptation-upcast.d.ts.map +1 -1
- package/dist/expressions/runtime-union-adaptation-upcast.js +268 -31
- package/dist/expressions/runtime-union-adaptation-upcast.js.map +1 -1
- package/dist/expressions/structural-anonymous-targets.d.ts.map +1 -1
- package/dist/expressions/structural-anonymous-targets.js +5 -0
- package/dist/expressions/structural-anonymous-targets.js.map +1 -1
- package/dist/expressions/structural-collection-adaptation.d.ts.map +1 -1
- package/dist/expressions/structural-collection-adaptation.js +4 -2
- package/dist/expressions/structural-collection-adaptation.js.map +1 -1
- package/dist/expressions/structural-object-adaptation.d.ts.map +1 -1
- package/dist/expressions/structural-object-adaptation.js +58 -3
- package/dist/expressions/structural-object-adaptation.js.map +1 -1
- package/dist/expressions/structural-property-model.d.ts.map +1 -1
- package/dist/expressions/structural-property-model.js +7 -3
- package/dist/expressions/structural-property-model.js.map +1 -1
- package/dist/expressions/structural-type-shapes.d.ts.map +1 -1
- package/dist/expressions/structural-type-shapes.js +1 -1
- package/dist/expressions/structural-type-shapes.js.map +1 -1
- package/dist/expressions/structural-type-shapes.test.js +2 -1
- package/dist/expressions/structural-type-shapes.test.js.map +1 -1
- package/dist/expressions/type-assertion-emitters.d.ts.map +1 -1
- package/dist/expressions/type-assertion-emitters.js +231 -15
- package/dist/expressions/type-assertion-emitters.js.map +1 -1
- package/dist/fixture-regression-mirrors.test.js +43 -112
- package/dist/fixture-regression-mirrors.test.js.map +1 -1
- package/dist/generated-files.d.ts +0 -1
- package/dist/generated-files.d.ts.map +1 -1
- package/dist/generated-files.js +0 -229
- package/dist/generated-files.js.map +1 -1
- package/dist/generated-files.test.js +53 -1
- package/dist/generated-files.test.js.map +1 -1
- package/dist/golden-tests/runner.d.ts.map +1 -1
- package/dist/golden-tests/runner.js +1 -0
- package/dist/golden-tests/runner.js.map +1 -1
- package/dist/integration-cases/arrow-and-generics-a.test.js +52 -32
- package/dist/integration-cases/arrow-and-generics-a.test.js.map +1 -1
- package/dist/integration-cases/arrow-and-generics-b.test.js +17 -23
- package/dist/integration-cases/arrow-and-generics-b.test.js.map +1 -1
- package/dist/integration-cases/await-and-intrinsics.test.js +12 -10
- package/dist/integration-cases/await-and-intrinsics.test.js.map +1 -1
- package/dist/integration-cases/clr-iterable-overloads.test.js +58 -27
- package/dist/integration-cases/clr-iterable-overloads.test.js.map +1 -1
- package/dist/integration-cases/full-module-and-promises.test.js +21 -19
- package/dist/integration-cases/full-module-and-promises.test.js.map +1 -1
- package/dist/integration-cases/helpers.d.ts.map +1 -1
- package/dist/integration-cases/helpers.js +12 -33
- package/dist/integration-cases/helpers.js.map +1 -1
- package/dist/integration-cases/may14-downstream-contracts.test.d.ts +2 -0
- package/dist/integration-cases/may14-downstream-contracts.test.d.ts.map +1 -0
- package/dist/integration-cases/may14-downstream-contracts.test.js +522 -0
- package/dist/integration-cases/may14-downstream-contracts.test.js.map +1 -0
- package/dist/integration-cases/object-literals-and-channels.test.js +10 -4
- package/dist/integration-cases/object-literals-and-channels.test.js.map +1 -1
- package/dist/integration-cases/regression-coverage-a.test.js +36 -30
- package/dist/integration-cases/regression-coverage-a.test.js.map +1 -1
- package/dist/integration-cases/regression-coverage-b.test.js +95 -111
- package/dist/integration-cases/regression-coverage-b.test.js.map +1 -1
- package/dist/integration-cases/regression-coverage-c.test.js +499 -197
- package/dist/integration-cases/regression-coverage-c.test.js.map +1 -1
- package/dist/integration.test.d.ts +1 -0
- package/dist/integration.test.d.ts.map +1 -1
- package/dist/integration.test.js +1 -0
- package/dist/integration.test.js.map +1 -1
- package/dist/json-aot-generic.test.js +48 -200
- package/dist/json-aot-generic.test.js.map +1 -1
- package/dist/statements/block-emitters/block-and-return.d.ts +1 -1
- package/dist/statements/block-emitters/block-and-return.d.ts.map +1 -1
- package/dist/statements/block-emitters/block-and-return.js +9 -3
- package/dist/statements/block-emitters/block-and-return.js.map +1 -1
- package/dist/statements/classes/properties.d.ts.map +1 -1
- package/dist/statements/classes/properties.js.map +1 -1
- package/dist/statements/control/conditionals/architecture-invariants.test.d.ts +2 -0
- package/dist/statements/control/conditionals/architecture-invariants.test.d.ts.map +1 -0
- package/dist/statements/control/conditionals/architecture-invariants.test.js +19 -0
- package/dist/statements/control/conditionals/architecture-invariants.test.js.map +1 -0
- package/dist/statements/control/conditionals/branch-context.d.ts +4 -6
- package/dist/statements/control/conditionals/branch-context.d.ts.map +1 -1
- package/dist/statements/control/conditionals/branch-context.js +104 -31
- package/dist/statements/control/conditionals/branch-context.js.map +1 -1
- package/dist/statements/control/conditionals/guard-analysis.d.ts +2 -2
- package/dist/statements/control/conditionals/guard-analysis.d.ts.map +1 -1
- package/dist/statements/control/conditionals/guard-analysis.js +1 -1
- package/dist/statements/control/conditionals/guard-analysis.js.map +1 -1
- package/dist/statements/control/conditionals/guard-detectors-discriminant.d.ts +2 -1
- package/dist/statements/control/conditionals/guard-detectors-discriminant.d.ts.map +1 -1
- package/dist/statements/control/conditionals/guard-detectors-discriminant.js +83 -1
- package/dist/statements/control/conditionals/guard-detectors-discriminant.js.map +1 -1
- package/dist/statements/control/conditionals/guard-detectors-structural.d.ts +2 -7
- package/dist/statements/control/conditionals/guard-detectors-structural.d.ts.map +1 -1
- package/dist/statements/control/conditionals/guard-detectors-structural.js +47 -82
- package/dist/statements/control/conditionals/guard-detectors-structural.js.map +1 -1
- package/dist/statements/control/conditionals/guard-detectors.d.ts +2 -2
- package/dist/statements/control/conditionals/guard-detectors.d.ts.map +1 -1
- package/dist/statements/control/conditionals/guard-detectors.js +2 -2
- package/dist/statements/control/conditionals/guard-detectors.js.map +1 -1
- package/dist/statements/control/conditionals/guard-extraction.d.ts +5 -7
- package/dist/statements/control/conditionals/guard-extraction.d.ts.map +1 -1
- package/dist/statements/control/conditionals/guard-extraction.js +3 -158
- package/dist/statements/control/conditionals/guard-extraction.js.map +1 -1
- package/dist/statements/control/conditionals/guard-types.d.ts +16 -26
- package/dist/statements/control/conditionals/guard-types.d.ts.map +1 -1
- package/dist/statements/control/conditionals/guard-types.js +23 -1
- package/dist/statements/control/conditionals/guard-types.js.map +1 -1
- package/dist/statements/control/conditionals/if-emit-instanceof-guards.d.ts.map +1 -1
- package/dist/statements/control/conditionals/if-emit-instanceof-guards.js +5 -8
- package/dist/statements/control/conditionals/if-emit-instanceof-guards.js.map +1 -1
- package/dist/statements/control/conditionals/if-emit-predicate-guards.d.ts +2 -8
- package/dist/statements/control/conditionals/if-emit-predicate-guards.d.ts.map +1 -1
- package/dist/statements/control/conditionals/if-emit-predicate-guards.js +4 -84
- package/dist/statements/control/conditionals/if-emit-predicate-guards.js.map +1 -1
- package/dist/statements/control/conditionals/if-emit-property-discriminant-guards.d.ts +2 -0
- package/dist/statements/control/conditionals/if-emit-property-discriminant-guards.d.ts.map +1 -1
- package/dist/statements/control/conditionals/if-emit-property-discriminant-guards.js +87 -3
- package/dist/statements/control/conditionals/if-emit-property-discriminant-guards.js.map +1 -1
- package/dist/statements/control/conditionals/if-emit-typeof-array-guards.d.ts.map +1 -1
- package/dist/statements/control/conditionals/if-emit-typeof-array-guards.js +254 -20
- package/dist/statements/control/conditionals/if-emit-typeof-array-guards.js.map +1 -1
- package/dist/statements/control/conditionals/if-emit-union-guards.d.ts +2 -2
- package/dist/statements/control/conditionals/if-emit-union-guards.d.ts.map +1 -1
- package/dist/statements/control/conditionals/if-emit-union-guards.js +2 -2
- package/dist/statements/control/conditionals/if-emit-union-guards.js.map +1 -1
- package/dist/statements/control/conditionals/if-emitter.d.ts.map +1 -1
- package/dist/statements/control/conditionals/if-emitter.js +36 -43
- package/dist/statements/control/conditionals/if-emitter.js.map +1 -1
- package/dist/statements/control/conditionals/ir-branch-narrowings.d.ts +5 -0
- package/dist/statements/control/conditionals/ir-branch-narrowings.d.ts.map +1 -0
- package/dist/statements/control/conditionals/ir-branch-narrowings.js +16 -0
- package/dist/statements/control/conditionals/ir-branch-narrowings.js.map +1 -0
- package/dist/statements/control/loops.d.ts +2 -9
- package/dist/statements/control/loops.d.ts.map +1 -1
- package/dist/statements/control/loops.js +56 -48
- package/dist/statements/control/loops.js.map +1 -1
- package/dist/statements/declarations/classes.d.ts.map +1 -1
- package/dist/statements/declarations/classes.js.map +1 -1
- package/dist/statements/declarations/interfaces.d.ts.map +1 -1
- package/dist/statements/declarations/interfaces.js.map +1 -1
- package/dist/statements/declarations/structs.test.js +5 -4
- package/dist/statements/declarations/structs.test.js.map +1 -1
- package/dist/statements/declarations/type-aliases.js.map +1 -1
- package/dist/statements/declarations/variables.d.ts.map +1 -1
- package/dist/statements/declarations/variables.js +7 -4
- package/dist/statements/declarations/variables.js.map +1 -1
- package/dist/statements/statement-cases/flow-and-void.test.js +3 -3
- package/dist/statements/statement-cases/flow-and-void.test.js.map +1 -1
- package/dist/statements/statement-cases/helpers.d.ts +3 -2
- package/dist/statements/statement-cases/helpers.d.ts.map +1 -1
- package/dist/statements/statement-cases/helpers.js +1 -1
- package/dist/statements/statement-cases/helpers.js.map +1 -1
- package/dist/statements/statement-cases/if-and-instanceof-guards.test.js +21 -21
- package/dist/statements/statement-cases/if-and-instanceof-guards.test.js.map +1 -1
- package/dist/statements/statement-cases/union-guards-basic.test.js +3 -80
- package/dist/statements/statement-cases/union-guards-basic.test.js.map +1 -1
- package/dist/statements/statement-cases/union-guards-nullish-and-object.test.js +0 -196
- package/dist/statements/statement-cases/union-guards-nullish-and-object.test.js.map +1 -1
- package/dist/statements/statement-cases/union-guards-predicate-and-truthy.test.js +15 -15
- package/dist/statements/statement-cases/union-guards-predicate-and-truthy.test.js.map +1 -1
- package/dist/statements/statement-cases/union-guards-remapped-a.test.js +7 -189
- package/dist/statements/statement-cases/union-guards-remapped-a.test.js.map +1 -1
- package/dist/statements/statement-cases/union-guards-remapped-b.test.js +7 -193
- package/dist/statements/statement-cases/union-guards-remapped-b.test.js.map +1 -1
- package/dist/test-ir-strict.d.ts +7 -0
- package/dist/test-ir-strict.d.ts.map +1 -0
- package/dist/test-ir-strict.js +9 -0
- package/dist/test-ir-strict.js.map +1 -0
- package/dist/type-assertion.test.js +5 -4
- package/dist/type-assertion.test.js.map +1 -1
- package/dist/types/emitter.d.ts.map +1 -1
- package/dist/types/emitter.js +7 -1
- package/dist/types/emitter.js.map +1 -1
- package/dist/types/intersections.d.ts +2 -2
- package/dist/types/intersections.d.ts.map +1 -1
- package/dist/types/intersections.js +26 -6
- package/dist/types/intersections.js.map +1 -1
- package/dist/types/parameters.d.ts.map +1 -1
- package/dist/types/parameters.js +30 -5
- package/dist/types/parameters.js.map +1 -1
- package/dist/types/reference-structural-signatures.d.ts.map +1 -1
- package/dist/types/reference-structural-signatures.js +3 -6
- package/dist/types/reference-structural-signatures.js.map +1 -1
- package/dist/types/references-cases/array-and-cross-module.test.js +2 -4
- package/dist/types/references-cases/array-and-cross-module.test.js.map +1 -1
- package/dist/types/references-cases/bindings-and-local.test.js +2 -4
- package/dist/types/references-cases/bindings-and-local.test.js.map +1 -1
- package/dist/types/references-cases/helpers.d.ts +3 -2
- package/dist/types/references-cases/helpers.d.ts.map +1 -1
- package/dist/types/references-cases/helpers.js +2 -1
- package/dist/types/references-cases/helpers.js.map +1 -1
- package/dist/types/references.d.ts.map +1 -1
- package/dist/types/references.js +21 -2
- package/dist/types/references.js.map +1 -1
- package/dist/types/unions-cases/basic-and-ordering.test.js +51 -0
- package/dist/types/unions-cases/basic-and-ordering.test.js.map +1 -1
- package/dist/types/unions.d.ts.map +1 -1
- package/dist/types/unions.js +17 -1
- package/dist/types/unions.js.map +1 -1
- package/dist/types.d.ts +3 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/dist/core/semantic/js-value-types.d.ts +0 -5
- package/dist/core/semantic/js-value-types.d.ts.map +0 -1
- package/dist/core/semantic/js-value-types.js +0 -42
- package/dist/core/semantic/js-value-types.js.map +0 -1
- package/dist/core/semantic/type-resolution-cases/narrow-typeof.test.d.ts +0 -2
- package/dist/core/semantic/type-resolution-cases/narrow-typeof.test.d.ts.map +0 -1
- package/dist/core/semantic/type-resolution-cases/narrow-typeof.test.js +0 -98
- package/dist/core/semantic/type-resolution-cases/narrow-typeof.test.js.map +0 -1
- package/dist/expressions/calls/call-dynamic-import.d.ts +0 -11
- package/dist/expressions/calls/call-dynamic-import.d.ts.map +0 -1
- package/dist/expressions/calls/call-dynamic-import.js +0 -148
- package/dist/expressions/calls/call-dynamic-import.js.map +0 -1
|
@@ -85,26 +85,25 @@ describe("End-to-End Integration", () => {
|
|
|
85
85
|
expect(csharp).to.match(/updatePresenceDomain\(new global::Fixture\.Presence\.domain\.UpdatePresenceParams\s*\{\s*status = input\.status,\s*client = input\.client,\s*pingOnly = input\.pingOnly,\s*slimPresence = input\.slimPresence,\s*historyLimitDays = input\.historyLimitDays,\s*lastUpdateId = input\.lastUpdateId\s*\}\)/);
|
|
86
86
|
expect(csharp).not.to.include("(global::Fixture.Presence.domain.UpdatePresenceParams)(object)input");
|
|
87
87
|
});
|
|
88
|
-
it("uses runtime equality for
|
|
88
|
+
it("uses runtime equality for unknown-vs-boolean strict comparisons", () => {
|
|
89
89
|
const source = `
|
|
90
|
-
export function hasSubdomain(body: Record<string,
|
|
91
|
-
return body
|
|
90
|
+
export function hasSubdomain(body: Record<string, unknown>): boolean {
|
|
91
|
+
return body["allow_subdomains"] === true;
|
|
92
92
|
}
|
|
93
93
|
`;
|
|
94
94
|
const csharp = compileToCSharp(source);
|
|
95
95
|
expect(csharp).to.include('global::System.Object.Equals(body["allow_subdomains"], true)');
|
|
96
96
|
expect(csharp).not.to.include('body["allow_subdomains"] == true');
|
|
97
97
|
});
|
|
98
|
-
it("casts
|
|
98
|
+
it("casts unknown record member reads after typeof guards when assigning to nullable concrete slots", () => {
|
|
99
99
|
const source = `
|
|
100
|
-
import type { JsValue } from "@tsonic/core/types.js";
|
|
101
100
|
|
|
102
101
|
type JwtPayload = {
|
|
103
102
|
email?: string;
|
|
104
103
|
exp?: number;
|
|
105
104
|
};
|
|
106
105
|
|
|
107
|
-
export function read(payloadObject: Record<string,
|
|
106
|
+
export function read(payloadObject: Record<string, unknown>): JwtPayload {
|
|
108
107
|
let exp: number | undefined = undefined;
|
|
109
108
|
if (typeof payloadObject.exp === "number") {
|
|
110
109
|
exp = payloadObject.exp as number;
|
|
@@ -124,16 +123,15 @@ describe("End-to-End Integration", () => {
|
|
|
124
123
|
const csharp = compileToCSharp(source, "/test/test.ts", {
|
|
125
124
|
surface: "@tsonic/js",
|
|
126
125
|
});
|
|
127
|
-
expect(csharp).to.match(/exp\s*=\s*\(
|
|
128
|
-
expect(csharp).to.match(/payload\.email\s*=\s*\(string
|
|
126
|
+
expect(csharp).to.match(/exp\s*=\s*\(\(\(global::System\.Func<object\?>\)[\s\S]*?\)\)\(\) switch \{ int __tsonic_number_int_/);
|
|
127
|
+
expect(csharp).to.match(/payload\.email\s*=\s*\(string\)\(\(global::System\.Func<object\?>\)[\s\S]*?\)\)\(\);/);
|
|
129
128
|
expect(csharp).not.to.include('exp = payloadObject["exp"];');
|
|
130
129
|
expect(csharp).not.to.include('payload.email = payloadObject["email"];');
|
|
131
130
|
});
|
|
132
|
-
it("
|
|
131
|
+
it("rejects broad unknown Array.isArray narrowing before emission", () => {
|
|
133
132
|
const source = `
|
|
134
|
-
import type { JsValue } from "@tsonic/core/types.js";
|
|
135
133
|
|
|
136
|
-
declare function parseJsonValueText(value: string):
|
|
134
|
+
declare function parseJsonValueText(value: string): unknown;
|
|
137
135
|
|
|
138
136
|
export function countObjects(value: string): number {
|
|
139
137
|
const parsed = parseJsonValueText(value);
|
|
@@ -151,13 +149,9 @@ describe("End-to-End Integration", () => {
|
|
|
151
149
|
return count;
|
|
152
150
|
}
|
|
153
151
|
`;
|
|
154
|
-
|
|
152
|
+
expect(() => compileToCSharp(source, "/test/test.ts", {
|
|
155
153
|
surface: "@tsonic/js",
|
|
156
|
-
});
|
|
157
|
-
expect(csharp).to.include("((global::System.Array)parsed).Length");
|
|
158
|
-
expect(csharp).to.include("((global::System.Array)parsed).GetValue(i)");
|
|
159
|
-
expect(csharp).not.to.include("((object)parsed).Length");
|
|
160
|
-
expect(csharp).not.to.include("((object)parsed)[i]");
|
|
154
|
+
})).to.throw(/Array\.isArray cannot narrow a broad runtime value/);
|
|
161
155
|
});
|
|
162
156
|
it("compares optional runtime-union member reads to literals without Match projections", () => {
|
|
163
157
|
const source = `
|
|
@@ -177,7 +171,9 @@ describe("End-to-End Integration", () => {
|
|
|
177
171
|
return "None";
|
|
178
172
|
}
|
|
179
173
|
`;
|
|
180
|
-
const csharp = compileToCSharp(source
|
|
174
|
+
const csharp = compileToCSharp(source, "/test/test.ts", {
|
|
175
|
+
surface: "@tsonic/js",
|
|
176
|
+
});
|
|
181
177
|
expect(csharp).to.include("options?.sameSite is global::Tsonic.Internal.Union<bool, string> __tsonic_union_compare_1");
|
|
182
178
|
expect(csharp).to.include("__tsonic_union_compare_1.Is1()");
|
|
183
179
|
expect(csharp).to.include("__tsonic_union_compare_1.As1() == true");
|
|
@@ -200,7 +196,9 @@ describe("End-to-End Integration", () => {
|
|
|
200
196
|
|
|
201
197
|
return "other";
|
|
202
198
|
}
|
|
203
|
-
|
|
199
|
+
`, "/test/test.ts", {
|
|
200
|
+
surface: "@tsonic/js",
|
|
201
|
+
});
|
|
204
202
|
expect(csharp).to.include("__tsonic_union_compare_1");
|
|
205
203
|
expect(csharp).to.include("__tsonic_union_compare_2");
|
|
206
204
|
});
|
|
@@ -230,7 +228,9 @@ describe("End-to-End Integration", () => {
|
|
|
230
228
|
portOrOptionsOrPath.host
|
|
231
229
|
);
|
|
232
230
|
}
|
|
233
|
-
|
|
231
|
+
`, "/test/test.ts", {
|
|
232
|
+
surface: "@tsonic/js",
|
|
233
|
+
});
|
|
234
234
|
expect(csharp).to.include("portOrOptionsOrPath.Is2()");
|
|
235
235
|
expect(csharp).to.include("portOrOptionsOrPath.Is1()");
|
|
236
236
|
expect(csharp).to.include("return connectPort((portOrOptionsOrPath.As3()).port, (portOrOptionsOrPath.As3()).host);");
|
|
@@ -407,7 +407,7 @@ describe("End-to-End Integration", () => {
|
|
|
407
407
|
);
|
|
408
408
|
}
|
|
409
409
|
`, "/test/test.ts", { surface: "@tsonic/nodejs" }));
|
|
410
|
-
expect(csharp).to.match(/resp\.end\(global::Tsonic\.Internal\.Union<[^>]+>\.
|
|
410
|
+
expect(csharp).to.match(/resp\.end\(global::Tsonic\.Internal\.Union<[^>]+>\.From3\(text\)\);/);
|
|
411
411
|
expect(csharp).to.include('normalizeHeaderValue(resp.getHeader("x-test") == null ? default(global::Tsonic.Internal.Union<string[], string>?) : global::Tsonic.Internal.Union<string[], string>.From2(resp.getHeader("x-test")));');
|
|
412
412
|
expect(csharp).not.to.include("resp.end(text);");
|
|
413
413
|
expect(csharp).not.to.include('normalizeHeaderValue(resp.getHeader("x-test"));');
|
|
@@ -453,13 +453,12 @@ describe("End-to-End Integration", () => {
|
|
|
453
453
|
});
|
|
454
454
|
it("passes boxed storage values through broad calls after typeof-number narrowing", () => {
|
|
455
455
|
const csharp = compileToCSharp(`
|
|
456
|
-
import type { JsValue } from "@tsonic/core/types.js";
|
|
457
456
|
|
|
458
|
-
const toNumberArg = (value:
|
|
457
|
+
const toNumberArg = (value: unknown): number => {
|
|
459
458
|
return Number(value);
|
|
460
459
|
};
|
|
461
460
|
|
|
462
|
-
export function run(args: readonly
|
|
461
|
+
export function run(args: readonly unknown[]): number {
|
|
463
462
|
const arg0 = args.length > 0 ? args[0] : undefined;
|
|
464
463
|
if (typeof arg0 === "number") {
|
|
465
464
|
return toNumberArg(arg0);
|
|
@@ -468,16 +467,27 @@ describe("End-to-End Integration", () => {
|
|
|
468
467
|
return 0;
|
|
469
468
|
}
|
|
470
469
|
`, "/test/test.ts", { surface: "@tsonic/js" });
|
|
471
|
-
expect(csharp).to.include(
|
|
470
|
+
expect(csharp).to.include("if ((arg0 is double || arg0 is int))");
|
|
472
471
|
expect(csharp).to.include("return toNumberArg(arg0);");
|
|
473
472
|
expect(csharp).not.to.include("toNumberArg((object?)(double)arg0)");
|
|
474
473
|
});
|
|
475
|
-
it("
|
|
474
|
+
it("rejects typeof-number narrowing as proof for int storage", () => {
|
|
475
|
+
expect(() => compileToCSharp(`
|
|
476
|
+
import type { int } from "@tsonic/core/types.js";
|
|
477
|
+
|
|
478
|
+
export function readInt(value: unknown): int {
|
|
479
|
+
if (typeof value === "number") {
|
|
480
|
+
return value;
|
|
481
|
+
}
|
|
482
|
+
return 0;
|
|
483
|
+
}
|
|
484
|
+
`, "/test/test.ts", { surface: "@tsonic/js" })).to.throw("Implicit narrowing not allowed");
|
|
485
|
+
});
|
|
486
|
+
it("keeps broad unknown typeof-object guards on the runtime typeof helper instead of union member checks", () => {
|
|
476
487
|
const csharp = compileToCSharp(`
|
|
477
|
-
import type { JsValue } from "@tsonic/core/types.js";
|
|
478
488
|
|
|
479
489
|
export class Checker {
|
|
480
|
-
static isObject(value:
|
|
490
|
+
static isObject(value: unknown | undefined): boolean {
|
|
481
491
|
if (value === undefined || value === null) {
|
|
482
492
|
return false;
|
|
483
493
|
}
|
|
@@ -490,7 +500,8 @@ describe("End-to-End Integration", () => {
|
|
|
490
500
|
}
|
|
491
501
|
}
|
|
492
502
|
`, "/test/test.ts", { surface: "@tsonic/js" });
|
|
493
|
-
expect(csharp).to.include(
|
|
503
|
+
expect(csharp).to.include("value != null");
|
|
504
|
+
expect(csharp).not.to.include("global::Tsonic.Runtime.Operators.@typeof");
|
|
494
505
|
expect(csharp).not.to.include("if (!(((global::System.Object)(value)) != null && (value.Is1() || value.Is2())))");
|
|
495
506
|
});
|
|
496
507
|
it("calls exact external member overloads instead of wrapping object arguments into implementation unions", () => {
|
|
@@ -526,7 +537,7 @@ describe("End-to-End Integration", () => {
|
|
|
526
537
|
" bind(options: BindOptions, callback?: () => void): void;",
|
|
527
538
|
"}",
|
|
528
539
|
].join("\n"),
|
|
529
|
-
}, "src/index.ts");
|
|
540
|
+
}, "src/index.ts", { surface: "@tsonic/js" });
|
|
530
541
|
expect(csharp).to.include("socket.bind(options);");
|
|
531
542
|
expect(csharp).not.to.include("global::Tsonic.Internal.Union<global::System.Action, double, BindOptions>.From3(options)");
|
|
532
543
|
});
|
|
@@ -824,7 +835,7 @@ describe("End-to-End Integration", () => {
|
|
|
824
835
|
});
|
|
825
836
|
it("preserves compiler-generated anonymous carriers over unrelated structural globals", () => {
|
|
826
837
|
const csharp = compileToCSharp(`
|
|
827
|
-
declare function deepEqual(left:
|
|
838
|
+
declare function deepEqual(left: unknown, right: unknown): void;
|
|
828
839
|
|
|
829
840
|
export function run(): void {
|
|
830
841
|
const first = { user: { name: "Alice" } };
|
|
@@ -853,23 +864,22 @@ describe("End-to-End Integration", () => {
|
|
|
853
864
|
});
|
|
854
865
|
it("resolves emitted structural alias storage names during CLR member materialization", () => {
|
|
855
866
|
const csharp = compileToCSharp(`
|
|
856
|
-
import type { JsValue } from "@tsonic/core/types.js";
|
|
857
867
|
import { List } from "@tsonic/dotnet/System.Collections.Generic.js";
|
|
858
868
|
|
|
859
869
|
type NarrowFilter = {
|
|
860
870
|
op: string;
|
|
861
|
-
value:
|
|
871
|
+
value: unknown | undefined;
|
|
862
872
|
negated?: boolean;
|
|
863
873
|
};
|
|
864
874
|
|
|
865
|
-
declare function getObjectField(value:
|
|
875
|
+
declare function getObjectField(value: unknown, key: string): unknown | undefined;
|
|
866
876
|
|
|
867
|
-
export function parse(entries:
|
|
877
|
+
export function parse(entries: unknown[]): NarrowFilter[] | undefined {
|
|
868
878
|
const filters = new List<NarrowFilter>();
|
|
869
879
|
for (let i = 0; i < entries.length; i++) {
|
|
870
880
|
const entry = entries[i]!;
|
|
871
881
|
if (Array.isArray(entry)) {
|
|
872
|
-
const tuple = entry as
|
|
882
|
+
const tuple = entry as unknown[];
|
|
873
883
|
const filter: NarrowFilter = {
|
|
874
884
|
op: tuple[0] as string,
|
|
875
885
|
value: tuple[1],
|
|
@@ -887,7 +897,9 @@ describe("End-to-End Integration", () => {
|
|
|
887
897
|
}
|
|
888
898
|
return filters.ToArray();
|
|
889
899
|
}
|
|
890
|
-
|
|
900
|
+
`, "/test/test.ts", {
|
|
901
|
+
surface: "@tsonic/js",
|
|
902
|
+
});
|
|
891
903
|
expect(csharp).to.include("class NarrowFilter__Alias");
|
|
892
904
|
expect(csharp).to.include("new global::System.Collections.Generic.List<NarrowFilter__Alias>()");
|
|
893
905
|
expect(csharp).to.include("filters.Add(filter);");
|
|
@@ -916,7 +928,7 @@ describe("End-to-End Integration", () => {
|
|
|
916
928
|
}
|
|
917
929
|
`);
|
|
918
930
|
expect(csharp).to.include("class MkdirOptions__Alias");
|
|
919
|
-
expect(csharp).to.include("((global::System.Object)(options))
|
|
931
|
+
expect(csharp).to.include("((global::System.Object)(options)) == null");
|
|
920
932
|
expect(csharp).to.include("options.Is1()");
|
|
921
933
|
expect(csharp).not.to.include("ICE: Anonymous object type reached emitter");
|
|
922
934
|
});
|
|
@@ -924,7 +936,7 @@ describe("End-to-End Integration", () => {
|
|
|
924
936
|
const csharp = compileToCSharp(`
|
|
925
937
|
import { FileNotFoundException } from "@tsonic/dotnet/System.IO.js";
|
|
926
938
|
|
|
927
|
-
export function isMissing(error:
|
|
939
|
+
export function isMissing(error: unknown): boolean {
|
|
928
940
|
return error instanceof FileNotFoundException;
|
|
929
941
|
}
|
|
930
942
|
`);
|
|
@@ -963,6 +975,87 @@ describe("End-to-End Integration", () => {
|
|
|
963
975
|
expect(csharp).not.to.include("readValue_flag");
|
|
964
976
|
expect(csharp).not.to.include("readValue_encoding");
|
|
965
977
|
});
|
|
978
|
+
it("preserves override on methods generated from overload family bodies", () => {
|
|
979
|
+
const source = `
|
|
980
|
+
import { overloads as O } from "@tsonic/core/lang.js";
|
|
981
|
+
import type { int } from "@tsonic/core/types.js";
|
|
982
|
+
|
|
983
|
+
export class DbContext {
|
|
984
|
+
SaveChanges(): int {
|
|
985
|
+
return 0 as int;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
export class WorkspaceDbContext extends DbContext {
|
|
990
|
+
override SaveChanges(): int;
|
|
991
|
+
SaveChanges(_acceptAllChangesOnSuccess?: boolean): int {
|
|
992
|
+
throw new Error("stub");
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
SaveChangesDefault(): int {
|
|
996
|
+
return super.SaveChanges();
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
O<WorkspaceDbContext>()
|
|
1001
|
+
.method((context) => context.SaveChangesDefault)
|
|
1002
|
+
.family((context) => context.SaveChanges);
|
|
1003
|
+
`;
|
|
1004
|
+
const csharp = compileToCSharp(source);
|
|
1005
|
+
expect(csharp).to.include("public override int SaveChanges()");
|
|
1006
|
+
expect(csharp).not.to.include("public new int SaveChanges()");
|
|
1007
|
+
});
|
|
1008
|
+
it("emits expression-tree object literal bodies as anonymous objects", () => {
|
|
1009
|
+
const source = `
|
|
1010
|
+
interface Expression_1<TDelegate> {}
|
|
1011
|
+
|
|
1012
|
+
export class EntityTypeBuilder<TEntity> {
|
|
1013
|
+
HasKey<TKey>(_keySelector: Expression_1<(row: TEntity) => TKey>): void {}
|
|
1014
|
+
HasIndex<TKey>(_indexSelector: Expression_1<(row: TEntity) => TKey>): void {}
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
export class AuthProvider {
|
|
1018
|
+
WorkspaceId: string = "";
|
|
1019
|
+
Id: string = "";
|
|
1020
|
+
DisplayName: string = "";
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
export function configure(builder: EntityTypeBuilder<AuthProvider>): void {
|
|
1024
|
+
builder.HasKey((row: AuthProvider) => ({
|
|
1025
|
+
WorkspaceId: row.WorkspaceId,
|
|
1026
|
+
Id: row.Id,
|
|
1027
|
+
}));
|
|
1028
|
+
|
|
1029
|
+
builder.HasIndex((row: AuthProvider) => ({
|
|
1030
|
+
WorkspaceId: row.WorkspaceId,
|
|
1031
|
+
DisplayName: row.DisplayName,
|
|
1032
|
+
}));
|
|
1033
|
+
}
|
|
1034
|
+
`;
|
|
1035
|
+
const csharp = compileToCSharp(source);
|
|
1036
|
+
expect(csharp).to.include("builder.HasKey((AuthProvider row) => new { WorkspaceId = row.WorkspaceId, Id = row.Id });");
|
|
1037
|
+
expect(csharp).to.include("builder.HasIndex((AuthProvider row) => new { WorkspaceId = row.WorkspaceId, DisplayName = row.DisplayName });");
|
|
1038
|
+
expect(csharp).not.to.include("Dictionary<string, object?>");
|
|
1039
|
+
expect(csharp).not.to.include("new global::System.Collections.Generic.Dictionary");
|
|
1040
|
+
});
|
|
1041
|
+
it("keeps explicit nominal casts on direct member access", () => {
|
|
1042
|
+
const source = `
|
|
1043
|
+
export class Person {
|
|
1044
|
+
name: string;
|
|
1045
|
+
|
|
1046
|
+
constructor(name: string) {
|
|
1047
|
+
this.name = name;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
export function readName(value: object): string {
|
|
1052
|
+
return (value as Person).name;
|
|
1053
|
+
}
|
|
1054
|
+
`;
|
|
1055
|
+
const csharp = compileToCSharp(source);
|
|
1056
|
+
expect(csharp).to.include("return ((Person)value).name;");
|
|
1057
|
+
expect(csharp).not.to.include("Structural.GetProperty");
|
|
1058
|
+
});
|
|
966
1059
|
it("directly specializes awaited array-or-string overloads when omitted parameters fold away", () => {
|
|
967
1060
|
const csharp = compileToCSharp(`
|
|
968
1061
|
import { overloads as O } from "@tsonic/core/lang.js";
|
|
@@ -1050,15 +1143,15 @@ describe("End-to-End Integration", () => {
|
|
|
1050
1143
|
};
|
|
1051
1144
|
|
|
1052
1145
|
export class ServerLike {
|
|
1053
|
-
|
|
1146
|
+
#allowHalfOpen: boolean;
|
|
1054
1147
|
|
|
1055
1148
|
constructor(
|
|
1056
1149
|
optionsOrListener?: ServerOpts | (() => void)
|
|
1057
1150
|
) {
|
|
1058
1151
|
if (typeof optionsOrListener === "function") {
|
|
1059
|
-
this
|
|
1152
|
+
this.#allowHalfOpen = false;
|
|
1060
1153
|
} else {
|
|
1061
|
-
this
|
|
1154
|
+
this.#allowHalfOpen = optionsOrListener?.allowHalfOpen ?? false;
|
|
1062
1155
|
}
|
|
1063
1156
|
}
|
|
1064
1157
|
}
|
|
@@ -1100,11 +1193,19 @@ describe("End-to-End Integration", () => {
|
|
|
1100
1193
|
it("emits source-owned union aliases with source alias carrier names", () => {
|
|
1101
1194
|
const csharp = compileToCSharp(`
|
|
1102
1195
|
class Ok<T> {
|
|
1103
|
-
|
|
1196
|
+
value: T;
|
|
1197
|
+
|
|
1198
|
+
constructor(value: T) {
|
|
1199
|
+
this.value = value;
|
|
1200
|
+
}
|
|
1104
1201
|
}
|
|
1105
1202
|
|
|
1106
1203
|
class Err<E> {
|
|
1107
|
-
|
|
1204
|
+
error: E;
|
|
1205
|
+
|
|
1206
|
+
constructor(error: E) {
|
|
1207
|
+
this.error = error;
|
|
1208
|
+
}
|
|
1108
1209
|
}
|
|
1109
1210
|
|
|
1110
1211
|
type Result<T, E> = Ok<T> | Err<E>;
|
|
@@ -1118,6 +1219,66 @@ describe("End-to-End Integration", () => {
|
|
|
1118
1219
|
expect(csharp).to.include(".From");
|
|
1119
1220
|
expect(csharp).to.not.include("Tsonic.Internal.Union");
|
|
1120
1221
|
});
|
|
1222
|
+
it("erases broad object source-owned union aliases in emitted signatures", () => {
|
|
1223
|
+
const csharp = compileToCSharp(`
|
|
1224
|
+
type ConsoleValue = string | number | boolean | object | null | undefined;
|
|
1225
|
+
|
|
1226
|
+
export function log(...data: ConsoleValue[]): void {
|
|
1227
|
+
}
|
|
1228
|
+
`);
|
|
1229
|
+
expect(csharp).to.include("public static void log(params object?[] data)");
|
|
1230
|
+
expect(csharp).to.not.include("ConsoleValue");
|
|
1231
|
+
expect(csharp).to.not.include("Tsonic.Internal.Union");
|
|
1232
|
+
});
|
|
1233
|
+
it("preserves scalar typeof branches for broad-object-erased unions", () => {
|
|
1234
|
+
const csharp = compileToCSharp(`
|
|
1235
|
+
type Value = string | number | boolean | object | null | undefined;
|
|
1236
|
+
|
|
1237
|
+
export function coerce(value?: Value): boolean {
|
|
1238
|
+
if (value === undefined || value === null) {
|
|
1239
|
+
return false;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
if (typeof value === "boolean") {
|
|
1243
|
+
return value;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
if (typeof value === "number") {
|
|
1247
|
+
return value !== 0;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
return true;
|
|
1251
|
+
}
|
|
1252
|
+
`);
|
|
1253
|
+
expect(csharp).to.include("if (value is bool)");
|
|
1254
|
+
expect(csharp).to.include("if ((value is double || value is int))");
|
|
1255
|
+
expect(csharp).to.include("return (value switch { int ");
|
|
1256
|
+
expect(csharp).to.include("=> (double)__tsonic_number_int_");
|
|
1257
|
+
expect(csharp).to.include("double __tsonic_number_double_");
|
|
1258
|
+
expect(csharp).to.include("var __tsonic_number_value_");
|
|
1259
|
+
expect(csharp).to.not.include("return (double)value != 0");
|
|
1260
|
+
expect(csharp).to.not.include("if (false)");
|
|
1261
|
+
expect(csharp).to.not.include("global::System.Object.Equals((double)value, 0)");
|
|
1262
|
+
});
|
|
1263
|
+
it("uses projected runtime-union member types in boolean contexts", () => {
|
|
1264
|
+
const csharp = compileToCSharp(`
|
|
1265
|
+
type NumberValue = string | number | boolean | null | undefined;
|
|
1266
|
+
|
|
1267
|
+
export function coerce(value?: NumberValue): number {
|
|
1268
|
+
if (value === undefined || value === null) {
|
|
1269
|
+
return 0;
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
if (typeof value === "boolean") {
|
|
1273
|
+
return value ? 1 : 0;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
return 1;
|
|
1277
|
+
}
|
|
1278
|
+
`);
|
|
1279
|
+
expect(csharp).to.include("return (double)((value.As1()) ? 1 : 0);");
|
|
1280
|
+
expect(csharp).to.not.include("value.As1()) is global::Tsonic.Internal.Union");
|
|
1281
|
+
});
|
|
1121
1282
|
it("directly specializes async void overloads when omitted parameters fold away", () => {
|
|
1122
1283
|
const csharp = compileToCSharp(`
|
|
1123
1284
|
import { overloads as O } from "@tsonic/core/lang.js";
|
|
@@ -1159,8 +1320,8 @@ describe("End-to-End Integration", () => {
|
|
|
1159
1320
|
import type { int } from "@tsonic/core/types.js";
|
|
1160
1321
|
|
|
1161
1322
|
export class MkdirOptions {
|
|
1162
|
-
|
|
1163
|
-
|
|
1323
|
+
recursive?: boolean;
|
|
1324
|
+
mode?: int;
|
|
1164
1325
|
}
|
|
1165
1326
|
|
|
1166
1327
|
declare function implDefault(path: string): Promise<void>;
|
|
@@ -1203,8 +1364,8 @@ describe("End-to-End Integration", () => {
|
|
|
1203
1364
|
import type { int } from "@tsonic/core/types.js";
|
|
1204
1365
|
|
|
1205
1366
|
export class MkdirOptions {
|
|
1206
|
-
|
|
1207
|
-
|
|
1367
|
+
recursive?: boolean;
|
|
1368
|
+
mode?: int;
|
|
1208
1369
|
}
|
|
1209
1370
|
|
|
1210
1371
|
declare const fs: {
|
|
@@ -1285,7 +1446,7 @@ describe("End-to-End Integration", () => {
|
|
|
1285
1446
|
it("emits generic property empty-array initializers using the declared element type", () => {
|
|
1286
1447
|
const csharp = compileToCSharp(`
|
|
1287
1448
|
export class Box<T> {
|
|
1288
|
-
|
|
1449
|
+
items: Array<T | null> = [] as Array<T | null>;
|
|
1289
1450
|
}
|
|
1290
1451
|
`);
|
|
1291
1452
|
expect(csharp).to.include("public T?[] items { get; set; } = global::System.Array.Empty<T?>();");
|
|
@@ -1294,14 +1455,17 @@ describe("End-to-End Integration", () => {
|
|
|
1294
1455
|
it("emits generic undefined constructor arguments using the generic default type", () => {
|
|
1295
1456
|
const csharp = compileToCSharp(`
|
|
1296
1457
|
export class IntervalIterationResult<T> {
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
) {
|
|
1458
|
+
done: boolean;
|
|
1459
|
+
value: T | undefined;
|
|
1460
|
+
|
|
1461
|
+
constructor(done: boolean, value: T | undefined) {
|
|
1462
|
+
this.done = done;
|
|
1463
|
+
this.value = value;
|
|
1464
|
+
}
|
|
1301
1465
|
}
|
|
1302
1466
|
|
|
1303
1467
|
export class IntervalAsyncIterator<T> {
|
|
1304
|
-
|
|
1468
|
+
close(): IntervalIterationResult<T> {
|
|
1305
1469
|
return new IntervalIterationResult(true, undefined);
|
|
1306
1470
|
}
|
|
1307
1471
|
}
|
|
@@ -1336,15 +1500,15 @@ describe("End-to-End Integration", () => {
|
|
|
1336
1500
|
O(readFile_text).family(readFile);
|
|
1337
1501
|
|
|
1338
1502
|
export class FsPromises {
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1503
|
+
readFile(path: string): Promise<byte[]>;
|
|
1504
|
+
readFile(path: string, encoding: string): Promise<string>;
|
|
1505
|
+
readFile(_path: any, _encoding?: any): any {
|
|
1342
1506
|
throw new Error("stub");
|
|
1343
1507
|
}
|
|
1344
|
-
|
|
1508
|
+
readFile_bytes(path: string): Promise<byte[]> {
|
|
1345
1509
|
return readFile(path);
|
|
1346
1510
|
}
|
|
1347
|
-
|
|
1511
|
+
readFile_text(path: string, encoding: string): Promise<string> {
|
|
1348
1512
|
return readFile(path, encoding);
|
|
1349
1513
|
}
|
|
1350
1514
|
}
|
|
@@ -1388,17 +1552,17 @@ describe("End-to-End Integration", () => {
|
|
|
1388
1552
|
O(readFileSync_text).family(readFileSync);
|
|
1389
1553
|
|
|
1390
1554
|
export class FsModuleNamespace {
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1555
|
+
readFileSync(path: string): byte[];
|
|
1556
|
+
readFileSync(path: string, encoding: string): string;
|
|
1557
|
+
readFileSync(_path: any, _encoding?: any): any {
|
|
1394
1558
|
throw new Error("stub");
|
|
1395
1559
|
}
|
|
1396
1560
|
|
|
1397
|
-
|
|
1561
|
+
readFileSync_bytes(path: string): byte[] {
|
|
1398
1562
|
return readFileSync(path);
|
|
1399
1563
|
}
|
|
1400
1564
|
|
|
1401
|
-
|
|
1565
|
+
readFileSync_text(path: string, encoding: string): string {
|
|
1402
1566
|
return readFileSync(path, encoding);
|
|
1403
1567
|
}
|
|
1404
1568
|
}
|
|
@@ -1491,31 +1655,31 @@ describe("End-to-End Integration", () => {
|
|
|
1491
1655
|
expect(csharp).not.to.include("return global::System.Convert.ToInt64((byte)holder.TotalMilliseconds);");
|
|
1492
1656
|
expect(csharp).not.to.include("return global::System.Convert.ToInt32((byte)(month + 1));");
|
|
1493
1657
|
});
|
|
1494
|
-
it("
|
|
1495
|
-
|
|
1658
|
+
it("rejects broad JS numbers flowing to imported CLR integral overload parameters", () => {
|
|
1659
|
+
expect(() => compileToCSharp(`
|
|
1496
1660
|
import type { int } from "@tsonic/core/types.js";
|
|
1497
1661
|
import { Process } from "@tsonic/dotnet/System.Diagnostics.js";
|
|
1498
1662
|
|
|
1499
1663
|
declare const process: Process;
|
|
1500
1664
|
|
|
1501
1665
|
class ExecOptions {
|
|
1502
|
-
|
|
1666
|
+
timeout: number = 0;
|
|
1503
1667
|
}
|
|
1504
1668
|
|
|
1505
1669
|
export function run(options?: ExecOptions | null): boolean {
|
|
1506
1670
|
const timeout = options?.timeout ?? 0;
|
|
1507
1671
|
return process.WaitForExit(timeout);
|
|
1508
1672
|
}
|
|
1509
|
-
`);
|
|
1510
|
-
expect(csharp).to.include("return process.WaitForExit((int)timeout);");
|
|
1511
|
-
expect(csharp).not.to.include("return process.WaitForExit(timeout);");
|
|
1673
|
+
`)).to.throw("Implicit narrowing not allowed");
|
|
1512
1674
|
});
|
|
1513
1675
|
it("null-checks optional Array.isArray runtime-union guards before member tests", () => {
|
|
1514
1676
|
const csharp = compileToCSharp(`
|
|
1515
1677
|
export function hasArray(values?: string[] | number): boolean {
|
|
1516
1678
|
return Array.isArray(values);
|
|
1517
1679
|
}
|
|
1518
|
-
|
|
1680
|
+
`, "/test/test.ts", {
|
|
1681
|
+
surface: "@tsonic/js",
|
|
1682
|
+
});
|
|
1519
1683
|
expect(csharp).to.include("((global::System.Object)(values)) != null");
|
|
1520
1684
|
expect(csharp).to.include("values.Is1()");
|
|
1521
1685
|
});
|
|
@@ -1635,7 +1799,7 @@ describe("End-to-End Integration", () => {
|
|
|
1635
1799
|
requestHeaders: Record<string, string | readonly string[] | undefined>,
|
|
1636
1800
|
): Record<string, string> {
|
|
1637
1801
|
const headers: Record<string, string> = {};
|
|
1638
|
-
for (const key
|
|
1802
|
+
for (const key of Object.keys(requestHeaders)) {
|
|
1639
1803
|
const headerValue = normalizeHeaderValue(requestHeaders[key]);
|
|
1640
1804
|
if (headerValue !== undefined) {
|
|
1641
1805
|
headers[key] = headerValue;
|
|
@@ -1652,7 +1816,6 @@ describe("End-to-End Integration", () => {
|
|
|
1652
1816
|
it("prefers contextual union surfaces for local safe dictionary reads", () => {
|
|
1653
1817
|
const csharp = compileToCSharp(`
|
|
1654
1818
|
import { asinterface } from "@tsonic/core/lang.js";
|
|
1655
|
-
import type { JsValue } from "@tsonic/core/types.js";
|
|
1656
1819
|
|
|
1657
1820
|
interface RequestWithHeadersLookup {
|
|
1658
1821
|
headers: Record<string, string | readonly string[] | undefined>;
|
|
@@ -1670,10 +1833,10 @@ describe("End-to-End Integration", () => {
|
|
|
1670
1833
|
return value.join(", ");
|
|
1671
1834
|
}
|
|
1672
1835
|
|
|
1673
|
-
export function run(request:
|
|
1836
|
+
export function run(request: unknown): Record<string, string> {
|
|
1674
1837
|
const headers: Record<string, string> = {};
|
|
1675
1838
|
const requestHeaders = asinterface<RequestWithHeadersLookup>(request).headers;
|
|
1676
|
-
for (const key
|
|
1839
|
+
for (const key of Object.keys(requestHeaders)) {
|
|
1677
1840
|
const headerValue = normalizeHeaderValue(requestHeaders[key]);
|
|
1678
1841
|
if (headerValue !== undefined) {
|
|
1679
1842
|
headers[key] = headerValue;
|
|
@@ -1714,7 +1877,7 @@ describe("End-to-End Integration", () => {
|
|
|
1714
1877
|
"export function run(request: IncomingMessage): Record<string, string> {",
|
|
1715
1878
|
" const headers: Record<string, string> = {};",
|
|
1716
1879
|
" const requestHeaders = asinterface<RequestWithHeadersLookup>(request).headers;",
|
|
1717
|
-
" for (const key
|
|
1880
|
+
" for (const key of Object.keys(requestHeaders)) {",
|
|
1718
1881
|
" const headerValue = normalizeHeaderValue(requestHeaders[key]);",
|
|
1719
1882
|
" if (headerValue !== undefined) {",
|
|
1720
1883
|
" headers[key] = headerValue;",
|
|
@@ -1860,19 +2023,19 @@ describe("End-to-End Integration", () => {
|
|
|
1860
2023
|
expect(csharp).not.to.include("(object)span");
|
|
1861
2024
|
expect(csharp).not.to.include("(object)destSpan");
|
|
1862
2025
|
});
|
|
1863
|
-
it("keeps
|
|
2026
|
+
it("keeps unknown spread-array conditionals on object arrays instead of numeric unions", () => {
|
|
1864
2027
|
const csharp = compileToCSharp(`
|
|
1865
|
-
declare function inspect(value:
|
|
2028
|
+
declare function inspect(value: unknown): string;
|
|
1866
2029
|
|
|
1867
2030
|
export function format(
|
|
1868
|
-
message?:
|
|
1869
|
-
optionalParams: readonly
|
|
2031
|
+
message?: unknown,
|
|
2032
|
+
optionalParams: readonly unknown[] = []
|
|
1870
2033
|
): string {
|
|
1871
2034
|
const values =
|
|
1872
2035
|
message === undefined ? [...optionalParams] : [message, ...optionalParams];
|
|
1873
2036
|
return values.map((value) => inspect(value)).join(" ");
|
|
1874
2037
|
}
|
|
1875
|
-
|
|
2038
|
+
`, "/test/test.ts", { surface: "@tsonic/js" });
|
|
1876
2039
|
expect(csharp).not.to.include("Union<double[], object?[]>");
|
|
1877
2040
|
expect(csharp).not.to.include("(double)message");
|
|
1878
2041
|
expect(csharp).not.to.include('.toArray().join(" ")');
|
|
@@ -1896,7 +2059,7 @@ describe("End-to-End Integration", () => {
|
|
|
1896
2059
|
it("widens narrowed runtime-subset handlers without re-matching extracted members", () => {
|
|
1897
2060
|
const csharp = compileToCSharp(`
|
|
1898
2061
|
type RequestHandler = (request: string) => void;
|
|
1899
|
-
type ErrorRequestHandler = (error:
|
|
2062
|
+
type ErrorRequestHandler = (error: unknown, request: string) => void;
|
|
1900
2063
|
|
|
1901
2064
|
class Router {}
|
|
1902
2065
|
|
|
@@ -2023,13 +2186,13 @@ describe("End-to-End Integration", () => {
|
|
|
2023
2186
|
});
|
|
2024
2187
|
it("packs rest arrays for local function values inferred from call results", () => {
|
|
2025
2188
|
const csharp = compileToCSharp(`
|
|
2026
|
-
type DebugLogFunction = (message: string, ...args:
|
|
2189
|
+
type DebugLogFunction = (message: string, ...args: unknown[]) => void;
|
|
2027
2190
|
|
|
2028
2191
|
declare function debuglog(section: string): DebugLogFunction;
|
|
2029
2192
|
declare function deprecate(
|
|
2030
|
-
fn: (...args:
|
|
2193
|
+
fn: (...args: unknown[]) => unknown,
|
|
2031
2194
|
message: string
|
|
2032
|
-
): (...args:
|
|
2195
|
+
): (...args: unknown[]) => unknown;
|
|
2033
2196
|
|
|
2034
2197
|
export function run(): void {
|
|
2035
2198
|
const debug = debuglog("test");
|
|
@@ -2047,12 +2210,12 @@ describe("End-to-End Integration", () => {
|
|
|
2047
2210
|
it("invokes narrowed handler assertions without matching extracted delegate members", () => {
|
|
2048
2211
|
const csharp = compileToCSharp(`
|
|
2049
2212
|
type RequestHandler = (request: string) => void;
|
|
2050
|
-
type ErrorRequestHandler = (error:
|
|
2213
|
+
type ErrorRequestHandler = (error: unknown, request: string) => void;
|
|
2051
2214
|
type MiddlewareHandler = RequestHandler | ErrorRequestHandler;
|
|
2052
2215
|
|
|
2053
2216
|
export function run(
|
|
2054
2217
|
handlers: MiddlewareHandler[],
|
|
2055
|
-
currentError?:
|
|
2218
|
+
currentError?: unknown
|
|
2056
2219
|
): void {
|
|
2057
2220
|
const entry = handlers[0]!;
|
|
2058
2221
|
if (currentError === undefined) {
|
|
@@ -2079,26 +2242,26 @@ describe("End-to-End Integration", () => {
|
|
|
2079
2242
|
request: Request,
|
|
2080
2243
|
response: Response,
|
|
2081
2244
|
next: NextFunction
|
|
2082
|
-
) =>
|
|
2245
|
+
) => unknown | Promise<unknown>;
|
|
2083
2246
|
type ErrorRequestHandler = (
|
|
2084
|
-
error:
|
|
2247
|
+
error: unknown,
|
|
2085
2248
|
request: Request,
|
|
2086
2249
|
response: Response,
|
|
2087
2250
|
next: NextFunction
|
|
2088
|
-
) =>
|
|
2251
|
+
) => unknown | Promise<unknown>;
|
|
2089
2252
|
type MiddlewareHandler = RequestHandler | ErrorRequestHandler;
|
|
2090
2253
|
|
|
2091
|
-
declare function isMiddlewareHandler(value:
|
|
2254
|
+
declare function isMiddlewareHandler(value: unknown): value is MiddlewareHandler;
|
|
2092
2255
|
declare function isErrorHandler(
|
|
2093
2256
|
value: MiddlewareHandler,
|
|
2094
2257
|
treatAsError: boolean
|
|
2095
2258
|
): value is ErrorRequestHandler;
|
|
2096
2259
|
|
|
2097
2260
|
export async function run(
|
|
2098
|
-
handlers:
|
|
2261
|
+
handlers: unknown[],
|
|
2099
2262
|
request: Request,
|
|
2100
2263
|
response: Response,
|
|
2101
|
-
currentError:
|
|
2264
|
+
currentError: unknown
|
|
2102
2265
|
): Promise<void> {
|
|
2103
2266
|
let error = currentError;
|
|
2104
2267
|
const next = async (_value?: NextControl): Promise<void> => {};
|
|
@@ -2123,27 +2286,27 @@ describe("End-to-End Integration", () => {
|
|
|
2123
2286
|
}
|
|
2124
2287
|
`);
|
|
2125
2288
|
expect(csharp).to.include("isErrorHandler(");
|
|
2126
|
-
expect(csharp).to.include("MiddlewareHandler From1(global::System.Func<
|
|
2127
|
-
expect(csharp).to.include("MiddlewareHandler From2(global::System.Func<Request__Alias, Response__Alias");
|
|
2128
|
-
expect(csharp).to.match(/\.
|
|
2129
|
-
expect(csharp).to.match(/\.
|
|
2289
|
+
expect(csharp).to.include("MiddlewareHandler From1(global::System.Func<Request__Alias, Response__Alias");
|
|
2290
|
+
expect(csharp).to.include("MiddlewareHandler From2(global::System.Func<object?, Request__Alias, Response__Alias");
|
|
2291
|
+
expect(csharp).to.match(/\.As1\(\)\)\(request, response, next\)\.Match(?:<[^\n]+>)?\(/);
|
|
2292
|
+
expect(csharp).to.match(/\.As2\(\)\)\(error, request, response, next\)\.Match(?:<[^\n]+>)?\(/);
|
|
2130
2293
|
expect(csharp).not.to.include("handler.Is2()");
|
|
2131
2294
|
});
|
|
2132
|
-
it("passes callable and nominal source-union members directly into broad
|
|
2295
|
+
it("passes callable and nominal source-union members directly into broad unknown guard predicates", () => {
|
|
2133
2296
|
const csharp = compileToCSharp(`
|
|
2134
2297
|
class Router {}
|
|
2135
2298
|
|
|
2136
2299
|
type PathSpec = string | RegExp | readonly PathSpec[];
|
|
2137
2300
|
type RequestHandler = (request: string) => void;
|
|
2138
2301
|
|
|
2139
|
-
declare function isPathSpec(value:
|
|
2302
|
+
declare function isPathSpec(value: unknown): value is PathSpec;
|
|
2140
2303
|
|
|
2141
2304
|
export function run(first: PathSpec | RequestHandler | Router): boolean {
|
|
2142
2305
|
return isPathSpec(first);
|
|
2143
2306
|
}
|
|
2144
2307
|
`);
|
|
2145
|
-
expect(csharp).to.include("first.Match<object
|
|
2146
|
-
expect(csharp.split(".Match<object
|
|
2308
|
+
expect(csharp).to.include("first.Match<object>(");
|
|
2309
|
+
expect(csharp.split(".Match<object>(").length - 1).to.equal(2);
|
|
2147
2310
|
expect(csharp).not.to.include("new global::System.InvalidCastException");
|
|
2148
2311
|
});
|
|
2149
2312
|
it("narrows predicate-guarded source unions before exact branch-local call arguments", () => {
|
|
@@ -2154,7 +2317,7 @@ describe("End-to-End Integration", () => {
|
|
|
2154
2317
|
type RequestHandler = (request: string) => void;
|
|
2155
2318
|
type MiddlewareLike = RequestHandler | Router;
|
|
2156
2319
|
|
|
2157
|
-
declare function isPathSpec(value:
|
|
2320
|
+
declare function isPathSpec(value: unknown): value is PathSpec;
|
|
2158
2321
|
declare function addMiddlewareLayer(path: PathSpec, handlers: readonly MiddlewareLike[]): void;
|
|
2159
2322
|
declare function useRootMiddleware(first: MiddlewareLike, rest: readonly MiddlewareLike[]): void;
|
|
2160
2323
|
|
|
@@ -2167,17 +2330,17 @@ describe("End-to-End Integration", () => {
|
|
|
2167
2330
|
useRootMiddleware(first, rest);
|
|
2168
2331
|
}
|
|
2169
2332
|
`);
|
|
2170
|
-
expect(csharp).to.include("if (isPathSpec(first.Match<object
|
|
2333
|
+
expect(csharp).to.include("if (isPathSpec(first.Match<object>(");
|
|
2171
2334
|
expect(csharp).to.include("addMiddlewareLayer((first.As1()), rest);");
|
|
2172
2335
|
expect(csharp).to.include("useRootMiddleware((first.As2()), rest);");
|
|
2173
2336
|
expect(csharp).not.to.include("addMiddlewareLayer(first, rest);");
|
|
2174
2337
|
expect(csharp).not.to.include("useRootMiddleware(first, rest);");
|
|
2175
2338
|
});
|
|
2176
|
-
it("keeps broad
|
|
2339
|
+
it("keeps broad unknown call arguments on their storage carrier after typeof narrowing", () => {
|
|
2177
2340
|
const csharp = compileToCSharp(`
|
|
2178
|
-
declare function toNumericValue(value:
|
|
2341
|
+
declare function toNumericValue(value: unknown): number;
|
|
2179
2342
|
|
|
2180
|
-
export function run(value?:
|
|
2343
|
+
export function run(value?: unknown): number {
|
|
2181
2344
|
if (value === undefined || value === null) {
|
|
2182
2345
|
return 0;
|
|
2183
2346
|
}
|
|
@@ -2192,28 +2355,42 @@ describe("End-to-End Integration", () => {
|
|
|
2192
2355
|
|
|
2193
2356
|
return toNumericValue(value);
|
|
2194
2357
|
}
|
|
2195
|
-
|
|
2358
|
+
`, "/test/test.ts", {
|
|
2359
|
+
surface: "@tsonic/js",
|
|
2360
|
+
});
|
|
2196
2361
|
expect(csharp).to.include("return toNumericValue(value);");
|
|
2197
2362
|
expect(csharp).not.to.include("toNumericValue(value.Match<object?>");
|
|
2198
2363
|
});
|
|
2199
2364
|
it("uses runtime equality for unannotated broad assertion locals", () => {
|
|
2200
2365
|
const csharp = compileToCSharp(`
|
|
2201
|
-
import type { JsValue } from "@tsonic/core/types.js";
|
|
2202
2366
|
|
|
2203
2367
|
export function run<T>(left: T, right: T): boolean {
|
|
2204
|
-
const leftValue = left as
|
|
2205
|
-
const rightValue = right as
|
|
2368
|
+
const leftValue = left as unknown | undefined;
|
|
2369
|
+
const rightValue = right as unknown | undefined;
|
|
2206
2370
|
return leftValue === rightValue;
|
|
2207
2371
|
}
|
|
2208
2372
|
`, "/test/test.ts", { surface: "@tsonic/js" });
|
|
2209
2373
|
expect(csharp).to.include("return global::System.Object.Equals(leftValue, rightValue);");
|
|
2210
2374
|
expect(csharp).not.to.include("return leftValue == rightValue;");
|
|
2211
2375
|
});
|
|
2212
|
-
it("
|
|
2376
|
+
it("rejects concrete array assertions after broad Array.isArray guards", () => {
|
|
2377
|
+
expect(() => compileToCSharp(`
|
|
2378
|
+
|
|
2379
|
+
export function run(value: unknown): string[] | undefined {
|
|
2380
|
+
if (Array.isArray(value)) {
|
|
2381
|
+
const list = value as string[];
|
|
2382
|
+
list.push("x");
|
|
2383
|
+
return list;
|
|
2384
|
+
}
|
|
2385
|
+
|
|
2386
|
+
return undefined;
|
|
2387
|
+
}
|
|
2388
|
+
`, "/test/test.ts", { surface: "@tsonic/js" })).to.throw(/Array\.isArray cannot narrow a broad runtime value/);
|
|
2389
|
+
});
|
|
2390
|
+
it("casts concrete union Array.isArray-narrowed storage directly for concrete array assertions", () => {
|
|
2213
2391
|
const csharp = compileToCSharp(`
|
|
2214
|
-
import type { JsValue } from "@tsonic/core/types.js";
|
|
2215
2392
|
|
|
2216
|
-
export function run(value:
|
|
2393
|
+
export function run(value: string | string[]): string[] | undefined {
|
|
2217
2394
|
if (Array.isArray(value)) {
|
|
2218
2395
|
const list = value as string[];
|
|
2219
2396
|
list.push("x");
|
|
@@ -2223,7 +2400,7 @@ describe("End-to-End Integration", () => {
|
|
|
2223
2400
|
return undefined;
|
|
2224
2401
|
}
|
|
2225
2402
|
`, "/test/test.ts", { surface: "@tsonic/js" });
|
|
2226
|
-
expect(csharp).to.include("string[] list = (
|
|
2403
|
+
expect(csharp).to.include("string[] list = (value.As1());");
|
|
2227
2404
|
expect(csharp).not.to.include("(global::js.Array)value");
|
|
2228
2405
|
expect(csharp).not.to.match(/global::System\.Linq\.Enumerable\.Select<object\?, string>\(\(global::js\.Array\)value/);
|
|
2229
2406
|
});
|
|
@@ -2261,7 +2438,9 @@ describe("End-to-End Integration", () => {
|
|
|
2261
2438
|
|
|
2262
2439
|
return false;
|
|
2263
2440
|
}
|
|
2264
|
-
|
|
2441
|
+
`, "/test/test.ts", {
|
|
2442
|
+
surface: "@tsonic/js",
|
|
2443
|
+
});
|
|
2265
2444
|
expect(csharp).to.include("pathSpec.Is1()");
|
|
2266
2445
|
expect(csharp).not.to.include("(pathSpec.As1()).Is1()");
|
|
2267
2446
|
expect(csharp).not.to.include("((pathSpec.As1()).As1())[index]");
|
|
@@ -2286,20 +2465,20 @@ describe("End-to-End Integration", () => {
|
|
|
2286
2465
|
expect(csharp).not.to.include("pathOrName.Is3()");
|
|
2287
2466
|
expect(csharp).to.include("pathOrName.As1()");
|
|
2288
2467
|
});
|
|
2289
|
-
it("
|
|
2468
|
+
it("materializes js Date constructor union arguments while preserving nullish selection", () => {
|
|
2290
2469
|
const csharp = compileToCSharp(`
|
|
2291
2470
|
class Holder {
|
|
2292
|
-
|
|
2471
|
+
date: Date | undefined;
|
|
2293
2472
|
|
|
2294
|
-
|
|
2473
|
+
constructor(date?: Date) {
|
|
2295
2474
|
this.date = date;
|
|
2296
2475
|
}
|
|
2297
2476
|
}
|
|
2298
2477
|
|
|
2299
2478
|
class Box {
|
|
2300
|
-
|
|
2479
|
+
value: Date;
|
|
2301
2480
|
|
|
2302
|
-
|
|
2481
|
+
constructor(value: Date) {
|
|
2303
2482
|
this.value = value;
|
|
2304
2483
|
}
|
|
2305
2484
|
}
|
|
@@ -2310,10 +2489,9 @@ describe("End-to-End Integration", () => {
|
|
|
2310
2489
|
return new Box(selected);
|
|
2311
2490
|
}
|
|
2312
2491
|
`, "/test/src/index.ts", { surface: "@tsonic/js" });
|
|
2313
|
-
expect(csharp).to.include("var fallback = new global::js.Date((
|
|
2492
|
+
expect(csharp).to.include("var fallback = new global::js.Date(global::Tsonic.Internal.Union<double, string>.From1(0));");
|
|
2314
2493
|
expect(csharp).to.include("var selected = holder.date ?? fallback;");
|
|
2315
2494
|
expect(csharp).to.include("return new Box(selected);");
|
|
2316
|
-
expect(csharp).not.to.include("Union2_");
|
|
2317
2495
|
expect(csharp).not.to.include(".From1(selected)");
|
|
2318
2496
|
});
|
|
2319
2497
|
it("returns narrowed string members from overload implementations with broad return types", () => {
|
|
@@ -2332,13 +2510,13 @@ describe("End-to-End Integration", () => {
|
|
|
2332
2510
|
type PathSpec = string | FileInfo | readonly PathSpec[];
|
|
2333
2511
|
|
|
2334
2512
|
class Application extends Router {
|
|
2335
|
-
get(name: string):
|
|
2513
|
+
get(name: string): unknown;
|
|
2336
2514
|
override get(path: PathSpec, ...handlers: RouteHandler[]): this;
|
|
2337
2515
|
override get(_nameOrPath: any, ..._handlers: any[]): any {
|
|
2338
2516
|
throw new Error("stub");
|
|
2339
2517
|
}
|
|
2340
2518
|
|
|
2341
|
-
get_name(name: string):
|
|
2519
|
+
get_name(name: string): unknown {
|
|
2342
2520
|
return name;
|
|
2343
2521
|
}
|
|
2344
2522
|
|
|
@@ -2350,7 +2528,7 @@ describe("End-to-End Integration", () => {
|
|
|
2350
2528
|
O<Application>().method(x => x.get_name).family(x => x.get);
|
|
2351
2529
|
O<Application>().method(x => x.get_path).family(x => x.get);
|
|
2352
2530
|
`);
|
|
2353
|
-
expect(csharp).to.include("public object? get(string name)");
|
|
2531
|
+
expect(csharp).to.include("public new object? get(string name)");
|
|
2354
2532
|
expect(csharp).to.include("return name;");
|
|
2355
2533
|
expect(csharp).to.not.include("name.Is");
|
|
2356
2534
|
expect(csharp).not.to.include("get_name");
|
|
@@ -2410,7 +2588,7 @@ describe("End-to-End Integration", () => {
|
|
|
2410
2588
|
| TypedArrayInput<TElement>;
|
|
2411
2589
|
|
|
2412
2590
|
export class Uint16Array {
|
|
2413
|
-
|
|
2591
|
+
constructor(lengthOrValues: TypedArrayConstructorInput<number>) {
|
|
2414
2592
|
void lengthOrValues;
|
|
2415
2593
|
}
|
|
2416
2594
|
}
|
|
@@ -2446,7 +2624,7 @@ describe("End-to-End Integration", () => {
|
|
|
2446
2624
|
| TypedArrayInput<TElement>;
|
|
2447
2625
|
|
|
2448
2626
|
export class Uint8Array {
|
|
2449
|
-
|
|
2627
|
+
constructor(lengthOrValues: TypedArrayConstructorInput<number>) {
|
|
2450
2628
|
void lengthOrValues;
|
|
2451
2629
|
}
|
|
2452
2630
|
}
|
|
@@ -2456,7 +2634,7 @@ describe("End-to-End Integration", () => {
|
|
|
2456
2634
|
import { Uint8Array } from "./typed-array-core.js";
|
|
2457
2635
|
|
|
2458
2636
|
class Parameters {
|
|
2459
|
-
|
|
2637
|
+
Modulus: byte[] | null = null;
|
|
2460
2638
|
}
|
|
2461
2639
|
|
|
2462
2640
|
export function run(parameters: Parameters): Uint8Array {
|
|
@@ -2484,7 +2662,7 @@ describe("End-to-End Integration", () => {
|
|
|
2484
2662
|
import { Uint8Array } from "@tsonic/js/index.js";
|
|
2485
2663
|
|
|
2486
2664
|
class Parameters {
|
|
2487
|
-
|
|
2665
|
+
Modulus: byte[] | null = null;
|
|
2488
2666
|
}
|
|
2489
2667
|
|
|
2490
2668
|
export function run(parameters: Parameters): Uint8Array {
|
|
@@ -2516,13 +2694,13 @@ describe("End-to-End Integration", () => {
|
|
|
2516
2694
|
| TypedArrayInput<TElement>;
|
|
2517
2695
|
|
|
2518
2696
|
export class TypedArrayBase<TElement extends number> {
|
|
2519
|
-
|
|
2697
|
+
constructor(lengthOrValues: int | TypedArrayInput<TElement>) {
|
|
2520
2698
|
void lengthOrValues;
|
|
2521
2699
|
}
|
|
2522
2700
|
}
|
|
2523
2701
|
|
|
2524
2702
|
export class Uint8Array extends TypedArrayBase<number> {
|
|
2525
|
-
|
|
2703
|
+
constructor(lengthOrValues: TypedArrayConstructorInput<number>) {
|
|
2526
2704
|
super(lengthOrValues);
|
|
2527
2705
|
}
|
|
2528
2706
|
}
|
|
@@ -2560,8 +2738,10 @@ describe("End-to-End Integration", () => {
|
|
|
2560
2738
|
});
|
|
2561
2739
|
it("preserves narrowed runtime-union members when coercing Uint8Array byte elements", () => {
|
|
2562
2740
|
const csharp = compileToCSharp(`
|
|
2741
|
+
import type { byte } from "@tsonic/core/types.js";
|
|
2742
|
+
|
|
2563
2743
|
export function create(
|
|
2564
|
-
generatorOrEncoding:
|
|
2744
|
+
generatorOrEncoding: byte | Uint8Array | string
|
|
2565
2745
|
): Uint8Array {
|
|
2566
2746
|
if (typeof generatorOrEncoding === "number") {
|
|
2567
2747
|
return new Uint8Array([generatorOrEncoding]);
|
|
@@ -2572,7 +2752,7 @@ describe("End-to-End Integration", () => {
|
|
|
2572
2752
|
`, "/test/test.ts", {
|
|
2573
2753
|
surface: "@tsonic/js",
|
|
2574
2754
|
});
|
|
2575
|
-
expect(csharp).to.include("new global::js.Uint8Array(global::js.TypedArrayConstructorInput<byte>.From2(global::js.TypedArrayInput<byte>.From1(new byte[] { (
|
|
2755
|
+
expect(csharp).to.include("new global::js.Uint8Array(global::js.TypedArrayConstructorInput<byte>.From2(global::js.TypedArrayInput<byte>.From1(new byte[] { (generatorOrEncoding.As3()) })))");
|
|
2576
2756
|
expect(csharp).not.to.include("new global::js.Uint8Array(new byte[] { (byte)generatorOrEncoding })");
|
|
2577
2757
|
});
|
|
2578
2758
|
it("rewraps plain string call arguments through runtime-union surfaces", () => {
|
|
@@ -2640,7 +2820,7 @@ describe("End-to-End Integration", () => {
|
|
|
2640
2820
|
export class Uint8Array {}
|
|
2641
2821
|
`,
|
|
2642
2822
|
}, "src/index.ts", { surface: "@tsonic/js" }));
|
|
2643
|
-
expect(csharp).to.include("return Buffer.fromNonString(
|
|
2823
|
+
expect(csharp).to.include("return Buffer.fromNonString(value.Match<global::Tsonic.Internal.Union<double[], global::fixturejs.Uint8Array, global::Test.Buffer>>(");
|
|
2644
2824
|
expect(csharp).not.to.include("return Buffer.fromNonString(value);");
|
|
2645
2825
|
expect(csharp).not.to.include("return Buffer.fromNonString(global::Tsonic.Internal.Union<double[], global::Test.Buffer, global::fixturejs.Uint8Array, string>");
|
|
2646
2826
|
});
|
|
@@ -2651,7 +2831,7 @@ describe("End-to-End Integration", () => {
|
|
|
2651
2831
|
declare function takesBytes(values: byte[]): void;
|
|
2652
2832
|
|
|
2653
2833
|
export function create(
|
|
2654
|
-
generatorOrEncoding:
|
|
2834
|
+
generatorOrEncoding: byte | Uint8Array | string
|
|
2655
2835
|
): void {
|
|
2656
2836
|
if (typeof generatorOrEncoding === "number") {
|
|
2657
2837
|
takesBytes([generatorOrEncoding]);
|
|
@@ -2660,7 +2840,7 @@ describe("End-to-End Integration", () => {
|
|
|
2660
2840
|
`, "/test/test.ts", {
|
|
2661
2841
|
surface: "@tsonic/js",
|
|
2662
2842
|
});
|
|
2663
|
-
expect(csharp).to.include("takesBytes(new byte[] { (
|
|
2843
|
+
expect(csharp).to.include("takesBytes(new byte[] { (generatorOrEncoding.As3()) })");
|
|
2664
2844
|
expect(csharp).not.to.include("takesBytes(new byte[] { (byte)generatorOrEncoding })");
|
|
2665
2845
|
});
|
|
2666
2846
|
it("preserves explicit numeric assertion targets in arithmetic operands", () => {
|
|
@@ -2711,7 +2891,7 @@ describe("End-to-End Integration", () => {
|
|
|
2711
2891
|
it("emits shadowed instanceof receivers from actual local storage", () => {
|
|
2712
2892
|
const csharp = compileToCSharp(`
|
|
2713
2893
|
class BoolValue {
|
|
2714
|
-
|
|
2894
|
+
value: boolean;
|
|
2715
2895
|
|
|
2716
2896
|
constructor(value: boolean) {
|
|
2717
2897
|
this.value = value;
|
|
@@ -2732,15 +2912,17 @@ describe("End-to-End Integration", () => {
|
|
|
2732
2912
|
expect(csharp).to.match(/if \(shadow__1 is BoolValue shadow__is_\d+\)/);
|
|
2733
2913
|
expect(csharp).not.to.include("(int)(object)shadow__1 is BoolValue");
|
|
2734
2914
|
});
|
|
2735
|
-
it("
|
|
2915
|
+
it("keeps exact-int Uint8Array length constructors on the numeric arm", () => {
|
|
2736
2916
|
const csharp = compileToCSharp(`
|
|
2737
|
-
|
|
2917
|
+
import type { int } from "@tsonic/core/types.js";
|
|
2918
|
+
|
|
2919
|
+
export function run(start: int, end: int): Uint8Array {
|
|
2738
2920
|
return new Uint8Array(end - start);
|
|
2739
2921
|
}
|
|
2740
2922
|
`, "/test/test.ts", {
|
|
2741
2923
|
surface: "@tsonic/js",
|
|
2742
2924
|
});
|
|
2743
|
-
expect(csharp).to.include("new global::js.Uint8Array(global::js.TypedArrayConstructorInput<byte>.From1(
|
|
2925
|
+
expect(csharp).to.include("new global::js.Uint8Array(global::js.TypedArrayConstructorInput<byte>.From1(end - start))");
|
|
2744
2926
|
expect(csharp).not.to.include("new global::js.Uint8Array((int)global::js.TypedArrayConstructorInput");
|
|
2745
2927
|
});
|
|
2746
2928
|
it("does not recast materialized typed-array constructor length unions", () => {
|
|
@@ -2770,14 +2952,15 @@ describe("End-to-End Integration", () => {
|
|
|
2770
2952
|
});
|
|
2771
2953
|
it("keeps conditional Uint8Array length constructors on the numeric arm", () => {
|
|
2772
2954
|
const csharp = compileToCSharp(`
|
|
2773
|
-
|
|
2955
|
+
import type { int } from "@tsonic/core/types.js";
|
|
2956
|
+
|
|
2957
|
+
export function run(totalLength: int): Uint8Array {
|
|
2774
2958
|
return new Uint8Array(totalLength === 0 ? 1 : totalLength);
|
|
2775
2959
|
}
|
|
2776
2960
|
`, "/test/test.ts", {
|
|
2777
2961
|
surface: "@tsonic/js",
|
|
2778
2962
|
});
|
|
2779
|
-
expect(csharp).to.include("return new global::js.Uint8Array(global::js.TypedArrayConstructorInput<byte>.From1(
|
|
2780
|
-
expect(csharp).to.include("totalLength == 0 ? 1 :");
|
|
2963
|
+
expect(csharp).to.include("return new global::js.Uint8Array(global::js.TypedArrayConstructorInput<byte>.From1(totalLength == 0 ? 1 : totalLength));");
|
|
2781
2964
|
expect(csharp).not.to.include("return new global::js.Uint8Array(totalLength == 0 ? global::js.TypedArrayConstructorInput<byte>.From2(");
|
|
2782
2965
|
});
|
|
2783
2966
|
it("keeps narrowed Uint8Array length access as a direct member read", () => {
|
|
@@ -2838,7 +3021,9 @@ describe("End-to-End Integration", () => {
|
|
|
2838
3021
|
}
|
|
2839
3022
|
}
|
|
2840
3023
|
`,
|
|
2841
|
-
}, "src/index.ts"
|
|
3024
|
+
}, "src/index.ts", {
|
|
3025
|
+
surface: "@tsonic/js",
|
|
3026
|
+
});
|
|
2842
3027
|
expect(csharp).to.include("if (nextCount > rule.maxCount.Value)");
|
|
2843
3028
|
expect(csharp).to.include("String(rule.maxCount.Value)");
|
|
2844
3029
|
expect(csharp).not.to.include("rule.maxCount.Value.Value");
|
|
@@ -2856,9 +3041,12 @@ describe("End-to-End Integration", () => {
|
|
|
2856
3041
|
}, "src/index.ts", {
|
|
2857
3042
|
surface: "@tsonic/js",
|
|
2858
3043
|
});
|
|
2859
|
-
expect(csharp).to.include("if (chunk.
|
|
2860
|
-
expect(csharp).to.include("chunk__is_1.
|
|
2861
|
-
expect(csharp).to.include("
|
|
3044
|
+
expect(csharp).to.include("if (chunk.Is4())");
|
|
3045
|
+
expect(csharp).to.include("return ServerResponse._copyUint8Array(chunk__is_1.buffer);");
|
|
3046
|
+
expect(csharp).to.include("return ServerResponse._copyUint8Array(chunk__is_2);");
|
|
3047
|
+
expect(csharp).to.include("if (chunk.Is2())");
|
|
3048
|
+
expect(csharp).to.include("for (int index = 0; index < source.length;");
|
|
3049
|
+
expect(csharp).to.include("source.at(index)");
|
|
2862
3050
|
expect(csharp).not.to.include("new global::js.Array<object>(chunk__is_1).length");
|
|
2863
3051
|
});
|
|
2864
3052
|
it("lowers non-byte typed-array array-literal constructors through concrete CLR arrays", () => {
|
|
@@ -2877,16 +3065,15 @@ describe("End-to-End Integration", () => {
|
|
|
2877
3065
|
expect(csharp).not.to.include("new Int16Array(global::Tsonic.Internal.Union<double[], global::System.Collections.Generic.IEnumerable<double>>");
|
|
2878
3066
|
expect(csharp).not.to.include("new Float32Array(global::Tsonic.Internal.Union<double[], global::System.Collections.Generic.IEnumerable<double>>");
|
|
2879
3067
|
});
|
|
2880
|
-
it("
|
|
2881
|
-
|
|
3068
|
+
it("rejects broad numeric lengths for non-byte typed-array constructors", () => {
|
|
3069
|
+
expect(() => compileToCSharp(`
|
|
2882
3070
|
export function run(start: number, end: number): void {
|
|
2883
3071
|
const view = new Int16Array(end - start);
|
|
2884
3072
|
void view;
|
|
2885
3073
|
}
|
|
2886
3074
|
`, "/test/test.ts", {
|
|
2887
3075
|
surface: "@tsonic/js",
|
|
2888
|
-
});
|
|
2889
|
-
expect(csharp).to.include("new global::js.Int16Array(global::js.TypedArrayConstructorInput<short>.From1((int)(end - start)))");
|
|
3076
|
+
})).to.throw("Implicit narrowing not allowed");
|
|
2890
3077
|
});
|
|
2891
3078
|
it("casts Uint8Array element assignments to byte", () => {
|
|
2892
3079
|
const csharp = compileToCSharp(`
|
|
@@ -2902,12 +3089,12 @@ describe("End-to-End Integration", () => {
|
|
|
2902
3089
|
expect(csharp).to.include("data.set(i, 255);");
|
|
2903
3090
|
expect(csharp).not.to.include("data[i] = 255;");
|
|
2904
3091
|
});
|
|
2905
|
-
it("
|
|
2906
|
-
|
|
3092
|
+
it("rejects JS numeric expressions when assigning into int slots", () => {
|
|
3093
|
+
expect(() => compileToCSharp(`
|
|
2907
3094
|
import type { int } from "@tsonic/core/types.js";
|
|
2908
3095
|
|
|
2909
3096
|
class CursorPosition {
|
|
2910
|
-
|
|
3097
|
+
rows: int = 0;
|
|
2911
3098
|
}
|
|
2912
3099
|
|
|
2913
3100
|
export function run(totalLength: number): CursorPosition {
|
|
@@ -2917,19 +3104,36 @@ describe("End-to-End Integration", () => {
|
|
|
2917
3104
|
}
|
|
2918
3105
|
`, "/test/test.ts", {
|
|
2919
3106
|
surface: "@tsonic/js",
|
|
2920
|
-
});
|
|
2921
|
-
expect(csharp).to.include("pos.rows = (int)global::js.Math.floor(totalLength / 80);");
|
|
3107
|
+
})).to.throw("Implicit narrowing not allowed");
|
|
2922
3108
|
});
|
|
2923
|
-
it("
|
|
3109
|
+
it("emits explicit numeric narrowings when assigning into int slots", () => {
|
|
2924
3110
|
const csharp = compileToCSharp(`
|
|
2925
3111
|
import type { int } from "@tsonic/core/types.js";
|
|
2926
3112
|
|
|
3113
|
+
class CursorPosition {
|
|
3114
|
+
rows: int = 0;
|
|
3115
|
+
}
|
|
3116
|
+
|
|
3117
|
+
export function run(totalLength: int): CursorPosition {
|
|
3118
|
+
const pos = new CursorPosition();
|
|
3119
|
+
pos.rows = (totalLength + 1) as int;
|
|
3120
|
+
return pos;
|
|
3121
|
+
}
|
|
3122
|
+
`, "/test/test.ts", {
|
|
3123
|
+
surface: "@tsonic/js",
|
|
3124
|
+
});
|
|
3125
|
+
expect(csharp).to.include("pos.rows = (int)(totalLength + 1);");
|
|
3126
|
+
});
|
|
3127
|
+
it("rejects JS numeric expressions when assigning through exact int property slots", () => {
|
|
3128
|
+
expect(() => compileToCSharp(`
|
|
3129
|
+
import type { int } from "@tsonic/core/types.js";
|
|
3130
|
+
|
|
2927
3131
|
class Counter {
|
|
2928
|
-
|
|
3132
|
+
#value: int = 0;
|
|
2929
3133
|
|
|
2930
|
-
|
|
3134
|
+
set value(v: number) {
|
|
2931
3135
|
const offset = 123;
|
|
2932
|
-
this
|
|
3136
|
+
this.#value = v + offset;
|
|
2933
3137
|
}
|
|
2934
3138
|
}
|
|
2935
3139
|
|
|
@@ -2937,15 +3141,36 @@ describe("End-to-End Integration", () => {
|
|
|
2937
3141
|
const counter = new Counter();
|
|
2938
3142
|
counter.value = value;
|
|
2939
3143
|
}
|
|
3144
|
+
`, "/test/test.ts", {
|
|
3145
|
+
surface: "@tsonic/js",
|
|
3146
|
+
})).to.throw("Implicit narrowing not allowed");
|
|
3147
|
+
});
|
|
3148
|
+
it("emits explicit numeric narrowings when assigning through exact int property slots", () => {
|
|
3149
|
+
const csharp = compileToCSharp(`
|
|
3150
|
+
import type { int } from "@tsonic/core/types.js";
|
|
3151
|
+
|
|
3152
|
+
class Counter {
|
|
3153
|
+
#value: int = 0;
|
|
3154
|
+
|
|
3155
|
+
set value(v: int) {
|
|
3156
|
+
const offset: int = 123;
|
|
3157
|
+
this.#value = (v + offset) as int;
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
|
|
3161
|
+
export function run(value: int): void {
|
|
3162
|
+
const counter = new Counter();
|
|
3163
|
+
counter.value = value;
|
|
3164
|
+
}
|
|
2940
3165
|
`, "/test/test.ts", {
|
|
2941
3166
|
surface: "@tsonic/js",
|
|
2942
3167
|
});
|
|
2943
|
-
expect(csharp).to.include("this.
|
|
3168
|
+
expect(csharp).to.include("this.__private_value = (int)(v + offset);");
|
|
2944
3169
|
});
|
|
2945
3170
|
it("keeps context-narrowed numeric conditionals on the contextual branch type", () => {
|
|
2946
3171
|
const csharp = compileToCSharp(`
|
|
2947
3172
|
export function build(): number[] {
|
|
2948
|
-
const table: number[] =
|
|
3173
|
+
const table: number[] = [0];
|
|
2949
3174
|
const polynomial = 0xedb88320;
|
|
2950
3175
|
let crc = 0;
|
|
2951
3176
|
crc = (crc & 1) === 1 ? (crc >>> 1) ^ polynomial : crc >>> 1;
|
|
@@ -2986,7 +3211,7 @@ describe("End-to-End Integration", () => {
|
|
|
2986
3211
|
|
|
2987
3212
|
export function run(drafts: { type: string; to: string; topic?: string; content: string }[]): void {
|
|
2988
3213
|
const inputs = new List<{ type: string; to: string; topic?: string; content: string }>();
|
|
2989
|
-
for (let i = 0; i < drafts.
|
|
3214
|
+
for (let i = 0; i < drafts.Length; i++) {
|
|
2990
3215
|
const d = drafts[i];
|
|
2991
3216
|
inputs.Add({ type: d.type, to: d.to, topic: d.topic, content: d.content });
|
|
2992
3217
|
}
|
|
@@ -3168,6 +3393,33 @@ describe("End-to-End Integration", () => {
|
|
|
3168
3393
|
expect(csharp).not.to.include("return new TLSServer((TlsOptions__Alias)(optionsOrListener.As2()), secureConnectionListener ?? null);");
|
|
3169
3394
|
expect(csharp).not.to.include("global::Tsonic.Internal.Union<global::System.Action<TLSSocket>, TlsOptions__Alias>.From2");
|
|
3170
3395
|
});
|
|
3396
|
+
it("keeps nullable projected union members direct when assigning to matching storage", () => {
|
|
3397
|
+
const csharp = compileToCSharp(`
|
|
3398
|
+
export class Options {
|
|
3399
|
+
allowHalfOpen?: boolean;
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3402
|
+
class Socket {}
|
|
3403
|
+
|
|
3404
|
+
export class Server {
|
|
3405
|
+
_allowHalfOpen: boolean;
|
|
3406
|
+
|
|
3407
|
+
constructor(
|
|
3408
|
+
optionsOrListener?: Options | ((socket: Socket) => void) | null,
|
|
3409
|
+
) {
|
|
3410
|
+
let options: Options | null = null;
|
|
3411
|
+
if (typeof optionsOrListener !== "function") {
|
|
3412
|
+
options = optionsOrListener ?? null;
|
|
3413
|
+
}
|
|
3414
|
+
|
|
3415
|
+
this._allowHalfOpen = options?.allowHalfOpen ?? false;
|
|
3416
|
+
}
|
|
3417
|
+
}
|
|
3418
|
+
`, "/test/test.ts", { surface: "@tsonic/js" });
|
|
3419
|
+
expect(csharp).to.include("options = ((object)optionsOrListener == null ? default(Options) : (optionsOrListener.As2())) ?? null;");
|
|
3420
|
+
expect(csharp).not.to.include(").Match<Options>");
|
|
3421
|
+
expect(csharp).not.to.include("Cannot cast runtime union functionType");
|
|
3422
|
+
});
|
|
3171
3423
|
it("materializes typeof complements before later local initializers in nested nullish guards", () => {
|
|
3172
3424
|
const csharp = compileToCSharp(`
|
|
3173
3425
|
import type { byte } from "@tsonic/core/types.js";
|
|
@@ -3199,9 +3451,22 @@ describe("End-to-End Integration", () => {
|
|
|
3199
3451
|
}
|
|
3200
3452
|
`, "/test/test.ts", { surface: "@tsonic/js" });
|
|
3201
3453
|
expect(csharp).to.include("var value = chunkOrCallback.Match");
|
|
3202
|
-
expect(csharp).to.include("global::Tsonic.Internal.Union<byte[], global::js.Uint8Array,
|
|
3454
|
+
expect(csharp).to.include("global::Tsonic.Internal.Union<byte[], string, global::js.Uint8Array, global::Test.Buffer>");
|
|
3203
3455
|
expect(csharp).to.include('__tsonic_union_member_2 => throw new global::System.InvalidCastException("Cannot materialize runtime union functionType to unionType")');
|
|
3204
|
-
expect(csharp).not.to.include("var value = (global::Tsonic.Internal.Union<byte[], global::js.Uint8Array,
|
|
3456
|
+
expect(csharp).not.to.include("var value = (global::Tsonic.Internal.Union<byte[], string, global::js.Uint8Array, global::Test.Buffer>)chunkOrCallback;");
|
|
3457
|
+
});
|
|
3458
|
+
it("keeps numeric return context for conditionals with mixed numeric carriers", () => {
|
|
3459
|
+
const csharp = compileToCSharp(`
|
|
3460
|
+
import type { byte, int } from "@tsonic/core/types.js";
|
|
3461
|
+
|
|
3462
|
+
export function read(values: byte[], offset: int): number {
|
|
3463
|
+
const value = values[offset]!;
|
|
3464
|
+
return value >= 0x80 ? value - 0x100 : value;
|
|
3465
|
+
}
|
|
3466
|
+
`);
|
|
3467
|
+
expect(csharp).to.include("return value >= 0x80 ? (double)(value - 0x100) : value;");
|
|
3468
|
+
expect(csharp).not.to.include("Union<int, byte>");
|
|
3469
|
+
expect(csharp).not.to.include(".From1(value - 0x100)");
|
|
3205
3470
|
});
|
|
3206
3471
|
it("tightens sequential typeof-plus-undefined ternary locals before storage reuse", () => {
|
|
3207
3472
|
const csharp = compileToCSharp(`
|
|
@@ -3302,11 +3567,11 @@ describe("End-to-End Integration", () => {
|
|
|
3302
3567
|
it("preserves generic iterable assertion surfaces after predicate narrowing", () => {
|
|
3303
3568
|
const csharp = compileToCSharp(`
|
|
3304
3569
|
declare function isIterableObject(
|
|
3305
|
-
value:
|
|
3306
|
-
): value is Iterable<
|
|
3570
|
+
value: unknown
|
|
3571
|
+
): value is Iterable<unknown>;
|
|
3307
3572
|
declare function consume<T>(value: T): void;
|
|
3308
3573
|
|
|
3309
|
-
export function run<T>(item:
|
|
3574
|
+
export function run<T>(item: unknown): void {
|
|
3310
3575
|
if (isIterableObject(item)) {
|
|
3311
3576
|
for (const value of item as Iterable<T>) {
|
|
3312
3577
|
consume(value);
|
|
@@ -3409,12 +3674,16 @@ describe("End-to-End Integration", () => {
|
|
|
3409
3674
|
});
|
|
3410
3675
|
it("materializes narrower function arrays into union-element arrays at call sites", () => {
|
|
3411
3676
|
const csharp = compileToCSharp(`
|
|
3412
|
-
type RouteHandler = (req: string) =>
|
|
3413
|
-
type ErrorHandler = (error:
|
|
3677
|
+
type RouteHandler = (req: string) => unknown;
|
|
3678
|
+
type ErrorHandler = (error: unknown, req: string) => unknown;
|
|
3414
3679
|
type Handler = RouteHandler | ErrorHandler;
|
|
3415
3680
|
|
|
3416
3681
|
class RouteBox {
|
|
3417
|
-
|
|
3682
|
+
handlers: Handler[];
|
|
3683
|
+
|
|
3684
|
+
constructor(handlers: Handler[]) {
|
|
3685
|
+
this.handlers = handlers;
|
|
3686
|
+
}
|
|
3418
3687
|
}
|
|
3419
3688
|
|
|
3420
3689
|
function flatten(handlers: RouteHandler[]): RouteHandler[] {
|
|
@@ -3453,14 +3722,14 @@ describe("End-to-End Integration", () => {
|
|
|
3453
3722
|
});
|
|
3454
3723
|
it("treats fixed lambda parameters against rest callbacks as positional values", () => {
|
|
3455
3724
|
const csharp = compileToCSharp(`
|
|
3456
|
-
type EventListener = (...args:
|
|
3725
|
+
type EventListener = (...args: unknown[]) => void;
|
|
3457
3726
|
|
|
3458
3727
|
declare function consume(listener: EventListener): void;
|
|
3459
3728
|
|
|
3460
3729
|
export function main(): void {
|
|
3461
|
-
let first:
|
|
3462
|
-
let second:
|
|
3463
|
-
let third:
|
|
3730
|
+
let first: unknown = undefined;
|
|
3731
|
+
let second: unknown = undefined;
|
|
3732
|
+
let third: unknown = undefined;
|
|
3464
3733
|
|
|
3465
3734
|
consume((arg1, arg2, arg3) => {
|
|
3466
3735
|
first = arg1;
|
|
@@ -3473,6 +3742,27 @@ describe("End-to-End Integration", () => {
|
|
|
3473
3742
|
expect(csharp).to.include("first = arg1;");
|
|
3474
3743
|
expect(csharp).to.not.include("first = (object?[])arg1;");
|
|
3475
3744
|
});
|
|
3745
|
+
it("preserves explicit semantic types for fixed parameters lowered from rest callbacks", () => {
|
|
3746
|
+
const csharp = compileToCSharp(`
|
|
3747
|
+
type RuntimeValue = string | number | boolean | object | null | undefined;
|
|
3748
|
+
type EventListener = (...args: RuntimeValue[]) => void;
|
|
3749
|
+
|
|
3750
|
+
declare function consume(listener: EventListener): void;
|
|
3751
|
+
|
|
3752
|
+
export function main(): void {
|
|
3753
|
+
let received: number = 0;
|
|
3754
|
+
consume((value: RuntimeValue) => {
|
|
3755
|
+
if (typeof value === "number") {
|
|
3756
|
+
received = value;
|
|
3757
|
+
}
|
|
3758
|
+
});
|
|
3759
|
+
}
|
|
3760
|
+
`);
|
|
3761
|
+
expect(csharp).to.include("object? value = __unused_args[0];");
|
|
3762
|
+
expect(csharp).to.include("if ((value is double || value is int))");
|
|
3763
|
+
expect(csharp).to.include("received = (double)(value switch { int ");
|
|
3764
|
+
expect(csharp).to.not.include("if (false)");
|
|
3765
|
+
});
|
|
3476
3766
|
it("preserves nullable array arguments when forwarding identical signatures", () => {
|
|
3477
3767
|
const csharp = compileToCSharp(`
|
|
3478
3768
|
class Child {}
|
|
@@ -3495,18 +3785,18 @@ describe("End-to-End Integration", () => {
|
|
|
3495
3785
|
it("preserves readable array surfaces after setter writes before length reads", () => {
|
|
3496
3786
|
const csharp = compileToCSharp(`
|
|
3497
3787
|
declare class Assert {
|
|
3498
|
-
static Equal(expected:
|
|
3788
|
+
static Equal(expected: unknown, actual: unknown): void;
|
|
3499
3789
|
}
|
|
3500
3790
|
|
|
3501
3791
|
class Proc {
|
|
3502
|
-
|
|
3792
|
+
#argv: string[] = [];
|
|
3503
3793
|
|
|
3504
3794
|
get argv(): string[] {
|
|
3505
|
-
return this
|
|
3795
|
+
return this.#argv;
|
|
3506
3796
|
}
|
|
3507
3797
|
|
|
3508
3798
|
set argv(value: string[] | undefined) {
|
|
3509
|
-
this
|
|
3799
|
+
this.#argv = value ?? [];
|
|
3510
3800
|
}
|
|
3511
3801
|
}
|
|
3512
3802
|
|
|
@@ -3516,7 +3806,7 @@ describe("End-to-End Integration", () => {
|
|
|
3516
3806
|
}
|
|
3517
3807
|
`, "/test/test.ts", { surface: "@tsonic/js" });
|
|
3518
3808
|
expect(csharp).to.include("p.argv = default(string[]);");
|
|
3519
|
-
expect(csharp).to.include("Assert.Equal((object)(double)0,
|
|
3809
|
+
expect(csharp).to.include("Assert.Equal((object)(double)0, p.argv.Length);");
|
|
3520
3810
|
expect(csharp).to.not.include("new global::js.Array<object>((object)p.argv).length");
|
|
3521
3811
|
});
|
|
3522
3812
|
it("erases compiler-generated structural assertion casts for nominal receivers", () => {
|
|
@@ -3551,28 +3841,26 @@ describe("End-to-End Integration", () => {
|
|
|
3551
3841
|
expect(csharp).to.include('server.listen("/tmp/socket"');
|
|
3552
3842
|
expect(csharp).to.include('request.on("data"');
|
|
3553
3843
|
});
|
|
3554
|
-
it("prefers inferred conditional array surfaces over broad
|
|
3844
|
+
it("prefers inferred conditional array surfaces over broad unknown sinks", () => {
|
|
3555
3845
|
const csharp = compileToCSharp(`
|
|
3556
|
-
import type { JsValue } from "@tsonic/core/types.js";
|
|
3557
3846
|
|
|
3558
3847
|
declare function readIds(json: string): string[];
|
|
3559
3848
|
|
|
3560
|
-
export function run(json: string, useJson: boolean): Record<string,
|
|
3561
|
-
const obj: Record<string,
|
|
3849
|
+
export function run(json: string, useJson: boolean): Record<string, unknown> {
|
|
3850
|
+
const obj: Record<string, unknown> = {};
|
|
3562
3851
|
obj["channel_ids"] = useJson ? readIds(json) : [];
|
|
3563
3852
|
return obj;
|
|
3564
3853
|
}
|
|
3565
3854
|
`, "/test/test.ts", { surface: "@tsonic/js" });
|
|
3566
3855
|
expect(csharp).to.include('obj["channel_ids"] = useJson ? readIds(json) : global::System.Array.Empty<string>();');
|
|
3567
3856
|
});
|
|
3568
|
-
it("keeps nullable conditional array call surfaces direct over broad
|
|
3857
|
+
it("keeps nullable conditional array call surfaces direct over broad unknown sinks", () => {
|
|
3569
3858
|
const csharp = compileToCSharp(`
|
|
3570
|
-
import type { JsValue } from "@tsonic/core/types.js";
|
|
3571
3859
|
|
|
3572
3860
|
declare function maybeIds(json: string): string[] | undefined;
|
|
3573
3861
|
|
|
3574
|
-
export function run(json: string, useJson: boolean): Record<string,
|
|
3575
|
-
const obj: Record<string,
|
|
3862
|
+
export function run(json: string, useJson: boolean): Record<string, unknown> {
|
|
3863
|
+
const obj: Record<string, unknown> = {};
|
|
3576
3864
|
obj["channel_ids"] = useJson ? maybeIds(json) : [];
|
|
3577
3865
|
return obj;
|
|
3578
3866
|
}
|
|
@@ -3582,11 +3870,10 @@ describe("End-to-End Integration", () => {
|
|
|
3582
3870
|
});
|
|
3583
3871
|
it("keeps conditional reference-array surfaces direct when one branch is nullish", () => {
|
|
3584
3872
|
const csharp = compileToCSharp(`
|
|
3585
|
-
import type { JsValue } from "@tsonic/core/types.js";
|
|
3586
3873
|
import { JsonSerializer } from "@tsonic/dotnet/System.Text.Json.js";
|
|
3587
3874
|
|
|
3588
|
-
export function run(json: string, useJson: boolean): Record<string,
|
|
3589
|
-
const obj: Record<string,
|
|
3875
|
+
export function run(json: string, useJson: boolean): Record<string, unknown> {
|
|
3876
|
+
const obj: Record<string, unknown> = {};
|
|
3590
3877
|
obj["channel_ids"] =
|
|
3591
3878
|
useJson ? JsonSerializer.Deserialize<string[]>(json) : [];
|
|
3592
3879
|
return obj;
|
|
@@ -3922,7 +4209,7 @@ describe("End-to-End Integration", () => {
|
|
|
3922
4209
|
`,
|
|
3923
4210
|
}, "src/test.ts", { surface: "@tsonic/js" });
|
|
3924
4211
|
expect(csharp).to.include("public static Result<T, E> From1(Err__Alias<E> value)");
|
|
3925
|
-
expect(csharp).to.include("var result = await global::System.Threading.Tasks.Task.FromResult(render());");
|
|
4212
|
+
expect(csharp).to.include("var result = await global::System.Threading.Tasks.Task.FromResult(global::Test.render__Module.render());");
|
|
3926
4213
|
expect(csharp).to.include("if (!result.Match<bool>(__tsonic_union_member_1 => __tsonic_union_member_1.success, __tsonic_union_member_2 => __tsonic_union_member_2.success))");
|
|
3927
4214
|
expect(csharp).to.match(/return result__1_\d+\.error;/);
|
|
3928
4215
|
expect(csharp).not.to.include("if (result.Is2())");
|
|
@@ -4013,8 +4300,8 @@ describe("End-to-End Integration", () => {
|
|
|
4013
4300
|
return String(actualEnd + start);
|
|
4014
4301
|
}
|
|
4015
4302
|
`, "/test/test.ts", { surface: "@tsonic/js" });
|
|
4016
|
-
expect(csharp).to.include("clamp(lengthValue +
|
|
4017
|
-
expect(csharp).to.include("clamp(
|
|
4303
|
+
expect(csharp).to.include("clamp(lengthValue + end.Value, 0, lengthValue)");
|
|
4304
|
+
expect(csharp).to.include("clamp(end.Value, 0, lengthValue)");
|
|
4018
4305
|
expect(csharp).not.to.include("clamp(lengthValue + end, 0, lengthValue)");
|
|
4019
4306
|
});
|
|
4020
4307
|
it("wraps nested runtime-union carriers without projecting members", () => {
|
|
@@ -4118,7 +4405,7 @@ describe("End-to-End Integration", () => {
|
|
|
4118
4405
|
});
|
|
4119
4406
|
it("materializes union array arms to broad object arrays without throwing", () => {
|
|
4120
4407
|
const csharp = compileToCSharp(`
|
|
4121
|
-
import type { int
|
|
4408
|
+
import type { int } from "@tsonic/core/types.js";
|
|
4122
4409
|
|
|
4123
4410
|
interface RecordWithTtl {
|
|
4124
4411
|
address: string;
|
|
@@ -4126,14 +4413,29 @@ describe("End-to-End Integration", () => {
|
|
|
4126
4413
|
}
|
|
4127
4414
|
|
|
4128
4415
|
export function run(result: string[] | RecordWithTtl[]): number {
|
|
4129
|
-
const values = result as Array<
|
|
4416
|
+
const values = result as Array<unknown>;
|
|
4130
4417
|
return values.length;
|
|
4131
4418
|
}
|
|
4132
4419
|
`, "/test/test.ts", { surface: "@tsonic/js" });
|
|
4133
4420
|
expect(csharp).to.include("result.Match<object?[]>");
|
|
4134
|
-
expect(csharp).to.
|
|
4421
|
+
expect(csharp).to.include("global::System.Linq.Enumerable.Select");
|
|
4135
4422
|
expect(csharp).not.to.include("Cannot materialize runtime union arrayType to arrayType");
|
|
4136
4423
|
});
|
|
4424
|
+
it("emits in-operator checks only for string-key dictionary carriers", () => {
|
|
4425
|
+
const csharp = compileToCSharp(`
|
|
4426
|
+
export function hasKey(values: Record<string, number>): boolean {
|
|
4427
|
+
return "total" in values;
|
|
4428
|
+
}
|
|
4429
|
+
`);
|
|
4430
|
+
expect(csharp).to.include('return values.ContainsKey("total");');
|
|
4431
|
+
});
|
|
4432
|
+
it("rejects in-operator checks over declared object properties", () => {
|
|
4433
|
+
expect(() => compileToCSharp(`
|
|
4434
|
+
export function hasName(value: { name?: string }): boolean {
|
|
4435
|
+
return "name" in value;
|
|
4436
|
+
}
|
|
4437
|
+
`)).to.throw(/'in' operator is only supported/);
|
|
4438
|
+
});
|
|
4137
4439
|
});
|
|
4138
4440
|
});
|
|
4139
4441
|
//# sourceMappingURL=regression-coverage-c.test.js.map
|