sway_core/semantic_analysis/
symbol_collection_context.rsuse crate::{
language::{parsed::Declaration, Visibility},
namespace::{LexicalScopeId, ModulePath, ResolvedDeclaration},
semantic_analysis::Namespace,
Engines,
};
use sway_error::handler::{ErrorEmitted, Handler};
use sway_types::{span::Span, Ident};
use super::{namespace::Items, ConstShadowingMode, GenericShadowingMode};
#[derive(Clone)]
pub struct SymbolCollectionContext {
pub(crate) namespace: Namespace,
const_shadowing_mode: ConstShadowingMode,
generic_shadowing_mode: GenericShadowingMode,
}
impl SymbolCollectionContext {
pub fn new(namespace: Namespace) -> Self {
Self {
namespace,
const_shadowing_mode: ConstShadowingMode::ItemStyle,
generic_shadowing_mode: GenericShadowingMode::Disallow,
}
}
pub fn scoped<T>(
&mut self,
engines: &Engines,
span: Span,
decl: Option<Declaration>,
with_scoped_ctx: impl FnOnce(&mut SymbolCollectionContext) -> Result<T, ErrorEmitted>,
) -> (Result<T, ErrorEmitted>, LexicalScopeId) {
let decl = decl.map(ResolvedDeclaration::Parsed);
let lexical_scope_id: LexicalScopeId =
self.namespace.current_module_mut().write(engines, |m| {
m.push_new_lexical_scope(span.clone(), decl.clone())
});
let ret = with_scoped_ctx(self);
self.namespace
.current_module_mut()
.write(engines, |m| m.pop_lexical_scope());
(ret, lexical_scope_id)
}
pub fn enter_lexical_scope<T>(
&mut self,
handler: &Handler,
engines: &Engines,
span: Span,
with_ctx: impl FnOnce(&mut SymbolCollectionContext) -> Result<T, ErrorEmitted>,
) -> Result<T, ErrorEmitted> {
self.namespace
.current_module_mut()
.write(engines, |m| m.enter_lexical_scope(handler, span.clone()))?;
let ret = with_ctx(self);
self.namespace
.current_module_mut()
.write(engines, |m| m.pop_lexical_scope());
ret
}
pub fn enter_submodule<T>(
&mut self,
handler: &Handler,
engines: &Engines,
mod_name: Ident,
visibility: Visibility,
module_span: Span,
with_submod_ctx: impl FnOnce(&mut SymbolCollectionContext) -> T,
) -> Result<T, ErrorEmitted> {
self.namespace
.push_submodule(handler, engines, mod_name, visibility, module_span)?;
let ret = with_submod_ctx(self);
self.namespace.pop_submodule();
Ok(ret)
}
pub(crate) fn insert_parsed_symbol(
&mut self,
handler: &Handler,
engines: &Engines,
name: Ident,
item: Declaration,
) -> Result<(), ErrorEmitted> {
self.namespace.current_module_mut().write(engines, |m| {
Items::insert_parsed_symbol(
handler,
engines,
m,
name.clone(),
item.clone(),
self.const_shadowing_mode,
self.generic_shadowing_mode,
)
})
}
pub fn namespace_mut(&mut self) -> &mut Namespace {
&mut self.namespace
}
pub fn namespace(&self) -> &Namespace {
&self.namespace
}
pub(crate) fn star_import(
&mut self,
handler: &Handler,
engines: &Engines,
src: &ModulePath,
visibility: Visibility,
) -> Result<(), ErrorEmitted> {
self.namespace_mut()
.star_import_to_current_module(handler, engines, src, visibility)
}
pub(crate) fn variant_star_import(
&mut self,
handler: &Handler,
engines: &Engines,
src: &ModulePath,
enum_name: &Ident,
visibility: Visibility,
) -> Result<(), ErrorEmitted> {
self.namespace_mut()
.variant_star_import_to_current_module(handler, engines, src, enum_name, visibility)
}
pub(crate) fn self_import(
&mut self,
handler: &Handler,
engines: &Engines,
src: &ModulePath,
alias: Option<Ident>,
visibility: Visibility,
) -> Result<(), ErrorEmitted> {
self.namespace_mut()
.self_import_to_current_module(handler, engines, src, alias, visibility)
}
pub(crate) fn item_import(
&mut self,
handler: &Handler,
engines: &Engines,
src: &ModulePath,
item: &Ident,
alias: Option<Ident>,
visibility: Visibility,
) -> Result<(), ErrorEmitted> {
self.namespace_mut()
.item_import_to_current_module(handler, engines, src, item, alias, visibility)
}
#[allow(clippy::too_many_arguments)]
pub(crate) fn variant_import(
&mut self,
handler: &Handler,
engines: &Engines,
src: &ModulePath,
enum_name: &Ident,
variant_name: &Ident,
alias: Option<Ident>,
visibility: Visibility,
) -> Result<(), ErrorEmitted> {
self.namespace_mut().variant_import_to_current_module(
handler,
engines,
src,
enum_name,
variant_name,
alias,
visibility,
)
}
}