diff options
author | Edwin Cheng <[email protected]> | 2020-02-09 09:17:56 +0000 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2020-02-09 09:17:56 +0000 |
commit | dd0421e587bf312bd79eb98c821e0be437f6b361 (patch) | |
tree | f6ea75230ca12ba8d18666b62f3f1bf451df5af2 | |
parent | 3e1d97790be166f8735607c552a94a28ab9b09b8 (diff) |
Handle macro token cases for rename
-rw-r--r-- | crates/ra_ide/src/references.rs | 75 | ||||
-rw-r--r-- | crates/ra_ide/src/references/rename.rs | 19 |
2 files changed, 69 insertions, 25 deletions
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs index a6320bd2f..bc241fb5a 100644 --- a/crates/ra_ide/src/references.rs +++ b/crates/ra_ide/src/references.rs | |||
@@ -13,6 +13,7 @@ mod classify; | |||
13 | mod rename; | 13 | mod rename; |
14 | mod search_scope; | 14 | mod search_scope; |
15 | 15 | ||
16 | use crate::expand::descend_into_macros_with_analyzer; | ||
16 | use hir::{InFile, SourceBinder}; | 17 | use hir::{InFile, SourceBinder}; |
17 | use once_cell::unsync::Lazy; | 18 | use once_cell::unsync::Lazy; |
18 | use ra_db::{SourceDatabase, SourceDatabaseExt}; | 19 | use ra_db::{SourceDatabase, SourceDatabaseExt}; |
@@ -192,39 +193,63 @@ fn process_definition( | |||
192 | 193 | ||
193 | let parse = Lazy::new(|| SourceFile::parse(&text)); | 194 | let parse = Lazy::new(|| SourceFile::parse(&text)); |
194 | let mut sb = Lazy::new(|| SourceBinder::new(db)); | 195 | let mut sb = Lazy::new(|| SourceBinder::new(db)); |
196 | let mut analyzer = None; | ||
195 | 197 | ||
196 | for (idx, _) in text.match_indices(pat) { | 198 | for (idx, _) in text.match_indices(pat) { |
197 | let offset = TextUnit::from_usize(idx); | 199 | let offset = TextUnit::from_usize(idx); |
198 | 200 | ||
199 | if let Some(name_ref) = | 201 | let (name_ref, range) = if let Some(name_ref) = |
200 | find_node_at_offset::<ast::NameRef>(parse.tree().syntax(), offset) | 202 | find_node_at_offset::<ast::NameRef>(parse.tree().syntax(), offset) |
201 | { | 203 | { |
202 | let range = name_ref.syntax().text_range(); | 204 | let range = name_ref.syntax().text_range(); |
203 | if let Some(search_range) = search_range { | 205 | (InFile::new(file_id.into(), name_ref), range) |
204 | if !range.is_subrange(&search_range) { | 206 | } else { |
205 | continue; | 207 | // Handle macro token cases |
206 | } | 208 | let t = match parse.tree().syntax().token_at_offset(offset) { |
209 | TokenAtOffset::None => continue, | ||
210 | TokenAtOffset::Single(t) => t, | ||
211 | TokenAtOffset::Between(_, t) => t, | ||
212 | }; | ||
213 | let range = t.text_range(); | ||
214 | let analyzer = analyzer.get_or_insert( | ||
215 | sb.analyze(InFile::new(file_id.into(), parse.tree().syntax()), None), | ||
216 | ); | ||
217 | |||
218 | let expanded = descend_into_macros_with_analyzer( | ||
219 | db, | ||
220 | &analyzer, | ||
221 | InFile::new(file_id.into(), t), | ||
222 | ); | ||
223 | if let Some(token) = ast::NameRef::cast(expanded.value.parent()) { | ||
224 | (expanded.with_value(token), range) | ||
225 | } else { | ||
226 | continue; | ||
207 | } | 227 | } |
208 | // FIXME: reuse sb | 228 | }; |
209 | // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098 | 229 | |
210 | 230 | if let Some(search_range) = search_range { | |
211 | if let Some(d) = classify_name_ref(&mut sb, InFile::new(file_id.into(), &name_ref)) | 231 | if !range.is_subrange(&search_range) { |
212 | { | 232 | continue; |
213 | if d == def { | 233 | } |
214 | let kind = if is_record_lit_name_ref(&name_ref) | 234 | } |
215 | || is_call_expr_name_ref(&name_ref) | 235 | // FIXME: reuse sb |
216 | { | 236 | // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098 |
217 | ReferenceKind::StructLiteral | 237 | |
218 | } else { | 238 | if let Some(d) = classify_name_ref(&mut sb, name_ref.as_ref()) { |
219 | ReferenceKind::Other | 239 | if d == def { |
220 | }; | 240 | let kind = if is_record_lit_name_ref(&name_ref.value) |
221 | 241 | || is_call_expr_name_ref(&name_ref.value) | |
222 | refs.push(Reference { | 242 | { |
223 | file_range: FileRange { file_id, range }, | 243 | ReferenceKind::StructLiteral |
224 | kind, | 244 | } else { |
225 | access: reference_access(&d.kind, &name_ref), | 245 | ReferenceKind::Other |
226 | }); | 246 | }; |
227 | } | 247 | |
248 | refs.push(Reference { | ||
249 | file_range: FileRange { file_id, range }, | ||
250 | kind, | ||
251 | access: reference_access(&d.kind, &name_ref.value), | ||
252 | }); | ||
228 | } | 253 | } |
229 | } | 254 | } |
230 | } | 255 | } |
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs index 08e77c01f..c46b78cb6 100644 --- a/crates/ra_ide/src/references/rename.rs +++ b/crates/ra_ide/src/references/rename.rs | |||
@@ -211,6 +211,25 @@ mod tests { | |||
211 | } | 211 | } |
212 | 212 | ||
213 | #[test] | 213 | #[test] |
214 | fn test_rename_for_macro_args() { | ||
215 | test_rename( | ||
216 | r#" | ||
217 | macro_rules! foo {($i:ident) => {$i} } | ||
218 | fn main() { | ||
219 | let a<|> = "test"; | ||
220 | foo!(a); | ||
221 | }"#, | ||
222 | "b", | ||
223 | r#" | ||
224 | macro_rules! foo {($i:ident) => {$i} } | ||
225 | fn main() { | ||
226 | let b = "test"; | ||
227 | foo!(b); | ||
228 | }"#, | ||
229 | ); | ||
230 | } | ||
231 | |||
232 | #[test] | ||
214 | fn test_rename_for_param_inside() { | 233 | fn test_rename_for_param_inside() { |
215 | test_rename( | 234 | test_rename( |
216 | r#" | 235 | r#" |