c-next 0.2.11 → 0.2.13

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 (75) hide show
  1. package/README.md +80 -649
  2. package/dist/index.js +8273 -6357
  3. package/dist/index.js.map +4 -4
  4. package/grammar/C.g4 +17 -4
  5. package/package.json +3 -3
  6. package/src/__tests__/index.test.ts +1 -1
  7. package/src/cli/CleanCommand.ts +8 -12
  8. package/src/cli/Cli.ts +29 -6
  9. package/src/cli/Runner.ts +42 -62
  10. package/src/cli/__tests__/CleanCommand.test.ts +10 -10
  11. package/src/cli/__tests__/Cli.test.ts +59 -7
  12. package/src/cli/__tests__/ConfigPrinter.test.ts +12 -12
  13. package/src/cli/__tests__/PathNormalizer.test.ts +5 -5
  14. package/src/cli/__tests__/Runner.test.ts +108 -82
  15. package/src/cli/serve/ServeCommand.ts +1 -1
  16. package/src/cli/types/ICliConfig.ts +2 -2
  17. package/src/lib/parseWithSymbols.ts +21 -21
  18. package/src/transpiler/Transpiler.ts +99 -46
  19. package/src/transpiler/__tests__/DualCodePaths.test.ts +29 -29
  20. package/src/transpiler/__tests__/Transpiler.coverage.test.ts +244 -72
  21. package/src/transpiler/__tests__/Transpiler.test.ts +32 -72
  22. package/src/transpiler/__tests__/determineProjectRoot.test.ts +30 -28
  23. package/src/transpiler/__tests__/needsConditionalPreprocessing.test.ts +1 -1
  24. package/src/transpiler/data/CNextMarkerDetector.ts +34 -0
  25. package/src/transpiler/data/CppEntryPointScanner.ts +174 -0
  26. package/src/transpiler/data/FileDiscovery.ts +2 -105
  27. package/src/transpiler/data/InputExpansion.ts +37 -81
  28. package/src/transpiler/data/__tests__/CNextMarkerDetector.test.ts +62 -0
  29. package/src/transpiler/data/__tests__/CppEntryPointScanner.test.ts +239 -0
  30. package/src/transpiler/data/__tests__/FileDiscovery.test.ts +45 -191
  31. package/src/transpiler/data/__tests__/InputExpansion.test.ts +36 -204
  32. package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +2 -2
  33. package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +4 -5
  34. package/src/transpiler/logic/parser/c/grammar/C.interp +33 -3
  35. package/src/transpiler/logic/parser/c/grammar/C.tokens +237 -207
  36. package/src/transpiler/logic/parser/c/grammar/CLexer.interp +48 -3
  37. package/src/transpiler/logic/parser/c/grammar/CLexer.tokens +237 -207
  38. package/src/transpiler/logic/parser/c/grammar/CLexer.ts +702 -611
  39. package/src/transpiler/logic/parser/c/grammar/CParser.ts +1221 -1107
  40. package/src/transpiler/logic/symbols/SymbolTable.ts +147 -73
  41. package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +157 -14
  42. package/src/transpiler/logic/symbols/c/__tests__/CResolver.integration.test.ts +3 -3
  43. package/src/transpiler/logic/symbols/c/collectors/StructCollector.ts +7 -37
  44. package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolInfoAdapter.test.ts +6 -6
  45. package/src/transpiler/logic/symbols/cnext/adapters/TSymbolInfoAdapter.ts +28 -27
  46. package/src/transpiler/logic/symbols/cnext/index.ts +4 -4
  47. package/src/transpiler/logic/symbols/cnext/utils/SymbolNameUtils.ts +5 -5
  48. package/src/transpiler/output/codegen/CodeGenerator.ts +16 -1
  49. package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +15 -0
  50. package/src/transpiler/output/codegen/__tests__/ExpressionWalker.test.ts +3 -3
  51. package/src/transpiler/output/codegen/__tests__/RequireInclude.test.ts +14 -14
  52. package/src/transpiler/output/codegen/__tests__/TrackVariableTypeHelpers.test.ts +2 -2
  53. package/src/transpiler/output/codegen/helpers/FunctionContextManager.ts +15 -3
  54. package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +14 -6
  55. package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +1 -0
  56. package/src/transpiler/output/codegen/types/IFunctionContextCallbacks.ts +2 -0
  57. package/src/transpiler/output/codegen/utils/QualifiedNameGenerator.ts +7 -7
  58. package/src/transpiler/output/codegen/utils/__tests__/QualifiedNameGenerator.test.ts +3 -3
  59. package/src/transpiler/output/headers/BaseHeaderGenerator.ts +10 -1
  60. package/src/transpiler/output/headers/HeaderGenerator.ts +3 -0
  61. package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +6 -2
  62. package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +16 -0
  63. package/src/transpiler/output/headers/adapters/HeaderSymbolAdapter.ts +19 -19
  64. package/src/transpiler/output/headers/adapters/__tests__/HeaderSymbolAdapter.test.ts +5 -5
  65. package/src/transpiler/state/SymbolRegistry.ts +10 -12
  66. package/src/transpiler/state/__tests__/SymbolRegistry.test.ts +11 -13
  67. package/src/transpiler/types/ICachedFileEntry.ts +4 -0
  68. package/src/transpiler/types/IPipelineFile.ts +3 -0
  69. package/src/transpiler/types/ITranspilerConfig.ts +2 -2
  70. package/src/transpiler/types/symbols/IScopeSymbol.ts +1 -1
  71. package/src/utils/FunctionUtils.ts +3 -3
  72. package/src/utils/__tests__/FunctionUtils.test.ts +6 -4
  73. package/src/utils/cache/CacheManager.ts +28 -15
  74. package/src/utils/cache/__tests__/CacheManager.test.ts +6 -4
  75. package/src/transpiler/data/types/IDiscoveryOptions.ts +0 -15
@@ -40,7 +40,7 @@ describe("Transpiler coverage tests", () => {
40
40
 
41
41
  const transpiler = new Transpiler(
42
42
  {
43
- inputs: ["/project/src/main.cnx"],
43
+ input: "/project/src/main.cnx",
44
44
  outDir: "/project/build",
45
45
  cppRequired: true,
46
46
  noCache: true,
@@ -58,7 +58,7 @@ describe("Transpiler coverage tests", () => {
58
58
 
59
59
  it("transpileSource respects cppRequired config", async () => {
60
60
  const transpiler = new Transpiler(
61
- { inputs: [], cppRequired: true, noCache: true },
61
+ { input: "", cppRequired: true, noCache: true },
62
62
  mockFs,
63
63
  );
64
64
 
@@ -90,7 +90,7 @@ describe("Transpiler coverage tests", () => {
90
90
 
91
91
  const transpiler = new Transpiler(
92
92
  {
93
- inputs: ["/project/src/main.cnx"],
93
+ input: "/project/src/main.cnx",
94
94
  includeDirs: ["/project/include"],
95
95
  outDir: "/project/build",
96
96
  noCache: true,
@@ -118,7 +118,7 @@ describe("Transpiler coverage tests", () => {
118
118
 
119
119
  const transpiler = new Transpiler(
120
120
  {
121
- inputs: ["/project/src/main.cnx"],
121
+ input: "/project/src/main.cnx",
122
122
  includeDirs: ["/project/include"],
123
123
  outDir: "/project/build",
124
124
  noCache: true,
@@ -154,7 +154,7 @@ describe("Transpiler coverage tests", () => {
154
154
 
155
155
  const transpiler = new Transpiler(
156
156
  {
157
- inputs: ["/project/src/main.cnx"],
157
+ input: "/project/src/main.cnx",
158
158
  includeDirs: ["/project/include"],
159
159
  outDir: "/project/build",
160
160
  debugMode: true,
@@ -199,7 +199,7 @@ describe("Transpiler coverage tests", () => {
199
199
 
200
200
  const transpiler = new Transpiler(
201
201
  {
202
- inputs: ["/project/src/main.cnx"],
202
+ input: "/project/src/main.cnx",
203
203
  includeDirs: ["/project/include"],
204
204
  outDir: "/project/build",
205
205
  noCache: true,
@@ -227,7 +227,7 @@ describe("Transpiler coverage tests", () => {
227
227
 
228
228
  const transpiler = new Transpiler(
229
229
  {
230
- inputs: ["/project/src/main.cnx"],
230
+ input: "/project/src/main.cnx",
231
231
  includeDirs: ["/project/include"],
232
232
  outDir: "/project/build",
233
233
  noCache: true,
@@ -259,7 +259,7 @@ describe("Transpiler coverage tests", () => {
259
259
 
260
260
  const transpiler = new Transpiler(
261
261
  {
262
- inputs: ["/project/src/main.cnx"],
262
+ input: "/project/src/main.cnx",
263
263
  includeDirs: ["/project/include"],
264
264
  outDir: "/project/build",
265
265
  noCache: true,
@@ -283,7 +283,7 @@ describe("Transpiler coverage tests", () => {
283
283
 
284
284
  const transpiler = new Transpiler(
285
285
  {
286
- inputs: ["/project/src/main.cnx"],
286
+ input: "/project/src/main.cnx",
287
287
  outDir: "/project/build",
288
288
  parseOnly: true,
289
289
  noCache: true,
@@ -306,7 +306,7 @@ describe("Transpiler coverage tests", () => {
306
306
  describe("Result builders", () => {
307
307
  it("buildCatchResult handles Error objects", async () => {
308
308
  // Create a transpiler that will fail during generation
309
- const transpiler = new Transpiler({ inputs: [], noCache: true }, mockFs);
309
+ const transpiler = new Transpiler({ input: "", noCache: true }, mockFs);
310
310
 
311
311
  // Mock an internal failure by transpiling invalid code that passes parsing
312
312
  // but fails in a later stage
@@ -324,7 +324,7 @@ describe("Transpiler coverage tests", () => {
324
324
 
325
325
  it("buildCatchResult handles non-Error objects", async () => {
326
326
  // Use transpileSource with a scenario that might throw
327
- const transpiler = new Transpiler({ inputs: [], noCache: true }, mockFs);
327
+ const transpiler = new Transpiler({ input: "", noCache: true }, mockFs);
328
328
 
329
329
  // Test with valid code to ensure normal path works
330
330
  const result = (
@@ -353,7 +353,7 @@ describe("Transpiler coverage tests", () => {
353
353
 
354
354
  const transpiler = new Transpiler(
355
355
  {
356
- inputs: ["/project/src/main.cnx"],
356
+ input: "/project/src/main.cnx",
357
357
  noCache: true,
358
358
  },
359
359
  mockFs,
@@ -383,7 +383,7 @@ describe("Transpiler coverage tests", () => {
383
383
 
384
384
  const transpiler = new Transpiler(
385
385
  {
386
- inputs: ["/project/src/file2.cnx"],
386
+ input: "/project/src/file2.cnx",
387
387
  includeDirs: ["/project/src"],
388
388
  outDir: "/project/build",
389
389
  noCache: true,
@@ -420,7 +420,7 @@ describe("Transpiler coverage tests", () => {
420
420
 
421
421
  const transpiler = new Transpiler(
422
422
  {
423
- inputs: ["/project/src/bad.cnx"],
423
+ input: "/project/src/bad.cnx",
424
424
  outDir: "/project/build",
425
425
  noCache: true,
426
426
  },
@@ -455,7 +455,7 @@ describe("Transpiler coverage tests", () => {
455
455
 
456
456
  const transpiler = new Transpiler(
457
457
  {
458
- inputs: ["/project/src/main.cnx"],
458
+ input: "/project/src/main.cnx",
459
459
  outDir: "/project/build",
460
460
  noCache: true,
461
461
  },
@@ -487,7 +487,7 @@ describe("Transpiler coverage tests", () => {
487
487
 
488
488
  const transpiler = new Transpiler(
489
489
  {
490
- inputs: ["/project/src/main.cnx"],
490
+ input: "/project/src/main.cnx",
491
491
  outDir: "/project/build",
492
492
  cppRequired: true,
493
493
  noCache: true,
@@ -513,7 +513,7 @@ describe("Transpiler coverage tests", () => {
513
513
 
514
514
  const transpiler = new Transpiler(
515
515
  {
516
- inputs: ["/project/src/internal.cnx"],
516
+ input: "/project/src/internal.cnx",
517
517
  outDir: "/project/build",
518
518
  noCache: true,
519
519
  },
@@ -544,7 +544,7 @@ describe("Transpiler coverage tests", () => {
544
544
 
545
545
  const transpiler = new Transpiler(
546
546
  {
547
- inputs: ["/project/src/lib.cnx"],
547
+ input: "/project/src/lib.cnx",
548
548
  outDir: "/project/build",
549
549
  cppRequired: true,
550
550
  noCache: true,
@@ -570,7 +570,7 @@ describe("Transpiler coverage tests", () => {
570
570
  describe("Target configuration", () => {
571
571
  it("passes target to code generator", async () => {
572
572
  const transpiler = new Transpiler(
573
- { inputs: [], target: "esp32", noCache: true },
573
+ { input: "", target: "esp32", noCache: true },
574
574
  mockFs,
575
575
  );
576
576
 
@@ -594,7 +594,7 @@ describe("Transpiler coverage tests", () => {
594
594
  // Use transpileSource which works better with MockFileSystem
595
595
  const transpiler = new Transpiler(
596
596
  {
597
- inputs: [],
597
+ input: "",
598
598
  cppRequired: true,
599
599
  noCache: true,
600
600
  },
@@ -639,7 +639,7 @@ describe("Transpiler coverage tests", () => {
639
639
 
640
640
  const transpiler = new Transpiler(
641
641
  {
642
- inputs: ["/project/src/main.cnx"],
642
+ input: "/project/src/main.cnx",
643
643
  includeDirs: ["/project/include"],
644
644
  outDir: "/project/build",
645
645
  noCache: true,
@@ -660,7 +660,7 @@ describe("Transpiler coverage tests", () => {
660
660
 
661
661
  describe("getSymbolTable", () => {
662
662
  it("returns the symbol table instance", () => {
663
- const transpiler = new Transpiler({ inputs: [], noCache: true }, mockFs);
663
+ const transpiler = new Transpiler({ input: "", noCache: true }, mockFs);
664
664
 
665
665
  const symbolTable = transpiler.getSymbolTable();
666
666
 
@@ -680,7 +680,7 @@ describe("Transpiler coverage tests", () => {
680
680
 
681
681
  const transpiler = new Transpiler(
682
682
  {
683
- inputs: ["/project/main.cnx"], // Needed for project root detection
683
+ input: "/project/main.cnx", // Needed for project root detection
684
684
  noCache: false, // Enable cache
685
685
  },
686
686
  mockFs,
@@ -717,7 +717,7 @@ describe("Transpiler coverage tests", () => {
717
717
 
718
718
  const transpiler = new Transpiler(
719
719
  {
720
- inputs: ["/project/src/lib.cnx"],
720
+ input: "/project/src/lib.cnx",
721
721
  outDir: "/project/build",
722
722
  cppRequired: true,
723
723
  noCache: true,
@@ -740,7 +740,7 @@ describe("Transpiler coverage tests", () => {
740
740
 
741
741
  describe("Analyzer errors", () => {
742
742
  it("returns error result for MISRA violations", async () => {
743
- const transpiler = new Transpiler({ inputs: [], noCache: true }, mockFs);
743
+ const transpiler = new Transpiler({ input: "", noCache: true }, mockFs);
744
744
 
745
745
  // Code with MISRA violation - function call in if condition (Rule 13.5)
746
746
  // Note: This may or may not trigger depending on analyzer config
@@ -762,7 +762,7 @@ describe("Transpiler coverage tests", () => {
762
762
  });
763
763
 
764
764
  it("returns error result for analyzer errors via transpileSource", async () => {
765
- const transpiler = new Transpiler({ inputs: [], noCache: true }, mockFs);
765
+ const transpiler = new Transpiler({ input: "", noCache: true }, mockFs);
766
766
 
767
767
  // Code that triggers initialization analyzer error
768
768
  const result = (
@@ -806,7 +806,7 @@ describe("Transpiler coverage tests", () => {
806
806
 
807
807
  // First run populates cache
808
808
  const config = {
809
- inputs: ["/project/src/main.cnx"],
809
+ input: "/project/src/main.cnx",
810
810
  includeDirs: ["/project/include"],
811
811
  outDir: "/project/build",
812
812
  noCache: false,
@@ -837,7 +837,7 @@ describe("Transpiler coverage tests", () => {
837
837
  );
838
838
 
839
839
  const config = {
840
- inputs: ["/project/src/main.cnx"],
840
+ input: "/project/src/main.cnx",
841
841
  includeDirs: ["/project/include"],
842
842
  outDir: "/project/build",
843
843
  noCache: false,
@@ -877,7 +877,7 @@ describe("Transpiler coverage tests", () => {
877
877
 
878
878
  const transpiler = new Transpiler(
879
879
  {
880
- inputs: ["/project/src/main.cnx"],
880
+ input: "/project/src/main.cnx",
881
881
  includeDirs: ["/project/include"],
882
882
  outDir: "/project/build",
883
883
  debugMode: true,
@@ -922,7 +922,7 @@ describe("Transpiler coverage tests", () => {
922
922
  );
923
923
 
924
924
  const config = {
925
- inputs: ["/project/src/main.cnx"],
925
+ input: "/project/src/main.cnx",
926
926
  includeDirs: ["/project/include"],
927
927
  outDir: "/project/build",
928
928
  noCache: false, // Enable cache
@@ -964,7 +964,7 @@ describe("Transpiler coverage tests", () => {
964
964
  );
965
965
 
966
966
  const config = {
967
- inputs: ["/project/src/main.cnx"],
967
+ input: "/project/src/main.cnx",
968
968
  includeDirs: ["/project/include"],
969
969
  outDir: "/project/build",
970
970
  noCache: false, // Enable cache
@@ -993,6 +993,200 @@ describe("Transpiler coverage tests", () => {
993
993
  expect(writeCalls.some((w) => w.path.endsWith(".cpp"))).toBe(true);
994
994
  });
995
995
  });
996
+
997
+ // ==========================================================================
998
+ // C++ entry point discovery
999
+ // ==========================================================================
1000
+
1001
+ describe("C++ entry point discovery", () => {
1002
+ it("discovers C-Next files from C++ entry point via header markers", async () => {
1003
+ // Create a C-Next source file
1004
+ mockFs.addFile(
1005
+ "/project/src/led.cnx",
1006
+ "scope LED { public void on() { } }",
1007
+ );
1008
+
1009
+ // Create the generated header with marker
1010
+ mockFs.addFile(
1011
+ "/project/src/led.h",
1012
+ `/**
1013
+ * Generated by C-Next Transpiler from: led.cnx
1014
+ * A safer C for embedded systems
1015
+ */
1016
+ void LED_on(void);`,
1017
+ );
1018
+
1019
+ // Create a C++ entry point that includes the header
1020
+ mockFs.addFile(
1021
+ "/project/src/main.cpp",
1022
+ `#include "led.h"
1023
+ int main() { LED_on(); return 0; }`,
1024
+ );
1025
+
1026
+ const transpiler = new Transpiler(
1027
+ {
1028
+ input: "/project/src/main.cpp",
1029
+ outDir: "/project/build",
1030
+ noCache: true,
1031
+ },
1032
+ mockFs,
1033
+ );
1034
+
1035
+ const result = await transpiler.transpile({ kind: "files" });
1036
+
1037
+ expect(result.success).toBe(true);
1038
+ expect(result.filesProcessed).toBe(1);
1039
+ expect(result.files[0].sourcePath).toContain("led.cnx");
1040
+ });
1041
+
1042
+ it("returns empty result when no C-Next markers found in C++ include tree", async () => {
1043
+ // Create a regular C header (no C-Next marker)
1044
+ mockFs.addFile(
1045
+ "/project/src/utils.h",
1046
+ `#ifndef UTILS_H
1047
+ #define UTILS_H
1048
+ void helper(void);
1049
+ #endif`,
1050
+ );
1051
+
1052
+ // Create a C++ entry point
1053
+ mockFs.addFile(
1054
+ "/project/src/main.cpp",
1055
+ `#include "utils.h"
1056
+ int main() { helper(); return 0; }`,
1057
+ );
1058
+
1059
+ const transpiler = new Transpiler(
1060
+ {
1061
+ input: "/project/src/main.cpp",
1062
+ outDir: "/project/build",
1063
+ noCache: true,
1064
+ },
1065
+ mockFs,
1066
+ );
1067
+
1068
+ const result = await transpiler.transpile({ kind: "files" });
1069
+
1070
+ expect(result.success).toBe(true);
1071
+ expect(result.filesProcessed).toBe(0);
1072
+ });
1073
+
1074
+ it("reports scanner errors with Error prefix", async () => {
1075
+ // Create a header with marker pointing to non-existent .cnx
1076
+ mockFs.addFile(
1077
+ "/project/src/missing.h",
1078
+ `/**
1079
+ * Generated by C-Next Transpiler from: missing.cnx
1080
+ */
1081
+ void Missing_func(void);`,
1082
+ );
1083
+
1084
+ // Create C++ entry point
1085
+ mockFs.addFile(
1086
+ "/project/src/main.cpp",
1087
+ `#include "missing.h"
1088
+ int main() { return 0; }`,
1089
+ );
1090
+
1091
+ const transpiler = new Transpiler(
1092
+ {
1093
+ input: "/project/src/main.cpp",
1094
+ outDir: "/project/build",
1095
+ noCache: true,
1096
+ },
1097
+ mockFs,
1098
+ );
1099
+
1100
+ const result = await transpiler.transpile({ kind: "files" });
1101
+
1102
+ // Should have error about missing .cnx file
1103
+ expect(result.warnings.some((w) => w.includes("Error:"))).toBe(true);
1104
+ expect(result.warnings.some((w) => w.includes("missing.cnx"))).toBe(true);
1105
+ });
1106
+
1107
+ it("discovers multiple C-Next files from C++ entry point", async () => {
1108
+ // Create two C-Next source files
1109
+ mockFs.addFile(
1110
+ "/project/src/led.cnx",
1111
+ "scope LED { public void on() { } }",
1112
+ );
1113
+ mockFs.addFile(
1114
+ "/project/src/motor.cnx",
1115
+ "scope Motor { public void start() { } }",
1116
+ );
1117
+
1118
+ // Create generated headers with markers
1119
+ mockFs.addFile(
1120
+ "/project/src/led.h",
1121
+ `/**
1122
+ * Generated by C-Next Transpiler from: led.cnx
1123
+ */
1124
+ void LED_on(void);`,
1125
+ );
1126
+ mockFs.addFile(
1127
+ "/project/src/motor.h",
1128
+ `/**
1129
+ * Generated by C-Next Transpiler from: motor.cnx
1130
+ */
1131
+ void Motor_start(void);`,
1132
+ );
1133
+
1134
+ // Create C++ entry point that includes both
1135
+ mockFs.addFile(
1136
+ "/project/src/main.cpp",
1137
+ `#include "led.h"
1138
+ #include "motor.h"
1139
+ int main() { LED_on(); Motor_start(); return 0; }`,
1140
+ );
1141
+
1142
+ const transpiler = new Transpiler(
1143
+ {
1144
+ input: "/project/src/main.cpp",
1145
+ outDir: "/project/build",
1146
+ noCache: true,
1147
+ },
1148
+ mockFs,
1149
+ );
1150
+
1151
+ const result = await transpiler.transpile({ kind: "files" });
1152
+
1153
+ expect(result.success).toBe(true);
1154
+ expect(result.filesProcessed).toBe(2);
1155
+ });
1156
+
1157
+ it("handles .c entry point as well as .cpp", async () => {
1158
+ mockFs.addFile(
1159
+ "/project/src/led.cnx",
1160
+ "scope LED { public void on() { } }",
1161
+ );
1162
+ mockFs.addFile(
1163
+ "/project/src/led.h",
1164
+ `/**
1165
+ * Generated by C-Next Transpiler from: led.cnx
1166
+ */
1167
+ void LED_on(void);`,
1168
+ );
1169
+ mockFs.addFile(
1170
+ "/project/src/main.c",
1171
+ `#include "led.h"
1172
+ int main() { LED_on(); return 0; }`,
1173
+ );
1174
+
1175
+ const transpiler = new Transpiler(
1176
+ {
1177
+ input: "/project/src/main.c",
1178
+ outDir: "/project/build",
1179
+ noCache: true,
1180
+ },
1181
+ mockFs,
1182
+ );
1183
+
1184
+ const result = await transpiler.transpile({ kind: "files" });
1185
+
1186
+ expect(result.success).toBe(true);
1187
+ expect(result.filesProcessed).toBe(1);
1188
+ });
1189
+ });
996
1190
  });
997
1191
 
998
1192
  // =============================================================================
@@ -1011,44 +1205,22 @@ describe("Transpiler coverage integration tests", () => {
1011
1205
  });
1012
1206
 
1013
1207
  // ==========================================================================
1014
- // Directory discovery tests (covers lines 414-415)
1208
+ // Entry point discovery tests
1015
1209
  // ==========================================================================
1016
1210
 
1017
- it("discovers C-Next files from directory input", async () => {
1018
- // Create a directory with multiple .cnx files
1211
+ it("discovers included files from entry point", async () => {
1212
+ // Create a directory with entry point that includes other files
1019
1213
  const srcDir = join(testDir, "src");
1020
1214
  mkdirSync(srcDir, { recursive: true });
1021
1215
 
1022
- writeFileSync(join(srcDir, "file1.cnx"), "void func1() { }");
1023
- writeFileSync(join(srcDir, "file2.cnx"), "void func2() { }");
1024
- writeFileSync(join(srcDir, "file3.cnx"), "void func3() { }");
1025
-
1026
- // Use directory as input (not individual files)
1027
- // This exercises the FileDiscovery.discover() path at lines 408-416
1028
- const transpiler = new Transpiler({
1029
- inputs: [srcDir], // Directory input triggers discovery loop
1030
- outDir: testDir,
1031
- noCache: true,
1032
- });
1033
-
1034
- const result = await transpiler.transpile({ kind: "files" });
1035
-
1036
- expect(result.success).toBe(true);
1037
- // Should have processed all 3 files
1038
- expect(result.filesProcessed).toBe(3);
1039
- });
1040
-
1041
- it("discovers C-Next files recursively from directory", async () => {
1042
- // Create nested directory structure
1043
- const srcDir = join(testDir, "src");
1044
- const subDir = join(srcDir, "submodule");
1045
- mkdirSync(subDir, { recursive: true });
1046
-
1047
- writeFileSync(join(srcDir, "main.cnx"), "void main() { }");
1048
- writeFileSync(join(subDir, "helper.cnx"), "void helper() { }");
1216
+ writeFileSync(
1217
+ join(srcDir, "main.cnx"),
1218
+ '#include "helper.cnx"\nvoid main() { }',
1219
+ );
1220
+ writeFileSync(join(srcDir, "helper.cnx"), "void helper() { }");
1049
1221
 
1050
1222
  const transpiler = new Transpiler({
1051
- inputs: [srcDir],
1223
+ input: join(srcDir, "main.cnx"),
1052
1224
  outDir: testDir,
1053
1225
  noCache: true,
1054
1226
  });
@@ -1056,7 +1228,7 @@ describe("Transpiler coverage integration tests", () => {
1056
1228
  const result = await transpiler.transpile({ kind: "files" });
1057
1229
 
1058
1230
  expect(result.success).toBe(true);
1059
- // Should find files in subdirectories too
1231
+ // Should have processed entry point + included file
1060
1232
  expect(result.filesProcessed).toBe(2);
1061
1233
  });
1062
1234
 
@@ -1086,7 +1258,7 @@ describe("Transpiler coverage integration tests", () => {
1086
1258
  );
1087
1259
 
1088
1260
  const config = {
1089
- inputs: [join(testDir, "main.cnx")],
1261
+ input: join(testDir, "main.cnx"),
1090
1262
  includeDirs: [includeDir],
1091
1263
  outDir: testDir,
1092
1264
  noCache: false, // Enable caching
@@ -1126,7 +1298,7 @@ describe("Transpiler coverage integration tests", () => {
1126
1298
  );
1127
1299
 
1128
1300
  const config = {
1129
- inputs: [join(testDir, "main.cnx")],
1301
+ input: join(testDir, "main.cnx"),
1130
1302
  includeDirs: [includeDir],
1131
1303
  outDir: testDir,
1132
1304
  noCache: false, // Enable caching
@@ -1165,7 +1337,7 @@ describe("Transpiler coverage integration tests", () => {
1165
1337
  );
1166
1338
 
1167
1339
  const transpiler = new Transpiler({
1168
- inputs: [join(testDir, "main.cnx")],
1340
+ input: join(testDir, "main.cnx"),
1169
1341
  includeDirs: [testDir],
1170
1342
  outDir: testDir,
1171
1343
  noCache: true,
@@ -1190,7 +1362,7 @@ describe("Transpiler coverage integration tests", () => {
1190
1362
  );
1191
1363
 
1192
1364
  const config = {
1193
- inputs: [join(testDir, "main.cnx")],
1365
+ input: join(testDir, "main.cnx"),
1194
1366
  includeDirs: [testDir],
1195
1367
  outDir: testDir,
1196
1368
  noCache: false, // Enable cache
@@ -1224,7 +1396,7 @@ describe("Transpiler coverage integration tests", () => {
1224
1396
  );
1225
1397
 
1226
1398
  const transpiler = new Transpiler({
1227
- inputs: [join(srcDir, "lib.cnx")],
1399
+ input: join(srcDir, "lib.cnx"),
1228
1400
  outDir: buildDir,
1229
1401
  headerOutDir: includeDir,
1230
1402
  noCache: true,
@@ -1270,7 +1442,7 @@ describe("Transpiler coverage integration tests", () => {
1270
1442
  );
1271
1443
 
1272
1444
  const transpiler = new Transpiler({
1273
- inputs: [join(srcDir, "main.cnx")],
1445
+ input: join(srcDir, "main.cnx"),
1274
1446
  includeDirs: [includeDir],
1275
1447
  preprocess: false, // Explicitly disable preprocessing
1276
1448
  noCache: true,
@@ -1306,7 +1478,7 @@ describe("Transpiler coverage integration tests", () => {
1306
1478
  );
1307
1479
 
1308
1480
  const transpiler = new Transpiler({
1309
- inputs: [join(srcDir, "main.cnx")],
1481
+ input: join(srcDir, "main.cnx"),
1310
1482
  includeDirs: [includeDir],
1311
1483
  noCache: true,
1312
1484
  });
@@ -1358,7 +1530,7 @@ describe("Transpiler coverage integration tests", () => {
1358
1530
  );
1359
1531
 
1360
1532
  const transpiler = new Transpiler({
1361
- inputs: [join(srcDir, "main.cnx")],
1533
+ input: join(srcDir, "main.cnx"),
1362
1534
  includeDirs: [includeDir],
1363
1535
  noCache: true,
1364
1536
  });
@@ -1399,7 +1571,7 @@ describe("Transpiler coverage integration tests", () => {
1399
1571
  );
1400
1572
 
1401
1573
  const transpiler = new Transpiler({
1402
- inputs: [join(srcDir, "main.cnx")],
1574
+ input: join(srcDir, "main.cnx"),
1403
1575
  includeDirs: [includeDir],
1404
1576
  noCache: true,
1405
1577
  });