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
@@ -1,10 +1,17 @@
1
- import { describe, expect, it } from "vitest";
1
+ import { describe, expect, it, beforeEach } from "vitest";
2
2
  import parse from "./testHelpers";
3
+ import TestScopeUtils from "./testUtils";
3
4
  import FunctionCollector from "../collectors/FunctionCollector";
4
- import ESymbolKind from "../../../../../utils/types/ESymbolKind";
5
5
  import ESourceLanguage from "../../../../../utils/types/ESourceLanguage";
6
+ import SymbolRegistry from "../../../../state/SymbolRegistry";
7
+ import TypeResolver from "../../../../../utils/TypeResolver";
6
8
 
7
9
  describe("FunctionCollector", () => {
10
+ beforeEach(() => {
11
+ TestScopeUtils.resetGlobalScope();
12
+ SymbolRegistry.reset();
13
+ });
14
+
8
15
  describe("basic function extraction", () => {
9
16
  it("collects a void function with no parameters", () => {
10
17
  const code = `
@@ -13,16 +20,24 @@ describe("FunctionCollector", () => {
13
20
  `;
14
21
  const tree = parse(code);
15
22
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
16
- const symbol = FunctionCollector.collect(funcCtx, "test.cnx");
23
+ const globalScope = TestScopeUtils.getGlobalScope();
24
+ const body = funcCtx.block();
25
+ const symbol = FunctionCollector.collect(
26
+ funcCtx,
27
+ "test.cnx",
28
+ globalScope,
29
+ body,
30
+ );
17
31
 
18
- expect(symbol.kind).toBe(ESymbolKind.Function);
32
+ expect(symbol.kind).toBe("function");
19
33
  expect(symbol.name).toBe("doNothing");
20
- expect(symbol.returnType).toBe("void");
34
+ expect(TypeResolver.getTypeName(symbol.returnType)).toBe("void");
21
35
  expect(symbol.parameters).toEqual([]);
22
36
  expect(symbol.sourceFile).toBe("test.cnx");
23
37
  expect(symbol.sourceLanguage).toBe(ESourceLanguage.CNext);
24
38
  expect(symbol.visibility).toBe("private");
25
39
  expect(symbol.isExported).toBe(false);
40
+ expect(symbol.scope).toBe(globalScope);
26
41
  });
27
42
 
28
43
  it("collects a function with return type", () => {
@@ -33,9 +48,16 @@ describe("FunctionCollector", () => {
33
48
  `;
34
49
  const tree = parse(code);
35
50
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
36
- const symbol = FunctionCollector.collect(funcCtx, "test.cnx");
51
+ const globalScope = TestScopeUtils.getGlobalScope();
52
+ const body = funcCtx.block();
53
+ const symbol = FunctionCollector.collect(
54
+ funcCtx,
55
+ "test.cnx",
56
+ globalScope,
57
+ body,
58
+ );
37
59
 
38
- expect(symbol.returnType).toBe("u32");
60
+ expect(TypeResolver.getTypeName(symbol.returnType)).toBe("u32");
39
61
  });
40
62
 
41
63
  it("collects a function with primitive parameters", () => {
@@ -46,21 +68,22 @@ describe("FunctionCollector", () => {
46
68
  `;
47
69
  const tree = parse(code);
48
70
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
49
- const symbol = FunctionCollector.collect(funcCtx, "test.cnx");
71
+ const globalScope = TestScopeUtils.getGlobalScope();
72
+ const body = funcCtx.block();
73
+ const symbol = FunctionCollector.collect(
74
+ funcCtx,
75
+ "test.cnx",
76
+ globalScope,
77
+ body,
78
+ );
50
79
 
51
80
  expect(symbol.parameters.length).toBe(2);
52
- expect(symbol.parameters[0]).toEqual({
53
- name: "a",
54
- type: "i32",
55
- isConst: false,
56
- isArray: false,
57
- });
58
- expect(symbol.parameters[1]).toEqual({
59
- name: "b",
60
- type: "i32",
61
- isConst: false,
62
- isArray: false,
63
- });
81
+ expect(symbol.parameters[0].name).toBe("a");
82
+ expect(TypeResolver.getTypeName(symbol.parameters[0].type)).toBe("i32");
83
+ expect(symbol.parameters[0].isConst).toBe(false);
84
+ expect(symbol.parameters[0].isArray).toBe(false);
85
+ expect(symbol.parameters[1].name).toBe("b");
86
+ expect(TypeResolver.getTypeName(symbol.parameters[1].type)).toBe("i32");
64
87
  });
65
88
  });
66
89
 
@@ -72,7 +95,14 @@ describe("FunctionCollector", () => {
72
95
  `;
73
96
  const tree = parse(code);
74
97
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
75
- const symbol = FunctionCollector.collect(funcCtx, "test.cnx");
98
+ const globalScope = TestScopeUtils.getGlobalScope();
99
+ const body = funcCtx.block();
100
+ const symbol = FunctionCollector.collect(
101
+ funcCtx,
102
+ "test.cnx",
103
+ globalScope,
104
+ body,
105
+ );
76
106
 
77
107
  expect(symbol.parameters[0].isConst).toBe(true);
78
108
  });
@@ -84,7 +114,14 @@ describe("FunctionCollector", () => {
84
114
  `;
85
115
  const tree = parse(code);
86
116
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
87
- const symbol = FunctionCollector.collect(funcCtx, "test.cnx");
117
+ const globalScope = TestScopeUtils.getGlobalScope();
118
+ const body = funcCtx.block();
119
+ const symbol = FunctionCollector.collect(
120
+ funcCtx,
121
+ "test.cnx",
122
+ globalScope,
123
+ body,
124
+ );
88
125
 
89
126
  expect(symbol.parameters[0].isArray).toBe(true);
90
127
  expect(symbol.parameters[0].arrayDimensions).toEqual([""]);
@@ -97,10 +134,17 @@ describe("FunctionCollector", () => {
97
134
  `;
98
135
  const tree = parse(code);
99
136
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
100
- const symbol = FunctionCollector.collect(funcCtx, "test.cnx");
137
+ const globalScope = TestScopeUtils.getGlobalScope();
138
+ const body = funcCtx.block();
139
+ const symbol = FunctionCollector.collect(
140
+ funcCtx,
141
+ "test.cnx",
142
+ globalScope,
143
+ body,
144
+ );
101
145
 
102
146
  expect(symbol.parameters[0].isArray).toBe(true);
103
- expect(symbol.parameters[0].arrayDimensions).toEqual(["256"]);
147
+ expect(symbol.parameters[0].arrayDimensions).toEqual([256]);
104
148
  });
105
149
 
106
150
  it("handles multi-dimensional array parameters (C-Next style)", () => {
@@ -110,51 +154,40 @@ describe("FunctionCollector", () => {
110
154
  `;
111
155
  const tree = parse(code);
112
156
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
113
- const symbol = FunctionCollector.collect(funcCtx, "test.cnx");
157
+ const globalScope = TestScopeUtils.getGlobalScope();
158
+ const body = funcCtx.block();
159
+ const symbol = FunctionCollector.collect(
160
+ funcCtx,
161
+ "test.cnx",
162
+ globalScope,
163
+ body,
164
+ );
114
165
 
115
166
  expect(symbol.parameters[0].isArray).toBe(true);
116
- expect(symbol.parameters[0].arrayDimensions).toEqual(["4", "4"]);
117
- });
118
- });
119
-
120
- describe("signature generation", () => {
121
- it("generates signature for overload detection", () => {
122
- const code = `
123
- i32 calculate(u32 x, f32 y) {
124
- return 0;
125
- }
126
- `;
127
- const tree = parse(code);
128
- const funcCtx = tree.declaration(0)!.functionDeclaration()!;
129
- const symbol = FunctionCollector.collect(funcCtx, "test.cnx");
130
-
131
- expect(symbol.signature).toBe("i32 calculate(u32, f32)");
132
- });
133
-
134
- it("includes scope prefix in signature", () => {
135
- const code = `
136
- void init() {
137
- }
138
- `;
139
- const tree = parse(code);
140
- const funcCtx = tree.declaration(0)!.functionDeclaration()!;
141
- const symbol = FunctionCollector.collect(funcCtx, "test.cnx", "Motor");
142
-
143
- expect(symbol.signature).toBe("void Motor_init()");
167
+ expect(symbol.parameters[0].arrayDimensions).toEqual([4, 4]);
144
168
  });
145
169
  });
146
170
 
147
171
  describe("scoped functions", () => {
148
- it("prefixes name with scope when scopeName is provided", () => {
172
+ it("uses scope reference properly", () => {
149
173
  const code = `
150
174
  void update() {
151
175
  }
152
176
  `;
153
177
  const tree = parse(code);
154
178
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
155
- const symbol = FunctionCollector.collect(funcCtx, "motor.cnx", "Motor");
179
+ const motorScope = TestScopeUtils.createMockScope("Motor");
180
+ const body = funcCtx.block();
181
+ const symbol = FunctionCollector.collect(
182
+ funcCtx,
183
+ "motor.cnx",
184
+ motorScope,
185
+ body,
186
+ );
156
187
 
157
- expect(symbol.name).toBe("Motor_update");
188
+ expect(symbol.name).toBe("update");
189
+ expect(symbol.scope).toBe(motorScope);
190
+ expect(symbol.scope.name).toBe("Motor");
158
191
  });
159
192
 
160
193
  it("respects visibility parameter", () => {
@@ -164,10 +197,13 @@ describe("FunctionCollector", () => {
164
197
  `;
165
198
  const tree = parse(code);
166
199
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
200
+ const motorScope = TestScopeUtils.createMockScope("Motor");
201
+ const body = funcCtx.block();
167
202
  const symbol = FunctionCollector.collect(
168
203
  funcCtx,
169
204
  "motor.cnx",
170
- "Motor",
205
+ motorScope,
206
+ body,
171
207
  "public",
172
208
  );
173
209
 
@@ -182,10 +218,13 @@ describe("FunctionCollector", () => {
182
218
  `;
183
219
  const tree = parse(code);
184
220
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
221
+ const motorScope = TestScopeUtils.createMockScope("Motor");
222
+ const body = funcCtx.block();
185
223
  const symbol = FunctionCollector.collect(
186
224
  funcCtx,
187
225
  "motor.cnx",
188
- "Motor",
226
+ motorScope,
227
+ body,
189
228
  "private",
190
229
  );
191
230
 
@@ -204,9 +243,16 @@ describe("FunctionCollector", () => {
204
243
  `;
205
244
  const tree = parse(code);
206
245
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
207
- const symbol = FunctionCollector.collect(funcCtx, "test.cnx");
246
+ const globalScope = TestScopeUtils.getGlobalScope();
247
+ const body = funcCtx.block();
248
+ const symbol = FunctionCollector.collect(
249
+ funcCtx,
250
+ "test.cnx",
251
+ globalScope,
252
+ body,
253
+ );
208
254
 
209
- expect(symbol.returnType).toBe("Point");
255
+ expect(TypeResolver.getTypeName(symbol.returnType)).toBe("Point");
210
256
  });
211
257
 
212
258
  it("handles user-defined parameter types", () => {
@@ -217,10 +263,17 @@ describe("FunctionCollector", () => {
217
263
  `;
218
264
  const tree = parse(code);
219
265
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
220
- const symbol = FunctionCollector.collect(funcCtx, "test.cnx");
266
+ const globalScope = TestScopeUtils.getGlobalScope();
267
+ const body = funcCtx.block();
268
+ const symbol = FunctionCollector.collect(
269
+ funcCtx,
270
+ "test.cnx",
271
+ globalScope,
272
+ body,
273
+ );
221
274
 
222
- expect(symbol.parameters[0].type).toBe("Point");
223
- expect(symbol.parameters[1].type).toBe("Point");
275
+ expect(TypeResolver.getTypeName(symbol.parameters[0].type)).toBe("Point");
276
+ expect(TypeResolver.getTypeName(symbol.parameters[1].type)).toBe("Point");
224
277
  });
225
278
  });
226
279
 
@@ -233,9 +286,171 @@ describe("FunctionCollector", () => {
233
286
  `;
234
287
  const tree = parse(code);
235
288
  const funcCtx = tree.declaration(0)!.functionDeclaration()!;
236
- const symbol = FunctionCollector.collect(funcCtx, "test.cnx");
289
+ const globalScope = TestScopeUtils.getGlobalScope();
290
+ const body = funcCtx.block();
291
+ const symbol = FunctionCollector.collect(
292
+ funcCtx,
293
+ "test.cnx",
294
+ globalScope,
295
+ body,
296
+ );
237
297
 
238
298
  expect(symbol.sourceLine).toBe(3);
239
299
  });
240
300
  });
301
+
302
+ describe("collectAndRegister", () => {
303
+ it("returns a valid function symbol", () => {
304
+ const code = `
305
+ void doNothing() {
306
+ }
307
+ `;
308
+ const tree = parse(code);
309
+ const funcCtx = tree.declaration(0)!.functionDeclaration()!;
310
+ const body = funcCtx.block();
311
+
312
+ const symbol = FunctionCollector.collectAndRegister(
313
+ funcCtx,
314
+ "test.cnx",
315
+ undefined,
316
+ body,
317
+ "private",
318
+ );
319
+
320
+ expect(symbol.name).toBe("doNothing");
321
+ expect(TypeResolver.getTypeName(symbol.returnType)).toBe("void");
322
+ expect(symbol.visibility).toBe("private");
323
+ });
324
+
325
+ it("registers function in SymbolRegistry global scope", () => {
326
+ const code = `
327
+ u32 getValue() {
328
+ return 42;
329
+ }
330
+ `;
331
+ const tree = parse(code);
332
+ const funcCtx = tree.declaration(0)!.functionDeclaration()!;
333
+ const body = funcCtx.block();
334
+
335
+ FunctionCollector.collectAndRegister(
336
+ funcCtx,
337
+ "test.cnx",
338
+ undefined,
339
+ body,
340
+ "private",
341
+ );
342
+
343
+ const globalScope = SymbolRegistry.getGlobalScope();
344
+ expect(globalScope.functions.length).toBe(1);
345
+ expect(globalScope.functions[0].name).toBe("getValue");
346
+ });
347
+
348
+ it("creates scope and registers scoped functions", () => {
349
+ const code = `
350
+ void init() {
351
+ }
352
+ `;
353
+ const tree = parse(code);
354
+ const funcCtx = tree.declaration(0)!.functionDeclaration()!;
355
+ const body = funcCtx.block();
356
+
357
+ FunctionCollector.collectAndRegister(
358
+ funcCtx,
359
+ "motor.cnx",
360
+ "Motor",
361
+ body,
362
+ "public",
363
+ );
364
+
365
+ const motorScope = SymbolRegistry.getOrCreateScope("Motor");
366
+ expect(motorScope.functions.length).toBe(1);
367
+ expect(motorScope.functions[0].name).toBe("init");
368
+ expect(motorScope.functions[0].visibility).toBe("public");
369
+ });
370
+
371
+ it("reuses existing scope when registering multiple functions", () => {
372
+ const code = `
373
+ void funcA() {
374
+ }
375
+ void funcB() {
376
+ }
377
+ `;
378
+ const tree = parse(code);
379
+ const funcACtx = tree.declaration(0)!.functionDeclaration()!;
380
+ const funcBCtx = tree.declaration(1)!.functionDeclaration()!;
381
+
382
+ FunctionCollector.collectAndRegister(
383
+ funcACtx,
384
+ "test.cnx",
385
+ "Test",
386
+ funcACtx.block(),
387
+ "public",
388
+ );
389
+ FunctionCollector.collectAndRegister(
390
+ funcBCtx,
391
+ "test.cnx",
392
+ "Test",
393
+ funcBCtx.block(),
394
+ "private",
395
+ );
396
+
397
+ const testScope = SymbolRegistry.getOrCreateScope("Test");
398
+ expect(testScope.functions.length).toBe(2);
399
+ expect(testScope.functions[0].name).toBe("funcA");
400
+ expect(testScope.functions[1].name).toBe("funcB");
401
+ });
402
+
403
+ it("stores body AST reference in registered function", () => {
404
+ const code = `
405
+ void testFunc() {
406
+ u32 x <- 1;
407
+ }
408
+ `;
409
+ const tree = parse(code);
410
+ const funcCtx = tree.declaration(0)!.functionDeclaration()!;
411
+ const body = funcCtx.block();
412
+
413
+ FunctionCollector.collectAndRegister(
414
+ funcCtx,
415
+ "test.cnx",
416
+ undefined,
417
+ body,
418
+ "private",
419
+ );
420
+
421
+ const globalScope = SymbolRegistry.getGlobalScope();
422
+ const registeredFunc = globalScope.functions[0];
423
+ expect(registeredFunc.body).toBe(body);
424
+ });
425
+
426
+ it("resolves function via SymbolRegistry.resolveFunction", () => {
427
+ const code = `
428
+ i32 calculate(u32 x) {
429
+ return x * 2;
430
+ }
431
+ `;
432
+ const tree = parse(code);
433
+ const funcCtx = tree.declaration(0)!.functionDeclaration()!;
434
+
435
+ FunctionCollector.collectAndRegister(
436
+ funcCtx,
437
+ "test.cnx",
438
+ undefined,
439
+ funcCtx.block(),
440
+ "private",
441
+ );
442
+
443
+ const globalScope = SymbolRegistry.getGlobalScope();
444
+ const resolved = SymbolRegistry.resolveFunction("calculate", globalScope);
445
+ expect(resolved).not.toBeNull();
446
+ expect(resolved!.name).toBe("calculate");
447
+ expect(resolved!.returnType.kind).toBe("primitive");
448
+ // Cast to primitive type to access primitive property
449
+ const returnType = resolved!.returnType as {
450
+ kind: "primitive";
451
+ primitive: string;
452
+ };
453
+ expect(returnType.primitive).toBe("i32");
454
+ });
455
+ });
241
456
  });
@@ -1,10 +1,14 @@
1
- import { describe, expect, it } from "vitest";
1
+ import { describe, expect, it, beforeEach } from "vitest";
2
2
  import parse from "./testHelpers";
3
+ import TestScopeUtils from "./testUtils";
3
4
  import RegisterCollector from "../collectors/RegisterCollector";
4
- import ESymbolKind from "../../../../../utils/types/ESymbolKind";
5
5
  import ESourceLanguage from "../../../../../utils/types/ESourceLanguage";
6
6
 
7
7
  describe("RegisterCollector", () => {
8
+ beforeEach(() => {
9
+ TestScopeUtils.resetGlobalScope();
10
+ });
11
+
8
12
  describe("basic register extraction", () => {
9
13
  it("collects a simple register with primitive members", () => {
10
14
  const code = `
@@ -15,14 +19,21 @@ describe("RegisterCollector", () => {
15
19
  `;
16
20
  const tree = parse(code);
17
21
  const regCtx = tree.declaration(0)!.registerDeclaration()!;
18
- const symbol = RegisterCollector.collect(regCtx, "test.cnx", new Set());
22
+ const globalScope = TestScopeUtils.getGlobalScope();
23
+ const symbol = RegisterCollector.collect(
24
+ regCtx,
25
+ "test.cnx",
26
+ new Set(),
27
+ globalScope,
28
+ );
19
29
 
20
- expect(symbol.kind).toBe(ESymbolKind.Register);
30
+ expect(symbol.kind).toBe("register");
21
31
  expect(symbol.name).toBe("GPIO");
22
32
  expect(symbol.baseAddress).toBe("0x40000000");
23
33
  expect(symbol.sourceFile).toBe("test.cnx");
24
34
  expect(symbol.sourceLanguage).toBe(ESourceLanguage.CNext);
25
35
  expect(symbol.isExported).toBe(true);
36
+ expect(symbol.scope).toBe(globalScope);
26
37
 
27
38
  expect(symbol.members.size).toBe(2);
28
39
  expect(symbol.members.get("DATA")).toEqual({
@@ -49,7 +60,13 @@ describe("RegisterCollector", () => {
49
60
  `;
50
61
  const tree = parse(code);
51
62
  const regCtx = tree.declaration(0)!.registerDeclaration()!;
52
- const symbol = RegisterCollector.collect(regCtx, "test.cnx", new Set());
63
+ const globalScope = TestScopeUtils.getGlobalScope();
64
+ const symbol = RegisterCollector.collect(
65
+ regCtx,
66
+ "test.cnx",
67
+ new Set(),
68
+ globalScope,
69
+ );
53
70
 
54
71
  expect(symbol.members.get("RX")?.access).toBe("ro");
55
72
  expect(symbol.members.get("TX")?.access).toBe("wo");
@@ -70,7 +87,13 @@ describe("RegisterCollector", () => {
70
87
  `;
71
88
  const tree = parse(code);
72
89
  const regCtx = tree.declaration(0)!.registerDeclaration()!;
73
- const symbol = RegisterCollector.collect(regCtx, "test.cnx", new Set());
90
+ const globalScope = TestScopeUtils.getGlobalScope();
91
+ const symbol = RegisterCollector.collect(
92
+ regCtx,
93
+ "test.cnx",
94
+ new Set(),
95
+ globalScope,
96
+ );
74
97
 
75
98
  expect(symbol.members.get("COUNT8")?.cType).toBe("uint8_t");
76
99
  expect(symbol.members.get("COUNT16")?.cType).toBe("uint16_t");
@@ -90,10 +113,12 @@ describe("RegisterCollector", () => {
90
113
  const tree = parse(code);
91
114
  const regCtx = tree.declaration(0)!.registerDeclaration()!;
92
115
  const knownBitmaps = new Set(["StatusFlags"]);
116
+ const globalScope = TestScopeUtils.getGlobalScope();
93
117
  const symbol = RegisterCollector.collect(
94
118
  regCtx,
95
119
  "test.cnx",
96
120
  knownBitmaps,
121
+ globalScope,
97
122
  );
98
123
 
99
124
  const member = symbol.members.get("FLAGS");
@@ -109,14 +134,20 @@ describe("RegisterCollector", () => {
109
134
  `;
110
135
  const tree = parse(code);
111
136
  const regCtx = tree.declaration(0)!.registerDeclaration()!;
112
- const symbol = RegisterCollector.collect(regCtx, "test.cnx", new Set());
137
+ const globalScope = TestScopeUtils.getGlobalScope();
138
+ const symbol = RegisterCollector.collect(
139
+ regCtx,
140
+ "test.cnx",
141
+ new Set(),
142
+ globalScope,
143
+ );
113
144
 
114
145
  expect(symbol.members.get("VALUE")?.bitmapType).toBeUndefined();
115
146
  });
116
147
  });
117
148
 
118
149
  describe("scoped registers", () => {
119
- it("prefixes name with scope when scopeName is provided", () => {
150
+ it("uses scope reference properly", () => {
120
151
  const code = `
121
152
  register CTRL @ 0x40005000 {
122
153
  STATUS: u32 rw @ 0x00,
@@ -124,14 +155,17 @@ describe("RegisterCollector", () => {
124
155
  `;
125
156
  const tree = parse(code);
126
157
  const regCtx = tree.declaration(0)!.registerDeclaration()!;
158
+ const motorScope = TestScopeUtils.createMockScope("Motor");
127
159
  const symbol = RegisterCollector.collect(
128
160
  regCtx,
129
161
  "motor.cnx",
130
162
  new Set(),
131
- "Motor",
163
+ motorScope,
132
164
  );
133
165
 
134
- expect(symbol.name).toBe("Motor_CTRL");
166
+ expect(symbol.name).toBe("CTRL");
167
+ expect(symbol.scope).toBe(motorScope);
168
+ expect(symbol.scope.name).toBe("Motor");
135
169
  });
136
170
 
137
171
  it("resolves scoped bitmap types", () => {
@@ -144,11 +178,12 @@ describe("RegisterCollector", () => {
144
178
  const regCtx = tree.declaration(0)!.registerDeclaration()!;
145
179
  // Bitmap would be collected as Motor_MotorFlags in a scope
146
180
  const knownBitmaps = new Set(["Motor_MotorFlags"]);
181
+ const motorScope = TestScopeUtils.createMockScope("Motor");
147
182
  const symbol = RegisterCollector.collect(
148
183
  regCtx,
149
184
  "motor.cnx",
150
185
  knownBitmaps,
151
- "Motor",
186
+ motorScope,
152
187
  );
153
188
 
154
189
  // The collector checks both scoped and unscoped names
@@ -165,7 +200,13 @@ describe("RegisterCollector", () => {
165
200
  `;
166
201
  const tree = parse(code);
167
202
  const regCtx = tree.declaration(0)!.registerDeclaration()!;
168
- const symbol = RegisterCollector.collect(regCtx, "test.cnx", new Set());
203
+ const globalScope = TestScopeUtils.getGlobalScope();
204
+ const symbol = RegisterCollector.collect(
205
+ regCtx,
206
+ "test.cnx",
207
+ new Set(),
208
+ globalScope,
209
+ );
169
210
 
170
211
  expect(symbol.baseAddress).toBe("BASE_ADDR");
171
212
  });
@@ -181,7 +222,13 @@ describe("RegisterCollector", () => {
181
222
  `;
182
223
  const tree = parse(code);
183
224
  const regCtx = tree.declaration(0)!.registerDeclaration()!;
184
- const symbol = RegisterCollector.collect(regCtx, "test.cnx", new Set());
225
+ const globalScope = TestScopeUtils.getGlobalScope();
226
+ const symbol = RegisterCollector.collect(
227
+ regCtx,
228
+ "test.cnx",
229
+ new Set(),
230
+ globalScope,
231
+ );
185
232
 
186
233
  expect(symbol.sourceLine).toBe(3);
187
234
  });