diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-01 10:30:25 +0100 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-01 10:30:25 +0100 |
commit | 42a883f06c28ddeab22e5703a578f19110dde7f3 (patch) | |
tree | fe57697b54ccfb791fe96c13cb553a8570516270 /crates/ra_syntax/src/ast.rs | |
parent | dec9bde10868b5e459535449476d17a6a0987b3e (diff) | |
parent | 9e213385c9d06db3c8ca20812779e2b8f8ad2c71 (diff) |
Merge #1078
1078: rewrite syntax trees r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_syntax/src/ast.rs')
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 246 |
1 files changed, 161 insertions, 85 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index fd7e63f84..9a44afc67 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -7,7 +7,7 @@ use itertools::Itertools; | |||
7 | 7 | ||
8 | pub use self::generated::*; | 8 | pub use self::generated::*; |
9 | use crate::{ | 9 | use crate::{ |
10 | syntax_node::{SyntaxNode, SyntaxNodeChildren, TreeArc, RaTypes}, | 10 | syntax_node::{SyntaxNode, SyntaxNodeChildren, TreeArc, RaTypes, SyntaxToken, SyntaxElement, SyntaxElementChildren}, |
11 | SmolStr, | 11 | SmolStr, |
12 | SyntaxKind::*, | 12 | SyntaxKind::*, |
13 | }; | 13 | }; |
@@ -27,7 +27,8 @@ pub trait AstNode: | |||
27 | 27 | ||
28 | pub trait AstToken: AstNode { | 28 | pub trait AstToken: AstNode { |
29 | fn text(&self) -> &SmolStr { | 29 | fn text(&self) -> &SmolStr { |
30 | self.syntax().leaf_text().unwrap() | 30 | // self.syntax().leaf_text().unwrap() |
31 | unimplemented!() | ||
31 | } | 32 | } |
32 | } | 33 | } |
33 | 34 | ||
@@ -126,8 +127,8 @@ pub trait AttrsOwner: AstNode { | |||
126 | } | 127 | } |
127 | 128 | ||
128 | pub trait DocCommentsOwner: AstNode { | 129 | pub trait DocCommentsOwner: AstNode { |
129 | fn doc_comments(&self) -> AstChildren<Comment> { | 130 | fn doc_comments(&self) -> CommentIter { |
130 | children(self) | 131 | CommentIter { iter: self.syntax().children_with_tokens() } |
131 | } | 132 | } |
132 | 133 | ||
133 | /// Returns the textual content of a doc comment block as a single string. | 134 | /// Returns the textual content of a doc comment block as a single string. |
@@ -179,9 +180,9 @@ impl Attr { | |||
179 | 180 | ||
180 | pub fn as_atom(&self) -> Option<SmolStr> { | 181 | pub fn as_atom(&self) -> Option<SmolStr> { |
181 | let tt = self.value()?; | 182 | let tt = self.value()?; |
182 | let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?; | 183 | let (_bra, attr, _ket) = tt.syntax().children_with_tokens().collect_tuple()?; |
183 | if attr.kind() == IDENT { | 184 | if attr.kind() == IDENT { |
184 | Some(attr.leaf_text().unwrap().clone()) | 185 | Some(attr.as_token()?.text().clone()) |
185 | } else { | 186 | } else { |
186 | None | 187 | None |
187 | } | 188 | } |
@@ -189,10 +190,10 @@ impl Attr { | |||
189 | 190 | ||
190 | pub fn as_call(&self) -> Option<(SmolStr, &TokenTree)> { | 191 | pub fn as_call(&self) -> Option<(SmolStr, &TokenTree)> { |
191 | let tt = self.value()?; | 192 | let tt = self.value()?; |
192 | let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?; | 193 | let (_bra, attr, args, _ket) = tt.syntax().children_with_tokens().collect_tuple()?; |
193 | let args = TokenTree::cast(args)?; | 194 | let args = TokenTree::cast(args.as_node()?)?; |
194 | if attr.kind() == IDENT { | 195 | if attr.kind() == IDENT { |
195 | Some((attr.leaf_text().unwrap().clone(), args)) | 196 | Some((attr.as_token()?.text().clone(), args)) |
196 | } else { | 197 | } else { |
197 | None | 198 | None |
198 | } | 199 | } |
@@ -200,16 +201,35 @@ impl Attr { | |||
200 | 201 | ||
201 | pub fn as_named(&self) -> Option<SmolStr> { | 202 | pub fn as_named(&self) -> Option<SmolStr> { |
202 | let tt = self.value()?; | 203 | let tt = self.value()?; |
203 | let attr = tt.syntax().children().nth(1)?; | 204 | let attr = tt.syntax().children_with_tokens().nth(1)?; |
204 | if attr.kind() == IDENT { | 205 | if attr.kind() == IDENT { |
205 | Some(attr.leaf_text().unwrap().clone()) | 206 | Some(attr.as_token()?.text().clone()) |
206 | } else { | 207 | } else { |
207 | None | 208 | None |
208 | } | 209 | } |
209 | } | 210 | } |
210 | } | 211 | } |
211 | 212 | ||
212 | impl Comment { | 213 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
214 | pub struct Comment<'a>(SyntaxToken<'a>); | ||
215 | |||
216 | impl<'a> Comment<'a> { | ||
217 | pub fn cast(token: SyntaxToken<'a>) -> Option<Self> { | ||
218 | if token.kind() == COMMENT { | ||
219 | Some(Comment(token)) | ||
220 | } else { | ||
221 | None | ||
222 | } | ||
223 | } | ||
224 | |||
225 | pub fn syntax(&self) -> SyntaxToken<'a> { | ||
226 | self.0 | ||
227 | } | ||
228 | |||
229 | pub fn text(&self) -> &'a SmolStr { | ||
230 | self.0.text() | ||
231 | } | ||
232 | |||
213 | pub fn flavor(&self) -> CommentFlavor { | 233 | pub fn flavor(&self) -> CommentFlavor { |
214 | let text = self.text(); | 234 | let text = self.text(); |
215 | if text.starts_with("///") { | 235 | if text.starts_with("///") { |
@@ -230,13 +250,16 @@ impl Comment { | |||
230 | pub fn prefix(&self) -> &'static str { | 250 | pub fn prefix(&self) -> &'static str { |
231 | self.flavor().prefix() | 251 | self.flavor().prefix() |
232 | } | 252 | } |
253 | } | ||
233 | 254 | ||
234 | pub fn count_newlines_lazy(&self) -> impl Iterator<Item = &()> { | 255 | pub struct CommentIter<'a> { |
235 | self.text().chars().filter(|&c| c == '\n').map(|_| &()) | 256 | iter: SyntaxElementChildren<'a>, |
236 | } | 257 | } |
237 | 258 | ||
238 | pub fn has_newlines(&self) -> bool { | 259 | impl<'a> Iterator for CommentIter<'a> { |
239 | self.count_newlines_lazy().count() > 0 | 260 | type Item = Comment<'a>; |
261 | fn next(&mut self) -> Option<Comment<'a>> { | ||
262 | self.iter.by_ref().find_map(|el| el.as_token().and_then(Comment::cast)) | ||
240 | } | 263 | } |
241 | } | 264 | } |
242 | 265 | ||
@@ -267,27 +290,42 @@ impl CommentFlavor { | |||
267 | } | 290 | } |
268 | } | 291 | } |
269 | 292 | ||
270 | impl Whitespace { | 293 | pub struct Whitespace<'a>(SyntaxToken<'a>); |
271 | pub fn count_newlines_lazy(&self) -> impl Iterator<Item = &()> { | 294 | |
272 | self.text().chars().filter(|&c| c == '\n').map(|_| &()) | 295 | impl<'a> Whitespace<'a> { |
296 | pub fn cast(token: SyntaxToken<'a>) -> Option<Self> { | ||
297 | if token.kind() == WHITESPACE { | ||
298 | Some(Whitespace(token)) | ||
299 | } else { | ||
300 | None | ||
301 | } | ||
302 | } | ||
303 | |||
304 | pub fn syntax(&self) -> SyntaxToken<'a> { | ||
305 | self.0 | ||
273 | } | 306 | } |
274 | 307 | ||
275 | pub fn has_newlines(&self) -> bool { | 308 | pub fn text(&self) -> &'a SmolStr { |
276 | self.text().contains('\n') | 309 | self.0.text() |
310 | } | ||
311 | |||
312 | pub fn spans_multiple_lines(&self) -> bool { | ||
313 | let text = self.text(); | ||
314 | text.find('\n').map_or(false, |idx| text[idx + 1..].contains('\n')) | ||
277 | } | 315 | } |
278 | } | 316 | } |
279 | 317 | ||
280 | impl Name { | 318 | impl Name { |
281 | pub fn text(&self) -> &SmolStr { | 319 | pub fn text(&self) -> &SmolStr { |
282 | let ident = self.syntax().first_child().unwrap(); | 320 | let ident = self.syntax().first_child_or_token().unwrap().as_token().unwrap(); |
283 | ident.leaf_text().unwrap() | 321 | ident.text() |
284 | } | 322 | } |
285 | } | 323 | } |
286 | 324 | ||
287 | impl NameRef { | 325 | impl NameRef { |
288 | pub fn text(&self) -> &SmolStr { | 326 | pub fn text(&self) -> &SmolStr { |
289 | let ident = self.syntax().first_child().unwrap(); | 327 | let ident = self.syntax().first_child_or_token().unwrap().as_token().unwrap(); |
290 | ident.leaf_text().unwrap() | 328 | ident.text() |
291 | } | 329 | } |
292 | } | 330 | } |
293 | 331 | ||
@@ -316,7 +354,7 @@ impl ImplBlock { | |||
316 | 354 | ||
317 | impl Module { | 355 | impl Module { |
318 | pub fn has_semi(&self) -> bool { | 356 | pub fn has_semi(&self) -> bool { |
319 | match self.syntax().last_child() { | 357 | match self.syntax().last_child_or_token() { |
320 | None => false, | 358 | None => false, |
321 | Some(node) => node.kind() == SEMI, | 359 | Some(node) => node.kind() == SEMI, |
322 | } | 360 | } |
@@ -325,7 +363,7 @@ impl Module { | |||
325 | 363 | ||
326 | impl LetStmt { | 364 | impl LetStmt { |
327 | pub fn has_semi(&self) -> bool { | 365 | pub fn has_semi(&self) -> bool { |
328 | match self.syntax().last_child() { | 366 | match self.syntax().last_child_or_token() { |
329 | None => false, | 367 | None => false, |
330 | Some(node) => node.kind() == SEMI, | 368 | Some(node) => node.kind() == SEMI, |
331 | } | 369 | } |
@@ -360,7 +398,7 @@ impl IfExpr { | |||
360 | 398 | ||
361 | impl ExprStmt { | 399 | impl ExprStmt { |
362 | pub fn has_semi(&self) -> bool { | 400 | pub fn has_semi(&self) -> bool { |
363 | match self.syntax().last_child() { | 401 | match self.syntax().last_child_or_token() { |
364 | None => false, | 402 | None => false, |
365 | Some(node) => node.kind() == SEMI, | 403 | Some(node) => node.kind() == SEMI, |
366 | } | 404 | } |
@@ -384,7 +422,7 @@ impl PathSegment { | |||
384 | let res = if let Some(name_ref) = self.name_ref() { | 422 | let res = if let Some(name_ref) = self.name_ref() { |
385 | PathSegmentKind::Name(name_ref) | 423 | PathSegmentKind::Name(name_ref) |
386 | } else { | 424 | } else { |
387 | match self.syntax().first_child()?.kind() { | 425 | match self.syntax().first_child_or_token()?.kind() { |
388 | SELF_KW => PathSegmentKind::SelfKw, | 426 | SELF_KW => PathSegmentKind::SelfKw, |
389 | SUPER_KW => PathSegmentKind::SuperKw, | 427 | SUPER_KW => PathSegmentKind::SuperKw, |
390 | CRATE_KW => PathSegmentKind::CrateKw, | 428 | CRATE_KW => PathSegmentKind::CrateKw, |
@@ -395,7 +433,7 @@ impl PathSegment { | |||
395 | } | 433 | } |
396 | 434 | ||
397 | pub fn has_colon_colon(&self) -> bool { | 435 | pub fn has_colon_colon(&self) -> bool { |
398 | match self.syntax.first_child().map(|s| s.kind()) { | 436 | match self.syntax.first_child_or_token().map(|s| s.kind()) { |
399 | Some(COLONCOLON) => true, | 437 | Some(COLONCOLON) => true, |
400 | _ => false, | 438 | _ => false, |
401 | } | 439 | } |
@@ -410,7 +448,7 @@ impl Path { | |||
410 | 448 | ||
411 | impl UseTree { | 449 | impl UseTree { |
412 | pub fn has_star(&self) -> bool { | 450 | pub fn has_star(&self) -> bool { |
413 | self.syntax().children().any(|it| it.kind() == STAR) | 451 | self.syntax().children_with_tokens().any(|it| it.kind() == STAR) |
414 | } | 452 | } |
415 | } | 453 | } |
416 | 454 | ||
@@ -425,7 +463,7 @@ impl UseTreeList { | |||
425 | 463 | ||
426 | impl RefPat { | 464 | impl RefPat { |
427 | pub fn is_mut(&self) -> bool { | 465 | pub fn is_mut(&self) -> bool { |
428 | self.syntax().children().any(|n| n.kind() == MUT_KW) | 466 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) |
429 | } | 467 | } |
430 | } | 468 | } |
431 | 469 | ||
@@ -500,19 +538,19 @@ impl EnumVariant { | |||
500 | 538 | ||
501 | impl PointerType { | 539 | impl PointerType { |
502 | pub fn is_mut(&self) -> bool { | 540 | pub fn is_mut(&self) -> bool { |
503 | self.syntax().children().any(|n| n.kind() == MUT_KW) | 541 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) |
504 | } | 542 | } |
505 | } | 543 | } |
506 | 544 | ||
507 | impl ReferenceType { | 545 | impl ReferenceType { |
508 | pub fn is_mut(&self) -> bool { | 546 | pub fn is_mut(&self) -> bool { |
509 | self.syntax().children().any(|n| n.kind() == MUT_KW) | 547 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) |
510 | } | 548 | } |
511 | } | 549 | } |
512 | 550 | ||
513 | impl RefExpr { | 551 | impl RefExpr { |
514 | pub fn is_mut(&self) -> bool { | 552 | pub fn is_mut(&self) -> bool { |
515 | self.syntax().children().any(|n| n.kind() == MUT_KW) | 553 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) |
516 | } | 554 | } |
517 | } | 555 | } |
518 | 556 | ||
@@ -528,7 +566,7 @@ pub enum PrefixOp { | |||
528 | 566 | ||
529 | impl PrefixExpr { | 567 | impl PrefixExpr { |
530 | pub fn op_kind(&self) -> Option<PrefixOp> { | 568 | pub fn op_kind(&self) -> Option<PrefixOp> { |
531 | match self.syntax().first_child()?.kind() { | 569 | match self.op_token()?.kind() { |
532 | STAR => Some(PrefixOp::Deref), | 570 | STAR => Some(PrefixOp::Deref), |
533 | EXCL => Some(PrefixOp::Not), | 571 | EXCL => Some(PrefixOp::Not), |
534 | MINUS => Some(PrefixOp::Neg), | 572 | MINUS => Some(PrefixOp::Neg), |
@@ -536,8 +574,8 @@ impl PrefixExpr { | |||
536 | } | 574 | } |
537 | } | 575 | } |
538 | 576 | ||
539 | pub fn op(&self) -> Option<&SyntaxNode> { | 577 | pub fn op_token(&self) -> Option<SyntaxToken> { |
540 | self.syntax().first_child() | 578 | self.syntax().first_child_or_token()?.as_token() |
541 | } | 579 | } |
542 | } | 580 | } |
543 | 581 | ||
@@ -608,40 +646,42 @@ pub enum BinOp { | |||
608 | } | 646 | } |
609 | 647 | ||
610 | impl BinExpr { | 648 | impl BinExpr { |
611 | fn op_details(&self) -> Option<(&SyntaxNode, BinOp)> { | 649 | fn op_details(&self) -> Option<(SyntaxToken, BinOp)> { |
612 | self.syntax().children().find_map(|c| match c.kind() { | 650 | self.syntax().children_with_tokens().filter_map(|it| it.as_token()).find_map(|c| { |
613 | PIPEPIPE => Some((c, BinOp::BooleanOr)), | 651 | match c.kind() { |
614 | AMPAMP => Some((c, BinOp::BooleanAnd)), | 652 | PIPEPIPE => Some((c, BinOp::BooleanOr)), |
615 | EQEQ => Some((c, BinOp::EqualityTest)), | 653 | AMPAMP => Some((c, BinOp::BooleanAnd)), |
616 | NEQ => Some((c, BinOp::NegatedEqualityTest)), | 654 | EQEQ => Some((c, BinOp::EqualityTest)), |
617 | LTEQ => Some((c, BinOp::LesserEqualTest)), | 655 | NEQ => Some((c, BinOp::NegatedEqualityTest)), |
618 | GTEQ => Some((c, BinOp::GreaterEqualTest)), | 656 | LTEQ => Some((c, BinOp::LesserEqualTest)), |
619 | L_ANGLE => Some((c, BinOp::LesserTest)), | 657 | GTEQ => Some((c, BinOp::GreaterEqualTest)), |
620 | R_ANGLE => Some((c, BinOp::GreaterTest)), | 658 | L_ANGLE => Some((c, BinOp::LesserTest)), |
621 | PLUS => Some((c, BinOp::Addition)), | 659 | R_ANGLE => Some((c, BinOp::GreaterTest)), |
622 | STAR => Some((c, BinOp::Multiplication)), | 660 | PLUS => Some((c, BinOp::Addition)), |
623 | MINUS => Some((c, BinOp::Subtraction)), | 661 | STAR => Some((c, BinOp::Multiplication)), |
624 | SLASH => Some((c, BinOp::Division)), | 662 | MINUS => Some((c, BinOp::Subtraction)), |
625 | PERCENT => Some((c, BinOp::Remainder)), | 663 | SLASH => Some((c, BinOp::Division)), |
626 | SHL => Some((c, BinOp::LeftShift)), | 664 | PERCENT => Some((c, BinOp::Remainder)), |
627 | SHR => Some((c, BinOp::RightShift)), | 665 | SHL => Some((c, BinOp::LeftShift)), |
628 | CARET => Some((c, BinOp::BitwiseXor)), | 666 | SHR => Some((c, BinOp::RightShift)), |
629 | PIPE => Some((c, BinOp::BitwiseOr)), | 667 | CARET => Some((c, BinOp::BitwiseXor)), |
630 | AMP => Some((c, BinOp::BitwiseAnd)), | 668 | PIPE => Some((c, BinOp::BitwiseOr)), |
631 | DOTDOT => Some((c, BinOp::RangeRightOpen)), | 669 | AMP => Some((c, BinOp::BitwiseAnd)), |
632 | DOTDOTEQ => Some((c, BinOp::RangeRightClosed)), | 670 | DOTDOT => Some((c, BinOp::RangeRightOpen)), |
633 | EQ => Some((c, BinOp::Assignment)), | 671 | DOTDOTEQ => Some((c, BinOp::RangeRightClosed)), |
634 | PLUSEQ => Some((c, BinOp::AddAssign)), | 672 | EQ => Some((c, BinOp::Assignment)), |
635 | SLASHEQ => Some((c, BinOp::DivAssign)), | 673 | PLUSEQ => Some((c, BinOp::AddAssign)), |
636 | STAREQ => Some((c, BinOp::MulAssign)), | 674 | SLASHEQ => Some((c, BinOp::DivAssign)), |
637 | PERCENTEQ => Some((c, BinOp::RemAssign)), | 675 | STAREQ => Some((c, BinOp::MulAssign)), |
638 | SHREQ => Some((c, BinOp::ShrAssign)), | 676 | PERCENTEQ => Some((c, BinOp::RemAssign)), |
639 | SHLEQ => Some((c, BinOp::ShlAssign)), | 677 | SHREQ => Some((c, BinOp::ShrAssign)), |
640 | MINUSEQ => Some((c, BinOp::SubAssign)), | 678 | SHLEQ => Some((c, BinOp::ShlAssign)), |
641 | PIPEEQ => Some((c, BinOp::BitOrAssign)), | 679 | MINUSEQ => Some((c, BinOp::SubAssign)), |
642 | AMPEQ => Some((c, BinOp::BitAndAssign)), | 680 | PIPEEQ => Some((c, BinOp::BitOrAssign)), |
643 | CARETEQ => Some((c, BinOp::BitXorAssign)), | 681 | AMPEQ => Some((c, BinOp::BitAndAssign)), |
644 | _ => None, | 682 | CARETEQ => Some((c, BinOp::BitXorAssign)), |
683 | _ => None, | ||
684 | } | ||
645 | }) | 685 | }) |
646 | } | 686 | } |
647 | 687 | ||
@@ -649,7 +689,7 @@ impl BinExpr { | |||
649 | self.op_details().map(|t| t.1) | 689 | self.op_details().map(|t| t.1) |
650 | } | 690 | } |
651 | 691 | ||
652 | pub fn op(&self) -> Option<&SyntaxNode> { | 692 | pub fn op_token(&self) -> Option<SyntaxToken> { |
653 | self.op_details().map(|t| t.0) | 693 | self.op_details().map(|t| t.0) |
654 | } | 694 | } |
655 | 695 | ||
@@ -680,11 +720,23 @@ pub enum SelfParamFlavor { | |||
680 | } | 720 | } |
681 | 721 | ||
682 | impl SelfParam { | 722 | impl SelfParam { |
723 | pub fn self_kw_token(&self) -> SyntaxToken { | ||
724 | self.syntax() | ||
725 | .children_with_tokens() | ||
726 | .filter_map(|it| it.as_token()) | ||
727 | .find(|it| it.kind() == SELF_KW) | ||
728 | .expect("invalid tree: self param must have self") | ||
729 | } | ||
730 | |||
683 | pub fn flavor(&self) -> SelfParamFlavor { | 731 | pub fn flavor(&self) -> SelfParamFlavor { |
684 | let borrowed = self.syntax().children().any(|n| n.kind() == AMP); | 732 | let borrowed = self.syntax().children_with_tokens().any(|n| n.kind() == AMP); |
685 | if borrowed { | 733 | if borrowed { |
686 | // check for a `mut` coming after the & -- `mut &self` != `&mut self` | 734 | // check for a `mut` coming after the & -- `mut &self` != `&mut self` |
687 | if self.syntax().children().skip_while(|n| n.kind() != AMP).any(|n| n.kind() == MUT_KW) | 735 | if self |
736 | .syntax() | ||
737 | .children_with_tokens() | ||
738 | .skip_while(|n| n.kind() != AMP) | ||
739 | .any(|n| n.kind() == MUT_KW) | ||
688 | { | 740 | { |
689 | SelfParamFlavor::MutRef | 741 | SelfParamFlavor::MutRef |
690 | } else { | 742 | } else { |
@@ -707,25 +759,31 @@ pub enum LiteralFlavor { | |||
707 | Bool, | 759 | Bool, |
708 | } | 760 | } |
709 | 761 | ||
710 | impl LiteralExpr { | 762 | impl Literal { |
763 | pub fn token(&self) -> SyntaxToken { | ||
764 | match self.syntax().first_child_or_token().unwrap() { | ||
765 | SyntaxElement::Token(token) => token, | ||
766 | _ => unreachable!(), | ||
767 | } | ||
768 | } | ||
769 | |||
711 | pub fn flavor(&self) -> LiteralFlavor { | 770 | pub fn flavor(&self) -> LiteralFlavor { |
712 | let syntax = self.syntax(); | 771 | match self.token().kind() { |
713 | match syntax.kind() { | ||
714 | INT_NUMBER => { | 772 | INT_NUMBER => { |
715 | let allowed_suffix_list = [ | 773 | let allowed_suffix_list = [ |
716 | "isize", "i128", "i64", "i32", "i16", "i8", "usize", "u128", "u64", "u32", | 774 | "isize", "i128", "i64", "i32", "i16", "i8", "usize", "u128", "u64", "u32", |
717 | "u16", "u8", | 775 | "u16", "u8", |
718 | ]; | 776 | ]; |
719 | let text = syntax.text().to_string(); | 777 | let text = self.token().text().to_string(); |
720 | let suffix = allowed_suffix_list | 778 | let suffix = allowed_suffix_list |
721 | .iter() | 779 | .iter() |
722 | .find(|&s| text.ends_with(s)) | 780 | .find(|&s| text.ends_with(s)) |
723 | .map(|&suf| SmolStr::new(suf)); | 781 | .map(|&suf| SmolStr::new(suf)); |
724 | LiteralFlavor::IntNumber { suffix: suffix } | 782 | LiteralFlavor::IntNumber { suffix } |
725 | } | 783 | } |
726 | FLOAT_NUMBER => { | 784 | FLOAT_NUMBER => { |
727 | let allowed_suffix_list = ["f64", "f32"]; | 785 | let allowed_suffix_list = ["f64", "f32"]; |
728 | let text = syntax.text().to_string(); | 786 | let text = self.token().text().to_string(); |
729 | let suffix = allowed_suffix_list | 787 | let suffix = allowed_suffix_list |
730 | .iter() | 788 | .iter() |
731 | .find(|&s| text.ends_with(s)) | 789 | .find(|&s| text.ends_with(s)) |
@@ -750,11 +808,29 @@ impl NamedField { | |||
750 | 808 | ||
751 | impl BindPat { | 809 | impl BindPat { |
752 | pub fn is_mutable(&self) -> bool { | 810 | pub fn is_mutable(&self) -> bool { |
753 | self.syntax().children().any(|n| n.kind() == MUT_KW) | 811 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) |
754 | } | 812 | } |
755 | 813 | ||
756 | pub fn is_ref(&self) -> bool { | 814 | pub fn is_ref(&self) -> bool { |
757 | self.syntax().children().any(|n| n.kind() == REF_KW) | 815 | self.syntax().children_with_tokens().any(|n| n.kind() == REF_KW) |
816 | } | ||
817 | } | ||
818 | |||
819 | impl LifetimeParam { | ||
820 | pub fn lifetime_token(&self) -> Option<SyntaxToken> { | ||
821 | self.syntax() | ||
822 | .children_with_tokens() | ||
823 | .filter_map(|it| it.as_token()) | ||
824 | .find(|it| it.kind() == LIFETIME) | ||
825 | } | ||
826 | } | ||
827 | |||
828 | impl WherePred { | ||
829 | pub fn lifetime_token(&self) -> Option<SyntaxToken> { | ||
830 | self.syntax() | ||
831 | .children_with_tokens() | ||
832 | .filter_map(|it| it.as_token()) | ||
833 | .find(|it| it.kind() == LIFETIME) | ||
758 | } | 834 | } |
759 | } | 835 | } |
760 | 836 | ||
@@ -835,7 +911,7 @@ where | |||
835 | let pred = predicates.next().unwrap(); | 911 | let pred = predicates.next().unwrap(); |
836 | let mut bounds = pred.type_bound_list().unwrap().bounds(); | 912 | let mut bounds = pred.type_bound_list().unwrap().bounds(); |
837 | 913 | ||
838 | assert_eq!("'a", pred.lifetime().unwrap().syntax().text().to_string()); | 914 | assert_eq!("'a", pred.lifetime_token().unwrap().text()); |
839 | 915 | ||
840 | assert_bound("'b", bounds.next()); | 916 | assert_bound("'b", bounds.next()); |
841 | assert_bound("'c", bounds.next()); | 917 | assert_bound("'c", bounds.next()); |