aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/ast/node_ext.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/ast/node_ext.rs')
-rw-r--r--crates/ra_syntax/src/ast/node_ext.rs99
1 files changed, 57 insertions, 42 deletions
diff --git a/crates/ra_syntax/src/ast/node_ext.rs b/crates/ra_syntax/src/ast/node_ext.rs
index 242900643..bba7310ad 100644
--- a/crates/ra_syntax/src/ast/node_ext.rs
+++ b/crates/ra_syntax/src/ast/node_ext.rs
@@ -7,7 +7,7 @@ use itertools::Itertools;
7use ra_parser::SyntaxKind; 7use ra_parser::SyntaxKind;
8 8
9use crate::{ 9use crate::{
10 ast::{self, support, AstNode, AttrInput, NameOwner, SyntaxNode}, 10 ast::{self, support, AstNode, NameOwner, SyntaxNode},
11 SmolStr, SyntaxElement, SyntaxToken, T, 11 SmolStr, SyntaxElement, SyntaxToken, T,
12}; 12};
13 13
@@ -39,29 +39,23 @@ pub enum AttrKind {
39 39
40impl ast::Attr { 40impl ast::Attr {
41 pub fn as_simple_atom(&self) -> Option<SmolStr> { 41 pub fn as_simple_atom(&self) -> Option<SmolStr> {
42 match self.input() { 42 if self.eq_token().is_some() || self.token_tree().is_some() {
43 None => self.simple_name(), 43 return None;
44 Some(_) => None,
45 } 44 }
45 self.simple_name()
46 } 46 }
47 47
48 pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> { 48 pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
49 match self.input() { 49 let tt = self.token_tree()?;
50 Some(AttrInput::TokenTree(tt)) => Some((self.simple_name()?, tt)), 50 Some((self.simple_name()?, tt))
51 _ => None,
52 }
53 } 51 }
54 52
55 pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> { 53 pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> {
56 match self.input() { 54 let lit = self.literal()?;
57 Some(AttrInput::Literal(lit)) => { 55 let key = self.simple_name()?;
58 let key = self.simple_name()?; 56 // FIXME: escape? raw string?
59 // FIXME: escape? raw string? 57 let value = lit.syntax().first_token()?.text().trim_matches('"').into();
60 let value = lit.syntax().first_token()?.text().trim_matches('"').into(); 58 Some((key, value))
61 Some((key, value))
62 }
63 _ => None,
64 }
65 } 59 }
66 60
67 pub fn simple_name(&self) -> Option<SmolStr> { 61 pub fn simple_name(&self) -> Option<SmolStr> {
@@ -141,7 +135,7 @@ impl ast::UseTreeList {
141 } 135 }
142} 136}
143 137
144impl ast::ImplDef { 138impl ast::Impl {
145 pub fn target_type(&self) -> Option<ast::TypeRef> { 139 pub fn target_type(&self) -> Option<ast::TypeRef> {
146 match self.target() { 140 match self.target() {
147 (Some(t), None) | (_, Some(t)) => Some(t), 141 (Some(t), None) | (_, Some(t)) => Some(t),
@@ -166,16 +160,16 @@ impl ast::ImplDef {
166 160
167#[derive(Debug, Clone, PartialEq, Eq)] 161#[derive(Debug, Clone, PartialEq, Eq)]
168pub enum StructKind { 162pub enum StructKind {
169 Record(ast::RecordFieldDefList), 163 Record(ast::RecordFieldList),
170 Tuple(ast::TupleFieldDefList), 164 Tuple(ast::TupleFieldList),
171 Unit, 165 Unit,
172} 166}
173 167
174impl StructKind { 168impl StructKind {
175 fn from_node<N: AstNode>(node: &N) -> StructKind { 169 fn from_node<N: AstNode>(node: &N) -> StructKind {
176 if let Some(nfdl) = support::child::<ast::RecordFieldDefList>(node.syntax()) { 170 if let Some(nfdl) = support::child::<ast::RecordFieldList>(node.syntax()) {
177 StructKind::Record(nfdl) 171 StructKind::Record(nfdl)
178 } else if let Some(pfl) = support::child::<ast::TupleFieldDefList>(node.syntax()) { 172 } else if let Some(pfl) = support::child::<ast::TupleFieldList>(node.syntax()) {
179 StructKind::Tuple(pfl) 173 StructKind::Tuple(pfl)
180 } else { 174 } else {
181 StructKind::Unit 175 StructKind::Unit
@@ -183,17 +177,17 @@ impl StructKind {
183 } 177 }
184} 178}
185 179
186impl ast::StructDef { 180impl ast::Struct {
187 pub fn kind(&self) -> StructKind { 181 pub fn kind(&self) -> StructKind {
188 StructKind::from_node(self) 182 StructKind::from_node(self)
189 } 183 }
190} 184}
191 185
192impl ast::RecordField { 186impl ast::RecordExprField {
193 pub fn for_field_name(field_name: &ast::NameRef) -> Option<ast::RecordField> { 187 pub fn for_field_name(field_name: &ast::NameRef) -> Option<ast::RecordExprField> {
194 let candidate = 188 let candidate =
195 field_name.syntax().parent().and_then(ast::RecordField::cast).or_else(|| { 189 field_name.syntax().parent().and_then(ast::RecordExprField::cast).or_else(|| {
196 field_name.syntax().ancestors().nth(4).and_then(ast::RecordField::cast) 190 field_name.syntax().ancestors().nth(4).and_then(ast::RecordExprField::cast)
197 })?; 191 })?;
198 if candidate.field_name().as_ref() == Some(field_name) { 192 if candidate.field_name().as_ref() == Some(field_name) {
199 Some(candidate) 193 Some(candidate)
@@ -247,12 +241,12 @@ impl ast::RecordFieldPat {
247 } 241 }
248} 242}
249 243
250impl ast::EnumVariant { 244impl ast::Variant {
251 pub fn parent_enum(&self) -> ast::EnumDef { 245 pub fn parent_enum(&self) -> ast::Enum {
252 self.syntax() 246 self.syntax()
253 .parent() 247 .parent()
254 .and_then(|it| it.parent()) 248 .and_then(|it| it.parent())
255 .and_then(ast::EnumDef::cast) 249 .and_then(ast::Enum::cast)
256 .expect("EnumVariants are always nested in Enums") 250 .expect("EnumVariants are always nested in Enums")
257 } 251 }
258 pub fn kind(&self) -> StructKind { 252 pub fn kind(&self) -> StructKind {
@@ -473,18 +467,39 @@ impl ast::TokenTree {
473 } 467 }
474} 468}
475 469
470impl ast::GenericParamList {
471 pub fn lifetime_params(&self) -> impl Iterator<Item = ast::LifetimeParam> {
472 self.generic_params().filter_map(|param| match param {
473 ast::GenericParam::LifetimeParam(it) => Some(it),
474 ast::GenericParam::TypeParam(_) | ast::GenericParam::ConstParam(_) => None,
475 })
476 }
477 pub fn type_params(&self) -> impl Iterator<Item = ast::TypeParam> {
478 self.generic_params().filter_map(|param| match param {
479 ast::GenericParam::TypeParam(it) => Some(it),
480 ast::GenericParam::LifetimeParam(_) | ast::GenericParam::ConstParam(_) => None,
481 })
482 }
483 pub fn const_params(&self) -> impl Iterator<Item = ast::ConstParam> {
484 self.generic_params().filter_map(|param| match param {
485 ast::GenericParam::ConstParam(it) => Some(it),
486 ast::GenericParam::TypeParam(_) | ast::GenericParam::LifetimeParam(_) => None,
487 })
488 }
489}
490
476impl ast::DocCommentsOwner for ast::SourceFile {} 491impl ast::DocCommentsOwner for ast::SourceFile {}
477impl ast::DocCommentsOwner for ast::FnDef {} 492impl ast::DocCommentsOwner for ast::Fn {}
478impl ast::DocCommentsOwner for ast::StructDef {} 493impl ast::DocCommentsOwner for ast::Struct {}
479impl ast::DocCommentsOwner for ast::UnionDef {} 494impl ast::DocCommentsOwner for ast::Union {}
480impl ast::DocCommentsOwner for ast::RecordFieldDef {} 495impl ast::DocCommentsOwner for ast::RecordField {}
481impl ast::DocCommentsOwner for ast::TupleFieldDef {} 496impl ast::DocCommentsOwner for ast::TupleField {}
482impl ast::DocCommentsOwner for ast::EnumDef {} 497impl ast::DocCommentsOwner for ast::Enum {}
483impl ast::DocCommentsOwner for ast::EnumVariant {} 498impl ast::DocCommentsOwner for ast::Variant {}
484impl ast::DocCommentsOwner for ast::TraitDef {} 499impl ast::DocCommentsOwner for ast::Trait {}
485impl ast::DocCommentsOwner for ast::Module {} 500impl ast::DocCommentsOwner for ast::Module {}
486impl ast::DocCommentsOwner for ast::StaticDef {} 501impl ast::DocCommentsOwner for ast::Static {}
487impl ast::DocCommentsOwner for ast::ConstDef {} 502impl ast::DocCommentsOwner for ast::Const {}
488impl ast::DocCommentsOwner for ast::TypeAliasDef {} 503impl ast::DocCommentsOwner for ast::TypeAlias {}
489impl ast::DocCommentsOwner for ast::ImplDef {} 504impl ast::DocCommentsOwner for ast::Impl {}
490impl ast::DocCommentsOwner for ast::MacroCall {} 505impl ast::DocCommentsOwner for ast::MacroCall {}