@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.
Files changed (125) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/ir/converters/expressions/access.d.ts.map +1 -1
  3. package/dist/ir/converters/expressions/access.js +61 -1
  4. package/dist/ir/converters/expressions/access.js.map +1 -1
  5. package/dist/ir/converters/expressions/calls.d.ts.map +1 -1
  6. package/dist/ir/converters/expressions/calls.js +293 -24
  7. package/dist/ir/converters/expressions/calls.js.map +1 -1
  8. package/dist/ir/converters/expressions/helpers.js +4 -4
  9. package/dist/ir/converters/expressions/helpers.js.map +1 -1
  10. package/dist/ir/converters/expressions/literals.d.ts +14 -0
  11. package/dist/ir/converters/expressions/literals.d.ts.map +1 -1
  12. package/dist/ir/converters/expressions/literals.js +22 -2
  13. package/dist/ir/converters/expressions/literals.js.map +1 -1
  14. package/dist/ir/converters/expressions/numeric-recovery.test.js +3 -2
  15. package/dist/ir/converters/expressions/numeric-recovery.test.js.map +1 -1
  16. package/dist/ir/converters/statements/helpers.d.ts.map +1 -1
  17. package/dist/ir/converters/statements/helpers.js +10 -4
  18. package/dist/ir/converters/statements/helpers.js.map +1 -1
  19. package/dist/ir/expression-converter.d.ts.map +1 -1
  20. package/dist/ir/expression-converter.js +38 -5
  21. package/dist/ir/expression-converter.js.map +1 -1
  22. package/dist/ir/index.d.ts +1 -1
  23. package/dist/ir/index.d.ts.map +1 -1
  24. package/dist/ir/index.js +1 -1
  25. package/dist/ir/index.js.map +1 -1
  26. package/dist/ir/statement-converter.d.ts.map +1 -1
  27. package/dist/ir/statement-converter.js +12 -0
  28. package/dist/ir/statement-converter.js.map +1 -1
  29. package/dist/ir/type-converter/inference.d.ts.map +1 -1
  30. package/dist/ir/type-converter/inference.js +50 -7
  31. package/dist/ir/type-converter/inference.js.map +1 -1
  32. package/dist/ir/type-converter/primitives.d.ts +26 -4
  33. package/dist/ir/type-converter/primitives.d.ts.map +1 -1
  34. package/dist/ir/type-converter/primitives.js +36 -2
  35. package/dist/ir/type-converter/primitives.js.map +1 -1
  36. package/dist/ir/type-converter/references.d.ts.map +1 -1
  37. package/dist/ir/type-converter/references.js +324 -11
  38. package/dist/ir/type-converter/references.js.map +1 -1
  39. package/dist/ir/type-converter/utility-types.d.ts +93 -0
  40. package/dist/ir/type-converter/utility-types.d.ts.map +1 -0
  41. package/dist/ir/type-converter/utility-types.js +528 -0
  42. package/dist/ir/type-converter/utility-types.js.map +1 -0
  43. package/dist/ir/type-converter/utility-types.test.d.ts +10 -0
  44. package/dist/ir/type-converter/utility-types.test.d.ts.map +1 -0
  45. package/dist/ir/type-converter/utility-types.test.js +1030 -0
  46. package/dist/ir/type-converter/utility-types.test.js.map +1 -0
  47. package/dist/ir/types/expressions.d.ts +40 -2
  48. package/dist/ir/types/expressions.d.ts.map +1 -1
  49. package/dist/ir/types/helpers.d.ts +3 -1
  50. package/dist/ir/types/helpers.d.ts.map +1 -1
  51. package/dist/ir/types/index.d.ts +2 -1
  52. package/dist/ir/types/index.d.ts.map +1 -1
  53. package/dist/ir/types/index.js +2 -0
  54. package/dist/ir/types/index.js.map +1 -1
  55. package/dist/ir/types/ir-types.d.ts +69 -11
  56. package/dist/ir/types/ir-types.d.ts.map +1 -1
  57. package/dist/ir/types/numeric-helpers.d.ts +46 -0
  58. package/dist/ir/types/numeric-helpers.d.ts.map +1 -0
  59. package/dist/ir/types/numeric-helpers.js +105 -0
  60. package/dist/ir/types/numeric-helpers.js.map +1 -0
  61. package/dist/ir/types/statements.d.ts +11 -1
  62. package/dist/ir/types/statements.d.ts.map +1 -1
  63. package/dist/ir/types.d.ts +2 -2
  64. package/dist/ir/types.d.ts.map +1 -1
  65. package/dist/ir/types.js +3 -1
  66. package/dist/ir/types.js.map +1 -1
  67. package/dist/ir/validation/anonymous-type-lowering-pass.d.ts +32 -0
  68. package/dist/ir/validation/anonymous-type-lowering-pass.d.ts.map +1 -0
  69. package/dist/ir/validation/anonymous-type-lowering-pass.js +854 -0
  70. package/dist/ir/validation/anonymous-type-lowering-pass.js.map +1 -0
  71. package/dist/ir/validation/attribute-collection-pass.d.ts +37 -0
  72. package/dist/ir/validation/attribute-collection-pass.d.ts.map +1 -0
  73. package/dist/ir/validation/attribute-collection-pass.js +282 -0
  74. package/dist/ir/validation/attribute-collection-pass.js.map +1 -0
  75. package/dist/ir/validation/attribute-collection-pass.test.d.ts +5 -0
  76. package/dist/ir/validation/attribute-collection-pass.test.d.ts.map +1 -0
  77. package/dist/ir/validation/attribute-collection-pass.test.js +215 -0
  78. package/dist/ir/validation/attribute-collection-pass.test.js.map +1 -0
  79. package/dist/ir/validation/index.d.ts +3 -0
  80. package/dist/ir/validation/index.d.ts.map +1 -1
  81. package/dist/ir/validation/index.js +3 -0
  82. package/dist/ir/validation/index.js.map +1 -1
  83. package/dist/ir/validation/numeric-coercion-pass.d.ts +77 -0
  84. package/dist/ir/validation/numeric-coercion-pass.d.ts.map +1 -0
  85. package/dist/ir/validation/numeric-coercion-pass.js +686 -0
  86. package/dist/ir/validation/numeric-coercion-pass.js.map +1 -0
  87. package/dist/ir/validation/numeric-invariants.test.js +130 -14
  88. package/dist/ir/validation/numeric-invariants.test.js.map +1 -1
  89. package/dist/ir/validation/numeric-proof-pass.d.ts.map +1 -1
  90. package/dist/ir/validation/numeric-proof-pass.js +68 -108
  91. package/dist/ir/validation/numeric-proof-pass.js.map +1 -1
  92. package/dist/ir/validation/soundness-gate.d.ts.map +1 -1
  93. package/dist/ir/validation/soundness-gate.js +23 -12
  94. package/dist/ir/validation/soundness-gate.js.map +1 -1
  95. package/dist/ir/validation/yield-lowering-pass.test.js +21 -12
  96. package/dist/ir/validation/yield-lowering-pass.test.js.map +1 -1
  97. package/dist/program/bindings.d.ts +20 -9
  98. package/dist/program/bindings.d.ts.map +1 -1
  99. package/dist/program/bindings.js +98 -36
  100. package/dist/program/bindings.js.map +1 -1
  101. package/dist/program/bindings.test.js +3 -3
  102. package/dist/program/dependency-graph.d.ts.map +1 -1
  103. package/dist/program/dependency-graph.js +31 -5
  104. package/dist/program/dependency-graph.js.map +1 -1
  105. package/dist/resolver/import-resolution.d.ts +4 -0
  106. package/dist/resolver/import-resolution.d.ts.map +1 -1
  107. package/dist/resolver/import-resolution.js +18 -7
  108. package/dist/resolver/import-resolution.js.map +1 -1
  109. package/dist/resolver.test.js +2 -2
  110. package/dist/resolver.test.js.map +1 -1
  111. package/dist/types/diagnostic.d.ts +1 -1
  112. package/dist/types/diagnostic.d.ts.map +1 -1
  113. package/dist/types/diagnostic.js.map +1 -1
  114. package/dist/validation/generics.d.ts.map +1 -1
  115. package/dist/validation/generics.js +133 -1
  116. package/dist/validation/generics.js.map +1 -1
  117. package/dist/validation/static-safety.js +13 -0
  118. package/dist/validation/static-safety.js.map +1 -1
  119. package/dist/validation/unsupported-utility-types.d.ts +10 -8
  120. package/dist/validation/unsupported-utility-types.d.ts.map +1 -1
  121. package/dist/validation/unsupported-utility-types.js +12 -19
  122. package/dist/validation/unsupported-utility-types.js.map +1 -1
  123. package/dist/validator.test.js +133 -28
  124. package/dist/validator.test.js.map +1 -1
  125. 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