diff options
-rw-r--r-- | crates/ra_mbe/src/syntax_bridge.rs | 23 | ||||
-rw-r--r-- | crates/ra_tt/src/lib.rs | 16 |
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 | ||
13 | use crate::subtree_source::SubtreeTokenSource; | 13 | use crate::subtree_source::SubtreeTokenSource; |
14 | use crate::ExpandError; | 14 | use crate::ExpandError; |
15 | use 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)] | ||
18 | pub struct TokenMap { | 18 | pub 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 | |||
24 | static TOKEN_MAP_COUNTER: AtomicU32 = AtomicU32::new(0); | ||
25 | |||
26 | /// Generate an unique token map id for each instance | ||
27 | fn make_uniq_token_map_id() -> u32 { | ||
28 | TOKEN_MAP_COUNTER.fetch_add(1, Ordering::SeqCst) | ||
29 | } | ||
30 | |||
31 | impl 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 | ||
106 | impl TokenMap { | 120 | impl 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)] |
28 | pub struct TokenId(pub u32); | 28 | pub struct TokenId(u32, u32); |
29 | 29 | ||
30 | impl TokenId { | 30 | impl 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 | ||