Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/mbe/src/token_map.rs')
| -rw-r--r-- | crates/mbe/src/token_map.rs | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/crates/mbe/src/token_map.rs b/crates/mbe/src/token_map.rs index 5871c0f125..b51d7575a1 100644 --- a/crates/mbe/src/token_map.rs +++ b/crates/mbe/src/token_map.rs @@ -8,30 +8,33 @@ use tt::Span; /// Maps absolute text ranges for the corresponding file to the relevant span data. #[derive(Debug, PartialEq, Eq, Clone, Hash)] -// FIXME: Rename to SpanMap -pub struct TokenMap<S: Span> { - // FIXME: This needs to be sorted by (FileId, AstId) - // Then we can do a binary search on the file id, - // then a bin search on the ast id? +pub struct SpanMap<S: Span> { spans: Vec<(TextSize, S)>, } -impl<S: Span> TokenMap<S> { +impl<S: Span> SpanMap<S> { + /// Creates a new empty [`SpanMap`]. pub fn empty() -> Self { Self { spans: Vec::new() } } + /// Finalizes the [`SpanMap`], shrinking its backing storage and validating that the offsets are + /// in order. pub fn finish(&mut self) { assert!(self.spans.iter().tuple_windows().all(|(a, b)| a.0 < b.0)); self.spans.shrink_to_fit(); } + /// Pushes a new span onto the [`SpanMap`]. pub fn push(&mut self, offset: TextSize, span: S) { + debug_assert!(self.spans.last().map_or(true, |&(last_offset, _)| last_offset < offset)); self.spans.push((offset, span)); } + /// Returns all [`TextRange`]s that correspond to the given span. + /// + /// Note this does a linear search through the entire backing vector. pub fn ranges_with_span(&self, span: S) -> impl Iterator<Item = TextRange> + '_ { - // FIXME: linear search self.spans.iter().enumerate().filter_map(move |(idx, &(end, s))| { if s != span { return None; @@ -41,14 +44,15 @@ impl<S: Span> TokenMap<S> { }) } - // FIXME: We need APIs for fetching the span of a token as well as for a whole node. The node - // one *is* fallible though. + /// Returns the span at the given position. pub fn span_at(&self, offset: TextSize) -> S { let entry = self.spans.partition_point(|&(it, _)| it <= offset); self.spans[entry].1 } - pub fn spans_for_node_range(&self, range: TextRange) -> impl Iterator<Item = S> + '_ { + /// Returns the spans associated with the given range. + /// In other words, this will return all spans that correspond to all offsets within the given range. + pub fn spans_for_range(&self, range: TextRange) -> impl Iterator<Item = S> + '_ { let (start, end) = (range.start(), range.end()); let start_entry = self.spans.partition_point(|&(it, _)| it <= start); let end_entry = self.spans[start_entry..].partition_point(|&(it, _)| it <= end); // FIXME: this might be wrong? |