@tsonic/frontend 0.0.11 → 0.0.13
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/ir/converters/expressions/access.d.ts.map +1 -1
- package/dist/ir/converters/expressions/access.js +61 -1
- package/dist/ir/converters/expressions/access.js.map +1 -1
- package/dist/ir/converters/expressions/calls.d.ts.map +1 -1
- package/dist/ir/converters/expressions/calls.js +293 -24
- package/dist/ir/converters/expressions/calls.js.map +1 -1
- package/dist/ir/converters/expressions/helpers.js +4 -4
- package/dist/ir/converters/expressions/helpers.js.map +1 -1
- package/dist/ir/converters/expressions/literals.d.ts +14 -0
- package/dist/ir/converters/expressions/literals.d.ts.map +1 -1
- package/dist/ir/converters/expressions/literals.js +22 -2
- package/dist/ir/converters/expressions/literals.js.map +1 -1
- package/dist/ir/converters/expressions/numeric-recovery.test.js +3 -2
- package/dist/ir/converters/expressions/numeric-recovery.test.js.map +1 -1
- package/dist/ir/converters/statements/helpers.d.ts.map +1 -1
- package/dist/ir/converters/statements/helpers.js +10 -4
- package/dist/ir/converters/statements/helpers.js.map +1 -1
- package/dist/ir/expression-converter.d.ts.map +1 -1
- package/dist/ir/expression-converter.js +38 -5
- package/dist/ir/expression-converter.js.map +1 -1
- package/dist/ir/index.d.ts +1 -1
- package/dist/ir/index.d.ts.map +1 -1
- package/dist/ir/index.js +1 -1
- package/dist/ir/index.js.map +1 -1
- package/dist/ir/statement-converter.d.ts.map +1 -1
- package/dist/ir/statement-converter.js +12 -0
- package/dist/ir/statement-converter.js.map +1 -1
- package/dist/ir/type-converter/inference.d.ts.map +1 -1
- package/dist/ir/type-converter/inference.js +50 -7
- package/dist/ir/type-converter/inference.js.map +1 -1
- package/dist/ir/type-converter/primitives.d.ts +26 -4
- package/dist/ir/type-converter/primitives.d.ts.map +1 -1
- package/dist/ir/type-converter/primitives.js +36 -2
- package/dist/ir/type-converter/primitives.js.map +1 -1
- package/dist/ir/type-converter/references.d.ts.map +1 -1
- package/dist/ir/type-converter/references.js +324 -11
- package/dist/ir/type-converter/references.js.map +1 -1
- package/dist/ir/type-converter/utility-types.d.ts +93 -0
- package/dist/ir/type-converter/utility-types.d.ts.map +1 -0
- package/dist/ir/type-converter/utility-types.js +528 -0
- package/dist/ir/type-converter/utility-types.js.map +1 -0
- package/dist/ir/type-converter/utility-types.test.d.ts +10 -0
- package/dist/ir/type-converter/utility-types.test.d.ts.map +1 -0
- package/dist/ir/type-converter/utility-types.test.js +1030 -0
- package/dist/ir/type-converter/utility-types.test.js.map +1 -0
- package/dist/ir/types/expressions.d.ts +40 -2
- package/dist/ir/types/expressions.d.ts.map +1 -1
- package/dist/ir/types/helpers.d.ts +3 -1
- package/dist/ir/types/helpers.d.ts.map +1 -1
- package/dist/ir/types/index.d.ts +2 -1
- package/dist/ir/types/index.d.ts.map +1 -1
- package/dist/ir/types/index.js +2 -0
- package/dist/ir/types/index.js.map +1 -1
- package/dist/ir/types/ir-types.d.ts +69 -11
- package/dist/ir/types/ir-types.d.ts.map +1 -1
- package/dist/ir/types/numeric-helpers.d.ts +46 -0
- package/dist/ir/types/numeric-helpers.d.ts.map +1 -0
- package/dist/ir/types/numeric-helpers.js +105 -0
- package/dist/ir/types/numeric-helpers.js.map +1 -0
- package/dist/ir/types/statements.d.ts +11 -1
- package/dist/ir/types/statements.d.ts.map +1 -1
- package/dist/ir/types.d.ts +2 -2
- package/dist/ir/types.d.ts.map +1 -1
- package/dist/ir/types.js +3 -1
- package/dist/ir/types.js.map +1 -1
- package/dist/ir/validation/anonymous-type-lowering-pass.d.ts +32 -0
- package/dist/ir/validation/anonymous-type-lowering-pass.d.ts.map +1 -0
- package/dist/ir/validation/anonymous-type-lowering-pass.js +854 -0
- package/dist/ir/validation/anonymous-type-lowering-pass.js.map +1 -0
- package/dist/ir/validation/attribute-collection-pass.d.ts +37 -0
- package/dist/ir/validation/attribute-collection-pass.d.ts.map +1 -0
- package/dist/ir/validation/attribute-collection-pass.js +282 -0
- package/dist/ir/validation/attribute-collection-pass.js.map +1 -0
- package/dist/ir/validation/attribute-collection-pass.test.d.ts +5 -0
- package/dist/ir/validation/attribute-collection-pass.test.d.ts.map +1 -0
- package/dist/ir/validation/attribute-collection-pass.test.js +215 -0
- package/dist/ir/validation/attribute-collection-pass.test.js.map +1 -0
- package/dist/ir/validation/index.d.ts +3 -0
- package/dist/ir/validation/index.d.ts.map +1 -1
- package/dist/ir/validation/index.js +3 -0
- package/dist/ir/validation/index.js.map +1 -1
- package/dist/ir/validation/numeric-coercion-pass.d.ts +77 -0
- package/dist/ir/validation/numeric-coercion-pass.d.ts.map +1 -0
- package/dist/ir/validation/numeric-coercion-pass.js +686 -0
- package/dist/ir/validation/numeric-coercion-pass.js.map +1 -0
- package/dist/ir/validation/numeric-invariants.test.js +130 -14
- 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 -108
- package/dist/ir/validation/numeric-proof-pass.js.map +1 -1
- package/dist/ir/validation/soundness-gate.d.ts.map +1 -1
- package/dist/ir/validation/soundness-gate.js +23 -12
- package/dist/ir/validation/soundness-gate.js.map +1 -1
- package/dist/ir/validation/yield-lowering-pass.test.js +21 -12
- package/dist/ir/validation/yield-lowering-pass.test.js.map +1 -1
- package/dist/program/bindings.d.ts +20 -9
- package/dist/program/bindings.d.ts.map +1 -1
- package/dist/program/bindings.js +98 -36
- package/dist/program/bindings.js.map +1 -1
- package/dist/program/bindings.test.js +3 -3
- package/dist/program/dependency-graph.d.ts.map +1 -1
- package/dist/program/dependency-graph.js +31 -5
- package/dist/program/dependency-graph.js.map +1 -1
- package/dist/resolver/import-resolution.d.ts +4 -0
- package/dist/resolver/import-resolution.d.ts.map +1 -1
- package/dist/resolver/import-resolution.js +18 -7
- package/dist/resolver/import-resolution.js.map +1 -1
- package/dist/resolver.test.js +2 -2
- package/dist/resolver.test.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/generics.d.ts.map +1 -1
- package/dist/validation/generics.js +133 -1
- package/dist/validation/generics.js.map +1 -1
- package/dist/validation/static-safety.js +13 -0
- package/dist/validation/static-safety.js.map +1 -1
- package/dist/validation/unsupported-utility-types.d.ts +10 -8
- package/dist/validation/unsupported-utility-types.d.ts.map +1 -1
- package/dist/validation/unsupported-utility-types.js +12 -19
- package/dist/validation/unsupported-utility-types.js.map +1 -1
- package/dist/validator.test.js +133 -28
- package/dist/validator.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,854 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anonymous Object Type Lowering Pass
|
|
3
|
+
*
|
|
4
|
+
* Transforms anonymous object types (IrObjectType) in type positions into
|
|
5
|
+
* generated named types (IrReferenceType) with synthetic interface declarations.
|
|
6
|
+
*
|
|
7
|
+
* This pass runs BEFORE soundness validation to ensure the emitter never
|
|
8
|
+
* receives IrObjectType nodes.
|
|
9
|
+
*
|
|
10
|
+
* Example transformation:
|
|
11
|
+
* ```
|
|
12
|
+
* const config: { value: number } = { value: 42 };
|
|
13
|
+
* ```
|
|
14
|
+
* becomes:
|
|
15
|
+
* ```
|
|
16
|
+
* interface __Anon_abc123 { value: number }
|
|
17
|
+
* const config: __Anon_abc123 = { value: 42 };
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
import { createHash } from "crypto";
|
|
21
|
+
/**
|
|
22
|
+
* Serialize an IrType to a stable string for shape signature
|
|
23
|
+
*/
|
|
24
|
+
const serializeType = (type) => {
|
|
25
|
+
switch (type.kind) {
|
|
26
|
+
case "primitiveType":
|
|
27
|
+
return type.name;
|
|
28
|
+
case "literalType":
|
|
29
|
+
return `lit:${typeof type.value}:${String(type.value)}`;
|
|
30
|
+
case "referenceType":
|
|
31
|
+
if (type.typeArguments && type.typeArguments.length > 0) {
|
|
32
|
+
return `ref:${type.name}<${type.typeArguments.map(serializeType).join(",")}>`;
|
|
33
|
+
}
|
|
34
|
+
return `ref:${type.name}`;
|
|
35
|
+
case "arrayType":
|
|
36
|
+
return `arr:${serializeType(type.elementType)}`;
|
|
37
|
+
case "tupleType":
|
|
38
|
+
return `tup:[${type.elementTypes.map(serializeType).join(",")}]`;
|
|
39
|
+
case "functionType": {
|
|
40
|
+
const params = type.parameters
|
|
41
|
+
.map((p) => (p.type ? serializeType(p.type) : "any"))
|
|
42
|
+
.join(",");
|
|
43
|
+
return `fn:(${params})=>${serializeType(type.returnType)}`;
|
|
44
|
+
}
|
|
45
|
+
case "unionType":
|
|
46
|
+
return `union:[${type.types.map(serializeType).join("|")}]`;
|
|
47
|
+
case "typeParameterType":
|
|
48
|
+
return `tp:${type.name}`;
|
|
49
|
+
case "voidType":
|
|
50
|
+
return "void";
|
|
51
|
+
case "anyType":
|
|
52
|
+
return "any";
|
|
53
|
+
case "unknownType":
|
|
54
|
+
return "unknown";
|
|
55
|
+
case "neverType":
|
|
56
|
+
return "never";
|
|
57
|
+
case "objectType": {
|
|
58
|
+
// Serialize property signatures
|
|
59
|
+
const propMembers = type.members
|
|
60
|
+
.filter((m) => m.kind === "propertySignature")
|
|
61
|
+
.map((m) => `prop:${m.isReadonly ? "ro:" : ""}${m.name}${m.isOptional ? "?" : ""}:${serializeType(m.type)}`);
|
|
62
|
+
// Serialize method signatures
|
|
63
|
+
const methodMembers = type.members
|
|
64
|
+
.filter((m) => m.kind === "methodSignature")
|
|
65
|
+
.map((m) => {
|
|
66
|
+
const params = m.parameters
|
|
67
|
+
.map((p) => (p.type ? serializeType(p.type) : "any"))
|
|
68
|
+
.join(",");
|
|
69
|
+
const ret = m.returnType ? serializeType(m.returnType) : "void";
|
|
70
|
+
return `method:${m.name}(${params})=>${ret}`;
|
|
71
|
+
});
|
|
72
|
+
const allMembers = [...propMembers, ...methodMembers].sort().join(";");
|
|
73
|
+
return `obj:{${allMembers}}`;
|
|
74
|
+
}
|
|
75
|
+
case "dictionaryType":
|
|
76
|
+
return `dict:[${serializeType(type.keyType)}]:${serializeType(type.valueType)}`;
|
|
77
|
+
case "intersectionType":
|
|
78
|
+
return `intersection:[${type.types.map(serializeType).join("&")}]`;
|
|
79
|
+
default:
|
|
80
|
+
return "unknown";
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Compute shape signature for an objectType
|
|
85
|
+
*/
|
|
86
|
+
const computeShapeSignature = (objectType) => {
|
|
87
|
+
return serializeType(objectType);
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Generate a short hash from shape signature
|
|
91
|
+
*/
|
|
92
|
+
const generateShapeHash = (signature) => {
|
|
93
|
+
return createHash("md5").update(signature).digest("hex").slice(0, 8);
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Convert interface members to class property declarations
|
|
97
|
+
*/
|
|
98
|
+
const interfaceMembersToClassMembers = (members) => {
|
|
99
|
+
return members
|
|
100
|
+
.filter((m) => m.kind === "propertySignature")
|
|
101
|
+
.map((m) => {
|
|
102
|
+
// For optional properties (title?: string), make type nullable and don't require
|
|
103
|
+
// For required properties (title: string), use required modifier
|
|
104
|
+
const isOptional = m.isOptional ?? false;
|
|
105
|
+
return {
|
|
106
|
+
kind: "propertyDeclaration",
|
|
107
|
+
name: m.name,
|
|
108
|
+
type: m.type,
|
|
109
|
+
initializer: undefined,
|
|
110
|
+
isStatic: false,
|
|
111
|
+
isReadonly: m.isReadonly ?? false,
|
|
112
|
+
accessibility: "public",
|
|
113
|
+
isRequired: !isOptional, // C# 11 required modifier - must be set in object initializer
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Generate a module-unique hash from file path
|
|
119
|
+
*/
|
|
120
|
+
const generateModuleHash = (filePath) => {
|
|
121
|
+
return createHash("md5").update(filePath).digest("hex").slice(0, 4);
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Get or create a generated type name for an object type shape
|
|
125
|
+
*/
|
|
126
|
+
const getOrCreateTypeName = (objectType, ctx) => {
|
|
127
|
+
const signature = computeShapeSignature(objectType);
|
|
128
|
+
const existing = ctx.shapeToName.get(signature);
|
|
129
|
+
if (existing) {
|
|
130
|
+
return existing;
|
|
131
|
+
}
|
|
132
|
+
// Generate name with module hash prefix to avoid collisions across modules
|
|
133
|
+
const moduleHash = generateModuleHash(ctx.moduleFilePath);
|
|
134
|
+
const shapeHash = generateShapeHash(signature);
|
|
135
|
+
const name = `__Anon_${moduleHash}_${shapeHash}`;
|
|
136
|
+
ctx.shapeToName.set(signature, name);
|
|
137
|
+
// Create a class declaration (not interface) so it can be instantiated
|
|
138
|
+
const declaration = {
|
|
139
|
+
kind: "classDeclaration",
|
|
140
|
+
name,
|
|
141
|
+
typeParameters: undefined,
|
|
142
|
+
superClass: undefined,
|
|
143
|
+
implements: [],
|
|
144
|
+
members: interfaceMembersToClassMembers(objectType.members),
|
|
145
|
+
isExported: true, // Public to avoid inconsistent accessibility errors
|
|
146
|
+
isStruct: false,
|
|
147
|
+
};
|
|
148
|
+
ctx.generatedDeclarations.push(declaration);
|
|
149
|
+
return name;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Extract the non-undefined/null type from a union type.
|
|
153
|
+
* For `T | undefined` or `T | null | undefined`, returns T.
|
|
154
|
+
* For non-union types, returns the type as-is.
|
|
155
|
+
*/
|
|
156
|
+
const stripNullishFromType = (type) => {
|
|
157
|
+
if (type.kind !== "unionType") {
|
|
158
|
+
return type;
|
|
159
|
+
}
|
|
160
|
+
const nonNullish = type.types.filter((t) => !(t.kind === "primitiveType" &&
|
|
161
|
+
(t.name === "undefined" || t.name === "null")));
|
|
162
|
+
if (nonNullish.length === 0) {
|
|
163
|
+
// All types were nullish, return original
|
|
164
|
+
return type;
|
|
165
|
+
}
|
|
166
|
+
if (nonNullish.length === type.types.length) {
|
|
167
|
+
// No nullish types were filtered
|
|
168
|
+
return type;
|
|
169
|
+
}
|
|
170
|
+
if (nonNullish.length === 1) {
|
|
171
|
+
// Safe: we checked length === 1
|
|
172
|
+
const first = nonNullish[0];
|
|
173
|
+
if (first !== undefined) {
|
|
174
|
+
return first;
|
|
175
|
+
}
|
|
176
|
+
return type;
|
|
177
|
+
}
|
|
178
|
+
// Return a new union with the filtered types
|
|
179
|
+
return { ...type, types: nonNullish };
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Lower a type, replacing objectType with referenceType
|
|
183
|
+
*/
|
|
184
|
+
const lowerType = (type, ctx) => {
|
|
185
|
+
switch (type.kind) {
|
|
186
|
+
case "objectType": {
|
|
187
|
+
// First, recursively lower any nested object types in members
|
|
188
|
+
const loweredMembers = type.members.map((m) => {
|
|
189
|
+
if (m.kind === "propertySignature") {
|
|
190
|
+
return {
|
|
191
|
+
...m,
|
|
192
|
+
type: lowerType(m.type, ctx),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
else if (m.kind === "methodSignature") {
|
|
196
|
+
return {
|
|
197
|
+
...m,
|
|
198
|
+
parameters: m.parameters.map((p) => lowerParameter(p, ctx)),
|
|
199
|
+
returnType: m.returnType ? lowerType(m.returnType, ctx) : undefined,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
return m;
|
|
203
|
+
});
|
|
204
|
+
const loweredObjectType = {
|
|
205
|
+
...type,
|
|
206
|
+
members: loweredMembers,
|
|
207
|
+
};
|
|
208
|
+
// Generate name for this shape
|
|
209
|
+
const typeName = getOrCreateTypeName(loweredObjectType, ctx);
|
|
210
|
+
// Return reference to generated type
|
|
211
|
+
const refType = {
|
|
212
|
+
kind: "referenceType",
|
|
213
|
+
name: typeName,
|
|
214
|
+
typeArguments: undefined,
|
|
215
|
+
resolvedClrType: undefined,
|
|
216
|
+
};
|
|
217
|
+
return refType;
|
|
218
|
+
}
|
|
219
|
+
case "arrayType":
|
|
220
|
+
return {
|
|
221
|
+
...type,
|
|
222
|
+
elementType: lowerType(type.elementType, ctx),
|
|
223
|
+
};
|
|
224
|
+
case "tupleType":
|
|
225
|
+
return {
|
|
226
|
+
...type,
|
|
227
|
+
elementTypes: type.elementTypes.map((et) => lowerType(et, ctx)),
|
|
228
|
+
};
|
|
229
|
+
case "functionType":
|
|
230
|
+
return {
|
|
231
|
+
...type,
|
|
232
|
+
parameters: type.parameters.map((p) => lowerParameter(p, ctx)),
|
|
233
|
+
returnType: lowerType(type.returnType, ctx),
|
|
234
|
+
};
|
|
235
|
+
case "unionType":
|
|
236
|
+
return {
|
|
237
|
+
...type,
|
|
238
|
+
types: type.types.map((t) => lowerType(t, ctx)),
|
|
239
|
+
};
|
|
240
|
+
case "intersectionType":
|
|
241
|
+
return {
|
|
242
|
+
...type,
|
|
243
|
+
types: type.types.map((t) => lowerType(t, ctx)),
|
|
244
|
+
};
|
|
245
|
+
case "dictionaryType":
|
|
246
|
+
return {
|
|
247
|
+
...type,
|
|
248
|
+
keyType: lowerType(type.keyType, ctx),
|
|
249
|
+
valueType: lowerType(type.valueType, ctx),
|
|
250
|
+
};
|
|
251
|
+
case "referenceType": {
|
|
252
|
+
// Lower both typeArguments and structuralMembers
|
|
253
|
+
const typeArgs = type.typeArguments;
|
|
254
|
+
const structuralMembers = type.structuralMembers;
|
|
255
|
+
const hasTypeArgs = typeArgs !== undefined && typeArgs.length > 0;
|
|
256
|
+
const hasStructuralMembers = structuralMembers !== undefined && structuralMembers.length > 0;
|
|
257
|
+
if (!hasTypeArgs && !hasStructuralMembers) {
|
|
258
|
+
return type;
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
...type,
|
|
262
|
+
typeArguments: hasTypeArgs
|
|
263
|
+
? typeArgs.map((ta) => lowerType(ta, ctx))
|
|
264
|
+
: undefined,
|
|
265
|
+
structuralMembers: hasStructuralMembers
|
|
266
|
+
? structuralMembers.map((m) => lowerInterfaceMember(m, ctx))
|
|
267
|
+
: undefined,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
// These types don't contain nested types
|
|
271
|
+
case "primitiveType":
|
|
272
|
+
case "literalType":
|
|
273
|
+
case "typeParameterType":
|
|
274
|
+
case "voidType":
|
|
275
|
+
case "anyType":
|
|
276
|
+
case "unknownType":
|
|
277
|
+
case "neverType":
|
|
278
|
+
return type;
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
/**
|
|
282
|
+
* Lower a parameter
|
|
283
|
+
*/
|
|
284
|
+
const lowerParameter = (param, ctx) => {
|
|
285
|
+
return {
|
|
286
|
+
...param,
|
|
287
|
+
type: param.type ? lowerType(param.type, ctx) : undefined,
|
|
288
|
+
pattern: lowerPattern(param.pattern, ctx),
|
|
289
|
+
initializer: param.initializer
|
|
290
|
+
? lowerExpression(param.initializer, ctx)
|
|
291
|
+
: undefined,
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
/**
|
|
295
|
+
* Lower a type parameter
|
|
296
|
+
*/
|
|
297
|
+
const lowerTypeParameter = (tp, ctx) => {
|
|
298
|
+
return {
|
|
299
|
+
...tp,
|
|
300
|
+
constraint: tp.constraint ? lowerType(tp.constraint, ctx) : undefined,
|
|
301
|
+
default: tp.default ? lowerType(tp.default, ctx) : undefined,
|
|
302
|
+
structuralMembers: tp.structuralMembers?.map((m) => lowerInterfaceMember(m, ctx)),
|
|
303
|
+
};
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* Lower an interface member
|
|
307
|
+
*/
|
|
308
|
+
const lowerInterfaceMember = (member, ctx) => {
|
|
309
|
+
switch (member.kind) {
|
|
310
|
+
case "propertySignature":
|
|
311
|
+
return {
|
|
312
|
+
...member,
|
|
313
|
+
type: lowerType(member.type, ctx),
|
|
314
|
+
};
|
|
315
|
+
case "methodSignature":
|
|
316
|
+
return {
|
|
317
|
+
...member,
|
|
318
|
+
typeParameters: member.typeParameters?.map((tp) => lowerTypeParameter(tp, ctx)),
|
|
319
|
+
parameters: member.parameters.map((p) => lowerParameter(p, ctx)),
|
|
320
|
+
returnType: member.returnType
|
|
321
|
+
? lowerType(member.returnType, ctx)
|
|
322
|
+
: undefined,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
/**
|
|
327
|
+
* Lower a pattern
|
|
328
|
+
*/
|
|
329
|
+
const lowerPattern = (pattern, ctx) => {
|
|
330
|
+
switch (pattern.kind) {
|
|
331
|
+
case "identifierPattern":
|
|
332
|
+
return {
|
|
333
|
+
...pattern,
|
|
334
|
+
type: pattern.type ? lowerType(pattern.type, ctx) : undefined,
|
|
335
|
+
};
|
|
336
|
+
case "arrayPattern":
|
|
337
|
+
return {
|
|
338
|
+
...pattern,
|
|
339
|
+
elements: pattern.elements.map((e) => e ? lowerPattern(e, ctx) : undefined),
|
|
340
|
+
};
|
|
341
|
+
case "objectPattern":
|
|
342
|
+
return {
|
|
343
|
+
...pattern,
|
|
344
|
+
properties: pattern.properties.map((p) => {
|
|
345
|
+
if (p.kind === "property") {
|
|
346
|
+
return {
|
|
347
|
+
...p,
|
|
348
|
+
value: lowerPattern(p.value, ctx),
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
else {
|
|
352
|
+
return {
|
|
353
|
+
...p,
|
|
354
|
+
pattern: lowerPattern(p.pattern, ctx),
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
}),
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
/**
|
|
362
|
+
* Lower an expression
|
|
363
|
+
*/
|
|
364
|
+
const lowerExpression = (expr, ctx) => {
|
|
365
|
+
switch (expr.kind) {
|
|
366
|
+
case "literal":
|
|
367
|
+
case "identifier":
|
|
368
|
+
case "this":
|
|
369
|
+
return expr;
|
|
370
|
+
case "array":
|
|
371
|
+
return {
|
|
372
|
+
...expr,
|
|
373
|
+
elements: expr.elements.map((e) => e ? lowerExpression(e, ctx) : undefined),
|
|
374
|
+
};
|
|
375
|
+
case "object":
|
|
376
|
+
return {
|
|
377
|
+
...expr,
|
|
378
|
+
contextualType: expr.contextualType
|
|
379
|
+
? lowerType(expr.contextualType, ctx)
|
|
380
|
+
: undefined,
|
|
381
|
+
properties: expr.properties.map((p) => {
|
|
382
|
+
if (p.kind === "property") {
|
|
383
|
+
return {
|
|
384
|
+
...p,
|
|
385
|
+
key: typeof p.key === "string" ? p.key : lowerExpression(p.key, ctx),
|
|
386
|
+
value: lowerExpression(p.value, ctx),
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
return {
|
|
391
|
+
...p,
|
|
392
|
+
expression: lowerExpression(p.expression, ctx),
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
}),
|
|
396
|
+
};
|
|
397
|
+
case "functionExpression": {
|
|
398
|
+
const loweredReturnType = expr.returnType
|
|
399
|
+
? lowerType(expr.returnType, ctx)
|
|
400
|
+
: undefined;
|
|
401
|
+
const bodyCtx = {
|
|
402
|
+
...ctx,
|
|
403
|
+
currentFunctionReturnType: loweredReturnType,
|
|
404
|
+
};
|
|
405
|
+
return {
|
|
406
|
+
...expr,
|
|
407
|
+
parameters: expr.parameters.map((p) => lowerParameter(p, ctx)),
|
|
408
|
+
returnType: loweredReturnType,
|
|
409
|
+
body: lowerBlockStatement(expr.body, bodyCtx),
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
case "arrowFunction": {
|
|
413
|
+
const loweredReturnType = expr.returnType
|
|
414
|
+
? lowerType(expr.returnType, ctx)
|
|
415
|
+
: undefined;
|
|
416
|
+
const bodyCtx = {
|
|
417
|
+
...ctx,
|
|
418
|
+
currentFunctionReturnType: loweredReturnType,
|
|
419
|
+
};
|
|
420
|
+
// For expression body arrow functions, we need to handle inferredType directly
|
|
421
|
+
if (expr.body.kind === "blockStatement") {
|
|
422
|
+
return {
|
|
423
|
+
...expr,
|
|
424
|
+
parameters: expr.parameters.map((p) => lowerParameter(p, ctx)),
|
|
425
|
+
returnType: loweredReturnType,
|
|
426
|
+
body: lowerBlockStatement(expr.body, bodyCtx),
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
else {
|
|
430
|
+
const loweredBody = lowerExpression(expr.body, ctx);
|
|
431
|
+
// If arrow has expression body and return type, propagate to expression's inferredType
|
|
432
|
+
const bodyWithType = loweredReturnType && loweredBody.inferredType?.kind === "objectType"
|
|
433
|
+
? { ...loweredBody, inferredType: loweredReturnType }
|
|
434
|
+
: loweredBody;
|
|
435
|
+
return {
|
|
436
|
+
...expr,
|
|
437
|
+
parameters: expr.parameters.map((p) => lowerParameter(p, ctx)),
|
|
438
|
+
returnType: loweredReturnType,
|
|
439
|
+
body: bodyWithType,
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
case "memberAccess":
|
|
444
|
+
return {
|
|
445
|
+
...expr,
|
|
446
|
+
object: lowerExpression(expr.object, ctx),
|
|
447
|
+
property: typeof expr.property === "string"
|
|
448
|
+
? expr.property
|
|
449
|
+
: lowerExpression(expr.property, ctx),
|
|
450
|
+
};
|
|
451
|
+
case "call":
|
|
452
|
+
return {
|
|
453
|
+
...expr,
|
|
454
|
+
callee: lowerExpression(expr.callee, ctx),
|
|
455
|
+
arguments: expr.arguments.map((a) => lowerExpression(a, ctx)),
|
|
456
|
+
typeArguments: expr.typeArguments?.map((ta) => lowerType(ta, ctx)),
|
|
457
|
+
};
|
|
458
|
+
case "new":
|
|
459
|
+
return {
|
|
460
|
+
...expr,
|
|
461
|
+
callee: lowerExpression(expr.callee, ctx),
|
|
462
|
+
arguments: expr.arguments.map((a) => lowerExpression(a, ctx)),
|
|
463
|
+
typeArguments: expr.typeArguments?.map((ta) => lowerType(ta, ctx)),
|
|
464
|
+
};
|
|
465
|
+
case "update":
|
|
466
|
+
case "unary":
|
|
467
|
+
case "await":
|
|
468
|
+
return {
|
|
469
|
+
...expr,
|
|
470
|
+
expression: lowerExpression(expr.expression, ctx),
|
|
471
|
+
};
|
|
472
|
+
case "yield":
|
|
473
|
+
return {
|
|
474
|
+
...expr,
|
|
475
|
+
expression: expr.expression
|
|
476
|
+
? lowerExpression(expr.expression, ctx)
|
|
477
|
+
: undefined,
|
|
478
|
+
};
|
|
479
|
+
case "binary":
|
|
480
|
+
case "logical":
|
|
481
|
+
return {
|
|
482
|
+
...expr,
|
|
483
|
+
left: lowerExpression(expr.left, ctx),
|
|
484
|
+
right: lowerExpression(expr.right, ctx),
|
|
485
|
+
};
|
|
486
|
+
case "conditional":
|
|
487
|
+
return {
|
|
488
|
+
...expr,
|
|
489
|
+
condition: lowerExpression(expr.condition, ctx),
|
|
490
|
+
whenTrue: lowerExpression(expr.whenTrue, ctx),
|
|
491
|
+
whenFalse: lowerExpression(expr.whenFalse, ctx),
|
|
492
|
+
};
|
|
493
|
+
case "assignment":
|
|
494
|
+
return {
|
|
495
|
+
...expr,
|
|
496
|
+
left: expr.left.kind === "identifierPattern" ||
|
|
497
|
+
expr.left.kind === "arrayPattern" ||
|
|
498
|
+
expr.left.kind === "objectPattern"
|
|
499
|
+
? lowerPattern(expr.left, ctx)
|
|
500
|
+
: lowerExpression(expr.left, ctx),
|
|
501
|
+
right: lowerExpression(expr.right, ctx),
|
|
502
|
+
};
|
|
503
|
+
case "templateLiteral":
|
|
504
|
+
return {
|
|
505
|
+
...expr,
|
|
506
|
+
expressions: expr.expressions.map((e) => lowerExpression(e, ctx)),
|
|
507
|
+
};
|
|
508
|
+
case "spread":
|
|
509
|
+
return {
|
|
510
|
+
...expr,
|
|
511
|
+
expression: lowerExpression(expr.expression, ctx),
|
|
512
|
+
};
|
|
513
|
+
case "numericNarrowing":
|
|
514
|
+
return {
|
|
515
|
+
...expr,
|
|
516
|
+
expression: lowerExpression(expr.expression, ctx),
|
|
517
|
+
inferredType: lowerType(expr.inferredType, ctx),
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
/**
|
|
522
|
+
* Lower a block statement specifically (for places that need IrBlockStatement)
|
|
523
|
+
*/
|
|
524
|
+
const lowerBlockStatement = (stmt, ctx) => {
|
|
525
|
+
return {
|
|
526
|
+
...stmt,
|
|
527
|
+
statements: stmt.statements.map((s) => lowerStatement(s, ctx)),
|
|
528
|
+
};
|
|
529
|
+
};
|
|
530
|
+
/**
|
|
531
|
+
* Lower a variable declaration specifically (for forStatement initializer)
|
|
532
|
+
*/
|
|
533
|
+
const lowerVariableDeclaration = (stmt, ctx) => {
|
|
534
|
+
return {
|
|
535
|
+
...stmt,
|
|
536
|
+
declarations: stmt.declarations.map((d) => ({
|
|
537
|
+
...d,
|
|
538
|
+
name: lowerPattern(d.name, ctx),
|
|
539
|
+
type: d.type ? lowerType(d.type, ctx) : undefined,
|
|
540
|
+
initializer: d.initializer
|
|
541
|
+
? lowerExpression(d.initializer, ctx)
|
|
542
|
+
: undefined,
|
|
543
|
+
})),
|
|
544
|
+
};
|
|
545
|
+
};
|
|
546
|
+
/**
|
|
547
|
+
* Lower a class member
|
|
548
|
+
*/
|
|
549
|
+
const lowerClassMember = (member, ctx) => {
|
|
550
|
+
switch (member.kind) {
|
|
551
|
+
case "methodDeclaration": {
|
|
552
|
+
const loweredReturnType = member.returnType
|
|
553
|
+
? lowerType(member.returnType, ctx)
|
|
554
|
+
: undefined;
|
|
555
|
+
const bodyCtx = {
|
|
556
|
+
...ctx,
|
|
557
|
+
currentFunctionReturnType: loweredReturnType,
|
|
558
|
+
};
|
|
559
|
+
return {
|
|
560
|
+
...member,
|
|
561
|
+
typeParameters: member.typeParameters?.map((tp) => lowerTypeParameter(tp, ctx)),
|
|
562
|
+
parameters: member.parameters.map((p) => lowerParameter(p, ctx)),
|
|
563
|
+
returnType: loweredReturnType,
|
|
564
|
+
body: member.body
|
|
565
|
+
? lowerBlockStatement(member.body, bodyCtx)
|
|
566
|
+
: undefined,
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
case "propertyDeclaration":
|
|
570
|
+
return {
|
|
571
|
+
...member,
|
|
572
|
+
type: member.type ? lowerType(member.type, ctx) : undefined,
|
|
573
|
+
initializer: member.initializer
|
|
574
|
+
? lowerExpression(member.initializer, ctx)
|
|
575
|
+
: undefined,
|
|
576
|
+
};
|
|
577
|
+
case "constructorDeclaration":
|
|
578
|
+
return {
|
|
579
|
+
...member,
|
|
580
|
+
parameters: member.parameters.map((p) => lowerParameter(p, ctx)),
|
|
581
|
+
body: member.body ? lowerBlockStatement(member.body, ctx) : undefined,
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
};
|
|
585
|
+
/**
|
|
586
|
+
* Lower a statement
|
|
587
|
+
*/
|
|
588
|
+
const lowerStatement = (stmt, ctx) => {
|
|
589
|
+
switch (stmt.kind) {
|
|
590
|
+
case "variableDeclaration":
|
|
591
|
+
return {
|
|
592
|
+
...stmt,
|
|
593
|
+
declarations: stmt.declarations.map((d) => ({
|
|
594
|
+
...d,
|
|
595
|
+
name: lowerPattern(d.name, ctx),
|
|
596
|
+
type: d.type ? lowerType(d.type, ctx) : undefined,
|
|
597
|
+
initializer: d.initializer
|
|
598
|
+
? lowerExpression(d.initializer, ctx)
|
|
599
|
+
: undefined,
|
|
600
|
+
})),
|
|
601
|
+
};
|
|
602
|
+
case "functionDeclaration": {
|
|
603
|
+
// First lower the return type
|
|
604
|
+
const loweredReturnType = stmt.returnType
|
|
605
|
+
? lowerType(stmt.returnType, ctx)
|
|
606
|
+
: undefined;
|
|
607
|
+
// Create context with the lowered return type for return statements
|
|
608
|
+
const bodyCtx = {
|
|
609
|
+
...ctx,
|
|
610
|
+
currentFunctionReturnType: loweredReturnType,
|
|
611
|
+
};
|
|
612
|
+
return {
|
|
613
|
+
...stmt,
|
|
614
|
+
typeParameters: stmt.typeParameters?.map((tp) => lowerTypeParameter(tp, ctx)),
|
|
615
|
+
parameters: stmt.parameters.map((p) => lowerParameter(p, ctx)),
|
|
616
|
+
returnType: loweredReturnType,
|
|
617
|
+
body: lowerBlockStatement(stmt.body, bodyCtx),
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
case "classDeclaration":
|
|
621
|
+
return {
|
|
622
|
+
...stmt,
|
|
623
|
+
typeParameters: stmt.typeParameters?.map((tp) => lowerTypeParameter(tp, ctx)),
|
|
624
|
+
superClass: stmt.superClass
|
|
625
|
+
? lowerExpression(stmt.superClass, ctx)
|
|
626
|
+
: undefined,
|
|
627
|
+
implements: stmt.implements.map((i) => lowerType(i, ctx)),
|
|
628
|
+
members: stmt.members.map((m) => lowerClassMember(m, ctx)),
|
|
629
|
+
};
|
|
630
|
+
case "interfaceDeclaration":
|
|
631
|
+
return {
|
|
632
|
+
...stmt,
|
|
633
|
+
typeParameters: stmt.typeParameters?.map((tp) => lowerTypeParameter(tp, ctx)),
|
|
634
|
+
extends: stmt.extends.map((e) => lowerType(e, ctx)),
|
|
635
|
+
members: stmt.members.map((m) => lowerInterfaceMember(m, ctx)),
|
|
636
|
+
};
|
|
637
|
+
case "enumDeclaration":
|
|
638
|
+
return {
|
|
639
|
+
...stmt,
|
|
640
|
+
members: stmt.members.map((m) => ({
|
|
641
|
+
...m,
|
|
642
|
+
initializer: m.initializer
|
|
643
|
+
? lowerExpression(m.initializer, ctx)
|
|
644
|
+
: undefined,
|
|
645
|
+
})),
|
|
646
|
+
};
|
|
647
|
+
case "typeAliasDeclaration":
|
|
648
|
+
// IMPORTANT: Do NOT lower the top-level objectType in a type alias declaration.
|
|
649
|
+
// The emitter already generates a class with __Alias suffix for these.
|
|
650
|
+
// We only lower nested objectTypes within the members.
|
|
651
|
+
if (stmt.type.kind === "objectType") {
|
|
652
|
+
// Lower nested types within the object type's members, but keep objectType as-is
|
|
653
|
+
const loweredMembers = stmt.type.members.map((m) => {
|
|
654
|
+
if (m.kind === "propertySignature") {
|
|
655
|
+
return {
|
|
656
|
+
...m,
|
|
657
|
+
type: lowerType(m.type, ctx),
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
else if (m.kind === "methodSignature") {
|
|
661
|
+
return {
|
|
662
|
+
...m,
|
|
663
|
+
parameters: m.parameters.map((p) => lowerParameter(p, ctx)),
|
|
664
|
+
returnType: m.returnType
|
|
665
|
+
? lowerType(m.returnType, ctx)
|
|
666
|
+
: undefined,
|
|
667
|
+
};
|
|
668
|
+
}
|
|
669
|
+
return m;
|
|
670
|
+
});
|
|
671
|
+
return {
|
|
672
|
+
...stmt,
|
|
673
|
+
typeParameters: stmt.typeParameters?.map((tp) => lowerTypeParameter(tp, ctx)),
|
|
674
|
+
type: {
|
|
675
|
+
...stmt.type,
|
|
676
|
+
members: loweredMembers,
|
|
677
|
+
},
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
// For non-objectType type aliases, lower the type normally
|
|
681
|
+
return {
|
|
682
|
+
...stmt,
|
|
683
|
+
typeParameters: stmt.typeParameters?.map((tp) => lowerTypeParameter(tp, ctx)),
|
|
684
|
+
type: lowerType(stmt.type, ctx),
|
|
685
|
+
};
|
|
686
|
+
case "expressionStatement":
|
|
687
|
+
return {
|
|
688
|
+
...stmt,
|
|
689
|
+
expression: lowerExpression(stmt.expression, ctx),
|
|
690
|
+
};
|
|
691
|
+
case "returnStatement": {
|
|
692
|
+
if (!stmt.expression) {
|
|
693
|
+
return stmt;
|
|
694
|
+
}
|
|
695
|
+
const loweredExpr = lowerExpression(stmt.expression, ctx);
|
|
696
|
+
// If we have a function return type and the expression's inferredType is objectType,
|
|
697
|
+
// replace it with the lowered type (stripping nullish from union if needed)
|
|
698
|
+
if (ctx.currentFunctionReturnType &&
|
|
699
|
+
loweredExpr.inferredType?.kind === "objectType") {
|
|
700
|
+
// Extract non-nullish part of return type (e.g., { title: string } from { title: string } | undefined)
|
|
701
|
+
const targetType = stripNullishFromType(ctx.currentFunctionReturnType);
|
|
702
|
+
return {
|
|
703
|
+
...stmt,
|
|
704
|
+
expression: { ...loweredExpr, inferredType: targetType },
|
|
705
|
+
};
|
|
706
|
+
}
|
|
707
|
+
return {
|
|
708
|
+
...stmt,
|
|
709
|
+
expression: loweredExpr,
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
case "ifStatement":
|
|
713
|
+
return {
|
|
714
|
+
...stmt,
|
|
715
|
+
condition: lowerExpression(stmt.condition, ctx),
|
|
716
|
+
thenStatement: lowerStatement(stmt.thenStatement, ctx),
|
|
717
|
+
elseStatement: stmt.elseStatement
|
|
718
|
+
? lowerStatement(stmt.elseStatement, ctx)
|
|
719
|
+
: undefined,
|
|
720
|
+
};
|
|
721
|
+
case "whileStatement":
|
|
722
|
+
return {
|
|
723
|
+
...stmt,
|
|
724
|
+
condition: lowerExpression(stmt.condition, ctx),
|
|
725
|
+
body: lowerStatement(stmt.body, ctx),
|
|
726
|
+
};
|
|
727
|
+
case "forStatement":
|
|
728
|
+
return {
|
|
729
|
+
...stmt,
|
|
730
|
+
initializer: stmt.initializer
|
|
731
|
+
? stmt.initializer.kind === "variableDeclaration"
|
|
732
|
+
? lowerVariableDeclaration(stmt.initializer, ctx)
|
|
733
|
+
: lowerExpression(stmt.initializer, ctx)
|
|
734
|
+
: undefined,
|
|
735
|
+
condition: stmt.condition
|
|
736
|
+
? lowerExpression(stmt.condition, ctx)
|
|
737
|
+
: undefined,
|
|
738
|
+
update: stmt.update ? lowerExpression(stmt.update, ctx) : undefined,
|
|
739
|
+
body: lowerStatement(stmt.body, ctx),
|
|
740
|
+
};
|
|
741
|
+
case "forOfStatement":
|
|
742
|
+
return {
|
|
743
|
+
...stmt,
|
|
744
|
+
variable: lowerPattern(stmt.variable, ctx),
|
|
745
|
+
expression: lowerExpression(stmt.expression, ctx),
|
|
746
|
+
body: lowerStatement(stmt.body, ctx),
|
|
747
|
+
};
|
|
748
|
+
case "switchStatement":
|
|
749
|
+
return {
|
|
750
|
+
...stmt,
|
|
751
|
+
expression: lowerExpression(stmt.expression, ctx),
|
|
752
|
+
cases: stmt.cases.map((c) => ({
|
|
753
|
+
...c,
|
|
754
|
+
test: c.test ? lowerExpression(c.test, ctx) : undefined,
|
|
755
|
+
statements: c.statements.map((s) => lowerStatement(s, ctx)),
|
|
756
|
+
})),
|
|
757
|
+
};
|
|
758
|
+
case "throwStatement":
|
|
759
|
+
return {
|
|
760
|
+
...stmt,
|
|
761
|
+
expression: lowerExpression(stmt.expression, ctx),
|
|
762
|
+
};
|
|
763
|
+
case "tryStatement":
|
|
764
|
+
return {
|
|
765
|
+
...stmt,
|
|
766
|
+
tryBlock: lowerBlockStatement(stmt.tryBlock, ctx),
|
|
767
|
+
catchClause: stmt.catchClause
|
|
768
|
+
? {
|
|
769
|
+
...stmt.catchClause,
|
|
770
|
+
parameter: stmt.catchClause.parameter
|
|
771
|
+
? lowerPattern(stmt.catchClause.parameter, ctx)
|
|
772
|
+
: undefined,
|
|
773
|
+
body: lowerBlockStatement(stmt.catchClause.body, ctx),
|
|
774
|
+
}
|
|
775
|
+
: undefined,
|
|
776
|
+
finallyBlock: stmt.finallyBlock
|
|
777
|
+
? lowerBlockStatement(stmt.finallyBlock, ctx)
|
|
778
|
+
: undefined,
|
|
779
|
+
};
|
|
780
|
+
case "blockStatement":
|
|
781
|
+
return {
|
|
782
|
+
...stmt,
|
|
783
|
+
statements: stmt.statements.map((s) => lowerStatement(s, ctx)),
|
|
784
|
+
};
|
|
785
|
+
case "yieldStatement":
|
|
786
|
+
return {
|
|
787
|
+
...stmt,
|
|
788
|
+
output: stmt.output ? lowerExpression(stmt.output, ctx) : undefined,
|
|
789
|
+
receiveTarget: stmt.receiveTarget
|
|
790
|
+
? lowerPattern(stmt.receiveTarget, ctx)
|
|
791
|
+
: undefined,
|
|
792
|
+
receivedType: stmt.receivedType
|
|
793
|
+
? lowerType(stmt.receivedType, ctx)
|
|
794
|
+
: undefined,
|
|
795
|
+
};
|
|
796
|
+
case "generatorReturnStatement":
|
|
797
|
+
return {
|
|
798
|
+
...stmt,
|
|
799
|
+
expression: stmt.expression
|
|
800
|
+
? lowerExpression(stmt.expression, ctx)
|
|
801
|
+
: undefined,
|
|
802
|
+
};
|
|
803
|
+
case "breakStatement":
|
|
804
|
+
case "continueStatement":
|
|
805
|
+
case "emptyStatement":
|
|
806
|
+
return stmt;
|
|
807
|
+
}
|
|
808
|
+
};
|
|
809
|
+
/**
|
|
810
|
+
* Lower a single module
|
|
811
|
+
*/
|
|
812
|
+
const lowerModule = (module) => {
|
|
813
|
+
const ctx = {
|
|
814
|
+
generatedDeclarations: [],
|
|
815
|
+
shapeToName: new Map(),
|
|
816
|
+
moduleFilePath: module.filePath,
|
|
817
|
+
};
|
|
818
|
+
// Lower all statements in the module body
|
|
819
|
+
const loweredBody = module.body.map((stmt) => lowerStatement(stmt, ctx));
|
|
820
|
+
// Lower exports
|
|
821
|
+
const loweredExports = module.exports.map((exp) => {
|
|
822
|
+
if (exp.kind === "default") {
|
|
823
|
+
return {
|
|
824
|
+
...exp,
|
|
825
|
+
expression: lowerExpression(exp.expression, ctx),
|
|
826
|
+
};
|
|
827
|
+
}
|
|
828
|
+
else if (exp.kind === "declaration") {
|
|
829
|
+
return {
|
|
830
|
+
...exp,
|
|
831
|
+
declaration: lowerStatement(exp.declaration, ctx),
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
return exp;
|
|
835
|
+
});
|
|
836
|
+
// Prepend generated declarations to module body
|
|
837
|
+
const newBody = [...ctx.generatedDeclarations, ...loweredBody];
|
|
838
|
+
return {
|
|
839
|
+
...module,
|
|
840
|
+
body: newBody,
|
|
841
|
+
exports: loweredExports,
|
|
842
|
+
};
|
|
843
|
+
};
|
|
844
|
+
/**
|
|
845
|
+
* Run anonymous type lowering pass on all modules
|
|
846
|
+
*/
|
|
847
|
+
export const runAnonymousTypeLoweringPass = (modules) => {
|
|
848
|
+
const loweredModules = modules.map((m) => lowerModule(m));
|
|
849
|
+
return {
|
|
850
|
+
ok: true,
|
|
851
|
+
modules: loweredModules,
|
|
852
|
+
};
|
|
853
|
+
};
|
|
854
|
+
//# sourceMappingURL=anonymous-type-lowering-pass.js.map
|