c-next 0.1.62 → 0.1.63
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/README.md +86 -63
- package/package.json +1 -1
- package/src/transpiler/Transpiler.ts +3 -2
- package/src/transpiler/__tests__/DualCodePaths.test.ts +1 -1
- package/src/transpiler/__tests__/Transpiler.coverage.test.ts +1 -1
- package/src/transpiler/__tests__/Transpiler.test.ts +0 -23
- package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +156 -70
- package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +31 -6
- package/src/transpiler/logic/symbols/cnext/utils/TypeUtils.ts +43 -11
- package/src/transpiler/output/codegen/CodeGenState.ts +811 -0
- package/src/transpiler/output/codegen/CodeGenerator.ts +817 -1377
- package/src/transpiler/output/codegen/TypeResolver.ts +193 -149
- package/src/transpiler/output/codegen/TypeValidator.ts +148 -370
- package/src/transpiler/output/codegen/__tests__/CodeGenState.test.ts +446 -0
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +326 -60
- package/src/transpiler/output/codegen/__tests__/TrackVariableTypeHelpers.test.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +435 -196
- package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +51 -67
- package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +495 -471
- package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +39 -43
- package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +52 -55
- package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +122 -62
- package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +101 -144
- package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +143 -126
- package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +287 -320
- package/src/transpiler/output/codegen/generators/GeneratorRegistry.ts +12 -0
- package/src/transpiler/output/codegen/generators/__tests__/GeneratorRegistry.test.ts +28 -1
- package/src/transpiler/output/codegen/generators/declarationGenerators/ArrayDimensionUtils.ts +67 -0
- package/src/transpiler/output/codegen/generators/declarationGenerators/ScopeGenerator.ts +121 -51
- package/src/transpiler/output/codegen/generators/declarationGenerators/StructGenerator.ts +100 -23
- package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ArrayDimensionUtils.test.ts +125 -0
- package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ScopeGenerator.test.ts +157 -4
- package/src/transpiler/output/codegen/generators/support/HelperGenerator.ts +23 -22
- package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +54 -61
- package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +21 -30
- package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +56 -53
- package/src/transpiler/output/codegen/helpers/CppModeHelper.ts +22 -30
- package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +108 -50
- package/src/transpiler/output/codegen/helpers/FloatBitHelper.ts +16 -31
- package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +103 -96
- package/src/transpiler/output/codegen/helpers/TypeGenerationHelper.ts +9 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +58 -103
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +97 -40
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +223 -128
- package/src/transpiler/output/codegen/helpers/__tests__/CppModeHelper.test.ts +68 -41
- package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +198 -47
- package/src/transpiler/output/codegen/helpers/__tests__/FloatBitHelper.test.ts +39 -37
- package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +191 -453
- package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +229 -0
- package/src/transpiler/output/codegen/resolution/ScopeResolver.ts +60 -0
- package/src/transpiler/output/codegen/resolution/SizeofResolver.ts +177 -0
- package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +336 -0
- package/src/transpiler/output/codegen/resolution/__tests__/SizeofResolver.test.ts +201 -0
- package/src/transpiler/output/codegen/types/ITypeResolverDeps.ts +0 -23
- package/src/transpiler/output/codegen/types/ITypeValidatorDeps.ts +0 -53
|
@@ -2,50 +2,34 @@
|
|
|
2
2
|
* Unit tests for ArrayInitHelper
|
|
3
3
|
*
|
|
4
4
|
* Issue #644: Tests for the extracted array initialization helper.
|
|
5
|
+
* Migrated to use CodeGenState instead of constructor DI.
|
|
5
6
|
*/
|
|
6
7
|
|
|
7
8
|
import { describe, it, expect, beforeEach, vi } from "vitest";
|
|
8
9
|
import ArrayInitHelper from "../ArrayInitHelper.js";
|
|
9
|
-
import
|
|
10
|
+
import CodeGenState from "../../CodeGenState.js";
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Default callbacks for testing.
|
|
14
|
+
*/
|
|
15
|
+
const defaultCallbacks = {
|
|
16
|
+
generateExpression: vi.fn(() => "{1, 2, 3}"),
|
|
17
|
+
getTypeName: vi.fn(() => "u8"),
|
|
18
|
+
generateArrayDimensions: vi.fn(
|
|
19
|
+
(dims: { expression: () => { getText: () => string } | null }[]) =>
|
|
20
|
+
dims
|
|
21
|
+
.map((d) => {
|
|
22
|
+
const expr = d.expression();
|
|
23
|
+
return expr ? `[${expr.getText()}]` : "[]";
|
|
24
|
+
})
|
|
25
|
+
.join(""),
|
|
26
|
+
),
|
|
27
|
+
};
|
|
20
28
|
|
|
29
|
+
describe("ArrayInitHelper", () => {
|
|
21
30
|
beforeEach(() => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
arrayInitState = {
|
|
25
|
-
lastArrayInitCount: 0,
|
|
26
|
-
lastArrayFillValue: undefined,
|
|
27
|
-
};
|
|
28
|
-
expectedType = null;
|
|
29
|
-
|
|
30
|
-
helper = new ArrayInitHelper({
|
|
31
|
-
typeRegistry,
|
|
32
|
-
localArrays,
|
|
33
|
-
arrayInitState,
|
|
34
|
-
getExpectedType: () => expectedType,
|
|
35
|
-
setExpectedType: (type) => {
|
|
36
|
-
expectedType = type;
|
|
37
|
-
},
|
|
38
|
-
generateExpression: vi.fn(() => "{1, 2, 3}"),
|
|
39
|
-
getTypeName: vi.fn(() => "u8"),
|
|
40
|
-
generateArrayDimensions: vi.fn((dims) =>
|
|
41
|
-
dims
|
|
42
|
-
.map((d: { expression: () => { getText: () => string } | null }) => {
|
|
43
|
-
const expr = d.expression();
|
|
44
|
-
return expr ? `[${expr.getText()}]` : "[]";
|
|
45
|
-
})
|
|
46
|
-
.join(""),
|
|
47
|
-
),
|
|
48
|
-
});
|
|
31
|
+
CodeGenState.reset();
|
|
32
|
+
vi.clearAllMocks();
|
|
49
33
|
});
|
|
50
34
|
|
|
51
35
|
describe("processArrayInit", () => {
|
|
@@ -56,114 +40,96 @@ describe("ArrayInitHelper", () => {
|
|
|
56
40
|
{ expression: () => ({ getText: () => "3" }) },
|
|
57
41
|
] as never;
|
|
58
42
|
|
|
59
|
-
//
|
|
60
|
-
const result =
|
|
43
|
+
// CodeGenState not modified by generateExpression mock (stays at 0)
|
|
44
|
+
const result = ArrayInitHelper.processArrayInit(
|
|
61
45
|
"arr",
|
|
62
46
|
typeCtx,
|
|
63
47
|
expression,
|
|
64
48
|
arrayDims,
|
|
65
49
|
false,
|
|
66
50
|
3,
|
|
51
|
+
defaultCallbacks,
|
|
67
52
|
);
|
|
68
53
|
|
|
69
54
|
expect(result).toBeNull();
|
|
70
55
|
});
|
|
71
56
|
|
|
72
57
|
it("handles size inference with array initializer", () => {
|
|
73
|
-
// Simulate generateExpression setting array init state
|
|
74
|
-
helper = new ArrayInitHelper({
|
|
75
|
-
typeRegistry,
|
|
76
|
-
localArrays,
|
|
77
|
-
arrayInitState,
|
|
78
|
-
getExpectedType: () => expectedType,
|
|
79
|
-
setExpectedType: (type) => {
|
|
80
|
-
expectedType = type;
|
|
81
|
-
},
|
|
82
|
-
generateExpression: vi.fn(() => {
|
|
83
|
-
arrayInitState.lastArrayInitCount = 3;
|
|
84
|
-
return "{1, 2, 3}";
|
|
85
|
-
}),
|
|
86
|
-
getTypeName: vi.fn(() => "u8"),
|
|
87
|
-
generateArrayDimensions: vi.fn(() => ""),
|
|
88
|
-
});
|
|
89
|
-
|
|
90
58
|
// Add existing type to registry
|
|
91
|
-
typeRegistry.set("arr", {
|
|
59
|
+
CodeGenState.typeRegistry.set("arr", {
|
|
92
60
|
baseType: "u8",
|
|
93
61
|
bitWidth: 8,
|
|
94
62
|
isArray: true,
|
|
95
63
|
isConst: false,
|
|
96
64
|
});
|
|
97
65
|
|
|
66
|
+
const callbacks = {
|
|
67
|
+
generateExpression: vi.fn(() => {
|
|
68
|
+
// Simulate generateExpression setting array init state
|
|
69
|
+
CodeGenState.lastArrayInitCount = 3;
|
|
70
|
+
return "{1, 2, 3}";
|
|
71
|
+
}),
|
|
72
|
+
getTypeName: vi.fn(() => "u8"),
|
|
73
|
+
generateArrayDimensions: vi.fn(() => ""),
|
|
74
|
+
};
|
|
75
|
+
|
|
98
76
|
const typeCtx = {} as never;
|
|
99
77
|
const expression = { getText: () => "[1, 2, 3]" } as never;
|
|
100
78
|
const arrayDims = [{ expression: () => null }] as never; // Empty dimension
|
|
101
79
|
|
|
102
|
-
const result =
|
|
80
|
+
const result = ArrayInitHelper.processArrayInit(
|
|
103
81
|
"arr",
|
|
104
82
|
typeCtx,
|
|
105
83
|
expression,
|
|
106
84
|
arrayDims,
|
|
107
85
|
true, // hasEmptyArrayDim
|
|
108
86
|
null, // no declared size
|
|
87
|
+
callbacks,
|
|
109
88
|
);
|
|
110
89
|
|
|
111
90
|
expect(result).not.toBeNull();
|
|
112
91
|
expect(result!.isArrayInit).toBe(true);
|
|
113
92
|
expect(result!.dimensionSuffix).toBe("[3]");
|
|
114
93
|
expect(result!.initValue).toBe("{1, 2, 3}");
|
|
115
|
-
expect(localArrays.has("arr")).toBe(true);
|
|
94
|
+
expect(CodeGenState.localArrays.has("arr")).toBe(true);
|
|
116
95
|
});
|
|
117
96
|
|
|
118
97
|
it("throws error for fill-all with empty dimension", () => {
|
|
119
|
-
|
|
120
|
-
typeRegistry,
|
|
121
|
-
localArrays,
|
|
122
|
-
arrayInitState,
|
|
123
|
-
getExpectedType: () => expectedType,
|
|
124
|
-
setExpectedType: (type) => {
|
|
125
|
-
expectedType = type;
|
|
126
|
-
},
|
|
98
|
+
const callbacks = {
|
|
127
99
|
generateExpression: vi.fn(() => {
|
|
128
|
-
|
|
100
|
+
CodeGenState.lastArrayFillValue = "0";
|
|
129
101
|
return "{0}";
|
|
130
102
|
}),
|
|
131
103
|
getTypeName: vi.fn(() => "u8"),
|
|
132
104
|
generateArrayDimensions: vi.fn(() => ""),
|
|
133
|
-
}
|
|
105
|
+
};
|
|
134
106
|
|
|
135
107
|
const typeCtx = {} as never;
|
|
136
108
|
const expression = { getText: () => "[0*]" } as never;
|
|
137
109
|
const arrayDims = [{ expression: () => null }] as never;
|
|
138
110
|
|
|
139
111
|
expect(() =>
|
|
140
|
-
|
|
112
|
+
ArrayInitHelper.processArrayInit(
|
|
141
113
|
"arr",
|
|
142
114
|
typeCtx,
|
|
143
115
|
expression,
|
|
144
116
|
arrayDims,
|
|
145
117
|
true, // hasEmptyArrayDim
|
|
146
118
|
null,
|
|
119
|
+
callbacks,
|
|
147
120
|
),
|
|
148
121
|
).toThrow("Fill-all syntax [0*] requires explicit array size");
|
|
149
122
|
});
|
|
150
123
|
|
|
151
124
|
it("throws error for array size mismatch", () => {
|
|
152
|
-
|
|
153
|
-
typeRegistry,
|
|
154
|
-
localArrays,
|
|
155
|
-
arrayInitState,
|
|
156
|
-
getExpectedType: () => expectedType,
|
|
157
|
-
setExpectedType: (type) => {
|
|
158
|
-
expectedType = type;
|
|
159
|
-
},
|
|
125
|
+
const callbacks = {
|
|
160
126
|
generateExpression: vi.fn(() => {
|
|
161
|
-
|
|
127
|
+
CodeGenState.lastArrayInitCount = 2; // Only 2 elements
|
|
162
128
|
return "{1, 2}";
|
|
163
129
|
}),
|
|
164
130
|
getTypeName: vi.fn(() => "u8"),
|
|
165
131
|
generateArrayDimensions: vi.fn(() => "[3]"),
|
|
166
|
-
}
|
|
132
|
+
};
|
|
167
133
|
|
|
168
134
|
const typeCtx = {} as never;
|
|
169
135
|
const expression = { getText: () => "[1, 2]" } as never;
|
|
@@ -172,33 +138,27 @@ describe("ArrayInitHelper", () => {
|
|
|
172
138
|
] as never;
|
|
173
139
|
|
|
174
140
|
expect(() =>
|
|
175
|
-
|
|
141
|
+
ArrayInitHelper.processArrayInit(
|
|
176
142
|
"arr",
|
|
177
143
|
typeCtx,
|
|
178
144
|
expression,
|
|
179
145
|
arrayDims,
|
|
180
146
|
false,
|
|
181
147
|
3, // declared size
|
|
148
|
+
callbacks,
|
|
182
149
|
),
|
|
183
150
|
).toThrow("Array size mismatch - declared [3] but got 2 elements");
|
|
184
151
|
});
|
|
185
152
|
|
|
186
153
|
it("expands fill-all for non-zero values", () => {
|
|
187
|
-
|
|
188
|
-
typeRegistry,
|
|
189
|
-
localArrays,
|
|
190
|
-
arrayInitState,
|
|
191
|
-
getExpectedType: () => expectedType,
|
|
192
|
-
setExpectedType: (type) => {
|
|
193
|
-
expectedType = type;
|
|
194
|
-
},
|
|
154
|
+
const callbacks = {
|
|
195
155
|
generateExpression: vi.fn(() => {
|
|
196
|
-
|
|
156
|
+
CodeGenState.lastArrayFillValue = "1";
|
|
197
157
|
return "{1}";
|
|
198
158
|
}),
|
|
199
159
|
getTypeName: vi.fn(() => "u8"),
|
|
200
160
|
generateArrayDimensions: vi.fn(() => "[3]"),
|
|
201
|
-
}
|
|
161
|
+
};
|
|
202
162
|
|
|
203
163
|
const typeCtx = {} as never;
|
|
204
164
|
const expression = { getText: () => "[1*]" } as never;
|
|
@@ -206,13 +166,14 @@ describe("ArrayInitHelper", () => {
|
|
|
206
166
|
{ expression: () => ({ getText: () => "3" }) },
|
|
207
167
|
] as never;
|
|
208
168
|
|
|
209
|
-
const result =
|
|
169
|
+
const result = ArrayInitHelper.processArrayInit(
|
|
210
170
|
"arr",
|
|
211
171
|
typeCtx,
|
|
212
172
|
expression,
|
|
213
173
|
arrayDims,
|
|
214
174
|
false,
|
|
215
175
|
3,
|
|
176
|
+
callbacks,
|
|
216
177
|
);
|
|
217
178
|
|
|
218
179
|
expect(result).not.toBeNull();
|
|
@@ -220,21 +181,14 @@ describe("ArrayInitHelper", () => {
|
|
|
220
181
|
});
|
|
221
182
|
|
|
222
183
|
it("does not expand fill-all for zero value", () => {
|
|
223
|
-
|
|
224
|
-
typeRegistry,
|
|
225
|
-
localArrays,
|
|
226
|
-
arrayInitState,
|
|
227
|
-
getExpectedType: () => expectedType,
|
|
228
|
-
setExpectedType: (type) => {
|
|
229
|
-
expectedType = type;
|
|
230
|
-
},
|
|
184
|
+
const callbacks = {
|
|
231
185
|
generateExpression: vi.fn(() => {
|
|
232
|
-
|
|
186
|
+
CodeGenState.lastArrayFillValue = "0";
|
|
233
187
|
return "{0}";
|
|
234
188
|
}),
|
|
235
189
|
getTypeName: vi.fn(() => "u8"),
|
|
236
190
|
generateArrayDimensions: vi.fn(() => "[3]"),
|
|
237
|
-
}
|
|
191
|
+
};
|
|
238
192
|
|
|
239
193
|
const typeCtx = {} as never;
|
|
240
194
|
const expression = { getText: () => "[0*]" } as never;
|
|
@@ -242,13 +196,14 @@ describe("ArrayInitHelper", () => {
|
|
|
242
196
|
{ expression: () => ({ getText: () => "3" }) },
|
|
243
197
|
] as never;
|
|
244
198
|
|
|
245
|
-
const result =
|
|
199
|
+
const result = ArrayInitHelper.processArrayInit(
|
|
246
200
|
"arr",
|
|
247
201
|
typeCtx,
|
|
248
202
|
expression,
|
|
249
203
|
arrayDims,
|
|
250
204
|
false,
|
|
251
205
|
3,
|
|
206
|
+
callbacks,
|
|
252
207
|
);
|
|
253
208
|
|
|
254
209
|
expect(result).not.toBeNull();
|
package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
2
|
import AssignmentExpectedTypeResolver from "../AssignmentExpectedTypeResolver.js";
|
|
3
3
|
import CNextSourceParser from "../../../../logic/parser/CNextSourceParser.js";
|
|
4
|
+
import CodeGenState from "../../CodeGenState.js";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Create a mock assignment target context by parsing a minimal assignment statement.
|
|
@@ -16,34 +17,66 @@ function parseAssignmentTarget(target: string) {
|
|
|
16
17
|
return assignStmt.assignmentTarget();
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Helper to set up struct fields in CodeGenState.symbols
|
|
22
|
+
*/
|
|
23
|
+
function setupStructFields(
|
|
24
|
+
structName: string,
|
|
25
|
+
fields: Map<string, string>,
|
|
26
|
+
): void {
|
|
27
|
+
if (!CodeGenState.symbols) {
|
|
28
|
+
CodeGenState.symbols = {
|
|
29
|
+
knownStructs: new Set(),
|
|
30
|
+
knownScopes: new Set(),
|
|
31
|
+
knownEnums: new Set(),
|
|
32
|
+
knownBitmaps: new Set(),
|
|
33
|
+
knownRegisters: new Set(),
|
|
34
|
+
structFields: new Map(),
|
|
35
|
+
structFieldArrays: new Map(),
|
|
36
|
+
structFieldDimensions: new Map(),
|
|
37
|
+
enumMembers: new Map(),
|
|
38
|
+
bitmapFields: new Map(),
|
|
39
|
+
bitmapBackingType: new Map(),
|
|
40
|
+
bitmapBitWidth: new Map(),
|
|
41
|
+
scopeMembers: new Map(),
|
|
42
|
+
scopeMemberVisibility: new Map(),
|
|
43
|
+
scopedRegisters: new Map(),
|
|
44
|
+
registerMemberAccess: new Map(),
|
|
45
|
+
registerMemberTypes: new Map(),
|
|
46
|
+
registerBaseAddresses: new Map(),
|
|
47
|
+
registerMemberOffsets: new Map(),
|
|
48
|
+
registerMemberCTypes: new Map(),
|
|
49
|
+
scopeVariableUsage: new Map(),
|
|
50
|
+
scopePrivateConstValues: new Map(),
|
|
51
|
+
functionReturnTypes: new Map(),
|
|
52
|
+
getSingleFunctionForVariable: () => null,
|
|
53
|
+
hasPublicSymbols: () => false,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
(CodeGenState.symbols.knownStructs as Set<string>).add(structName);
|
|
57
|
+
(CodeGenState.symbols.structFields as Map<string, Map<string, string>>).set(
|
|
58
|
+
structName,
|
|
59
|
+
fields,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
27
62
|
|
|
63
|
+
describe("AssignmentExpectedTypeResolver", () => {
|
|
28
64
|
beforeEach(() => {
|
|
29
|
-
|
|
30
|
-
structFields = new Map();
|
|
31
|
-
knownStructs = new Set();
|
|
32
|
-
|
|
33
|
-
resolver = new AssignmentExpectedTypeResolver({
|
|
34
|
-
typeRegistry: typeRegistry as any,
|
|
35
|
-
structFields,
|
|
36
|
-
isKnownStruct: (name) => knownStructs.has(name),
|
|
37
|
-
});
|
|
65
|
+
CodeGenState.reset();
|
|
38
66
|
});
|
|
39
67
|
|
|
40
68
|
describe("resolve()", () => {
|
|
41
69
|
describe("simple identifier", () => {
|
|
42
70
|
it("should resolve expected type for known variable", () => {
|
|
43
|
-
typeRegistry.set("counter", {
|
|
71
|
+
CodeGenState.typeRegistry.set("counter", {
|
|
72
|
+
baseType: "u32",
|
|
73
|
+
bitWidth: 32,
|
|
74
|
+
isArray: false,
|
|
75
|
+
isConst: false,
|
|
76
|
+
});
|
|
44
77
|
const target = parseAssignmentTarget("counter");
|
|
45
78
|
|
|
46
|
-
const result =
|
|
79
|
+
const result = AssignmentExpectedTypeResolver.resolve(target);
|
|
47
80
|
|
|
48
81
|
expect(result.expectedType).toBe("u32");
|
|
49
82
|
expect(result.assignmentContext).toEqual({
|
|
@@ -54,13 +87,16 @@ describe("AssignmentExpectedTypeResolver", () => {
|
|
|
54
87
|
});
|
|
55
88
|
|
|
56
89
|
it("should use specified overflow behavior", () => {
|
|
57
|
-
typeRegistry.set("counter", {
|
|
90
|
+
CodeGenState.typeRegistry.set("counter", {
|
|
58
91
|
baseType: "u8",
|
|
92
|
+
bitWidth: 8,
|
|
93
|
+
isArray: false,
|
|
94
|
+
isConst: false,
|
|
59
95
|
overflowBehavior: "wrap",
|
|
60
96
|
});
|
|
61
97
|
const target = parseAssignmentTarget("counter");
|
|
62
98
|
|
|
63
|
-
const result =
|
|
99
|
+
const result = AssignmentExpectedTypeResolver.resolve(target);
|
|
64
100
|
|
|
65
101
|
expect(result.assignmentContext?.overflowBehavior).toBe("wrap");
|
|
66
102
|
});
|
|
@@ -68,7 +104,7 @@ describe("AssignmentExpectedTypeResolver", () => {
|
|
|
68
104
|
it("should return null for unknown variable", () => {
|
|
69
105
|
const target = parseAssignmentTarget("unknown");
|
|
70
106
|
|
|
71
|
-
const result =
|
|
107
|
+
const result = AssignmentExpectedTypeResolver.resolve(target);
|
|
72
108
|
|
|
73
109
|
expect(result.expectedType).toBeNull();
|
|
74
110
|
expect(result.assignmentContext).toBeNull();
|
|
@@ -77,45 +113,61 @@ describe("AssignmentExpectedTypeResolver", () => {
|
|
|
77
113
|
|
|
78
114
|
describe("member access", () => {
|
|
79
115
|
it("should resolve expected type for struct field", () => {
|
|
80
|
-
typeRegistry.set("config", {
|
|
81
|
-
|
|
82
|
-
|
|
116
|
+
CodeGenState.typeRegistry.set("config", {
|
|
117
|
+
baseType: "Config",
|
|
118
|
+
bitWidth: 0,
|
|
119
|
+
isArray: false,
|
|
120
|
+
isConst: false,
|
|
121
|
+
});
|
|
122
|
+
setupStructFields("Config", new Map([["status", "Status"]]));
|
|
83
123
|
const target = parseAssignmentTarget("config.status");
|
|
84
124
|
|
|
85
|
-
const result =
|
|
125
|
+
const result = AssignmentExpectedTypeResolver.resolve(target);
|
|
86
126
|
|
|
87
127
|
expect(result.expectedType).toBe("Status");
|
|
88
128
|
});
|
|
89
129
|
|
|
90
130
|
it("should walk nested struct chain", () => {
|
|
91
|
-
typeRegistry.set("app", {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
131
|
+
CodeGenState.typeRegistry.set("app", {
|
|
132
|
+
baseType: "App",
|
|
133
|
+
bitWidth: 0,
|
|
134
|
+
isArray: false,
|
|
135
|
+
isConst: false,
|
|
136
|
+
});
|
|
137
|
+
setupStructFields("App", new Map([["config", "Config"]]));
|
|
138
|
+
setupStructFields("Config", new Map([["mode", "Mode"]]));
|
|
96
139
|
const target = parseAssignmentTarget("app.config.mode");
|
|
97
140
|
|
|
98
|
-
const result =
|
|
141
|
+
const result = AssignmentExpectedTypeResolver.resolve(target);
|
|
99
142
|
|
|
100
143
|
expect(result.expectedType).toBe("Mode");
|
|
101
144
|
});
|
|
102
145
|
|
|
103
146
|
it("should return null for non-struct root", () => {
|
|
104
|
-
typeRegistry.set("counter", {
|
|
147
|
+
CodeGenState.typeRegistry.set("counter", {
|
|
148
|
+
baseType: "u32",
|
|
149
|
+
bitWidth: 32,
|
|
150
|
+
isArray: false,
|
|
151
|
+
isConst: false,
|
|
152
|
+
});
|
|
105
153
|
const target = parseAssignmentTarget("counter.value");
|
|
106
154
|
|
|
107
|
-
const result =
|
|
155
|
+
const result = AssignmentExpectedTypeResolver.resolve(target);
|
|
108
156
|
|
|
109
157
|
expect(result.expectedType).toBeNull();
|
|
110
158
|
});
|
|
111
159
|
|
|
112
160
|
it("should return null for unknown field", () => {
|
|
113
|
-
typeRegistry.set("config", {
|
|
114
|
-
|
|
115
|
-
|
|
161
|
+
CodeGenState.typeRegistry.set("config", {
|
|
162
|
+
baseType: "Config",
|
|
163
|
+
bitWidth: 0,
|
|
164
|
+
isArray: false,
|
|
165
|
+
isConst: false,
|
|
166
|
+
});
|
|
167
|
+
setupStructFields("Config", new Map([["status", "Status"]]));
|
|
116
168
|
const target = parseAssignmentTarget("config.unknown");
|
|
117
169
|
|
|
118
|
-
const result =
|
|
170
|
+
const result = AssignmentExpectedTypeResolver.resolve(target);
|
|
119
171
|
|
|
120
172
|
expect(result.expectedType).toBeNull();
|
|
121
173
|
});
|
|
@@ -123,10 +175,15 @@ describe("AssignmentExpectedTypeResolver", () => {
|
|
|
123
175
|
|
|
124
176
|
describe("array access", () => {
|
|
125
177
|
it("should return null for array access target", () => {
|
|
126
|
-
typeRegistry.set("arr", {
|
|
178
|
+
CodeGenState.typeRegistry.set("arr", {
|
|
179
|
+
baseType: "u32",
|
|
180
|
+
bitWidth: 32,
|
|
181
|
+
isArray: true,
|
|
182
|
+
isConst: false,
|
|
183
|
+
});
|
|
127
184
|
const target = parseAssignmentTarget("arr[0]");
|
|
128
185
|
|
|
129
|
-
const result =
|
|
186
|
+
const result = AssignmentExpectedTypeResolver.resolve(target);
|
|
130
187
|
|
|
131
188
|
expect(result.expectedType).toBeNull();
|
|
132
189
|
expect(result.assignmentContext).toBeNull();
|