diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-11-12 11:09:44 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-11-12 11:09:44 +0000 |
commit | 99fa139beab0c03583c676554c3d807525f602af (patch) | |
tree | a2df8b9f6d26611283120faccb387723b1a0c944 /crates/syntax/src | |
parent | 802665873ddfa3f6a2ba6e97a3d9078f2e5cfa90 (diff) | |
parent | a27186636d030c847193ab21c59a1857a1e93785 (diff) |
Merge #6534
6534: Fix attachment of inner doc comments r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <[email protected]>
Diffstat (limited to 'crates/syntax/src')
-rw-r--r-- | crates/syntax/src/ast.rs | 19 | ||||
-rw-r--r-- | crates/syntax/src/ast/token_ext.rs | 51 | ||||
-rw-r--r-- | crates/syntax/src/parsing/text_tree_sink.rs | 27 |
3 files changed, 53 insertions, 44 deletions
diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs index 8a0e3d27b..7844f9ed6 100644 --- a/crates/syntax/src/ast.rs +++ b/crates/syntax/src/ast.rs | |||
@@ -115,10 +115,10 @@ fn test_doc_comment_none() { | |||
115 | } | 115 | } |
116 | 116 | ||
117 | #[test] | 117 | #[test] |
118 | fn test_doc_comment_of_items() { | 118 | fn test_outer_doc_comment_of_items() { |
119 | let file = SourceFile::parse( | 119 | let file = SourceFile::parse( |
120 | r#" | 120 | r#" |
121 | //! doc | 121 | /// doc |
122 | // non-doc | 122 | // non-doc |
123 | mod foo {} | 123 | mod foo {} |
124 | "#, | 124 | "#, |
@@ -130,6 +130,21 @@ fn test_doc_comment_of_items() { | |||
130 | } | 130 | } |
131 | 131 | ||
132 | #[test] | 132 | #[test] |
133 | fn test_inner_doc_comment_of_items() { | ||
134 | let file = SourceFile::parse( | ||
135 | r#" | ||
136 | //! doc | ||
137 | // non-doc | ||
138 | mod foo {} | ||
139 | "#, | ||
140 | ) | ||
141 | .ok() | ||
142 | .unwrap(); | ||
143 | let module = file.syntax().descendants().find_map(Module::cast).unwrap(); | ||
144 | assert!(module.doc_comment_text().is_none()); | ||
145 | } | ||
146 | |||
147 | #[test] | ||
133 | fn test_doc_comment_of_statics() { | 148 | fn test_doc_comment_of_statics() { |
134 | let file = SourceFile::parse( | 149 | let file = SourceFile::parse( |
135 | r#" | 150 | r#" |
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs index e4e512f2e..2661c753e 100644 --- a/crates/syntax/src/ast/token_ext.rs +++ b/crates/syntax/src/ast/token_ext.rs | |||
@@ -14,16 +14,15 @@ use crate::{ | |||
14 | 14 | ||
15 | impl ast::Comment { | 15 | impl ast::Comment { |
16 | pub fn kind(&self) -> CommentKind { | 16 | pub fn kind(&self) -> CommentKind { |
17 | kind_by_prefix(self.text()) | 17 | CommentKind::from_text(self.text()) |
18 | } | 18 | } |
19 | 19 | ||
20 | pub fn prefix(&self) -> &'static str { | 20 | pub fn prefix(&self) -> &'static str { |
21 | for (prefix, k) in COMMENT_PREFIX_TO_KIND.iter() { | 21 | let &(prefix, _kind) = CommentKind::BY_PREFIX |
22 | if *k == self.kind() && self.text().starts_with(prefix) { | 22 | .iter() |
23 | return prefix; | 23 | .find(|&(prefix, kind)| self.kind() == *kind && self.text().starts_with(prefix)) |
24 | } | 24 | .unwrap(); |
25 | } | 25 | prefix |
26 | unreachable!() | ||
27 | } | 26 | } |
28 | } | 27 | } |
29 | 28 | ||
@@ -55,29 +54,25 @@ pub enum CommentPlacement { | |||
55 | Outer, | 54 | Outer, |
56 | } | 55 | } |
57 | 56 | ||
58 | const COMMENT_PREFIX_TO_KIND: &[(&str, CommentKind)] = { | 57 | impl CommentKind { |
59 | use {CommentPlacement::*, CommentShape::*}; | 58 | const BY_PREFIX: [(&'static str, CommentKind); 8] = [ |
60 | &[ | 59 | ("/**/", CommentKind { shape: CommentShape::Block, doc: None }), |
61 | ("////", CommentKind { shape: Line, doc: None }), | 60 | ("////", CommentKind { shape: CommentShape::Line, doc: None }), |
62 | ("///", CommentKind { shape: Line, doc: Some(Outer) }), | 61 | ("///", CommentKind { shape: CommentShape::Line, doc: Some(CommentPlacement::Outer) }), |
63 | ("//!", CommentKind { shape: Line, doc: Some(Inner) }), | 62 | ("//!", CommentKind { shape: CommentShape::Line, doc: Some(CommentPlacement::Inner) }), |
64 | ("/**", CommentKind { shape: Block, doc: Some(Outer) }), | 63 | ("/**", CommentKind { shape: CommentShape::Block, doc: Some(CommentPlacement::Outer) }), |
65 | ("/*!", CommentKind { shape: Block, doc: Some(Inner) }), | 64 | ("/*!", CommentKind { shape: CommentShape::Block, doc: Some(CommentPlacement::Inner) }), |
66 | ("//", CommentKind { shape: Line, doc: None }), | 65 | ("//", CommentKind { shape: CommentShape::Line, doc: None }), |
67 | ("/*", CommentKind { shape: Block, doc: None }), | 66 | ("/*", CommentKind { shape: CommentShape::Block, doc: None }), |
68 | ] | 67 | ]; |
69 | }; | ||
70 | 68 | ||
71 | fn kind_by_prefix(text: &str) -> CommentKind { | 69 | pub(crate) fn from_text(text: &str) -> CommentKind { |
72 | if text == "/**/" { | 70 | let &(_prefix, kind) = CommentKind::BY_PREFIX |
73 | return CommentKind { shape: CommentShape::Block, doc: None }; | 71 | .iter() |
74 | } | 72 | .find(|&(prefix, _kind)| text.starts_with(prefix)) |
75 | for (prefix, kind) in COMMENT_PREFIX_TO_KIND.iter() { | 73 | .unwrap(); |
76 | if text.starts_with(prefix) { | 74 | kind |
77 | return *kind; | ||
78 | } | ||
79 | } | 75 | } |
80 | panic!("bad comment text: {:?}", text) | ||
81 | } | 76 | } |
82 | 77 | ||
83 | impl ast::Whitespace { | 78 | impl ast::Whitespace { |
diff --git a/crates/syntax/src/parsing/text_tree_sink.rs b/crates/syntax/src/parsing/text_tree_sink.rs index c1b5f246d..997bc5d28 100644 --- a/crates/syntax/src/parsing/text_tree_sink.rs +++ b/crates/syntax/src/parsing/text_tree_sink.rs | |||
@@ -5,6 +5,7 @@ use std::mem; | |||
5 | use parser::{ParseError, TreeSink}; | 5 | use parser::{ParseError, TreeSink}; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | ast, | ||
8 | parsing::Token, | 9 | parsing::Token, |
9 | syntax_node::GreenNode, | 10 | syntax_node::GreenNode, |
10 | SmolStr, SyntaxError, | 11 | SmolStr, SyntaxError, |
@@ -153,24 +154,22 @@ fn n_attached_trivias<'a>( | |||
153 | 154 | ||
154 | while let Some((i, (kind, text))) = trivias.next() { | 155 | while let Some((i, (kind, text))) = trivias.next() { |
155 | match kind { | 156 | match kind { |
156 | WHITESPACE => { | 157 | WHITESPACE if text.contains("\n\n") => { |
157 | if text.contains("\n\n") { | 158 | // we check whether the next token is a doc-comment |
158 | // we check whether the next token is a doc-comment | 159 | // and skip the whitespace in this case |
159 | // and skip the whitespace in this case | 160 | if let Some((COMMENT, peek_text)) = trivias.peek().map(|(_, pair)| pair) { |
160 | if let Some((peek_kind, peek_text)) = | 161 | let comment_kind = ast::CommentKind::from_text(peek_text); |
161 | trivias.peek().map(|(_, pair)| pair) | 162 | if comment_kind.doc == Some(ast::CommentPlacement::Outer) { |
162 | { | 163 | continue; |
163 | if *peek_kind == COMMENT | ||
164 | && peek_text.starts_with("///") | ||
165 | && !peek_text.starts_with("////") | ||
166 | { | ||
167 | continue; | ||
168 | } | ||
169 | } | 164 | } |
170 | break; | ||
171 | } | 165 | } |
166 | break; | ||
172 | } | 167 | } |
173 | COMMENT => { | 168 | COMMENT => { |
169 | let comment_kind = ast::CommentKind::from_text(text); | ||
170 | if comment_kind.doc == Some(ast::CommentPlacement::Inner) { | ||
171 | break; | ||
172 | } | ||
174 | res = i + 1; | 173 | res = i + 1; |
175 | } | 174 | } |
176 | _ => (), | 175 | _ => (), |