Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/span/src/map.rs')
-rw-r--r--crates/span/src/map.rs33
1 files changed, 31 insertions, 2 deletions
diff --git a/crates/span/src/map.rs b/crates/span/src/map.rs
index 7b42551099..1f396a1e97 100644
--- a/crates/span/src/map.rs
+++ b/crates/span/src/map.rs
@@ -1,7 +1,7 @@
//! A map that maps a span to every position in a file. Usually maps a span to some range of positions.
//! Allows bidirectional lookup.
-use std::hash::Hash;
+use std::{fmt, hash::Hash};
use stdx::{always, itertools::Itertools};
use syntax::{TextRange, TextSize};
@@ -52,7 +52,7 @@ where
/// 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: SpanData<S>) -> impl Iterator<Item = TextRange> + '_
+ pub fn ranges_with_span_exact(&self, span: SpanData<S>) -> impl Iterator<Item = TextRange> + '_
where
S: Copy,
{
@@ -65,6 +65,25 @@ where
})
}
+ /// Returns all [`TextRange`]s whose spans contain the given span.
+ ///
+ /// Note this does a linear search through the entire backing vector.
+ pub fn ranges_with_span(&self, span: SpanData<S>) -> impl Iterator<Item = TextRange> + '_
+ where
+ S: Copy,
+ {
+ self.spans.iter().enumerate().filter_map(move |(idx, &(end, s))| {
+ if s.anchor != span.anchor {
+ return None;
+ }
+ if !s.range.contains_range(span.range) {
+ return None;
+ }
+ let start = idx.checked_sub(1).map_or(TextSize::new(0), |prev| self.spans[prev].0);
+ Some(TextRange::new(start, end))
+ })
+ }
+
/// Returns the span at the given position.
pub fn span_at(&self, offset: TextSize) -> SpanData<S> {
let entry = self.spans.partition_point(|&(it, _)| it <= offset);
@@ -94,6 +113,16 @@ pub struct RealSpanMap {
end: TextSize,
}
+impl fmt::Display for RealSpanMap {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ writeln!(f, "RealSpanMap({:?}):", self.file_id)?;
+ for span in self.pairs.iter() {
+ writeln!(f, "{}: {}", u32::from(span.0), span.1.into_raw().into_u32())?;
+ }
+ Ok(())
+ }
+}
+
impl RealSpanMap {
/// Creates a real file span map that returns absolute ranges (relative ranges to the root ast id).
pub fn absolute(file_id: FileId) -> Self {