diff options
Diffstat (limited to 'crates/ra_syntax/src/ast/extensions.rs')
-rw-r--r-- | crates/ra_syntax/src/ast/extensions.rs | 64 |
1 files changed, 35 insertions, 29 deletions
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs index 72a30232d..5420f67ff 100644 --- a/crates/ra_syntax/src/ast/extensions.rs +++ b/crates/ra_syntax/src/ast/extensions.rs | |||
@@ -4,7 +4,7 @@ | |||
4 | use itertools::Itertools; | 4 | use itertools::Itertools; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | ast::{self, child_opt, children, AstNode}, | 7 | ast::{self, child_opt, children, AstNode, SyntaxNode}, |
8 | SmolStr, SyntaxElement, | 8 | SmolStr, SyntaxElement, |
9 | SyntaxKind::*, | 9 | SyntaxKind::*, |
10 | SyntaxToken, T, | 10 | SyntaxToken, T, |
@@ -13,15 +13,20 @@ use ra_parser::SyntaxKind; | |||
13 | 13 | ||
14 | impl ast::Name { | 14 | impl ast::Name { |
15 | pub fn text(&self) -> &SmolStr { | 15 | pub fn text(&self) -> &SmolStr { |
16 | let ident = self.syntax().first_child_or_token().unwrap().as_token().unwrap(); | 16 | text_of_first_token(self.syntax()) |
17 | ident.text() | ||
18 | } | 17 | } |
19 | } | 18 | } |
20 | 19 | ||
21 | impl ast::NameRef { | 20 | impl ast::NameRef { |
22 | pub fn text(&self) -> &SmolStr { | 21 | pub fn text(&self) -> &SmolStr { |
23 | let ident = self.syntax().first_child_or_token().unwrap().as_token().unwrap(); | 22 | text_of_first_token(self.syntax()) |
24 | ident.text() | 23 | } |
24 | } | ||
25 | |||
26 | fn text_of_first_token(node: &SyntaxNode) -> &SmolStr { | ||
27 | match node.0.green().children().first() { | ||
28 | Some(rowan::GreenElement::Token(it)) => it.text(), | ||
29 | _ => panic!(), | ||
25 | } | 30 | } |
26 | } | 31 | } |
27 | 32 | ||
@@ -50,10 +55,10 @@ impl ast::Attr { | |||
50 | } | 55 | } |
51 | } | 56 | } |
52 | 57 | ||
53 | pub fn as_call(&self) -> Option<(SmolStr, &ast::TokenTree)> { | 58 | pub fn as_call(&self) -> Option<(SmolStr, ast::TokenTree)> { |
54 | let tt = self.value()?; | 59 | let tt = self.value()?; |
55 | let (_bra, attr, args, _ket) = tt.syntax().children_with_tokens().collect_tuple()?; | 60 | let (_bra, attr, args, _ket) = tt.syntax().children_with_tokens().collect_tuple()?; |
56 | let args = ast::TokenTree::cast(args.as_node()?)?; | 61 | let args = ast::TokenTree::cast(args.as_node()?.clone())?; |
57 | if attr.kind() == IDENT { | 62 | if attr.kind() == IDENT { |
58 | Some((attr.as_token()?.text().clone(), args)) | 63 | Some((attr.as_token()?.text().clone(), args)) |
59 | } else { | 64 | } else { |
@@ -86,16 +91,16 @@ impl ast::Attr { | |||
86 | } | 91 | } |
87 | } | 92 | } |
88 | 93 | ||
89 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 94 | #[derive(Debug, Clone, PartialEq, Eq)] |
90 | pub enum PathSegmentKind<'a> { | 95 | pub enum PathSegmentKind { |
91 | Name(&'a ast::NameRef), | 96 | Name(ast::NameRef), |
92 | SelfKw, | 97 | SelfKw, |
93 | SuperKw, | 98 | SuperKw, |
94 | CrateKw, | 99 | CrateKw, |
95 | } | 100 | } |
96 | 101 | ||
97 | impl ast::PathSegment { | 102 | impl ast::PathSegment { |
98 | pub fn parent_path(&self) -> &ast::Path { | 103 | pub fn parent_path(&self) -> ast::Path { |
99 | self.syntax() | 104 | self.syntax() |
100 | .parent() | 105 | .parent() |
101 | .and_then(ast::Path::cast) | 106 | .and_then(ast::Path::cast) |
@@ -125,7 +130,7 @@ impl ast::PathSegment { | |||
125 | } | 130 | } |
126 | 131 | ||
127 | impl ast::Path { | 132 | impl ast::Path { |
128 | pub fn parent_path(&self) -> Option<&ast::Path> { | 133 | pub fn parent_path(&self) -> Option<ast::Path> { |
129 | self.syntax().parent().and_then(ast::Path::cast) | 134 | self.syntax().parent().and_then(ast::Path::cast) |
130 | } | 135 | } |
131 | } | 136 | } |
@@ -146,7 +151,7 @@ impl ast::UseTree { | |||
146 | } | 151 | } |
147 | 152 | ||
148 | impl ast::UseTreeList { | 153 | impl ast::UseTreeList { |
149 | pub fn parent_use_tree(&self) -> &ast::UseTree { | 154 | pub fn parent_use_tree(&self) -> ast::UseTree { |
150 | self.syntax() | 155 | self.syntax() |
151 | .parent() | 156 | .parent() |
152 | .and_then(ast::UseTree::cast) | 157 | .and_then(ast::UseTree::cast) |
@@ -155,21 +160,21 @@ impl ast::UseTreeList { | |||
155 | } | 160 | } |
156 | 161 | ||
157 | impl ast::ImplBlock { | 162 | impl ast::ImplBlock { |
158 | pub fn target_type(&self) -> Option<&ast::TypeRef> { | 163 | pub fn target_type(&self) -> Option<ast::TypeRef> { |
159 | match self.target() { | 164 | match self.target() { |
160 | (Some(t), None) | (_, Some(t)) => Some(t), | 165 | (Some(t), None) | (_, Some(t)) => Some(t), |
161 | _ => None, | 166 | _ => None, |
162 | } | 167 | } |
163 | } | 168 | } |
164 | 169 | ||
165 | pub fn target_trait(&self) -> Option<&ast::TypeRef> { | 170 | pub fn target_trait(&self) -> Option<ast::TypeRef> { |
166 | match self.target() { | 171 | match self.target() { |
167 | (Some(t), Some(_)) => Some(t), | 172 | (Some(t), Some(_)) => Some(t), |
168 | _ => None, | 173 | _ => None, |
169 | } | 174 | } |
170 | } | 175 | } |
171 | 176 | ||
172 | fn target(&self) -> (Option<&ast::TypeRef>, Option<&ast::TypeRef>) { | 177 | fn target(&self) -> (Option<ast::TypeRef>, Option<ast::TypeRef>) { |
173 | let mut types = children(self); | 178 | let mut types = children(self); |
174 | let first = types.next(); | 179 | let first = types.next(); |
175 | let second = types.next(); | 180 | let second = types.next(); |
@@ -182,13 +187,13 @@ impl ast::ImplBlock { | |||
182 | } | 187 | } |
183 | 188 | ||
184 | #[derive(Debug, Clone, PartialEq, Eq)] | 189 | #[derive(Debug, Clone, PartialEq, Eq)] |
185 | pub enum StructKind<'a> { | 190 | pub enum StructKind { |
186 | Tuple(&'a ast::PosFieldDefList), | 191 | Tuple(ast::PosFieldDefList), |
187 | Named(&'a ast::NamedFieldDefList), | 192 | Named(ast::NamedFieldDefList), |
188 | Unit, | 193 | Unit, |
189 | } | 194 | } |
190 | 195 | ||
191 | impl StructKind<'_> { | 196 | impl StructKind { |
192 | fn from_node<N: AstNode>(node: &N) -> StructKind { | 197 | fn from_node<N: AstNode>(node: &N) -> StructKind { |
193 | if let Some(nfdl) = child_opt::<_, ast::NamedFieldDefList>(node) { | 198 | if let Some(nfdl) = child_opt::<_, ast::NamedFieldDefList>(node) { |
194 | StructKind::Named(nfdl) | 199 | StructKind::Named(nfdl) |
@@ -218,7 +223,7 @@ impl ast::StructDef { | |||
218 | } | 223 | } |
219 | 224 | ||
220 | impl ast::EnumVariant { | 225 | impl ast::EnumVariant { |
221 | pub fn parent_enum(&self) -> &ast::EnumDef { | 226 | pub fn parent_enum(&self) -> ast::EnumDef { |
222 | self.syntax() | 227 | self.syntax() |
223 | .parent() | 228 | .parent() |
224 | .and_then(|it| it.parent()) | 229 | .and_then(|it| it.parent()) |
@@ -231,10 +236,10 @@ impl ast::EnumVariant { | |||
231 | } | 236 | } |
232 | 237 | ||
233 | impl ast::FnDef { | 238 | impl ast::FnDef { |
234 | pub fn semicolon_token(&self) -> Option<SyntaxToken<'_>> { | 239 | pub fn semicolon_token(&self) -> Option<SyntaxToken> { |
235 | self.syntax() | 240 | self.syntax() |
236 | .last_child_or_token() | 241 | .last_child_or_token() |
237 | .and_then(|it| it.as_token()) | 242 | .and_then(|it| it.as_token().cloned()) |
238 | .filter(|it| it.kind() == T![;]) | 243 | .filter(|it| it.kind() == T![;]) |
239 | } | 244 | } |
240 | } | 245 | } |
@@ -258,9 +263,9 @@ impl ast::ExprStmt { | |||
258 | } | 263 | } |
259 | 264 | ||
260 | #[derive(Debug, Clone, PartialEq, Eq)] | 265 | #[derive(Debug, Clone, PartialEq, Eq)] |
261 | pub enum FieldKind<'a> { | 266 | pub enum FieldKind { |
262 | Name(&'a ast::NameRef), | 267 | Name(ast::NameRef), |
263 | Index(SyntaxToken<'a>), | 268 | Index(SyntaxToken), |
264 | } | 269 | } |
265 | 270 | ||
266 | impl ast::FieldExpr { | 271 | impl ast::FieldExpr { |
@@ -271,6 +276,7 @@ impl ast::FieldExpr { | |||
271 | .find(|c| c.kind() == SyntaxKind::INT_NUMBER || c.kind() == SyntaxKind::FLOAT_NUMBER) | 276 | .find(|c| c.kind() == SyntaxKind::INT_NUMBER || c.kind() == SyntaxKind::FLOAT_NUMBER) |
272 | .as_ref() | 277 | .as_ref() |
273 | .and_then(SyntaxElement::as_token) | 278 | .and_then(SyntaxElement::as_token) |
279 | .cloned() | ||
274 | } | 280 | } |
275 | 281 | ||
276 | pub fn field_access(&self) -> Option<FieldKind> { | 282 | pub fn field_access(&self) -> Option<FieldKind> { |
@@ -326,7 +332,7 @@ impl ast::SelfParam { | |||
326 | pub fn self_kw_token(&self) -> SyntaxToken { | 332 | pub fn self_kw_token(&self) -> SyntaxToken { |
327 | self.syntax() | 333 | self.syntax() |
328 | .children_with_tokens() | 334 | .children_with_tokens() |
329 | .filter_map(|it| it.as_token()) | 335 | .filter_map(|it| it.as_token().cloned()) |
330 | .find(|it| it.kind() == T![self]) | 336 | .find(|it| it.kind() == T![self]) |
331 | .expect("invalid tree: self param must have self") | 337 | .expect("invalid tree: self param must have self") |
332 | } | 338 | } |
@@ -355,7 +361,7 @@ impl ast::LifetimeParam { | |||
355 | pub fn lifetime_token(&self) -> Option<SyntaxToken> { | 361 | pub fn lifetime_token(&self) -> Option<SyntaxToken> { |
356 | self.syntax() | 362 | self.syntax() |
357 | .children_with_tokens() | 363 | .children_with_tokens() |
358 | .filter_map(|it| it.as_token()) | 364 | .filter_map(|it| it.as_token().cloned()) |
359 | .find(|it| it.kind() == LIFETIME) | 365 | .find(|it| it.kind() == LIFETIME) |
360 | } | 366 | } |
361 | } | 367 | } |
@@ -364,7 +370,7 @@ impl ast::WherePred { | |||
364 | pub fn lifetime_token(&self) -> Option<SyntaxToken> { | 370 | pub fn lifetime_token(&self) -> Option<SyntaxToken> { |
365 | self.syntax() | 371 | self.syntax() |
366 | .children_with_tokens() | 372 | .children_with_tokens() |
367 | .filter_map(|it| it.as_token()) | 373 | .filter_map(|it| it.as_token().cloned()) |
368 | .find(|it| it.kind() == LIFETIME) | 374 | .find(|it| it.kind() == LIFETIME) |
369 | } | 375 | } |
370 | } | 376 | } |