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

100% Statements 11/11
83.33% Branches 5/6
100% Functions 1/1
100% Lines 11/11

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                                                                307x 1x       306x     307x 307x   307x 118x 118x   38x 38x         306x          
/**
 * Helper for extracting base identifier from assignment targets.
 * SonarCloud S3776: Extracted from walkStatementForModifications().
 */
import * as Parser from "../../../logic/parser/grammar/CNextParser";
 
/**
 * Result from extracting assignment target base identifier.
 */
interface IAssignmentTargetResult {
  /** The base identifier name, or null if not found */
  baseIdentifier: string | null;
  /** True if target has single-index subscript (array access, not bit extraction) */
  hasSingleIndexSubscript: boolean;
}
 
/**
 * Extracts base identifier from various assignment target patterns.
 * With unified grammar, all patterns use IDENTIFIER postfixTargetOp*.
 */
class AssignmentTargetExtractor {
  /**
   * Extract base identifier from an assignment target.
   *
   * Handles:
   * - Simple identifier: `x <- value`
   * - Member access: `x.field <- value` (returns 'x')
   * - Array access: `x[i] <- value` (returns 'x', flags subscript)
   */
  static extract(
    target: Parser.AssignmentTargetContext | undefined,
  ): IAssignmentTargetResult {
    if (!target) {
      return { baseIdentifier: null, hasSingleIndexSubscript: false };
    }
 
    // All patterns have base IDENTIFIER
    const baseIdentifier = target.IDENTIFIER()?.getText() ?? null;
 
    // Check postfixTargetOp for subscripts
    const postfixOps = target.postfixTargetOp();
    let hasSingleIndexSubscript = false;
 
    for (const op of postfixOps) {
      const exprs = op.expression();
      if (exprs.length === 1) {
        // Single-index subscript (array access)
        hasSingleIndexSubscript = true;
        break;
      }
      // Two-index subscript (bit extraction) doesn't set the flag
    }
 
    return { baseIdentifier, hasSingleIndexSubscript };
  }
}
 
export default AssignmentTargetExtractor;