diff options
author | Lukas Wirth <[email protected]> | 2021-02-13 16:57:14 +0000 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2021-02-13 16:57:14 +0000 |
commit | 8ac6041bcf7c970104939bdbdda5af4873ebd472 (patch) | |
tree | eb10eb5cac1c2c269e708144a96251336ff42e2b /crates/ide | |
parent | c395dd1032b66e28995189a26ed688b243d3cef8 (diff) |
Only use HIR when searching for enum constructors, otherwise fall back to AST
Diffstat (limited to 'crates/ide')
-rw-r--r-- | crates/ide/src/references.rs | 82 |
1 files changed, 34 insertions, 48 deletions
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 8a491f077..55a44ff01 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -70,14 +70,11 @@ pub(crate) fn find_all_refs( | |||
70 | }); | 70 | }); |
71 | usages.references.retain(|_, it| !it.is_empty()); | 71 | usages.references.retain(|_, it| !it.is_empty()); |
72 | } | 72 | } |
73 | Definition::ModuleDef(def @ hir::ModuleDef::Adt(_)) | 73 | Definition::ModuleDef(hir::ModuleDef::Adt(_)) |
74 | | Definition::ModuleDef(def @ hir::ModuleDef::Variant(_)) => { | 74 | | Definition::ModuleDef(hir::ModuleDef::Variant(_)) => { |
75 | refs.for_each(|it| { | 75 | refs.for_each(|it| { |
76 | it.retain(|reference| { | 76 | it.retain(|reference| { |
77 | reference | 77 | reference.name.as_name_ref().map_or(false, is_lit_name_ref) |
78 | .name | ||
79 | .as_name_ref() | ||
80 | .map_or(false, |name_ref| is_lit_name_ref(sema, def, name_ref)) | ||
81 | }) | 78 | }) |
82 | }); | 79 | }); |
83 | usages.references.retain(|_, it| !it.is_empty()); | 80 | usages.references.retain(|_, it| !it.is_empty()); |
@@ -189,55 +186,44 @@ fn is_enum_lit_name_ref( | |||
189 | enum_: hir::Enum, | 186 | enum_: hir::Enum, |
190 | name_ref: &ast::NameRef, | 187 | name_ref: &ast::NameRef, |
191 | ) -> bool { | 188 | ) -> bool { |
192 | for ancestor in name_ref.syntax().ancestors() { | 189 | let path_is_variant_of_enum = |path: ast::Path| { |
193 | match_ast! { | 190 | matches!( |
194 | match ancestor { | 191 | sema.resolve_path(&path), |
195 | ast::PathExpr(path_expr) => { | 192 | Some(PathResolution::Def(hir::ModuleDef::Variant(variant))) |
196 | return matches!( | 193 | if variant.parent_enum(sema.db) == enum_ |
197 | path_expr.path().and_then(|p| sema.resolve_path(&p)), | 194 | ) |
198 | Some(PathResolution::Def(hir::ModuleDef::Variant(variant))) | 195 | }; |
199 | if variant.parent_enum(sema.db) == enum_ | 196 | name_ref |
200 | ) | 197 | .syntax() |
201 | }, | 198 | .ancestors() |
202 | ast::RecordExpr(record_expr) => { | 199 | .find_map(|ancestor| { |
203 | return matches!( | 200 | match_ast! { |
204 | record_expr.path().and_then(|p| sema.resolve_path(&p)), | 201 | match ancestor { |
205 | Some(PathResolution::Def(hir::ModuleDef::Variant(variant))) | 202 | ast::PathExpr(path_expr) => path_expr.path().map(path_is_variant_of_enum), |
206 | if variant.parent_enum(sema.db) == enum_ | 203 | ast::RecordExpr(record_expr) => record_expr.path().map(path_is_variant_of_enum), |
207 | ) | 204 | _ => None, |
208 | }, | 205 | } |
209 | _ => (), | ||
210 | } | 206 | } |
211 | } | 207 | }) |
212 | } | 208 | .unwrap_or(false) |
213 | false | ||
214 | } | 209 | } |
215 | 210 | ||
216 | fn is_lit_name_ref( | 211 | fn path_ends_with(path: Option<ast::Path>, name_ref: &ast::NameRef) -> bool { |
217 | sema: &Semantics<RootDatabase>, | 212 | path.and_then(|path| path.segment()) |
218 | def: hir::ModuleDef, | 213 | .and_then(|segment| segment.name_ref()) |
219 | name_ref: &ast::NameRef, | 214 | .map_or(false, |segment| segment == *name_ref) |
220 | ) -> bool { | 215 | } |
221 | for ancestor in name_ref.syntax().ancestors() { | 216 | |
217 | fn is_lit_name_ref(name_ref: &ast::NameRef) -> bool { | ||
218 | name_ref.syntax().ancestors().find_map(|ancestor| { | ||
222 | match_ast! { | 219 | match_ast! { |
223 | match ancestor { | 220 | match ancestor { |
224 | ast::PathExpr(path_expr) => { | 221 | ast::PathExpr(path_expr) => Some(path_ends_with(path_expr.path(), name_ref)), |
225 | return matches!( | 222 | ast::RecordExpr(record_expr) => Some(path_ends_with(record_expr.path(), name_ref)), |
226 | path_expr.path().and_then(|p| sema.resolve_path(&p)), | 223 | _ => None, |
227 | Some(PathResolution::Def(def2)) if def == def2 | ||
228 | ) | ||
229 | }, | ||
230 | ast::RecordExpr(record_expr) => { | ||
231 | return matches!( | ||
232 | record_expr.path().and_then(|p| sema.resolve_path(&p)), | ||
233 | Some(PathResolution::Def(def2)) if def == def2 | ||
234 | ) | ||
235 | }, | ||
236 | _ => (), | ||
237 | } | 224 | } |
238 | } | 225 | } |
239 | } | 226 | }).unwrap_or(false) |
240 | false | ||
241 | } | 227 | } |
242 | 228 | ||
243 | #[cfg(test)] | 229 | #[cfg(test)] |