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 | 112x 112x 112x 115x 115x 104x 115x 6x 115x 18x 115x 116x 94x 27x 112x 112x 19x 19x 19x 93x | /**
* VariableDeclarationFormatter - Unified variable declaration string generation.
*
* Phase 2 of unified code generation: Provides a single source of truth for
* variable declaration formatting, eliminating sync issues between
* CodeGenerator and HeaderGeneratorUtils.
*
* Handles:
* - Modifier ordering (extern const volatile)
* - Type formatting with embedded dimensions (string<N> → char[N+1])
* - Array dimension placement after variable name
*
* This class is STATELESS - all decisions are pre-computed in IVariableFormatInput.
*/
import type IVariableFormatInput from "../types/IVariableFormatInput";
/** Modifier flags for variable declarations */
type IVariableModifiers = IVariableFormatInput["modifiers"];
class VariableDeclarationFormatter {
/**
* Format a variable declaration string.
*
* @param input - Normalized variable declaration input (all decisions pre-computed)
* @returns Formatted declaration string (e.g., "extern const uint32_t count")
*/
static format(input: IVariableFormatInput): string {
const modifierPrefix = VariableDeclarationFormatter.buildModifierPrefix(
input.modifiers,
);
const arrayDimsStr = VariableDeclarationFormatter.buildArrayDimensions(
input.arrayDimensions,
);
// Handle types with embedded dimensions (e.g., char[33] from string<32>)
// In C, array dimensions follow the variable name, not the type
return VariableDeclarationFormatter.formatWithEmbeddedDimensions(
modifierPrefix,
input.mappedType,
input.name,
arrayDimsStr,
);
}
/**
* Build the modifier prefix string with consistent ordering.
*
* Order: extern volatile const
* - Matches the established C-Next output format
* - atomic maps to volatile, so atomic and volatile are mutually exclusive
* - The caller should validate this before calling
*/
static buildModifierPrefix(modifiers: IVariableModifiers): string {
const parts: string[] = [];
if (modifiers.isExtern) {
parts.push("extern");
}
// atomic and volatile both map to volatile in C
// volatile comes before const to match established format
if (modifiers.isAtomic || modifiers.isVolatile) {
parts.push("volatile");
}
if (modifiers.isConst) {
parts.push("const");
}
return parts.length > 0 ? parts.join(" ") + " " : "";
}
/**
* Build array dimension string from dimensions array.
*
* @param dimensions - Array of dimension strings (e.g., ['10', '20'])
* @returns Formatted dimensions (e.g., '[10][20]')
*/
static buildArrayDimensions(dimensions?: readonly string[]): string {
if (!dimensions || dimensions.length === 0) {
return "";
}
return dimensions.map((d) => `[${d}]`).join("");
}
/**
* Format declaration handling types with embedded array dimensions.
*
* Handles types like char[33] from string<32> where the dimension is
* embedded in the mapped type. In C, array dimensions must follow the
* variable name:
* char greeting[33]; // Correct
* char[33] greeting; // Wrong
*
* For string arrays (string<32>[5] names), produces:
* char names[5][33]; // Additional dims first, embedded dim last
*/
private static formatWithEmbeddedDimensions(
modifierPrefix: string,
mappedType: string,
name: string,
additionalDims: string,
): string {
// Check if the mapped type has embedded array dimensions (e.g., char[33])
// This happens for string<N> types which map to char[N+1]
const embeddedMatch = /^(\w+)\[(\d+)\]$/.exec(mappedType);
if (embeddedMatch) {
const baseType = embeddedMatch[1];
const embeddedDim = embeddedMatch[2];
// Format: modifiers baseType name[additionalDims][embeddedDim]
return `${modifierPrefix}${baseType} ${name}${additionalDims}[${embeddedDim}]`;
}
// No embedded dimensions - standard format
return `${modifierPrefix}${mappedType} ${name}${additionalDims}`;
}
}
export default VariableDeclarationFormatter;
|