aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_mbe/src/syntax_bridge.rs23
-rw-r--r--crates/ra_tt/src/lib.rs16
2 files changed, 34 insertions, 5 deletions
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs
index 592fcf527..8d9217518 100644
--- a/crates/ra_mbe/src/syntax_bridge.rs
+++ b/crates/ra_mbe/src/syntax_bridge.rs
@@ -12,12 +12,26 @@ use tt::buffer::{Cursor, TokenBuffer};
12 12
13use crate::subtree_source::SubtreeTokenSource; 13use crate::subtree_source::SubtreeTokenSource;
14use crate::ExpandError; 14use crate::ExpandError;
15use std::sync::atomic::{AtomicU32, Ordering};
15 16
16/// Maps `tt::TokenId` to the relative range of the original token. 17/// Maps `tt::TokenId` to the relative range of the original token.
17#[derive(Default)]
18pub struct TokenMap { 18pub struct TokenMap {
19 /// Maps `tt::TokenId` to the *relative* source range. 19 /// Maps `tt::TokenId` to the *relative* source range.
20 tokens: Vec<TextRange>, 20 tokens: Vec<TextRange>,
21 map_id: u32,
22}
23
24static TOKEN_MAP_COUNTER: AtomicU32 = AtomicU32::new(0);
25
26/// Generate an unique token map id for each instance
27fn make_uniq_token_map_id() -> u32 {
28 TOKEN_MAP_COUNTER.fetch_add(1, Ordering::SeqCst)
29}
30
31impl std::default::Default for TokenMap {
32 fn default() -> TokenMap {
33 TokenMap { tokens: Default::default(), map_id: make_uniq_token_map_id() }
34 }
21} 35}
22 36
23/// Convert the syntax tree (what user has written) to a `TokenTree` (what macro 37/// Convert the syntax tree (what user has written) to a `TokenTree` (what macro
@@ -105,14 +119,17 @@ pub fn token_tree_to_items(tt: &tt::Subtree) -> Result<Parse<ast::MacroItems>, E
105 119
106impl TokenMap { 120impl TokenMap {
107 pub fn relative_range_of(&self, tt: tt::TokenId) -> Option<TextRange> { 121 pub fn relative_range_of(&self, tt: tt::TokenId) -> Option<TextRange> {
108 let idx = tt.0 as usize; 122 if self.map_id != tt.map_id() {
123 return None;
124 }
125 let idx = tt.token_id() as usize;
109 self.tokens.get(idx).copied() 126 self.tokens.get(idx).copied()
110 } 127 }
111 128
112 fn alloc(&mut self, relative_range: TextRange) -> tt::TokenId { 129 fn alloc(&mut self, relative_range: TextRange) -> tt::TokenId {
113 let id = self.tokens.len(); 130 let id = self.tokens.len();
114 self.tokens.push(relative_range); 131 self.tokens.push(relative_range);
115 tt::TokenId(id as u32) 132 tt::TokenId::new(id as u32, self.map_id)
116 } 133 }
117} 134}
118 135
diff --git a/crates/ra_tt/src/lib.rs b/crates/ra_tt/src/lib.rs
index 20c251ff4..96410ff22 100644
--- a/crates/ra_tt/src/lib.rs
+++ b/crates/ra_tt/src/lib.rs
@@ -25,11 +25,23 @@ use smol_str::SmolStr;
25/// source token and making sure that identities are preserved during macro 25/// source token and making sure that identities are preserved during macro
26/// expansion. 26/// expansion.
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 27#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
28pub struct TokenId(pub u32); 28pub struct TokenId(u32, u32);
29 29
30impl TokenId { 30impl TokenId {
31 pub fn new(token_id: u32, map_id: u32) -> TokenId {
32 TokenId(token_id, map_id)
33 }
34
31 pub const fn unspecified() -> TokenId { 35 pub const fn unspecified() -> TokenId {
32 TokenId(!0) 36 TokenId(!0, !0)
37 }
38
39 pub fn token_id(&self) -> u32 {
40 self.0
41 }
42
43 pub fn map_id(&self) -> u32 {
44 self.1
33 } 45 }
34} 46}
35 47