c-next 0.1.70 → 0.1.71

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 (204) 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 +173 -60
  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 +676 -258
  13. package/src/transpiler/logic/symbols/SymbolUtils.ts +2 -2
  14. package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +290 -782
  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/ISerializedSymbol.ts +11 -0
  112. package/src/transpiler/types/TPrimitiveKind.ts +20 -0
  113. package/src/transpiler/types/TType.ts +103 -0
  114. package/src/transpiler/types/TVisibility.ts +6 -0
  115. package/src/transpiler/types/symbol-kinds/TSymbolKind.ts +10 -0
  116. package/src/transpiler/types/symbol-kinds/TSymbolKindC.ts +12 -0
  117. package/src/transpiler/types/symbol-kinds/TSymbolKindCNext.ts +16 -0
  118. package/src/transpiler/types/symbol-kinds/TSymbolKindCpp.ts +14 -0
  119. package/src/transpiler/types/symbols/IBaseSymbol.ts +31 -0
  120. package/src/transpiler/{logic/symbols/types → types/symbols}/IBitmapFieldInfo.ts +2 -2
  121. package/src/transpiler/types/symbols/IBitmapSymbol.ts +21 -0
  122. package/src/transpiler/{logic/symbols/types → types/symbols}/IEnumSymbol.ts +5 -6
  123. package/src/transpiler/types/symbols/IFieldInfo.ts +26 -0
  124. package/src/transpiler/types/symbols/IFunctionSymbol.ts +30 -0
  125. package/src/transpiler/types/symbols/IParameterInfo.ts +26 -0
  126. package/src/transpiler/{logic/symbols/types → types/symbols}/IRegisterMemberInfo.ts +4 -4
  127. package/src/transpiler/types/symbols/IRegisterSymbol.ts +18 -0
  128. package/src/transpiler/types/symbols/IScopeSymbol.ts +32 -0
  129. package/src/transpiler/{logic/symbols/types → types/symbols}/IStructFieldInfo.ts +2 -1
  130. package/src/transpiler/types/symbols/IStructSymbol.ts +15 -0
  131. package/src/transpiler/types/symbols/IVariableSymbol.ts +30 -0
  132. package/src/transpiler/types/symbols/SymbolGuards.ts +43 -0
  133. package/src/transpiler/types/symbols/TAnySymbol.ts +22 -0
  134. package/src/transpiler/types/symbols/TSymbol.ts +32 -0
  135. package/src/transpiler/types/symbols/__tests__/IBaseSymbol.test.ts +56 -0
  136. package/src/transpiler/types/symbols/__tests__/SymbolGuards.test.ts +57 -0
  137. package/src/transpiler/types/symbols/c/ICBaseSymbol.ts +28 -0
  138. package/src/transpiler/types/symbols/c/ICEnumMemberSymbol.ts +17 -0
  139. package/src/transpiler/types/symbols/c/ICEnumSymbol.ts +17 -0
  140. package/src/transpiler/types/symbols/c/ICFieldInfo.ts +16 -0
  141. package/src/transpiler/types/symbols/c/ICFunctionSymbol.ts +21 -0
  142. package/src/transpiler/types/symbols/c/ICParameterInfo.ts +19 -0
  143. package/src/transpiler/types/symbols/c/ICStructSymbol.ts +21 -0
  144. package/src/transpiler/types/symbols/c/ICTypedefSymbol.ts +14 -0
  145. package/src/transpiler/types/symbols/c/ICVariableSymbol.ts +26 -0
  146. package/src/transpiler/types/symbols/c/TCSymbol.ts +26 -0
  147. package/src/transpiler/types/symbols/cpp/ICppBaseSymbol.ts +31 -0
  148. package/src/transpiler/types/symbols/cpp/ICppClassSymbol.ts +15 -0
  149. package/src/transpiler/types/symbols/cpp/ICppEnumMemberSymbol.ts +14 -0
  150. package/src/transpiler/types/symbols/cpp/ICppEnumSymbol.ts +14 -0
  151. package/src/transpiler/types/symbols/cpp/ICppFieldInfo.ts +16 -0
  152. package/src/transpiler/types/symbols/cpp/ICppFunctionSymbol.ts +21 -0
  153. package/src/transpiler/types/symbols/cpp/ICppNamespaceSymbol.ts +11 -0
  154. package/src/transpiler/types/symbols/cpp/ICppParameterInfo.ts +19 -0
  155. package/src/transpiler/types/symbols/cpp/ICppStructSymbol.ts +16 -0
  156. package/src/transpiler/types/symbols/cpp/ICppTypeAliasSymbol.ts +14 -0
  157. package/src/transpiler/types/symbols/cpp/ICppVariableSymbol.ts +23 -0
  158. package/src/transpiler/types/symbols/cpp/TCppSymbol.ts +30 -0
  159. package/src/utils/CppNamespaceUtils.ts +3 -4
  160. package/src/utils/FunctionUtils.ts +92 -0
  161. package/src/utils/ParameterUtils.ts +55 -0
  162. package/src/utils/PrimitiveKindUtils.ts +33 -0
  163. package/src/utils/ScopeUtils.ts +105 -0
  164. package/src/utils/TTypeUtils.ts +159 -0
  165. package/src/utils/TypeResolver.ts +132 -0
  166. package/src/utils/__tests__/CppNamespaceUtils.test.ts +92 -99
  167. package/src/utils/__tests__/FunctionUtils.test.ts +284 -0
  168. package/src/utils/__tests__/ParameterUtils.test.ts +174 -0
  169. package/src/utils/__tests__/PrimitiveKindUtils.test.ts +59 -0
  170. package/src/utils/__tests__/ScopeUtils.test.ts +53 -0
  171. package/src/utils/__tests__/TTypeUtils.test.ts +245 -0
  172. package/src/utils/__tests__/TypeResolver.test.ts +332 -0
  173. package/src/utils/cache/CacheManager.ts +91 -50
  174. package/src/utils/cache/__tests__/CacheManager.test.ts +180 -114
  175. package/src/transpiler/logic/symbols/AutoConstUpdater.ts +0 -93
  176. package/src/transpiler/logic/symbols/CSymbolCollector.ts +0 -648
  177. package/src/transpiler/logic/symbols/CppSymbolCollector.ts +0 -874
  178. package/src/transpiler/logic/symbols/SymbolCollectorContext.ts +0 -68
  179. package/src/transpiler/logic/symbols/__tests__/AutoConstUpdater.test.ts +0 -418
  180. package/src/transpiler/logic/symbols/__tests__/CSymbolCollector.test.ts +0 -685
  181. package/src/transpiler/logic/symbols/__tests__/CppSymbolCollector.test.ts +0 -1146
  182. package/src/transpiler/logic/symbols/__tests__/SymbolCollectorContext.test.ts +0 -290
  183. package/src/transpiler/logic/symbols/__tests__/cTestHelpers.ts +0 -43
  184. package/src/transpiler/logic/symbols/__tests__/cppTestHelpers.ts +0 -40
  185. package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +0 -595
  186. package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +0 -345
  187. package/src/transpiler/logic/symbols/types/IBaseSymbol.ts +0 -27
  188. package/src/transpiler/logic/symbols/types/IBitmapSymbol.ts +0 -23
  189. package/src/transpiler/logic/symbols/types/ICollectorContext.ts +0 -19
  190. package/src/transpiler/logic/symbols/types/IConflict.ts +0 -20
  191. package/src/transpiler/logic/symbols/types/IFieldInfo.ts +0 -18
  192. package/src/transpiler/logic/symbols/types/IFunctionSymbol.ts +0 -25
  193. package/src/transpiler/logic/symbols/types/IParameterInfo.ts +0 -24
  194. package/src/transpiler/logic/symbols/types/IRegisterSymbol.ts +0 -20
  195. package/src/transpiler/logic/symbols/types/IScopeSymbol.ts +0 -19
  196. package/src/transpiler/logic/symbols/types/IStructSymbol.ts +0 -16
  197. package/src/transpiler/logic/symbols/types/IVariableSymbol.ts +0 -30
  198. package/src/transpiler/logic/symbols/types/TSymbol.ts +0 -36
  199. package/src/transpiler/logic/symbols/types/__tests__/SymbolGuards.test.ts +0 -244
  200. package/src/transpiler/logic/symbols/types/typeGuards.ts +0 -44
  201. package/src/utils/types/ESymbolKind.ts +0 -19
  202. package/src/utils/types/ISymbol.ts +0 -64
  203. /package/src/transpiler/{types → constants}/BITMAP_BACKING_TYPE.ts +0 -0
  204. /package/src/transpiler/{types → constants}/BITMAP_SIZE.ts +0 -0
@@ -1,648 +0,0 @@
1
- /**
2
- * C Symbol Collector
3
- * Extracts symbols from C parse trees for the unified symbol table
4
- */
5
-
6
- import {
7
- CompilationUnitContext,
8
- ExternalDeclarationContext,
9
- FunctionDefinitionContext,
10
- DeclarationContext,
11
- DeclarationSpecifierContext,
12
- DeclarationSpecifiersContext,
13
- InitDeclaratorListContext,
14
- StructOrUnionSpecifierContext,
15
- EnumSpecifierContext,
16
- } from "../parser/c/grammar/CParser";
17
- import ISymbol from "../../../utils/types/ISymbol";
18
- import ESymbolKind from "../../../utils/types/ESymbolKind";
19
- import ESourceLanguage from "../../../utils/types/ESourceLanguage";
20
- import SymbolTable from "./SymbolTable";
21
- import SymbolUtils from "./SymbolUtils";
22
- import SymbolCollectorContext from "./SymbolCollectorContext";
23
- import ICollectorContext from "./types/ICollectorContext";
24
-
25
- /**
26
- * Collects symbols from a C parse tree
27
- */
28
- class CSymbolCollector {
29
- private readonly ctx: ICollectorContext;
30
-
31
- constructor(sourceFile: string, symbolTable?: SymbolTable) {
32
- this.ctx = SymbolCollectorContext.create(sourceFile, symbolTable);
33
- }
34
-
35
- /**
36
- * Get warnings generated during symbol collection
37
- */
38
- getWarnings(): string[] {
39
- return SymbolCollectorContext.getWarnings(this.ctx);
40
- }
41
-
42
- /**
43
- * Collect all symbols from a C compilation unit
44
- */
45
- collect(tree: CompilationUnitContext): ISymbol[] {
46
- SymbolCollectorContext.reset(this.ctx);
47
-
48
- const translationUnit = tree.translationUnit();
49
- if (!translationUnit) {
50
- return SymbolCollectorContext.getSymbols(this.ctx);
51
- }
52
-
53
- for (const extDecl of translationUnit.externalDeclaration()) {
54
- this.collectExternalDeclaration(extDecl);
55
- }
56
-
57
- return SymbolCollectorContext.getSymbols(this.ctx);
58
- }
59
-
60
- private collectExternalDeclaration(
61
- extDecl: ExternalDeclarationContext,
62
- ): void {
63
- // Function definition
64
- const funcDef = extDecl.functionDefinition();
65
- if (funcDef) {
66
- this.collectFunctionDefinition(funcDef);
67
- return;
68
- }
69
-
70
- // Declaration (typedef, struct, variable, function prototype)
71
- const decl = extDecl.declaration();
72
- if (decl) {
73
- this.collectDeclaration(decl);
74
- }
75
- }
76
-
77
- private collectFunctionDefinition(funcDef: FunctionDefinitionContext): void {
78
- const declarator = funcDef.declarator();
79
- if (!declarator) return;
80
-
81
- // Extract function name from declarator
82
- const name = this.extractDeclaratorName(declarator);
83
- if (!name) return;
84
-
85
- const line = funcDef.start?.line ?? 0;
86
-
87
- // Get return type from declaration specifiers
88
- const declSpecs = funcDef.declarationSpecifiers();
89
- const returnType = declSpecs
90
- ? this.extractTypeFromDeclSpecs(declSpecs)
91
- : "int";
92
-
93
- SymbolCollectorContext.addSymbol(this.ctx, {
94
- name,
95
- kind: ESymbolKind.Function,
96
- type: returnType,
97
- sourceFile: this.ctx.sourceFile,
98
- sourceLine: line,
99
- sourceLanguage: ESourceLanguage.C,
100
- isExported: true,
101
- isDeclaration: false,
102
- });
103
- }
104
-
105
- private collectDeclaration(decl: DeclarationContext): void {
106
- const declSpecs = decl.declarationSpecifiers();
107
- if (!declSpecs) return;
108
-
109
- const line = decl.start?.line ?? 0;
110
-
111
- // Check for typedef
112
- const isTypedef = this.hasStorageClass(declSpecs, "typedef");
113
- const isExtern = this.hasStorageClass(declSpecs, "extern");
114
-
115
- // Check for struct/union
116
- const structSpec = this.findStructOrUnionSpecifier(declSpecs);
117
- if (structSpec) {
118
- // For typedef struct, extract the typedef name from declarationSpecifiers
119
- const typedefName = isTypedef
120
- ? this.extractTypedefNameFromSpecs(declSpecs)
121
- : undefined;
122
- this.collectStructOrUnion(structSpec, line, typedefName, isTypedef);
123
- }
124
-
125
- // Check for enum
126
- const enumSpec = this.findEnumSpecifier(declSpecs);
127
- if (enumSpec) {
128
- this.collectEnum(enumSpec, line);
129
- }
130
-
131
- // Collect declarators (variables, function prototypes, typedefs)
132
- const initDeclList = decl.initDeclaratorList();
133
- if (initDeclList) {
134
- const baseType = this.extractTypeFromDeclSpecs(declSpecs);
135
- this.collectInitDeclaratorList(
136
- initDeclList,
137
- baseType,
138
- isTypedef,
139
- isExtern,
140
- line,
141
- );
142
- } else {
143
- // Handle case where identifier is parsed as typedefName in declarationSpecifiers
144
- // This happens for:
145
- // - Simple typedefs: typedef int MyInt;
146
- // - Variable declarations: int x;
147
- // - Anonymous struct variables: struct { int x; } point;
148
- // For structs/enums with their own name (struct Point {...};), the typedefName
149
- // will be the same as the struct/enum name and we skip it to avoid duplicates.
150
- this.collectFromDeclSpecsTypedefName(
151
- declSpecs,
152
- isTypedef,
153
- isExtern,
154
- line,
155
- structSpec,
156
- enumSpec,
157
- );
158
- }
159
- }
160
-
161
- /**
162
- * Collect symbols when identifier appears as typedefName in declarationSpecifiers
163
- * instead of in initDeclaratorList. This is a C grammar ambiguity.
164
- */
165
- private collectFromDeclSpecsTypedefName(
166
- declSpecs: DeclarationSpecifiersContext,
167
- isTypedef: boolean,
168
- isExtern: boolean,
169
- line: number,
170
- structSpec?: StructOrUnionSpecifierContext | null,
171
- enumSpec?: EnumSpecifierContext | null,
172
- ): void {
173
- const specs = declSpecs.declarationSpecifier();
174
- const { name: lastTypedefName, index: lastTypedefIndex } =
175
- this._findLastTypedefName(specs);
176
-
177
- if (!lastTypedefName || lastTypedefIndex < 0) return;
178
-
179
- // Skip duplicates for non-typedef declarations
180
- if (
181
- !isTypedef &&
182
- this._shouldSkipDuplicateTypedefName(
183
- lastTypedefName,
184
- structSpec,
185
- enumSpec,
186
- )
187
- ) {
188
- return;
189
- }
190
-
191
- const baseType = this._buildBaseTypeFromSpecs(specs, lastTypedefIndex);
192
- if (isTypedef) {
193
- this._addTypeSymbol(lastTypedefName, baseType, line);
194
- } else {
195
- this._addVariableSymbol(lastTypedefName, baseType, isExtern, line);
196
- }
197
- }
198
-
199
- /**
200
- * Extract typedef name from declaration specifiers.
201
- * For "typedef struct { ... } AppConfig;", this returns "AppConfig".
202
- * SonarCloud S3776: Extracted from collectDeclaration().
203
- */
204
- private extractTypedefNameFromSpecs(
205
- declSpecs: DeclarationSpecifiersContext,
206
- ): string | undefined {
207
- for (const spec of declSpecs.declarationSpecifier()) {
208
- const typeSpec = spec.typeSpecifier();
209
- if (typeSpec) {
210
- const typeName = typeSpec.typedefName?.();
211
- if (typeName) {
212
- return typeName.getText();
213
- }
214
- }
215
- }
216
- return undefined;
217
- }
218
-
219
- /**
220
- * Find the last typedefName in declaration specifiers.
221
- */
222
- private _findLastTypedefName(specs: DeclarationSpecifierContext[]): {
223
- name: string | undefined;
224
- index: number;
225
- } {
226
- let name: string | undefined;
227
- let index = -1;
228
-
229
- for (let i = 0; i < specs.length; i++) {
230
- const typeSpec = specs[i].typeSpecifier();
231
- const typedefName = typeSpec?.typedefName?.();
232
- if (typedefName) {
233
- name = typedefName.getText();
234
- index = i;
235
- }
236
- }
237
-
238
- return { name, index };
239
- }
240
-
241
- /**
242
- * Check if typedef name should be skipped to avoid duplicates.
243
- * For "struct Point { ... };" - "Point" is both struct name and typedefName.
244
- */
245
- private _shouldSkipDuplicateTypedefName(
246
- typedefName: string,
247
- structSpec?: StructOrUnionSpecifierContext | null,
248
- enumSpec?: EnumSpecifierContext | null,
249
- ): boolean {
250
- const structName = structSpec?.Identifier()?.getText();
251
- if (structName === typedefName) return true;
252
-
253
- const enumName = enumSpec?.Identifier()?.getText();
254
- if (enumName === typedefName) return true;
255
-
256
- return false;
257
- }
258
-
259
- /**
260
- * Build base type string from specifiers before the typedef name.
261
- */
262
- private _buildBaseTypeFromSpecs(
263
- specs: DeclarationSpecifierContext[],
264
- endIndex: number,
265
- ): string {
266
- const typeParts: string[] = [];
267
- for (let i = 0; i < endIndex; i++) {
268
- const typeSpec = specs[i].typeSpecifier();
269
- if (typeSpec) {
270
- typeParts.push(typeSpec.getText());
271
- }
272
- }
273
- return typeParts.join(" ") || "int";
274
- }
275
-
276
- /**
277
- * Add a type symbol (from typedef).
278
- */
279
- private _addTypeSymbol(name: string, baseType: string, line: number): void {
280
- SymbolCollectorContext.addSymbol(this.ctx, {
281
- name,
282
- kind: ESymbolKind.Type,
283
- type: baseType,
284
- sourceFile: this.ctx.sourceFile,
285
- sourceLine: line,
286
- sourceLanguage: ESourceLanguage.C,
287
- isExported: true,
288
- });
289
- }
290
-
291
- /**
292
- * Add a variable symbol.
293
- */
294
- private _addVariableSymbol(
295
- name: string,
296
- baseType: string,
297
- isExtern: boolean,
298
- line: number,
299
- ): void {
300
- SymbolCollectorContext.addSymbol(this.ctx, {
301
- name,
302
- kind: ESymbolKind.Variable,
303
- type: baseType,
304
- sourceFile: this.ctx.sourceFile,
305
- sourceLine: line,
306
- sourceLanguage: ESourceLanguage.C,
307
- isExported: !isExtern,
308
- isDeclaration: isExtern,
309
- });
310
- }
311
-
312
- private collectInitDeclaratorList(
313
- initDeclList: InitDeclaratorListContext,
314
- baseType: string,
315
- isTypedef: boolean,
316
- isExtern: boolean,
317
- line: number,
318
- ): void {
319
- for (const initDecl of initDeclList.initDeclarator()) {
320
- const declarator = initDecl.declarator();
321
- if (!declarator) continue;
322
-
323
- const name = this.extractDeclaratorName(declarator);
324
- if (!name) continue;
325
-
326
- // Check if this is a function declaration (has parameter list)
327
- const isFunction = this.declaratorIsFunction(declarator);
328
-
329
- if (isTypedef) {
330
- SymbolCollectorContext.addSymbol(this.ctx, {
331
- name,
332
- kind: ESymbolKind.Type,
333
- type: baseType,
334
- sourceFile: this.ctx.sourceFile,
335
- sourceLine: line,
336
- sourceLanguage: ESourceLanguage.C,
337
- isExported: true,
338
- });
339
- } else if (isFunction) {
340
- SymbolCollectorContext.addSymbol(this.ctx, {
341
- name,
342
- kind: ESymbolKind.Function,
343
- type: baseType,
344
- sourceFile: this.ctx.sourceFile,
345
- sourceLine: line,
346
- sourceLanguage: ESourceLanguage.C,
347
- isExported: !isExtern,
348
- isDeclaration: true,
349
- });
350
- } else {
351
- this._addVariableSymbol(name, baseType, isExtern, line);
352
- }
353
- }
354
- }
355
-
356
- private collectStructOrUnion(
357
- structSpec: StructOrUnionSpecifierContext,
358
- line: number,
359
- typedefName?: string,
360
- isTypedef?: boolean,
361
- ): void {
362
- const identifier = structSpec.Identifier();
363
-
364
- // Use typedef name for anonymous structs (e.g., typedef struct { ... } AppConfig;)
365
- const name = identifier?.getText() || typedefName;
366
- if (!name) return; // Skip if no name available
367
-
368
- const isUnion = structSpec.structOrUnion()?.getText() === "union";
369
-
370
- SymbolCollectorContext.addSymbol(this.ctx, {
371
- name,
372
- kind: ESymbolKind.Struct,
373
- type: isUnion ? "union" : "struct",
374
- sourceFile: this.ctx.sourceFile,
375
- sourceLine: line,
376
- sourceLanguage: ESourceLanguage.C,
377
- isExported: true,
378
- });
379
-
380
- // Issue #196 Bug 3: Mark named structs that are not typedef'd
381
- // These require 'struct' keyword when referenced in C
382
- // Example: "struct NamedPoint { ... };" -> needs "struct NamedPoint var"
383
- // But "typedef struct { ... } Rectangle;" -> just "Rectangle var"
384
- if (this.ctx.symbolTable && identifier && !isTypedef) {
385
- this.ctx.symbolTable.markNeedsStructKeyword(name);
386
- }
387
-
388
- // Extract struct field information if SymbolTable is available
389
- if (this.ctx.symbolTable) {
390
- const declList = structSpec.structDeclarationList();
391
- if (declList) {
392
- for (const structDecl of declList.structDeclaration()) {
393
- this.collectStructFields(name, structDecl);
394
- }
395
- }
396
- }
397
- }
398
-
399
- private collectEnum(enumSpec: EnumSpecifierContext, line: number): void {
400
- const identifier = enumSpec.Identifier();
401
- if (!identifier) return;
402
-
403
- const name = identifier.getText();
404
-
405
- SymbolCollectorContext.addSymbol(this.ctx, {
406
- name,
407
- kind: ESymbolKind.Enum,
408
- sourceFile: this.ctx.sourceFile,
409
- sourceLine: line,
410
- sourceLanguage: ESourceLanguage.C,
411
- isExported: true,
412
- });
413
-
414
- // Collect enum members
415
- const enumList = enumSpec.enumeratorList();
416
- if (enumList) {
417
- for (const enumeratorDef of enumList.enumerator()) {
418
- const enumConst = enumeratorDef.enumerationConstant();
419
- if (enumConst) {
420
- const memberName = enumConst.Identifier()?.getText();
421
- if (memberName) {
422
- SymbolCollectorContext.addSymbol(this.ctx, {
423
- name: memberName,
424
- kind: ESymbolKind.EnumMember,
425
- sourceFile: this.ctx.sourceFile,
426
- sourceLine: enumeratorDef.start?.line ?? line,
427
- sourceLanguage: ESourceLanguage.C,
428
- isExported: true,
429
- parent: name,
430
- });
431
- }
432
- }
433
- }
434
- }
435
- }
436
-
437
- /**
438
- * Collect struct field information
439
- */
440
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
441
- private collectStructFields(structName: string, structDecl: any): void {
442
- const specQualList = structDecl.specifierQualifierList?.();
443
- if (!specQualList) return;
444
-
445
- // Extract the field type from specifierQualifierList
446
- const fieldType = this.extractTypeFromSpecQualList(specQualList);
447
-
448
- // Extract field names from structDeclaratorList
449
- const structDeclList = structDecl.structDeclaratorList?.();
450
- if (!structDeclList) return;
451
-
452
- for (const structDeclarator of structDeclList.structDeclarator()) {
453
- const declarator = structDeclarator.declarator?.();
454
- if (!declarator) continue;
455
-
456
- const fieldName = this.extractDeclaratorName(declarator);
457
- if (!fieldName) continue;
458
-
459
- // Warn if field name conflicts with C-Next reserved property names
460
- if (SymbolUtils.isReservedFieldName(fieldName)) {
461
- SymbolCollectorContext.addWarning(
462
- this.ctx,
463
- SymbolUtils.getReservedFieldWarning("C", structName, fieldName),
464
- );
465
- }
466
-
467
- // Check if this field is an array and extract dimensions
468
- const arrayDimensions = this.extractArrayDimensions(declarator);
469
-
470
- // Add to SymbolTable
471
- this.ctx.symbolTable!.addStructField(
472
- structName,
473
- fieldName,
474
- fieldType,
475
- arrayDimensions.length > 0 ? arrayDimensions : undefined,
476
- );
477
- }
478
- }
479
-
480
- /**
481
- * Extract type from specifierQualifierList (for struct fields)
482
- * Issue #196 Bug 1 Fix: For struct/union field types, extract just the
483
- * identifier (e.g., "InnerConfig") not the concatenated text ("structInnerConfig")
484
- */
485
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
486
- private extractTypeFromSpecQualList(specQualList: any): string {
487
- const parts: string[] = [];
488
-
489
- // Traverse the specifierQualifierList
490
- let current = specQualList;
491
- while (current) {
492
- const typeSpec = current.typeSpecifier?.();
493
- if (typeSpec) {
494
- // Check for struct/union specifier - need to extract just the identifier
495
- const structSpec = typeSpec.structOrUnionSpecifier?.();
496
- if (structSpec) {
497
- const identifier = structSpec.Identifier?.();
498
- if (identifier) {
499
- // Use just the struct/union name, not "structName" concatenated
500
- parts.push(identifier.getText());
501
- } else {
502
- // Anonymous struct - use full text
503
- parts.push(typeSpec.getText());
504
- }
505
- } else {
506
- parts.push(typeSpec.getText());
507
- }
508
- }
509
-
510
- const typeQual = current.typeQualifier?.();
511
- if (typeQual) {
512
- parts.push(typeQual.getText());
513
- }
514
-
515
- current = current.specifierQualifierList?.();
516
- }
517
-
518
- return parts.join(" ") || "int";
519
- }
520
-
521
- /**
522
- * Extract array dimensions from a declarator
523
- */
524
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
525
- private extractArrayDimensions(declarator: any): number[] {
526
- // Navigate to directDeclarator
527
- const directDecl = declarator.directDeclarator?.();
528
- if (!directDecl) return [];
529
-
530
- // Use shared utility for regex-based extraction
531
- return SymbolUtils.parseArrayDimensions(directDecl.getText());
532
- }
533
-
534
- // Helper methods
535
-
536
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
537
- private extractDeclaratorName(declarator: any): string | null {
538
- // Direct declarator contains the identifier
539
- const directDecl = declarator.directDeclarator?.();
540
- if (!directDecl) return null;
541
-
542
- return this.extractDirectDeclaratorName(directDecl);
543
- }
544
-
545
- /**
546
- * Issue #355: Extract identifier from directDeclarator, handling arrays and function pointers.
547
- * The C grammar has recursive directDeclarator for arrays: `directDeclarator '[' ... ']'`
548
- * so `buf[8]` is parsed as directDeclarator('[', directDeclarator('buf'), ']')
549
- */
550
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
551
- private extractDirectDeclaratorName(directDecl: any): string | null {
552
- // Check for identifier (base case)
553
- const identifier = directDecl.Identifier?.();
554
- if (identifier) {
555
- return identifier.getText();
556
- }
557
-
558
- // Nested declarator in parentheses: '(' declarator ')'
559
- const nestedDecl = directDecl.declarator?.();
560
- if (nestedDecl) {
561
- return this.extractDeclaratorName(nestedDecl);
562
- }
563
-
564
- // Issue #355: Nested directDeclarator for arrays/functions
565
- // Grammar: directDeclarator '[' ... ']' or directDeclarator '(' ... ')'
566
- const nestedDirectDecl = directDecl.directDeclarator?.();
567
- if (nestedDirectDecl) {
568
- return this.extractDirectDeclaratorName(nestedDirectDecl);
569
- }
570
-
571
- return null;
572
- }
573
-
574
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
575
- private declaratorIsFunction(declarator: any): boolean {
576
- const directDecl = declarator.directDeclarator?.();
577
- if (!directDecl) return false;
578
-
579
- // Check for parameter type list (function with params) or empty parens (function without params)
580
- // The C grammar: directDeclarator '(' parameterTypeList ')' | directDeclarator '(' identifierList? ')'
581
- if (directDecl.parameterTypeList?.() !== null) return true;
582
-
583
- // Check for LeftParen token - indicates function declarator even with empty params
584
- if (directDecl.LeftParen?.()) return true;
585
-
586
- return false;
587
- }
588
-
589
- private extractTypeFromDeclSpecs(
590
- declSpecs: DeclarationSpecifiersContext,
591
- ): string {
592
- const parts: string[] = [];
593
-
594
- for (const spec of declSpecs.declarationSpecifier()) {
595
- const typeSpec = spec.typeSpecifier();
596
- if (typeSpec) {
597
- parts.push(typeSpec.getText());
598
- }
599
- }
600
-
601
- return parts.join(" ") || "int";
602
- }
603
-
604
- private hasStorageClass(
605
- declSpecs: DeclarationSpecifiersContext,
606
- storage: string,
607
- ): boolean {
608
- for (const spec of declSpecs.declarationSpecifier()) {
609
- const storageSpec = spec.storageClassSpecifier();
610
- if (storageSpec?.getText() === storage) {
611
- return true;
612
- }
613
- }
614
- return false;
615
- }
616
-
617
- private findStructOrUnionSpecifier(
618
- declSpecs: DeclarationSpecifiersContext,
619
- ): StructOrUnionSpecifierContext | null {
620
- for (const spec of declSpecs.declarationSpecifier()) {
621
- const typeSpec = spec.typeSpecifier();
622
- if (typeSpec) {
623
- const structSpec = typeSpec.structOrUnionSpecifier?.();
624
- if (structSpec) {
625
- return structSpec;
626
- }
627
- }
628
- }
629
- return null;
630
- }
631
-
632
- private findEnumSpecifier(
633
- declSpecs: DeclarationSpecifiersContext,
634
- ): EnumSpecifierContext | null {
635
- for (const spec of declSpecs.declarationSpecifier()) {
636
- const typeSpec = spec.typeSpecifier();
637
- if (typeSpec) {
638
- const enumSpec = typeSpec.enumSpecifier?.();
639
- if (enumSpec) {
640
- return enumSpec;
641
- }
642
- }
643
- }
644
- return null;
645
- }
646
- }
647
-
648
- export default CSymbolCollector;