diff options
author | Aleksey Kladov <[email protected]> | 2020-03-03 17:22:52 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-03-03 17:22:52 +0000 |
commit | 7d71cc72b5902300ed03db409b2a858517a1f5e0 (patch) | |
tree | 8cc0425d7b25c5da3f6a633a3addfb38640c5002 /crates/ra_ide | |
parent | 674770ef0473cf938d734f54bcf33524d9fdf5f8 (diff) |
Refactor reference search a bit
Diffstat (limited to 'crates/ra_ide')
-rw-r--r-- | crates/ra_ide/src/references.rs | 61 |
1 files changed, 36 insertions, 25 deletions
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs index 9b0785e1d..c9c9c6483 100644 --- a/crates/ra_ide/src/references.rs +++ b/crates/ra_ide/src/references.rs | |||
@@ -125,9 +125,29 @@ pub(crate) fn find_all_refs( | |||
125 | (find_node_at_offset::<ast::Name>(&syntax, position.offset), ReferenceKind::Other) | 125 | (find_node_at_offset::<ast::Name>(&syntax, position.offset), ReferenceKind::Other) |
126 | }; | 126 | }; |
127 | 127 | ||
128 | let RangeInfo { range, info: (name, def) } = find_name(&sema, &syntax, position, opt_name)?; | 128 | let RangeInfo { range, info: def } = find_name(&sema, &syntax, position, opt_name)?; |
129 | let declaration = def.try_to_nav(db)?; | ||
130 | 129 | ||
130 | let references = find_refs_to_def(db, &def, search_scope) | ||
131 | .into_iter() | ||
132 | .filter(|r| search_kind == ReferenceKind::Other || search_kind == r.kind) | ||
133 | .collect(); | ||
134 | |||
135 | let decl_range = def.try_to_nav(db)?.range(); | ||
136 | |||
137 | let declaration = Declaration { | ||
138 | nav: def.try_to_nav(db)?, | ||
139 | kind: ReferenceKind::Other, | ||
140 | access: decl_access(&def, &syntax, decl_range), | ||
141 | }; | ||
142 | |||
143 | Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references })) | ||
144 | } | ||
145 | |||
146 | pub(crate) fn find_refs_to_def( | ||
147 | db: &RootDatabase, | ||
148 | def: &NameDefinition, | ||
149 | search_scope: Option<SearchScope>, | ||
150 | ) -> Vec<Reference> { | ||
131 | let search_scope = { | 151 | let search_scope = { |
132 | let base = SearchScope::for_def(&def, db); | 152 | let base = SearchScope::for_def(&def, db); |
133 | match search_scope { | 153 | match search_scope { |
@@ -136,20 +156,12 @@ pub(crate) fn find_all_refs( | |||
136 | } | 156 | } |
137 | }; | 157 | }; |
138 | 158 | ||
139 | let decl_range = declaration.range(); | 159 | let name = match def.name(db) { |
140 | 160 | None => return Vec::new(), | |
141 | let declaration = Declaration { | 161 | Some(it) => it.to_string(), |
142 | nav: declaration, | ||
143 | kind: ReferenceKind::Other, | ||
144 | access: decl_access(&def, &name, &syntax, decl_range), | ||
145 | }; | 162 | }; |
146 | 163 | ||
147 | let references = process_definition(db, def, name, search_scope) | 164 | process_definition(db, def, name, search_scope) |
148 | .into_iter() | ||
149 | .filter(|r| search_kind == ReferenceKind::Other || search_kind == r.kind) | ||
150 | .collect(); | ||
151 | |||
152 | Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references })) | ||
153 | } | 165 | } |
154 | 166 | ||
155 | fn find_name( | 167 | fn find_name( |
@@ -157,21 +169,21 @@ fn find_name( | |||
157 | syntax: &SyntaxNode, | 169 | syntax: &SyntaxNode, |
158 | position: FilePosition, | 170 | position: FilePosition, |
159 | opt_name: Option<ast::Name>, | 171 | opt_name: Option<ast::Name>, |
160 | ) -> Option<RangeInfo<(String, NameDefinition)>> { | 172 | ) -> Option<RangeInfo<NameDefinition>> { |
161 | if let Some(name) = opt_name { | 173 | if let Some(name) = opt_name { |
162 | let def = classify_name(sema, &name)?.definition(); | 174 | let def = classify_name(sema, &name)?.definition(); |
163 | let range = name.syntax().text_range(); | 175 | let range = name.syntax().text_range(); |
164 | return Some(RangeInfo::new(range, (name.text().to_string(), def))); | 176 | return Some(RangeInfo::new(range, def)); |
165 | } | 177 | } |
166 | let name_ref = find_node_at_offset::<ast::NameRef>(&syntax, position.offset)?; | 178 | let name_ref = find_node_at_offset::<ast::NameRef>(&syntax, position.offset)?; |
167 | let def = classify_name_ref(sema, &name_ref)?.definition(); | 179 | let def = classify_name_ref(sema, &name_ref)?.definition(); |
168 | let range = name_ref.syntax().text_range(); | 180 | let range = name_ref.syntax().text_range(); |
169 | Some(RangeInfo::new(range, (name_ref.text().to_string(), def))) | 181 | Some(RangeInfo::new(range, def)) |
170 | } | 182 | } |
171 | 183 | ||
172 | fn process_definition( | 184 | fn process_definition( |
173 | db: &RootDatabase, | 185 | db: &RootDatabase, |
174 | def: NameDefinition, | 186 | def: &NameDefinition, |
175 | name: String, | 187 | name: String, |
176 | scope: SearchScope, | 188 | scope: SearchScope, |
177 | ) -> Vec<Reference> { | 189 | ) -> Vec<Reference> { |
@@ -217,7 +229,7 @@ fn process_definition( | |||
217 | 229 | ||
218 | if let Some(d) = classify_name_ref(&sema, &name_ref) { | 230 | if let Some(d) = classify_name_ref(&sema, &name_ref) { |
219 | let d = d.definition(); | 231 | let d = d.definition(); |
220 | if d == def { | 232 | if &d == def { |
221 | let kind = | 233 | let kind = |
222 | if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) { | 234 | if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) { |
223 | ReferenceKind::StructLiteral | 235 | ReferenceKind::StructLiteral |
@@ -240,7 +252,6 @@ fn process_definition( | |||
240 | 252 | ||
241 | fn decl_access( | 253 | fn decl_access( |
242 | def: &NameDefinition, | 254 | def: &NameDefinition, |
243 | name: &str, | ||
244 | syntax: &SyntaxNode, | 255 | syntax: &SyntaxNode, |
245 | range: TextRange, | 256 | range: TextRange, |
246 | ) -> Option<ReferenceAccess> { | 257 | ) -> Option<ReferenceAccess> { |
@@ -253,7 +264,7 @@ fn decl_access( | |||
253 | if stmt.initializer().is_some() { | 264 | if stmt.initializer().is_some() { |
254 | let pat = stmt.pat()?; | 265 | let pat = stmt.pat()?; |
255 | if let ast::Pat::BindPat(it) = pat { | 266 | if let ast::Pat::BindPat(it) = pat { |
256 | if it.name()?.text().as_str() == name { | 267 | if it.is_mutable() { |
257 | return Some(ReferenceAccess::Write); | 268 | return Some(ReferenceAccess::Write); |
258 | } | 269 | } |
259 | } | 270 | } |
@@ -463,7 +474,7 @@ mod tests { | |||
463 | let refs = get_all_refs(code); | 474 | let refs = get_all_refs(code); |
464 | check_result( | 475 | check_result( |
465 | refs, | 476 | refs, |
466 | "spam BIND_PAT FileId(1) [44; 48) Other Write", | 477 | "spam BIND_PAT FileId(1) [44; 48) Other", |
467 | &["FileId(1) [71; 75) Other Read", "FileId(1) [78; 82) Other Read"], | 478 | &["FileId(1) [71; 75) Other Read", "FileId(1) [78; 82) Other Read"], |
468 | ); | 479 | ); |
469 | } | 480 | } |
@@ -709,15 +720,15 @@ mod tests { | |||
709 | fn test_basic_highlight_read_write() { | 720 | fn test_basic_highlight_read_write() { |
710 | let code = r#" | 721 | let code = r#" |
711 | fn foo() { | 722 | fn foo() { |
712 | let i<|> = 0; | 723 | let mut i<|> = 0; |
713 | i = i + 1; | 724 | i = i + 1; |
714 | }"#; | 725 | }"#; |
715 | 726 | ||
716 | let refs = get_all_refs(code); | 727 | let refs = get_all_refs(code); |
717 | check_result( | 728 | check_result( |
718 | refs, | 729 | refs, |
719 | "i BIND_PAT FileId(1) [36; 37) Other Write", | 730 | "i BIND_PAT FileId(1) [40; 41) Other Write", |
720 | &["FileId(1) [55; 56) Other Write", "FileId(1) [59; 60) Other Read"], | 731 | &["FileId(1) [59; 60) Other Write", "FileId(1) [63; 64) Other Read"], |
721 | ); | 732 | ); |
722 | } | 733 | } |
723 | 734 | ||