charon_lib/ast/
meta_utils.rs1use crate::meta::*;
3use crate::names::{Disambiguator, Name, PathElem};
4use std::borrow::Cow;
5use std::cmp::Ordering;
6use std::iter::Iterator;
7use std::ops::Range;
8
9fn line_to_start_byte(source: &str, line_nbr: usize) -> usize {
13 let mut cur_byte = 0;
14 for (i, line) in source.split_inclusive('\n').enumerate() {
15 if line_nbr == i + 1 {
16 break;
17 }
18 cur_byte += line.len();
19 }
20 cur_byte
21}
22
23impl Loc {
24 fn dummy() -> Self {
25 Loc { line: 0, col: 0 }
26 }
27
28 fn min(l0: &Loc, l1: &Loc) -> Loc {
29 match l0.line.cmp(&l1.line) {
30 Ordering::Equal => Loc {
31 line: l0.line,
32 col: std::cmp::min(l0.col, l1.col),
33 },
34 Ordering::Less => *l0,
35 Ordering::Greater => *l1,
36 }
37 }
38
39 fn max(l0: &Loc, l1: &Loc) -> Loc {
40 match l0.line.cmp(&l1.line) {
41 Ordering::Equal => Loc {
42 line: l0.line,
43 col: std::cmp::max(l0.col, l1.col),
44 },
45 Ordering::Greater => *l0,
46 Ordering::Less => *l1,
47 }
48 }
49
50 pub fn to_byte(self, source: &str) -> usize {
51 line_to_start_byte(source, self.line) + self.col
52 }
53}
54
55impl SpanData {
56 pub fn dummy() -> Self {
57 SpanData {
58 file_id: FileId::from_raw(0),
59 beg: Loc::dummy(),
60 end: Loc::dummy(),
61 }
62 }
63
64 fn sort_key(&self) -> impl Ord {
66 (self.file_id, self.beg, self.end)
67 }
68
69 pub fn to_byte_range(self, source: &str) -> Range<usize> {
70 self.beg.to_byte(source)..self.end.to_byte(source)
71 }
72}
73
74impl PartialOrd for SpanData {
76 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
77 Some(self.cmp(other))
78 }
79}
80impl Ord for SpanData {
81 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
82 self.sort_key().cmp(&other.sort_key())
83 }
84}
85
86impl Span {
87 pub fn dummy() -> Self {
88 Span {
89 data: SpanData::dummy(),
90 generated_from_span: None,
91 }
92 }
93}
94
95pub fn combine_span(m0: &Span, m1: &Span) -> Span {
98 if m0.data.file_id == m1.data.file_id {
100 let data = SpanData {
101 file_id: m0.data.file_id,
102 beg: Loc::min(&m0.data.beg, &m1.data.beg),
103 end: Loc::max(&m0.data.end, &m1.data.end),
104 };
105
106 Span {
110 data,
111 generated_from_span: None,
112 }
113 } else {
114 *m0
117 }
118}
119
120pub fn combine_span_iter<'a, T: Iterator<Item = &'a Span>>(mut ms: T) -> Span {
122 let mut mc: Span = ms.next().copied().unwrap_or_default();
124 for m in ms {
125 mc = combine_span(&mc, m);
126 }
127
128 mc
129}
130
131impl FileName {
132 pub fn to_string(&self) -> Cow<'_, str> {
133 match self {
134 FileName::Virtual(path_buf) | FileName::Local(path_buf) => path_buf.to_string_lossy(),
135 FileName::NotReal(path) => Cow::Borrowed(path),
136 }
137 }
138}
139
140impl AttrInfo {
141 pub fn dummy_private() -> Self {
142 AttrInfo {
143 public: false,
144 ..Default::default()
145 }
146 }
147
148 pub fn dummy_public() -> Self {
149 AttrInfo {
150 public: true,
151 ..Default::default()
152 }
153 }
154}
155
156impl ItemOpacity {
157 pub fn with_content_visibility(self, contents_are_public: bool) -> Self {
158 use ItemOpacity::*;
159 match self {
160 Invisible => Invisible,
161 Transparent => Transparent,
162 Foreign if contents_are_public => Transparent,
163 Foreign => Opaque,
164 Opaque => Opaque,
165 }
166 }
167
168 pub fn with_private_contents(self) -> Self {
169 self.with_content_visibility(false)
170 }
171}
172
173impl ItemMeta {
174 pub fn renamed_name(&self) -> Name {
175 let mut name = self.name.clone();
176 if let Some(rename) = self.attr_info.rename.clone() {
177 *name.name.last_mut().unwrap() = PathElem::Ident(rename, Disambiguator::new(0));
178 }
179 name
180 }
181}
182
183impl Default for Span {
184 fn default() -> Self {
185 Self::dummy()
186 }
187}