@tsonic/frontend 0.0.14 → 0.0.16
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/graph/builder.js +2 -2
- package/dist/graph/builder.js.map +1 -1
- package/dist/graph/extraction/imports.js +1 -1
- package/dist/graph/extraction/imports.js.map +1 -1
- package/dist/graph/extraction/orchestrator.d.ts.map +1 -1
- package/dist/graph/extraction/orchestrator.js +3 -2
- package/dist/graph/extraction/orchestrator.js.map +1 -1
- package/dist/ir/binding/index.d.ts +155 -0
- package/dist/ir/binding/index.d.ts.map +1 -0
- package/dist/ir/binding/index.js +1035 -0
- package/dist/ir/binding/index.js.map +1 -0
- package/dist/ir/binding-resolution.test.js +193 -52
- package/dist/ir/binding-resolution.test.js.map +1 -1
- package/dist/ir/bindings-disambiguation.test.d.ts +11 -0
- package/dist/ir/bindings-disambiguation.test.d.ts.map +1 -0
- package/dist/ir/bindings-disambiguation.test.js +416 -0
- package/dist/ir/bindings-disambiguation.test.js.map +1 -0
- package/dist/ir/builder/exports.d.ts +20 -2
- package/dist/ir/builder/exports.d.ts.map +1 -1
- package/dist/ir/builder/exports.js +65 -6
- package/dist/ir/builder/exports.js.map +1 -1
- package/dist/ir/builder/imports.d.ts +9 -5
- package/dist/ir/builder/imports.d.ts.map +1 -1
- package/dist/ir/builder/imports.js +20 -31
- package/dist/ir/builder/imports.js.map +1 -1
- package/dist/ir/builder/orchestrator.d.ts +10 -1
- package/dist/ir/builder/orchestrator.d.ts.map +1 -1
- package/dist/ir/builder/orchestrator.js +32 -15
- package/dist/ir/builder/orchestrator.js.map +1 -1
- package/dist/ir/builder/statements.d.ts +7 -1
- package/dist/ir/builder/statements.d.ts.map +1 -1
- package/dist/ir/builder/statements.js +7 -2
- package/dist/ir/builder/statements.js.map +1 -1
- package/dist/ir/builder/types.d.ts +2 -0
- package/dist/ir/builder/types.d.ts.map +1 -1
- package/dist/ir/builder/validation.d.ts +4 -1
- package/dist/ir/builder/validation.d.ts.map +1 -1
- package/dist/ir/builder/validation.js +37 -37
- package/dist/ir/builder/validation.js.map +1 -1
- package/dist/ir/builder.test.js +55 -112
- package/dist/ir/builder.test.js.map +1 -1
- package/dist/ir/converters/anonymous-synthesis.d.ts +30 -8
- package/dist/ir/converters/anonymous-synthesis.d.ts.map +1 -1
- package/dist/ir/converters/anonymous-synthesis.js +46 -55
- package/dist/ir/converters/anonymous-synthesis.js.map +1 -1
- package/dist/ir/converters/context.d.ts +40 -0
- package/dist/ir/converters/context.d.ts.map +1 -0
- package/dist/ir/converters/context.js +25 -0
- package/dist/ir/converters/context.js.map +1 -0
- package/dist/ir/converters/expressions/access.d.ts +6 -1
- package/dist/ir/converters/expressions/access.d.ts.map +1 -1
- package/dist/ir/converters/expressions/access.js +389 -43
- package/dist/ir/converters/expressions/access.js.map +1 -1
- package/dist/ir/converters/expressions/calls.d.ts +24 -3
- package/dist/ir/converters/expressions/calls.d.ts.map +1 -1
- package/dist/ir/converters/expressions/calls.js +674 -397
- package/dist/ir/converters/expressions/calls.js.map +1 -1
- package/dist/ir/converters/expressions/collections.d.ts +16 -3
- package/dist/ir/converters/expressions/collections.d.ts.map +1 -1
- package/dist/ir/converters/expressions/collections.js +300 -46
- package/dist/ir/converters/expressions/collections.js.map +1 -1
- package/dist/ir/converters/expressions/functions.d.ts +10 -3
- package/dist/ir/converters/expressions/functions.d.ts.map +1 -1
- package/dist/ir/converters/expressions/functions.js +158 -32
- package/dist/ir/converters/expressions/functions.js.map +1 -1
- package/dist/ir/converters/expressions/helpers.d.ts +22 -23
- package/dist/ir/converters/expressions/helpers.d.ts.map +1 -1
- package/dist/ir/converters/expressions/helpers.js +242 -239
- package/dist/ir/converters/expressions/helpers.js.map +1 -1
- package/dist/ir/converters/expressions/index.d.ts +1 -1
- package/dist/ir/converters/expressions/index.d.ts.map +1 -1
- package/dist/ir/converters/expressions/index.js +1 -1
- package/dist/ir/converters/expressions/index.js.map +1 -1
- package/dist/ir/converters/expressions/literals.d.ts +12 -12
- package/dist/ir/converters/expressions/literals.d.ts.map +1 -1
- package/dist/ir/converters/expressions/literals.js +62 -17
- package/dist/ir/converters/expressions/literals.js.map +1 -1
- package/dist/ir/converters/expressions/numeric-recovery.test.d.ts +5 -2
- package/dist/ir/converters/expressions/numeric-recovery.test.d.ts.map +1 -1
- package/dist/ir/converters/expressions/numeric-recovery.test.js +62 -49
- package/dist/ir/converters/expressions/numeric-recovery.test.js.map +1 -1
- package/dist/ir/converters/expressions/operators.d.ts +13 -4
- package/dist/ir/converters/expressions/operators.d.ts.map +1 -1
- package/dist/ir/converters/expressions/operators.js +183 -33
- package/dist/ir/converters/expressions/operators.js.map +1 -1
- package/dist/ir/converters/expressions/other.d.ts +11 -3
- package/dist/ir/converters/expressions/other.d.ts.map +1 -1
- package/dist/ir/converters/expressions/other.js +26 -10
- package/dist/ir/converters/expressions/other.js.map +1 -1
- package/dist/ir/converters/flow-narrowing.d.ts +27 -0
- package/dist/ir/converters/flow-narrowing.d.ts.map +1 -0
- package/dist/ir/converters/flow-narrowing.js +73 -0
- package/dist/ir/converters/flow-narrowing.js.map +1 -0
- package/dist/ir/converters/statements/control/blocks.d.ts +8 -2
- package/dist/ir/converters/statements/control/blocks.d.ts.map +1 -1
- package/dist/ir/converters/statements/control/blocks.js +7 -2
- package/dist/ir/converters/statements/control/blocks.js.map +1 -1
- package/dist/ir/converters/statements/control/conditionals.d.ts +14 -4
- package/dist/ir/converters/statements/control/conditionals.d.ts.map +1 -1
- package/dist/ir/converters/statements/control/conditionals.js +36 -10
- package/dist/ir/converters/statements/control/conditionals.js.map +1 -1
- package/dist/ir/converters/statements/control/exceptions.d.ts +10 -3
- package/dist/ir/converters/statements/control/exceptions.d.ts.map +1 -1
- package/dist/ir/converters/statements/control/exceptions.js +13 -7
- package/dist/ir/converters/statements/control/exceptions.js.map +1 -1
- package/dist/ir/converters/statements/control/loops.d.ts +16 -5
- package/dist/ir/converters/statements/control/loops.d.ts.map +1 -1
- package/dist/ir/converters/statements/control/loops.js +25 -15
- package/dist/ir/converters/statements/control/loops.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/constructors.d.ts +3 -2
- package/dist/ir/converters/statements/declarations/classes/constructors.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/constructors.js +11 -7
- package/dist/ir/converters/statements/declarations/classes/constructors.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/methods.d.ts +2 -1
- package/dist/ir/converters/statements/declarations/classes/methods.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/methods.js +63 -11
- package/dist/ir/converters/statements/declarations/classes/methods.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/orchestrator.d.ts +2 -1
- package/dist/ir/converters/statements/declarations/classes/orchestrator.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/orchestrator.js +60 -40
- package/dist/ir/converters/statements/declarations/classes/orchestrator.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/override-detection.d.ts +6 -2
- package/dist/ir/converters/statements/declarations/classes/override-detection.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/override-detection.js +49 -50
- package/dist/ir/converters/statements/declarations/classes/override-detection.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/properties.d.ts +9 -1
- package/dist/ir/converters/statements/declarations/classes/properties.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/properties.js +119 -16
- package/dist/ir/converters/statements/declarations/classes/properties.js.map +1 -1
- package/dist/ir/converters/statements/declarations/enums.d.ts +2 -1
- package/dist/ir/converters/statements/declarations/enums.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/enums.js +8 -2
- package/dist/ir/converters/statements/declarations/enums.js.map +1 -1
- package/dist/ir/converters/statements/declarations/functions.d.ts +2 -1
- package/dist/ir/converters/statements/declarations/functions.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/functions.js +11 -6
- package/dist/ir/converters/statements/declarations/functions.js.map +1 -1
- package/dist/ir/converters/statements/declarations/index.d.ts +3 -1
- package/dist/ir/converters/statements/declarations/index.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/index.js +3 -1
- package/dist/ir/converters/statements/declarations/index.js.map +1 -1
- package/dist/ir/converters/statements/declarations/interfaces.d.ts +3 -2
- package/dist/ir/converters/statements/declarations/interfaces.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/interfaces.js +26 -20
- package/dist/ir/converters/statements/declarations/interfaces.js.map +1 -1
- package/dist/ir/converters/statements/declarations/registry.d.ts +72 -0
- package/dist/ir/converters/statements/declarations/registry.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/registry.js +92 -0
- package/dist/ir/converters/statements/declarations/registry.js.map +1 -1
- package/dist/ir/converters/statements/declarations/type-aliases.d.ts +2 -1
- package/dist/ir/converters/statements/declarations/type-aliases.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/type-aliases.js +6 -4
- package/dist/ir/converters/statements/declarations/type-aliases.js.map +1 -1
- package/dist/ir/converters/statements/declarations/variables.d.ts +11 -1
- package/dist/ir/converters/statements/declarations/variables.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/variables.js +123 -19
- package/dist/ir/converters/statements/declarations/variables.js.map +1 -1
- package/dist/ir/converters/statements/declarations.d.ts +4 -1
- package/dist/ir/converters/statements/declarations.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations.js +4 -1
- package/dist/ir/converters/statements/declarations.js.map +1 -1
- package/dist/ir/converters/statements/helpers.d.ts +4 -3
- package/dist/ir/converters/statements/helpers.d.ts.map +1 -1
- package/dist/ir/converters/statements/helpers.js +55 -31
- package/dist/ir/converters/statements/helpers.js.map +1 -1
- package/dist/ir/converters/statements/index.d.ts +1 -1
- package/dist/ir/converters/statements/index.d.ts.map +1 -1
- package/dist/ir/converters/statements/index.js +2 -1
- package/dist/ir/converters/statements/index.js.map +1 -1
- package/dist/ir/expression-converter.d.ts +10 -3
- package/dist/ir/expression-converter.d.ts.map +1 -1
- package/dist/ir/expression-converter.js +139 -57
- package/dist/ir/expression-converter.js.map +1 -1
- package/dist/ir/hierarchical-bindings-e2e.test.js +10 -6
- package/dist/ir/hierarchical-bindings-e2e.test.js.map +1 -1
- package/dist/ir/index.d.ts +5 -0
- package/dist/ir/index.d.ts.map +1 -1
- package/dist/ir/index.js +5 -0
- package/dist/ir/index.js.map +1 -1
- package/dist/ir/no-ts-type-inference.test.d.ts +17 -0
- package/dist/ir/no-ts-type-inference.test.d.ts.map +1 -0
- package/dist/ir/no-ts-type-inference.test.js +171 -0
- package/dist/ir/no-ts-type-inference.test.js.map +1 -0
- package/dist/ir/program-context.d.ts +87 -0
- package/dist/ir/program-context.d.ts.map +1 -0
- package/dist/ir/program-context.js +289 -0
- package/dist/ir/program-context.js.map +1 -0
- package/dist/ir/statement-converter.d.ts +14 -4
- package/dist/ir/statement-converter.d.ts.map +1 -1
- package/dist/ir/statement-converter.js +31 -21
- package/dist/ir/statement-converter.js.map +1 -1
- package/dist/ir/syntax/binding-patterns.d.ts +22 -0
- package/dist/ir/syntax/binding-patterns.d.ts.map +1 -0
- package/dist/ir/{type-converter/patterns.js → syntax/binding-patterns.js} +34 -8
- package/dist/ir/syntax/binding-patterns.js.map +1 -0
- package/dist/ir/thisarg-inference.test.d.ts +8 -0
- package/dist/ir/thisarg-inference.test.d.ts.map +1 -0
- package/dist/ir/thisarg-inference.test.js +94 -0
- package/dist/ir/thisarg-inference.test.js.map +1 -0
- package/dist/ir/type-system/index.d.ts +21 -0
- package/dist/ir/type-system/index.d.ts.map +1 -0
- package/dist/ir/type-system/index.js +43 -0
- package/dist/ir/type-system/index.js.map +1 -0
- package/dist/ir/type-system/internal/handle-types.d.ts +105 -0
- package/dist/ir/type-system/internal/handle-types.d.ts.map +1 -0
- package/dist/ir/type-system/internal/handle-types.js +13 -0
- package/dist/ir/type-system/internal/handle-types.js.map +1 -0
- package/dist/ir/type-system/internal/nominal-env.d.ts +66 -0
- package/dist/ir/type-system/internal/nominal-env.d.ts.map +1 -0
- package/dist/ir/type-system/internal/nominal-env.js +301 -0
- package/dist/ir/type-system/internal/nominal-env.js.map +1 -0
- package/dist/ir/type-system/internal/type-converter/arrays.d.ts +11 -0
- package/dist/ir/type-system/internal/type-converter/arrays.d.ts.map +1 -0
- package/dist/ir/{type-converter → type-system/internal/type-converter}/arrays.js +2 -2
- package/dist/ir/type-system/internal/type-converter/arrays.js.map +1 -0
- package/dist/ir/type-system/internal/type-converter/converter.d.ts +17 -0
- package/dist/ir/type-system/internal/type-converter/converter.d.ts.map +1 -0
- package/dist/ir/type-system/internal/type-converter/converter.js +16 -0
- package/dist/ir/type-system/internal/type-converter/converter.js.map +1 -0
- package/dist/ir/type-system/internal/type-converter/functions.d.ts +14 -0
- package/dist/ir/type-system/internal/type-converter/functions.d.ts.map +1 -0
- package/dist/ir/type-system/internal/type-converter/functions.js +66 -0
- package/dist/ir/type-system/internal/type-converter/functions.js.map +1 -0
- package/dist/ir/type-system/internal/type-converter/index.d.ts +11 -0
- package/dist/ir/type-system/internal/type-converter/index.d.ts.map +1 -0
- package/dist/ir/type-system/internal/type-converter/index.js +11 -0
- package/dist/ir/type-system/internal/type-converter/index.js.map +1 -0
- package/dist/ir/type-system/internal/type-converter/inference.d.ts +37 -0
- package/dist/ir/type-system/internal/type-converter/inference.d.ts.map +1 -0
- package/dist/ir/type-system/internal/type-converter/inference.js +32 -0
- package/dist/ir/type-system/internal/type-converter/inference.js.map +1 -0
- package/dist/ir/{type-converter → type-system/internal/type-converter}/literals.d.ts +1 -1
- package/dist/ir/type-system/internal/type-converter/literals.d.ts.map +1 -0
- package/dist/ir/type-system/internal/type-converter/literals.js.map +1 -0
- package/dist/ir/type-system/internal/type-converter/objects.d.ts +20 -0
- package/dist/ir/type-system/internal/type-converter/objects.d.ts.map +1 -0
- package/dist/ir/{type-converter → type-system/internal/type-converter}/objects.js +56 -6
- package/dist/ir/type-system/internal/type-converter/objects.js.map +1 -0
- package/dist/ir/{type-converter → type-system/internal/type-converter}/orchestrator.d.ts +3 -2
- package/dist/ir/type-system/internal/type-converter/orchestrator.d.ts.map +1 -0
- package/dist/ir/{type-converter → type-system/internal/type-converter}/orchestrator.js +63 -21
- package/dist/ir/type-system/internal/type-converter/orchestrator.js.map +1 -0
- package/dist/ir/{type-converter → type-system/internal/type-converter}/primitives.d.ts +4 -4
- package/dist/ir/type-system/internal/type-converter/primitives.d.ts.map +1 -0
- package/dist/ir/{type-converter → type-system/internal/type-converter}/primitives.js +2 -2
- package/dist/ir/type-system/internal/type-converter/primitives.js.map +1 -0
- package/dist/ir/{type-converter → type-system/internal/type-converter}/references.d.ts +3 -2
- package/dist/ir/type-system/internal/type-converter/references.d.ts.map +1 -0
- package/dist/ir/type-system/internal/type-converter/references.js +545 -0
- package/dist/ir/type-system/internal/type-converter/references.js.map +1 -0
- package/dist/ir/type-system/internal/type-converter/unions-intersections.d.ts +15 -0
- package/dist/ir/type-system/internal/type-converter/unions-intersections.d.ts.map +1 -0
- package/dist/ir/type-system/internal/type-converter/unions-intersections.js +22 -0
- package/dist/ir/type-system/internal/type-converter/unions-intersections.js.map +1 -0
- package/dist/ir/{type-converter → type-system/internal/type-converter}/utility-types.d.ts +23 -36
- package/dist/ir/type-system/internal/type-converter/utility-types.d.ts.map +1 -0
- package/dist/ir/type-system/internal/type-converter/utility-types.js +879 -0
- package/dist/ir/type-system/internal/type-converter/utility-types.js.map +1 -0
- package/dist/ir/type-system/internal/type-converter/utility-types.test.d.ts.map +1 -0
- package/dist/ir/{type-converter → type-system/internal/type-converter}/utility-types.test.js +398 -120
- package/dist/ir/type-system/internal/type-converter/utility-types.test.js.map +1 -0
- package/dist/ir/type-system/internal/type-converter.d.ts +9 -0
- package/dist/ir/type-system/internal/type-converter.d.ts.map +1 -0
- package/dist/ir/type-system/internal/type-converter.js +9 -0
- package/dist/ir/type-system/internal/type-converter.js.map +1 -0
- package/dist/ir/type-system/internal/type-registry.d.ts +112 -0
- package/dist/ir/type-system/internal/type-registry.d.ts.map +1 -0
- package/dist/ir/type-system/internal/type-registry.js +535 -0
- package/dist/ir/type-system/internal/type-registry.js.map +1 -0
- package/dist/ir/type-system/internal/universe/alias-table.d.ts +92 -0
- package/dist/ir/type-system/internal/universe/alias-table.d.ts.map +1 -0
- package/dist/ir/type-system/internal/universe/alias-table.js +222 -0
- package/dist/ir/type-system/internal/universe/alias-table.js.map +1 -0
- package/dist/ir/type-system/internal/universe/clr-catalog.d.ts +44 -0
- package/dist/ir/type-system/internal/universe/clr-catalog.d.ts.map +1 -0
- package/dist/ir/type-system/internal/universe/clr-catalog.js +1192 -0
- package/dist/ir/type-system/internal/universe/clr-catalog.js.map +1 -0
- package/dist/ir/type-system/internal/universe/index.d.ts +26 -0
- package/dist/ir/type-system/internal/universe/index.d.ts.map +1 -0
- package/dist/ir/type-system/internal/universe/index.js +30 -0
- package/dist/ir/type-system/internal/universe/index.js.map +1 -0
- package/dist/ir/type-system/internal/universe/resolution.d.ts +115 -0
- package/dist/ir/type-system/internal/universe/resolution.d.ts.map +1 -0
- package/dist/ir/type-system/internal/universe/resolution.js +181 -0
- package/dist/ir/type-system/internal/universe/resolution.js.map +1 -0
- package/dist/ir/type-system/internal/universe/source-catalog.d.ts +64 -0
- package/dist/ir/type-system/internal/universe/source-catalog.d.ts.map +1 -0
- package/dist/ir/type-system/internal/universe/source-catalog.js +96 -0
- package/dist/ir/type-system/internal/universe/source-catalog.js.map +1 -0
- package/dist/ir/type-system/internal/universe/types.d.ts +436 -0
- package/dist/ir/type-system/internal/universe/types.d.ts.map +1 -0
- package/dist/ir/type-system/internal/universe/types.js +69 -0
- package/dist/ir/type-system/internal/universe/types.js.map +1 -0
- package/dist/ir/type-system/internal/universe/unified-universe.d.ts +70 -0
- package/dist/ir/type-system/internal/universe/unified-universe.d.ts.map +1 -0
- package/dist/ir/type-system/internal/universe/unified-universe.js +319 -0
- package/dist/ir/type-system/internal/universe/unified-universe.js.map +1 -0
- package/dist/ir/type-system/type-system.d.ts +617 -0
- package/dist/ir/type-system/type-system.d.ts.map +1 -0
- package/dist/ir/type-system/type-system.js +2579 -0
- package/dist/ir/type-system/type-system.js.map +1 -0
- package/dist/ir/type-system/types.d.ts +176 -0
- package/dist/ir/type-system/types.d.ts.map +1 -0
- package/dist/ir/type-system/types.js +80 -0
- package/dist/ir/type-system/types.js.map +1 -0
- package/dist/ir/types/expressions.d.ts +35 -7
- package/dist/ir/types/expressions.d.ts.map +1 -1
- package/dist/ir/types/helpers.d.ts +22 -2
- package/dist/ir/types/helpers.d.ts.map +1 -1
- package/dist/ir/types/index.d.ts +4 -2
- package/dist/ir/types/index.d.ts.map +1 -1
- package/dist/ir/types/index.js +1 -0
- package/dist/ir/types/index.js.map +1 -1
- package/dist/ir/types/ir-substitution.d.ts +144 -0
- package/dist/ir/types/ir-substitution.d.ts.map +1 -0
- package/dist/ir/types/ir-substitution.js +569 -0
- package/dist/ir/types/ir-substitution.js.map +1 -0
- package/dist/ir/types/ir-types.d.ts +10 -4
- package/dist/ir/types/ir-types.d.ts.map +1 -1
- package/dist/ir/types/numeric-helpers.d.ts +2 -1
- package/dist/ir/types/numeric-helpers.d.ts.map +1 -1
- package/dist/ir/types/numeric-helpers.js +9 -3
- package/dist/ir/types/numeric-helpers.js.map +1 -1
- package/dist/ir/types/statements.d.ts +22 -1
- package/dist/ir/types/statements.d.ts.map +1 -1
- package/dist/ir/types.d.ts +1 -1
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/types.js.map +1 -1
- package/dist/ir/validation/anonymous-type-lowering-pass.d.ts.map +1 -1
- package/dist/ir/validation/anonymous-type-lowering-pass.js +153 -8
- package/dist/ir/validation/anonymous-type-lowering-pass.js.map +1 -1
- package/dist/ir/validation/arrow-return-finalization-pass.d.ts +28 -0
- package/dist/ir/validation/arrow-return-finalization-pass.d.ts.map +1 -0
- package/dist/ir/validation/arrow-return-finalization-pass.js +416 -0
- package/dist/ir/validation/arrow-return-finalization-pass.js.map +1 -0
- package/dist/ir/validation/attribute-collection-pass.d.ts.map +1 -1
- package/dist/ir/validation/attribute-collection-pass.js +40 -6
- package/dist/ir/validation/attribute-collection-pass.js.map +1 -1
- package/dist/ir/validation/attribute-collection-pass.test.js +43 -36
- package/dist/ir/validation/attribute-collection-pass.test.js.map +1 -1
- package/dist/ir/validation/char-validation-pass.d.ts +26 -0
- package/dist/ir/validation/char-validation-pass.d.ts.map +1 -0
- package/dist/ir/validation/char-validation-pass.js +495 -0
- package/dist/ir/validation/char-validation-pass.js.map +1 -0
- package/dist/ir/validation/index.d.ts +3 -0
- package/dist/ir/validation/index.d.ts.map +1 -1
- package/dist/ir/validation/index.js +3 -0
- package/dist/ir/validation/index.js.map +1 -1
- package/dist/ir/validation/numeric-coercion-pass.d.ts +22 -16
- package/dist/ir/validation/numeric-coercion-pass.d.ts.map +1 -1
- package/dist/ir/validation/numeric-coercion-pass.js +159 -51
- package/dist/ir/validation/numeric-coercion-pass.js.map +1 -1
- package/dist/ir/validation/numeric-invariants.test.js +72 -108
- package/dist/ir/validation/numeric-invariants.test.js.map +1 -1
- package/dist/ir/validation/numeric-proof-pass.d.ts.map +1 -1
- package/dist/ir/validation/numeric-proof-pass.js +71 -23
- package/dist/ir/validation/numeric-proof-pass.js.map +1 -1
- package/dist/ir/validation/rest-type-synthesis-pass.d.ts +24 -0
- package/dist/ir/validation/rest-type-synthesis-pass.d.ts.map +1 -0
- package/dist/ir/validation/rest-type-synthesis-pass.js +417 -0
- package/dist/ir/validation/rest-type-synthesis-pass.js.map +1 -0
- package/dist/ir/validation/soundness-gate.d.ts +11 -1
- package/dist/ir/validation/soundness-gate.d.ts.map +1 -1
- package/dist/ir/validation/soundness-gate.js +42 -10
- package/dist/ir/validation/soundness-gate.js.map +1 -1
- package/dist/ir/validation/soundness-gate.test.js +19 -2
- package/dist/ir/validation/soundness-gate.test.js.map +1 -1
- package/dist/ir/validation/virtual-marking-pass.d.ts +16 -0
- package/dist/ir/validation/virtual-marking-pass.d.ts.map +1 -0
- package/dist/ir/validation/virtual-marking-pass.js +77 -0
- package/dist/ir/validation/virtual-marking-pass.js.map +1 -0
- package/dist/ir/validation/yield-lowering-pass.test.js +2 -2
- package/dist/ir/validation/yield-lowering-pass.test.js.map +1 -1
- package/dist/program/bindings.d.ts +44 -0
- package/dist/program/bindings.d.ts.map +1 -1
- package/dist/program/bindings.js +248 -2
- package/dist/program/bindings.js.map +1 -1
- package/dist/program/bindings.test.js +30 -0
- package/dist/program/bindings.test.js.map +1 -1
- package/dist/program/creation.d.ts.map +1 -1
- package/dist/program/creation.js +158 -4
- package/dist/program/creation.js.map +1 -1
- package/dist/program/dependency-graph.d.ts.map +1 -1
- package/dist/program/dependency-graph.js +33 -26
- package/dist/program/dependency-graph.js.map +1 -1
- package/dist/program/index.d.ts +1 -1
- package/dist/program/index.d.ts.map +1 -1
- package/dist/program/types.d.ts +7 -8
- package/dist/program/types.d.ts.map +1 -1
- package/dist/resolver/clr-bindings-resolver.d.ts +6 -0
- package/dist/resolver/clr-bindings-resolver.d.ts.map +1 -1
- package/dist/resolver/clr-bindings-resolver.js +185 -39
- package/dist/resolver/clr-bindings-resolver.js.map +1 -1
- package/dist/resolver/clr-bindings-resolver.test.d.ts +2 -0
- package/dist/resolver/clr-bindings-resolver.test.d.ts.map +1 -0
- package/dist/resolver/clr-bindings-resolver.test.js +161 -0
- package/dist/resolver/clr-bindings-resolver.test.js.map +1 -0
- package/dist/resolver/import-resolution.d.ts +16 -1
- package/dist/resolver/import-resolution.d.ts.map +1 -1
- package/dist/resolver/import-resolution.js +29 -12
- package/dist/resolver/import-resolution.js.map +1 -1
- package/dist/resolver/namespace.d.ts +2 -1
- package/dist/resolver/namespace.d.ts.map +1 -1
- package/dist/resolver/namespace.js +5 -2
- package/dist/resolver/namespace.js.map +1 -1
- package/dist/resolver/namespace.test.js +6 -6
- package/dist/resolver/naming-policy.d.ts +20 -0
- package/dist/resolver/naming-policy.d.ts.map +1 -0
- package/dist/resolver/naming-policy.js +40 -0
- package/dist/resolver/naming-policy.js.map +1 -0
- package/dist/resolver/naming.d.ts +2 -5
- package/dist/resolver/naming.d.ts.map +1 -1
- package/dist/resolver/naming.js +3 -20
- package/dist/resolver/naming.js.map +1 -1
- package/dist/resolver.d.ts +2 -0
- package/dist/resolver.d.ts.map +1 -1
- package/dist/resolver.js +1 -0
- package/dist/resolver.js.map +1 -1
- package/dist/resolver.test.js +8 -3
- package/dist/resolver.test.js.map +1 -1
- package/dist/symbol-table/builder.d.ts +3 -1
- package/dist/symbol-table/builder.d.ts.map +1 -1
- package/dist/symbol-table/builder.js +9 -8
- package/dist/symbol-table/builder.js.map +1 -1
- package/dist/symbol-table/types.d.ts +2 -2
- package/dist/symbol-table/types.d.ts.map +1 -1
- package/dist/types/diagnostic.d.ts +12 -2
- package/dist/types/diagnostic.d.ts.map +1 -1
- package/dist/types/diagnostic.js +5 -1
- package/dist/types/diagnostic.js.map +1 -1
- package/dist/validation/core-intrinsics.d.ts +18 -0
- package/dist/validation/core-intrinsics.d.ts.map +1 -0
- package/dist/validation/core-intrinsics.js +186 -0
- package/dist/validation/core-intrinsics.js.map +1 -0
- package/dist/validation/extension-methods.d.ts +17 -0
- package/dist/validation/extension-methods.d.ts.map +1 -0
- package/dist/validation/extension-methods.js +133 -0
- package/dist/validation/extension-methods.js.map +1 -0
- package/dist/validation/generics.d.ts.map +1 -1
- package/dist/validation/generics.js +1 -129
- package/dist/validation/generics.js.map +1 -1
- package/dist/validation/imports.js +1 -1
- package/dist/validation/imports.js.map +1 -1
- package/dist/validation/index.d.ts +2 -0
- package/dist/validation/index.d.ts.map +1 -1
- package/dist/validation/index.js +2 -0
- package/dist/validation/index.js.map +1 -1
- package/dist/validation/orchestrator.d.ts.map +1 -1
- package/dist/validation/orchestrator.js +4 -0
- package/dist/validation/orchestrator.js.map +1 -1
- package/dist/validation/static-safety.d.ts +1 -0
- package/dist/validation/static-safety.d.ts.map +1 -1
- package/dist/validation/static-safety.js +366 -96
- package/dist/validation/static-safety.js.map +1 -1
- package/dist/validator.test.js +123 -1
- package/dist/validator.test.js.map +1 -1
- package/package.json +2 -2
- package/dist/ir/type-converter/arrays.d.ts +0 -10
- package/dist/ir/type-converter/arrays.d.ts.map +0 -1
- package/dist/ir/type-converter/arrays.js.map +0 -1
- package/dist/ir/type-converter/converter.d.ts +0 -6
- package/dist/ir/type-converter/converter.d.ts.map +0 -1
- package/dist/ir/type-converter/converter.js +0 -6
- package/dist/ir/type-converter/converter.js.map +0 -1
- package/dist/ir/type-converter/functions.d.ts +0 -10
- package/dist/ir/type-converter/functions.d.ts.map +0 -1
- package/dist/ir/type-converter/functions.js +0 -15
- package/dist/ir/type-converter/functions.js.map +0 -1
- package/dist/ir/type-converter/index.d.ts +0 -7
- package/dist/ir/type-converter/index.d.ts.map +0 -1
- package/dist/ir/type-converter/index.js +0 -7
- package/dist/ir/type-converter/index.js.map +0 -1
- package/dist/ir/type-converter/inference.d.ts +0 -32
- package/dist/ir/type-converter/inference.d.ts.map +0 -1
- package/dist/ir/type-converter/inference.js +0 -297
- package/dist/ir/type-converter/inference.js.map +0 -1
- package/dist/ir/type-converter/literals.d.ts.map +0 -1
- package/dist/ir/type-converter/literals.js.map +0 -1
- package/dist/ir/type-converter/objects.d.ts +0 -16
- package/dist/ir/type-converter/objects.d.ts.map +0 -1
- package/dist/ir/type-converter/objects.js.map +0 -1
- package/dist/ir/type-converter/orchestrator.d.ts.map +0 -1
- package/dist/ir/type-converter/orchestrator.js.map +0 -1
- package/dist/ir/type-converter/patterns.d.ts +0 -10
- package/dist/ir/type-converter/patterns.d.ts.map +0 -1
- package/dist/ir/type-converter/patterns.js.map +0 -1
- package/dist/ir/type-converter/primitives.d.ts.map +0 -1
- package/dist/ir/type-converter/primitives.js.map +0 -1
- package/dist/ir/type-converter/references.d.ts.map +0 -1
- package/dist/ir/type-converter/references.js +0 -371
- package/dist/ir/type-converter/references.js.map +0 -1
- package/dist/ir/type-converter/unions-intersections.d.ts +0 -14
- package/dist/ir/type-converter/unions-intersections.d.ts.map +0 -1
- package/dist/ir/type-converter/unions-intersections.js +0 -22
- package/dist/ir/type-converter/unions-intersections.js.map +0 -1
- package/dist/ir/type-converter/utility-types.d.ts.map +0 -1
- package/dist/ir/type-converter/utility-types.js +0 -528
- package/dist/ir/type-converter/utility-types.js.map +0 -1
- package/dist/ir/type-converter/utility-types.test.d.ts.map +0 -1
- package/dist/ir/type-converter/utility-types.test.js.map +0 -1
- package/dist/ir/type-converter.d.ts +0 -6
- package/dist/ir/type-converter.d.ts.map +0 -1
- package/dist/ir/type-converter.js +0 -6
- package/dist/ir/type-converter.js.map +0 -1
- /package/dist/ir/{type-converter → type-system/internal/type-converter}/literals.js +0 -0
- /package/dist/ir/{type-converter → type-system/internal/type-converter}/utility-types.test.d.ts +0 -0
|
@@ -0,0 +1,879 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility type expansion - Partial, Required, Readonly, Pick, Omit
|
|
3
|
+
*
|
|
4
|
+
* DETERMINISTIC IR TYPING (INV-0 compliant):
|
|
5
|
+
* These utility types are expanded using AST-based analysis only.
|
|
6
|
+
* No banned APIs (getTypeAtLocation, getTypeOfSymbolAtLocation, typeToTypeNode).
|
|
7
|
+
* Uses Binding for symbol resolution and extracts types from TypeNodes.
|
|
8
|
+
*/
|
|
9
|
+
import * as ts from "typescript";
|
|
10
|
+
/**
|
|
11
|
+
* Set of supported mapped utility types that can be expanded
|
|
12
|
+
*/
|
|
13
|
+
export const EXPANDABLE_UTILITY_TYPES = new Set([
|
|
14
|
+
"Partial",
|
|
15
|
+
"Required",
|
|
16
|
+
"Readonly",
|
|
17
|
+
"Pick",
|
|
18
|
+
"Omit",
|
|
19
|
+
]);
|
|
20
|
+
/**
|
|
21
|
+
* Check if a type name is an expandable utility type
|
|
22
|
+
*/
|
|
23
|
+
export const isExpandableUtilityType = (name) => EXPANDABLE_UTILITY_TYPES.has(name);
|
|
24
|
+
/**
|
|
25
|
+
* Set of supported conditional utility types that can be expanded
|
|
26
|
+
* Uses AST-based syntactic algorithms, not TS type evaluation.
|
|
27
|
+
*/
|
|
28
|
+
export const EXPANDABLE_CONDITIONAL_UTILITY_TYPES = new Set([
|
|
29
|
+
"NonNullable",
|
|
30
|
+
"Exclude",
|
|
31
|
+
"Extract",
|
|
32
|
+
"ReturnType",
|
|
33
|
+
"Parameters",
|
|
34
|
+
"Awaited",
|
|
35
|
+
]);
|
|
36
|
+
/**
|
|
37
|
+
* Check if a type name is an expandable conditional utility type
|
|
38
|
+
*/
|
|
39
|
+
export const isExpandableConditionalUtilityType = (name) => EXPANDABLE_CONDITIONAL_UTILITY_TYPES.has(name);
|
|
40
|
+
/**
|
|
41
|
+
* Maximum recursion depth for nested conditional utility expansion.
|
|
42
|
+
* Prevents infinite recursion on cyclic aliases or pathological inputs.
|
|
43
|
+
*/
|
|
44
|
+
const MAX_CONDITIONAL_UTILITY_RECURSION = 16;
|
|
45
|
+
/**
|
|
46
|
+
* Resolve a type alias to its underlying TypeNode (AST-based, INV-0 compliant).
|
|
47
|
+
* Follows type alias chains to get the actual type definition.
|
|
48
|
+
*
|
|
49
|
+
* @param node - The TypeNode to resolve
|
|
50
|
+
* @param binding - The Binding layer for symbol resolution
|
|
51
|
+
* @returns The resolved TypeNode, or the original if not a resolvable alias
|
|
52
|
+
*/
|
|
53
|
+
const resolveTypeAlias = (node, binding) => {
|
|
54
|
+
// Only type references can be aliases
|
|
55
|
+
if (!ts.isTypeReferenceNode(node))
|
|
56
|
+
return node;
|
|
57
|
+
if (!ts.isIdentifier(node.typeName))
|
|
58
|
+
return node;
|
|
59
|
+
// IMPORTANT: Do not resolve compiler-known utility types to their lib.d.ts
|
|
60
|
+
// conditional/type-alias definitions. We treat these as intrinsic and expand
|
|
61
|
+
// them ourselves (deterministically) when requested.
|
|
62
|
+
const name = node.typeName.text;
|
|
63
|
+
if (isExpandableUtilityType(name) ||
|
|
64
|
+
isExpandableConditionalUtilityType(name) ||
|
|
65
|
+
name === "Record" ||
|
|
66
|
+
name === "CLROf" ||
|
|
67
|
+
name === "out" ||
|
|
68
|
+
name === "ref" ||
|
|
69
|
+
name === "inref") {
|
|
70
|
+
return node;
|
|
71
|
+
}
|
|
72
|
+
// Use Binding to resolve the type reference
|
|
73
|
+
const declId = binding.resolveTypeReference(node);
|
|
74
|
+
if (!declId)
|
|
75
|
+
return node;
|
|
76
|
+
const declInfo = binding
|
|
77
|
+
._getHandleRegistry()
|
|
78
|
+
.getDecl(declId);
|
|
79
|
+
if (!declInfo)
|
|
80
|
+
return node;
|
|
81
|
+
// Look for a type alias declaration
|
|
82
|
+
const decl = declInfo.declNode;
|
|
83
|
+
if (!decl || !ts.isTypeAliasDeclaration(decl))
|
|
84
|
+
return node;
|
|
85
|
+
// Recursively resolve in case of chained aliases
|
|
86
|
+
return resolveTypeAlias(decl.type, binding);
|
|
87
|
+
};
|
|
88
|
+
const unwrapParens = (node) => {
|
|
89
|
+
let current = node;
|
|
90
|
+
while (ts.isParenthesizedTypeNode(current)) {
|
|
91
|
+
current = current.type;
|
|
92
|
+
}
|
|
93
|
+
return current;
|
|
94
|
+
};
|
|
95
|
+
const flattenUnionTypeNodes = (node) => {
|
|
96
|
+
const unwrapped = unwrapParens(node);
|
|
97
|
+
if (!ts.isUnionTypeNode(unwrapped))
|
|
98
|
+
return [unwrapped];
|
|
99
|
+
const parts = [];
|
|
100
|
+
for (const t of unwrapped.types) {
|
|
101
|
+
parts.push(...flattenUnionTypeNodes(t));
|
|
102
|
+
}
|
|
103
|
+
return parts;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Check if a TypeNode is a type parameter reference (symbol-based, INV-0 compliant)
|
|
107
|
+
*/
|
|
108
|
+
const isTypeParameterNode = (node, binding) => {
|
|
109
|
+
if (!ts.isTypeReferenceNode(node))
|
|
110
|
+
return false;
|
|
111
|
+
if (!ts.isIdentifier(node.typeName))
|
|
112
|
+
return false;
|
|
113
|
+
// Use Binding to resolve the type reference
|
|
114
|
+
const declId = binding.resolveTypeReference(node);
|
|
115
|
+
if (!declId)
|
|
116
|
+
return false;
|
|
117
|
+
const declInfo = binding
|
|
118
|
+
._getHandleRegistry()
|
|
119
|
+
.getDecl(declId);
|
|
120
|
+
if (!declInfo)
|
|
121
|
+
return false;
|
|
122
|
+
// Check if the declaration is a type parameter
|
|
123
|
+
const decl = declInfo.declNode;
|
|
124
|
+
return decl ? ts.isTypeParameterDeclaration(decl) : false;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Extract members from an interface or type alias declaration (AST-based).
|
|
128
|
+
* Used for utility type expansion.
|
|
129
|
+
*/
|
|
130
|
+
const extractMembersFromDeclaration = (decl, binding, convertType) => {
|
|
131
|
+
// Get type elements from declaration
|
|
132
|
+
const typeElements = ts.isInterfaceDeclaration(decl)
|
|
133
|
+
? decl.members
|
|
134
|
+
: ts.isTypeAliasDeclaration(decl) && ts.isTypeLiteralNode(decl.type)
|
|
135
|
+
? decl.type.members
|
|
136
|
+
: undefined;
|
|
137
|
+
if (!typeElements) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
// Check for index signatures - can't expand these
|
|
141
|
+
for (const member of typeElements) {
|
|
142
|
+
if (ts.isIndexSignatureDeclaration(member)) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const members = [];
|
|
147
|
+
for (const member of typeElements) {
|
|
148
|
+
if (ts.isPropertySignature(member)) {
|
|
149
|
+
const propName = ts.isIdentifier(member.name)
|
|
150
|
+
? member.name.text
|
|
151
|
+
: ts.isStringLiteral(member.name)
|
|
152
|
+
? member.name.text
|
|
153
|
+
: undefined;
|
|
154
|
+
if (!propName || !member.type) {
|
|
155
|
+
continue; // Skip computed keys or untyped properties
|
|
156
|
+
}
|
|
157
|
+
const isOptional = !!member.questionToken;
|
|
158
|
+
const isReadonly = member.modifiers?.some((m) => m.kind === ts.SyntaxKind.ReadonlyKeyword) ?? false;
|
|
159
|
+
members.push({
|
|
160
|
+
kind: "propertySignature",
|
|
161
|
+
name: propName,
|
|
162
|
+
type: convertType(member.type, binding),
|
|
163
|
+
isOptional,
|
|
164
|
+
isReadonly,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
if (ts.isMethodSignature(member)) {
|
|
168
|
+
const methodName = ts.isIdentifier(member.name)
|
|
169
|
+
? member.name.text
|
|
170
|
+
: undefined;
|
|
171
|
+
if (!methodName) {
|
|
172
|
+
continue; // Skip computed keys
|
|
173
|
+
}
|
|
174
|
+
members.push({
|
|
175
|
+
kind: "methodSignature",
|
|
176
|
+
name: methodName,
|
|
177
|
+
parameters: member.parameters.map((param, index) => ({
|
|
178
|
+
kind: "parameter",
|
|
179
|
+
pattern: {
|
|
180
|
+
kind: "identifierPattern",
|
|
181
|
+
name: ts.isIdentifier(param.name) ? param.name.text : `arg${index}`,
|
|
182
|
+
},
|
|
183
|
+
type: param.type ? convertType(param.type, binding) : undefined,
|
|
184
|
+
isOptional: !!param.questionToken,
|
|
185
|
+
isRest: !!param.dotDotDotToken,
|
|
186
|
+
passing: "value",
|
|
187
|
+
})),
|
|
188
|
+
returnType: member.type ? convertType(member.type, binding) : undefined,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return members.length > 0 ? members : null;
|
|
193
|
+
};
|
|
194
|
+
/**
|
|
195
|
+
* Extract literal keys from a TypeNode (AST-based).
|
|
196
|
+
* Returns null if the type contains non-literal constituents or is a type parameter.
|
|
197
|
+
*/
|
|
198
|
+
const extractLiteralKeysFromTypeNode = (node, binding) => {
|
|
199
|
+
// Check for type parameter
|
|
200
|
+
if (isTypeParameterNode(node, binding)) {
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
// Handle string literal: "foo"
|
|
204
|
+
if (ts.isLiteralTypeNode(node) && ts.isStringLiteral(node.literal)) {
|
|
205
|
+
return new Set([node.literal.text]);
|
|
206
|
+
}
|
|
207
|
+
// Handle number literal: 1
|
|
208
|
+
if (ts.isLiteralTypeNode(node) && ts.isNumericLiteral(node.literal)) {
|
|
209
|
+
return new Set([node.literal.text]);
|
|
210
|
+
}
|
|
211
|
+
// Handle union: "a" | "b" | "c"
|
|
212
|
+
if (ts.isUnionTypeNode(node)) {
|
|
213
|
+
const keys = new Set();
|
|
214
|
+
for (const member of node.types) {
|
|
215
|
+
if (ts.isLiteralTypeNode(member)) {
|
|
216
|
+
if (ts.isStringLiteral(member.literal)) {
|
|
217
|
+
keys.add(member.literal.text);
|
|
218
|
+
}
|
|
219
|
+
else if (ts.isNumericLiteral(member.literal)) {
|
|
220
|
+
keys.add(member.literal.text);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
return null; // Non-string/number literal
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
return null; // Non-literal in union
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return keys;
|
|
231
|
+
}
|
|
232
|
+
// String keyword - infinite set, can't expand
|
|
233
|
+
if (node.kind === ts.SyntaxKind.StringKeyword) {
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
// Number keyword - infinite set, can't expand
|
|
237
|
+
if (node.kind === ts.SyntaxKind.NumberKeyword) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
return null; // Not supported
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* Expand a mapped utility type to an IrObjectType.
|
|
244
|
+
*
|
|
245
|
+
* DETERMINISTIC IR TYPING (INV-0 compliant):
|
|
246
|
+
* Uses AST-based analysis only. Gets members from type declarations,
|
|
247
|
+
* not from ts.Type resolution.
|
|
248
|
+
*
|
|
249
|
+
* @param node - The TypeReferenceNode for the utility type
|
|
250
|
+
* @param typeName - The name of the utility type (Partial, Required, etc.)
|
|
251
|
+
* @param binding - The Binding layer for symbol resolution
|
|
252
|
+
* @param convertType - Function to convert nested types
|
|
253
|
+
* @returns IrObjectType with the expanded properties, or null if expansion fails
|
|
254
|
+
*/
|
|
255
|
+
export const expandUtilityType = (node, typeName, binding, convertType) => {
|
|
256
|
+
const debug = !!process.env.DEBUG_UTILITY;
|
|
257
|
+
if (debug)
|
|
258
|
+
console.log(`[UTILITY] Expanding ${typeName}`);
|
|
259
|
+
const typeArgs = node.typeArguments;
|
|
260
|
+
if (!typeArgs || typeArgs.length === 0) {
|
|
261
|
+
if (debug)
|
|
262
|
+
console.log(`[UTILITY] No type args`);
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
// Get the target type argument (first argument for all mapped utilities)
|
|
266
|
+
const targetArg = typeArgs[0];
|
|
267
|
+
if (!targetArg) {
|
|
268
|
+
if (debug)
|
|
269
|
+
console.log(`[UTILITY] No target arg`);
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
// Check if target is a type parameter (can't expand generics)
|
|
273
|
+
if (isTypeParameterNode(targetArg, binding)) {
|
|
274
|
+
if (debug)
|
|
275
|
+
console.log(`[UTILITY] Target is type param`);
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
// For Pick/Omit, check if the keys argument is a type parameter
|
|
279
|
+
if ((typeName === "Pick" || typeName === "Omit") && typeArgs.length >= 2) {
|
|
280
|
+
const keysArg = typeArgs[1];
|
|
281
|
+
if (keysArg && isTypeParameterNode(keysArg, binding)) {
|
|
282
|
+
if (debug)
|
|
283
|
+
console.log(`[UTILITY] Keys is type param`);
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
// Get base members - either from declaration or from recursive expansion
|
|
288
|
+
let baseMembers = null;
|
|
289
|
+
// Get the target type's declaration
|
|
290
|
+
if (!ts.isTypeReferenceNode(targetArg)) {
|
|
291
|
+
// Only support named type references (not inline object types)
|
|
292
|
+
if (debug)
|
|
293
|
+
console.log(`[UTILITY] Target not TypeRef: ${ts.SyntaxKind[targetArg.kind]}`);
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
const targetName = ts.isIdentifier(targetArg.typeName)
|
|
297
|
+
? targetArg.typeName.text
|
|
298
|
+
: undefined;
|
|
299
|
+
if (!targetName) {
|
|
300
|
+
if (debug)
|
|
301
|
+
console.log(`[UTILITY] No target name`);
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
if (debug)
|
|
305
|
+
console.log(`[UTILITY] Target: ${targetName}`);
|
|
306
|
+
// Check if target is itself a utility type (nested utility types)
|
|
307
|
+
if (isExpandableUtilityType(targetName) && targetArg.typeArguments?.length) {
|
|
308
|
+
// Recursively expand the inner utility type first
|
|
309
|
+
const innerExpanded = expandUtilityType(targetArg, targetName, binding, convertType);
|
|
310
|
+
if (innerExpanded) {
|
|
311
|
+
if (debug)
|
|
312
|
+
console.log(`[UTILITY] Recursively expanded ${targetName}, got ${innerExpanded.members.length} members`);
|
|
313
|
+
baseMembers = innerExpanded.members;
|
|
314
|
+
}
|
|
315
|
+
else {
|
|
316
|
+
if (debug)
|
|
317
|
+
console.log(`[UTILITY] Recursive expansion of ${targetName} failed`);
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
// Not a utility type, resolve from declaration using Binding
|
|
323
|
+
const declId = binding.resolveTypeReference(targetArg);
|
|
324
|
+
if (!declId) {
|
|
325
|
+
if (debug)
|
|
326
|
+
console.log(`[UTILITY] No DeclId for ${targetName}`);
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
const declInfo = binding
|
|
330
|
+
._getHandleRegistry()
|
|
331
|
+
.getDecl(declId);
|
|
332
|
+
if (!declInfo?.declNode) {
|
|
333
|
+
if (debug)
|
|
334
|
+
console.log(`[UTILITY] No declaration for ${targetName}`);
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
const decl = declInfo.declNode;
|
|
338
|
+
if (debug)
|
|
339
|
+
console.log(`[UTILITY] Found declaration: ${ts.SyntaxKind[decl.kind]}`);
|
|
340
|
+
// Check if it's an interface or type alias
|
|
341
|
+
if (!ts.isInterfaceDeclaration(decl) && !ts.isTypeAliasDeclaration(decl)) {
|
|
342
|
+
if (debug)
|
|
343
|
+
console.log(`[UTILITY] No interface/type alias decl`);
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
// Extract members from declaration (AST-based)
|
|
347
|
+
baseMembers = extractMembersFromDeclaration(decl, binding, convertType);
|
|
348
|
+
if (!baseMembers) {
|
|
349
|
+
if (debug)
|
|
350
|
+
console.log(`[UTILITY] extractMembersFromDeclaration returned null`);
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
if (debug)
|
|
354
|
+
console.log(`[UTILITY] Extracted ${baseMembers.length} members`);
|
|
355
|
+
}
|
|
356
|
+
if (!baseMembers) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
// Handle Pick/Omit - filter members by keys
|
|
360
|
+
if (typeName === "Pick" || typeName === "Omit") {
|
|
361
|
+
const keysArg = typeArgs[1];
|
|
362
|
+
if (!keysArg) {
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
const keys = extractLiteralKeysFromTypeNode(keysArg, binding);
|
|
366
|
+
if (!keys) {
|
|
367
|
+
return null; // Can't extract literal keys
|
|
368
|
+
}
|
|
369
|
+
const filteredMembers = baseMembers.filter((m) => {
|
|
370
|
+
const include = typeName === "Pick" ? keys.has(m.name) : !keys.has(m.name);
|
|
371
|
+
return include;
|
|
372
|
+
});
|
|
373
|
+
return { kind: "objectType", members: filteredMembers };
|
|
374
|
+
}
|
|
375
|
+
// Apply Partial/Required/Readonly transformations
|
|
376
|
+
const transformedMembers = baseMembers.map((m) => {
|
|
377
|
+
if (m.kind === "propertySignature") {
|
|
378
|
+
const isOptional = typeName === "Partial"
|
|
379
|
+
? true
|
|
380
|
+
: typeName === "Required"
|
|
381
|
+
? false
|
|
382
|
+
: m.isOptional;
|
|
383
|
+
const isReadonly = typeName === "Readonly" ? true : m.isReadonly;
|
|
384
|
+
return {
|
|
385
|
+
...m,
|
|
386
|
+
isOptional,
|
|
387
|
+
isReadonly,
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
return m;
|
|
391
|
+
});
|
|
392
|
+
return { kind: "objectType", members: transformedMembers };
|
|
393
|
+
};
|
|
394
|
+
/**
|
|
395
|
+
* Check if a TypeNode recursively contains type parameters.
|
|
396
|
+
* Uses symbol-based checks only (INV-0 compliant).
|
|
397
|
+
*/
|
|
398
|
+
const typeNodeContainsTypeParameter = (node, binding) => {
|
|
399
|
+
if (isTypeParameterNode(node, binding)) {
|
|
400
|
+
return true;
|
|
401
|
+
}
|
|
402
|
+
if (ts.isUnionTypeNode(node)) {
|
|
403
|
+
return node.types.some((t) => typeNodeContainsTypeParameter(t, binding));
|
|
404
|
+
}
|
|
405
|
+
if (ts.isIntersectionTypeNode(node)) {
|
|
406
|
+
return node.types.some((t) => typeNodeContainsTypeParameter(t, binding));
|
|
407
|
+
}
|
|
408
|
+
if (ts.isArrayTypeNode(node)) {
|
|
409
|
+
return typeNodeContainsTypeParameter(node.elementType, binding);
|
|
410
|
+
}
|
|
411
|
+
if (ts.isTypeReferenceNode(node) && node.typeArguments) {
|
|
412
|
+
return node.typeArguments.some((t) => typeNodeContainsTypeParameter(t, binding));
|
|
413
|
+
}
|
|
414
|
+
return false;
|
|
415
|
+
};
|
|
416
|
+
const flattenUnionIrType = (type) => {
|
|
417
|
+
if (type.kind === "neverType")
|
|
418
|
+
return [];
|
|
419
|
+
if (type.kind !== "unionType")
|
|
420
|
+
return [type];
|
|
421
|
+
const flat = [];
|
|
422
|
+
for (const t of type.types) {
|
|
423
|
+
flat.push(...flattenUnionIrType(t));
|
|
424
|
+
}
|
|
425
|
+
return flat;
|
|
426
|
+
};
|
|
427
|
+
const isProvablyAssignable = (source, target) => {
|
|
428
|
+
// Union target: assignable if assignable to any constituent
|
|
429
|
+
if (target.kind === "unionType") {
|
|
430
|
+
let sawUnknown = false;
|
|
431
|
+
for (const t of target.types) {
|
|
432
|
+
const res = isProvablyAssignable(source, t);
|
|
433
|
+
if (res === true)
|
|
434
|
+
return true;
|
|
435
|
+
if (res === null)
|
|
436
|
+
sawUnknown = true;
|
|
437
|
+
}
|
|
438
|
+
return sawUnknown ? null : false;
|
|
439
|
+
}
|
|
440
|
+
// Top types
|
|
441
|
+
if (target.kind === "anyType")
|
|
442
|
+
return true;
|
|
443
|
+
if (target.kind === "unknownType")
|
|
444
|
+
return true;
|
|
445
|
+
// Bottom
|
|
446
|
+
if (target.kind === "neverType")
|
|
447
|
+
return source.kind === "neverType";
|
|
448
|
+
if (source.kind === "neverType")
|
|
449
|
+
return true;
|
|
450
|
+
// Exact literals
|
|
451
|
+
if (source.kind === "literalType" && target.kind === "literalType") {
|
|
452
|
+
return source.value === target.value;
|
|
453
|
+
}
|
|
454
|
+
// Primitive ↔ primitive
|
|
455
|
+
if (source.kind === "primitiveType" && target.kind === "primitiveType") {
|
|
456
|
+
return source.name === target.name;
|
|
457
|
+
}
|
|
458
|
+
// Literal → primitive
|
|
459
|
+
if (source.kind === "literalType" && target.kind === "primitiveType") {
|
|
460
|
+
switch (typeof source.value) {
|
|
461
|
+
case "string":
|
|
462
|
+
return target.name === "string";
|
|
463
|
+
case "number":
|
|
464
|
+
// Numeric literal types are always assignable to `number`.
|
|
465
|
+
// Assignability to `int` is intentionally left unknown here (range-dependent).
|
|
466
|
+
if (target.name === "number")
|
|
467
|
+
return true;
|
|
468
|
+
if (target.name === "int")
|
|
469
|
+
return null;
|
|
470
|
+
return false;
|
|
471
|
+
case "boolean":
|
|
472
|
+
return target.name === "boolean";
|
|
473
|
+
default:
|
|
474
|
+
return null;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
// Primitive → literal is never provable (would require narrowing)
|
|
478
|
+
if (source.kind === "primitiveType" && target.kind === "literalType") {
|
|
479
|
+
return false;
|
|
480
|
+
}
|
|
481
|
+
// Other kinds (reference types, functions, objects, etc.) require richer typing.
|
|
482
|
+
return null;
|
|
483
|
+
};
|
|
484
|
+
/**
|
|
485
|
+
* Expand NonNullable<T> using syntactic filtering (INV-0 compliant).
|
|
486
|
+
*/
|
|
487
|
+
const expandNonNullable = (typeArg, binding, convertType) => {
|
|
488
|
+
// Check for type parameter
|
|
489
|
+
if (isTypeParameterNode(typeArg, binding)) {
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
// Resolve type aliases to get the underlying type
|
|
493
|
+
const resolved = resolveTypeAlias(typeArg, binding);
|
|
494
|
+
// Handle special keywords
|
|
495
|
+
if (resolved.kind === ts.SyntaxKind.AnyKeyword)
|
|
496
|
+
return { kind: "anyType" };
|
|
497
|
+
if (resolved.kind === ts.SyntaxKind.UnknownKeyword)
|
|
498
|
+
return { kind: "unknownType" };
|
|
499
|
+
if (resolved.kind === ts.SyntaxKind.NeverKeyword)
|
|
500
|
+
return { kind: "neverType" };
|
|
501
|
+
// Syntactic filtering of union types
|
|
502
|
+
if (ts.isUnionTypeNode(resolved)) {
|
|
503
|
+
const filtered = resolved.types.filter((t) => {
|
|
504
|
+
// Direct null/undefined keywords
|
|
505
|
+
if (t.kind === ts.SyntaxKind.NullKeyword)
|
|
506
|
+
return false;
|
|
507
|
+
if (t.kind === ts.SyntaxKind.UndefinedKeyword)
|
|
508
|
+
return false;
|
|
509
|
+
// LiteralTypeNode wrapping null/undefined
|
|
510
|
+
if (ts.isLiteralTypeNode(t) &&
|
|
511
|
+
(t.literal.kind === ts.SyntaxKind.NullKeyword ||
|
|
512
|
+
t.literal.kind === ts.SyntaxKind.UndefinedKeyword)) {
|
|
513
|
+
return false;
|
|
514
|
+
}
|
|
515
|
+
return true;
|
|
516
|
+
});
|
|
517
|
+
if (filtered.length === 0)
|
|
518
|
+
return { kind: "neverType" };
|
|
519
|
+
if (filtered.length === 1 && filtered[0]) {
|
|
520
|
+
return convertType(filtered[0], binding);
|
|
521
|
+
}
|
|
522
|
+
return {
|
|
523
|
+
kind: "unionType",
|
|
524
|
+
types: filtered.map((t) => convertType(t, binding)),
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
// Not a union — return as-is (null/undefined are already filtered by check above)
|
|
528
|
+
if (resolved.kind === ts.SyntaxKind.NullKeyword)
|
|
529
|
+
return { kind: "neverType" };
|
|
530
|
+
if (resolved.kind === ts.SyntaxKind.UndefinedKeyword)
|
|
531
|
+
return { kind: "neverType" };
|
|
532
|
+
return convertType(resolved, binding);
|
|
533
|
+
};
|
|
534
|
+
const expandConditionalUtilityTypeInternal = (node, typeName, binding, convertType, depth) => {
|
|
535
|
+
if (depth > MAX_CONDITIONAL_UTILITY_RECURSION) {
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
const typeArgs = node.typeArguments;
|
|
539
|
+
if (!typeArgs || typeArgs.length === 0) {
|
|
540
|
+
return null;
|
|
541
|
+
}
|
|
542
|
+
// Check for type parameters in any argument
|
|
543
|
+
for (const typeArg of typeArgs) {
|
|
544
|
+
if (typeNodeContainsTypeParameter(typeArg, binding)) {
|
|
545
|
+
return null;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
const firstArg = typeArgs[0];
|
|
549
|
+
if (!firstArg) {
|
|
550
|
+
return null;
|
|
551
|
+
}
|
|
552
|
+
switch (typeName) {
|
|
553
|
+
case "NonNullable":
|
|
554
|
+
return expandNonNullable(firstArg, binding, convertType);
|
|
555
|
+
case "Exclude": {
|
|
556
|
+
const secondArg = typeArgs[1];
|
|
557
|
+
if (!secondArg)
|
|
558
|
+
return null;
|
|
559
|
+
return expandExcludeExtract(firstArg, secondArg, false, binding, convertType, depth);
|
|
560
|
+
}
|
|
561
|
+
case "Extract": {
|
|
562
|
+
const secondArg = typeArgs[1];
|
|
563
|
+
if (!secondArg)
|
|
564
|
+
return null;
|
|
565
|
+
return expandExcludeExtract(firstArg, secondArg, true, binding, convertType, depth);
|
|
566
|
+
}
|
|
567
|
+
case "ReturnType":
|
|
568
|
+
return expandReturnType(firstArg, binding, convertType);
|
|
569
|
+
case "Parameters":
|
|
570
|
+
return expandParameters(firstArg, binding, convertType);
|
|
571
|
+
case "Awaited":
|
|
572
|
+
return expandAwaited(firstArg, binding, convertType);
|
|
573
|
+
default:
|
|
574
|
+
return null;
|
|
575
|
+
}
|
|
576
|
+
};
|
|
577
|
+
/**
|
|
578
|
+
* Expand Exclude<T, U> or Extract<T, U> using syntactic filtering (INV-0 compliant).
|
|
579
|
+
*/
|
|
580
|
+
const expandExcludeExtract = (tArg, uArg, isExtract, binding, convertType, depth) => {
|
|
581
|
+
// Check for type parameters
|
|
582
|
+
if (typeNodeContainsTypeParameter(tArg, binding)) {
|
|
583
|
+
return null;
|
|
584
|
+
}
|
|
585
|
+
if (typeNodeContainsTypeParameter(uArg, binding)) {
|
|
586
|
+
return null;
|
|
587
|
+
}
|
|
588
|
+
if (depth > MAX_CONDITIONAL_UTILITY_RECURSION) {
|
|
589
|
+
return null;
|
|
590
|
+
}
|
|
591
|
+
const tryExpandConditionalArg = (node) => {
|
|
592
|
+
const unwrapped = unwrapParens(node);
|
|
593
|
+
if (!ts.isTypeReferenceNode(unwrapped) || !ts.isIdentifier(unwrapped.typeName)) {
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
const name = unwrapped.typeName.text;
|
|
597
|
+
if (!isExpandableConditionalUtilityType(name)) {
|
|
598
|
+
return null;
|
|
599
|
+
}
|
|
600
|
+
if (!unwrapped.typeArguments?.length) {
|
|
601
|
+
return null;
|
|
602
|
+
}
|
|
603
|
+
return expandConditionalUtilityTypeInternal(unwrapped, name, binding, convertType, depth + 1);
|
|
604
|
+
};
|
|
605
|
+
const convertForFiltering = (node) => {
|
|
606
|
+
const directExpanded = tryExpandConditionalArg(node);
|
|
607
|
+
if (directExpanded)
|
|
608
|
+
return directExpanded;
|
|
609
|
+
const resolved = unwrapParens(resolveTypeAlias(unwrapParens(node), binding));
|
|
610
|
+
const resolvedExpanded = tryExpandConditionalArg(resolved);
|
|
611
|
+
if (resolvedExpanded)
|
|
612
|
+
return resolvedExpanded;
|
|
613
|
+
if (ts.isUnionTypeNode(resolved)) {
|
|
614
|
+
const parts = flattenUnionTypeNodes(resolved);
|
|
615
|
+
const converted = [];
|
|
616
|
+
for (const p of parts) {
|
|
617
|
+
const inner = convertForFiltering(p);
|
|
618
|
+
if (!inner)
|
|
619
|
+
return null;
|
|
620
|
+
converted.push(inner);
|
|
621
|
+
}
|
|
622
|
+
return { kind: "unionType", types: converted };
|
|
623
|
+
}
|
|
624
|
+
return convertType(resolved, binding);
|
|
625
|
+
};
|
|
626
|
+
const tType = convertForFiltering(tArg);
|
|
627
|
+
const uType = convertForFiltering(uArg);
|
|
628
|
+
if (!tType || !uType) {
|
|
629
|
+
return null;
|
|
630
|
+
}
|
|
631
|
+
const tMembers = flattenUnionIrType(tType);
|
|
632
|
+
const filtered = [];
|
|
633
|
+
for (const t of tMembers) {
|
|
634
|
+
const assignable = isProvablyAssignable(t, uType);
|
|
635
|
+
if (isExtract) {
|
|
636
|
+
// Conservative: keep unless we can prove NOT assignable
|
|
637
|
+
if (assignable !== false) {
|
|
638
|
+
filtered.push(t);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
else {
|
|
642
|
+
// Conservative: exclude only when we can prove assignable
|
|
643
|
+
if (assignable !== true) {
|
|
644
|
+
filtered.push(t);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
if (filtered.length === 0)
|
|
649
|
+
return { kind: "neverType" };
|
|
650
|
+
if (filtered.length === 1)
|
|
651
|
+
return filtered[0] ?? { kind: "neverType" };
|
|
652
|
+
return { kind: "unionType", types: filtered };
|
|
653
|
+
};
|
|
654
|
+
/**
|
|
655
|
+
* Expand ReturnType<F> by extracting from function type declaration (INV-0 compliant).
|
|
656
|
+
*/
|
|
657
|
+
const expandReturnType = (fArg, binding, convertType) => {
|
|
658
|
+
// Check for type parameter
|
|
659
|
+
if (isTypeParameterNode(fArg, binding)) {
|
|
660
|
+
return null;
|
|
661
|
+
}
|
|
662
|
+
// Distribute over unions: ReturnType<F1 | F2> = ReturnType<F1> | ReturnType<F2>
|
|
663
|
+
const unwrapped = unwrapParens(fArg);
|
|
664
|
+
if (ts.isUnionTypeNode(unwrapped)) {
|
|
665
|
+
const results = [];
|
|
666
|
+
for (const member of flattenUnionTypeNodes(unwrapped)) {
|
|
667
|
+
const result = expandReturnType(member, binding, convertType);
|
|
668
|
+
if (!result)
|
|
669
|
+
return null;
|
|
670
|
+
results.push(result);
|
|
671
|
+
}
|
|
672
|
+
const flat = results.flatMap((t) => flattenUnionIrType(t));
|
|
673
|
+
if (flat.length === 0)
|
|
674
|
+
return { kind: "neverType" };
|
|
675
|
+
if (flat.length === 1)
|
|
676
|
+
return flat[0] ?? { kind: "neverType" };
|
|
677
|
+
return { kind: "unionType", types: flat };
|
|
678
|
+
}
|
|
679
|
+
// Case 1: Direct function type node
|
|
680
|
+
if (ts.isFunctionTypeNode(unwrapped)) {
|
|
681
|
+
return unwrapped.type
|
|
682
|
+
? convertType(unwrapped.type, binding)
|
|
683
|
+
: { kind: "voidType" };
|
|
684
|
+
}
|
|
685
|
+
// Case 2: Type reference to function type alias
|
|
686
|
+
if (ts.isTypeReferenceNode(unwrapped) && ts.isIdentifier(unwrapped.typeName)) {
|
|
687
|
+
const declId = binding.resolveTypeReference(unwrapped);
|
|
688
|
+
if (declId) {
|
|
689
|
+
const declInfo = binding
|
|
690
|
+
._getHandleRegistry()
|
|
691
|
+
.getDecl(declId);
|
|
692
|
+
const decl = declInfo?.declNode;
|
|
693
|
+
if (decl &&
|
|
694
|
+
ts.isTypeAliasDeclaration(decl) &&
|
|
695
|
+
ts.isFunctionTypeNode(decl.type)) {
|
|
696
|
+
return decl.type.type
|
|
697
|
+
? convertType(decl.type.type, binding)
|
|
698
|
+
: { kind: "voidType" };
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
// Case 3: typeof function value (ReturnType<typeof fn>)
|
|
703
|
+
//
|
|
704
|
+
// INV-0 COMPLIANT: Resolve the identifier to a declaration via Binding and
|
|
705
|
+
// read the syntactic return type annotation (no ts.Type queries).
|
|
706
|
+
if (ts.isTypeQueryNode(unwrapped) && ts.isIdentifier(unwrapped.exprName)) {
|
|
707
|
+
const declId = binding.resolveIdentifier(unwrapped.exprName);
|
|
708
|
+
if (declId) {
|
|
709
|
+
const declInfo = binding
|
|
710
|
+
._getHandleRegistry()
|
|
711
|
+
.getDecl(declId);
|
|
712
|
+
const decl = declInfo?.declNode;
|
|
713
|
+
if (decl &&
|
|
714
|
+
(ts.isFunctionDeclaration(decl) || ts.isMethodDeclaration(decl))) {
|
|
715
|
+
return decl.type ? convertType(decl.type, binding) : null;
|
|
716
|
+
}
|
|
717
|
+
if (decl && ts.isVariableDeclaration(decl) && decl.type) {
|
|
718
|
+
return expandReturnType(decl.type, binding, convertType);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
return null; // Can't extract return type
|
|
723
|
+
};
|
|
724
|
+
/**
|
|
725
|
+
* Expand Parameters<F> by extracting from function type declaration (INV-0 compliant).
|
|
726
|
+
*/
|
|
727
|
+
const expandParameters = (fArg, binding, convertType) => {
|
|
728
|
+
// Check for type parameter
|
|
729
|
+
if (isTypeParameterNode(fArg, binding)) {
|
|
730
|
+
return null;
|
|
731
|
+
}
|
|
732
|
+
let functionType;
|
|
733
|
+
// Case 1: Direct function type node
|
|
734
|
+
if (ts.isFunctionTypeNode(fArg)) {
|
|
735
|
+
functionType = fArg;
|
|
736
|
+
}
|
|
737
|
+
// Case 2: Type reference to function type alias
|
|
738
|
+
if (!functionType &&
|
|
739
|
+
ts.isTypeReferenceNode(fArg) &&
|
|
740
|
+
ts.isIdentifier(fArg.typeName)) {
|
|
741
|
+
const declId = binding.resolveTypeReference(fArg);
|
|
742
|
+
if (declId) {
|
|
743
|
+
const declInfo = binding
|
|
744
|
+
._getHandleRegistry()
|
|
745
|
+
.getDecl(declId);
|
|
746
|
+
const decl = declInfo?.declNode;
|
|
747
|
+
if (decl &&
|
|
748
|
+
ts.isTypeAliasDeclaration(decl) &&
|
|
749
|
+
ts.isFunctionTypeNode(decl.type)) {
|
|
750
|
+
functionType = decl.type;
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
// Case 3: typeof function value (Parameters<typeof fn>)
|
|
755
|
+
//
|
|
756
|
+
// INV-0 COMPLIANT: Resolve the identifier to a declaration via Binding and
|
|
757
|
+
// read syntactic parameter type annotations (no ts.Type queries).
|
|
758
|
+
if (!functionType && ts.isTypeQueryNode(fArg) && ts.isIdentifier(fArg.exprName)) {
|
|
759
|
+
const declId = binding.resolveIdentifier(fArg.exprName);
|
|
760
|
+
if (declId) {
|
|
761
|
+
const declInfo = binding
|
|
762
|
+
._getHandleRegistry()
|
|
763
|
+
.getDecl(declId);
|
|
764
|
+
const decl = declInfo?.declNode;
|
|
765
|
+
if (decl && (ts.isFunctionDeclaration(decl) || ts.isMethodDeclaration(decl))) {
|
|
766
|
+
const paramTypes = decl.parameters.map((param) => param.type ? convertType(param.type, binding) : { kind: "anyType" });
|
|
767
|
+
return { kind: "tupleType", elementTypes: paramTypes };
|
|
768
|
+
}
|
|
769
|
+
if (decl && ts.isVariableDeclaration(decl) && decl.type) {
|
|
770
|
+
return expandParameters(decl.type, binding, convertType);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
if (!functionType) {
|
|
775
|
+
return null; // Can't extract parameters
|
|
776
|
+
}
|
|
777
|
+
// Build tuple type from parameters
|
|
778
|
+
const paramTypes = functionType.parameters.map((param) => param.type ? convertType(param.type, binding) : { kind: "anyType" });
|
|
779
|
+
return { kind: "tupleType", elementTypes: paramTypes };
|
|
780
|
+
};
|
|
781
|
+
/**
|
|
782
|
+
* Expand Awaited<T> by extracting from Promise type parameter (INV-0 compliant).
|
|
783
|
+
*/
|
|
784
|
+
const expandAwaited = (tArg, binding, convertType) => {
|
|
785
|
+
// Check for type parameter
|
|
786
|
+
if (isTypeParameterNode(tArg, binding)) {
|
|
787
|
+
return null;
|
|
788
|
+
}
|
|
789
|
+
// Handle Promise<T> or PromiseLike<T>
|
|
790
|
+
if (ts.isTypeReferenceNode(tArg) && ts.isIdentifier(tArg.typeName)) {
|
|
791
|
+
const name = tArg.typeName.text;
|
|
792
|
+
if ((name === "Promise" || name === "PromiseLike") && tArg.typeArguments) {
|
|
793
|
+
const innerArg = tArg.typeArguments[0];
|
|
794
|
+
if (innerArg) {
|
|
795
|
+
// Recursively unwrap nested promises
|
|
796
|
+
return (expandAwaited(innerArg, binding, convertType) ??
|
|
797
|
+
convertType(innerArg, binding));
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
// Not a Promise type - return as-is
|
|
802
|
+
return convertType(tArg, binding);
|
|
803
|
+
};
|
|
804
|
+
/**
|
|
805
|
+
* Expand a conditional utility type (NonNullable, Exclude, Extract) to IR.
|
|
806
|
+
*
|
|
807
|
+
* DETERMINISTIC IR TYPING (INV-0 compliant):
|
|
808
|
+
* Uses AST-based syntactic algorithms only. No getTypeAtLocation or typeToTypeNode.
|
|
809
|
+
*
|
|
810
|
+
* @param node - The TypeReferenceNode for the utility type
|
|
811
|
+
* @param typeName - The name of the utility type (NonNullable, Exclude, Extract, etc.)
|
|
812
|
+
* @param binding - The Binding layer for symbol resolution
|
|
813
|
+
* @param convertType - Function to convert nested types
|
|
814
|
+
* @returns IR type with the expanded result, or null if expansion fails
|
|
815
|
+
*/
|
|
816
|
+
export const expandConditionalUtilityType = (node, typeName, binding, convertType) => {
|
|
817
|
+
return expandConditionalUtilityTypeInternal(node, typeName, binding, convertType, 0);
|
|
818
|
+
};
|
|
819
|
+
/**
|
|
820
|
+
* Expand Record<K, T> to IrObjectType when K is a finite set of literal keys.
|
|
821
|
+
*
|
|
822
|
+
* DETERMINISTIC IR TYPING (INV-0 compliant):
|
|
823
|
+
* Uses AST-based analysis only. Extracts literal keys from TypeNode,
|
|
824
|
+
* not from ts.Type.
|
|
825
|
+
*
|
|
826
|
+
* Gating conditions:
|
|
827
|
+
* - Returns null if K contains type parameters (generic context)
|
|
828
|
+
* - Returns null if K is string or number (should remain IrDictionaryType)
|
|
829
|
+
* - Returns null if K contains non-literal types
|
|
830
|
+
*
|
|
831
|
+
* Examples:
|
|
832
|
+
* - Record<"a" | "b", number> → IrObjectType with props {a: number, b: number}
|
|
833
|
+
* - Record<1 | 2, string> → IrObjectType with props {"1": string, "2": string}
|
|
834
|
+
* - Record<string, number> → null (use IrDictionaryType)
|
|
835
|
+
* - Record<K, T> → null (type parameter)
|
|
836
|
+
*
|
|
837
|
+
* @param node - The TypeReferenceNode for Record<K, T>
|
|
838
|
+
* @param binding - The Binding layer for symbol resolution
|
|
839
|
+
* @param convertType - Function to convert nested types
|
|
840
|
+
* @returns IrObjectType with the expanded properties, or null if should use dictionary
|
|
841
|
+
*/
|
|
842
|
+
export const expandRecordType = (node, binding, convertType) => {
|
|
843
|
+
const typeArgs = node.typeArguments;
|
|
844
|
+
if (!typeArgs || typeArgs.length !== 2) {
|
|
845
|
+
return null;
|
|
846
|
+
}
|
|
847
|
+
const keyTypeNode = typeArgs[0];
|
|
848
|
+
const valueTypeNode = typeArgs[1];
|
|
849
|
+
if (!keyTypeNode || !valueTypeNode) {
|
|
850
|
+
return null;
|
|
851
|
+
}
|
|
852
|
+
// Check for type parameters in key (AST-based)
|
|
853
|
+
if (typeNodeContainsTypeParameter(keyTypeNode, binding)) {
|
|
854
|
+
return null;
|
|
855
|
+
}
|
|
856
|
+
// Check for type parameters in value (AST-based)
|
|
857
|
+
if (typeNodeContainsTypeParameter(valueTypeNode, binding)) {
|
|
858
|
+
return null;
|
|
859
|
+
}
|
|
860
|
+
// Try to extract finite literal keys (AST-based)
|
|
861
|
+
const literalKeys = extractLiteralKeysFromTypeNode(keyTypeNode, binding);
|
|
862
|
+
if (literalKeys === null || literalKeys.size === 0) {
|
|
863
|
+
// Not a finite set of literals - use IrDictionaryType
|
|
864
|
+
return null;
|
|
865
|
+
}
|
|
866
|
+
// Convert the value type
|
|
867
|
+
const irValueType = convertType(valueTypeNode, binding);
|
|
868
|
+
// Build IrObjectType with a property for each key
|
|
869
|
+
// Prefix numeric keys with '_' to make them valid C# identifiers
|
|
870
|
+
const members = Array.from(literalKeys).map((key) => ({
|
|
871
|
+
kind: "propertySignature",
|
|
872
|
+
name: /^\d/.test(key) ? `_${key}` : key,
|
|
873
|
+
type: irValueType,
|
|
874
|
+
isOptional: false,
|
|
875
|
+
isReadonly: false,
|
|
876
|
+
}));
|
|
877
|
+
return { kind: "objectType", members };
|
|
878
|
+
};
|
|
879
|
+
//# sourceMappingURL=utility-types.js.map
|