1use std::collections::{BTreeMap, HashMap};
2
3use serde::{Deserialize, Serialize};
4use spade_codespan::{ByteIndex, Span};
5
6use crate::location_info::Loc;
7
8#[derive(Debug, Serialize, Deserialize)]
10pub struct LocMap<T> {
11 inner: HashMap<usize, BTreeMap<ByteIndex, BTreeMap<ByteIndex, Vec<T>>>>,
12}
13
14impl<T> LocMap<T> {
15 pub fn new() -> Self {
16 Self {
17 inner: HashMap::new(),
18 }
19 }
20
21 pub fn insert(&mut self, thing: Loc<T>) {
22 self.inner
23 .entry(thing.file_id)
24 .or_insert(Default::default())
25 .entry(thing.span.start())
26 .or_insert(Default::default())
27 .entry(thing.span.end())
28 .or_insert(Default::default())
29 .push(thing.inner)
30 }
31
32 pub fn around(&self, loc: &Loc<()>) -> Vec<Loc<&T>> {
33 self.inner
34 .get(&loc.file_id)
35 .map(|starts| {
36 let after_start = starts.range(..=loc.span.start());
37 after_start
38 .map(|(start, ends)| {
39 ends.range(loc.span.end()..)
40 .map(|(end, things)| {
41 let with_locs = things.iter().map(|thing| {
42 Loc::new(thing, Span::new(*start, *end), loc.file_id)
43 });
44 with_locs
45 })
46 .flatten()
47 })
48 .flatten()
49 .rev()
50 .collect::<Vec<_>>()
51 })
52 .unwrap_or_default()
53 }
54}
55
56#[test]
57fn around_tests() {
58 let mut test = LocMap::new();
59
60 test.insert(Loc::new("a", Span::new(100, 105), 1));
61 test.insert(Loc::new("b", Span::new(262, 265), 1));
62 test.insert(Loc::new("c", Span::new(300, 305), 1));
63 test.insert(Loc::new("d", Span::new(400, 405), 1));
64 test.insert(Loc::new("e", Span::new(500, 500), 1));
65
66 test.insert(Loc::new("0", Span::new(0, 100), 1));
67 test.insert(Loc::new("1", Span::new(30, 70), 1));
68 test.insert(Loc::new("2", Span::new(40, 60), 1));
69 test.insert(Loc::new("3", Span::new(40, 70), 1));
70 test.insert(Loc::new("4", Span::new(45, 50), 1));
71
72 println!("{test:?}");
73
74 assert_eq!(
75 test.around(&Loc::new((), Span::new(263, 263), 1))
76 .iter()
77 .map(|l| *l.inner)
78 .collect::<Vec<_>>(),
79 vec!["b"]
80 );
81
82 assert_eq!(
83 test.around(&Loc::new((), Span::new(500, 500), 1))
84 .iter()
85 .map(|l| *l.inner)
86 .collect::<Vec<_>>(),
87 vec!["e"]
88 );
89
90 assert_eq!(
91 test.around(&Loc::new((), Span::new(50, 50), 1))
92 .iter()
93 .map(|l| *l.inner)
94 .collect::<Vec<_>>(),
95 vec!["4", "3", "2", "1", "0"],
96 )
97}