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.
- 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 +180 -63
- 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 +729 -265
- package/src/transpiler/logic/symbols/SymbolUtils.ts +2 -2
- package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +415 -751
- 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/IPipelineInput.ts +0 -3
- 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,14 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Unified Symbol Table
|
|
3
3
|
* Stores symbols from all source languages and detects conflicts
|
|
4
|
+
*
|
|
5
|
+
* ADR-055 Phase 7: Fully typed symbol storage using discriminated unions.
|
|
6
|
+
* - TSymbol: C-Next symbols (rich type system with TType)
|
|
7
|
+
* - TCSymbol: C header symbols (string types)
|
|
8
|
+
* - TCppSymbol: C++ header symbols (string types)
|
|
4
9
|
*/
|
|
5
10
|
|
|
6
|
-
import ISymbol from "../../../utils/types/ISymbol";
|
|
7
11
|
import ESourceLanguage from "../../../utils/types/ESourceLanguage";
|
|
8
|
-
import ESymbolKind from "../../../utils/types/ESymbolKind";
|
|
9
12
|
import LiteralUtils from "../../../utils/LiteralUtils";
|
|
10
|
-
import IConflict from "
|
|
11
|
-
import IStructFieldInfo from "
|
|
13
|
+
import IConflict from "../../types/IConflict";
|
|
14
|
+
import IStructFieldInfo from "../../types/symbols/IStructFieldInfo";
|
|
15
|
+
import TSymbol from "../../types/symbols/TSymbol";
|
|
16
|
+
import TCSymbol from "../../types/symbols/c/TCSymbol";
|
|
17
|
+
import TCppSymbol from "../../types/symbols/cpp/TCppSymbol";
|
|
18
|
+
import TAnySymbol from "../../types/symbols/TAnySymbol";
|
|
19
|
+
import IStructSymbol from "../../types/symbols/IStructSymbol";
|
|
20
|
+
import IEnumSymbol from "../../types/symbols/IEnumSymbol";
|
|
21
|
+
import IFunctionSymbol from "../../types/symbols/IFunctionSymbol";
|
|
22
|
+
import IVariableSymbol from "../../types/symbols/IVariableSymbol";
|
|
23
|
+
import TypeResolver from "../../../utils/TypeResolver";
|
|
24
|
+
import SymbolNameUtils from "./cnext/utils/SymbolNameUtils";
|
|
12
25
|
|
|
13
26
|
/**
|
|
14
27
|
* Central symbol table for cross-language interoperability
|
|
@@ -19,11 +32,39 @@ import IStructFieldInfo from "./types/IStructFieldInfo";
|
|
|
19
32
|
* - OK: Function overloads in C++ (different signatures)
|
|
20
33
|
*/
|
|
21
34
|
class SymbolTable {
|
|
22
|
-
|
|
23
|
-
|
|
35
|
+
// ========================================================================
|
|
36
|
+
// C-Next Symbol Storage (TSymbol)
|
|
37
|
+
// ========================================================================
|
|
38
|
+
|
|
39
|
+
/** All C-Next TSymbols indexed by name */
|
|
40
|
+
private readonly tSymbols: Map<string, TSymbol[]> = new Map();
|
|
41
|
+
|
|
42
|
+
/** C-Next TSymbols indexed by source file */
|
|
43
|
+
private readonly tSymbolsByFile: Map<string, TSymbol[]> = new Map();
|
|
44
|
+
|
|
45
|
+
// ========================================================================
|
|
46
|
+
// C Symbol Storage (TCSymbol)
|
|
47
|
+
// ========================================================================
|
|
48
|
+
|
|
49
|
+
/** All C symbols indexed by name */
|
|
50
|
+
private readonly cSymbols: Map<string, TCSymbol[]> = new Map();
|
|
51
|
+
|
|
52
|
+
/** C symbols indexed by source file */
|
|
53
|
+
private readonly cSymbolsByFile: Map<string, TCSymbol[]> = new Map();
|
|
54
|
+
|
|
55
|
+
// ========================================================================
|
|
56
|
+
// C++ Symbol Storage (TCppSymbol)
|
|
57
|
+
// ========================================================================
|
|
58
|
+
|
|
59
|
+
/** All C++ symbols indexed by name */
|
|
60
|
+
private readonly cppSymbols: Map<string, TCppSymbol[]> = new Map();
|
|
24
61
|
|
|
25
|
-
/**
|
|
26
|
-
private readonly
|
|
62
|
+
/** C++ symbols indexed by source file */
|
|
63
|
+
private readonly cppSymbolsByFile: Map<string, TCppSymbol[]> = new Map();
|
|
64
|
+
|
|
65
|
+
// ========================================================================
|
|
66
|
+
// Auxiliary Data (shared across languages)
|
|
67
|
+
// ========================================================================
|
|
27
68
|
|
|
28
69
|
/** Struct field information: struct name -> (field name -> field info) */
|
|
29
70
|
private readonly structFields: Map<string, Map<string, IStructFieldInfo>> =
|
|
@@ -42,331 +83,466 @@ class SymbolTable {
|
|
|
42
83
|
*/
|
|
43
84
|
private readonly enumBitWidth: Map<string, number> = new Map();
|
|
44
85
|
|
|
86
|
+
// ========================================================================
|
|
87
|
+
// C-Next Symbol Methods (TSymbol)
|
|
88
|
+
// ========================================================================
|
|
89
|
+
|
|
45
90
|
/**
|
|
46
|
-
* Add a
|
|
91
|
+
* Add a C-Next TSymbol to the table
|
|
47
92
|
*/
|
|
48
|
-
|
|
93
|
+
addTSymbol(symbol: TSymbol): void {
|
|
49
94
|
// Add to name index
|
|
50
|
-
const existing = this.
|
|
95
|
+
const existing = this.tSymbols.get(symbol.name);
|
|
51
96
|
if (existing) {
|
|
52
97
|
existing.push(symbol);
|
|
53
98
|
} else {
|
|
54
|
-
this.
|
|
99
|
+
this.tSymbols.set(symbol.name, [symbol]);
|
|
55
100
|
}
|
|
56
101
|
|
|
57
102
|
// Add to file index
|
|
58
|
-
const fileSymbols = this.
|
|
103
|
+
const fileSymbols = this.tSymbolsByFile.get(symbol.sourceFile);
|
|
59
104
|
if (fileSymbols) {
|
|
60
105
|
fileSymbols.push(symbol);
|
|
61
106
|
} else {
|
|
62
|
-
this.
|
|
107
|
+
this.tSymbolsByFile.set(symbol.sourceFile, [symbol]);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Auto-register struct fields for TypeResolver.getMemberTypeInfo()
|
|
111
|
+
if (symbol.kind === "struct") {
|
|
112
|
+
this.registerStructFields(symbol);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Register struct fields in structFields map for cross-file type resolution.
|
|
118
|
+
* Called automatically when adding struct symbols.
|
|
119
|
+
*/
|
|
120
|
+
private registerStructFields(struct: IStructSymbol): void {
|
|
121
|
+
const mangledName = SymbolNameUtils.getMangledName(struct);
|
|
122
|
+
|
|
123
|
+
for (const [fieldName, fieldInfo] of struct.fields) {
|
|
124
|
+
// Convert TType to string for structFields map
|
|
125
|
+
const typeString = TypeResolver.getTypeName(fieldInfo.type);
|
|
126
|
+
|
|
127
|
+
// Filter to only numeric dimensions (structFields doesn't support string dims)
|
|
128
|
+
const numericDims = fieldInfo.dimensions?.filter(
|
|
129
|
+
(d): d is number => typeof d === "number",
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
this.addStructField(
|
|
133
|
+
mangledName,
|
|
134
|
+
fieldName,
|
|
135
|
+
typeString,
|
|
136
|
+
numericDims && numericDims.length > 0 ? numericDims : undefined,
|
|
137
|
+
);
|
|
63
138
|
}
|
|
64
139
|
}
|
|
65
140
|
|
|
66
141
|
/**
|
|
67
|
-
* Add multiple
|
|
142
|
+
* Add multiple C-Next TSymbols at once
|
|
68
143
|
*/
|
|
69
|
-
|
|
144
|
+
addTSymbols(symbols: TSymbol[]): void {
|
|
70
145
|
for (const symbol of symbols) {
|
|
71
|
-
this.
|
|
146
|
+
this.addTSymbol(symbol);
|
|
72
147
|
}
|
|
73
148
|
}
|
|
74
149
|
|
|
75
150
|
/**
|
|
76
|
-
* Get a
|
|
151
|
+
* Get a TSymbol by name (returns first match, or undefined)
|
|
77
152
|
*/
|
|
78
|
-
|
|
79
|
-
const symbols = this.
|
|
153
|
+
getTSymbol(name: string): TSymbol | undefined {
|
|
154
|
+
const symbols = this.tSymbols.get(name);
|
|
80
155
|
return symbols?.[0];
|
|
81
156
|
}
|
|
82
157
|
|
|
83
158
|
/**
|
|
84
|
-
* Get all
|
|
159
|
+
* Get all TSymbols with a given name (for overload detection)
|
|
85
160
|
*/
|
|
86
|
-
|
|
87
|
-
return this.
|
|
161
|
+
getTOverloads(name: string): TSymbol[] {
|
|
162
|
+
return this.tSymbols.get(name) ?? [];
|
|
88
163
|
}
|
|
89
164
|
|
|
90
165
|
/**
|
|
91
|
-
*
|
|
166
|
+
* Get TSymbols by source file
|
|
92
167
|
*/
|
|
93
|
-
|
|
94
|
-
return this.
|
|
168
|
+
getTSymbolsByFile(file: string): TSymbol[] {
|
|
169
|
+
return this.tSymbolsByFile.get(file) ?? [];
|
|
95
170
|
}
|
|
96
171
|
|
|
97
172
|
/**
|
|
98
|
-
*
|
|
173
|
+
* Get all TSymbols
|
|
99
174
|
*/
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
175
|
+
getAllTSymbols(): TSymbol[] {
|
|
176
|
+
const result: TSymbol[] = [];
|
|
177
|
+
for (const symbols of this.tSymbols.values()) {
|
|
178
|
+
result.push(...symbols);
|
|
104
179
|
}
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Get all struct symbols (type-safe filtering)
|
|
185
|
+
*/
|
|
186
|
+
getStructSymbols(): IStructSymbol[] {
|
|
187
|
+
return this.getAllTSymbols().filter(
|
|
188
|
+
(s): s is IStructSymbol => s.kind === "struct",
|
|
189
|
+
);
|
|
190
|
+
}
|
|
105
191
|
|
|
106
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Get all enum symbols (type-safe filtering)
|
|
194
|
+
*/
|
|
195
|
+
getEnumSymbols(): IEnumSymbol[] {
|
|
196
|
+
return this.getAllTSymbols().filter(
|
|
197
|
+
(s): s is IEnumSymbol => s.kind === "enum",
|
|
198
|
+
);
|
|
107
199
|
}
|
|
108
200
|
|
|
109
201
|
/**
|
|
110
|
-
* Get all
|
|
111
|
-
* Per user requirement: Strict errors for cross-language conflicts
|
|
202
|
+
* Get all function symbols (type-safe filtering)
|
|
112
203
|
*/
|
|
113
|
-
|
|
114
|
-
|
|
204
|
+
getFunctionSymbols(): IFunctionSymbol[] {
|
|
205
|
+
return this.getAllTSymbols().filter(
|
|
206
|
+
(s): s is IFunctionSymbol => s.kind === "function",
|
|
207
|
+
);
|
|
208
|
+
}
|
|
115
209
|
|
|
116
|
-
|
|
117
|
-
|
|
210
|
+
/**
|
|
211
|
+
* Get all variable symbols (type-safe filtering)
|
|
212
|
+
*/
|
|
213
|
+
getVariableSymbols(): IVariableSymbol[] {
|
|
214
|
+
return this.getAllTSymbols().filter(
|
|
215
|
+
(s): s is IVariableSymbol => s.kind === "variable",
|
|
216
|
+
);
|
|
217
|
+
}
|
|
118
218
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
219
|
+
/**
|
|
220
|
+
* Get struct field type directly from TSymbol storage.
|
|
221
|
+
* This method queries IStructSymbol.fields directly, eliminating the need
|
|
222
|
+
* for the separate structFields Map for C-Next symbols.
|
|
223
|
+
*
|
|
224
|
+
* @param structName Name of the struct
|
|
225
|
+
* @param fieldName Name of the field
|
|
226
|
+
* @returns Field type string or undefined if not found
|
|
227
|
+
*/
|
|
228
|
+
getTStructFieldType(
|
|
229
|
+
structName: string,
|
|
230
|
+
fieldName: string,
|
|
231
|
+
): string | undefined {
|
|
232
|
+
const struct = this.getTOverloads(structName).find(
|
|
233
|
+
(s): s is IStructSymbol => s.kind === "struct",
|
|
234
|
+
);
|
|
235
|
+
if (!struct) {
|
|
236
|
+
return undefined;
|
|
123
237
|
}
|
|
124
|
-
|
|
125
|
-
return
|
|
238
|
+
const field = struct.fields.get(fieldName);
|
|
239
|
+
return field ? TypeResolver.getTypeName(field.type) : undefined;
|
|
126
240
|
}
|
|
127
241
|
|
|
128
242
|
/**
|
|
129
|
-
*
|
|
243
|
+
* Check if a TSymbol exists by name
|
|
130
244
|
*/
|
|
131
|
-
|
|
132
|
-
return this.
|
|
245
|
+
hasTSymbol(name: string): boolean {
|
|
246
|
+
return this.tSymbols.has(name);
|
|
133
247
|
}
|
|
134
248
|
|
|
135
249
|
/**
|
|
136
|
-
* Get
|
|
250
|
+
* Get TSymbol count
|
|
137
251
|
*/
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
for (const symbols of this.
|
|
141
|
-
|
|
142
|
-
if (symbol.sourceLanguage === lang) {
|
|
143
|
-
result.push(symbol);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
252
|
+
getTSize(): number {
|
|
253
|
+
let count = 0;
|
|
254
|
+
for (const symbols of this.tSymbols.values()) {
|
|
255
|
+
count += symbols.length;
|
|
146
256
|
}
|
|
147
|
-
return
|
|
257
|
+
return count;
|
|
148
258
|
}
|
|
149
259
|
|
|
260
|
+
// ========================================================================
|
|
261
|
+
// C Symbol Methods (TCSymbol)
|
|
262
|
+
// ========================================================================
|
|
263
|
+
|
|
150
264
|
/**
|
|
151
|
-
*
|
|
265
|
+
* Add a C symbol to the table
|
|
152
266
|
*/
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
267
|
+
addCSymbol(symbol: TCSymbol): void {
|
|
268
|
+
// Add to name index
|
|
269
|
+
const existing = this.cSymbols.get(symbol.name);
|
|
270
|
+
if (existing) {
|
|
271
|
+
existing.push(symbol);
|
|
272
|
+
} else {
|
|
273
|
+
this.cSymbols.set(symbol.name, [symbol]);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Add to file index
|
|
277
|
+
const fileSymbols = this.cSymbolsByFile.get(symbol.sourceFile);
|
|
278
|
+
if (fileSymbols) {
|
|
279
|
+
fileSymbols.push(symbol);
|
|
280
|
+
} else {
|
|
281
|
+
this.cSymbolsByFile.set(symbol.sourceFile, [symbol]);
|
|
157
282
|
}
|
|
158
|
-
return result;
|
|
159
283
|
}
|
|
160
284
|
|
|
161
285
|
/**
|
|
162
|
-
* Add
|
|
163
|
-
* @param structName Name of the struct
|
|
164
|
-
* @param fieldName Name of the field
|
|
165
|
-
* @param fieldType Type of the field (e.g., "uint32_t")
|
|
166
|
-
* @param arrayDimensions Optional array dimensions if field is an array
|
|
286
|
+
* Add multiple C symbols at once
|
|
167
287
|
*/
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
fieldType: string,
|
|
172
|
-
arrayDimensions?: number[],
|
|
173
|
-
): void {
|
|
174
|
-
let fields = this.structFields.get(structName);
|
|
175
|
-
if (!fields) {
|
|
176
|
-
fields = new Map();
|
|
177
|
-
this.structFields.set(structName, fields);
|
|
288
|
+
addCSymbols(symbols: TCSymbol[]): void {
|
|
289
|
+
for (const symbol of symbols) {
|
|
290
|
+
this.addCSymbol(symbol);
|
|
178
291
|
}
|
|
179
|
-
|
|
180
|
-
fields.set(fieldName, {
|
|
181
|
-
type: fieldType,
|
|
182
|
-
arrayDimensions,
|
|
183
|
-
});
|
|
184
292
|
}
|
|
185
293
|
|
|
186
294
|
/**
|
|
187
|
-
* Get
|
|
188
|
-
* @param structName Name of the struct
|
|
189
|
-
* @param fieldName Name of the field
|
|
190
|
-
* @returns Field type or undefined if not found
|
|
295
|
+
* Get a C symbol by name (returns first match, or undefined)
|
|
191
296
|
*/
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
): string | undefined {
|
|
196
|
-
const fields = this.structFields.get(structName);
|
|
197
|
-
return fields?.get(fieldName)?.type;
|
|
297
|
+
getCSymbol(name: string): TCSymbol | undefined {
|
|
298
|
+
const symbols = this.cSymbols.get(name);
|
|
299
|
+
return symbols?.[0];
|
|
198
300
|
}
|
|
199
301
|
|
|
200
302
|
/**
|
|
201
|
-
* Get
|
|
202
|
-
* @param structName Name of the struct
|
|
203
|
-
* @param fieldName Name of the field
|
|
204
|
-
* @returns Field info or undefined if not found
|
|
303
|
+
* Get all C symbols with a given name
|
|
205
304
|
*/
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
fieldName: string,
|
|
209
|
-
): IStructFieldInfo | undefined {
|
|
210
|
-
const fields = this.structFields.get(structName);
|
|
211
|
-
return fields?.get(fieldName);
|
|
305
|
+
getCOverloads(name: string): TCSymbol[] {
|
|
306
|
+
return this.cSymbols.get(name) ?? [];
|
|
212
307
|
}
|
|
213
308
|
|
|
214
309
|
/**
|
|
215
|
-
*
|
|
216
|
-
* @param structName Name of the struct (e.g., "NamedPoint")
|
|
310
|
+
* Get C symbols by source file
|
|
217
311
|
*/
|
|
218
|
-
|
|
219
|
-
this.
|
|
312
|
+
getCSymbolsByFile(file: string): TCSymbol[] {
|
|
313
|
+
return this.cSymbolsByFile.get(file) ?? [];
|
|
220
314
|
}
|
|
221
315
|
|
|
222
316
|
/**
|
|
223
|
-
*
|
|
224
|
-
* @param structName Name of the struct
|
|
225
|
-
* @returns true if the struct was defined as 'struct Name { ... }' without typedef
|
|
317
|
+
* Get all C symbols
|
|
226
318
|
*/
|
|
227
|
-
|
|
228
|
-
|
|
319
|
+
getAllCSymbols(): TCSymbol[] {
|
|
320
|
+
const result: TCSymbol[] = [];
|
|
321
|
+
for (const symbols of this.cSymbols.values()) {
|
|
322
|
+
result.push(...symbols);
|
|
323
|
+
}
|
|
324
|
+
return result;
|
|
229
325
|
}
|
|
230
326
|
|
|
327
|
+
// ========================================================================
|
|
328
|
+
// C++ Symbol Methods (TCppSymbol)
|
|
329
|
+
// ========================================================================
|
|
330
|
+
|
|
231
331
|
/**
|
|
232
|
-
*
|
|
233
|
-
* @returns Array of struct names
|
|
332
|
+
* Add a C++ symbol to the table
|
|
234
333
|
*/
|
|
235
|
-
|
|
236
|
-
|
|
334
|
+
addCppSymbol(symbol: TCppSymbol): void {
|
|
335
|
+
// Add to name index
|
|
336
|
+
const existing = this.cppSymbols.get(symbol.name);
|
|
337
|
+
if (existing) {
|
|
338
|
+
existing.push(symbol);
|
|
339
|
+
} else {
|
|
340
|
+
this.cppSymbols.set(symbol.name, [symbol]);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// Add to file index
|
|
344
|
+
const fileSymbols = this.cppSymbolsByFile.get(symbol.sourceFile);
|
|
345
|
+
if (fileSymbols) {
|
|
346
|
+
fileSymbols.push(symbol);
|
|
347
|
+
} else {
|
|
348
|
+
this.cppSymbolsByFile.set(symbol.sourceFile, [symbol]);
|
|
349
|
+
}
|
|
237
350
|
}
|
|
238
351
|
|
|
239
352
|
/**
|
|
240
|
-
*
|
|
241
|
-
* @param structNames Array of struct names requiring 'struct' keyword
|
|
353
|
+
* Add multiple C++ symbols at once
|
|
242
354
|
*/
|
|
243
|
-
|
|
244
|
-
for (const
|
|
245
|
-
this.
|
|
355
|
+
addCppSymbols(symbols: TCppSymbol[]): void {
|
|
356
|
+
for (const symbol of symbols) {
|
|
357
|
+
this.addCppSymbol(symbol);
|
|
246
358
|
}
|
|
247
359
|
}
|
|
248
360
|
|
|
249
361
|
/**
|
|
250
|
-
*
|
|
251
|
-
* @param enumName Name of the enum (e.g., "EPressureType")
|
|
252
|
-
* @param bitWidth Bit width from backing type (e.g., 8 for uint8_t)
|
|
362
|
+
* Get a C++ symbol by name (returns first match, or undefined)
|
|
253
363
|
*/
|
|
254
|
-
|
|
255
|
-
this.
|
|
364
|
+
getCppSymbol(name: string): TCppSymbol | undefined {
|
|
365
|
+
const symbols = this.cppSymbols.get(name);
|
|
366
|
+
return symbols?.[0];
|
|
256
367
|
}
|
|
257
368
|
|
|
258
369
|
/**
|
|
259
|
-
*
|
|
260
|
-
* @param enumName Name of the enum
|
|
261
|
-
* @returns Bit width or undefined if not a typed enum
|
|
370
|
+
* Get all C++ symbols with a given name
|
|
262
371
|
*/
|
|
263
|
-
|
|
264
|
-
return this.
|
|
372
|
+
getCppOverloads(name: string): TCppSymbol[] {
|
|
373
|
+
return this.cppSymbols.get(name) ?? [];
|
|
265
374
|
}
|
|
266
375
|
|
|
267
376
|
/**
|
|
268
|
-
*
|
|
269
|
-
* @returns Map of enum name -> bit width
|
|
377
|
+
* Get C++ symbols by source file
|
|
270
378
|
*/
|
|
271
|
-
|
|
272
|
-
return this.
|
|
379
|
+
getCppSymbolsByFile(file: string): TCppSymbol[] {
|
|
380
|
+
return this.cppSymbolsByFile.get(file) ?? [];
|
|
273
381
|
}
|
|
274
382
|
|
|
275
383
|
/**
|
|
276
|
-
*
|
|
277
|
-
* @param bitWidths Map of enum name -> bit width
|
|
384
|
+
* Get all C++ symbols
|
|
278
385
|
*/
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
386
|
+
getAllCppSymbols(): TCppSymbol[] {
|
|
387
|
+
const result: TCppSymbol[] = [];
|
|
388
|
+
for (const symbols of this.cppSymbols.values()) {
|
|
389
|
+
result.push(...symbols);
|
|
282
390
|
}
|
|
391
|
+
return result;
|
|
283
392
|
}
|
|
284
393
|
|
|
394
|
+
// ========================================================================
|
|
395
|
+
// Cross-Language Methods
|
|
396
|
+
// ========================================================================
|
|
397
|
+
|
|
285
398
|
/**
|
|
286
|
-
* Get all
|
|
287
|
-
* @param structName Name of the struct
|
|
288
|
-
* @returns Map of field names to field info, or undefined if struct not found
|
|
399
|
+
* Get all symbols across all languages
|
|
289
400
|
*/
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
401
|
+
getAllSymbols(): TAnySymbol[] {
|
|
402
|
+
return [
|
|
403
|
+
...this.getAllTSymbols(),
|
|
404
|
+
...this.getAllCSymbols(),
|
|
405
|
+
...this.getAllCppSymbols(),
|
|
406
|
+
];
|
|
294
407
|
}
|
|
295
408
|
|
|
296
409
|
/**
|
|
297
|
-
* Get
|
|
298
|
-
*
|
|
410
|
+
* Get first symbol matching a name across all languages.
|
|
411
|
+
* Searches TSymbol, then C, then C++ collections.
|
|
412
|
+
* Used by ISymbolLookup interface for constructor detection.
|
|
299
413
|
*/
|
|
300
|
-
|
|
301
|
-
return
|
|
414
|
+
getSymbol(name: string): TAnySymbol | undefined {
|
|
415
|
+
return (
|
|
416
|
+
this.getTSymbol(name) ?? this.getCSymbol(name) ?? this.getCppSymbol(name)
|
|
417
|
+
);
|
|
302
418
|
}
|
|
303
419
|
|
|
304
420
|
/**
|
|
305
|
-
*
|
|
306
|
-
* Merges cached fields into the existing structFields map
|
|
307
|
-
* @param fields Map of struct name -> (field name -> field info)
|
|
421
|
+
* Get all overloads for a name across all languages
|
|
308
422
|
*/
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
existingFields = new Map();
|
|
317
|
-
this.structFields.set(structName, existingFields);
|
|
318
|
-
}
|
|
423
|
+
getOverloads(name: string): TAnySymbol[] {
|
|
424
|
+
return [
|
|
425
|
+
...this.getTOverloads(name),
|
|
426
|
+
...this.getCOverloads(name),
|
|
427
|
+
...this.getCppOverloads(name),
|
|
428
|
+
];
|
|
429
|
+
}
|
|
319
430
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
431
|
+
/**
|
|
432
|
+
* Get symbols by source file across all languages
|
|
433
|
+
*/
|
|
434
|
+
getSymbolsByFile(file: string): TAnySymbol[] {
|
|
435
|
+
return [
|
|
436
|
+
...this.getTSymbolsByFile(file),
|
|
437
|
+
...this.getCSymbolsByFile(file),
|
|
438
|
+
...this.getCppSymbolsByFile(file),
|
|
439
|
+
];
|
|
325
440
|
}
|
|
326
441
|
|
|
327
442
|
/**
|
|
328
|
-
* Get
|
|
329
|
-
* @param file Source file path
|
|
330
|
-
* @returns Array of struct names defined in that file
|
|
443
|
+
* Get symbols by source language
|
|
331
444
|
*/
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
445
|
+
getSymbolsByLanguage(lang: ESourceLanguage): TAnySymbol[] {
|
|
446
|
+
switch (lang) {
|
|
447
|
+
case ESourceLanguage.CNext:
|
|
448
|
+
return this.getAllTSymbols();
|
|
449
|
+
case ESourceLanguage.C:
|
|
450
|
+
return this.getAllCSymbols();
|
|
451
|
+
case ESourceLanguage.Cpp:
|
|
452
|
+
return this.getAllCppSymbols();
|
|
453
|
+
}
|
|
340
454
|
}
|
|
341
455
|
|
|
342
456
|
/**
|
|
343
|
-
*
|
|
457
|
+
* Check if a symbol exists in any language
|
|
344
458
|
*/
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
459
|
+
hasSymbol(name: string): boolean {
|
|
460
|
+
return (
|
|
461
|
+
this.tSymbols.has(name) ||
|
|
462
|
+
this.cSymbols.has(name) ||
|
|
463
|
+
this.cppSymbols.has(name)
|
|
464
|
+
);
|
|
351
465
|
}
|
|
352
466
|
|
|
353
467
|
/**
|
|
354
|
-
* Get symbol count
|
|
468
|
+
* Get total symbol count
|
|
355
469
|
*/
|
|
356
470
|
get size(): number {
|
|
471
|
+
return this.getTSize() + this.getCSize() + this.getCppSize();
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Get C symbol count
|
|
476
|
+
*/
|
|
477
|
+
getCSize(): number {
|
|
357
478
|
let count = 0;
|
|
358
|
-
for (const symbols of this.
|
|
479
|
+
for (const symbols of this.cSymbols.values()) {
|
|
359
480
|
count += symbols.length;
|
|
360
481
|
}
|
|
361
482
|
return count;
|
|
362
483
|
}
|
|
363
484
|
|
|
485
|
+
/**
|
|
486
|
+
* Get C++ symbol count
|
|
487
|
+
*/
|
|
488
|
+
getCppSize(): number {
|
|
489
|
+
let count = 0;
|
|
490
|
+
for (const symbols of this.cppSymbols.values()) {
|
|
491
|
+
count += symbols.length;
|
|
492
|
+
}
|
|
493
|
+
return count;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// ========================================================================
|
|
497
|
+
// Conflict Detection
|
|
498
|
+
// ========================================================================
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Check if a symbol has conflicts
|
|
502
|
+
*/
|
|
503
|
+
hasConflict(name: string): boolean {
|
|
504
|
+
const allSymbols = this.getOverloads(name);
|
|
505
|
+
if (allSymbols.length <= 1) {
|
|
506
|
+
return false;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
return this.detectConflict(allSymbols) !== null;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Get all conflicts in the symbol table
|
|
514
|
+
* Per user requirement: Strict errors for cross-language conflicts
|
|
515
|
+
*/
|
|
516
|
+
getConflicts(): IConflict[] {
|
|
517
|
+
const conflicts: IConflict[] = [];
|
|
518
|
+
const allNames = new Set<string>();
|
|
519
|
+
|
|
520
|
+
// Collect all symbol names from all languages
|
|
521
|
+
for (const name of this.tSymbols.keys()) allNames.add(name);
|
|
522
|
+
for (const name of this.cSymbols.keys()) allNames.add(name);
|
|
523
|
+
for (const name of this.cppSymbols.keys()) allNames.add(name);
|
|
524
|
+
|
|
525
|
+
for (const name of allNames) {
|
|
526
|
+
const symbols = this.getOverloads(name);
|
|
527
|
+
if (symbols.length <= 1) continue;
|
|
528
|
+
|
|
529
|
+
const conflict = this.detectConflict(symbols);
|
|
530
|
+
if (conflict) {
|
|
531
|
+
conflicts.push(conflict);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
return conflicts;
|
|
536
|
+
}
|
|
537
|
+
|
|
364
538
|
/**
|
|
365
539
|
* Detect if a set of symbols with the same name represents a conflict
|
|
366
540
|
*/
|
|
367
|
-
private detectConflict(symbols:
|
|
541
|
+
private detectConflict(symbols: TAnySymbol[]): IConflict | null {
|
|
368
542
|
// Filter out pure declarations (extern in C) - they don't count as definitions
|
|
369
|
-
const definitions = symbols.filter(
|
|
543
|
+
const definitions = symbols.filter(
|
|
544
|
+
(s) => !("isDeclaration" in s && s.isDeclaration),
|
|
545
|
+
);
|
|
370
546
|
|
|
371
547
|
if (definitions.length <= 1) {
|
|
372
548
|
// 0 or 1 definitions = no conflict
|
|
@@ -374,47 +550,58 @@ class SymbolTable {
|
|
|
374
550
|
}
|
|
375
551
|
|
|
376
552
|
// Issue #221: Filter out function parameters from conflict detection
|
|
377
|
-
// Function parameters have a parent
|
|
378
|
-
// is NOT qualified with the parent prefix (unlike scope-level variables like Math_counter).
|
|
379
|
-
// Parameters with the same name in different functions are not conflicts.
|
|
553
|
+
// Function parameters have a parent but their name is NOT qualified with the parent prefix.
|
|
380
554
|
const globalDefinitions = definitions.filter((def) => {
|
|
381
|
-
//
|
|
382
|
-
if (
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
//
|
|
387
|
-
//
|
|
388
|
-
//
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
555
|
+
// C-Next variables with scope need special handling
|
|
556
|
+
if (
|
|
557
|
+
def.sourceLanguage === ESourceLanguage.CNext &&
|
|
558
|
+
def.kind === "variable"
|
|
559
|
+
) {
|
|
560
|
+
// After sourceLanguage check, def is narrowed to TSymbol
|
|
561
|
+
// After kind check, def is narrowed to IVariableSymbol
|
|
562
|
+
// Global scope means no conflict filtering needed
|
|
563
|
+
if (def.scope.name === "") return true;
|
|
564
|
+
// Scope-level variables vs function parameters:
|
|
565
|
+
// We can't easily distinguish here, so keep all for now
|
|
566
|
+
return true;
|
|
567
|
+
}
|
|
568
|
+
// C/C++ symbols: check parent field
|
|
569
|
+
if ("parent" in def && def.parent) {
|
|
570
|
+
// Non-variable symbols with parents are kept
|
|
571
|
+
if (def.kind !== "variable") return true;
|
|
572
|
+
// Variables with parents might be function parameters - filter out
|
|
573
|
+
return false;
|
|
392
574
|
}
|
|
393
|
-
|
|
394
|
-
// Non-variable symbols with parents (functions, enums, etc.) are kept
|
|
395
575
|
return true;
|
|
396
576
|
});
|
|
397
577
|
|
|
398
578
|
if (globalDefinitions.length <= 1) {
|
|
399
|
-
// After filtering parameters, 0 or 1 definitions = no conflict
|
|
400
579
|
return null;
|
|
401
580
|
}
|
|
402
581
|
|
|
403
582
|
// Check for C++ function overloads (different signatures are OK)
|
|
404
|
-
const cppFunctions =
|
|
405
|
-
(s) =>
|
|
583
|
+
const cppFunctions = globalDefinitions.filter(
|
|
584
|
+
(s) =>
|
|
585
|
+
s.sourceLanguage === ESourceLanguage.Cpp &&
|
|
586
|
+
s.kind === "function" &&
|
|
587
|
+
"parameters" in s,
|
|
406
588
|
);
|
|
407
|
-
if (cppFunctions.length ===
|
|
408
|
-
// All are C++ functions with signatures
|
|
409
|
-
const
|
|
589
|
+
if (cppFunctions.length === globalDefinitions.length) {
|
|
590
|
+
// All are C++ functions with signatures - check for unique signatures
|
|
591
|
+
const signatures = cppFunctions.map((f) => {
|
|
592
|
+
if ("parameters" in f && f.parameters) {
|
|
593
|
+
const params = f.parameters as ReadonlyArray<{ type?: string }>;
|
|
594
|
+
return params.map((p) => p.type ?? "").join(",");
|
|
595
|
+
}
|
|
596
|
+
return "";
|
|
597
|
+
});
|
|
598
|
+
const uniqueSignatures = new Set(signatures);
|
|
410
599
|
if (uniqueSignatures.size === cppFunctions.length) {
|
|
411
|
-
// All signatures are unique = valid overload, no conflict
|
|
412
600
|
return null;
|
|
413
601
|
}
|
|
414
602
|
}
|
|
415
603
|
|
|
416
604
|
// Check for cross-language conflict (C-Next vs C or C++)
|
|
417
|
-
// Issue #221: Use globalDefinitions for C-Next to exclude function parameters
|
|
418
605
|
const cnextDefs = globalDefinitions.filter(
|
|
419
606
|
(s) => s.sourceLanguage === ESourceLanguage.CNext,
|
|
420
607
|
);
|
|
@@ -426,7 +613,6 @@ class SymbolTable {
|
|
|
426
613
|
);
|
|
427
614
|
|
|
428
615
|
if (cnextDefs.length > 0 && (cDefs.length > 0 || cppDefs.length > 0)) {
|
|
429
|
-
// C-Next + C/C++ conflict = ERROR
|
|
430
616
|
const locations = globalDefinitions.map(
|
|
431
617
|
(s) =>
|
|
432
618
|
`${s.sourceLanguage.toUpperCase()} (${s.sourceFile}:${s.sourceLine})`,
|
|
@@ -441,26 +627,261 @@ class SymbolTable {
|
|
|
441
627
|
}
|
|
442
628
|
|
|
443
629
|
// Multiple definitions in same language (excluding overloads) = ERROR
|
|
630
|
+
// Issue #817: Group by scope AND kind - symbols in different scopes don't conflict,
|
|
631
|
+
// and symbols with different kinds (variable vs scope) don't conflict either
|
|
444
632
|
if (cnextDefs.length > 1) {
|
|
445
|
-
const
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
633
|
+
const byScopeAndKind = this.groupCNextSymbolsByScopeAndKind(cnextDefs);
|
|
634
|
+
|
|
635
|
+
// Check each scope+kind group for conflicts (multiple symbols in same scope with same kind)
|
|
636
|
+
for (const symbols of byScopeAndKind.values()) {
|
|
637
|
+
if (symbols.length > 1) {
|
|
638
|
+
const locations = symbols.map(
|
|
639
|
+
(s) => `${s.sourceFile}:${s.sourceLine}`,
|
|
640
|
+
);
|
|
641
|
+
const scopeName = symbols[0].scope.name;
|
|
642
|
+
const displayName =
|
|
643
|
+
scopeName === ""
|
|
644
|
+
? symbols[0].name
|
|
645
|
+
: `${scopeName}.${symbols[0].name}`;
|
|
646
|
+
return {
|
|
647
|
+
symbolName: displayName,
|
|
648
|
+
definitions: symbols,
|
|
649
|
+
severity: "error",
|
|
650
|
+
message: `Symbol conflict: '${displayName}' is defined multiple times in C-Next:\n ${locations.join("\n ")}`,
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
}
|
|
452
654
|
}
|
|
453
655
|
|
|
454
656
|
// Same symbol in C and C++ - typically OK (same symbol)
|
|
455
|
-
// But if they have different types, might be a warning
|
|
456
657
|
if (cDefs.length > 0 && cppDefs.length > 0) {
|
|
457
|
-
// For now, allow C/C++ to share symbols (common pattern)
|
|
458
658
|
return null;
|
|
459
659
|
}
|
|
460
660
|
|
|
461
661
|
return null;
|
|
462
662
|
}
|
|
463
663
|
|
|
664
|
+
/**
|
|
665
|
+
* Issue #817: Group C-Next symbols by scope name and kind.
|
|
666
|
+
*
|
|
667
|
+
* Symbols in different scopes don't conflict (Foo.enabled vs Bar.enabled
|
|
668
|
+
* generate Foo_enabled and Bar_enabled). Symbols with different kinds also
|
|
669
|
+
* don't conflict (variable LED vs scope LED are distinct).
|
|
670
|
+
*
|
|
671
|
+
* @param symbols C-Next symbols to group (must all be TSymbol)
|
|
672
|
+
* @returns Map from "scopeName:kind" key to array of symbols
|
|
673
|
+
*/
|
|
674
|
+
private groupCNextSymbolsByScopeAndKind(
|
|
675
|
+
symbols: TAnySymbol[],
|
|
676
|
+
): Map<string, TSymbol[]> {
|
|
677
|
+
const byScopeAndKind = new Map<string, TSymbol[]>();
|
|
678
|
+
|
|
679
|
+
for (const def of symbols) {
|
|
680
|
+
const tSymbol = def as TSymbol;
|
|
681
|
+
const scopeName = tSymbol.scope.name;
|
|
682
|
+
const key = `${scopeName}:${tSymbol.kind}`;
|
|
683
|
+
const existing = byScopeAndKind.get(key);
|
|
684
|
+
if (existing) {
|
|
685
|
+
existing.push(tSymbol);
|
|
686
|
+
} else {
|
|
687
|
+
byScopeAndKind.set(key, [tSymbol]);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
return byScopeAndKind;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// ========================================================================
|
|
695
|
+
// Struct Field Information
|
|
696
|
+
// ========================================================================
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Add struct field information
|
|
700
|
+
* @param structName Name of the struct
|
|
701
|
+
* @param fieldName Name of the field
|
|
702
|
+
* @param fieldType Type of the field (e.g., "uint32_t")
|
|
703
|
+
* @param arrayDimensions Optional array dimensions if field is an array
|
|
704
|
+
*/
|
|
705
|
+
addStructField(
|
|
706
|
+
structName: string,
|
|
707
|
+
fieldName: string,
|
|
708
|
+
fieldType: string,
|
|
709
|
+
arrayDimensions?: number[],
|
|
710
|
+
): void {
|
|
711
|
+
let fields = this.structFields.get(structName);
|
|
712
|
+
if (!fields) {
|
|
713
|
+
fields = new Map();
|
|
714
|
+
this.structFields.set(structName, fields);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
fields.set(fieldName, {
|
|
718
|
+
type: fieldType,
|
|
719
|
+
arrayDimensions,
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Get struct field type
|
|
725
|
+
* @param structName Name of the struct
|
|
726
|
+
* @param fieldName Name of the field
|
|
727
|
+
* @returns Field type or undefined if not found
|
|
728
|
+
*/
|
|
729
|
+
getStructFieldType(
|
|
730
|
+
structName: string,
|
|
731
|
+
fieldName: string,
|
|
732
|
+
): string | undefined {
|
|
733
|
+
const fields = this.structFields.get(structName);
|
|
734
|
+
return fields?.get(fieldName)?.type;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* Get struct field info (type and array dimensions)
|
|
739
|
+
* @param structName Name of the struct
|
|
740
|
+
* @param fieldName Name of the field
|
|
741
|
+
* @returns Field info or undefined if not found
|
|
742
|
+
*/
|
|
743
|
+
getStructFieldInfo(
|
|
744
|
+
structName: string,
|
|
745
|
+
fieldName: string,
|
|
746
|
+
): IStructFieldInfo | undefined {
|
|
747
|
+
const fields = this.structFields.get(structName);
|
|
748
|
+
return fields?.get(fieldName);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Get all fields for a struct
|
|
753
|
+
* @param structName Name of the struct
|
|
754
|
+
* @returns Map of field names to field info, or undefined if struct not found
|
|
755
|
+
*/
|
|
756
|
+
getStructFields(
|
|
757
|
+
structName: string,
|
|
758
|
+
): Map<string, IStructFieldInfo> | undefined {
|
|
759
|
+
return this.structFields.get(structName);
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
/**
|
|
763
|
+
* Get all struct fields for cache serialization
|
|
764
|
+
* @returns Map of struct name -> (field name -> field info)
|
|
765
|
+
*/
|
|
766
|
+
getAllStructFields(): Map<string, Map<string, IStructFieldInfo>> {
|
|
767
|
+
return this.structFields;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Restore struct fields from cache
|
|
772
|
+
* Merges cached fields into the existing structFields map
|
|
773
|
+
* @param fields Map of struct name -> (field name -> field info)
|
|
774
|
+
*/
|
|
775
|
+
restoreStructFields(
|
|
776
|
+
fields: Map<string, Map<string, IStructFieldInfo>>,
|
|
777
|
+
): void {
|
|
778
|
+
for (const [structName, fieldMap] of fields) {
|
|
779
|
+
let existingFields = this.structFields.get(structName);
|
|
780
|
+
if (!existingFields) {
|
|
781
|
+
existingFields = new Map();
|
|
782
|
+
this.structFields.set(structName, existingFields);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
for (const [fieldName, fieldInfo] of fieldMap) {
|
|
786
|
+
existingFields.set(fieldName, fieldInfo);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* Get struct names defined in a specific source file
|
|
793
|
+
* @param file Source file path
|
|
794
|
+
* @returns Array of struct names defined in that file
|
|
795
|
+
*/
|
|
796
|
+
getStructNamesByFile(file: string): string[] {
|
|
797
|
+
const fileSymbols = this.getSymbolsByFile(file);
|
|
798
|
+
const symbolNames = fileSymbols.map((s) => s.name);
|
|
799
|
+
return symbolNames.filter((name) => this.structFields.has(name));
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
// ========================================================================
|
|
803
|
+
// Struct Keyword Tracking
|
|
804
|
+
// ========================================================================
|
|
805
|
+
|
|
806
|
+
/**
|
|
807
|
+
* Issue #196 Bug 3: Mark a struct as requiring 'struct' keyword in C
|
|
808
|
+
* @param structName Name of the struct (e.g., "NamedPoint")
|
|
809
|
+
*/
|
|
810
|
+
markNeedsStructKeyword(structName: string): void {
|
|
811
|
+
this.needsStructKeyword.add(structName);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
/**
|
|
815
|
+
* Issue #196 Bug 3: Check if a struct requires 'struct' keyword in C
|
|
816
|
+
* @param structName Name of the struct
|
|
817
|
+
* @returns true if the struct was defined as 'struct Name { ... }' without typedef
|
|
818
|
+
*/
|
|
819
|
+
checkNeedsStructKeyword(structName: string): boolean {
|
|
820
|
+
return this.needsStructKeyword.has(structName);
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* Issue #196 Bug 3: Get all struct names requiring 'struct' keyword
|
|
825
|
+
* @returns Array of struct names
|
|
826
|
+
*/
|
|
827
|
+
getAllNeedsStructKeyword(): string[] {
|
|
828
|
+
return Array.from(this.needsStructKeyword);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
/**
|
|
832
|
+
* Issue #196 Bug 3: Restore needsStructKeyword from cache
|
|
833
|
+
* @param structNames Array of struct names requiring 'struct' keyword
|
|
834
|
+
*/
|
|
835
|
+
restoreNeedsStructKeyword(structNames: string[]): void {
|
|
836
|
+
for (const name of structNames) {
|
|
837
|
+
this.needsStructKeyword.add(name);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// ========================================================================
|
|
842
|
+
// Enum Bit Width Tracking
|
|
843
|
+
// ========================================================================
|
|
844
|
+
|
|
845
|
+
/**
|
|
846
|
+
* Issue #208: Add enum bit width for a typed enum
|
|
847
|
+
* @param enumName Name of the enum (e.g., "EPressureType")
|
|
848
|
+
* @param bitWidth Bit width from backing type (e.g., 8 for uint8_t)
|
|
849
|
+
*/
|
|
850
|
+
addEnumBitWidth(enumName: string, bitWidth: number): void {
|
|
851
|
+
this.enumBitWidth.set(enumName, bitWidth);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
/**
|
|
855
|
+
* Issue #208: Get enum bit width for a typed enum
|
|
856
|
+
* @param enumName Name of the enum
|
|
857
|
+
* @returns Bit width or undefined if not a typed enum
|
|
858
|
+
*/
|
|
859
|
+
getEnumBitWidth(enumName: string): number | undefined {
|
|
860
|
+
return this.enumBitWidth.get(enumName);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
/**
|
|
864
|
+
* Issue #208: Get all enum bit widths for cache serialization
|
|
865
|
+
* @returns Map of enum name -> bit width
|
|
866
|
+
*/
|
|
867
|
+
getAllEnumBitWidths(): Map<string, number> {
|
|
868
|
+
return this.enumBitWidth;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
/**
|
|
872
|
+
* Issue #208: Restore enum bit widths from cache
|
|
873
|
+
* @param bitWidths Map of enum name -> bit width
|
|
874
|
+
*/
|
|
875
|
+
restoreEnumBitWidths(bitWidths: Map<string, number>): void {
|
|
876
|
+
for (const [enumName, width] of bitWidths) {
|
|
877
|
+
this.enumBitWidth.set(enumName, width);
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// ========================================================================
|
|
882
|
+
// External Array Dimension Resolution
|
|
883
|
+
// ========================================================================
|
|
884
|
+
|
|
464
885
|
/**
|
|
465
886
|
* Issue #461: Resolve external const array dimensions
|
|
466
887
|
*
|
|
@@ -472,59 +893,102 @@ class SymbolTable {
|
|
|
472
893
|
* external .cnx files that were not available during initial symbol collection.
|
|
473
894
|
*/
|
|
474
895
|
resolveExternalArrayDimensions(): void {
|
|
475
|
-
|
|
896
|
+
const constValues = this.buildConstValuesMap();
|
|
897
|
+
if (constValues.size === 0) {
|
|
898
|
+
return;
|
|
899
|
+
}
|
|
900
|
+
this.resolveArrayDimensionsWithConstants(constValues);
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* Build a map of const variable names to their integer values.
|
|
905
|
+
*/
|
|
906
|
+
private buildConstValuesMap(): Map<string, number> {
|
|
476
907
|
const constValues = new Map<string, number>();
|
|
477
|
-
for (const symbol of this.
|
|
478
|
-
if (
|
|
479
|
-
|
|
480
|
-
symbol.
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
constValues.set(symbol.name, value);
|
|
908
|
+
for (const symbol of this.getAllTSymbols()) {
|
|
909
|
+
if (symbol.kind === "variable" && symbol.isConst) {
|
|
910
|
+
// After kind check, symbol is narrowed to IVariableSymbol
|
|
911
|
+
if (symbol.initialValue !== undefined) {
|
|
912
|
+
const value = LiteralUtils.parseIntegerLiteral(symbol.initialValue);
|
|
913
|
+
if (value !== undefined) {
|
|
914
|
+
constValues.set(symbol.name, value);
|
|
915
|
+
}
|
|
486
916
|
}
|
|
487
917
|
}
|
|
488
918
|
}
|
|
919
|
+
return constValues;
|
|
920
|
+
}
|
|
489
921
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
for (const symbol of this.
|
|
922
|
+
/**
|
|
923
|
+
* Resolve string array dimensions using const values lookup.
|
|
924
|
+
*/
|
|
925
|
+
private resolveArrayDimensionsWithConstants(
|
|
926
|
+
constValues: Map<string, number>,
|
|
927
|
+
): void {
|
|
928
|
+
for (const symbol of this.getAllTSymbols()) {
|
|
497
929
|
if (
|
|
498
|
-
symbol.kind ===
|
|
930
|
+
symbol.kind === "variable" &&
|
|
499
931
|
symbol.isArray &&
|
|
500
932
|
symbol.arrayDimensions
|
|
501
933
|
) {
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
return dim;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
// Try to resolve from const values
|
|
511
|
-
const constValue = constValues.get(dim);
|
|
512
|
-
if (constValue !== undefined) {
|
|
513
|
-
modified = true;
|
|
514
|
-
return String(constValue);
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
// Keep original (unresolved macro reference)
|
|
518
|
-
return dim;
|
|
519
|
-
});
|
|
934
|
+
// After kind check, symbol is narrowed to IVariableSymbol
|
|
935
|
+
this.resolveVariableArrayDimensions(symbol, constValues);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
520
939
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
940
|
+
/**
|
|
941
|
+
* Resolve array dimensions for a single variable symbol.
|
|
942
|
+
*/
|
|
943
|
+
private resolveVariableArrayDimensions(
|
|
944
|
+
variable: IVariableSymbol,
|
|
945
|
+
constValues: Map<string, number>,
|
|
946
|
+
): void {
|
|
947
|
+
let modified = false;
|
|
948
|
+
const resolvedDimensions = variable.arrayDimensions!.map((dim) => {
|
|
949
|
+
if (typeof dim === "number") {
|
|
950
|
+
return dim;
|
|
525
951
|
}
|
|
952
|
+
const constValue = constValues.get(dim);
|
|
953
|
+
if (constValue !== undefined) {
|
|
954
|
+
modified = true;
|
|
955
|
+
return constValue;
|
|
956
|
+
}
|
|
957
|
+
return dim;
|
|
958
|
+
});
|
|
959
|
+
|
|
960
|
+
if (modified) {
|
|
961
|
+
// Mutate in place - symbol is already in storage, cloning would require
|
|
962
|
+
// updating all maps. The readonly typing prevents accidental mutations
|
|
963
|
+
// elsewhere; this controlled mutation is intentional during resolution.
|
|
964
|
+
(
|
|
965
|
+
variable as unknown as { arrayDimensions: (number | string)[] }
|
|
966
|
+
).arrayDimensions = resolvedDimensions;
|
|
526
967
|
}
|
|
527
968
|
}
|
|
969
|
+
|
|
970
|
+
// ========================================================================
|
|
971
|
+
// Clear / Reset
|
|
972
|
+
// ========================================================================
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* Clear all symbols
|
|
976
|
+
*/
|
|
977
|
+
clear(): void {
|
|
978
|
+
// C-Next
|
|
979
|
+
this.tSymbols.clear();
|
|
980
|
+
this.tSymbolsByFile.clear();
|
|
981
|
+
// C
|
|
982
|
+
this.cSymbols.clear();
|
|
983
|
+
this.cSymbolsByFile.clear();
|
|
984
|
+
// C++
|
|
985
|
+
this.cppSymbols.clear();
|
|
986
|
+
this.cppSymbolsByFile.clear();
|
|
987
|
+
// Auxiliary
|
|
988
|
+
this.structFields.clear();
|
|
989
|
+
this.needsStructKeyword.clear();
|
|
990
|
+
this.enumBitWidth.clear();
|
|
991
|
+
}
|
|
528
992
|
}
|
|
529
993
|
|
|
530
994
|
export default SymbolTable;
|