diff options
Diffstat (limited to 'crates/syntax')
-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() { |