All files / utils TypeCheckUtils.ts

100% Statements 14/14
100% Branches 2/2
100% Functions 8/8
100% Lines 14/14

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                20x                       20x     20x     20x     20x                   100x                   6x                   6x                   4x                   53x                   7x 7x                   9x                     40x          
/**
 * Type checking utilities for C-Next types.
 * Pure predicate functions for type classification.
 *
 * Extracted from CodeGenerator.ts as part of ADR-109 decomposition.
 */
 
/** All integer types in C-Next */
const INTEGER_TYPES = [
  "u8",
  "u16",
  "u32",
  "u64",
  "i8",
  "i16",
  "i32",
  "i64",
] as const;
 
/** Unsigned integer types */
const UNSIGNED_TYPES = ["u8", "u16", "u32", "u64"] as const;
 
/** Signed integer types */
const SIGNED_TYPES = ["i8", "i16", "i32", "i64"] as const;
 
/** Floating point types */
const FLOAT_TYPES = ["f32", "f64"] as const;
 
/** Standard bit widths for MMIO optimization */
const STANDARD_WIDTHS = [8, 16, 32] as const;
 
class TypeCheckUtils {
  /**
   * Check if a type name is a C-Next integer type.
   *
   * @param typeName - The type name to check
   * @returns true if it's u8, u16, u32, u64, i8, i16, i32, or i64
   */
  static isInteger(typeName: string): boolean {
    return (INTEGER_TYPES as readonly string[]).includes(typeName);
  }
 
  /**
   * Check if a type name is an unsigned integer type.
   *
   * @param typeName - The type name to check
   * @returns true if it's u8, u16, u32, or u64
   */
  static isUnsigned(typeName: string): boolean {
    return (UNSIGNED_TYPES as readonly string[]).includes(typeName);
  }
 
  /**
   * Check if a type name is a signed integer type.
   *
   * @param typeName - The type name to check
   * @returns true if it's i8, i16, i32, or i64
   */
  static isSigned(typeName: string): boolean {
    return (SIGNED_TYPES as readonly string[]).includes(typeName);
  }
 
  /**
   * Check if a type name is a floating point type.
   *
   * @param typeName - The type name to check
   * @returns true if it's f32 or f64
   */
  static isFloat(typeName: string): boolean {
    return (FLOAT_TYPES as readonly string[]).includes(typeName);
  }
 
  /**
   * Check if a type name is a string type (string<N>).
   *
   * @param typeName - The type name to check
   * @returns true if it matches string<N> pattern
   */
  static isString(typeName: string): boolean {
    return /^string<\d+>$/.test(typeName);
  }
 
  /**
   * Extract capacity from a string type.
   *
   * @param typeName - The string type (e.g., "string<32>")
   * @returns The capacity or null if not a string type
   */
  static getStringCapacity(typeName: string): number | null {
    const match = /^string<(\d+)>$/.exec(typeName);
    return match ? Number.parseInt(match[1], 10) : null;
  }
 
  /**
   * Check if a bit width is a standard MMIO-optimizable width.
   *
   * @param width - The bit width
   * @returns true if it's 8, 16, or 32 bits
   */
  static isStandardWidth(width: number): boolean {
    return (STANDARD_WIDTHS as readonly number[]).includes(width);
  }
 
  /**
   * Check if a type uses native C arithmetic (no overflow checking).
   * Floats overflow to infinity, so they don't need clamp/wrap.
   *
   * @param typeName - The type name
   * @returns true if it's a float type
   */
  static usesNativeArithmetic(typeName: string): boolean {
    return typeName.startsWith("f");
  }
}
 
export default TypeCheckUtils;