aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/ast/extensions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/ast/extensions.rs')
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs90
1 files changed, 36 insertions, 54 deletions
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index b50a89864..76b7655e6 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -5,9 +5,7 @@ use itertools::Itertools;
5use ra_parser::SyntaxKind; 5use ra_parser::SyntaxKind;
6 6
7use crate::{ 7use crate::{
8 ast::{ 8 ast::{self, support, AstNode, AttrInput, NameOwner, SyntaxNode},
9 self, child_opt, children, support, AstNode, AstToken, AttrInput, NameOwner, SyntaxNode,
10 },
11 SmolStr, SyntaxElement, SyntaxToken, T, 9 SmolStr, SyntaxElement, SyntaxToken, T,
12}; 10};
13 11
@@ -23,11 +21,7 @@ impl ast::NameRef {
23 } 21 }
24 22
25 pub fn as_tuple_field(&self) -> Option<usize> { 23 pub fn as_tuple_field(&self) -> Option<usize> {
26 if let Some(ast::NameRefToken::IntNumber(token)) = self.name_ref_token_token() { 24 self.text().parse().ok()
27 token.text().as_str().parse().ok()
28 } else {
29 None
30 }
31 } 25 }
32} 26}
33 27
@@ -83,7 +77,7 @@ impl ast::Attr {
83 first_token.and_then(|token| token.next_token()).as_ref().map(SyntaxToken::kind); 77 first_token.and_then(|token| token.next_token()).as_ref().map(SyntaxToken::kind);
84 78
85 match (first_token_kind, second_token_kind) { 79 match (first_token_kind, second_token_kind) {
86 (Some(SyntaxKind::POUND), Some(SyntaxKind::EXCL)) => AttrKind::Inner, 80 (Some(SyntaxKind::POUND), Some(T![!])) => AttrKind::Inner,
87 _ => AttrKind::Outer, 81 _ => AttrKind::Outer,
88 } 82 }
89 } 83 }
@@ -161,7 +155,7 @@ impl ast::ImplDef {
161 } 155 }
162 156
163 fn target(&self) -> (Option<ast::TypeRef>, Option<ast::TypeRef>) { 157 fn target(&self) -> (Option<ast::TypeRef>, Option<ast::TypeRef>) {
164 let mut types = children(self); 158 let mut types = support::children(self.syntax());
165 let first = types.next(); 159 let first = types.next();
166 let second = types.next(); 160 let second = types.next();
167 (first, second) 161 (first, second)
@@ -177,9 +171,9 @@ pub enum StructKind {
177 171
178impl StructKind { 172impl StructKind {
179 fn from_node<N: AstNode>(node: &N) -> StructKind { 173 fn from_node<N: AstNode>(node: &N) -> StructKind {
180 if let Some(nfdl) = child_opt::<_, ast::RecordFieldDefList>(node) { 174 if let Some(nfdl) = support::child::<ast::RecordFieldDefList>(node.syntax()) {
181 StructKind::Record(nfdl) 175 StructKind::Record(nfdl)
182 } else if let Some(pfl) = child_opt::<_, ast::TupleFieldDefList>(node) { 176 } else if let Some(pfl) = support::child::<ast::TupleFieldDefList>(node.syntax()) {
183 StructKind::Tuple(pfl) 177 StructKind::Tuple(pfl)
184 } else { 178 } else {
185 StructKind::Unit 179 StructKind::Unit
@@ -281,7 +275,7 @@ pub enum SelfParamKind {
281impl ast::SelfParam { 275impl ast::SelfParam {
282 pub fn kind(&self) -> SelfParamKind { 276 pub fn kind(&self) -> SelfParamKind {
283 if self.amp_token().is_some() { 277 if self.amp_token().is_some() {
284 if self.amp_mut_kw_token().is_some() { 278 if self.mut_token().is_some() {
285 SelfParamKind::MutRef 279 SelfParamKind::MutRef
286 } else { 280 } else {
287 SelfParamKind::Ref 281 SelfParamKind::Ref
@@ -290,24 +284,6 @@ impl ast::SelfParam {
290 SelfParamKind::Owned 284 SelfParamKind::Owned
291 } 285 }
292 } 286 }
293
294 /// the "mut" in "mut self", not the one in "&mut self"
295 pub fn mut_kw_token(&self) -> Option<ast::MutKw> {
296 self.syntax()
297 .children_with_tokens()
298 .filter_map(|it| it.into_token())
299 .take_while(|it| it.kind() != T![&])
300 .find_map(ast::MutKw::cast)
301 }
302
303 /// the "mut" in "&mut self", not the one in "mut self"
304 pub fn amp_mut_kw_token(&self) -> Option<ast::MutKw> {
305 self.syntax()
306 .children_with_tokens()
307 .filter_map(|it| it.into_token())
308 .skip_while(|it| it.kind() != T![&])
309 .find_map(ast::MutKw::cast)
310 }
311} 287}
312 288
313#[derive(Clone, Debug, PartialEq, Eq, Hash)] 289#[derive(Clone, Debug, PartialEq, Eq, Hash)]
@@ -317,14 +293,14 @@ pub enum TypeBoundKind {
317 /// for<'a> ... 293 /// for<'a> ...
318 ForType(ast::ForType), 294 ForType(ast::ForType),
319 /// 'a 295 /// 'a
320 Lifetime(ast::Lifetime), 296 Lifetime(SyntaxToken),
321} 297}
322 298
323impl ast::TypeBound { 299impl ast::TypeBound {
324 pub fn kind(&self) -> TypeBoundKind { 300 pub fn kind(&self) -> TypeBoundKind {
325 if let Some(path_type) = children(self).next() { 301 if let Some(path_type) = support::children(self.syntax()).next() {
326 TypeBoundKind::PathType(path_type) 302 TypeBoundKind::PathType(path_type)
327 } else if let Some(for_type) = children(self).next() { 303 } else if let Some(for_type) = support::children(self.syntax()).next() {
328 TypeBoundKind::ForType(for_type) 304 TypeBoundKind::ForType(for_type)
329 } else if let Some(lifetime) = self.lifetime_token() { 305 } else if let Some(lifetime) = self.lifetime_token() {
330 TypeBoundKind::Lifetime(lifetime) 306 TypeBoundKind::Lifetime(lifetime)
@@ -333,23 +309,23 @@ impl ast::TypeBound {
333 } 309 }
334 } 310 }
335 311
336 pub fn const_question_token(&self) -> Option<ast::Question> { 312 pub fn const_question_token(&self) -> Option<SyntaxToken> {
337 self.syntax() 313 self.syntax()
338 .children_with_tokens() 314 .children_with_tokens()
339 .filter_map(|it| it.into_token()) 315 .filter_map(|it| it.into_token())
340 .take_while(|it| it.kind() != T![const]) 316 .take_while(|it| it.kind() != T![const])
341 .find_map(ast::Question::cast) 317 .find(|it| it.kind() == T![?])
342 } 318 }
343 319
344 pub fn question_token(&self) -> Option<ast::Question> { 320 pub fn question_token(&self) -> Option<SyntaxToken> {
345 if self.const_kw_token().is_some() { 321 if self.const_token().is_some() {
346 self.syntax() 322 self.syntax()
347 .children_with_tokens() 323 .children_with_tokens()
348 .filter_map(|it| it.into_token()) 324 .filter_map(|it| it.into_token())
349 .skip_while(|it| it.kind() != T![const]) 325 .skip_while(|it| it.kind() != T![const])
350 .find_map(ast::Question::cast) 326 .find(|it| it.kind() == T![?])
351 } else { 327 } else {
352 support::token(&self.syntax) 328 support::token(&self.syntax, T![?])
353 } 329 }
354 } 330 }
355} 331}
@@ -364,13 +340,13 @@ pub enum VisibilityKind {
364 340
365impl ast::Visibility { 341impl ast::Visibility {
366 pub fn kind(&self) -> VisibilityKind { 342 pub fn kind(&self) -> VisibilityKind {
367 if let Some(path) = children(self).next() { 343 if let Some(path) = support::children(self.syntax()).next() {
368 VisibilityKind::In(path) 344 VisibilityKind::In(path)
369 } else if self.crate_kw_token().is_some() { 345 } else if self.crate_token().is_some() {
370 VisibilityKind::PubCrate 346 VisibilityKind::PubCrate
371 } else if self.super_kw_token().is_some() { 347 } else if self.super_token().is_some() {
372 VisibilityKind::PubSuper 348 VisibilityKind::PubSuper
373 } else if self.self_kw_token().is_some() { 349 } else if self.self_token().is_some() {
374 VisibilityKind::PubSuper 350 VisibilityKind::PubSuper
375 } else { 351 } else {
376 VisibilityKind::Pub 352 VisibilityKind::Pub
@@ -390,12 +366,12 @@ impl ast::MacroCall {
390} 366}
391 367
392impl ast::LifetimeParam { 368impl ast::LifetimeParam {
393 pub fn lifetime_bounds(&self) -> impl Iterator<Item = ast::Lifetime> { 369 pub fn lifetime_bounds(&self) -> impl Iterator<Item = SyntaxToken> {
394 self.syntax() 370 self.syntax()
395 .children_with_tokens() 371 .children_with_tokens()
396 .filter_map(|it| it.into_token()) 372 .filter_map(|it| it.into_token())
397 .skip_while(|x| x.kind() != T![:]) 373 .skip_while(|x| x.kind() != T![:])
398 .filter_map(ast::Lifetime::cast) 374 .filter(|it| it.kind() == T![lifetime])
399 } 375 }
400} 376}
401 377
@@ -403,7 +379,7 @@ impl ast::RangePat {
403 pub fn start(&self) -> Option<ast::Pat> { 379 pub fn start(&self) -> Option<ast::Pat> {
404 self.syntax() 380 self.syntax()
405 .children_with_tokens() 381 .children_with_tokens()
406 .take_while(|it| !ast::RangeSeparator::can_cast(it.kind())) 382 .take_while(|it| !(it.kind() == T![..] || it.kind() == T![..=]))
407 .filter_map(|it| it.into_node()) 383 .filter_map(|it| it.into_node())
408 .find_map(ast::Pat::cast) 384 .find_map(ast::Pat::cast)
409 } 385 }
@@ -411,18 +387,24 @@ impl ast::RangePat {
411 pub fn end(&self) -> Option<ast::Pat> { 387 pub fn end(&self) -> Option<ast::Pat> {
412 self.syntax() 388 self.syntax()
413 .children_with_tokens() 389 .children_with_tokens()
414 .skip_while(|it| !ast::RangeSeparator::can_cast(it.kind())) 390 .skip_while(|it| !(it.kind() == T![..] || it.kind() == T![..=]))
415 .filter_map(|it| it.into_node()) 391 .filter_map(|it| it.into_node())
416 .find_map(ast::Pat::cast) 392 .find_map(ast::Pat::cast)
417 } 393 }
418} 394}
419 395
420impl ast::TokenTree { 396impl ast::TokenTree {
421 pub fn left_delimiter(&self) -> Option<ast::LeftDelimiter> { 397 pub fn left_delimiter_token(&self) -> Option<SyntaxToken> {
422 self.syntax().first_child_or_token()?.into_token().and_then(ast::LeftDelimiter::cast) 398 self.syntax().first_child_or_token()?.into_token().filter(|it| match it.kind() {
423 } 399 T!['{'] | T!['('] | T!['['] => true,
424 400 _ => false,
425 pub fn right_delimiter(&self) -> Option<ast::RightDelimiter> { 401 })
426 self.syntax().last_child_or_token()?.into_token().and_then(ast::RightDelimiter::cast) 402 }
403
404 pub fn right_delimiter_token(&self) -> Option<SyntaxToken> {
405 self.syntax().last_child_or_token()?.into_token().filter(|it| match it.kind() {
406 T!['{'] | T!['('] | T!['['] => true,
407 _ => false,
408 })
427 } 409 }
428} 410}