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.rs24
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?