aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/doc_links.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/doc_links.rs')
-rw-r--r--crates/ide/src/doc_links.rs50
1 files changed, 36 insertions, 14 deletions
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index 367fac05e..de10406bc 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -1,6 +1,6 @@
1//! Resolves and rewrites links in markdown documentation. 1//! Resolves and rewrites links in markdown documentation.
2 2
3use std::{convert::TryFrom, iter::once}; 3use std::{convert::TryFrom, iter::once, ops::Range};
4 4
5use itertools::Itertools; 5use itertools::Itertools;
6use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag}; 6use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag};
@@ -39,7 +39,7 @@ pub(crate) fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Defi
39 if target.contains("://") { 39 if target.contains("://") {
40 (target.to_string(), title.to_string()) 40 (target.to_string(), title.to_string())
41 } else { 41 } else {
42 // Two posibilities: 42 // Two possibilities:
43 // * path-based links: `../../module/struct.MyStruct.html` 43 // * path-based links: `../../module/struct.MyStruct.html`
44 // * module-based links (AKA intra-doc links): `super::super::module::MyStruct` 44 // * module-based links (AKA intra-doc links): `super::super::module::MyStruct`
45 if let Some(rewritten) = rewrite_intra_doc_link(db, *definition, target, title) { 45 if let Some(rewritten) = rewrite_intra_doc_link(db, *definition, target, title) {
@@ -61,6 +61,30 @@ pub(crate) fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Defi
61 out 61 out
62} 62}
63 63
64pub(crate) fn extract_definitions_from_markdown(
65 markdown: &str,
66) -> Vec<(String, Option<hir::Namespace>, Range<usize>)> {
67 let mut res = vec![];
68 let mut cb = |link: BrokenLink| {
69 Some((
70 /*url*/ link.reference.to_owned().into(),
71 /*title*/ link.reference.to_owned().into(),
72 ))
73 };
74 let doc = Parser::new_with_broken_link_callback(markdown, Options::empty(), Some(&mut cb));
75 for (event, range) in doc.into_offset_iter() {
76 match event {
77 Event::Start(Tag::Link(_link_type, ref target, ref title)) => {
78 let link = if target.is_empty() { title } else { target };
79 let (link, ns) = parse_link(link);
80 res.push((link.to_string(), ns, range));
81 }
82 _ => {}
83 }
84 }
85 res
86}
87
64/// Remove all links in markdown documentation. 88/// Remove all links in markdown documentation.
65pub(crate) fn remove_links(markdown: &str) -> String { 89pub(crate) fn remove_links(markdown: &str) -> String {
66 let mut drop_link = false; 90 let mut drop_link = false;
@@ -192,9 +216,7 @@ fn rewrite_intra_doc_link(
192 Definition::Field(it) => it.resolve_doc_path(db, link, ns), 216 Definition::Field(it) => it.resolve_doc_path(db, link, ns),
193 Definition::SelfType(_) 217 Definition::SelfType(_)
194 | Definition::Local(_) 218 | Definition::Local(_)
195 | Definition::TypeParam(_) 219 | Definition::GenericParam(_)
196 | Definition::ConstParam(_)
197 | Definition::LifetimeParam(_)
198 | Definition::Label(_) => return None, 220 | Definition::Label(_) => return None,
199 }?; 221 }?;
200 let krate = resolved.module(db)?.krate(); 222 let krate = resolved.module(db)?.krate();
@@ -420,7 +442,7 @@ fn get_symbol_fragment(db: &dyn HirDatabase, field_or_assoc: &FieldOrAssocItem)
420 function.as_assoc_item(db).map(|assoc| assoc.container(db)), 442 function.as_assoc_item(db).map(|assoc| assoc.container(db)),
421 Some(AssocItemContainer::Trait(..)) 443 Some(AssocItemContainer::Trait(..))
422 ); 444 );
423 // This distinction may get more complicated when specialisation is available. 445 // This distinction may get more complicated when specialization is available.
424 // Rustdoc makes this decision based on whether a method 'has defaultness'. 446 // Rustdoc makes this decision based on whether a method 'has defaultness'.
425 // Currently this is only the case for provided trait methods. 447 // Currently this is only the case for provided trait methods.
426 if is_trait_method && !function.has_body(db) { 448 if is_trait_method && !function.has_body(db) {
@@ -464,7 +486,7 @@ mod tests {
464 fn test_doc_url_struct() { 486 fn test_doc_url_struct() {
465 check( 487 check(
466 r#" 488 r#"
467pub struct Fo<|>o; 489pub struct Fo$0o;
468"#, 490"#,
469 expect![[r#"https://docs.rs/test/*/test/struct.Foo.html"#]], 491 expect![[r#"https://docs.rs/test/*/test/struct.Foo.html"#]],
470 ); 492 );
@@ -474,7 +496,7 @@ pub struct Fo<|>o;
474 fn test_doc_url_fn() { 496 fn test_doc_url_fn() {
475 check( 497 check(
476 r#" 498 r#"
477pub fn fo<|>o() {} 499pub fn fo$0o() {}
478"#, 500"#,
479 expect![[r##"https://docs.rs/test/*/test/fn.foo.html#method.foo"##]], 501 expect![[r##"https://docs.rs/test/*/test/fn.foo.html#method.foo"##]],
480 ); 502 );
@@ -487,7 +509,7 @@ pub fn fo<|>o() {}
487pub struct Foo; 509pub struct Foo;
488 510
489impl Foo { 511impl Foo {
490 pub fn met<|>hod() {} 512 pub fn met$0hod() {}
491} 513}
492 514
493"#, 515"#,
@@ -500,7 +522,7 @@ impl Foo {
500 check( 522 check(
501 r#" 523 r#"
502pub trait Bar { 524pub trait Bar {
503 fn met<|>hod() {} 525 fn met$0hod() {}
504} 526}
505 527
506"#, 528"#,
@@ -513,7 +535,7 @@ pub trait Bar {
513 check( 535 check(
514 r#" 536 r#"
515pub trait Foo { 537pub trait Foo {
516 fn met<|>hod(); 538 fn met$0hod();
517} 539}
518 540
519"#, 541"#,
@@ -526,7 +548,7 @@ pub trait Foo {
526 check( 548 check(
527 r#" 549 r#"
528pub struct Foo { 550pub struct Foo {
529 pub fie<|>ld: () 551 pub fie$0ld: ()
530} 552}
531 553
532"#, 554"#,
@@ -539,7 +561,7 @@ pub struct Foo {
539 check( 561 check(
540 r#" 562 r#"
541pub mod foo { 563pub mod foo {
542 pub mod ba<|>r {} 564 pub mod ba$0r {}
543} 565}
544 "#, 566 "#,
545 expect![[r#"https://docs.rs/test/*/test/foo/bar/index.html"#]], 567 expect![[r#"https://docs.rs/test/*/test/foo/bar/index.html"#]],
@@ -564,7 +586,7 @@ pub mod wrapper {
564} 586}
565 587
566fn foo() { 588fn foo() {
567 let bar: wrapper::It<|>em; 589 let bar: wrapper::It$0em;
568} 590}
569 "#, 591 "#,
570 expect![[r#"https://docs.rs/test/*/test/wrapper/module/struct.Item.html"#]], 592 expect![[r#"https://docs.rs/test/*/test/wrapper/module/struct.Item.html"#]],