aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide/src/references.rs74
-rw-r--r--crates/ra_ide/src/references/rename.rs19
2 files changed, 68 insertions, 25 deletions
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index a6320bd2f..de924fad2 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -13,6 +13,7 @@ mod classify;
13mod rename; 13mod rename;
14mod search_scope; 14mod search_scope;
15 15
16use crate::expand::descend_into_macros_with_analyzer;
16use hir::{InFile, SourceBinder}; 17use hir::{InFile, SourceBinder};
17use once_cell::unsync::Lazy; 18use once_cell::unsync::Lazy;
18use ra_db::{SourceDatabase, SourceDatabaseExt}; 19use ra_db::{SourceDatabase, SourceDatabaseExt};
@@ -192,39 +193,62 @@ 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_with(|| {
215 sb.analyze(InFile::new(file_id.into(), parse.tree().syntax()), None)
216 });
217 let expanded = descend_into_macros_with_analyzer(
218 db,
219 &analyzer,
220 InFile::new(file_id.into(), t),
221 );
222 if let Some(token) = ast::NameRef::cast(expanded.value.parent()) {
223 (expanded.with_value(token), range)
224 } else {
225 continue;
207 } 226 }
208 // FIXME: reuse sb 227 };
209 // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098 228
210 229 if let Some(search_range) = search_range {
211 if let Some(d) = classify_name_ref(&mut sb, InFile::new(file_id.into(), &name_ref)) 230 if !range.is_subrange(&search_range) {
212 { 231 continue;
213 if d == def { 232 }
214 let kind = if is_record_lit_name_ref(&name_ref) 233 }
215 || is_call_expr_name_ref(&name_ref) 234 // FIXME: reuse sb
216 { 235 // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098
217 ReferenceKind::StructLiteral 236
218 } else { 237 if let Some(d) = classify_name_ref(&mut sb, name_ref.as_ref()) {
219 ReferenceKind::Other 238 if d == def {
220 }; 239 let kind = if is_record_lit_name_ref(&name_ref.value)
221 240 || is_call_expr_name_ref(&name_ref.value)
222 refs.push(Reference { 241 {
223 file_range: FileRange { file_id, range }, 242 ReferenceKind::StructLiteral
224 kind, 243 } else {
225 access: reference_access(&d.kind, &name_ref), 244 ReferenceKind::Other
226 }); 245 };
227 } 246
247 refs.push(Reference {
248 file_range: FileRange { file_id, range },
249 kind,
250 access: reference_access(&d.kind, &name_ref.value),
251 });
228 } 252 }
229 } 253 }
230 } 254 }
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#"