c-next 0.1.48 → 0.1.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/codegen/CodeGenerator.ts +120 -41
- package/src/pipeline/Pipeline.ts +53 -0
- package/src/project/Project.ts +31 -0
package/package.json
CHANGED
|
@@ -189,7 +189,7 @@ interface GeneratorContext {
|
|
|
189
189
|
indentLevel: number;
|
|
190
190
|
scopeMembers: Map<string, Set<string>>; // scope -> member names (ADR-016)
|
|
191
191
|
currentParameters: Map<string, TParameterInfo>; // ADR-006: track params for pointer semantics
|
|
192
|
-
|
|
192
|
+
// Issue #558: modifiedParameters removed - now uses analysis-phase results from this.modifiedParameters
|
|
193
193
|
localArrays: Set<string>; // ADR-006: track local array variables (no & needed)
|
|
194
194
|
localVariables: Set<string>; // ADR-016: track local variables (allowed as bare identifiers)
|
|
195
195
|
floatBitShadows: Set<string>; // Track declared shadow variables for float bit indexing
|
|
@@ -221,7 +221,7 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
221
221
|
indentLevel: 0,
|
|
222
222
|
scopeMembers: new Map(), // ADR-016: renamed from namespaceMembers
|
|
223
223
|
currentParameters: new Map(),
|
|
224
|
-
|
|
224
|
+
// Issue #558: modifiedParameters removed - now uses analysis-phase results
|
|
225
225
|
localArrays: new Set(),
|
|
226
226
|
localVariables: new Set(), // ADR-016: track local variables
|
|
227
227
|
floatBitShadows: new Set(), // Track declared shadow variables for float bit indexing
|
|
@@ -327,6 +327,17 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
327
327
|
*/
|
|
328
328
|
private readonly modifiedParameters: Map<string, Set<string>> = new Map();
|
|
329
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Issue #558: Pending cross-file modifications to inject after analyzePassByValue clears.
|
|
332
|
+
* Set by Pipeline before generate() to share modifications from previously processed files.
|
|
333
|
+
*/
|
|
334
|
+
private pendingCrossFileModifications: Map<string, Set<string>> | null = null;
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Issue #558: Pending cross-file parameter lists to inject for transitive propagation.
|
|
338
|
+
*/
|
|
339
|
+
private pendingCrossFileParamLists: Map<string, string[]> | null = null;
|
|
340
|
+
|
|
330
341
|
/**
|
|
331
342
|
* Issue #269: Tracks which parameters should pass by value
|
|
332
343
|
* Map of functionName -> Set of passByValue parameter names
|
|
@@ -1061,7 +1072,7 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
1061
1072
|
this.context.localVariables.clear();
|
|
1062
1073
|
this.context.floatBitShadows.clear();
|
|
1063
1074
|
this.context.floatShadowCurrent.clear();
|
|
1064
|
-
|
|
1075
|
+
// Issue #558: modifiedParameters tracking removed - uses analysis-phase results
|
|
1065
1076
|
this.context.inFunctionBody = true;
|
|
1066
1077
|
}
|
|
1067
1078
|
|
|
@@ -1106,13 +1117,14 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
1106
1117
|
|
|
1107
1118
|
/**
|
|
1108
1119
|
* Issue #268: Update symbol parameters with auto-const info.
|
|
1109
|
-
*
|
|
1120
|
+
* Issue #558: Now uses analysis-phase results for modification tracking.
|
|
1110
1121
|
*/
|
|
1111
1122
|
updateFunctionParamsAutoConst(functionName: string): void {
|
|
1112
|
-
// Collect unmodified parameters for this function
|
|
1123
|
+
// Collect unmodified parameters for this function using analysis results
|
|
1113
1124
|
const unmodifiedParams = new Set<string>();
|
|
1125
|
+
const modifiedSet = this.modifiedParameters.get(functionName);
|
|
1114
1126
|
for (const [paramName] of this.context.currentParameters) {
|
|
1115
|
-
if (!
|
|
1127
|
+
if (!modifiedSet?.has(paramName)) {
|
|
1116
1128
|
unmodifiedParams.add(paramName);
|
|
1117
1129
|
}
|
|
1118
1130
|
}
|
|
@@ -1121,11 +1133,49 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
1121
1133
|
|
|
1122
1134
|
/**
|
|
1123
1135
|
* Issue #268: Mark a parameter as modified for auto-const tracking.
|
|
1136
|
+
* Issue #558: Now a no-op - analysis phase handles all modification tracking
|
|
1137
|
+
* including transitive propagation across function calls and files.
|
|
1124
1138
|
*/
|
|
1125
|
-
markParameterModified(
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1139
|
+
markParameterModified(_paramName: string): void {
|
|
1140
|
+
// No-op: Analysis phase (analyzePassByValue) now handles all modification
|
|
1141
|
+
// tracking including cross-file and transitive propagation.
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
/**
|
|
1145
|
+
* Issue #558: Check if a parameter is modified using analysis-phase results.
|
|
1146
|
+
* This is the unified source of truth for modification tracking.
|
|
1147
|
+
*/
|
|
1148
|
+
private _isCurrentParameterModified(paramName: string): boolean {
|
|
1149
|
+
const funcName = this.context.currentFunctionName;
|
|
1150
|
+
if (!funcName) return false;
|
|
1151
|
+
return this.modifiedParameters.get(funcName)?.has(paramName) ?? false;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
/**
|
|
1155
|
+
* Issue #558: Get the modified parameters map for cross-file propagation.
|
|
1156
|
+
* Returns function name -> set of modified parameter names.
|
|
1157
|
+
*/
|
|
1158
|
+
getModifiedParameters(): ReadonlyMap<string, Set<string>> {
|
|
1159
|
+
return this.modifiedParameters;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
/**
|
|
1163
|
+
* Issue #558: Set cross-file modification data to inject during analyzePassByValue.
|
|
1164
|
+
* Called by Pipeline before generate() to share modifications from previously processed files.
|
|
1165
|
+
*/
|
|
1166
|
+
setCrossFileModifications(
|
|
1167
|
+
modifications: Map<string, Set<string>>,
|
|
1168
|
+
paramLists: Map<string, string[]>,
|
|
1169
|
+
): void {
|
|
1170
|
+
this.pendingCrossFileModifications = modifications;
|
|
1171
|
+
this.pendingCrossFileParamLists = paramLists;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
/**
|
|
1175
|
+
* Issue #558: Get the function parameter lists for cross-file propagation.
|
|
1176
|
+
*/
|
|
1177
|
+
getFunctionParamLists(): ReadonlyMap<string, string[]> {
|
|
1178
|
+
return this.functionParamLists;
|
|
1129
1179
|
}
|
|
1130
1180
|
|
|
1131
1181
|
/**
|
|
@@ -1539,7 +1589,7 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
1539
1589
|
indentLevel: 0,
|
|
1540
1590
|
scopeMembers: new Map(), // ADR-016
|
|
1541
1591
|
currentParameters: new Map(),
|
|
1542
|
-
|
|
1592
|
+
// Issue #558: modifiedParameters removed - uses analysis-phase results
|
|
1543
1593
|
localArrays: new Set(),
|
|
1544
1594
|
localVariables: new Set(), // ADR-016
|
|
1545
1595
|
floatBitShadows: new Set(), // Track declared shadow variables for float bit indexing
|
|
@@ -2025,6 +2075,29 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
2025
2075
|
// Phase 1: Collect function parameter lists and direct modifications
|
|
2026
2076
|
this.collectFunctionParametersAndModifications(tree);
|
|
2027
2077
|
|
|
2078
|
+
// Issue #558: Inject cross-file data before transitive propagation
|
|
2079
|
+
if (this.pendingCrossFileModifications) {
|
|
2080
|
+
for (const [funcName, params] of this.pendingCrossFileModifications) {
|
|
2081
|
+
const existing = this.modifiedParameters.get(funcName);
|
|
2082
|
+
if (existing) {
|
|
2083
|
+
for (const param of params) {
|
|
2084
|
+
existing.add(param);
|
|
2085
|
+
}
|
|
2086
|
+
} else {
|
|
2087
|
+
this.modifiedParameters.set(funcName, new Set(params));
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2090
|
+
this.pendingCrossFileModifications = null; // Clear after use
|
|
2091
|
+
}
|
|
2092
|
+
if (this.pendingCrossFileParamLists) {
|
|
2093
|
+
for (const [funcName, params] of this.pendingCrossFileParamLists) {
|
|
2094
|
+
if (!this.functionParamLists.has(funcName)) {
|
|
2095
|
+
this.functionParamLists.set(funcName, params);
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
this.pendingCrossFileParamLists = null; // Clear after use
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2028
2101
|
// Phase 2: Fixed-point iteration for transitive modifications
|
|
2029
2102
|
this.propagateTransitiveModifications();
|
|
2030
2103
|
|
|
@@ -2120,17 +2193,31 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
2120
2193
|
// Check for assignment statements
|
|
2121
2194
|
if (stmt.assignmentStatement()) {
|
|
2122
2195
|
const assign = stmt.assignmentStatement()!;
|
|
2123
|
-
// Get the target - use assignmentTarget() which has IDENTIFIER()
|
|
2124
2196
|
const target = assign.assignmentTarget();
|
|
2197
|
+
|
|
2198
|
+
// Issue #558: Extract base identifier from assignment target
|
|
2199
|
+
// - Simple identifier: x <- value
|
|
2200
|
+
// - Member access: x.field <- value (first IDENTIFIER is the base)
|
|
2201
|
+
// - Array access: x[i] <- value
|
|
2202
|
+
let baseIdentifier: string | null = null;
|
|
2203
|
+
|
|
2125
2204
|
if (target?.IDENTIFIER()) {
|
|
2126
|
-
// Simple identifier assignment
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2205
|
+
// Simple identifier assignment
|
|
2206
|
+
baseIdentifier = target.IDENTIFIER()!.getText();
|
|
2207
|
+
} else if (target?.memberAccess()) {
|
|
2208
|
+
// Member access: first IDENTIFIER is the base (e.g., cfg.value -> cfg)
|
|
2209
|
+
const identifiers = target.memberAccess()!.IDENTIFIER();
|
|
2210
|
+
if (identifiers.length > 0) {
|
|
2211
|
+
baseIdentifier = identifiers[0].getText();
|
|
2133
2212
|
}
|
|
2213
|
+
} else if (target?.arrayAccess()) {
|
|
2214
|
+
// Array access: IDENTIFIER is the base (e.g., arr[0] -> arr)
|
|
2215
|
+
baseIdentifier = target.arrayAccess()!.IDENTIFIER()?.getText() ?? null;
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
if (baseIdentifier && paramSet.has(baseIdentifier)) {
|
|
2219
|
+
// Direct or member/array assignment modifies the parameter
|
|
2220
|
+
this.modifiedParameters.get(funcName)!.add(baseIdentifier);
|
|
2134
2221
|
}
|
|
2135
2222
|
}
|
|
2136
2223
|
|
|
@@ -5358,8 +5445,7 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
5358
5445
|
// Track parameters for ADR-006 pointer semantics
|
|
5359
5446
|
this._setParameters(ctx.parameterList() ?? null);
|
|
5360
5447
|
|
|
5361
|
-
// Issue #
|
|
5362
|
-
this.context.modifiedParameters.clear();
|
|
5448
|
+
// Issue #558: modifiedParameters tracking removed - uses analysis-phase results
|
|
5363
5449
|
|
|
5364
5450
|
// ADR-016: Clear local variables and mark that we're in a function body
|
|
5365
5451
|
this.context.localVariables.clear();
|
|
@@ -5525,8 +5611,8 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
5525
5611
|
// Arrays pass naturally as pointers
|
|
5526
5612
|
if (dims.length > 0) {
|
|
5527
5613
|
const dimStr = dims.map((d) => this._generateArrayDimension(d)).join("");
|
|
5528
|
-
// Issue #268: Add const for unmodified array parameters
|
|
5529
|
-
const wasModified = this.
|
|
5614
|
+
// Issue #268/#558: Add const for unmodified array parameters (uses analysis results)
|
|
5615
|
+
const wasModified = this._isCurrentParameterModified(name);
|
|
5530
5616
|
const autoConst = !wasModified && !constMod ? "const " : "";
|
|
5531
5617
|
return `${autoConst}${constMod}${type} ${name}${dimStr}`;
|
|
5532
5618
|
}
|
|
@@ -5557,8 +5643,8 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
5557
5643
|
// ADR-045: String parameters (non-array) are passed as char*
|
|
5558
5644
|
// Issue #551: Handle before unknown type check
|
|
5559
5645
|
if (ctx.type().stringType() && dims.length === 0) {
|
|
5560
|
-
// Issue #268: Add const for unmodified string parameters
|
|
5561
|
-
const wasModified = this.
|
|
5646
|
+
// Issue #268/#558: Add const for unmodified string parameters (uses analysis results)
|
|
5647
|
+
const wasModified = this._isCurrentParameterModified(name);
|
|
5562
5648
|
const autoConst = !wasModified && !constMod ? "const " : "";
|
|
5563
5649
|
return `${autoConst}${constMod}char* ${name}`;
|
|
5564
5650
|
}
|
|
@@ -5566,8 +5652,8 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
5566
5652
|
// ADR-006: Pass by reference for known struct types and known primitives
|
|
5567
5653
|
// Issue #551: Unknown types (external enums, typedefs) use pass-by-value
|
|
5568
5654
|
if (this._isKnownStruct(typeName) || this._isKnownPrimitive(typeName)) {
|
|
5569
|
-
// Issue #268: Add const for unmodified pointer parameters
|
|
5570
|
-
const wasModified = this.
|
|
5655
|
+
// Issue #268/#558: Add const for unmodified pointer parameters (uses analysis results)
|
|
5656
|
+
const wasModified = this._isCurrentParameterModified(name);
|
|
5571
5657
|
const autoConst = !wasModified && !constMod ? "const " : "";
|
|
5572
5658
|
// Issue #409: In C++ mode, use references (&) instead of pointers (*)
|
|
5573
5659
|
// This allows C-Next callbacks to match C++ function pointer signatures
|
|
@@ -6833,10 +6919,7 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
6833
6919
|
throw new Error(constError);
|
|
6834
6920
|
}
|
|
6835
6921
|
|
|
6836
|
-
// Issue #
|
|
6837
|
-
if (this.context.currentParameters.has(id)) {
|
|
6838
|
-
this.context.modifiedParameters.add(id);
|
|
6839
|
-
}
|
|
6922
|
+
// Issue #558: Parameter modification tracking removed - uses analysis-phase results
|
|
6840
6923
|
|
|
6841
6924
|
// Invalidate float shadow when variable is assigned directly
|
|
6842
6925
|
const shadowName = `__bits_${id}`;
|
|
@@ -6962,10 +7045,7 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
6962
7045
|
);
|
|
6963
7046
|
}
|
|
6964
7047
|
|
|
6965
|
-
// Issue #
|
|
6966
|
-
if (this.context.currentParameters.has(arrayName)) {
|
|
6967
|
-
this.context.modifiedParameters.add(arrayName);
|
|
6968
|
-
}
|
|
7048
|
+
// Issue #558: Parameter modification tracking removed - uses analysis-phase results
|
|
6969
7049
|
}
|
|
6970
7050
|
|
|
6971
7051
|
// Check member access on const struct - validate the root is not const
|
|
@@ -6978,10 +7058,7 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
6978
7058
|
throw new Error(`${constError} (member access)`);
|
|
6979
7059
|
}
|
|
6980
7060
|
|
|
6981
|
-
// Issue #
|
|
6982
|
-
if (this.context.currentParameters.has(rootName)) {
|
|
6983
|
-
this.context.modifiedParameters.add(rootName);
|
|
6984
|
-
}
|
|
7061
|
+
// Issue #558: Parameter modification tracking removed - uses analysis-phase results
|
|
6985
7062
|
|
|
6986
7063
|
// ADR-013: Check for read-only register members (ro = implicitly const)
|
|
6987
7064
|
if (identifiers.length >= 2) {
|
|
@@ -7124,7 +7201,8 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
7124
7201
|
!paramInfo.isStruct &&
|
|
7125
7202
|
this._isKnownPrimitive(paramInfo.baseType)
|
|
7126
7203
|
) {
|
|
7127
|
-
|
|
7204
|
+
// Issue #558: In C++ mode, primitives that become references don't need dereferencing
|
|
7205
|
+
return this.cppMode ? id : `(*${id})`;
|
|
7128
7206
|
}
|
|
7129
7207
|
return id;
|
|
7130
7208
|
}
|
|
@@ -8657,7 +8735,8 @@ export default class CodeGenerator implements IOrchestrator {
|
|
|
8657
8735
|
!paramInfo.isStruct &&
|
|
8658
8736
|
this._isKnownPrimitive(paramInfo.baseType)
|
|
8659
8737
|
) {
|
|
8660
|
-
|
|
8738
|
+
// Issue #558: In C++ mode, primitives that become references don't need dereferencing
|
|
8739
|
+
return this.cppMode ? id : `(*${id})`;
|
|
8661
8740
|
}
|
|
8662
8741
|
return id;
|
|
8663
8742
|
}
|
package/src/pipeline/Pipeline.ts
CHANGED
|
@@ -82,6 +82,17 @@ class Pipeline {
|
|
|
82
82
|
* Used to include C headers in generated .h files instead of forward-declaring types.
|
|
83
83
|
*/
|
|
84
84
|
private readonly headerIncludeDirectives: Map<string, string> = new Map();
|
|
85
|
+
/**
|
|
86
|
+
* Issue #558: Accumulated parameter modifications across all processed files.
|
|
87
|
+
* Used for cross-file const inference in C++ mode.
|
|
88
|
+
*/
|
|
89
|
+
private readonly accumulatedModifications: Map<string, Set<string>> =
|
|
90
|
+
new Map();
|
|
91
|
+
/**
|
|
92
|
+
* Issue #558: Accumulated function parameter lists across all processed files.
|
|
93
|
+
* Used for cross-file const inference transitive propagation.
|
|
94
|
+
*/
|
|
95
|
+
private readonly accumulatedParamLists: Map<string, string[]> = new Map();
|
|
85
96
|
|
|
86
97
|
constructor(config: IPipelineConfig) {
|
|
87
98
|
// Apply defaults
|
|
@@ -137,6 +148,10 @@ class Pipeline {
|
|
|
137
148
|
await this.cacheManager.initialize();
|
|
138
149
|
}
|
|
139
150
|
|
|
151
|
+
// Issue #558: Reset cross-file modification tracking for new run
|
|
152
|
+
this.accumulatedModifications.clear();
|
|
153
|
+
this.accumulatedParamLists.clear();
|
|
154
|
+
|
|
140
155
|
// Stage 1: Discover source files
|
|
141
156
|
const { cnextFiles, headerFiles } = await this.discoverSources();
|
|
142
157
|
|
|
@@ -146,6 +161,15 @@ class Pipeline {
|
|
|
146
161
|
return result;
|
|
147
162
|
}
|
|
148
163
|
|
|
164
|
+
// Issue #558: Sort files by dependency order for correct cross-file const inference.
|
|
165
|
+
// Files that are included by others should be processed first so their
|
|
166
|
+
// parameter modifications are available during transitive propagation.
|
|
167
|
+
// Simple heuristic: reverse the discovery order since includes are added
|
|
168
|
+
// after the files that include them.
|
|
169
|
+
if (this.cppDetected) {
|
|
170
|
+
cnextFiles.reverse();
|
|
171
|
+
}
|
|
172
|
+
|
|
149
173
|
// Ensure output directory exists if specified
|
|
150
174
|
if (this.config.outDir && !existsSync(this.config.outDir)) {
|
|
151
175
|
mkdirSync(this.config.outDir, { recursive: true });
|
|
@@ -788,6 +812,14 @@ class Pipeline {
|
|
|
788
812
|
);
|
|
789
813
|
}
|
|
790
814
|
|
|
815
|
+
// Issue #558: Inject cross-file data for const inference
|
|
816
|
+
if (this.cppDetected && this.accumulatedModifications.size > 0) {
|
|
817
|
+
this.codeGenerator.setCrossFileModifications(
|
|
818
|
+
this.accumulatedModifications,
|
|
819
|
+
this.accumulatedParamLists,
|
|
820
|
+
);
|
|
821
|
+
}
|
|
822
|
+
|
|
791
823
|
const code = this.codeGenerator.generate(
|
|
792
824
|
tree,
|
|
793
825
|
this.symbolTable,
|
|
@@ -822,6 +854,27 @@ class Pipeline {
|
|
|
822
854
|
}
|
|
823
855
|
this.passByValueParamsCollectors.set(file.path, passByValueCopy);
|
|
824
856
|
|
|
857
|
+
// Issue #558: Collect modifications and param lists for cross-file const inference
|
|
858
|
+
if (this.cppDetected) {
|
|
859
|
+
const fileModifications = this.codeGenerator.getModifiedParameters();
|
|
860
|
+
for (const [funcName, params] of fileModifications) {
|
|
861
|
+
const existing = this.accumulatedModifications.get(funcName);
|
|
862
|
+
if (existing) {
|
|
863
|
+
for (const param of params) {
|
|
864
|
+
existing.add(param);
|
|
865
|
+
}
|
|
866
|
+
} else {
|
|
867
|
+
this.accumulatedModifications.set(funcName, new Set(params));
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
const fileParamLists = this.codeGenerator.getFunctionParamLists();
|
|
871
|
+
for (const [funcName, params] of fileParamLists) {
|
|
872
|
+
if (!this.accumulatedParamLists.has(funcName)) {
|
|
873
|
+
this.accumulatedParamLists.set(funcName, [...params]);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
|
|
825
878
|
// Issue #424: Store user includes for header generation
|
|
826
879
|
// These may define macros used in array dimensions
|
|
827
880
|
// Issue #461: Transform .cnx includes to .h for header generation
|
package/src/project/Project.ts
CHANGED
|
@@ -63,6 +63,13 @@ class Project {
|
|
|
63
63
|
* Compile the project
|
|
64
64
|
*/
|
|
65
65
|
async compile(): Promise<IProjectResult> {
|
|
66
|
+
// Issue #558: For C++ mode, use Pipeline.run() to enable cross-file const inference.
|
|
67
|
+
// This is needed because struct parameters passed to modifying functions in other
|
|
68
|
+
// files must not be marked const.
|
|
69
|
+
if (this.config.cppRequired) {
|
|
70
|
+
return this.compileWithPipeline();
|
|
71
|
+
}
|
|
72
|
+
|
|
66
73
|
// Compile each input file individually to avoid cross‑file symbol leakage.
|
|
67
74
|
const results: any[] = [];
|
|
68
75
|
// Build the full list of .cnx/.cnext files from srcDirs and explicit files
|
|
@@ -175,6 +182,30 @@ class Project {
|
|
|
175
182
|
|
|
176
183
|
return aggregate;
|
|
177
184
|
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Issue #558: Compile using Pipeline.run() for cross-file const inference in C++ mode.
|
|
188
|
+
*/
|
|
189
|
+
private async compileWithPipeline(): Promise<IProjectResult> {
|
|
190
|
+
const pipelineResult = await this.pipeline.run();
|
|
191
|
+
|
|
192
|
+
// Convert Pipeline result to Project result format
|
|
193
|
+
return {
|
|
194
|
+
success: pipelineResult.success,
|
|
195
|
+
filesProcessed: pipelineResult.filesProcessed,
|
|
196
|
+
symbolsCollected: pipelineResult.symbolsCollected,
|
|
197
|
+
conflicts: pipelineResult.conflicts,
|
|
198
|
+
errors: pipelineResult.errors.map((e) => {
|
|
199
|
+
if (typeof e === "string") return e;
|
|
200
|
+
const path = (e as any).sourcePath ?? "";
|
|
201
|
+
return path
|
|
202
|
+
? `${path}:${e.line}:${e.column} ${e.message}`
|
|
203
|
+
: `${e.line}:${e.column} ${e.message}`;
|
|
204
|
+
}),
|
|
205
|
+
warnings: pipelineResult.warnings,
|
|
206
|
+
outputFiles: pipelineResult.outputFiles,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
178
209
|
/**
|
|
179
210
|
* Get the symbol table (for testing/inspection)
|
|
180
211
|
*/
|