diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-02 08:50:09 +0100 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-04-02 08:50:09 +0100 |
commit | d21a677715196c46b73017acbae0105ef554284d (patch) | |
tree | 318d41ba567cf7ce1c5b4ead1857da64aa24242f /crates/ra_syntax/src/ast/tokens.rs | |
parent | c2912892effbcf24d94da235b9ac0d2a7fccea5d (diff) | |
parent | 3f3ff2f0f4c188c606a96506325d96726c842239 (diff) |
Merge #1085
1085: add ast::tokens r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/ra_syntax/src/ast/tokens.rs')
-rw-r--r-- | crates/ra_syntax/src/ast/tokens.rs | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/ast/tokens.rs b/crates/ra_syntax/src/ast/tokens.rs new file mode 100644 index 000000000..76a12cd64 --- /dev/null +++ b/crates/ra_syntax/src/ast/tokens.rs | |||
@@ -0,0 +1,92 @@ | |||
1 | use crate::{ | ||
2 | SyntaxToken, | ||
3 | SyntaxKind::{COMMENT, WHITESPACE}, | ||
4 | ast::AstToken, | ||
5 | }; | ||
6 | |||
7 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
8 | pub struct Comment<'a>(SyntaxToken<'a>); | ||
9 | |||
10 | impl<'a> AstToken<'a> for Comment<'a> { | ||
11 | fn cast(token: SyntaxToken<'a>) -> Option<Self> { | ||
12 | if token.kind() == COMMENT { | ||
13 | Some(Comment(token)) | ||
14 | } else { | ||
15 | None | ||
16 | } | ||
17 | } | ||
18 | fn syntax(&self) -> SyntaxToken<'a> { | ||
19 | self.0 | ||
20 | } | ||
21 | } | ||
22 | |||
23 | impl<'a> Comment<'a> { | ||
24 | pub fn flavor(&self) -> CommentFlavor { | ||
25 | let text = self.text(); | ||
26 | if text.starts_with("///") { | ||
27 | CommentFlavor::OuterDoc | ||
28 | } else if text.starts_with("//!") { | ||
29 | CommentFlavor::InnerDoc | ||
30 | } else if text.starts_with("//") { | ||
31 | CommentFlavor::Line | ||
32 | } else { | ||
33 | CommentFlavor::Multiline | ||
34 | } | ||
35 | } | ||
36 | |||
37 | pub fn is_doc_comment(&self) -> bool { | ||
38 | self.flavor().is_doc_comment() | ||
39 | } | ||
40 | |||
41 | pub fn prefix(&self) -> &'static str { | ||
42 | self.flavor().prefix() | ||
43 | } | ||
44 | } | ||
45 | |||
46 | #[derive(Debug, PartialEq, Eq)] | ||
47 | pub enum CommentFlavor { | ||
48 | Line, | ||
49 | OuterDoc, | ||
50 | InnerDoc, | ||
51 | Multiline, | ||
52 | } | ||
53 | |||
54 | impl CommentFlavor { | ||
55 | pub fn prefix(&self) -> &'static str { | ||
56 | match *self { | ||
57 | CommentFlavor::Line => "//", | ||
58 | CommentFlavor::OuterDoc => "///", | ||
59 | CommentFlavor::InnerDoc => "//!", | ||
60 | CommentFlavor::Multiline => "/*", | ||
61 | } | ||
62 | } | ||
63 | |||
64 | pub fn is_doc_comment(&self) -> bool { | ||
65 | match self { | ||
66 | CommentFlavor::OuterDoc | CommentFlavor::InnerDoc => true, | ||
67 | _ => false, | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | |||
72 | pub struct Whitespace<'a>(SyntaxToken<'a>); | ||
73 | |||
74 | impl<'a> AstToken<'a> for Whitespace<'a> { | ||
75 | fn cast(token: SyntaxToken<'a>) -> Option<Self> { | ||
76 | if token.kind() == WHITESPACE { | ||
77 | Some(Whitespace(token)) | ||
78 | } else { | ||
79 | None | ||
80 | } | ||
81 | } | ||
82 | fn syntax(&self) -> SyntaxToken<'a> { | ||
83 | self.0 | ||
84 | } | ||
85 | } | ||
86 | |||
87 | impl<'a> Whitespace<'a> { | ||
88 | pub fn spans_multiple_lines(&self) -> bool { | ||
89 | let text = self.text(); | ||
90 | text.find('\n').map_or(false, |idx| text[idx + 1..].contains('\n')) | ||
91 | } | ||
92 | } | ||