All files / TRANSPILE/3-Render/codegen/generators/expressions ExpressionGenerator.ts

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

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                                                        47x           3021x   3021x 3010x               11x 11x     11x       11x        
/**
 * Expression Generator Entry Point
 *
 * Generates ternary expressions with ADR-022 safety constraints, and passes a
 * non-ternary expression through.
 *
 * #1445 box 3: takes `TPlannedTernary`, not the node. The node was read for
 * exactly one thing -- the number of `orExpression` children -- and each child
 * was handed straight back to the orchestrator. The pass-through
 * `generateExpression` that wrapped this is gone with it: it called
 * `node.ternaryExpression()` and delegated, which is the walker's step, not a
 * generator's.
 */
import IGeneratorOutput from "../IGeneratorOutput";
import TGeneratorEffect from "../TGeneratorEffect";
import IGeneratorInput from "../IGeneratorInput";
import IGeneratorState from "../IGeneratorState";
import IOrchestrator from "../IOrchestrator";
import TGeneratorFn from "../TGeneratorFn";
import type TPlannedTernary from "../../types/TPlannedTernary";
 
/**
 * Generate C code for a ternary expression (ADR-022).
 *
 * Safety constraints are enforced in pass 2.1, not here: #1322 moved every
 * ADR-022 rule there -- nested ternary (E0710), the controlling-expression
 * rule (E0701) and no function call in a condition (E0702).
 */
const generateTernaryExpr: TGeneratorFn<TPlannedTernary> = (
  planned: TPlannedTernary,
  _input: IGeneratorInput,
  _state: IGeneratorState,
  orchestrator: IOrchestrator,
): IGeneratorOutput => {
  const effects: TGeneratorEffect[] = [];
 
  if (planned.kind === "value") {
    return { code: planned.code, effects };
  }
 
  // Parentheses are already present from the grammar.
  //
  // Issue #992: clear inDeclarationInit in the ARMS only -- a struct
  // initializer inside one needs a compound literal, not a plain designated
  // initializer. The condition keeps the flag as it stands.
  const condition = planned.renderCondition();
  const trueCode = orchestrator.state.withoutDeclarationInit(
    planned.renderTrue,
  );
  const falseCode = orchestrator.state.withoutDeclarationInit(
    planned.renderFalse,
  );
 
  return { code: `(${condition}) ? ${trueCode} : ${falseCode}`, effects };
};
 
export default generateTernaryExpr;