factorio-codegen 0.1.2

Lua code generator for factorio-rs
Documentation
mod common;

use common::must_ok;
use factorio_codegen::LuaGenerator;
use factorio_ir::{
    block::Block,
    expression::Expression,
    function::{Function, Parameter},
    literal::Literal,
    module::{Module, Symbol},
    scope::Scope,
    stage::Stage,
    statement::Statement,
    r#type::Type,
};

#[test]
fn generates_module_with_private_helper_and_exported_handler() {
    let module = Module {
        name: "bound_detector".to_string(),
        stage: Stage::Control,
        body: Block {
            statements: vec![Statement::FunctionDecl(Function {
                name: "helper".to_string(),
                params: vec![],
                body: Block {
                    statements: vec![Statement::Return(Some(Expression::Literal(Literal::Int(
                        1,
                    ))))],
                },
                doc: None,
                debug: None,
                event: None,
                event_filter: None,
            })],
        },
        imports: vec![],
        submodules: vec![],
        locales: vec![],
        symbols: vec![Symbol {
            scope: Scope::Public,
            statement: Statement::FunctionDecl(Function {
                name: "on_init".to_string(),
                params: vec![Parameter {
                    name: "event".to_string(),
                    r#type: Type::Void,
                    source_type: None,
                }],
                body: Block {
                    statements: vec![Statement::VariableDecl {
                        name: "count".to_string(),
                        ty: Type::Int,
                        source_type: None,
                        value: Expression::Literal(Literal::Int(0)),
                    }],
                },
                doc: None,
                debug: None,
                event: None,
                event_filter: None,
            }),
        }],
    };

    let output = must_ok(LuaGenerator::new().generate_module(&module));

    assert_eq!(
        output,
        concat!(
            "-- Generated by factorio-rs@0.1.2\n",
            "-- Module: `bound_detector`\n",
            "local function helper()\n",
            "\treturn 1\n",
            "end\n",
            "local boundDetector = {}\n",
            "function boundDetector.on_init(event)\n",
            "\tlocal count = 0\n",
            "end\n",
            "return boundDetector\n",
        )
    );
}

#[test]
fn omits_unreachable_private_helper_when_pruned() {
    use factorio_ir::prune::prune_modules;

    let mut module = Module {
        name: "bound_detector".to_string(),
        stage: Stage::Control,
        body: Block {
            statements: vec![Statement::FunctionDecl(Function {
                name: "helper".to_string(),
                params: vec![],
                body: Block {
                    statements: vec![Statement::Return(Some(Expression::Literal(Literal::Int(
                        1,
                    ))))],
                },
                doc: None,
                debug: None,
                event: None,
                event_filter: None,
            })],
        },
        imports: vec![],
        submodules: vec![],
        locales: vec![],
        symbols: vec![Symbol {
            scope: Scope::Public,
            statement: Statement::FunctionDecl(Function {
                name: "on_init".to_string(),
                params: vec![Parameter {
                    name: "event".to_string(),
                    r#type: Type::Void,
                    source_type: None,
                }],
                body: Block {
                    statements: vec![Statement::VariableDecl {
                        name: "count".to_string(),
                        ty: Type::Int,
                        source_type: None,
                        value: Expression::Literal(Literal::Int(0)),
                    }],
                },
                doc: None,
                debug: None,
                event: Some("on_init".to_string()),
                event_filter: None,
            }),
        }],
    };

    prune_modules(std::slice::from_mut(&mut module));

    let output = must_ok(LuaGenerator::new().generate_module(&module));

    assert_eq!(
        output,
        concat!(
            "-- Generated by factorio-rs@0.1.2\n",
            "-- Module: `bound_detector`\n",
            "local boundDetector = {}\n",
            "function boundDetector.on_init(event)\n",
            "\tlocal count = 0\n",
            "end\n",
            "return boundDetector\n",
        )
    );
}