c-next 0.1.70 → 0.1.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/package.json +1 -1
  2. package/src/lib/__tests__/parseCHeader.mocked.test.ts +69 -54
  3. package/src/lib/parseCHeader.ts +56 -23
  4. package/src/lib/parseWithSymbols.ts +195 -53
  5. package/src/transpiler/Transpiler.ts +180 -63
  6. package/src/transpiler/logic/analysis/FunctionCallAnalyzer.ts +1 -2
  7. package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +1 -2
  8. package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +51 -2
  9. package/src/transpiler/logic/analysis/__tests__/FunctionCallAnalyzer.test.ts +18 -12
  10. package/src/transpiler/logic/analysis/__tests__/InitializationAnalyzer.test.ts +9 -9
  11. package/src/transpiler/logic/analysis/__tests__/runAnalyzers.test.ts +5 -5
  12. package/src/transpiler/logic/symbols/SymbolTable.ts +729 -265
  13. package/src/transpiler/logic/symbols/SymbolUtils.ts +2 -2
  14. package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +415 -751
  15. package/src/transpiler/logic/symbols/c/__tests__/CResolver.integration.test.ts +573 -0
  16. package/src/transpiler/logic/symbols/c/__tests__/testHelpers.ts +20 -0
  17. package/src/transpiler/logic/symbols/c/collectors/EnumCollector.ts +82 -0
  18. package/src/transpiler/logic/symbols/c/collectors/FunctionCollector.ts +106 -0
  19. package/src/transpiler/logic/symbols/c/collectors/StructCollector.ts +173 -0
  20. package/src/transpiler/logic/symbols/c/collectors/TypedefCollector.ts +35 -0
  21. package/src/transpiler/logic/symbols/c/collectors/VariableCollector.ts +80 -0
  22. package/src/transpiler/logic/symbols/c/index.ts +333 -0
  23. package/src/transpiler/logic/symbols/c/utils/DeclaratorUtils.ts +269 -0
  24. package/src/transpiler/logic/symbols/cnext/__tests__/BitmapCollector.test.ts +50 -11
  25. package/src/transpiler/logic/symbols/cnext/__tests__/CNextResolver.integration.test.ts +45 -34
  26. package/src/transpiler/logic/symbols/cnext/__tests__/EnumCollector.test.ts +30 -13
  27. package/src/transpiler/logic/symbols/cnext/__tests__/FunctionCollector.test.ts +279 -64
  28. package/src/transpiler/logic/symbols/cnext/__tests__/RegisterCollector.test.ts +60 -13
  29. package/src/transpiler/logic/symbols/cnext/__tests__/ScopeCollector.test.ts +40 -37
  30. package/src/transpiler/logic/symbols/cnext/__tests__/StructCollector.test.ts +131 -45
  31. package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolInfoAdapter.test.ts +223 -139
  32. package/src/transpiler/logic/symbols/cnext/__tests__/VariableCollector.test.ts +79 -25
  33. package/src/transpiler/logic/symbols/cnext/__tests__/testUtils.ts +53 -0
  34. package/src/transpiler/logic/symbols/cnext/adapters/TSymbolInfoAdapter.ts +83 -43
  35. package/src/transpiler/logic/symbols/cnext/collectors/BitmapCollector.ts +14 -13
  36. package/src/transpiler/logic/symbols/cnext/collectors/EnumCollector.ts +11 -10
  37. package/src/transpiler/logic/symbols/cnext/collectors/FunctionCollector.ts +83 -34
  38. package/src/transpiler/logic/symbols/cnext/collectors/RegisterCollector.ts +22 -18
  39. package/src/transpiler/logic/symbols/cnext/collectors/ScopeCollector.ts +53 -35
  40. package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +30 -23
  41. package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +18 -19
  42. package/src/transpiler/logic/symbols/cnext/index.ts +36 -14
  43. package/src/transpiler/logic/symbols/cnext/types/IScopeCollectorResult.ts +2 -2
  44. package/src/transpiler/logic/symbols/cnext/utils/SymbolNameUtils.ts +27 -0
  45. package/src/transpiler/logic/symbols/cpp/__tests__/CppResolver.integration.test.ts +270 -0
  46. package/src/transpiler/logic/symbols/cpp/__tests__/testHelpers.ts +20 -0
  47. package/src/transpiler/logic/symbols/cpp/collectors/ClassCollector.ts +317 -0
  48. package/src/transpiler/logic/symbols/cpp/collectors/EnumCollector.ts +71 -0
  49. package/src/transpiler/logic/symbols/cpp/collectors/FunctionCollector.ts +155 -0
  50. package/src/transpiler/logic/symbols/cpp/collectors/NamespaceCollector.ts +65 -0
  51. package/src/transpiler/logic/symbols/cpp/collectors/TypeAliasCollector.ts +46 -0
  52. package/src/transpiler/logic/symbols/cpp/collectors/VariableCollector.ts +54 -0
  53. package/src/transpiler/logic/symbols/cpp/index.ts +366 -0
  54. package/src/transpiler/logic/symbols/cpp/utils/DeclaratorUtils.ts +248 -0
  55. package/src/transpiler/logic/symbols/shared/IExtractedParameter.ts +18 -0
  56. package/src/transpiler/logic/symbols/shared/ParameterExtractorUtils.ts +73 -0
  57. package/src/transpiler/output/codegen/CodeGenerator.ts +268 -1674
  58. package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +7 -1
  59. package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +2 -1
  60. package/src/transpiler/output/codegen/assignment/handlers/AssignmentHandlerUtils.ts +7 -1
  61. package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +6 -2
  62. package/src/transpiler/output/codegen/assignment/handlers/RegisterHandlers.ts +2 -1
  63. package/src/transpiler/output/codegen/generators/declarationGenerators/ScopeGenerator.ts +21 -8
  64. package/src/transpiler/output/codegen/generators/declarationGenerators/ScopedRegisterGenerator.ts +3 -2
  65. package/src/transpiler/output/codegen/generators/expressions/CallExprUtils.ts +9 -3
  66. package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprGenerator.test.ts +3 -4
  67. package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprUtils.test.ts +4 -8
  68. package/src/transpiler/output/codegen/helpers/ArgumentGenerator.ts +236 -0
  69. package/src/transpiler/output/codegen/helpers/CppConstructorHelper.ts +3 -3
  70. package/src/transpiler/output/codegen/helpers/FunctionContextManager.ts +435 -0
  71. package/src/transpiler/output/codegen/helpers/StringOperationsHelper.ts +203 -0
  72. package/src/transpiler/output/codegen/helpers/SymbolLookupHelper.ts +8 -12
  73. package/src/transpiler/output/codegen/helpers/TypeRegistrationEngine.ts +520 -0
  74. package/src/transpiler/output/codegen/helpers/VariableDeclHelper.ts +735 -0
  75. package/src/transpiler/output/codegen/helpers/VariableDeclarationFormatter.ts +1 -1
  76. package/src/transpiler/output/codegen/helpers/__tests__/ArgumentGenerator.test.ts +521 -0
  77. package/src/transpiler/output/codegen/helpers/__tests__/CppConstructorHelper.test.ts +4 -5
  78. package/src/transpiler/output/codegen/helpers/__tests__/FunctionContextManager.test.ts +983 -0
  79. package/src/transpiler/output/codegen/helpers/__tests__/StringOperationsHelper.test.ts +269 -0
  80. package/src/transpiler/output/codegen/helpers/__tests__/SymbolLookupHelper.test.ts +31 -32
  81. package/src/transpiler/output/codegen/helpers/__tests__/TypeRegistrationEngine.test.ts +186 -0
  82. package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclHelper.test.ts +460 -0
  83. package/src/transpiler/output/codegen/helpers/types/IArgumentGeneratorCallbacks.ts +32 -0
  84. package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +5 -1
  85. package/src/transpiler/output/codegen/types/IFunctionContextCallbacks.ts +12 -0
  86. package/src/transpiler/output/codegen/types/IVariableFormatInput.ts +1 -1
  87. package/src/transpiler/output/codegen/utils/QualifiedNameGenerator.ts +114 -0
  88. package/src/transpiler/output/codegen/utils/__tests__/QualifiedNameGenerator.test.ts +183 -0
  89. package/src/transpiler/output/headers/BaseHeaderGenerator.ts +4 -4
  90. package/src/transpiler/output/headers/ExternalTypeHeaderBuilder.ts +7 -7
  91. package/src/transpiler/output/headers/HeaderGenerator.ts +9 -7
  92. package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +19 -20
  93. package/src/transpiler/output/headers/__tests__/BaseHeaderGenerator.test.ts +15 -18
  94. package/src/transpiler/output/headers/__tests__/CHeaderGenerator.test.ts +63 -64
  95. package/src/transpiler/output/headers/__tests__/CppHeaderGenerator.test.ts +36 -32
  96. package/src/transpiler/output/headers/__tests__/ExternalTypeHeaderBuilder.test.ts +26 -26
  97. package/src/transpiler/output/headers/__tests__/HeaderGenerator.test.ts +87 -59
  98. package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +57 -58
  99. package/src/transpiler/output/headers/adapters/HeaderSymbolAdapter.ts +222 -0
  100. package/src/transpiler/output/headers/adapters/__tests__/HeaderSymbolAdapter.test.ts +538 -0
  101. package/src/transpiler/output/headers/types/IGroupedSymbols.ts +8 -8
  102. package/src/transpiler/output/headers/types/IHeaderSymbol.ts +62 -0
  103. package/src/transpiler/state/CodeGenState.ts +20 -33
  104. package/src/transpiler/state/SymbolRegistry.ts +181 -0
  105. package/src/transpiler/{types → state}/TranspilerState.ts +1 -1
  106. package/src/transpiler/state/__tests__/CodeGenState.test.ts +67 -59
  107. package/src/transpiler/state/__tests__/SymbolRegistry.test.ts +249 -0
  108. package/src/transpiler/{types → state}/__tests__/TranspilerState.test.ts +1 -1
  109. package/src/transpiler/types/ICachedFileEntry.ts +1 -1
  110. package/src/transpiler/types/IConflict.ts +14 -0
  111. package/src/transpiler/types/IPipelineInput.ts +0 -3
  112. package/src/transpiler/types/ISerializedSymbol.ts +11 -0
  113. package/src/transpiler/types/TPrimitiveKind.ts +20 -0
  114. package/src/transpiler/types/TType.ts +103 -0
  115. package/src/transpiler/types/TVisibility.ts +6 -0
  116. package/src/transpiler/types/symbol-kinds/TSymbolKind.ts +10 -0
  117. package/src/transpiler/types/symbol-kinds/TSymbolKindC.ts +12 -0
  118. package/src/transpiler/types/symbol-kinds/TSymbolKindCNext.ts +16 -0
  119. package/src/transpiler/types/symbol-kinds/TSymbolKindCpp.ts +14 -0
  120. package/src/transpiler/types/symbols/IBaseSymbol.ts +31 -0
  121. package/src/transpiler/{logic/symbols/types → types/symbols}/IBitmapFieldInfo.ts +2 -2
  122. package/src/transpiler/types/symbols/IBitmapSymbol.ts +21 -0
  123. package/src/transpiler/{logic/symbols/types → types/symbols}/IEnumSymbol.ts +5 -6
  124. package/src/transpiler/types/symbols/IFieldInfo.ts +26 -0
  125. package/src/transpiler/types/symbols/IFunctionSymbol.ts +30 -0
  126. package/src/transpiler/types/symbols/IParameterInfo.ts +26 -0
  127. package/src/transpiler/{logic/symbols/types → types/symbols}/IRegisterMemberInfo.ts +4 -4
  128. package/src/transpiler/types/symbols/IRegisterSymbol.ts +18 -0
  129. package/src/transpiler/types/symbols/IScopeSymbol.ts +32 -0
  130. package/src/transpiler/{logic/symbols/types → types/symbols}/IStructFieldInfo.ts +2 -1
  131. package/src/transpiler/types/symbols/IStructSymbol.ts +15 -0
  132. package/src/transpiler/types/symbols/IVariableSymbol.ts +30 -0
  133. package/src/transpiler/types/symbols/SymbolGuards.ts +43 -0
  134. package/src/transpiler/types/symbols/TAnySymbol.ts +22 -0
  135. package/src/transpiler/types/symbols/TSymbol.ts +32 -0
  136. package/src/transpiler/types/symbols/__tests__/IBaseSymbol.test.ts +56 -0
  137. package/src/transpiler/types/symbols/__tests__/SymbolGuards.test.ts +57 -0
  138. package/src/transpiler/types/symbols/c/ICBaseSymbol.ts +28 -0
  139. package/src/transpiler/types/symbols/c/ICEnumMemberSymbol.ts +17 -0
  140. package/src/transpiler/types/symbols/c/ICEnumSymbol.ts +17 -0
  141. package/src/transpiler/types/symbols/c/ICFieldInfo.ts +16 -0
  142. package/src/transpiler/types/symbols/c/ICFunctionSymbol.ts +21 -0
  143. package/src/transpiler/types/symbols/c/ICParameterInfo.ts +19 -0
  144. package/src/transpiler/types/symbols/c/ICStructSymbol.ts +21 -0
  145. package/src/transpiler/types/symbols/c/ICTypedefSymbol.ts +14 -0
  146. package/src/transpiler/types/symbols/c/ICVariableSymbol.ts +26 -0
  147. package/src/transpiler/types/symbols/c/TCSymbol.ts +26 -0
  148. package/src/transpiler/types/symbols/cpp/ICppBaseSymbol.ts +31 -0
  149. package/src/transpiler/types/symbols/cpp/ICppClassSymbol.ts +15 -0
  150. package/src/transpiler/types/symbols/cpp/ICppEnumMemberSymbol.ts +14 -0
  151. package/src/transpiler/types/symbols/cpp/ICppEnumSymbol.ts +14 -0
  152. package/src/transpiler/types/symbols/cpp/ICppFieldInfo.ts +16 -0
  153. package/src/transpiler/types/symbols/cpp/ICppFunctionSymbol.ts +21 -0
  154. package/src/transpiler/types/symbols/cpp/ICppNamespaceSymbol.ts +11 -0
  155. package/src/transpiler/types/symbols/cpp/ICppParameterInfo.ts +19 -0
  156. package/src/transpiler/types/symbols/cpp/ICppStructSymbol.ts +16 -0
  157. package/src/transpiler/types/symbols/cpp/ICppTypeAliasSymbol.ts +14 -0
  158. package/src/transpiler/types/symbols/cpp/ICppVariableSymbol.ts +23 -0
  159. package/src/transpiler/types/symbols/cpp/TCppSymbol.ts +30 -0
  160. package/src/utils/CppNamespaceUtils.ts +3 -4
  161. package/src/utils/FunctionUtils.ts +92 -0
  162. package/src/utils/ParameterUtils.ts +55 -0
  163. package/src/utils/PrimitiveKindUtils.ts +33 -0
  164. package/src/utils/ScopeUtils.ts +105 -0
  165. package/src/utils/TTypeUtils.ts +159 -0
  166. package/src/utils/TypeResolver.ts +132 -0
  167. package/src/utils/__tests__/CppNamespaceUtils.test.ts +92 -99
  168. package/src/utils/__tests__/FunctionUtils.test.ts +284 -0
  169. package/src/utils/__tests__/ParameterUtils.test.ts +174 -0
  170. package/src/utils/__tests__/PrimitiveKindUtils.test.ts +59 -0
  171. package/src/utils/__tests__/ScopeUtils.test.ts +53 -0
  172. package/src/utils/__tests__/TTypeUtils.test.ts +245 -0
  173. package/src/utils/__tests__/TypeResolver.test.ts +332 -0
  174. package/src/utils/cache/CacheManager.ts +91 -50
  175. package/src/utils/cache/__tests__/CacheManager.test.ts +180 -114
  176. package/src/transpiler/logic/symbols/AutoConstUpdater.ts +0 -93
  177. package/src/transpiler/logic/symbols/CSymbolCollector.ts +0 -648
  178. package/src/transpiler/logic/symbols/CppSymbolCollector.ts +0 -874
  179. package/src/transpiler/logic/symbols/SymbolCollectorContext.ts +0 -68
  180. package/src/transpiler/logic/symbols/__tests__/AutoConstUpdater.test.ts +0 -418
  181. package/src/transpiler/logic/symbols/__tests__/CSymbolCollector.test.ts +0 -685
  182. package/src/transpiler/logic/symbols/__tests__/CppSymbolCollector.test.ts +0 -1146
  183. package/src/transpiler/logic/symbols/__tests__/SymbolCollectorContext.test.ts +0 -290
  184. package/src/transpiler/logic/symbols/__tests__/cTestHelpers.ts +0 -43
  185. package/src/transpiler/logic/symbols/__tests__/cppTestHelpers.ts +0 -40
  186. package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +0 -595
  187. package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +0 -345
  188. package/src/transpiler/logic/symbols/types/IBaseSymbol.ts +0 -27
  189. package/src/transpiler/logic/symbols/types/IBitmapSymbol.ts +0 -23
  190. package/src/transpiler/logic/symbols/types/ICollectorContext.ts +0 -19
  191. package/src/transpiler/logic/symbols/types/IConflict.ts +0 -20
  192. package/src/transpiler/logic/symbols/types/IFieldInfo.ts +0 -18
  193. package/src/transpiler/logic/symbols/types/IFunctionSymbol.ts +0 -25
  194. package/src/transpiler/logic/symbols/types/IParameterInfo.ts +0 -24
  195. package/src/transpiler/logic/symbols/types/IRegisterSymbol.ts +0 -20
  196. package/src/transpiler/logic/symbols/types/IScopeSymbol.ts +0 -19
  197. package/src/transpiler/logic/symbols/types/IStructSymbol.ts +0 -16
  198. package/src/transpiler/logic/symbols/types/IVariableSymbol.ts +0 -30
  199. package/src/transpiler/logic/symbols/types/TSymbol.ts +0 -36
  200. package/src/transpiler/logic/symbols/types/__tests__/SymbolGuards.test.ts +0 -244
  201. package/src/transpiler/logic/symbols/types/typeGuards.ts +0 -44
  202. package/src/utils/types/ESymbolKind.ts +0 -19
  203. package/src/utils/types/ISymbol.ts +0 -64
  204. /package/src/transpiler/{types → constants}/BITMAP_BACKING_TYPE.ts +0 -0
  205. /package/src/transpiler/{types → constants}/BITMAP_SIZE.ts +0 -0
@@ -30,8 +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 ESymbolKind from "../../utils/types/ESymbolKind";
34
- import ESourceLanguage from "../../utils/types/ESourceLanguage";
33
+ import TypeResolver from "../../utils/TypeResolver";
35
34
 
36
35
  /**
37
36
  * Default target capabilities (safe fallback)
@@ -471,16 +470,12 @@ export default class CodeGenState {
471
470
  return localInfo;
472
471
  }
473
472
 
474
- // Fall back to SymbolTable for cross-file C-Next variables only.
473
+ // ADR-055 Phase 7: Fall back to SymbolTable for cross-file C-Next variables only.
475
474
  // C/C++ header symbols don't have complete type info (e.g., isArray),
476
- // so we only use C-Next symbols from SymbolTable.
477
- const symbol = this.symbolTable.getSymbol(name);
478
- if (
479
- symbol?.kind === ESymbolKind.Variable &&
480
- symbol.type &&
481
- symbol.sourceLanguage === ESourceLanguage.CNext
482
- ) {
483
- return this.convertSymbolToTypeInfo(symbol);
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);
484
479
  }
485
480
 
486
481
  return undefined;
@@ -496,17 +491,14 @@ export default class CodeGenState {
496
491
 
497
492
  /**
498
493
  * Check if a variable type is registered (locally or in SymbolTable).
494
+ * ADR-055 Phase 7: Uses getTSymbol for typed symbol lookup.
499
495
  */
500
496
  static hasVariableTypeInfo(name: string): boolean {
501
497
  if (this.typeRegistry.has(name)) {
502
498
  return true;
503
499
  }
504
- const symbol = this.symbolTable.getSymbol(name);
505
- return (
506
- symbol?.kind === ESymbolKind.Variable &&
507
- symbol.type !== undefined &&
508
- symbol.sourceLanguage === ESourceLanguage.CNext
509
- );
500
+ const symbol = this.symbolTable.getTSymbol(name);
501
+ return symbol?.kind === "variable" && symbol.type !== undefined;
510
502
  }
511
503
 
512
504
  /**
@@ -533,37 +525,32 @@ export default class CodeGenState {
533
525
  }
534
526
 
535
527
  /**
536
- * Convert an ISymbol to TTypeInfo for unified type lookups.
537
- * Used when looking up cross-file variables from SymbolTable.
528
+ * Convert a TSymbol IVariableSymbol to TTypeInfo for unified type lookups.
529
+ * ADR-055 Phase 7: Works with typed TSymbol instead of ISymbol.
538
530
  */
539
- private static convertSymbolToTypeInfo(symbol: {
540
- type?: string;
541
- isArray?: boolean;
542
- arrayDimensions?: string[];
543
- isConst?: boolean;
544
- isAtomic?: boolean;
545
- }): TTypeInfo {
546
- const rawType = symbol.type || "unknown";
531
+ private static convertTSymbolToTypeInfo(
532
+ symbol: import("../types/symbols/IVariableSymbol").default,
533
+ ): TTypeInfo {
534
+ const typeName = TypeResolver.getTypeName(symbol.type);
547
535
 
548
- // Parse string<N> type pattern
536
+ // Parse string capacity using regex
549
537
  const stringPattern = /^string<(\d+)>$/;
550
- const stringMatch = stringPattern.exec(rawType);
538
+ const stringMatch = stringPattern.exec(typeName);
551
539
  const isString = stringMatch !== null;
552
540
  const stringCapacity = stringMatch
553
541
  ? Number.parseInt(stringMatch[1], 10)
554
542
  : undefined;
555
- // Use "char" for string types to match local convention (StringDeclHelper.ts)
556
- const baseType = isString ? "char" : rawType;
543
+ // Use char for string types to match local convention
544
+ const baseType = isString ? "char" : typeName;
557
545
 
558
546
  const isEnum = this.isKnownEnum(baseType);
559
547
 
560
548
  return {
561
549
  baseType,
562
- // Use bitWidth 8 for strings (char), otherwise lookup from TYPE_WIDTH
563
550
  bitWidth: isString ? 8 : TYPE_WIDTH[baseType] || 0,
564
551
  isArray: symbol.isArray || false,
565
552
  arrayDimensions: symbol.arrayDimensions
566
- ?.map((d) => Number.parseInt(d, 10))
553
+ ?.map((d) => (typeof d === "number" ? d : Number.parseInt(d, 10)))
567
554
  .filter((n) => !Number.isNaN(n)),
568
555
  isConst: symbol.isConst || false,
569
556
  isAtomic: symbol.isAtomic || false,
@@ -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,7 +6,7 @@
6
6
  * and typed accessors for all accumulated data.
7
7
  */
8
8
 
9
- import ICodeGenSymbols from "./ICodeGenSymbols";
9
+ import ICodeGenSymbols from "../types/ICodeGenSymbols";
10
10
 
11
11
  /**
12
12
  * Encapsulates the 6 accumulated state fields from Transpiler.
@@ -6,25 +6,51 @@ 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 ESymbolKind from "../../../utils/types/ESymbolKind";
10
9
  import ESourceLanguage from "../../../utils/types/ESourceLanguage";
11
- import ISymbol from "../../../utils/types/ISymbol";
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";
12
14
 
13
15
  /**
14
- * Create a minimal ISymbol for testing with required fields.
16
+ * Create a minimal C-Next IVariableSymbol for testing.
15
17
  */
16
- function createTestSymbol(
17
- overrides: Partial<ISymbol> & {
18
- name: string;
19
- kind: ESymbolKind;
20
- sourceLanguage: ESourceLanguage;
21
- },
22
- ): ISymbol {
18
+ function createCNextVariableSymbol(
19
+ overrides: Partial<IVariableSymbol> & { name: string },
20
+ ): IVariableSymbol {
23
21
  return {
24
- sourceFile: "test.cnx",
25
- sourceLine: 1,
26
- isExported: false,
27
- ...overrides,
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,
28
54
  };
29
55
  }
30
56
 
@@ -389,14 +415,12 @@ describe("CodeGenState", () => {
389
415
 
390
416
  it("getVariableTypeInfo falls back to SymbolTable for C-Next variables", () => {
391
417
  // Add a C-Next variable to SymbolTable (simulating cross-file include)
392
- CodeGenState.symbolTable.addSymbol(
393
- createTestSymbol({
418
+ CodeGenState.symbolTable.addTSymbol(
419
+ createCNextVariableSymbol({
394
420
  name: "crossFileVar",
395
- kind: ESymbolKind.Variable,
396
- type: "u16",
397
- sourceLanguage: ESourceLanguage.CNext,
421
+ type: TTypeUtils.createPrimitive("u16"),
398
422
  isArray: true,
399
- arrayDimensions: ["10"],
423
+ arrayDimensions: [10],
400
424
  }),
401
425
  );
402
426
 
@@ -411,12 +435,10 @@ describe("CodeGenState", () => {
411
435
 
412
436
  it("getVariableTypeInfo does not use C header symbols", () => {
413
437
  // Add a C header variable (should NOT be used)
414
- CodeGenState.symbolTable.addSymbol(
415
- createTestSymbol({
438
+ CodeGenState.symbolTable.addCSymbol(
439
+ createCVariableSymbol({
416
440
  name: "cHeaderVar",
417
- kind: ESymbolKind.Variable,
418
441
  type: "uint32_t",
419
- sourceLanguage: ESourceLanguage.C,
420
442
  }),
421
443
  );
422
444
 
@@ -433,12 +455,10 @@ describe("CodeGenState", () => {
433
455
  };
434
456
  CodeGenState.setVariableTypeInfo("mixedVar", localInfo);
435
457
 
436
- CodeGenState.symbolTable.addSymbol(
437
- createTestSymbol({
458
+ CodeGenState.symbolTable.addTSymbol(
459
+ createCNextVariableSymbol({
438
460
  name: "mixedVar",
439
- kind: ESymbolKind.Variable,
440
- type: "u8",
441
- sourceLanguage: ESourceLanguage.CNext,
461
+ type: TTypeUtils.createPrimitive("u8"),
442
462
  }),
443
463
  );
444
464
 
@@ -460,12 +480,10 @@ describe("CodeGenState", () => {
460
480
  });
461
481
 
462
482
  it("hasVariableTypeInfo returns true for C-Next SymbolTable variable", () => {
463
- CodeGenState.symbolTable.addSymbol(
464
- createTestSymbol({
483
+ CodeGenState.symbolTable.addTSymbol(
484
+ createCNextVariableSymbol({
465
485
  name: "crossFileVar",
466
- kind: ESymbolKind.Variable,
467
- type: "u32",
468
- sourceLanguage: ESourceLanguage.CNext,
486
+ type: TTypeUtils.createPrimitive("u32"),
469
487
  }),
470
488
  );
471
489
 
@@ -477,12 +495,10 @@ describe("CodeGenState", () => {
477
495
  });
478
496
 
479
497
  it("hasVariableTypeInfo returns false for C header variable", () => {
480
- CodeGenState.symbolTable.addSymbol(
481
- createTestSymbol({
498
+ CodeGenState.symbolTable.addCSymbol(
499
+ createCVariableSymbol({
482
500
  name: "cVar",
483
- kind: ESymbolKind.Variable,
484
501
  type: "int",
485
- sourceLanguage: ESourceLanguage.C,
486
502
  }),
487
503
  );
488
504
 
@@ -540,12 +556,10 @@ describe("CodeGenState", () => {
540
556
  });
541
557
 
542
558
  it("convertSymbolToTypeInfo handles string<N> types", () => {
543
- CodeGenState.symbolTable.addSymbol(
544
- createTestSymbol({
559
+ CodeGenState.symbolTable.addTSymbol(
560
+ createCNextVariableSymbol({
545
561
  name: "myString",
546
- kind: ESymbolKind.Variable,
547
- type: "string<32>",
548
- sourceLanguage: ESourceLanguage.CNext,
562
+ type: TTypeUtils.createString(32),
549
563
  }),
550
564
  );
551
565
 
@@ -563,12 +577,10 @@ describe("CodeGenState", () => {
563
577
  knownEnums: new Set(["EColor"]),
564
578
  });
565
579
 
566
- CodeGenState.symbolTable.addSymbol(
567
- createTestSymbol({
580
+ CodeGenState.symbolTable.addTSymbol(
581
+ createCNextVariableSymbol({
568
582
  name: "color",
569
- kind: ESymbolKind.Variable,
570
- type: "EColor",
571
- sourceLanguage: ESourceLanguage.CNext,
583
+ type: TTypeUtils.createEnum("EColor"),
572
584
  }),
573
585
  );
574
586
 
@@ -580,12 +592,10 @@ describe("CodeGenState", () => {
580
592
  });
581
593
 
582
594
  it("convertSymbolToTypeInfo handles const and atomic", () => {
583
- CodeGenState.symbolTable.addSymbol(
584
- createTestSymbol({
595
+ CodeGenState.symbolTable.addTSymbol(
596
+ createCNextVariableSymbol({
585
597
  name: "constAtomicVar",
586
- kind: ESymbolKind.Variable,
587
- type: "u32",
588
- sourceLanguage: ESourceLanguage.CNext,
598
+ type: TTypeUtils.createPrimitive("u32"),
589
599
  isConst: true,
590
600
  isAtomic: true,
591
601
  }),
@@ -598,14 +608,12 @@ describe("CodeGenState", () => {
598
608
  });
599
609
 
600
610
  it("convertSymbolToTypeInfo filters invalid array dimensions", () => {
601
- CodeGenState.symbolTable.addSymbol(
602
- createTestSymbol({
611
+ CodeGenState.symbolTable.addTSymbol(
612
+ createCNextVariableSymbol({
603
613
  name: "arrayVar",
604
- kind: ESymbolKind.Variable,
605
- type: "u8",
606
- sourceLanguage: ESourceLanguage.CNext,
614
+ type: TTypeUtils.createPrimitive("u8"),
607
615
  isArray: true,
608
- arrayDimensions: ["10", "invalid", "20"],
616
+ arrayDimensions: [10, "invalid", 20],
609
617
  }),
610
618
  );
611
619