Skip to main content

factorio_ir/module/
mod.rs

1//! Compilation units: modules, Factorio stages, and locale payloads.
2
3pub mod locale;
4pub mod stage;
5
6use crate::ast::{block::Block, scope::Scope, statement::Statement};
7
8use self::{
9    locale::{LocaleFile, PendingLocaleFile},
10    stage::Stage,
11};
12
13#[derive(Debug, Clone, PartialEq)]
14pub struct Symbol {
15    pub scope: Scope,
16    pub statement: Statement,
17}
18
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub struct ModuleImport {
21    /// Dotted module path inside the Factorio mod (e.g. `shared.player`).
22    pub module: String,
23    pub local: String,
24    pub items: Vec<ImportedItem>,
25    /// When set, `require` targets this Factorio mod instead of the consuming mod.
26    pub factorio_mod: Option<String>,
27    /// Path prefix inside the Factorio mod (`Some("lua")`, `Some("")`, ...).
28    /// When [`Self::factorio_mod`] is `None`, codegen always uses `lua`.
29    pub module_root: Option<String>,
30}
31
32#[derive(Debug, Clone, PartialEq, Eq)]
33pub struct ImportedItem {
34    pub name: String,
35    pub local: String,
36}
37
38/// Vtable emitted for a `(Trait, Concrete)` pair used by `dyn` coercion.
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub struct VTable {
41    /// Symbol name, e.g. `__vt_Display_Point`.
42    pub name: String,
43    /// Concrete type whose methods the vtable forwards to.
44    pub concrete_type: String,
45    /// Method names present on the trait (and thus on this vtable).
46    pub methods: Vec<String>,
47}
48
49#[derive(Debug, Clone, PartialEq)]
50pub struct Module {
51    pub name: String,
52    pub stage: Stage,
53    pub body: Block,
54    pub symbols: Vec<Symbol>,
55    pub imports: Vec<ModuleImport>,
56    pub submodules: Vec<String>,
57    /// Locale `.cfg` data declared via `locale!` in this module.
58    pub locales: Vec<LocaleFile>,
59    /// Parsed `locale!` blocks waiting for `Type::CONST` resolution (possibly
60    /// across imports). Cleared once [`locales`](Self::locales) is filled.
61    pub pending_locales: Vec<PendingLocaleFile>,
62    /// Vtables for `dyn Trait` dispatch, emitted before other module locals.
63    pub vtables: Vec<VTable>,
64}
65
66impl Module {
67    #[must_use]
68    pub fn imported_item_local(&self, type_name: &str) -> Option<&str> {
69        self.imports
70            .iter()
71            .flat_map(|import| import.items.iter())
72            .find_map(|item| {
73                if item.name == type_name {
74                    Some(item.local.as_str())
75                } else {
76                    None
77                }
78            })
79    }
80
81    #[must_use]
82    pub fn is_imported_type_extension(&self, struct_decl: &crate::ast::structure::Struct) -> bool {
83        struct_decl.fields.is_empty() && self.imported_item_local(&struct_decl.name).is_some()
84    }
85}