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.rs | 33 |
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 { |