Fix incorrect newline emission in Attrs::docs

This commit is contained in:
Lukas Wirth
2021-03-17 16:10:58 +01:00
parent ec824a92d0
commit 5734b347dd
4 changed files with 80 additions and 62 deletions

View File

@@ -76,7 +76,7 @@ impl ops::Deref for Attrs {
impl RawAttrs { impl RawAttrs {
pub(crate) const EMPTY: Self = Self { entries: None }; pub(crate) const EMPTY: Self = Self { entries: None };
pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Self { pub(crate) fn new(owner: &dyn ast::AttrsOwner, hygiene: &Hygiene) -> Self {
let entries = collect_attrs(owner) let entries = collect_attrs(owner)
.enumerate() .enumerate()
.flat_map(|(i, attr)| match attr { .flat_map(|(i, attr)| match attr {
@@ -92,7 +92,7 @@ impl RawAttrs {
Self { entries: if entries.is_empty() { None } else { Some(entries) } } Self { entries: if entries.is_empty() { None } else { Some(entries) } }
} }
fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Self { fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn ast::AttrsOwner>) -> Self {
let hygiene = Hygiene::new(db.upcast(), owner.file_id); let hygiene = Hygiene::new(db.upcast(), owner.file_id);
Self::new(owner.value, &hygiene) Self::new(owner.value, &hygiene)
} }
@@ -178,7 +178,7 @@ impl Attrs {
Some(it) => { Some(it) => {
let raw_attrs = RawAttrs::from_attrs_owner( let raw_attrs = RawAttrs::from_attrs_owner(
db, db,
it.as_ref().map(|it| it as &dyn AttrsOwner), it.as_ref().map(|it| it as &dyn ast::AttrsOwner),
); );
match mod_data.definition_source(db) { match mod_data.definition_source(db) {
InFile { file_id, value: ModuleSource::SourceFile(file) } => raw_attrs InFile { file_id, value: ModuleSource::SourceFile(file) } => raw_attrs
@@ -189,9 +189,9 @@ impl Attrs {
None => RawAttrs::from_attrs_owner( None => RawAttrs::from_attrs_owner(
db, db,
mod_data.definition_source(db).as_ref().map(|src| match src { mod_data.definition_source(db).as_ref().map(|src| match src {
ModuleSource::SourceFile(file) => file as &dyn AttrsOwner, ModuleSource::SourceFile(file) => file as &dyn ast::AttrsOwner,
ModuleSource::Module(module) => module as &dyn AttrsOwner, ModuleSource::Module(module) => module as &dyn ast::AttrsOwner,
ModuleSource::BlockExpr(block) => block as &dyn AttrsOwner, ModuleSource::BlockExpr(block) => block as &dyn ast::AttrsOwner,
}), }),
), ),
} }
@@ -249,7 +249,7 @@ impl Attrs {
let mut res = ArenaMap::default(); let mut res = ArenaMap::default();
for (id, var) in src.value.iter() { for (id, var) in src.value.iter() {
let attrs = RawAttrs::from_attrs_owner(db, src.with_value(var as &dyn AttrsOwner)) let attrs = RawAttrs::from_attrs_owner(db, src.with_value(var as &dyn ast::AttrsOwner))
.filter(db, krate); .filter(db, krate);
res.insert(id, attrs) res.insert(id, attrs)
@@ -283,7 +283,7 @@ impl Attrs {
/// Constructs a map that maps the lowered `Attr`s in this `Attrs` back to its original syntax nodes. /// Constructs a map that maps the lowered `Attr`s in this `Attrs` back to its original syntax nodes.
/// ///
/// `owner` must be the original owner of the attributes. /// `owner` must be the original owner of the attributes.
pub fn source_map(&self, owner: &dyn AttrsOwner) -> AttrSourceMap { pub fn source_map(&self, owner: &dyn ast::AttrsOwner) -> AttrSourceMap {
AttrSourceMap { attrs: collect_attrs(owner).collect() } AttrSourceMap { attrs: collect_attrs(owner).collect() }
} }
@@ -321,9 +321,7 @@ impl Attrs {
let mut buf = String::new(); let mut buf = String::new();
for doc in docs { for doc in docs {
// str::lines doesn't yield anything for the empty string // str::lines doesn't yield anything for the empty string
if doc.is_empty() { if !doc.is_empty() {
buf.push('\n');
} else {
buf.extend(Itertools::intersperse( buf.extend(Itertools::intersperse(
doc.lines().map(|line| { doc.lines().map(|line| {
line.char_indices() line.char_indices()
@@ -436,7 +434,7 @@ impl Attr {
/// ///
/// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of /// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of
/// the attribute represented by `Attr`. /// the attribute represented by `Attr`.
pub fn to_src(&self, owner: &dyn AttrsOwner) -> Either<ast::Attr, ast::Comment> { pub fn to_src(&self, owner: &dyn ast::AttrsOwner) -> Either<ast::Attr, ast::Comment> {
collect_attrs(owner).nth(self.index as usize).unwrap_or_else(|| { collect_attrs(owner).nth(self.index as usize).unwrap_or_else(|| {
panic!("cannot find `Attr` at index {} in {}", self.index, owner.syntax()) panic!("cannot find `Attr` at index {} in {}", self.index, owner.syntax())
}) })
@@ -528,7 +526,7 @@ where
N: ast::AttrsOwner, N: ast::AttrsOwner,
{ {
let src = InFile::new(src.file_id, src.to_node(db.upcast())); let src = InFile::new(src.file_id, src.to_node(db.upcast()));
RawAttrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) RawAttrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn ast::AttrsOwner))
} }
fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> RawAttrs { fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> RawAttrs {
@@ -537,7 +535,9 @@ fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase
tree.raw_attrs(mod_item.into()).clone() tree.raw_attrs(mod_item.into()).clone()
} }
fn collect_attrs(owner: &dyn AttrsOwner) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> { fn collect_attrs(
owner: &dyn ast::AttrsOwner,
) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> {
let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) let (inner_attrs, inner_docs) = inner_attributes(owner.syntax())
.map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs)))); .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs))));

View File

@@ -1533,12 +1533,21 @@ fn my() {}
fn test_hover_struct_doc_comment() { fn test_hover_struct_doc_comment() {
check( check(
r#" r#"
/// bar docs /// This is an example
/// multiline doc
///
/// # Example
///
/// ```
/// let five = 5;
///
/// assert_eq!(6, my_crate::add_one(5));
/// ```
struct Bar; struct Bar;
fn foo() { let bar = Ba$0r; } fn foo() { let bar = Ba$0r; }
"#, "#,
expect![[r#" expect![[r##"
*Bar* *Bar*
```rust ```rust
@@ -1551,8 +1560,17 @@ fn foo() { let bar = Ba$0r; }
--- ---
bar docs This is an example
"#]], multiline doc
# Example
```
let five = 5;
assert_eq!(6, my_crate::add_one(5));
```
"##]],
); );
} }

View File

@@ -53,15 +53,15 @@ pub fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo>
match callable.kind() { match callable.kind() {
hir::CallableKind::Function(func) => { hir::CallableKind::Function(func) => {
res.doc = func.docs(db).map(|it| it.as_str().to_string()); res.doc = func.docs(db).map(|it| it.into());
format_to!(res.signature, "fn {}", func.name(db)); format_to!(res.signature, "fn {}", func.name(db));
} }
hir::CallableKind::TupleStruct(strukt) => { hir::CallableKind::TupleStruct(strukt) => {
res.doc = strukt.docs(db).map(|it| it.as_str().to_string()); res.doc = strukt.docs(db).map(|it| it.into());
format_to!(res.signature, "struct {}", strukt.name(db)); format_to!(res.signature, "struct {}", strukt.name(db));
} }
hir::CallableKind::TupleEnumVariant(variant) => { hir::CallableKind::TupleEnumVariant(variant) => {
res.doc = variant.docs(db).map(|it| it.as_str().to_string()); res.doc = variant.docs(db).map(|it| it.into());
format_to!( format_to!(
res.signature, res.signature,
"enum {}::{}", "enum {}::{}",