All files / transpiler/output/codegen/helpers CppModeHelper.ts

100% Statements 9/9
100% Branches 14/14
100% Functions 9/9
100% Lines 9/9

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                                                849x                       17x                       27x                     65x                     2x                     4x                         7x                         6x                     2x          
/**
 * CppModeHelper - Utilities for C/C++ mode-specific code generation
 *
 * Issue #644: Extracted from CodeGenerator to consolidate cppMode conditionals.
 *
 * In C mode, struct parameters are passed by pointer (need & for address, * for type).
 * In C++ mode, struct parameters are passed by reference (no & needed, & for type).
 */
 
/**
 * Options for C/C++ mode helpers.
 */
interface CppModeOptions {
  /** Whether we're generating C++ code */
  cppMode: boolean;
}
 
/**
 * Helper class for C/C++ mode-specific code generation patterns.
 */
class CppModeHelper {
  private readonly cppMode: boolean;
 
  constructor(options: CppModeOptions) {
    this.cppMode = options.cppMode;
  }
 
  /**
   * Get address-of expression for struct parameter passing.
   * C mode: `&expr` (pass pointer to struct)
   * C++ mode: `expr` (pass reference directly)
   *
   * @param expr - The expression to potentially wrap
   * @returns The expression with address-of operator in C mode
   */
  maybeAddressOf(expr: string): string {
    return this.cppMode ? expr : `&${expr}`;
  }
 
  /**
   * Get dereference expression for struct parameter access.
   * C mode: `(*expr)` (dereference pointer)
   * C++ mode: `expr` (reference can be used directly)
   *
   * @param expr - The expression to potentially dereference
   * @returns The expression with dereference in C mode
   */
  maybeDereference(expr: string): string {
    return this.cppMode ? expr : `(*${expr})`;
  }
 
  /**
   * Get the type modifier for struct parameter declarations.
   * C mode: `*` (pointer type)
   * C++ mode: `&` (reference type)
   *
   * @returns The type modifier character
   */
  refOrPtr(): string {
    return this.cppMode ? "&" : "*";
  }
 
  /**
   * Get the member access separator for struct parameters.
   * C mode: `->` (pointer member access)
   * C++ mode: `.` (reference member access)
   *
   * @returns The member access separator
   */
  memberSeparator(): string {
    return this.cppMode ? "." : "->";
  }
 
  /**
   * Get NULL literal for the current mode.
   * C mode: `NULL`
   * C++ mode: `nullptr`
   *
   * @returns The null pointer literal
   */
  nullLiteral(): string {
    return this.cppMode ? "nullptr" : "NULL";
  }
 
  /**
   * Generate a cast expression for the current mode.
   * C mode: `(type)expr`
   * C++ mode: `static_cast<type>(expr)`
   *
   * @param type - The target type
   * @param expr - The expression to cast
   * @returns The cast expression
   */
  cast(type: string, expr: string): string {
    return this.cppMode ? `static_cast<${type}>(${expr})` : `(${type})${expr}`;
  }
 
  /**
   * Generate a reinterpret cast expression for the current mode.
   * C mode: `(type)expr`
   * C++ mode: `reinterpret_cast<type>(expr)`
   *
   * @param type - The target type
   * @param expr - The expression to cast
   * @returns The cast expression
   */
  reinterpretCast(type: string, expr: string): string {
    return this.cppMode
      ? `reinterpret_cast<${type}>(${expr})`
      : `(${type})${expr}`;
  }
 
  /**
   * Check if we're in C++ mode.
   *
   * @returns True if generating C++ code
   */
  isCppMode(): boolean {
    return this.cppMode;
  }
}
 
export default CppModeHelper;