aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src')
-rw-r--r--crates/ide/src/doc_links.rs96
1 files changed, 94 insertions, 2 deletions
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index 0608c2ac6..b9d53bcd4 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -112,6 +112,7 @@ pub fn get_doc_link<T: Resolvable + Clone>(db: &dyn HirDatabase, definition: &T)
112// version of import map which follows the same process as rustdoc. Otherwise there'll always be some 112// version of import map which follows the same process as rustdoc. Otherwise there'll always be some
113// edge cases where we select the wrong import path. 113// edge cases where we select the wrong import path.
114fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> { 114fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
115 eprintln!("enter");
115 // Get the outermost definition for the moduledef. This is used to resolve the public path to the type, 116 // Get the outermost definition for the moduledef. This is used to resolve the public path to the type,
116 // then we can join the method, field, etc onto it if required. 117 // then we can join the method, field, etc onto it if required.
117 let target_def: ModuleDef = match definition { 118 let target_def: ModuleDef = match definition {
@@ -131,8 +132,8 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
131 let module = definition.module(db)?; 132 let module = definition.module(db)?;
132 let krate = module.krate(); 133 let krate = module.krate();
133 let import_map = db.import_map(krate.into()); 134 let import_map = db.import_map(krate.into());
134 let base = once(krate.display_name(db).unwrap()) 135 let base = once(krate.display_name(db)?)
135 .chain(import_map.path_of(ns).unwrap().segments.iter().map(|name| format!("{}", name))) 136 .chain(import_map.path_of(ns)?.segments.iter().map(|name| format!("{}", name)))
136 .join("/"); 137 .join("/");
137 138
138 let filename = get_symbol_filename(db, &target_def); 139 let filename = get_symbol_filename(db, &target_def);
@@ -152,6 +153,7 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
152 Definition::Field(field) => get_symbol_fragment(db, &FieldOrAssocItem::Field(field)), 153 Definition::Field(field) => get_symbol_fragment(db, &FieldOrAssocItem::Field(field)),
153 _ => None, 154 _ => None,
154 }; 155 };
156 eprintln!("end-ish");
155 157
156 get_doc_url(db, &krate) 158 get_doc_url(db, &krate)
157 .and_then(|url| url.join(&base).ok()) 159 .and_then(|url| url.join(&base).ok())
@@ -430,3 +432,93 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
430 } 432 }
431 } 433 }
432} 434}
435
436#[cfg(test)]
437mod tests {
438 use expect_test::{expect, Expect};
439
440 use crate::mock_analysis::analysis_and_position;
441
442 fn check(ra_fixture: &str, expect: Expect) {
443 let (analysis, position) = analysis_and_position(ra_fixture);
444 let url = analysis.external_docs(position).unwrap().unwrap();
445
446 expect.assert_eq(&url)
447 }
448
449 #[test]
450 fn test_doc_url_struct() {
451 check(
452 r#"
453pub struct Fo<|>o;
454"#,
455 expect![[r#"https://docs.rs/test/*/test/struct.Foo.html"#]],
456 );
457 }
458
459 // TODO: Fix this test. Fails on `import_map.path_of(ns)`
460 #[test]
461 fn test_doc_url_fn() {
462 check(
463 r#"
464pub fn fo<|>o() {}
465"#,
466 expect![[r#""#]],
467 );
468 }
469
470 #[test]
471 fn test_doc_url_inherent_method() {
472 check(
473 r#"
474pub struct Foo;
475
476impl Foo {
477 pub fn met<|>hod() {}
478}
479
480"#,
481 expect![[r##"https://docs.rs/test/*/test/struct.Foo.html#method.method"##]],
482 );
483 }
484
485 #[test]
486 fn test_doc_url_trait_provided_method() {
487 check(
488 r#"
489pub trait Bar {
490 fn met<|>hod() {}
491}
492
493"#,
494 expect![[r##"https://docs.rs/test/*/test/trait.Bar.html#method.method"##]],
495 );
496 }
497
498 #[test]
499 fn test_doc_url_trait_required_method() {
500 check(
501 r#"
502pub trait Foo {
503 fn met<|>hod();
504}
505
506"#,
507 expect![[r##"https://docs.rs/test/*/test/trait.Foo.html#tymethod.method"##]],
508 );
509 }
510
511
512 #[test]
513 fn test_doc_url_field() {
514 check(
515 r#"
516pub struct Foo {
517 pub fie<|>ld: ()
518}
519
520"#,
521 expect![[r##"https://docs.rs/test/*/test/struct.Foo.html#structfield.field"##]],
522 );
523 }
524}