@tsonic/frontend 0.0.61 → 0.0.63
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/dependency-graph.d.ts +1 -1
- package/dist/dependency-graph.d.ts.map +1 -1
- package/dist/dependency-graph.js +1 -1
- package/dist/dependency-graph.js.map +1 -1
- package/dist/dotnet-metadata.d.ts +0 -12
- package/dist/dotnet-metadata.d.ts.map +1 -1
- package/dist/dotnet-metadata.js +3 -25
- package/dist/dotnet-metadata.js.map +1 -1
- package/dist/dotnet-metadata.test.js.map +1 -1
- package/dist/generic-function-values.d.ts +11 -0
- package/dist/generic-function-values.d.ts.map +1 -0
- package/dist/generic-function-values.js +243 -0
- package/dist/generic-function-values.js.map +1 -0
- package/dist/generic-function-values.test.d.ts +2 -0
- package/dist/generic-function-values.test.d.ts.map +1 -0
- package/dist/generic-function-values.test.js +256 -0
- package/dist/generic-function-values.test.js.map +1 -0
- package/dist/graph/extraction/imports.d.ts +5 -0
- package/dist/graph/extraction/imports.d.ts.map +1 -1
- package/dist/graph/extraction/imports.js +30 -0
- package/dist/graph/extraction/imports.js.map +1 -1
- package/dist/graph/extraction/index.d.ts +1 -1
- package/dist/graph/extraction/index.d.ts.map +1 -1
- package/dist/graph/extraction/index.js +1 -1
- package/dist/graph/extraction/index.js.map +1 -1
- package/dist/graph/extraction/orchestrator.d.ts.map +1 -1
- package/dist/graph/extraction/orchestrator.js +16 -2
- package/dist/graph/extraction/orchestrator.js.map +1 -1
- package/dist/graph/extraction.d.ts +1 -1
- package/dist/graph/extraction.d.ts.map +1 -1
- package/dist/graph/extraction.js +1 -1
- package/dist/graph/extraction.js.map +1 -1
- package/dist/ir/binding/binding-factory.d.ts +17 -0
- package/dist/ir/binding/binding-factory.d.ts.map +1 -0
- package/dist/ir/binding/binding-factory.js +765 -0
- package/dist/ir/binding/binding-factory.js.map +1 -0
- package/dist/ir/binding/binding-helpers.d.ts +90 -0
- package/dist/ir/binding/binding-helpers.d.ts.map +1 -0
- package/dist/ir/binding/binding-helpers.js +387 -0
- package/dist/ir/binding/binding-helpers.js.map +1 -0
- package/dist/ir/binding/binding-types.d.ts +203 -0
- package/dist/ir/binding/binding-types.d.ts.map +1 -0
- package/dist/ir/binding/binding-types.js +9 -0
- package/dist/ir/binding/binding-types.js.map +1 -0
- package/dist/ir/binding/index.d.ts +4 -151
- package/dist/ir/binding/index.d.ts.map +1 -1
- package/dist/ir/binding/index.js +3 -1124
- package/dist/ir/binding/index.js.map +1 -1
- package/dist/ir/binding-resolution.test.js +4 -1
- package/dist/ir/binding-resolution.test.js.map +1 -1
- package/dist/ir/bindings-disambiguation.test.js.map +1 -1
- package/dist/ir/builder/imports.d.ts.map +1 -1
- package/dist/ir/builder/imports.js +91 -5
- package/dist/ir/builder/imports.js.map +1 -1
- package/dist/ir/builder.test.js +456 -24
- package/dist/ir/builder.test.js.map +1 -1
- package/dist/ir/converters/anonymous-synthesis.d.ts +3 -3
- package/dist/ir/converters/anonymous-synthesis.d.ts.map +1 -1
- package/dist/ir/converters/anonymous-synthesis.js +45 -8
- package/dist/ir/converters/anonymous-synthesis.js.map +1 -1
- package/dist/ir/converters/expressions/access/access-converter.d.ts +14 -0
- package/dist/ir/converters/expressions/access/access-converter.d.ts.map +1 -0
- package/dist/ir/converters/expressions/access/access-converter.js +141 -0
- package/dist/ir/converters/expressions/access/access-converter.js.map +1 -0
- package/dist/ir/converters/expressions/access/binding-resolution.d.ts +35 -0
- package/dist/ir/converters/expressions/access/binding-resolution.d.ts.map +1 -0
- package/dist/ir/converters/expressions/access/binding-resolution.js +384 -0
- package/dist/ir/converters/expressions/access/binding-resolution.js.map +1 -0
- package/dist/ir/converters/expressions/access/member-resolution.d.ts +67 -0
- package/dist/ir/converters/expressions/access/member-resolution.d.ts.map +1 -0
- package/dist/ir/converters/expressions/access/member-resolution.js +262 -0
- package/dist/ir/converters/expressions/access/member-resolution.js.map +1 -0
- package/dist/ir/converters/expressions/access.d.ts +1 -7
- package/dist/ir/converters/expressions/access.d.ts.map +1 -1
- package/dist/ir/converters/expressions/access.js +1 -720
- package/dist/ir/converters/expressions/access.js.map +1 -1
- package/dist/ir/converters/expressions/calls/call-converter.d.ts +23 -0
- package/dist/ir/converters/expressions/calls/call-converter.d.ts.map +1 -0
- package/dist/ir/converters/expressions/calls/call-converter.js +526 -0
- package/dist/ir/converters/expressions/calls/call-converter.js.map +1 -0
- package/dist/ir/converters/expressions/calls/call-site-analysis.d.ts +53 -0
- package/dist/ir/converters/expressions/calls/call-site-analysis.d.ts.map +1 -0
- package/dist/ir/converters/expressions/calls/call-site-analysis.js +554 -0
- package/dist/ir/converters/expressions/calls/call-site-analysis.js.map +1 -0
- package/dist/ir/converters/expressions/calls/new-converter.d.ts +21 -0
- package/dist/ir/converters/expressions/calls/new-converter.d.ts.map +1 -0
- package/dist/ir/converters/expressions/calls/new-converter.js +182 -0
- package/dist/ir/converters/expressions/calls/new-converter.js.map +1 -0
- package/dist/ir/converters/expressions/calls.d.ts +2 -28
- package/dist/ir/converters/expressions/calls.d.ts.map +1 -1
- package/dist/ir/converters/expressions/calls.js +2 -953
- package/dist/ir/converters/expressions/calls.js.map +1 -1
- package/dist/ir/converters/expressions/collections.d.ts.map +1 -1
- package/dist/ir/converters/expressions/collections.js +56 -28
- package/dist/ir/converters/expressions/collections.js.map +1 -1
- package/dist/ir/converters/expressions/functions.js +3 -3
- package/dist/ir/converters/expressions/functions.js.map +1 -1
- package/dist/ir/converters/expressions/helpers.d.ts.map +1 -1
- package/dist/ir/converters/expressions/helpers.js +1 -0
- package/dist/ir/converters/expressions/helpers.js.map +1 -1
- package/dist/ir/converters/expressions/operators.d.ts.map +1 -1
- package/dist/ir/converters/expressions/operators.js +1 -1
- package/dist/ir/converters/expressions/operators.js.map +1 -1
- package/dist/ir/converters/expressions/other.d.ts.map +1 -1
- package/dist/ir/converters/expressions/other.js +17 -2
- package/dist/ir/converters/expressions/other.js.map +1 -1
- package/dist/ir/converters/flow-narrowing.d.ts.map +1 -1
- package/dist/ir/converters/flow-narrowing.js +3 -2
- package/dist/ir/converters/flow-narrowing.js.map +1 -1
- package/dist/ir/converters/statements/control/loops.d.ts.map +1 -1
- package/dist/ir/converters/statements/control/loops.js +8 -2
- package/dist/ir/converters/statements/control/loops.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/constructors.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/constructors.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/methods.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/methods.js +71 -23
- package/dist/ir/converters/statements/declarations/classes/methods.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/orchestrator.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/orchestrator.js +10 -4
- package/dist/ir/converters/statements/declarations/classes/orchestrator.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/override-detection.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/override-detection.js +5 -1
- package/dist/ir/converters/statements/declarations/classes/override-detection.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/properties.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/properties.js +2 -1
- package/dist/ir/converters/statements/declarations/classes/properties.js.map +1 -1
- package/dist/ir/converters/statements/declarations/type-aliases.js +1 -1
- package/dist/ir/converters/statements/declarations/type-aliases.js.map +1 -1
- package/dist/ir/converters/statements/declarations/variables.d.ts +2 -2
- package/dist/ir/converters/statements/declarations/variables.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/variables.js +290 -3
- package/dist/ir/converters/statements/declarations/variables.js.map +1 -1
- package/dist/ir/converters/statements/helpers.d.ts.map +1 -1
- package/dist/ir/converters/statements/helpers.js +10 -2
- package/dist/ir/converters/statements/helpers.js.map +1 -1
- package/dist/ir/converters/type-env.d.ts.map +1 -1
- package/dist/ir/converters/type-env.js.map +1 -1
- package/dist/ir/expression-converter.d.ts +0 -1
- package/dist/ir/expression-converter.d.ts.map +1 -1
- package/dist/ir/expression-converter.js +25 -4
- package/dist/ir/expression-converter.js.map +1 -1
- package/dist/ir/field-marker.test.js.map +1 -1
- package/dist/ir/generic-function-value-lowering.test.d.ts +2 -0
- package/dist/ir/generic-function-value-lowering.test.d.ts.map +1 -0
- package/dist/ir/generic-function-value-lowering.test.js +312 -0
- package/dist/ir/generic-function-value-lowering.test.js.map +1 -0
- package/dist/ir/generic-validator.d.ts +3 -4
- package/dist/ir/generic-validator.d.ts.map +1 -1
- package/dist/ir/generic-validator.js +3 -35
- package/dist/ir/generic-validator.js.map +1 -1
- package/dist/ir/program-context.d.ts +7 -0
- package/dist/ir/program-context.d.ts.map +1 -1
- package/dist/ir/program-context.js +7 -2
- package/dist/ir/program-context.js.map +1 -1
- package/dist/ir/statement-converter.d.ts +0 -2
- package/dist/ir/statement-converter.d.ts.map +1 -1
- package/dist/ir/statement-converter.js +0 -3
- package/dist/ir/statement-converter.js.map +1 -1
- package/dist/ir/type-system/internal/handle-types.d.ts +16 -16
- package/dist/ir/type-system/internal/handle-types.d.ts.map +1 -1
- package/dist/ir/type-system/internal/nominal-env.d.ts +0 -2
- package/dist/ir/type-system/internal/nominal-env.d.ts.map +1 -1
- package/dist/ir/type-system/internal/nominal-env.js +2 -6
- package/dist/ir/type-system/internal/nominal-env.js.map +1 -1
- package/dist/ir/type-system/internal/type-converter/converter.d.ts +3 -1
- package/dist/ir/type-system/internal/type-converter/converter.d.ts.map +1 -1
- package/dist/ir/type-system/internal/type-converter/converter.js +3 -1
- package/dist/ir/type-system/internal/type-converter/converter.js.map +1 -1
- package/dist/ir/type-system/internal/type-converter/objects.js +7 -1
- package/dist/ir/type-system/internal/type-converter/objects.js.map +1 -1
- package/dist/ir/type-system/internal/type-converter/orchestrator.d.ts +0 -2
- package/dist/ir/type-system/internal/type-converter/orchestrator.d.ts.map +1 -1
- package/dist/ir/type-system/internal/type-converter/orchestrator.js +318 -24
- package/dist/ir/type-system/internal/type-converter/orchestrator.js.map +1 -1
- package/dist/ir/type-system/internal/type-converter/orchestrator.test.d.ts +2 -0
- package/dist/ir/type-system/internal/type-converter/orchestrator.test.d.ts.map +1 -0
- package/dist/ir/type-system/internal/type-converter/orchestrator.test.js +265 -0
- package/dist/ir/type-system/internal/type-converter/orchestrator.test.js.map +1 -0
- package/dist/ir/type-system/internal/type-converter/primitives.d.ts.map +1 -1
- package/dist/ir/type-system/internal/type-converter/primitives.js +5 -0
- package/dist/ir/type-system/internal/type-converter/primitives.js.map +1 -1
- package/dist/ir/type-system/internal/type-converter/references.d.ts.map +1 -1
- package/dist/ir/type-system/internal/type-converter/references.js +172 -26
- package/dist/ir/type-system/internal/type-converter/references.js.map +1 -1
- package/dist/ir/type-system/internal/type-converter/utility-types.d.ts.map +1 -1
- package/dist/ir/type-system/internal/type-converter/utility-types.js +154 -4
- package/dist/ir/type-system/internal/type-converter/utility-types.js.map +1 -1
- package/dist/ir/type-system/internal/type-converter/utility-types.test.js +91 -1
- package/dist/ir/type-system/internal/type-converter/utility-types.test.js.map +1 -1
- package/dist/ir/type-system/internal/type-registry.d.ts +1 -1
- package/dist/ir/type-system/internal/type-registry.d.ts.map +1 -1
- package/dist/ir/type-system/internal/type-registry.js +15 -11
- package/dist/ir/type-system/internal/type-registry.js.map +1 -1
- package/dist/ir/type-system/internal/universe/alias-table.d.ts +0 -14
- package/dist/ir/type-system/internal/universe/alias-table.d.ts.map +1 -1
- package/dist/ir/type-system/internal/universe/alias-table.js +0 -17
- package/dist/ir/type-system/internal/universe/alias-table.js.map +1 -1
- package/dist/ir/type-system/internal/universe/clr-catalog.d.ts +3 -0
- package/dist/ir/type-system/internal/universe/clr-catalog.d.ts.map +1 -1
- package/dist/ir/type-system/internal/universe/clr-catalog.js +4 -1027
- package/dist/ir/type-system/internal/universe/clr-catalog.js.map +1 -1
- package/dist/ir/type-system/internal/universe/clr-entry-converter.d.ts +51 -0
- package/dist/ir/type-system/internal/universe/clr-entry-converter.d.ts.map +1 -0
- package/dist/ir/type-system/internal/universe/clr-entry-converter.js +657 -0
- package/dist/ir/type-system/internal/universe/clr-entry-converter.js.map +1 -0
- package/dist/ir/type-system/internal/universe/clr-type-parser.d.ts +52 -0
- package/dist/ir/type-system/internal/universe/clr-type-parser.d.ts.map +1 -0
- package/dist/ir/type-system/internal/universe/clr-type-parser.js +415 -0
- package/dist/ir/type-system/internal/universe/clr-type-parser.js.map +1 -0
- package/dist/ir/type-system/internal/universe/index.d.ts +1 -1
- package/dist/ir/type-system/internal/universe/index.d.ts.map +1 -1
- package/dist/ir/type-system/internal/universe/index.js +1 -3
- package/dist/ir/type-system/internal/universe/index.js.map +1 -1
- package/dist/ir/type-system/internal/universe/source-catalog.js +3 -1
- package/dist/ir/type-system/internal/universe/source-catalog.js.map +1 -1
- package/dist/ir/type-system/internal/universe/types.d.ts +7 -0
- package/dist/ir/type-system/internal/universe/types.d.ts.map +1 -1
- package/dist/ir/type-system/internal/universe/types.js.map +1 -1
- package/dist/ir/type-system/internal/universe/unified-universe.d.ts.map +1 -1
- package/dist/ir/type-system/internal/universe/unified-universe.js +16 -1
- package/dist/ir/type-system/internal/universe/unified-universe.js.map +1 -1
- package/dist/ir/type-system/internal/universe/unified-universe.test.d.ts +2 -0
- package/dist/ir/type-system/internal/universe/unified-universe.test.d.ts.map +1 -0
- package/dist/ir/type-system/internal/universe/unified-universe.test.js +89 -0
- package/dist/ir/type-system/internal/universe/unified-universe.test.js.map +1 -0
- package/dist/ir/type-system/type-system-call-resolution.d.ts +69 -0
- package/dist/ir/type-system/type-system-call-resolution.d.ts.map +1 -0
- package/dist/ir/type-system/type-system-call-resolution.js +1121 -0
- package/dist/ir/type-system/type-system-call-resolution.js.map +1 -0
- package/dist/ir/type-system/type-system-inference.d.ts +98 -0
- package/dist/ir/type-system/type-system-inference.d.ts.map +1 -0
- package/dist/ir/type-system/type-system-inference.js +1083 -0
- package/dist/ir/type-system/type-system-inference.js.map +1 -0
- package/dist/ir/type-system/type-system-relations.d.ts +15 -0
- package/dist/ir/type-system/type-system-relations.d.ts.map +1 -0
- package/dist/ir/type-system/type-system-relations.js +152 -0
- package/dist/ir/type-system/type-system-relations.js.map +1 -0
- package/dist/ir/type-system/type-system-state.d.ts +436 -0
- package/dist/ir/type-system/type-system-state.d.ts.map +1 -0
- package/dist/ir/type-system/type-system-state.js +212 -0
- package/dist/ir/type-system/type-system-state.js.map +1 -0
- package/dist/ir/type-system/type-system-utilities.d.ts +56 -0
- package/dist/ir/type-system/type-system-utilities.d.ts.map +1 -0
- package/dist/ir/type-system/type-system-utilities.js +373 -0
- package/dist/ir/type-system/type-system-utilities.js.map +1 -0
- package/dist/ir/type-system/type-system.d.ts +17 -350
- package/dist/ir/type-system/type-system.d.ts.map +1 -1
- package/dist/ir/type-system/type-system.js +67 -2764
- package/dist/ir/type-system/type-system.js.map +1 -1
- package/dist/ir/types/index.d.ts +1 -0
- 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.js +1 -1
- package/dist/ir/types/ir-substitution.js.map +1 -1
- package/dist/ir/types/ir-types.d.ts.map +1 -1
- package/dist/ir/types/module.d.ts +11 -0
- package/dist/ir/types/module.d.ts.map +1 -1
- package/dist/ir/types/statements.d.ts +1 -1
- package/dist/ir/types/type-ops.d.ts +9 -0
- package/dist/ir/types/type-ops.d.ts.map +1 -0
- package/dist/ir/types/type-ops.js +134 -0
- package/dist/ir/types/type-ops.js.map +1 -0
- package/dist/ir/types/type-ops.test.d.ts +2 -0
- package/dist/ir/types/type-ops.test.d.ts.map +1 -0
- package/dist/ir/types/type-ops.test.js +73 -0
- package/dist/ir/types/type-ops.test.js.map +1 -0
- package/dist/ir/validation/anonymous-type-lowering-pass.d.ts.map +1 -1
- package/dist/ir/validation/anonymous-type-lowering-pass.js +101 -49
- package/dist/ir/validation/anonymous-type-lowering-pass.js.map +1 -1
- package/dist/ir/validation/arrow-return-finalization-pass.js +13 -3
- package/dist/ir/validation/arrow-return-finalization-pass.js.map +1 -1
- package/dist/ir/validation/attribute-collection/arg-extractor.d.ts +58 -0
- package/dist/ir/validation/attribute-collection/arg-extractor.d.ts.map +1 -0
- package/dist/ir/validation/attribute-collection/arg-extractor.js +284 -0
- package/dist/ir/validation/attribute-collection/arg-extractor.js.map +1 -0
- package/dist/ir/validation/attribute-collection/marker-parser.d.ts +28 -0
- package/dist/ir/validation/attribute-collection/marker-parser.d.ts.map +1 -0
- package/dist/ir/validation/attribute-collection/marker-parser.js +404 -0
- package/dist/ir/validation/attribute-collection/marker-parser.js.map +1 -0
- package/dist/ir/validation/attribute-collection/orchestrator.d.ts +28 -0
- package/dist/ir/validation/attribute-collection/orchestrator.d.ts.map +1 -0
- package/dist/ir/validation/attribute-collection/orchestrator.js +332 -0
- package/dist/ir/validation/attribute-collection/orchestrator.js.map +1 -0
- package/dist/ir/validation/attribute-collection-pass.d.ts +1 -23
- package/dist/ir/validation/attribute-collection-pass.d.ts.map +1 -1
- package/dist/ir/validation/attribute-collection-pass.js +1 -953
- package/dist/ir/validation/attribute-collection-pass.js.map +1 -1
- package/dist/ir/validation/attribute-collection-pass.test.js +42 -19
- package/dist/ir/validation/attribute-collection-pass.test.js.map +1 -1
- package/dist/ir/validation/char-validation-pass.d.ts.map +1 -1
- package/dist/ir/validation/char-validation-pass.js +6 -3
- package/dist/ir/validation/char-validation-pass.js.map +1 -1
- package/dist/ir/validation/numeric-coercion-pass.d.ts.map +1 -1
- package/dist/ir/validation/numeric-coercion-pass.js.map +1 -1
- package/dist/ir/validation/numeric-invariants.test.js +46 -0
- 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 +68 -1
- package/dist/ir/validation/numeric-proof-pass.js.map +1 -1
- package/dist/ir/validation/rest-type-synthesis-pass.js +1 -1
- package/dist/ir/validation/rest-type-synthesis-pass.js.map +1 -1
- package/dist/ir/validation/soundness-gate.d.ts.map +1 -1
- package/dist/ir/validation/soundness-gate.js +8 -5
- package/dist/ir/validation/soundness-gate.js.map +1 -1
- package/dist/ir/validation/soundness-gate.test.js +158 -0
- package/dist/ir/validation/soundness-gate.test.js.map +1 -1
- package/dist/ir/validation/yield-lowering-pass.d.ts +11 -5
- package/dist/ir/validation/yield-lowering-pass.d.ts.map +1 -1
- package/dist/ir/validation/yield-lowering-pass.js +942 -48
- package/dist/ir/validation/yield-lowering-pass.js.map +1 -1
- package/dist/ir/validation/yield-lowering-pass.test.js +1333 -127
- package/dist/ir/validation/yield-lowering-pass.test.js.map +1 -1
- package/dist/program/binding-loader.d.ts +37 -0
- package/dist/program/binding-loader.d.ts.map +1 -0
- package/dist/program/binding-loader.js +155 -0
- package/dist/program/binding-loader.js.map +1 -0
- package/dist/program/binding-registry.d.ts +106 -0
- package/dist/program/binding-registry.d.ts.map +1 -0
- package/dist/program/binding-registry.js +590 -0
- package/dist/program/binding-registry.js.map +1 -0
- package/dist/program/binding-types.d.ts +166 -0
- package/dist/program/binding-types.d.ts.map +1 -0
- package/dist/program/binding-types.js +57 -0
- package/dist/program/binding-types.js.map +1 -0
- package/dist/program/bindings.d.ts +6 -271
- package/dist/program/bindings.d.ts.map +1 -1
- package/dist/program/bindings.js +7 -781
- package/dist/program/bindings.js.map +1 -1
- package/dist/program/clr-bindings-discovery.d.ts +19 -0
- package/dist/program/clr-bindings-discovery.d.ts.map +1 -0
- package/dist/program/clr-bindings-discovery.js +150 -0
- package/dist/program/clr-bindings-discovery.js.map +1 -0
- package/dist/program/clr-bindings-discovery.test.d.ts +2 -0
- package/dist/program/clr-bindings-discovery.test.d.ts.map +1 -0
- package/dist/program/clr-bindings-discovery.test.js +119 -0
- package/dist/program/clr-bindings-discovery.test.js.map +1 -0
- package/dist/program/creation.d.ts.map +1 -1
- package/dist/program/creation.js +2 -1
- package/dist/program/creation.js.map +1 -1
- package/dist/program/creation.test.js.map +1 -1
- package/dist/program/dependency-graph.d.ts +2 -2
- package/dist/program/dependency-graph.d.ts.map +1 -1
- package/dist/program/dependency-graph.js +26 -42
- package/dist/program/dependency-graph.js.map +1 -1
- package/dist/resolver/clr-bindings-resolver.d.ts +0 -1
- package/dist/resolver/clr-bindings-resolver.d.ts.map +1 -1
- package/dist/resolver/clr-bindings-resolver.js +22 -30
- package/dist/resolver/clr-bindings-resolver.js.map +1 -1
- package/dist/resolver/clr-bindings-resolver.test.js +0 -27
- package/dist/resolver/clr-bindings-resolver.test.js.map +1 -1
- package/dist/resolver/import-resolution.d.ts +1 -1
- package/dist/resolver/import-resolution.d.ts.map +1 -1
- package/dist/resolver/import-resolution.js +2 -7
- package/dist/resolver/import-resolution.js.map +1 -1
- package/dist/resolver/namespace.d.ts.map +1 -1
- package/dist/resolver/namespace.js +1 -3
- package/dist/resolver/namespace.js.map +1 -1
- package/dist/resolver/naming.d.ts.map +1 -1
- package/dist/resolver/naming.js +1 -0
- package/dist/resolver/naming.js.map +1 -1
- package/dist/tsbindgen/names.d.ts.map +1 -1
- package/dist/tsbindgen/names.js +4 -2
- package/dist/tsbindgen/names.js.map +1 -1
- package/dist/types/diagnostic.d.ts +1 -1
- package/dist/types/diagnostic.d.ts.map +1 -1
- package/dist/types/diagnostic.js.map +1 -1
- package/dist/validation/core-intrinsics.d.ts.map +1 -1
- package/dist/validation/core-intrinsics.js +3 -1
- package/dist/validation/core-intrinsics.js.map +1 -1
- package/dist/validation/extension-methods.d.ts.map +1 -1
- package/dist/validation/extension-methods.js.map +1 -1
- package/dist/validation/features.d.ts.map +1 -1
- package/dist/validation/features.js +38 -13
- package/dist/validation/features.js.map +1 -1
- package/dist/validation/features.test.d.ts +2 -0
- package/dist/validation/features.test.d.ts.map +1 -0
- package/dist/validation/features.test.js +273 -0
- package/dist/validation/features.test.js.map +1 -0
- package/dist/validation/generics.d.ts +1 -1
- package/dist/validation/generics.d.ts.map +1 -1
- package/dist/validation/generics.js +2 -26
- package/dist/validation/generics.js.map +1 -1
- package/dist/validation/imports.d.ts.map +1 -1
- package/dist/validation/imports.js +2 -1
- package/dist/validation/imports.js.map +1 -1
- package/dist/validation/imports.test.d.ts +2 -0
- package/dist/validation/imports.test.d.ts.map +1 -0
- package/dist/validation/imports.test.js +112 -0
- package/dist/validation/imports.test.js.map +1 -0
- package/dist/validation/static-safety.d.ts +6 -6
- package/dist/validation/static-safety.d.ts.map +1 -1
- package/dist/validation/static-safety.js +163 -94
- package/dist/validation/static-safety.js.map +1 -1
- package/dist/validation/unsupported-utility-types.d.ts +3 -3
- package/dist/validation/unsupported-utility-types.d.ts.map +1 -1
- package/dist/validation/unsupported-utility-types.js +4 -7
- package/dist/validation/unsupported-utility-types.js.map +1 -1
- package/dist/validator.maximus.test.d.ts +2 -0
- package/dist/validator.maximus.test.d.ts.map +1 -0
- package/dist/validator.maximus.test.js +1214 -0
- package/dist/validator.maximus.test.js.map +1 -0
- package/dist/validator.test.js +152 -18
- package/dist/validator.test.js.map +1 -1
- package/package.json +1 -1
- package/dist/ir/converters/statements/declarations/registry.d.ts +0 -96
- package/dist/ir/converters/statements/declarations/registry.d.ts.map +0 -1
- package/dist/ir/converters/statements/declarations/registry.js +0 -130
- package/dist/ir/converters/statements/declarations/registry.js.map +0 -1
- package/dist/ir/this-parameter-inference.test.d.ts +0 -13
- package/dist/ir/this-parameter-inference.test.d.ts.map +0 -1
- package/dist/ir/this-parameter-inference.test.js +0 -165
- package/dist/ir/this-parameter-inference.test.js.map +0 -1
- package/dist/metadata/bindings-loader.d.ts +0 -41
- package/dist/metadata/bindings-loader.d.ts.map +0 -1
- package/dist/metadata/bindings-loader.js +0 -308
- package/dist/metadata/bindings-loader.js.map +0 -1
- package/dist/metadata/bindings-loader.test.d.ts +0 -5
- package/dist/metadata/bindings-loader.test.d.ts.map +0 -1
- package/dist/metadata/bindings-loader.test.js +0 -117
- package/dist/metadata/bindings-loader.test.js.map +0 -1
- package/dist/metadata/index.d.ts +0 -8
- package/dist/metadata/index.d.ts.map +0 -1
- package/dist/metadata/index.js +0 -7
- package/dist/metadata/index.js.map +0 -1
- package/dist/metadata/library-loader.d.ts +0 -42
- package/dist/metadata/library-loader.d.ts.map +0 -1
- package/dist/metadata/library-loader.js +0 -126
- package/dist/metadata/library-loader.js.map +0 -1
- package/dist/metadata/loader.d.ts +0 -26
- package/dist/metadata/loader.d.ts.map +0 -1
- package/dist/metadata/loader.js +0 -333
- package/dist/metadata/loader.js.map +0 -1
- package/dist/metadata/loader.test.d.ts +0 -5
- package/dist/metadata/loader.test.d.ts.map +0 -1
- package/dist/metadata/loader.test.js +0 -119
- package/dist/metadata/loader.test.js.map +0 -1
- package/dist/resolver/naming-policy.d.ts +0 -20
- package/dist/resolver/naming-policy.d.ts.map +0 -1
- package/dist/resolver/naming-policy.js +0 -40
- package/dist/resolver/naming-policy.js.map +0 -1
- package/dist/types/bindings.d.ts +0 -153
- package/dist/types/bindings.d.ts.map +0 -1
- package/dist/types/bindings.js +0 -14
- package/dist/types/bindings.js.map +0 -1
- package/dist/types/metadata.d.ts +0 -196
- package/dist/types/metadata.d.ts.map +0 -1
- package/dist/types/metadata.js +0 -10
- package/dist/types/metadata.js.map +0 -1
- package/dist/types/nested-types.d.ts +0 -111
- package/dist/types/nested-types.d.ts.map +0 -1
- package/dist/types/nested-types.js +0 -176
- package/dist/types/nested-types.js.map +0 -1
- package/dist/types/nested-types.test.d.ts +0 -5
- package/dist/types/nested-types.test.d.ts.map +0 -1
- package/dist/types/nested-types.test.js +0 -135
- package/dist/types/nested-types.test.js.map +0 -1
- package/dist/types/ref-parameters.d.ts +0 -123
- package/dist/types/ref-parameters.d.ts.map +0 -1
- package/dist/types/ref-parameters.js +0 -203
- package/dist/types/ref-parameters.js.map +0 -1
- package/dist/types/ref-parameters.test.d.ts +0 -5
- package/dist/types/ref-parameters.test.d.ts.map +0 -1
- package/dist/types/ref-parameters.test.js +0 -147
- package/dist/types/ref-parameters.test.js.map +0 -1
|
@@ -0,0 +1,1121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeSystem Call Resolution — Signature Extraction, Type ID Attachment, and Call Resolution
|
|
3
|
+
*
|
|
4
|
+
* Handles call resolution, signature extraction, type ID attachment, and structural member lookup.
|
|
5
|
+
*
|
|
6
|
+
* DAG position: depends on type-system-state and type-system-relations
|
|
7
|
+
*/
|
|
8
|
+
import { substituteIrType as irSubstitute, } from "../types/ir-substitution.js";
|
|
9
|
+
import { stableIrTypeKey, unwrapAsyncWrapperType } from "../types/type-ops.js";
|
|
10
|
+
import { unknownType, voidType } from "./types.js";
|
|
11
|
+
import { emitDiagnostic, resolveTypeIdByName, normalizeToNominal, isNullishPrimitive, addUndefinedToType, stripTsonicExtensionWrappers, poisonedCall, } from "./type-system-state.js";
|
|
12
|
+
import { typesEqual } from "./type-system-relations.js";
|
|
13
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
14
|
+
// getRawSignature — Extract raw signature from HandleRegistry
|
|
15
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
16
|
+
/**
|
|
17
|
+
* Get or compute raw signature info from SignatureId.
|
|
18
|
+
* Caches the result for subsequent calls.
|
|
19
|
+
*/
|
|
20
|
+
export const getRawSignature = (state, sigId) => {
|
|
21
|
+
const cached = state.signatureRawCache.get(sigId.id);
|
|
22
|
+
if (cached)
|
|
23
|
+
return cached;
|
|
24
|
+
const sigInfo = state.handleRegistry.getSignature(sigId);
|
|
25
|
+
if (!sigInfo)
|
|
26
|
+
return undefined;
|
|
27
|
+
// Convert parameter types from TypeNodes to IrTypes
|
|
28
|
+
const parameterTypes = sigInfo.parameters.map((p) => {
|
|
29
|
+
const baseType = p.typeNode
|
|
30
|
+
? convertTypeNode(state, p.typeNode)
|
|
31
|
+
: undefined;
|
|
32
|
+
if (!baseType)
|
|
33
|
+
return undefined;
|
|
34
|
+
// Optional/defaulted parameters must accept explicit `undefined` at call sites.
|
|
35
|
+
return p.isOptional ? addUndefinedToType(baseType) : baseType;
|
|
36
|
+
});
|
|
37
|
+
// Convert a TypeScript `this:` parameter type (if present) to an IrType.
|
|
38
|
+
const thisParameterType = (() => {
|
|
39
|
+
const n = sigInfo.thisTypeNode;
|
|
40
|
+
return n ? convertTypeNode(state, n) : undefined;
|
|
41
|
+
})();
|
|
42
|
+
// Extract parameter modes
|
|
43
|
+
const parameterModes = sigInfo.parameters.map((p) => p.mode ?? "value");
|
|
44
|
+
// Extract parameter names
|
|
45
|
+
const parameterNames = sigInfo.parameters.map((p) => p.name);
|
|
46
|
+
// Extract type parameters
|
|
47
|
+
const typeParameters = (sigInfo.typeParameters ?? []).map((tp) => ({
|
|
48
|
+
name: tp.name,
|
|
49
|
+
constraint: tp.constraintNode
|
|
50
|
+
? convertTypeNode(state, tp.constraintNode)
|
|
51
|
+
: undefined,
|
|
52
|
+
defaultType: tp.defaultNode
|
|
53
|
+
? convertTypeNode(state, tp.defaultNode)
|
|
54
|
+
: undefined,
|
|
55
|
+
}));
|
|
56
|
+
const isConstructor = sigInfo.declaringMemberName === "constructor";
|
|
57
|
+
// Convert return type
|
|
58
|
+
const returnType = (() => {
|
|
59
|
+
if (sigInfo.returnTypeNode)
|
|
60
|
+
return convertTypeNode(state, sigInfo.returnTypeNode);
|
|
61
|
+
// Class constructor declarations do not have return type annotations in TS syntax.
|
|
62
|
+
// Deterministically synthesize the constructed instance type using the declaring
|
|
63
|
+
// identity captured in Binding and the (class) type parameters captured for the
|
|
64
|
+
// constructor signature.
|
|
65
|
+
if (isConstructor && sigInfo.declaringTypeTsName) {
|
|
66
|
+
const typeArguments = typeParameters.map((tp) => ({
|
|
67
|
+
kind: "typeParameterType",
|
|
68
|
+
name: tp.name,
|
|
69
|
+
}));
|
|
70
|
+
return {
|
|
71
|
+
kind: "referenceType",
|
|
72
|
+
name: sigInfo.declaringTypeTsName,
|
|
73
|
+
...(typeArguments.length > 0 ? { typeArguments } : {}),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return voidType;
|
|
77
|
+
})();
|
|
78
|
+
// Extract type predicate (already extracted in Binding at registration time)
|
|
79
|
+
let typePredicate;
|
|
80
|
+
if (sigInfo.typePredicate) {
|
|
81
|
+
const pred = sigInfo.typePredicate;
|
|
82
|
+
const targetType = convertTypeNode(state, pred.targetTypeNode);
|
|
83
|
+
if (pred.kind === "param") {
|
|
84
|
+
typePredicate = {
|
|
85
|
+
kind: "param",
|
|
86
|
+
parameterIndex: pred.parameterIndex,
|
|
87
|
+
targetType,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
typePredicate = {
|
|
92
|
+
kind: "this",
|
|
93
|
+
targetType,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const rawSig = {
|
|
98
|
+
parameterTypes,
|
|
99
|
+
thisParameterType,
|
|
100
|
+
returnType,
|
|
101
|
+
parameterModes,
|
|
102
|
+
typeParameters,
|
|
103
|
+
parameterNames,
|
|
104
|
+
typePredicate,
|
|
105
|
+
declaringTypeTsName: sigInfo.declaringTypeTsName,
|
|
106
|
+
declaringMemberName: sigInfo.declaringMemberName,
|
|
107
|
+
};
|
|
108
|
+
state.signatureRawCache.set(sigId.id, rawSig);
|
|
109
|
+
return rawSig;
|
|
110
|
+
};
|
|
111
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
112
|
+
// Type ID attachment — Attach canonical TypeIds to IR types
|
|
113
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
114
|
+
/**
|
|
115
|
+
* Attach canonical TypeIds to IR types where possible.
|
|
116
|
+
*
|
|
117
|
+
* This keeps nominal identity stable throughout the pipeline and enables
|
|
118
|
+
* emit-time resolution without relying on string name matching.
|
|
119
|
+
*/
|
|
120
|
+
export const attachParameterTypeIds = (state, p) => ({
|
|
121
|
+
...p,
|
|
122
|
+
type: p.type ? attachTypeIds(state, p.type) : undefined,
|
|
123
|
+
});
|
|
124
|
+
export const attachTypeParameterTypeIds = (state, tp) => ({
|
|
125
|
+
...tp,
|
|
126
|
+
constraint: tp.constraint ? attachTypeIds(state, tp.constraint) : undefined,
|
|
127
|
+
default: tp.default ? attachTypeIds(state, tp.default) : undefined,
|
|
128
|
+
structuralMembers: tp.structuralMembers?.map((m) => attachInterfaceMemberTypeIds(state, m)),
|
|
129
|
+
});
|
|
130
|
+
export const attachInterfaceMemberTypeIds = (state, m) => {
|
|
131
|
+
if (m.kind === "propertySignature") {
|
|
132
|
+
return { ...m, type: attachTypeIds(state, m.type) };
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
...m,
|
|
136
|
+
typeParameters: m.typeParameters?.map((tp) => attachTypeParameterTypeIds(state, tp)),
|
|
137
|
+
parameters: m.parameters.map((p) => attachParameterTypeIds(state, p)),
|
|
138
|
+
returnType: m.returnType ? attachTypeIds(state, m.returnType) : undefined,
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
export const attachTypeIds = (state, type) => {
|
|
142
|
+
switch (type.kind) {
|
|
143
|
+
case "referenceType": {
|
|
144
|
+
const typeId = type.typeId ??
|
|
145
|
+
resolveTypeIdByName(state, type.resolvedClrType ?? type.name, type.typeArguments?.length);
|
|
146
|
+
return {
|
|
147
|
+
...type,
|
|
148
|
+
...(type.typeArguments
|
|
149
|
+
? {
|
|
150
|
+
typeArguments: type.typeArguments.map((t) => attachTypeIds(state, t)),
|
|
151
|
+
}
|
|
152
|
+
: {}),
|
|
153
|
+
...(type.structuralMembers
|
|
154
|
+
? {
|
|
155
|
+
structuralMembers: type.structuralMembers.map((m) => attachInterfaceMemberTypeIds(state, m)),
|
|
156
|
+
}
|
|
157
|
+
: {}),
|
|
158
|
+
...(typeId ? { typeId } : {}),
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
case "arrayType":
|
|
162
|
+
return { ...type, elementType: attachTypeIds(state, type.elementType) };
|
|
163
|
+
case "tupleType":
|
|
164
|
+
return {
|
|
165
|
+
...type,
|
|
166
|
+
elementTypes: type.elementTypes.map((t) => attachTypeIds(state, t)),
|
|
167
|
+
};
|
|
168
|
+
case "functionType":
|
|
169
|
+
return {
|
|
170
|
+
...type,
|
|
171
|
+
parameters: type.parameters.map((p) => attachParameterTypeIds(state, p)),
|
|
172
|
+
returnType: attachTypeIds(state, type.returnType),
|
|
173
|
+
};
|
|
174
|
+
case "objectType":
|
|
175
|
+
return {
|
|
176
|
+
...type,
|
|
177
|
+
members: type.members.map((m) => attachInterfaceMemberTypeIds(state, m)),
|
|
178
|
+
};
|
|
179
|
+
case "dictionaryType":
|
|
180
|
+
return {
|
|
181
|
+
...type,
|
|
182
|
+
keyType: attachTypeIds(state, type.keyType),
|
|
183
|
+
valueType: attachTypeIds(state, type.valueType),
|
|
184
|
+
};
|
|
185
|
+
case "unionType":
|
|
186
|
+
case "intersectionType":
|
|
187
|
+
return { ...type, types: type.types.map((t) => attachTypeIds(state, t)) };
|
|
188
|
+
default:
|
|
189
|
+
return type;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
193
|
+
// convertTypeNode — Deterministic type syntax conversion
|
|
194
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
195
|
+
/**
|
|
196
|
+
* Deterministic type syntax conversion with canonical TypeId attachment.
|
|
197
|
+
*
|
|
198
|
+
* The underlying converter is syntax-only; this wrapper re-attaches the
|
|
199
|
+
* nominal identity from the UnifiedUniverse so downstream passes (including
|
|
200
|
+
* the emitter) can resolve CLR types without re-driving a parallel lookup.
|
|
201
|
+
*/
|
|
202
|
+
export const convertTypeNode = (state, node) => {
|
|
203
|
+
return attachTypeIds(state, state.convertTypeNodeRaw(node));
|
|
204
|
+
};
|
|
205
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
206
|
+
// delegateToFunctionType — Delegate → IrFunctionType conversion
|
|
207
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
208
|
+
/**
|
|
209
|
+
* Convert a nominal CLR delegate type to an IrFunctionType by reading its Invoke signature.
|
|
210
|
+
*
|
|
211
|
+
* This is used for deterministic lambda typing when the expected type is a delegate
|
|
212
|
+
* (e.g., custom delegates from CLR metadata).
|
|
213
|
+
*/
|
|
214
|
+
export const delegateToFunctionType = (state, type) => {
|
|
215
|
+
// Expression<TDelegate> wrapper: treat as its underlying delegate type for
|
|
216
|
+
// deterministic lambda contextual typing.
|
|
217
|
+
//
|
|
218
|
+
// This models C#'s implicit lambda conversion to Expression<Func<...>>:
|
|
219
|
+
// the TypeScript surface uses Expression<TDelegate>, but lambdas should be
|
|
220
|
+
// typed against the delegate shape.
|
|
221
|
+
if (type.kind === "referenceType" &&
|
|
222
|
+
type.name === "Expression_1" &&
|
|
223
|
+
(type.typeArguments?.length ?? 0) === 1) {
|
|
224
|
+
const inner = type.typeArguments?.[0];
|
|
225
|
+
if (!inner)
|
|
226
|
+
return undefined;
|
|
227
|
+
if (inner.kind === "functionType")
|
|
228
|
+
return inner;
|
|
229
|
+
return delegateToFunctionType(state, inner);
|
|
230
|
+
}
|
|
231
|
+
const normalized = normalizeToNominal(state, type);
|
|
232
|
+
if (!normalized)
|
|
233
|
+
return undefined;
|
|
234
|
+
const entry = state.unifiedCatalog.getByTypeId(normalized.typeId);
|
|
235
|
+
if (!entry || entry.kind !== "delegate")
|
|
236
|
+
return undefined;
|
|
237
|
+
const invokeMember = state.unifiedCatalog.getMember(normalized.typeId, "Invoke") ??
|
|
238
|
+
state.unifiedCatalog.getMember(normalized.typeId, "invoke");
|
|
239
|
+
const invokeSig = invokeMember?.signatures?.[0];
|
|
240
|
+
if (!invokeSig)
|
|
241
|
+
return undefined;
|
|
242
|
+
const typeParams = state.unifiedCatalog.getTypeParameters(normalized.typeId);
|
|
243
|
+
const subst = new Map();
|
|
244
|
+
for (let i = 0; i < Math.min(typeParams.length, normalized.typeArgs.length); i++) {
|
|
245
|
+
const tp = typeParams[i];
|
|
246
|
+
const arg = normalized.typeArgs[i];
|
|
247
|
+
if (tp && arg)
|
|
248
|
+
subst.set(tp.name, arg);
|
|
249
|
+
}
|
|
250
|
+
const substitute = (t) => subst.size > 0 ? irSubstitute(t, subst) : t;
|
|
251
|
+
const parameters = invokeSig.parameters.map((p) => {
|
|
252
|
+
const paramType = substitute(p.type);
|
|
253
|
+
return {
|
|
254
|
+
kind: "parameter",
|
|
255
|
+
pattern: {
|
|
256
|
+
kind: "identifierPattern",
|
|
257
|
+
name: p.name,
|
|
258
|
+
...(paramType ? { type: paramType } : {}),
|
|
259
|
+
},
|
|
260
|
+
type: paramType,
|
|
261
|
+
initializer: undefined,
|
|
262
|
+
isOptional: p.isOptional,
|
|
263
|
+
isRest: p.isRest,
|
|
264
|
+
passing: p.mode,
|
|
265
|
+
};
|
|
266
|
+
});
|
|
267
|
+
return {
|
|
268
|
+
kind: "functionType",
|
|
269
|
+
parameters,
|
|
270
|
+
returnType: substitute(invokeSig.returnType),
|
|
271
|
+
};
|
|
272
|
+
};
|
|
273
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
274
|
+
// lookupStructuralMember — Structural (object) type member lookup
|
|
275
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
276
|
+
/**
|
|
277
|
+
* Look up a member on a structural (object) type.
|
|
278
|
+
*/
|
|
279
|
+
export const lookupStructuralMember = (state, type, memberName, site) => {
|
|
280
|
+
const addUndefinedToTypeLocal = (t) => {
|
|
281
|
+
const undefinedType = {
|
|
282
|
+
kind: "primitiveType",
|
|
283
|
+
name: "undefined",
|
|
284
|
+
};
|
|
285
|
+
if (t.kind === "unionType") {
|
|
286
|
+
const hasUndefined = t.types.some((x) => x.kind === "primitiveType" && x.name === "undefined");
|
|
287
|
+
return hasUndefined ? t : { ...t, types: [...t.types, undefinedType] };
|
|
288
|
+
}
|
|
289
|
+
return { kind: "unionType", types: [t, undefinedType] };
|
|
290
|
+
};
|
|
291
|
+
if (type.kind === "objectType") {
|
|
292
|
+
const member = type.members.find((m) => m.name === memberName);
|
|
293
|
+
if (member) {
|
|
294
|
+
if (member.kind === "propertySignature") {
|
|
295
|
+
return member.isOptional
|
|
296
|
+
? addUndefinedToTypeLocal(member.type)
|
|
297
|
+
: member.type;
|
|
298
|
+
}
|
|
299
|
+
// Method signature - return function type using the same parameters
|
|
300
|
+
if (member.kind === "methodSignature") {
|
|
301
|
+
const funcType = {
|
|
302
|
+
kind: "functionType",
|
|
303
|
+
parameters: member.parameters,
|
|
304
|
+
returnType: member.returnType ?? voidType,
|
|
305
|
+
};
|
|
306
|
+
return funcType;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
if (type.kind === "referenceType" &&
|
|
311
|
+
type.structuralMembers &&
|
|
312
|
+
type.structuralMembers.length > 0) {
|
|
313
|
+
const member = type.structuralMembers.find((m) => m.name === memberName);
|
|
314
|
+
if (member) {
|
|
315
|
+
if (member.kind === "propertySignature") {
|
|
316
|
+
return member.isOptional
|
|
317
|
+
? addUndefinedToTypeLocal(member.type)
|
|
318
|
+
: member.type;
|
|
319
|
+
}
|
|
320
|
+
if (member.kind === "methodSignature") {
|
|
321
|
+
const funcType = {
|
|
322
|
+
kind: "functionType",
|
|
323
|
+
parameters: member.parameters,
|
|
324
|
+
returnType: member.returnType ?? voidType,
|
|
325
|
+
};
|
|
326
|
+
return funcType;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
emitDiagnostic(state, "TSN5203", `Member '${memberName}' not found on structural type`, site);
|
|
331
|
+
return unknownType;
|
|
332
|
+
};
|
|
333
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
334
|
+
// computeReceiverSubstitution — Receiver type → substitution map
|
|
335
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
336
|
+
/**
|
|
337
|
+
* Compute receiver substitution for a method call.
|
|
338
|
+
*
|
|
339
|
+
* Given a receiver type (e.g., Array<string>) and a declaring type's TS name,
|
|
340
|
+
* computes the substitution map for class type parameters.
|
|
341
|
+
*
|
|
342
|
+
* Phase 6: Uses TypeId-based NominalEnv.getInstantiation().
|
|
343
|
+
*/
|
|
344
|
+
export const computeReceiverSubstitution = (state, receiverType, declaringTypeTsName, _declaringMemberName) => {
|
|
345
|
+
const normalized = normalizeToNominal(state, receiverType);
|
|
346
|
+
if (!normalized)
|
|
347
|
+
return undefined;
|
|
348
|
+
const declaringTypeId = resolveTypeIdByName(state, declaringTypeTsName);
|
|
349
|
+
if (!declaringTypeId)
|
|
350
|
+
return undefined;
|
|
351
|
+
return state.nominalEnv.getInstantiation(normalized.typeId, normalized.typeArgs, declaringTypeId);
|
|
352
|
+
};
|
|
353
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
354
|
+
// inferMethodTypeArgsFromArguments — Generic method type argument inference
|
|
355
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
356
|
+
/**
|
|
357
|
+
* Deterministic type argument inference from call-site arguments.
|
|
358
|
+
*
|
|
359
|
+
* Walks parameter and argument shapes without ambiguity.
|
|
360
|
+
*/
|
|
361
|
+
export const inferMethodTypeArgsFromArguments = (state, methodTypeParams, parameterTypes, argTypes) => {
|
|
362
|
+
if (methodTypeParams.length === 0)
|
|
363
|
+
return new Map();
|
|
364
|
+
const methodTypeParamNames = new Set(methodTypeParams.map((p) => p.name));
|
|
365
|
+
const substitution = new Map();
|
|
366
|
+
const tryUnify = (parameterType, argumentType) => {
|
|
367
|
+
// Method type parameter position: infer directly
|
|
368
|
+
if (parameterType.kind === "typeParameterType") {
|
|
369
|
+
if (!methodTypeParamNames.has(parameterType.name)) {
|
|
370
|
+
// Not a method type parameter (could be outer generic) — ignore
|
|
371
|
+
return true;
|
|
372
|
+
}
|
|
373
|
+
const existing = substitution.get(parameterType.name);
|
|
374
|
+
if (existing) {
|
|
375
|
+
// A self-mapping like `B -> B` can be produced when a lambda argument was typed
|
|
376
|
+
// contextually from the unresolved expected signature. This provides no real
|
|
377
|
+
// inference signal and must not block later concrete inference.
|
|
378
|
+
if (existing.kind === "typeParameterType" &&
|
|
379
|
+
existing.name === parameterType.name) {
|
|
380
|
+
substitution.set(parameterType.name, argumentType);
|
|
381
|
+
return true;
|
|
382
|
+
}
|
|
383
|
+
return typesEqual(existing, argumentType);
|
|
384
|
+
}
|
|
385
|
+
substitution.set(parameterType.name, argumentType);
|
|
386
|
+
return true;
|
|
387
|
+
}
|
|
388
|
+
// Poison/any provides no deterministic information
|
|
389
|
+
if (argumentType.kind === "unknownType" ||
|
|
390
|
+
argumentType.kind === "anyType") {
|
|
391
|
+
return true;
|
|
392
|
+
}
|
|
393
|
+
// Intersection argument types: unify through each constituent.
|
|
394
|
+
//
|
|
395
|
+
// This is required for airplane-grade extension method typing where the receiver
|
|
396
|
+
// often has the form `TShape & <extension markers> & <method table>`.
|
|
397
|
+
// Generic inference must still be able to infer through the real CLR shape in the intersection.
|
|
398
|
+
if (argumentType.kind === "intersectionType") {
|
|
399
|
+
for (const part of argumentType.types) {
|
|
400
|
+
if (!part)
|
|
401
|
+
continue;
|
|
402
|
+
if (!tryUnify(parameterType, part))
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
407
|
+
// Expression<TDelegate> wrapper: infer through the underlying delegate shape.
|
|
408
|
+
// This is required for Queryable APIs that use Expression<Func<...>>.
|
|
409
|
+
if (parameterType.kind === "referenceType" &&
|
|
410
|
+
parameterType.name === "Expression_1" &&
|
|
411
|
+
(parameterType.typeArguments?.length ?? 0) === 1) {
|
|
412
|
+
const inner = parameterType.typeArguments?.[0];
|
|
413
|
+
return inner ? tryUnify(inner, argumentType) : true;
|
|
414
|
+
}
|
|
415
|
+
// Delegate unification: allow deterministic inference through the delegate's
|
|
416
|
+
// Invoke signature when a lambda (functionType) is passed to a CLR delegate
|
|
417
|
+
// parameter (Func/Action/custom delegates).
|
|
418
|
+
//
|
|
419
|
+
// Without this, generic methods like:
|
|
420
|
+
// Select<TResult>(selector: Func<TSource, TResult>)
|
|
421
|
+
// cannot infer TResult from a lambda argument, causing TSN5201/TSN5202.
|
|
422
|
+
if (parameterType.kind === "referenceType" &&
|
|
423
|
+
argumentType.kind === "functionType") {
|
|
424
|
+
const delegateFn = delegateToFunctionType(state, parameterType);
|
|
425
|
+
if (delegateFn)
|
|
426
|
+
return tryUnify(delegateFn, argumentType);
|
|
427
|
+
}
|
|
428
|
+
if (parameterType.kind === "functionType" &&
|
|
429
|
+
argumentType.kind === "referenceType") {
|
|
430
|
+
const delegateFn = delegateToFunctionType(state, argumentType);
|
|
431
|
+
if (delegateFn)
|
|
432
|
+
return tryUnify(parameterType, delegateFn);
|
|
433
|
+
}
|
|
434
|
+
// Array<T> ↔ T[] unification
|
|
435
|
+
if (parameterType.kind === "referenceType" &&
|
|
436
|
+
parameterType.name === "Array" &&
|
|
437
|
+
(parameterType.typeArguments?.length ?? 0) === 1 &&
|
|
438
|
+
argumentType.kind === "arrayType") {
|
|
439
|
+
const elementParam = parameterType.typeArguments?.[0];
|
|
440
|
+
return elementParam
|
|
441
|
+
? tryUnify(elementParam, argumentType.elementType)
|
|
442
|
+
: true;
|
|
443
|
+
}
|
|
444
|
+
// Union parameter type: allow deterministic inference through common nullish unions.
|
|
445
|
+
// Example: constructor(value: T | null) with argument of type T.
|
|
446
|
+
if (parameterType.kind === "unionType") {
|
|
447
|
+
const nonNullish = parameterType.types.filter((t) => t && !isNullishPrimitive(t));
|
|
448
|
+
const nullish = parameterType.types.filter((t) => t && isNullishPrimitive(t));
|
|
449
|
+
const candidates = isNullishPrimitive(argumentType)
|
|
450
|
+
? nullish
|
|
451
|
+
: nonNullish;
|
|
452
|
+
if (candidates.length === 1) {
|
|
453
|
+
const only = candidates[0];
|
|
454
|
+
return only ? tryUnify(only, argumentType) : true;
|
|
455
|
+
}
|
|
456
|
+
// Conservative: ambiguous unions provide no deterministic signal.
|
|
457
|
+
return true;
|
|
458
|
+
}
|
|
459
|
+
if (parameterType.kind === "arrayType" &&
|
|
460
|
+
argumentType.kind === "referenceType" &&
|
|
461
|
+
argumentType.name === "Array" &&
|
|
462
|
+
(argumentType.typeArguments?.length ?? 0) === 1) {
|
|
463
|
+
const elementArg = argumentType.typeArguments?.[0];
|
|
464
|
+
return elementArg
|
|
465
|
+
? tryUnify(parameterType.elementType, elementArg)
|
|
466
|
+
: true;
|
|
467
|
+
}
|
|
468
|
+
// Same-kind structural unification
|
|
469
|
+
if (parameterType.kind !== argumentType.kind) {
|
|
470
|
+
// Type mismatch provides no deterministic inference signal.
|
|
471
|
+
return true;
|
|
472
|
+
}
|
|
473
|
+
switch (parameterType.kind) {
|
|
474
|
+
case "primitiveType":
|
|
475
|
+
return true;
|
|
476
|
+
case "literalType":
|
|
477
|
+
return true;
|
|
478
|
+
case "referenceType": {
|
|
479
|
+
const argRef = argumentType;
|
|
480
|
+
const sameNominal = (() => {
|
|
481
|
+
if (parameterType.typeId && argRef.typeId) {
|
|
482
|
+
return parameterType.typeId.stableId === argRef.typeId.stableId;
|
|
483
|
+
}
|
|
484
|
+
return parameterType.name === argRef.name;
|
|
485
|
+
})();
|
|
486
|
+
// Direct generic unification when the nominals match
|
|
487
|
+
if (sameNominal) {
|
|
488
|
+
const paramArgs = parameterType.typeArguments ?? [];
|
|
489
|
+
const argArgs = argRef.typeArguments ?? [];
|
|
490
|
+
if (paramArgs.length !== argArgs.length)
|
|
491
|
+
return true;
|
|
492
|
+
for (let i = 0; i < paramArgs.length; i++) {
|
|
493
|
+
const pa = paramArgs[i];
|
|
494
|
+
const aa = argArgs[i];
|
|
495
|
+
if (!pa || !aa)
|
|
496
|
+
continue;
|
|
497
|
+
if (!tryUnify(pa, aa))
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
return true;
|
|
501
|
+
}
|
|
502
|
+
// Inheritance/interface unification: allow argumentType to flow through
|
|
503
|
+
// its inheritance chain to the parameter type (e.g., List<T> → IEnumerable<T>).
|
|
504
|
+
const paramNominal = normalizeToNominal(state, parameterType);
|
|
505
|
+
const argNominal = normalizeToNominal(state, argRef);
|
|
506
|
+
if (paramNominal && argNominal) {
|
|
507
|
+
const inst = state.nominalEnv.getInstantiation(argNominal.typeId, argNominal.typeArgs, paramNominal.typeId);
|
|
508
|
+
if (inst) {
|
|
509
|
+
const targetTypeParams = state.unifiedCatalog.getTypeParameters(paramNominal.typeId);
|
|
510
|
+
const instantiatedArgs = targetTypeParams.map((tp) => inst.get(tp.name));
|
|
511
|
+
const paramArgs = parameterType.typeArguments ?? [];
|
|
512
|
+
if (instantiatedArgs.every((t) => t !== undefined) &&
|
|
513
|
+
paramArgs.length === instantiatedArgs.length) {
|
|
514
|
+
for (let i = 0; i < paramArgs.length; i++) {
|
|
515
|
+
const pa = paramArgs[i];
|
|
516
|
+
const aa = instantiatedArgs[i];
|
|
517
|
+
if (!pa || !aa)
|
|
518
|
+
continue;
|
|
519
|
+
if (!tryUnify(pa, aa))
|
|
520
|
+
return false;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
return true;
|
|
526
|
+
}
|
|
527
|
+
case "arrayType":
|
|
528
|
+
return tryUnify(parameterType.elementType, argumentType.elementType);
|
|
529
|
+
case "tupleType": {
|
|
530
|
+
const argTuple = argumentType;
|
|
531
|
+
if (parameterType.elementTypes.length !== argTuple.elementTypes.length) {
|
|
532
|
+
return true;
|
|
533
|
+
}
|
|
534
|
+
for (let i = 0; i < parameterType.elementTypes.length; i++) {
|
|
535
|
+
const pe = parameterType.elementTypes[i];
|
|
536
|
+
const ae = argTuple.elementTypes[i];
|
|
537
|
+
if (!pe || !ae)
|
|
538
|
+
continue;
|
|
539
|
+
if (!tryUnify(pe, ae))
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
return true;
|
|
543
|
+
}
|
|
544
|
+
case "functionType": {
|
|
545
|
+
const argFn = argumentType;
|
|
546
|
+
if (parameterType.parameters.length !== argFn.parameters.length) {
|
|
547
|
+
return true;
|
|
548
|
+
}
|
|
549
|
+
for (let i = 0; i < parameterType.parameters.length; i++) {
|
|
550
|
+
const pp = parameterType.parameters[i];
|
|
551
|
+
const ap = argFn.parameters[i];
|
|
552
|
+
const pt = pp?.type;
|
|
553
|
+
const at = ap?.type;
|
|
554
|
+
if (pt && at) {
|
|
555
|
+
if (!tryUnify(pt, at))
|
|
556
|
+
return false;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
return tryUnify(parameterType.returnType, argFn.returnType);
|
|
560
|
+
}
|
|
561
|
+
case "objectType":
|
|
562
|
+
case "dictionaryType":
|
|
563
|
+
// Conservative: only infer through these when shapes already match exactly.
|
|
564
|
+
return true;
|
|
565
|
+
case "voidType":
|
|
566
|
+
case "neverType":
|
|
567
|
+
return true;
|
|
568
|
+
default:
|
|
569
|
+
return true;
|
|
570
|
+
}
|
|
571
|
+
};
|
|
572
|
+
const pairs = Math.min(parameterTypes.length, argTypes.length);
|
|
573
|
+
for (let i = 0; i < pairs; i++) {
|
|
574
|
+
const paramType = parameterTypes[i];
|
|
575
|
+
const argType = argTypes[i];
|
|
576
|
+
if (!paramType || !argType)
|
|
577
|
+
continue;
|
|
578
|
+
if (!tryUnify(paramType, argType))
|
|
579
|
+
return undefined;
|
|
580
|
+
}
|
|
581
|
+
return substitution;
|
|
582
|
+
};
|
|
583
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
584
|
+
// mapEntriesEqual — Pure helper for map comparison
|
|
585
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
586
|
+
export const mapEntriesEqual = (left, right) => {
|
|
587
|
+
if (left.size !== right.size)
|
|
588
|
+
return false;
|
|
589
|
+
for (const [key, leftValue] of left) {
|
|
590
|
+
const rightValue = right.get(key);
|
|
591
|
+
if (!rightValue || !typesEqual(leftValue, rightValue))
|
|
592
|
+
return false;
|
|
593
|
+
}
|
|
594
|
+
return true;
|
|
595
|
+
};
|
|
596
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
597
|
+
// collectExpectedReturnCandidates — Return type candidate expansion
|
|
598
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
599
|
+
export const collectExpectedReturnCandidates = (state, type) => {
|
|
600
|
+
const queue = [type];
|
|
601
|
+
const out = [];
|
|
602
|
+
const seen = new Set();
|
|
603
|
+
const enqueue = (candidate) => {
|
|
604
|
+
if (!candidate)
|
|
605
|
+
return;
|
|
606
|
+
const key = stableIrTypeKey(candidate);
|
|
607
|
+
if (seen.has(key))
|
|
608
|
+
return;
|
|
609
|
+
seen.add(key);
|
|
610
|
+
queue.push(candidate);
|
|
611
|
+
};
|
|
612
|
+
while (queue.length > 0) {
|
|
613
|
+
const current = queue.shift();
|
|
614
|
+
if (!current)
|
|
615
|
+
continue;
|
|
616
|
+
out.push(current);
|
|
617
|
+
if (current.kind === "unionType") {
|
|
618
|
+
for (const member of current.types)
|
|
619
|
+
enqueue(member);
|
|
620
|
+
continue;
|
|
621
|
+
}
|
|
622
|
+
if (current.kind === "referenceType" && current.typeArguments) {
|
|
623
|
+
const typeId = current.typeId ??
|
|
624
|
+
resolveTypeIdByName(state, current.resolvedClrType ?? current.name, current.typeArguments.length);
|
|
625
|
+
if (typeId) {
|
|
626
|
+
const entry = state.unifiedCatalog.getByTypeId(typeId);
|
|
627
|
+
if (entry?.aliasedType) {
|
|
628
|
+
const aliasSubst = new Map();
|
|
629
|
+
const aliasTypeParams = entry.typeParameters;
|
|
630
|
+
const aliasTypeArgs = current.typeArguments;
|
|
631
|
+
for (let i = 0; i < Math.min(aliasTypeParams.length, aliasTypeArgs.length); i++) {
|
|
632
|
+
const tp = aliasTypeParams[i];
|
|
633
|
+
const ta = aliasTypeArgs[i];
|
|
634
|
+
if (tp && ta)
|
|
635
|
+
aliasSubst.set(tp.name, ta);
|
|
636
|
+
}
|
|
637
|
+
const expanded = aliasSubst.size > 0
|
|
638
|
+
? irSubstitute(entry.aliasedType, aliasSubst)
|
|
639
|
+
: entry.aliasedType;
|
|
640
|
+
enqueue(expanded);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
enqueue(unwrapAsyncWrapperType(current));
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
return out;
|
|
647
|
+
};
|
|
648
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
649
|
+
// containsMethodTypeParameter — Pure recursive type parameter check
|
|
650
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
651
|
+
export const containsMethodTypeParameter = (type, unresolved) => {
|
|
652
|
+
if (type.kind === "typeParameterType")
|
|
653
|
+
return unresolved.has(type.name);
|
|
654
|
+
if (type.kind === "referenceType") {
|
|
655
|
+
return (type.typeArguments ?? []).some((t) => t ? containsMethodTypeParameter(t, unresolved) : false);
|
|
656
|
+
}
|
|
657
|
+
if (type.kind === "arrayType") {
|
|
658
|
+
return containsMethodTypeParameter(type.elementType, unresolved);
|
|
659
|
+
}
|
|
660
|
+
if (type.kind === "tupleType") {
|
|
661
|
+
return type.elementTypes.some((t) => t ? containsMethodTypeParameter(t, unresolved) : false);
|
|
662
|
+
}
|
|
663
|
+
if (type.kind === "functionType") {
|
|
664
|
+
const paramsContain = type.parameters.some((p) => p.type ? containsMethodTypeParameter(p.type, unresolved) : false);
|
|
665
|
+
return (paramsContain || containsMethodTypeParameter(type.returnType, unresolved));
|
|
666
|
+
}
|
|
667
|
+
if (type.kind === "unionType" || type.kind === "intersectionType") {
|
|
668
|
+
return type.types.some((t) => t ? containsMethodTypeParameter(t, unresolved) : false);
|
|
669
|
+
}
|
|
670
|
+
if (type.kind === "objectType") {
|
|
671
|
+
return type.members.some((m) => {
|
|
672
|
+
if (m.kind === "propertySignature") {
|
|
673
|
+
return containsMethodTypeParameter(m.type, unresolved);
|
|
674
|
+
}
|
|
675
|
+
if (m.kind === "methodSignature") {
|
|
676
|
+
const paramsContain = m.parameters.some((p) => p.type ? containsMethodTypeParameter(p.type, unresolved) : false);
|
|
677
|
+
return (paramsContain ||
|
|
678
|
+
(m.returnType
|
|
679
|
+
? containsMethodTypeParameter(m.returnType, unresolved)
|
|
680
|
+
: false));
|
|
681
|
+
}
|
|
682
|
+
return false;
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
return false;
|
|
686
|
+
};
|
|
687
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
688
|
+
// normalizeCatalogTsName — Pure catalog name normalization
|
|
689
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
690
|
+
export const normalizeCatalogTsName = (name) => {
|
|
691
|
+
if (name.endsWith("$instance"))
|
|
692
|
+
return name.slice(0, -"$instance".length);
|
|
693
|
+
if (name.startsWith("__") && name.endsWith("$views")) {
|
|
694
|
+
return name.slice("__".length, -"$views".length);
|
|
695
|
+
}
|
|
696
|
+
return name;
|
|
697
|
+
};
|
|
698
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
699
|
+
// isArityCompatible — Pure arity check for overload resolution
|
|
700
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
701
|
+
export const isArityCompatible = (signature, argumentCount) => {
|
|
702
|
+
const params = signature.parameters;
|
|
703
|
+
if (params.length === 0)
|
|
704
|
+
return argumentCount === 0;
|
|
705
|
+
// Rest parameter can absorb any extra args.
|
|
706
|
+
const restIndex = params.findIndex((p) => p.isRest);
|
|
707
|
+
if (restIndex >= 0) {
|
|
708
|
+
// Only support `...rest` in the last position.
|
|
709
|
+
if (restIndex !== params.length - 1)
|
|
710
|
+
return false;
|
|
711
|
+
// Must supply all non-rest parameters.
|
|
712
|
+
if (argumentCount < restIndex)
|
|
713
|
+
return false;
|
|
714
|
+
return true;
|
|
715
|
+
}
|
|
716
|
+
// Too many args for non-rest signature.
|
|
717
|
+
if (argumentCount > params.length)
|
|
718
|
+
return false;
|
|
719
|
+
// Missing args must correspond to optional parameters.
|
|
720
|
+
for (let i = argumentCount; i < params.length; i++) {
|
|
721
|
+
const p = params[i];
|
|
722
|
+
if (!p || !p.isOptional)
|
|
723
|
+
return false;
|
|
724
|
+
}
|
|
725
|
+
return true;
|
|
726
|
+
};
|
|
727
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
728
|
+
// scoreSignatureMatch — Overload scoring
|
|
729
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
730
|
+
export const scoreSignatureMatch = (state, parameterTypes, argTypes, argumentCount) => {
|
|
731
|
+
let score = 0;
|
|
732
|
+
const pairs = Math.min(argumentCount, parameterTypes.length, argTypes.length);
|
|
733
|
+
for (let i = 0; i < pairs; i++) {
|
|
734
|
+
const pt = parameterTypes[i];
|
|
735
|
+
const at = argTypes[i];
|
|
736
|
+
if (!pt || !at)
|
|
737
|
+
continue;
|
|
738
|
+
if (typesEqual(pt, at)) {
|
|
739
|
+
score += 3;
|
|
740
|
+
continue;
|
|
741
|
+
}
|
|
742
|
+
const pNom = normalizeToNominal(state, pt);
|
|
743
|
+
const aNom = normalizeToNominal(state, at);
|
|
744
|
+
if (!pNom || !aNom)
|
|
745
|
+
continue;
|
|
746
|
+
if (pNom.typeId.stableId === aNom.typeId.stableId) {
|
|
747
|
+
score += 2;
|
|
748
|
+
continue;
|
|
749
|
+
}
|
|
750
|
+
const inst = state.nominalEnv.getInstantiation(aNom.typeId, aNom.typeArgs, pNom.typeId);
|
|
751
|
+
if (inst)
|
|
752
|
+
score += 1;
|
|
753
|
+
}
|
|
754
|
+
return score;
|
|
755
|
+
};
|
|
756
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
757
|
+
// tryResolveCallFromUnifiedCatalog — Assembly-origin overload resolution
|
|
758
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
759
|
+
export const tryResolveCallFromUnifiedCatalog = (state, declaringTypeTsName, declaringMemberName, query) => {
|
|
760
|
+
const { argumentCount, receiverType, explicitTypeArgs, argTypes } = query;
|
|
761
|
+
if (!argTypes)
|
|
762
|
+
return undefined;
|
|
763
|
+
if (argTypes.length < argumentCount)
|
|
764
|
+
return undefined;
|
|
765
|
+
for (let i = 0; i < argumentCount; i++) {
|
|
766
|
+
if (!argTypes[i])
|
|
767
|
+
return undefined;
|
|
768
|
+
}
|
|
769
|
+
const catalogTypeName = normalizeCatalogTsName(declaringTypeTsName);
|
|
770
|
+
const declaringTypeId = resolveTypeIdByName(state, catalogTypeName);
|
|
771
|
+
if (!declaringTypeId)
|
|
772
|
+
return undefined;
|
|
773
|
+
const entry = state.unifiedCatalog.getByTypeId(declaringTypeId);
|
|
774
|
+
if (!entry || entry.origin !== "assembly")
|
|
775
|
+
return undefined;
|
|
776
|
+
const member = state.unifiedCatalog.getMember(declaringTypeId, declaringMemberName);
|
|
777
|
+
const candidates = member?.signatures;
|
|
778
|
+
if (!candidates || candidates.length === 0)
|
|
779
|
+
return undefined;
|
|
780
|
+
const resolveCandidate = (signature) => {
|
|
781
|
+
if (!isArityCompatible(signature, argumentCount))
|
|
782
|
+
return undefined;
|
|
783
|
+
let workingParams = signature.parameters.map((p) => p.type);
|
|
784
|
+
let workingReturn = signature.returnType;
|
|
785
|
+
// Receiver substitution (class type params) for instance calls.
|
|
786
|
+
if (receiverType) {
|
|
787
|
+
const receiverSubst = computeReceiverSubstitution(state, receiverType, catalogTypeName, declaringMemberName);
|
|
788
|
+
if (receiverSubst && receiverSubst.size > 0) {
|
|
789
|
+
workingParams = workingParams.map((p) => irSubstitute(p, receiverSubst));
|
|
790
|
+
workingReturn = irSubstitute(workingReturn, receiverSubst);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
// Method type parameter substitution.
|
|
794
|
+
const methodTypeParams = signature.typeParameters.map((tp) => ({
|
|
795
|
+
name: tp.name,
|
|
796
|
+
constraint: tp.constraint,
|
|
797
|
+
defaultType: tp.defaultType,
|
|
798
|
+
}));
|
|
799
|
+
if (methodTypeParams.length > 0) {
|
|
800
|
+
const callSubst = new Map();
|
|
801
|
+
if (explicitTypeArgs) {
|
|
802
|
+
for (let i = 0; i < Math.min(explicitTypeArgs.length, methodTypeParams.length); i++) {
|
|
803
|
+
const param = methodTypeParams[i];
|
|
804
|
+
const arg = explicitTypeArgs[i];
|
|
805
|
+
if (param && arg) {
|
|
806
|
+
callSubst.set(param.name, arg);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
const paramsForInference = callSubst.size > 0
|
|
811
|
+
? workingParams.map((p) => irSubstitute(p, callSubst))
|
|
812
|
+
: workingParams;
|
|
813
|
+
const inferred = inferMethodTypeArgsFromArguments(state, methodTypeParams, paramsForInference, argTypes);
|
|
814
|
+
if (!inferred)
|
|
815
|
+
return undefined;
|
|
816
|
+
for (const [name, inferredType] of inferred) {
|
|
817
|
+
const existing = callSubst.get(name);
|
|
818
|
+
if (existing) {
|
|
819
|
+
if (!typesEqual(existing, inferredType))
|
|
820
|
+
return undefined;
|
|
821
|
+
continue;
|
|
822
|
+
}
|
|
823
|
+
callSubst.set(name, inferredType);
|
|
824
|
+
}
|
|
825
|
+
for (const tp of methodTypeParams) {
|
|
826
|
+
if (!callSubst.has(tp.name) && tp.defaultType) {
|
|
827
|
+
callSubst.set(tp.name, tp.defaultType);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
if (callSubst.size > 0) {
|
|
831
|
+
workingParams = workingParams.map((p) => irSubstitute(p, callSubst));
|
|
832
|
+
workingReturn = irSubstitute(workingReturn, callSubst);
|
|
833
|
+
}
|
|
834
|
+
const unresolved = new Set(methodTypeParams
|
|
835
|
+
.map((tp) => tp.name)
|
|
836
|
+
.filter((name) => !callSubst.has(name)));
|
|
837
|
+
if (unresolved.size > 0 &&
|
|
838
|
+
containsMethodTypeParameter(workingReturn, unresolved)) {
|
|
839
|
+
return undefined;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
return {
|
|
843
|
+
parameterTypes: workingParams,
|
|
844
|
+
parameterModes: signature.parameters.map((p) => p.mode),
|
|
845
|
+
returnType: workingReturn,
|
|
846
|
+
typePredicate: undefined,
|
|
847
|
+
diagnostics: [],
|
|
848
|
+
};
|
|
849
|
+
};
|
|
850
|
+
let best;
|
|
851
|
+
for (const sig of candidates) {
|
|
852
|
+
const resolved = resolveCandidate(sig);
|
|
853
|
+
if (!resolved)
|
|
854
|
+
continue;
|
|
855
|
+
if (resolved.returnType.kind === "unknownType")
|
|
856
|
+
continue;
|
|
857
|
+
const candidate = {
|
|
858
|
+
resolved,
|
|
859
|
+
score: scoreSignatureMatch(state, resolved.parameterTypes, argTypes, argumentCount),
|
|
860
|
+
typeParamCount: sig.typeParameters.length,
|
|
861
|
+
parameterCount: sig.parameters.length,
|
|
862
|
+
stableId: sig.stableId,
|
|
863
|
+
};
|
|
864
|
+
if (!best) {
|
|
865
|
+
best = candidate;
|
|
866
|
+
continue;
|
|
867
|
+
}
|
|
868
|
+
const better = candidate.score > best.score ||
|
|
869
|
+
(candidate.score === best.score &&
|
|
870
|
+
candidate.typeParamCount < best.typeParamCount) ||
|
|
871
|
+
(candidate.score === best.score &&
|
|
872
|
+
candidate.typeParamCount === best.typeParamCount &&
|
|
873
|
+
candidate.parameterCount < best.parameterCount) ||
|
|
874
|
+
(candidate.score === best.score &&
|
|
875
|
+
candidate.typeParamCount === best.typeParamCount &&
|
|
876
|
+
candidate.parameterCount === best.parameterCount &&
|
|
877
|
+
candidate.stableId < best.stableId);
|
|
878
|
+
if (better)
|
|
879
|
+
best = candidate;
|
|
880
|
+
}
|
|
881
|
+
return best?.resolved;
|
|
882
|
+
};
|
|
883
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
884
|
+
// resolveCall — Main entry point for call resolution
|
|
885
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
886
|
+
export const resolveCall = (state, query) => {
|
|
887
|
+
const { sigId, argumentCount, receiverType, explicitTypeArgs, argTypes, expectedReturnType, site, } = query;
|
|
888
|
+
// Extension method scopes are modeled as TS-only wrapper types (e.g. __TsonicExt_Ef<T>).
|
|
889
|
+
// They must erase to their underlying CLR shapes for deterministic call inference.
|
|
890
|
+
const effectiveReceiverType = receiverType
|
|
891
|
+
? stripTsonicExtensionWrappers(receiverType)
|
|
892
|
+
: undefined;
|
|
893
|
+
// 1. Load raw signature (cached)
|
|
894
|
+
const rawSig = getRawSignature(state, sigId);
|
|
895
|
+
if (!rawSig) {
|
|
896
|
+
// BINDING CONTRACT VIOLATION (Alice's spec): If Binding returned a
|
|
897
|
+
// SignatureId, HandleRegistry.getSignature(sigId) MUST succeed.
|
|
898
|
+
// This indicates a bug in Binding, not a normal runtime condition.
|
|
899
|
+
//
|
|
900
|
+
// However, we cannot throw during normal compilation as it would
|
|
901
|
+
// crash the compiler. Instead, emit diagnostic and return poisoned
|
|
902
|
+
// result with correct arity.
|
|
903
|
+
emitDiagnostic(state, "TSN5203", `Cannot resolve signature (Binding contract violation: ID ${sigId.id} not in HandleRegistry)`, site);
|
|
904
|
+
return poisonedCall(argumentCount, state.diagnostics.slice());
|
|
905
|
+
}
|
|
906
|
+
// 2. Start with raw types
|
|
907
|
+
let workingParams = [...rawSig.parameterTypes];
|
|
908
|
+
let workingThisParam = rawSig.thisParameterType;
|
|
909
|
+
let workingReturn = rawSig.returnType;
|
|
910
|
+
let workingPredicate = rawSig.typePredicate;
|
|
911
|
+
// 3. Compute receiver substitution (class type params)
|
|
912
|
+
if (effectiveReceiverType &&
|
|
913
|
+
rawSig.declaringTypeTsName &&
|
|
914
|
+
rawSig.declaringMemberName) {
|
|
915
|
+
const receiverSubst = computeReceiverSubstitution(state, effectiveReceiverType, rawSig.declaringTypeTsName, rawSig.declaringMemberName);
|
|
916
|
+
if (receiverSubst && receiverSubst.size > 0) {
|
|
917
|
+
workingParams = workingParams.map((p) => p ? irSubstitute(p, receiverSubst) : undefined);
|
|
918
|
+
if (workingThisParam) {
|
|
919
|
+
workingThisParam = irSubstitute(workingThisParam, receiverSubst);
|
|
920
|
+
}
|
|
921
|
+
workingReturn = irSubstitute(workingReturn, receiverSubst);
|
|
922
|
+
if (workingPredicate) {
|
|
923
|
+
workingPredicate =
|
|
924
|
+
workingPredicate.kind === "param"
|
|
925
|
+
? {
|
|
926
|
+
...workingPredicate,
|
|
927
|
+
targetType: irSubstitute(workingPredicate.targetType, receiverSubst),
|
|
928
|
+
}
|
|
929
|
+
: {
|
|
930
|
+
...workingPredicate,
|
|
931
|
+
targetType: irSubstitute(workingPredicate.targetType, receiverSubst),
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
// 4. Compute call substitution (method type params)
|
|
937
|
+
const methodTypeParams = rawSig.typeParameters;
|
|
938
|
+
if (methodTypeParams.length > 0) {
|
|
939
|
+
const callSubst = new Map();
|
|
940
|
+
// Source 1: Explicit type args from call syntax
|
|
941
|
+
if (explicitTypeArgs) {
|
|
942
|
+
for (let i = 0; i < Math.min(explicitTypeArgs.length, methodTypeParams.length); i++) {
|
|
943
|
+
const param = methodTypeParams[i];
|
|
944
|
+
const arg = explicitTypeArgs[i];
|
|
945
|
+
if (param && arg) {
|
|
946
|
+
callSubst.set(param.name, arg);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
// Source 2: Deterministic argument-driven unification
|
|
951
|
+
// 2a) Receiver-driven unification via TS `this:` parameter
|
|
952
|
+
//
|
|
953
|
+
// Method-table extension typing represents the receiver as an explicit `this:` parameter
|
|
954
|
+
// in the `.d.ts` signature. Generic methods like:
|
|
955
|
+
// ToArrayAsync<T>(this: IQueryable<T>, ...): Task<T[]>
|
|
956
|
+
// must infer T from the receiver even when there are ZERO call arguments.
|
|
957
|
+
//
|
|
958
|
+
// This is airplane-grade determinism: we anchor inference to the selected TS signature's
|
|
959
|
+
// `this:` type and the IR receiver type (not TS structural tricks).
|
|
960
|
+
if (effectiveReceiverType && workingThisParam) {
|
|
961
|
+
const receiverParamForInference = callSubst.size > 0
|
|
962
|
+
? irSubstitute(workingThisParam, callSubst)
|
|
963
|
+
: workingThisParam;
|
|
964
|
+
const inferredFromReceiver = inferMethodTypeArgsFromArguments(state, methodTypeParams, [receiverParamForInference], [effectiveReceiverType]);
|
|
965
|
+
if (inferredFromReceiver) {
|
|
966
|
+
for (const [name, inferredType] of inferredFromReceiver) {
|
|
967
|
+
const existing = callSubst.get(name);
|
|
968
|
+
if (existing) {
|
|
969
|
+
if (!typesEqual(existing, inferredType)) {
|
|
970
|
+
emitDiagnostic(state, "TSN5202", `Conflicting type argument inference for '${name}' (receiver)`, site);
|
|
971
|
+
return poisonedCall(argumentCount, state.diagnostics.slice());
|
|
972
|
+
}
|
|
973
|
+
continue;
|
|
974
|
+
}
|
|
975
|
+
callSubst.set(name, inferredType);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
// 2b) Argument-driven unification (run even when argTypes is empty).
|
|
980
|
+
if (argTypes) {
|
|
981
|
+
const paramsForInference = callSubst.size > 0
|
|
982
|
+
? workingParams.map((p) => p ? irSubstitute(p, callSubst) : undefined)
|
|
983
|
+
: workingParams;
|
|
984
|
+
const inferred = inferMethodTypeArgsFromArguments(state, methodTypeParams, paramsForInference, argTypes);
|
|
985
|
+
if (!inferred) {
|
|
986
|
+
emitDiagnostic(state, "TSN5202", "Type arguments cannot be inferred deterministically from arguments", site);
|
|
987
|
+
return poisonedCall(argumentCount, state.diagnostics.slice());
|
|
988
|
+
}
|
|
989
|
+
for (const [name, inferredType] of inferred) {
|
|
990
|
+
const existing = callSubst.get(name);
|
|
991
|
+
if (existing) {
|
|
992
|
+
if (!typesEqual(existing, inferredType)) {
|
|
993
|
+
emitDiagnostic(state, "TSN5202", `Conflicting type argument inference for '${name}'`, site);
|
|
994
|
+
return poisonedCall(argumentCount, state.diagnostics.slice());
|
|
995
|
+
}
|
|
996
|
+
continue;
|
|
997
|
+
}
|
|
998
|
+
callSubst.set(name, inferredType);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
// Source 3: Contextual expected return type from the call site.
|
|
1002
|
+
// This handles generic APIs where method type parameters appear only in
|
|
1003
|
+
// the return position (or where argument inference is intentionally weak).
|
|
1004
|
+
if (expectedReturnType) {
|
|
1005
|
+
const returnForInference = callSubst.size > 0
|
|
1006
|
+
? irSubstitute(workingReturn, callSubst)
|
|
1007
|
+
: workingReturn;
|
|
1008
|
+
const expectedCandidates = collectExpectedReturnCandidates(state, expectedReturnType);
|
|
1009
|
+
let matched;
|
|
1010
|
+
for (const candidate of expectedCandidates) {
|
|
1011
|
+
const inferred = inferMethodTypeArgsFromArguments(state, methodTypeParams, [returnForInference], [candidate]);
|
|
1012
|
+
if (!inferred || inferred.size === 0)
|
|
1013
|
+
continue;
|
|
1014
|
+
let conflictsWithExisting = false;
|
|
1015
|
+
for (const [name, inferredType] of inferred) {
|
|
1016
|
+
const existing = callSubst.get(name);
|
|
1017
|
+
if (existing && !typesEqual(existing, inferredType)) {
|
|
1018
|
+
conflictsWithExisting = true;
|
|
1019
|
+
break;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
if (conflictsWithExisting)
|
|
1023
|
+
continue;
|
|
1024
|
+
if (matched && !mapEntriesEqual(matched, inferred)) {
|
|
1025
|
+
// Ambiguous contextual-return inference: ignore this source and
|
|
1026
|
+
// rely on explicit/argument/default inference only.
|
|
1027
|
+
matched = undefined;
|
|
1028
|
+
break;
|
|
1029
|
+
}
|
|
1030
|
+
matched = inferred;
|
|
1031
|
+
}
|
|
1032
|
+
if (matched) {
|
|
1033
|
+
for (const [name, inferredType] of matched) {
|
|
1034
|
+
const existing = callSubst.get(name);
|
|
1035
|
+
if (existing) {
|
|
1036
|
+
if (!typesEqual(existing, inferredType)) {
|
|
1037
|
+
emitDiagnostic(state, "TSN5202", `Conflicting type argument inference for '${name}' (expected return context)`, site);
|
|
1038
|
+
return poisonedCall(argumentCount, state.diagnostics.slice());
|
|
1039
|
+
}
|
|
1040
|
+
continue;
|
|
1041
|
+
}
|
|
1042
|
+
callSubst.set(name, inferredType);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
// Source 4: Default type parameters
|
|
1047
|
+
for (const tp of methodTypeParams) {
|
|
1048
|
+
if (!callSubst.has(tp.name) && tp.defaultType) {
|
|
1049
|
+
callSubst.set(tp.name, tp.defaultType);
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
// Apply call substitution
|
|
1053
|
+
if (callSubst.size > 0) {
|
|
1054
|
+
workingParams = workingParams.map((p) => p ? irSubstitute(p, callSubst) : undefined);
|
|
1055
|
+
workingReturn = irSubstitute(workingReturn, callSubst);
|
|
1056
|
+
if (workingPredicate) {
|
|
1057
|
+
workingPredicate =
|
|
1058
|
+
workingPredicate.kind === "param"
|
|
1059
|
+
? {
|
|
1060
|
+
...workingPredicate,
|
|
1061
|
+
targetType: irSubstitute(workingPredicate.targetType, callSubst),
|
|
1062
|
+
}
|
|
1063
|
+
: {
|
|
1064
|
+
...workingPredicate,
|
|
1065
|
+
targetType: irSubstitute(workingPredicate.targetType, callSubst),
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
// Check for unresolved method type parameters (after explicit/arg/default inference)
|
|
1070
|
+
const unresolved = new Set(methodTypeParams
|
|
1071
|
+
.map((tp) => tp.name)
|
|
1072
|
+
.filter((name) => !callSubst.has(name)));
|
|
1073
|
+
if (unresolved.size > 0 &&
|
|
1074
|
+
containsMethodTypeParameter(workingReturn, unresolved)) {
|
|
1075
|
+
const fallback = argTypes && rawSig.declaringTypeTsName && rawSig.declaringMemberName
|
|
1076
|
+
? tryResolveCallFromUnifiedCatalog(state, rawSig.declaringTypeTsName, rawSig.declaringMemberName, query)
|
|
1077
|
+
: undefined;
|
|
1078
|
+
if (fallback) {
|
|
1079
|
+
return fallback;
|
|
1080
|
+
}
|
|
1081
|
+
emitDiagnostic(state, "TSN5202", "Return type contains unresolved type parameters - explicit type arguments required", site);
|
|
1082
|
+
workingReturn = unknownType;
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
const resolved = {
|
|
1086
|
+
parameterTypes: workingParams,
|
|
1087
|
+
parameterModes: rawSig.parameterModes,
|
|
1088
|
+
returnType: workingReturn,
|
|
1089
|
+
typePredicate: workingPredicate,
|
|
1090
|
+
diagnostics: [],
|
|
1091
|
+
};
|
|
1092
|
+
// CLR overload correction (airplane-grade determinism):
|
|
1093
|
+
//
|
|
1094
|
+
// TypeScript cannot always select the correct overload for CLR APIs because some
|
|
1095
|
+
// Tsonic surface types intentionally erase to TS primitives (e.g., `char` is `string`
|
|
1096
|
+
// in @tsonic/core for TSC compatibility). This can cause TS to resolve calls like
|
|
1097
|
+
// Console.writeLine("Hello") to a `char` overload, which is semantically invalid.
|
|
1098
|
+
//
|
|
1099
|
+
// When we have full argument types, and the call targets an assembly-origin type,
|
|
1100
|
+
// prefer the best matching overload from the UnifiedTypeCatalog if it scores higher
|
|
1101
|
+
// than the TS-selected signature.
|
|
1102
|
+
if (!resolved.typePredicate &&
|
|
1103
|
+
argTypes &&
|
|
1104
|
+
rawSig.declaringTypeTsName &&
|
|
1105
|
+
rawSig.declaringMemberName) {
|
|
1106
|
+
const hasAllArgTypes = argTypes.length >= argumentCount &&
|
|
1107
|
+
Array.from({ length: argumentCount }, (_, i) => argTypes[i]).every((t) => t !== undefined);
|
|
1108
|
+
if (hasAllArgTypes) {
|
|
1109
|
+
const catalogResolved = tryResolveCallFromUnifiedCatalog(state, rawSig.declaringTypeTsName, rawSig.declaringMemberName, query);
|
|
1110
|
+
if (catalogResolved) {
|
|
1111
|
+
const currentScore = scoreSignatureMatch(state, resolved.parameterTypes, argTypes, argumentCount);
|
|
1112
|
+
const catalogScore = scoreSignatureMatch(state, catalogResolved.parameterTypes, argTypes, argumentCount);
|
|
1113
|
+
if (catalogScore > currentScore) {
|
|
1114
|
+
return catalogResolved;
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
return resolved;
|
|
1120
|
+
};
|
|
1121
|
+
//# sourceMappingURL=type-system-call-resolution.js.map
|