harn_modules/
visibility.rs1use std::path::Path;
4
5use crate::{normalize_path, DefKind, ModuleGraph};
6
7pub fn sibling_module_access(importer: &Path, target: &Path) -> bool {
9 normalize_path(importer)
10 .parent()
11 .is_some_and(|directory| sibling_directory_access(directory, target))
12}
13
14pub fn sibling_directory_access(importer_directory: &Path, target: &Path) -> bool {
16 normalize_path(target)
17 .parent()
18 .is_some_and(|directory| normalize_path(importer_directory) == directory)
19}
20
21impl ModuleGraph {
22 pub fn exports_for_module(&self, file: &Path) -> Vec<String> {
24 let file = normalize_path(file);
25 let Some(module) = self.modules.get(&file) else {
26 return Vec::new();
27 };
28 let mut exports: Vec<String> = module.exports.iter().cloned().collect();
29 exports.sort();
30 exports
31 }
32
33 pub fn exports_for_import(&self, importer: &Path, target: &Path) -> Vec<String> {
36 let importer = normalize_path(importer);
37 let target = normalize_path(target);
38 let Some(module) = self.modules.get(&target) else {
39 return Vec::new();
40 };
41 let mut names = module.exports.clone();
42 if sibling_module_access(&importer, &target) {
43 names.extend(module.sibling_exports.iter().cloned());
44 }
45 let mut names: Vec<_> = names.into_iter().collect();
46 names.sort();
47 names
48 }
49
50 pub(crate) fn exported_kind_for_import(
51 &self,
52 importer: &Path,
53 target: &Path,
54 name: &str,
55 ) -> Option<DefKind> {
56 self.exported_kind_for_resolved_import(
57 sibling_module_access(importer, target),
58 &normalize_path(target),
59 name,
60 )
61 }
62
63 pub(crate) fn exported_kind_for_resolved_import(
66 &self,
67 sibling: bool,
68 target: &Path,
69 name: &str,
70 ) -> Option<DefKind> {
71 if sibling {
72 if let Some(module) = self.modules.get(target) {
73 if module.sibling_exports.contains(name) {
74 return module
75 .declarations
76 .get(name)
77 .map(|declaration| declaration.kind);
78 }
79 }
80 }
81 self.exported_kind(target, name)
82 }
83}