erg_compiler/module/
global.rs1use erg_common::config::ErgConfig;
2use erg_common::pathutil::NormalizedPathBuf;
3use erg_common::shared::MappedRwLockReadGuard;
4use erg_common::spawn::safe_yield;
5
6use crate::context::{Context, ModuleContext};
7
8use super::cache::{ModuleEntry, SharedGeneralizationCache, SharedModuleCache};
9use super::errors::{SharedCompileErrors, SharedCompileWarnings};
10use super::graph::SharedModuleGraph;
11use super::impls::SharedTraitImpls;
12use super::index::SharedModuleIndex;
13use super::promise::SharedPromises;
14
15fn try_forever<T, F: FnMut() -> Result<T, ()>>(mut f: F) -> T {
16 loop {
17 if let Ok(res) = f() {
18 return res;
19 }
20 safe_yield();
21 }
22}
23
24#[derive(Debug, Clone, Default)]
25pub struct SharedCompilerResource {
26 pub mod_cache: SharedModuleCache,
27 pub py_mod_cache: SharedModuleCache,
28 pub index: SharedModuleIndex,
29 pub graph: SharedModuleGraph,
30 pub trait_impls: SharedTraitImpls,
34 pub promises: SharedPromises,
35 pub errors: SharedCompileErrors,
36 pub warns: SharedCompileWarnings,
37 pub gen_cache: SharedGeneralizationCache,
38}
39
40impl SharedCompilerResource {
41 pub fn new(cfg: ErgConfig) -> Self {
44 let graph = SharedModuleGraph::new();
45 let self_ = Self {
46 mod_cache: SharedModuleCache::new(),
47 py_mod_cache: SharedModuleCache::new(),
48 index: SharedModuleIndex::new(),
49 graph: graph.clone(),
50 trait_impls: SharedTraitImpls::new(),
51 promises: SharedPromises::new(graph, NormalizedPathBuf::from(cfg.input.path())),
52 errors: SharedCompileErrors::new(),
53 warns: SharedCompileWarnings::new(),
54 gen_cache: SharedGeneralizationCache::new(),
55 };
56 Context::init_builtins(cfg, self_.clone());
57 self_
58 }
59
60 pub fn inherit<P: Into<NormalizedPathBuf>>(&self, path: P) -> Self {
61 let mut _self = self.clone();
62 _self.promises.root = path.into();
63 _self
64 }
65
66 pub fn clear_all(&self) {
68 self.mod_cache.initialize();
69 self.py_mod_cache.initialize();
70 self.index.initialize();
71 self.graph.initialize();
72 self.trait_impls.initialize();
73 self.promises.initialize();
74 self.errors.clear();
75 self.warns.clear();
76 }
77
78 pub fn clear(&self, path: &NormalizedPathBuf) -> Option<ModuleEntry> {
81 let mut old = None;
82 for child in self.graph.children(path) {
83 self.clear(&child);
84 }
85 try_forever(|| {
86 if let Some(ent) = self.mod_cache.try_remove(path)? {
87 old = Some(ent);
88 }
89 Ok(())
90 });
91 try_forever(|| {
92 if let Some(ent) = self.py_mod_cache.try_remove(path)? {
93 old = Some(ent);
94 }
95 Ok(())
96 });
97 self.index.remove_path(path);
98 self.trait_impls.remove_by_path(path);
100 self.promises.remove(path);
101 self.errors.remove(path);
102 self.warns.remove(path);
103 old
104 }
105
106 pub fn clear_path(&self, path: &NormalizedPathBuf) {
107 try_forever(|| self.mod_cache.try_remove(path));
108 try_forever(|| self.py_mod_cache.try_remove(path));
109 self.index.remove_path(path);
110 self.trait_impls.remove_by_path(path);
112 self.promises.remove(path);
113 self.errors.remove(path);
114 self.warns.remove(path);
115 }
116
117 pub fn rename_path(&self, old: &NormalizedPathBuf, new: NormalizedPathBuf) {
118 self.mod_cache.rename_path(old, new.clone());
119 self.py_mod_cache.rename_path(old, new.clone());
120 self.index.rename_path(old, new.clone());
121 self.trait_impls.rename_path(old, new.clone());
122 self.graph.rename_path(old, new.clone());
123 self.promises.rename(old, new);
124 }
125
126 pub fn insert_module(&self, path: NormalizedPathBuf, entry: ModuleEntry) {
127 if path.to_string_lossy().ends_with(".d.er") {
128 self.py_mod_cache.insert(path, entry);
129 } else {
130 self.mod_cache.insert(path, entry);
131 }
132 }
133
134 pub fn remove_module(&self, path: &std::path::Path) -> Option<ModuleEntry> {
137 if path.to_string_lossy().ends_with(".d.er") {
138 try_forever(|| self.py_mod_cache.try_remove(path))
139 } else {
140 try_forever(|| self.mod_cache.try_remove(path))
141 }
142 }
143
144 pub fn get_module(
145 &self,
146 path: &std::path::Path,
147 ) -> Option<MappedRwLockReadGuard<'_, ModuleEntry>> {
148 if path.to_string_lossy().ends_with(".d.er") {
149 self.py_mod_cache.get(path)
150 } else {
151 self.mod_cache.get(path)
152 }
153 }
154
155 pub fn raw_ref_ctx_with_timeout(
156 &self,
157 path: &std::path::Path,
158 timeout: std::time::Duration,
159 ) -> Option<&ModuleContext> {
160 if path.to_string_lossy().ends_with(".d.er") {
161 self.py_mod_cache.raw_ref_ctx_with_timeout(path, timeout)
162 } else {
163 self.mod_cache.raw_ref_ctx_with_timeout(path, timeout)
164 }
165 }
166
167 pub fn raw_ref_builtins_ctx(&self) -> Option<&ModuleContext> {
168 self.mod_cache.raw_ref_builtins_ctx()
169 }
170
171 pub fn raw_modules(&self) -> impl Iterator<Item = &ModuleEntry> {
172 self.mod_cache
173 .raw_values()
174 .chain(self.py_mod_cache.raw_values())
175 }
176
177 pub fn raw_path_and_modules(&self) -> impl Iterator<Item = (&NormalizedPathBuf, &ModuleEntry)> {
178 self.mod_cache
179 .raw_iter()
180 .chain(self.py_mod_cache.raw_iter())
181 }
182}