c-next 0.2.12 → 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 +7387 -6211
- package/dist/index.js.map +4 -4
- package/grammar/C.g4 +9 -3
- package/package.json +1 -2
- 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 +88 -43
- 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 +19 -1
- package/src/transpiler/logic/parser/c/grammar/C.tokens +231 -213
- package/src/transpiler/logic/parser/c/grammar/CLexer.interp +28 -1
- package/src/transpiler/logic/parser/c/grammar/CLexer.tokens +231 -213
- package/src/transpiler/logic/parser/c/grammar/CLexer.ts +654 -600
- package/src/transpiler/logic/parser/c/grammar/CParser.ts +1175 -1099
- package/src/transpiler/logic/symbols/SymbolTable.ts +19 -7
- package/src/transpiler/logic/symbols/__tests__/SymbolTable.test.ts +78 -0
- 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 +7 -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/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/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/transpiler/data/types/IDiscoveryOptions.ts +0 -15
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tests for QualifiedNameGenerator
|
|
3
3
|
*
|
|
4
|
-
* QualifiedNameGenerator is the ONLY place that constructs C
|
|
4
|
+
* QualifiedNameGenerator is the ONLY place that constructs transpiled C names
|
|
5
5
|
* like "Test_fillData" from function symbols.
|
|
6
6
|
*/
|
|
7
7
|
import { describe, it, expect, beforeEach } from "vitest";
|
|
@@ -120,7 +120,7 @@ describe("QualifiedNameGenerator", () => {
|
|
|
120
120
|
);
|
|
121
121
|
});
|
|
122
122
|
|
|
123
|
-
it("returns
|
|
123
|
+
it("returns transpiled C name for simple scope", () => {
|
|
124
124
|
expect(
|
|
125
125
|
QualifiedNameGenerator.forFunctionStrings("Test", "fillData"),
|
|
126
126
|
).toBe("Test_fillData");
|
|
@@ -168,7 +168,7 @@ describe("QualifiedNameGenerator", () => {
|
|
|
168
168
|
);
|
|
169
169
|
});
|
|
170
170
|
|
|
171
|
-
it("returns
|
|
171
|
+
it("returns transpiled C name for simple scope", () => {
|
|
172
172
|
expect(QualifiedNameGenerator.forMember("Test", "counter")).toBe(
|
|
173
173
|
"Test_counter",
|
|
174
174
|
);
|
|
@@ -38,6 +38,14 @@ abstract class BaseHeaderGenerator {
|
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
* Generate a header file from symbols
|
|
41
|
+
*
|
|
42
|
+
* @param symbols - Array of symbols to include in header
|
|
43
|
+
* @param filename - Output filename (used for include guard)
|
|
44
|
+
* @param options - Header generation options (includes cppMode)
|
|
45
|
+
* @param typeInput - Optional type information for full definitions
|
|
46
|
+
* @param passByValueParams - Map of function names to pass-by-value parameter names
|
|
47
|
+
* @param allKnownEnums - All known enum names from entire compilation
|
|
48
|
+
* @param sourcePath - Optional source file path for header comment
|
|
41
49
|
*/
|
|
42
50
|
generate(
|
|
43
51
|
symbols: IHeaderSymbol[],
|
|
@@ -46,6 +54,7 @@ abstract class BaseHeaderGenerator {
|
|
|
46
54
|
typeInput?: IHeaderTypeInput,
|
|
47
55
|
passByValueParams?: TPassByValueParams,
|
|
48
56
|
allKnownEnums?: ReadonlySet<string>,
|
|
57
|
+
sourcePath?: string,
|
|
49
58
|
): string {
|
|
50
59
|
const guard = HeaderGeneratorUtils.makeGuard(filename, options.guardPrefix);
|
|
51
60
|
|
|
@@ -98,7 +107,7 @@ abstract class BaseHeaderGenerator {
|
|
|
98
107
|
|
|
99
108
|
// Build header sections using utility methods
|
|
100
109
|
const lines: string[] = [
|
|
101
|
-
...HeaderGeneratorUtils.generateHeaderStart(guard),
|
|
110
|
+
...HeaderGeneratorUtils.generateHeaderStart(guard, sourcePath),
|
|
102
111
|
...HeaderGeneratorUtils.generateIncludes(options, headersToInclude),
|
|
103
112
|
...HeaderGeneratorUtils.generateCppWrapperStart(),
|
|
104
113
|
...HeaderGeneratorUtils.generateForwardDeclarations(
|
|
@@ -37,6 +37,7 @@ class HeaderGenerator {
|
|
|
37
37
|
* @param typeInput - Optional type information for full definitions
|
|
38
38
|
* @param passByValueParams - Map of function names to pass-by-value parameter names
|
|
39
39
|
* @param allKnownEnums - All known enum names from entire compilation
|
|
40
|
+
* @param sourcePath - Optional source file path for header comment
|
|
40
41
|
*/
|
|
41
42
|
generate(
|
|
42
43
|
symbols: IHeaderSymbol[],
|
|
@@ -45,6 +46,7 @@ class HeaderGenerator {
|
|
|
45
46
|
typeInput?: IHeaderTypeInput,
|
|
46
47
|
passByValueParams?: TPassByValueParams,
|
|
47
48
|
allKnownEnums?: ReadonlySet<string>,
|
|
49
|
+
sourcePath?: string,
|
|
48
50
|
): string {
|
|
49
51
|
const generator = options.cppMode ? this.cppGenerator : this.cGenerator;
|
|
50
52
|
|
|
@@ -55,6 +57,7 @@ class HeaderGenerator {
|
|
|
55
57
|
typeInput,
|
|
56
58
|
passByValueParams,
|
|
57
59
|
allKnownEnums,
|
|
60
|
+
sourcePath,
|
|
58
61
|
);
|
|
59
62
|
}
|
|
60
63
|
|
|
@@ -250,13 +250,17 @@ class HeaderGeneratorUtils {
|
|
|
250
250
|
/**
|
|
251
251
|
* Generate header guard opening and file comment
|
|
252
252
|
*/
|
|
253
|
-
static generateHeaderStart(guard: string): string[] {
|
|
253
|
+
static generateHeaderStart(guard: string, sourcePath?: string): string[] {
|
|
254
|
+
const generatedLine = sourcePath
|
|
255
|
+
? ` * Generated by C-Next Transpiler from: ${sourcePath}`
|
|
256
|
+
: " * Generated by C-Next Transpiler";
|
|
257
|
+
|
|
254
258
|
return [
|
|
255
259
|
`#ifndef ${guard}`,
|
|
256
260
|
`#define ${guard}`,
|
|
257
261
|
"",
|
|
258
262
|
"/**",
|
|
259
|
-
|
|
263
|
+
generatedLine,
|
|
260
264
|
" * Header file for cross-language interoperability",
|
|
261
265
|
" */",
|
|
262
266
|
"",
|
|
@@ -502,6 +502,22 @@ describe("HeaderGeneratorUtils", () => {
|
|
|
502
502
|
expect(lines).toContain("#define MY_FILE_H");
|
|
503
503
|
expect(lines.some((l) => l.includes("Generated by C-Next"))).toBe(true);
|
|
504
504
|
});
|
|
505
|
+
|
|
506
|
+
it("should include source path in generation comment when provided", () => {
|
|
507
|
+
const lines = HeaderGeneratorUtils.generateHeaderStart(
|
|
508
|
+
"TEST_H",
|
|
509
|
+
"led.cnx",
|
|
510
|
+
);
|
|
511
|
+
expect(lines.join("\n")).toContain(
|
|
512
|
+
"Generated by C-Next Transpiler from: led.cnx",
|
|
513
|
+
);
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
it("should use default comment when no source path provided", () => {
|
|
517
|
+
const lines = HeaderGeneratorUtils.generateHeaderStart("TEST_H");
|
|
518
|
+
expect(lines.join("\n")).toContain("Generated by C-Next Transpiler");
|
|
519
|
+
expect(lines.join("\n")).not.toContain("from:");
|
|
520
|
+
});
|
|
505
521
|
});
|
|
506
522
|
|
|
507
523
|
describe("generateIncludes", () => {
|
|
@@ -54,8 +54,8 @@ class HeaderSymbolAdapter {
|
|
|
54
54
|
// Convert TType return type to string
|
|
55
55
|
const returnTypeStr = TypeResolver.getTypeName(func.returnType);
|
|
56
56
|
|
|
57
|
-
// Get
|
|
58
|
-
const
|
|
57
|
+
// Get transpiled C name (scope-prefixed)
|
|
58
|
+
const cName = SymbolNameUtils.getTranspiledCName(func);
|
|
59
59
|
const isGlobal = func.scope.name === "";
|
|
60
60
|
|
|
61
61
|
// Convert parameters to IParameterSymbol[]
|
|
@@ -74,10 +74,10 @@ class HeaderSymbolAdapter {
|
|
|
74
74
|
const paramTypes = func.parameters.map((p) =>
|
|
75
75
|
TypeResolver.getTypeName(p.type),
|
|
76
76
|
);
|
|
77
|
-
const signature = `${returnTypeStr} ${
|
|
77
|
+
const signature = `${returnTypeStr} ${cName}(${paramTypes.join(", ")})`;
|
|
78
78
|
|
|
79
79
|
return {
|
|
80
|
-
name:
|
|
80
|
+
name: cName,
|
|
81
81
|
kind: "function",
|
|
82
82
|
type: returnTypeStr,
|
|
83
83
|
isExported: func.isExported,
|
|
@@ -92,8 +92,8 @@ class HeaderSymbolAdapter {
|
|
|
92
92
|
private static convertVariable(
|
|
93
93
|
variable: import("../../../types/symbols/IVariableSymbol").default,
|
|
94
94
|
): IHeaderSymbol {
|
|
95
|
-
// Get
|
|
96
|
-
const
|
|
95
|
+
// Get transpiled C name (scope-prefixed)
|
|
96
|
+
const cName = SymbolNameUtils.getTranspiledCName(variable);
|
|
97
97
|
const isGlobal = variable.scope.name === "";
|
|
98
98
|
|
|
99
99
|
// Convert TType to string
|
|
@@ -107,7 +107,7 @@ class HeaderSymbolAdapter {
|
|
|
107
107
|
);
|
|
108
108
|
|
|
109
109
|
return {
|
|
110
|
-
name:
|
|
110
|
+
name: cName,
|
|
111
111
|
kind: "variable",
|
|
112
112
|
type: typeStr,
|
|
113
113
|
isExported: variable.isExported,
|
|
@@ -124,12 +124,12 @@ class HeaderSymbolAdapter {
|
|
|
124
124
|
private static convertStruct(
|
|
125
125
|
struct: import("../../../types/symbols/IStructSymbol").default,
|
|
126
126
|
): IHeaderSymbol {
|
|
127
|
-
// Get
|
|
128
|
-
const
|
|
127
|
+
// Get transpiled C name (scope-prefixed)
|
|
128
|
+
const cName = SymbolNameUtils.getTranspiledCName(struct);
|
|
129
129
|
const isGlobal = struct.scope.name === "";
|
|
130
130
|
|
|
131
131
|
return {
|
|
132
|
-
name:
|
|
132
|
+
name: cName,
|
|
133
133
|
kind: "struct",
|
|
134
134
|
isExported: struct.isExported,
|
|
135
135
|
parent: isGlobal ? undefined : struct.scope.name,
|
|
@@ -141,12 +141,12 @@ class HeaderSymbolAdapter {
|
|
|
141
141
|
private static convertEnum(
|
|
142
142
|
enumSym: import("../../../types/symbols/IEnumSymbol").default,
|
|
143
143
|
): IHeaderSymbol {
|
|
144
|
-
// Get
|
|
145
|
-
const
|
|
144
|
+
// Get transpiled C name (scope-prefixed)
|
|
145
|
+
const cName = SymbolNameUtils.getTranspiledCName(enumSym);
|
|
146
146
|
const isGlobal = enumSym.scope.name === "";
|
|
147
147
|
|
|
148
148
|
return {
|
|
149
|
-
name:
|
|
149
|
+
name: cName,
|
|
150
150
|
kind: "enum",
|
|
151
151
|
isExported: enumSym.isExported,
|
|
152
152
|
parent: isGlobal ? undefined : enumSym.scope.name,
|
|
@@ -158,12 +158,12 @@ class HeaderSymbolAdapter {
|
|
|
158
158
|
private static convertBitmap(
|
|
159
159
|
bitmap: import("../../../types/symbols/IBitmapSymbol").default,
|
|
160
160
|
): IHeaderSymbol {
|
|
161
|
-
// Get
|
|
162
|
-
const
|
|
161
|
+
// Get transpiled C name (scope-prefixed)
|
|
162
|
+
const cName = SymbolNameUtils.getTranspiledCName(bitmap);
|
|
163
163
|
const isGlobal = bitmap.scope.name === "";
|
|
164
164
|
|
|
165
165
|
return {
|
|
166
|
-
name:
|
|
166
|
+
name: cName,
|
|
167
167
|
kind: "bitmap",
|
|
168
168
|
type: bitmap.backingType,
|
|
169
169
|
isExported: bitmap.isExported,
|
|
@@ -176,12 +176,12 @@ class HeaderSymbolAdapter {
|
|
|
176
176
|
private static convertRegister(
|
|
177
177
|
register: import("../../../types/symbols/IRegisterSymbol").default,
|
|
178
178
|
): IHeaderSymbol {
|
|
179
|
-
// Get
|
|
180
|
-
const
|
|
179
|
+
// Get transpiled C name (scope-prefixed)
|
|
180
|
+
const cName = SymbolNameUtils.getTranspiledCName(register);
|
|
181
181
|
const isGlobal = register.scope.name === "";
|
|
182
182
|
|
|
183
183
|
return {
|
|
184
|
-
name:
|
|
184
|
+
name: cName,
|
|
185
185
|
kind: "register",
|
|
186
186
|
isExported: register.isExported,
|
|
187
187
|
parent: isGlobal ? undefined : register.scope.name,
|
|
@@ -48,7 +48,7 @@ describe("HeaderSymbolAdapter", () => {
|
|
|
48
48
|
expect(result.parent).toBeUndefined();
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
it("should convert scoped variable with
|
|
51
|
+
it("should convert scoped variable with transpiled C name", () => {
|
|
52
52
|
const tSymbol: IVariableSymbol = {
|
|
53
53
|
kind: "variable",
|
|
54
54
|
name: "speed",
|
|
@@ -235,7 +235,7 @@ describe("HeaderSymbolAdapter", () => {
|
|
|
235
235
|
expect(result.parent).toBeUndefined();
|
|
236
236
|
});
|
|
237
237
|
|
|
238
|
-
it("should convert scoped struct with
|
|
238
|
+
it("should convert scoped struct with transpiled C name", () => {
|
|
239
239
|
const geometryScope = ScopeUtils.createScope("Geometry", globalScope);
|
|
240
240
|
const tSymbol: IStructSymbol = {
|
|
241
241
|
kind: "struct",
|
|
@@ -279,7 +279,7 @@ describe("HeaderSymbolAdapter", () => {
|
|
|
279
279
|
expect(result.isExported).toBe(true);
|
|
280
280
|
});
|
|
281
281
|
|
|
282
|
-
it("should convert scoped enum with
|
|
282
|
+
it("should convert scoped enum with transpiled C name", () => {
|
|
283
283
|
const tSymbol: IEnumSymbol = {
|
|
284
284
|
kind: "enum",
|
|
285
285
|
name: "EMode",
|
|
@@ -327,7 +327,7 @@ describe("HeaderSymbolAdapter", () => {
|
|
|
327
327
|
expect(result.isExported).toBe(true);
|
|
328
328
|
});
|
|
329
329
|
|
|
330
|
-
it("should convert scoped bitmap with
|
|
330
|
+
it("should convert scoped bitmap with transpiled C name", () => {
|
|
331
331
|
const tSymbol: IBitmapSymbol = {
|
|
332
332
|
kind: "bitmap",
|
|
333
333
|
name: "Status",
|
|
@@ -373,7 +373,7 @@ describe("HeaderSymbolAdapter", () => {
|
|
|
373
373
|
expect(result.isExported).toBe(true);
|
|
374
374
|
});
|
|
375
375
|
|
|
376
|
-
it("should convert scoped register with
|
|
376
|
+
it("should convert scoped register with transpiled C name", () => {
|
|
377
377
|
const tSymbol: IRegisterSymbol = {
|
|
378
378
|
kind: "register",
|
|
379
379
|
name: "CTRL",
|
|
@@ -133,27 +133,27 @@ class SymbolRegistry {
|
|
|
133
133
|
// ============================================================================
|
|
134
134
|
|
|
135
135
|
/**
|
|
136
|
-
* Find a function by its C
|
|
136
|
+
* Find a function by its transpiled C name (e.g., "Test_fillData").
|
|
137
137
|
*
|
|
138
138
|
* This is a bridge method for gradual migration. New code should use
|
|
139
139
|
* resolveFunction() with bare names and scope references instead.
|
|
140
140
|
*
|
|
141
|
-
* @param
|
|
141
|
+
* @param cName Transpiled C function name (e.g., "Test_fillData", "main")
|
|
142
142
|
* @returns The function symbol, or null if not found
|
|
143
143
|
*/
|
|
144
|
-
static
|
|
144
|
+
static findByCName(cName: string): IFunctionSymbol | null {
|
|
145
145
|
// Check global scope first (no underscore = global function)
|
|
146
146
|
for (const func of this.globalScope.functions) {
|
|
147
|
-
if (func.name ===
|
|
147
|
+
if (func.name === cName) {
|
|
148
148
|
return func;
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
// Check all scopes - the
|
|
152
|
+
// Check all scopes - the C name should match scope_name pattern
|
|
153
153
|
for (const [scopePath, scope] of this.scopes) {
|
|
154
154
|
const prefix = scopePath.replaceAll(".", "_") + "_";
|
|
155
155
|
for (const func of scope.functions) {
|
|
156
|
-
if (prefix + func.name ===
|
|
156
|
+
if (prefix + func.name === cName) {
|
|
157
157
|
return func;
|
|
158
158
|
}
|
|
159
159
|
}
|
|
@@ -163,17 +163,15 @@ class SymbolRegistry {
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
/**
|
|
166
|
-
* Get the scope of a function given its C
|
|
166
|
+
* Get the scope of a function given its transpiled C name.
|
|
167
167
|
*
|
|
168
168
|
* This is a bridge method for gradual migration.
|
|
169
169
|
*
|
|
170
|
-
* @param
|
|
170
|
+
* @param cName Transpiled C function name
|
|
171
171
|
* @returns The scope the function belongs to, or null if not found
|
|
172
172
|
*/
|
|
173
|
-
static
|
|
174
|
-
|
|
175
|
-
): IScopeSymbol | null {
|
|
176
|
-
const func = this.findByMangledName(mangledName);
|
|
173
|
+
static getScopeByCFunctionName(cName: string): IScopeSymbol | null {
|
|
174
|
+
const func = this.findByCName(cName);
|
|
177
175
|
return func?.scope ?? null;
|
|
178
176
|
}
|
|
179
177
|
}
|
|
@@ -141,7 +141,7 @@ describe("SymbolRegistry", () => {
|
|
|
141
141
|
});
|
|
142
142
|
});
|
|
143
143
|
|
|
144
|
-
describe("
|
|
144
|
+
describe("findByCName", () => {
|
|
145
145
|
it("finds global function by bare name", () => {
|
|
146
146
|
const global = SymbolRegistry.getGlobalScope();
|
|
147
147
|
const func = FunctionUtils.create({
|
|
@@ -156,11 +156,11 @@ describe("SymbolRegistry", () => {
|
|
|
156
156
|
});
|
|
157
157
|
SymbolRegistry.registerFunction(func);
|
|
158
158
|
|
|
159
|
-
const found = SymbolRegistry.
|
|
159
|
+
const found = SymbolRegistry.findByCName("main");
|
|
160
160
|
expect(found).toBe(func);
|
|
161
161
|
});
|
|
162
162
|
|
|
163
|
-
it("finds scoped function by
|
|
163
|
+
it("finds scoped function by transpiled C name", () => {
|
|
164
164
|
const scope = SymbolRegistry.getOrCreateScope("Test");
|
|
165
165
|
const func = FunctionUtils.create({
|
|
166
166
|
name: "fillData",
|
|
@@ -174,11 +174,11 @@ describe("SymbolRegistry", () => {
|
|
|
174
174
|
});
|
|
175
175
|
SymbolRegistry.registerFunction(func);
|
|
176
176
|
|
|
177
|
-
const found = SymbolRegistry.
|
|
177
|
+
const found = SymbolRegistry.findByCName("Test_fillData");
|
|
178
178
|
expect(found).toBe(func);
|
|
179
179
|
});
|
|
180
180
|
|
|
181
|
-
it("finds nested scope function by
|
|
181
|
+
it("finds nested scope function by transpiled C name", () => {
|
|
182
182
|
const scope = SymbolRegistry.getOrCreateScope("Outer.Inner");
|
|
183
183
|
const func = FunctionUtils.create({
|
|
184
184
|
name: "deepFunc",
|
|
@@ -192,17 +192,17 @@ describe("SymbolRegistry", () => {
|
|
|
192
192
|
});
|
|
193
193
|
SymbolRegistry.registerFunction(func);
|
|
194
194
|
|
|
195
|
-
const found = SymbolRegistry.
|
|
195
|
+
const found = SymbolRegistry.findByCName("Outer_Inner_deepFunc");
|
|
196
196
|
expect(found).toBe(func);
|
|
197
197
|
});
|
|
198
198
|
|
|
199
199
|
it("returns null for unknown function", () => {
|
|
200
|
-
const found = SymbolRegistry.
|
|
200
|
+
const found = SymbolRegistry.findByCName("Unknown_func");
|
|
201
201
|
expect(found).toBeNull();
|
|
202
202
|
});
|
|
203
203
|
});
|
|
204
204
|
|
|
205
|
-
describe("
|
|
205
|
+
describe("getScopeByCFunctionName", () => {
|
|
206
206
|
it("returns scope for scoped function", () => {
|
|
207
207
|
const scope = SymbolRegistry.getOrCreateScope("Motor");
|
|
208
208
|
const func = FunctionUtils.create({
|
|
@@ -217,8 +217,7 @@ describe("SymbolRegistry", () => {
|
|
|
217
217
|
});
|
|
218
218
|
SymbolRegistry.registerFunction(func);
|
|
219
219
|
|
|
220
|
-
const foundScope =
|
|
221
|
-
SymbolRegistry.getScopeByMangledFunctionName("Motor_init");
|
|
220
|
+
const foundScope = SymbolRegistry.getScopeByCFunctionName("Motor_init");
|
|
222
221
|
expect(foundScope).toBe(scope);
|
|
223
222
|
});
|
|
224
223
|
|
|
@@ -236,13 +235,12 @@ describe("SymbolRegistry", () => {
|
|
|
236
235
|
});
|
|
237
236
|
SymbolRegistry.registerFunction(func);
|
|
238
237
|
|
|
239
|
-
const foundScope = SymbolRegistry.
|
|
238
|
+
const foundScope = SymbolRegistry.getScopeByCFunctionName("helper");
|
|
240
239
|
expect(foundScope).toBe(global);
|
|
241
240
|
});
|
|
242
241
|
|
|
243
242
|
it("returns null for unknown function", () => {
|
|
244
|
-
const foundScope =
|
|
245
|
-
SymbolRegistry.getScopeByMangledFunctionName("Unknown_func");
|
|
243
|
+
const foundScope = SymbolRegistry.getScopeByCFunctionName("Unknown_func");
|
|
246
244
|
expect(foundScope).toBeNull();
|
|
247
245
|
});
|
|
248
246
|
});
|
|
@@ -22,6 +22,9 @@ interface IPipelineFile {
|
|
|
22
22
|
|
|
23
23
|
/** C-Next includes for transitive enum resolution */
|
|
24
24
|
readonly cnextIncludes?: ReadonlyArray<{ path: string }>;
|
|
25
|
+
|
|
26
|
+
/** Override for source-relative path (used in source mode) */
|
|
27
|
+
readonly sourceRelativePath?: string;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
export default IPipelineFile;
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* configuration interface that supports both single-file and multi-file builds.
|
|
6
6
|
*/
|
|
7
7
|
interface ITranspilerConfig {
|
|
8
|
-
/**
|
|
9
|
-
|
|
8
|
+
/** Entry point .cnx file to transpile */
|
|
9
|
+
input: string;
|
|
10
10
|
|
|
11
11
|
/** Include directories for C/C++ header discovery */
|
|
12
12
|
includeDirs?: string[];
|
|
@@ -16,7 +16,7 @@ interface IScopeSymbol extends IBaseSymbol {
|
|
|
16
16
|
/** Parent scope (global scope's parent is itself) */
|
|
17
17
|
readonly parent: IScopeSymbol;
|
|
18
18
|
|
|
19
|
-
/** List of member names (local names, not
|
|
19
|
+
/** List of member names (local names, not transpiled C names) */
|
|
20
20
|
readonly members: string[];
|
|
21
21
|
|
|
22
22
|
/** Functions in this scope */
|
|
@@ -52,17 +52,17 @@ class FunctionUtils {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
// ============================================================================
|
|
55
|
-
//
|
|
55
|
+
// Transpiled C Names
|
|
56
56
|
// ============================================================================
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
|
-
* Get the C
|
|
59
|
+
* Get the transpiled C name for a function.
|
|
60
60
|
*
|
|
61
61
|
* For global scope functions, returns the bare name.
|
|
62
62
|
* For scoped functions, returns "Scope_name" (e.g., "Test_fillData").
|
|
63
63
|
* For nested scopes, returns "Outer_Inner_name".
|
|
64
64
|
*/
|
|
65
|
-
static
|
|
65
|
+
static getTranspiledCName(func: IFunctionSymbol): string {
|
|
66
66
|
const scopePath = ScopeUtils.getScopePath(func.scope);
|
|
67
67
|
if (scopePath.length === 0) {
|
|
68
68
|
return func.name;
|
|
@@ -153,7 +153,7 @@ describe("IFunctionSymbol", () => {
|
|
|
153
153
|
});
|
|
154
154
|
});
|
|
155
155
|
|
|
156
|
-
describe("FunctionUtils.
|
|
156
|
+
describe("FunctionUtils.getTranspiledCName", () => {
|
|
157
157
|
it("returns bare name for global scope function", () => {
|
|
158
158
|
const global = ScopeUtils.createGlobalScope();
|
|
159
159
|
|
|
@@ -168,7 +168,7 @@ describe("IFunctionSymbol", () => {
|
|
|
168
168
|
sourceLine: 1,
|
|
169
169
|
});
|
|
170
170
|
|
|
171
|
-
expect(FunctionUtils.
|
|
171
|
+
expect(FunctionUtils.getTranspiledCName(func)).toBe("main");
|
|
172
172
|
});
|
|
173
173
|
|
|
174
174
|
it("returns scope-prefixed name for scoped function", () => {
|
|
@@ -186,7 +186,7 @@ describe("IFunctionSymbol", () => {
|
|
|
186
186
|
sourceLine: 10,
|
|
187
187
|
});
|
|
188
188
|
|
|
189
|
-
expect(FunctionUtils.
|
|
189
|
+
expect(FunctionUtils.getTranspiledCName(func)).toBe("Test_fillData");
|
|
190
190
|
});
|
|
191
191
|
|
|
192
192
|
it("returns nested scope-prefixed name for nested scope function", () => {
|
|
@@ -205,7 +205,9 @@ describe("IFunctionSymbol", () => {
|
|
|
205
205
|
sourceLine: 20,
|
|
206
206
|
});
|
|
207
207
|
|
|
208
|
-
expect(FunctionUtils.
|
|
208
|
+
expect(FunctionUtils.getTranspiledCName(func)).toBe(
|
|
209
|
+
"Outer_Inner_process",
|
|
210
|
+
);
|
|
209
211
|
});
|
|
210
212
|
});
|
|
211
213
|
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Options for file discovery
|
|
3
|
-
*/
|
|
4
|
-
interface IDiscoveryOptions {
|
|
5
|
-
/** File extensions to include (default: all supported) */
|
|
6
|
-
extensions?: string[];
|
|
7
|
-
|
|
8
|
-
/** Whether to recurse into subdirectories */
|
|
9
|
-
recursive?: boolean;
|
|
10
|
-
|
|
11
|
-
/** Patterns to exclude */
|
|
12
|
-
excludePatterns?: RegExp[];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export default IDiscoveryOptions;
|