Skip to main content

factorio_ir/
module.rs

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