/**
 * Conditional statement converters (if, switch)
 *
 * Phase 5 Step 4: Uses ProgramContext instead of Binding.
 */
import * as ts from "typescript";
import { convertExpression } from "../../../expression-converter.js";
import { convertStatementSingle, flattenStatementResult, convertStatement, } from "../../../statement-converter.js";
import { collectTypeNarrowingsInTruthyExpr, collectTypeNarrowingsInFalsyExpr, withAppliedNarrowings, } from "../../flow-narrowing.js";
import { withVariableTypeEnv } from "../../type-env.js";
/**
 * Convert if statement
 *
 * @param expectedReturnType - Return type from enclosing function for contextual typing.
 *                             Passed through to nested statements for return expressions.
 */
export const convertIfStatement = (node, ctx, expectedReturnType) => {
    const thenCtx = withAppliedNarrowings(ctx, collectTypeNarrowingsInTruthyExpr(node.expression, ctx));
    const elseCtx = (() => {
        if (!node.elseStatement)
            return ctx;
        return withAppliedNarrowings(ctx, collectTypeNarrowingsInFalsyExpr(node.expression, ctx));
    })();
    const thenStmt = convertStatementSingle(node.thenStatement, thenCtx, expectedReturnType);
    const elseStmt = node.elseStatement
        ? convertStatementSingle(node.elseStatement, elseCtx, expectedReturnType)
        : undefined;
    return {
        kind: "ifStatement",
        condition: convertExpression(node.expression, ctx, undefined),
        thenStatement: thenStmt ?? { kind: "emptyStatement" },
        elseStatement: elseStmt ?? undefined,
    };
};
/**
 * Convert switch statement
 *
 * @param expectedReturnType - Return type from enclosing function for contextual typing.
 */
export const convertSwitchStatement = (node, ctx, expectedReturnType) => {
    return {
        kind: "switchStatement",
        expression: convertExpression(node.expression, ctx, undefined),
        cases: node.caseBlock.clauses.map((clause) => convertSwitchCase(clause, ctx, expectedReturnType)),
    };
};
/**
 * Convert switch case
 *
 * @param expectedReturnType - Return type from enclosing function for contextual typing.
 */
export const convertSwitchCase = (node, ctx, expectedReturnType) => {
    let currentCtx = ctx;
    const statements = [];
    for (const s of node.statements) {
        const converted = convertStatement(s, currentCtx, expectedReturnType);
        statements.push(...flattenStatementResult(converted));
        if (ts.isVariableStatement(s) &&
            converted !== null &&
            !Array.isArray(converted)) {
            const single = converted;
            if (single.kind !== "variableDeclaration")
                continue;
            currentCtx = withVariableTypeEnv(currentCtx, s.declarationList.declarations, single);
        }
    }
    return {
        kind: "switchCase",
        test: ts.isCaseClause(node)
            ? convertExpression(node.expression, ctx, undefined)
            : undefined,
        statements,
    };
};
//# sourceMappingURL=conditionals.js.map