diff options
-rw-r--r-- | crates/hir_def/src/attr.rs | 28 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 26 | ||||
-rw-r--r-- | crates/ide_db/src/call_info.rs | 6 | ||||
-rw-r--r-- | crates/ide_db/src/call_info/tests.rs | 82 |
4 files changed, 80 insertions, 62 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index aeeb2c5cf..b7353d868 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -76,7 +76,7 @@ impl ops::Deref for Attrs { | |||
76 | impl RawAttrs { | 76 | impl RawAttrs { |
77 | pub(crate) const EMPTY: Self = Self { entries: None }; | 77 | pub(crate) const EMPTY: Self = Self { entries: None }; |
78 | 78 | ||
79 | pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Self { | 79 | pub(crate) fn new(owner: &dyn ast::AttrsOwner, hygiene: &Hygiene) -> Self { |
80 | let entries = collect_attrs(owner) | 80 | let entries = collect_attrs(owner) |
81 | .enumerate() | 81 | .enumerate() |
82 | .flat_map(|(i, attr)| match attr { | 82 | .flat_map(|(i, attr)| match attr { |
@@ -92,7 +92,7 @@ impl RawAttrs { | |||
92 | Self { entries: if entries.is_empty() { None } else { Some(entries) } } | 92 | Self { entries: if entries.is_empty() { None } else { Some(entries) } } |
93 | } | 93 | } |
94 | 94 | ||
95 | fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Self { | 95 | fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn ast::AttrsOwner>) -> Self { |
96 | let hygiene = Hygiene::new(db.upcast(), owner.file_id); | 96 | let hygiene = Hygiene::new(db.upcast(), owner.file_id); |
97 | Self::new(owner.value, &hygiene) | 97 | Self::new(owner.value, &hygiene) |
98 | } | 98 | } |
@@ -178,7 +178,7 @@ impl Attrs { | |||
178 | Some(it) => { | 178 | Some(it) => { |
179 | let raw_attrs = RawAttrs::from_attrs_owner( | 179 | let raw_attrs = RawAttrs::from_attrs_owner( |
180 | db, | 180 | db, |
181 | it.as_ref().map(|it| it as &dyn AttrsOwner), | 181 | it.as_ref().map(|it| it as &dyn ast::AttrsOwner), |
182 | ); | 182 | ); |
183 | match mod_data.definition_source(db) { | 183 | match mod_data.definition_source(db) { |
184 | InFile { file_id, value: ModuleSource::SourceFile(file) } => raw_attrs | 184 | InFile { file_id, value: ModuleSource::SourceFile(file) } => raw_attrs |
@@ -189,9 +189,9 @@ impl Attrs { | |||
189 | None => RawAttrs::from_attrs_owner( | 189 | None => RawAttrs::from_attrs_owner( |
190 | db, | 190 | db, |
191 | mod_data.definition_source(db).as_ref().map(|src| match src { | 191 | mod_data.definition_source(db).as_ref().map(|src| match src { |
192 | ModuleSource::SourceFile(file) => file as &dyn AttrsOwner, | 192 | ModuleSource::SourceFile(file) => file as &dyn ast::AttrsOwner, |
193 | ModuleSource::Module(module) => module as &dyn AttrsOwner, | 193 | ModuleSource::Module(module) => module as &dyn ast::AttrsOwner, |
194 | ModuleSource::BlockExpr(block) => block as &dyn AttrsOwner, | 194 | ModuleSource::BlockExpr(block) => block as &dyn ast::AttrsOwner, |
195 | }), | 195 | }), |
196 | ), | 196 | ), |
197 | } | 197 | } |
@@ -249,7 +249,7 @@ impl Attrs { | |||
249 | let mut res = ArenaMap::default(); | 249 | let mut res = ArenaMap::default(); |
250 | 250 | ||
251 | for (id, var) in src.value.iter() { | 251 | for (id, var) in src.value.iter() { |
252 | let attrs = RawAttrs::from_attrs_owner(db, src.with_value(var as &dyn AttrsOwner)) | 252 | let attrs = RawAttrs::from_attrs_owner(db, src.with_value(var as &dyn ast::AttrsOwner)) |
253 | .filter(db, krate); | 253 | .filter(db, krate); |
254 | 254 | ||
255 | res.insert(id, attrs) | 255 | res.insert(id, attrs) |
@@ -283,7 +283,7 @@ impl Attrs { | |||
283 | /// Constructs a map that maps the lowered `Attr`s in this `Attrs` back to its original syntax nodes. | 283 | /// Constructs a map that maps the lowered `Attr`s in this `Attrs` back to its original syntax nodes. |
284 | /// | 284 | /// |
285 | /// `owner` must be the original owner of the attributes. | 285 | /// `owner` must be the original owner of the attributes. |
286 | pub fn source_map(&self, owner: &dyn AttrsOwner) -> AttrSourceMap { | 286 | pub fn source_map(&self, owner: &dyn ast::AttrsOwner) -> AttrSourceMap { |
287 | AttrSourceMap { attrs: collect_attrs(owner).collect() } | 287 | AttrSourceMap { attrs: collect_attrs(owner).collect() } |
288 | } | 288 | } |
289 | 289 | ||
@@ -321,9 +321,7 @@ impl Attrs { | |||
321 | let mut buf = String::new(); | 321 | let mut buf = String::new(); |
322 | for doc in docs { | 322 | for doc in docs { |
323 | // str::lines doesn't yield anything for the empty string | 323 | // str::lines doesn't yield anything for the empty string |
324 | if doc.is_empty() { | 324 | if !doc.is_empty() { |
325 | buf.push('\n'); | ||
326 | } else { | ||
327 | buf.extend(Itertools::intersperse( | 325 | buf.extend(Itertools::intersperse( |
328 | doc.lines().map(|line| { | 326 | doc.lines().map(|line| { |
329 | line.char_indices() | 327 | line.char_indices() |
@@ -436,7 +434,7 @@ impl Attr { | |||
436 | /// | 434 | /// |
437 | /// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of | 435 | /// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of |
438 | /// the attribute represented by `Attr`. | 436 | /// the attribute represented by `Attr`. |
439 | pub fn to_src(&self, owner: &dyn AttrsOwner) -> Either<ast::Attr, ast::Comment> { | 437 | pub fn to_src(&self, owner: &dyn ast::AttrsOwner) -> Either<ast::Attr, ast::Comment> { |
440 | collect_attrs(owner).nth(self.index as usize).unwrap_or_else(|| { | 438 | collect_attrs(owner).nth(self.index as usize).unwrap_or_else(|| { |
441 | panic!("cannot find `Attr` at index {} in {}", self.index, owner.syntax()) | 439 | panic!("cannot find `Attr` at index {} in {}", self.index, owner.syntax()) |
442 | }) | 440 | }) |
@@ -528,7 +526,7 @@ where | |||
528 | N: ast::AttrsOwner, | 526 | N: ast::AttrsOwner, |
529 | { | 527 | { |
530 | let src = InFile::new(src.file_id, src.to_node(db.upcast())); | 528 | let src = InFile::new(src.file_id, src.to_node(db.upcast())); |
531 | RawAttrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) | 529 | RawAttrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn ast::AttrsOwner)) |
532 | } | 530 | } |
533 | 531 | ||
534 | fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> RawAttrs { | 532 | 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 | |||
537 | tree.raw_attrs(mod_item.into()).clone() | 535 | tree.raw_attrs(mod_item.into()).clone() |
538 | } | 536 | } |
539 | 537 | ||
540 | fn collect_attrs(owner: &dyn AttrsOwner) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> { | 538 | fn collect_attrs( |
539 | owner: &dyn ast::AttrsOwner, | ||
540 | ) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> { | ||
541 | let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) | 541 | let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) |
542 | .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs)))); | 542 | .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs)))); |
543 | 543 | ||
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index cc2b79124..15d309d7d 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -1533,12 +1533,21 @@ fn my() {} | |||
1533 | fn test_hover_struct_doc_comment() { | 1533 | fn test_hover_struct_doc_comment() { |
1534 | check( | 1534 | check( |
1535 | r#" | 1535 | r#" |
1536 | /// bar docs | 1536 | /// This is an example |
1537 | /// multiline doc | ||
1538 | /// | ||
1539 | /// # Example | ||
1540 | /// | ||
1541 | /// ``` | ||
1542 | /// let five = 5; | ||
1543 | /// | ||
1544 | /// assert_eq!(6, my_crate::add_one(5)); | ||
1545 | /// ``` | ||
1537 | struct Bar; | 1546 | struct Bar; |
1538 | 1547 | ||
1539 | fn foo() { let bar = Ba$0r; } | 1548 | fn foo() { let bar = Ba$0r; } |
1540 | "#, | 1549 | "#, |
1541 | expect![[r#" | 1550 | expect![[r##" |
1542 | *Bar* | 1551 | *Bar* |
1543 | 1552 | ||
1544 | ```rust | 1553 | ```rust |
@@ -1551,8 +1560,17 @@ fn foo() { let bar = Ba$0r; } | |||
1551 | 1560 | ||
1552 | --- | 1561 | --- |
1553 | 1562 | ||
1554 | bar docs | 1563 | This is an example |
1555 | "#]], | 1564 | multiline doc |
1565 | |||
1566 | # Example | ||
1567 | |||
1568 | ``` | ||
1569 | let five = 5; | ||
1570 | |||
1571 | assert_eq!(6, my_crate::add_one(5)); | ||
1572 | ``` | ||
1573 | "##]], | ||
1556 | ); | 1574 | ); |
1557 | } | 1575 | } |
1558 | 1576 | ||
diff --git a/crates/ide_db/src/call_info.rs b/crates/ide_db/src/call_info.rs index d4016973c..7e26c3ccf 100644 --- a/crates/ide_db/src/call_info.rs +++ b/crates/ide_db/src/call_info.rs | |||
@@ -53,15 +53,15 @@ pub fn call_info(db: &RootDatabase, position: FilePosition) -> Option<CallInfo> | |||
53 | 53 | ||
54 | match callable.kind() { | 54 | match callable.kind() { |
55 | hir::CallableKind::Function(func) => { | 55 | hir::CallableKind::Function(func) => { |
56 | res.doc = func.docs(db).map(|it| it.as_str().to_string()); | 56 | res.doc = func.docs(db).map(|it| it.into()); |
57 | format_to!(res.signature, "fn {}", func.name(db)); | 57 | format_to!(res.signature, "fn {}", func.name(db)); |
58 | } | 58 | } |
59 | hir::CallableKind::TupleStruct(strukt) => { | 59 | hir::CallableKind::TupleStruct(strukt) => { |
60 | res.doc = strukt.docs(db).map(|it| it.as_str().to_string()); | 60 | res.doc = strukt.docs(db).map(|it| it.into()); |
61 | format_to!(res.signature, "struct {}", strukt.name(db)); | 61 | format_to!(res.signature, "struct {}", strukt.name(db)); |
62 | } | 62 | } |
63 | hir::CallableKind::TupleEnumVariant(variant) => { | 63 | hir::CallableKind::TupleEnumVariant(variant) => { |
64 | res.doc = variant.docs(db).map(|it| it.as_str().to_string()); | 64 | res.doc = variant.docs(db).map(|it| it.into()); |
65 | format_to!( | 65 | format_to!( |
66 | res.signature, | 66 | res.signature, |
67 | "enum {}::{}", | 67 | "enum {}::{}", |
diff --git a/crates/ide_db/src/call_info/tests.rs b/crates/ide_db/src/call_info/tests.rs index 9f84c253c..75ab3eb6e 100644 --- a/crates/ide_db/src/call_info/tests.rs +++ b/crates/ide_db/src/call_info/tests.rs | |||
@@ -220,11 +220,11 @@ fn bar() { | |||
220 | } | 220 | } |
221 | "#, | 221 | "#, |
222 | expect![[r#" | 222 | expect![[r#" |
223 | test | 223 | test |
224 | ------ | 224 | ------ |
225 | fn foo(j: u32) -> u32 | 225 | fn foo(j: u32) -> u32 |
226 | (<j: u32>) | 226 | (<j: u32>) |
227 | "#]], | 227 | "#]], |
228 | ); | 228 | ); |
229 | } | 229 | } |
230 | 230 | ||
@@ -249,19 +249,19 @@ pub fn do() { | |||
249 | add_one($0 | 249 | add_one($0 |
250 | }"#, | 250 | }"#, |
251 | expect![[r##" | 251 | expect![[r##" |
252 | Adds one to the number given. | 252 | Adds one to the number given. |
253 | 253 | ||
254 | # Examples | 254 | # Examples |
255 | 255 | ||
256 | ``` | 256 | ``` |
257 | let five = 5; | 257 | let five = 5; |
258 | 258 | ||
259 | assert_eq!(6, my_crate::add_one(5)); | 259 | assert_eq!(6, my_crate::add_one(5)); |
260 | ``` | 260 | ``` |
261 | ------ | 261 | ------ |
262 | fn add_one(x: i32) -> i32 | 262 | fn add_one(x: i32) -> i32 |
263 | (<x: i32>) | 263 | (<x: i32>) |
264 | "##]], | 264 | "##]], |
265 | ); | 265 | ); |
266 | } | 266 | } |
267 | 267 | ||
@@ -291,19 +291,19 @@ pub fn do_it() { | |||
291 | } | 291 | } |
292 | "#, | 292 | "#, |
293 | expect![[r##" | 293 | expect![[r##" |
294 | Adds one to the number given. | 294 | Adds one to the number given. |
295 | 295 | ||
296 | # Examples | 296 | # Examples |
297 | 297 | ||
298 | ``` | 298 | ``` |
299 | let five = 5; | 299 | let five = 5; |
300 | 300 | ||
301 | assert_eq!(6, my_crate::add_one(5)); | 301 | assert_eq!(6, my_crate::add_one(5)); |
302 | ``` | 302 | ``` |
303 | ------ | 303 | ------ |
304 | fn add_one(x: i32) -> i32 | 304 | fn add_one(x: i32) -> i32 |
305 | (<x: i32>) | 305 | (<x: i32>) |
306 | "##]], | 306 | "##]], |
307 | ); | 307 | ); |
308 | } | 308 | } |
309 | 309 | ||
@@ -335,13 +335,13 @@ pub fn foo(mut r: WriteHandler<()>) { | |||
335 | } | 335 | } |
336 | "#, | 336 | "#, |
337 | expect![[r#" | 337 | expect![[r#" |
338 | Method is called when writer finishes. | 338 | Method is called when writer finishes. |
339 | 339 | ||
340 | By default this method stops actor's `Context`. | 340 | By default this method stops actor's `Context`. |
341 | ------ | 341 | ------ |
342 | fn finished(&mut self, ctx: &mut {unknown}) | 342 | fn finished(&mut self, ctx: &mut {unknown}) |
343 | (<ctx: &mut {unknown}>) | 343 | (<ctx: &mut {unknown}>) |
344 | "#]], | 344 | "#]], |
345 | ); | 345 | ); |
346 | } | 346 | } |
347 | 347 | ||
@@ -389,11 +389,11 @@ fn main() { | |||
389 | } | 389 | } |
390 | "#, | 390 | "#, |
391 | expect![[r#" | 391 | expect![[r#" |
392 | A cool tuple struct | 392 | A cool tuple struct |
393 | ------ | 393 | ------ |
394 | struct S(u32, i32) | 394 | struct S(u32, i32) |
395 | (u32, <i32>) | 395 | (u32, <i32>) |
396 | "#]], | 396 | "#]], |
397 | ); | 397 | ); |
398 | } | 398 | } |
399 | 399 | ||
@@ -431,11 +431,11 @@ fn main() { | |||
431 | } | 431 | } |
432 | "#, | 432 | "#, |
433 | expect![[r#" | 433 | expect![[r#" |
434 | A Variant | 434 | A Variant |
435 | ------ | 435 | ------ |
436 | enum E::A(i32) | 436 | enum E::A(i32) |
437 | (<i32>) | 437 | (<i32>) |
438 | "#]], | 438 | "#]], |
439 | ); | 439 | ); |
440 | } | 440 | } |
441 | 441 | ||