c-next 0.1.65 → 0.1.67
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 +5 -1
- package/src/transpiler/Transpiler.ts +49 -42
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +129 -0
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +27 -3
- package/src/transpiler/output/codegen/CodeGenerator.ts +131 -186
- package/src/transpiler/output/codegen/TypeResolver.ts +2 -2
- package/src/transpiler/output/codegen/TypeValidator.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +1087 -0
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +665 -1315
- package/src/transpiler/output/codegen/__tests__/TypeResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/TypeValidator.resolution.test.ts +1 -1
- package/src/transpiler/output/codegen/__tests__/TypeValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/analysis/MemberChainAnalyzer.ts +1 -1
- package/src/transpiler/output/codegen/analysis/StringLengthCounter.ts +1 -1
- package/src/transpiler/output/codegen/analysis/__tests__/MemberChainAnalyzer.test.ts +1 -1
- package/src/transpiler/output/codegen/analysis/__tests__/StringLengthCounter.test.ts +1 -1
- package/src/transpiler/output/codegen/assignment/AssignmentClassifier.ts +1 -1
- package/src/transpiler/output/codegen/assignment/__tests__/AssignmentClassifier.test.ts +1 -1
- package/src/transpiler/output/codegen/assignment/handlers/AccessPatternHandlers.ts +24 -27
- package/src/transpiler/output/codegen/assignment/handlers/ArrayHandlers.ts +25 -18
- package/src/transpiler/output/codegen/assignment/handlers/BitAccessHandlers.ts +27 -33
- package/src/transpiler/output/codegen/assignment/handlers/BitmapHandlers.ts +39 -42
- package/src/transpiler/output/codegen/assignment/handlers/RegisterHandlers.ts +39 -97
- package/src/transpiler/output/codegen/assignment/handlers/RegisterUtils.ts +75 -0
- package/src/transpiler/output/codegen/assignment/handlers/SimpleHandler.ts +9 -6
- package/src/transpiler/output/codegen/assignment/handlers/SpecialHandlers.ts +30 -22
- package/src/transpiler/output/codegen/assignment/handlers/StringHandlers.ts +42 -50
- package/src/transpiler/output/codegen/assignment/handlers/TAssignmentHandler.ts +6 -5
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/AccessPatternHandlers.test.ts +81 -134
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/ArrayHandlers.test.ts +85 -124
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitAccessHandlers.test.ts +82 -124
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/BitmapHandlers.test.ts +135 -297
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterHandlers.test.ts +105 -227
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/RegisterUtils.test.ts +214 -1
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/SpecialHandlers.test.ts +66 -127
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/StringHandlers.test.ts +37 -83
- package/src/transpiler/output/codegen/assignment/handlers/__tests__/handlerTestUtils.ts +162 -0
- package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +618 -12
- package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +819 -0
- package/src/transpiler/output/codegen/helpers/ArrayInitHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/AssignmentExpectedTypeResolver.ts +1 -1
- package/src/transpiler/output/codegen/helpers/AssignmentValidator.ts +1 -1
- package/src/transpiler/output/codegen/helpers/CppModeHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/EnumAssignmentValidator.ts +1 -1
- package/src/transpiler/output/codegen/helpers/FloatBitHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +337 -0
- package/src/transpiler/output/codegen/helpers/ParameterSignatureBuilder.ts +135 -0
- package/src/transpiler/output/codegen/helpers/StringDeclHelper.ts +1 -1
- package/src/transpiler/output/codegen/helpers/VariableDeclarationFormatter.ts +118 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ArrayInitHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentExpectedTypeResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/AssignmentValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/CppModeHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/EnumAssignmentValidator.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/FloatBitHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +426 -0
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterSignatureBuilder.test.ts +315 -0
- package/src/transpiler/output/codegen/helpers/__tests__/StringDeclHelper.test.ts +1 -1
- package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclarationFormatter.test.ts +333 -0
- package/src/transpiler/output/codegen/resolution/EnumTypeResolver.ts +1 -1
- package/src/transpiler/output/codegen/resolution/ScopeResolver.ts +1 -1
- package/src/transpiler/output/codegen/resolution/SizeofResolver.ts +1 -1
- package/src/transpiler/output/codegen/resolution/__tests__/EnumTypeResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/resolution/__tests__/SizeofResolver.test.ts +1 -1
- package/src/transpiler/output/codegen/types/ICodeGenApi.ts +57 -0
- package/src/transpiler/output/codegen/types/IParameterInput.ts +58 -0
- package/src/transpiler/output/codegen/types/IVariableFormatInput.ts +51 -0
- package/src/transpiler/output/headers/BaseHeaderGenerator.ts +20 -35
- package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +21 -48
- package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +0 -64
- package/src/transpiler/{output/codegen → state}/CodeGenState.ts +46 -26
- package/src/transpiler/{output/codegen → state}/__tests__/CodeGenState.test.ts +12 -2
- package/src/transpiler/output/codegen/assignment/handlers/IHandlerDeps.ts +0 -161
package/src/transpiler/output/codegen/assignment/handlers/__tests__/AccessPatternHandlers.test.ts
CHANGED
|
@@ -3,53 +3,12 @@
|
|
|
3
3
|
* Tests global/this access and member chain handler functions.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { describe, expect, it, vi } from "vitest";
|
|
6
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
7
7
|
import accessPatternHandlers from "../AccessPatternHandlers";
|
|
8
8
|
import AssignmentKind from "../../AssignmentKind";
|
|
9
9
|
import IAssignmentContext from "../../IAssignmentContext";
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Create mock dependencies for testing.
|
|
14
|
-
*/
|
|
15
|
-
function createMockDeps(overrides: Record<string, unknown> = {}): IHandlerDeps {
|
|
16
|
-
const base = {
|
|
17
|
-
typeRegistry: new Map(),
|
|
18
|
-
symbols: {
|
|
19
|
-
structFields: new Map(),
|
|
20
|
-
structFieldDimensions: new Map(),
|
|
21
|
-
bitmapFields: new Map(),
|
|
22
|
-
registerMemberAccess: new Map(),
|
|
23
|
-
registerBaseAddresses: new Map(),
|
|
24
|
-
registerMemberOffsets: new Map(),
|
|
25
|
-
registerMemberTypes: new Map(),
|
|
26
|
-
},
|
|
27
|
-
currentScope: null,
|
|
28
|
-
currentParameters: new Map(),
|
|
29
|
-
targetCapabilities: { hasLDREX: false },
|
|
30
|
-
generateAssignmentTarget: vi.fn().mockReturnValue("target"),
|
|
31
|
-
generateExpression: vi
|
|
32
|
-
.fn()
|
|
33
|
-
.mockImplementation((ctx) => ctx?.mockValue ?? "0"),
|
|
34
|
-
markNeedsString: vi.fn(),
|
|
35
|
-
markClampOpUsed: vi.fn(),
|
|
36
|
-
isKnownScope: vi.fn().mockReturnValue(false),
|
|
37
|
-
isKnownStruct: vi.fn().mockReturnValue(false),
|
|
38
|
-
validateCrossScopeVisibility: vi.fn(),
|
|
39
|
-
validateBitmapFieldLiteral: vi.fn(),
|
|
40
|
-
checkArrayBounds: vi.fn(),
|
|
41
|
-
analyzeMemberChainForBitAccess: vi
|
|
42
|
-
.fn()
|
|
43
|
-
.mockReturnValue({ isBitAccess: false }),
|
|
44
|
-
tryEvaluateConstant: vi.fn().mockReturnValue(undefined),
|
|
45
|
-
getMemberTypeInfo: vi.fn().mockReturnValue(null),
|
|
46
|
-
generateFloatBitWrite: vi.fn().mockReturnValue(null),
|
|
47
|
-
foldBooleanToInt: vi.fn().mockImplementation((expr) => expr),
|
|
48
|
-
generateAtomicRMW: vi.fn().mockReturnValue("atomic_rmw"),
|
|
49
|
-
...overrides,
|
|
50
|
-
};
|
|
51
|
-
return base as unknown as IHandlerDeps;
|
|
52
|
-
}
|
|
10
|
+
import CodeGenState from "../../../../../state/CodeGenState";
|
|
11
|
+
import HandlerTestUtils from "./handlerTestUtils";
|
|
53
12
|
|
|
54
13
|
/**
|
|
55
14
|
* Create mock context for testing.
|
|
@@ -80,6 +39,12 @@ function createMockContext(
|
|
|
80
39
|
}
|
|
81
40
|
|
|
82
41
|
describe("AccessPatternHandlers", () => {
|
|
42
|
+
beforeEach(() => {
|
|
43
|
+
CodeGenState.reset();
|
|
44
|
+
HandlerTestUtils.setupMockGenerator();
|
|
45
|
+
HandlerTestUtils.setupMockSymbols();
|
|
46
|
+
});
|
|
47
|
+
|
|
83
48
|
describe("handler registration", () => {
|
|
84
49
|
it("registers all expected access pattern kinds", () => {
|
|
85
50
|
const kinds = accessPatternHandlers.map(([kind]) => kind);
|
|
@@ -126,27 +91,30 @@ describe("AccessPatternHandlers", () => {
|
|
|
126
91
|
)?.[1];
|
|
127
92
|
|
|
128
93
|
it("generates standard assignment for global member", () => {
|
|
129
|
-
|
|
130
|
-
|
|
94
|
+
HandlerTestUtils.setupMockGenerator({
|
|
95
|
+
generateAssignmentTarget: vi.fn().mockReturnValue("Counter_value"),
|
|
96
|
+
});
|
|
131
97
|
const ctx = createMockContext();
|
|
132
98
|
|
|
133
|
-
const result = getHandler()!(ctx
|
|
99
|
+
const result = getHandler()!(ctx);
|
|
134
100
|
|
|
135
101
|
expect(result).toBe("Counter_value = 5;");
|
|
136
102
|
});
|
|
137
103
|
|
|
138
104
|
it("validates cross-scope visibility when first id is a scope", () => {
|
|
139
105
|
const validateCrossScopeVisibility = vi.fn();
|
|
140
|
-
|
|
141
|
-
isKnownScope: vi.fn().mockReturnValue(true),
|
|
142
|
-
validateCrossScopeVisibility,
|
|
106
|
+
HandlerTestUtils.setupMockGenerator({
|
|
143
107
|
generateAssignmentTarget: vi.fn().mockReturnValue("Motor_speed"),
|
|
108
|
+
validateCrossScopeVisibility,
|
|
109
|
+
});
|
|
110
|
+
HandlerTestUtils.setupMockSymbols({
|
|
111
|
+
knownScopes: new Set(["Motor"]),
|
|
144
112
|
});
|
|
145
113
|
const ctx = createMockContext({
|
|
146
114
|
identifiers: ["Motor", "speed"],
|
|
147
115
|
});
|
|
148
116
|
|
|
149
|
-
getHandler()!(ctx
|
|
117
|
+
getHandler()!(ctx);
|
|
150
118
|
|
|
151
119
|
expect(validateCrossScopeVisibility).toHaveBeenCalledWith(
|
|
152
120
|
"Motor",
|
|
@@ -156,22 +124,24 @@ describe("AccessPatternHandlers", () => {
|
|
|
156
124
|
|
|
157
125
|
it("does not validate when first id is not a scope", () => {
|
|
158
126
|
const validateCrossScopeVisibility = vi.fn();
|
|
159
|
-
|
|
160
|
-
isKnownScope: vi.fn().mockReturnValue(false),
|
|
161
|
-
validateCrossScopeVisibility,
|
|
127
|
+
HandlerTestUtils.setupMockGenerator({
|
|
162
128
|
generateAssignmentTarget: vi.fn().mockReturnValue("someVar"),
|
|
129
|
+
validateCrossScopeVisibility,
|
|
130
|
+
});
|
|
131
|
+
HandlerTestUtils.setupMockSymbols({
|
|
132
|
+
knownScopes: new Set(),
|
|
163
133
|
});
|
|
164
134
|
const ctx = createMockContext({
|
|
165
135
|
identifiers: ["someVar"],
|
|
166
136
|
});
|
|
167
137
|
|
|
168
|
-
getHandler()!(ctx
|
|
138
|
+
getHandler()!(ctx);
|
|
169
139
|
|
|
170
140
|
expect(validateCrossScopeVisibility).not.toHaveBeenCalled();
|
|
171
141
|
});
|
|
172
142
|
|
|
173
143
|
it("handles compound assignment", () => {
|
|
174
|
-
|
|
144
|
+
HandlerTestUtils.setupMockGenerator({
|
|
175
145
|
generateAssignmentTarget: vi.fn().mockReturnValue("Counter_value"),
|
|
176
146
|
});
|
|
177
147
|
const ctx = createMockContext({
|
|
@@ -179,7 +149,7 @@ describe("AccessPatternHandlers", () => {
|
|
|
179
149
|
cOp: "+=",
|
|
180
150
|
});
|
|
181
151
|
|
|
182
|
-
const result = getHandler()!(ctx
|
|
152
|
+
const result = getHandler()!(ctx);
|
|
183
153
|
|
|
184
154
|
expect(result).toBe("Counter_value += 5;");
|
|
185
155
|
});
|
|
@@ -192,7 +162,7 @@ describe("AccessPatternHandlers", () => {
|
|
|
192
162
|
)?.[1];
|
|
193
163
|
|
|
194
164
|
it("generates array element assignment", () => {
|
|
195
|
-
|
|
165
|
+
HandlerTestUtils.setupMockGenerator({
|
|
196
166
|
generateAssignmentTarget: vi.fn().mockReturnValue("Buffer_data[i]"),
|
|
197
167
|
});
|
|
198
168
|
const ctx = createMockContext({
|
|
@@ -201,7 +171,7 @@ describe("AccessPatternHandlers", () => {
|
|
|
201
171
|
hasArrayAccess: true,
|
|
202
172
|
});
|
|
203
173
|
|
|
204
|
-
const result = getHandler()!(ctx
|
|
174
|
+
const result = getHandler()!(ctx);
|
|
205
175
|
|
|
206
176
|
expect(result).toBe("Buffer_data[i] = 5;");
|
|
207
177
|
});
|
|
@@ -214,8 +184,8 @@ describe("AccessPatternHandlers", () => {
|
|
|
214
184
|
)?.[1];
|
|
215
185
|
|
|
216
186
|
it("generates scoped member assignment", () => {
|
|
217
|
-
|
|
218
|
-
|
|
187
|
+
CodeGenState.currentScope = "Motor";
|
|
188
|
+
HandlerTestUtils.setupMockGenerator({
|
|
219
189
|
generateAssignmentTarget: vi.fn().mockReturnValue("Motor_speed"),
|
|
220
190
|
});
|
|
221
191
|
const ctx = createMockContext({
|
|
@@ -224,23 +194,23 @@ describe("AccessPatternHandlers", () => {
|
|
|
224
194
|
hasGlobal: false,
|
|
225
195
|
});
|
|
226
196
|
|
|
227
|
-
const result = getHandler()!(ctx
|
|
197
|
+
const result = getHandler()!(ctx);
|
|
228
198
|
|
|
229
199
|
expect(result).toBe("Motor_speed = 5;");
|
|
230
200
|
});
|
|
231
201
|
|
|
232
202
|
it("throws when used outside scope", () => {
|
|
233
|
-
|
|
203
|
+
CodeGenState.currentScope = null;
|
|
234
204
|
const ctx = createMockContext({ hasThis: true, hasGlobal: false });
|
|
235
205
|
|
|
236
|
-
expect(() => getHandler()!(ctx
|
|
206
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
237
207
|
"'this' can only be used inside a scope",
|
|
238
208
|
);
|
|
239
209
|
});
|
|
240
210
|
|
|
241
211
|
it("handles compound assignment", () => {
|
|
242
|
-
|
|
243
|
-
|
|
212
|
+
CodeGenState.currentScope = "Motor";
|
|
213
|
+
HandlerTestUtils.setupMockGenerator({
|
|
244
214
|
generateAssignmentTarget: vi.fn().mockReturnValue("Motor_count"),
|
|
245
215
|
});
|
|
246
216
|
const ctx = createMockContext({
|
|
@@ -251,7 +221,7 @@ describe("AccessPatternHandlers", () => {
|
|
|
251
221
|
cOp: "-=",
|
|
252
222
|
});
|
|
253
223
|
|
|
254
|
-
const result = getHandler()!(ctx
|
|
224
|
+
const result = getHandler()!(ctx);
|
|
255
225
|
|
|
256
226
|
expect(result).toBe("Motor_count -= 5;");
|
|
257
227
|
});
|
|
@@ -264,8 +234,8 @@ describe("AccessPatternHandlers", () => {
|
|
|
264
234
|
)?.[1];
|
|
265
235
|
|
|
266
236
|
it("generates scoped array element assignment", () => {
|
|
267
|
-
|
|
268
|
-
|
|
237
|
+
CodeGenState.currentScope = "Motor";
|
|
238
|
+
HandlerTestUtils.setupMockGenerator({
|
|
269
239
|
generateAssignmentTarget: vi.fn().mockReturnValue("Motor_items[0]"),
|
|
270
240
|
});
|
|
271
241
|
const ctx = createMockContext({
|
|
@@ -276,7 +246,7 @@ describe("AccessPatternHandlers", () => {
|
|
|
276
246
|
hasArrayAccess: true,
|
|
277
247
|
});
|
|
278
248
|
|
|
279
|
-
const result = getHandler()!(ctx
|
|
249
|
+
const result = getHandler()!(ctx);
|
|
280
250
|
|
|
281
251
|
expect(result).toBe("Motor_items[0] = 5;");
|
|
282
252
|
});
|
|
@@ -289,7 +259,7 @@ describe("AccessPatternHandlers", () => {
|
|
|
289
259
|
)?.[1];
|
|
290
260
|
|
|
291
261
|
it("generates read-modify-write for single bit", () => {
|
|
292
|
-
|
|
262
|
+
HandlerTestUtils.setupMockGenerator({
|
|
293
263
|
generateExpression: vi.fn().mockReturnValue("LED_BIT"),
|
|
294
264
|
});
|
|
295
265
|
const ctx = createMockContext({
|
|
@@ -298,7 +268,7 @@ describe("AccessPatternHandlers", () => {
|
|
|
298
268
|
generatedValue: "true",
|
|
299
269
|
});
|
|
300
270
|
|
|
301
|
-
const result = getHandler()!(ctx
|
|
271
|
+
const result = getHandler()!(ctx);
|
|
302
272
|
|
|
303
273
|
expect(result).toContain("GPIO7_DR_SET =");
|
|
304
274
|
expect(result).toContain("& ~(1 <<");
|
|
@@ -306,18 +276,11 @@ describe("AccessPatternHandlers", () => {
|
|
|
306
276
|
});
|
|
307
277
|
|
|
308
278
|
it("generates simple write for write-only register single bit", () => {
|
|
309
|
-
|
|
310
|
-
const deps = createMockDeps({
|
|
279
|
+
HandlerTestUtils.setupMockGenerator({
|
|
311
280
|
generateExpression: vi.fn().mockReturnValue("LED_BIT"),
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
bitmapFields: new Map(),
|
|
316
|
-
registerMemberAccess,
|
|
317
|
-
registerBaseAddresses: new Map(),
|
|
318
|
-
registerMemberOffsets: new Map(),
|
|
319
|
-
registerMemberTypes: new Map(),
|
|
320
|
-
},
|
|
281
|
+
});
|
|
282
|
+
HandlerTestUtils.setupMockSymbols({
|
|
283
|
+
registerMemberAccess: new Map([["GPIO7_DR_SET", "wo"]]),
|
|
321
284
|
});
|
|
322
285
|
const ctx = createMockContext({
|
|
323
286
|
identifiers: ["GPIO7", "DR_SET"],
|
|
@@ -325,24 +288,17 @@ describe("AccessPatternHandlers", () => {
|
|
|
325
288
|
generatedValue: "true",
|
|
326
289
|
});
|
|
327
290
|
|
|
328
|
-
const result = getHandler()!(ctx
|
|
291
|
+
const result = getHandler()!(ctx);
|
|
329
292
|
|
|
330
293
|
expect(result).toBe("GPIO7_DR_SET = (1 << LED_BIT);");
|
|
331
294
|
});
|
|
332
295
|
|
|
333
296
|
it("throws on write-only register with false value", () => {
|
|
334
|
-
|
|
335
|
-
const deps = createMockDeps({
|
|
297
|
+
HandlerTestUtils.setupMockGenerator({
|
|
336
298
|
generateExpression: vi.fn().mockReturnValue("LED_BIT"),
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
bitmapFields: new Map(),
|
|
341
|
-
registerMemberAccess,
|
|
342
|
-
registerBaseAddresses: new Map(),
|
|
343
|
-
registerMemberOffsets: new Map(),
|
|
344
|
-
registerMemberTypes: new Map(),
|
|
345
|
-
},
|
|
299
|
+
});
|
|
300
|
+
HandlerTestUtils.setupMockSymbols({
|
|
301
|
+
registerMemberAccess: new Map([["GPIO7_DR_SET", "wo"]]),
|
|
346
302
|
});
|
|
347
303
|
const ctx = createMockContext({
|
|
348
304
|
identifiers: ["GPIO7", "DR_SET"],
|
|
@@ -350,13 +306,13 @@ describe("AccessPatternHandlers", () => {
|
|
|
350
306
|
generatedValue: "false",
|
|
351
307
|
});
|
|
352
308
|
|
|
353
|
-
expect(() => getHandler()!(ctx
|
|
309
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
354
310
|
"Cannot assign false to write-only register bit",
|
|
355
311
|
);
|
|
356
312
|
});
|
|
357
313
|
|
|
358
314
|
it("generates read-modify-write for bit range", () => {
|
|
359
|
-
|
|
315
|
+
HandlerTestUtils.setupMockGenerator({
|
|
360
316
|
generateExpression: vi
|
|
361
317
|
.fn()
|
|
362
318
|
.mockReturnValueOnce("0")
|
|
@@ -368,7 +324,7 @@ describe("AccessPatternHandlers", () => {
|
|
|
368
324
|
generatedValue: "value",
|
|
369
325
|
});
|
|
370
326
|
|
|
371
|
-
const result = getHandler()!(ctx
|
|
327
|
+
const result = getHandler()!(ctx);
|
|
372
328
|
|
|
373
329
|
expect(result).toContain("GPIO7_DR_SET =");
|
|
374
330
|
expect(result).toContain("& ~(");
|
|
@@ -376,21 +332,14 @@ describe("AccessPatternHandlers", () => {
|
|
|
376
332
|
});
|
|
377
333
|
|
|
378
334
|
it("generates simple write for write-only bit range", () => {
|
|
379
|
-
|
|
380
|
-
const deps = createMockDeps({
|
|
335
|
+
HandlerTestUtils.setupMockGenerator({
|
|
381
336
|
generateExpression: vi
|
|
382
337
|
.fn()
|
|
383
338
|
.mockReturnValueOnce("0")
|
|
384
339
|
.mockReturnValueOnce("8"),
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
bitmapFields: new Map(),
|
|
389
|
-
registerMemberAccess,
|
|
390
|
-
registerBaseAddresses: new Map(),
|
|
391
|
-
registerMemberOffsets: new Map(),
|
|
392
|
-
registerMemberTypes: new Map(),
|
|
393
|
-
},
|
|
340
|
+
});
|
|
341
|
+
HandlerTestUtils.setupMockSymbols({
|
|
342
|
+
registerMemberAccess: new Map([["GPIO7_DR_SET", "w1s"]]),
|
|
394
343
|
});
|
|
395
344
|
const ctx = createMockContext({
|
|
396
345
|
identifiers: ["GPIO7", "DR_SET"],
|
|
@@ -398,27 +347,20 @@ describe("AccessPatternHandlers", () => {
|
|
|
398
347
|
generatedValue: "value",
|
|
399
348
|
});
|
|
400
349
|
|
|
401
|
-
const result = getHandler()!(ctx
|
|
350
|
+
const result = getHandler()!(ctx);
|
|
402
351
|
|
|
403
352
|
expect(result).not.toContain("& ~");
|
|
404
353
|
});
|
|
405
354
|
|
|
406
355
|
it("throws on write-only bit range with 0 value", () => {
|
|
407
|
-
|
|
408
|
-
const deps = createMockDeps({
|
|
356
|
+
HandlerTestUtils.setupMockGenerator({
|
|
409
357
|
generateExpression: vi
|
|
410
358
|
.fn()
|
|
411
359
|
.mockReturnValueOnce("0")
|
|
412
360
|
.mockReturnValueOnce("8"),
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
bitmapFields: new Map(),
|
|
417
|
-
registerMemberAccess,
|
|
418
|
-
registerBaseAddresses: new Map(),
|
|
419
|
-
registerMemberOffsets: new Map(),
|
|
420
|
-
registerMemberTypes: new Map(),
|
|
421
|
-
},
|
|
361
|
+
});
|
|
362
|
+
HandlerTestUtils.setupMockSymbols({
|
|
363
|
+
registerMemberAccess: new Map([["GPIO7_DR_SET", "w1c"]]),
|
|
422
364
|
});
|
|
423
365
|
const ctx = createMockContext({
|
|
424
366
|
identifiers: ["GPIO7", "DR_SET"],
|
|
@@ -426,13 +368,12 @@ describe("AccessPatternHandlers", () => {
|
|
|
426
368
|
generatedValue: "0",
|
|
427
369
|
});
|
|
428
370
|
|
|
429
|
-
expect(() => getHandler()!(ctx
|
|
371
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
430
372
|
"Cannot assign 0 to write-only register bits",
|
|
431
373
|
);
|
|
432
374
|
});
|
|
433
375
|
|
|
434
376
|
it("throws on compound assignment", () => {
|
|
435
|
-
const deps = createMockDeps();
|
|
436
377
|
const ctx = createMockContext({
|
|
437
378
|
identifiers: ["GPIO7", "DR_SET"],
|
|
438
379
|
subscripts: [{ mockValue: "LED_BIT" } as never],
|
|
@@ -440,7 +381,7 @@ describe("AccessPatternHandlers", () => {
|
|
|
440
381
|
cnextOp: "+<-",
|
|
441
382
|
});
|
|
442
383
|
|
|
443
|
-
expect(() => getHandler()!(ctx
|
|
384
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
444
385
|
"Compound assignment operators not supported for bit field access",
|
|
445
386
|
);
|
|
446
387
|
});
|
|
@@ -453,23 +394,26 @@ describe("AccessPatternHandlers", () => {
|
|
|
453
394
|
)?.[1];
|
|
454
395
|
|
|
455
396
|
it("generates standard member chain assignment", () => {
|
|
456
|
-
|
|
397
|
+
HandlerTestUtils.setupMockGenerator({
|
|
457
398
|
generateAssignmentTarget: vi
|
|
458
399
|
.fn()
|
|
459
400
|
.mockReturnValue("device.config.value"),
|
|
401
|
+
analyzeMemberChainForBitAccess: vi
|
|
402
|
+
.fn()
|
|
403
|
+
.mockReturnValue({ isBitAccess: false }),
|
|
460
404
|
});
|
|
461
405
|
const ctx = createMockContext({
|
|
462
406
|
identifiers: ["device", "config", "value"],
|
|
463
407
|
memberAccessDepth: 2,
|
|
464
408
|
});
|
|
465
409
|
|
|
466
|
-
const result = getHandler()!(ctx
|
|
410
|
+
const result = getHandler()!(ctx);
|
|
467
411
|
|
|
468
412
|
expect(result).toBe("device.config.value = 5;");
|
|
469
413
|
});
|
|
470
414
|
|
|
471
415
|
it("generates bit access when detected in member chain", () => {
|
|
472
|
-
|
|
416
|
+
HandlerTestUtils.setupMockGenerator({
|
|
473
417
|
analyzeMemberChainForBitAccess: vi.fn().mockReturnValue({
|
|
474
418
|
isBitAccess: true,
|
|
475
419
|
baseTarget: "grid[2][3].flags",
|
|
@@ -483,7 +427,7 @@ describe("AccessPatternHandlers", () => {
|
|
|
483
427
|
generatedValue: "true",
|
|
484
428
|
});
|
|
485
429
|
|
|
486
|
-
const result = getHandler()!(ctx
|
|
430
|
+
const result = getHandler()!(ctx);
|
|
487
431
|
|
|
488
432
|
expect(result).toContain("grid[2][3].flags =");
|
|
489
433
|
expect(result).toContain("& ~(1 << 0)");
|
|
@@ -491,7 +435,7 @@ describe("AccessPatternHandlers", () => {
|
|
|
491
435
|
});
|
|
492
436
|
|
|
493
437
|
it("uses 1ULL for 64-bit bit access", () => {
|
|
494
|
-
|
|
438
|
+
HandlerTestUtils.setupMockGenerator({
|
|
495
439
|
analyzeMemberChainForBitAccess: vi.fn().mockReturnValue({
|
|
496
440
|
isBitAccess: true,
|
|
497
441
|
baseTarget: "data.flags",
|
|
@@ -505,13 +449,13 @@ describe("AccessPatternHandlers", () => {
|
|
|
505
449
|
generatedValue: "false",
|
|
506
450
|
});
|
|
507
451
|
|
|
508
|
-
const result = getHandler()!(ctx
|
|
452
|
+
const result = getHandler()!(ctx);
|
|
509
453
|
|
|
510
454
|
expect(result).toContain("1ULL << bit");
|
|
511
455
|
});
|
|
512
456
|
|
|
513
457
|
it("throws on compound assignment for bit access in member chain", () => {
|
|
514
|
-
|
|
458
|
+
HandlerTestUtils.setupMockGenerator({
|
|
515
459
|
analyzeMemberChainForBitAccess: vi.fn().mockReturnValue({
|
|
516
460
|
isBitAccess: true,
|
|
517
461
|
baseTarget: "data.flags",
|
|
@@ -524,14 +468,17 @@ describe("AccessPatternHandlers", () => {
|
|
|
524
468
|
cnextOp: "+<-",
|
|
525
469
|
});
|
|
526
470
|
|
|
527
|
-
expect(() => getHandler()!(ctx
|
|
471
|
+
expect(() => getHandler()!(ctx)).toThrow(
|
|
528
472
|
"Compound assignment operators not supported for bit field access",
|
|
529
473
|
);
|
|
530
474
|
});
|
|
531
475
|
|
|
532
476
|
it("handles compound assignment for normal member chain", () => {
|
|
533
|
-
|
|
477
|
+
HandlerTestUtils.setupMockGenerator({
|
|
534
478
|
generateAssignmentTarget: vi.fn().mockReturnValue("obj.field"),
|
|
479
|
+
analyzeMemberChainForBitAccess: vi
|
|
480
|
+
.fn()
|
|
481
|
+
.mockReturnValue({ isBitAccess: false }),
|
|
535
482
|
});
|
|
536
483
|
const ctx = createMockContext({
|
|
537
484
|
identifiers: ["obj", "field"],
|
|
@@ -539,7 +486,7 @@ describe("AccessPatternHandlers", () => {
|
|
|
539
486
|
cOp: "*=",
|
|
540
487
|
});
|
|
541
488
|
|
|
542
|
-
const result = getHandler()!(ctx
|
|
489
|
+
const result = getHandler()!(ctx);
|
|
543
490
|
|
|
544
491
|
expect(result).toBe("obj.field *= 5;");
|
|
545
492
|
});
|