@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
|
@@ -1,421 +1,384 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Call and new expression converters
|
|
3
|
+
*
|
|
4
|
+
* ALICE'S SPEC: All call resolution goes through TypeSystem.resolveCall().
|
|
5
|
+
* NO FALLBACKS ALLOWED. If TypeSystem can't resolve, return unknownType.
|
|
3
6
|
*/
|
|
4
7
|
import * as ts from "typescript";
|
|
5
|
-
import {
|
|
8
|
+
import { getSourceSpan, extractTypeArguments, checkIfRequiresSpecialization, } from "./helpers.js";
|
|
6
9
|
import { convertExpression } from "../../expression-converter.js";
|
|
7
|
-
import { convertType, convertTsTypeToIr } from "../../type-converter.js";
|
|
8
10
|
/**
|
|
9
|
-
* Extract argument passing modes from resolved signature
|
|
10
|
-
* Returns array aligned with arguments, indicating ref/out/in/value for each
|
|
11
|
+
* Extract argument passing modes from resolved signature.
|
|
12
|
+
* Returns array aligned with arguments, indicating ref/out/in/value for each.
|
|
13
|
+
*
|
|
14
|
+
* ALICE'S SPEC: Uses TypeSystem to get parameter modes.
|
|
15
|
+
* Parameter modes were normalized in Binding at registration time.
|
|
11
16
|
*/
|
|
12
|
-
const extractArgumentPassing = (node,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// Extract parameters from declaration
|
|
21
|
-
if (ts.isFunctionDeclaration(decl) ||
|
|
22
|
-
ts.isMethodDeclaration(decl) ||
|
|
23
|
-
ts.isConstructorDeclaration(decl) ||
|
|
24
|
-
ts.isArrowFunction(decl) ||
|
|
25
|
-
ts.isFunctionExpression(decl)) {
|
|
26
|
-
parameters = decl.parameters;
|
|
27
|
-
}
|
|
28
|
-
if (parameters.length === 0) {
|
|
29
|
-
return undefined;
|
|
30
|
-
}
|
|
31
|
-
// Build passing mode for each parameter
|
|
32
|
-
const passingModes = [];
|
|
33
|
-
for (const param of parameters) {
|
|
34
|
-
let passing = "value";
|
|
35
|
-
// Check if parameter type is ref<T>, out<T>, or in<T>
|
|
36
|
-
if (param.type &&
|
|
37
|
-
ts.isTypeReferenceNode(param.type) &&
|
|
38
|
-
ts.isIdentifier(param.type.typeName)) {
|
|
39
|
-
const typeName = param.type.typeName.text;
|
|
40
|
-
if ((typeName === "ref" || typeName === "out" || typeName === "in") &&
|
|
41
|
-
param.type.typeArguments &&
|
|
42
|
-
param.type.typeArguments.length > 0) {
|
|
43
|
-
passing = typeName === "in" ? "in" : typeName;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
passingModes.push(passing);
|
|
47
|
-
}
|
|
48
|
-
return passingModes;
|
|
49
|
-
}
|
|
50
|
-
catch {
|
|
17
|
+
const extractArgumentPassing = (node, ctx) => {
|
|
18
|
+
// Get the TypeSystem
|
|
19
|
+
const typeSystem = ctx.typeSystem;
|
|
20
|
+
// Handle both CallExpression and NewExpression
|
|
21
|
+
const sigId = ts.isCallExpression(node)
|
|
22
|
+
? ctx.binding.resolveCallSignature(node)
|
|
23
|
+
: ctx.binding.resolveConstructorSignature(node);
|
|
24
|
+
if (!sigId)
|
|
51
25
|
return undefined;
|
|
52
|
-
|
|
26
|
+
// Use TypeSystem.resolveCall() to get parameter modes
|
|
27
|
+
const resolved = typeSystem.resolveCall({
|
|
28
|
+
sigId,
|
|
29
|
+
argumentCount: ts.isCallExpression(node)
|
|
30
|
+
? node.arguments.length
|
|
31
|
+
: (node.arguments?.length ?? 0),
|
|
32
|
+
});
|
|
33
|
+
// Return parameter modes from TypeSystem (already normalized in Binding)
|
|
34
|
+
return resolved.parameterModes;
|
|
53
35
|
};
|
|
54
36
|
/**
|
|
55
|
-
*
|
|
37
|
+
* Get the declared return type from a call or new expression's signature.
|
|
38
|
+
*
|
|
39
|
+
* This function extracts the return type from the **signature declaration's TypeNode**,
|
|
40
|
+
* NOT from TypeScript's inferred type. This is critical for preserving CLR type aliases.
|
|
41
|
+
*
|
|
42
|
+
* For generic methods, type parameters are substituted using the receiver's type arguments.
|
|
43
|
+
* For example: `dict.get(key)` where `dict: Dictionary<int, Todo>` returns `Todo | undefined`,
|
|
44
|
+
* not `TValue | undefined`.
|
|
45
|
+
*
|
|
46
|
+
* Returns undefined if:
|
|
47
|
+
* - No signature found
|
|
48
|
+
* - No declaration on signature
|
|
49
|
+
* - No return type annotation on declaration
|
|
56
50
|
*/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
51
|
+
// DELETED: getReturnTypeFromFunctionType - Was part of fallback path
|
|
52
|
+
// DELETED: getCalleesDeclaredType - Was part of fallback path
|
|
53
|
+
// Alice's spec: TypeSystem.resolveCall() is the single source of truth.
|
|
54
|
+
/**
|
|
55
|
+
* Walk a property access chain and build a qualified name.
|
|
56
|
+
* For `Foo.Bar.Baz`, returns "Foo.Bar.Baz" by walking the AST identifiers.
|
|
57
|
+
* This avoids getText() which bakes source formatting into type identity.
|
|
58
|
+
*/
|
|
59
|
+
const buildQualifiedName = (expr) => {
|
|
60
|
+
if (ts.isIdentifier(expr)) {
|
|
61
|
+
return expr.text;
|
|
63
62
|
}
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
if (ts.isPropertyAccessExpression(expr)) {
|
|
64
|
+
const parts = [];
|
|
65
|
+
let current = expr;
|
|
66
|
+
while (ts.isPropertyAccessExpression(current)) {
|
|
67
|
+
parts.unshift(current.name.text);
|
|
68
|
+
current = current.expression;
|
|
69
|
+
}
|
|
70
|
+
if (ts.isIdentifier(current)) {
|
|
71
|
+
parts.unshift(current.text);
|
|
72
|
+
return parts.join(".");
|
|
73
|
+
}
|
|
66
74
|
}
|
|
75
|
+
return undefined;
|
|
67
76
|
};
|
|
77
|
+
// DELETED: getDeclaredReturnTypeFallback - Alice's spec: no fallbacks allowed
|
|
78
|
+
// TypeSystem.resolveCall() is the single source of truth.
|
|
79
|
+
// DELETED: normalizeReceiverToNominal - No longer needed without NominalEnv fallback
|
|
80
|
+
// DELETED: getDeclaredReturnTypeNominalEnvFallback - Alice's spec: no fallbacks allowed
|
|
81
|
+
// TypeSystem.resolveCall() is the single source of truth.
|
|
68
82
|
/**
|
|
69
|
-
*
|
|
70
|
-
*
|
|
83
|
+
* Get the declared return type from a call or new expression's signature.
|
|
84
|
+
*
|
|
85
|
+
* ALICE'S SPEC: Uses TypeSystem.resolveCall() EXCLUSIVELY.
|
|
86
|
+
* NO FALLBACKS. If TypeSystem can't resolve, return unknownType.
|
|
87
|
+
* This ensures any missing TypeSystem functionality surfaces as test failures.
|
|
71
88
|
*/
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
89
|
+
export const getDeclaredReturnType = (node, ctx, receiverIrType) => {
|
|
90
|
+
const DEBUG = process.env.DEBUG_RETURN_TYPE === "1";
|
|
91
|
+
const methodName = ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)
|
|
92
|
+
? node.expression.name.text
|
|
93
|
+
: undefined;
|
|
94
|
+
if (DEBUG && methodName) {
|
|
95
|
+
console.log("[getDeclaredReturnType]", methodName, "receiver:", receiverIrType);
|
|
96
|
+
}
|
|
97
|
+
// Handle new expressions specially - they construct the type from the expression
|
|
98
|
+
if (ts.isNewExpression(node)) {
|
|
99
|
+
// For new expressions with explicit type arguments
|
|
100
|
+
if (node.typeArguments && node.typeArguments.length > 0) {
|
|
101
|
+
const typeName = buildQualifiedName(node.expression);
|
|
102
|
+
if (typeName) {
|
|
103
|
+
// PHASE 4 (Alice's spec): Use captureTypeSyntax + typeFromSyntax
|
|
104
|
+
const typeSystem = ctx.typeSystem;
|
|
85
105
|
return {
|
|
86
|
-
kind: "
|
|
87
|
-
|
|
88
|
-
|
|
106
|
+
kind: "referenceType",
|
|
107
|
+
name: typeName,
|
|
108
|
+
typeArguments: node.typeArguments.map((ta) => typeSystem.typeFromSyntax(ctx.binding.captureTypeSyntax(ta))),
|
|
89
109
|
};
|
|
90
110
|
}
|
|
91
111
|
}
|
|
112
|
+
// For constructors without type arguments, use the class name
|
|
113
|
+
const typeName = buildQualifiedName(node.expression);
|
|
114
|
+
if (typeName) {
|
|
115
|
+
return { kind: "referenceType", name: typeName };
|
|
116
|
+
}
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
// For call expressions, use TypeSystem.resolveCall() EXCLUSIVELY
|
|
120
|
+
const typeSystem = ctx.typeSystem;
|
|
121
|
+
const sigId = ctx.binding.resolveCallSignature(node);
|
|
122
|
+
if (!sigId) {
|
|
123
|
+
if (DEBUG && methodName)
|
|
124
|
+
console.log("[getDeclaredReturnType]", methodName, "No signature resolved");
|
|
92
125
|
return undefined;
|
|
93
126
|
}
|
|
94
|
-
|
|
127
|
+
// Get argument count for totality
|
|
128
|
+
const argumentCount = node.arguments.length;
|
|
129
|
+
// Extract explicit type arguments from call site if any
|
|
130
|
+
// PHASE 4 (Alice's spec): Use captureTypeSyntax + typeFromSyntax
|
|
131
|
+
const explicitTypeArgs = node.typeArguments
|
|
132
|
+
? node.typeArguments.map((ta) => typeSystem.typeFromSyntax(ctx.binding.captureTypeSyntax(ta)))
|
|
133
|
+
: undefined;
|
|
134
|
+
// Use TypeSystem.resolveCall() - guaranteed to return a result
|
|
135
|
+
// NO FALLBACK: If TypeSystem returns unknownType, that's the answer
|
|
136
|
+
const resolved = typeSystem.resolveCall({
|
|
137
|
+
sigId,
|
|
138
|
+
argumentCount,
|
|
139
|
+
receiverType: receiverIrType,
|
|
140
|
+
explicitTypeArgs,
|
|
141
|
+
});
|
|
142
|
+
if (DEBUG && methodName) {
|
|
143
|
+
console.log("[getDeclaredReturnType]", methodName, "TypeSystem returned:", resolved.returnType);
|
|
144
|
+
}
|
|
145
|
+
// Return TypeSystem's answer directly - no fallbacks
|
|
146
|
+
return resolved.returnType;
|
|
147
|
+
};
|
|
148
|
+
const extractArgumentPassingFromParameterModifiers = (modifiers, argCount) => {
|
|
149
|
+
if (modifiers.length === 0)
|
|
95
150
|
return undefined;
|
|
151
|
+
const passing = Array(argCount).fill("value");
|
|
152
|
+
for (const mod of modifiers) {
|
|
153
|
+
if (mod.index >= 0 && mod.index < argCount) {
|
|
154
|
+
passing[mod.index] = mod.modifier;
|
|
155
|
+
}
|
|
96
156
|
}
|
|
157
|
+
return passing;
|
|
97
158
|
};
|
|
98
159
|
/**
|
|
99
|
-
*
|
|
160
|
+
* Extract argument passing modes from CLR bindings for the *selected overload*.
|
|
100
161
|
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
162
|
+
* CRITICAL: Methods can be overloaded, and overloads can differ in ref/out/in modifiers.
|
|
163
|
+
* We must not attach a single overload's modifiers to the member access itself.
|
|
103
164
|
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* TypeScript's type instantiation mechanism loses aliasSymbol, but TypeNodes don't.
|
|
165
|
+
* This resolver selects the best-matching binding overload using the call's argument
|
|
166
|
+
* types, then applies that overload's parameterModifiers.
|
|
107
167
|
*/
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
168
|
+
const extractArgumentPassingFromBinding = (callee, argCount, ctx, parameterTypes, argTypes) => {
|
|
169
|
+
if (callee.kind !== "memberAccess" || !callee.memberBinding)
|
|
170
|
+
return undefined;
|
|
171
|
+
// Fast path: already-resolved modifiers (extension methods or non-overloaded members).
|
|
172
|
+
const directMods = callee.memberBinding.parameterModifiers;
|
|
173
|
+
if (directMods && directMods.length > 0) {
|
|
174
|
+
return extractArgumentPassingFromParameterModifiers(directMods, argCount);
|
|
175
|
+
}
|
|
176
|
+
// No member binding → no CLR parameter modifiers.
|
|
177
|
+
const binding = callee.memberBinding;
|
|
178
|
+
const overloadsAll = ctx.bindings.getClrMemberOverloads(binding.assembly, binding.type, binding.member);
|
|
179
|
+
if (!overloadsAll || overloadsAll.length === 0)
|
|
180
|
+
return undefined;
|
|
181
|
+
const calledName = typeof callee.property === "string" ? callee.property : undefined;
|
|
182
|
+
const overloads = calledName
|
|
183
|
+
? overloadsAll.filter((m) => m.alias === calledName || m.name === calledName)
|
|
184
|
+
: overloadsAll;
|
|
185
|
+
if (overloads.length === 0)
|
|
186
|
+
return undefined;
|
|
187
|
+
const matchTypes = parameterTypes ?? argTypes;
|
|
188
|
+
const hasMatchTypes = matchTypes && matchTypes.some((t) => t !== undefined);
|
|
189
|
+
const splitSignatureTypeList = (str) => {
|
|
190
|
+
const result = [];
|
|
191
|
+
let depth = 0;
|
|
192
|
+
let current = "";
|
|
193
|
+
for (const char of str) {
|
|
194
|
+
if (char === "[") {
|
|
195
|
+
depth++;
|
|
196
|
+
current += char;
|
|
130
197
|
}
|
|
131
|
-
if (
|
|
132
|
-
|
|
133
|
-
|
|
198
|
+
else if (char === "]") {
|
|
199
|
+
depth--;
|
|
200
|
+
current += char;
|
|
134
201
|
}
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
202
|
+
else if (char === "," && depth === 0) {
|
|
203
|
+
result.push(current.trim());
|
|
204
|
+
current = "";
|
|
138
205
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
return undefined;
|
|
142
|
-
// Get the type arguments from the receiver's type
|
|
143
|
-
// IMPORTANT: We must trace back to the ORIGINAL source code AST to preserve
|
|
144
|
-
// CLR type aliases like `int`. TypeScript's typeToTypeNode() does NOT preserve
|
|
145
|
-
// type aliases - it synthesizes primitive keywords like NumberKeyword instead.
|
|
146
|
-
//
|
|
147
|
-
// Look for the variable declaration that has type arguments in:
|
|
148
|
-
// 1. Explicit type annotation: const dict: Dictionary<int, Todo> = ...
|
|
149
|
-
// 2. NewExpression initializer: const dict = new Dictionary<int, Todo>()
|
|
150
|
-
// 3. Other declaration forms (property, parameter)
|
|
151
|
-
const receiverSymbol = checker.getSymbolAtLocation(receiver);
|
|
152
|
-
if (receiverSymbol) {
|
|
153
|
-
const receiverDecls = receiverSymbol.getDeclarations();
|
|
154
|
-
if (receiverDecls) {
|
|
155
|
-
for (const decl of receiverDecls) {
|
|
156
|
-
// Helper to build substitution map from type argument nodes
|
|
157
|
-
const buildMapFromTypeArgs = (typeArgNodes) => {
|
|
158
|
-
if (typeParamDecls &&
|
|
159
|
-
typeArgNodes.length === typeParamDecls.length) {
|
|
160
|
-
const substitutionMap = new Map();
|
|
161
|
-
for (let i = 0; i < typeParamDecls.length; i++) {
|
|
162
|
-
const paramDecl = typeParamDecls[i];
|
|
163
|
-
const argNode = typeArgNodes[i];
|
|
164
|
-
if (paramDecl && argNode) {
|
|
165
|
-
substitutionMap.set(paramDecl.name.text, argNode);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return substitutionMap;
|
|
169
|
-
}
|
|
170
|
-
return undefined;
|
|
171
|
-
};
|
|
172
|
-
// Check explicit type annotation first
|
|
173
|
-
if (ts.isVariableDeclaration(decl) && decl.type) {
|
|
174
|
-
if (ts.isTypeReferenceNode(decl.type) && decl.type.typeArguments) {
|
|
175
|
-
const result = buildMapFromTypeArgs(decl.type.typeArguments);
|
|
176
|
-
if (result)
|
|
177
|
-
return result;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
// Check initializer: new Dictionary<int, Todo>()
|
|
181
|
-
// This handles: const todos = new Dictionary<int, Todo>();
|
|
182
|
-
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
183
|
-
// Handle direct NewExpression
|
|
184
|
-
if (ts.isNewExpression(decl.initializer) &&
|
|
185
|
-
decl.initializer.typeArguments) {
|
|
186
|
-
const result = buildMapFromTypeArgs(decl.initializer.typeArguments);
|
|
187
|
-
if (result)
|
|
188
|
-
return result;
|
|
189
|
-
}
|
|
190
|
-
// Handle AsExpression (type assertion): new List<int>() as List<int>
|
|
191
|
-
// The type arguments are in the AsExpression's type, not the NewExpression
|
|
192
|
-
if (ts.isAsExpression(decl.initializer)) {
|
|
193
|
-
const asType = decl.initializer.type;
|
|
194
|
-
if (ts.isTypeReferenceNode(asType) && asType.typeArguments) {
|
|
195
|
-
const result = buildMapFromTypeArgs(asType.typeArguments);
|
|
196
|
-
if (result)
|
|
197
|
-
return result;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
// Also check property declarations with type annotation
|
|
202
|
-
if (ts.isPropertyDeclaration(decl) &&
|
|
203
|
-
decl.type &&
|
|
204
|
-
ts.isTypeReferenceNode(decl.type) &&
|
|
205
|
-
decl.type.typeArguments) {
|
|
206
|
-
const result = buildMapFromTypeArgs(decl.type.typeArguments);
|
|
207
|
-
if (result)
|
|
208
|
-
return result;
|
|
209
|
-
}
|
|
210
|
-
// Check property declaration initializer
|
|
211
|
-
if (ts.isPropertyDeclaration(decl) && decl.initializer) {
|
|
212
|
-
if (ts.isNewExpression(decl.initializer) &&
|
|
213
|
-
decl.initializer.typeArguments) {
|
|
214
|
-
const result = buildMapFromTypeArgs(decl.initializer.typeArguments);
|
|
215
|
-
if (result)
|
|
216
|
-
return result;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
// Check parameter declarations
|
|
220
|
-
if (ts.isParameter(decl) &&
|
|
221
|
-
decl.type &&
|
|
222
|
-
ts.isTypeReferenceNode(decl.type) &&
|
|
223
|
-
decl.type.typeArguments) {
|
|
224
|
-
const result = buildMapFromTypeArgs(decl.type.typeArguments);
|
|
225
|
-
if (result)
|
|
226
|
-
return result;
|
|
227
|
-
}
|
|
228
|
-
}
|
|
206
|
+
else {
|
|
207
|
+
current += char;
|
|
229
208
|
}
|
|
230
209
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
*
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
210
|
+
if (current.trim())
|
|
211
|
+
result.push(current.trim());
|
|
212
|
+
return result;
|
|
213
|
+
};
|
|
214
|
+
const parseParameterTypes = (sig) => {
|
|
215
|
+
if (!sig)
|
|
216
|
+
return [];
|
|
217
|
+
const paramsMatch = sig.match(/\|\(([^)]*)\):/);
|
|
218
|
+
const paramsStr = paramsMatch?.[1]?.trim();
|
|
219
|
+
if (!paramsStr)
|
|
220
|
+
return [];
|
|
221
|
+
return splitSignatureTypeList(paramsStr).map((s) => s.trim());
|
|
222
|
+
};
|
|
223
|
+
const extractSimpleClrName = (typeName) => {
|
|
224
|
+
let t = typeName.trim();
|
|
225
|
+
if (t.endsWith("&"))
|
|
226
|
+
t = t.slice(0, -1);
|
|
227
|
+
if (t.endsWith("[]"))
|
|
228
|
+
t = t.slice(0, -2);
|
|
229
|
+
const bracket = t.indexOf("[");
|
|
230
|
+
if (bracket >= 0)
|
|
231
|
+
t = t.slice(0, bracket);
|
|
232
|
+
const lastDot = t.lastIndexOf(".");
|
|
233
|
+
if (lastDot >= 0)
|
|
234
|
+
t = t.slice(lastDot + 1);
|
|
235
|
+
return t;
|
|
236
|
+
};
|
|
237
|
+
const primitiveToClrSimpleName = (name) => {
|
|
238
|
+
switch (name) {
|
|
239
|
+
case "string":
|
|
240
|
+
return "String";
|
|
241
|
+
case "boolean":
|
|
242
|
+
case "bool":
|
|
243
|
+
return "Boolean";
|
|
244
|
+
case "char":
|
|
245
|
+
return "Char";
|
|
246
|
+
case "byte":
|
|
247
|
+
return "Byte";
|
|
248
|
+
case "sbyte":
|
|
249
|
+
return "SByte";
|
|
250
|
+
case "short":
|
|
251
|
+
return "Int16";
|
|
252
|
+
case "ushort":
|
|
253
|
+
return "UInt16";
|
|
254
|
+
case "int":
|
|
255
|
+
return "Int32";
|
|
256
|
+
case "uint":
|
|
257
|
+
return "UInt32";
|
|
258
|
+
case "long":
|
|
259
|
+
return "Int64";
|
|
260
|
+
case "ulong":
|
|
261
|
+
return "UInt64";
|
|
262
|
+
case "float":
|
|
263
|
+
return "Single";
|
|
264
|
+
case "double":
|
|
265
|
+
return "Double";
|
|
266
|
+
case "decimal":
|
|
267
|
+
return "Decimal";
|
|
268
|
+
default:
|
|
269
|
+
return undefined;
|
|
251
270
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
if (substituted) {
|
|
259
|
-
newTypeArgs.push(substituted);
|
|
260
|
-
anySubstituted = true;
|
|
261
|
-
}
|
|
262
|
-
else {
|
|
263
|
-
newTypeArgs.push(arg);
|
|
264
|
-
}
|
|
271
|
+
};
|
|
272
|
+
const collectMatchNames = (t) => {
|
|
273
|
+
switch (t.kind) {
|
|
274
|
+
case "primitiveType": {
|
|
275
|
+
const mapped = primitiveToClrSimpleName(t.name);
|
|
276
|
+
return mapped ? [mapped] : [];
|
|
265
277
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
return
|
|
278
|
+
case "referenceType": {
|
|
279
|
+
const lastDot = t.name.lastIndexOf(".");
|
|
280
|
+
const simple = lastDot >= 0 ? t.name.slice(lastDot + 1) : t.name;
|
|
281
|
+
return [simple.replace(/\$instance$/, "").replace(/^\_\_/, "").replace(/\$views$/, "")];
|
|
270
282
|
}
|
|
283
|
+
case "unionType":
|
|
284
|
+
return Array.from(new Set(t.types.flatMap((x) => collectMatchNames(x))));
|
|
285
|
+
case "intersectionType":
|
|
286
|
+
return Array.from(new Set(t.types.flatMap((x) => collectMatchNames(x))));
|
|
287
|
+
default:
|
|
288
|
+
return [];
|
|
271
289
|
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
290
|
+
};
|
|
291
|
+
const modifiersKey = (m) => {
|
|
292
|
+
const mods = m.parameterModifiers ?? [];
|
|
293
|
+
if (mods.length === 0)
|
|
294
|
+
return "";
|
|
295
|
+
return [...mods]
|
|
296
|
+
.slice()
|
|
297
|
+
.sort((a, b) => a.index - b.index)
|
|
298
|
+
.map((mod) => `${mod.index}:${mod.modifier}`)
|
|
299
|
+
.join(",");
|
|
300
|
+
};
|
|
301
|
+
const scoreCandidate = (m) => {
|
|
302
|
+
if (!hasMatchTypes)
|
|
303
|
+
return 0;
|
|
304
|
+
const paramTypes = parseParameterTypes(m.signature);
|
|
305
|
+
let score = 0;
|
|
306
|
+
for (let i = 0; i < argCount; i++) {
|
|
307
|
+
const expected = matchTypes?.[i];
|
|
308
|
+
if (!expected)
|
|
309
|
+
continue;
|
|
310
|
+
const expectedNames = collectMatchNames(expected);
|
|
311
|
+
if (expectedNames.length === 0)
|
|
312
|
+
continue;
|
|
313
|
+
const paramType = paramTypes[i];
|
|
314
|
+
if (!paramType)
|
|
315
|
+
continue;
|
|
316
|
+
const paramName = extractSimpleClrName(paramType);
|
|
317
|
+
if (expectedNames.includes(paramName)) {
|
|
318
|
+
score += 10;
|
|
289
319
|
}
|
|
290
320
|
else {
|
|
291
|
-
|
|
321
|
+
score -= 3;
|
|
292
322
|
}
|
|
293
323
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
*
|
|
312
|
-
* The key insight is that TypeScript's type instantiation mechanism loses
|
|
313
|
-
* aliasSymbol, but the original TypeNodes in variable declarations preserve
|
|
314
|
-
* the type aliases. We trace back to those TypeNodes and substitute.
|
|
315
|
-
*/
|
|
316
|
-
const extractParameterTypes = (node, checker) => {
|
|
317
|
-
try {
|
|
318
|
-
const signature = checker.getResolvedSignature(node);
|
|
319
|
-
if (!signature) {
|
|
320
|
-
return undefined;
|
|
321
|
-
}
|
|
322
|
-
const sigParams = signature.getParameters();
|
|
323
|
-
if (sigParams.length === 0) {
|
|
324
|
-
return undefined;
|
|
324
|
+
return score;
|
|
325
|
+
};
|
|
326
|
+
// Discard candidates that can't accept the provided arguments (best-effort, arity only).
|
|
327
|
+
const candidates = overloads.filter((m) => {
|
|
328
|
+
if (typeof m.parameterCount !== "number")
|
|
329
|
+
return true;
|
|
330
|
+
return m.parameterCount >= argCount;
|
|
331
|
+
});
|
|
332
|
+
if (candidates.length === 0)
|
|
333
|
+
return undefined;
|
|
334
|
+
let bestScore = Number.NEGATIVE_INFINITY;
|
|
335
|
+
let best = [];
|
|
336
|
+
for (const c of candidates) {
|
|
337
|
+
const score = scoreCandidate(c);
|
|
338
|
+
if (score > bestScore) {
|
|
339
|
+
bestScore = score;
|
|
340
|
+
best = [c];
|
|
325
341
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
const substitutionMap = buildTypeParameterSubstitutionMap(node, checker);
|
|
329
|
-
// Build parameter type array using instantiated types from signature
|
|
330
|
-
const paramTypes = [];
|
|
331
|
-
for (const sigParam of sigParams) {
|
|
332
|
-
const decl = sigParam.valueDeclaration;
|
|
333
|
-
// Get the declaration's type node if available
|
|
334
|
-
if (decl && ts.isParameter(decl) && decl.type) {
|
|
335
|
-
// Check if the declaration type is a type parameter
|
|
336
|
-
const declType = checker.getTypeAtLocation(decl.type);
|
|
337
|
-
const isTypeParameter = Boolean(declType.flags & ts.TypeFlags.TypeParameter);
|
|
338
|
-
if (isTypeParameter) {
|
|
339
|
-
if (substitutionMap) {
|
|
340
|
-
// Type parameter case: use substitution map to preserve CLR aliases
|
|
341
|
-
const substituted = substituteTypeNode(decl.type, substitutionMap, checker);
|
|
342
|
-
if (substituted) {
|
|
343
|
-
const irType = convertType(substituted, checker);
|
|
344
|
-
if (irType) {
|
|
345
|
-
paramTypes.push(irType);
|
|
346
|
-
continue;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
// Type parameter without substitution (e.g., generic function call with inferred types)
|
|
351
|
-
// The type parameter is INFERRED from the argument, so don't validate against
|
|
352
|
-
// TypeScript's instantiated type (which loses CLR type aliases like `int`).
|
|
353
|
-
// Push undefined to skip validation for this parameter.
|
|
354
|
-
paramTypes.push(undefined);
|
|
355
|
-
continue;
|
|
356
|
-
}
|
|
357
|
-
else {
|
|
358
|
-
// Non-type-parameter: use declaration type node directly
|
|
359
|
-
// This preserves imported CLR type aliases like `int`
|
|
360
|
-
const irType = convertType(decl.type, checker);
|
|
361
|
-
if (irType) {
|
|
362
|
-
paramTypes.push(irType);
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
// Fallback: Use instantiated type from getTypeOfSymbolAtLocation
|
|
368
|
-
// This handles cases where we couldn't get the declaration type
|
|
369
|
-
const paramType = checker.getTypeOfSymbolAtLocation(sigParam, decl ?? node);
|
|
370
|
-
const irType = convertTsTypeToIr(paramType, checker);
|
|
371
|
-
paramTypes.push(irType);
|
|
342
|
+
else if (score === bestScore) {
|
|
343
|
+
best.push(c);
|
|
372
344
|
}
|
|
373
|
-
return paramTypes;
|
|
374
345
|
}
|
|
375
|
-
|
|
346
|
+
if (best.length === 0)
|
|
376
347
|
return undefined;
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
* Extract argument passing modes from member binding's parameter modifiers.
|
|
381
|
-
* Converts parameterModifiers to the argumentPassing array format.
|
|
382
|
-
* Returns undefined if no modifiers are present.
|
|
383
|
-
*/
|
|
384
|
-
const extractArgumentPassingFromBinding = (callee, argCount) => {
|
|
385
|
-
// Check if callee is a member access with parameter modifiers
|
|
386
|
-
if (callee.kind !== "memberAccess" ||
|
|
387
|
-
!callee.memberBinding?.parameterModifiers) {
|
|
348
|
+
// If ambiguous, only accept when all best candidates agree on modifiers.
|
|
349
|
+
const first = best[0];
|
|
350
|
+
if (!first)
|
|
388
351
|
return undefined;
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
if (modifiers.length === 0) {
|
|
352
|
+
const key = modifiersKey(first);
|
|
353
|
+
if (best.some((m) => modifiersKey(m) !== key)) {
|
|
392
354
|
return undefined;
|
|
393
355
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
if (mod.index >= 0 && mod.index < argCount) {
|
|
399
|
-
passing[mod.index] = mod.modifier;
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
return passing;
|
|
356
|
+
const chosenMods = first.parameterModifiers;
|
|
357
|
+
if (!chosenMods || chosenMods.length === 0)
|
|
358
|
+
return undefined;
|
|
359
|
+
return extractArgumentPassingFromParameterModifiers(chosenMods, argCount);
|
|
403
360
|
};
|
|
404
361
|
/**
|
|
405
362
|
* Convert call expression
|
|
406
363
|
*/
|
|
407
|
-
export const convertCallExpression = (node,
|
|
408
|
-
// Check for
|
|
409
|
-
//
|
|
364
|
+
export const convertCallExpression = (node, ctx) => {
|
|
365
|
+
// Check for trycast<T>(x) - special intrinsic for safe casting
|
|
366
|
+
// trycast<T>(x) compiles to C#: x as T (safe cast, returns null on failure)
|
|
410
367
|
if (ts.isIdentifier(node.expression) &&
|
|
411
|
-
node.expression.text === "
|
|
368
|
+
node.expression.text === "trycast" &&
|
|
412
369
|
node.typeArguments &&
|
|
413
370
|
node.typeArguments.length === 1 &&
|
|
414
371
|
node.arguments.length === 1) {
|
|
415
372
|
// We've verified length === 1 above, so these are guaranteed to exist
|
|
416
373
|
const targetTypeNode = node.typeArguments[0];
|
|
417
|
-
const
|
|
418
|
-
|
|
374
|
+
const argNode = node.arguments[0];
|
|
375
|
+
if (!targetTypeNode || !argNode) {
|
|
376
|
+
throw new Error("ICE: trycast requires exactly 1 type argument and 1 argument");
|
|
377
|
+
}
|
|
378
|
+
// PHASE 4 (Alice's spec): Use captureTypeSyntax + typeFromSyntax
|
|
379
|
+
const typeSystem = ctx.typeSystem;
|
|
380
|
+
const targetType = typeSystem.typeFromSyntax(ctx.binding.captureTypeSyntax(targetTypeNode));
|
|
381
|
+
const argExpr = convertExpression(argNode, ctx, undefined);
|
|
419
382
|
// Build union type T | null for inferredType
|
|
420
383
|
const nullType = { kind: "primitiveType", name: "null" };
|
|
421
384
|
const unionType = {
|
|
@@ -423,39 +386,238 @@ export const convertCallExpression = (node, checker) => {
|
|
|
423
386
|
types: [targetType, nullType],
|
|
424
387
|
};
|
|
425
388
|
return {
|
|
426
|
-
kind: "
|
|
389
|
+
kind: "trycast",
|
|
427
390
|
expression: argExpr,
|
|
428
391
|
targetType,
|
|
429
392
|
inferredType: unionType,
|
|
430
393
|
sourceSpan: getSourceSpan(node),
|
|
431
394
|
};
|
|
432
395
|
}
|
|
396
|
+
// Check for stackalloc<T>(size) - language intrinsic for stack allocation.
|
|
397
|
+
// stackalloc<T>(size) compiles to C#: stackalloc T[size]
|
|
398
|
+
if (ts.isIdentifier(node.expression) &&
|
|
399
|
+
node.expression.text === "stackalloc" &&
|
|
400
|
+
node.typeArguments &&
|
|
401
|
+
node.typeArguments.length === 1 &&
|
|
402
|
+
node.arguments.length === 1) {
|
|
403
|
+
const elementTypeNode = node.typeArguments[0];
|
|
404
|
+
const sizeNode = node.arguments[0];
|
|
405
|
+
if (!elementTypeNode || !sizeNode) {
|
|
406
|
+
throw new Error("ICE: stackalloc requires exactly 1 type argument and 1 argument");
|
|
407
|
+
}
|
|
408
|
+
const typeSystem = ctx.typeSystem;
|
|
409
|
+
const elementType = typeSystem.typeFromSyntax(ctx.binding.captureTypeSyntax(elementTypeNode));
|
|
410
|
+
const sizeExpr = convertExpression(sizeNode, ctx, {
|
|
411
|
+
kind: "primitiveType",
|
|
412
|
+
name: "int",
|
|
413
|
+
});
|
|
414
|
+
return {
|
|
415
|
+
kind: "stackalloc",
|
|
416
|
+
elementType,
|
|
417
|
+
size: sizeExpr,
|
|
418
|
+
inferredType: {
|
|
419
|
+
kind: "referenceType",
|
|
420
|
+
name: "Span",
|
|
421
|
+
typeArguments: [elementType],
|
|
422
|
+
},
|
|
423
|
+
sourceSpan: getSourceSpan(node),
|
|
424
|
+
};
|
|
425
|
+
}
|
|
433
426
|
// Extract type arguments from the call signature
|
|
434
|
-
const typeArguments = extractTypeArguments(node,
|
|
435
|
-
const requiresSpecialization = checkIfRequiresSpecialization(node,
|
|
436
|
-
|
|
437
|
-
const
|
|
438
|
-
//
|
|
439
|
-
const
|
|
440
|
-
//
|
|
441
|
-
//
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
427
|
+
const typeArguments = extractTypeArguments(node, ctx);
|
|
428
|
+
const requiresSpecialization = checkIfRequiresSpecialization(node, ctx);
|
|
429
|
+
// Convert callee first so we can access memberBinding and receiver type
|
|
430
|
+
const callee = convertExpression(node.expression, ctx, undefined);
|
|
431
|
+
// Extract receiver type for member method calls (e.g., dict.get() → dict's type)
|
|
432
|
+
const receiverIrType = callee.kind === "memberAccess" ? callee.object.inferredType : undefined;
|
|
433
|
+
// Resolve call (two-pass):
|
|
434
|
+
// 1) Resolve parameter types (for expectedType threading)
|
|
435
|
+
// 2) Convert arguments, then re-resolve with argTypes to infer generics deterministically
|
|
436
|
+
const typeSystem = ctx.typeSystem;
|
|
437
|
+
const sigId = ctx.binding.resolveCallSignature(node);
|
|
438
|
+
const argumentCount = node.arguments.length;
|
|
439
|
+
const explicitTypeArgs = node.typeArguments
|
|
440
|
+
? node.typeArguments.map((ta) => typeSystem.typeFromSyntax(ctx.binding.captureTypeSyntax(ta)))
|
|
441
|
+
: undefined;
|
|
442
|
+
// If we can't resolve a signature handle (common for calls through function-typed
|
|
443
|
+
// variables), fall back to the callee's inferred function type.
|
|
444
|
+
const calleeFunctionType = (() => {
|
|
445
|
+
const t = callee.inferredType;
|
|
446
|
+
if (!t)
|
|
447
|
+
return undefined;
|
|
448
|
+
if (t.kind === "functionType")
|
|
449
|
+
return t;
|
|
450
|
+
return typeSystem.delegateToFunctionType(t) ?? undefined;
|
|
451
|
+
})();
|
|
452
|
+
if (!sigId && calleeFunctionType) {
|
|
453
|
+
const params = calleeFunctionType.parameters;
|
|
454
|
+
const paramTypesForArgs = [];
|
|
455
|
+
const hasRest = params.some((p) => p.isRest);
|
|
456
|
+
for (let i = 0; i < node.arguments.length; i++) {
|
|
457
|
+
const p = params[i] ?? (hasRest ? params[params.length - 1] : undefined);
|
|
458
|
+
paramTypesForArgs[i] = p?.type;
|
|
459
|
+
}
|
|
460
|
+
const args = [];
|
|
461
|
+
for (let i = 0; i < node.arguments.length; i++) {
|
|
462
|
+
const arg = node.arguments[i];
|
|
463
|
+
if (!arg)
|
|
464
|
+
continue;
|
|
465
|
+
const expectedType = paramTypesForArgs[i];
|
|
448
466
|
if (ts.isSpreadElement(arg)) {
|
|
449
|
-
|
|
467
|
+
const spreadExpr = convertExpression(arg.expression, ctx, undefined);
|
|
468
|
+
args.push({
|
|
450
469
|
kind: "spread",
|
|
451
|
-
expression:
|
|
470
|
+
expression: spreadExpr,
|
|
471
|
+
inferredType: spreadExpr.inferredType,
|
|
452
472
|
sourceSpan: getSourceSpan(arg),
|
|
453
|
-
};
|
|
473
|
+
});
|
|
474
|
+
continue;
|
|
454
475
|
}
|
|
455
|
-
|
|
456
|
-
}
|
|
476
|
+
args.push(convertExpression(arg, ctx, expectedType));
|
|
477
|
+
}
|
|
478
|
+
return {
|
|
479
|
+
kind: "call",
|
|
480
|
+
callee,
|
|
481
|
+
arguments: args,
|
|
482
|
+
isOptional: node.questionDotToken !== undefined,
|
|
483
|
+
inferredType: calleeFunctionType.returnType,
|
|
484
|
+
sourceSpan: getSourceSpan(node),
|
|
485
|
+
typeArguments,
|
|
486
|
+
requiresSpecialization,
|
|
487
|
+
argumentPassing: extractArgumentPassing(node, ctx),
|
|
488
|
+
parameterTypes: paramTypesForArgs,
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
const initialResolved = sigId
|
|
492
|
+
? typeSystem.resolveCall({
|
|
493
|
+
sigId,
|
|
494
|
+
argumentCount,
|
|
495
|
+
receiverType: receiverIrType,
|
|
496
|
+
explicitTypeArgs,
|
|
497
|
+
})
|
|
498
|
+
: undefined;
|
|
499
|
+
const initialParameterTypes = initialResolved?.parameterTypes;
|
|
500
|
+
const isLambdaArg = (expr) => {
|
|
501
|
+
if (ts.isArrowFunction(expr) || ts.isFunctionExpression(expr))
|
|
502
|
+
return true;
|
|
503
|
+
if (ts.isParenthesizedExpression(expr))
|
|
504
|
+
return isLambdaArg(expr.expression);
|
|
505
|
+
return false;
|
|
506
|
+
};
|
|
507
|
+
const isExplicitlyTypedLambdaArg = (expr) => {
|
|
508
|
+
if (ts.isParenthesizedExpression(expr)) {
|
|
509
|
+
return isExplicitlyTypedLambdaArg(expr.expression);
|
|
510
|
+
}
|
|
511
|
+
if (!ts.isArrowFunction(expr) && !ts.isFunctionExpression(expr)) {
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
if (expr.type)
|
|
515
|
+
return true;
|
|
516
|
+
if (expr.typeParameters && expr.typeParameters.length > 0)
|
|
517
|
+
return true;
|
|
518
|
+
return expr.parameters.some((p) => p.type !== undefined);
|
|
519
|
+
};
|
|
520
|
+
const shouldDeferLambdaForInference = (expr) => isLambdaArg(expr) && !isExplicitlyTypedLambdaArg(expr);
|
|
521
|
+
// Pass 1: convert non-lambda arguments and infer type args from them.
|
|
522
|
+
const argsWorking = new Array(node.arguments.length);
|
|
523
|
+
const argTypesForInference = Array(node.arguments.length).fill(undefined);
|
|
524
|
+
for (let index = 0; index < node.arguments.length; index++) {
|
|
525
|
+
const arg = node.arguments[index];
|
|
526
|
+
if (!arg)
|
|
527
|
+
continue;
|
|
528
|
+
const expectedType = initialParameterTypes?.[index];
|
|
529
|
+
if (ts.isSpreadElement(arg)) {
|
|
530
|
+
const spreadExpr = convertExpression(arg.expression, ctx, undefined);
|
|
531
|
+
argsWorking[index] = {
|
|
532
|
+
kind: "spread",
|
|
533
|
+
expression: spreadExpr,
|
|
534
|
+
inferredType: spreadExpr.inferredType,
|
|
535
|
+
sourceSpan: getSourceSpan(arg),
|
|
536
|
+
};
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
if (shouldDeferLambdaForInference(arg)) {
|
|
540
|
+
// Defer *untyped* lambda conversion until after we infer generic type args
|
|
541
|
+
// from other arguments. Explicitly typed lambdas are safe to convert early
|
|
542
|
+
// and often provide the only deterministic inference signal.
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
const converted = convertExpression(arg, ctx, expectedType);
|
|
546
|
+
argsWorking[index] = converted;
|
|
547
|
+
argTypesForInference[index] = converted.inferredType;
|
|
548
|
+
}
|
|
549
|
+
const lambdaContextResolved = sigId
|
|
550
|
+
? typeSystem.resolveCall({
|
|
551
|
+
sigId,
|
|
552
|
+
argumentCount,
|
|
553
|
+
receiverType: receiverIrType,
|
|
554
|
+
explicitTypeArgs,
|
|
555
|
+
argTypes: argTypesForInference,
|
|
556
|
+
})
|
|
557
|
+
: initialResolved;
|
|
558
|
+
const parameterTypesForLambdaContext = lambdaContextResolved?.parameterTypes ?? initialParameterTypes;
|
|
559
|
+
// Pass 2: convert lambda arguments with inferred parameter types in scope.
|
|
560
|
+
for (let index = 0; index < node.arguments.length; index++) {
|
|
561
|
+
if (argsWorking[index])
|
|
562
|
+
continue;
|
|
563
|
+
const arg = node.arguments[index];
|
|
564
|
+
if (!arg)
|
|
565
|
+
continue;
|
|
566
|
+
if (ts.isSpreadElement(arg))
|
|
567
|
+
continue;
|
|
568
|
+
if (!isLambdaArg(arg))
|
|
569
|
+
continue;
|
|
570
|
+
const expectedType = parameterTypesForLambdaContext?.[index];
|
|
571
|
+
const lambdaExpectedType = expectedType?.kind === "functionType"
|
|
572
|
+
? expectedType
|
|
573
|
+
: expectedType
|
|
574
|
+
? typeSystem.delegateToFunctionType(expectedType) ?? expectedType
|
|
575
|
+
: undefined;
|
|
576
|
+
argsWorking[index] = convertExpression(arg, ctx, lambdaExpectedType);
|
|
577
|
+
}
|
|
578
|
+
const convertedArgs = argsWorking.map((a) => {
|
|
579
|
+
if (!a) {
|
|
580
|
+
throw new Error("ICE: call argument conversion produced a hole");
|
|
581
|
+
}
|
|
582
|
+
return a;
|
|
583
|
+
});
|
|
584
|
+
const argTypes = convertedArgs.map((a) => a.kind === "spread" ? undefined : a.inferredType);
|
|
585
|
+
const finalResolved = sigId
|
|
586
|
+
? typeSystem.resolveCall({
|
|
587
|
+
sigId,
|
|
588
|
+
argumentCount,
|
|
589
|
+
receiverType: receiverIrType,
|
|
590
|
+
explicitTypeArgs,
|
|
591
|
+
argTypes,
|
|
592
|
+
})
|
|
593
|
+
: lambdaContextResolved;
|
|
594
|
+
const parameterTypes = finalResolved?.parameterTypes ?? initialParameterTypes;
|
|
595
|
+
const inferredType = finalResolved?.returnType ?? { kind: "unknownType" };
|
|
596
|
+
const argumentPassingFromBinding = extractArgumentPassingFromBinding(callee, node.arguments.length, ctx, parameterTypes, argTypes);
|
|
597
|
+
const argumentPassing = argumentPassingFromBinding ??
|
|
598
|
+
(finalResolved
|
|
599
|
+
? finalResolved.parameterModes.slice(0, node.arguments.length)
|
|
600
|
+
: extractArgumentPassing(node, ctx));
|
|
601
|
+
const narrowing = (() => {
|
|
602
|
+
const pred = finalResolved?.typePredicate;
|
|
603
|
+
if (!pred)
|
|
604
|
+
return undefined;
|
|
605
|
+
if (pred.kind !== "param")
|
|
606
|
+
return undefined;
|
|
607
|
+
return {
|
|
608
|
+
kind: "typePredicate",
|
|
609
|
+
argIndex: pred.parameterIndex,
|
|
610
|
+
targetType: pred.targetType,
|
|
611
|
+
};
|
|
612
|
+
})();
|
|
613
|
+
return {
|
|
614
|
+
kind: "call",
|
|
615
|
+
callee,
|
|
616
|
+
// Pass parameter types as expectedType for deterministic contextual typing
|
|
617
|
+
// This ensures `spreadArray([1,2,3], [4,5,6])` with `number[]` params produces `double[]`
|
|
618
|
+
arguments: convertedArgs,
|
|
457
619
|
isOptional: node.questionDotToken !== undefined,
|
|
458
|
-
inferredType
|
|
620
|
+
inferredType,
|
|
459
621
|
sourceSpan: getSourceSpan(node),
|
|
460
622
|
typeArguments,
|
|
461
623
|
requiresSpecialization,
|
|
@@ -464,29 +626,144 @@ export const convertCallExpression = (node, checker) => {
|
|
|
464
626
|
narrowing,
|
|
465
627
|
};
|
|
466
628
|
};
|
|
629
|
+
// DELETED: getConstructedType - Phase 15 uses resolveCall.returnType instead
|
|
467
630
|
/**
|
|
468
631
|
* Convert new expression
|
|
632
|
+
*
|
|
633
|
+
* Phase 15 (Alice's spec): Two-pass resolution for deterministic constructor typing.
|
|
634
|
+
* 1) Resolve once (without argTypes) to get parameter types for expected-type threading.
|
|
635
|
+
* 2) Convert non-lambda arguments first, collecting argTypes for inference.
|
|
636
|
+
* 3) Re-resolve with argTypes to infer constructor type parameters.
|
|
637
|
+
* 4) Convert lambda arguments using instantiated parameter types.
|
|
638
|
+
* 5) Final resolve with full argTypes.
|
|
639
|
+
* 6) inferredType MUST be finalResolved.returnType.
|
|
469
640
|
*/
|
|
470
|
-
export const convertNewExpression = (node,
|
|
471
|
-
// Extract type arguments
|
|
472
|
-
const typeArguments = extractTypeArguments(node,
|
|
473
|
-
const requiresSpecialization = checkIfRequiresSpecialization(node,
|
|
641
|
+
export const convertNewExpression = (node, ctx) => {
|
|
642
|
+
// Extract explicit type arguments (for IR output, not inference)
|
|
643
|
+
const typeArguments = extractTypeArguments(node, ctx);
|
|
644
|
+
const requiresSpecialization = checkIfRequiresSpecialization(node, ctx);
|
|
645
|
+
// Convert callee (the constructor expression)
|
|
646
|
+
const callee = convertExpression(node.expression, ctx, undefined);
|
|
647
|
+
// Two-pass resolution (matching convertCallExpression pattern)
|
|
648
|
+
const typeSystem = ctx.typeSystem;
|
|
649
|
+
const sigId = ctx.binding.resolveConstructorSignature(node);
|
|
650
|
+
const argumentCount = node.arguments?.length ?? 0;
|
|
651
|
+
// Extract explicit type arguments from call site
|
|
652
|
+
const explicitTypeArgs = node.typeArguments
|
|
653
|
+
? node.typeArguments.map((ta) => typeSystem.typeFromSyntax(ctx.binding.captureTypeSyntax(ta)))
|
|
654
|
+
: undefined;
|
|
655
|
+
// Initial resolution (without argTypes) for parameter type threading
|
|
656
|
+
const initialResolved = sigId
|
|
657
|
+
? typeSystem.resolveCall({
|
|
658
|
+
sigId,
|
|
659
|
+
argumentCount,
|
|
660
|
+
explicitTypeArgs,
|
|
661
|
+
})
|
|
662
|
+
: undefined;
|
|
663
|
+
const initialParameterTypes = initialResolved?.parameterTypes;
|
|
664
|
+
const isLambdaArg = (expr) => {
|
|
665
|
+
if (ts.isArrowFunction(expr) || ts.isFunctionExpression(expr))
|
|
666
|
+
return true;
|
|
667
|
+
if (ts.isParenthesizedExpression(expr))
|
|
668
|
+
return isLambdaArg(expr.expression);
|
|
669
|
+
return false;
|
|
670
|
+
};
|
|
671
|
+
// Pass 1: convert non-lambda arguments and collect argTypes for inference
|
|
672
|
+
const argsWorking = new Array(argumentCount);
|
|
673
|
+
const argTypesForInference = Array(argumentCount).fill(undefined);
|
|
674
|
+
const args = node.arguments ?? [];
|
|
675
|
+
for (let index = 0; index < args.length; index++) {
|
|
676
|
+
const arg = args[index];
|
|
677
|
+
if (!arg)
|
|
678
|
+
continue;
|
|
679
|
+
const expectedType = initialParameterTypes?.[index];
|
|
680
|
+
if (ts.isSpreadElement(arg)) {
|
|
681
|
+
const spreadExpr = convertExpression(arg.expression, ctx, undefined);
|
|
682
|
+
argsWorking[index] = {
|
|
683
|
+
kind: "spread",
|
|
684
|
+
expression: spreadExpr,
|
|
685
|
+
inferredType: spreadExpr.inferredType,
|
|
686
|
+
sourceSpan: getSourceSpan(arg),
|
|
687
|
+
};
|
|
688
|
+
continue;
|
|
689
|
+
}
|
|
690
|
+
if (isLambdaArg(arg)) {
|
|
691
|
+
// Defer lambda conversion until after generic type arg inference
|
|
692
|
+
continue;
|
|
693
|
+
}
|
|
694
|
+
const converted = convertExpression(arg, ctx, expectedType);
|
|
695
|
+
argsWorking[index] = converted;
|
|
696
|
+
argTypesForInference[index] = converted.inferredType;
|
|
697
|
+
}
|
|
698
|
+
// Re-resolve with argTypes to infer constructor type parameters
|
|
699
|
+
const lambdaContextResolved = sigId
|
|
700
|
+
? typeSystem.resolveCall({
|
|
701
|
+
sigId,
|
|
702
|
+
argumentCount,
|
|
703
|
+
explicitTypeArgs,
|
|
704
|
+
argTypes: argTypesForInference,
|
|
705
|
+
})
|
|
706
|
+
: initialResolved;
|
|
707
|
+
const parameterTypesForLambdaContext = lambdaContextResolved?.parameterTypes ?? initialParameterTypes;
|
|
708
|
+
// Pass 2: convert lambda arguments with inferred parameter types
|
|
709
|
+
for (let index = 0; index < args.length; index++) {
|
|
710
|
+
if (argsWorking[index])
|
|
711
|
+
continue;
|
|
712
|
+
const arg = args[index];
|
|
713
|
+
if (!arg)
|
|
714
|
+
continue;
|
|
715
|
+
if (ts.isSpreadElement(arg))
|
|
716
|
+
continue;
|
|
717
|
+
if (!isLambdaArg(arg))
|
|
718
|
+
continue;
|
|
719
|
+
const expectedType = parameterTypesForLambdaContext?.[index];
|
|
720
|
+
const lambdaExpectedType = expectedType?.kind === "functionType"
|
|
721
|
+
? expectedType
|
|
722
|
+
: expectedType
|
|
723
|
+
? typeSystem.delegateToFunctionType(expectedType) ?? expectedType
|
|
724
|
+
: undefined;
|
|
725
|
+
argsWorking[index] = convertExpression(arg, ctx, lambdaExpectedType);
|
|
726
|
+
}
|
|
727
|
+
// Fill any remaining undefined slots (shouldn't happen, but be safe)
|
|
728
|
+
const convertedArgs = argsWorking.map((a, index) => {
|
|
729
|
+
if (a)
|
|
730
|
+
return a;
|
|
731
|
+
const arg = args[index];
|
|
732
|
+
if (!arg) {
|
|
733
|
+
throw new Error("ICE: new expression argument conversion produced a hole");
|
|
734
|
+
}
|
|
735
|
+
return convertExpression(arg, ctx, undefined);
|
|
736
|
+
});
|
|
737
|
+
// Collect final argTypes
|
|
738
|
+
const argTypes = convertedArgs.map((a) => a.kind === "spread" ? undefined : a.inferredType);
|
|
739
|
+
// Final resolution with full argTypes
|
|
740
|
+
const finalResolved = sigId
|
|
741
|
+
? typeSystem.resolveCall({
|
|
742
|
+
sigId,
|
|
743
|
+
argumentCount,
|
|
744
|
+
explicitTypeArgs,
|
|
745
|
+
argTypes,
|
|
746
|
+
})
|
|
747
|
+
: lambdaContextResolved;
|
|
748
|
+
// Phase 15: inferredType MUST be finalResolved.returnType
|
|
749
|
+
// If sigId is missing, use unknownType (do not fabricate a nominal type)
|
|
750
|
+
const inferredType = finalResolved?.returnType ?? { kind: "unknownType" };
|
|
751
|
+
const parameterTypes = finalResolved?.parameterTypes ?? initialParameterTypes;
|
|
752
|
+
// Phase 18: IrNewExpression.typeArguments must include inferred type arguments.
|
|
753
|
+
// The emitter relies on this field to emit generic constructor calls (e.g., new Box<int>(...)).
|
|
754
|
+
const inferredTypeArguments = inferredType.kind === "referenceType" ? inferredType.typeArguments : undefined;
|
|
755
|
+
const typeArgumentsForIr = typeArguments ??
|
|
756
|
+
(inferredTypeArguments && inferredTypeArguments.length > 0
|
|
757
|
+
? inferredTypeArguments
|
|
758
|
+
: undefined);
|
|
474
759
|
return {
|
|
475
760
|
kind: "new",
|
|
476
|
-
callee
|
|
477
|
-
arguments:
|
|
478
|
-
|
|
479
|
-
return {
|
|
480
|
-
kind: "spread",
|
|
481
|
-
expression: convertExpression(arg.expression, checker),
|
|
482
|
-
sourceSpan: getSourceSpan(arg),
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
return convertExpression(arg, checker);
|
|
486
|
-
}) ?? [],
|
|
487
|
-
inferredType: getInferredType(node, checker),
|
|
761
|
+
callee,
|
|
762
|
+
arguments: convertedArgs,
|
|
763
|
+
inferredType,
|
|
488
764
|
sourceSpan: getSourceSpan(node),
|
|
489
|
-
|
|
765
|
+
parameterTypes,
|
|
766
|
+
typeArguments: typeArgumentsForIr,
|
|
490
767
|
requiresSpecialization,
|
|
491
768
|
};
|
|
492
769
|
};
|