Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | 146x 352x 198x 154x 154x 153x 51x 28x 59x 13x 46x 59x 59x | /**
* AutoConstUpdater
* Issue #588: Extracted from Transpiler to logic layer
*
* Updates symbol parameters with auto-const information based on code generation
* analysis. Parameters that are not modified in function bodies can be marked
* as auto-const, enabling correct const qualifier generation in headers.
*/
import ISymbol from "../../../utils/types/ISymbol";
import ESymbolKind from "../../../utils/types/ESymbolKind";
/**
* Utility class for updating symbol parameters with auto-const information.
*
* In C-Next, struct parameters are passed by pointer by default. If a parameter
* is never modified, it can be marked as `const` in the generated C code.
* This class encapsulates the logic to determine which parameters qualify.
*/
class AutoConstUpdater {
/**
* Update symbols with auto-const information.
*
* For each function symbol, checks if its parameters were unmodified during
* code generation and marks them as auto-const if they meet the criteria.
*
* @param symbols - Array of symbols to update (typically from a single file)
* @param unmodifiedParams - Map of function name to set of unmodified param names
* @param knownEnums - Set of known enum type names (these don't get pointer semantics)
*/
static update(
symbols: ISymbol[],
unmodifiedParams: ReadonlyMap<string, ReadonlySet<string>>,
knownEnums: ReadonlySet<string>,
): void {
for (const symbol of symbols) {
if (symbol.kind !== ESymbolKind.Function || !symbol.parameters) {
continue;
}
const unmodified = unmodifiedParams.get(symbol.name);
if (!unmodified) continue;
// Update each parameter's isAutoConst
for (const param of symbol.parameters) {
if (
AutoConstUpdater.shouldMarkAutoConst(param, unmodified, knownEnums)
) {
param.isAutoConst = true;
}
}
}
}
/**
* Determine if a parameter should be marked as auto-const.
*
* A parameter qualifies for auto-const if:
* 1. It was not modified in the function body
* 2. It would get pointer semantics in generated C (not a primitive/enum)
*
* @param param - The parameter to check
* @param unmodified - Set of unmodified parameter names for this function
* @param knownEnums - Set of known enum type names
* @returns true if the parameter should be marked as auto-const
*/
static shouldMarkAutoConst(
param: NonNullable<ISymbol["parameters"]>[number],
unmodified: ReadonlySet<string>,
knownEnums: ReadonlySet<string>,
): boolean {
// Parameter must be unmodified
if (!unmodified.has(param.name)) {
return false;
}
// Check if parameter would get pointer semantics
const isPointerParam =
!param.isConst &&
!param.isArray &&
param.type !== "f32" &&
param.type !== "f64" &&
param.type !== "ISR" &&
!knownEnums.has(param.type);
// Array params also become pointers in C
const isArrayParam = param.isArray && !param.isConst;
return isPointerParam || isArrayParam;
}
}
export default AutoConstUpdater;
|