c-next 0.1.62 → 0.1.63

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 (55) hide show
  1. package/README.md +86 -63
  2. package/package.json +1 -1
  3. package/src/transpiler/Transpiler.ts +3 -2
  4. package/src/transpiler/__tests__/DualCodePaths.test.ts +1 -1
  5. package/src/transpiler/__tests__/Transpiler.coverage.test.ts +1 -1
  6. package/src/transpiler/__tests__/Transpiler.test.ts +0 -23
  7. package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +156 -70
  8. package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +31 -6
  9. package/src/transpiler/logic/symbols/cnext/utils/TypeUtils.ts +43 -11
  10. package/src/transpiler/output/codegen/CodeGenState.ts +811 -0
  11. package/src/transpiler/output/codegen/CodeGenerator.ts +817 -1377
  12. package/src/transpiler/output/codegen/TypeResolver.ts +193 -149
  13. package/src/transpiler/output/codegen/TypeValidator.ts +148 -370
  14. package/src/transpiler/output/codegen/__tests__/CodeGenState.test.ts +446 -0
  15. package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +326 -60
  16. package/src/transpiler/output/codegen/__tests__/TrackVariableTypeHelpers.test.ts +1 -1
  17. package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +435 -196
  18. package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +51 -67
  19. package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +495 -471
  20. package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +39 -43
  21. package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +52 -55
  22. package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +122 -62
  23. package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +101 -144
  24. package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +143 -126
  25. package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +287 -320
  26. package/src/transpiler/output/codegen/generators/GeneratorRegistry.ts +12 -0
  27. package/src/transpiler/output/codegen/generators/__tests__/GeneratorRegistry.test.ts +28 -1
  28. package/src/transpiler/output/codegen/generators/declarationGenerators/ArrayDimensionUtils.ts +67 -0
  29. package/src/transpiler/output/codegen/generators/declarationGenerators/ScopeGenerator.ts +121 -51
  30. package/src/transpiler/output/codegen/generators/declarationGenerators/StructGenerator.ts +100 -23
  31. package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ArrayDimensionUtils.test.ts +125 -0
  32. package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ScopeGenerator.test.ts +157 -4
  33. package/src/transpiler/output/codegen/generators/support/HelperGenerator.ts +23 -22
  34. package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +54 -61
  35. package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +21 -30
  36. package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +56 -53
  37. package/src/transpiler/output/codegen/helpers/CppModeHelper.ts +22 -30
  38. package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +108 -50
  39. package/src/transpiler/output/codegen/helpers/FloatBitHelper.ts +16 -31
  40. package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +103 -96
  41. package/src/transpiler/output/codegen/helpers/TypeGenerationHelper.ts +9 -0
  42. package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +58 -103
  43. package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +97 -40
  44. package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +223 -128
  45. package/src/transpiler/output/codegen/helpers/__tests__/CppModeHelper.test.ts +68 -41
  46. package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +198 -47
  47. package/src/transpiler/output/codegen/helpers/__tests__/FloatBitHelper.test.ts +39 -37
  48. package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +191 -453
  49. package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +229 -0
  50. package/src/transpiler/output/codegen/resolution/ScopeResolver.ts +60 -0
  51. package/src/transpiler/output/codegen/resolution/SizeofResolver.ts +177 -0
  52. package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +336 -0
  53. package/src/transpiler/output/codegen/resolution/__tests__/SizeofResolver.test.ts +201 -0
  54. package/src/transpiler/output/codegen/types/ITypeResolverDeps.ts +0 -23
  55. package/src/transpiler/output/codegen/types/ITypeValidatorDeps.ts +0 -53
@@ -0,0 +1,446 @@
1
+ /**
2
+ * Tests for CodeGenState - centralized code generation state management
3
+ */
4
+
5
+ import { describe, it, expect, beforeEach } from "vitest";
6
+ import CodeGenState from "../CodeGenState";
7
+ import TTypeInfo from "../types/TTypeInfo";
8
+ import ICodeGenSymbols from "../../../types/ICodeGenSymbols";
9
+
10
+ /**
11
+ * Create a minimal mock ICodeGenSymbols with default empty collections.
12
+ */
13
+ function createMockSymbols(
14
+ overrides: Partial<{
15
+ knownScopes: Set<string>;
16
+ knownEnums: Set<string>;
17
+ knownBitmaps: Set<string>;
18
+ knownStructs: Set<string>;
19
+ knownRegisters: Set<string>;
20
+ enumMembers: Map<string, Map<string, number>>;
21
+ structFields: Map<string, Map<string, string>>;
22
+ structFieldArrays: Map<string, Set<string>>;
23
+ functionReturnTypes: Map<string, string>;
24
+ scopeMemberVisibility: Map<string, Map<string, "public" | "private">>;
25
+ }> = {},
26
+ ): ICodeGenSymbols {
27
+ return {
28
+ knownScopes: overrides.knownScopes ?? new Set(),
29
+ knownEnums: overrides.knownEnums ?? new Set(),
30
+ knownBitmaps: overrides.knownBitmaps ?? new Set(),
31
+ knownStructs: overrides.knownStructs ?? new Set(),
32
+ knownRegisters: overrides.knownRegisters ?? new Set(),
33
+ scopeMembers: new Map(),
34
+ scopeMemberVisibility: overrides.scopeMemberVisibility ?? new Map(),
35
+ structFields: overrides.structFields ?? new Map(),
36
+ structFieldArrays: overrides.structFieldArrays ?? new Map(),
37
+ structFieldDimensions: new Map(),
38
+ enumMembers: overrides.enumMembers ?? new Map(),
39
+ bitmapFields: new Map(),
40
+ bitmapBackingType: new Map(),
41
+ bitmapBitWidth: new Map(),
42
+ scopedRegisters: new Map(),
43
+ registerMemberAccess: new Map(),
44
+ registerMemberTypes: new Map(),
45
+ registerBaseAddresses: new Map(),
46
+ registerMemberOffsets: new Map(),
47
+ registerMemberCTypes: new Map(),
48
+ scopeVariableUsage: new Map(),
49
+ scopePrivateConstValues: new Map(),
50
+ functionReturnTypes: overrides.functionReturnTypes ?? new Map(),
51
+ getSingleFunctionForVariable: () => null,
52
+ hasPublicSymbols: () => false,
53
+ };
54
+ }
55
+
56
+ describe("CodeGenState", () => {
57
+ beforeEach(() => {
58
+ CodeGenState.reset();
59
+ });
60
+
61
+ describe("reset()", () => {
62
+ it("resets all state to initial values", () => {
63
+ // Set some state
64
+ CodeGenState.currentScope = "TestScope";
65
+ CodeGenState.currentFunctionName = "testFunc";
66
+ CodeGenState.needsStdint = true;
67
+ CodeGenState.indentLevel = 5;
68
+
69
+ // Reset
70
+ CodeGenState.reset();
71
+
72
+ // Verify reset
73
+ expect(CodeGenState.currentScope).toBeNull();
74
+ expect(CodeGenState.currentFunctionName).toBeNull();
75
+ expect(CodeGenState.needsStdint).toBe(false);
76
+ expect(CodeGenState.indentLevel).toBe(0);
77
+ });
78
+
79
+ it("accepts custom target capabilities", () => {
80
+ const customTarget = {
81
+ hasFPU: true,
82
+ hasHardwareDivide: false,
83
+ maxBitWidth: 32,
84
+ hasAtomic: true,
85
+ wordSize: 32 as const,
86
+ hasLdrexStrex: true,
87
+ hasBasepri: true,
88
+ };
89
+
90
+ CodeGenState.reset(customTarget);
91
+
92
+ expect(CodeGenState.targetCapabilities).toEqual(customTarget);
93
+ });
94
+ });
95
+
96
+ describe("Scope Member Helpers", () => {
97
+ it("getScopeMembers returns undefined for unknown scope", () => {
98
+ expect(CodeGenState.getScopeMembers("UnknownScope")).toBeUndefined();
99
+ });
100
+
101
+ it("getScopeMembers returns members for known scope", () => {
102
+ const members = new Set(["member1", "member2"]);
103
+ CodeGenState.scopeMembers.set("TestScope", members);
104
+
105
+ expect(CodeGenState.getScopeMembers("TestScope")).toBe(members);
106
+ });
107
+
108
+ it("isCurrentScopeMember returns false when not in a scope", () => {
109
+ CodeGenState.currentScope = null;
110
+ expect(CodeGenState.isCurrentScopeMember("anyMember")).toBe(false);
111
+ });
112
+
113
+ it("isCurrentScopeMember returns false for non-member", () => {
114
+ CodeGenState.currentScope = "TestScope";
115
+ CodeGenState.scopeMembers.set("TestScope", new Set(["member1"]));
116
+
117
+ expect(CodeGenState.isCurrentScopeMember("nonMember")).toBe(false);
118
+ });
119
+
120
+ it("isCurrentScopeMember returns true for member", () => {
121
+ CodeGenState.currentScope = "TestScope";
122
+ CodeGenState.scopeMembers.set("TestScope", new Set(["member1"]));
123
+
124
+ expect(CodeGenState.isCurrentScopeMember("member1")).toBe(true);
125
+ });
126
+ });
127
+
128
+ describe("resolveIdentifier()", () => {
129
+ it("returns identifier unchanged when not in a scope", () => {
130
+ CodeGenState.currentScope = null;
131
+ expect(CodeGenState.resolveIdentifier("varName")).toBe("varName");
132
+ });
133
+
134
+ it("returns identifier unchanged when not a scope member", () => {
135
+ CodeGenState.currentScope = "TestScope";
136
+ CodeGenState.scopeMembers.set("TestScope", new Set(["member1"]));
137
+
138
+ expect(CodeGenState.resolveIdentifier("varName")).toBe("varName");
139
+ });
140
+
141
+ it("returns scoped name for scope member", () => {
142
+ CodeGenState.currentScope = "TestScope";
143
+ CodeGenState.scopeMembers.set("TestScope", new Set(["member1"]));
144
+
145
+ expect(CodeGenState.resolveIdentifier("member1")).toBe(
146
+ "TestScope_member1",
147
+ );
148
+ });
149
+ });
150
+
151
+ describe("Struct Field Helpers", () => {
152
+ const mockSymbols = createMockSymbols({
153
+ knownStructs: new Set(["MyStruct"]),
154
+ structFields: new Map([["MyStruct", new Map([["field1", "u32"]])]]),
155
+ structFieldArrays: new Map([["MyStruct", new Set(["arrayField"])]]),
156
+ });
157
+
158
+ it("getStructFieldType returns undefined without symbols", () => {
159
+ CodeGenState.symbols = null;
160
+ expect(
161
+ CodeGenState.getStructFieldType("MyStruct", "field1"),
162
+ ).toBeUndefined();
163
+ });
164
+
165
+ it("getStructFieldType returns field type with symbols", () => {
166
+ CodeGenState.symbols = mockSymbols;
167
+ expect(CodeGenState.getStructFieldType("MyStruct", "field1")).toBe("u32");
168
+ });
169
+
170
+ it("isStructFieldArray returns false without symbols", () => {
171
+ CodeGenState.symbols = null;
172
+ expect(CodeGenState.isStructFieldArray("MyStruct", "arrayField")).toBe(
173
+ false,
174
+ );
175
+ });
176
+
177
+ it("isStructFieldArray returns true for array field", () => {
178
+ CodeGenState.symbols = mockSymbols;
179
+ expect(CodeGenState.isStructFieldArray("MyStruct", "arrayField")).toBe(
180
+ true,
181
+ );
182
+ });
183
+
184
+ it("isStructFieldArray returns false for non-array field", () => {
185
+ CodeGenState.symbols = mockSymbols;
186
+ expect(CodeGenState.isStructFieldArray("MyStruct", "field1")).toBe(false);
187
+ });
188
+ });
189
+
190
+ describe("getEnumMembers()", () => {
191
+ it("returns undefined without symbols", () => {
192
+ CodeGenState.symbols = null;
193
+ expect(CodeGenState.getEnumMembers("MyEnum")).toBeUndefined();
194
+ });
195
+
196
+ it("returns enum members when available", () => {
197
+ const enumMembers = new Map([
198
+ ["VALUE1", 0],
199
+ ["VALUE2", 1],
200
+ ]);
201
+ CodeGenState.symbols = createMockSymbols({
202
+ knownEnums: new Set(["MyEnum"]),
203
+ enumMembers: new Map([["MyEnum", enumMembers]]),
204
+ });
205
+
206
+ expect(CodeGenState.getEnumMembers("MyEnum")).toBe(enumMembers);
207
+ });
208
+ });
209
+
210
+ describe("getFunctionReturnType()", () => {
211
+ it("returns undefined without symbols", () => {
212
+ CodeGenState.symbols = null;
213
+ expect(CodeGenState.getFunctionReturnType("myFunc")).toBeUndefined();
214
+ });
215
+
216
+ it("returns return type when available", () => {
217
+ CodeGenState.symbols = createMockSymbols({
218
+ functionReturnTypes: new Map([["myFunc", "u32"]]),
219
+ });
220
+
221
+ expect(CodeGenState.getFunctionReturnType("myFunc")).toBe("u32");
222
+ });
223
+ });
224
+
225
+ describe("Include Flag Helpers", () => {
226
+ it("requireStdint sets needsStdint", () => {
227
+ expect(CodeGenState.needsStdint).toBe(false);
228
+ CodeGenState.requireStdint();
229
+ expect(CodeGenState.needsStdint).toBe(true);
230
+ });
231
+
232
+ it("requireStdbool sets needsStdbool", () => {
233
+ expect(CodeGenState.needsStdbool).toBe(false);
234
+ CodeGenState.requireStdbool();
235
+ expect(CodeGenState.needsStdbool).toBe(true);
236
+ });
237
+
238
+ it("requireString sets needsString", () => {
239
+ expect(CodeGenState.needsString).toBe(false);
240
+ CodeGenState.requireString();
241
+ expect(CodeGenState.needsString).toBe(true);
242
+ });
243
+
244
+ it("requireCMSIS sets needsCMSIS", () => {
245
+ expect(CodeGenState.needsCMSIS).toBe(false);
246
+ CodeGenState.requireCMSIS();
247
+ expect(CodeGenState.needsCMSIS).toBe(true);
248
+ });
249
+
250
+ it("requireLimits sets needsLimits", () => {
251
+ expect(CodeGenState.needsLimits).toBe(false);
252
+ CodeGenState.requireLimits();
253
+ expect(CodeGenState.needsLimits).toBe(true);
254
+ });
255
+
256
+ it("requireISR sets needsISR", () => {
257
+ expect(CodeGenState.needsISR).toBe(false);
258
+ CodeGenState.requireISR();
259
+ expect(CodeGenState.needsISR).toBe(true);
260
+ });
261
+ });
262
+
263
+ describe("Type Registration Helpers", () => {
264
+ it("registerType adds to typeRegistry", () => {
265
+ const typeInfo: TTypeInfo = {
266
+ baseType: "u32",
267
+ bitWidth: 32,
268
+ isArray: false,
269
+ isConst: false,
270
+ };
271
+
272
+ CodeGenState.registerType("myVar", typeInfo);
273
+
274
+ expect(CodeGenState.typeRegistry.get("myVar")).toBe(typeInfo);
275
+ });
276
+
277
+ it("registerConstValue adds to constValues", () => {
278
+ CodeGenState.registerConstValue("MY_CONST", 42);
279
+ expect(CodeGenState.constValues.get("MY_CONST")).toBe(42);
280
+ });
281
+
282
+ it("registerLocalVariable adds to localVariables", () => {
283
+ CodeGenState.registerLocalVariable("localVar");
284
+ expect(CodeGenState.localVariables.has("localVar")).toBe(true);
285
+ expect(CodeGenState.localArrays.has("localVar")).toBe(false);
286
+ });
287
+
288
+ it("registerLocalVariable with isArray adds to both sets", () => {
289
+ CodeGenState.registerLocalVariable("localArr", true);
290
+ expect(CodeGenState.localVariables.has("localArr")).toBe(true);
291
+ expect(CodeGenState.localArrays.has("localArr")).toBe(true);
292
+ });
293
+
294
+ it("registerFunctionSignature adds to functionSignatures and knownFunctions", () => {
295
+ const sig = {
296
+ name: "myFunc",
297
+ returnType: "void",
298
+ parameters: [],
299
+ isPublic: true,
300
+ };
301
+
302
+ CodeGenState.registerFunctionSignature("myFunc", sig);
303
+
304
+ expect(CodeGenState.functionSignatures.get("myFunc")).toBe(sig);
305
+ expect(CodeGenState.knownFunctions.has("myFunc")).toBe(true);
306
+ });
307
+
308
+ it("registerCallbackType adds to callbackTypes", () => {
309
+ const info = {
310
+ functionName: "onClick",
311
+ returnType: "void",
312
+ parameters: [
313
+ {
314
+ name: "x",
315
+ type: "u32",
316
+ isArray: false,
317
+ isConst: false,
318
+ isPointer: false,
319
+ arrayDims: "",
320
+ },
321
+ ],
322
+ typedefName: "ClickHandler",
323
+ };
324
+
325
+ CodeGenState.registerCallbackType("MyCallback", info);
326
+
327
+ expect(CodeGenState.callbackTypes.get("MyCallback")).toBe(info);
328
+ });
329
+
330
+ it("registerCallbackFieldType adds to callbackFieldTypes", () => {
331
+ CodeGenState.registerCallbackFieldType(
332
+ "MyStruct_onClick",
333
+ "ClickHandler",
334
+ );
335
+ expect(CodeGenState.callbackFieldTypes.get("MyStruct_onClick")).toBe(
336
+ "ClickHandler",
337
+ );
338
+ });
339
+ });
340
+
341
+ describe("Overflow Operation Helpers", () => {
342
+ it("markClampOpUsed adds to usedClampOps", () => {
343
+ CodeGenState.markClampOpUsed("add", "u8");
344
+ expect(CodeGenState.usedClampOps.has("add_u8")).toBe(true);
345
+ });
346
+
347
+ it("markSafeDivOpUsed adds to usedSafeDivOps", () => {
348
+ CodeGenState.markSafeDivOpUsed("div", "i32");
349
+ expect(CodeGenState.usedSafeDivOps.has("div_i32")).toBe(true);
350
+ });
351
+ });
352
+
353
+ describe("Float Bit Shadow Helpers", () => {
354
+ it("registerFloatBitShadow adds to floatBitShadows", () => {
355
+ CodeGenState.registerFloatBitShadow("myFloat_bits");
356
+ expect(CodeGenState.floatBitShadows.has("myFloat_bits")).toBe(true);
357
+ });
358
+
359
+ it("hasFloatBitShadow returns correct value", () => {
360
+ expect(CodeGenState.hasFloatBitShadow("myFloat_bits")).toBe(false);
361
+ CodeGenState.registerFloatBitShadow("myFloat_bits");
362
+ expect(CodeGenState.hasFloatBitShadow("myFloat_bits")).toBe(true);
363
+ });
364
+
365
+ it("markFloatShadowCurrent adds to floatShadowCurrent", () => {
366
+ CodeGenState.markFloatShadowCurrent("myFloat_bits");
367
+ expect(CodeGenState.floatShadowCurrent.has("myFloat_bits")).toBe(true);
368
+ });
369
+
370
+ it("isFloatShadowCurrent returns correct value", () => {
371
+ expect(CodeGenState.isFloatShadowCurrent("myFloat_bits")).toBe(false);
372
+ CodeGenState.markFloatShadowCurrent("myFloat_bits");
373
+ expect(CodeGenState.isFloatShadowCurrent("myFloat_bits")).toBe(true);
374
+ });
375
+ });
376
+
377
+ describe("C++ Mode Helpers", () => {
378
+ it("addPendingTempDeclaration adds declaration", () => {
379
+ CodeGenState.addPendingTempDeclaration("int _tmp0 = x;");
380
+ expect(CodeGenState.pendingTempDeclarations).toContain("int _tmp0 = x;");
381
+ });
382
+
383
+ it("flushPendingTempDeclarations returns and clears declarations", () => {
384
+ CodeGenState.addPendingTempDeclaration("int _tmp0 = x;");
385
+ CodeGenState.addPendingTempDeclaration("int _tmp1 = y;");
386
+
387
+ const decls = CodeGenState.flushPendingTempDeclarations();
388
+
389
+ expect(decls).toHaveLength(2);
390
+ expect(decls).toContain("int _tmp0 = x;");
391
+ expect(decls).toContain("int _tmp1 = y;");
392
+ expect(CodeGenState.pendingTempDeclarations).toHaveLength(0);
393
+ });
394
+
395
+ it("getNextTempVarName returns incrementing names", () => {
396
+ CodeGenState.reset(); // Reset counter
397
+ expect(CodeGenState.getNextTempVarName()).toBe("_tmp0");
398
+ expect(CodeGenState.getNextTempVarName()).toBe("_tmp1");
399
+ expect(CodeGenState.getNextTempVarName()).toBe("_tmp2");
400
+ });
401
+ });
402
+
403
+ describe("Symbol Lookup Helpers", () => {
404
+ it("isKnownEnum returns false without symbols", () => {
405
+ CodeGenState.symbols = null;
406
+ expect(CodeGenState.isKnownEnum("MyEnum")).toBe(false);
407
+ });
408
+
409
+ it("isKnownEnum returns true for known enum", () => {
410
+ CodeGenState.symbols = createMockSymbols({
411
+ knownEnums: new Set(["MyEnum"]),
412
+ });
413
+
414
+ expect(CodeGenState.isKnownEnum("MyEnum")).toBe(true);
415
+ expect(CodeGenState.isKnownEnum("UnknownEnum")).toBe(false);
416
+ });
417
+
418
+ it("isKnownScope returns false without symbols", () => {
419
+ CodeGenState.symbols = null;
420
+ expect(CodeGenState.isKnownScope("MyScope")).toBe(false);
421
+ });
422
+
423
+ it("isKnownScope returns true for known scope", () => {
424
+ CodeGenState.symbols = createMockSymbols({
425
+ knownScopes: new Set(["MyScope"]),
426
+ });
427
+
428
+ expect(CodeGenState.isKnownScope("MyScope")).toBe(true);
429
+ expect(CodeGenState.isKnownScope("UnknownScope")).toBe(false);
430
+ });
431
+ });
432
+
433
+ describe("Local Variable Helpers", () => {
434
+ it("isLocalVariable returns correct value", () => {
435
+ expect(CodeGenState.isLocalVariable("myVar")).toBe(false);
436
+ CodeGenState.localVariables.add("myVar");
437
+ expect(CodeGenState.isLocalVariable("myVar")).toBe(true);
438
+ });
439
+
440
+ it("isLocalArray returns correct value", () => {
441
+ expect(CodeGenState.isLocalArray("myArr")).toBe(false);
442
+ CodeGenState.localArrays.add("myArr");
443
+ expect(CodeGenState.isLocalArray("myArr")).toBe(true);
444
+ });
445
+ });
446
+ });