c-next 0.1.70 → 0.1.72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/lib/__tests__/parseCHeader.mocked.test.ts +69 -54
- package/src/lib/parseCHeader.ts +56 -23
- package/src/lib/parseWithSymbols.ts +195 -53
- package/src/transpiler/Transpiler.ts +180 -63
- package/src/transpiler/logic/analysis/FunctionCallAnalyzer.ts +1 -2
- package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +1 -2
- package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +51 -2
- package/src/transpiler/logic/analysis/__tests__/FunctionCallAnalyzer.test.ts +18 -12
- package/src/transpiler/logic/analysis/__tests__/InitializationAnalyzer.test.ts +9 -9
- package/src/transpiler/logic/analysis/__tests__/runAnalyzers.test.ts +5 -5
- package/src/transpiler/logic/symbols/SymbolTable.ts +729 -265
- package/src/transpiler/logic/symbols/SymbolUtils.ts +2 -2
- package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +415 -751
- package/src/transpiler/logic/symbols/c/__tests__/CResolver.integration.test.ts +573 -0
- package/src/transpiler/logic/symbols/c/__tests__/testHelpers.ts +20 -0
- package/src/transpiler/logic/symbols/c/collectors/EnumCollector.ts +82 -0
- package/src/transpiler/logic/symbols/c/collectors/FunctionCollector.ts +106 -0
- package/src/transpiler/logic/symbols/c/collectors/StructCollector.ts +173 -0
- package/src/transpiler/logic/symbols/c/collectors/TypedefCollector.ts +35 -0
- package/src/transpiler/logic/symbols/c/collectors/VariableCollector.ts +80 -0
- package/src/transpiler/logic/symbols/c/index.ts +333 -0
- package/src/transpiler/logic/symbols/c/utils/DeclaratorUtils.ts +269 -0
- package/src/transpiler/logic/symbols/cnext/__tests__/BitmapCollector.test.ts +50 -11
- package/src/transpiler/logic/symbols/cnext/__tests__/CNextResolver.integration.test.ts +45 -34
- package/src/transpiler/logic/symbols/cnext/__tests__/EnumCollector.test.ts +30 -13
- package/src/transpiler/logic/symbols/cnext/__tests__/FunctionCollector.test.ts +279 -64
- package/src/transpiler/logic/symbols/cnext/__tests__/RegisterCollector.test.ts +60 -13
- package/src/transpiler/logic/symbols/cnext/__tests__/ScopeCollector.test.ts +40 -37
- package/src/transpiler/logic/symbols/cnext/__tests__/StructCollector.test.ts +131 -45
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolInfoAdapter.test.ts +223 -139
- package/src/transpiler/logic/symbols/cnext/__tests__/VariableCollector.test.ts +79 -25
- package/src/transpiler/logic/symbols/cnext/__tests__/testUtils.ts +53 -0
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolInfoAdapter.ts +83 -43
- package/src/transpiler/logic/symbols/cnext/collectors/BitmapCollector.ts +14 -13
- package/src/transpiler/logic/symbols/cnext/collectors/EnumCollector.ts +11 -10
- package/src/transpiler/logic/symbols/cnext/collectors/FunctionCollector.ts +83 -34
- package/src/transpiler/logic/symbols/cnext/collectors/RegisterCollector.ts +22 -18
- package/src/transpiler/logic/symbols/cnext/collectors/ScopeCollector.ts +53 -35
- package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +30 -23
- package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +18 -19
- package/src/transpiler/logic/symbols/cnext/index.ts +36 -14
- package/src/transpiler/logic/symbols/cnext/types/IScopeCollectorResult.ts +2 -2
- package/src/transpiler/logic/symbols/cnext/utils/SymbolNameUtils.ts +27 -0
- package/src/transpiler/logic/symbols/cpp/__tests__/CppResolver.integration.test.ts +270 -0
- package/src/transpiler/logic/symbols/cpp/__tests__/testHelpers.ts +20 -0
- package/src/transpiler/logic/symbols/cpp/collectors/ClassCollector.ts +317 -0
- package/src/transpiler/logic/symbols/cpp/collectors/EnumCollector.ts +71 -0
- package/src/transpiler/logic/symbols/cpp/collectors/FunctionCollector.ts +155 -0
- package/src/transpiler/logic/symbols/cpp/collectors/NamespaceCollector.ts +65 -0
- package/src/transpiler/logic/symbols/cpp/collectors/TypeAliasCollector.ts +46 -0
- package/src/transpiler/logic/symbols/cpp/collectors/VariableCollector.ts +54 -0
- package/src/transpiler/logic/symbols/cpp/index.ts +366 -0
- package/src/transpiler/logic/symbols/cpp/utils/DeclaratorUtils.ts +248 -0
- package/src/transpiler/logic/symbols/shared/IExtractedParameter.ts +18 -0
- package/src/transpiler/logic/symbols/shared/ParameterExtractorUtils.ts +73 -0
- package/src/transpiler/output/codegen/CodeGenerator.ts +268 -1674
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +7 -1
- package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +2 -1
- package/src/transpiler/output/codegen/assignment/handlers/AssignmentHandlerUtils.ts +7 -1
- package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +6 -2
- package/src/transpiler/output/codegen/assignment/handlers/RegisterHandlers.ts +2 -1
- package/src/transpiler/output/codegen/generators/declarationGenerators/ScopeGenerator.ts +21 -8
- package/src/transpiler/output/codegen/generators/declarationGenerators/ScopedRegisterGenerator.ts +3 -2
- package/src/transpiler/output/codegen/generators/expressions/CallExprUtils.ts +9 -3
- package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprGenerator.test.ts +3 -4
- package/src/transpiler/output/codegen/generators/expressions/__tests__/CallExprUtils.test.ts +4 -8
- package/src/transpiler/output/codegen/helpers/ArgumentGenerator.ts +236 -0
- package/src/transpiler/output/codegen/helpers/CppConstructorHelper.ts +3 -3
- package/src/transpiler/output/codegen/helpers/FunctionContextManager.ts +435 -0
- package/src/transpiler/output/codegen/helpers/StringOperationsHelper.ts +203 -0
- package/src/transpiler/output/codegen/helpers/SymbolLookupHelper.ts +8 -12
- package/src/transpiler/output/codegen/helpers/TypeRegistrationEngine.ts +520 -0
- package/src/transpiler/output/codegen/helpers/VariableDeclHelper.ts +735 -0
- package/src/transpiler/output/codegen/helpers/VariableDeclarationFormatter.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/ArgumentGenerator.test.ts +521 -0
- package/src/transpiler/output/codegen/helpers/__tests__/CppConstructorHelper.test.ts +4 -5
- package/src/transpiler/output/codegen/helpers/__tests__/FunctionContextManager.test.ts +983 -0
- package/src/transpiler/output/codegen/helpers/__tests__/StringOperationsHelper.test.ts +269 -0
- package/src/transpiler/output/codegen/helpers/__tests__/SymbolLookupHelper.test.ts +31 -32
- package/src/transpiler/output/codegen/helpers/__tests__/TypeRegistrationEngine.test.ts +186 -0
- package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclHelper.test.ts +460 -0
- package/src/transpiler/output/codegen/helpers/types/IArgumentGeneratorCallbacks.ts +32 -0
- package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +5 -1
- package/src/transpiler/output/codegen/types/IFunctionContextCallbacks.ts +12 -0
- package/src/transpiler/output/codegen/types/IVariableFormatInput.ts +1 -1
- package/src/transpiler/output/codegen/utils/QualifiedNameGenerator.ts +114 -0
- package/src/transpiler/output/codegen/utils/__tests__/QualifiedNameGenerator.test.ts +183 -0
- package/src/transpiler/output/headers/BaseHeaderGenerator.ts +4 -4
- package/src/transpiler/output/headers/ExternalTypeHeaderBuilder.ts +7 -7
- package/src/transpiler/output/headers/HeaderGenerator.ts +9 -7
- package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +19 -20
- package/src/transpiler/output/headers/__tests__/BaseHeaderGenerator.test.ts +15 -18
- package/src/transpiler/output/headers/__tests__/CHeaderGenerator.test.ts +63 -64
- package/src/transpiler/output/headers/__tests__/CppHeaderGenerator.test.ts +36 -32
- package/src/transpiler/output/headers/__tests__/ExternalTypeHeaderBuilder.test.ts +26 -26
- package/src/transpiler/output/headers/__tests__/HeaderGenerator.test.ts +87 -59
- package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +57 -58
- package/src/transpiler/output/headers/adapters/HeaderSymbolAdapter.ts +222 -0
- package/src/transpiler/output/headers/adapters/__tests__/HeaderSymbolAdapter.test.ts +538 -0
- package/src/transpiler/output/headers/types/IGroupedSymbols.ts +8 -8
- package/src/transpiler/output/headers/types/IHeaderSymbol.ts +62 -0
- package/src/transpiler/state/CodeGenState.ts +20 -33
- package/src/transpiler/state/SymbolRegistry.ts +181 -0
- package/src/transpiler/{types → state}/TranspilerState.ts +1 -1
- package/src/transpiler/state/__tests__/CodeGenState.test.ts +67 -59
- package/src/transpiler/state/__tests__/SymbolRegistry.test.ts +249 -0
- package/src/transpiler/{types → state}/__tests__/TranspilerState.test.ts +1 -1
- package/src/transpiler/types/ICachedFileEntry.ts +1 -1
- package/src/transpiler/types/IConflict.ts +14 -0
- package/src/transpiler/types/IPipelineInput.ts +0 -3
- package/src/transpiler/types/ISerializedSymbol.ts +11 -0
- package/src/transpiler/types/TPrimitiveKind.ts +20 -0
- package/src/transpiler/types/TType.ts +103 -0
- package/src/transpiler/types/TVisibility.ts +6 -0
- package/src/transpiler/types/symbol-kinds/TSymbolKind.ts +10 -0
- package/src/transpiler/types/symbol-kinds/TSymbolKindC.ts +12 -0
- package/src/transpiler/types/symbol-kinds/TSymbolKindCNext.ts +16 -0
- package/src/transpiler/types/symbol-kinds/TSymbolKindCpp.ts +14 -0
- package/src/transpiler/types/symbols/IBaseSymbol.ts +31 -0
- package/src/transpiler/{logic/symbols/types → types/symbols}/IBitmapFieldInfo.ts +2 -2
- package/src/transpiler/types/symbols/IBitmapSymbol.ts +21 -0
- package/src/transpiler/{logic/symbols/types → types/symbols}/IEnumSymbol.ts +5 -6
- package/src/transpiler/types/symbols/IFieldInfo.ts +26 -0
- package/src/transpiler/types/symbols/IFunctionSymbol.ts +30 -0
- package/src/transpiler/types/symbols/IParameterInfo.ts +26 -0
- package/src/transpiler/{logic/symbols/types → types/symbols}/IRegisterMemberInfo.ts +4 -4
- package/src/transpiler/types/symbols/IRegisterSymbol.ts +18 -0
- package/src/transpiler/types/symbols/IScopeSymbol.ts +32 -0
- package/src/transpiler/{logic/symbols/types → types/symbols}/IStructFieldInfo.ts +2 -1
- package/src/transpiler/types/symbols/IStructSymbol.ts +15 -0
- package/src/transpiler/types/symbols/IVariableSymbol.ts +30 -0
- package/src/transpiler/types/symbols/SymbolGuards.ts +43 -0
- package/src/transpiler/types/symbols/TAnySymbol.ts +22 -0
- package/src/transpiler/types/symbols/TSymbol.ts +32 -0
- package/src/transpiler/types/symbols/__tests__/IBaseSymbol.test.ts +56 -0
- package/src/transpiler/types/symbols/__tests__/SymbolGuards.test.ts +57 -0
- package/src/transpiler/types/symbols/c/ICBaseSymbol.ts +28 -0
- package/src/transpiler/types/symbols/c/ICEnumMemberSymbol.ts +17 -0
- package/src/transpiler/types/symbols/c/ICEnumSymbol.ts +17 -0
- package/src/transpiler/types/symbols/c/ICFieldInfo.ts +16 -0
- package/src/transpiler/types/symbols/c/ICFunctionSymbol.ts +21 -0
- package/src/transpiler/types/symbols/c/ICParameterInfo.ts +19 -0
- package/src/transpiler/types/symbols/c/ICStructSymbol.ts +21 -0
- package/src/transpiler/types/symbols/c/ICTypedefSymbol.ts +14 -0
- package/src/transpiler/types/symbols/c/ICVariableSymbol.ts +26 -0
- package/src/transpiler/types/symbols/c/TCSymbol.ts +26 -0
- package/src/transpiler/types/symbols/cpp/ICppBaseSymbol.ts +31 -0
- package/src/transpiler/types/symbols/cpp/ICppClassSymbol.ts +15 -0
- package/src/transpiler/types/symbols/cpp/ICppEnumMemberSymbol.ts +14 -0
- package/src/transpiler/types/symbols/cpp/ICppEnumSymbol.ts +14 -0
- package/src/transpiler/types/symbols/cpp/ICppFieldInfo.ts +16 -0
- package/src/transpiler/types/symbols/cpp/ICppFunctionSymbol.ts +21 -0
- package/src/transpiler/types/symbols/cpp/ICppNamespaceSymbol.ts +11 -0
- package/src/transpiler/types/symbols/cpp/ICppParameterInfo.ts +19 -0
- package/src/transpiler/types/symbols/cpp/ICppStructSymbol.ts +16 -0
- package/src/transpiler/types/symbols/cpp/ICppTypeAliasSymbol.ts +14 -0
- package/src/transpiler/types/symbols/cpp/ICppVariableSymbol.ts +23 -0
- package/src/transpiler/types/symbols/cpp/TCppSymbol.ts +30 -0
- package/src/utils/CppNamespaceUtils.ts +3 -4
- package/src/utils/FunctionUtils.ts +92 -0
- package/src/utils/ParameterUtils.ts +55 -0
- package/src/utils/PrimitiveKindUtils.ts +33 -0
- package/src/utils/ScopeUtils.ts +105 -0
- package/src/utils/TTypeUtils.ts +159 -0
- package/src/utils/TypeResolver.ts +132 -0
- package/src/utils/__tests__/CppNamespaceUtils.test.ts +92 -99
- package/src/utils/__tests__/FunctionUtils.test.ts +284 -0
- package/src/utils/__tests__/ParameterUtils.test.ts +174 -0
- package/src/utils/__tests__/PrimitiveKindUtils.test.ts +59 -0
- package/src/utils/__tests__/ScopeUtils.test.ts +53 -0
- package/src/utils/__tests__/TTypeUtils.test.ts +245 -0
- package/src/utils/__tests__/TypeResolver.test.ts +332 -0
- package/src/utils/cache/CacheManager.ts +91 -50
- package/src/utils/cache/__tests__/CacheManager.test.ts +180 -114
- package/src/transpiler/logic/symbols/AutoConstUpdater.ts +0 -93
- package/src/transpiler/logic/symbols/CSymbolCollector.ts +0 -648
- package/src/transpiler/logic/symbols/CppSymbolCollector.ts +0 -874
- package/src/transpiler/logic/symbols/SymbolCollectorContext.ts +0 -68
- package/src/transpiler/logic/symbols/__tests__/AutoConstUpdater.test.ts +0 -418
- package/src/transpiler/logic/symbols/__tests__/CSymbolCollector.test.ts +0 -685
- package/src/transpiler/logic/symbols/__tests__/CppSymbolCollector.test.ts +0 -1146
- package/src/transpiler/logic/symbols/__tests__/SymbolCollectorContext.test.ts +0 -290
- package/src/transpiler/logic/symbols/__tests__/cTestHelpers.ts +0 -43
- package/src/transpiler/logic/symbols/__tests__/cppTestHelpers.ts +0 -40
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +0 -595
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +0 -345
- package/src/transpiler/logic/symbols/types/IBaseSymbol.ts +0 -27
- package/src/transpiler/logic/symbols/types/IBitmapSymbol.ts +0 -23
- package/src/transpiler/logic/symbols/types/ICollectorContext.ts +0 -19
- package/src/transpiler/logic/symbols/types/IConflict.ts +0 -20
- package/src/transpiler/logic/symbols/types/IFieldInfo.ts +0 -18
- package/src/transpiler/logic/symbols/types/IFunctionSymbol.ts +0 -25
- package/src/transpiler/logic/symbols/types/IParameterInfo.ts +0 -24
- package/src/transpiler/logic/symbols/types/IRegisterSymbol.ts +0 -20
- package/src/transpiler/logic/symbols/types/IScopeSymbol.ts +0 -19
- package/src/transpiler/logic/symbols/types/IStructSymbol.ts +0 -16
- package/src/transpiler/logic/symbols/types/IVariableSymbol.ts +0 -30
- package/src/transpiler/logic/symbols/types/TSymbol.ts +0 -36
- package/src/transpiler/logic/symbols/types/__tests__/SymbolGuards.test.ts +0 -244
- package/src/transpiler/logic/symbols/types/typeGuards.ts +0 -44
- package/src/utils/types/ESymbolKind.ts +0 -19
- package/src/utils/types/ISymbol.ts +0 -64
- /package/src/transpiler/{types → constants}/BITMAP_BACKING_TYPE.ts +0 -0
- /package/src/transpiler/{types → constants}/BITMAP_SIZE.ts +0 -0
|
@@ -75,7 +75,7 @@ class VariableDeclarationFormatter {
|
|
|
75
75
|
* @param dimensions - Array of dimension strings (e.g., ['10', '20'])
|
|
76
76
|
* @returns Formatted dimensions (e.g., '[10][20]')
|
|
77
77
|
*/
|
|
78
|
-
static buildArrayDimensions(dimensions?: string[]): string {
|
|
78
|
+
static buildArrayDimensions(dimensions?: readonly string[]): string {
|
|
79
79
|
if (!dimensions || dimensions.length === 0) {
|
|
80
80
|
return "";
|
|
81
81
|
}
|
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for ArgumentGenerator
|
|
3
|
+
* Issue #794: Extract Argument Generator from CodeGenerator
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
7
|
+
import ArgumentGenerator from "../ArgumentGenerator";
|
|
8
|
+
import CodeGenState from "../../../../state/CodeGenState";
|
|
9
|
+
import IArgumentGeneratorCallbacks from "../types/IArgumentGeneratorCallbacks";
|
|
10
|
+
|
|
11
|
+
describe("ArgumentGenerator", () => {
|
|
12
|
+
// Mock callbacks that return predictable values
|
|
13
|
+
const createMockCallbacks = (
|
|
14
|
+
overrides: Partial<IArgumentGeneratorCallbacks> = {},
|
|
15
|
+
): IArgumentGeneratorCallbacks => ({
|
|
16
|
+
getLvalueType: () => null,
|
|
17
|
+
getMemberAccessArrayStatus: () => "not-array",
|
|
18
|
+
needsCppMemberConversion: () => false,
|
|
19
|
+
isStringSubscriptAccess: () => false,
|
|
20
|
+
generateExpression: (ctx) => ctx.getText(),
|
|
21
|
+
...overrides,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
beforeEach(() => {
|
|
25
|
+
CodeGenState.reset();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe("handleIdentifierArg", () => {
|
|
29
|
+
describe("parameters", () => {
|
|
30
|
+
it("returns parameter name unchanged (already pointers)", () => {
|
|
31
|
+
CodeGenState.currentParameters.set("cfg", {
|
|
32
|
+
name: "cfg",
|
|
33
|
+
baseType: "Config",
|
|
34
|
+
isArray: false,
|
|
35
|
+
isStruct: true,
|
|
36
|
+
isConst: false,
|
|
37
|
+
isCallback: false,
|
|
38
|
+
isString: false,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const result = ArgumentGenerator.handleIdentifierArg("cfg");
|
|
42
|
+
expect(result).toBe("cfg");
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe("local arrays", () => {
|
|
47
|
+
it("returns array name unchanged (decay to pointers)", () => {
|
|
48
|
+
CodeGenState.localArrays.add("buffer");
|
|
49
|
+
|
|
50
|
+
const result = ArgumentGenerator.handleIdentifierArg("buffer");
|
|
51
|
+
expect(result).toBe("buffer");
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe("global arrays", () => {
|
|
56
|
+
it("returns global array name unchanged", () => {
|
|
57
|
+
CodeGenState.setVariableTypeInfo("globalArr", {
|
|
58
|
+
baseType: "u8",
|
|
59
|
+
bitWidth: 8,
|
|
60
|
+
isArray: true,
|
|
61
|
+
isConst: false,
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const result = ArgumentGenerator.handleIdentifierArg("globalArr");
|
|
65
|
+
expect(result).toBe("globalArr");
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("adds & for global strings (char arrays passed by reference)", () => {
|
|
69
|
+
CodeGenState.cppMode = false;
|
|
70
|
+
CodeGenState.setVariableTypeInfo("name", {
|
|
71
|
+
baseType: "char",
|
|
72
|
+
bitWidth: 8,
|
|
73
|
+
isArray: true,
|
|
74
|
+
isConst: false,
|
|
75
|
+
isString: true,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
const result = ArgumentGenerator.handleIdentifierArg("name");
|
|
79
|
+
expect(result).toBe("&name");
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe("scope members", () => {
|
|
84
|
+
it("prefixes scope member and adds & in C mode", () => {
|
|
85
|
+
CodeGenState.cppMode = false;
|
|
86
|
+
CodeGenState.currentScope = "LED";
|
|
87
|
+
CodeGenState.setScopeMembers("LED", new Set(["brightness"]));
|
|
88
|
+
|
|
89
|
+
const result = ArgumentGenerator.handleIdentifierArg("brightness");
|
|
90
|
+
expect(result).toBe("&LED_brightness");
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("prefixes scope member without & in C++ mode", () => {
|
|
94
|
+
CodeGenState.cppMode = true;
|
|
95
|
+
CodeGenState.currentScope = "LED";
|
|
96
|
+
CodeGenState.setScopeMembers("LED", new Set(["brightness"]));
|
|
97
|
+
|
|
98
|
+
const result = ArgumentGenerator.handleIdentifierArg("brightness");
|
|
99
|
+
expect(result).toBe("LED_brightness");
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe("local variables", () => {
|
|
104
|
+
it("adds & for local variable in C mode", () => {
|
|
105
|
+
CodeGenState.cppMode = false;
|
|
106
|
+
|
|
107
|
+
const result = ArgumentGenerator.handleIdentifierArg("value");
|
|
108
|
+
expect(result).toBe("&value");
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("returns local variable unchanged in C++ mode", () => {
|
|
112
|
+
CodeGenState.cppMode = true;
|
|
113
|
+
|
|
114
|
+
const result = ArgumentGenerator.handleIdentifierArg("value");
|
|
115
|
+
expect(result).toBe("value");
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe("handleRvalueArg", () => {
|
|
121
|
+
it("returns expression unchanged when no target type", () => {
|
|
122
|
+
const callbacks = createMockCallbacks({
|
|
123
|
+
generateExpression: () => "42",
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const result = ArgumentGenerator.handleRvalueArg(
|
|
127
|
+
null as never, // ctx not used in this path
|
|
128
|
+
undefined,
|
|
129
|
+
callbacks,
|
|
130
|
+
);
|
|
131
|
+
expect(result).toBe("42");
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("returns expression unchanged for void target type", () => {
|
|
135
|
+
const callbacks = createMockCallbacks({
|
|
136
|
+
generateExpression: () => "doSomething()",
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const result = ArgumentGenerator.handleRvalueArg(
|
|
140
|
+
null as never,
|
|
141
|
+
"void",
|
|
142
|
+
callbacks,
|
|
143
|
+
);
|
|
144
|
+
expect(result).toBe("doSomething()");
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("returns expression unchanged in C++ mode (rvalues bind to const T&)", () => {
|
|
148
|
+
CodeGenState.cppMode = true;
|
|
149
|
+
const callbacks = createMockCallbacks({
|
|
150
|
+
generateExpression: () => "42",
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const result = ArgumentGenerator.handleRvalueArg(
|
|
154
|
+
null as never,
|
|
155
|
+
"u8",
|
|
156
|
+
callbacks,
|
|
157
|
+
);
|
|
158
|
+
expect(result).toBe("42");
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("wraps in compound literal for C mode", () => {
|
|
162
|
+
CodeGenState.cppMode = false;
|
|
163
|
+
const callbacks = createMockCallbacks({
|
|
164
|
+
generateExpression: () => "42",
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const result = ArgumentGenerator.handleRvalueArg(
|
|
168
|
+
null as never,
|
|
169
|
+
"u8",
|
|
170
|
+
callbacks,
|
|
171
|
+
);
|
|
172
|
+
expect(result).toBe("&(uint8_t){42}");
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("uses correct C type for compound literal", () => {
|
|
176
|
+
CodeGenState.cppMode = false;
|
|
177
|
+
const callbacks = createMockCallbacks({
|
|
178
|
+
generateExpression: () => "1000",
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
const result = ArgumentGenerator.handleRvalueArg(
|
|
182
|
+
null as never,
|
|
183
|
+
"i32",
|
|
184
|
+
callbacks,
|
|
185
|
+
);
|
|
186
|
+
expect(result).toBe("&(int32_t){1000}");
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
describe("createCppMemberConversionTemp", () => {
|
|
191
|
+
it("creates temp variable with static_cast in C++ mode", () => {
|
|
192
|
+
CodeGenState.cppMode = true;
|
|
193
|
+
CodeGenState.tempVarCounter = 0;
|
|
194
|
+
const callbacks = createMockCallbacks({
|
|
195
|
+
generateExpression: () => "cfg.value",
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const result = ArgumentGenerator.createCppMemberConversionTemp(
|
|
199
|
+
null as never,
|
|
200
|
+
"u8",
|
|
201
|
+
callbacks,
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
expect(result).toBe("_cnx_tmp_0");
|
|
205
|
+
expect(CodeGenState.pendingTempDeclarations).toContain(
|
|
206
|
+
"uint8_t _cnx_tmp_0 = static_cast<uint8_t>(cfg.value);",
|
|
207
|
+
);
|
|
208
|
+
expect(CodeGenState.tempVarCounter).toBe(1);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it("increments temp counter for multiple temps", () => {
|
|
212
|
+
CodeGenState.cppMode = true;
|
|
213
|
+
CodeGenState.tempVarCounter = 5;
|
|
214
|
+
const callbacks = createMockCallbacks({
|
|
215
|
+
generateExpression: () => "x",
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
const result = ArgumentGenerator.createCppMemberConversionTemp(
|
|
219
|
+
null as never,
|
|
220
|
+
"i16",
|
|
221
|
+
callbacks,
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
expect(result).toBe("_cnx_tmp_5");
|
|
225
|
+
expect(CodeGenState.tempVarCounter).toBe(6);
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
describe("maybeCastStringSubscript", () => {
|
|
230
|
+
it("returns expr unchanged when no target type", () => {
|
|
231
|
+
const callbacks = createMockCallbacks({
|
|
232
|
+
isStringSubscriptAccess: () => true,
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const result = ArgumentGenerator.maybeCastStringSubscript(
|
|
236
|
+
null as never,
|
|
237
|
+
"&buf[0]",
|
|
238
|
+
undefined,
|
|
239
|
+
callbacks,
|
|
240
|
+
);
|
|
241
|
+
expect(result).toBe("&buf[0]");
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it("returns expr unchanged when not string subscript", () => {
|
|
245
|
+
const callbacks = createMockCallbacks({
|
|
246
|
+
isStringSubscriptAccess: () => false,
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const result = ArgumentGenerator.maybeCastStringSubscript(
|
|
250
|
+
null as never,
|
|
251
|
+
"&arr[0]",
|
|
252
|
+
"u8",
|
|
253
|
+
callbacks,
|
|
254
|
+
);
|
|
255
|
+
expect(result).toBe("&arr[0]");
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it("casts string subscript to integer pointer type in C mode", () => {
|
|
259
|
+
CodeGenState.cppMode = false;
|
|
260
|
+
const callbacks = createMockCallbacks({
|
|
261
|
+
isStringSubscriptAccess: () => true,
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const result = ArgumentGenerator.maybeCastStringSubscript(
|
|
265
|
+
null as never,
|
|
266
|
+
"&buf[0]",
|
|
267
|
+
"u8",
|
|
268
|
+
callbacks,
|
|
269
|
+
);
|
|
270
|
+
expect(result).toBe("(uint8_t*)&buf[0]");
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it("casts string subscript with reinterpret_cast in C++ mode", () => {
|
|
274
|
+
CodeGenState.cppMode = true;
|
|
275
|
+
const callbacks = createMockCallbacks({
|
|
276
|
+
isStringSubscriptAccess: () => true,
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
const result = ArgumentGenerator.maybeCastStringSubscript(
|
|
280
|
+
null as never,
|
|
281
|
+
"&buf[0]",
|
|
282
|
+
"u8",
|
|
283
|
+
callbacks,
|
|
284
|
+
);
|
|
285
|
+
expect(result).toBe("reinterpret_cast<uint8_t*>(&buf[0])");
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it("does not cast for float types", () => {
|
|
289
|
+
CodeGenState.cppMode = false;
|
|
290
|
+
const callbacks = createMockCallbacks({
|
|
291
|
+
isStringSubscriptAccess: () => true,
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
const result = ArgumentGenerator.maybeCastStringSubscript(
|
|
295
|
+
null as never,
|
|
296
|
+
"&buf[0]",
|
|
297
|
+
"f32",
|
|
298
|
+
callbacks,
|
|
299
|
+
);
|
|
300
|
+
expect(result).toBe("&buf[0]");
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it("does not cast for bool type", () => {
|
|
304
|
+
CodeGenState.cppMode = false;
|
|
305
|
+
const callbacks = createMockCallbacks({
|
|
306
|
+
isStringSubscriptAccess: () => true,
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
const result = ArgumentGenerator.maybeCastStringSubscript(
|
|
310
|
+
null as never,
|
|
311
|
+
"&buf[0]",
|
|
312
|
+
"bool",
|
|
313
|
+
callbacks,
|
|
314
|
+
);
|
|
315
|
+
expect(result).toBe("&buf[0]");
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
describe("handleMemberAccessArg", () => {
|
|
320
|
+
it("returns expression unchanged for array member (no & needed)", () => {
|
|
321
|
+
const callbacks = createMockCallbacks({
|
|
322
|
+
getMemberAccessArrayStatus: () => "array",
|
|
323
|
+
generateExpression: () => "result.data",
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
const result = ArgumentGenerator.handleMemberAccessArg(
|
|
327
|
+
null as never,
|
|
328
|
+
"u8",
|
|
329
|
+
callbacks,
|
|
330
|
+
);
|
|
331
|
+
expect(result).toBe("result.data");
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
it("creates temp for C++ conversion when needed", () => {
|
|
335
|
+
CodeGenState.cppMode = true;
|
|
336
|
+
CodeGenState.tempVarCounter = 0;
|
|
337
|
+
const callbacks = createMockCallbacks({
|
|
338
|
+
getMemberAccessArrayStatus: () => "not-array",
|
|
339
|
+
needsCppMemberConversion: () => true,
|
|
340
|
+
generateExpression: () => "cfg.enabled",
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
const result = ArgumentGenerator.handleMemberAccessArg(
|
|
344
|
+
null as never,
|
|
345
|
+
"u8",
|
|
346
|
+
callbacks,
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
expect(result).toBe("_cnx_tmp_0");
|
|
350
|
+
expect(CodeGenState.pendingTempDeclarations).toHaveLength(1);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it("returns null for default lvalue handling", () => {
|
|
354
|
+
const callbacks = createMockCallbacks({
|
|
355
|
+
getMemberAccessArrayStatus: () => "not-array",
|
|
356
|
+
needsCppMemberConversion: () => false,
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
const result = ArgumentGenerator.handleMemberAccessArg(
|
|
360
|
+
null as never,
|
|
361
|
+
"u8",
|
|
362
|
+
callbacks,
|
|
363
|
+
);
|
|
364
|
+
expect(result).toBeNull();
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it("returns null when array status is unknown", () => {
|
|
368
|
+
const callbacks = createMockCallbacks({
|
|
369
|
+
getMemberAccessArrayStatus: () => "unknown",
|
|
370
|
+
needsCppMemberConversion: () => false,
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
const result = ArgumentGenerator.handleMemberAccessArg(
|
|
374
|
+
null as never,
|
|
375
|
+
"u8",
|
|
376
|
+
callbacks,
|
|
377
|
+
);
|
|
378
|
+
expect(result).toBeNull();
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
describe("handleLvalueArg", () => {
|
|
383
|
+
it("delegates to handleMemberAccessArg for member access", () => {
|
|
384
|
+
const callbacks = createMockCallbacks({
|
|
385
|
+
getMemberAccessArrayStatus: () => "array",
|
|
386
|
+
generateExpression: () => "result.buffer",
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
const result = ArgumentGenerator.handleLvalueArg(
|
|
390
|
+
null as never,
|
|
391
|
+
"member",
|
|
392
|
+
"u8",
|
|
393
|
+
callbacks,
|
|
394
|
+
);
|
|
395
|
+
expect(result).toBe("result.buffer");
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
it("generates expression with & for member when not array", () => {
|
|
399
|
+
CodeGenState.cppMode = false;
|
|
400
|
+
const callbacks = createMockCallbacks({
|
|
401
|
+
getMemberAccessArrayStatus: () => "not-array",
|
|
402
|
+
needsCppMemberConversion: () => false,
|
|
403
|
+
generateExpression: () => "obj.field",
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
const result = ArgumentGenerator.handleLvalueArg(
|
|
407
|
+
null as never,
|
|
408
|
+
"member",
|
|
409
|
+
"u8",
|
|
410
|
+
callbacks,
|
|
411
|
+
);
|
|
412
|
+
expect(result).toBe("&obj.field");
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
it("handles array access with & and string subscript cast", () => {
|
|
416
|
+
CodeGenState.cppMode = false;
|
|
417
|
+
const callbacks = createMockCallbacks({
|
|
418
|
+
generateExpression: () => "buf[0]",
|
|
419
|
+
isStringSubscriptAccess: () => true,
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
const result = ArgumentGenerator.handleLvalueArg(
|
|
423
|
+
null as never,
|
|
424
|
+
"array",
|
|
425
|
+
"u8",
|
|
426
|
+
callbacks,
|
|
427
|
+
);
|
|
428
|
+
expect(result).toBe("(uint8_t*)&buf[0]");
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
it("returns expression with & for array without string cast", () => {
|
|
432
|
+
CodeGenState.cppMode = false;
|
|
433
|
+
const callbacks = createMockCallbacks({
|
|
434
|
+
generateExpression: () => "arr[i]",
|
|
435
|
+
isStringSubscriptAccess: () => false,
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
const result = ArgumentGenerator.handleLvalueArg(
|
|
439
|
+
null as never,
|
|
440
|
+
"array",
|
|
441
|
+
"u8",
|
|
442
|
+
callbacks,
|
|
443
|
+
);
|
|
444
|
+
expect(result).toBe("&arr[i]");
|
|
445
|
+
});
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
describe("generateArg (main dispatcher)", () => {
|
|
449
|
+
it("handles simple identifier", () => {
|
|
450
|
+
CodeGenState.cppMode = false;
|
|
451
|
+
const callbacks = createMockCallbacks({
|
|
452
|
+
getLvalueType: () => null,
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
const result = ArgumentGenerator.generateArg(
|
|
456
|
+
null as never,
|
|
457
|
+
"value",
|
|
458
|
+
"u8",
|
|
459
|
+
callbacks,
|
|
460
|
+
);
|
|
461
|
+
expect(result).toBe("&value");
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
it("handles parameter identifier", () => {
|
|
465
|
+
CodeGenState.currentParameters.set("cfg", {
|
|
466
|
+
name: "cfg",
|
|
467
|
+
baseType: "Config",
|
|
468
|
+
isArray: false,
|
|
469
|
+
isStruct: true,
|
|
470
|
+
isConst: false,
|
|
471
|
+
isCallback: false,
|
|
472
|
+
isString: false,
|
|
473
|
+
});
|
|
474
|
+
const callbacks = createMockCallbacks({
|
|
475
|
+
getLvalueType: () => null,
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
const result = ArgumentGenerator.generateArg(
|
|
479
|
+
null as never,
|
|
480
|
+
"cfg",
|
|
481
|
+
"Config",
|
|
482
|
+
callbacks,
|
|
483
|
+
);
|
|
484
|
+
expect(result).toBe("cfg");
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
it("handles lvalue expressions", () => {
|
|
488
|
+
CodeGenState.cppMode = false;
|
|
489
|
+
const callbacks = createMockCallbacks({
|
|
490
|
+
getLvalueType: () => "member",
|
|
491
|
+
getMemberAccessArrayStatus: () => "not-array",
|
|
492
|
+
needsCppMemberConversion: () => false,
|
|
493
|
+
generateExpression: () => "obj.field",
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
const result = ArgumentGenerator.generateArg(
|
|
497
|
+
null as never,
|
|
498
|
+
null, // no simple identifier
|
|
499
|
+
"u8",
|
|
500
|
+
callbacks,
|
|
501
|
+
);
|
|
502
|
+
expect(result).toBe("&obj.field");
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
it("handles rvalue expressions", () => {
|
|
506
|
+
CodeGenState.cppMode = false;
|
|
507
|
+
const callbacks = createMockCallbacks({
|
|
508
|
+
getLvalueType: () => null,
|
|
509
|
+
generateExpression: () => "42",
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
const result = ArgumentGenerator.generateArg(
|
|
513
|
+
null as never,
|
|
514
|
+
null, // no simple identifier
|
|
515
|
+
"u8",
|
|
516
|
+
callbacks,
|
|
517
|
+
);
|
|
518
|
+
expect(result).toBe("&(uint8_t){42}");
|
|
519
|
+
});
|
|
520
|
+
});
|
|
521
|
+
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
2
|
import CppConstructorHelper from "../CppConstructorHelper.js";
|
|
3
|
-
import ESymbolKind from "../../../../../utils/types/ESymbolKind.js";
|
|
4
3
|
|
|
5
4
|
describe("CppConstructorHelper", () => {
|
|
6
5
|
describe("toQualifiedName", () => {
|
|
@@ -87,7 +86,7 @@ describe("CppConstructorHelper", () => {
|
|
|
87
86
|
|
|
88
87
|
it("returns false when symbol is not a function", () => {
|
|
89
88
|
const mockSymbolTable = {
|
|
90
|
-
getSymbol: () => ({ kind:
|
|
89
|
+
getSymbol: () => ({ kind: "variable" as const }),
|
|
91
90
|
};
|
|
92
91
|
expect(
|
|
93
92
|
CppConstructorHelper.hasConstructor("MyClass", mockSymbolTable),
|
|
@@ -98,7 +97,7 @@ describe("CppConstructorHelper", () => {
|
|
|
98
97
|
const mockSymbolTable = {
|
|
99
98
|
getSymbol: (name: string) => {
|
|
100
99
|
if (name === "MyClass::MyClass") {
|
|
101
|
-
return { kind:
|
|
100
|
+
return { kind: "function" as const };
|
|
102
101
|
}
|
|
103
102
|
return undefined;
|
|
104
103
|
},
|
|
@@ -112,7 +111,7 @@ describe("CppConstructorHelper", () => {
|
|
|
112
111
|
const mockSymbolTable = {
|
|
113
112
|
getSymbol: (name: string) => {
|
|
114
113
|
if (name === "TestNS::MyClass::MyClass") {
|
|
115
|
-
return { kind:
|
|
114
|
+
return { kind: "function" as const };
|
|
116
115
|
}
|
|
117
116
|
return undefined;
|
|
118
117
|
},
|
|
@@ -126,7 +125,7 @@ describe("CppConstructorHelper", () => {
|
|
|
126
125
|
const mockSymbolTable = {
|
|
127
126
|
getSymbol: (name: string) => {
|
|
128
127
|
if (name === "TestNS::MyClass::MyClass") {
|
|
129
|
-
return { kind:
|
|
128
|
+
return { kind: "function" as const };
|
|
130
129
|
}
|
|
131
130
|
return undefined;
|
|
132
131
|
},
|