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 | 208 |
1 files changed, 103 insertions, 105 deletions
diff --git a/crates/mbe/src/token_map.rs b/crates/mbe/src/token_map.rs index 73a27df5db..1af50c8b3b 100644 --- a/crates/mbe/src/token_map.rs +++ b/crates/mbe/src/token_map.rs @@ -2,123 +2,121 @@ use std::hash::Hash; -use parser::{SyntaxKind, T}; -use syntax::{TextRange, TextSize}; - -use crate::syntax_bridge::SyntheticTokenId; - -#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] -enum TokenTextRange { - Token(TextRange), - Delimiter(TextRange), +use syntax::TextRange; +use tt::Span; + +// pub type HirFile = u32; +// pub type FileRange = (HirFile, TextRange); +// Option<MacroCallId>, LocalSyntaxContet +// pub type SyntaxContext = (); +// pub type LocalSyntaxContext = u32; + +/// 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> { + // 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 span_map: Vec<(TextRange, S)>, + // span_map2: rustc_hash::FxHashMap<TextRange, usize>, } -impl TokenTextRange { - fn by_kind(self, kind: SyntaxKind) -> Option<TextRange> { - match self { - TokenTextRange::Token(it) => Some(it), - TokenTextRange::Delimiter(it) => match kind { - T!['{'] | T!['('] | T!['['] => Some(TextRange::at(it.start(), 1.into())), - T!['}'] | T![')'] | T![']'] => { - Some(TextRange::at(it.end() - TextSize::of('}'), 1.into())) - } - _ => None, - }, - } +impl<S> Default for TokenMap<S> { + fn default() -> Self { + Self { span_map: Vec::new() } } } -/// Maps `tt::TokenId` to the relative range of the original token. -#[derive(Debug, PartialEq, Eq, Clone, Default, Hash)] -pub struct TokenMap { - /// Maps `tt::TokenId` to the *relative* source range. - entries: Vec<(tt::TokenId, TokenTextRange)>, - pub synthetic_entries: Vec<(tt::TokenId, SyntheticTokenId)>, -} - -impl TokenMap { - pub fn token_by_range(&self, relative_range: TextRange) -> Option<tt::TokenId> { - let &(token_id, _) = self.entries.iter().find(|(_, range)| match range { - TokenTextRange::Token(it) => *it == relative_range, - TokenTextRange::Delimiter(it) => { - let open = TextRange::at(it.start(), 1.into()); - let close = TextRange::at(it.end() - TextSize::of('}'), 1.into()); - open == relative_range || close == relative_range - } - })?; - Some(token_id) - } - - pub fn ranges_by_token( - &self, - token_id: tt::TokenId, - kind: SyntaxKind, - ) -> impl Iterator<Item = TextRange> + '_ { - self.entries - .iter() - .filter(move |&&(tid, _)| tid == token_id) - .filter_map(move |(_, range)| range.by_kind(kind)) - } - - pub fn synthetic_token_id(&self, token_id: tt::TokenId) -> Option<SyntheticTokenId> { - self.synthetic_entries.iter().find(|(tid, _)| *tid == token_id).map(|(_, id)| *id) - } - - pub fn first_range_by_token( - &self, - token_id: tt::TokenId, - kind: SyntaxKind, - ) -> Option<TextRange> { - self.ranges_by_token(token_id, kind).next() - } - +impl<S: Span> TokenMap<S> { pub(crate) fn shrink_to_fit(&mut self) { - self.entries.shrink_to_fit(); - self.synthetic_entries.shrink_to_fit(); - } - - pub(crate) fn insert(&mut self, token_id: tt::TokenId, relative_range: TextRange) { - self.entries.push((token_id, TokenTextRange::Token(relative_range))); - } - - pub(crate) fn insert_synthetic(&mut self, token_id: tt::TokenId, id: SyntheticTokenId) { - self.synthetic_entries.push((token_id, id)); + self.span_map.shrink_to_fit(); } - pub(crate) fn insert_delim( - &mut self, - token_id: tt::TokenId, - open_relative_range: TextRange, - close_relative_range: TextRange, - ) -> usize { - let res = self.entries.len(); - let cover = open_relative_range.cover(close_relative_range); - - self.entries.push((token_id, TokenTextRange::Delimiter(cover))); - res + pub(crate) fn insert(&mut self, range: TextRange, span: S) { + self.span_map.push((range, span)); } - pub(crate) fn update_close_delim(&mut self, idx: usize, close_relative_range: TextRange) { - let (_, token_text_range) = &mut self.entries[idx]; - if let TokenTextRange::Delimiter(dim) = token_text_range { - let cover = dim.cover(close_relative_range); - *token_text_range = TokenTextRange::Delimiter(cover); - } - } - - pub(crate) fn remove_delim(&mut self, idx: usize) { - // FIXME: This could be accidentally quadratic - self.entries.remove(idx); + pub fn ranges_with_span(&self, span: S) -> impl Iterator<Item = TextRange> + '_ { + self.span_map.iter().filter_map( + move |(range, s)| { + if s == &span { + Some(*range) + } else { + None + } + }, + ) } - pub fn entries(&self) -> impl Iterator<Item = (tt::TokenId, TextRange)> + '_ { - self.entries.iter().filter_map(|&(tid, tr)| match tr { - TokenTextRange::Token(range) => Some((tid, range)), - TokenTextRange::Delimiter(_) => None, - }) + pub fn span_for_range(&self, range: TextRange) -> Option<S> { + self.span_map.iter().find_map(|(r, s)| if r == &range { Some(s.clone()) } else { None }) } - pub fn filter(&mut self, id: impl Fn(tt::TokenId) -> bool) { - self.entries.retain(|&(tid, _)| id(tid)); - } + // pub fn ranges_by_token( + // &self, + // token_id: tt::TokenId, + // kind: SyntaxKind, + // ) -> impl Iterator<Item = TextRange> + '_ { + // self.entries + // .iter() + // .filter(move |&&(tid, _)| tid == token_id) + // .filter_map(move |(_, range)| range.by_kind(kind)) + // } + + // pub(crate) fn remove_delim(&mut self, idx: usize) { + // // FIXME: This could be accidentally quadratic + // self.entries.remove(idx); + // } + + // pub fn entries(&self) -> impl Iterator<Item = (tt::TokenId, TextRange)> + '_ { + // self.entries.iter().filter_map(|&(tid, tr)| match tr { + // TokenTextRange::Token(range) => Some((tid, range)), + // TokenTextRange::Delimiter(_) => None, + // }) + // } + + // pub fn filter(&mut self, id: impl Fn(tt::TokenId) -> bool) { + // self.entries.retain(|&(tid, _)| id(tid)); + // } + // pub fn synthetic_token_id(&self, token_id: tt::TokenId) -> Option<SyntheticTokenId> { + // self.synthetic_entries.iter().find(|(tid, _)| *tid == token_id).map(|(_, id)| *id) + // } + + // pub fn first_range_by_token( + // &self, + // token_id: tt::TokenId, + // kind: SyntaxKind, + // ) -> Option<TextRange> { + // self.ranges_by_token(token_id, kind).next() + // } + + // pub(crate) fn insert(&mut self, token_id: tt::TokenId, relative_range: TextRange) { + // self.entries.push((token_id, TokenTextRange::Token(relative_range))); + // } + + // pub(crate) fn insert_synthetic(&mut self, token_id: tt::TokenId, id: SyntheticTokenId) { + // self.synthetic_entries.push((token_id, id)); + // } + + // pub(crate) fn insert_delim( + // &mut self, + // token_id: tt::TokenId, + // open_relative_range: TextRange, + // close_relative_range: TextRange, + // ) -> usize { + // let res = self.entries.len(); + // let cover = open_relative_range.cover(close_relative_range); + + // self.entries.push((token_id, TokenTextRange::Delimiter(cover))); + // res + // } + + // pub(crate) fn update_close_delim(&mut self, idx: usize, close_relative_range: TextRange) { + // let (_, token_text_range) = &mut self.entries[idx]; + // if let TokenTextRange::Delimiter(dim) = token_text_range { + // let cover = dim.cover(close_relative_range); + // *token_text_range = TokenTextRange::Delimiter(cover); + // } + // } } |