Skip to main content

luaur_analysis/methods/
frontend_get_module_environment.rs

1use crate::records::binding::Binding;
2use crate::records::frontend::Frontend;
3use crate::records::scope::Scope;
4use crate::records::source_module::SourceModule;
5use crate::records::symbol::Symbol;
6use crate::type_aliases::scope_ptr_type::ScopePtr;
7use alloc::sync::Arc;
8use luaur_ast::records::location::Location;
9use luaur_config::records::config::Config;
10use std::ffi::CString;
11
12impl Frontend {
13    pub fn get_module_environment(
14        &self,
15        module: &SourceModule,
16        config: &Config,
17        for_autocomplete: bool,
18    ) -> ScopePtr {
19        let mut result = if for_autocomplete {
20            self.globals_for_autocomplete.global_scope.clone()
21        } else {
22            self.globals.global_scope.clone()
23        };
24
25        if let Some(environment_name) = &module.environment_name {
26            result = self.get_environment_scope(environment_name.clone());
27        }
28
29        if !config.globals.is_empty() {
30            result = Arc::new(Scope::new(&result, 0));
31
32            for global in &config.globals {
33                let global_cstr =
34                    CString::new(global.as_str()).expect("global names cannot contain NUL");
35                let name = module.names.get(global_cstr.as_ptr());
36
37                if !name.value.is_null() {
38                    let scope = Arc::get_mut(&mut result)
39                        .expect("new module environment scope is uniquely owned");
40                    let binding =
41                        scope
42                            .bindings
43                            .entry(Symbol::from_global(name))
44                            .or_insert(Binding {
45                                type_id: core::ptr::null(),
46                                location: Location::default(),
47                                deprecated: false,
48                                deprecated_suggestion: alloc::string::String::new(),
49                                documentation_symbol: None,
50                            });
51                    binding.type_id = unsafe { (*self.builtin_types).anyType };
52                }
53            }
54        }
55
56        result
57    }
58}