@@ -146,7 +146,8 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
146
146
}
147
147
} {
148
148
let range = sema. original_range ( & node) . range ;
149
- let text = hover_text_from_name_kind ( db, name_kind. clone ( ) ) . map ( |text| rewrite_links ( db, & text, & name_kind) . unwrap_or ( text) ) ;
149
+ let text = hover_text_from_name_kind ( db, name_kind. clone ( ) ) ;
150
+ let text = text. map ( |text| rewrite_links ( db, & text, & name_kind) . unwrap_or ( text) ) ;
150
151
res. extend ( text) ;
151
152
152
153
if !res. is_empty ( ) {
@@ -405,8 +406,8 @@ fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) ->
405
406
Err ( _) => {
406
407
let link_str = String :: from_utf8 ( link. url . clone ( ) ) . unwrap ( ) ;
407
408
let link_text = String :: from_utf8 ( link. title . clone ( ) ) . unwrap ( ) ;
408
- let resolved = try_resolve_path ( db, definition, & link_str)
409
- . or_else ( || try_resolve_intra ( db, definition, & link_text , & link_str) ) ;
409
+ let resolved = try_resolve_intra ( db, definition, & link_text , & link_str)
410
+ . or_else ( || try_resolve_path ( db, definition, & link_str) ) ;
410
411
411
412
if let Some ( resolved) = resolved {
412
413
link. url = resolved. as_bytes ( ) . to_vec ( ) ;
@@ -420,7 +421,7 @@ fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) ->
420
421
} ) ;
421
422
let mut out = Vec :: new ( ) ;
422
423
format_commonmark ( doc, & ComrakOptions :: default ( ) , & mut out) . ok ( ) ?;
423
- Some ( String :: from_utf8 ( out) . unwrap ( ) )
424
+ Some ( String :: from_utf8 ( out) . unwrap ( ) . trim ( ) . to_string ( ) )
424
425
}
425
426
426
427
#[ derive( PartialEq , Eq , Hash , Copy , Clone , Debug ) ]
@@ -470,32 +471,7 @@ fn try_resolve_intra(db: &RootDatabase, definition: &Definition, link_text: &str
470
471
let modpath = ModPath :: from_src ( path, & Hygiene :: new_unhygienic ( ) ) . unwrap ( ) ;
471
472
472
473
// Resolve it relative to symbol's location (according to the RFC this should consider small scopes
473
- let resolver = {
474
- use ra_hir_def:: * ;
475
- use hir:: * ;
476
-
477
- // TODO: This should be replaced by implementing HasResolver/TryHasResolver on ModuleDef and Definition.
478
- match definition {
479
- Definition :: ModuleDef ( def) => match def {
480
- ModuleDef :: Module ( m) => Into :: < ModuleId > :: into ( m. clone ( ) ) . resolver ( db) ,
481
- ModuleDef :: Function ( f) => Into :: < FunctionId > :: into ( f. clone ( ) ) . resolver ( db) ,
482
- ModuleDef :: Adt ( adt) => Into :: < AdtId > :: into ( adt. clone ( ) ) . resolver ( db) ,
483
- ModuleDef :: EnumVariant ( ev) => Into :: < GenericDefId > :: into ( Into :: < GenericDef > :: into ( ev. clone ( ) ) ) . resolver ( db) ,
484
- ModuleDef :: Const ( c) => Into :: < GenericDefId > :: into ( Into :: < GenericDef > :: into ( c. clone ( ) ) ) . resolver ( db) ,
485
- ModuleDef :: Static ( s) => Into :: < StaticId > :: into ( s. clone ( ) ) . resolver ( db) ,
486
- ModuleDef :: Trait ( t) => Into :: < TraitId > :: into ( t. clone ( ) ) . resolver ( db) ,
487
- ModuleDef :: TypeAlias ( t) => Into :: < ModuleId > :: into ( t. module ( db) ) . resolver ( db) ,
488
- // TODO: This should be a resolver relative to `std`
489
- ModuleDef :: BuiltinType ( _t) => Into :: < ModuleId > :: into ( definition. module ( db) ?) . resolver ( db)
490
- } ,
491
- Definition :: Field ( field) => Into :: < VariantId > :: into ( Into :: < VariantDef > :: into ( field. parent_def ( db) ) ) . resolver ( db) ,
492
- Definition :: Macro ( m) => Into :: < ModuleId > :: into ( m. module ( db) ?) . resolver ( db) ,
493
- Definition :: SelfType ( imp) => Into :: < ImplId > :: into ( imp. clone ( ) ) . resolver ( db) ,
494
- // it's possible, read probable, that other arms of this are also unreachable
495
- Definition :: Local ( _local) => unreachable ! ( ) ,
496
- Definition :: TypeParam ( tp) => Into :: < ModuleId > :: into ( tp. module ( db) ) . resolver ( db)
497
- }
498
- } ;
474
+ let resolver = definition. resolver ( db) ?;
499
475
500
476
// Namespace disambiguation
501
477
let namespace = Namespace :: from_intra_spec ( link_target) ;
@@ -527,7 +503,7 @@ fn try_resolve_intra(db: &RootDatabase, definition: &Definition, link_text: &str
527
503
get_doc_url ( db, & krate) ?
528
504
. join ( & format ! ( "{}/" , krate. display_name( db) ?) ) . ok ( ) ?
529
505
. join ( & path. segments . iter ( ) . map ( |name| format ! ( "{}" , name) ) . join ( "/" ) ) . ok ( ) ?
530
- . join ( & get_symbol_filename ( db, definition ) ?) . ok ( ) ?
506
+ . join ( & get_symbol_filename ( db, & Definition :: ModuleDef ( def ) ) ?) . ok ( ) ?
531
507
. into_string ( )
532
508
)
533
509
}
@@ -637,11 +613,20 @@ mod tests {
637
613
638
614
use crate :: mock_analysis:: analysis_and_position;
639
615
640
- fn trim_markup ( s : & str ) -> & str {
641
- s. trim_start_matches ( "```rust\n " ) . trim_end_matches ( "\n ```" )
616
+ fn trim_markup ( s : & str ) -> String {
617
+ s
618
+ . replace ( "``` rust" , "```rust" )
619
+ . replace ( "-----" , "___" )
620
+ . replace ( "\n \n ___\n \n " , "\n ___\n \n " )
621
+ . replace ( "\\ <-" , "<-" )
622
+ . trim_start_matches ( "test\n ```\n \n " )
623
+ . trim_start_matches ( "```rust\n " )
624
+ . trim_start_matches ( "test\n ```\n \n ```rust\n " )
625
+ . trim_end_matches ( "\n ```" )
626
+ . to_string ( )
642
627
}
643
628
644
- fn trim_markup_opt ( s : Option < & str > ) -> Option < & str > {
629
+ fn trim_markup_opt ( s : Option < & str > ) -> Option < String > {
645
630
s. map ( trim_markup)
646
631
}
647
632
@@ -689,7 +674,7 @@ fn main() {
689
674
) ;
690
675
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
691
676
assert_eq ! ( hover. range, TextRange :: new( 58 . into( ) , 63 . into( ) ) ) ;
692
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "u32" ) ) ;
677
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "u32" ) ) ;
693
678
}
694
679
695
680
#[ test]
@@ -818,7 +803,7 @@ fn main() {
818
803
};
819
804
}
820
805
"# ,
821
- & [ "Foo\n ```\n \n ```rust\n field_a: u32" ] ,
806
+ & [ "test:: Foo\n ```\n \n ```rust\n field_a: u32" ] ,
822
807
) ;
823
808
824
809
// Hovering over the field in the definition
@@ -835,7 +820,7 @@ fn main() {
835
820
};
836
821
}
837
822
"# ,
838
- & [ "Foo\n ```\n \n ```rust\n field_a: u32" ] ,
823
+ & [ "test:: Foo\n ```\n \n ```rust\n field_a: u32" ] ,
839
824
) ;
840
825
}
841
826
@@ -888,7 +873,7 @@ fn main() {
888
873
" ,
889
874
) ;
890
875
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
891
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "Option\n ```\n \n ```rust\n Some" ) ) ;
876
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "test:: Option\n ```\n \n ```rust\n Some" ) ) ;
892
877
893
878
let ( analysis, position) = analysis_and_position (
894
879
"
@@ -901,7 +886,7 @@ fn main() {
901
886
" ,
902
887
) ;
903
888
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
904
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "Option<i32>" ) ) ;
889
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "Option<i32>" ) ) ;
905
890
}
906
891
907
892
#[ test]
@@ -915,7 +900,7 @@ fn main() {
915
900
}
916
901
"# ,
917
902
& [ "
918
- Option
903
+ test:: Option
919
904
```
920
905
921
906
```rust
@@ -940,7 +925,7 @@ The None variant
940
925
}
941
926
"# ,
942
927
& [ "
943
- Option
928
+ test:: Option
944
929
```
945
930
946
931
```rust
@@ -958,14 +943,14 @@ The Some variant
958
943
fn hover_for_local_variable ( ) {
959
944
let ( analysis, position) = analysis_and_position ( "fn func(foo: i32) { fo<|>o; }" ) ;
960
945
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
961
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "i32" ) ) ;
946
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "i32" ) ) ;
962
947
}
963
948
964
949
#[ test]
965
950
fn hover_for_local_variable_pat ( ) {
966
951
let ( analysis, position) = analysis_and_position ( "fn func(fo<|>o: i32) {}" ) ;
967
952
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
968
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "i32" ) ) ;
953
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "i32" ) ) ;
969
954
}
970
955
971
956
#[ test]
@@ -976,14 +961,14 @@ fn func(foo: i32) { if true { <|>foo; }; }
976
961
" ,
977
962
) ;
978
963
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
979
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "i32" ) ) ;
964
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "i32" ) ) ;
980
965
}
981
966
982
967
#[ test]
983
968
fn hover_for_param_edge ( ) {
984
969
let ( analysis, position) = analysis_and_position ( "fn func(<|>foo: i32) {}" ) ;
985
970
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
986
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "i32" ) ) ;
971
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "i32" ) ) ;
987
972
}
988
973
989
974
#[ test]
@@ -1004,7 +989,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1004
989
" ,
1005
990
) ;
1006
991
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
1007
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "Thing" ) ) ;
992
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "Thing" ) ) ;
1008
993
}
1009
994
1010
995
#[ test]
@@ -1028,8 +1013,8 @@ fn func(foo: i32) { if true { <|>foo; }; }
1028
1013
) ;
1029
1014
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
1030
1015
assert_eq ! (
1031
- trim_markup_opt( hover. info. first( ) ) ,
1032
- Some ( "wrapper::Thing\n ```\n \n ```rust\n fn new() -> Thing" )
1016
+ trim_markup_opt( hover. info. first( ) ) . as_deref ( ) ,
1017
+ Some ( "test:: wrapper::Thing\n ```\n \n ```rust\n fn new() -> Thing" )
1033
1018
) ;
1034
1019
}
1035
1020
@@ -1052,7 +1037,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1052
1037
" ,
1053
1038
) ;
1054
1039
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
1055
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "const C: u32" ) ) ;
1040
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "const C: u32" ) ) ;
1056
1041
}
1057
1042
1058
1043
#[ test]
@@ -1068,7 +1053,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1068
1053
" ,
1069
1054
) ;
1070
1055
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
1071
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "Thing" ) ) ;
1056
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "Thing" ) ) ;
1072
1057
1073
1058
/* FIXME: revive these tests
1074
1059
let (analysis, position) = analysis_and_position(
@@ -1125,7 +1110,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1125
1110
" ,
1126
1111
) ;
1127
1112
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
1128
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "i32" ) ) ;
1113
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "i32" ) ) ;
1129
1114
}
1130
1115
1131
1116
#[ test]
@@ -1142,7 +1127,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1142
1127
" ,
1143
1128
) ;
1144
1129
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
1145
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "macro_rules! foo" ) ) ;
1130
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "macro_rules! foo" ) ) ;
1146
1131
}
1147
1132
1148
1133
#[ test]
@@ -1153,7 +1138,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1153
1138
" ,
1154
1139
) ;
1155
1140
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
1156
- assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "i32" ) ) ;
1141
+ assert_eq ! ( trim_markup_opt( hover. info. first( ) ) . as_deref ( ) , Some ( "i32" ) ) ;
1157
1142
}
1158
1143
1159
1144
#[ test]
@@ -1414,6 +1399,59 @@ fn func(foo: i32) { if true { <|>foo; }; }
1414
1399
) ;
1415
1400
}
1416
1401
1402
+ #[ test]
1403
+ fn test_hover_path_link ( ) {
1404
+ check_hover_result (
1405
+ r"
1406
+ //- /lib.rs
1407
+ pub struct Foo;
1408
+ /// [Foo](struct.Foo.html)
1409
+ pub struct B<|>ar
1410
+ " ,
1411
+ & [ "pub struct Bar\n ```\n ___\n \n [Foo](https://docs.rs/test/*/test/struct.Foo.html)" ]
1412
+ ) ;
1413
+ }
1414
+
1415
+ #[ test]
1416
+ fn test_hover_intra_link ( ) {
1417
+ check_hover_result (
1418
+ r"
1419
+ //- /lib.rs
1420
+ pub struct Foo;
1421
+ /// [Foo](Foo)
1422
+ pub struct B<|>ar
1423
+ " ,
1424
+ & [ "pub struct Bar\n ```\n ___\n \n [Foo](https://docs.rs/test/*/test/struct.Foo.html)" ]
1425
+ ) ;
1426
+ }
1427
+
1428
+ #[ test]
1429
+ fn test_hover_intra_link_shortlink ( ) {
1430
+ check_hover_result (
1431
+ r"
1432
+ //- /lib.rs
1433
+ pub struct Foo;
1434
+ /// [Foo]
1435
+ pub struct B<|>ar
1436
+ " ,
1437
+ & [ "pub struct Bar\n ```\n ___\n \n [Foo](https://docs.rs/test/*/test/struct.Foo.html)" ]
1438
+ ) ;
1439
+ }
1440
+
1441
+ #[ test]
1442
+ fn test_hover_intra_link_namespaced ( ) {
1443
+ check_hover_result (
1444
+ r"
1445
+ //- /lib.rs
1446
+ pub struct Foo;
1447
+ fn Foo() {}
1448
+ /// [Foo()]
1449
+ pub struct B<|>ar
1450
+ " ,
1451
+ & [ "pub struct Bar\n ```\n ___\n \n [Foo](https://docs.rs/test/*/test/struct.Foo.html)" ]
1452
+ ) ;
1453
+ }
1454
+
1417
1455
#[ test]
1418
1456
fn test_hover_macro_generated_struct_fn_doc_comment ( ) {
1419
1457
mark:: check!( hover_macro_generated_struct_fn_doc_comment) ;
@@ -1438,7 +1476,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1438
1476
bar.fo<|>o();
1439
1477
}
1440
1478
"# ,
1441
- & [ "Bar\n ```\n \n ```rust\n fn foo(&self)\n ```\n ___\n \n Do the foo" ] ,
1479
+ & [ "test:: Bar\n ```\n \n ```rust\n fn foo(&self)\n ```\n ___\n \n Do the foo" ] ,
1442
1480
) ;
1443
1481
}
1444
1482
@@ -1466,7 +1504,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
1466
1504
bar.fo<|>o();
1467
1505
}
1468
1506
"# ,
1469
- & [ "Bar\n ```\n \n ```rust\n fn foo(&self)\n ```\n ___\n \n Do the foo" ] ,
1507
+ & [ "test:: Bar\n ```\n \n ```rust\n fn foo(&self)\n ```\n ___\n \n Do the foo" ] ,
1470
1508
) ;
1471
1509
}
1472
1510
0 commit comments