@@ -112,6 +112,7 @@ pub fn get_doc_link<T: Resolvable + Clone>(db: &dyn HirDatabase, definition: &T)
112112// version of import map which follows the same process as rustdoc. Otherwise there'll always be some
113113// edge cases where we select the wrong import path.
114114fn get_doc_link ( db : & RootDatabase , definition : Definition ) -> Option < String > {
115+ eprintln ! ( "enter" ) ;
115116 // Get the outermost definition for the moduledef. This is used to resolve the public path to the type,
116117 // then we can join the method, field, etc onto it if required.
117118 let target_def: ModuleDef = match definition {
@@ -131,8 +132,8 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
131132 let module = definition. module ( db) ?;
132133 let krate = module. krate ( ) ;
133134 let import_map = db. import_map ( krate. into ( ) ) ;
134- let base = once ( krate. display_name ( db) . unwrap ( ) )
135- . chain ( import_map. path_of ( ns) . unwrap ( ) . segments . iter ( ) . map ( |name| format ! ( "{}" , name) ) )
135+ let base = once ( krate. display_name ( db) ? )
136+ . chain ( import_map. path_of ( ns) ? . segments . iter ( ) . map ( |name| format ! ( "{}" , name) ) )
136137 . join ( "/" ) ;
137138
138139 let filename = get_symbol_filename ( db, & target_def) ;
@@ -152,6 +153,7 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
152153 Definition :: Field ( field) => get_symbol_fragment ( db, & FieldOrAssocItem :: Field ( field) ) ,
153154 _ => None ,
154155 } ;
156+ eprintln ! ( "end-ish" ) ;
155157
156158 get_doc_url ( db, & krate)
157159 . and_then ( |url| url. join ( & base) . ok ( ) )
@@ -430,3 +432,93 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
430432 }
431433 }
432434}
435+
436+ #[ cfg( test) ]
437+ mod 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#"
453+ pub 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#"
464+ pub fn fo<|>o() {}
465+ "# ,
466+ expect ! [ [ r#""# ] ] ,
467+ ) ;
468+ }
469+
470+ #[ test]
471+ fn test_doc_url_inherent_method ( ) {
472+ check (
473+ r#"
474+ pub struct Foo;
475+
476+ impl 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#"
489+ pub 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#"
502+ pub 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#"
516+ pub 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+ }
0 commit comments