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 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | 351x 4x 347x 47x 300x 174x 126x 8x 118x 115x 3x 47x 58x 47x 3x 44x 4x 40x 174x 174x 8x 8x 115x 115x 115x 3x 3x 170x 85x 85x | /**
* ParameterSignatureBuilder - Stateless builder for C/C++ parameter signatures
*
* Takes a normalized IParameterInput and produces the final parameter string.
* All decisions (const, pass-by-value, etc.) are pre-computed in the input.
*
* This is the single source of truth for parameter formatting, used by both:
* - CodeGenerator (via ParameterInputAdapter.fromAST)
* - BaseHeaderGenerator (via ParameterInputAdapter.fromSymbol)
*/
import IParameterInput from "../types/IParameterInput";
/**
* Static helper class for building C/C++ parameter signature strings.
*/
class ParameterSignatureBuilder {
/**
* Build a parameter signature string from normalized input.
*
* @param param - Normalized parameter input (all decisions pre-computed)
* @param refSuffix - '*' for C mode (pointer), '&' for C++ mode (reference)
* @returns The formatted parameter string (e.g., "const uint32_t* value")
*/
static build(param: IParameterInput, refSuffix: string): string {
// Callback parameters: just typedef name and param name
if (param.isCallback && param.callbackTypedefName) {
return `${param.callbackTypedefName} ${param.name}`;
}
// Array parameters with dimensions
if (
param.isArray &&
param.arrayDimensions &&
param.arrayDimensions.length > 0
) {
return this._buildArrayParam(param);
}
// Pass-by-value parameters (ISR, float, enum, small primitives)
if (param.isPassByValue) {
return this._buildPassByValueParam(param);
}
// Non-array string: string<N> -> const char* name
if (param.isString && !param.isArray) {
return this._buildStringParam(param);
}
// Known struct or known primitive: pass by reference
if (param.isPassByReference) {
return this._buildRefParam(param, refSuffix);
}
// Unknown types: pass by value (standard C semantics)
return this._buildUnknownParam(param);
}
/**
* Build array parameter signature.
* Examples:
* - u32[10] arr -> const uint32_t arr[10]
* - u8[4][4] matrix -> const uint8_t matrix[4][4]
* - string<32>[5] names -> const char names[5][33]
* - string[5] names -> char* names[5] (unbounded string array)
*/
private static _buildArrayParam(param: IParameterInput): string {
const constPrefix = this._getConstPrefix(param);
const dims = param.arrayDimensions!.map((d) => `[${d}]`).join("");
// Unbounded string arrays use char* (array of char pointers)
if (param.isUnboundedString) {
return `${constPrefix}char* ${param.name}${dims}`;
}
// Bounded string arrays use char (dimensions include capacity)
if (param.isString) {
return `${constPrefix}char ${param.name}${dims}`;
}
return `${constPrefix}${param.mappedType} ${param.name}${dims}`;
}
/**
* Build pass-by-value parameter signature.
* Used for: ISR, f32, f64, enums, small unmodified primitives.
* Example: float value, ISR handler, Status s
*/
private static _buildPassByValueParam(param: IParameterInput): string {
const constMod = param.isConst ? "const " : "";
return `${constMod}${param.mappedType} ${param.name}`;
}
/**
* Build non-array string parameter signature.
* string<N> -> const char* name (with auto-const if unmodified)
*/
private static _buildStringParam(param: IParameterInput): string {
const constPrefix = this._getConstPrefix(param);
return `${constPrefix}char* ${param.name}`;
}
/**
* Build pass-by-reference parameter signature.
* C mode: const Point* p
* C++ mode: const Point& p (unless forcePointerSyntax)
*
* Issue #895: When forcePointerSyntax is set, always use pointer syntax
* because C callback typedefs expect pointers, not C++ references.
*/
private static _buildRefParam(
param: IParameterInput,
refSuffix: string,
): string {
const constPrefix = this._getConstPrefix(param);
// Issue #895: Override refSuffix for callback-compatible functions
const actualSuffix = param.forcePointerSyntax ? "*" : refSuffix;
return `${constPrefix}${param.mappedType}${actualSuffix} ${param.name}`;
}
/**
* Build unknown type parameter (pass by value, standard C semantics).
*/
private static _buildUnknownParam(param: IParameterInput): string {
const constMod = param.isConst ? "const " : "";
return `${constMod}${param.mappedType} ${param.name}`;
}
/**
* Get const prefix combining explicit const, auto-const, and forced const.
* Priority: forceConst > isConst > isAutoConst
* Issue #895: forceConst preserves const from callback typedef signature.
*/
private static _getConstPrefix(param: IParameterInput): string {
// Any source of const results in "const " prefix
if (param.forceConst || param.isConst || param.isAutoConst) {
return "const ";
}
return "";
}
}
export default ParameterSignatureBuilder;
|