sway_core/semantic_analysis/namespace/
module.rs1use crate::{
2 engine_threading::Engines,
3 language::{
4 ty::{self},
5 Visibility,
6 },
7 Ident, TypeId,
8};
9
10use super::{
11 lexical_scope::{Items, LexicalScope, ResolvedFunctionDecl},
12 LexicalScopeId, ModuleName, ModulePath, ModulePathBuf, ResolvedDeclaration,
13 ResolvedTraitImplItem, TraitMap,
14};
15
16use rustc_hash::FxHasher;
17use std::{collections::HashMap, hash::BuildHasherDefault};
18use sway_error::handler::Handler;
19use sway_error::{error::CompileError, handler::ErrorEmitted};
20use sway_types::{span::Span, Spanned};
21
22#[derive(Clone, Debug)]
31pub struct Module {
32 submodules: im::HashMap<ModuleName, Module, BuildHasherDefault<FxHasher>>,
40 pub lexical_scopes: Vec<LexicalScope>,
42 pub current_lexical_scope_id: LexicalScopeId,
44 pub lexical_scopes_spans: HashMap<Span, LexicalScopeId>,
46 name: Ident,
49 visibility: Visibility,
51 span: Option<Span>,
53 mod_path: ModulePathBuf,
59}
60
61impl Module {
62 pub(super) fn new(
63 name: Ident,
64 visibility: Visibility,
65 span: Option<Span>,
66 parent_mod_path: &ModulePathBuf,
67 ) -> Self {
68 let mut mod_path = parent_mod_path.clone();
69 mod_path.push(name.clone());
70 Self {
71 visibility,
72 submodules: Default::default(),
73 lexical_scopes: vec![LexicalScope::default()],
74 lexical_scopes_spans: Default::default(),
75 current_lexical_scope_id: 0,
76 name,
77 span,
78 mod_path,
79 }
80 }
81
82 pub fn name(&self) -> &Ident {
83 &self.name
84 }
85
86 pub fn visibility(&self) -> &Visibility {
87 &self.visibility
88 }
89
90 pub fn span(&self) -> &Option<Span> {
91 &self.span
92 }
93
94 pub fn set_span(&mut self, span: Span) {
95 self.span = Some(span);
96 }
97
98 pub(super) fn add_new_submodule(
99 &mut self,
100 name: &Ident,
101 visibility: Visibility,
102 span: Option<Span>,
103 ) {
104 let module = Self::new(name.clone(), visibility, span, &self.mod_path);
105 self.submodules.insert(name.to_string(), module);
106 }
107
108 pub fn read<R>(&self, _engines: &crate::Engines, mut f: impl FnMut(&Module) -> R) -> R {
109 f(self)
110 }
111
112 pub fn write<R>(
113 &mut self,
114 _engines: &crate::Engines,
115 mut f: impl FnMut(&mut Module) -> R,
116 ) -> R {
117 f(self)
118 }
119
120 pub fn mod_path(&self) -> &ModulePath {
121 self.mod_path.as_slice()
122 }
123
124 pub fn mod_path_buf(&self) -> ModulePathBuf {
125 self.mod_path.clone()
126 }
127
128 pub fn submodules(&self) -> &im::HashMap<ModuleName, Module, BuildHasherDefault<FxHasher>> {
130 &self.submodules
131 }
132
133 pub fn has_submodule(&self, name: &Ident) -> bool {
134 self.submodule(&[name.clone()]).is_some()
135 }
136
137 pub fn submodules_mut(
139 &mut self,
140 ) -> &mut im::HashMap<ModuleName, Module, BuildHasherDefault<FxHasher>> {
141 &mut self.submodules
142 }
143
144 pub fn submodule(&self, path: &ModulePath) -> Option<&Module> {
146 let mut module = self;
147 for ident in path.iter() {
148 match module.submodules.get(ident.as_str()) {
149 Some(ns) => module = ns,
150 None => return None,
151 }
152 }
153 Some(module)
154 }
155
156 pub fn submodule_mut(&mut self, path: &ModulePath) -> Option<&mut Module> {
158 let mut module = self;
159 for ident in path.iter() {
160 match module.submodules.get_mut(ident.as_str()) {
161 Some(ns) => module = ns,
162 None => return None,
163 }
164 }
165 Some(module)
166 }
167
168 pub(crate) fn lookup_submodule(
172 &self,
173 handler: &Handler,
174 path: &[Ident],
175 ) -> Result<&Module, ErrorEmitted> {
176 match self.submodule(path) {
177 None => Err(handler.emit_err(module_not_found(path, true))),
178 Some(module) => Ok(module),
179 }
180 }
181
182 pub fn root_lexical_scope_id(&self) -> LexicalScopeId {
184 0
185 }
186
187 pub fn root_lexical_scope(&self) -> &LexicalScope {
189 self.lexical_scopes
190 .get(self.root_lexical_scope_id())
191 .unwrap()
192 }
193
194 pub fn get_lexical_scope(&self, id: LexicalScopeId) -> Option<&LexicalScope> {
195 self.lexical_scopes.get(id)
196 }
197
198 pub fn get_lexical_scope_mut(&mut self, id: LexicalScopeId) -> Option<&mut LexicalScope> {
199 self.lexical_scopes.get_mut(id)
200 }
201
202 pub fn current_lexical_scope(&self) -> &LexicalScope {
204 self.lexical_scopes
205 .get(self.current_lexical_scope_id)
206 .unwrap()
207 }
208
209 pub fn current_lexical_scope_mut(&mut self) -> &mut LexicalScope {
211 self.lexical_scopes
212 .get_mut(self.current_lexical_scope_id)
213 .unwrap()
214 }
215
216 pub fn current_items(&self) -> &Items {
218 &self.current_lexical_scope().items
219 }
220
221 pub fn root_items(&self) -> &Items {
223 &self.root_lexical_scope().items
224 }
225
226 pub fn current_items_mut(&mut self) -> &mut Items {
228 &mut self.current_lexical_scope_mut().items
229 }
230
231 pub fn current_lexical_scope_id(&self) -> LexicalScopeId {
232 self.current_lexical_scope_id
233 }
234
235 pub fn enter_lexical_scope(
237 &mut self,
238 handler: &Handler,
239 span: Span,
240 ) -> Result<LexicalScopeId, ErrorEmitted> {
241 let id_opt = self.lexical_scopes_spans.get(&span);
242 match id_opt {
243 Some(id) => {
244 let visitor_parent = self.current_lexical_scope_id;
245 self.current_lexical_scope_id = *id;
246 self.current_lexical_scope_mut().visitor_parent = Some(visitor_parent);
247
248 Ok(self.current_lexical_scope_id)
249 }
250 None => Err(handler.emit_err(CompileError::Internal(
251 "Could not find a valid lexical scope for this source location.",
252 span.clone(),
253 ))),
254 }
255 }
256
257 pub fn push_new_lexical_scope(
259 &mut self,
260 span: Span,
261 declaration: Option<ResolvedDeclaration>,
262 ) -> LexicalScopeId {
263 let previous_scope_id = self.current_lexical_scope_id();
264 let previous_scope = self.lexical_scopes.get(previous_scope_id).unwrap();
265 let new_scoped_id = {
266 self.lexical_scopes.push(LexicalScope {
267 parent: Some(previous_scope_id),
268 visitor_parent: Some(previous_scope_id),
269 items: Items {
270 symbols_unique_while_collecting_unifications: previous_scope
271 .items
272 .symbols_unique_while_collecting_unifications
273 .clone(),
274 ..Default::default()
275 },
276 declaration,
277 ..Default::default()
278 });
279 self.lexical_scopes.len() - 1
280 };
281 let previous_scope = self.lexical_scopes.get_mut(previous_scope_id).unwrap();
282 previous_scope.children.push(new_scoped_id);
283 self.current_lexical_scope_id = new_scoped_id;
284 self.lexical_scopes_spans.insert(span, new_scoped_id);
285 new_scoped_id
286 }
287
288 pub fn pop_lexical_scope(&mut self) {
290 let parent_scope_id = self.current_lexical_scope().visitor_parent;
291 self.current_lexical_scope_id = parent_scope_id.unwrap(); }
293
294 pub fn walk_scope_chain_early_return<T>(
295 &self,
296 mut f: impl FnMut(&LexicalScope) -> Result<Option<T>, ErrorEmitted>,
297 ) -> Result<Option<T>, ErrorEmitted> {
298 let mut lexical_scope_opt = Some(self.current_lexical_scope());
299 while let Some(lexical_scope) = lexical_scope_opt {
300 let result = f(lexical_scope)?;
301 if let Some(result) = result {
302 return Ok(Some(result));
303 }
304 if let Some(parent_scope_id) = lexical_scope.parent {
305 lexical_scope_opt = self.get_lexical_scope(parent_scope_id);
306 } else {
307 lexical_scope_opt = None;
308 }
309 }
310 Ok(None)
311 }
312
313 pub fn walk_scope_chain(&self, mut f: impl FnMut(&LexicalScope)) {
314 let mut lexical_scope_opt = Some(self.current_lexical_scope());
315 while let Some(lexical_scope) = lexical_scope_opt {
316 f(lexical_scope);
317 if let Some(parent_scope_id) = lexical_scope.parent {
318 lexical_scope_opt = self.get_lexical_scope(parent_scope_id);
319 } else {
320 lexical_scope_opt = None;
321 }
322 }
323 }
324
325 pub fn get_items_for_type(
326 &self,
327 engines: &Engines,
328 type_id: TypeId,
329 ) -> Vec<ResolvedTraitImplItem> {
330 TraitMap::get_items_for_type(self, engines, type_id)
331 }
332
333 pub fn resolve_symbol(
334 &self,
335 handler: &Handler,
336 engines: &Engines,
337 symbol: &Ident,
338 ) -> Result<(ResolvedDeclaration, ModulePathBuf), ErrorEmitted> {
339 let mut last_handler = Handler::default();
340 let ret = self.walk_scope_chain_early_return(|lexical_scope| {
341 last_handler = Handler::default();
342 Ok(lexical_scope
343 .items
344 .resolve_symbol(&last_handler, engines, symbol, &self.mod_path)
345 .ok()
346 .flatten())
347 })?;
348
349 handler.append(last_handler);
350
351 if let Some(ret) = ret {
352 Ok(ret)
353 } else {
354 Err(handler.emit_err(CompileError::SymbolNotFound {
356 name: symbol.clone(),
357 span: symbol.span(),
358 }))
359 }
360 }
361
362 pub fn get_methods_for_type(
363 &self,
364 engines: &Engines,
365 type_id: TypeId,
366 ) -> Vec<ResolvedFunctionDecl> {
367 self.get_items_for_type(engines, type_id)
368 .into_iter()
369 .filter_map(|item| match item {
370 ResolvedTraitImplItem::Parsed(_) => unreachable!(),
371 ResolvedTraitImplItem::Typed(item) => match item {
372 ty::TyTraitItem::Fn(decl_ref) => Some(ResolvedFunctionDecl::Typed(decl_ref)),
373 ty::TyTraitItem::Constant(_decl_ref) => None,
374 ty::TyTraitItem::Type(_decl_ref) => None,
375 },
376 })
377 .collect::<Vec<_>>()
378 }
379}
380
381pub fn module_not_found(path: &[Ident], skip_package_name: bool) -> CompileError {
386 CompileError::ModuleNotFound {
387 span: path
388 .iter()
389 .skip(if skip_package_name { 1 } else { 0 })
390 .fold(path.last().unwrap().span(), |acc, this_one| {
391 if acc.source_id() == this_one.span().source_id() {
392 Span::join(acc, &this_one.span())
393 } else {
394 acc
395 }
396 }),
397 name: path
398 .iter()
399 .skip(if skip_package_name { 1 } else { 0 })
400 .map(|x| x.as_str())
401 .collect::<Vec<_>>()
402 .join("::"),
403 }
404}