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.rs41
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)
+ }
+ })
}
}