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.
- package/package.json +1 -1
- package/src/lib/__tests__/parseCHeader.mocked.test.ts +69 -54
- package/src/lib/parseCHeader.ts +56 -23
- package/src/lib/parseWithSymbols.ts +195 -53
- package/src/transpiler/Transpiler.ts +173 -60
- package/src/transpiler/logic/analysis/FunctionCallAnalyzer.ts +1 -2
- package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +1 -2
- package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +51 -2
- package/src/transpiler/logic/analysis/__tests__/FunctionCallAnalyzer.test.ts +18 -12
- package/src/transpiler/logic/analysis/__tests__/InitializationAnalyzer.test.ts +9 -9
- package/src/transpiler/logic/analysis/__tests__/runAnalyzers.test.ts +5 -5
- package/src/transpiler/logic/symbols/SymbolTable.ts +676 -258
- package/src/transpiler/logic/symbols/SymbolUtils.ts +2 -2
- package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +290 -782
- package/src/transpiler/logic/symbols/c/__tests__/CResolver.integration.test.ts +573 -0
- package/src/transpiler/logic/symbols/c/__tests__/testHelpers.ts +20 -0
- package/src/transpiler/logic/symbols/c/collectors/EnumCollector.ts +82 -0
- package/src/transpiler/logic/symbols/c/collectors/FunctionCollector.ts +106 -0
- package/src/transpiler/logic/symbols/c/collectors/StructCollector.ts +173 -0
- package/src/transpiler/logic/symbols/c/collectors/TypedefCollector.ts +35 -0
- package/src/transpiler/logic/symbols/c/collectors/VariableCollector.ts +80 -0
- package/src/transpiler/logic/symbols/c/index.ts +333 -0
- package/src/transpiler/logic/symbols/c/utils/DeclaratorUtils.ts +269 -0
- package/src/transpiler/logic/symbols/cnext/__tests__/BitmapCollector.test.ts +50 -11
- package/src/transpiler/logic/symbols/cnext/__tests__/CNextResolver.integration.test.ts +45 -34
- package/src/transpiler/logic/symbols/cnext/__tests__/EnumCollector.test.ts +30 -13
- package/src/transpiler/logic/symbols/cnext/__tests__/FunctionCollector.test.ts +279 -64
- package/src/transpiler/logic/symbols/cnext/__tests__/RegisterCollector.test.ts +60 -13
- package/src/transpiler/logic/symbols/cnext/__tests__/ScopeCollector.test.ts +40 -37
- package/src/transpiler/logic/symbols/cnext/__tests__/StructCollector.test.ts +131 -45
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolInfoAdapter.test.ts +223 -139
- package/src/transpiler/logic/symbols/cnext/__tests__/VariableCollector.test.ts +79 -25
- package/src/transpiler/logic/symbols/cnext/__tests__/testUtils.ts +53 -0
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolInfoAdapter.ts +83 -43
- package/src/transpiler/logic/symbols/cnext/collectors/BitmapCollector.ts +14 -13
- package/src/transpiler/logic/symbols/cnext/collectors/EnumCollector.ts +11 -10
- package/src/transpiler/logic/symbols/cnext/collectors/FunctionCollector.ts +83 -34
- package/src/transpiler/logic/symbols/cnext/collectors/RegisterCollector.ts +22 -18
- package/src/transpiler/logic/symbols/cnext/collectors/ScopeCollector.ts +53 -35
- package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +30 -23
- package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +18 -19
- package/src/transpiler/logic/symbols/cnext/index.ts +36 -14
- package/src/transpiler/logic/symbols/cnext/types/IScopeCollectorResult.ts +2 -2
- package/src/transpiler/logic/symbols/cnext/utils/SymbolNameUtils.ts +27 -0
- package/src/transpiler/logic/symbols/cpp/__tests__/CppResolver.integration.test.ts +270 -0
- package/src/transpiler/logic/symbols/cpp/__tests__/testHelpers.ts +20 -0
- package/src/transpiler/logic/symbols/cpp/collectors/ClassCollector.ts +317 -0
- package/src/transpiler/logic/symbols/cpp/collectors/EnumCollector.ts +71 -0
- package/src/transpiler/logic/symbols/cpp/collectors/FunctionCollector.ts +155 -0
- package/src/transpiler/logic/symbols/cpp/collectors/NamespaceCollector.ts +65 -0
- package/src/transpiler/logic/symbols/cpp/collectors/TypeAliasCollector.ts +46 -0
- package/src/transpiler/logic/symbols/cpp/collectors/VariableCollector.ts +54 -0
- package/src/transpiler/logic/symbols/cpp/index.ts +366 -0
- package/src/transpiler/logic/symbols/cpp/utils/DeclaratorUtils.ts +248 -0
- package/src/transpiler/logic/symbols/shared/IExtractedParameter.ts +18 -0
- package/src/transpiler/logic/symbols/shared/ParameterExtractorUtils.ts +73 -0
- package/src/transpiler/output/codegen/CodeGenerator.ts +268 -1674
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +7 -1
- package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +2 -1
- package/src/transpiler/output/codegen/assignment/handlers/AssignmentHandlerUtils.ts +7 -1
- package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +6 -2
- package/src/transpiler/output/codegen/assignment/handlers/RegisterHandlers.ts +2 -1
- package/src/transpiler/output/codegen/generators/declarationGenerators/ScopeGenerator.ts +21 -8
- package/src/transpiler/output/codegen/generators/declarationGenerators/ScopedRegisterGenerator.ts +3 -2
- package/src/transpiler/output/codegen/generators/expressions/CallExprUtils.ts +9 -3
- package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprGenerator.test.ts +3 -4
- package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprUtils.test.ts +4 -8
- package/src/transpiler/output/codegen/helpers/ArgumentGenerator.ts +236 -0
- package/src/transpiler/output/codegen/helpers/CppConstructorHelper.ts +3 -3
- package/src/transpiler/output/codegen/helpers/FunctionContextManager.ts +435 -0
- package/src/transpiler/output/codegen/helpers/StringOperationsHelper.ts +203 -0
- package/src/transpiler/output/codegen/helpers/SymbolLookupHelper.ts +8 -12
- package/src/transpiler/output/codegen/helpers/TypeRegistrationEngine.ts +520 -0
- package/src/transpiler/output/codegen/helpers/VariableDeclHelper.ts +735 -0
- package/src/transpiler/output/codegen/helpers/VariableDeclarationFormatter.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/ArgumentGenerator.test.ts +521 -0
- package/src/transpiler/output/codegen/helpers/__tests__/CppConstructorHelper.test.ts +4 -5
- package/src/transpiler/output/codegen/helpers/__tests__/FunctionContextManager.test.ts +983 -0
- package/src/transpiler/output/codegen/helpers/__tests__/StringOperationsHelper.test.ts +269 -0
- package/src/transpiler/output/codegen/helpers/__tests__/SymbolLookupHelper.test.ts +31 -32
- package/src/transpiler/output/codegen/helpers/__tests__/TypeRegistrationEngine.test.ts +186 -0
- package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclHelper.test.ts +460 -0
- package/src/transpiler/output/codegen/helpers/types/IArgumentGeneratorCallbacks.ts +32 -0
- package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +5 -1
- package/src/transpiler/output/codegen/types/IFunctionContextCallbacks.ts +12 -0
- package/src/transpiler/output/codegen/types/IVariableFormatInput.ts +1 -1
- package/src/transpiler/output/codegen/utils/QualifiedNameGenerator.ts +114 -0
- package/src/transpiler/output/codegen/utils/__tests__/QualifiedNameGenerator.test.ts +183 -0
- package/src/transpiler/output/headers/BaseHeaderGenerator.ts +4 -4
- package/src/transpiler/output/headers/ExternalTypeHeaderBuilder.ts +7 -7
- package/src/transpiler/output/headers/HeaderGenerator.ts +9 -7
- package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +19 -20
- package/src/transpiler/output/headers/__tests__/BaseHeaderGenerator.test.ts +15 -18
- package/src/transpiler/output/headers/__tests__/CHeaderGenerator.test.ts +63 -64
- package/src/transpiler/output/headers/__tests__/CppHeaderGenerator.test.ts +36 -32
- package/src/transpiler/output/headers/__tests__/ExternalTypeHeaderBuilder.test.ts +26 -26
- package/src/transpiler/output/headers/__tests__/HeaderGenerator.test.ts +87 -59
- package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +57 -58
- package/src/transpiler/output/headers/adapters/HeaderSymbolAdapter.ts +222 -0
- package/src/transpiler/output/headers/adapters/__tests__/HeaderSymbolAdapter.test.ts +538 -0
- package/src/transpiler/output/headers/types/IGroupedSymbols.ts +8 -8
- package/src/transpiler/output/headers/types/IHeaderSymbol.ts +62 -0
- package/src/transpiler/state/CodeGenState.ts +20 -33
- package/src/transpiler/state/SymbolRegistry.ts +181 -0
- package/src/transpiler/{types → state}/TranspilerState.ts +1 -1
- package/src/transpiler/state/__tests__/CodeGenState.test.ts +67 -59
- package/src/transpiler/state/__tests__/SymbolRegistry.test.ts +249 -0
- package/src/transpiler/{types → state}/__tests__/TranspilerState.test.ts +1 -1
- package/src/transpiler/types/ICachedFileEntry.ts +1 -1
- package/src/transpiler/types/IConflict.ts +14 -0
- package/src/transpiler/types/ISerializedSymbol.ts +11 -0
- package/src/transpiler/types/TPrimitiveKind.ts +20 -0
- package/src/transpiler/types/TType.ts +103 -0
- package/src/transpiler/types/TVisibility.ts +6 -0
- package/src/transpiler/types/symbol-kinds/TSymbolKind.ts +10 -0
- package/src/transpiler/types/symbol-kinds/TSymbolKindC.ts +12 -0
- package/src/transpiler/types/symbol-kinds/TSymbolKindCNext.ts +16 -0
- package/src/transpiler/types/symbol-kinds/TSymbolKindCpp.ts +14 -0
- package/src/transpiler/types/symbols/IBaseSymbol.ts +31 -0
- package/src/transpiler/{logic/symbols/types → types/symbols}/IBitmapFieldInfo.ts +2 -2
- package/src/transpiler/types/symbols/IBitmapSymbol.ts +21 -0
- package/src/transpiler/{logic/symbols/types → types/symbols}/IEnumSymbol.ts +5 -6
- package/src/transpiler/types/symbols/IFieldInfo.ts +26 -0
- package/src/transpiler/types/symbols/IFunctionSymbol.ts +30 -0
- package/src/transpiler/types/symbols/IParameterInfo.ts +26 -0
- package/src/transpiler/{logic/symbols/types → types/symbols}/IRegisterMemberInfo.ts +4 -4
- package/src/transpiler/types/symbols/IRegisterSymbol.ts +18 -0
- package/src/transpiler/types/symbols/IScopeSymbol.ts +32 -0
- package/src/transpiler/{logic/symbols/types → types/symbols}/IStructFieldInfo.ts +2 -1
- package/src/transpiler/types/symbols/IStructSymbol.ts +15 -0
- package/src/transpiler/types/symbols/IVariableSymbol.ts +30 -0
- package/src/transpiler/types/symbols/SymbolGuards.ts +43 -0
- package/src/transpiler/types/symbols/TAnySymbol.ts +22 -0
- package/src/transpiler/types/symbols/TSymbol.ts +32 -0
- package/src/transpiler/types/symbols/__tests__/IBaseSymbol.test.ts +56 -0
- package/src/transpiler/types/symbols/__tests__/SymbolGuards.test.ts +57 -0
- package/src/transpiler/types/symbols/c/ICBaseSymbol.ts +28 -0
- package/src/transpiler/types/symbols/c/ICEnumMemberSymbol.ts +17 -0
- package/src/transpiler/types/symbols/c/ICEnumSymbol.ts +17 -0
- package/src/transpiler/types/symbols/c/ICFieldInfo.ts +16 -0
- package/src/transpiler/types/symbols/c/ICFunctionSymbol.ts +21 -0
- package/src/transpiler/types/symbols/c/ICParameterInfo.ts +19 -0
- package/src/transpiler/types/symbols/c/ICStructSymbol.ts +21 -0
- package/src/transpiler/types/symbols/c/ICTypedefSymbol.ts +14 -0
- package/src/transpiler/types/symbols/c/ICVariableSymbol.ts +26 -0
- package/src/transpiler/types/symbols/c/TCSymbol.ts +26 -0
- package/src/transpiler/types/symbols/cpp/ICppBaseSymbol.ts +31 -0
- package/src/transpiler/types/symbols/cpp/ICppClassSymbol.ts +15 -0
- package/src/transpiler/types/symbols/cpp/ICppEnumMemberSymbol.ts +14 -0
- package/src/transpiler/types/symbols/cpp/ICppEnumSymbol.ts +14 -0
- package/src/transpiler/types/symbols/cpp/ICppFieldInfo.ts +16 -0
- package/src/transpiler/types/symbols/cpp/ICppFunctionSymbol.ts +21 -0
- package/src/transpiler/types/symbols/cpp/ICppNamespaceSymbol.ts +11 -0
- package/src/transpiler/types/symbols/cpp/ICppParameterInfo.ts +19 -0
- package/src/transpiler/types/symbols/cpp/ICppStructSymbol.ts +16 -0
- package/src/transpiler/types/symbols/cpp/ICppTypeAliasSymbol.ts +14 -0
- package/src/transpiler/types/symbols/cpp/ICppVariableSymbol.ts +23 -0
- package/src/transpiler/types/symbols/cpp/TCppSymbol.ts +30 -0
- package/src/utils/CppNamespaceUtils.ts +3 -4
- package/src/utils/FunctionUtils.ts +92 -0
- package/src/utils/ParameterUtils.ts +55 -0
- package/src/utils/PrimitiveKindUtils.ts +33 -0
- package/src/utils/ScopeUtils.ts +105 -0
- package/src/utils/TTypeUtils.ts +159 -0
- package/src/utils/TypeResolver.ts +132 -0
- package/src/utils/__tests__/CppNamespaceUtils.test.ts +92 -99
- package/src/utils/__tests__/FunctionUtils.test.ts +284 -0
- package/src/utils/__tests__/ParameterUtils.test.ts +174 -0
- package/src/utils/__tests__/PrimitiveKindUtils.test.ts +59 -0
- package/src/utils/__tests__/ScopeUtils.test.ts +53 -0
- package/src/utils/__tests__/TTypeUtils.test.ts +245 -0
- package/src/utils/__tests__/TypeResolver.test.ts +332 -0
- package/src/utils/cache/CacheManager.ts +91 -50
- package/src/utils/cache/__tests__/CacheManager.test.ts +180 -114
- package/src/transpiler/logic/symbols/AutoConstUpdater.ts +0 -93
- package/src/transpiler/logic/symbols/CSymbolCollector.ts +0 -648
- package/src/transpiler/logic/symbols/CppSymbolCollector.ts +0 -874
- package/src/transpiler/logic/symbols/SymbolCollectorContext.ts +0 -68
- package/src/transpiler/logic/symbols/__tests__/AutoConstUpdater.test.ts +0 -418
- package/src/transpiler/logic/symbols/__tests__/CSymbolCollector.test.ts +0 -685
- package/src/transpiler/logic/symbols/__tests__/CppSymbolCollector.test.ts +0 -1146
- package/src/transpiler/logic/symbols/__tests__/SymbolCollectorContext.test.ts +0 -290
- package/src/transpiler/logic/symbols/__tests__/cTestHelpers.ts +0 -43
- package/src/transpiler/logic/symbols/__tests__/cppTestHelpers.ts +0 -40
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +0 -595
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +0 -345
- package/src/transpiler/logic/symbols/types/IBaseSymbol.ts +0 -27
- package/src/transpiler/logic/symbols/types/IBitmapSymbol.ts +0 -23
- package/src/transpiler/logic/symbols/types/ICollectorContext.ts +0 -19
- package/src/transpiler/logic/symbols/types/IConflict.ts +0 -20
- package/src/transpiler/logic/symbols/types/IFieldInfo.ts +0 -18
- package/src/transpiler/logic/symbols/types/IFunctionSymbol.ts +0 -25
- package/src/transpiler/logic/symbols/types/IParameterInfo.ts +0 -24
- package/src/transpiler/logic/symbols/types/IRegisterSymbol.ts +0 -20
- package/src/transpiler/logic/symbols/types/IScopeSymbol.ts +0 -19
- package/src/transpiler/logic/symbols/types/IStructSymbol.ts +0 -16
- package/src/transpiler/logic/symbols/types/IVariableSymbol.ts +0 -30
- package/src/transpiler/logic/symbols/types/TSymbol.ts +0 -36
- package/src/transpiler/logic/symbols/types/__tests__/SymbolGuards.test.ts +0 -244
- package/src/transpiler/logic/symbols/types/typeGuards.ts +0 -44
- package/src/utils/types/ESymbolKind.ts +0 -19
- package/src/utils/types/ISymbol.ts +0 -64
- /package/src/transpiler/{types → constants}/BITMAP_BACKING_TYPE.ts +0 -0
- /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;
|