aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2019-12-13 15:55:51 +0000
committerEdwin Cheng <[email protected]>2019-12-18 03:20:22 +0000
commit320416d7561e9926ecbbc392cc2efd48740610e0 (patch)
treef20bbcfca5e079582ecd6ea87b2b4972b34fe7f2
parent59295854f892b0a8f42a6fbc80b04d1f1c695828 (diff)
Add TokenTextRange
-rw-r--r--crates/ra_hir_expand/src/lib.rs4
-rw-r--r--crates/ra_mbe/src/syntax_bridge.rs41
2 files changed, 35 insertions, 10 deletions
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index cb4e1950b..720a29ea5 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -227,7 +227,7 @@ impl ExpansionInfo {
227 let token_id = self.macro_arg.1.token_by_range(range)?; 227 let token_id = self.macro_arg.1.token_by_range(range)?;
228 let token_id = self.macro_def.0.map_id_down(token_id); 228 let token_id = self.macro_def.0.map_id_down(token_id);
229 229
230 let range = self.exp_map.range_by_token(token_id)?; 230 let range = self.exp_map.range_by_token(token_id)?.range(token.value.kind())?;
231 231
232 let token = algo::find_covering_element(&self.expanded.value, range).into_token()?; 232 let token = algo::find_covering_element(&self.expanded.value, range).into_token()?;
233 233
@@ -248,7 +248,7 @@ impl ExpansionInfo {
248 } 248 }
249 }; 249 };
250 250
251 let range = token_map.range_by_token(token_id)?; 251 let range = token_map.range_by_token(token_id)?.range(token.value.kind())?;
252 let token = algo::find_covering_element(&tt.value, range + tt.value.text_range().start()) 252 let token = algo::find_covering_element(&tt.value, range + tt.value.text_range().start())
253 .into_token()?; 253 .into_token()?;
254 Some((tt.with_value(token), origin)) 254 Some((tt.with_value(token), origin))
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs
index a85bb058b..44a51b7a5 100644
--- a/crates/ra_mbe/src/syntax_bridge.rs
+++ b/crates/ra_mbe/src/syntax_bridge.rs
@@ -12,11 +12,30 @@ use tt::buffer::{Cursor, TokenBuffer};
12use crate::subtree_source::SubtreeTokenSource; 12use crate::subtree_source::SubtreeTokenSource;
13use crate::ExpandError; 13use crate::ExpandError;
14 14
15#[derive(Debug, PartialEq, Eq, Clone, Copy)]
16pub enum TokenTextRange {
17 Token(TextRange),
18 Delimiter(TextRange, TextRange),
19}
20
21impl TokenTextRange {
22 pub fn range(self, kind: SyntaxKind) -> Option<TextRange> {
23 match self {
24 TokenTextRange::Token(it) => Some(it),
25 TokenTextRange::Delimiter(open, close) => match kind {
26 T!['{'] | T!['('] | T!['['] => Some(open),
27 T!['}'] | T![')'] | T![']'] => Some(close),
28 _ => None,
29 },
30 }
31 }
32}
33
15/// Maps `tt::TokenId` to the relative range of the original token. 34/// Maps `tt::TokenId` to the relative range of the original token.
16#[derive(Debug, PartialEq, Eq, Default)] 35#[derive(Debug, PartialEq, Eq, Default)]
17pub struct TokenMap { 36pub struct TokenMap {
18 /// Maps `tt::TokenId` to the *relative* source range. 37 /// Maps `tt::TokenId` to the *relative* source range.
19 entries: Vec<(tt::TokenId, TextRange)>, 38 entries: Vec<(tt::TokenId, TokenTextRange)>,
20} 39}
21 40
22/// Convert the syntax tree (what user has written) to a `TokenTree` (what macro 41/// Convert the syntax tree (what user has written) to a `TokenTree` (what macro
@@ -72,26 +91,32 @@ pub fn token_tree_to_syntax_node(
72 91
73impl TokenMap { 92impl TokenMap {
74 pub fn token_by_range(&self, relative_range: TextRange) -> Option<tt::TokenId> { 93 pub fn token_by_range(&self, relative_range: TextRange) -> Option<tt::TokenId> {
75 let &(token_id, _) = self.entries.iter().find(|(_, range)| *range == relative_range)?; 94 let &(token_id, _) = self.entries.iter().find(|(_, range)| match range {
95 TokenTextRange::Token(it) => *it == relative_range,
96 TokenTextRange::Delimiter(open, close) => {
97 *open == relative_range || *close == relative_range
98 }
99 })?;
76 Some(token_id) 100 Some(token_id)
77 } 101 }
78 102
79 pub fn range_by_token(&self, token_id: tt::TokenId) -> Option<TextRange> { 103 pub fn range_by_token(&self, token_id: tt::TokenId) -> Option<TokenTextRange> {
80 let &(_, range) = self.entries.iter().find(|(tid, _)| *tid == token_id)?; 104 let &(_, range) = self.entries.iter().find(|(tid, _)| *tid == token_id)?;
81 Some(range) 105 Some(range)
82 } 106 }
83 107
84 fn insert(&mut self, token_id: tt::TokenId, relative_range: TextRange) { 108 fn insert(&mut self, token_id: tt::TokenId, relative_range: TextRange) {
85 self.entries.push((token_id, relative_range)); 109 self.entries.push((token_id, TokenTextRange::Token(relative_range)));
86 } 110 }
87 111
88 fn insert_delim( 112 fn insert_delim(
89 &mut self, 113 &mut self,
90 _token_id: tt::TokenId, 114 token_id: tt::TokenId,
91 _open_relative_range: TextRange, 115 open_relative_range: TextRange,
92 _close_relative_range: TextRange, 116 close_relative_range: TextRange,
93 ) { 117 ) {
94 // FIXME: Add entries for delimiter 118 self.entries
119 .push((token_id, TokenTextRange::Delimiter(open_relative_range, close_relative_range)));
95 } 120 }
96} 121}
97 122