@tsonic/emitter 0.0.2 → 0.0.4
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/adapter-generator.d.ts.map +1 -1
- package/dist/adapter-generator.js +3 -2
- package/dist/adapter-generator.js.map +1 -1
- package/dist/array.test.js +1 -1
- package/dist/array.test.js.map +1 -1
- package/dist/core/imports.d.ts +2 -2
- package/dist/core/imports.d.ts.map +1 -1
- package/dist/core/imports.js +60 -4
- package/dist/core/imports.js.map +1 -1
- package/dist/core/imports.test.js +4 -4
- package/dist/core/imports.test.js.map +1 -1
- package/dist/core/module-emitter/static-container.d.ts.map +1 -1
- package/dist/core/module-emitter/static-container.js +3 -1
- package/dist/core/module-emitter/static-container.js.map +1 -1
- package/dist/emitter-types/core.d.ts +13 -0
- package/dist/emitter-types/core.d.ts.map +1 -1
- package/dist/emitter-types/identifiers.d.ts +23 -0
- package/dist/emitter-types/identifiers.d.ts.map +1 -0
- package/dist/emitter-types/identifiers.js +164 -0
- package/dist/emitter-types/identifiers.js.map +1 -0
- package/dist/emitter-types/index.d.ts +2 -1
- package/dist/emitter-types/index.d.ts.map +1 -1
- package/dist/emitter-types/index.js +1 -0
- package/dist/emitter-types/index.js.map +1 -1
- package/dist/emitter.d.ts.map +1 -1
- package/dist/emitter.js +47 -0
- package/dist/emitter.js.map +1 -1
- package/dist/expression-emitter.d.ts.map +1 -1
- package/dist/expression-emitter.js +6 -4
- package/dist/expression-emitter.js.map +1 -1
- package/dist/expressions/access.d.ts.map +1 -1
- package/dist/expressions/access.js +57 -11
- package/dist/expressions/access.js.map +1 -1
- package/dist/expressions/calls.d.ts.map +1 -1
- package/dist/expressions/calls.js +117 -0
- package/dist/expressions/calls.js.map +1 -1
- package/dist/expressions/functions.js +1 -1
- package/dist/expressions/functions.js.map +1 -1
- package/dist/expressions/identifiers.d.ts.map +1 -1
- package/dist/expressions/identifiers.js +3 -2
- package/dist/expressions/identifiers.js.map +1 -1
- package/dist/expressions/operators.d.ts +23 -3
- package/dist/expressions/operators.d.ts.map +1 -1
- package/dist/expressions/operators.js +90 -9
- package/dist/expressions/operators.js.map +1 -1
- package/dist/expressions/other.d.ts +4 -0
- package/dist/expressions/other.d.ts.map +1 -1
- package/dist/expressions/other.js +6 -1
- package/dist/expressions/other.js.map +1 -1
- package/dist/golden-tests/runner.d.ts.map +1 -1
- package/dist/golden-tests/runner.js +1 -0
- package/dist/golden-tests/runner.js.map +1 -1
- package/dist/hierarchical-bindings.test.js +15 -5
- package/dist/hierarchical-bindings.test.js.map +1 -1
- package/dist/integration.test.js +3 -2
- package/dist/integration.test.js.map +1 -1
- package/dist/statements/classes/inline-types.d.ts.map +1 -1
- package/dist/statements/classes/inline-types.js +3 -1
- package/dist/statements/classes/inline-types.js.map +1 -1
- package/dist/statements/classes/members/methods.d.ts.map +1 -1
- package/dist/statements/classes/members/methods.js +8 -4
- package/dist/statements/classes/members/methods.js.map +1 -1
- package/dist/statements/classes/members/properties.d.ts.map +1 -1
- package/dist/statements/classes/members/properties.js +3 -2
- package/dist/statements/classes/members/properties.js.map +1 -1
- package/dist/statements/classes/parameters.d.ts.map +1 -1
- package/dist/statements/classes/parameters.js +4 -3
- package/dist/statements/classes/parameters.js.map +1 -1
- package/dist/statements/classes/properties.d.ts.map +1 -1
- package/dist/statements/classes/properties.js +5 -4
- package/dist/statements/classes/properties.js.map +1 -1
- package/dist/statements/control/loops.d.ts.map +1 -1
- package/dist/statements/control/loops.js +5 -2
- package/dist/statements/control/loops.js.map +1 -1
- package/dist/statements/declarations/classes.d.ts.map +1 -1
- package/dist/statements/declarations/classes.js +6 -4
- package/dist/statements/declarations/classes.js.map +1 -1
- package/dist/statements/declarations/enums.d.ts.map +1 -1
- package/dist/statements/declarations/enums.js +8 -4
- package/dist/statements/declarations/enums.js.map +1 -1
- package/dist/statements/declarations/functions.d.ts.map +1 -1
- package/dist/statements/declarations/functions.js +6 -2
- package/dist/statements/declarations/functions.js.map +1 -1
- package/dist/statements/declarations/interfaces.d.ts.map +1 -1
- package/dist/statements/declarations/interfaces.js +2 -1
- package/dist/statements/declarations/interfaces.js.map +1 -1
- package/dist/statements/declarations/type-aliases.d.ts.map +1 -1
- package/dist/statements/declarations/type-aliases.js +3 -2
- package/dist/statements/declarations/type-aliases.js.map +1 -1
- package/dist/statements/declarations/variables.d.ts.map +1 -1
- package/dist/statements/declarations/variables.js +7 -5
- package/dist/statements/declarations/variables.js.map +1 -1
- package/dist/types/parameters.test.js +4 -4
- package/dist/types/parameters.test.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/dist/async-investigation.test.d.ts +0 -5
- package/dist/async-investigation.test.d.ts.map +0 -1
- package/dist/async-investigation.test.js +0 -239
- package/dist/async-investigation.test.js.map +0 -1
- package/dist/tests/emitter/expression-emission.test.d.ts +0 -6
- package/dist/tests/emitter/expression-emission.test.d.ts.map +0 -1
- package/dist/tests/emitter/expression-emission.test.js +0 -322
- package/dist/tests/emitter/expression-emission.test.js.map +0 -1
- package/dist/tests/emitter/import-handling.test.d.ts +0 -6
- package/dist/tests/emitter/import-handling.test.d.ts.map +0 -1
- package/dist/tests/emitter/import-handling.test.js +0 -76
- package/dist/tests/emitter/import-handling.test.js.map +0 -1
- package/dist/tests/emitter/module-generation.test.d.ts +0 -6
- package/dist/tests/emitter/module-generation.test.d.ts.map +0 -1
- package/dist/tests/emitter/module-generation.test.js +0 -147
- package/dist/tests/emitter/module-generation.test.js.map +0 -1
- package/dist/tests/emitter/statement-emission.test.d.ts +0 -6
- package/dist/tests/emitter/statement-emission.test.d.ts.map +0 -1
- package/dist/tests/emitter/statement-emission.test.js +0 -138
- package/dist/tests/emitter/statement-emission.test.js.map +0 -1
- package/dist/tests/emitter/type-emission.test.d.ts +0 -6
- package/dist/tests/emitter/type-emission.test.d.ts.map +0 -1
- package/dist/tests/emitter/type-emission.test.js +0 -109
- package/dist/tests/emitter/type-emission.test.js.map +0 -1
- package/dist/tests/generics/call-site-rewriting.test.d.ts +0 -6
- package/dist/tests/generics/call-site-rewriting.test.d.ts.map +0 -1
- package/dist/tests/generics/call-site-rewriting.test.js +0 -92
- package/dist/tests/generics/call-site-rewriting.test.js.map +0 -1
- package/dist/tests/generics/generic-classes.test.d.ts +0 -6
- package/dist/tests/generics/generic-classes.test.d.ts.map +0 -1
- package/dist/tests/generics/generic-classes.test.js +0 -55
- package/dist/tests/generics/generic-classes.test.js.map +0 -1
- package/dist/tests/generics/generic-functions.test.d.ts +0 -6
- package/dist/tests/generics/generic-functions.test.d.ts.map +0 -1
- package/dist/tests/generics/generic-functions.test.js +0 -275
- package/dist/tests/generics/generic-functions.test.js.map +0 -1
- package/dist/tests/generics/interfaces.test.d.ts +0 -6
- package/dist/tests/generics/interfaces.test.d.ts.map +0 -1
- package/dist/tests/generics/interfaces.test.js +0 -139
- package/dist/tests/generics/interfaces.test.js.map +0 -1
- package/dist/tests/generics/type-aliases.test.d.ts +0 -6
- package/dist/tests/generics/type-aliases.test.d.ts.map +0 -1
- package/dist/tests/generics/type-aliases.test.js +0 -124
- package/dist/tests/generics/type-aliases.test.js.map +0 -1
- package/dist/tests/hierarchical-bindings-full-pipeline.test.d.ts +0 -6
- package/dist/tests/hierarchical-bindings-full-pipeline.test.d.ts.map +0 -1
- package/dist/tests/hierarchical-bindings-full-pipeline.test.js +0 -202
- package/dist/tests/hierarchical-bindings-full-pipeline.test.js.map +0 -1
- package/dist/tests/ref-out-parameters.test.d.ts +0 -5
- package/dist/tests/ref-out-parameters.test.d.ts.map +0 -1
- package/dist/tests/ref-out-parameters.test.js +0 -136
- package/dist/tests/ref-out-parameters.test.js.map +0 -1
- package/dist/tests/structs/struct-emission.test.d.ts +0 -5
- package/dist/tests/structs/struct-emission.test.d.ts.map +0 -1
- package/dist/tests/structs/struct-emission.test.js +0 -165
- package/dist/tests/structs/struct-emission.test.js.map +0 -1
- package/dist/union.test.d.ts +0 -6
- package/dist/union.test.d.ts.map +0 -1
- package/dist/union.test.js +0 -367
- package/dist/union.test.js.map +0 -1
|
@@ -3,16 +3,56 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { emitExpression } from "../expression-emitter.js";
|
|
5
5
|
import { isExplicitViewProperty, extractInterfaceNameFromView, } from "@tsonic/frontend/types/explicit-views.js";
|
|
6
|
+
import { escapeCSharpIdentifier } from "../emitter-types/index.js";
|
|
7
|
+
/**
|
|
8
|
+
* Check if an expression represents a static type reference (not an instance)
|
|
9
|
+
* Static type references are: namespace.Type or direct Type identifiers that resolve to types
|
|
10
|
+
*/
|
|
11
|
+
const isStaticTypeReference = (expr) => {
|
|
12
|
+
// If the object is an identifier that's a type name (e.g., Console, Enumerable)
|
|
13
|
+
// we need to check if the member binding's type matches what would be
|
|
14
|
+
// accessed statically. For instance access, the object would be a variable.
|
|
15
|
+
//
|
|
16
|
+
// A simple heuristic: if the member binding exists and the object is an identifier
|
|
17
|
+
// or a member access (like System.Console), AND the property name is being looked up
|
|
18
|
+
// on the type itself (not on an instance), it's static.
|
|
19
|
+
//
|
|
20
|
+
// The key insight: for instance calls, the object will have an inferredType that's
|
|
21
|
+
// the CLR type (e.g., List<T>), whereas for static calls the object IS the type.
|
|
22
|
+
//
|
|
23
|
+
// For now, we use the presence of inferredType on the object to detect instance access:
|
|
24
|
+
// - Instance: `numbers.add()` → numbers has inferredType: List<T>
|
|
25
|
+
// - Static: `Console.WriteLine()` → Console doesn't have a meaningful inferredType
|
|
26
|
+
// (or its inferredType would be "typeof Console" not "Console")
|
|
27
|
+
const objectType = expr.object.inferredType;
|
|
28
|
+
// If object has a reference type as inferredType, it's an instance access
|
|
29
|
+
if (objectType?.kind === "referenceType" ||
|
|
30
|
+
objectType?.kind === "arrayType") {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
// Otherwise it's likely a static access (type.member pattern)
|
|
34
|
+
return true;
|
|
35
|
+
};
|
|
6
36
|
/**
|
|
7
37
|
* Emit a member access expression (dot notation or bracket notation)
|
|
8
38
|
*/
|
|
9
39
|
export const emitMemberAccess = (expr, context) => {
|
|
10
40
|
// Check if this is a hierarchical member binding
|
|
11
41
|
if (expr.memberBinding) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
42
|
+
const { type, member } = expr.memberBinding;
|
|
43
|
+
// Determine if this is a static or instance member access
|
|
44
|
+
if (isStaticTypeReference(expr)) {
|
|
45
|
+
// Static access: emit full CLR type and member with global:: prefix
|
|
46
|
+
const text = `global::${type}.${member}`;
|
|
47
|
+
return [{ text }, context];
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
// Instance access: emit object.ClrMemberName
|
|
51
|
+
const [objectFrag, newContext] = emitExpression(expr.object, context);
|
|
52
|
+
const accessor = expr.isOptional ? "?." : ".";
|
|
53
|
+
const text = `${objectFrag.text}${accessor}${member}`;
|
|
54
|
+
return [{ text }, newContext];
|
|
55
|
+
}
|
|
16
56
|
}
|
|
17
57
|
const [objectFrag, newContext] = emitExpression(expr.object, context);
|
|
18
58
|
// Default runtime to "js" when not specified
|
|
@@ -21,15 +61,13 @@ export const emitMemberAccess = (expr, context) => {
|
|
|
21
61
|
// Check if this is array index access - rewrite to static helper
|
|
22
62
|
const objectType = expr.object.inferredType;
|
|
23
63
|
const isArrayType = objectType?.kind === "arrayType";
|
|
24
|
-
// For TS arrays, use Tsonic.
|
|
64
|
+
// For TS arrays, use Tsonic.JSRuntime.Array.get() in BOTH modes
|
|
25
65
|
// This provides TS array semantics (auto-grow, sparse arrays, etc.)
|
|
26
|
-
// Note: Tsonic.Runtime is compiler support for lowered TS constructs (both modes)
|
|
27
|
-
// Tsonic.JSRuntime is JS built-ins like .map/.filter (js mode only)
|
|
28
66
|
if (isArrayType) {
|
|
29
67
|
const indexContext = { ...newContext, isArrayIndex: true };
|
|
30
68
|
const [propFrag, contextWithIndex] = emitExpression(expr.property, indexContext);
|
|
31
69
|
const finalContext = { ...contextWithIndex, isArrayIndex: false };
|
|
32
|
-
const text = `global::Tsonic.
|
|
70
|
+
const text = `global::Tsonic.JSRuntime.Array.get(${objectFrag.text}, ${propFrag.text})`;
|
|
33
71
|
return [{ text }, finalContext];
|
|
34
72
|
}
|
|
35
73
|
// CLR indexer access (non-TS-array types like List<T>, string, etc.)
|
|
@@ -52,10 +90,18 @@ export const emitMemberAccess = (expr, context) => {
|
|
|
52
90
|
const prop = expr.property;
|
|
53
91
|
const objectType = expr.object.inferredType;
|
|
54
92
|
const isArrayType = objectType?.kind === "arrayType";
|
|
55
|
-
// In JS runtime mode, rewrite array.length → global::Tsonic.
|
|
93
|
+
// In JS runtime mode, rewrite array.length → global::Tsonic.JSRuntime.Array.length(array)
|
|
56
94
|
// In dotnet mode, there is no JS emulation - users access .Count directly on List<T>
|
|
57
95
|
if (isArrayType && prop === "length" && runtime === "js") {
|
|
58
|
-
const text = `global::Tsonic.
|
|
96
|
+
const text = `global::Tsonic.JSRuntime.Array.length(${objectFrag.text})`;
|
|
97
|
+
return [{ text }, newContext];
|
|
98
|
+
}
|
|
99
|
+
// Check if this is a string type
|
|
100
|
+
const isStringType = objectType?.kind === "primitiveType" && objectType.name === "string";
|
|
101
|
+
// In JS runtime mode, rewrite string.length → global::Tsonic.JSRuntime.String.length(string)
|
|
102
|
+
// In dotnet mode, use C#'s native .Length property
|
|
103
|
+
if (isStringType && prop === "length" && runtime === "js") {
|
|
104
|
+
const text = `global::Tsonic.JSRuntime.String.length(${objectFrag.text})`;
|
|
59
105
|
return [{ text }, newContext];
|
|
60
106
|
}
|
|
61
107
|
// Handle explicit interface view properties (As_IInterface)
|
|
@@ -71,7 +117,7 @@ export const emitMemberAccess = (expr, context) => {
|
|
|
71
117
|
}
|
|
72
118
|
// Regular property access
|
|
73
119
|
const accessor = expr.isOptional ? "?." : ".";
|
|
74
|
-
const text = `${objectFrag.text}${accessor}${prop}`;
|
|
120
|
+
const text = `${objectFrag.text}${accessor}${escapeCSharpIdentifier(prop)}`;
|
|
75
121
|
return [{ text }, newContext];
|
|
76
122
|
};
|
|
77
123
|
//# sourceMappingURL=access.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access.js","sourceRoot":"","sources":["../../src/expressions/access.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EACL,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"access.js","sourceRoot":"","sources":["../../src/expressions/access.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calls.d.ts","sourceRoot":"","sources":["../../src/expressions/calls.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"calls.d.ts","sourceRoot":"","sources":["../../src/expressions/calls.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAU,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA+L7D;;GAEG;AACH,eAAO,MAAM,QAAQ,GACnB,MAAM,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAC7C,SAAS,cAAc,KACtB,CAAC,cAAc,EAAE,cAAc,CAkJjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,OAAO,GAClB,MAAM,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC,EAC5C,SAAS,cAAc,KACtB,CAAC,cAAc,EAAE,cAAc,CA8CjC,CAAC"}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { emitExpression } from "../expression-emitter.js";
|
|
5
5
|
import { emitTypeArguments, generateSpecializedName } from "./identifiers.js";
|
|
6
|
+
import { emitType } from "../type-emitter.js";
|
|
6
7
|
/**
|
|
7
8
|
* Ref/out/in parameter handling:
|
|
8
9
|
* The frontend extracts parameter passing modes from resolved signatures
|
|
@@ -16,6 +17,68 @@ import { emitTypeArguments, generateSpecializedName } from "./identifiers.js";
|
|
|
16
17
|
const isLValue = (expr) => {
|
|
17
18
|
return expr.kind === "identifier" || expr.kind === "memberAccess";
|
|
18
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* Check if a member access expression targets System.Text.Json.JsonSerializer
|
|
22
|
+
*/
|
|
23
|
+
const isJsonSerializerCall = (callee) => {
|
|
24
|
+
if (callee.kind !== "memberAccess")
|
|
25
|
+
return null;
|
|
26
|
+
if (!callee.memberBinding)
|
|
27
|
+
return null;
|
|
28
|
+
const { type, member } = callee.memberBinding;
|
|
29
|
+
// Check if this is System.Text.Json.JsonSerializer
|
|
30
|
+
if (type !== "System.Text.Json.JsonSerializer")
|
|
31
|
+
return null;
|
|
32
|
+
// Check if the member is Serialize or Deserialize
|
|
33
|
+
if (member === "Serialize")
|
|
34
|
+
return { method: "Serialize" };
|
|
35
|
+
if (member === "Deserialize")
|
|
36
|
+
return { method: "Deserialize" };
|
|
37
|
+
return null;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Ensure a C# type string has global:: prefix for unambiguous resolution
|
|
41
|
+
*/
|
|
42
|
+
const ensureGlobalPrefix = (typeStr) => {
|
|
43
|
+
// Skip primitives and already-prefixed types
|
|
44
|
+
if (typeStr.startsWith("global::") ||
|
|
45
|
+
typeStr === "string" ||
|
|
46
|
+
typeStr === "int" ||
|
|
47
|
+
typeStr === "long" ||
|
|
48
|
+
typeStr === "short" ||
|
|
49
|
+
typeStr === "byte" ||
|
|
50
|
+
typeStr === "sbyte" ||
|
|
51
|
+
typeStr === "uint" ||
|
|
52
|
+
typeStr === "ulong" ||
|
|
53
|
+
typeStr === "ushort" ||
|
|
54
|
+
typeStr === "float" ||
|
|
55
|
+
typeStr === "double" ||
|
|
56
|
+
typeStr === "decimal" ||
|
|
57
|
+
typeStr === "bool" ||
|
|
58
|
+
typeStr === "char" ||
|
|
59
|
+
typeStr === "object" ||
|
|
60
|
+
typeStr === "void") {
|
|
61
|
+
return typeStr;
|
|
62
|
+
}
|
|
63
|
+
// Handle generic types: List<Foo> -> global::List<global::Foo>
|
|
64
|
+
// For now, just add prefix to the outer type
|
|
65
|
+
// The inner types should already be handled by emitType
|
|
66
|
+
return `global::${typeStr}`;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Register a type with the JSON AOT registry
|
|
70
|
+
*/
|
|
71
|
+
const registerJsonAotType = (type, context) => {
|
|
72
|
+
if (!type)
|
|
73
|
+
return;
|
|
74
|
+
if (!context.options.jsonAotRegistry)
|
|
75
|
+
return;
|
|
76
|
+
const registry = context.options.jsonAotRegistry;
|
|
77
|
+
const [typeStr] = emitType(type, context);
|
|
78
|
+
const globalType = ensureGlobalPrefix(typeStr);
|
|
79
|
+
registry.rootTypes.add(globalType);
|
|
80
|
+
registry.needsJsonAot = true;
|
|
81
|
+
};
|
|
19
82
|
/**
|
|
20
83
|
* Check if a call expression needs an explicit cast because the inferred type
|
|
21
84
|
* differs from the C# return type. This handles cases like Math.floor() which
|
|
@@ -45,10 +108,64 @@ const needsIntCast = (expr, calleeName) => {
|
|
|
45
108
|
];
|
|
46
109
|
return mathMethodsReturningDouble.some((m) => calleeName === m || calleeName.endsWith(`.${m.split(".").pop()}`));
|
|
47
110
|
};
|
|
111
|
+
/**
|
|
112
|
+
* Emit a JsonSerializer call with NativeAOT-compatible options.
|
|
113
|
+
* Rewrites:
|
|
114
|
+
* JsonSerializer.Serialize(value) → JsonSerializer.Serialize(value, TsonicJson.Options)
|
|
115
|
+
* JsonSerializer.Deserialize<T>(json) → JsonSerializer.Deserialize<T>(json, TsonicJson.Options)
|
|
116
|
+
*/
|
|
117
|
+
const emitJsonSerializerCall = (expr, context, method) => {
|
|
118
|
+
let currentContext = context;
|
|
119
|
+
// Register the type with the JSON AOT registry
|
|
120
|
+
if (method === "Serialize") {
|
|
121
|
+
// For Serialize, get type from first argument's inferredType
|
|
122
|
+
const firstArg = expr.arguments[0];
|
|
123
|
+
if (firstArg && firstArg.kind !== "spread") {
|
|
124
|
+
registerJsonAotType(firstArg.inferredType, context);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
// For Deserialize, get type from type arguments
|
|
129
|
+
const typeArg = expr.typeArguments?.[0];
|
|
130
|
+
if (typeArg) {
|
|
131
|
+
registerJsonAotType(typeArg, context);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Emit type arguments for Deserialize<T>
|
|
135
|
+
let typeArgsStr = "";
|
|
136
|
+
if (expr.typeArguments && expr.typeArguments.length > 0) {
|
|
137
|
+
const [typeArgs, typeContext] = emitTypeArguments(expr.typeArguments, currentContext);
|
|
138
|
+
typeArgsStr = typeArgs;
|
|
139
|
+
currentContext = typeContext;
|
|
140
|
+
}
|
|
141
|
+
// Emit arguments
|
|
142
|
+
const args = [];
|
|
143
|
+
for (const arg of expr.arguments) {
|
|
144
|
+
if (arg.kind === "spread") {
|
|
145
|
+
const [spreadFrag, ctx] = emitExpression(arg.expression, currentContext);
|
|
146
|
+
args.push(spreadFrag.text);
|
|
147
|
+
currentContext = ctx;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const [argFrag, ctx] = emitExpression(arg, currentContext);
|
|
151
|
+
args.push(argFrag.text);
|
|
152
|
+
currentContext = ctx;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Add TsonicJson.Options as the last argument for NativeAOT compatibility
|
|
156
|
+
args.push("TsonicJson.Options");
|
|
157
|
+
const text = `global::System.Text.Json.JsonSerializer.${method}${typeArgsStr}(${args.join(", ")})`;
|
|
158
|
+
return [{ text }, currentContext];
|
|
159
|
+
};
|
|
48
160
|
/**
|
|
49
161
|
* Emit a function call expression
|
|
50
162
|
*/
|
|
51
163
|
export const emitCall = (expr, context) => {
|
|
164
|
+
// Check for JsonSerializer calls (NativeAOT support)
|
|
165
|
+
const jsonCall = isJsonSerializerCall(expr.callee);
|
|
166
|
+
if (jsonCall) {
|
|
167
|
+
return emitJsonSerializerCall(expr, context, jsonCall.method);
|
|
168
|
+
}
|
|
52
169
|
// Type-aware method call rewriting
|
|
53
170
|
// Use inferredType to determine if we need to rewrite as static helper
|
|
54
171
|
if (expr.callee.kind === "memberAccess" &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calls.js","sourceRoot":"","sources":["../../src/expressions/calls.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"calls.js","sourceRoot":"","sources":["../../src/expressions/calls.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,7 +38,7 @@ export const emitArrowFunction = (expr, context) => {
|
|
|
38
38
|
const blockContext = currentContext.isStatic
|
|
39
39
|
? indent(currentContext)
|
|
40
40
|
: currentContext;
|
|
41
|
-
const [blockCode
|
|
41
|
+
const [blockCode] = emitStatement(expr.body, blockContext);
|
|
42
42
|
const params = paramNames.join(", ");
|
|
43
43
|
// The block code has proper indentation, just prepend the lambda signature
|
|
44
44
|
const text = `(${params}) =>\n${blockCode}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"functions.js","sourceRoot":"","sources":["../../src/expressions/functions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAkC,MAAM,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,KAA4D,EAC5D,OAAuB,EACW,EAAE;IACpC,oEAAoE;IACpE,oCAAoC;IACpC,MAAM,IAAI,GAAG,2BAA2B,CAAC;IACzC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;AAC7B,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,IAAsD,EACtD,OAAuB,EACW,EAAE;IACpC,sCAAsC;IACtC,IAAI,cAAc,GAAG,OAAO,CAAC;IAC7B,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;YAC/C,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,cAAc;IACd,IAAI,QAAgB,CAAC;IACrB,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACzD,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YACxC,mCAAmC;YACnC,wEAAwE;YACxE,iEAAiE;YACjE,MAAM,YAAY,GAAG,cAAc,CAAC,QAAQ;gBAC1C,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC;gBACxB,CAAC,CAAC,cAAc,CAAC;YACnB,MAAM,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"functions.js","sourceRoot":"","sources":["../../src/expressions/functions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAkC,MAAM,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExD;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,KAA4D,EAC5D,OAAuB,EACW,EAAE;IACpC,oEAAoE;IACpE,oCAAoC;IACpC,MAAM,IAAI,GAAG,2BAA2B,CAAC;IACzC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;AAC7B,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,IAAsD,EACtD,OAAuB,EACW,EAAE;IACpC,sCAAsC;IACtC,IAAI,cAAc,GAAG,OAAO,CAAC;IAC7B,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;YAC/C,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,cAAc;IACd,IAAI,QAAgB,CAAC;IACrB,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACzD,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YACxC,mCAAmC;YACnC,wEAAwE;YACxE,iEAAiE;YACjE,MAAM,YAAY,GAAG,cAAc,CAAC,QAAQ;gBAC1C,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC;gBACxB,CAAC,CAAC,cAAc,CAAC;YACnB,MAAM,CAAC,SAAS,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;YAE3D,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrC,2EAA2E;YAC3E,MAAM,IAAI,GAAG,IAAI,MAAM,SAAS,SAAS,EAAE,CAAC;YAE5C,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,cAAc,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;YACzE,cAAc,GAAG,UAAU,CAAC;YAC5B,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC3B,CAAC;IACH,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,oBAAoB,CAAC;IAClC,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,MAAM,QAAQ,QAAQ,EAAE,CAAC;IAC1C,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,cAAc,CAAC,CAAC;AACpC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identifiers.d.ts","sourceRoot":"","sources":["../../src/expressions/identifiers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"identifiers.d.ts","sourceRoot":"","sources":["../../src/expressions/identifiers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAmB7D;;GAEG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,EACnD,SAAS,cAAc,KACtB,CAAC,cAAc,EAAE,cAAc,CA+CjC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAC5B,UAAU,SAAS,MAAM,EAAE,EAC3B,SAAS,cAAc,KACtB,CAAC,MAAM,EAAE,cAAc,CAezB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAClC,UAAU,MAAM,EAChB,UAAU,SAAS,MAAM,EAAE,EAC3B,SAAS,cAAc,KACtB,CAAC,MAAM,EAAE,cAAc,CAczB,CAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Identifier and type argument emitters
|
|
3
3
|
*/
|
|
4
4
|
import { emitType } from "../type-emitter.js";
|
|
5
|
+
import { escapeCSharpIdentifier } from "../emitter-types/index.js";
|
|
5
6
|
/**
|
|
6
7
|
* Fallback mappings for well-known runtime globals
|
|
7
8
|
* Used when binding manifests are not available (e.g., in tests)
|
|
@@ -59,8 +60,8 @@ export const emitIdentifier = (expr, context) => {
|
|
|
59
60
|
return [{ text: fallback }, context];
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
|
-
// Fallback: use identifier as-is
|
|
63
|
-
return [{ text: expr.name }, context];
|
|
63
|
+
// Fallback: use identifier as-is (escape C# keywords)
|
|
64
|
+
return [{ text: escapeCSharpIdentifier(expr.name) }, context];
|
|
64
65
|
};
|
|
65
66
|
/**
|
|
66
67
|
* Emit type arguments as C# generic type parameters
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identifiers.js","sourceRoot":"","sources":["../../src/expressions/identifiers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"identifiers.js","sourceRoot":"","sources":["../../src/expressions/identifiers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Operator expression emitters (binary, logical, unary, update, assignment, conditional)
|
|
3
3
|
*/
|
|
4
|
-
import { IrExpression } from "@tsonic/frontend";
|
|
4
|
+
import { IrExpression, IrType } from "@tsonic/frontend";
|
|
5
5
|
import { EmitterContext, CSharpFragment } from "../types.js";
|
|
6
6
|
/**
|
|
7
7
|
* Emit a binary operator expression
|
|
8
|
+
*
|
|
9
|
+
* When the expression has an integer inferredType (from `as int` etc.),
|
|
10
|
+
* or when expectedType requires an integer, we wrap the result with an
|
|
11
|
+
* explicit cast to ensure correct C# semantics.
|
|
12
|
+
* This handles cases like `(i + 1) as int` which must emit as `(int)(i + 1)`.
|
|
13
|
+
*
|
|
14
|
+
* @param expr - The binary expression
|
|
15
|
+
* @param context - Emitter context
|
|
16
|
+
* @param expectedType - Optional expected type from outer context (assignment, return, etc.)
|
|
8
17
|
*/
|
|
9
18
|
export declare const emitBinary: (expr: Extract<IrExpression, {
|
|
10
19
|
kind: "binary";
|
|
11
|
-
}>, context: EmitterContext) => [CSharpFragment, EmitterContext];
|
|
20
|
+
}>, context: EmitterContext, expectedType?: IrType) => [CSharpFragment, EmitterContext];
|
|
12
21
|
/**
|
|
13
22
|
* Emit a logical operator expression (&&, ||, ??)
|
|
14
23
|
*
|
|
@@ -27,10 +36,18 @@ export declare const emitLogical: (expr: Extract<IrExpression, {
|
|
|
27
36
|
}>, context: EmitterContext) => [CSharpFragment, EmitterContext];
|
|
28
37
|
/**
|
|
29
38
|
* Emit a unary operator expression (-, +, !, ~, typeof, void, delete)
|
|
39
|
+
*
|
|
40
|
+
* When the expression has an integer inferredType (from `as int` etc.),
|
|
41
|
+
* or when expectedType requires an integer, we wrap the result with an
|
|
42
|
+
* explicit cast. This handles `-1 as int`.
|
|
43
|
+
*
|
|
44
|
+
* @param expr - The unary expression
|
|
45
|
+
* @param context - Emitter context
|
|
46
|
+
* @param expectedType - Optional expected type from outer context
|
|
30
47
|
*/
|
|
31
48
|
export declare const emitUnary: (expr: Extract<IrExpression, {
|
|
32
49
|
kind: "unary";
|
|
33
|
-
}>, context: EmitterContext) => [CSharpFragment, EmitterContext];
|
|
50
|
+
}>, context: EmitterContext, expectedType?: IrType) => [CSharpFragment, EmitterContext];
|
|
34
51
|
/**
|
|
35
52
|
* Emit an update operator expression (++, --)
|
|
36
53
|
*/
|
|
@@ -39,6 +56,9 @@ export declare const emitUpdate: (expr: Extract<IrExpression, {
|
|
|
39
56
|
}>, context: EmitterContext) => [CSharpFragment, EmitterContext];
|
|
40
57
|
/**
|
|
41
58
|
* Emit an assignment expression (=, +=, -=, etc.)
|
|
59
|
+
*
|
|
60
|
+
* Passes the LHS type as expected type to RHS, enabling proper integer
|
|
61
|
+
* literal emission for cases like `this.value = this.value + 1`.
|
|
42
62
|
*/
|
|
43
63
|
export declare const emitAssignment: (expr: Extract<IrExpression, {
|
|
44
64
|
kind: "assignment";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operators.d.ts","sourceRoot":"","sources":["../../src/expressions/operators.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"operators.d.ts","sourceRoot":"","sources":["../../src/expressions/operators.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA8E7D;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,UAAU,GACrB,MAAM,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,EAC/C,SAAS,cAAc,EACvB,eAAe,MAAM,KACpB,CAAC,cAAc,EAAE,cAAc,CA6CjC,CAAC;AAUF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,GACtB,MAAM,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,EAChD,SAAS,cAAc,KACtB,CAAC,cAAc,EAAE,cAAc,CAYjC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,SAAS,GACpB,MAAM,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,EAC9C,SAAS,cAAc,EACvB,eAAe,MAAM,KACpB,CAAC,cAAc,EAAE,cAAc,CAwCjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,UAAU,GACrB,MAAM,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,EAC/C,SAAS,cAAc,KACtB,CAAC,cAAc,EAAE,cAAc,CAQjC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,EACnD,SAAS,cAAc,KACtB,CAAC,cAAc,EAAE,cAAc,CAsCjC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAC1B,MAAM,OAAO,CAAC,YAAY,EAAE;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC,EACpD,SAAS,cAAc,KACtB,CAAC,cAAc,EAAE,cAAc,CAOjC,CAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Operator expression emitters (binary, logical, unary, update, assignment, conditional)
|
|
3
3
|
*/
|
|
4
4
|
import { emitExpression } from "../expression-emitter.js";
|
|
5
|
+
import { getExpectedClrTypeForNumeric } from "./literals.js";
|
|
5
6
|
/**
|
|
6
7
|
* Get operator precedence for proper parenthesization
|
|
7
8
|
*/
|
|
@@ -35,12 +36,62 @@ const getPrecedence = (operator) => {
|
|
|
35
36
|
};
|
|
36
37
|
return precedences[operator] ?? 16;
|
|
37
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* Get the C# type name for an integer CLR type (for explicit casts).
|
|
41
|
+
* Returns the type keyword or undefined if not an integer type.
|
|
42
|
+
*/
|
|
43
|
+
const getIntegerCastType = (irType) => {
|
|
44
|
+
const clrType = getExpectedClrTypeForNumeric(irType);
|
|
45
|
+
if (!clrType)
|
|
46
|
+
return undefined;
|
|
47
|
+
// Map to C# type keywords for casts
|
|
48
|
+
const typeMap = {
|
|
49
|
+
int: "int",
|
|
50
|
+
Int32: "int",
|
|
51
|
+
"System.Int32": "int",
|
|
52
|
+
long: "long",
|
|
53
|
+
Int64: "long",
|
|
54
|
+
"System.Int64": "long",
|
|
55
|
+
short: "short",
|
|
56
|
+
Int16: "short",
|
|
57
|
+
"System.Int16": "short",
|
|
58
|
+
byte: "byte",
|
|
59
|
+
Byte: "byte",
|
|
60
|
+
"System.Byte": "byte",
|
|
61
|
+
sbyte: "sbyte",
|
|
62
|
+
SByte: "sbyte",
|
|
63
|
+
"System.SByte": "sbyte",
|
|
64
|
+
uint: "uint",
|
|
65
|
+
UInt32: "uint",
|
|
66
|
+
"System.UInt32": "uint",
|
|
67
|
+
ulong: "ulong",
|
|
68
|
+
UInt64: "ulong",
|
|
69
|
+
"System.UInt64": "ulong",
|
|
70
|
+
ushort: "ushort",
|
|
71
|
+
UInt16: "ushort",
|
|
72
|
+
"System.UInt16": "ushort",
|
|
73
|
+
};
|
|
74
|
+
return typeMap[clrType];
|
|
75
|
+
};
|
|
38
76
|
/**
|
|
39
77
|
* Emit a binary operator expression
|
|
78
|
+
*
|
|
79
|
+
* When the expression has an integer inferredType (from `as int` etc.),
|
|
80
|
+
* or when expectedType requires an integer, we wrap the result with an
|
|
81
|
+
* explicit cast to ensure correct C# semantics.
|
|
82
|
+
* This handles cases like `(i + 1) as int` which must emit as `(int)(i + 1)`.
|
|
83
|
+
*
|
|
84
|
+
* @param expr - The binary expression
|
|
85
|
+
* @param context - Emitter context
|
|
86
|
+
* @param expectedType - Optional expected type from outer context (assignment, return, etc.)
|
|
40
87
|
*/
|
|
41
|
-
export const emitBinary = (expr, context) => {
|
|
42
|
-
|
|
43
|
-
|
|
88
|
+
export const emitBinary = (expr, context, expectedType) => {
|
|
89
|
+
// Check if this binary expression should produce an integer result
|
|
90
|
+
// Priority: expression's own inferredType > expectedType from context
|
|
91
|
+
const integerCastType = getIntegerCastType(expr.inferredType) || getIntegerCastType(expectedType);
|
|
92
|
+
// Pass expected type to children so literals emit correctly
|
|
93
|
+
const [leftFrag, leftContext] = emitExpression(expr.left, context, integerCastType ? expr.inferredType : undefined);
|
|
94
|
+
const [rightFrag, rightContext] = emitExpression(expr.right, leftContext, integerCastType ? expr.inferredType : undefined);
|
|
44
95
|
// Map JavaScript operators to C# operators
|
|
45
96
|
const operatorMap = {
|
|
46
97
|
"===": "==",
|
|
@@ -56,7 +107,12 @@ export const emitBinary = (expr, context) => {
|
|
|
56
107
|
const text = `${leftFrag.text} is ${rightFrag.text}`;
|
|
57
108
|
return [{ text, precedence: 7 }, rightContext];
|
|
58
109
|
}
|
|
59
|
-
|
|
110
|
+
let text = `${leftFrag.text} ${op} ${rightFrag.text}`;
|
|
111
|
+
// Wrap with explicit cast if integer type is required
|
|
112
|
+
// This ensures correctness even if child expressions have mixed types
|
|
113
|
+
if (integerCastType) {
|
|
114
|
+
text = `(${integerCastType})(${text})`;
|
|
115
|
+
}
|
|
60
116
|
return [{ text, precedence: getPrecedence(expr.operator) }, rightContext];
|
|
61
117
|
};
|
|
62
118
|
/**
|
|
@@ -92,9 +148,21 @@ export const emitLogical = (expr, context) => {
|
|
|
92
148
|
};
|
|
93
149
|
/**
|
|
94
150
|
* Emit a unary operator expression (-, +, !, ~, typeof, void, delete)
|
|
151
|
+
*
|
|
152
|
+
* When the expression has an integer inferredType (from `as int` etc.),
|
|
153
|
+
* or when expectedType requires an integer, we wrap the result with an
|
|
154
|
+
* explicit cast. This handles `-1 as int`.
|
|
155
|
+
*
|
|
156
|
+
* @param expr - The unary expression
|
|
157
|
+
* @param context - Emitter context
|
|
158
|
+
* @param expectedType - Optional expected type from outer context
|
|
95
159
|
*/
|
|
96
|
-
export const emitUnary = (expr, context) => {
|
|
97
|
-
|
|
160
|
+
export const emitUnary = (expr, context, expectedType) => {
|
|
161
|
+
// Check if this unary expression should produce an integer result
|
|
162
|
+
// Priority: expression's own inferredType > expectedType from context
|
|
163
|
+
const integerCastType = getIntegerCastType(expr.inferredType) || getIntegerCastType(expectedType);
|
|
164
|
+
// Pass expected type to operand so literals emit correctly
|
|
165
|
+
const [operandFrag, newContext] = emitExpression(expr.expression, context, integerCastType ? expr.inferredType : undefined);
|
|
98
166
|
if (expr.operator === "typeof") {
|
|
99
167
|
// typeof becomes global::Tsonic.Runtime.Operators.typeof()
|
|
100
168
|
const text = `global::Tsonic.Runtime.Operators.@typeof(${operandFrag.text})`;
|
|
@@ -110,7 +178,12 @@ export const emitUnary = (expr, context) => {
|
|
|
110
178
|
const text = `/* delete ${operandFrag.text} */`;
|
|
111
179
|
return [{ text }, newContext];
|
|
112
180
|
}
|
|
113
|
-
|
|
181
|
+
let text = `${expr.operator}${operandFrag.text}`;
|
|
182
|
+
// Wrap with explicit cast if integer type is required
|
|
183
|
+
// This handles cases like `-1 as int` emitting as `(int)(-1)`
|
|
184
|
+
if (integerCastType && (expr.operator === "-" || expr.operator === "+")) {
|
|
185
|
+
text = `(${integerCastType})(${text})`;
|
|
186
|
+
}
|
|
114
187
|
return [{ text, precedence: 15 }, newContext];
|
|
115
188
|
};
|
|
116
189
|
/**
|
|
@@ -125,11 +198,15 @@ export const emitUpdate = (expr, context) => {
|
|
|
125
198
|
};
|
|
126
199
|
/**
|
|
127
200
|
* Emit an assignment expression (=, +=, -=, etc.)
|
|
201
|
+
*
|
|
202
|
+
* Passes the LHS type as expected type to RHS, enabling proper integer
|
|
203
|
+
* literal emission for cases like `this.value = this.value + 1`.
|
|
128
204
|
*/
|
|
129
205
|
export const emitAssignment = (expr, context) => {
|
|
130
206
|
// Left side can be an expression or a pattern (for destructuring)
|
|
131
207
|
let leftText;
|
|
132
208
|
let leftContext;
|
|
209
|
+
let leftType;
|
|
133
210
|
if ("kind" in expr.left &&
|
|
134
211
|
(expr.left.kind === "identifierPattern" ||
|
|
135
212
|
expr.left.kind === "arrayPattern" ||
|
|
@@ -138,6 +215,7 @@ export const emitAssignment = (expr, context) => {
|
|
|
138
215
|
if (expr.left.kind === "identifierPattern") {
|
|
139
216
|
leftText = expr.left.name;
|
|
140
217
|
leftContext = context;
|
|
218
|
+
leftType = expr.left.type; // Patterns use `type`, not `inferredType`
|
|
141
219
|
}
|
|
142
220
|
else {
|
|
143
221
|
leftText = "/* destructuring */";
|
|
@@ -145,11 +223,14 @@ export const emitAssignment = (expr, context) => {
|
|
|
145
223
|
}
|
|
146
224
|
}
|
|
147
225
|
else {
|
|
148
|
-
const
|
|
226
|
+
const leftExpr = expr.left;
|
|
227
|
+
const [leftFrag, ctx] = emitExpression(leftExpr, context);
|
|
149
228
|
leftText = leftFrag.text;
|
|
150
229
|
leftContext = ctx;
|
|
230
|
+
leftType = leftExpr.inferredType;
|
|
151
231
|
}
|
|
152
|
-
|
|
232
|
+
// Pass LHS type as expected type to RHS for proper integer handling
|
|
233
|
+
const [rightFrag, rightContext] = emitExpression(expr.right, leftContext, leftType);
|
|
153
234
|
const text = `${leftText} ${expr.operator} ${rightFrag.text}`;
|
|
154
235
|
return [{ text, precedence: 3 }, rightContext];
|
|
155
236
|
};
|