aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax
diff options
context:
space:
mode:
Diffstat (limited to 'crates/syntax')
-rw-r--r--crates/syntax/src/ast.rs29
-rw-r--r--crates/syntax/src/ast/token_ext.rs19
-rw-r--r--crates/syntax/src/ast/traits.rs18
-rw-r--r--crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast20
-rw-r--r--crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast78
5 files changed, 79 insertions, 85 deletions
diff --git a/crates/syntax/src/ast.rs b/crates/syntax/src/ast.rs
index 19261686c..38e0b04ef 100644
--- a/crates/syntax/src/ast.rs
+++ b/crates/syntax/src/ast.rs
@@ -118,7 +118,7 @@ fn test_doc_comment_none() {
118 .ok() 118 .ok()
119 .unwrap(); 119 .unwrap();
120 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 120 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
121 assert!(module.doc_comment_text().is_none()); 121 assert!(module.doc_comments().doc_comment_text().is_none());
122} 122}
123 123
124#[test] 124#[test]
@@ -133,7 +133,7 @@ fn test_outer_doc_comment_of_items() {
133 .ok() 133 .ok()
134 .unwrap(); 134 .unwrap();
135 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 135 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
136 assert_eq!("doc", module.doc_comment_text().unwrap()); 136 assert_eq!(" doc", module.doc_comments().doc_comment_text().unwrap());
137} 137}
138 138
139#[test] 139#[test]
@@ -148,7 +148,7 @@ fn test_inner_doc_comment_of_items() {
148 .ok() 148 .ok()
149 .unwrap(); 149 .unwrap();
150 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 150 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
151 assert!(module.doc_comment_text().is_none()); 151 assert!(module.doc_comments().doc_comment_text().is_none());
152} 152}
153 153
154#[test] 154#[test]
@@ -162,7 +162,7 @@ fn test_doc_comment_of_statics() {
162 .ok() 162 .ok()
163 .unwrap(); 163 .unwrap();
164 let st = file.syntax().descendants().find_map(Static::cast).unwrap(); 164 let st = file.syntax().descendants().find_map(Static::cast).unwrap();
165 assert_eq!("Number of levels", st.doc_comment_text().unwrap()); 165 assert_eq!(" Number of levels", st.doc_comments().doc_comment_text().unwrap());
166} 166}
167 167
168#[test] 168#[test]
@@ -181,7 +181,10 @@ fn test_doc_comment_preserves_indents() {
181 .ok() 181 .ok()
182 .unwrap(); 182 .unwrap();
183 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 183 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
184 assert_eq!("doc1\n```\nfn foo() {\n // ...\n}\n```", module.doc_comment_text().unwrap()); 184 assert_eq!(
185 " doc1\n ```\n fn foo() {\n // ...\n }\n ```",
186 module.doc_comments().doc_comment_text().unwrap()
187 );
185} 188}
186 189
187#[test] 190#[test]
@@ -198,7 +201,7 @@ fn test_doc_comment_preserves_newlines() {
198 .ok() 201 .ok()
199 .unwrap(); 202 .unwrap();
200 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 203 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
201 assert_eq!("this\nis\nmod\nfoo", module.doc_comment_text().unwrap()); 204 assert_eq!(" this\n is\n mod\n foo", module.doc_comments().doc_comment_text().unwrap());
202} 205}
203 206
204#[test] 207#[test]
@@ -212,7 +215,7 @@ fn test_doc_comment_single_line_block_strips_suffix() {
212 .ok() 215 .ok()
213 .unwrap(); 216 .unwrap();
214 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 217 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
215 assert_eq!("this is mod foo", module.doc_comment_text().unwrap()); 218 assert_eq!(" this is mod foo", module.doc_comments().doc_comment_text().unwrap());
216} 219}
217 220
218#[test] 221#[test]
@@ -226,7 +229,7 @@ fn test_doc_comment_single_line_block_strips_suffix_whitespace() {
226 .ok() 229 .ok()
227 .unwrap(); 230 .unwrap();
228 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 231 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
229 assert_eq!("this is mod foo ", module.doc_comment_text().unwrap()); 232 assert_eq!(" this is mod foo ", module.doc_comments().doc_comment_text().unwrap());
230} 233}
231 234
232#[test] 235#[test]
@@ -245,8 +248,8 @@ fn test_doc_comment_multi_line_block_strips_suffix() {
245 .unwrap(); 248 .unwrap();
246 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 249 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
247 assert_eq!( 250 assert_eq!(
248 " this\n is\n mod foo\n ", 251 "\n this\n is\n mod foo\n ",
249 module.doc_comment_text().unwrap() 252 module.doc_comments().doc_comment_text().unwrap()
250 ); 253 );
251} 254}
252 255
@@ -259,8 +262,8 @@ fn test_comments_preserve_trailing_whitespace() {
259 .unwrap(); 262 .unwrap();
260 let def = file.syntax().descendants().find_map(Struct::cast).unwrap(); 263 let def = file.syntax().descendants().find_map(Struct::cast).unwrap();
261 assert_eq!( 264 assert_eq!(
262 "Representation of a Realm. \nIn the specification these are called Realm Records.", 265 " Representation of a Realm. \n In the specification these are called Realm Records.",
263 def.doc_comment_text().unwrap() 266 def.doc_comments().doc_comment_text().unwrap()
264 ); 267 );
265} 268}
266 269
@@ -276,7 +279,7 @@ fn test_four_slash_line_comment() {
276 .ok() 279 .ok()
277 .unwrap(); 280 .unwrap();
278 let module = file.syntax().descendants().find_map(Module::cast).unwrap(); 281 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
279 assert_eq!("doc comment", module.doc_comment_text().unwrap()); 282 assert_eq!(" doc comment", module.doc_comments().doc_comment_text().unwrap());
280} 283}
281 284
282#[test] 285#[test]
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs
index 977eb8181..6c242d126 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -33,23 +33,20 @@ impl ast::Comment {
33 prefix 33 prefix
34 } 34 }
35 35
36 /// Returns the textual content of a doc comment block as a single string. 36 /// Returns the textual content of a doc comment node as a single string with prefix and suffix
37 /// That is, strips leading `///` (+ optional 1 character of whitespace), 37 /// removed.
38 /// trailing `*/`, trailing whitespace and then joins the lines.
39 pub fn doc_comment(&self) -> Option<&str> { 38 pub fn doc_comment(&self) -> Option<&str> {
40 let kind = self.kind(); 39 let kind = self.kind();
41 match kind { 40 match kind {
42 CommentKind { shape, doc: Some(_) } => { 41 CommentKind { shape, doc: Some(_) } => {
43 let prefix = kind.prefix(); 42 let prefix = kind.prefix();
44 let text = &self.text()[prefix.len()..]; 43 let text = &self.text()[prefix.len()..];
45 let ws = text.chars().next().filter(|c| c.is_whitespace()); 44 let text = if shape == CommentShape::Block {
46 let text = ws.map_or(text, |ws| &text[ws.len_utf8()..]); 45 text.strip_suffix("*/").unwrap_or(text)
47 match shape { 46 } else {
48 CommentShape::Block if text.ends_with("*/") => { 47 text
49 Some(&text[..text.len() - "*/".len()]) 48 };
50 } 49 Some(text)
51 _ => Some(text),
52 }
53 } 50 }
54 _ => None, 51 _ => None,
55 } 52 }
diff --git a/crates/syntax/src/ast/traits.rs b/crates/syntax/src/ast/traits.rs
index 13a769d51..ddd213637 100644
--- a/crates/syntax/src/ast/traits.rs
+++ b/crates/syntax/src/ast/traits.rs
@@ -1,8 +1,6 @@
1//! Various traits that are implemented by ast nodes. 1//! Various traits that are implemented by ast nodes.
2//! 2//!
3//! The implementations are usually trivial, and live in generated.rs 3//! The implementations are usually trivial, and live in generated.rs
4use itertools::Itertools;
5
6use crate::{ 4use crate::{
7 ast::{self, support, AstChildren, AstNode, AstToken}, 5 ast::{self, support, AstChildren, AstNode, AstToken},
8 syntax_node::SyntaxElementChildren, 6 syntax_node::SyntaxElementChildren,
@@ -72,14 +70,10 @@ pub trait AttrsOwner: AstNode {
72 } 70 }
73} 71}
74 72
75pub trait DocCommentsOwner: AstNode { 73pub trait DocCommentsOwner: AttrsOwner {
76 fn doc_comments(&self) -> CommentIter { 74 fn doc_comments(&self) -> CommentIter {
77 CommentIter { iter: self.syntax().children_with_tokens() } 75 CommentIter { iter: self.syntax().children_with_tokens() }
78 } 76 }
79
80 fn doc_comment_text(&self) -> Option<String> {
81 self.doc_comments().doc_comment_text()
82 }
83} 77}
84 78
85impl CommentIter { 79impl CommentIter {
@@ -87,12 +81,12 @@ impl CommentIter {
87 CommentIter { iter: syntax_node.children_with_tokens() } 81 CommentIter { iter: syntax_node.children_with_tokens() }
88 } 82 }
89 83
90 /// Returns the textual content of a doc comment block as a single string. 84 #[cfg(test)]
91 /// That is, strips leading `///` (+ optional 1 character of whitespace),
92 /// trailing `*/`, trailing whitespace and then joins the lines.
93 pub fn doc_comment_text(self) -> Option<String> { 85 pub fn doc_comment_text(self) -> Option<String> {
94 let docs = 86 let docs = itertools::Itertools::join(
95 self.filter_map(|comment| comment.doc_comment().map(ToOwned::to_owned)).join("\n"); 87 &mut self.filter_map(|comment| comment.doc_comment().map(ToOwned::to_owned)),
88 "\n",
89 );
96 if docs.is_empty() { 90 if docs.is_empty() {
97 None 91 None
98 } else { 92 } else {
diff --git a/crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast b/crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast
index 495e4c51b..a84088bf3 100644
--- a/crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast
+++ b/crates/syntax/test_data/parser/inline/ok/0139_param_outer_arg.rast
@@ -6,16 +6,16 @@ [email protected]
6 [email protected] "f" 6 [email protected] "f"
7 [email protected] 7 [email protected]
8 [email protected] "(" 8 [email protected] "("
9 ATTR@5..13 9 PARAM@5..23
10 POUND@5..6 "#" 10 ATTR@5..13
11 L_BRACK@6..7 "[" 11 POUND@5..6 "#"
12 PATH@7..12 12 L_BRACK@6..7 "["
13 PATH_SEGMENT@7..12 13 [email protected]
14 NAME_REF@7..12 14 PATH_SEGMENT@7..12
15 IDENT@7..12 "attr1" 15 NAME_REF@7..12
16 R_BRACK@12..13 "]" 16 IDENT@7..12 "attr1"
17 WHITESPACE@13..14 " " 17 R_BRACK@12..13 "]"
18 PARAM@14..23 18 WHITESPACE@13..14 " "
19 [email protected] 19 [email protected]
20 [email protected] 20 [email protected]
21 [email protected] "pat" 21 [email protected] "pat"
diff --git a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast b/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast
index e10521d85..88470c41c 100644
--- a/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast
+++ b/crates/syntax/test_data/parser/ok/0051_parameter_attrs.rast
@@ -6,25 +6,25 @@ [email protected]
6 [email protected] "g1" 6 [email protected] "g1"
7 [email protected] 7 [email protected]
8 [email protected] "(" 8 [email protected] "("
9 ATTR@6..14 9 PARAM@6..33
10 POUND@6..7 "#" 10 ATTR@6..14
11 L_BRACK@7..8 "[" 11 POUND@6..7 "#"
12 PATH@8..13 12 L_BRACK@7..8 "["
13 PATH_SEGMENT@8..13 13 [email protected]
14 NAME_REF@8..13 14 PATH_SEGMENT@8..13
15 IDENT@8..13 "attr1" 15 NAME_REF@8..13
16 R_BRACK@13..14 "]" 16 IDENT@8..13 "attr1"
17 WHITESPACE@14..15 " " 17 R_BRACK@13..14 "]"
18 ATTR@15..23 18 WHITESPACE@14..15 " "
19 POUND@15..16 "#" 19 ATTR@15..23
20 L_BRACK@16..17 "[" 20 POUND@15..16 "#"
21 PATH@17..22 21 L_BRACK@16..17 "["
22 PATH_SEGMENT@17..22 22 [email protected]
23 NAME_REF@17..22 23 PATH_SEGMENT@17..22
24 IDENT@17..22 "attr2" 24 NAME_REF@17..22
25 R_BRACK@22..23 "]" 25 IDENT@17..22 "attr2"
26 WHITESPACE@23..24 " " 26 R_BRACK@22..23 "]"
27 PARAM@24..33 27 WHITESPACE@23..24 " "
28 [email protected] 28 [email protected]
29 [email protected] 29 [email protected]
30 [email protected] "pat" 30 [email protected] "pat"
@@ -48,16 +48,16 @@ [email protected]
48 [email protected] "g2" 48 [email protected] "g2"
49 [email protected] 49 [email protected]
50 [email protected] "(" 50 [email protected] "("
51 ATT[email protected]2 51 PARAM@44..58
52 POUND@44..45 "#" 52 ATTR@44..52
53 L_BRACK@45..46 "[" 53 POUND@44..45 "#"
54 PATH@46..51 54 L_BRACK@45..46 "["
55 PATH_SEGMENT@46..51 55 [email protected]
56 NAME_REF@46..51 56 PATH_SEGMENT@46..51
57 IDENT@46..51 "attr1" 57 NAME_REF@46..51
58 R_BRACK@51..52 "]" 58 IDENT@46..51 "attr1"
59 WHITESPACE@52..53 " " 59 R_BRACK@51..52 "]"
60 PARAM@53..58 60 WHITESPACE@52..53 " "
61 [email protected] 61 [email protected]
62 [email protected] 62 [email protected]
63 [email protected] "x" 63 [email protected] "x"
@@ -203,16 +203,16 @@ [email protected]
203 [email protected] "bar" 203 [email protected] "bar"
204 [email protected] 204 [email protected]
205 [email protected] "(" 205 [email protected] "("
206 ATT[email protected]04 206 PARAM@197..211
207 POUND@197..198 "#" 207 ATTR@197..204
208 L_BRACK@198..199 "[" 208 POUND@197..198 "#"
209 PATH@199..203 209 L_BRACK@198..199 "["
210 PATH_SEGMENT@199..203 210 [email protected]
211 NAME_REF@199..203 211 PATH_SEGMENT@199..203
212 IDENT@199..203 "attr" 212 NAME_REF@199..203
213 R_BRACK@203..204 "]" 213 IDENT@199..203 "attr"
214 WHITESPACE@204..205 " " 214 R_BRACK@203..204 "]"
215 PARAM@205..211 215 WHITESPACE@204..205 " "
216 [email protected] 216 [email protected]
217 [email protected] "_" 217 [email protected] "_"
218 [email protected] ":" 218 [email protected] ":"