diff options
-rw-r--r-- | crates/ra_ide_api/src/folding_ranges.rs | 7 | ||||
-rw-r--r-- | crates/ra_ide_api/src/typing.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/tokens.rs | 83 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/traits.rs | 2 |
4 files changed, 58 insertions, 36 deletions
diff --git a/crates/ra_ide_api/src/folding_ranges.rs b/crates/ra_ide_api/src/folding_ranges.rs index eada0b7de..6987fcc9e 100644 --- a/crates/ra_ide_api/src/folding_ranges.rs +++ b/crates/ra_ide_api/src/folding_ranges.rs | |||
@@ -145,7 +145,10 @@ fn contiguous_range_for_comment<'a>( | |||
145 | visited.insert(first); | 145 | visited.insert(first); |
146 | 146 | ||
147 | // Only fold comments of the same flavor | 147 | // Only fold comments of the same flavor |
148 | let group_flavor = first.flavor(); | 148 | let group_kind = first.kind(); |
149 | if !group_kind.shape.is_line() { | ||
150 | return None; | ||
151 | } | ||
149 | 152 | ||
150 | let mut last = first; | 153 | let mut last = first; |
151 | for element in first.syntax().siblings_with_tokens(Direction::Next) { | 154 | for element in first.syntax().siblings_with_tokens(Direction::Next) { |
@@ -158,7 +161,7 @@ fn contiguous_range_for_comment<'a>( | |||
158 | } | 161 | } |
159 | } | 162 | } |
160 | if let Some(c) = ast::Comment::cast(token) { | 163 | if let Some(c) = ast::Comment::cast(token) { |
161 | if c.flavor() == group_flavor { | 164 | if c.kind() == group_kind { |
162 | visited.insert(c); | 165 | visited.insert(c); |
163 | last = c; | 166 | last = c; |
164 | continue; | 167 | continue; |
diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs index aeeeea082..ae53bca77 100644 --- a/crates/ra_ide_api/src/typing.rs +++ b/crates/ra_ide_api/src/typing.rs | |||
@@ -15,7 +15,7 @@ pub(crate) fn on_enter(db: &RootDatabase, position: FilePosition) -> Option<Sour | |||
15 | .left_biased() | 15 | .left_biased() |
16 | .and_then(ast::Comment::cast)?; | 16 | .and_then(ast::Comment::cast)?; |
17 | 17 | ||
18 | if comment.flavor() == ast::CommentFlavor::Multiline { | 18 | if comment.kind().shape.is_block() { |
19 | return None; | 19 | return None; |
20 | } | 20 | } |
21 | 21 | ||
diff --git a/crates/ra_syntax/src/ast/tokens.rs b/crates/ra_syntax/src/ast/tokens.rs index 76a12cd64..7c30ff15c 100644 --- a/crates/ra_syntax/src/ast/tokens.rs +++ b/crates/ra_syntax/src/ast/tokens.rs | |||
@@ -21,52 +21,71 @@ impl<'a> AstToken<'a> for Comment<'a> { | |||
21 | } | 21 | } |
22 | 22 | ||
23 | impl<'a> Comment<'a> { | 23 | impl<'a> Comment<'a> { |
24 | pub fn flavor(&self) -> CommentFlavor { | 24 | pub fn kind(&self) -> CommentKind { |
25 | let text = self.text(); | 25 | kind_by_prefix(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 | } | 26 | } |
40 | 27 | ||
41 | pub fn prefix(&self) -> &'static str { | 28 | pub fn prefix(&self) -> &'static str { |
42 | self.flavor().prefix() | 29 | prefix_by_kind(self.kind()) |
43 | } | 30 | } |
44 | } | 31 | } |
45 | 32 | ||
46 | #[derive(Debug, PartialEq, Eq)] | 33 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
47 | pub enum CommentFlavor { | 34 | pub struct CommentKind { |
35 | pub shape: CommentShape, | ||
36 | pub doc: Option<CommentPlacement>, | ||
37 | } | ||
38 | |||
39 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
40 | pub enum CommentShape { | ||
48 | Line, | 41 | Line, |
49 | OuterDoc, | 42 | Block, |
50 | InnerDoc, | ||
51 | Multiline, | ||
52 | } | 43 | } |
53 | 44 | ||
54 | impl CommentFlavor { | 45 | impl CommentShape { |
55 | pub fn prefix(&self) -> &'static str { | 46 | pub fn is_line(self) -> bool { |
56 | match *self { | 47 | self == CommentShape::Line |
57 | CommentFlavor::Line => "//", | 48 | } |
58 | CommentFlavor::OuterDoc => "///", | 49 | |
59 | CommentFlavor::InnerDoc => "//!", | 50 | pub fn is_block(self) -> bool { |
60 | CommentFlavor::Multiline => "/*", | 51 | self == CommentShape::Block |
52 | } | ||
53 | } | ||
54 | |||
55 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | ||
56 | pub enum CommentPlacement { | ||
57 | Inner, | ||
58 | Outer, | ||
59 | } | ||
60 | |||
61 | const COMMENT_PREFIX_TO_KIND: &[(&str, CommentKind)] = { | ||
62 | use {CommentShape::*, CommentPlacement::*}; | ||
63 | &[ | ||
64 | ("///", CommentKind { shape: Line, doc: Some(Outer) }), | ||
65 | ("//!", CommentKind { shape: Line, doc: Some(Inner) }), | ||
66 | ("/**", CommentKind { shape: Block, doc: Some(Outer) }), | ||
67 | ("/**", CommentKind { shape: Block, doc: Some(Inner) }), | ||
68 | ("//", CommentKind { shape: Line, doc: None }), | ||
69 | ("/*", CommentKind { shape: Block, doc: None }), | ||
70 | ] | ||
71 | }; | ||
72 | |||
73 | fn kind_by_prefix(text: &str) -> CommentKind { | ||
74 | for (prefix, kind) in COMMENT_PREFIX_TO_KIND.iter() { | ||
75 | if text.starts_with(prefix) { | ||
76 | return *kind; | ||
61 | } | 77 | } |
62 | } | 78 | } |
79 | panic!("bad comment text: {:?}", text) | ||
80 | } | ||
63 | 81 | ||
64 | pub fn is_doc_comment(&self) -> bool { | 82 | fn prefix_by_kind(kind: CommentKind) -> &'static str { |
65 | match self { | 83 | for (prefix, k) in COMMENT_PREFIX_TO_KIND.iter() { |
66 | CommentFlavor::OuterDoc | CommentFlavor::InnerDoc => true, | 84 | if *k == kind { |
67 | _ => false, | 85 | return prefix; |
68 | } | 86 | } |
69 | } | 87 | } |
88 | unreachable!() | ||
70 | } | 89 | } |
71 | 90 | ||
72 | pub struct Whitespace<'a>(SyntaxToken<'a>); | 91 | pub struct Whitespace<'a>(SyntaxToken<'a>); |
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs index 43d1509fa..98aa22085 100644 --- a/crates/ra_syntax/src/ast/traits.rs +++ b/crates/ra_syntax/src/ast/traits.rs | |||
@@ -111,7 +111,7 @@ pub trait DocCommentsOwner: AstNode { | |||
111 | let mut has_comments = false; | 111 | let mut has_comments = false; |
112 | let docs = self | 112 | let docs = self |
113 | .doc_comments() | 113 | .doc_comments() |
114 | .filter(|comment| comment.is_doc_comment()) | 114 | .filter(|comment| comment.kind().doc.is_some()) |
115 | .map(|comment| { | 115 | .map(|comment| { |
116 | has_comments = true; | 116 | has_comments = true; |
117 | let prefix_len = comment.prefix().len(); | 117 | let prefix_len = comment.prefix().len(); |