diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-02-12 18:01:36 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-02-12 18:01:36 +0000 |
commit | 88253907f4bc3beaa7b8f2e58cb652f653f92d56 (patch) | |
tree | 1669ff0e6ab614c679f245f84d0f9a8202366e0e /crates/syntax/src/ast | |
parent | 4d51b5644458c7dcb97a4d445f1b379cd2548a78 (diff) | |
parent | fd6cf4d566174dbdb50259bbbfdaf5a12f81544d (diff) |
Merge #7358
7358: Refactor reference searching to work with the ast r=matklad a=Veykril
Addresses #4290
This PR is still a bit unpolished. Its main purpose for now is to discuss the direction of the changes as to whether this seems to be the right approach or not. I annotated a few parts with reviews to give a better overwiew without having to read into it too much.
Big part of the diff are test output changes in the `references` module.
Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/syntax/src/ast')
-rw-r--r-- | crates/syntax/src/ast/node_ext.rs | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 5c8cf900f..b105cb0e0 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs | |||
@@ -274,10 +274,7 @@ impl ast::Struct { | |||
274 | 274 | ||
275 | impl ast::RecordExprField { | 275 | impl ast::RecordExprField { |
276 | pub fn for_field_name(field_name: &ast::NameRef) -> Option<ast::RecordExprField> { | 276 | pub fn for_field_name(field_name: &ast::NameRef) -> Option<ast::RecordExprField> { |
277 | let candidate = | 277 | let candidate = Self::for_name_ref(field_name)?; |
278 | field_name.syntax().parent().and_then(ast::RecordExprField::cast).or_else(|| { | ||
279 | field_name.syntax().ancestors().nth(4).and_then(ast::RecordExprField::cast) | ||
280 | })?; | ||
281 | if candidate.field_name().as_ref() == Some(field_name) { | 278 | if candidate.field_name().as_ref() == Some(field_name) { |
282 | Some(candidate) | 279 | Some(candidate) |
283 | } else { | 280 | } else { |
@@ -285,6 +282,13 @@ impl ast::RecordExprField { | |||
285 | } | 282 | } |
286 | } | 283 | } |
287 | 284 | ||
285 | pub fn for_name_ref(name_ref: &ast::NameRef) -> Option<ast::RecordExprField> { | ||
286 | let syn = name_ref.syntax(); | ||
287 | syn.parent() | ||
288 | .and_then(ast::RecordExprField::cast) | ||
289 | .or_else(|| syn.ancestors().nth(4).and_then(ast::RecordExprField::cast)) | ||
290 | } | ||
291 | |||
288 | /// Deals with field init shorthand | 292 | /// Deals with field init shorthand |
289 | pub fn field_name(&self) -> Option<ast::NameRef> { | 293 | pub fn field_name(&self) -> Option<ast::NameRef> { |
290 | if let Some(name_ref) = self.name_ref() { | 294 | if let Some(name_ref) = self.name_ref() { |
@@ -294,6 +298,7 @@ impl ast::RecordExprField { | |||
294 | } | 298 | } |
295 | } | 299 | } |
296 | 300 | ||
301 | #[derive(Debug, Clone, PartialEq)] | ||
297 | pub enum NameOrNameRef { | 302 | pub enum NameOrNameRef { |
298 | Name(ast::Name), | 303 | Name(ast::Name), |
299 | NameRef(ast::NameRef), | 304 | NameRef(ast::NameRef), |
@@ -309,6 +314,23 @@ impl fmt::Display for NameOrNameRef { | |||
309 | } | 314 | } |
310 | 315 | ||
311 | impl ast::RecordPatField { | 316 | impl ast::RecordPatField { |
317 | pub fn for_field_name_ref(field_name: &ast::NameRef) -> Option<ast::RecordPatField> { | ||
318 | let candidate = field_name.syntax().parent().and_then(ast::RecordPatField::cast)?; | ||
319 | match candidate.field_name()? { | ||
320 | NameOrNameRef::NameRef(name_ref) if name_ref == *field_name => Some(candidate), | ||
321 | _ => None, | ||
322 | } | ||
323 | } | ||
324 | |||
325 | pub fn for_field_name(field_name: &ast::Name) -> Option<ast::RecordPatField> { | ||
326 | let candidate = | ||
327 | field_name.syntax().ancestors().nth(3).and_then(ast::RecordPatField::cast)?; | ||
328 | match candidate.field_name()? { | ||
329 | NameOrNameRef::Name(name) if name == *field_name => Some(candidate), | ||
330 | _ => None, | ||
331 | } | ||
332 | } | ||
333 | |||
312 | /// Deals with field init shorthand | 334 | /// Deals with field init shorthand |
313 | pub fn field_name(&self) -> Option<NameOrNameRef> { | 335 | pub fn field_name(&self) -> Option<NameOrNameRef> { |
314 | if let Some(name_ref) = self.name_ref() { | 336 | if let Some(name_ref) = self.name_ref() { |