sway_core/semantic_analysis/namespace/
package.rs1use super::{module::Module, Ident, ModuleName};
2use crate::{language::Visibility, namespace::ModulePathBuf};
3use rustc_hash::FxHasher;
4use std::hash::BuildHasherDefault;
5use sway_types::{span::Span, ProgramId};
6
7#[derive(Clone, Debug)]
12pub struct Package {
13 root_module: Module,
15 program_id: ProgramId,
17 is_contract_package: bool,
19 pub external_packages: im::HashMap<ModuleName, Package, BuildHasherDefault<FxHasher>>,
24}
25
26impl Package {
27 pub fn new(
34 package_name: Ident,
35 span: Option<Span>,
36 program_id: ProgramId,
37 is_contract_package: bool,
38 ) -> Self {
39 let module = Module::new(package_name, Visibility::Public, span, &vec![]);
41 Self {
42 root_module: module,
43 program_id,
44 is_contract_package,
45 external_packages: Default::default(),
46 }
47 }
48
49 pub fn add_external(&mut self, package_name: String, external_package: Package) {
53 assert!(!self.external_packages.contains_key(&package_name));
55 self.external_packages
56 .insert(package_name, external_package);
57 }
58
59 pub fn root_module(&self) -> &Module {
60 &self.root_module
61 }
62
63 pub fn root_module_mut(&mut self) -> &mut Module {
64 &mut self.root_module
65 }
66
67 pub fn name(&self) -> &Ident {
68 self.root_module.name()
69 }
70
71 pub fn program_id(&self) -> ProgramId {
72 self.program_id
73 }
74
75 pub(crate) fn check_path_is_in_package(&self, mod_path: &ModulePathBuf) -> bool {
76 !mod_path.is_empty() && mod_path[0] == *self.root_module.name()
77 }
78
79 pub(crate) fn package_relative_path(mod_path: &ModulePathBuf) -> ModulePathBuf {
80 mod_path[1..].to_vec()
81 }
82
83 pub(super) fn is_contract_package(&self) -> bool {
84 self.is_contract_package
85 }
86
87 pub fn module_from_absolute_path(&self, mod_path: &ModulePathBuf) -> Option<&Module> {
89 assert!(!mod_path.is_empty());
90 let package_relative_path = Self::package_relative_path(mod_path);
91 if mod_path[0] == *self.root_module.name() {
92 self.root_module.submodule(&package_relative_path)
93 } else if let Some(external_package) = self.external_packages.get(&mod_path[0].to_string())
94 {
95 external_package
96 .root_module()
97 .submodule(&package_relative_path)
98 } else {
99 None
100 }
101 }
102}