1use ahash::HashMap;
2use ahash::HashSet;
3use serde::Deserialize;
4use serde::Serialize;
5
6use mago_database::file::FileId;
7
8use crate::symbol::SymbolIdentifier;
9
10#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
16pub struct CodebaseDiff {
17 keep: HashSet<SymbolIdentifier>,
20
21 keep_signature: HashSet<SymbolIdentifier>,
25
26 add_or_delete: HashSet<SymbolIdentifier>,
29
30 diff_map: HashMap<FileId, Vec<(usize, usize, isize, isize)>>,
34
35 deletion_ranges_map: HashMap<FileId, Vec<(usize, usize)>>,
37}
38
39impl CodebaseDiff {
40 #[inline]
41 pub fn new() -> Self {
42 Self::default()
43 }
44
45 #[inline]
47 pub fn extend(&mut self, other: Self) {
48 self.keep.extend(other.keep);
49 self.keep_signature.extend(other.keep_signature);
50 self.add_or_delete.extend(other.add_or_delete);
51 for (source, diffs) in other.diff_map {
52 self.diff_map.entry(source).or_default().extend(diffs);
53 }
54 for (source, ranges) in other.deletion_ranges_map {
55 self.deletion_ranges_map.entry(source).or_default().extend(ranges);
56 }
57 }
58
59 #[inline]
61 pub fn get_keep(&self) -> &HashSet<SymbolIdentifier> {
62 &self.keep
63 }
64
65 #[inline]
67 pub fn get_keep_signature(&self) -> &HashSet<SymbolIdentifier> {
68 &self.keep_signature
69 }
70
71 #[inline]
73 pub fn get_add_or_delete(&self) -> &HashSet<SymbolIdentifier> {
74 &self.add_or_delete
75 }
76
77 #[inline]
79 pub fn get_diff_map(&self) -> &HashMap<FileId, Vec<(usize, usize, isize, isize)>> {
80 &self.diff_map
81 }
82
83 #[inline]
85 pub fn get_deletion_ranges_map(&self) -> &HashMap<FileId, Vec<(usize, usize)>> {
86 &self.deletion_ranges_map
87 }
88
89 #[inline]
91 pub fn set_keep(&mut self, keep_set: impl IntoIterator<Item = SymbolIdentifier>) {
92 self.keep = keep_set.into_iter().collect();
93 }
94
95 #[inline]
97 pub fn with_keep(mut self, keep_set: impl IntoIterator<Item = SymbolIdentifier>) -> Self {
98 self.set_keep(keep_set);
99 self
100 }
101
102 #[inline]
104 pub fn add_keep_entry(&mut self, entry: SymbolIdentifier) -> bool {
105 self.keep.insert(entry)
106 }
107
108 #[inline]
110 pub fn with_added_keep_entry(mut self, entry: SymbolIdentifier) -> Self {
111 self.add_keep_entry(entry);
112 self
113 }
114
115 #[inline]
117 pub fn add_keep_entries(&mut self, entries: impl IntoIterator<Item = SymbolIdentifier>) {
118 self.keep.extend(entries);
119 }
120
121 #[inline]
123 pub fn with_added_keep_entries(mut self, entries: impl IntoIterator<Item = SymbolIdentifier>) -> Self {
124 self.add_keep_entries(entries);
125 self
126 }
127
128 #[inline]
130 pub fn unset_keep(&mut self) {
131 self.keep.clear();
132 }
133
134 #[inline]
136 pub fn without_keep(mut self) -> Self {
137 self.unset_keep();
138 self
139 }
140
141 #[inline]
143 pub fn set_keep_signature(&mut self, keep_set: impl IntoIterator<Item = SymbolIdentifier>) {
144 self.keep_signature = keep_set.into_iter().collect();
145 }
146
147 #[inline]
149 pub fn with_keep_signature(mut self, keep_set: impl IntoIterator<Item = SymbolIdentifier>) -> Self {
150 self.set_keep_signature(keep_set);
151 self
152 }
153
154 #[inline]
156 pub fn add_keep_signature_entry(&mut self, entry: SymbolIdentifier) -> bool {
157 self.keep_signature.insert(entry)
158 }
159
160 #[inline]
162 pub fn with_added_keep_signature_entry(mut self, entry: SymbolIdentifier) -> Self {
163 self.add_keep_signature_entry(entry);
164 self
165 }
166
167 #[inline]
169 pub fn add_keep_signature_entries(&mut self, entries: impl IntoIterator<Item = SymbolIdentifier>) {
170 self.keep_signature.extend(entries);
171 }
172
173 #[inline]
175 pub fn with_added_keep_signature_entries(mut self, entries: impl IntoIterator<Item = SymbolIdentifier>) -> Self {
176 self.add_keep_signature_entries(entries);
177 self
178 }
179
180 #[inline]
182 pub fn unset_keep_signature(&mut self) {
183 self.keep_signature.clear();
184 }
185
186 #[inline]
188 pub fn without_keep_signature(mut self) -> Self {
189 self.unset_keep_signature();
190 self
191 }
192
193 #[inline]
195 pub fn set_add_or_delete(&mut self, change_set: impl IntoIterator<Item = SymbolIdentifier>) {
196 self.add_or_delete = change_set.into_iter().collect();
197 }
198
199 #[inline]
201 pub fn with_add_or_delete(mut self, change_set: impl IntoIterator<Item = SymbolIdentifier>) -> Self {
202 self.set_add_or_delete(change_set);
203 self
204 }
205
206 #[inline]
208 pub fn add_add_or_delete_entry(&mut self, entry: SymbolIdentifier) -> bool {
209 self.add_or_delete.insert(entry)
210 }
211
212 #[inline]
214 pub fn contains_add_or_delete_entry(&self, entry: &SymbolIdentifier) -> bool {
215 self.add_or_delete.contains(entry)
216 }
217
218 #[inline]
220 pub fn with_added_add_or_delete_entry(mut self, entry: SymbolIdentifier) -> Self {
221 self.add_add_or_delete_entry(entry);
222 self
223 }
224
225 #[inline]
227 pub fn add_add_or_delete_entries(&mut self, entries: impl IntoIterator<Item = SymbolIdentifier>) {
228 self.add_or_delete.extend(entries);
229 }
230
231 #[inline]
233 pub fn with_added_add_or_delete_entries(mut self, entries: impl IntoIterator<Item = SymbolIdentifier>) -> Self {
234 self.add_add_or_delete_entries(entries);
235 self
236 }
237
238 #[inline]
240 pub fn unset_add_or_delete(&mut self) {
241 self.add_or_delete.clear();
242 }
243
244 #[inline]
246 pub fn without_add_or_delete(mut self) -> Self {
247 self.unset_add_or_delete();
248 self
249 }
250
251 #[inline]
253 pub fn set_diff_map(&mut self, map: HashMap<FileId, Vec<(usize, usize, isize, isize)>>) {
254 self.diff_map = map;
255 }
256
257 #[inline]
259 pub fn with_diff_map(mut self, map: HashMap<FileId, Vec<(usize, usize, isize, isize)>>) -> Self {
260 self.set_diff_map(map);
261 self
262 }
263
264 #[inline]
266 pub fn add_diff_map_entry(
267 &mut self,
268 source: FileId,
269 diffs: Vec<(usize, usize, isize, isize)>,
270 ) -> Option<Vec<(usize, usize, isize, isize)>> {
271 self.diff_map.insert(source, diffs)
272 }
273
274 #[inline]
276 pub fn with_added_diff_map_entry(mut self, source: FileId, diffs: Vec<(usize, usize, isize, isize)>) -> Self {
277 self.add_diff_map_entry(source, diffs);
278 self
279 }
280
281 #[inline]
283 pub fn add_diffs_for_source(
284 &mut self,
285 source: FileId,
286 diffs: impl IntoIterator<Item = (usize, usize, isize, isize)>,
287 ) {
288 self.diff_map.entry(source).or_default().extend(diffs);
289 }
290
291 #[inline]
293 pub fn with_added_diffs_for_source(
294 mut self,
295 source: FileId,
296 diffs: impl IntoIterator<Item = (usize, usize, isize, isize)>,
297 ) -> Self {
298 self.add_diffs_for_source(source, diffs);
299 self
300 }
301
302 #[inline]
304 pub fn unset_diff_map(&mut self) {
305 self.diff_map.clear();
306 }
307
308 #[inline]
310 pub fn without_diff_map(mut self) -> Self {
311 self.unset_diff_map();
312 self
313 }
314
315 #[inline]
317 pub fn set_deletion_ranges_map(&mut self, map: HashMap<FileId, Vec<(usize, usize)>>) {
318 self.deletion_ranges_map = map;
319 }
320
321 #[inline]
323 pub fn with_deletion_ranges_map(mut self, map: HashMap<FileId, Vec<(usize, usize)>>) -> Self {
324 self.set_deletion_ranges_map(map);
325 self
326 }
327
328 #[inline]
330 pub fn add_deletion_ranges_entry(
331 &mut self,
332 source: FileId,
333 ranges: Vec<(usize, usize)>,
334 ) -> Option<Vec<(usize, usize)>> {
335 self.deletion_ranges_map.insert(source, ranges)
336 }
337
338 #[inline]
340 pub fn with_added_deletion_ranges_entry(mut self, file: FileId, ranges: Vec<(usize, usize)>) -> Self {
341 self.add_deletion_ranges_entry(file, ranges);
342 self
343 }
344
345 #[inline]
347 pub fn add_deletion_ranges_for_source(&mut self, file: FileId, ranges: impl IntoIterator<Item = (usize, usize)>) {
348 self.deletion_ranges_map.entry(file).or_default().extend(ranges);
349 }
350
351 #[inline]
353 pub fn with_added_deletion_ranges_for_source(
354 mut self,
355 file: FileId,
356 ranges: impl IntoIterator<Item = (usize, usize)>,
357 ) -> Self {
358 self.add_deletion_ranges_for_source(file, ranges);
359 self
360 }
361
362 #[inline]
364 pub fn unset_deletion_ranges_map(&mut self) {
365 self.deletion_ranges_map.clear();
366 }
367
368 #[inline]
370 pub fn without_deletion_ranges_map(mut self) -> Self {
371 self.unset_deletion_ranges_map();
372 self
373 }
374}