c-next 0.1.64 → 0.1.66

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 (33) hide show
  1. package/grammar/CNext.g4 +9 -2
  2. package/package.json +5 -1
  3. package/src/transpiler/logic/parser/grammar/CNext.interp +2 -1
  4. package/src/transpiler/logic/parser/grammar/CNextListener.ts +11 -0
  5. package/src/transpiler/logic/parser/grammar/CNextParser.ts +992 -870
  6. package/src/transpiler/logic/parser/grammar/CNextVisitor.ts +7 -0
  7. package/src/transpiler/logic/symbols/cnext/__tests__/FunctionCollector.test.ts +6 -6
  8. package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolAdapter.test.ts +179 -0
  9. package/src/transpiler/logic/symbols/cnext/__tests__/VariableCollector.test.ts +55 -0
  10. package/src/transpiler/logic/symbols/cnext/adapters/TSymbolAdapter.ts +76 -8
  11. package/src/transpiler/logic/symbols/cnext/collectors/FunctionCollector.ts +9 -10
  12. package/src/transpiler/logic/symbols/cnext/collectors/StructCollector.ts +7 -1
  13. package/src/transpiler/logic/symbols/cnext/collectors/VariableCollector.ts +33 -14
  14. package/src/transpiler/output/codegen/CodeGenerator.ts +243 -166
  15. package/src/transpiler/output/codegen/__tests__/CodeGenerator.coverage.test.ts +1086 -0
  16. package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +254 -22
  17. package/src/transpiler/output/codegen/generators/declarationGenerators/ArrayDimensionUtils.ts +17 -9
  18. package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ArrayDimensionUtils.test.ts +5 -3
  19. package/src/transpiler/output/codegen/generators/declarationGenerators/__tests__/ScopeGenerator.test.ts +12 -7
  20. package/src/transpiler/output/codegen/generators/expressions/PostfixExpressionGenerator.ts +624 -12
  21. package/src/transpiler/output/codegen/generators/expressions/__tests__/PostfixExpressionGenerator.test.ts +819 -0
  22. package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +337 -0
  23. package/src/transpiler/output/codegen/helpers/ParameterSignatureBuilder.ts +135 -0
  24. package/src/transpiler/output/codegen/helpers/TypeGenerationHelper.ts +4 -0
  25. package/src/transpiler/output/codegen/helpers/VariableDeclarationFormatter.ts +118 -0
  26. package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +426 -0
  27. package/src/transpiler/output/codegen/helpers/__tests__/ParameterSignatureBuilder.test.ts +315 -0
  28. package/src/transpiler/output/codegen/helpers/__tests__/VariableDeclarationFormatter.test.ts +333 -0
  29. package/src/transpiler/output/codegen/types/IParameterInput.ts +58 -0
  30. package/src/transpiler/output/codegen/types/IVariableFormatInput.ts +51 -0
  31. package/src/transpiler/output/headers/BaseHeaderGenerator.ts +20 -35
  32. package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +21 -48
  33. package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +0 -64
@@ -1568,7 +1568,7 @@ describe("CodeGenerator", () => {
1568
1568
 
1569
1569
  it("should generate array parameter", () => {
1570
1570
  const source = `
1571
- void process(u32 arr[10]) { }
1571
+ void process(u32[10] arr) { }
1572
1572
  `;
1573
1573
  const { tree, tokenStream } = CNextSourceParser.parse(source);
1574
1574
  const generator = new CodeGenerator();
@@ -5284,7 +5284,7 @@ describe("CodeGenerator", () => {
5284
5284
  describe("Array passed to function", () => {
5285
5285
  it("should pass array without address-of operator", () => {
5286
5286
  const source = `
5287
- void processData(u32 data[]) { }
5287
+ void processData(u32[5] data) { }
5288
5288
  u32[5] myData;
5289
5289
  void main() {
5290
5290
  processData(myData);
@@ -5942,7 +5942,7 @@ describe("CodeGenerator", () => {
5942
5942
  describe("Function with array return type simulation", () => {
5943
5943
  it("should handle function returning via output parameter", () => {
5944
5944
  const source = `
5945
- void getData(u8 output[]) {
5945
+ void getData(u8[2] output) {
5946
5946
  output[0] <- 1;
5947
5947
  output[1] <- 2;
5948
5948
  }
@@ -6285,7 +6285,7 @@ describe("CodeGenerator", () => {
6285
6285
  describe("Array parameter bounds", () => {
6286
6286
  it("should handle sized array parameter", () => {
6287
6287
  const source = `
6288
- void process(u32 arr[10]) {
6288
+ void process(u32[10] arr) {
6289
6289
  arr[0] <- 1;
6290
6290
  }
6291
6291
  `;
@@ -6813,7 +6813,7 @@ describe("CodeGenerator", () => {
6813
6813
  describe("Local array tracking", () => {
6814
6814
  it("should track local arrays for function arguments", () => {
6815
6815
  const source = `
6816
- void process(u8 arr[]) { }
6816
+ void process(u8[10] arr) { }
6817
6817
  void main() {
6818
6818
  u8[10] local;
6819
6819
  process(local);
@@ -8067,7 +8067,7 @@ describe("CodeGenerator", () => {
8067
8067
 
8068
8068
  it("should handle identifier argument (array)", () => {
8069
8069
  const source = `
8070
- void callee(u32 arr[10]) { }
8070
+ void callee(u32[10] arr) { }
8071
8071
  void test() {
8072
8072
  u32[10] data;
8073
8073
  callee(data);
@@ -8181,7 +8181,7 @@ describe("CodeGenerator", () => {
8181
8181
  it("should handle struct field array argument", () => {
8182
8182
  const source = `
8183
8183
  struct Data { u32 values[10]; }
8184
- void callee(u32 arr[10]) { }
8184
+ void callee(u32[10] arr) { }
8185
8185
  void test(Data d) {
8186
8186
  callee(d.values);
8187
8187
  }
@@ -8246,7 +8246,7 @@ describe("CodeGenerator", () => {
8246
8246
  it("should handle struct member array as argument (array decay)", () => {
8247
8247
  const source = `
8248
8248
  struct Config { u8 data[16]; }
8249
- void processData(u8 buffer[16]) { }
8249
+ void processData(u8[16] buffer) { }
8250
8250
  void test() {
8251
8251
  Config cfg;
8252
8252
  processData(cfg.data);
@@ -8377,7 +8377,7 @@ describe("CodeGenerator", () => {
8377
8377
 
8378
8378
  it("should process array parameter type", () => {
8379
8379
  const source = `
8380
- void test(u32 arr[10]) {
8380
+ void test(u32[10] arr) {
8381
8381
  u32 x <- arr[0];
8382
8382
  }
8383
8383
  `;
@@ -8583,7 +8583,7 @@ describe("CodeGenerator", () => {
8583
8583
 
8584
8584
  it("should error on sizeof of array parameter", () => {
8585
8585
  const source = `
8586
- void test(u32 arr[10]) {
8586
+ void test(u32[10] arr) {
8587
8587
  u32 size <- sizeof(arr);
8588
8588
  }
8589
8589
  `;
@@ -8670,7 +8670,7 @@ describe("CodeGenerator", () => {
8670
8670
 
8671
8671
  it("should handle parameter array access", () => {
8672
8672
  const source = `
8673
- void test(u32 arr[10]) {
8673
+ void test(u32[10] arr) {
8674
8674
  u32 val <- arr[0];
8675
8675
  }
8676
8676
  `;
@@ -10032,7 +10032,7 @@ describe("CodeGenerator", () => {
10032
10032
 
10033
10033
  it("should resolve array parameter", () => {
10034
10034
  const source = `
10035
- void test(u32 arr[10]) {
10035
+ void test(u32[10] arr) {
10036
10036
  arr[0] <- 1;
10037
10037
  }
10038
10038
  `;
@@ -11078,7 +11078,7 @@ describe("CodeGenerator", () => {
11078
11078
 
11079
11079
  it("should not dereference array parameter for index access", () => {
11080
11080
  const source = `
11081
- u32 getElement(u32 arr[10]) {
11081
+ u32 getElement(u32[10] arr) {
11082
11082
  return arr[5];
11083
11083
  }
11084
11084
  `;
@@ -11263,7 +11263,7 @@ describe("CodeGenerator", () => {
11263
11263
  describe("function call argument generation", () => {
11264
11264
  it("should handle array argument passed to function", () => {
11265
11265
  const source = `
11266
- void process(u32 data[10]) {
11266
+ void process(u32[10] data) {
11267
11267
  data[0] <- 1;
11268
11268
  }
11269
11269
  void test() {
@@ -12301,7 +12301,7 @@ describe("CodeGenerator", () => {
12301
12301
  describe("array parameter dimensions", () => {
12302
12302
  it("should handle multi-dimensional array parameter", () => {
12303
12303
  const source = `
12304
- void processMatrix(u32 matrix[3][3]) {
12304
+ void processMatrix(u32[3][3] matrix) {
12305
12305
  matrix[0][0] <- 1;
12306
12306
  }
12307
12307
  `;
@@ -12318,10 +12318,52 @@ describe("CodeGenerator", () => {
12318
12318
 
12319
12319
  expect(code).toContain("uint32_t matrix[3][3]");
12320
12320
  });
12321
+ });
12322
+
12323
+ describe("C-style array parameter rejection", () => {
12324
+ it("should reject C-style array parameter with single dimension", () => {
12325
+ const source = `
12326
+ void process(u8 data[8]) {
12327
+ data[0] <- 0xFF;
12328
+ }
12329
+ `;
12330
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
12331
+ const generator = new CodeGenerator();
12332
+ const symbolTable = new SymbolTable();
12333
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
12334
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
12335
+
12336
+ expect(() => {
12337
+ generator.generate(tree, symbolTable, tokenStream, {
12338
+ symbolInfo: symbols,
12339
+ sourcePath: "test.cnx",
12340
+ });
12341
+ }).toThrow(/C-style array parameter is not allowed/);
12342
+ });
12343
+
12344
+ it("should reject C-style array parameter with multiple dimensions", () => {
12345
+ const source = `
12346
+ void process(u32 matrix[3][3]) {
12347
+ matrix[0][0] <- 1;
12348
+ }
12349
+ `;
12350
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
12351
+ const generator = new CodeGenerator();
12352
+ const symbolTable = new SymbolTable();
12353
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
12354
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
12355
+
12356
+ expect(() => {
12357
+ generator.generate(tree, symbolTable, tokenStream, {
12358
+ symbolInfo: symbols,
12359
+ sourcePath: "test.cnx",
12360
+ });
12361
+ }).toThrow(/C-style array parameter is not allowed/);
12362
+ });
12321
12363
 
12322
- it("should handle unsized array parameter", () => {
12364
+ it("should reject C-style unsized array parameter", () => {
12323
12365
  const source = `
12324
- void processData(u8 data[], u32 len) {
12366
+ void process(u8 data[]) {
12325
12367
  data[0] <- 0xFF;
12326
12368
  }
12327
12369
  `;
@@ -12331,12 +12373,202 @@ describe("CodeGenerator", () => {
12331
12373
  const tSymbols = CNextResolver.resolve(tree, "test.cnx");
12332
12374
  const symbols = TSymbolInfoAdapter.convert(tSymbols);
12333
12375
 
12376
+ expect(() => {
12377
+ generator.generate(tree, symbolTable, tokenStream, {
12378
+ symbolInfo: symbols,
12379
+ sourcePath: "test.cnx",
12380
+ });
12381
+ }).toThrow(/C-style array parameter is not allowed/);
12382
+ });
12383
+
12384
+ it("should suggest correct C-Next style syntax in error message", () => {
12385
+ const source = `
12386
+ void process(i32 values[10]) {
12387
+ values[0] <- 1;
12388
+ }
12389
+ `;
12390
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
12391
+ const generator = new CodeGenerator();
12392
+ const symbolTable = new SymbolTable();
12393
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
12394
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
12395
+
12396
+ expect(() => {
12397
+ generator.generate(tree, symbolTable, tokenStream, {
12398
+ symbolInfo: symbols,
12399
+ sourcePath: "test.cnx",
12400
+ });
12401
+ }).toThrow(/Use 'i32\[10\] values' instead of 'i32 values\[10\]'/);
12402
+ });
12403
+ });
12404
+
12405
+ describe("user type array parameters", () => {
12406
+ it("should handle struct array parameter with C-Next style", () => {
12407
+ const source = `
12408
+ struct Point { i32 x; i32 y; }
12409
+ void processPoints(Point[4] points) {
12410
+ points[0].x <- 10;
12411
+ }
12412
+ `;
12413
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
12414
+ const generator = new CodeGenerator();
12415
+ const symbolTable = new SymbolTable();
12416
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
12417
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
12418
+
12334
12419
  const code = generator.generate(tree, symbolTable, tokenStream, {
12335
12420
  symbolInfo: symbols,
12336
12421
  sourcePath: "test.cnx",
12337
12422
  });
12338
12423
 
12339
- expect(code).toContain("uint8_t data[]");
12424
+ expect(code).toContain("Point points[4]");
12425
+ });
12426
+
12427
+ it("should detect struct type in arrayType for parameter", () => {
12428
+ const source = `
12429
+ struct Data { u32 value; }
12430
+ void process(Data[8] items) {
12431
+ items[0].value <- 42;
12432
+ }
12433
+ `;
12434
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
12435
+ const generator = new CodeGenerator();
12436
+ const symbolTable = new SymbolTable();
12437
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
12438
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
12439
+
12440
+ const code = generator.generate(tree, symbolTable, tokenStream, {
12441
+ symbolInfo: symbols,
12442
+ sourcePath: "test.cnx",
12443
+ });
12444
+
12445
+ expect(code).toContain("Data items[8]");
12446
+ expect(code).toContain("items[0].value = 42");
12447
+ });
12448
+ });
12449
+
12450
+ describe("multi-dimensional C-Next style array parameters", () => {
12451
+ it("should handle 2D array parameter", () => {
12452
+ const source = `
12453
+ void processMatrix(i32[4][4] matrix) {
12454
+ matrix[0][0] <- 1;
12455
+ }
12456
+ `;
12457
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
12458
+ const generator = new CodeGenerator();
12459
+ const symbolTable = new SymbolTable();
12460
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
12461
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
12462
+
12463
+ const code = generator.generate(tree, symbolTable, tokenStream, {
12464
+ symbolInfo: symbols,
12465
+ sourcePath: "test.cnx",
12466
+ });
12467
+
12468
+ expect(code).toContain("int32_t matrix[4][4]");
12469
+ });
12470
+
12471
+ it("should handle 3D array parameter", () => {
12472
+ const source = `
12473
+ void processCube(u8[2][3][4] cube) {
12474
+ cube[0][0][0] <- 0xFF;
12475
+ }
12476
+ `;
12477
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
12478
+ const generator = new CodeGenerator();
12479
+ const symbolTable = new SymbolTable();
12480
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
12481
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
12482
+
12483
+ const code = generator.generate(tree, symbolTable, tokenStream, {
12484
+ symbolInfo: symbols,
12485
+ sourcePath: "test.cnx",
12486
+ });
12487
+
12488
+ expect(code).toContain("uint8_t cube[2][3][4]");
12489
+ });
12490
+
12491
+ it("should reject unbounded array parameter for memory safety", () => {
12492
+ const source = `
12493
+ void processRows(u32[][4] rows, u32 count) {
12494
+ rows[0][0] <- 1;
12495
+ }
12496
+ `;
12497
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
12498
+ const generator = new CodeGenerator();
12499
+ const symbolTable = new SymbolTable();
12500
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
12501
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
12502
+
12503
+ expect(() => {
12504
+ generator.generate(tree, symbolTable, tokenStream, {
12505
+ symbolInfo: symbols,
12506
+ sourcePath: "test.cnx",
12507
+ });
12508
+ }).toThrow(/Unbounded array parameters are not allowed/);
12509
+ });
12510
+
12511
+ it("should reject simple unbounded array parameter", () => {
12512
+ const source = `
12513
+ void process(u8[] data) {
12514
+ data[0] <- 0xFF;
12515
+ }
12516
+ `;
12517
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
12518
+ const generator = new CodeGenerator();
12519
+ const symbolTable = new SymbolTable();
12520
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
12521
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
12522
+
12523
+ expect(() => {
12524
+ generator.generate(tree, symbolTable, tokenStream, {
12525
+ symbolInfo: symbols,
12526
+ sourcePath: "test.cnx",
12527
+ });
12528
+ }).toThrow(/Unbounded array parameters are not allowed/);
12529
+ });
12530
+ });
12531
+
12532
+ describe("string array parameter capacity", () => {
12533
+ it("should add capacity dimension for string array parameter", () => {
12534
+ const source = `
12535
+ void processNames(string<16>[5] names) {
12536
+ names[0] <- "test";
12537
+ }
12538
+ `;
12539
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
12540
+ const generator = new CodeGenerator();
12541
+ const symbolTable = new SymbolTable();
12542
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
12543
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
12544
+
12545
+ const code = generator.generate(tree, symbolTable, tokenStream, {
12546
+ symbolInfo: symbols,
12547
+ sourcePath: "test.cnx",
12548
+ });
12549
+
12550
+ // string<16>[5] -> char[5][17] (capacity + 1 for null terminator)
12551
+ expect(code).toContain("char names[5][17]");
12552
+ });
12553
+
12554
+ it("should handle string array with larger capacity", () => {
12555
+ const source = `
12556
+ void logMessages(string<128>[10] messages) {
12557
+ messages[0] <- "hello";
12558
+ }
12559
+ `;
12560
+ const { tree, tokenStream } = CNextSourceParser.parse(source);
12561
+ const generator = new CodeGenerator();
12562
+ const symbolTable = new SymbolTable();
12563
+ const tSymbols = CNextResolver.resolve(tree, "test.cnx");
12564
+ const symbols = TSymbolInfoAdapter.convert(tSymbols);
12565
+
12566
+ const code = generator.generate(tree, symbolTable, tokenStream, {
12567
+ symbolInfo: symbols,
12568
+ sourcePath: "test.cnx",
12569
+ });
12570
+
12571
+ expect(code).toContain("char messages[10][129]");
12340
12572
  });
12341
12573
  });
12342
12574
 
@@ -12633,7 +12865,7 @@ describe("CodeGenerator", () => {
12633
12865
  describe("string array parameters", () => {
12634
12866
  it("should handle string array parameter with capacity", () => {
12635
12867
  const source = `
12636
- void processNames(string<32> names[10]) {
12868
+ void processNames(string<32>[10] names) {
12637
12869
  string<32> first <- names[0];
12638
12870
  }
12639
12871
  `;
@@ -13499,7 +13731,7 @@ describe("CodeGenerator", () => {
13499
13731
 
13500
13732
  it("should handle array parameters", () => {
13501
13733
  const source = `
13502
- void sum(u32 values[], u32 count) {
13734
+ void sum(u32[10] values) {
13503
13735
  u32 total <- 0;
13504
13736
  }
13505
13737
  `;
@@ -13515,7 +13747,7 @@ describe("CodeGenerator", () => {
13515
13747
  });
13516
13748
 
13517
13749
  expect(code).toContain("values");
13518
- expect(code).toContain("count");
13750
+ expect(code).toContain("uint32_t values[10]");
13519
13751
  });
13520
13752
  });
13521
13753
 
@@ -15254,7 +15486,7 @@ describe("CodeGenerator", () => {
15254
15486
 
15255
15487
  it("should generate function with array parameter", () => {
15256
15488
  const source = `
15257
- void process(u32 arr[10]) {
15489
+ void process(u32[10] arr) {
15258
15490
  u32 val <- arr[0];
15259
15491
  }
15260
15492
  `;
@@ -23,18 +23,26 @@ function generateArrayTypeDimension(
23
23
  return "";
24
24
  }
25
25
 
26
- const sizeExpr = arrayTypeCtx.expression();
27
- if (!sizeExpr) {
28
- return "[]";
29
- }
26
+ // Handle all dimensions from arrayType (supports u8[4][4], u8[], etc.)
27
+ const dims = arrayTypeCtx.arrayTypeDimension();
28
+ let result = "";
29
+ for (const dim of dims) {
30
+ const sizeExpr = dim.expression();
31
+ if (!sizeExpr) {
32
+ result += "[]";
33
+ continue;
34
+ }
30
35
 
31
- const constValue = orchestrator.tryEvaluateConstant(sizeExpr);
32
- if (constValue === undefined) {
33
- // Fall back to expression generation for macros, enums, etc.
34
- return `[${orchestrator.generateExpression(sizeExpr)}]`;
36
+ const constValue = orchestrator.tryEvaluateConstant(sizeExpr);
37
+ if (constValue === undefined) {
38
+ // Fall back to expression generation for macros, enums, etc.
39
+ result += `[${orchestrator.generateExpression(sizeExpr)}]`;
40
+ } else {
41
+ result += `[${constValue}]`;
42
+ }
35
43
  }
36
44
 
37
- return `[${constValue}]`;
45
+ return result;
38
46
  }
39
47
 
40
48
  /**
@@ -26,7 +26,7 @@ describe("ArrayDimensionUtils", () => {
26
26
  it("returns [] for context with no expression", () => {
27
27
  const orchestrator = createMockOrchestrator();
28
28
  const ctx = {
29
- expression: () => null,
29
+ arrayTypeDimension: () => [{ expression: () => null }],
30
30
  };
31
31
  const result = ArrayDimensionUtils.generateArrayTypeDimension(
32
32
  ctx as never,
@@ -38,7 +38,9 @@ describe("ArrayDimensionUtils", () => {
38
38
  it("returns constant dimension when evaluable", () => {
39
39
  const orchestrator = createMockOrchestrator(16);
40
40
  const ctx = {
41
- expression: () => ({ getText: () => "16" }),
41
+ arrayTypeDimension: () => [
42
+ { expression: () => ({ getText: () => "16" }) },
43
+ ],
42
44
  };
43
45
  const result = ArrayDimensionUtils.generateArrayTypeDimension(
44
46
  ctx as never,
@@ -52,7 +54,7 @@ describe("ArrayDimensionUtils", () => {
52
54
  const orchestrator = createMockOrchestrator(undefined, "BUFFER_SIZE");
53
55
  const mockExpr = { getText: () => "BUFFER_SIZE" };
54
56
  const ctx = {
55
- expression: () => mockExpr,
57
+ arrayTypeDimension: () => [{ expression: () => mockExpr }],
56
58
  };
57
59
  const result = ArrayDimensionUtils.generateArrayTypeDimension(
58
60
  ctx as never,
@@ -44,15 +44,11 @@ function createMockConstModifier(
44
44
 
45
45
  /**
46
46
  * Create a mock array type context.
47
+ * Updated for new grammar: arrayType has arrayTypeDimension() which returns dimensions
47
48
  */
48
49
  function createMockArrayType(sizeExpr?: string | null) {
49
- if (sizeExpr === null) {
50
- // Empty brackets - no expression
51
- return {
52
- expression: () => null,
53
- };
54
- }
55
- return {
50
+ // Create a single dimension with optional expression
51
+ const mockDimension = {
56
52
  expression: () =>
57
53
  sizeExpr
58
54
  ? {
@@ -61,6 +57,15 @@ function createMockArrayType(sizeExpr?: string | null) {
61
57
  }
62
58
  : null,
63
59
  };
60
+
61
+ return {
62
+ // New grammar: arrayTypeDimension() returns array of dimensions
63
+ arrayTypeDimension: () => [mockDimension],
64
+ // Keep primitiveType for base type extraction
65
+ primitiveType: () => null,
66
+ userType: () => null,
67
+ stringType: () => null,
68
+ };
64
69
  }
65
70
 
66
71
  /**