aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax/src/ast
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-02-12 18:01:36 +0000
committerGitHub <[email protected]>2021-02-12 18:01:36 +0000
commit88253907f4bc3beaa7b8f2e58cb652f653f92d56 (patch)
tree1669ff0e6ab614c679f245f84d0f9a8202366e0e /crates/syntax/src/ast
parent4d51b5644458c7dcb97a4d445f1b379cd2548a78 (diff)
parentfd6cf4d566174dbdb50259bbbfdaf5a12f81544d (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.rs30
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
275impl ast::RecordExprField { 275impl 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)]
297pub enum NameOrNameRef { 302pub 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
311impl ast::RecordPatField { 316impl 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() {