aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide_api/src/folding_ranges.rs7
-rw-r--r--crates/ra_ide_api/src/typing.rs2
-rw-r--r--crates/ra_syntax/src/ast/tokens.rs83
-rw-r--r--crates/ra_syntax/src/ast/traits.rs2
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
23impl<'a> Comment<'a> { 23impl<'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)]
47pub enum CommentFlavor { 34pub struct CommentKind {
35 pub shape: CommentShape,
36 pub doc: Option<CommentPlacement>,
37}
38
39#[derive(Debug, PartialEq, Eq, Clone, Copy)]
40pub enum CommentShape {
48 Line, 41 Line,
49 OuterDoc, 42 Block,
50 InnerDoc,
51 Multiline,
52} 43}
53 44
54impl CommentFlavor { 45impl 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)]
56pub enum CommentPlacement {
57 Inner,
58 Outer,
59}
60
61const 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
73fn 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 { 82fn 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
72pub struct Whitespace<'a>(SyntaxToken<'a>); 91pub 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();