c-next 0.1.69 → 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 +240 -205
- package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +1 -2
- package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +742 -0
- package/src/transpiler/logic/analysis/__tests__/FunctionCallAnalyzer.test.ts +102 -15
- 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/{output/codegen → logic/analysis}/helpers/AssignmentTargetExtractor.ts +1 -1
- package/src/transpiler/{output/codegen → logic/analysis}/helpers/ChildStatementCollector.ts +1 -1
- package/src/transpiler/{output/codegen → logic/analysis}/helpers/StatementExpressionCollector.ts +1 -1
- package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/AssignmentTargetExtractor.test.ts +2 -2
- package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/ChildStatementCollector.test.ts +2 -2
- package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/StatementExpressionCollector.test.ts +2 -2
- 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 +310 -2288
- package/src/transpiler/output/codegen/TypeRegistrationUtils.ts +4 -6
- package/src/transpiler/output/codegen/TypeResolver.ts +2 -2
- package/src/transpiler/output/codegen/TypeValidator.ts +5 -5
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +7 -1
- package/src/transpiler/output/codegen/__tests__/TypeRegistrationUtils.test.ts +36 -51
- package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +20 -17
- package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +3 -3
- package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +1 -1
- package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +1 -1
- package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +9 -9
- package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +12 -12
- package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +13 -12
- package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +23 -17
- package/src/transpiler/output/codegen/assignment/handlers/ArrayHandlers.ts +2 -2
- package/src/transpiler/output/codegen/assignment/handlers/AssignmentHandlerUtils.ts +7 -1
- package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +3 -3
- package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +9 -5
- package/src/transpiler/output/codegen/assignment/handlers/RegisterHandlers.ts +2 -1
- package/src/transpiler/output/codegen/assignment/handlers/SpecialHandlers.ts +4 -4
- package/src/transpiler/output/codegen/assignment/handlers/StringHandlers.ts +5 -5
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/ArrayHandlers.test.ts +23 -25
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts +20 -36
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitmapHandlers.test.ts +18 -18
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/SpecialHandlers.test.ts +42 -32
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/handlerTestUtils.ts +5 -4
- 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/CallExprGenerator.ts +14 -6
- package/src/transpiler/output/codegen/generators/expressions/CallExprUtils.ts +9 -3
- package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +19 -16
- package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprGenerator.test.ts +24 -8
- package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprUtils.test.ts +4 -8
- package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +15 -2
- package/src/transpiler/output/codegen/helpers/ArgumentGenerator.ts +236 -0
- package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +2 -1
- package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +2 -2
- package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +3 -3
- package/src/transpiler/output/codegen/helpers/CppConstructorHelper.ts +3 -3
- package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +1 -1
- package/src/transpiler/output/codegen/helpers/FunctionContextManager.ts +435 -0
- package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +2 -2
- 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__/ArrayInitHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +7 -7
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +7 -7
- package/src/transpiler/output/codegen/helpers/__tests__/CppConstructorHelper.test.ts +4 -5
- package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +2 -2
- package/src/transpiler/output/codegen/helpers/__tests__/FunctionContextManager.test.ts +983 -0
- package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +4 -4
- 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 +7 -3
- package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +5 -5
- 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 +109 -4
- 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 +277 -1
- 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
- /package/src/transpiler/{output/codegen → logic/analysis}/helpers/TransitiveModificationPropagator.ts +0 -0
- /package/src/transpiler/{output/codegen → logic/analysis}/helpers/__tests__/TransitiveModificationPropagator.test.ts +0 -0
|
@@ -30,6 +30,7 @@ import ICallbackTypeInfo from "../output/codegen/types/ICallbackTypeInfo";
|
|
|
30
30
|
import ITargetCapabilities from "../output/codegen/types/ITargetCapabilities";
|
|
31
31
|
import TOverflowBehavior from "../output/codegen/types/TOverflowBehavior";
|
|
32
32
|
import TYPE_WIDTH from "../output/codegen/types/TYPE_WIDTH";
|
|
33
|
+
import TypeResolver from "../../utils/TypeResolver";
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* Default target capabilities (safe fallback)
|
|
@@ -101,8 +102,12 @@ export default class CodeGenState {
|
|
|
101
102
|
// TYPE TRACKING
|
|
102
103
|
// ===========================================================================
|
|
103
104
|
|
|
104
|
-
/**
|
|
105
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Track variable types for bit access, .length, and type inference.
|
|
107
|
+
* PRIVATE: Use getVariableTypeInfo()/setVariableTypeInfo() instead.
|
|
108
|
+
* This ensures cross-file variables from SymbolTable are also found.
|
|
109
|
+
*/
|
|
110
|
+
private static typeRegistry: Map<string, TTypeInfo> = new Map();
|
|
106
111
|
|
|
107
112
|
/** Bug #8: Compile-time const values for array size resolution */
|
|
108
113
|
static constValues: Map<string, number> = new Map();
|
|
@@ -451,9 +456,109 @@ export default class CodeGenState {
|
|
|
451
456
|
|
|
452
457
|
/**
|
|
453
458
|
* Get type info for a variable.
|
|
459
|
+
* Checks local typeRegistry first, then falls back to SymbolTable
|
|
460
|
+
* for cross-file variables from included .cnx files.
|
|
461
|
+
*
|
|
462
|
+
* Issue #786: This unified lookup ensures cross-file variables
|
|
463
|
+
* (defined in included files) are found even before code generation
|
|
464
|
+
* registers them locally.
|
|
465
|
+
*/
|
|
466
|
+
static getVariableTypeInfo(name: string): TTypeInfo | undefined {
|
|
467
|
+
// First check the local type registry (current file's variables)
|
|
468
|
+
const localInfo = this.typeRegistry.get(name);
|
|
469
|
+
if (localInfo) {
|
|
470
|
+
return localInfo;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// ADR-055 Phase 7: Fall back to SymbolTable for cross-file C-Next variables only.
|
|
474
|
+
// C/C++ header symbols don't have complete type info (e.g., isArray),
|
|
475
|
+
// so we only use C-Next TSymbols from SymbolTable.
|
|
476
|
+
const symbol = this.symbolTable.getTSymbol(name);
|
|
477
|
+
if (symbol?.kind === "variable" && symbol.type) {
|
|
478
|
+
return this.convertTSymbolToTypeInfo(symbol);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return undefined;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Legacy alias for getVariableTypeInfo.
|
|
486
|
+
* @deprecated Use getVariableTypeInfo() instead
|
|
454
487
|
*/
|
|
455
488
|
static getTypeInfo(name: string): TTypeInfo | undefined {
|
|
456
|
-
return this.
|
|
489
|
+
return this.getVariableTypeInfo(name);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Check if a variable type is registered (locally or in SymbolTable).
|
|
494
|
+
* ADR-055 Phase 7: Uses getTSymbol for typed symbol lookup.
|
|
495
|
+
*/
|
|
496
|
+
static hasVariableTypeInfo(name: string): boolean {
|
|
497
|
+
if (this.typeRegistry.has(name)) {
|
|
498
|
+
return true;
|
|
499
|
+
}
|
|
500
|
+
const symbol = this.symbolTable.getTSymbol(name);
|
|
501
|
+
return symbol?.kind === "variable" && symbol.type !== undefined;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Set variable type info in the local registry.
|
|
506
|
+
*/
|
|
507
|
+
static setVariableTypeInfo(name: string, info: TTypeInfo): void {
|
|
508
|
+
this.typeRegistry.set(name, info);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Delete variable type info from the local registry.
|
|
513
|
+
*/
|
|
514
|
+
static deleteVariableTypeInfo(name: string): void {
|
|
515
|
+
this.typeRegistry.delete(name);
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Get a read-only view of the local type registry.
|
|
520
|
+
* Used for passing to helper functions that need to iterate over types.
|
|
521
|
+
* Note: This only returns locally registered types, not cross-file symbols.
|
|
522
|
+
*/
|
|
523
|
+
static getTypeRegistryView(): ReadonlyMap<string, TTypeInfo> {
|
|
524
|
+
return this.typeRegistry;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Convert a TSymbol IVariableSymbol to TTypeInfo for unified type lookups.
|
|
529
|
+
* ADR-055 Phase 7: Works with typed TSymbol instead of ISymbol.
|
|
530
|
+
*/
|
|
531
|
+
private static convertTSymbolToTypeInfo(
|
|
532
|
+
symbol: import("../types/symbols/IVariableSymbol").default,
|
|
533
|
+
): TTypeInfo {
|
|
534
|
+
const typeName = TypeResolver.getTypeName(symbol.type);
|
|
535
|
+
|
|
536
|
+
// Parse string capacity using regex
|
|
537
|
+
const stringPattern = /^string<(\d+)>$/;
|
|
538
|
+
const stringMatch = stringPattern.exec(typeName);
|
|
539
|
+
const isString = stringMatch !== null;
|
|
540
|
+
const stringCapacity = stringMatch
|
|
541
|
+
? Number.parseInt(stringMatch[1], 10)
|
|
542
|
+
: undefined;
|
|
543
|
+
// Use char for string types to match local convention
|
|
544
|
+
const baseType = isString ? "char" : typeName;
|
|
545
|
+
|
|
546
|
+
const isEnum = this.isKnownEnum(baseType);
|
|
547
|
+
|
|
548
|
+
return {
|
|
549
|
+
baseType,
|
|
550
|
+
bitWidth: isString ? 8 : TYPE_WIDTH[baseType] || 0,
|
|
551
|
+
isArray: symbol.isArray || false,
|
|
552
|
+
arrayDimensions: symbol.arrayDimensions
|
|
553
|
+
?.map((d) => (typeof d === "number" ? d : Number.parseInt(d, 10)))
|
|
554
|
+
.filter((n) => !Number.isNaN(n)),
|
|
555
|
+
isConst: symbol.isConst || false,
|
|
556
|
+
isAtomic: symbol.isAtomic || false,
|
|
557
|
+
isEnum,
|
|
558
|
+
enumTypeName: isEnum ? baseType : undefined,
|
|
559
|
+
isString,
|
|
560
|
+
stringCapacity,
|
|
561
|
+
};
|
|
457
562
|
}
|
|
458
563
|
|
|
459
564
|
/**
|
|
@@ -785,7 +890,7 @@ export default class CodeGenState {
|
|
|
785
890
|
* Register a variable type.
|
|
786
891
|
*/
|
|
787
892
|
static registerType(name: string, info: TTypeInfo): void {
|
|
788
|
-
this.
|
|
893
|
+
this.setVariableTypeInfo(name, info);
|
|
789
894
|
}
|
|
790
895
|
|
|
791
896
|
/**
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SymbolRegistry - Central registry for C-Next symbol management
|
|
3
|
+
*
|
|
4
|
+
* Provides centralized storage and lookup for all symbols in the C-Next transpiler.
|
|
5
|
+
*
|
|
6
|
+
* Design decisions:
|
|
7
|
+
* - Static class with global state (reset between transpilation runs)
|
|
8
|
+
* - `getOrCreateScope` handles scope merging across files (same scope name = same object)
|
|
9
|
+
* - `resolveFunction` walks scope chain (current -> parent -> global)
|
|
10
|
+
* - String keys in Maps for lookup, but values are proper symbol objects
|
|
11
|
+
*/
|
|
12
|
+
import ScopeUtils from "../../utils/ScopeUtils";
|
|
13
|
+
import type IScopeSymbol from "../types/symbols/IScopeSymbol";
|
|
14
|
+
import type IFunctionSymbol from "../types/symbols/IFunctionSymbol";
|
|
15
|
+
|
|
16
|
+
class SymbolRegistry {
|
|
17
|
+
/** The global scope singleton (recreated on reset) */
|
|
18
|
+
private static globalScope: IScopeSymbol = ScopeUtils.createGlobalScope();
|
|
19
|
+
|
|
20
|
+
/** Map from scope path (e.g., "Outer.Inner") to scope object */
|
|
21
|
+
private static readonly scopes: Map<string, IScopeSymbol> = new Map();
|
|
22
|
+
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// Scope Management
|
|
25
|
+
// ============================================================================
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get the global scope singleton.
|
|
29
|
+
*
|
|
30
|
+
* The global scope has:
|
|
31
|
+
* - name: "" (empty string)
|
|
32
|
+
* - parent: points to itself (self-reference)
|
|
33
|
+
*/
|
|
34
|
+
static getGlobalScope(): IScopeSymbol {
|
|
35
|
+
return this.globalScope;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get a scope by its dotted path without creating it.
|
|
40
|
+
*
|
|
41
|
+
* Use this for read-only lookups where you don't want to create
|
|
42
|
+
* orphaned scopes. Returns null if the scope doesn't exist.
|
|
43
|
+
*/
|
|
44
|
+
static getScope(path: string): IScopeSymbol | null {
|
|
45
|
+
if (path === "") return this.globalScope;
|
|
46
|
+
return this.scopes.get(path) ?? null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get or create a scope by its dotted path.
|
|
51
|
+
*
|
|
52
|
+
* For simple names (e.g., "Test"), creates scope with global parent.
|
|
53
|
+
* For dotted paths (e.g., "Outer.Inner"), creates nested scopes.
|
|
54
|
+
*
|
|
55
|
+
* If the scope already exists, returns the existing scope.
|
|
56
|
+
* This enables scope merging across files.
|
|
57
|
+
*
|
|
58
|
+
* Note: This creates scopes that don't exist. For read-only lookups,
|
|
59
|
+
* use getScope() instead to avoid creating orphaned scopes.
|
|
60
|
+
*/
|
|
61
|
+
static getOrCreateScope(path: string): IScopeSymbol {
|
|
62
|
+
if (path === "") return this.globalScope;
|
|
63
|
+
if (this.scopes.has(path)) return this.scopes.get(path)!;
|
|
64
|
+
|
|
65
|
+
const parts = path.split(".");
|
|
66
|
+
const name = parts.pop()!;
|
|
67
|
+
const parentPath = parts.join(".");
|
|
68
|
+
const parent =
|
|
69
|
+
parentPath === "" ? this.globalScope : this.getOrCreateScope(parentPath);
|
|
70
|
+
|
|
71
|
+
const scope = ScopeUtils.createScope(name, parent);
|
|
72
|
+
this.scopes.set(path, scope);
|
|
73
|
+
return scope;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ============================================================================
|
|
77
|
+
// Function Management
|
|
78
|
+
// ============================================================================
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Register a function in its scope.
|
|
82
|
+
*
|
|
83
|
+
* The function is added to the scope's functions array.
|
|
84
|
+
*/
|
|
85
|
+
static registerFunction(func: IFunctionSymbol): void {
|
|
86
|
+
func.scope.functions.push(func);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Resolve a function by name, walking the scope chain.
|
|
91
|
+
*
|
|
92
|
+
* Searches in order:
|
|
93
|
+
* 1. Current scope
|
|
94
|
+
* 2. Parent scope
|
|
95
|
+
* 3. Parent's parent (recursively)
|
|
96
|
+
* 4. Global scope
|
|
97
|
+
*
|
|
98
|
+
* Returns null if the function is not found.
|
|
99
|
+
*/
|
|
100
|
+
static resolveFunction(
|
|
101
|
+
name: string,
|
|
102
|
+
fromScope: IScopeSymbol,
|
|
103
|
+
): IFunctionSymbol | null {
|
|
104
|
+
// Search in current scope
|
|
105
|
+
const found = fromScope.functions.find((f) => f.name === name);
|
|
106
|
+
if (found) return found;
|
|
107
|
+
|
|
108
|
+
// Walk up the scope chain (stop when we reach global scope's self-reference)
|
|
109
|
+
if (fromScope !== this.globalScope && fromScope.parent !== fromScope) {
|
|
110
|
+
return this.resolveFunction(name, fromScope.parent);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ============================================================================
|
|
117
|
+
// Reset
|
|
118
|
+
// ============================================================================
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Reset all registry state.
|
|
122
|
+
*
|
|
123
|
+
* Creates a fresh global scope and clears all registered scopes.
|
|
124
|
+
* Call this between transpilation runs.
|
|
125
|
+
*/
|
|
126
|
+
static reset(): void {
|
|
127
|
+
this.globalScope = ScopeUtils.createGlobalScope();
|
|
128
|
+
this.scopes.clear();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// Bridge Methods (for gradual migration from string-based lookups)
|
|
133
|
+
// ============================================================================
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Find a function by its C-mangled name (e.g., "Test_fillData").
|
|
137
|
+
*
|
|
138
|
+
* This is a bridge method for gradual migration. New code should use
|
|
139
|
+
* resolveFunction() with bare names and scope references instead.
|
|
140
|
+
*
|
|
141
|
+
* @param mangledName C-mangled function name (e.g., "Test_fillData", "main")
|
|
142
|
+
* @returns The function symbol, or null if not found
|
|
143
|
+
*/
|
|
144
|
+
static findByMangledName(mangledName: string): IFunctionSymbol | null {
|
|
145
|
+
// Check global scope first (no underscore = global function)
|
|
146
|
+
for (const func of this.globalScope.functions) {
|
|
147
|
+
if (func.name === mangledName) {
|
|
148
|
+
return func;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Check all scopes - the mangled name should match scope_name pattern
|
|
153
|
+
for (const [scopePath, scope] of this.scopes) {
|
|
154
|
+
const prefix = scopePath.replaceAll(".", "_") + "_";
|
|
155
|
+
for (const func of scope.functions) {
|
|
156
|
+
if (prefix + func.name === mangledName) {
|
|
157
|
+
return func;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Get the scope of a function given its C-mangled name.
|
|
167
|
+
*
|
|
168
|
+
* This is a bridge method for gradual migration.
|
|
169
|
+
*
|
|
170
|
+
* @param mangledName C-mangled function name
|
|
171
|
+
* @returns The scope the function belongs to, or null if not found
|
|
172
|
+
*/
|
|
173
|
+
static getScopeByMangledFunctionName(
|
|
174
|
+
mangledName: string,
|
|
175
|
+
): IScopeSymbol | null {
|
|
176
|
+
const func = this.findByMangledName(mangledName);
|
|
177
|
+
return func?.scope ?? null;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export default SymbolRegistry;
|
|
@@ -6,6 +6,53 @@ import { describe, it, expect, beforeEach } from "vitest";
|
|
|
6
6
|
import CodeGenState from "../CodeGenState";
|
|
7
7
|
import TTypeInfo from "../../output/codegen/types/TTypeInfo";
|
|
8
8
|
import ICodeGenSymbols from "../../types/ICodeGenSymbols";
|
|
9
|
+
import ESourceLanguage from "../../../utils/types/ESourceLanguage";
|
|
10
|
+
import IVariableSymbol from "../../types/symbols/IVariableSymbol";
|
|
11
|
+
import ICVariableSymbol from "../../types/symbols/c/ICVariableSymbol";
|
|
12
|
+
import TestScopeUtils from "../../logic/symbols/cnext/__tests__/testUtils";
|
|
13
|
+
import TTypeUtils from "../../../utils/TTypeUtils";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create a minimal C-Next IVariableSymbol for testing.
|
|
17
|
+
*/
|
|
18
|
+
function createCNextVariableSymbol(
|
|
19
|
+
overrides: Partial<IVariableSymbol> & { name: string },
|
|
20
|
+
): IVariableSymbol {
|
|
21
|
+
return {
|
|
22
|
+
kind: "variable",
|
|
23
|
+
name: overrides.name,
|
|
24
|
+
sourceFile: overrides.sourceFile ?? "test.cnx",
|
|
25
|
+
sourceLine: overrides.sourceLine ?? 1,
|
|
26
|
+
sourceLanguage: ESourceLanguage.CNext,
|
|
27
|
+
isExported: overrides.isExported ?? false,
|
|
28
|
+
scope: overrides.scope ?? TestScopeUtils.createMockGlobalScope(),
|
|
29
|
+
type: overrides.type ?? TTypeUtils.createPrimitive("u32"),
|
|
30
|
+
isConst: overrides.isConst ?? false,
|
|
31
|
+
isAtomic: overrides.isAtomic ?? false,
|
|
32
|
+
isArray: overrides.isArray ?? false,
|
|
33
|
+
arrayDimensions: overrides.arrayDimensions,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Create a minimal C ICVariableSymbol for testing.
|
|
39
|
+
*/
|
|
40
|
+
function createCVariableSymbol(
|
|
41
|
+
overrides: Partial<ICVariableSymbol> & { name: string; type: string },
|
|
42
|
+
): ICVariableSymbol {
|
|
43
|
+
return {
|
|
44
|
+
kind: "variable",
|
|
45
|
+
name: overrides.name,
|
|
46
|
+
sourceFile: overrides.sourceFile ?? "test.h",
|
|
47
|
+
sourceLine: overrides.sourceLine ?? 1,
|
|
48
|
+
sourceLanguage: ESourceLanguage.C,
|
|
49
|
+
isExported: overrides.isExported ?? false,
|
|
50
|
+
type: overrides.type,
|
|
51
|
+
isConst: overrides.isConst,
|
|
52
|
+
isArray: overrides.isArray,
|
|
53
|
+
arrayDimensions: overrides.arrayDimensions,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
9
56
|
|
|
10
57
|
/**
|
|
11
58
|
* Create a minimal mock ICodeGenSymbols with default empty collections.
|
|
@@ -281,7 +328,7 @@ describe("CodeGenState", () => {
|
|
|
281
328
|
|
|
282
329
|
CodeGenState.registerType("myVar", typeInfo);
|
|
283
330
|
|
|
284
|
-
expect(CodeGenState.
|
|
331
|
+
expect(CodeGenState.getVariableTypeInfo("myVar")).toBe(typeInfo);
|
|
285
332
|
});
|
|
286
333
|
|
|
287
334
|
it("registerConstValue adds to constValues", () => {
|
|
@@ -348,6 +395,235 @@ describe("CodeGenState", () => {
|
|
|
348
395
|
});
|
|
349
396
|
});
|
|
350
397
|
|
|
398
|
+
describe("Variable Type Info API (Issue #786)", () => {
|
|
399
|
+
it("getVariableTypeInfo returns local type info from registry", () => {
|
|
400
|
+
const typeInfo: TTypeInfo = {
|
|
401
|
+
baseType: "u32",
|
|
402
|
+
bitWidth: 32,
|
|
403
|
+
isArray: false,
|
|
404
|
+
isConst: false,
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
CodeGenState.setVariableTypeInfo("localVar", typeInfo);
|
|
408
|
+
|
|
409
|
+
expect(CodeGenState.getVariableTypeInfo("localVar")).toBe(typeInfo);
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
it("getVariableTypeInfo returns undefined for unknown variable", () => {
|
|
413
|
+
expect(CodeGenState.getVariableTypeInfo("unknownVar")).toBeUndefined();
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
it("getVariableTypeInfo falls back to SymbolTable for C-Next variables", () => {
|
|
417
|
+
// Add a C-Next variable to SymbolTable (simulating cross-file include)
|
|
418
|
+
CodeGenState.symbolTable.addTSymbol(
|
|
419
|
+
createCNextVariableSymbol({
|
|
420
|
+
name: "crossFileVar",
|
|
421
|
+
type: TTypeUtils.createPrimitive("u16"),
|
|
422
|
+
isArray: true,
|
|
423
|
+
arrayDimensions: [10],
|
|
424
|
+
}),
|
|
425
|
+
);
|
|
426
|
+
|
|
427
|
+
const result = CodeGenState.getVariableTypeInfo("crossFileVar");
|
|
428
|
+
|
|
429
|
+
expect(result).toBeDefined();
|
|
430
|
+
expect(result?.baseType).toBe("u16");
|
|
431
|
+
expect(result?.bitWidth).toBe(16);
|
|
432
|
+
expect(result?.isArray).toBe(true);
|
|
433
|
+
expect(result?.arrayDimensions).toEqual([10]);
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
it("getVariableTypeInfo does not use C header symbols", () => {
|
|
437
|
+
// Add a C header variable (should NOT be used)
|
|
438
|
+
CodeGenState.symbolTable.addCSymbol(
|
|
439
|
+
createCVariableSymbol({
|
|
440
|
+
name: "cHeaderVar",
|
|
441
|
+
type: "uint32_t",
|
|
442
|
+
}),
|
|
443
|
+
);
|
|
444
|
+
|
|
445
|
+
expect(CodeGenState.getVariableTypeInfo("cHeaderVar")).toBeUndefined();
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it("getVariableTypeInfo prefers local registry over SymbolTable", () => {
|
|
449
|
+
// Add both local and SymbolTable version
|
|
450
|
+
const localInfo: TTypeInfo = {
|
|
451
|
+
baseType: "i32",
|
|
452
|
+
bitWidth: 32,
|
|
453
|
+
isArray: false,
|
|
454
|
+
isConst: true,
|
|
455
|
+
};
|
|
456
|
+
CodeGenState.setVariableTypeInfo("mixedVar", localInfo);
|
|
457
|
+
|
|
458
|
+
CodeGenState.symbolTable.addTSymbol(
|
|
459
|
+
createCNextVariableSymbol({
|
|
460
|
+
name: "mixedVar",
|
|
461
|
+
type: TTypeUtils.createPrimitive("u8"),
|
|
462
|
+
}),
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
// Should return local info, not SymbolTable info
|
|
466
|
+
const result = CodeGenState.getVariableTypeInfo("mixedVar");
|
|
467
|
+
expect(result?.baseType).toBe("i32");
|
|
468
|
+
expect(result?.isConst).toBe(true);
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
it("hasVariableTypeInfo returns true for local registry", () => {
|
|
472
|
+
CodeGenState.setVariableTypeInfo("localVar", {
|
|
473
|
+
baseType: "u8",
|
|
474
|
+
bitWidth: 8,
|
|
475
|
+
isArray: false,
|
|
476
|
+
isConst: false,
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
expect(CodeGenState.hasVariableTypeInfo("localVar")).toBe(true);
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
it("hasVariableTypeInfo returns true for C-Next SymbolTable variable", () => {
|
|
483
|
+
CodeGenState.symbolTable.addTSymbol(
|
|
484
|
+
createCNextVariableSymbol({
|
|
485
|
+
name: "crossFileVar",
|
|
486
|
+
type: TTypeUtils.createPrimitive("u32"),
|
|
487
|
+
}),
|
|
488
|
+
);
|
|
489
|
+
|
|
490
|
+
expect(CodeGenState.hasVariableTypeInfo("crossFileVar")).toBe(true);
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
it("hasVariableTypeInfo returns false for unknown variable", () => {
|
|
494
|
+
expect(CodeGenState.hasVariableTypeInfo("unknownVar")).toBe(false);
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
it("hasVariableTypeInfo returns false for C header variable", () => {
|
|
498
|
+
CodeGenState.symbolTable.addCSymbol(
|
|
499
|
+
createCVariableSymbol({
|
|
500
|
+
name: "cVar",
|
|
501
|
+
type: "int",
|
|
502
|
+
}),
|
|
503
|
+
);
|
|
504
|
+
|
|
505
|
+
expect(CodeGenState.hasVariableTypeInfo("cVar")).toBe(false);
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
it("setVariableTypeInfo and deleteVariableTypeInfo work correctly", () => {
|
|
509
|
+
const typeInfo: TTypeInfo = {
|
|
510
|
+
baseType: "f32",
|
|
511
|
+
bitWidth: 32,
|
|
512
|
+
isArray: false,
|
|
513
|
+
isConst: false,
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
CodeGenState.setVariableTypeInfo("tempVar", typeInfo);
|
|
517
|
+
expect(CodeGenState.getVariableTypeInfo("tempVar")).toBe(typeInfo);
|
|
518
|
+
|
|
519
|
+
CodeGenState.deleteVariableTypeInfo("tempVar");
|
|
520
|
+
expect(CodeGenState.getVariableTypeInfo("tempVar")).toBeUndefined();
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
it("getTypeRegistryView returns readonly view", () => {
|
|
524
|
+
CodeGenState.setVariableTypeInfo("var1", {
|
|
525
|
+
baseType: "u8",
|
|
526
|
+
bitWidth: 8,
|
|
527
|
+
isArray: false,
|
|
528
|
+
isConst: false,
|
|
529
|
+
});
|
|
530
|
+
CodeGenState.setVariableTypeInfo("var2", {
|
|
531
|
+
baseType: "u16",
|
|
532
|
+
bitWidth: 16,
|
|
533
|
+
isArray: false,
|
|
534
|
+
isConst: false,
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
const view = CodeGenState.getTypeRegistryView();
|
|
538
|
+
|
|
539
|
+
expect(view.size).toBe(2);
|
|
540
|
+
expect(view.has("var1")).toBe(true);
|
|
541
|
+
expect(view.has("var2")).toBe(true);
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
it("getTypeInfo is deprecated alias for getVariableTypeInfo", () => {
|
|
545
|
+
const typeInfo: TTypeInfo = {
|
|
546
|
+
baseType: "u64",
|
|
547
|
+
bitWidth: 64,
|
|
548
|
+
isArray: false,
|
|
549
|
+
isConst: false,
|
|
550
|
+
};
|
|
551
|
+
|
|
552
|
+
CodeGenState.setVariableTypeInfo("aliasVar", typeInfo);
|
|
553
|
+
|
|
554
|
+
// getTypeInfo should return same result
|
|
555
|
+
expect(CodeGenState.getTypeInfo("aliasVar")).toBe(typeInfo);
|
|
556
|
+
});
|
|
557
|
+
|
|
558
|
+
it("convertSymbolToTypeInfo handles string<N> types", () => {
|
|
559
|
+
CodeGenState.symbolTable.addTSymbol(
|
|
560
|
+
createCNextVariableSymbol({
|
|
561
|
+
name: "myString",
|
|
562
|
+
type: TTypeUtils.createString(32),
|
|
563
|
+
}),
|
|
564
|
+
);
|
|
565
|
+
|
|
566
|
+
const result = CodeGenState.getVariableTypeInfo("myString");
|
|
567
|
+
|
|
568
|
+
expect(result?.baseType).toBe("char");
|
|
569
|
+
expect(result?.bitWidth).toBe(8);
|
|
570
|
+
expect(result?.isString).toBe(true);
|
|
571
|
+
expect(result?.stringCapacity).toBe(32);
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
it("convertSymbolToTypeInfo handles enum types", () => {
|
|
575
|
+
// Register an enum
|
|
576
|
+
CodeGenState.symbols = createMockSymbols({
|
|
577
|
+
knownEnums: new Set(["EColor"]),
|
|
578
|
+
});
|
|
579
|
+
|
|
580
|
+
CodeGenState.symbolTable.addTSymbol(
|
|
581
|
+
createCNextVariableSymbol({
|
|
582
|
+
name: "color",
|
|
583
|
+
type: TTypeUtils.createEnum("EColor"),
|
|
584
|
+
}),
|
|
585
|
+
);
|
|
586
|
+
|
|
587
|
+
const result = CodeGenState.getVariableTypeInfo("color");
|
|
588
|
+
|
|
589
|
+
expect(result?.baseType).toBe("EColor");
|
|
590
|
+
expect(result?.isEnum).toBe(true);
|
|
591
|
+
expect(result?.enumTypeName).toBe("EColor");
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
it("convertSymbolToTypeInfo handles const and atomic", () => {
|
|
595
|
+
CodeGenState.symbolTable.addTSymbol(
|
|
596
|
+
createCNextVariableSymbol({
|
|
597
|
+
name: "constAtomicVar",
|
|
598
|
+
type: TTypeUtils.createPrimitive("u32"),
|
|
599
|
+
isConst: true,
|
|
600
|
+
isAtomic: true,
|
|
601
|
+
}),
|
|
602
|
+
);
|
|
603
|
+
|
|
604
|
+
const result = CodeGenState.getVariableTypeInfo("constAtomicVar");
|
|
605
|
+
|
|
606
|
+
expect(result?.isConst).toBe(true);
|
|
607
|
+
expect(result?.isAtomic).toBe(true);
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
it("convertSymbolToTypeInfo filters invalid array dimensions", () => {
|
|
611
|
+
CodeGenState.symbolTable.addTSymbol(
|
|
612
|
+
createCNextVariableSymbol({
|
|
613
|
+
name: "arrayVar",
|
|
614
|
+
type: TTypeUtils.createPrimitive("u8"),
|
|
615
|
+
isArray: true,
|
|
616
|
+
arrayDimensions: [10, "invalid", 20],
|
|
617
|
+
}),
|
|
618
|
+
);
|
|
619
|
+
|
|
620
|
+
const result = CodeGenState.getVariableTypeInfo("arrayVar");
|
|
621
|
+
|
|
622
|
+
// Should only include valid numeric dimensions
|
|
623
|
+
expect(result?.arrayDimensions).toEqual([10, 20]);
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
|
|
351
627
|
describe("Overflow Operation Helpers", () => {
|
|
352
628
|
it("markClampOpUsed adds to usedClampOps", () => {
|
|
353
629
|
CodeGenState.markClampOpUsed("add", "u8");
|