@tsonic/frontend 0.0.31 → 0.0.33
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/dotnet-metadata.d.ts +47 -5
- package/dist/dotnet-metadata.d.ts.map +1 -1
- package/dist/dotnet-metadata.js +131 -31
- package/dist/dotnet-metadata.js.map +1 -1
- package/dist/dotnet-metadata.test.d.ts +2 -0
- package/dist/dotnet-metadata.test.d.ts.map +1 -0
- package/dist/dotnet-metadata.test.js +121 -0
- package/dist/dotnet-metadata.test.js.map +1 -0
- package/dist/ir/converters/expressions/calls.d.ts.map +1 -1
- package/dist/ir/converters/expressions/calls.js +33 -0
- package/dist/ir/converters/expressions/calls.js.map +1 -1
- package/dist/ir/converters/expressions/operators.js +2 -2
- package/dist/ir/converters/expressions/operators.js.map +1 -1
- package/dist/ir/converters/flow-narrowing.d.ts +4 -3
- package/dist/ir/converters/flow-narrowing.d.ts.map +1 -1
- package/dist/ir/converters/flow-narrowing.js +28 -5
- package/dist/ir/converters/flow-narrowing.js.map +1 -1
- package/dist/ir/converters/statements/control/conditionals.js +3 -3
- package/dist/ir/converters/statements/control/conditionals.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/methods.d.ts +8 -1
- package/dist/ir/converters/statements/declarations/classes/methods.d.ts.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/methods.js +730 -57
- 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 +38 -9
- package/dist/ir/converters/statements/declarations/classes/orchestrator.js.map +1 -1
- package/dist/ir/converters/statements/declarations/classes/override-detection.d.ts +8 -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 +101 -13
- 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 +17 -2
- package/dist/ir/converters/statements/declarations/classes/properties.js.map +1 -1
- package/dist/ir/types/helpers.d.ts +1 -1
- package/dist/ir/types/helpers.d.ts.map +1 -1
- package/dist/ir/types/index.d.ts +1 -1
- package/dist/ir/types/index.d.ts.map +1 -1
- package/dist/ir/types/index.js.map +1 -1
- package/dist/ir/types/ir-types.d.ts +5 -1
- package/dist/ir/types/ir-types.d.ts.map +1 -1
- package/dist/ir/types/statements.d.ts +5 -4
- 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 +22 -3
- package/dist/ir/validation/anonymous-type-lowering-pass.js.map +1 -1
- package/dist/ir/validation/attribute-collection-pass.d.ts.map +1 -1
- package/dist/ir/validation/attribute-collection-pass.js +28 -2
- package/dist/ir/validation/attribute-collection-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 +13 -3
- package/dist/ir/validation/numeric-coercion-pass.js.map +1 -1
- package/dist/ir/validation/numeric-coercion-pass.test.d.ts +2 -0
- package/dist/ir/validation/numeric-coercion-pass.test.d.ts.map +1 -0
- package/dist/ir/validation/numeric-coercion-pass.test.js +53 -0
- package/dist/ir/validation/numeric-coercion-pass.test.js.map +1 -0
- package/dist/ir/validation/rest-type-synthesis-pass.d.ts.map +1 -1
- package/dist/ir/validation/rest-type-synthesis-pass.js +70 -22
- 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 +5 -0
- package/dist/ir/validation/soundness-gate.js.map +1 -1
- package/dist/ir/validation/virtual-marking-pass.d.ts +2 -2
- package/dist/ir/validation/virtual-marking-pass.d.ts.map +1 -1
- package/dist/ir/validation/virtual-marking-pass.js +26 -6
- package/dist/ir/validation/virtual-marking-pass.js.map +1 -1
- package/dist/program/bindings.d.ts +8 -0
- package/dist/program/bindings.d.ts.map +1 -1
- package/dist/program/bindings.js +37 -3
- package/dist/program/bindings.js.map +1 -1
- package/dist/program/dependency-graph.d.ts.map +1 -1
- package/dist/program/dependency-graph.js +9 -1
- package/dist/program/dependency-graph.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 +2 -0
- package/dist/validation/core-intrinsics.js.map +1 -1
- package/package.json +1 -1
|
@@ -5,66 +5,23 @@ import * as ts from "typescript";
|
|
|
5
5
|
import { convertBlockStatement } from "../../control.js";
|
|
6
6
|
import { hasStaticModifier, getAccessibility, convertTypeParameters, convertParameters, } from "../../helpers.js";
|
|
7
7
|
import { detectOverride } from "./override-detection.js";
|
|
8
|
-
/**
|
|
9
|
-
* DETERMINISTIC: Convert a TypeNode to a string for signature matching.
|
|
10
|
-
* Uses only AST structure, not TypeScript's type inference.
|
|
11
|
-
*/
|
|
12
|
-
const typeNodeToSignatureString = (typeNode) => {
|
|
13
|
-
// Handle type references: Foo, List<T>, etc.
|
|
14
|
-
if (ts.isTypeReferenceNode(typeNode)) {
|
|
15
|
-
// EntityName is Identifier | QualifiedName - handle both
|
|
16
|
-
const name = ts.isIdentifier(typeNode.typeName)
|
|
17
|
-
? typeNode.typeName.text
|
|
18
|
-
: typeNode.typeName.right.text; // QualifiedName: get rightmost identifier
|
|
19
|
-
return name;
|
|
20
|
-
}
|
|
21
|
-
// Handle keyword types
|
|
22
|
-
switch (typeNode.kind) {
|
|
23
|
-
case ts.SyntaxKind.NumberKeyword:
|
|
24
|
-
return "number";
|
|
25
|
-
case ts.SyntaxKind.StringKeyword:
|
|
26
|
-
return "string";
|
|
27
|
-
case ts.SyntaxKind.BooleanKeyword:
|
|
28
|
-
return "boolean";
|
|
29
|
-
case ts.SyntaxKind.VoidKeyword:
|
|
30
|
-
return "void";
|
|
31
|
-
case ts.SyntaxKind.AnyKeyword:
|
|
32
|
-
return "any";
|
|
33
|
-
case ts.SyntaxKind.UnknownKeyword:
|
|
34
|
-
return "unknown";
|
|
35
|
-
case ts.SyntaxKind.NeverKeyword:
|
|
36
|
-
return "never";
|
|
37
|
-
case ts.SyntaxKind.ObjectKeyword:
|
|
38
|
-
return "object";
|
|
39
|
-
case ts.SyntaxKind.SymbolKeyword:
|
|
40
|
-
return "symbol";
|
|
41
|
-
case ts.SyntaxKind.BigIntKeyword:
|
|
42
|
-
return "bigint";
|
|
43
|
-
case ts.SyntaxKind.UndefinedKeyword:
|
|
44
|
-
return "undefined";
|
|
45
|
-
case ts.SyntaxKind.NullKeyword:
|
|
46
|
-
return "null";
|
|
47
|
-
}
|
|
48
|
-
// Handle array types: T[]
|
|
49
|
-
if (ts.isArrayTypeNode(typeNode)) {
|
|
50
|
-
return `${typeNodeToSignatureString(typeNode.elementType)}[]`;
|
|
51
|
-
}
|
|
52
|
-
// For other complex types, fall back to any
|
|
53
|
-
return "any";
|
|
54
|
-
};
|
|
55
8
|
/**
|
|
56
9
|
* Convert method declaration to IR
|
|
57
10
|
*/
|
|
58
11
|
export const convertMethod = (node, ctx, superClass) => {
|
|
59
12
|
const memberName = ts.isIdentifier(node.name) ? node.name.text : "[computed]";
|
|
60
|
-
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
13
|
+
const parameters = convertParameters(node.parameters, ctx);
|
|
14
|
+
const overrideInfo = detectOverride(memberName, "method", superClass, ctx, parameters);
|
|
15
|
+
const declaredAccessibility = getAccessibility(node);
|
|
16
|
+
const accessibility = (() => {
|
|
17
|
+
if (!overrideInfo.isOverride || !overrideInfo.requiredAccessibility) {
|
|
18
|
+
return declaredAccessibility;
|
|
19
|
+
}
|
|
20
|
+
// Airplane-grade: always emit CLR-required accessibility for overrides.
|
|
21
|
+
// The TS surface may lose access modifiers (e.g., protected members exposed as callable
|
|
22
|
+
// overloads to avoid unstable renames like Dispose2), but C# compilation enforces the truth.
|
|
23
|
+
return overrideInfo.requiredAccessibility;
|
|
24
|
+
})();
|
|
68
25
|
// Get return type from declared annotation for contextual typing
|
|
69
26
|
// PHASE 4 (Alice's spec): Use captureTypeSyntax + typeFromSyntax
|
|
70
27
|
const returnType = node.type
|
|
@@ -74,7 +31,7 @@ export const convertMethod = (node, ctx, superClass) => {
|
|
|
74
31
|
kind: "methodDeclaration",
|
|
75
32
|
name: memberName,
|
|
76
33
|
typeParameters: convertTypeParameters(node.typeParameters, ctx),
|
|
77
|
-
parameters
|
|
34
|
+
parameters,
|
|
78
35
|
returnType,
|
|
79
36
|
// Pass return type to body for contextual typing of return statements
|
|
80
37
|
body: node.body
|
|
@@ -83,9 +40,725 @@ export const convertMethod = (node, ctx, superClass) => {
|
|
|
83
40
|
isStatic: hasStaticModifier(node),
|
|
84
41
|
isAsync: !!node.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword),
|
|
85
42
|
isGenerator: !!node.asteriskToken,
|
|
86
|
-
accessibility
|
|
43
|
+
accessibility,
|
|
87
44
|
isOverride: overrideInfo.isOverride ? true : undefined,
|
|
88
45
|
isShadow: overrideInfo.isShadow ? true : undefined,
|
|
89
46
|
};
|
|
90
47
|
};
|
|
48
|
+
const primitiveTypeToClrName = (name) => {
|
|
49
|
+
switch (name) {
|
|
50
|
+
case "string":
|
|
51
|
+
return "System.String";
|
|
52
|
+
case "number":
|
|
53
|
+
return "System.Double";
|
|
54
|
+
case "boolean":
|
|
55
|
+
return "System.Boolean";
|
|
56
|
+
case "int":
|
|
57
|
+
return "System.Int32";
|
|
58
|
+
case "char":
|
|
59
|
+
return "System.Char";
|
|
60
|
+
default:
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
const getClrName = (type) => {
|
|
65
|
+
if (type.kind !== "referenceType")
|
|
66
|
+
return undefined;
|
|
67
|
+
return type.resolvedClrType ?? type.typeId?.clrName;
|
|
68
|
+
};
|
|
69
|
+
const typesEqualForIsType = (a, b) => {
|
|
70
|
+
if (!a || !b)
|
|
71
|
+
return false;
|
|
72
|
+
// Bridge primitive types to their canonical CLR types (System.String etc).
|
|
73
|
+
if (a.kind === "primitiveType" && b.kind === "referenceType") {
|
|
74
|
+
const clr = getClrName(b);
|
|
75
|
+
const expected = primitiveTypeToClrName(a.name);
|
|
76
|
+
return !!expected && clr === expected;
|
|
77
|
+
}
|
|
78
|
+
if (a.kind === "referenceType" && b.kind === "primitiveType") {
|
|
79
|
+
const clr = getClrName(a);
|
|
80
|
+
const expected = primitiveTypeToClrName(b.name);
|
|
81
|
+
return !!expected && clr === expected;
|
|
82
|
+
}
|
|
83
|
+
if (a.kind !== b.kind)
|
|
84
|
+
return false;
|
|
85
|
+
switch (a.kind) {
|
|
86
|
+
case "primitiveType":
|
|
87
|
+
return b.kind === "primitiveType" && a.name === b.name;
|
|
88
|
+
case "typeParameterType":
|
|
89
|
+
return b.kind === "typeParameterType" && a.name === b.name;
|
|
90
|
+
case "arrayType":
|
|
91
|
+
return b.kind === "arrayType" && typesEqualForIsType(a.elementType, b.elementType);
|
|
92
|
+
case "referenceType": {
|
|
93
|
+
if (b.kind !== "referenceType")
|
|
94
|
+
return false;
|
|
95
|
+
const aStable = a.typeId?.stableId ?? a.resolvedClrType;
|
|
96
|
+
const bStable = b.typeId?.stableId ?? b.resolvedClrType;
|
|
97
|
+
if (aStable && bStable)
|
|
98
|
+
return aStable === bStable;
|
|
99
|
+
if (a.name !== b.name)
|
|
100
|
+
return false;
|
|
101
|
+
const aArgs = a.typeArguments ?? [];
|
|
102
|
+
const bArgs = b.typeArguments ?? [];
|
|
103
|
+
if (aArgs.length !== bArgs.length)
|
|
104
|
+
return false;
|
|
105
|
+
for (let i = 0; i < aArgs.length; i++) {
|
|
106
|
+
if (!typesEqualForIsType(aArgs[i], bArgs[i]))
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
default:
|
|
112
|
+
// isType is only supported for primitive/array/nominal/type-param equality during overload specialization.
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const specializeExpression = (expr, paramTypesByDeclId) => {
|
|
117
|
+
switch (expr.kind) {
|
|
118
|
+
case "literal":
|
|
119
|
+
case "identifier":
|
|
120
|
+
case "this":
|
|
121
|
+
return expr;
|
|
122
|
+
case "call": {
|
|
123
|
+
const callee = specializeExpression(expr.callee, paramTypesByDeclId);
|
|
124
|
+
const args = expr.arguments.map((a) => a.kind === "spread"
|
|
125
|
+
? { ...a, expression: specializeExpression(a.expression, paramTypesByDeclId) }
|
|
126
|
+
: specializeExpression(a, paramTypesByDeclId));
|
|
127
|
+
// Compile-time-only isType<T>(param)
|
|
128
|
+
if (callee.kind === "identifier" &&
|
|
129
|
+
callee.name === "isType" &&
|
|
130
|
+
expr.typeArguments &&
|
|
131
|
+
expr.typeArguments.length === 1 &&
|
|
132
|
+
args.length === 1 &&
|
|
133
|
+
args[0]?.kind === "identifier" &&
|
|
134
|
+
args[0].declId) {
|
|
135
|
+
const target = expr.typeArguments[0];
|
|
136
|
+
const actual = paramTypesByDeclId.get(args[0].declId.id);
|
|
137
|
+
const value = typesEqualForIsType(actual, target);
|
|
138
|
+
return { kind: "literal", value, inferredType: { kind: "primitiveType", name: "boolean" }, sourceSpan: expr.sourceSpan };
|
|
139
|
+
}
|
|
140
|
+
return { ...expr, callee, arguments: args };
|
|
141
|
+
}
|
|
142
|
+
case "new":
|
|
143
|
+
return {
|
|
144
|
+
...expr,
|
|
145
|
+
callee: specializeExpression(expr.callee, paramTypesByDeclId),
|
|
146
|
+
arguments: expr.arguments.map((a) => a.kind === "spread"
|
|
147
|
+
? { ...a, expression: specializeExpression(a.expression, paramTypesByDeclId) }
|
|
148
|
+
: specializeExpression(a, paramTypesByDeclId)),
|
|
149
|
+
};
|
|
150
|
+
case "functionExpression":
|
|
151
|
+
return {
|
|
152
|
+
...expr,
|
|
153
|
+
body: specializeStatement(expr.body, paramTypesByDeclId),
|
|
154
|
+
};
|
|
155
|
+
case "arrowFunction":
|
|
156
|
+
return {
|
|
157
|
+
...expr,
|
|
158
|
+
body: expr.body.kind === "blockStatement"
|
|
159
|
+
? specializeStatement(expr.body, paramTypesByDeclId)
|
|
160
|
+
: specializeExpression(expr.body, paramTypesByDeclId),
|
|
161
|
+
};
|
|
162
|
+
case "unary": {
|
|
163
|
+
const inner = specializeExpression(expr.expression, paramTypesByDeclId);
|
|
164
|
+
if (expr.operator === "!" && inner.kind === "literal" && typeof inner.value === "boolean") {
|
|
165
|
+
return { kind: "literal", value: !inner.value, inferredType: { kind: "primitiveType", name: "boolean" }, sourceSpan: expr.sourceSpan };
|
|
166
|
+
}
|
|
167
|
+
return { ...expr, expression: inner };
|
|
168
|
+
}
|
|
169
|
+
case "logical": {
|
|
170
|
+
const left = specializeExpression(expr.left, paramTypesByDeclId);
|
|
171
|
+
if (left.kind === "literal" && typeof left.value === "boolean") {
|
|
172
|
+
if (expr.operator === "&&") {
|
|
173
|
+
if (left.value === false) {
|
|
174
|
+
return { kind: "literal", value: false, inferredType: { kind: "primitiveType", name: "boolean" }, sourceSpan: expr.sourceSpan };
|
|
175
|
+
}
|
|
176
|
+
return specializeExpression(expr.right, paramTypesByDeclId);
|
|
177
|
+
}
|
|
178
|
+
if (expr.operator === "||") {
|
|
179
|
+
if (left.value === true) {
|
|
180
|
+
return { kind: "literal", value: true, inferredType: { kind: "primitiveType", name: "boolean" }, sourceSpan: expr.sourceSpan };
|
|
181
|
+
}
|
|
182
|
+
return specializeExpression(expr.right, paramTypesByDeclId);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const right = specializeExpression(expr.right, paramTypesByDeclId);
|
|
186
|
+
return { ...expr, left, right };
|
|
187
|
+
}
|
|
188
|
+
case "binary":
|
|
189
|
+
return {
|
|
190
|
+
...expr,
|
|
191
|
+
left: specializeExpression(expr.left, paramTypesByDeclId),
|
|
192
|
+
right: specializeExpression(expr.right, paramTypesByDeclId),
|
|
193
|
+
};
|
|
194
|
+
case "conditional":
|
|
195
|
+
return {
|
|
196
|
+
...expr,
|
|
197
|
+
condition: specializeExpression(expr.condition, paramTypesByDeclId),
|
|
198
|
+
whenTrue: specializeExpression(expr.whenTrue, paramTypesByDeclId),
|
|
199
|
+
whenFalse: specializeExpression(expr.whenFalse, paramTypesByDeclId),
|
|
200
|
+
};
|
|
201
|
+
case "assignment":
|
|
202
|
+
return {
|
|
203
|
+
...expr,
|
|
204
|
+
right: specializeExpression(expr.right, paramTypesByDeclId),
|
|
205
|
+
};
|
|
206
|
+
case "templateLiteral":
|
|
207
|
+
return {
|
|
208
|
+
...expr,
|
|
209
|
+
expressions: expr.expressions.map((e) => specializeExpression(e, paramTypesByDeclId)),
|
|
210
|
+
};
|
|
211
|
+
case "spread":
|
|
212
|
+
return {
|
|
213
|
+
...expr,
|
|
214
|
+
expression: specializeExpression(expr.expression, paramTypesByDeclId),
|
|
215
|
+
};
|
|
216
|
+
case "await":
|
|
217
|
+
return {
|
|
218
|
+
...expr,
|
|
219
|
+
expression: specializeExpression(expr.expression, paramTypesByDeclId),
|
|
220
|
+
};
|
|
221
|
+
case "yield":
|
|
222
|
+
return {
|
|
223
|
+
...expr,
|
|
224
|
+
expression: expr.expression
|
|
225
|
+
? specializeExpression(expr.expression, paramTypesByDeclId)
|
|
226
|
+
: undefined,
|
|
227
|
+
};
|
|
228
|
+
case "numericNarrowing":
|
|
229
|
+
return {
|
|
230
|
+
...expr,
|
|
231
|
+
expression: specializeExpression(expr.expression, paramTypesByDeclId),
|
|
232
|
+
};
|
|
233
|
+
case "typeAssertion":
|
|
234
|
+
return {
|
|
235
|
+
...expr,
|
|
236
|
+
expression: specializeExpression(expr.expression, paramTypesByDeclId),
|
|
237
|
+
};
|
|
238
|
+
case "trycast":
|
|
239
|
+
return {
|
|
240
|
+
...expr,
|
|
241
|
+
expression: specializeExpression(expr.expression, paramTypesByDeclId),
|
|
242
|
+
};
|
|
243
|
+
case "stackalloc":
|
|
244
|
+
return {
|
|
245
|
+
...expr,
|
|
246
|
+
size: specializeExpression(expr.size, paramTypesByDeclId),
|
|
247
|
+
};
|
|
248
|
+
case "memberAccess":
|
|
249
|
+
return {
|
|
250
|
+
...expr,
|
|
251
|
+
object: specializeExpression(expr.object, paramTypesByDeclId),
|
|
252
|
+
property: typeof expr.property === "string"
|
|
253
|
+
? expr.property
|
|
254
|
+
: specializeExpression(expr.property, paramTypesByDeclId),
|
|
255
|
+
};
|
|
256
|
+
case "array":
|
|
257
|
+
return {
|
|
258
|
+
...expr,
|
|
259
|
+
elements: expr.elements.map((e) => e
|
|
260
|
+
? e.kind === "spread"
|
|
261
|
+
? { ...e, expression: specializeExpression(e.expression, paramTypesByDeclId) }
|
|
262
|
+
: specializeExpression(e, paramTypesByDeclId)
|
|
263
|
+
: undefined),
|
|
264
|
+
};
|
|
265
|
+
case "object":
|
|
266
|
+
return {
|
|
267
|
+
...expr,
|
|
268
|
+
properties: expr.properties.map((p) => p.kind === "spread"
|
|
269
|
+
? { ...p, expression: specializeExpression(p.expression, paramTypesByDeclId) }
|
|
270
|
+
: {
|
|
271
|
+
...p,
|
|
272
|
+
key: typeof p.key === "string" ? p.key : specializeExpression(p.key, paramTypesByDeclId),
|
|
273
|
+
value: specializeExpression(p.value, paramTypesByDeclId),
|
|
274
|
+
}),
|
|
275
|
+
};
|
|
276
|
+
case "update":
|
|
277
|
+
return {
|
|
278
|
+
...expr,
|
|
279
|
+
expression: specializeExpression(expr.expression, paramTypesByDeclId),
|
|
280
|
+
};
|
|
281
|
+
default:
|
|
282
|
+
return expr;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
const specializeStatement = (stmt, paramTypesByDeclId) => {
|
|
286
|
+
const statementAlwaysTerminates = (s) => {
|
|
287
|
+
switch (s.kind) {
|
|
288
|
+
case "returnStatement":
|
|
289
|
+
case "throwStatement":
|
|
290
|
+
case "generatorReturnStatement":
|
|
291
|
+
return true;
|
|
292
|
+
case "blockStatement": {
|
|
293
|
+
for (const inner of s.statements) {
|
|
294
|
+
if (statementAlwaysTerminates(inner))
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
case "ifStatement":
|
|
300
|
+
return s.elseStatement
|
|
301
|
+
? statementAlwaysTerminates(s.thenStatement) &&
|
|
302
|
+
statementAlwaysTerminates(s.elseStatement)
|
|
303
|
+
: false;
|
|
304
|
+
case "tryStatement": {
|
|
305
|
+
const tryOk = statementAlwaysTerminates(s.tryBlock);
|
|
306
|
+
const catchOk = s.catchClause
|
|
307
|
+
? statementAlwaysTerminates(s.catchClause.body)
|
|
308
|
+
: true;
|
|
309
|
+
const finallyOk = s.finallyBlock ? statementAlwaysTerminates(s.finallyBlock) : true;
|
|
310
|
+
return tryOk && catchOk && finallyOk;
|
|
311
|
+
}
|
|
312
|
+
default:
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
switch (stmt.kind) {
|
|
317
|
+
case "blockStatement": {
|
|
318
|
+
const statements = [];
|
|
319
|
+
for (const s of stmt.statements) {
|
|
320
|
+
const specialized = specializeStatement(s, paramTypesByDeclId);
|
|
321
|
+
statements.push(specialized);
|
|
322
|
+
if (statementAlwaysTerminates(specialized)) {
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return {
|
|
327
|
+
...stmt,
|
|
328
|
+
statements,
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
case "ifStatement": {
|
|
332
|
+
const condition = specializeExpression(stmt.condition, paramTypesByDeclId);
|
|
333
|
+
const thenStatement = specializeStatement(stmt.thenStatement, paramTypesByDeclId);
|
|
334
|
+
const elseStatement = stmt.elseStatement
|
|
335
|
+
? specializeStatement(stmt.elseStatement, paramTypesByDeclId)
|
|
336
|
+
: undefined;
|
|
337
|
+
if (condition.kind === "literal" && typeof condition.value === "boolean") {
|
|
338
|
+
return condition.value ? thenStatement : elseStatement ?? { kind: "emptyStatement" };
|
|
339
|
+
}
|
|
340
|
+
return { ...stmt, condition, thenStatement, elseStatement };
|
|
341
|
+
}
|
|
342
|
+
case "expressionStatement":
|
|
343
|
+
return { ...stmt, expression: specializeExpression(stmt.expression, paramTypesByDeclId) };
|
|
344
|
+
case "returnStatement":
|
|
345
|
+
return {
|
|
346
|
+
...stmt,
|
|
347
|
+
expression: stmt.expression
|
|
348
|
+
? specializeExpression(stmt.expression, paramTypesByDeclId)
|
|
349
|
+
: undefined,
|
|
350
|
+
};
|
|
351
|
+
case "variableDeclaration":
|
|
352
|
+
return {
|
|
353
|
+
...stmt,
|
|
354
|
+
declarations: stmt.declarations.map((d) => ({
|
|
355
|
+
...d,
|
|
356
|
+
initializer: d.initializer
|
|
357
|
+
? specializeExpression(d.initializer, paramTypesByDeclId)
|
|
358
|
+
: undefined,
|
|
359
|
+
})),
|
|
360
|
+
};
|
|
361
|
+
case "whileStatement":
|
|
362
|
+
return {
|
|
363
|
+
...stmt,
|
|
364
|
+
condition: specializeExpression(stmt.condition, paramTypesByDeclId),
|
|
365
|
+
body: specializeStatement(stmt.body, paramTypesByDeclId),
|
|
366
|
+
};
|
|
367
|
+
case "forStatement": {
|
|
368
|
+
const initializer = (() => {
|
|
369
|
+
if (!stmt.initializer)
|
|
370
|
+
return undefined;
|
|
371
|
+
if (stmt.initializer.kind === "variableDeclaration") {
|
|
372
|
+
const specialized = specializeStatement(stmt.initializer, paramTypesByDeclId);
|
|
373
|
+
if (specialized.kind !== "variableDeclaration") {
|
|
374
|
+
throw new Error("ICE: forStatement initializer specialization changed kind");
|
|
375
|
+
}
|
|
376
|
+
return specialized;
|
|
377
|
+
}
|
|
378
|
+
return specializeExpression(stmt.initializer, paramTypesByDeclId);
|
|
379
|
+
})();
|
|
380
|
+
return {
|
|
381
|
+
...stmt,
|
|
382
|
+
initializer,
|
|
383
|
+
condition: stmt.condition
|
|
384
|
+
? specializeExpression(stmt.condition, paramTypesByDeclId)
|
|
385
|
+
: undefined,
|
|
386
|
+
update: stmt.update
|
|
387
|
+
? specializeExpression(stmt.update, paramTypesByDeclId)
|
|
388
|
+
: undefined,
|
|
389
|
+
body: specializeStatement(stmt.body, paramTypesByDeclId),
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
case "forOfStatement":
|
|
393
|
+
case "forInStatement":
|
|
394
|
+
return {
|
|
395
|
+
...stmt,
|
|
396
|
+
expression: specializeExpression(stmt.expression, paramTypesByDeclId),
|
|
397
|
+
body: specializeStatement(stmt.body, paramTypesByDeclId),
|
|
398
|
+
};
|
|
399
|
+
case "switchStatement":
|
|
400
|
+
return {
|
|
401
|
+
...stmt,
|
|
402
|
+
expression: specializeExpression(stmt.expression, paramTypesByDeclId),
|
|
403
|
+
cases: stmt.cases.map((c) => ({
|
|
404
|
+
...c,
|
|
405
|
+
test: c.test ? specializeExpression(c.test, paramTypesByDeclId) : undefined,
|
|
406
|
+
statements: c.statements.map((s) => specializeStatement(s, paramTypesByDeclId)),
|
|
407
|
+
})),
|
|
408
|
+
};
|
|
409
|
+
case "tryStatement":
|
|
410
|
+
return {
|
|
411
|
+
...stmt,
|
|
412
|
+
tryBlock: specializeStatement(stmt.tryBlock, paramTypesByDeclId),
|
|
413
|
+
catchClause: stmt.catchClause
|
|
414
|
+
? {
|
|
415
|
+
...stmt.catchClause,
|
|
416
|
+
body: specializeStatement(stmt.catchClause.body, paramTypesByDeclId),
|
|
417
|
+
}
|
|
418
|
+
: undefined,
|
|
419
|
+
finallyBlock: stmt.finallyBlock
|
|
420
|
+
? specializeStatement(stmt.finallyBlock, paramTypesByDeclId)
|
|
421
|
+
: undefined,
|
|
422
|
+
};
|
|
423
|
+
case "throwStatement":
|
|
424
|
+
return {
|
|
425
|
+
...stmt,
|
|
426
|
+
expression: specializeExpression(stmt.expression, paramTypesByDeclId),
|
|
427
|
+
};
|
|
428
|
+
default:
|
|
429
|
+
return stmt;
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
const assertNoIsTypeCalls = (stmt) => {
|
|
433
|
+
const visitExpr = (expr) => {
|
|
434
|
+
switch (expr.kind) {
|
|
435
|
+
case "literal":
|
|
436
|
+
case "identifier":
|
|
437
|
+
case "this":
|
|
438
|
+
return true;
|
|
439
|
+
case "spread":
|
|
440
|
+
return visitExpr(expr.expression);
|
|
441
|
+
case "memberAccess":
|
|
442
|
+
return (visitExpr(expr.object) &&
|
|
443
|
+
(typeof expr.property === "string" ? true : visitExpr(expr.property)));
|
|
444
|
+
case "call":
|
|
445
|
+
return (!(expr.callee.kind === "identifier" && expr.callee.name === "isType") &&
|
|
446
|
+
visitExpr(expr.callee) &&
|
|
447
|
+
expr.arguments.every((a) => a.kind === "spread" ? visitExpr(a.expression) : visitExpr(a)));
|
|
448
|
+
case "new":
|
|
449
|
+
return (visitExpr(expr.callee) &&
|
|
450
|
+
expr.arguments.every((a) => a.kind === "spread" ? visitExpr(a.expression) : visitExpr(a)));
|
|
451
|
+
case "functionExpression":
|
|
452
|
+
return expr.body.statements.every(visitStmt);
|
|
453
|
+
case "arrowFunction":
|
|
454
|
+
return expr.body.kind === "blockStatement"
|
|
455
|
+
? expr.body.statements.every(visitStmt)
|
|
456
|
+
: visitExpr(expr.body);
|
|
457
|
+
case "update":
|
|
458
|
+
case "unary":
|
|
459
|
+
return visitExpr(expr.expression);
|
|
460
|
+
case "binary":
|
|
461
|
+
case "logical":
|
|
462
|
+
return visitExpr(expr.left) && visitExpr(expr.right);
|
|
463
|
+
case "conditional":
|
|
464
|
+
return (visitExpr(expr.condition) &&
|
|
465
|
+
visitExpr(expr.whenTrue) &&
|
|
466
|
+
visitExpr(expr.whenFalse));
|
|
467
|
+
case "assignment":
|
|
468
|
+
return visitExpr(expr.right);
|
|
469
|
+
case "templateLiteral":
|
|
470
|
+
return expr.expressions.every(visitExpr);
|
|
471
|
+
case "array":
|
|
472
|
+
return expr.elements.every((e) => {
|
|
473
|
+
if (!e)
|
|
474
|
+
return true;
|
|
475
|
+
return e.kind === "spread" ? visitExpr(e.expression) : visitExpr(e);
|
|
476
|
+
});
|
|
477
|
+
case "object":
|
|
478
|
+
return expr.properties.every((p) => {
|
|
479
|
+
if (p.kind === "spread")
|
|
480
|
+
return visitExpr(p.expression);
|
|
481
|
+
const keyOk = typeof p.key === "string" ? true : visitExpr(p.key);
|
|
482
|
+
return keyOk && visitExpr(p.value);
|
|
483
|
+
});
|
|
484
|
+
case "await":
|
|
485
|
+
return visitExpr(expr.expression);
|
|
486
|
+
case "yield":
|
|
487
|
+
return expr.expression ? visitExpr(expr.expression) : true;
|
|
488
|
+
case "numericNarrowing":
|
|
489
|
+
return visitExpr(expr.expression);
|
|
490
|
+
case "typeAssertion":
|
|
491
|
+
return visitExpr(expr.expression);
|
|
492
|
+
case "trycast":
|
|
493
|
+
return visitExpr(expr.expression);
|
|
494
|
+
case "stackalloc":
|
|
495
|
+
return visitExpr(expr.size);
|
|
496
|
+
default:
|
|
497
|
+
return true;
|
|
498
|
+
}
|
|
499
|
+
};
|
|
500
|
+
const visitStmt = (s) => {
|
|
501
|
+
switch (s.kind) {
|
|
502
|
+
case "blockStatement":
|
|
503
|
+
return s.statements.every(visitStmt);
|
|
504
|
+
case "ifStatement":
|
|
505
|
+
return (visitExpr(s.condition) &&
|
|
506
|
+
visitStmt(s.thenStatement) &&
|
|
507
|
+
(s.elseStatement ? visitStmt(s.elseStatement) : true));
|
|
508
|
+
case "expressionStatement":
|
|
509
|
+
return visitExpr(s.expression);
|
|
510
|
+
case "returnStatement":
|
|
511
|
+
return s.expression ? visitExpr(s.expression) : true;
|
|
512
|
+
case "variableDeclaration":
|
|
513
|
+
return s.declarations.every((d) => (d.initializer ? visitExpr(d.initializer) : true));
|
|
514
|
+
case "whileStatement":
|
|
515
|
+
return visitExpr(s.condition) && visitStmt(s.body);
|
|
516
|
+
case "forStatement":
|
|
517
|
+
return ((s.initializer
|
|
518
|
+
? s.initializer.kind === "variableDeclaration"
|
|
519
|
+
? visitStmt(s.initializer)
|
|
520
|
+
: visitExpr(s.initializer)
|
|
521
|
+
: true) &&
|
|
522
|
+
(s.condition ? visitExpr(s.condition) : true) &&
|
|
523
|
+
(s.update ? visitExpr(s.update) : true) &&
|
|
524
|
+
visitStmt(s.body));
|
|
525
|
+
case "forOfStatement":
|
|
526
|
+
case "forInStatement":
|
|
527
|
+
return visitExpr(s.expression) && visitStmt(s.body);
|
|
528
|
+
case "switchStatement":
|
|
529
|
+
return (visitExpr(s.expression) &&
|
|
530
|
+
s.cases.every((c) => (c.test ? visitExpr(c.test) : true) && c.statements.every(visitStmt)));
|
|
531
|
+
case "tryStatement":
|
|
532
|
+
return (visitStmt(s.tryBlock) &&
|
|
533
|
+
(s.catchClause ? visitStmt(s.catchClause.body) : true) &&
|
|
534
|
+
(s.finallyBlock ? visitStmt(s.finallyBlock) : true));
|
|
535
|
+
case "throwStatement":
|
|
536
|
+
return visitExpr(s.expression);
|
|
537
|
+
case "yieldStatement":
|
|
538
|
+
return s.output ? visitExpr(s.output) : true;
|
|
539
|
+
case "generatorReturnStatement":
|
|
540
|
+
return s.expression ? visitExpr(s.expression) : true;
|
|
541
|
+
default:
|
|
542
|
+
return true;
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
return visitStmt(stmt);
|
|
546
|
+
};
|
|
547
|
+
const assertNoMissingParamRefs = (stmt, missingDeclIds) => {
|
|
548
|
+
const visitExpr = (expr) => {
|
|
549
|
+
switch (expr.kind) {
|
|
550
|
+
case "literal":
|
|
551
|
+
case "this":
|
|
552
|
+
return true;
|
|
553
|
+
case "identifier":
|
|
554
|
+
return expr.declId ? !missingDeclIds.has(expr.declId.id) : true;
|
|
555
|
+
case "spread":
|
|
556
|
+
return visitExpr(expr.expression);
|
|
557
|
+
case "memberAccess":
|
|
558
|
+
return (visitExpr(expr.object) &&
|
|
559
|
+
(typeof expr.property === "string" ? true : visitExpr(expr.property)));
|
|
560
|
+
case "call":
|
|
561
|
+
return (visitExpr(expr.callee) &&
|
|
562
|
+
expr.arguments.every((a) => a.kind === "spread" ? visitExpr(a.expression) : visitExpr(a)));
|
|
563
|
+
case "new":
|
|
564
|
+
return (visitExpr(expr.callee) &&
|
|
565
|
+
expr.arguments.every((a) => a.kind === "spread" ? visitExpr(a.expression) : visitExpr(a)));
|
|
566
|
+
case "functionExpression":
|
|
567
|
+
return expr.body.statements.every(visitStmt);
|
|
568
|
+
case "arrowFunction":
|
|
569
|
+
return expr.body.kind === "blockStatement"
|
|
570
|
+
? expr.body.statements.every(visitStmt)
|
|
571
|
+
: visitExpr(expr.body);
|
|
572
|
+
case "update":
|
|
573
|
+
case "unary":
|
|
574
|
+
return visitExpr(expr.expression);
|
|
575
|
+
case "binary":
|
|
576
|
+
case "logical":
|
|
577
|
+
return visitExpr(expr.left) && visitExpr(expr.right);
|
|
578
|
+
case "conditional":
|
|
579
|
+
return (visitExpr(expr.condition) &&
|
|
580
|
+
visitExpr(expr.whenTrue) &&
|
|
581
|
+
visitExpr(expr.whenFalse));
|
|
582
|
+
case "assignment":
|
|
583
|
+
return visitExpr(expr.right);
|
|
584
|
+
case "templateLiteral":
|
|
585
|
+
return expr.expressions.every(visitExpr);
|
|
586
|
+
case "array":
|
|
587
|
+
return expr.elements.every((e) => {
|
|
588
|
+
if (!e)
|
|
589
|
+
return true;
|
|
590
|
+
return e.kind === "spread" ? visitExpr(e.expression) : visitExpr(e);
|
|
591
|
+
});
|
|
592
|
+
case "object":
|
|
593
|
+
return expr.properties.every((p) => {
|
|
594
|
+
if (p.kind === "spread")
|
|
595
|
+
return visitExpr(p.expression);
|
|
596
|
+
const keyOk = typeof p.key === "string" ? true : visitExpr(p.key);
|
|
597
|
+
return keyOk && visitExpr(p.value);
|
|
598
|
+
});
|
|
599
|
+
case "await":
|
|
600
|
+
return visitExpr(expr.expression);
|
|
601
|
+
case "yield":
|
|
602
|
+
return expr.expression ? visitExpr(expr.expression) : true;
|
|
603
|
+
case "numericNarrowing":
|
|
604
|
+
return visitExpr(expr.expression);
|
|
605
|
+
case "typeAssertion":
|
|
606
|
+
return visitExpr(expr.expression);
|
|
607
|
+
case "trycast":
|
|
608
|
+
return visitExpr(expr.expression);
|
|
609
|
+
case "stackalloc":
|
|
610
|
+
return visitExpr(expr.size);
|
|
611
|
+
default:
|
|
612
|
+
return true;
|
|
613
|
+
}
|
|
614
|
+
};
|
|
615
|
+
const visitStmt = (s) => {
|
|
616
|
+
switch (s.kind) {
|
|
617
|
+
case "blockStatement":
|
|
618
|
+
return s.statements.every(visitStmt);
|
|
619
|
+
case "ifStatement":
|
|
620
|
+
return (visitExpr(s.condition) &&
|
|
621
|
+
visitStmt(s.thenStatement) &&
|
|
622
|
+
(s.elseStatement ? visitStmt(s.elseStatement) : true));
|
|
623
|
+
case "expressionStatement":
|
|
624
|
+
return visitExpr(s.expression);
|
|
625
|
+
case "returnStatement":
|
|
626
|
+
return s.expression ? visitExpr(s.expression) : true;
|
|
627
|
+
case "variableDeclaration":
|
|
628
|
+
return s.declarations.every((d) => (d.initializer ? visitExpr(d.initializer) : true));
|
|
629
|
+
case "whileStatement":
|
|
630
|
+
return visitExpr(s.condition) && visitStmt(s.body);
|
|
631
|
+
case "forStatement":
|
|
632
|
+
return ((s.initializer
|
|
633
|
+
? s.initializer.kind === "variableDeclaration"
|
|
634
|
+
? visitStmt(s.initializer)
|
|
635
|
+
: visitExpr(s.initializer)
|
|
636
|
+
: true) &&
|
|
637
|
+
(s.condition ? visitExpr(s.condition) : true) &&
|
|
638
|
+
(s.update ? visitExpr(s.update) : true) &&
|
|
639
|
+
visitStmt(s.body));
|
|
640
|
+
case "forOfStatement":
|
|
641
|
+
case "forInStatement":
|
|
642
|
+
return visitExpr(s.expression) && visitStmt(s.body);
|
|
643
|
+
case "switchStatement":
|
|
644
|
+
return (visitExpr(s.expression) &&
|
|
645
|
+
s.cases.every((c) => (c.test ? visitExpr(c.test) : true) && c.statements.every(visitStmt)));
|
|
646
|
+
case "tryStatement":
|
|
647
|
+
return (visitStmt(s.tryBlock) &&
|
|
648
|
+
(s.catchClause ? visitStmt(s.catchClause.body) : true) &&
|
|
649
|
+
(s.finallyBlock ? visitStmt(s.finallyBlock) : true));
|
|
650
|
+
case "throwStatement":
|
|
651
|
+
return visitExpr(s.expression);
|
|
652
|
+
case "yieldStatement":
|
|
653
|
+
return s.output ? visitExpr(s.output) : true;
|
|
654
|
+
case "generatorReturnStatement":
|
|
655
|
+
return s.expression ? visitExpr(s.expression) : true;
|
|
656
|
+
default:
|
|
657
|
+
return true;
|
|
658
|
+
}
|
|
659
|
+
};
|
|
660
|
+
return visitStmt(stmt);
|
|
661
|
+
};
|
|
662
|
+
/**
|
|
663
|
+
* Convert a TypeScript overload group (`sig; sig; impl {}`) into one C# method per signature.
|
|
664
|
+
*
|
|
665
|
+
* The implementation body is written once and specialized per overload by erasing
|
|
666
|
+
* `isType<T>(pN)` branches that don't match the current overload signature.
|
|
667
|
+
*/
|
|
668
|
+
export const convertMethodOverloadGroup = (nodes, ctx, superClass) => {
|
|
669
|
+
const impls = nodes.filter((n) => !!n.body);
|
|
670
|
+
if (impls.length !== 1) {
|
|
671
|
+
throw new Error(`ICE: method overload group must contain exactly one implementation body (found ${impls.length})`);
|
|
672
|
+
}
|
|
673
|
+
const impl = impls[0];
|
|
674
|
+
const memberName = ts.isIdentifier(impl.name) ? impl.name.text : "[computed]";
|
|
675
|
+
const sigs = nodes.filter((n) => !n.body);
|
|
676
|
+
if (sigs.length === 0) {
|
|
677
|
+
return [convertMethod(impl, ctx, superClass)];
|
|
678
|
+
}
|
|
679
|
+
const implBody = impl.body
|
|
680
|
+
? convertBlockStatement(impl.body, ctx, undefined)
|
|
681
|
+
: undefined;
|
|
682
|
+
if (!implBody) {
|
|
683
|
+
throw new Error("ICE: overload implementation must have a body");
|
|
684
|
+
}
|
|
685
|
+
const implParams = convertParameters(impl.parameters, ctx);
|
|
686
|
+
// Map implementation param DeclId.id -> index.
|
|
687
|
+
const implParamDeclIds = [];
|
|
688
|
+
for (const p of impl.parameters) {
|
|
689
|
+
if (!ts.isIdentifier(p.name)) {
|
|
690
|
+
throw new Error(`ICE: overload implementations currently require identifier parameters (got non-identifier in '${memberName}')`);
|
|
691
|
+
}
|
|
692
|
+
const id = ctx.binding.resolveIdentifier(p.name);
|
|
693
|
+
if (!id) {
|
|
694
|
+
throw new Error(`ICE: could not resolve parameter '${p.name.text}'`);
|
|
695
|
+
}
|
|
696
|
+
implParamDeclIds.push(id.id);
|
|
697
|
+
}
|
|
698
|
+
const declaredAccessibility = getAccessibility(impl);
|
|
699
|
+
const isStatic = hasStaticModifier(impl);
|
|
700
|
+
const isAsync = !!impl.modifiers?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword);
|
|
701
|
+
const isGenerator = !!impl.asteriskToken;
|
|
702
|
+
// Convert each signature into a concrete method emission.
|
|
703
|
+
const out = [];
|
|
704
|
+
for (const sig of sigs) {
|
|
705
|
+
const sigParams = convertParameters(sig.parameters, ctx);
|
|
706
|
+
const returnType = sig.type
|
|
707
|
+
? ctx.typeSystem.typeFromSyntax(ctx.binding.captureTypeSyntax(sig.type))
|
|
708
|
+
: undefined;
|
|
709
|
+
if (sigParams.length > implParams.length) {
|
|
710
|
+
throw new Error(`ICE: overload signature parameter count exceeds implementation for '${memberName}' (sig=${sigParams.length}, impl=${implParams.length})`);
|
|
711
|
+
}
|
|
712
|
+
const parameters = sigParams.map((p, i) => ({
|
|
713
|
+
...p,
|
|
714
|
+
pattern: implParams[i].pattern,
|
|
715
|
+
}));
|
|
716
|
+
const overrideInfo = detectOverride(memberName, "method", superClass, ctx, parameters);
|
|
717
|
+
// If this signature matches a non-virtual CLR base method, do not emit a new method
|
|
718
|
+
// (avoid accidental `new` shadowing). Users still inherit the base implementation.
|
|
719
|
+
if (overrideInfo.isShadow) {
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
const accessibility = overrideInfo.isOverride && overrideInfo.requiredAccessibility
|
|
723
|
+
? overrideInfo.requiredAccessibility
|
|
724
|
+
: declaredAccessibility;
|
|
725
|
+
const paramTypesByDeclId = new Map();
|
|
726
|
+
for (let i = 0; i < implParamDeclIds.length; i++) {
|
|
727
|
+
const declId = implParamDeclIds[i];
|
|
728
|
+
const t = i < parameters.length
|
|
729
|
+
? parameters[i]?.type
|
|
730
|
+
: { kind: "primitiveType", name: "undefined" };
|
|
731
|
+
if (t)
|
|
732
|
+
paramTypesByDeclId.set(declId, t);
|
|
733
|
+
}
|
|
734
|
+
const specialized = specializeStatement(implBody, paramTypesByDeclId);
|
|
735
|
+
if (!assertNoIsTypeCalls(specialized)) {
|
|
736
|
+
throw new Error(`ICE: isType<T>(...) must be erased during overload specialization for '${memberName}'.`);
|
|
737
|
+
}
|
|
738
|
+
if (sigParams.length < implParams.length) {
|
|
739
|
+
const missing = new Set();
|
|
740
|
+
for (let i = sigParams.length; i < implParamDeclIds.length; i++) {
|
|
741
|
+
missing.add(implParamDeclIds[i]);
|
|
742
|
+
}
|
|
743
|
+
if (missing.size > 0 && !assertNoMissingParamRefs(specialized, missing)) {
|
|
744
|
+
throw new Error(`ICE: overload '${memberName}' implementation references parameters not present in the current signature (sigParams=${sigParams.length}, implParams=${implParams.length}).`);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
out.push({
|
|
748
|
+
kind: "methodDeclaration",
|
|
749
|
+
name: memberName,
|
|
750
|
+
typeParameters: convertTypeParameters(sig.typeParameters, ctx),
|
|
751
|
+
parameters,
|
|
752
|
+
returnType,
|
|
753
|
+
body: specialized,
|
|
754
|
+
isStatic,
|
|
755
|
+
isAsync,
|
|
756
|
+
isGenerator,
|
|
757
|
+
accessibility,
|
|
758
|
+
isOverride: overrideInfo.isOverride ? true : undefined,
|
|
759
|
+
isShadow: overrideInfo.isShadow ? true : undefined,
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
return out;
|
|
763
|
+
};
|
|
91
764
|
//# sourceMappingURL=methods.js.map
|