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,1146 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import parseCpp from "./cppTestHelpers";
3
- import CppSymbolCollector from "../CppSymbolCollector";
4
- import SymbolTable from "../SymbolTable";
5
- import ESymbolKind from "../../../../utils/types/ESymbolKind";
6
- import ESourceLanguage from "../../../../utils/types/ESourceLanguage";
7
-
8
- describe("CppSymbolCollector - Basic Functionality", () => {
9
- it("creates collector with source file", () => {
10
- const collector = new CppSymbolCollector("test.hpp");
11
- expect(collector).toBeDefined();
12
- });
13
-
14
- it("returns empty array for empty translation unit", () => {
15
- const code = "";
16
- const tree = parseCpp(code);
17
- const collector = new CppSymbolCollector("test.hpp");
18
- const symbols = collector.collect(tree);
19
- expect(symbols).toEqual([]);
20
- });
21
-
22
- it("returns empty array for null tree context", () => {
23
- const collector = new CppSymbolCollector("test.hpp");
24
- const symbols = collector.collect(null as any);
25
- expect(symbols).toEqual([]);
26
- });
27
-
28
- it("tracks source file correctly", () => {
29
- const code = `void foo();`;
30
- const tree = parseCpp(code);
31
- const collector = new CppSymbolCollector("myfile.hpp");
32
- const symbols = collector.collect(tree);
33
- expect(symbols[0].sourceFile).toBe("myfile.hpp");
34
- });
35
-
36
- it("tracks source line numbers", () => {
37
- const code = `
38
-
39
- void foo();`;
40
- const tree = parseCpp(code);
41
- const collector = new CppSymbolCollector("test.hpp");
42
- const symbols = collector.collect(tree);
43
- expect(symbols[0].sourceLine).toBe(3);
44
- });
45
- });
46
-
47
- describe("CppSymbolCollector - Namespace Handling", () => {
48
- it("collects simple namespace", () => {
49
- const code = `namespace hw { }`;
50
- const tree = parseCpp(code);
51
- const collector = new CppSymbolCollector("test.hpp");
52
- const symbols = collector.collect(tree);
53
-
54
- const ns = symbols.find((s) => s.name === "hw");
55
- expect(ns?.kind).toBe(ESymbolKind.Namespace);
56
- expect(ns?.sourceLanguage).toBe(ESourceLanguage.Cpp);
57
- expect(ns?.isExported).toBe(true);
58
- });
59
-
60
- it("collects namespace with function", () => {
61
- const code = `
62
- namespace hw {
63
- void init();
64
- }
65
- `;
66
- const tree = parseCpp(code);
67
- const collector = new CppSymbolCollector("test.hpp");
68
- const symbols = collector.collect(tree);
69
-
70
- expect(symbols).toHaveLength(2);
71
- const func = symbols.find((s) => s.name === "hw::init");
72
- expect(func?.kind).toBe(ESymbolKind.Function);
73
- expect(func?.parent).toBe("hw");
74
- });
75
-
76
- it("handles nested namespaces", () => {
77
- const code = `
78
- namespace Outer {
79
- namespace Inner {
80
- void foo();
81
- }
82
- }
83
- `;
84
- const tree = parseCpp(code);
85
- const collector = new CppSymbolCollector("test.hpp");
86
- const symbols = collector.collect(tree);
87
-
88
- const outerNs = symbols.find((s) => s.name === "Outer");
89
- const innerNs = symbols.find((s) => s.name === "Inner");
90
- const func = symbols.find((s) => s.name === "Outer::Inner::foo");
91
-
92
- expect(outerNs).toBeDefined();
93
- expect(innerNs).toBeDefined();
94
- expect(func?.parent).toBe("Outer::Inner");
95
- });
96
-
97
- it("handles triple-nested namespaces", () => {
98
- const code = `
99
- namespace A {
100
- namespace B {
101
- namespace C {
102
- int value;
103
- }
104
- }
105
- }
106
- `;
107
- const tree = parseCpp(code);
108
- const collector = new CppSymbolCollector("test.hpp");
109
- const symbols = collector.collect(tree);
110
-
111
- const varSymbol = symbols.find((s) => s.name === "A::B::C::value");
112
- expect(varSymbol?.kind).toBe(ESymbolKind.Variable);
113
- expect(varSymbol?.parent).toBe("A::B::C");
114
- });
115
-
116
- it("handles reopened namespaces", () => {
117
- const code = `
118
- namespace hw {
119
- void init();
120
- }
121
- namespace hw {
122
- void shutdown();
123
- }
124
- `;
125
- const tree = parseCpp(code);
126
- const collector = new CppSymbolCollector("test.hpp");
127
- const symbols = collector.collect(tree);
128
-
129
- const init = symbols.find((s) => s.name === "hw::init");
130
- const shutdown = symbols.find((s) => s.name === "hw::shutdown");
131
- expect(init).toBeDefined();
132
- expect(shutdown).toBeDefined();
133
- });
134
-
135
- it("handles anonymous namespace", () => {
136
- const code = `
137
- namespace {
138
- void helper();
139
- }
140
- `;
141
- const tree = parseCpp(code);
142
- const collector = new CppSymbolCollector("test.hpp");
143
- const symbols = collector.collect(tree);
144
-
145
- // Anonymous namespace should NOT create a namespace symbol
146
- const ns = symbols.find((s) => s.kind === ESymbolKind.Namespace);
147
- expect(ns).toBeUndefined();
148
- });
149
- });
150
-
151
- describe("CppSymbolCollector - Function Definitions", () => {
152
- it("collects simple function with return type", () => {
153
- const code = `int add(int a, int b);`;
154
- const tree = parseCpp(code);
155
- const collector = new CppSymbolCollector("test.hpp");
156
- const symbols = collector.collect(tree);
157
-
158
- const func = symbols[0];
159
- expect(func.kind).toBe(ESymbolKind.Function);
160
- expect(func.name).toBe("add");
161
- expect(func.type).toBe("int");
162
- expect(func.sourceLanguage).toBe(ESourceLanguage.Cpp);
163
- });
164
-
165
- it("collects function in namespace with qualified name", () => {
166
- const code = `
167
- namespace utils {
168
- int clamp(int val, int min, int max);
169
- }
170
- `;
171
- const tree = parseCpp(code);
172
- const collector = new CppSymbolCollector("test.hpp");
173
- const symbols = collector.collect(tree);
174
-
175
- const func = symbols.find((s) => s.name === "utils::clamp");
176
- expect(func?.kind).toBe(ESymbolKind.Function);
177
- expect(func?.type).toBe("int");
178
- expect(func?.parent).toBe("utils");
179
- });
180
-
181
- it("extracts function parameters (Issue #322)", () => {
182
- const code = `void process(int count, const char* msg);`;
183
- const tree = parseCpp(code);
184
- const collector = new CppSymbolCollector("test.hpp");
185
- const symbols = collector.collect(tree);
186
-
187
- const func = symbols[0];
188
- expect(func.parameters).toHaveLength(2);
189
- expect(func.parameters?.[0]).toEqual({
190
- name: "count",
191
- type: "int",
192
- isConst: false,
193
- isArray: false,
194
- });
195
- expect(func.parameters?.[1]).toEqual({
196
- name: "msg",
197
- type: "char*",
198
- isConst: true,
199
- isArray: false,
200
- });
201
- });
202
-
203
- it("handles function with no parameters", () => {
204
- const code = `void init();`;
205
- const tree = parseCpp(code);
206
- const collector = new CppSymbolCollector("test.hpp");
207
- const symbols = collector.collect(tree);
208
-
209
- const func = symbols[0];
210
- expect(func.parameters).toBeUndefined();
211
- });
212
-
213
- it("handles function pointer return types", () => {
214
- const code = `int* getData();`;
215
- const tree = parseCpp(code);
216
- const collector = new CppSymbolCollector("test.hpp");
217
- const symbols = collector.collect(tree);
218
-
219
- const func = symbols[0];
220
- expect(func.type).toBe("int");
221
- });
222
-
223
- it("defaults to void for functions without return type", () => {
224
- const code = `
225
- namespace test {
226
- foo();
227
- }
228
- `;
229
- // This might not parse correctly, but test the fallback
230
- try {
231
- const tree = parseCpp(code);
232
- const collector = new CppSymbolCollector("test.hpp");
233
- collector.collect(tree);
234
- // If it parses, we check fallback behavior
235
- } catch (e) {
236
- // Parse error is acceptable for malformed code
237
- expect(e).toBeDefined();
238
- }
239
- });
240
- });
241
-
242
- describe("CppSymbolCollector - Class/Struct Definitions", () => {
243
- it("collects named class definition", () => {
244
- const code = `class MyClass { };`;
245
- const tree = parseCpp(code);
246
- const collector = new CppSymbolCollector("test.hpp");
247
- const symbols = collector.collect(tree);
248
-
249
- const cls = symbols[0];
250
- expect(cls.kind).toBe(ESymbolKind.Class);
251
- expect(cls.name).toBe("MyClass");
252
- expect(cls.sourceLanguage).toBe(ESourceLanguage.Cpp);
253
- });
254
-
255
- it("collects named struct definition", () => {
256
- const code = `struct Point { int x; int y; };`;
257
- const tree = parseCpp(code);
258
- const symbolTable = new SymbolTable();
259
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
260
- const symbols = collector.collect(tree);
261
-
262
- const struct = symbols[0];
263
- expect(struct.kind).toBe(ESymbolKind.Class);
264
- expect(struct.name).toBe("Point");
265
- });
266
-
267
- it("collects class in namespace", () => {
268
- const code = `
269
- namespace hw {
270
- class Device { };
271
- }
272
- `;
273
- const tree = parseCpp(code);
274
- const collector = new CppSymbolCollector("test.hpp");
275
- const symbols = collector.collect(tree);
276
-
277
- const cls = symbols.find((s) => s.name === "hw::Device");
278
- expect(cls?.kind).toBe(ESymbolKind.Class);
279
- expect(cls?.parent).toBe("hw");
280
- });
281
-
282
- it("handles empty class", () => {
283
- const code = `class Empty { };`;
284
- const tree = parseCpp(code);
285
- const collector = new CppSymbolCollector("test.hpp");
286
- const symbols = collector.collect(tree);
287
-
288
- expect(symbols).toHaveLength(1);
289
- expect(symbols[0].name).toBe("Empty");
290
- });
291
- });
292
-
293
- describe("CppSymbolCollector - Class Member Functions", () => {
294
- it("collects member function declaration", () => {
295
- const code = `
296
- class MyClass {
297
- public:
298
- void doSomething();
299
- };
300
- `;
301
- const tree = parseCpp(code);
302
- const symbolTable = new SymbolTable();
303
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
304
- const symbols = collector.collect(tree);
305
-
306
- const method = symbols.find((s) => s.name === "MyClass::doSomething");
307
- expect(method?.kind).toBe(ESymbolKind.Function);
308
- expect(method?.parent).toBe("MyClass");
309
- expect(method?.isDeclaration).toBe(true);
310
- });
311
-
312
- it("collects inline member function definition", () => {
313
- const code = `
314
- class MyClass {
315
- public:
316
- void doSomething() { }
317
- };
318
- `;
319
- const tree = parseCpp(code);
320
- const symbolTable = new SymbolTable();
321
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
322
- const symbols = collector.collect(tree);
323
-
324
- const method = symbols.find((s) => s.name === "MyClass::doSomething");
325
- expect(method?.kind).toBe(ESymbolKind.Function);
326
- expect(method?.type).toBe("void");
327
- });
328
-
329
- it("collects member function with return type", () => {
330
- const code = `
331
- class MyClass {
332
- public:
333
- int getValue();
334
- };
335
- `;
336
- const tree = parseCpp(code);
337
- const symbolTable = new SymbolTable();
338
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
339
- const symbols = collector.collect(tree);
340
-
341
- const method = symbols.find((s) => s.name === "MyClass::getValue");
342
- expect(method?.type).toBe("int");
343
- });
344
-
345
- it("collects member function with parameters (Issue #322)", () => {
346
- const code = `
347
- class MyClass {
348
- public:
349
- void set(int val);
350
- };
351
- `;
352
- const tree = parseCpp(code);
353
- const symbolTable = new SymbolTable();
354
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
355
- const symbols = collector.collect(tree);
356
-
357
- const method = symbols.find((s) => s.name === "MyClass::set");
358
- expect(method?.parameters).toHaveLength(1);
359
- expect(method?.parameters?.[0].type).toBe("int");
360
- });
361
-
362
- it("collects static member function", () => {
363
- const code = `
364
- class Utils {
365
- public:
366
- static int abs(int x);
367
- };
368
- `;
369
- const tree = parseCpp(code);
370
- const symbolTable = new SymbolTable();
371
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
372
- const symbols = collector.collect(tree);
373
-
374
- const method = symbols.find((s) => s.name === "Utils::abs");
375
- expect(method?.kind).toBe(ESymbolKind.Function);
376
- });
377
-
378
- it("collects inline function with explicit return type", () => {
379
- const code = `
380
- class Counter {
381
- public:
382
- int getValue() { return count; }
383
- private:
384
- int count;
385
- };
386
- `;
387
- const tree = parseCpp(code);
388
- const symbolTable = new SymbolTable();
389
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
390
- const symbols = collector.collect(tree);
391
-
392
- const method = symbols.find((s) => s.name === "Counter::getValue");
393
- expect(method?.kind).toBe(ESymbolKind.Function);
394
- expect(method?.type).toBe("int");
395
- expect(method?.isDeclaration).toBeUndefined(); // inline def, not declaration
396
- });
397
-
398
- it("collects inline function with parameters", () => {
399
- const code = `
400
- class Math {
401
- public:
402
- int add(int a, int b) { return a + b; }
403
- };
404
- `;
405
- const tree = parseCpp(code);
406
- const symbolTable = new SymbolTable();
407
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
408
- const symbols = collector.collect(tree);
409
-
410
- const method = symbols.find((s) => s.name === "Math::add");
411
- expect(method?.parameters).toHaveLength(2);
412
- expect(method?.parameters?.[0].name).toBe("a");
413
- expect(method?.parameters?.[1].name).toBe("b");
414
- });
415
-
416
- it("handles class with mixed inline and declaration methods", () => {
417
- const code = `
418
- class Mixed {
419
- public:
420
- void inlineMethod() { }
421
- void declaredMethod();
422
- int data;
423
- };
424
- `;
425
- const tree = parseCpp(code);
426
- const symbolTable = new SymbolTable();
427
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
428
- const symbols = collector.collect(tree);
429
-
430
- const inline = symbols.find((s) => s.name === "Mixed::inlineMethod");
431
- const declared = symbols.find((s) => s.name === "Mixed::declaredMethod");
432
-
433
- expect(inline?.kind).toBe(ESymbolKind.Function);
434
- expect(inline?.isDeclaration).toBeUndefined();
435
- expect(declared?.kind).toBe(ESymbolKind.Function);
436
- expect(declared?.isDeclaration).toBe(true);
437
-
438
- // Data field should be in symbol table
439
- const field = symbolTable.getStructFieldInfo("Mixed", "data");
440
- expect(field?.type).toBe("int");
441
- });
442
- });
443
-
444
- describe("CppSymbolCollector - Struct Field Collection", () => {
445
- it("registers struct fields in SymbolTable", () => {
446
- const code = `
447
- struct Point {
448
- int x;
449
- int y;
450
- };
451
- `;
452
- const tree = parseCpp(code);
453
- const symbolTable = new SymbolTable();
454
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
455
-
456
- collector.collect(tree);
457
-
458
- const fields = symbolTable.getStructFields("Point");
459
- expect(fields?.size).toBe(2);
460
- expect(fields?.get("x")?.type).toBe("int");
461
- expect(fields?.get("y")?.type).toBe("int");
462
- });
463
-
464
- it("registers array fields with dimensions", () => {
465
- const code = `
466
- struct Buffer {
467
- uint8_t data[256];
468
- };
469
- `;
470
- const tree = parseCpp(code);
471
- const symbolTable = new SymbolTable();
472
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
473
-
474
- collector.collect(tree);
475
-
476
- const field = symbolTable.getStructFieldInfo("Buffer", "data");
477
- expect(field?.type).toBe("uint8_t");
478
- expect(field?.arrayDimensions).toEqual([256]);
479
- });
480
-
481
- it("registers multi-dimensional array fields", () => {
482
- const code = `
483
- struct Matrix {
484
- float values[4][4];
485
- };
486
- `;
487
- const tree = parseCpp(code);
488
- const symbolTable = new SymbolTable();
489
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
490
-
491
- collector.collect(tree);
492
-
493
- const field = symbolTable.getStructFieldInfo("Matrix", "values");
494
- expect(field?.arrayDimensions).toEqual([4, 4]);
495
- });
496
-
497
- it("generates warning for reserved field name 'length'", () => {
498
- const code = `
499
- struct MyStruct {
500
- int length;
501
- };
502
- `;
503
- const tree = parseCpp(code);
504
- const symbolTable = new SymbolTable();
505
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
506
-
507
- collector.collect(tree);
508
- const warnings = collector.getWarnings();
509
-
510
- expect(warnings).toHaveLength(1);
511
- expect(warnings[0]).toContain("conflicts with C-Next's .length property");
512
- });
513
-
514
- it("does not generate warning for 'capacity' (not currently reserved)", () => {
515
- const code = `
516
- struct MyStruct {
517
- int capacity;
518
- };
519
- `;
520
- const tree = parseCpp(code);
521
- const symbolTable = new SymbolTable();
522
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
523
-
524
- collector.collect(tree);
525
- const warnings = collector.getWarnings();
526
-
527
- // 'capacity' is not in RESERVED_FIELD_NAMES (only 'length' is)
528
- expect(warnings).toHaveLength(0);
529
- });
530
-
531
- it("does not register fields when SymbolTable is not provided", () => {
532
- const code = `
533
- struct Point {
534
- int x;
535
- int y;
536
- };
537
- `;
538
- const tree = parseCpp(code);
539
- const collector = new CppSymbolCollector("test.hpp");
540
-
541
- const symbols = collector.collect(tree);
542
-
543
- // Should collect struct symbol but not register fields
544
- expect(symbols).toHaveLength(1);
545
- expect(symbols[0].kind).toBe(ESymbolKind.Class);
546
- });
547
- });
548
-
549
- describe("CppSymbolCollector - Enum Handling", () => {
550
- it("collects C++11 enum class with explicit type", () => {
551
- const code = `enum class EMode : uint8_t { OFF, ON };`;
552
- const tree = parseCpp(code);
553
- const collector = new CppSymbolCollector("test.hpp");
554
- const symbols = collector.collect(tree);
555
-
556
- const enumSymbol = symbols[0];
557
- expect(enumSymbol.kind).toBe(ESymbolKind.Enum);
558
- expect(enumSymbol.name).toBe("EMode");
559
- expect(enumSymbol.sourceLanguage).toBe(ESourceLanguage.Cpp);
560
- });
561
-
562
- it("collects C++11 enum class without explicit type", () => {
563
- const code = `enum class EColor { RED, GREEN, BLUE };`;
564
- const tree = parseCpp(code);
565
- const collector = new CppSymbolCollector("test.hpp");
566
- const symbols = collector.collect(tree);
567
-
568
- const enumSymbol = symbols[0];
569
- expect(enumSymbol.kind).toBe(ESymbolKind.Enum);
570
- expect(enumSymbol.name).toBe("EColor");
571
- });
572
-
573
- it("collects typed enum (not class)", () => {
574
- const code = `enum EFlags : uint16_t { FLAG_NONE, FLAG_READ };`;
575
- const tree = parseCpp(code);
576
- const collector = new CppSymbolCollector("test.hpp");
577
- const symbols = collector.collect(tree);
578
-
579
- const enumSymbol = symbols[0];
580
- expect(enumSymbol.kind).toBe(ESymbolKind.Enum);
581
- expect(enumSymbol.name).toBe("EFlags");
582
- });
583
-
584
- it("collects traditional C-style enum", () => {
585
- const code = `enum ELegacy { LEGACY_A, LEGACY_B };`;
586
- const tree = parseCpp(code);
587
- const collector = new CppSymbolCollector("test.hpp");
588
- const symbols = collector.collect(tree);
589
-
590
- const enumSymbol = symbols[0];
591
- expect(enumSymbol.kind).toBe(ESymbolKind.Enum);
592
- expect(enumSymbol.name).toBe("ELegacy");
593
- });
594
-
595
- it("collects enum in namespace", () => {
596
- const code = `
597
- namespace hw {
598
- enum class EStatus { OK, ERROR };
599
- }
600
- `;
601
- const tree = parseCpp(code);
602
- const collector = new CppSymbolCollector("test.hpp");
603
- const symbols = collector.collect(tree);
604
-
605
- const enumSymbol = symbols.find((s) => s.name === "hw::EStatus");
606
- expect(enumSymbol?.kind).toBe(ESymbolKind.Enum);
607
- expect(enumSymbol?.parent).toBe("hw");
608
- });
609
-
610
- it("extracts enum bit width for uint8_t backing type (Issue #208)", () => {
611
- const code = `enum class EMode : uint8_t { OFF, ON };`;
612
- const tree = parseCpp(code);
613
- const symbolTable = new SymbolTable();
614
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
615
-
616
- collector.collect(tree);
617
-
618
- const bitWidth = symbolTable.getEnumBitWidth("EMode");
619
- expect(bitWidth).toBe(8);
620
- });
621
-
622
- it("extracts enum bit width for uint16_t backing type (Issue #208)", () => {
623
- const code = `enum class EFlags : uint16_t { NONE, READ };`;
624
- const tree = parseCpp(code);
625
- const symbolTable = new SymbolTable();
626
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
627
-
628
- collector.collect(tree);
629
-
630
- const bitWidth = symbolTable.getEnumBitWidth("EFlags");
631
- expect(bitWidth).toBe(16);
632
- });
633
-
634
- it("extracts enum bit width for uint32_t backing type (Issue #208)", () => {
635
- const code = `enum class ELarge : uint32_t { VALUE };`;
636
- const tree = parseCpp(code);
637
- const symbolTable = new SymbolTable();
638
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
639
-
640
- collector.collect(tree);
641
-
642
- const bitWidth = symbolTable.getEnumBitWidth("ELarge");
643
- expect(bitWidth).toBe(32);
644
- });
645
-
646
- it("extracts enum bit width for int8_t backing type (Issue #208)", () => {
647
- const code = `enum class ESigned : int8_t { NEG = -1, ZERO = 0 };`;
648
- const tree = parseCpp(code);
649
- const symbolTable = new SymbolTable();
650
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
651
-
652
- collector.collect(tree);
653
-
654
- const bitWidth = symbolTable.getEnumBitWidth("ESigned");
655
- expect(bitWidth).toBe(8);
656
- });
657
-
658
- it("does not extract bit width for untyped enums", () => {
659
- const code = `enum ELegacy { A, B };`;
660
- const tree = parseCpp(code);
661
- const symbolTable = new SymbolTable();
662
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
663
-
664
- collector.collect(tree);
665
-
666
- const bitWidth = symbolTable.getEnumBitWidth("ELegacy");
667
- expect(bitWidth).toBeUndefined();
668
- });
669
- });
670
-
671
- describe("CppSymbolCollector - Function Parameters (Issue #322)", () => {
672
- it("extracts parameters with names and types", () => {
673
- const code = `void func(int x, double y);`;
674
- const tree = parseCpp(code);
675
- const collector = new CppSymbolCollector("test.hpp");
676
- const symbols = collector.collect(tree);
677
-
678
- const func = symbols[0];
679
- expect(func.parameters).toHaveLength(2);
680
- expect(func.parameters?.[0]).toEqual({
681
- name: "x",
682
- type: "int",
683
- isConst: false,
684
- isArray: false,
685
- });
686
- expect(func.parameters?.[1]).toEqual({
687
- name: "y",
688
- type: "double",
689
- isConst: false,
690
- isArray: false,
691
- });
692
- });
693
-
694
- it("detects const parameters", () => {
695
- const code = `void func(const int x);`;
696
- const tree = parseCpp(code);
697
- const collector = new CppSymbolCollector("test.hpp");
698
- const symbols = collector.collect(tree);
699
-
700
- const param = symbols[0].parameters?.[0];
701
- expect(param?.isConst).toBe(true);
702
- });
703
-
704
- it("detects pointer parameters", () => {
705
- const code = `void func(char* str);`;
706
- const tree = parseCpp(code);
707
- const collector = new CppSymbolCollector("test.hpp");
708
- const symbols = collector.collect(tree);
709
-
710
- const param = symbols[0].parameters?.[0];
711
- expect(param?.type).toBe("char*");
712
- });
713
-
714
- it("handles const pointer parameters", () => {
715
- const code = `void func(const char* msg);`;
716
- const tree = parseCpp(code);
717
- const collector = new CppSymbolCollector("test.hpp");
718
- const symbols = collector.collect(tree);
719
-
720
- const param = symbols[0].parameters?.[0];
721
- expect(param?.type).toBe("char*");
722
- expect(param?.isConst).toBe(true);
723
- });
724
-
725
- it("handles abstract declarators (parameters without names)", () => {
726
- const code = `void func(int, double);`;
727
- const tree = parseCpp(code);
728
- const collector = new CppSymbolCollector("test.hpp");
729
- const symbols = collector.collect(tree);
730
-
731
- const func = symbols[0];
732
- expect(func.parameters).toHaveLength(2);
733
- expect(func.parameters?.[0].name).toBe("");
734
- expect(func.parameters?.[0].type).toBe("int");
735
- });
736
-
737
- it("handles multiple pointer levels", () => {
738
- const code = `void func(char** argv);`;
739
- const tree = parseCpp(code);
740
- const collector = new CppSymbolCollector("test.hpp");
741
- const symbols = collector.collect(tree);
742
-
743
- const param = symbols[0].parameters?.[0];
744
- expect(param?.type).toContain("*");
745
- });
746
-
747
- it("handles mixed parameter types", () => {
748
- const code = `void func(int a, const char* b, double c, bool d);`;
749
- const tree = parseCpp(code);
750
- const collector = new CppSymbolCollector("test.hpp");
751
- const symbols = collector.collect(tree);
752
-
753
- const func = symbols[0];
754
- expect(func.parameters).toHaveLength(4);
755
- });
756
-
757
- it("returns undefined for functions with no parameters", () => {
758
- const code = `void func();`;
759
- const tree = parseCpp(code);
760
- const collector = new CppSymbolCollector("test.hpp");
761
- const symbols = collector.collect(tree);
762
-
763
- const func = symbols[0];
764
- expect(func.parameters).toBeUndefined();
765
- });
766
-
767
- it("handles reference parameters", () => {
768
- const code = `void func(int& ref);`;
769
- const tree = parseCpp(code);
770
- const collector = new CppSymbolCollector("test.hpp");
771
- const symbols = collector.collect(tree);
772
-
773
- const param = symbols[0].parameters?.[0];
774
- expect(param).toBeDefined();
775
- expect(param?.name).toBe("ref");
776
- });
777
- });
778
-
779
- describe("CppSymbolCollector - Type Aliases", () => {
780
- it("collects using declaration (type alias)", () => {
781
- const code = `using MyInt = int;`;
782
- const tree = parseCpp(code);
783
- const collector = new CppSymbolCollector("test.hpp");
784
- const symbols = collector.collect(tree);
785
-
786
- const alias = symbols[0];
787
- expect(alias.kind).toBe(ESymbolKind.Type);
788
- expect(alias.name).toBe("MyInt");
789
- });
790
-
791
- it("collects using declaration in namespace", () => {
792
- const code = `
793
- namespace utils {
794
- using Counter = uint32_t;
795
- }
796
- `;
797
- const tree = parseCpp(code);
798
- const collector = new CppSymbolCollector("test.hpp");
799
- const symbols = collector.collect(tree);
800
-
801
- // Find the Counter symbol - it may not be qualified with namespace prefix
802
- const alias = symbols.find(
803
- (s) => s.name === "Counter" || s.name === "utils::Counter",
804
- );
805
- expect(alias).toBeDefined();
806
- expect(alias?.kind).toBe(ESymbolKind.Type);
807
- });
808
-
809
- it("skips using directives (not declarations)", () => {
810
- const code = `using namespace std;`;
811
- const tree = parseCpp(code);
812
- const collector = new CppSymbolCollector("test.hpp");
813
- const symbols = collector.collect(tree);
814
-
815
- // Using directive should be skipped
816
- expect(symbols).toHaveLength(0);
817
- });
818
- });
819
-
820
- describe("CppSymbolCollector - Anonymous Struct Typedef (Issue #342)", () => {
821
- it("collects anonymous struct with typedef", () => {
822
- const code = `
823
- typedef struct {
824
- int x;
825
- int y;
826
- } Point;
827
- `;
828
- const tree = parseCpp(code);
829
- const symbolTable = new SymbolTable();
830
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
831
-
832
- const symbols = collector.collect(tree);
833
-
834
- // Should create symbol for typedef name
835
- const typeSymbol = symbols.find((s) => s.name === "Point");
836
- expect(typeSymbol?.kind).toBe(ESymbolKind.Class);
837
- });
838
-
839
- it("registers anonymous struct fields using typedef name", () => {
840
- const code = `
841
- typedef struct {
842
- int x;
843
- int y;
844
- } Point;
845
- `;
846
- const tree = parseCpp(code);
847
- const symbolTable = new SymbolTable();
848
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
849
-
850
- collector.collect(tree);
851
-
852
- // Fields should be registered under typedef name
853
- const fields = symbolTable.getStructFields("Point");
854
- expect(fields?.size).toBe(2);
855
- expect(fields?.get("x")?.type).toBe("int");
856
- expect(fields?.get("y")?.type).toBe("int");
857
- });
858
-
859
- it("handles anonymous struct with array fields", () => {
860
- const code = `
861
- typedef struct {
862
- uint8_t data[256];
863
- } Buffer;
864
- `;
865
- const tree = parseCpp(code);
866
- const symbolTable = new SymbolTable();
867
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
868
-
869
- collector.collect(tree);
870
-
871
- const field = symbolTable.getStructFieldInfo("Buffer", "data");
872
- expect(field?.arrayDimensions).toEqual([256]);
873
- });
874
- });
875
-
876
- describe("CppSymbolCollector - Template Declarations", () => {
877
- it("skips simple template class", () => {
878
- const code = `
879
- template<typename T>
880
- class Container {
881
- T value;
882
- };
883
- `;
884
- const tree = parseCpp(code);
885
- const collector = new CppSymbolCollector("test.hpp");
886
- const symbols = collector.collect(tree);
887
-
888
- // Templates should be skipped
889
- expect(symbols).toHaveLength(0);
890
- });
891
-
892
- it("skips template function", () => {
893
- const code = `
894
- template<typename T>
895
- T max(T a, T b) { return a > b ? a : b; }
896
- `;
897
- const tree = parseCpp(code);
898
- const collector = new CppSymbolCollector("test.hpp");
899
- const symbols = collector.collect(tree);
900
-
901
- expect(symbols).toHaveLength(0);
902
- });
903
-
904
- it("skips template with multiple parameters", () => {
905
- const code = `
906
- template<typename T, int SIZE>
907
- class Buffer {
908
- T data[SIZE];
909
- };
910
- `;
911
- const tree = parseCpp(code);
912
- const collector = new CppSymbolCollector("test.hpp");
913
- const symbols = collector.collect(tree);
914
-
915
- expect(symbols).toHaveLength(0);
916
- });
917
- });
918
-
919
- describe("CppSymbolCollector - Edge Cases", () => {
920
- it("handles missing declarator name gracefully", () => {
921
- const code = `void;`;
922
- try {
923
- const tree = parseCpp(code);
924
- const collector = new CppSymbolCollector("test.hpp");
925
- expect(() => collector.collect(tree)).not.toThrow();
926
- } catch (e) {
927
- // Parse error is acceptable
928
- expect(e).toBeDefined();
929
- }
930
- });
931
-
932
- it("handles multiple declarations in one statement", () => {
933
- const code = `int a, b, c;`;
934
- const tree = parseCpp(code);
935
- const collector = new CppSymbolCollector("test.hpp");
936
- const symbols = collector.collect(tree);
937
-
938
- expect(symbols).toHaveLength(3);
939
- expect(symbols.map((s) => s.name)).toContain("a");
940
- expect(symbols.map((s) => s.name)).toContain("b");
941
- expect(symbols.map((s) => s.name)).toContain("c");
942
- });
943
-
944
- it("handles function overloads (same name, different signatures)", () => {
945
- const code = `
946
- void foo(int x);
947
- void foo(double x);
948
- void foo(int x, int y);
949
- `;
950
- const tree = parseCpp(code);
951
- const collector = new CppSymbolCollector("test.hpp");
952
- const symbols = collector.collect(tree);
953
-
954
- const fooFuncs = symbols.filter((s) => s.name === "foo");
955
- expect(fooFuncs).toHaveLength(3);
956
- });
957
-
958
- it("handles extern declarations", () => {
959
- const code = `extern int globalVar;`;
960
- const tree = parseCpp(code);
961
- const collector = new CppSymbolCollector("test.hpp");
962
- const symbols = collector.collect(tree);
963
-
964
- const varSymbol = symbols[0];
965
- expect(varSymbol.kind).toBe(ESymbolKind.Variable);
966
- expect(varSymbol.name).toBe("globalVar");
967
- // Note: CppSymbolCollector doesn't currently set isDeclaration for extern variables
968
- // This is acceptable as it's primarily used for functions
969
- });
970
-
971
- it("handles complex type names", () => {
972
- const code = `unsigned long long getValue();`;
973
- const tree = parseCpp(code);
974
- const collector = new CppSymbolCollector("test.hpp");
975
- const symbols = collector.collect(tree);
976
-
977
- const func = symbols[0];
978
- expect(func.type).toBeDefined();
979
- expect(func.type).toContain("long");
980
- });
981
-
982
- it("resets state between collect() calls", () => {
983
- const code1 = `void foo();`;
984
- const code2 = `void bar();`;
985
- const tree1 = parseCpp(code1);
986
- const tree2 = parseCpp(code2);
987
-
988
- const collector = new CppSymbolCollector("test.hpp");
989
- const symbols1 = collector.collect(tree1);
990
- const symbols2 = collector.collect(tree2);
991
-
992
- expect(symbols1).toHaveLength(1);
993
- expect(symbols2).toHaveLength(1);
994
- expect(symbols1[0].name).toBe("foo");
995
- expect(symbols2[0].name).toBe("bar");
996
- });
997
-
998
- it("clears warnings between collect() calls", () => {
999
- const code = `struct S { int length; };`;
1000
- const tree = parseCpp(code);
1001
- const symbolTable = new SymbolTable();
1002
- const collector = new CppSymbolCollector("test.hpp", symbolTable);
1003
-
1004
- collector.collect(tree);
1005
- const warnings1 = collector.getWarnings();
1006
-
1007
- collector.collect(tree);
1008
- const warnings2 = collector.getWarnings();
1009
-
1010
- expect(warnings1).toHaveLength(1);
1011
- expect(warnings2).toHaveLength(1);
1012
- });
1013
- });
1014
-
1015
- describe("CppSymbolCollector - Real C++ Header Integration", () => {
1016
- it("parses comprehensive-cpp.hpp successfully", () => {
1017
- const fs = require("fs");
1018
- const path = require("path");
1019
- const headerPath = path.join(
1020
- __dirname,
1021
- "../../../../../tests/cpp-interop/comprehensive-cpp.hpp",
1022
- );
1023
- const code = fs.readFileSync(headerPath, "utf-8");
1024
-
1025
- const tree = parseCpp(code);
1026
- const symbolTable = new SymbolTable();
1027
- const collector = new CppSymbolCollector(
1028
- "comprehensive-cpp.hpp",
1029
- symbolTable,
1030
- );
1031
-
1032
- const symbols = collector.collect(tree);
1033
-
1034
- // Verify key symbols are collected
1035
- expect(symbols.length).toBeGreaterThan(0);
1036
-
1037
- // Check namespace
1038
- const hwNs = symbols.find((s) => s.name === "hw");
1039
- expect(hwNs?.kind).toBe(ESymbolKind.Namespace);
1040
-
1041
- // Check enum class
1042
- const emode = symbols.find((s) => s.name === "EMode");
1043
- expect(emode?.kind).toBe(ESymbolKind.Enum);
1044
-
1045
- // Check bit width extraction
1046
- const bitWidth = symbolTable.getEnumBitWidth("EMode");
1047
- expect(bitWidth).toBe(8);
1048
- });
1049
-
1050
- it("collects all namespaces from comprehensive header", () => {
1051
- const fs = require("fs");
1052
- const path = require("path");
1053
- const headerPath = path.join(
1054
- __dirname,
1055
- "../../../../../tests/cpp-interop/comprehensive-cpp.hpp",
1056
- );
1057
- const code = fs.readFileSync(headerPath, "utf-8");
1058
-
1059
- const tree = parseCpp(code);
1060
- const collector = new CppSymbolCollector("comprehensive-cpp.hpp");
1061
- const symbols = collector.collect(tree);
1062
-
1063
- const namespaces = symbols.filter((s) => s.kind === ESymbolKind.Namespace);
1064
- expect(namespaces.length).toBeGreaterThan(0);
1065
-
1066
- // hw and utils namespaces should be present
1067
- const nsNames = namespaces.map((ns) => ns.name);
1068
- expect(nsNames).toContain("hw");
1069
- expect(nsNames).toContain("utils");
1070
- });
1071
-
1072
- it("collects all enum types from comprehensive header", () => {
1073
- const fs = require("fs");
1074
- const path = require("path");
1075
- const headerPath = path.join(
1076
- __dirname,
1077
- "../../../../../tests/cpp-interop/comprehensive-cpp.hpp",
1078
- );
1079
- const code = fs.readFileSync(headerPath, "utf-8");
1080
-
1081
- const tree = parseCpp(code);
1082
- const collector = new CppSymbolCollector("comprehensive-cpp.hpp");
1083
- const symbols = collector.collect(tree);
1084
-
1085
- const enums = symbols.filter((s) => s.kind === ESymbolKind.Enum);
1086
- expect(enums.length).toBeGreaterThan(3); // Multiple enum types
1087
-
1088
- const enumNames = enums.map((e) => e.name);
1089
- expect(enumNames).toContain("EMode");
1090
- expect(enumNames).toContain("EColor");
1091
- expect(enumNames).toContain("EFlags");
1092
- });
1093
-
1094
- it("collects all classes from comprehensive header", () => {
1095
- const fs = require("fs");
1096
- const path = require("path");
1097
- const headerPath = path.join(
1098
- __dirname,
1099
- "../../../../../tests/cpp-interop/comprehensive-cpp.hpp",
1100
- );
1101
- const code = fs.readFileSync(headerPath, "utf-8");
1102
-
1103
- const tree = parseCpp(code);
1104
- const symbolTable = new SymbolTable();
1105
- const collector = new CppSymbolCollector(
1106
- "comprehensive-cpp.hpp",
1107
- symbolTable,
1108
- );
1109
- const symbols = collector.collect(tree);
1110
-
1111
- const classes = symbols.filter((s) => s.kind === ESymbolKind.Class);
1112
- expect(classes.length).toBeGreaterThan(5);
1113
-
1114
- const classNames = classes.map((c) => c.name);
1115
- expect(classNames).toContain("CommandHandler");
1116
- expect(classNames).toContain("MathUtils");
1117
- });
1118
-
1119
- it("extracts struct fields from comprehensive header", () => {
1120
- const fs = require("fs");
1121
- const path = require("path");
1122
- const headerPath = path.join(
1123
- __dirname,
1124
- "../../../../../tests/cpp-interop/comprehensive-cpp.hpp",
1125
- );
1126
- const code = fs.readFileSync(headerPath, "utf-8");
1127
-
1128
- const tree = parseCpp(code);
1129
- const symbolTable = new SymbolTable();
1130
- const collector = new CppSymbolCollector(
1131
- "comprehensive-cpp.hpp",
1132
- symbolTable,
1133
- );
1134
-
1135
- collector.collect(tree);
1136
-
1137
- // Point struct should have x and y fields
1138
- const pointFields = symbolTable.getStructFields("Point");
1139
- expect(pointFields?.get("x")).toBeDefined();
1140
- expect(pointFields?.get("y")).toBeDefined();
1141
-
1142
- // Result struct should have multiple fields
1143
- const resultFields = symbolTable.getStructFields("Result");
1144
- expect(resultFields?.size).toBeGreaterThan(2);
1145
- });
1146
- });