@@ -112,6 +112,7 @@ pub fn get_doc_link<T: Resolvable + Clone>(db: &dyn HirDatabase, definition: &T)
112
112
// version of import map which follows the same process as rustdoc. Otherwise there'll always be some
113
113
// edge cases where we select the wrong import path.
114
114
fn get_doc_link ( db : & RootDatabase , definition : Definition ) -> Option < String > {
115
+ eprintln ! ( "enter" ) ;
115
116
// Get the outermost definition for the moduledef. This is used to resolve the public path to the type,
116
117
// then we can join the method, field, etc onto it if required.
117
118
let target_def: ModuleDef = match definition {
@@ -131,8 +132,8 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
131
132
let module = definition. module ( db) ?;
132
133
let krate = module. krate ( ) ;
133
134
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) ) )
136
137
. join ( "/" ) ;
137
138
138
139
let filename = get_symbol_filename ( db, & target_def) ;
@@ -152,6 +153,7 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
152
153
Definition :: Field ( field) => get_symbol_fragment ( db, & FieldOrAssocItem :: Field ( field) ) ,
153
154
_ => None ,
154
155
} ;
156
+ eprintln ! ( "end-ish" ) ;
155
157
156
158
get_doc_url ( db, & krate)
157
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) ]
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