From d644728d82df10b034d0ea736590c781afa2ba15 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 7 Feb 2021 18:38:12 +0100 Subject: Refactor reference searching to work with the ast --- crates/syntax/src/ast/node_ext.rs | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'crates/syntax') 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 { impl ast::RecordExprField { pub fn for_field_name(field_name: &ast::NameRef) -> Option { - let candidate = - field_name.syntax().parent().and_then(ast::RecordExprField::cast).or_else(|| { - field_name.syntax().ancestors().nth(4).and_then(ast::RecordExprField::cast) - })?; + let candidate = Self::for_name_ref(field_name)?; if candidate.field_name().as_ref() == Some(field_name) { Some(candidate) } else { @@ -285,6 +282,13 @@ impl ast::RecordExprField { } } + pub fn for_name_ref(name_ref: &ast::NameRef) -> Option { + let syn = name_ref.syntax(); + syn.parent() + .and_then(ast::RecordExprField::cast) + .or_else(|| syn.ancestors().nth(4).and_then(ast::RecordExprField::cast)) + } + /// Deals with field init shorthand pub fn field_name(&self) -> Option { if let Some(name_ref) = self.name_ref() { @@ -294,6 +298,7 @@ impl ast::RecordExprField { } } +#[derive(Debug, Clone, PartialEq)] pub enum NameOrNameRef { Name(ast::Name), NameRef(ast::NameRef), @@ -309,6 +314,23 @@ impl fmt::Display for NameOrNameRef { } impl ast::RecordPatField { + pub fn for_field_name_ref(field_name: &ast::NameRef) -> Option { + let candidate = field_name.syntax().parent().and_then(ast::RecordPatField::cast)?; + match candidate.field_name()? { + NameOrNameRef::NameRef(name_ref) if name_ref == *field_name => Some(candidate), + _ => None, + } + } + + pub fn for_field_name(field_name: &ast::Name) -> Option { + let candidate = + field_name.syntax().ancestors().nth(3).and_then(ast::RecordPatField::cast)?; + match candidate.field_name()? { + NameOrNameRef::Name(name) if name == *field_name => Some(candidate), + _ => None, + } + } + /// Deals with field init shorthand pub fn field_name(&self) -> Option { if let Some(name_ref) = self.name_ref() { -- cgit v1.2.3