Skip to main content

syn_sem/semantic/tree/
public.rs

1use super::{
2    format::{self, Brief, PrintFilter},
3    inner::PathTree,
4    item::{ItemIndex, PrivItem, PubItem},
5    node::{Node, NodeIndex},
6    private::PrivPathTree,
7    ty::{OwnedType, Type, TypeId, UniqueTypes},
8    PathId,
9};
10use crate::{etc::util::IntoPathSegments, GetOwned};
11use std::fmt;
12
13/// Hides [`PrivPathTree`] from clients.
14pub trait AsPrivPathTree<'gcx> {
15    fn as_private_path_tree(&self) -> &PrivPathTree<'gcx>;
16}
17
18impl<'gcx> AsPrivPathTree<'gcx> for PubPathTree<'gcx> {
19    fn as_private_path_tree(&self) -> &PrivPathTree<'gcx> {
20        &self.inner
21    }
22}
23
24impl<'gcx> AsPrivPathTree<'gcx> for PrivPathTree<'gcx> {
25    fn as_private_path_tree(&self) -> &PrivPathTree<'gcx> {
26        self
27    }
28}
29
30pub struct PubPathTree<'gcx> {
31    pub(crate) inner: PrivPathTree<'gcx>,
32}
33
34impl<'gcx> PubPathTree<'gcx> {
35    pub const ROOT: NodeIndex = PathTree::<PrivItem>::ROOT;
36
37    pub(crate) fn new(tree: PrivPathTree<'gcx>) -> Self {
38        Self { inner: tree }
39    }
40
41    pub fn crate_node(&self) -> NodeIndex {
42        self.inner.crate_node
43    }
44
45    pub fn crate_name(&self) -> String {
46        self.inner.get_name_path(self.crate_node())
47    }
48
49    pub fn types(&self) -> &UniqueTypes<'gcx> {
50        self.inner.types()
51    }
52
53    pub fn get_type(&self, tid: TypeId) -> &Type<'gcx> {
54        self.inner.get_type(tid)
55    }
56
57    pub fn contains_generic_param_in_type(&self, tid: TypeId) -> bool {
58        self.inner.contains_generic_param_in_type(tid)
59    }
60
61    /// Finds the node from the given `base` + `key` ignoring visibility.
62    pub fn search<I>(&self, base: NodeIndex, key: I) -> Option<NodeIndex>
63    where
64        I: IntoPathSegments,
65    {
66        self.inner.norm_search(base, key)
67    }
68
69    /// Finds the visible items from the given `base` + `key`.
70    pub fn traverse<I, F, R>(&self, base: NodeIndex, key: I, mut f: F) -> Option<R>
71    where
72        I: IntoPathSegments,
73        F: FnMut(PathId, PubItem<'_>) -> Option<R>,
74    {
75        self.inner.traverse(base, key, |_vis, pid, item| {
76            let item = PubItem::new(item)?;
77            f(pid, item)
78        })
79    }
80
81    pub fn parent_item<F>(&self, index: NodeIndex, mut filter: F) -> PathId
82    where
83        F: FnMut(PubItem<'_>) -> bool,
84    {
85        self.inner.parent_item(index, |item| {
86            if let Some(item) = PubItem::new(item) {
87                filter(item)
88            } else {
89                false
90            }
91        })
92    }
93
94    pub fn iter(&self) -> impl Iterator<Item = (PathId, PubItem<'_>)> {
95        self.inner
96            .iter()
97            .filter_map(|(pid, item)| PubItem::new(item).map(|item| (pid, item)))
98    }
99
100    pub fn get_name_path(&self, index: NodeIndex) -> String {
101        self.inner.get_name_path(index)
102    }
103
104    pub fn node(&self, index: NodeIndex) -> PubNode<'_> {
105        PubNode {
106            inner: &self.inner[index],
107        }
108    }
109
110    pub fn item(&self, pid: PathId) -> PubItem<'_> {
111        PubItem::new(&self.inner[pid]).unwrap()
112    }
113
114    pub fn debug_brief(&self) -> Brief<'_, Self> {
115        Brief::new(self)
116    }
117}
118
119impl GetOwned<TypeId> for PubPathTree<'_> {
120    type Owned = OwnedType;
121
122    fn get_owned(&self, tid: TypeId) -> Self::Owned {
123        self.inner.get_owned(tid)
124    }
125}
126
127impl Default for PubPathTree<'_> {
128    fn default() -> Self {
129        todo!()
130    }
131}
132
133impl fmt::Debug for PubPathTree<'_> {
134    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135        self.inner.fmt(f)
136    }
137}
138
139impl format::DebugBriefly for PubPathTree<'_> {
140    fn fmt_briefly(&self, f: &mut fmt::Formatter<'_>, filter: &PrintFilter) -> fmt::Result {
141        self.inner.fmt_briefly(f, filter)
142    }
143
144    fn name(&self) -> &'static str {
145        "PubPathTree"
146    }
147}
148
149pub struct PubNode<'a> {
150    inner: &'a Node<PrivItem>,
151}
152
153impl<'a> PubNode<'a> {
154    pub fn iter(&self) -> impl Iterator<Item = (ItemIndex, PubItem<'_>)> + Clone {
155        self.inner
156            .iter()
157            .filter_map(|(index, item)| PubItem::new(item).map(|item| (index, item)))
158    }
159}
160
161pub mod pub_filter {
162    use crate::semantic::tree::{inner::filter, public::PubItem};
163
164    pub fn block(item: PubItem<'_>) -> bool {
165        filter::block(&item)
166    }
167
168    pub fn block_fn(item: PubItem<'_>) -> bool {
169        filter::block_fn(&item)
170    }
171
172    pub fn block_mod(item: PubItem<'_>) -> bool {
173        filter::block_mod(&item)
174    }
175
176    pub fn block_mod_struct(item: PubItem<'_>) -> bool {
177        filter::block_mod_struct(&item)
178    }
179
180    pub fn enum_(item: PubItem<'_>) -> bool {
181        filter::enum_(&item)
182    }
183
184    pub fn mod_(item: PubItem<'_>) -> bool {
185        filter::mod_(&item)
186    }
187
188    pub fn struct_(item: PubItem<'_>) -> bool {
189        filter::struct_(&item)
190    }
191}