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.rs208
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);
+ // }
+ // }
}