Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/syntax/src/ast/traits.rs')
| -rw-r--r-- | crates/syntax/src/ast/traits.rs | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/crates/syntax/src/ast/traits.rs b/crates/syntax/src/ast/traits.rs index eae3a7e2fe..98b1087e64 100644 --- a/crates/syntax/src/ast/traits.rs +++ b/crates/syntax/src/ast/traits.rs @@ -1,10 +1,12 @@ //! Various traits that are implemented by ast nodes. //! //! The implementations are usually trivial, and live in generated.rs +use itertools::Either; + use crate::{ ast::{self, support, AstChildren, AstNode, AstToken}, syntax_node::SyntaxElementChildren, - SyntaxToken, T, + SyntaxElement, SyntaxToken, T, }; pub trait HasName: AstNode { @@ -71,14 +73,17 @@ pub trait HasAttrs: AstNode { } pub trait HasDocComments: HasAttrs { - fn doc_comments(&self) -> CommentIter { - CommentIter { iter: self.syntax().children_with_tokens() } + fn doc_comments(&self) -> DocCommentIter { + DocCommentIter { iter: self.syntax().children_with_tokens() } + } + fn doc_comments_and_attrs(&self) -> AttrCommentIter { + AttrCommentIter { iter: self.syntax().children_with_tokens() } } } -impl CommentIter { - pub fn from_syntax_node(syntax_node: &ast::SyntaxNode) -> CommentIter { - CommentIter { iter: syntax_node.children_with_tokens() } +impl DocCommentIter { + pub fn from_syntax_node(syntax_node: &ast::SyntaxNode) -> DocCommentIter { + DocCommentIter { iter: syntax_node.children_with_tokens() } } #[cfg(test)] @@ -95,13 +100,31 @@ impl CommentIter { } } -pub struct CommentIter { +pub struct DocCommentIter { iter: SyntaxElementChildren, } -impl Iterator for CommentIter { +impl Iterator for DocCommentIter { type Item = ast::Comment; fn next(&mut self) -> Option<ast::Comment> { - self.iter.by_ref().find_map(|el| el.into_token().and_then(ast::Comment::cast)) + self.iter.by_ref().find_map(|el| { + el.into_token().and_then(ast::Comment::cast).filter(ast::Comment::is_doc) + }) + } +} + +pub struct AttrCommentIter { + iter: SyntaxElementChildren, +} + +impl Iterator for AttrCommentIter { + type Item = Either<ast::Comment, ast::Attr>; + fn next(&mut self) -> Option<Self::Item> { + self.iter.by_ref().find_map(|el| match el { + SyntaxElement::Node(node) => ast::Attr::cast(node).map(Either::Right), + SyntaxElement::Token(tok) => { + ast::Comment::cast(tok).filter(ast::Comment::is_doc).map(Either::Left) + } + }) } } |