From ec824a92d05caa1908cb25cbd5b969c8e995aaa7 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Wed, 17 Mar 2021 14:38:11 +0100 Subject: Better handling of block doc comments --- crates/syntax/src/ast.rs | 29 ++++++++++++++++------------- crates/syntax/src/ast/token_ext.rs | 19 ++++++++----------- crates/syntax/src/ast/traits.rs | 16 +++++----------- 3 files changed, 29 insertions(+), 35 deletions(-) (limited to 'crates/syntax/src') 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() { .ok() .unwrap(); let module = file.syntax().descendants().find_map(Module::cast).unwrap(); - assert!(module.doc_comment_text().is_none()); + assert!(module.doc_comments().doc_comment_text().is_none()); } #[test] @@ -133,7 +133,7 @@ fn test_outer_doc_comment_of_items() { .ok() .unwrap(); let module = file.syntax().descendants().find_map(Module::cast).unwrap(); - assert_eq!("doc", module.doc_comment_text().unwrap()); + assert_eq!(" doc", module.doc_comments().doc_comment_text().unwrap()); } #[test] @@ -148,7 +148,7 @@ fn test_inner_doc_comment_of_items() { .ok() .unwrap(); let module = file.syntax().descendants().find_map(Module::cast).unwrap(); - assert!(module.doc_comment_text().is_none()); + assert!(module.doc_comments().doc_comment_text().is_none()); } #[test] @@ -162,7 +162,7 @@ fn test_doc_comment_of_statics() { .ok() .unwrap(); let st = file.syntax().descendants().find_map(Static::cast).unwrap(); - assert_eq!("Number of levels", st.doc_comment_text().unwrap()); + assert_eq!(" Number of levels", st.doc_comments().doc_comment_text().unwrap()); } #[test] @@ -181,7 +181,10 @@ fn test_doc_comment_preserves_indents() { .ok() .unwrap(); let module = file.syntax().descendants().find_map(Module::cast).unwrap(); - assert_eq!("doc1\n```\nfn foo() {\n // ...\n}\n```", module.doc_comment_text().unwrap()); + assert_eq!( + " doc1\n ```\n fn foo() {\n // ...\n }\n ```", + module.doc_comments().doc_comment_text().unwrap() + ); } #[test] @@ -198,7 +201,7 @@ fn test_doc_comment_preserves_newlines() { .ok() .unwrap(); let module = file.syntax().descendants().find_map(Module::cast).unwrap(); - assert_eq!("this\nis\nmod\nfoo", module.doc_comment_text().unwrap()); + assert_eq!(" this\n is\n mod\n foo", module.doc_comments().doc_comment_text().unwrap()); } #[test] @@ -212,7 +215,7 @@ fn test_doc_comment_single_line_block_strips_suffix() { .ok() .unwrap(); let module = file.syntax().descendants().find_map(Module::cast).unwrap(); - assert_eq!("this is mod foo", module.doc_comment_text().unwrap()); + assert_eq!(" this is mod foo", module.doc_comments().doc_comment_text().unwrap()); } #[test] @@ -226,7 +229,7 @@ fn test_doc_comment_single_line_block_strips_suffix_whitespace() { .ok() .unwrap(); let module = file.syntax().descendants().find_map(Module::cast).unwrap(); - assert_eq!("this is mod foo ", module.doc_comment_text().unwrap()); + assert_eq!(" this is mod foo ", module.doc_comments().doc_comment_text().unwrap()); } #[test] @@ -245,8 +248,8 @@ fn test_doc_comment_multi_line_block_strips_suffix() { .unwrap(); let module = file.syntax().descendants().find_map(Module::cast).unwrap(); assert_eq!( - " this\n is\n mod foo\n ", - module.doc_comment_text().unwrap() + "\n this\n is\n mod foo\n ", + module.doc_comments().doc_comment_text().unwrap() ); } @@ -259,8 +262,8 @@ fn test_comments_preserve_trailing_whitespace() { .unwrap(); let def = file.syntax().descendants().find_map(Struct::cast).unwrap(); assert_eq!( - "Representation of a Realm. \nIn the specification these are called Realm Records.", - def.doc_comment_text().unwrap() + " Representation of a Realm. \n In the specification these are called Realm Records.", + def.doc_comments().doc_comment_text().unwrap() ); } @@ -276,7 +279,7 @@ fn test_four_slash_line_comment() { .ok() .unwrap(); let module = file.syntax().descendants().find_map(Module::cast).unwrap(); - assert_eq!("doc comment", module.doc_comment_text().unwrap()); + assert_eq!(" doc comment", module.doc_comments().doc_comment_text().unwrap()); } #[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 { prefix } - /// Returns the textual content of a doc comment block as a single string. - /// That is, strips leading `///` (+ optional 1 character of whitespace), - /// trailing `*/`, trailing whitespace and then joins the lines. + /// Returns the textual content of a doc comment node as a single string with prefix and suffix + /// removed. pub fn doc_comment(&self) -> Option<&str> { let kind = self.kind(); match kind { CommentKind { shape, doc: Some(_) } => { let prefix = kind.prefix(); let text = &self.text()[prefix.len()..]; - let ws = text.chars().next().filter(|c| c.is_whitespace()); - let text = ws.map_or(text, |ws| &text[ws.len_utf8()..]); - match shape { - CommentShape::Block if text.ends_with("*/") => { - Some(&text[..text.len() - "*/".len()]) - } - _ => Some(text), - } + let text = if shape == CommentShape::Block { + text.strip_suffix("*/").unwrap_or(text) + } else { + text + }; + Some(text) } _ => None, } diff --git a/crates/syntax/src/ast/traits.rs b/crates/syntax/src/ast/traits.rs index 96d4cc997..ddd213637 100644 --- a/crates/syntax/src/ast/traits.rs +++ b/crates/syntax/src/ast/traits.rs @@ -1,8 +1,6 @@ //! Various traits that are implemented by ast nodes. //! //! The implementations are usually trivial, and live in generated.rs -use itertools::Itertools; - use crate::{ ast::{self, support, AstChildren, AstNode, AstToken}, syntax_node::SyntaxElementChildren, @@ -76,10 +74,6 @@ pub trait DocCommentsOwner: AttrsOwner { fn doc_comments(&self) -> CommentIter { CommentIter { iter: self.syntax().children_with_tokens() } } - - fn doc_comment_text(&self) -> Option { - self.doc_comments().doc_comment_text() - } } impl CommentIter { @@ -87,12 +81,12 @@ impl CommentIter { CommentIter { iter: syntax_node.children_with_tokens() } } - /// Returns the textual content of a doc comment block as a single string. - /// That is, strips leading `///` (+ optional 1 character of whitespace), - /// trailing `*/`, trailing whitespace and then joins the lines. + #[cfg(test)] pub fn doc_comment_text(self) -> Option { - let docs = - self.filter_map(|comment| comment.doc_comment().map(ToOwned::to_owned)).join("\n"); + let docs = itertools::Itertools::join( + &mut self.filter_map(|comment| comment.doc_comment().map(ToOwned::to_owned)), + "\n", + ); if docs.is_empty() { None } else { -- cgit v1.2.3