c-next 0.1.70 → 0.1.72

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 (205) hide show
  1. package/package.json +1 -1
  2. package/src/lib/__tests__/parseCHeader.mocked.test.ts +69 -54
  3. package/src/lib/parseCHeader.ts +56 -23
  4. package/src/lib/parseWithSymbols.ts +195 -53
  5. package/src/transpiler/Transpiler.ts +180 -63
  6. package/src/transpiler/logic/analysis/FunctionCallAnalyzer.ts +1 -2
  7. package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +1 -2
  8. package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +51 -2
  9. package/src/transpiler/logic/analysis/__tests__/FunctionCallAnalyzer.test.ts +18 -12
  10. package/src/transpiler/logic/analysis/__tests__/InitializationAnalyzer.test.ts +9 -9
  11. package/src/transpiler/logic/analysis/__tests__/runAnalyzers.test.ts +5 -5
  12. package/src/transpiler/logic/symbols/SymbolTable.ts +729 -265
  13. package/src/transpiler/logic/symbols/SymbolUtils.ts +2 -2
  14. package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +415 -751
  15. package/src/transpiler/logic/symbols/c/__tests__/CResolver.integration.test.ts +573 -0
  16. package/src/transpiler/logic/symbols/c/__tests__/testHelpers.ts +20 -0
  17. package/src/transpiler/logic/symbols/c/collectors/EnumCollector.ts +82 -0
  18. package/src/transpiler/logic/symbols/c/collectors/FunctionCollector.ts +106 -0
  19. package/src/transpiler/logic/symbols/c/collectors/StructCollector.ts +173 -0
  20. package/src/transpiler/logic/symbols/c/collectors/TypedefCollector.ts +35 -0
  21. package/src/transpiler/logic/symbols/c/collectors/VariableCollector.ts +80 -0
  22. package/src/transpiler/logic/symbols/c/index.ts +333 -0
  23. package/src/transpiler/logic/symbols/c/utils/DeclaratorUtils.ts +269 -0
  24. package/src/transpiler/logic/symbols/cnext/__tests__/BitmapCollector.test.ts +50 -11
  25. package/src/transpiler/logic/symbols/cnext/__tests__/CNextResolver.integration.test.ts +45 -34
  26. package/src/transpiler/logic/symbols/cnext/__tests__/EnumCollector.test.ts +30 -13
  27. package/src/transpiler/logic/symbols/cnext/__tests__/FunctionCollector.test.ts +279 -64
  28. package/src/transpiler/logic/symbols/cnext/__tests__/RegisterCollector.test.ts +60 -13
  29. package/src/transpiler/logic/symbols/cnext/__tests__/ScopeCollector.test.ts +40 -37
  30. package/src/transpiler/logic/symbols/cnext/__tests__/StructCollector.test.ts +131 -45
  31. package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolInfoAdapter.test.ts +223 -139
  32. package/src/transpiler/logic/symbols/cnext/__tests__/VariableCollector.test.ts +79 -25
  33. package/src/transpiler/logic/symbols/cnext/__tests__/testUtils.ts +53 -0
  34. package/src/transpiler/logic/symbols/cnext/adapters/TSymbolInfoAdapter.ts +83 -43
  35. package/src/transpiler/logic/symbols/cnext/collectors/BitmapCollector.ts +14 -13
  36. package/src/transpiler/logic/symbols/cnext/collectors/EnumCollector.ts +11 -10
  37. package/src/transpiler/logic/symbols/cnext/collectors/FunctionCollector.ts +83 -34
  38. package/src/transpiler/logic/symbols/cnext/collectors/RegisterCollector.ts +22 -18
  39. package/src/transpiler/logic/symbols/cnext/collectors/ScopeCollector.ts +53 -35
  40. package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +30 -23
  41. package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +18 -19
  42. package/src/transpiler/logic/symbols/cnext/index.ts +36 -14
  43. package/src/transpiler/logic/symbols/cnext/types/IScopeCollectorResult.ts +2 -2
  44. package/src/transpiler/logic/symbols/cnext/utils/SymbolNameUtils.ts +27 -0
  45. package/src/transpiler/logic/symbols/cpp/__tests__/CppResolver.integration.test.ts +270 -0
  46. package/src/transpiler/logic/symbols/cpp/__tests__/testHelpers.ts +20 -0
  47. package/src/transpiler/logic/symbols/cpp/collectors/ClassCollector.ts +317 -0
  48. package/src/transpiler/logic/symbols/cpp/collectors/EnumCollector.ts +71 -0
  49. package/src/transpiler/logic/symbols/cpp/collectors/FunctionCollector.ts +155 -0
  50. package/src/transpiler/logic/symbols/cpp/collectors/NamespaceCollector.ts +65 -0
  51. package/src/transpiler/logic/symbols/cpp/collectors/TypeAliasCollector.ts +46 -0
  52. package/src/transpiler/logic/symbols/cpp/collectors/VariableCollector.ts +54 -0
  53. package/src/transpiler/logic/symbols/cpp/index.ts +366 -0
  54. package/src/transpiler/logic/symbols/cpp/utils/DeclaratorUtils.ts +248 -0
  55. package/src/transpiler/logic/symbols/shared/IExtractedParameter.ts +18 -0
  56. package/src/transpiler/logic/symbols/shared/ParameterExtractorUtils.ts +73 -0
  57. package/src/transpiler/output/codegen/CodeGenerator.ts +268 -1674
  58. package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +7 -1
  59. package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +2 -1
  60. package/src/transpiler/output/codegen/assignment/handlers/AssignmentHandlerUtils.ts +7 -1
  61. package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +6 -2
  62. package/src/transpiler/output/codegen/assignment/handlers/RegisterHandlers.ts +2 -1
  63. package/src/transpiler/output/codegen/generators/declarationGenerators/ScopeGenerator.ts +21 -8
  64. package/src/transpiler/output/codegen/generators/declarationGenerators/ScopedRegisterGenerator.ts +3 -2
  65. package/src/transpiler/output/codegen/generators/expressions/CallExprUtils.ts +9 -3
  66. package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprGenerator.test.ts +3 -4
  67. package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprUtils.test.ts +4 -8
  68. package/src/transpiler/output/codegen/helpers/ArgumentGenerator.ts +236 -0
  69. package/src/transpiler/output/codegen/helpers/CppConstructorHelper.ts +3 -3
  70. package/src/transpiler/output/codegen/helpers/FunctionContextManager.ts +435 -0
  71. package/src/transpiler/output/codegen/helpers/StringOperationsHelper.ts +203 -0
  72. package/src/transpiler/output/codegen/helpers/SymbolLookupHelper.ts +8 -12
  73. package/src/transpiler/output/codegen/helpers/TypeRegistrationEngine.ts +520 -0
  74. package/src/transpiler/output/codegen/helpers/VariableDeclHelper.ts +735 -0
  75. package/src/transpiler/output/codegen/helpers/VariableDeclarationFormatter.ts +1 -1
  76. package/src/transpiler/output/codegen/helpers/__tests__/ArgumentGenerator.test.ts +521 -0
  77. package/src/transpiler/output/codegen/helpers/__tests__/CppConstructorHelper.test.ts +4 -5
  78. package/src/transpiler/output/codegen/helpers/__tests__/FunctionContextManager.test.ts +983 -0
  79. package/src/transpiler/output/codegen/helpers/__tests__/StringOperationsHelper.test.ts +269 -0
  80. package/src/transpiler/output/codegen/helpers/__tests__/SymbolLookupHelper.test.ts +31 -32
  81. package/src/transpiler/output/codegen/helpers/__tests__/TypeRegistrationEngine.test.ts +186 -0
  82. package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclHelper.test.ts +460 -0
  83. package/src/transpiler/output/codegen/helpers/types/IArgumentGeneratorCallbacks.ts +32 -0
  84. package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +5 -1
  85. package/src/transpiler/output/codegen/types/IFunctionContextCallbacks.ts +12 -0
  86. package/src/transpiler/output/codegen/types/IVariableFormatInput.ts +1 -1
  87. package/src/transpiler/output/codegen/utils/QualifiedNameGenerator.ts +114 -0
  88. package/src/transpiler/output/codegen/utils/__tests__/QualifiedNameGenerator.test.ts +183 -0
  89. package/src/transpiler/output/headers/BaseHeaderGenerator.ts +4 -4
  90. package/src/transpiler/output/headers/ExternalTypeHeaderBuilder.ts +7 -7
  91. package/src/transpiler/output/headers/HeaderGenerator.ts +9 -7
  92. package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +19 -20
  93. package/src/transpiler/output/headers/__tests__/BaseHeaderGenerator.test.ts +15 -18
  94. package/src/transpiler/output/headers/__tests__/CHeaderGenerator.test.ts +63 -64
  95. package/src/transpiler/output/headers/__tests__/CppHeaderGenerator.test.ts +36 -32
  96. package/src/transpiler/output/headers/__tests__/ExternalTypeHeaderBuilder.test.ts +26 -26
  97. package/src/transpiler/output/headers/__tests__/HeaderGenerator.test.ts +87 -59
  98. package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +57 -58
  99. package/src/transpiler/output/headers/adapters/HeaderSymbolAdapter.ts +222 -0
  100. package/src/transpiler/output/headers/adapters/__tests__/HeaderSymbolAdapter.test.ts +538 -0
  101. package/src/transpiler/output/headers/types/IGroupedSymbols.ts +8 -8
  102. package/src/transpiler/output/headers/types/IHeaderSymbol.ts +62 -0
  103. package/src/transpiler/state/CodeGenState.ts +20 -33
  104. package/src/transpiler/state/SymbolRegistry.ts +181 -0
  105. package/src/transpiler/{types → state}/TranspilerState.ts +1 -1
  106. package/src/transpiler/state/__tests__/CodeGenState.test.ts +67 -59
  107. package/src/transpiler/state/__tests__/SymbolRegistry.test.ts +249 -0
  108. package/src/transpiler/{types → state}/__tests__/TranspilerState.test.ts +1 -1
  109. package/src/transpiler/types/ICachedFileEntry.ts +1 -1
  110. package/src/transpiler/types/IConflict.ts +14 -0
  111. package/src/transpiler/types/IPipelineInput.ts +0 -3
  112. package/src/transpiler/types/ISerializedSymbol.ts +11 -0
  113. package/src/transpiler/types/TPrimitiveKind.ts +20 -0
  114. package/src/transpiler/types/TType.ts +103 -0
  115. package/src/transpiler/types/TVisibility.ts +6 -0
  116. package/src/transpiler/types/symbol-kinds/TSymbolKind.ts +10 -0
  117. package/src/transpiler/types/symbol-kinds/TSymbolKindC.ts +12 -0
  118. package/src/transpiler/types/symbol-kinds/TSymbolKindCNext.ts +16 -0
  119. package/src/transpiler/types/symbol-kinds/TSymbolKindCpp.ts +14 -0
  120. package/src/transpiler/types/symbols/IBaseSymbol.ts +31 -0
  121. package/src/transpiler/{logic/symbols/types → types/symbols}/IBitmapFieldInfo.ts +2 -2
  122. package/src/transpiler/types/symbols/IBitmapSymbol.ts +21 -0
  123. package/src/transpiler/{logic/symbols/types → types/symbols}/IEnumSymbol.ts +5 -6
  124. package/src/transpiler/types/symbols/IFieldInfo.ts +26 -0
  125. package/src/transpiler/types/symbols/IFunctionSymbol.ts +30 -0
  126. package/src/transpiler/types/symbols/IParameterInfo.ts +26 -0
  127. package/src/transpiler/{logic/symbols/types → types/symbols}/IRegisterMemberInfo.ts +4 -4
  128. package/src/transpiler/types/symbols/IRegisterSymbol.ts +18 -0
  129. package/src/transpiler/types/symbols/IScopeSymbol.ts +32 -0
  130. package/src/transpiler/{logic/symbols/types → types/symbols}/IStructFieldInfo.ts +2 -1
  131. package/src/transpiler/types/symbols/IStructSymbol.ts +15 -0
  132. package/src/transpiler/types/symbols/IVariableSymbol.ts +30 -0
  133. package/src/transpiler/types/symbols/SymbolGuards.ts +43 -0
  134. package/src/transpiler/types/symbols/TAnySymbol.ts +22 -0
  135. package/src/transpiler/types/symbols/TSymbol.ts +32 -0
  136. package/src/transpiler/types/symbols/__tests__/IBaseSymbol.test.ts +56 -0
  137. package/src/transpiler/types/symbols/__tests__/SymbolGuards.test.ts +57 -0
  138. package/src/transpiler/types/symbols/c/ICBaseSymbol.ts +28 -0
  139. package/src/transpiler/types/symbols/c/ICEnumMemberSymbol.ts +17 -0
  140. package/src/transpiler/types/symbols/c/ICEnumSymbol.ts +17 -0
  141. package/src/transpiler/types/symbols/c/ICFieldInfo.ts +16 -0
  142. package/src/transpiler/types/symbols/c/ICFunctionSymbol.ts +21 -0
  143. package/src/transpiler/types/symbols/c/ICParameterInfo.ts +19 -0
  144. package/src/transpiler/types/symbols/c/ICStructSymbol.ts +21 -0
  145. package/src/transpiler/types/symbols/c/ICTypedefSymbol.ts +14 -0
  146. package/src/transpiler/types/symbols/c/ICVariableSymbol.ts +26 -0
  147. package/src/transpiler/types/symbols/c/TCSymbol.ts +26 -0
  148. package/src/transpiler/types/symbols/cpp/ICppBaseSymbol.ts +31 -0
  149. package/src/transpiler/types/symbols/cpp/ICppClassSymbol.ts +15 -0
  150. package/src/transpiler/types/symbols/cpp/ICppEnumMemberSymbol.ts +14 -0
  151. package/src/transpiler/types/symbols/cpp/ICppEnumSymbol.ts +14 -0
  152. package/src/transpiler/types/symbols/cpp/ICppFieldInfo.ts +16 -0
  153. package/src/transpiler/types/symbols/cpp/ICppFunctionSymbol.ts +21 -0
  154. package/src/transpiler/types/symbols/cpp/ICppNamespaceSymbol.ts +11 -0
  155. package/src/transpiler/types/symbols/cpp/ICppParameterInfo.ts +19 -0
  156. package/src/transpiler/types/symbols/cpp/ICppStructSymbol.ts +16 -0
  157. package/src/transpiler/types/symbols/cpp/ICppTypeAliasSymbol.ts +14 -0
  158. package/src/transpiler/types/symbols/cpp/ICppVariableSymbol.ts +23 -0
  159. package/src/transpiler/types/symbols/cpp/TCppSymbol.ts +30 -0
  160. package/src/utils/CppNamespaceUtils.ts +3 -4
  161. package/src/utils/FunctionUtils.ts +92 -0
  162. package/src/utils/ParameterUtils.ts +55 -0
  163. package/src/utils/PrimitiveKindUtils.ts +33 -0
  164. package/src/utils/ScopeUtils.ts +105 -0
  165. package/src/utils/TTypeUtils.ts +159 -0
  166. package/src/utils/TypeResolver.ts +132 -0
  167. package/src/utils/__tests__/CppNamespaceUtils.test.ts +92 -99
  168. package/src/utils/__tests__/FunctionUtils.test.ts +284 -0
  169. package/src/utils/__tests__/ParameterUtils.test.ts +174 -0
  170. package/src/utils/__tests__/PrimitiveKindUtils.test.ts +59 -0
  171. package/src/utils/__tests__/ScopeUtils.test.ts +53 -0
  172. package/src/utils/__tests__/TTypeUtils.test.ts +245 -0
  173. package/src/utils/__tests__/TypeResolver.test.ts +332 -0
  174. package/src/utils/cache/CacheManager.ts +91 -50
  175. package/src/utils/cache/__tests__/CacheManager.test.ts +180 -114
  176. package/src/transpiler/logic/symbols/AutoConstUpdater.ts +0 -93
  177. package/src/transpiler/logic/symbols/CSymbolCollector.ts +0 -648
  178. package/src/transpiler/logic/symbols/CppSymbolCollector.ts +0 -874
  179. package/src/transpiler/logic/symbols/SymbolCollectorContext.ts +0 -68
  180. package/src/transpiler/logic/symbols/__tests__/AutoConstUpdater.test.ts +0 -418
  181. package/src/transpiler/logic/symbols/__tests__/CSymbolCollector.test.ts +0 -685
  182. package/src/transpiler/logic/symbols/__tests__/CppSymbolCollector.test.ts +0 -1146
  183. package/src/transpiler/logic/symbols/__tests__/SymbolCollectorContext.test.ts +0 -290
  184. package/src/transpiler/logic/symbols/__tests__/cTestHelpers.ts +0 -43
  185. package/src/transpiler/logic/symbols/__tests__/cppTestHelpers.ts +0 -40
  186. package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +0 -595
  187. package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +0 -345
  188. package/src/transpiler/logic/symbols/types/IBaseSymbol.ts +0 -27
  189. package/src/transpiler/logic/symbols/types/IBitmapSymbol.ts +0 -23
  190. package/src/transpiler/logic/symbols/types/ICollectorContext.ts +0 -19
  191. package/src/transpiler/logic/symbols/types/IConflict.ts +0 -20
  192. package/src/transpiler/logic/symbols/types/IFieldInfo.ts +0 -18
  193. package/src/transpiler/logic/symbols/types/IFunctionSymbol.ts +0 -25
  194. package/src/transpiler/logic/symbols/types/IParameterInfo.ts +0 -24
  195. package/src/transpiler/logic/symbols/types/IRegisterSymbol.ts +0 -20
  196. package/src/transpiler/logic/symbols/types/IScopeSymbol.ts +0 -19
  197. package/src/transpiler/logic/symbols/types/IStructSymbol.ts +0 -16
  198. package/src/transpiler/logic/symbols/types/IVariableSymbol.ts +0 -30
  199. package/src/transpiler/logic/symbols/types/TSymbol.ts +0 -36
  200. package/src/transpiler/logic/symbols/types/__tests__/SymbolGuards.test.ts +0 -244
  201. package/src/transpiler/logic/symbols/types/typeGuards.ts +0 -44
  202. package/src/utils/types/ESymbolKind.ts +0 -19
  203. package/src/utils/types/ISymbol.ts +0 -64
  204. /package/src/transpiler/{types → constants}/BITMAP_BACKING_TYPE.ts +0 -0
  205. /package/src/transpiler/{types → constants}/BITMAP_SIZE.ts +0 -0
@@ -75,7 +75,7 @@ class VariableDeclarationFormatter {
75
75
  * @param dimensions - Array of dimension strings (e.g., ['10', '20'])
76
76
  * @returns Formatted dimensions (e.g., '[10][20]')
77
77
  */
78
- static buildArrayDimensions(dimensions?: string[]): string {
78
+ static buildArrayDimensions(dimensions?: readonly string[]): string {
79
79
  if (!dimensions || dimensions.length === 0) {
80
80
  return "";
81
81
  }
@@ -0,0 +1,521 @@
1
+ /**
2
+ * Unit tests for ArgumentGenerator
3
+ * Issue #794: Extract Argument Generator from CodeGenerator
4
+ */
5
+
6
+ import { describe, it, expect, beforeEach } from "vitest";
7
+ import ArgumentGenerator from "../ArgumentGenerator";
8
+ import CodeGenState from "../../../../state/CodeGenState";
9
+ import IArgumentGeneratorCallbacks from "../types/IArgumentGeneratorCallbacks";
10
+
11
+ describe("ArgumentGenerator", () => {
12
+ // Mock callbacks that return predictable values
13
+ const createMockCallbacks = (
14
+ overrides: Partial<IArgumentGeneratorCallbacks> = {},
15
+ ): IArgumentGeneratorCallbacks => ({
16
+ getLvalueType: () => null,
17
+ getMemberAccessArrayStatus: () => "not-array",
18
+ needsCppMemberConversion: () => false,
19
+ isStringSubscriptAccess: () => false,
20
+ generateExpression: (ctx) => ctx.getText(),
21
+ ...overrides,
22
+ });
23
+
24
+ beforeEach(() => {
25
+ CodeGenState.reset();
26
+ });
27
+
28
+ describe("handleIdentifierArg", () => {
29
+ describe("parameters", () => {
30
+ it("returns parameter name unchanged (already pointers)", () => {
31
+ CodeGenState.currentParameters.set("cfg", {
32
+ name: "cfg",
33
+ baseType: "Config",
34
+ isArray: false,
35
+ isStruct: true,
36
+ isConst: false,
37
+ isCallback: false,
38
+ isString: false,
39
+ });
40
+
41
+ const result = ArgumentGenerator.handleIdentifierArg("cfg");
42
+ expect(result).toBe("cfg");
43
+ });
44
+ });
45
+
46
+ describe("local arrays", () => {
47
+ it("returns array name unchanged (decay to pointers)", () => {
48
+ CodeGenState.localArrays.add("buffer");
49
+
50
+ const result = ArgumentGenerator.handleIdentifierArg("buffer");
51
+ expect(result).toBe("buffer");
52
+ });
53
+ });
54
+
55
+ describe("global arrays", () => {
56
+ it("returns global array name unchanged", () => {
57
+ CodeGenState.setVariableTypeInfo("globalArr", {
58
+ baseType: "u8",
59
+ bitWidth: 8,
60
+ isArray: true,
61
+ isConst: false,
62
+ });
63
+
64
+ const result = ArgumentGenerator.handleIdentifierArg("globalArr");
65
+ expect(result).toBe("globalArr");
66
+ });
67
+
68
+ it("adds & for global strings (char arrays passed by reference)", () => {
69
+ CodeGenState.cppMode = false;
70
+ CodeGenState.setVariableTypeInfo("name", {
71
+ baseType: "char",
72
+ bitWidth: 8,
73
+ isArray: true,
74
+ isConst: false,
75
+ isString: true,
76
+ });
77
+
78
+ const result = ArgumentGenerator.handleIdentifierArg("name");
79
+ expect(result).toBe("&name");
80
+ });
81
+ });
82
+
83
+ describe("scope members", () => {
84
+ it("prefixes scope member and adds & in C mode", () => {
85
+ CodeGenState.cppMode = false;
86
+ CodeGenState.currentScope = "LED";
87
+ CodeGenState.setScopeMembers("LED", new Set(["brightness"]));
88
+
89
+ const result = ArgumentGenerator.handleIdentifierArg("brightness");
90
+ expect(result).toBe("&LED_brightness");
91
+ });
92
+
93
+ it("prefixes scope member without & in C++ mode", () => {
94
+ CodeGenState.cppMode = true;
95
+ CodeGenState.currentScope = "LED";
96
+ CodeGenState.setScopeMembers("LED", new Set(["brightness"]));
97
+
98
+ const result = ArgumentGenerator.handleIdentifierArg("brightness");
99
+ expect(result).toBe("LED_brightness");
100
+ });
101
+ });
102
+
103
+ describe("local variables", () => {
104
+ it("adds & for local variable in C mode", () => {
105
+ CodeGenState.cppMode = false;
106
+
107
+ const result = ArgumentGenerator.handleIdentifierArg("value");
108
+ expect(result).toBe("&value");
109
+ });
110
+
111
+ it("returns local variable unchanged in C++ mode", () => {
112
+ CodeGenState.cppMode = true;
113
+
114
+ const result = ArgumentGenerator.handleIdentifierArg("value");
115
+ expect(result).toBe("value");
116
+ });
117
+ });
118
+ });
119
+
120
+ describe("handleRvalueArg", () => {
121
+ it("returns expression unchanged when no target type", () => {
122
+ const callbacks = createMockCallbacks({
123
+ generateExpression: () => "42",
124
+ });
125
+
126
+ const result = ArgumentGenerator.handleRvalueArg(
127
+ null as never, // ctx not used in this path
128
+ undefined,
129
+ callbacks,
130
+ );
131
+ expect(result).toBe("42");
132
+ });
133
+
134
+ it("returns expression unchanged for void target type", () => {
135
+ const callbacks = createMockCallbacks({
136
+ generateExpression: () => "doSomething()",
137
+ });
138
+
139
+ const result = ArgumentGenerator.handleRvalueArg(
140
+ null as never,
141
+ "void",
142
+ callbacks,
143
+ );
144
+ expect(result).toBe("doSomething()");
145
+ });
146
+
147
+ it("returns expression unchanged in C++ mode (rvalues bind to const T&)", () => {
148
+ CodeGenState.cppMode = true;
149
+ const callbacks = createMockCallbacks({
150
+ generateExpression: () => "42",
151
+ });
152
+
153
+ const result = ArgumentGenerator.handleRvalueArg(
154
+ null as never,
155
+ "u8",
156
+ callbacks,
157
+ );
158
+ expect(result).toBe("42");
159
+ });
160
+
161
+ it("wraps in compound literal for C mode", () => {
162
+ CodeGenState.cppMode = false;
163
+ const callbacks = createMockCallbacks({
164
+ generateExpression: () => "42",
165
+ });
166
+
167
+ const result = ArgumentGenerator.handleRvalueArg(
168
+ null as never,
169
+ "u8",
170
+ callbacks,
171
+ );
172
+ expect(result).toBe("&(uint8_t){42}");
173
+ });
174
+
175
+ it("uses correct C type for compound literal", () => {
176
+ CodeGenState.cppMode = false;
177
+ const callbacks = createMockCallbacks({
178
+ generateExpression: () => "1000",
179
+ });
180
+
181
+ const result = ArgumentGenerator.handleRvalueArg(
182
+ null as never,
183
+ "i32",
184
+ callbacks,
185
+ );
186
+ expect(result).toBe("&(int32_t){1000}");
187
+ });
188
+ });
189
+
190
+ describe("createCppMemberConversionTemp", () => {
191
+ it("creates temp variable with static_cast in C++ mode", () => {
192
+ CodeGenState.cppMode = true;
193
+ CodeGenState.tempVarCounter = 0;
194
+ const callbacks = createMockCallbacks({
195
+ generateExpression: () => "cfg.value",
196
+ });
197
+
198
+ const result = ArgumentGenerator.createCppMemberConversionTemp(
199
+ null as never,
200
+ "u8",
201
+ callbacks,
202
+ );
203
+
204
+ expect(result).toBe("_cnx_tmp_0");
205
+ expect(CodeGenState.pendingTempDeclarations).toContain(
206
+ "uint8_t _cnx_tmp_0 = static_cast<uint8_t>(cfg.value);",
207
+ );
208
+ expect(CodeGenState.tempVarCounter).toBe(1);
209
+ });
210
+
211
+ it("increments temp counter for multiple temps", () => {
212
+ CodeGenState.cppMode = true;
213
+ CodeGenState.tempVarCounter = 5;
214
+ const callbacks = createMockCallbacks({
215
+ generateExpression: () => "x",
216
+ });
217
+
218
+ const result = ArgumentGenerator.createCppMemberConversionTemp(
219
+ null as never,
220
+ "i16",
221
+ callbacks,
222
+ );
223
+
224
+ expect(result).toBe("_cnx_tmp_5");
225
+ expect(CodeGenState.tempVarCounter).toBe(6);
226
+ });
227
+ });
228
+
229
+ describe("maybeCastStringSubscript", () => {
230
+ it("returns expr unchanged when no target type", () => {
231
+ const callbacks = createMockCallbacks({
232
+ isStringSubscriptAccess: () => true,
233
+ });
234
+
235
+ const result = ArgumentGenerator.maybeCastStringSubscript(
236
+ null as never,
237
+ "&buf[0]",
238
+ undefined,
239
+ callbacks,
240
+ );
241
+ expect(result).toBe("&buf[0]");
242
+ });
243
+
244
+ it("returns expr unchanged when not string subscript", () => {
245
+ const callbacks = createMockCallbacks({
246
+ isStringSubscriptAccess: () => false,
247
+ });
248
+
249
+ const result = ArgumentGenerator.maybeCastStringSubscript(
250
+ null as never,
251
+ "&arr[0]",
252
+ "u8",
253
+ callbacks,
254
+ );
255
+ expect(result).toBe("&arr[0]");
256
+ });
257
+
258
+ it("casts string subscript to integer pointer type in C mode", () => {
259
+ CodeGenState.cppMode = false;
260
+ const callbacks = createMockCallbacks({
261
+ isStringSubscriptAccess: () => true,
262
+ });
263
+
264
+ const result = ArgumentGenerator.maybeCastStringSubscript(
265
+ null as never,
266
+ "&buf[0]",
267
+ "u8",
268
+ callbacks,
269
+ );
270
+ expect(result).toBe("(uint8_t*)&buf[0]");
271
+ });
272
+
273
+ it("casts string subscript with reinterpret_cast in C++ mode", () => {
274
+ CodeGenState.cppMode = true;
275
+ const callbacks = createMockCallbacks({
276
+ isStringSubscriptAccess: () => true,
277
+ });
278
+
279
+ const result = ArgumentGenerator.maybeCastStringSubscript(
280
+ null as never,
281
+ "&buf[0]",
282
+ "u8",
283
+ callbacks,
284
+ );
285
+ expect(result).toBe("reinterpret_cast<uint8_t*>(&buf[0])");
286
+ });
287
+
288
+ it("does not cast for float types", () => {
289
+ CodeGenState.cppMode = false;
290
+ const callbacks = createMockCallbacks({
291
+ isStringSubscriptAccess: () => true,
292
+ });
293
+
294
+ const result = ArgumentGenerator.maybeCastStringSubscript(
295
+ null as never,
296
+ "&buf[0]",
297
+ "f32",
298
+ callbacks,
299
+ );
300
+ expect(result).toBe("&buf[0]");
301
+ });
302
+
303
+ it("does not cast for bool type", () => {
304
+ CodeGenState.cppMode = false;
305
+ const callbacks = createMockCallbacks({
306
+ isStringSubscriptAccess: () => true,
307
+ });
308
+
309
+ const result = ArgumentGenerator.maybeCastStringSubscript(
310
+ null as never,
311
+ "&buf[0]",
312
+ "bool",
313
+ callbacks,
314
+ );
315
+ expect(result).toBe("&buf[0]");
316
+ });
317
+ });
318
+
319
+ describe("handleMemberAccessArg", () => {
320
+ it("returns expression unchanged for array member (no & needed)", () => {
321
+ const callbacks = createMockCallbacks({
322
+ getMemberAccessArrayStatus: () => "array",
323
+ generateExpression: () => "result.data",
324
+ });
325
+
326
+ const result = ArgumentGenerator.handleMemberAccessArg(
327
+ null as never,
328
+ "u8",
329
+ callbacks,
330
+ );
331
+ expect(result).toBe("result.data");
332
+ });
333
+
334
+ it("creates temp for C++ conversion when needed", () => {
335
+ CodeGenState.cppMode = true;
336
+ CodeGenState.tempVarCounter = 0;
337
+ const callbacks = createMockCallbacks({
338
+ getMemberAccessArrayStatus: () => "not-array",
339
+ needsCppMemberConversion: () => true,
340
+ generateExpression: () => "cfg.enabled",
341
+ });
342
+
343
+ const result = ArgumentGenerator.handleMemberAccessArg(
344
+ null as never,
345
+ "u8",
346
+ callbacks,
347
+ );
348
+
349
+ expect(result).toBe("_cnx_tmp_0");
350
+ expect(CodeGenState.pendingTempDeclarations).toHaveLength(1);
351
+ });
352
+
353
+ it("returns null for default lvalue handling", () => {
354
+ const callbacks = createMockCallbacks({
355
+ getMemberAccessArrayStatus: () => "not-array",
356
+ needsCppMemberConversion: () => false,
357
+ });
358
+
359
+ const result = ArgumentGenerator.handleMemberAccessArg(
360
+ null as never,
361
+ "u8",
362
+ callbacks,
363
+ );
364
+ expect(result).toBeNull();
365
+ });
366
+
367
+ it("returns null when array status is unknown", () => {
368
+ const callbacks = createMockCallbacks({
369
+ getMemberAccessArrayStatus: () => "unknown",
370
+ needsCppMemberConversion: () => false,
371
+ });
372
+
373
+ const result = ArgumentGenerator.handleMemberAccessArg(
374
+ null as never,
375
+ "u8",
376
+ callbacks,
377
+ );
378
+ expect(result).toBeNull();
379
+ });
380
+ });
381
+
382
+ describe("handleLvalueArg", () => {
383
+ it("delegates to handleMemberAccessArg for member access", () => {
384
+ const callbacks = createMockCallbacks({
385
+ getMemberAccessArrayStatus: () => "array",
386
+ generateExpression: () => "result.buffer",
387
+ });
388
+
389
+ const result = ArgumentGenerator.handleLvalueArg(
390
+ null as never,
391
+ "member",
392
+ "u8",
393
+ callbacks,
394
+ );
395
+ expect(result).toBe("result.buffer");
396
+ });
397
+
398
+ it("generates expression with & for member when not array", () => {
399
+ CodeGenState.cppMode = false;
400
+ const callbacks = createMockCallbacks({
401
+ getMemberAccessArrayStatus: () => "not-array",
402
+ needsCppMemberConversion: () => false,
403
+ generateExpression: () => "obj.field",
404
+ });
405
+
406
+ const result = ArgumentGenerator.handleLvalueArg(
407
+ null as never,
408
+ "member",
409
+ "u8",
410
+ callbacks,
411
+ );
412
+ expect(result).toBe("&obj.field");
413
+ });
414
+
415
+ it("handles array access with & and string subscript cast", () => {
416
+ CodeGenState.cppMode = false;
417
+ const callbacks = createMockCallbacks({
418
+ generateExpression: () => "buf[0]",
419
+ isStringSubscriptAccess: () => true,
420
+ });
421
+
422
+ const result = ArgumentGenerator.handleLvalueArg(
423
+ null as never,
424
+ "array",
425
+ "u8",
426
+ callbacks,
427
+ );
428
+ expect(result).toBe("(uint8_t*)&buf[0]");
429
+ });
430
+
431
+ it("returns expression with & for array without string cast", () => {
432
+ CodeGenState.cppMode = false;
433
+ const callbacks = createMockCallbacks({
434
+ generateExpression: () => "arr[i]",
435
+ isStringSubscriptAccess: () => false,
436
+ });
437
+
438
+ const result = ArgumentGenerator.handleLvalueArg(
439
+ null as never,
440
+ "array",
441
+ "u8",
442
+ callbacks,
443
+ );
444
+ expect(result).toBe("&arr[i]");
445
+ });
446
+ });
447
+
448
+ describe("generateArg (main dispatcher)", () => {
449
+ it("handles simple identifier", () => {
450
+ CodeGenState.cppMode = false;
451
+ const callbacks = createMockCallbacks({
452
+ getLvalueType: () => null,
453
+ });
454
+
455
+ const result = ArgumentGenerator.generateArg(
456
+ null as never,
457
+ "value",
458
+ "u8",
459
+ callbacks,
460
+ );
461
+ expect(result).toBe("&value");
462
+ });
463
+
464
+ it("handles parameter identifier", () => {
465
+ CodeGenState.currentParameters.set("cfg", {
466
+ name: "cfg",
467
+ baseType: "Config",
468
+ isArray: false,
469
+ isStruct: true,
470
+ isConst: false,
471
+ isCallback: false,
472
+ isString: false,
473
+ });
474
+ const callbacks = createMockCallbacks({
475
+ getLvalueType: () => null,
476
+ });
477
+
478
+ const result = ArgumentGenerator.generateArg(
479
+ null as never,
480
+ "cfg",
481
+ "Config",
482
+ callbacks,
483
+ );
484
+ expect(result).toBe("cfg");
485
+ });
486
+
487
+ it("handles lvalue expressions", () => {
488
+ CodeGenState.cppMode = false;
489
+ const callbacks = createMockCallbacks({
490
+ getLvalueType: () => "member",
491
+ getMemberAccessArrayStatus: () => "not-array",
492
+ needsCppMemberConversion: () => false,
493
+ generateExpression: () => "obj.field",
494
+ });
495
+
496
+ const result = ArgumentGenerator.generateArg(
497
+ null as never,
498
+ null, // no simple identifier
499
+ "u8",
500
+ callbacks,
501
+ );
502
+ expect(result).toBe("&obj.field");
503
+ });
504
+
505
+ it("handles rvalue expressions", () => {
506
+ CodeGenState.cppMode = false;
507
+ const callbacks = createMockCallbacks({
508
+ getLvalueType: () => null,
509
+ generateExpression: () => "42",
510
+ });
511
+
512
+ const result = ArgumentGenerator.generateArg(
513
+ null as never,
514
+ null, // no simple identifier
515
+ "u8",
516
+ callbacks,
517
+ );
518
+ expect(result).toBe("&(uint8_t){42}");
519
+ });
520
+ });
521
+ });
@@ -1,6 +1,5 @@
1
1
  import { describe, it, expect } from "vitest";
2
2
  import CppConstructorHelper from "../CppConstructorHelper.js";
3
- import ESymbolKind from "../../../../../utils/types/ESymbolKind.js";
4
3
 
5
4
  describe("CppConstructorHelper", () => {
6
5
  describe("toQualifiedName", () => {
@@ -87,7 +86,7 @@ describe("CppConstructorHelper", () => {
87
86
 
88
87
  it("returns false when symbol is not a function", () => {
89
88
  const mockSymbolTable = {
90
- getSymbol: () => ({ kind: ESymbolKind.Variable }),
89
+ getSymbol: () => ({ kind: "variable" as const }),
91
90
  };
92
91
  expect(
93
92
  CppConstructorHelper.hasConstructor("MyClass", mockSymbolTable),
@@ -98,7 +97,7 @@ describe("CppConstructorHelper", () => {
98
97
  const mockSymbolTable = {
99
98
  getSymbol: (name: string) => {
100
99
  if (name === "MyClass::MyClass") {
101
- return { kind: ESymbolKind.Function };
100
+ return { kind: "function" as const };
102
101
  }
103
102
  return undefined;
104
103
  },
@@ -112,7 +111,7 @@ describe("CppConstructorHelper", () => {
112
111
  const mockSymbolTable = {
113
112
  getSymbol: (name: string) => {
114
113
  if (name === "TestNS::MyClass::MyClass") {
115
- return { kind: ESymbolKind.Function };
114
+ return { kind: "function" as const };
116
115
  }
117
116
  return undefined;
118
117
  },
@@ -126,7 +125,7 @@ describe("CppConstructorHelper", () => {
126
125
  const mockSymbolTable = {
127
126
  getSymbol: (name: string) => {
128
127
  if (name === "TestNS::MyClass::MyClass") {
129
- return { kind: ESymbolKind.Function };
128
+ return { kind: "function" as const };
130
129
  }
131
130
  return undefined;
132
131
  },