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.
- package/README.md +80 -649
- package/dist/index.js +8273 -6357
- package/dist/index.js.map +4 -4
- package/grammar/C.g4 +17 -4
- package/package.json +3 -3
- package/src/__tests__/index.test.ts +1 -1
- package/src/cli/CleanCommand.ts +8 -12
- package/src/cli/Cli.ts +29 -6
- package/src/cli/Runner.ts +42 -62
- package/src/cli/__tests__/CleanCommand.test.ts +10 -10
- package/src/cli/__tests__/Cli.test.ts +59 -7
- package/src/cli/__tests__/ConfigPrinter.test.ts +12 -12
- package/src/cli/__tests__/PathNormalizer.test.ts +5 -5
- package/src/cli/__tests__/Runner.test.ts +108 -82
- package/src/cli/serve/ServeCommand.ts +1 -1
- package/src/cli/types/ICliConfig.ts +2 -2
- package/src/lib/parseWithSymbols.ts +21 -21
- package/src/transpiler/Transpiler.ts +99 -46
- package/src/transpiler/__tests__/DualCodePaths.test.ts +29 -29
- package/src/transpiler/__tests__/Transpiler.coverage.test.ts +244 -72
- package/src/transpiler/__tests__/Transpiler.test.ts +32 -72
- package/src/transpiler/__tests__/determineProjectRoot.test.ts +30 -28
- package/src/transpiler/__tests__/needsConditionalPreprocessing.test.ts +1 -1
- package/src/transpiler/data/CNextMarkerDetector.ts +34 -0
- package/src/transpiler/data/CppEntryPointScanner.ts +174 -0
- package/src/transpiler/data/FileDiscovery.ts +2 -105
- package/src/transpiler/data/InputExpansion.ts +37 -81
- package/src/transpiler/data/__tests__/CNextMarkerDetector.test.ts +62 -0
- package/src/transpiler/data/__tests__/CppEntryPointScanner.test.ts +239 -0
- package/src/transpiler/data/__tests__/FileDiscovery.test.ts +45 -191
- package/src/transpiler/data/__tests__/InputExpansion.test.ts +36 -204
- package/src/transpiler/logic/analysis/InitializationAnalyzer.ts +2 -2
- package/src/transpiler/logic/analysis/PassByValueAnalyzer.ts +4 -5
- package/src/transpiler/logic/parser/c/grammar/C.interp +33 -3
- package/src/transpiler/logic/parser/c/grammar/C.tokens +237 -207
- package/src/transpiler/logic/parser/c/grammar/CLexer.interp +48 -3
- package/src/transpiler/logic/parser/c/grammar/CLexer.tokens +237 -207
- package/src/transpiler/logic/parser/c/grammar/CLexer.ts +702 -611
- package/src/transpiler/logic/parser/c/grammar/CParser.ts +1221 -1107
- package/src/transpiler/logic/symbols/SymbolTable.ts +147 -73
- package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +157 -14
- package/src/transpiler/logic/symbols/c/__tests__/CResolver.integration.test.ts +3 -3
- package/src/transpiler/logic/symbols/c/collectors/StructCollector.ts +7 -37
- package/src/transpiler/logic/symbols/cnext/__tests__/TSymbolInfoAdapter.test.ts +6 -6
- package/src/transpiler/logic/symbols/cnext/adapters/TSymbolInfoAdapter.ts +28 -27
- package/src/transpiler/logic/symbols/cnext/index.ts +4 -4
- package/src/transpiler/logic/symbols/cnext/utils/SymbolNameUtils.ts +5 -5
- package/src/transpiler/output/codegen/CodeGenerator.ts +16 -1
- package/src/transpiler/output/codegen/__tests__/CodeGenerator.test.ts +15 -0
- package/src/transpiler/output/codegen/__tests__/ExpressionWalker.test.ts +3 -3
- package/src/transpiler/output/codegen/__tests__/RequireInclude.test.ts +14 -14
- package/src/transpiler/output/codegen/__tests__/TrackVariableTypeHelpers.test.ts +2 -2
- package/src/transpiler/output/codegen/helpers/FunctionContextManager.ts +15 -3
- package/src/transpiler/output/codegen/helpers/ParameterInputAdapter.ts +14 -6
- package/src/transpiler/output/codegen/helpers/__tests__/ParameterInputAdapter.test.ts +1 -0
- package/src/transpiler/output/codegen/types/IFunctionContextCallbacks.ts +2 -0
- package/src/transpiler/output/codegen/utils/QualifiedNameGenerator.ts +7 -7
- package/src/transpiler/output/codegen/utils/__tests__/QualifiedNameGenerator.test.ts +3 -3
- package/src/transpiler/output/headers/BaseHeaderGenerator.ts +10 -1
- package/src/transpiler/output/headers/HeaderGenerator.ts +3 -0
- package/src/transpiler/output/headers/HeaderGeneratorUtils.ts +6 -2
- package/src/transpiler/output/headers/__tests__/HeaderGeneratorUtils.test.ts +16 -0
- package/src/transpiler/output/headers/adapters/HeaderSymbolAdapter.ts +19 -19
- package/src/transpiler/output/headers/adapters/__tests__/HeaderSymbolAdapter.test.ts +5 -5
- package/src/transpiler/state/SymbolRegistry.ts +10 -12
- package/src/transpiler/state/__tests__/SymbolRegistry.test.ts +11 -13
- package/src/transpiler/types/ICachedFileEntry.ts +4 -0
- package/src/transpiler/types/IPipelineFile.ts +3 -0
- package/src/transpiler/types/ITranspilerConfig.ts +2 -2
- package/src/transpiler/types/symbols/IScopeSymbol.ts +1 -1
- package/src/utils/FunctionUtils.ts +3 -3
- package/src/utils/__tests__/FunctionUtils.test.ts +6 -4
- package/src/utils/cache/CacheManager.ts +28 -15
- package/src/utils/cache/__tests__/CacheManager.test.ts +6 -4
- 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
|
-
|
|
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
|
-
{
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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({
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
{
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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
|
-
|
|
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
|
-
|
|
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({
|
|
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({
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
1208
|
+
// Entry point discovery tests
|
|
1015
1209
|
// ==========================================================================
|
|
1016
1210
|
|
|
1017
|
-
it("discovers
|
|
1018
|
-
// Create a directory with
|
|
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(
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1574
|
+
input: join(srcDir, "main.cnx"),
|
|
1403
1575
|
includeDirs: [includeDir],
|
|
1404
1576
|
noCache: true,
|
|
1405
1577
|
});
|