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
@@ -1,685 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import parseC from "./cTestHelpers";
3
- import CSymbolCollector from "../CSymbolCollector";
4
- import SymbolTable from "../SymbolTable";
5
- import ESymbolKind from "../../../../utils/types/ESymbolKind";
6
- import ESourceLanguage from "../../../../utils/types/ESourceLanguage";
7
-
8
- describe("CSymbolCollector - Basic Functionality", () => {
9
- it("creates collector with source file", () => {
10
- const collector = new CSymbolCollector("test.h");
11
- expect(collector).toBeDefined();
12
- });
13
-
14
- it("returns empty array for empty translation unit", () => {
15
- const code = "";
16
- const tree = parseC(code);
17
- const collector = new CSymbolCollector("test.h");
18
- const symbols = collector.collect(tree);
19
- expect(symbols).toEqual([]);
20
- });
21
-
22
- it("tracks source file correctly", () => {
23
- const code = `void foo();`;
24
- const tree = parseC(code);
25
- const collector = new CSymbolCollector("myfile.h");
26
- const symbols = collector.collect(tree);
27
- expect(symbols[0].sourceFile).toBe("myfile.h");
28
- });
29
-
30
- it("tracks source line numbers", () => {
31
- const code = `
32
-
33
- void foo();`;
34
- const tree = parseC(code);
35
- const collector = new CSymbolCollector("test.h");
36
- const symbols = collector.collect(tree);
37
- expect(symbols[0].sourceLine).toBe(3);
38
- });
39
-
40
- it("sets source language to C", () => {
41
- const code = `void foo();`;
42
- const tree = parseC(code);
43
- const collector = new CSymbolCollector("test.h");
44
- const symbols = collector.collect(tree);
45
- expect(symbols[0].sourceLanguage).toBe(ESourceLanguage.C);
46
- });
47
-
48
- it("returns empty warnings initially", () => {
49
- const collector = new CSymbolCollector("test.h");
50
- expect(collector.getWarnings()).toEqual([]);
51
- });
52
- });
53
-
54
- describe("CSymbolCollector - Function Definitions", () => {
55
- it("collects function definition", () => {
56
- const code = `void foo() { }`;
57
- const tree = parseC(code);
58
- const collector = new CSymbolCollector("test.h");
59
- const symbols = collector.collect(tree);
60
-
61
- expect(symbols).toHaveLength(1);
62
- expect(symbols[0].name).toBe("foo");
63
- expect(symbols[0].kind).toBe(ESymbolKind.Function);
64
- expect(symbols[0].type).toBe("void");
65
- expect(symbols[0].isExported).toBe(true);
66
- expect(symbols[0].isDeclaration).toBe(false);
67
- });
68
-
69
- it("collects function with return type", () => {
70
- const code = `int getCount() { return 0; }`;
71
- const tree = parseC(code);
72
- const collector = new CSymbolCollector("test.h");
73
- const symbols = collector.collect(tree);
74
-
75
- expect(symbols[0].type).toBe("int");
76
- });
77
-
78
- it("collects function with complex return type", () => {
79
- const code = `unsigned long getValue() { return 0; }`;
80
- const tree = parseC(code);
81
- const collector = new CSymbolCollector("test.h");
82
- const symbols = collector.collect(tree);
83
-
84
- // Type parts are space-separated
85
- expect(symbols[0].type).toBe("unsigned long");
86
- });
87
-
88
- it("defaults to int when no return type specified", () => {
89
- // Old C style - no return type means int
90
- const code = `foo() { }`;
91
- const tree = parseC(code);
92
- const collector = new CSymbolCollector("test.h");
93
- const symbols = collector.collect(tree);
94
-
95
- expect(symbols[0].type).toBe("int");
96
- });
97
-
98
- it("collects multiple function definitions", () => {
99
- const code = `
100
- void init() { }
101
- int process() { return 0; }
102
- void cleanup() { }
103
- `;
104
- const tree = parseC(code);
105
- const collector = new CSymbolCollector("test.h");
106
- const symbols = collector.collect(tree);
107
-
108
- expect(symbols).toHaveLength(3);
109
- expect(symbols.map((s) => s.name)).toEqual(["init", "process", "cleanup"]);
110
- });
111
- });
112
-
113
- describe("CSymbolCollector - Function Prototypes", () => {
114
- it("collects function prototype", () => {
115
- const code = `void bar();`;
116
- const tree = parseC(code);
117
- const collector = new CSymbolCollector("test.h");
118
- const symbols = collector.collect(tree);
119
-
120
- expect(symbols).toHaveLength(1);
121
- expect(symbols[0].name).toBe("bar");
122
- expect(symbols[0].kind).toBe(ESymbolKind.Function);
123
- expect(symbols[0].isDeclaration).toBe(true);
124
- expect(symbols[0].isExported).toBe(true);
125
- });
126
-
127
- it("collects extern function prototype", () => {
128
- const code = `extern void externalFunc();`;
129
- const tree = parseC(code);
130
- const collector = new CSymbolCollector("test.h");
131
- const symbols = collector.collect(tree);
132
-
133
- expect(symbols[0].name).toBe("externalFunc");
134
- expect(symbols[0].isExported).toBe(false);
135
- expect(symbols[0].isDeclaration).toBe(true);
136
- });
137
-
138
- it("collects function prototype with parameters", () => {
139
- const code = `int add(int a, int b);`;
140
- const tree = parseC(code);
141
- const collector = new CSymbolCollector("test.h");
142
- const symbols = collector.collect(tree);
143
-
144
- expect(symbols[0].name).toBe("add");
145
- expect(symbols[0].type).toBe("int");
146
- });
147
- });
148
-
149
- describe("CSymbolCollector - Variable Declarations", () => {
150
- it("collects global variable", () => {
151
- const code = `int counter;`;
152
- const tree = parseC(code);
153
- const collector = new CSymbolCollector("test.h");
154
- const symbols = collector.collect(tree);
155
-
156
- expect(symbols).toHaveLength(1);
157
- expect(symbols[0].name).toBe("counter");
158
- expect(symbols[0].kind).toBe(ESymbolKind.Variable);
159
- expect(symbols[0].type).toBe("int");
160
- expect(symbols[0].isExported).toBe(true);
161
- });
162
-
163
- it("collects extern variable", () => {
164
- const code = `extern int globalValue;`;
165
- const tree = parseC(code);
166
- const collector = new CSymbolCollector("test.h");
167
- const symbols = collector.collect(tree);
168
-
169
- expect(symbols[0].name).toBe("globalValue");
170
- expect(symbols[0].kind).toBe(ESymbolKind.Variable);
171
- expect(symbols[0].isExported).toBe(false);
172
- expect(symbols[0].isDeclaration).toBe(true);
173
- });
174
-
175
- it("collects multiple variables in one declaration", () => {
176
- const code = `int x, y, z;`;
177
- const tree = parseC(code);
178
- const collector = new CSymbolCollector("test.h");
179
- const symbols = collector.collect(tree);
180
-
181
- expect(symbols).toHaveLength(3);
182
- expect(symbols.map((s) => s.name)).toEqual(["x", "y", "z"]);
183
- symbols.forEach((s) => {
184
- expect(s.kind).toBe(ESymbolKind.Variable);
185
- expect(s.type).toBe("int");
186
- });
187
- });
188
- });
189
-
190
- describe("CSymbolCollector - Typedefs", () => {
191
- it("collects simple typedef", () => {
192
- const code = `typedef int MyInt;`;
193
- const tree = parseC(code);
194
- const collector = new CSymbolCollector("test.h");
195
- const symbols = collector.collect(tree);
196
-
197
- expect(symbols).toHaveLength(1);
198
- expect(symbols[0].name).toBe("MyInt");
199
- expect(symbols[0].kind).toBe(ESymbolKind.Type);
200
- expect(symbols[0].type).toBe("int");
201
- expect(symbols[0].isExported).toBe(true);
202
- });
203
-
204
- it("collects typedef with unsigned type", () => {
205
- const code = `typedef unsigned char uint8_t;`;
206
- const tree = parseC(code);
207
- const collector = new CSymbolCollector("test.h");
208
- const symbols = collector.collect(tree);
209
-
210
- expect(symbols[0].name).toBe("uint8_t");
211
- expect(symbols[0].kind).toBe(ESymbolKind.Type);
212
- });
213
-
214
- it("collects multiple typedefs", () => {
215
- const code = `
216
- typedef int Int32;
217
- typedef unsigned int UInt32;
218
- `;
219
- const tree = parseC(code);
220
- const collector = new CSymbolCollector("test.h");
221
- const symbols = collector.collect(tree);
222
-
223
- expect(symbols).toHaveLength(2);
224
- expect(symbols[0].name).toBe("Int32");
225
- expect(symbols[1].name).toBe("UInt32");
226
- });
227
- });
228
-
229
- describe("CSymbolCollector - Structs", () => {
230
- it("collects named struct", () => {
231
- const code = `struct Point { int x; int y; };`;
232
- const tree = parseC(code);
233
- const collector = new CSymbolCollector("test.h");
234
- const symbols = collector.collect(tree);
235
-
236
- const structSym = symbols.find((s) => s.name === "Point");
237
- expect(structSym).toBeDefined();
238
- expect(structSym?.kind).toBe(ESymbolKind.Struct);
239
- expect(structSym?.type).toBe("struct");
240
- expect(structSym?.isExported).toBe(true);
241
- });
242
-
243
- it("marks named struct as needing struct keyword", () => {
244
- const code = `struct Point { int x; int y; };`;
245
- const tree = parseC(code);
246
- const symbolTable = new SymbolTable();
247
- const collector = new CSymbolCollector("test.h", symbolTable);
248
- collector.collect(tree);
249
-
250
- expect(symbolTable.checkNeedsStructKeyword("Point")).toBe(true);
251
- });
252
-
253
- it("collects typedef struct (anonymous)", () => {
254
- const code = `typedef struct { int x; int y; } Point;`;
255
- const tree = parseC(code);
256
- const collector = new CSymbolCollector("test.h");
257
- const symbols = collector.collect(tree);
258
-
259
- // Anonymous typedef struct creates a struct symbol with the typedef name
260
- const structSym = symbols.find(
261
- (s) => s.name === "Point" && s.kind === ESymbolKind.Struct,
262
- );
263
- expect(structSym).toBeDefined();
264
- });
265
-
266
- it("does not mark typedef struct as needing struct keyword", () => {
267
- const code = `typedef struct { int x; int y; } Point;`;
268
- const tree = parseC(code);
269
- const symbolTable = new SymbolTable();
270
- const collector = new CSymbolCollector("test.h", symbolTable);
271
- collector.collect(tree);
272
-
273
- expect(symbolTable.checkNeedsStructKeyword("Point")).toBe(false);
274
- });
275
-
276
- it("collects typedef struct with tag name", () => {
277
- const code = `typedef struct _Point { int x; int y; } Point;`;
278
- const tree = parseC(code);
279
- const collector = new CSymbolCollector("test.h");
280
- const symbols = collector.collect(tree);
281
-
282
- // Should have struct with tag name
283
- const structSym = symbols.find(
284
- (s) => s.name === "_Point" && s.kind === ESymbolKind.Struct,
285
- );
286
- expect(structSym).toBeDefined();
287
- });
288
-
289
- it("collects union", () => {
290
- const code = `union Data { int i; float f; };`;
291
- const tree = parseC(code);
292
- const collector = new CSymbolCollector("test.h");
293
- const symbols = collector.collect(tree);
294
-
295
- const unionSym = symbols.find((s) => s.name === "Data");
296
- expect(unionSym).toBeDefined();
297
- expect(unionSym?.kind).toBe(ESymbolKind.Struct);
298
- expect(unionSym?.type).toBe("union");
299
- });
300
-
301
- it("skips anonymous struct without typedef", () => {
302
- const code = `struct { int x; } point;`;
303
- const tree = parseC(code);
304
- const collector = new CSymbolCollector("test.h");
305
- const symbols = collector.collect(tree);
306
-
307
- // Should only have the variable, no struct symbol
308
- expect(symbols).toHaveLength(1);
309
- expect(symbols[0].name).toBe("point");
310
- expect(symbols[0].kind).toBe(ESymbolKind.Variable);
311
- });
312
- });
313
-
314
- describe("CSymbolCollector - Struct Fields", () => {
315
- it("collects struct fields into symbol table", () => {
316
- const code = `struct Point { int x; int y; };`;
317
- const tree = parseC(code);
318
- const symbolTable = new SymbolTable();
319
- const collector = new CSymbolCollector("test.h", symbolTable);
320
- collector.collect(tree);
321
-
322
- const fieldsMap = symbolTable.getStructFields("Point");
323
- expect(fieldsMap).toBeDefined();
324
- expect(fieldsMap?.size).toBe(2);
325
- expect(fieldsMap?.get("x")?.type).toBe("int");
326
- expect(fieldsMap?.get("y")?.type).toBe("int");
327
- });
328
-
329
- it("collects struct fields with different types", () => {
330
- const code = `struct Person { char name[32]; int age; float height; };`;
331
- const tree = parseC(code);
332
- const symbolTable = new SymbolTable();
333
- const collector = new CSymbolCollector("test.h", symbolTable);
334
- collector.collect(tree);
335
-
336
- const fieldsMap = symbolTable.getStructFields("Person");
337
- expect(fieldsMap).toBeDefined();
338
- expect(fieldsMap?.size).toBe(3);
339
- expect(fieldsMap?.get("name")?.type).toBe("char");
340
- expect(fieldsMap?.get("age")?.type).toBe("int");
341
- expect(fieldsMap?.get("height")?.type).toBe("float");
342
- });
343
-
344
- it("collects array field dimensions", () => {
345
- const code = `struct Buffer { char data[256]; };`;
346
- const tree = parseC(code);
347
- const symbolTable = new SymbolTable();
348
- const collector = new CSymbolCollector("test.h", symbolTable);
349
- collector.collect(tree);
350
-
351
- const fieldsMap = symbolTable.getStructFields("Buffer");
352
- expect(fieldsMap?.get("data")?.arrayDimensions).toEqual([256]);
353
- });
354
-
355
- it("collects multi-dimensional array fields", () => {
356
- const code = `struct Matrix { int data[3][3]; };`;
357
- const tree = parseC(code);
358
- const symbolTable = new SymbolTable();
359
- const collector = new CSymbolCollector("test.h", symbolTable);
360
- collector.collect(tree);
361
-
362
- const fieldsMap = symbolTable.getStructFields("Matrix");
363
- expect(fieldsMap?.get("data")?.arrayDimensions).toEqual([3, 3]);
364
- });
365
-
366
- it("collects nested struct field type correctly", () => {
367
- const code = `
368
- struct Inner { int value; };
369
- struct Outer { struct Inner inner; };
370
- `;
371
- const tree = parseC(code);
372
- const symbolTable = new SymbolTable();
373
- const collector = new CSymbolCollector("test.h", symbolTable);
374
- collector.collect(tree);
375
-
376
- const fieldsMap = symbolTable.getStructFields("Outer");
377
- expect(fieldsMap?.get("inner")?.type).toBe("Inner");
378
- });
379
-
380
- it("warns about reserved field names", () => {
381
- const code = `struct Test { int length; };`;
382
- const tree = parseC(code);
383
- const symbolTable = new SymbolTable();
384
- const collector = new CSymbolCollector("test.h", symbolTable);
385
- collector.collect(tree);
386
-
387
- const warnings = collector.getWarnings();
388
- expect(warnings.length).toBeGreaterThan(0);
389
- expect(warnings[0]).toContain("length");
390
- expect(warnings[0]).toContain("conflicts with C-Next");
391
- });
392
- });
393
-
394
- describe("CSymbolCollector - Enums", () => {
395
- it("collects named enum", () => {
396
- const code = `enum Color { RED, GREEN, BLUE };`;
397
- const tree = parseC(code);
398
- const collector = new CSymbolCollector("test.h");
399
- const symbols = collector.collect(tree);
400
-
401
- const enumSym = symbols.find(
402
- (s) => s.name === "Color" && s.kind === ESymbolKind.Enum,
403
- );
404
- expect(enumSym).toBeDefined();
405
- expect(enumSym?.isExported).toBe(true);
406
- });
407
-
408
- it("collects enum members", () => {
409
- const code = `enum Color { RED, GREEN, BLUE };`;
410
- const tree = parseC(code);
411
- const collector = new CSymbolCollector("test.h");
412
- const symbols = collector.collect(tree);
413
-
414
- const members = symbols.filter((s) => s.kind === ESymbolKind.EnumMember);
415
- expect(members).toHaveLength(3);
416
- expect(members.map((m) => m.name)).toEqual(["RED", "GREEN", "BLUE"]);
417
- members.forEach((m) => {
418
- expect(m.parent).toBe("Color");
419
- expect(m.isExported).toBe(true);
420
- });
421
- });
422
-
423
- it("collects enum member line numbers", () => {
424
- const code = `enum Status {
425
- OK,
426
- ERROR,
427
- PENDING
428
- };`;
429
- const tree = parseC(code);
430
- const collector = new CSymbolCollector("test.h");
431
- const symbols = collector.collect(tree);
432
-
433
- const members = symbols.filter((s) => s.kind === ESymbolKind.EnumMember);
434
- expect(members[0].sourceLine).toBe(2);
435
- expect(members[1].sourceLine).toBe(3);
436
- expect(members[2].sourceLine).toBe(4);
437
- });
438
-
439
- it("skips anonymous enum", () => {
440
- const code = `enum { OPTION_A, OPTION_B };`;
441
- const tree = parseC(code);
442
- const collector = new CSymbolCollector("test.h");
443
- const symbols = collector.collect(tree);
444
-
445
- // Anonymous enums don't create an Enum symbol
446
- const enumSym = symbols.find((s) => s.kind === ESymbolKind.Enum);
447
- expect(enumSym).toBeUndefined();
448
- });
449
- });
450
-
451
- describe("CSymbolCollector - Complex Declarators", () => {
452
- it("handles array variable declaration", () => {
453
- const code = `int values[10];`;
454
- const tree = parseC(code);
455
- const collector = new CSymbolCollector("test.h");
456
- const symbols = collector.collect(tree);
457
-
458
- expect(symbols[0].name).toBe("values");
459
- expect(symbols[0].kind).toBe(ESymbolKind.Variable);
460
- });
461
-
462
- it("handles function pointer typedef", () => {
463
- const code = `typedef void (*Callback)(int);`;
464
- const tree = parseC(code);
465
- const collector = new CSymbolCollector("test.h");
466
- const symbols = collector.collect(tree);
467
-
468
- expect(symbols[0].name).toBe("Callback");
469
- expect(symbols[0].kind).toBe(ESymbolKind.Type);
470
- });
471
-
472
- it("handles pointer variable", () => {
473
- const code = `int *ptr;`;
474
- const tree = parseC(code);
475
- const collector = new CSymbolCollector("test.h");
476
- const symbols = collector.collect(tree);
477
-
478
- expect(symbols[0].name).toBe("ptr");
479
- expect(symbols[0].kind).toBe(ESymbolKind.Variable);
480
- });
481
-
482
- it("handles array field declarator (Issue #355)", () => {
483
- // Issue #355: extractDirectDeclaratorName must handle recursive directDeclarator for arrays
484
- const code = `struct Test { char buf[8]; };`;
485
- const tree = parseC(code);
486
- const symbolTable = new SymbolTable();
487
- const collector = new CSymbolCollector("test.h", symbolTable);
488
- collector.collect(tree);
489
-
490
- const fieldsMap = symbolTable.getStructFields("Test");
491
- expect(fieldsMap?.get("buf")).toBeDefined();
492
- expect(fieldsMap?.get("buf")?.arrayDimensions).toEqual([8]);
493
- });
494
-
495
- it("handles multi-dimensional array field declarator", () => {
496
- const code = `struct Matrix { int data[4][4]; };`;
497
- const tree = parseC(code);
498
- const symbolTable = new SymbolTable();
499
- const collector = new CSymbolCollector("test.h", symbolTable);
500
- collector.collect(tree);
501
-
502
- const fieldsMap = symbolTable.getStructFields("Matrix");
503
- expect(fieldsMap?.get("data")).toBeDefined();
504
- expect(fieldsMap?.get("data")?.arrayDimensions).toEqual([4, 4]);
505
- });
506
- });
507
-
508
- describe("CSymbolCollector - Edge Cases", () => {
509
- it("handles struct with single field", () => {
510
- // Note: C doesn't allow truly empty structs, so we test with minimal field
511
- const code = `struct Minimal { int x; };`;
512
- const tree = parseC(code);
513
- const symbolTable = new SymbolTable();
514
- const collector = new CSymbolCollector("test.h", symbolTable);
515
- const symbols = collector.collect(tree);
516
-
517
- expect(symbols.find((s) => s.name === "Minimal")).toBeDefined();
518
- expect(symbolTable.getStructFields("Minimal")?.size).toBe(1);
519
- });
520
-
521
- it("handles struct with type qualifiers", () => {
522
- const code = `struct Test { const int value; };`;
523
- const tree = parseC(code);
524
- const symbolTable = new SymbolTable();
525
- const collector = new CSymbolCollector("test.h", symbolTable);
526
- collector.collect(tree);
527
-
528
- const fieldsMap = symbolTable.getStructFields("Test");
529
- expect(fieldsMap?.get("value")).toBeDefined();
530
- });
531
-
532
- it("resets symbols between collect calls", () => {
533
- const collector = new CSymbolCollector("test.h");
534
-
535
- const code1 = `void foo();`;
536
- const tree1 = parseC(code1);
537
- const symbols1 = collector.collect(tree1);
538
- expect(symbols1).toHaveLength(1);
539
-
540
- const code2 = `void bar();`;
541
- const tree2 = parseC(code2);
542
- const symbols2 = collector.collect(tree2);
543
- expect(symbols2).toHaveLength(1);
544
- expect(symbols2[0].name).toBe("bar");
545
- });
546
-
547
- it("handles declaration without init declarator list", () => {
548
- // Just a struct declaration without variable
549
- const code = `struct Point { int x; };`;
550
- const tree = parseC(code);
551
- const collector = new CSymbolCollector("test.h");
552
- const symbols = collector.collect(tree);
553
-
554
- expect(symbols).toHaveLength(1);
555
- expect(symbols[0].kind).toBe(ESymbolKind.Struct);
556
- });
557
-
558
- it("handles static storage class", () => {
559
- const code = `static int privateVar;`;
560
- const tree = parseC(code);
561
- const collector = new CSymbolCollector("test.h");
562
- const symbols = collector.collect(tree);
563
-
564
- // Static variables are still collected
565
- expect(symbols[0].name).toBe("privateVar");
566
- });
567
-
568
- it("handles const qualifier", () => {
569
- const code = `const int MAX_VALUE = 100;`;
570
- const tree = parseC(code);
571
- const collector = new CSymbolCollector("test.h");
572
- const symbols = collector.collect(tree);
573
-
574
- expect(symbols[0].name).toBe("MAX_VALUE");
575
- expect(symbols[0].kind).toBe(ESymbolKind.Variable);
576
- });
577
-
578
- it("handles mixed declarations", () => {
579
- const code = `
580
- typedef int Int;
581
- struct Point { int x; int y; };
582
- enum Status { OK, ERROR };
583
- void init();
584
- extern int counter;
585
- `;
586
- const tree = parseC(code);
587
- const collector = new CSymbolCollector("test.h");
588
- const symbols = collector.collect(tree);
589
-
590
- const typedef = symbols.find((s) => s.name === "Int");
591
- const struct = symbols.find((s) => s.name === "Point");
592
- const enumSym = symbols.find(
593
- (s) => s.name === "Status" && s.kind === ESymbolKind.Enum,
594
- );
595
- const func = symbols.find((s) => s.name === "init");
596
- const variable = symbols.find((s) => s.name === "counter");
597
-
598
- expect(typedef?.kind).toBe(ESymbolKind.Type);
599
- expect(struct?.kind).toBe(ESymbolKind.Struct);
600
- expect(enumSym?.kind).toBe(ESymbolKind.Enum);
601
- expect(func?.kind).toBe(ESymbolKind.Function);
602
- expect(variable?.kind).toBe(ESymbolKind.Variable);
603
- });
604
- });
605
-
606
- describe("CSymbolCollector - Additional Edge Cases", () => {
607
- it("does not duplicate named enum as variable", () => {
608
- // When we have "enum Status { OK };" - Status should only be an Enum, not also a Variable
609
- const code = `enum Status { OK, ERROR };`;
610
- const tree = parseC(code);
611
- const collector = new CSymbolCollector("test.h");
612
- const symbols = collector.collect(tree);
613
-
614
- const enumSymbols = symbols.filter((s) => s.name === "Status");
615
- expect(enumSymbols).toHaveLength(1);
616
- expect(enumSymbols[0].kind).toBe(ESymbolKind.Enum);
617
- });
618
-
619
- it("handles typedef struct forward declaration pattern", () => {
620
- // Common C pattern: typedef struct Point Point; followed by struct Point { ... };
621
- const code = `
622
- struct Point;
623
- typedef struct Point Point;
624
- struct Point { int x; int y; };
625
- `;
626
- const tree = parseC(code);
627
- const collector = new CSymbolCollector("test.h");
628
- const symbols = collector.collect(tree);
629
-
630
- // Should have struct Point symbols and typedef Point
631
- const pointSymbols = symbols.filter((s) => s.name === "Point");
632
- // 4 symbols total:
633
- // - Struct from forward declaration (struct Point;)
634
- // - Struct from typedef's struct specifier (typedef struct Point ...)
635
- // - Type from typedef (... Point;)
636
- // - Struct from definition (struct Point { ... })
637
- expect(pointSymbols.length).toBe(4);
638
-
639
- const structSymbol = pointSymbols.find(
640
- (s) => s.kind === ESymbolKind.Struct,
641
- );
642
- const typeSymbol = pointSymbols.find((s) => s.kind === ESymbolKind.Type);
643
- expect(structSymbol).toBeDefined();
644
- expect(typeSymbol).toBeDefined();
645
- });
646
-
647
- it("handles struct field with anonymous struct type", () => {
648
- const code = `struct Outer { struct { int x; } inner; };`;
649
- const tree = parseC(code);
650
- const symbolTable = new SymbolTable();
651
- const collector = new CSymbolCollector("test.h", symbolTable);
652
- collector.collect(tree);
653
-
654
- const fieldsMap = symbolTable.getStructFields("Outer");
655
- expect(fieldsMap?.get("inner")).toBeDefined();
656
- });
657
-
658
- it("handles function returning pointer", () => {
659
- const code = `int* getPtr();`;
660
- const tree = parseC(code);
661
- const collector = new CSymbolCollector("test.h");
662
- const symbols = collector.collect(tree);
663
-
664
- expect(symbols[0].name).toBe("getPtr");
665
- expect(symbols[0].kind).toBe(ESymbolKind.Function);
666
- });
667
- });
668
-
669
- describe("CSymbolCollector - Without SymbolTable", () => {
670
- it("still collects symbols without symbolTable", () => {
671
- const code = `struct Point { int x; int y; };`;
672
- const tree = parseC(code);
673
- const collector = new CSymbolCollector("test.h"); // No symbolTable
674
- const symbols = collector.collect(tree);
675
-
676
- expect(symbols.find((s) => s.name === "Point")).toBeDefined();
677
- });
678
-
679
- it("does not crash when collecting struct fields without symbolTable", () => {
680
- const code = `struct Point { int x; int y; };`;
681
- const tree = parseC(code);
682
- const collector = new CSymbolCollector("test.h"); // No symbolTable
683
- expect(() => collector.collect(tree)).not.toThrow();
684
- });
685
- });