Skip to content

Commit f8823e8

Browse files
committed
Properly fetch inner and outer docs on hir-level
1 parent eac7799 commit f8823e8

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

crates/hir_def/src/attr.rs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,17 @@ impl Attrs {
110110
}
111111

112112
pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs {
113-
let outer_docs = ast::CommentIter::from_syntax_node(owner.syntax()).map(|docs_text| {
113+
let (inner_attrs, inner_docs) = inner_attributes(owner.syntax())
114+
.map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs))));
115+
116+
let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none());
117+
let attrs = outer_attrs
118+
.chain(inner_attrs.into_iter().flatten())
119+
.map(|attr| (attr.syntax().text_range().start(), Attr::from_src(attr, hygiene)));
120+
121+
let outer_docs =
122+
ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer);
123+
let docs = outer_docs.chain(inner_docs.into_iter().flatten()).map(|docs_text| {
114124
(
115125
docs_text.syntax().text_range().start(),
116126
docs_text.doc_comment().map(|doc| Attr {
@@ -119,13 +129,8 @@ impl Attrs {
119129
}),
120130
)
121131
});
122-
let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none());
123-
let inner_attrs = inner_attributes(owner.syntax()).into_iter().flatten();
124-
let attrs = outer_attrs
125-
.chain(inner_attrs)
126-
.map(|attr| (attr.syntax().text_range().start(), Attr::from_src(attr, hygiene)));
127132
// sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved
128-
let attrs: Vec<_> = outer_docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect();
133+
let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect();
129134
let entries = if attrs.is_empty() {
130135
// Avoid heap allocation
131136
None
@@ -186,36 +191,39 @@ impl Attrs {
186191
}
187192
}
188193

189-
fn inner_attributes(syntax: &SyntaxNode) -> Option<impl Iterator<Item = ast::Attr>> {
190-
let (attrs, _docs) = match_ast! {
194+
fn inner_attributes(
195+
syntax: &SyntaxNode,
196+
) -> Option<(impl Iterator<Item = ast::Attr>, impl Iterator<Item = ast::Comment>)> {
197+
let (attrs, docs) = match_ast! {
191198
match syntax {
192-
ast::SourceFile(it) => (it.attrs(), None::<ast::Comment>),
199+
ast::SourceFile(it) => (it.attrs(), ast::CommentIter::from_syntax_node(it.syntax())),
193200
ast::ExternBlock(it) => {
194201
let extern_item_list = it.extern_item_list()?;
195-
(extern_item_list.attrs(), None)
202+
(extern_item_list.attrs(), ast::CommentIter::from_syntax_node(extern_item_list.syntax()))
196203
},
197204
ast::Fn(it) => {
198205
let body = it.body()?;
199-
(body.attrs(), None)
206+
(body.attrs(), ast::CommentIter::from_syntax_node(body.syntax()))
200207
},
201208
ast::Impl(it) => {
202209
let assoc_item_list = it.assoc_item_list()?;
203-
(assoc_item_list.attrs(), None)
210+
(assoc_item_list.attrs(), ast::CommentIter::from_syntax_node(assoc_item_list.syntax()))
204211
},
205212
ast::Module(it) => {
206213
let item_list = it.item_list()?;
207-
(item_list.attrs(), None)
214+
(item_list.attrs(), ast::CommentIter::from_syntax_node(item_list.syntax()))
208215
},
209216
// FIXME: BlockExpr's only accept inner attributes in specific cases
210217
// Excerpt from the reference:
211-
// Block expressions accept outer and inner attributes, but only when they are the outer
212-
// expression of an expression statement or the final expression of another block expression.
218+
// Block expressions accept outer and inner attributes, but only when they are the outer
219+
// expression of an expression statement or the final expression of another block expression.
213220
ast::BlockExpr(it) => return None,
214221
_ => return None,
215222
}
216223
};
217224
let attrs = attrs.filter(|attr| attr.excl_token().is_some());
218-
Some(attrs)
225+
let docs = docs.filter(|doc| doc.is_inner());
226+
Some((attrs, docs))
219227
}
220228

221229
#[derive(Debug, Clone, PartialEq, Eq)]

crates/syntax/src/ast/token_ext.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@ impl ast::Comment {
1717
CommentKind::from_text(self.text())
1818
}
1919

20+
pub fn is_inner(&self) -> bool {
21+
self.kind().doc == Some(CommentPlacement::Inner)
22+
}
23+
24+
pub fn is_outer(&self) -> bool {
25+
self.kind().doc == Some(CommentPlacement::Outer)
26+
}
27+
2028
pub fn prefix(&self) -> &'static str {
2129
let &(prefix, _kind) = CommentKind::BY_PREFIX
2230
.iter()

0 commit comments

Comments
 (0)