@tsonic/emitter 0.0.66 → 0.0.68

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 (113) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/array.test.js +67 -3
  3. package/dist/array.test.js.map +1 -1
  4. package/dist/core/format/backend-ast/index.d.ts +1 -1
  5. package/dist/core/format/backend-ast/index.d.ts.map +1 -1
  6. package/dist/core/format/backend-ast/index.js.map +1 -1
  7. package/dist/core/format/backend-ast/printer.d.ts.map +1 -1
  8. package/dist/core/format/backend-ast/printer.js +5 -1
  9. package/dist/core/format/backend-ast/printer.js.map +1 -1
  10. package/dist/core/format/backend-ast/types.d.ts +6 -1
  11. package/dist/core/format/backend-ast/types.d.ts.map +1 -1
  12. package/dist/core/format/module-emitter/orchestrator.d.ts.map +1 -1
  13. package/dist/core/format/module-emitter/orchestrator.js +7 -0
  14. package/dist/core/format/module-emitter/orchestrator.js.map +1 -1
  15. package/dist/core/module-emitter.test.js +125 -0
  16. package/dist/core/module-emitter.test.js.map +1 -1
  17. package/dist/core/semantic/imports.d.ts.map +1 -1
  18. package/dist/core/semantic/imports.js +62 -4
  19. package/dist/core/semantic/imports.js.map +1 -1
  20. package/dist/core/semantic/imports.test.js +186 -0
  21. package/dist/core/semantic/imports.test.js.map +1 -1
  22. package/dist/core/semantic/module-map.d.ts.map +1 -1
  23. package/dist/core/semantic/module-map.js +6 -0
  24. package/dist/core/semantic/module-map.js.map +1 -1
  25. package/dist/core/semantic/module-map.test.js +52 -1
  26. package/dist/core/semantic/module-map.test.js.map +1 -1
  27. package/dist/core/semantic/mutable-storage.d.ts +10 -0
  28. package/dist/core/semantic/mutable-storage.d.ts.map +1 -0
  29. package/dist/core/semantic/mutable-storage.js +479 -0
  30. package/dist/core/semantic/mutable-storage.js.map +1 -0
  31. package/dist/core/semantic/type-resolution.d.ts.map +1 -1
  32. package/dist/core/semantic/type-resolution.js +14 -5
  33. package/dist/core/semantic/type-resolution.js.map +1 -1
  34. package/dist/core/semantic/type-resolution.test.js +2 -0
  35. package/dist/core/semantic/type-resolution.test.js.map +1 -1
  36. package/dist/core/semantic/unsafe.d.ts.map +1 -1
  37. package/dist/core/semantic/unsafe.js +4 -0
  38. package/dist/core/semantic/unsafe.js.map +1 -1
  39. package/dist/emitter-types/core.d.ts +10 -0
  40. package/dist/emitter-types/core.d.ts.map +1 -1
  41. package/dist/expression-emitter.d.ts.map +1 -1
  42. package/dist/expression-emitter.js +73 -3
  43. package/dist/expression-emitter.js.map +1 -1
  44. package/dist/expressions/access.d.ts +2 -2
  45. package/dist/expressions/access.d.ts.map +1 -1
  46. package/dist/expressions/access.js +16 -2
  47. package/dist/expressions/access.js.map +1 -1
  48. package/dist/expressions/calls/call-emitter.d.ts.map +1 -1
  49. package/dist/expressions/calls/call-emitter.js +1350 -122
  50. package/dist/expressions/calls/call-emitter.js.map +1 -1
  51. package/dist/expressions/collections.d.ts +3 -0
  52. package/dist/expressions/collections.d.ts.map +1 -1
  53. package/dist/expressions/collections.js +126 -43
  54. package/dist/expressions/collections.js.map +1 -1
  55. package/dist/expressions/functions.d.ts.map +1 -1
  56. package/dist/expressions/functions.js +126 -50
  57. package/dist/expressions/functions.js.map +1 -1
  58. package/dist/expressions/index.test.js +447 -0
  59. package/dist/expressions/index.test.js.map +1 -1
  60. package/dist/expressions/operators/assignment-emitter.d.ts.map +1 -1
  61. package/dist/expressions/operators/assignment-emitter.js +5 -1
  62. package/dist/expressions/operators/assignment-emitter.js.map +1 -1
  63. package/dist/expressions/parentheses.d.ts.map +1 -1
  64. package/dist/expressions/parentheses.js +4 -0
  65. package/dist/expressions/parentheses.js.map +1 -1
  66. package/dist/integration.test.js +343 -0
  67. package/dist/integration.test.js.map +1 -1
  68. package/dist/json-aot-generic.test.js +114 -0
  69. package/dist/json-aot-generic.test.js.map +1 -1
  70. package/dist/patterns.d.ts.map +1 -1
  71. package/dist/patterns.js +194 -0
  72. package/dist/patterns.js.map +1 -1
  73. package/dist/patterns.test.js +79 -0
  74. package/dist/patterns.test.js.map +1 -1
  75. package/dist/statements/classes/members/properties.d.ts.map +1 -1
  76. package/dist/statements/classes/members/properties.js +10 -3
  77. package/dist/statements/classes/members/properties.js.map +1 -1
  78. package/dist/statements/classes/members/static-readonly-properties.test.js +74 -1
  79. package/dist/statements/classes/members/static-readonly-properties.test.js.map +1 -1
  80. package/dist/statements/classes/properties.d.ts.map +1 -1
  81. package/dist/statements/classes/properties.js +4 -2
  82. package/dist/statements/classes/properties.js.map +1 -1
  83. package/dist/statements/control/conditionals/if-emitter.d.ts.map +1 -1
  84. package/dist/statements/control/conditionals/if-emitter.js +137 -0
  85. package/dist/statements/control/conditionals/if-emitter.js.map +1 -1
  86. package/dist/statements/control/loops.d.ts.map +1 -1
  87. package/dist/statements/control/loops.js +65 -3
  88. package/dist/statements/control/loops.js.map +1 -1
  89. package/dist/statements/declarations/classes.d.ts.map +1 -1
  90. package/dist/statements/declarations/classes.js +4 -1
  91. package/dist/statements/declarations/classes.js.map +1 -1
  92. package/dist/statements/declarations/interfaces-mutable-storage.test.d.ts +2 -0
  93. package/dist/statements/declarations/interfaces-mutable-storage.test.d.ts.map +1 -0
  94. package/dist/statements/declarations/interfaces-mutable-storage.test.js +84 -0
  95. package/dist/statements/declarations/interfaces-mutable-storage.test.js.map +1 -0
  96. package/dist/statements/declarations/interfaces.d.ts.map +1 -1
  97. package/dist/statements/declarations/interfaces.js +4 -1
  98. package/dist/statements/declarations/interfaces.js.map +1 -1
  99. package/dist/statements/declarations/variables.d.ts.map +1 -1
  100. package/dist/statements/declarations/variables.js +89 -2
  101. package/dist/statements/declarations/variables.js.map +1 -1
  102. package/dist/types/functions.d.ts.map +1 -1
  103. package/dist/types/functions.js +3 -1
  104. package/dist/types/functions.js.map +1 -1
  105. package/dist/types/references.d.ts.map +1 -1
  106. package/dist/types/references.js +19 -16
  107. package/dist/types/references.js.map +1 -1
  108. package/dist/types/references.test.js +17 -0
  109. package/dist/types/references.test.js.map +1 -1
  110. package/dist/types/unions.d.ts.map +1 -1
  111. package/dist/types/unions.js +41 -16
  112. package/dist/types/unions.js.map +1 -1
  113. package/package.json +2 -2
@@ -190,6 +190,329 @@ describe("Expression Emission", () => {
190
190
  // No using statements
191
191
  expect(result).not.to.include("using System");
192
192
  });
193
+ it("should emit global function calls using csharpName on identifier callees", () => {
194
+ const module = {
195
+ kind: "module",
196
+ filePath: "/src/test.ts",
197
+ namespace: "MyApp",
198
+ className: "test",
199
+ isStaticContainer: true,
200
+ imports: [],
201
+ body: [
202
+ {
203
+ kind: "expressionStatement",
204
+ expression: {
205
+ kind: "call",
206
+ callee: {
207
+ kind: "identifier",
208
+ name: "clearInterval",
209
+ resolvedClrType: "Tsonic.JSRuntime.Timers",
210
+ resolvedAssembly: "Tsonic.JSRuntime",
211
+ csharpName: "Timers.clearInterval",
212
+ },
213
+ arguments: [{ kind: "literal", value: 1 }],
214
+ isOptional: false,
215
+ },
216
+ },
217
+ ],
218
+ exports: [],
219
+ };
220
+ const result = emitModule(module);
221
+ expect(result).to.include("global::Tsonic.JSRuntime.Timers.clearInterval(1)");
222
+ });
223
+ it("should preserve char-typed string indexing while string contexts still use ToString()", () => {
224
+ const stringIndexExpr = {
225
+ kind: "memberAccess",
226
+ object: {
227
+ kind: "identifier",
228
+ name: "source",
229
+ inferredType: { kind: "primitiveType", name: "string" },
230
+ },
231
+ property: {
232
+ kind: "literal",
233
+ value: 0,
234
+ inferredType: { kind: "primitiveType", name: "int" },
235
+ },
236
+ isComputed: true,
237
+ isOptional: false,
238
+ inferredType: { kind: "primitiveType", name: "string" },
239
+ accessKind: "stringChar",
240
+ };
241
+ const module = {
242
+ kind: "module",
243
+ filePath: "/src/test.ts",
244
+ namespace: "MyApp",
245
+ className: "test",
246
+ isStaticContainer: true,
247
+ imports: [],
248
+ body: [
249
+ {
250
+ kind: "variableDeclaration",
251
+ declarationKind: "const",
252
+ isExported: false,
253
+ declarations: [
254
+ {
255
+ kind: "variableDeclarator",
256
+ name: { kind: "identifierPattern", name: "source" },
257
+ type: { kind: "primitiveType", name: "string" },
258
+ initializer: { kind: "literal", value: "abc" },
259
+ },
260
+ {
261
+ kind: "variableDeclarator",
262
+ name: { kind: "identifierPattern", name: "letter" },
263
+ type: { kind: "primitiveType", name: "char" },
264
+ initializer: stringIndexExpr,
265
+ },
266
+ {
267
+ kind: "variableDeclarator",
268
+ name: { kind: "identifierPattern", name: "text" },
269
+ type: { kind: "primitiveType", name: "string" },
270
+ initializer: stringIndexExpr,
271
+ },
272
+ ],
273
+ },
274
+ ],
275
+ exports: [],
276
+ };
277
+ const result = emitModule(module);
278
+ expect(result).to.include('string source = "abc";');
279
+ expect(result).to.include("char letter = source[0];");
280
+ expect(result).to.include("string text = source[0].ToString();");
281
+ });
282
+ it("should convert char identifiers to string when a call argument expects string", () => {
283
+ const module = {
284
+ kind: "module",
285
+ filePath: "/src/test.ts",
286
+ namespace: "MyApp",
287
+ className: "test",
288
+ isStaticContainer: true,
289
+ imports: [],
290
+ body: [
291
+ {
292
+ kind: "variableDeclaration",
293
+ declarationKind: "const",
294
+ isExported: false,
295
+ declarations: [
296
+ {
297
+ kind: "variableDeclarator",
298
+ name: { kind: "identifierPattern", name: "ch" },
299
+ type: { kind: "primitiveType", name: "char" },
300
+ initializer: { kind: "literal", value: "x" },
301
+ },
302
+ ],
303
+ },
304
+ {
305
+ kind: "expressionStatement",
306
+ expression: {
307
+ kind: "call",
308
+ callee: {
309
+ kind: "memberAccess",
310
+ object: {
311
+ kind: "identifier",
312
+ name: "regex",
313
+ resolvedClrType: "System.Text.RegularExpressions.Regex",
314
+ resolvedAssembly: "System.Text.RegularExpressions",
315
+ inferredType: { kind: "referenceType", name: "RegExp" },
316
+ },
317
+ property: "test",
318
+ isComputed: false,
319
+ isOptional: false,
320
+ inferredType: {
321
+ kind: "functionType",
322
+ parameters: [
323
+ {
324
+ kind: "parameter",
325
+ pattern: {
326
+ kind: "identifierPattern",
327
+ name: "text",
328
+ },
329
+ type: { kind: "primitiveType", name: "string" },
330
+ isOptional: false,
331
+ isRest: false,
332
+ passing: "value",
333
+ },
334
+ ],
335
+ returnType: { kind: "primitiveType", name: "boolean" },
336
+ },
337
+ memberBinding: {
338
+ kind: "method",
339
+ assembly: "System.Text.RegularExpressions",
340
+ type: "System.Text.RegularExpressions.Regex",
341
+ member: "test",
342
+ },
343
+ },
344
+ arguments: [
345
+ {
346
+ kind: "identifier",
347
+ name: "ch",
348
+ inferredType: { kind: "primitiveType", name: "char" },
349
+ },
350
+ ],
351
+ parameterTypes: [{ kind: "primitiveType", name: "string" }],
352
+ inferredType: { kind: "primitiveType", name: "boolean" },
353
+ isOptional: false,
354
+ },
355
+ },
356
+ ],
357
+ exports: [],
358
+ };
359
+ const result = emitModule(module);
360
+ expect(result).to.include("char ch = 'x';");
361
+ expect(result).to.include("test(ch.ToString())");
362
+ });
363
+ it("should emit spread arguments without an invalid params call-site modifier", () => {
364
+ const module = {
365
+ kind: "module",
366
+ filePath: "/src/test.ts",
367
+ namespace: "MyApp",
368
+ className: "test",
369
+ isStaticContainer: true,
370
+ imports: [],
371
+ body: [
372
+ {
373
+ kind: "variableDeclaration",
374
+ declarationKind: "const",
375
+ isExported: false,
376
+ declarations: [
377
+ {
378
+ kind: "variableDeclarator",
379
+ name: { kind: "identifierPattern", name: "parts" },
380
+ type: {
381
+ kind: "arrayType",
382
+ elementType: { kind: "primitiveType", name: "string" },
383
+ },
384
+ initializer: {
385
+ kind: "array",
386
+ elements: [
387
+ { kind: "literal", value: "a" },
388
+ { kind: "literal", value: "b" },
389
+ ],
390
+ },
391
+ },
392
+ ],
393
+ },
394
+ {
395
+ kind: "expressionStatement",
396
+ expression: {
397
+ kind: "call",
398
+ callee: {
399
+ kind: "identifier",
400
+ name: "joinPath",
401
+ resolvedClrType: "nodejs.path",
402
+ resolvedAssembly: "nodejs",
403
+ csharpName: "path.join",
404
+ },
405
+ arguments: [
406
+ { kind: "literal", value: "root" },
407
+ {
408
+ kind: "spread",
409
+ expression: {
410
+ kind: "identifier",
411
+ name: "parts",
412
+ inferredType: {
413
+ kind: "arrayType",
414
+ elementType: { kind: "primitiveType", name: "string" },
415
+ },
416
+ },
417
+ },
418
+ ],
419
+ isOptional: false,
420
+ },
421
+ },
422
+ ],
423
+ exports: [],
424
+ };
425
+ const result = emitModule(module);
426
+ expect(result).to.include('global::nodejs.path.join("root", parts)');
427
+ expect(result).not.to.include("params ");
428
+ });
429
+ it("should emit mixed array spreads through deterministic concat chains", () => {
430
+ const module = {
431
+ kind: "module",
432
+ filePath: "/src/test.ts",
433
+ namespace: "MyApp",
434
+ className: "test",
435
+ isStaticContainer: true,
436
+ imports: [],
437
+ body: [
438
+ {
439
+ kind: "variableDeclaration",
440
+ declarationKind: "const",
441
+ isExported: false,
442
+ declarations: [
443
+ {
444
+ kind: "variableDeclarator",
445
+ name: { kind: "identifierPattern", name: "values" },
446
+ type: {
447
+ kind: "arrayType",
448
+ elementType: { kind: "primitiveType", name: "int" },
449
+ },
450
+ initializer: {
451
+ kind: "array",
452
+ elements: [
453
+ {
454
+ kind: "literal",
455
+ value: 1,
456
+ numericIntent: "Int32",
457
+ inferredType: { kind: "primitiveType", name: "int" },
458
+ },
459
+ {
460
+ kind: "literal",
461
+ value: 2,
462
+ numericIntent: "Int32",
463
+ inferredType: { kind: "primitiveType", name: "int" },
464
+ },
465
+ ],
466
+ },
467
+ },
468
+ {
469
+ kind: "variableDeclarator",
470
+ name: { kind: "identifierPattern", name: "copy" },
471
+ type: {
472
+ kind: "arrayType",
473
+ elementType: { kind: "primitiveType", name: "int" },
474
+ },
475
+ initializer: {
476
+ kind: "array",
477
+ elements: [
478
+ {
479
+ kind: "literal",
480
+ value: 0,
481
+ numericIntent: "Int32",
482
+ inferredType: { kind: "primitiveType", name: "int" },
483
+ },
484
+ {
485
+ kind: "spread",
486
+ expression: {
487
+ kind: "identifier",
488
+ name: "values",
489
+ inferredType: {
490
+ kind: "arrayType",
491
+ elementType: { kind: "primitiveType", name: "int" },
492
+ },
493
+ },
494
+ },
495
+ {
496
+ kind: "literal",
497
+ value: 3,
498
+ numericIntent: "Int32",
499
+ inferredType: { kind: "primitiveType", name: "int" },
500
+ },
501
+ ],
502
+ },
503
+ },
504
+ ],
505
+ },
506
+ ],
507
+ exports: [],
508
+ };
509
+ const result = emitModule(module);
510
+ expect(result).to.include("global::System.Linq.Enumerable.ToArray");
511
+ expect(result).to.include("global::System.Linq.Enumerable.Concat");
512
+ expect(result).to.include("new int[] { 0 }");
513
+ expect(result).to.include("new int[] { 3 }");
514
+ expect(result).not.to.include("/* ...spread */");
515
+ });
193
516
  it("should emit hierarchical member bindings correctly", () => {
194
517
  const module = {
195
518
  kind: "module",
@@ -2110,5 +2433,129 @@ describe("Expression Emission", () => {
2110
2433
  const result = emitModule(module);
2111
2434
  expect(result).to.include("ok(default(object))");
2112
2435
  });
2436
+ it("should lower tuple-rest function value calls as positional arguments", () => {
2437
+ const tupleRestType = {
2438
+ kind: "unionType",
2439
+ types: [
2440
+ { kind: "tupleType", elementTypes: [] },
2441
+ {
2442
+ kind: "tupleType",
2443
+ elementTypes: [
2444
+ { kind: "primitiveType", name: "number" },
2445
+ ],
2446
+ },
2447
+ ],
2448
+ };
2449
+ const module = {
2450
+ kind: "module",
2451
+ filePath: "/src/test.ts",
2452
+ namespace: "MyApp",
2453
+ className: "test",
2454
+ isStaticContainer: true,
2455
+ imports: [],
2456
+ body: [
2457
+ {
2458
+ kind: "expressionStatement",
2459
+ expression: {
2460
+ kind: "call",
2461
+ callee: {
2462
+ kind: "identifier",
2463
+ name: "next",
2464
+ inferredType: {
2465
+ kind: "functionType",
2466
+ parameters: [
2467
+ {
2468
+ kind: "parameter",
2469
+ pattern: { kind: "identifierPattern", name: "args" },
2470
+ type: tupleRestType,
2471
+ isOptional: false,
2472
+ isRest: true,
2473
+ passing: "value",
2474
+ },
2475
+ ],
2476
+ returnType: { kind: "unknownType" },
2477
+ },
2478
+ },
2479
+ arguments: [{ kind: "literal", value: 5, numericIntent: "Int32" }],
2480
+ isOptional: false,
2481
+ parameterTypes: [tupleRestType],
2482
+ inferredType: { kind: "unknownType" },
2483
+ sourceSpan: {
2484
+ file: "/src/test.ts",
2485
+ line: 1,
2486
+ column: 1,
2487
+ length: 7,
2488
+ },
2489
+ },
2490
+ },
2491
+ ],
2492
+ exports: [],
2493
+ };
2494
+ const result = emitModule(module);
2495
+ expect(result).to.include("next(5)");
2496
+ expect(result).to.not.include("new object[] { 5 }");
2497
+ });
2498
+ it("should lower zero-arg tuple-rest function value calls without synthetic arrays", () => {
2499
+ const tupleRestType = {
2500
+ kind: "unionType",
2501
+ types: [
2502
+ { kind: "tupleType", elementTypes: [] },
2503
+ {
2504
+ kind: "tupleType",
2505
+ elementTypes: [
2506
+ { kind: "primitiveType", name: "number" },
2507
+ ],
2508
+ },
2509
+ ],
2510
+ };
2511
+ const module = {
2512
+ kind: "module",
2513
+ filePath: "/src/test.ts",
2514
+ namespace: "MyApp",
2515
+ className: "test",
2516
+ isStaticContainer: true,
2517
+ imports: [],
2518
+ body: [
2519
+ {
2520
+ kind: "expressionStatement",
2521
+ expression: {
2522
+ kind: "call",
2523
+ callee: {
2524
+ kind: "identifier",
2525
+ name: "next",
2526
+ inferredType: {
2527
+ kind: "functionType",
2528
+ parameters: [
2529
+ {
2530
+ kind: "parameter",
2531
+ pattern: { kind: "identifierPattern", name: "args" },
2532
+ type: tupleRestType,
2533
+ isOptional: false,
2534
+ isRest: true,
2535
+ passing: "value",
2536
+ },
2537
+ ],
2538
+ returnType: { kind: "unknownType" },
2539
+ },
2540
+ },
2541
+ arguments: [],
2542
+ isOptional: false,
2543
+ parameterTypes: [tupleRestType],
2544
+ inferredType: { kind: "unknownType" },
2545
+ sourceSpan: {
2546
+ file: "/src/test.ts",
2547
+ line: 1,
2548
+ column: 1,
2549
+ length: 6,
2550
+ },
2551
+ },
2552
+ },
2553
+ ],
2554
+ exports: [],
2555
+ };
2556
+ const result = emitModule(module);
2557
+ expect(result).to.include("next()");
2558
+ expect(result).to.not.include("new object[0]");
2559
+ });
2113
2560
  });
2114
2561
  //# sourceMappingURL=index.test.js.map