/**
 * IR Visitor Pattern
 *
 * Base class for IR transformations and analysis
 */
/**
 * Generic visitor for IR traversal
 */
export class IRVisitor {
    visitProgram(program) {
        for (const module of program.modules.values()) {
            this.visitModule(module);
        }
        return undefined;
    }
    visitModule(module) {
        for (const decl of module.declarations) {
            this.visitDeclaration(decl);
        }
        return undefined;
    }
    visitDeclaration(decl) {
        switch (decl.kind) {
            case 'function':
                return this.visitFunction(decl);
            case 'class':
                return this.visitClass(decl);
            case 'const':
                return this.visitExpr(decl.value);
            case 'interface':
            case 'typeAlias':
                return undefined;
        }
    }
    visitFunction(_func) {
        // TODO: Add proper AST-level statement visiting
        // For now, skip AST-level function bodies
        return undefined;
    }
    visitClass(_cls) {
        // TODO: Add proper AST-level statement visiting
        // For now, skip AST-level method bodies
        return undefined;
    }
    visitBlock(block) {
        for (const instruction of block.instructions) {
            this.visitInstruction(instruction);
        }
        return undefined;
    }
    visitInstruction(instruction) {
        switch (instruction.kind) {
            case 'assign':
                return this.visitExpr(instruction.value);
            case 'call':
                instruction.args.forEach(arg => this.visitExpr(arg));
                return this.visitExpr(instruction.callee);
            case 'fieldAssign':
                this.visitExpr(instruction.object);
                return this.visitExpr(instruction.value);
            case 'indexAssign':
                this.visitExpr(instruction.object);
                this.visitExpr(instruction.index);
                return this.visitExpr(instruction.value);
            case 'memberAssign':
                this.visitExpr(instruction.object);
                return this.visitExpr(instruction.value);
            case 'expr':
                return this.visitExpr(instruction.value);
        }
    }
    visitExpr(expr) {
        switch (expr.kind) {
            case 'literal':
            case 'variable':
                return undefined;
            case 'binary':
                this.visitExpr(expr.left);
                return this.visitExpr(expr.right);
            case 'unary':
                return this.visitExpr(expr.operand);
            case 'conditional':
                this.visitExpr(expr.condition);
                this.visitExpr(expr.whenTrue);
                return this.visitExpr(expr.whenFalse);
            case 'member':
                return this.visitExpr(expr.object);
            case 'index':
                this.visitExpr(expr.object);
                return this.visitExpr(expr.index);
            case 'callExpr':
                this.visitExpr(expr.callee);
                expr.args.forEach(arg => this.visitExpr(arg));
                return undefined;
            case 'methodCall':
                this.visitExpr(expr.object);
                expr.args.forEach(arg => this.visitExpr(arg));
                return undefined;
            case 'new':
                expr.args.forEach(arg => this.visitExpr(arg));
                return undefined;
            case 'array':
                expr.elements.forEach(el => this.visitExpr(el));
                return undefined;
            case 'object':
                expr.properties.forEach(prop => this.visitExpr(prop.value));
                return undefined;
            case 'lambda':
                // Visit lambda body block (instructions only, terminator is implicit)
                expr.body.instructions.forEach(inst => this.visitInstruction(inst));
                if (expr.body.terminator.kind === 'return' && expr.body.terminator.value) {
                    this.visitExpr(expr.body.terminator.value);
                }
                return undefined;
            case 'move':
            case 'borrow':
                return this.visitExpr(expr.source);
        }
    }
}
//# sourceMappingURL=visitor.js.map