Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make module name mandatory and private #6271

Merged
merged 9 commits into from
Jul 19, 2024
24 changes: 13 additions & 11 deletions forc-pkg/src/pkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1602,15 +1602,17 @@ pub fn dependency_namespace(
let node_idx = &graph[node];
let name = Ident::new_no_span(node_idx.name.clone());
let mut root_module = if let Some(contract_id_value) = contract_id_value {
namespace::default_with_contract_id(engines, name.clone(), contract_id_value, experimental)?
namespace::default_with_contract_id(
engines,
name.clone(),
Visibility::Public,
contract_id_value,
experimental,
)?
} else {
namespace::Module::new(name)
namespace::Module::new(name, Visibility::Public, None)
};

root_module.write(engines, |root_module| {
root_module.visibility = Visibility::Public;
});

// Add direct dependencies.
let mut core_added = false;
for edge in graph.edges_directed(node, Direction::Outgoing) {
Expand All @@ -1633,14 +1635,13 @@ pub fn dependency_namespace(
let contract_id_value = format!("0x{dep_contract_id}");
let node_idx = &graph[dep_node];
let name = Ident::new_no_span(node_idx.name.clone());
let mut module = namespace::default_with_contract_id(
namespace::default_with_contract_id(
engines,
name.clone(),
Visibility::Private,
contract_id_value,
experimental,
)?;
module.visibility = Visibility::Public;
module
)?
}
};
dep_namespace.is_external = true;
Expand Down Expand Up @@ -2732,7 +2733,8 @@ pub fn check(
.program_id(engines)
.read(engines, |m| m.clone());
// module.name = Some(Ident::new_no_span(pkg.name.clone()));
module.span = Some(
// module.span = Some(
jjcnn marked this conversation as resolved.
Show resolved Hide resolved
module.set_span(
Span::new(
manifest.entry_string()?,
0,
Expand Down
28 changes: 18 additions & 10 deletions sway-core/src/semantic_analysis/namespace/contract_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,33 @@ use super::{lexical_scope::SymbolMap, root::ResolvedDeclaration, Module, Root};
pub fn default_with_contract_id(
engines: &Engines,
name: Ident,
visibility: Visibility,
contract_id_value: String,
experimental: crate::ExperimentalFlags,
) -> Result<Module, vec1::Vec1<CompileError>> {
let handler = <_>::default();
default_with_contract_id_inner(&handler, engines, name, contract_id_value, experimental)
.map_err(|_| {
let (errors, warnings) = handler.consume();
assert!(warnings.is_empty());
default_with_contract_id_inner(
&handler,
engines,
name,
visibility,
contract_id_value,
experimental,
)
.map_err(|_| {
let (errors, warnings) = handler.consume();
assert!(warnings.is_empty());

// Invariant: `.value == None` => `!errors.is_empty()`.
vec1::Vec1::try_from_vec(errors).unwrap()
})
// Invariant: `.value == None` => `!errors.is_empty()`.
vec1::Vec1::try_from_vec(errors).unwrap()
})
}

fn default_with_contract_id_inner(
handler: &Handler,
engines: &Engines,
ns_name: Ident,
visibility: Visibility,
contract_id_value: String,
experimental: crate::ExperimentalFlags,
) -> Result<Module, ErrorEmitted> {
Expand Down Expand Up @@ -95,10 +104,9 @@ fn default_with_contract_id_inner(
content: AstNodeContent::Declaration(Declaration::ConstantDeclaration(const_decl_id)),
span: const_item_span.clone(),
};
let mut root = Root::from(Module::new(ns_name.clone()));
let mut root = Root::from(Module::new(ns_name.clone(), Visibility::Public, None));
let mut ns = Namespace::init_root(&mut root);
// This is pretty hacky but that's okay because of this code is being removed pretty soon
ns.root.module.visibility = Visibility::Public;
let type_check_ctx = TypeCheckContext::from_namespace(&mut ns, engines, experimental);
let typed_node = TyAstNode::type_check(handler, type_check_ctx, &ast_node).unwrap();
// get the decl out of the typed node:
Expand All @@ -117,7 +125,7 @@ fn default_with_contract_id_inner(
};
compiled_constants.insert(name, ResolvedDeclaration::Typed(typed_decl));

let mut ret = Module::new(ns_name);
let mut ret = Module::new(ns_name, visibility, None);
ret.current_lexical_scope_mut().items.symbols = compiled_constants;
Ok(ret)
}
46 changes: 33 additions & 13 deletions sway-core/src/semantic_analysis/namespace/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ pub struct Module {
/// Module name used is the same as declared in `mod name;`.
name: Ident,
/// Whether or not this is a `pub` module
pub visibility: Visibility,
visibility: Visibility,
/// Empty span at the beginning of the file implementing the module
pub span: Option<Span>,
span: Option<Span>,
/// Indicates whether the module is external to the current package. External modules are
/// imported in the `Forc.toml` file.
pub is_external: bool,
Expand All @@ -52,36 +52,56 @@ pub struct Module {
}

impl Module {
pub fn new(name: Ident) -> Self {
pub fn new(name: Ident, visibility: Visibility, span: Option<Span>) -> Self {
Self {
visibility: Visibility::Private,
visibility,
submodules: Default::default(),
lexical_scopes: vec![LexicalScope::default()],
current_lexical_scope_id: 0,
name,
span: Default::default(),
span,
is_external: Default::default(),
mod_path: Default::default(),
}
}

pub fn name(&self) -> &Ident {
&self.name
}

pub(super) fn clone_with_new_name(&self, name: Ident, mod_path: ModulePathBuf) -> Self {
// Specialized constructor for cloning Namespace::init. Should not be used for anything else
pub(super) fn new_submodule_from_init(
&self,
name: Ident,
visibility: Visibility,
span: Option<Span>,
is_external: bool,
mod_path: ModulePathBuf,
) -> Self {
Self {
visibility: self.visibility,
visibility,
submodules: self.submodules.clone(),
lexical_scopes: self.lexical_scopes.clone(),
current_lexical_scope_id: self.current_lexical_scope_id,
name,
span: self.span.clone(),
is_external: self.is_external,
span,
is_external,
mod_path,
}
}

pub fn name(&self) -> &Ident {
&self.name
}

pub fn visibility(&self) -> &Visibility {
&self.visibility
}

pub fn span(&self) -> &Option<Span> {
&self.span
}

pub fn set_span(&mut self, span: Span) {
self.span = Some(span);
}

pub fn read<R>(&self, _engines: &crate::Engines, mut f: impl FnMut(&Module) -> R) -> R {
f(self)
}
Expand Down
19 changes: 8 additions & 11 deletions sway-core/src/semantic_analysis/namespace/namespace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,13 +295,14 @@ impl Namespace {
self.module_mut(engines)
.submodules
.entry(mod_name.to_string())
.or_insert(init.clone_with_new_name(mod_name, submod_path.clone()));
.or_insert(init.new_submodule_from_init(
mod_name,
visibility,
Some(module_span),
is_external,
submod_path.clone(),
));
let parent_mod_path = std::mem::replace(&mut self.mod_path, submod_path.clone());
// self.module() now refers to a different module, so refetch
let new_module = self.module_mut(engines);
new_module.span = Some(module_span);
new_module.visibility = visibility;
new_module.is_external = is_external;
SubmoduleNamespace {
namespace: self,
parent_mod_path,
Expand All @@ -316,14 +317,10 @@ impl Namespace {
visibility: Visibility,
module_span: Span,
) {
let mut module = Module::new(mod_name.clone());
module.visibility = visibility;
module.span = Some(module_span);

self.module_mut(engines)
.submodules
.entry(mod_name.to_string())
.or_insert(module);
.or_insert(Module::new(mod_name.clone(), visibility, Some(module_span)));
self.mod_path.push(mod_name);
}

Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/semantic_analysis/namespace/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ impl Root {
// we don't check the first prefix because direct children are always accessible
for prefix in iter_prefixes(src).skip(1) {
let module = self.module.lookup_submodule(handler, engines, prefix)?;
if module.visibility.is_private() {
if module.visibility().is_private() {
let prefix_last = prefix[prefix.len() - 1].clone();
handler.emit_err(CompileError::ImportPrivateModule {
span: prefix_last.span(),
Expand Down
2 changes: 1 addition & 1 deletion sway-core/src/semantic_analysis/type_check_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ impl<'a> TypeCheckContext<'a> {
let module = self
.namespace()
.lookup_submodule_from_absolute_path(handler, engines, prefix)?;
if module.visibility.is_private() {
if module.visibility().is_private() {
let prefix_last = prefix[prefix.len() - 1].clone();
handler.emit_err(CompileError::ImportPrivateModule {
span: prefix_last.span(),
Expand Down
8 changes: 4 additions & 4 deletions sway-lsp/src/traverse/typed_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ impl Parse for ty::TySideEffect {
if let Some(span) = ctx
.namespace
.submodule(ctx.engines, mod_path)
.and_then(|tgt_submod| tgt_submod.span.clone())
.and_then(|tgt_submod| tgt_submod.span().clone())
{
token.type_def = Some(TypeDefinition::Ident(Ident::new(span)));
}
Expand Down Expand Up @@ -169,7 +169,7 @@ impl Parse for ty::TySideEffect {
if let Some(span) = ctx
.namespace
.submodule(ctx.engines, call_path)
.and_then(|tgt_submod| tgt_submod.span.clone())
.and_then(|tgt_submod| tgt_submod.span().clone())
{
token.type_def = Some(TypeDefinition::Ident(Ident::new(span)));
}
Expand All @@ -192,7 +192,7 @@ impl Parse for ty::TySideEffect {
if let Some(span) = ctx
.namespace
.submodule(ctx.engines, &[mod_name.clone()])
.and_then(|tgt_submod| tgt_submod.span.clone())
.and_then(|tgt_submod| tgt_submod.span().clone())
{
token.type_def = Some(TypeDefinition::Ident(Ident::new(span)));
}
Expand Down Expand Up @@ -1209,7 +1209,7 @@ fn collect_call_path_prefixes(ctx: &ParseContext, prefixes: &[Ident]) {
if let Some(span) = ctx
.namespace
.submodule(ctx.engines, mod_path)
.and_then(|tgt_submod| tgt_submod.span.clone())
.and_then(|tgt_submod| tgt_submod.span().clone())
{
token.kind = SymbolKind::Module;
token.type_def = Some(TypeDefinition::Ident(Ident::new(span)));
Expand Down
12 changes: 8 additions & 4 deletions test/src/ir_generation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use std::{
use anyhow::Result;
use colored::Colorize;
use sway_core::{
compile_ir_context_to_finalized_asm, compile_to_ast, ir_generation::compile_program, namespace,
BuildTarget, Engines,
compile_ir_context_to_finalized_asm, compile_to_ast, ir_generation::compile_program,
language::Visibility, namespace, BuildTarget, Engines,
};
use sway_error::handler::Handler;

Expand Down Expand Up @@ -564,15 +564,19 @@ fn compile_core(
.submodules()
.into_iter()
.fold(
namespace::Module::new(sway_types::Ident::new_no_span("core".to_string())),
namespace::Module::new(
sway_types::Ident::new_no_span("core".to_string()),
Visibility::Private,
None,
),
|mut core_mod, (name, sub_mod)| {
core_mod.insert_submodule(name.clone(), sub_mod.clone());
core_mod
},
);

// Create a module for std and insert the core module.
let mut std_module = namespace::Module::new(lib_name);
let mut std_module = namespace::Module::new(lib_name, Visibility::Private, None);
std_module.insert_submodule("core".to_owned(), core_module);
std_module
}
Expand Down
Loading