midenc_hir/ir/symbols/
symbol_use.rs1use alloc::collections::VecDeque;
2use core::fmt;
3
4use super::SymbolPathAttr;
5use crate::{Entity, EntityListItem, EntityRef, OperationRef, UnsafeIntrusiveEntityRef};
6
7pub type SymbolUseRef = UnsafeIntrusiveEntityRef<SymbolUse>;
8pub type SymbolUseList = crate::EntityList<SymbolUse>;
9pub type SymbolUseIter<'a> = crate::EntityIter<'a, SymbolUse>;
10pub type SymbolUseCursor<'a> = crate::EntityCursor<'a, SymbolUse>;
11pub type SymbolUseCursorMut<'a> = crate::EntityCursorMut<'a, SymbolUse>;
12
13#[derive(Copy, Clone)]
15pub struct SymbolUse {
16    pub owner: OperationRef,
18    pub attr: crate::interner::Symbol,
20}
21impl SymbolUse {
22    #[inline]
23    pub fn new(owner: OperationRef, symbol: crate::interner::Symbol) -> Self {
24        Self {
25            owner,
26            attr: symbol,
27        }
28    }
29
30    pub fn symbol(&self) -> EntityRef<'_, SymbolPathAttr> {
31        EntityRef::map(self.owner.borrow(), |owner| {
32            owner.get_typed_attribute::<SymbolPathAttr>(self.attr).expect("expected symbol")
33        })
34    }
35}
36impl fmt::Debug for SymbolUse {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        let op = self.owner.borrow();
39        let value = op.get_typed_attribute::<SymbolPathAttr>(self.attr);
40        f.debug_struct("SymbolUse")
41            .field("attr", &self.attr)
42            .field("symbol", &value.as_ref().map(|value| &value.path))
43            .finish_non_exhaustive()
44    }
45}
46
47impl Entity for SymbolUse {}
48impl EntityListItem for SymbolUse {}
49
50pub struct SymbolUsesIter {
55    items: VecDeque<SymbolUse>,
56}
57impl SymbolUsesIter {
58    #[inline]
59    pub fn is_empty(&self) -> bool {
60        self.items.is_empty()
61    }
62}
63impl ExactSizeIterator for SymbolUsesIter {
64    #[inline(always)]
65    fn len(&self) -> usize {
66        self.items.len()
67    }
68}
69impl From<VecDeque<SymbolUse>> for SymbolUsesIter {
70    fn from(items: VecDeque<SymbolUse>) -> Self {
71        Self { items }
72    }
73}
74impl FromIterator<SymbolUseRef> for SymbolUsesIter {
75    fn from_iter<T: IntoIterator<Item = SymbolUseRef>>(iter: T) -> Self {
76        Self {
77            items: iter.into_iter().map(|user| *user.borrow()).collect(),
78        }
79    }
80}
81impl core::iter::FusedIterator for SymbolUsesIter {}
82impl Iterator for SymbolUsesIter {
83    type Item = SymbolUse;
84
85    #[inline]
86    fn next(&mut self) -> Option<Self::Item> {
87        self.items.pop_front()
88    }
89}
90
91pub struct SymbolUseRefsIter {
96    items: VecDeque<SymbolUseRef>,
97}
98impl SymbolUseRefsIter {
99    #[inline]
100    pub fn is_empty(&self) -> bool {
101        self.items.is_empty()
102    }
103}
104impl ExactSizeIterator for SymbolUseRefsIter {
105    #[inline(always)]
106    fn len(&self) -> usize {
107        self.items.len()
108    }
109}
110impl From<VecDeque<SymbolUseRef>> for SymbolUseRefsIter {
111    fn from(items: VecDeque<SymbolUseRef>) -> Self {
112        Self { items }
113    }
114}
115impl FromIterator<SymbolUseRef> for SymbolUseRefsIter {
116    fn from_iter<T: IntoIterator<Item = SymbolUseRef>>(iter: T) -> Self {
117        Self {
118            items: iter.into_iter().collect(),
119        }
120    }
121}
122impl core::iter::FusedIterator for SymbolUseRefsIter {}
123impl Iterator for SymbolUseRefsIter {
124    type Item = SymbolUseRef;
125
126    #[inline]
127    fn next(&mut self) -> Option<Self::Item> {
128        self.items.pop_front()
129    }
130}