diff options
Diffstat (limited to 'crates/ide/src')
-rw-r--r-- | crates/ide/src/hover.rs | 597 | ||||
-rw-r--r-- | crates/ide/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/ide/src/link_rewrite.rs | 81 | ||||
-rw-r--r-- | crates/ide/src/mock_analysis.rs | 2 |
4 files changed, 625 insertions, 56 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index c75b2a510..b012e4900 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -14,6 +14,7 @@ use test_utils::mark; | |||
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | display::{macro_label, ShortLabel, ToNav, TryToNav}, | 16 | display::{macro_label, ShortLabel, ToNav, TryToNav}, |
17 | link_rewrite::rewrite_links, | ||
17 | markup::Markup, | 18 | markup::Markup, |
18 | runnables::runnable, | 19 | runnables::runnable, |
19 | FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, | 20 | FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, |
@@ -92,7 +93,8 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
92 | }; | 93 | }; |
93 | if let Some(definition) = definition { | 94 | if let Some(definition) = definition { |
94 | if let Some(markup) = hover_for_definition(db, definition) { | 95 | if let Some(markup) = hover_for_definition(db, definition) { |
95 | res.markup = markup; | 96 | let markup = rewrite_links(db, &markup.as_str(), &definition); |
97 | res.markup = Markup::from(markup); | ||
96 | if let Some(action) = show_implementations_action(db, definition) { | 98 | if let Some(action) = show_implementations_action(db, definition) { |
97 | res.actions.push(action); | 99 | res.actions.push(action); |
98 | } | 100 | } |
@@ -425,6 +427,7 @@ fn main() { | |||
425 | "#, | 427 | "#, |
426 | expect![[r#" | 428 | expect![[r#" |
427 | *iter* | 429 | *iter* |
430 | |||
428 | ```rust | 431 | ```rust |
429 | Iter<Scan<OtherStruct<OtherStruct<i32>>, |&mut u32, &u32, &mut u32| -> Option<u32>, u32>> | 432 | Iter<Scan<OtherStruct<OtherStruct<i32>>, |&mut u32, &u32, &mut u32| -> Option<u32>, u32>> |
430 | ``` | 433 | ``` |
@@ -443,6 +446,11 @@ fn main() { let foo_test = fo<|>o(); } | |||
443 | "#, | 446 | "#, |
444 | expect![[r#" | 447 | expect![[r#" |
445 | *foo* | 448 | *foo* |
449 | |||
450 | ```rust | ||
451 | test | ||
452 | ``` | ||
453 | |||
446 | ```rust | 454 | ```rust |
447 | pub fn foo() -> u32 | 455 | pub fn foo() -> u32 |
448 | ``` | 456 | ``` |
@@ -487,6 +495,11 @@ fn main() { let foo_test = fo<|>o(); } | |||
487 | "#, | 495 | "#, |
488 | expect![[r#" | 496 | expect![[r#" |
489 | *foo* | 497 | *foo* |
498 | |||
499 | ```rust | ||
500 | test | ||
501 | ``` | ||
502 | |||
490 | ```rust | 503 | ```rust |
491 | pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str | 504 | pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str |
492 | ``` | 505 | ``` |
@@ -504,6 +517,11 @@ fn main() { } | |||
504 | "#, | 517 | "#, |
505 | expect![[r#" | 518 | expect![[r#" |
506 | *foo* | 519 | *foo* |
520 | |||
521 | ```rust | ||
522 | test | ||
523 | ``` | ||
524 | |||
507 | ```rust | 525 | ```rust |
508 | pub fn foo(a: u32, b: u32) -> u32 | 526 | pub fn foo(a: u32, b: u32) -> u32 |
509 | ``` | 527 | ``` |
@@ -525,20 +543,27 @@ pub fn foo<|>(_: &Path) {} | |||
525 | 543 | ||
526 | fn main() { } | 544 | fn main() { } |
527 | "#, | 545 | "#, |
528 | expect![[r#" | 546 | expect![[r##" |
529 | *foo* | 547 | *foo* |
548 | |||
549 | ```rust | ||
550 | test | ||
551 | ``` | ||
552 | |||
530 | ```rust | 553 | ```rust |
531 | pub fn foo(_: &Path) | 554 | pub fn foo(_: &Path) |
532 | ``` | 555 | ``` |
533 | ___ | 556 | |
557 | --- | ||
534 | 558 | ||
535 | # Example | 559 | # Example |
560 | |||
536 | ``` | 561 | ``` |
537 | # use std::path::Path; | 562 | # use std::path::Path; |
538 | # | 563 | # |
539 | foo(Path::new("hello, world!")) | 564 | foo(Path::new("hello, world!")) |
540 | ``` | 565 | ``` |
541 | "#]], | 566 | "##]], |
542 | ); | 567 | ); |
543 | } | 568 | } |
544 | 569 | ||
@@ -555,8 +580,9 @@ fn main() { | |||
555 | "#, | 580 | "#, |
556 | expect![[r#" | 581 | expect![[r#" |
557 | *field_a* | 582 | *field_a* |
583 | |||
558 | ```rust | 584 | ```rust |
559 | Foo | 585 | test::Foo |
560 | ``` | 586 | ``` |
561 | 587 | ||
562 | ```rust | 588 | ```rust |
@@ -576,8 +602,9 @@ fn main() { | |||
576 | "#, | 602 | "#, |
577 | expect![[r#" | 603 | expect![[r#" |
578 | *field_a* | 604 | *field_a* |
605 | |||
579 | ```rust | 606 | ```rust |
580 | Foo | 607 | test::Foo |
581 | ``` | 608 | ``` |
582 | 609 | ||
583 | ```rust | 610 | ```rust |
@@ -593,6 +620,11 @@ fn main() { | |||
593 | r#"const foo<|>: u32 = 123;"#, | 620 | r#"const foo<|>: u32 = 123;"#, |
594 | expect![[r#" | 621 | expect![[r#" |
595 | *foo* | 622 | *foo* |
623 | |||
624 | ```rust | ||
625 | test | ||
626 | ``` | ||
627 | |||
596 | ```rust | 628 | ```rust |
597 | const foo: u32 = 123 | 629 | const foo: u32 = 123 |
598 | ``` | 630 | ``` |
@@ -602,6 +634,11 @@ fn main() { | |||
602 | r#"static foo<|>: u32 = 456;"#, | 634 | r#"static foo<|>: u32 = 456;"#, |
603 | expect![[r#" | 635 | expect![[r#" |
604 | *foo* | 636 | *foo* |
637 | |||
638 | ```rust | ||
639 | test | ||
640 | ``` | ||
641 | |||
605 | ```rust | 642 | ```rust |
606 | static foo: u32 | 643 | static foo: u32 |
607 | ``` | 644 | ``` |
@@ -620,6 +657,7 @@ fn main() { | |||
620 | }"#, | 657 | }"#, |
621 | expect![[r#" | 658 | expect![[r#" |
622 | *zz* | 659 | *zz* |
660 | |||
623 | ```rust | 661 | ```rust |
624 | Test<i32, u8> | 662 | Test<i32, u8> |
625 | ``` | 663 | ``` |
@@ -638,8 +676,9 @@ fn main() { So<|>me(12); } | |||
638 | "#, | 676 | "#, |
639 | expect![[r#" | 677 | expect![[r#" |
640 | *Some* | 678 | *Some* |
679 | |||
641 | ```rust | 680 | ```rust |
642 | Option | 681 | test::Option |
643 | ``` | 682 | ``` |
644 | 683 | ||
645 | ```rust | 684 | ```rust |
@@ -657,6 +696,7 @@ fn main() { let b<|>ar = Some(12); } | |||
657 | "#, | 696 | "#, |
658 | expect![[r#" | 697 | expect![[r#" |
659 | *bar* | 698 | *bar* |
699 | |||
660 | ```rust | 700 | ```rust |
661 | Option<i32> | 701 | Option<i32> |
662 | ``` | 702 | ``` |
@@ -675,14 +715,16 @@ enum Option<T> { | |||
675 | "#, | 715 | "#, |
676 | expect![[r#" | 716 | expect![[r#" |
677 | *None* | 717 | *None* |
718 | |||
678 | ```rust | 719 | ```rust |
679 | Option | 720 | test::Option |
680 | ``` | 721 | ``` |
681 | 722 | ||
682 | ```rust | 723 | ```rust |
683 | None | 724 | None |
684 | ``` | 725 | ``` |
685 | ___ | 726 | |
727 | --- | ||
686 | 728 | ||
687 | The None variant | 729 | The None variant |
688 | "#]], | 730 | "#]], |
@@ -700,14 +742,16 @@ fn main() { | |||
700 | "#, | 742 | "#, |
701 | expect![[r#" | 743 | expect![[r#" |
702 | *Some* | 744 | *Some* |
745 | |||
703 | ```rust | 746 | ```rust |
704 | Option | 747 | test::Option |
705 | ``` | 748 | ``` |
706 | 749 | ||
707 | ```rust | 750 | ```rust |
708 | Some | 751 | Some |
709 | ``` | 752 | ``` |
710 | ___ | 753 | |
754 | --- | ||
711 | 755 | ||
712 | The Some variant | 756 | The Some variant |
713 | "#]], | 757 | "#]], |
@@ -720,6 +764,7 @@ fn main() { | |||
720 | r#"fn func(foo: i32) { fo<|>o; }"#, | 764 | r#"fn func(foo: i32) { fo<|>o; }"#, |
721 | expect![[r#" | 765 | expect![[r#" |
722 | *foo* | 766 | *foo* |
767 | |||
723 | ```rust | 768 | ```rust |
724 | i32 | 769 | i32 |
725 | ``` | 770 | ``` |
@@ -733,6 +778,7 @@ fn main() { | |||
733 | r#"fn func(fo<|>o: i32) {}"#, | 778 | r#"fn func(fo<|>o: i32) {}"#, |
734 | expect![[r#" | 779 | expect![[r#" |
735 | *foo* | 780 | *foo* |
781 | |||
736 | ```rust | 782 | ```rust |
737 | i32 | 783 | i32 |
738 | ``` | 784 | ``` |
@@ -746,6 +792,7 @@ fn main() { | |||
746 | r#"fn func(foo: i32) { if true { <|>foo; }; }"#, | 792 | r#"fn func(foo: i32) { if true { <|>foo; }; }"#, |
747 | expect![[r#" | 793 | expect![[r#" |
748 | *foo* | 794 | *foo* |
795 | |||
749 | ```rust | 796 | ```rust |
750 | i32 | 797 | i32 |
751 | ``` | 798 | ``` |
@@ -759,6 +806,7 @@ fn main() { | |||
759 | r#"fn func(<|>foo: i32) {}"#, | 806 | r#"fn func(<|>foo: i32) {}"#, |
760 | expect![[r#" | 807 | expect![[r#" |
761 | *foo* | 808 | *foo* |
809 | |||
762 | ```rust | 810 | ```rust |
763 | i32 | 811 | i32 |
764 | ``` | 812 | ``` |
@@ -778,6 +826,7 @@ fn main() { | |||
778 | fn f(_x<|>: impl Deref<Target=u8> + DerefMut<Target=u8>) {}"#, | 826 | fn f(_x<|>: impl Deref<Target=u8> + DerefMut<Target=u8>) {}"#, |
779 | expect![[r#" | 827 | expect![[r#" |
780 | *_x* | 828 | *_x* |
829 | |||
781 | ```rust | 830 | ```rust |
782 | impl Deref<Target = u8> + DerefMut<Target = u8> | 831 | impl Deref<Target = u8> + DerefMut<Target = u8> |
783 | ``` | 832 | ``` |
@@ -799,6 +848,7 @@ fn main() { let foo_<|>test = Thing::new(); } | |||
799 | "#, | 848 | "#, |
800 | expect![[r#" | 849 | expect![[r#" |
801 | *foo_test* | 850 | *foo_test* |
851 | |||
802 | ```rust | 852 | ```rust |
803 | Thing | 853 | Thing |
804 | ``` | 854 | ``` |
@@ -822,8 +872,9 @@ fn main() { let foo_test = wrapper::Thing::new<|>(); } | |||
822 | "#, | 872 | "#, |
823 | expect![[r#" | 873 | expect![[r#" |
824 | *new* | 874 | *new* |
875 | |||
825 | ```rust | 876 | ```rust |
826 | wrapper::Thing | 877 | test::wrapper::Thing |
827 | ``` | 878 | ``` |
828 | 879 | ||
829 | ```rust | 880 | ```rust |
@@ -852,6 +903,11 @@ fn main() { | |||
852 | "#, | 903 | "#, |
853 | expect![[r#" | 904 | expect![[r#" |
854 | *C* | 905 | *C* |
906 | |||
907 | ```rust | ||
908 | test | ||
909 | ``` | ||
910 | |||
855 | ```rust | 911 | ```rust |
856 | const C: u32 = 1 | 912 | const C: u32 = 1 |
857 | ``` | 913 | ``` |
@@ -929,6 +985,7 @@ fn y() { | |||
929 | "#, | 985 | "#, |
930 | expect![[r#" | 986 | expect![[r#" |
931 | *x* | 987 | *x* |
988 | |||
932 | ```rust | 989 | ```rust |
933 | i32 | 990 | i32 |
934 | ``` | 991 | ``` |
@@ -946,6 +1003,11 @@ fn f() { fo<|>o!(); } | |||
946 | "#, | 1003 | "#, |
947 | expect![[r#" | 1004 | expect![[r#" |
948 | *foo* | 1005 | *foo* |
1006 | |||
1007 | ```rust | ||
1008 | test | ||
1009 | ``` | ||
1010 | |||
949 | ```rust | 1011 | ```rust |
950 | macro_rules! foo | 1012 | macro_rules! foo |
951 | ``` | 1013 | ``` |
@@ -976,6 +1038,11 @@ id! { | |||
976 | "#, | 1038 | "#, |
977 | expect![[r#" | 1039 | expect![[r#" |
978 | *foo* | 1040 | *foo* |
1041 | |||
1042 | ```rust | ||
1043 | test | ||
1044 | ``` | ||
1045 | |||
979 | ```rust | 1046 | ```rust |
980 | fn foo() | 1047 | fn foo() |
981 | ``` | 1048 | ``` |
@@ -992,6 +1059,7 @@ fn foo(bar:u32) { let a = id!(ba<|>r); } | |||
992 | "#, | 1059 | "#, |
993 | expect![[r#" | 1060 | expect![[r#" |
994 | *bar* | 1061 | *bar* |
1062 | |||
995 | ```rust | 1063 | ```rust |
996 | u32 | 1064 | u32 |
997 | ``` | 1065 | ``` |
@@ -1009,6 +1077,7 @@ fn foo(bar:u32) { let a = id!(ba<|>r); } | |||
1009 | "#, | 1077 | "#, |
1010 | expect![[r#" | 1078 | expect![[r#" |
1011 | *bar* | 1079 | *bar* |
1080 | |||
1012 | ```rust | 1081 | ```rust |
1013 | u32 | 1082 | u32 |
1014 | ``` | 1083 | ``` |
@@ -1067,6 +1136,11 @@ fn foo() { | |||
1067 | "#, | 1136 | "#, |
1068 | expect![[r#" | 1137 | expect![[r#" |
1069 | *bar* | 1138 | *bar* |
1139 | |||
1140 | ```rust | ||
1141 | test | ||
1142 | ``` | ||
1143 | |||
1070 | ```rust | 1144 | ```rust |
1071 | fn bar() -> bool | 1145 | fn bar() -> bool |
1072 | ``` | 1146 | ``` |
@@ -1099,12 +1173,18 @@ fn bar() { fo<|>o(); } | |||
1099 | ", | 1173 | ", |
1100 | expect![[r#" | 1174 | expect![[r#" |
1101 | *foo* | 1175 | *foo* |
1176 | |||
1177 | ```rust | ||
1178 | test | ||
1179 | ``` | ||
1180 | |||
1102 | ```rust | 1181 | ```rust |
1103 | fn foo() | 1182 | fn foo() |
1104 | ``` | 1183 | ``` |
1105 | ___ | ||
1106 | 1184 | ||
1107 | <- ` ` here | 1185 | --- |
1186 | |||
1187 | \<- ` ` here | ||
1108 | "#]], | 1188 | "#]], |
1109 | ); | 1189 | ); |
1110 | } | 1190 | } |
@@ -1115,6 +1195,11 @@ fn bar() { fo<|>o(); } | |||
1115 | r#"async fn foo<|>() {}"#, | 1195 | r#"async fn foo<|>() {}"#, |
1116 | expect![[r#" | 1196 | expect![[r#" |
1117 | *foo* | 1197 | *foo* |
1198 | |||
1199 | ```rust | ||
1200 | test | ||
1201 | ``` | ||
1202 | |||
1118 | ```rust | 1203 | ```rust |
1119 | async fn foo() | 1204 | async fn foo() |
1120 | ``` | 1205 | ``` |
@@ -1124,6 +1209,11 @@ fn bar() { fo<|>o(); } | |||
1124 | r#"pub const unsafe fn foo<|>() {}"#, | 1209 | r#"pub const unsafe fn foo<|>() {}"#, |
1125 | expect![[r#" | 1210 | expect![[r#" |
1126 | *foo* | 1211 | *foo* |
1212 | |||
1213 | ```rust | ||
1214 | test | ||
1215 | ``` | ||
1216 | |||
1127 | ```rust | 1217 | ```rust |
1128 | pub const unsafe fn foo() | 1218 | pub const unsafe fn foo() |
1129 | ``` | 1219 | ``` |
@@ -1133,6 +1223,11 @@ fn bar() { fo<|>o(); } | |||
1133 | r#"pub(crate) async unsafe extern "C" fn foo<|>() {}"#, | 1223 | r#"pub(crate) async unsafe extern "C" fn foo<|>() {}"#, |
1134 | expect![[r#" | 1224 | expect![[r#" |
1135 | *foo* | 1225 | *foo* |
1226 | |||
1227 | ```rust | ||
1228 | test | ||
1229 | ``` | ||
1230 | |||
1136 | ```rust | 1231 | ```rust |
1137 | pub(crate) async unsafe extern "C" fn foo() | 1232 | pub(crate) async unsafe extern "C" fn foo() |
1138 | ``` | 1233 | ``` |
@@ -1210,6 +1305,11 @@ fn my() {} | |||
1210 | "#, | 1305 | "#, |
1211 | expect![[r#" | 1306 | expect![[r#" |
1212 | *my* | 1307 | *my* |
1308 | |||
1309 | ```rust | ||
1310 | test | ||
1311 | ``` | ||
1312 | |||
1213 | ```rust | 1313 | ```rust |
1214 | mod my | 1314 | mod my |
1215 | ``` | 1315 | ``` |
@@ -1228,10 +1328,16 @@ fn foo() { let bar = Ba<|>r; } | |||
1228 | "#, | 1328 | "#, |
1229 | expect![[r#" | 1329 | expect![[r#" |
1230 | *Bar* | 1330 | *Bar* |
1331 | |||
1332 | ```rust | ||
1333 | test | ||
1334 | ``` | ||
1335 | |||
1231 | ```rust | 1336 | ```rust |
1232 | struct Bar | 1337 | struct Bar |
1233 | ``` | 1338 | ``` |
1234 | ___ | 1339 | |
1340 | --- | ||
1235 | 1341 | ||
1236 | bar docs | 1342 | bar docs |
1237 | "#]], | 1343 | "#]], |
@@ -1249,10 +1355,16 @@ fn foo() { let bar = Ba<|>r; } | |||
1249 | "#, | 1355 | "#, |
1250 | expect![[r#" | 1356 | expect![[r#" |
1251 | *Bar* | 1357 | *Bar* |
1358 | |||
1359 | ```rust | ||
1360 | test | ||
1361 | ``` | ||
1362 | |||
1252 | ```rust | 1363 | ```rust |
1253 | struct Bar | 1364 | struct Bar |
1254 | ``` | 1365 | ``` |
1255 | ___ | 1366 | |
1367 | --- | ||
1256 | 1368 | ||
1257 | bar docs | 1369 | bar docs |
1258 | "#]], | 1370 | "#]], |
@@ -1272,10 +1384,16 @@ fn foo() { let bar = Ba<|>r; } | |||
1272 | "#, | 1384 | "#, |
1273 | expect![[r#" | 1385 | expect![[r#" |
1274 | *Bar* | 1386 | *Bar* |
1387 | |||
1388 | ```rust | ||
1389 | test | ||
1390 | ``` | ||
1391 | |||
1275 | ```rust | 1392 | ```rust |
1276 | struct Bar | 1393 | struct Bar |
1277 | ``` | 1394 | ``` |
1278 | ___ | 1395 | |
1396 | --- | ||
1279 | 1397 | ||
1280 | bar docs 0 | 1398 | bar docs 0 |
1281 | 1399 | ||
@@ -1287,6 +1405,371 @@ fn foo() { let bar = Ba<|>r; } | |||
1287 | } | 1405 | } |
1288 | 1406 | ||
1289 | #[test] | 1407 | #[test] |
1408 | fn test_hover_path_link() { | ||
1409 | check( | ||
1410 | r" | ||
1411 | //- /lib.rs | ||
1412 | pub struct Foo; | ||
1413 | /// [Foo](struct.Foo.html) | ||
1414 | pub struct B<|>ar | ||
1415 | ", | ||
1416 | expect![[r#" | ||
1417 | *Bar* | ||
1418 | |||
1419 | ```rust | ||
1420 | test | ||
1421 | ``` | ||
1422 | |||
1423 | ```rust | ||
1424 | pub struct Bar | ||
1425 | ``` | ||
1426 | |||
1427 | --- | ||
1428 | |||
1429 | [Foo](https://docs.rs/test/*/test/struct.Foo.html) | ||
1430 | "#]], | ||
1431 | ); | ||
1432 | } | ||
1433 | |||
1434 | #[test] | ||
1435 | fn test_hover_path_link_no_strip() { | ||
1436 | check( | ||
1437 | r" | ||
1438 | //- /lib.rs | ||
1439 | pub struct Foo; | ||
1440 | /// [struct Foo](struct.Foo.html) | ||
1441 | pub struct B<|>ar | ||
1442 | ", | ||
1443 | expect![[r#" | ||
1444 | *Bar* | ||
1445 | |||
1446 | ```rust | ||
1447 | test | ||
1448 | ``` | ||
1449 | |||
1450 | ```rust | ||
1451 | pub struct Bar | ||
1452 | ``` | ||
1453 | |||
1454 | --- | ||
1455 | |||
1456 | [struct Foo](https://docs.rs/test/*/test/struct.Foo.html) | ||
1457 | "#]], | ||
1458 | ); | ||
1459 | } | ||
1460 | |||
1461 | #[ignore = "path based links currently only support documentation on ModuleDef items"] | ||
1462 | #[test] | ||
1463 | fn test_hover_path_link_field() { | ||
1464 | check( | ||
1465 | r" | ||
1466 | //- /lib.rs | ||
1467 | pub struct Foo; | ||
1468 | pub struct Bar { | ||
1469 | /// [Foo](struct.Foo.html) | ||
1470 | fie<|>ld: () | ||
1471 | } | ||
1472 | ", | ||
1473 | expect![[r#" | ||
1474 | *field* | ||
1475 | |||
1476 | ```rust | ||
1477 | test::Bar | ||
1478 | ``` | ||
1479 | |||
1480 | ```rust | ||
1481 | field: () | ||
1482 | ``` | ||
1483 | |||
1484 | --- | ||
1485 | |||
1486 | [Foo](https://docs.rs/test/*/test/struct.Foo.html) | ||
1487 | "#]], | ||
1488 | ); | ||
1489 | } | ||
1490 | |||
1491 | #[test] | ||
1492 | fn test_hover_intra_link() { | ||
1493 | check( | ||
1494 | r" | ||
1495 | //- /lib.rs | ||
1496 | pub mod foo { | ||
1497 | pub struct Foo; | ||
1498 | } | ||
1499 | /// [Foo](foo::Foo) | ||
1500 | pub struct B<|>ar | ||
1501 | ", | ||
1502 | expect![[r#" | ||
1503 | *Bar* | ||
1504 | |||
1505 | ```rust | ||
1506 | test | ||
1507 | ``` | ||
1508 | |||
1509 | ```rust | ||
1510 | pub struct Bar | ||
1511 | ``` | ||
1512 | |||
1513 | --- | ||
1514 | |||
1515 | [Foo](https://docs.rs/test/*/test/foo/struct.Foo.html) | ||
1516 | "#]], | ||
1517 | ); | ||
1518 | } | ||
1519 | |||
1520 | #[test] | ||
1521 | fn test_hover_intra_link_html_root_url() { | ||
1522 | check( | ||
1523 | r#" | ||
1524 | //- /lib.rs | ||
1525 | |||
1526 | #![doc(arbitrary_attribute = "test", html_root_url = "https:/example.com", arbitrary_attribute2)] | ||
1527 | |||
1528 | pub mod foo { | ||
1529 | pub struct Foo; | ||
1530 | } | ||
1531 | /// [Foo](foo::Foo) | ||
1532 | pub struct B<|>ar | ||
1533 | "#, | ||
1534 | expect![[r#" | ||
1535 | *Bar* | ||
1536 | |||
1537 | ```rust | ||
1538 | test | ||
1539 | ``` | ||
1540 | |||
1541 | ```rust | ||
1542 | pub struct Bar | ||
1543 | ``` | ||
1544 | |||
1545 | --- | ||
1546 | |||
1547 | [Foo](https://example.com/test/foo/struct.Foo.html) | ||
1548 | "#]], | ||
1549 | ); | ||
1550 | } | ||
1551 | |||
1552 | #[test] | ||
1553 | fn test_hover_intra_link_shortlink() { | ||
1554 | check( | ||
1555 | r" | ||
1556 | //- /lib.rs | ||
1557 | pub struct Foo; | ||
1558 | /// [Foo] | ||
1559 | pub struct B<|>ar | ||
1560 | ", | ||
1561 | expect![[r#" | ||
1562 | *Bar* | ||
1563 | |||
1564 | ```rust | ||
1565 | test | ||
1566 | ``` | ||
1567 | |||
1568 | ```rust | ||
1569 | pub struct Bar | ||
1570 | ``` | ||
1571 | |||
1572 | --- | ||
1573 | |||
1574 | [Foo](https://docs.rs/test/*/test/struct.Foo.html) | ||
1575 | "#]], | ||
1576 | ); | ||
1577 | } | ||
1578 | |||
1579 | #[test] | ||
1580 | fn test_hover_intra_link_shortlink_code() { | ||
1581 | check( | ||
1582 | r" | ||
1583 | //- /lib.rs | ||
1584 | pub struct Foo; | ||
1585 | /// [`Foo`] | ||
1586 | pub struct B<|>ar | ||
1587 | ", | ||
1588 | expect![[r#" | ||
1589 | *Bar* | ||
1590 | |||
1591 | ```rust | ||
1592 | test | ||
1593 | ``` | ||
1594 | |||
1595 | ```rust | ||
1596 | pub struct Bar | ||
1597 | ``` | ||
1598 | |||
1599 | --- | ||
1600 | |||
1601 | [`Foo`](https://docs.rs/test/*/test/struct.Foo.html) | ||
1602 | "#]], | ||
1603 | ); | ||
1604 | } | ||
1605 | |||
1606 | #[test] | ||
1607 | fn test_hover_intra_link_namespaced() { | ||
1608 | check( | ||
1609 | r" | ||
1610 | //- /lib.rs | ||
1611 | pub struct Foo; | ||
1612 | fn Foo() {} | ||
1613 | /// [Foo()] | ||
1614 | pub struct B<|>ar | ||
1615 | ", | ||
1616 | expect![[r#" | ||
1617 | *Bar* | ||
1618 | |||
1619 | ```rust | ||
1620 | test | ||
1621 | ``` | ||
1622 | |||
1623 | ```rust | ||
1624 | pub struct Bar | ||
1625 | ``` | ||
1626 | |||
1627 | --- | ||
1628 | |||
1629 | [Foo](https://docs.rs/test/*/test/struct.Foo.html) | ||
1630 | "#]], | ||
1631 | ); | ||
1632 | } | ||
1633 | |||
1634 | #[test] | ||
1635 | fn test_hover_intra_link_shortlink_namspaced_code() { | ||
1636 | check( | ||
1637 | r" | ||
1638 | //- /lib.rs | ||
1639 | pub struct Foo; | ||
1640 | /// [`struct Foo`] | ||
1641 | pub struct B<|>ar | ||
1642 | ", | ||
1643 | expect![[r#" | ||
1644 | *Bar* | ||
1645 | |||
1646 | ```rust | ||
1647 | test | ||
1648 | ``` | ||
1649 | |||
1650 | ```rust | ||
1651 | pub struct Bar | ||
1652 | ``` | ||
1653 | |||
1654 | --- | ||
1655 | |||
1656 | [`Foo`](https://docs.rs/test/*/test/struct.Foo.html) | ||
1657 | "#]], | ||
1658 | ); | ||
1659 | } | ||
1660 | |||
1661 | #[test] | ||
1662 | fn test_hover_intra_link_shortlink_namspaced_code_with_at() { | ||
1663 | check( | ||
1664 | r" | ||
1665 | //- /lib.rs | ||
1666 | pub struct Foo; | ||
1667 | /// [`struct@Foo`] | ||
1668 | pub struct B<|>ar | ||
1669 | ", | ||
1670 | expect![[r#" | ||
1671 | *Bar* | ||
1672 | |||
1673 | ```rust | ||
1674 | test | ||
1675 | ``` | ||
1676 | |||
1677 | ```rust | ||
1678 | pub struct Bar | ||
1679 | ``` | ||
1680 | |||
1681 | --- | ||
1682 | |||
1683 | [`Foo`](https://docs.rs/test/*/test/struct.Foo.html) | ||
1684 | "#]], | ||
1685 | ); | ||
1686 | } | ||
1687 | |||
1688 | #[test] | ||
1689 | fn test_hover_intra_link_reference() { | ||
1690 | check( | ||
1691 | r" | ||
1692 | //- /lib.rs | ||
1693 | pub struct Foo; | ||
1694 | /// [my Foo][foo] | ||
1695 | /// | ||
1696 | /// [foo]: Foo | ||
1697 | pub struct B<|>ar | ||
1698 | ", | ||
1699 | expect![[r#" | ||
1700 | *Bar* | ||
1701 | |||
1702 | ```rust | ||
1703 | test | ||
1704 | ``` | ||
1705 | |||
1706 | ```rust | ||
1707 | pub struct Bar | ||
1708 | ``` | ||
1709 | |||
1710 | --- | ||
1711 | |||
1712 | [my Foo](https://docs.rs/test/*/test/struct.Foo.html) | ||
1713 | "#]], | ||
1714 | ); | ||
1715 | } | ||
1716 | |||
1717 | #[test] | ||
1718 | fn test_hover_external_url() { | ||
1719 | check( | ||
1720 | r" | ||
1721 | //- /lib.rs | ||
1722 | pub struct Foo; | ||
1723 | /// [external](https://www.google.com) | ||
1724 | pub struct B<|>ar | ||
1725 | ", | ||
1726 | expect![[r#" | ||
1727 | *Bar* | ||
1728 | |||
1729 | ```rust | ||
1730 | test | ||
1731 | ``` | ||
1732 | |||
1733 | ```rust | ||
1734 | pub struct Bar | ||
1735 | ``` | ||
1736 | |||
1737 | --- | ||
1738 | |||
1739 | [external](https://www.google.com) | ||
1740 | "#]], | ||
1741 | ); | ||
1742 | } | ||
1743 | |||
1744 | // Check that we don't rewrite links which we can't identify | ||
1745 | #[test] | ||
1746 | fn test_hover_unknown_target() { | ||
1747 | check( | ||
1748 | r" | ||
1749 | //- /lib.rs | ||
1750 | pub struct Foo; | ||
1751 | /// [baz](Baz) | ||
1752 | pub struct B<|>ar | ||
1753 | ", | ||
1754 | expect![[r#" | ||
1755 | *Bar* | ||
1756 | |||
1757 | ```rust | ||
1758 | test | ||
1759 | ``` | ||
1760 | |||
1761 | ```rust | ||
1762 | pub struct Bar | ||
1763 | ``` | ||
1764 | |||
1765 | --- | ||
1766 | |||
1767 | [baz](Baz) | ||
1768 | "#]], | ||
1769 | ); | ||
1770 | } | ||
1771 | |||
1772 | #[test] | ||
1290 | fn test_hover_macro_generated_struct_fn_doc_comment() { | 1773 | fn test_hover_macro_generated_struct_fn_doc_comment() { |
1291 | mark::check!(hover_macro_generated_struct_fn_doc_comment); | 1774 | mark::check!(hover_macro_generated_struct_fn_doc_comment); |
1292 | 1775 | ||
@@ -1308,16 +1791,18 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
1308 | "#, | 1791 | "#, |
1309 | expect![[r#" | 1792 | expect![[r#" |
1310 | *foo* | 1793 | *foo* |
1794 | |||
1311 | ```rust | 1795 | ```rust |
1312 | Bar | 1796 | test::Bar |
1313 | ``` | 1797 | ``` |
1314 | 1798 | ||
1315 | ```rust | 1799 | ```rust |
1316 | fn foo(&self) | 1800 | fn foo(&self) |
1317 | ``` | 1801 | ``` |
1318 | ___ | ||
1319 | 1802 | ||
1320 | Do the foo | 1803 | --- |
1804 | |||
1805 | Do the foo | ||
1321 | "#]], | 1806 | "#]], |
1322 | ); | 1807 | ); |
1323 | } | 1808 | } |
@@ -1344,14 +1829,16 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
1344 | "#, | 1829 | "#, |
1345 | expect![[r#" | 1830 | expect![[r#" |
1346 | *foo* | 1831 | *foo* |
1832 | |||
1347 | ```rust | 1833 | ```rust |
1348 | Bar | 1834 | test::Bar |
1349 | ``` | 1835 | ``` |
1350 | 1836 | ||
1351 | ```rust | 1837 | ```rust |
1352 | fn foo(&self) | 1838 | fn foo(&self) |
1353 | ``` | 1839 | ``` |
1354 | ___ | 1840 | |
1841 | --- | ||
1355 | 1842 | ||
1356 | Do the foo | 1843 | Do the foo |
1357 | "#]], | 1844 | "#]], |
@@ -1526,7 +2013,7 @@ fn main() { let s<|>t = S{ f1:0 }; } | |||
1526 | GoToType( | 2013 | GoToType( |
1527 | [ | 2014 | [ |
1528 | HoverGotoTypeData { | 2015 | HoverGotoTypeData { |
1529 | mod_path: "S", | 2016 | mod_path: "test::S", |
1530 | nav: NavigationTarget { | 2017 | nav: NavigationTarget { |
1531 | file_id: FileId( | 2018 | file_id: FileId( |
1532 | 1, | 2019 | 1, |
@@ -1565,7 +2052,7 @@ fn main() { let s<|>t = S{ f1:Arg(0) }; } | |||
1565 | GoToType( | 2052 | GoToType( |
1566 | [ | 2053 | [ |
1567 | HoverGotoTypeData { | 2054 | HoverGotoTypeData { |
1568 | mod_path: "S", | 2055 | mod_path: "test::S", |
1569 | nav: NavigationTarget { | 2056 | nav: NavigationTarget { |
1570 | file_id: FileId( | 2057 | file_id: FileId( |
1571 | 1, | 2058 | 1, |
@@ -1584,7 +2071,7 @@ fn main() { let s<|>t = S{ f1:Arg(0) }; } | |||
1584 | }, | 2071 | }, |
1585 | }, | 2072 | }, |
1586 | HoverGotoTypeData { | 2073 | HoverGotoTypeData { |
1587 | mod_path: "Arg", | 2074 | mod_path: "test::Arg", |
1588 | nav: NavigationTarget { | 2075 | nav: NavigationTarget { |
1589 | file_id: FileId( | 2076 | file_id: FileId( |
1590 | 1, | 2077 | 1, |
@@ -1623,7 +2110,7 @@ fn main() { let s<|>t = S{ f1: S{ f1: Arg(0) } }; } | |||
1623 | GoToType( | 2110 | GoToType( |
1624 | [ | 2111 | [ |
1625 | HoverGotoTypeData { | 2112 | HoverGotoTypeData { |
1626 | mod_path: "S", | 2113 | mod_path: "test::S", |
1627 | nav: NavigationTarget { | 2114 | nav: NavigationTarget { |
1628 | file_id: FileId( | 2115 | file_id: FileId( |
1629 | 1, | 2116 | 1, |
@@ -1642,7 +2129,7 @@ fn main() { let s<|>t = S{ f1: S{ f1: Arg(0) } }; } | |||
1642 | }, | 2129 | }, |
1643 | }, | 2130 | }, |
1644 | HoverGotoTypeData { | 2131 | HoverGotoTypeData { |
1645 | mod_path: "Arg", | 2132 | mod_path: "test::Arg", |
1646 | nav: NavigationTarget { | 2133 | nav: NavigationTarget { |
1647 | file_id: FileId( | 2134 | file_id: FileId( |
1648 | 1, | 2135 | 1, |
@@ -1684,7 +2171,7 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); } | |||
1684 | GoToType( | 2171 | GoToType( |
1685 | [ | 2172 | [ |
1686 | HoverGotoTypeData { | 2173 | HoverGotoTypeData { |
1687 | mod_path: "A", | 2174 | mod_path: "test::A", |
1688 | nav: NavigationTarget { | 2175 | nav: NavigationTarget { |
1689 | file_id: FileId( | 2176 | file_id: FileId( |
1690 | 1, | 2177 | 1, |
@@ -1703,7 +2190,7 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); } | |||
1703 | }, | 2190 | }, |
1704 | }, | 2191 | }, |
1705 | HoverGotoTypeData { | 2192 | HoverGotoTypeData { |
1706 | mod_path: "B", | 2193 | mod_path: "test::B", |
1707 | nav: NavigationTarget { | 2194 | nav: NavigationTarget { |
1708 | file_id: FileId( | 2195 | file_id: FileId( |
1709 | 1, | 2196 | 1, |
@@ -1722,7 +2209,7 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); } | |||
1722 | }, | 2209 | }, |
1723 | }, | 2210 | }, |
1724 | HoverGotoTypeData { | 2211 | HoverGotoTypeData { |
1725 | mod_path: "M::C", | 2212 | mod_path: "test::M::C", |
1726 | nav: NavigationTarget { | 2213 | nav: NavigationTarget { |
1727 | file_id: FileId( | 2214 | file_id: FileId( |
1728 | 1, | 2215 | 1, |
@@ -1761,7 +2248,7 @@ fn main() { let s<|>t = foo(); } | |||
1761 | GoToType( | 2248 | GoToType( |
1762 | [ | 2249 | [ |
1763 | HoverGotoTypeData { | 2250 | HoverGotoTypeData { |
1764 | mod_path: "Foo", | 2251 | mod_path: "test::Foo", |
1765 | nav: NavigationTarget { | 2252 | nav: NavigationTarget { |
1766 | file_id: FileId( | 2253 | file_id: FileId( |
1767 | 1, | 2254 | 1, |
@@ -1801,7 +2288,7 @@ fn main() { let s<|>t = foo(); } | |||
1801 | GoToType( | 2288 | GoToType( |
1802 | [ | 2289 | [ |
1803 | HoverGotoTypeData { | 2290 | HoverGotoTypeData { |
1804 | mod_path: "Foo", | 2291 | mod_path: "test::Foo", |
1805 | nav: NavigationTarget { | 2292 | nav: NavigationTarget { |
1806 | file_id: FileId( | 2293 | file_id: FileId( |
1807 | 1, | 2294 | 1, |
@@ -1820,7 +2307,7 @@ fn main() { let s<|>t = foo(); } | |||
1820 | }, | 2307 | }, |
1821 | }, | 2308 | }, |
1822 | HoverGotoTypeData { | 2309 | HoverGotoTypeData { |
1823 | mod_path: "S", | 2310 | mod_path: "test::S", |
1824 | nav: NavigationTarget { | 2311 | nav: NavigationTarget { |
1825 | file_id: FileId( | 2312 | file_id: FileId( |
1826 | 1, | 2313 | 1, |
@@ -1860,7 +2347,7 @@ fn main() { let s<|>t = foo(); } | |||
1860 | GoToType( | 2347 | GoToType( |
1861 | [ | 2348 | [ |
1862 | HoverGotoTypeData { | 2349 | HoverGotoTypeData { |
1863 | mod_path: "Foo", | 2350 | mod_path: "test::Foo", |
1864 | nav: NavigationTarget { | 2351 | nav: NavigationTarget { |
1865 | file_id: FileId( | 2352 | file_id: FileId( |
1866 | 1, | 2353 | 1, |
@@ -1879,7 +2366,7 @@ fn main() { let s<|>t = foo(); } | |||
1879 | }, | 2366 | }, |
1880 | }, | 2367 | }, |
1881 | HoverGotoTypeData { | 2368 | HoverGotoTypeData { |
1882 | mod_path: "Bar", | 2369 | mod_path: "test::Bar", |
1883 | nav: NavigationTarget { | 2370 | nav: NavigationTarget { |
1884 | file_id: FileId( | 2371 | file_id: FileId( |
1885 | 1, | 2372 | 1, |
@@ -1922,7 +2409,7 @@ fn main() { let s<|>t = foo(); } | |||
1922 | GoToType( | 2409 | GoToType( |
1923 | [ | 2410 | [ |
1924 | HoverGotoTypeData { | 2411 | HoverGotoTypeData { |
1925 | mod_path: "Foo", | 2412 | mod_path: "test::Foo", |
1926 | nav: NavigationTarget { | 2413 | nav: NavigationTarget { |
1927 | file_id: FileId( | 2414 | file_id: FileId( |
1928 | 1, | 2415 | 1, |
@@ -1941,7 +2428,7 @@ fn main() { let s<|>t = foo(); } | |||
1941 | }, | 2428 | }, |
1942 | }, | 2429 | }, |
1943 | HoverGotoTypeData { | 2430 | HoverGotoTypeData { |
1944 | mod_path: "Bar", | 2431 | mod_path: "test::Bar", |
1945 | nav: NavigationTarget { | 2432 | nav: NavigationTarget { |
1946 | file_id: FileId( | 2433 | file_id: FileId( |
1947 | 1, | 2434 | 1, |
@@ -1960,7 +2447,7 @@ fn main() { let s<|>t = foo(); } | |||
1960 | }, | 2447 | }, |
1961 | }, | 2448 | }, |
1962 | HoverGotoTypeData { | 2449 | HoverGotoTypeData { |
1963 | mod_path: "S1", | 2450 | mod_path: "test::S1", |
1964 | nav: NavigationTarget { | 2451 | nav: NavigationTarget { |
1965 | file_id: FileId( | 2452 | file_id: FileId( |
1966 | 1, | 2453 | 1, |
@@ -1979,7 +2466,7 @@ fn main() { let s<|>t = foo(); } | |||
1979 | }, | 2466 | }, |
1980 | }, | 2467 | }, |
1981 | HoverGotoTypeData { | 2468 | HoverGotoTypeData { |
1982 | mod_path: "S2", | 2469 | mod_path: "test::S2", |
1983 | nav: NavigationTarget { | 2470 | nav: NavigationTarget { |
1984 | file_id: FileId( | 2471 | file_id: FileId( |
1985 | 1, | 2472 | 1, |
@@ -2016,7 +2503,7 @@ fn foo(ar<|>g: &impl Foo) {} | |||
2016 | GoToType( | 2503 | GoToType( |
2017 | [ | 2504 | [ |
2018 | HoverGotoTypeData { | 2505 | HoverGotoTypeData { |
2019 | mod_path: "Foo", | 2506 | mod_path: "test::Foo", |
2020 | nav: NavigationTarget { | 2507 | nav: NavigationTarget { |
2021 | file_id: FileId( | 2508 | file_id: FileId( |
2022 | 1, | 2509 | 1, |
@@ -2056,7 +2543,7 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {} | |||
2056 | GoToType( | 2543 | GoToType( |
2057 | [ | 2544 | [ |
2058 | HoverGotoTypeData { | 2545 | HoverGotoTypeData { |
2059 | mod_path: "Foo", | 2546 | mod_path: "test::Foo", |
2060 | nav: NavigationTarget { | 2547 | nav: NavigationTarget { |
2061 | file_id: FileId( | 2548 | file_id: FileId( |
2062 | 1, | 2549 | 1, |
@@ -2075,7 +2562,7 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {} | |||
2075 | }, | 2562 | }, |
2076 | }, | 2563 | }, |
2077 | HoverGotoTypeData { | 2564 | HoverGotoTypeData { |
2078 | mod_path: "Bar", | 2565 | mod_path: "test::Bar", |
2079 | nav: NavigationTarget { | 2566 | nav: NavigationTarget { |
2080 | file_id: FileId( | 2567 | file_id: FileId( |
2081 | 1, | 2568 | 1, |
@@ -2094,7 +2581,7 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {} | |||
2094 | }, | 2581 | }, |
2095 | }, | 2582 | }, |
2096 | HoverGotoTypeData { | 2583 | HoverGotoTypeData { |
2097 | mod_path: "S", | 2584 | mod_path: "test::S", |
2098 | nav: NavigationTarget { | 2585 | nav: NavigationTarget { |
2099 | file_id: FileId( | 2586 | file_id: FileId( |
2100 | 1, | 2587 | 1, |
@@ -2132,7 +2619,7 @@ fn foo(ar<|>g: &impl Foo<S>) {} | |||
2132 | GoToType( | 2619 | GoToType( |
2133 | [ | 2620 | [ |
2134 | HoverGotoTypeData { | 2621 | HoverGotoTypeData { |
2135 | mod_path: "Foo", | 2622 | mod_path: "test::Foo", |
2136 | nav: NavigationTarget { | 2623 | nav: NavigationTarget { |
2137 | file_id: FileId( | 2624 | file_id: FileId( |
2138 | 1, | 2625 | 1, |
@@ -2151,7 +2638,7 @@ fn foo(ar<|>g: &impl Foo<S>) {} | |||
2151 | }, | 2638 | }, |
2152 | }, | 2639 | }, |
2153 | HoverGotoTypeData { | 2640 | HoverGotoTypeData { |
2154 | mod_path: "S", | 2641 | mod_path: "test::S", |
2155 | nav: NavigationTarget { | 2642 | nav: NavigationTarget { |
2156 | file_id: FileId( | 2643 | file_id: FileId( |
2157 | 1, | 2644 | 1, |
@@ -2194,7 +2681,7 @@ fn main() { let s<|>t = foo(); } | |||
2194 | GoToType( | 2681 | GoToType( |
2195 | [ | 2682 | [ |
2196 | HoverGotoTypeData { | 2683 | HoverGotoTypeData { |
2197 | mod_path: "B", | 2684 | mod_path: "test::B", |
2198 | nav: NavigationTarget { | 2685 | nav: NavigationTarget { |
2199 | file_id: FileId( | 2686 | file_id: FileId( |
2200 | 1, | 2687 | 1, |
@@ -2213,7 +2700,7 @@ fn main() { let s<|>t = foo(); } | |||
2213 | }, | 2700 | }, |
2214 | }, | 2701 | }, |
2215 | HoverGotoTypeData { | 2702 | HoverGotoTypeData { |
2216 | mod_path: "Foo", | 2703 | mod_path: "test::Foo", |
2217 | nav: NavigationTarget { | 2704 | nav: NavigationTarget { |
2218 | file_id: FileId( | 2705 | file_id: FileId( |
2219 | 1, | 2706 | 1, |
@@ -2250,7 +2737,7 @@ fn foo(ar<|>g: &dyn Foo) {} | |||
2250 | GoToType( | 2737 | GoToType( |
2251 | [ | 2738 | [ |
2252 | HoverGotoTypeData { | 2739 | HoverGotoTypeData { |
2253 | mod_path: "Foo", | 2740 | mod_path: "test::Foo", |
2254 | nav: NavigationTarget { | 2741 | nav: NavigationTarget { |
2255 | file_id: FileId( | 2742 | file_id: FileId( |
2256 | 1, | 2743 | 1, |
@@ -2288,7 +2775,7 @@ fn foo(ar<|>g: &dyn Foo<S>) {} | |||
2288 | GoToType( | 2775 | GoToType( |
2289 | [ | 2776 | [ |
2290 | HoverGotoTypeData { | 2777 | HoverGotoTypeData { |
2291 | mod_path: "Foo", | 2778 | mod_path: "test::Foo", |
2292 | nav: NavigationTarget { | 2779 | nav: NavigationTarget { |
2293 | file_id: FileId( | 2780 | file_id: FileId( |
2294 | 1, | 2781 | 1, |
@@ -2307,7 +2794,7 @@ fn foo(ar<|>g: &dyn Foo<S>) {} | |||
2307 | }, | 2794 | }, |
2308 | }, | 2795 | }, |
2309 | HoverGotoTypeData { | 2796 | HoverGotoTypeData { |
2310 | mod_path: "S", | 2797 | mod_path: "test::S", |
2311 | nav: NavigationTarget { | 2798 | nav: NavigationTarget { |
2312 | file_id: FileId( | 2799 | file_id: FileId( |
2313 | 1, | 2800 | 1, |
@@ -2348,7 +2835,7 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} | |||
2348 | GoToType( | 2835 | GoToType( |
2349 | [ | 2836 | [ |
2350 | HoverGotoTypeData { | 2837 | HoverGotoTypeData { |
2351 | mod_path: "ImplTrait", | 2838 | mod_path: "test::ImplTrait", |
2352 | nav: NavigationTarget { | 2839 | nav: NavigationTarget { |
2353 | file_id: FileId( | 2840 | file_id: FileId( |
2354 | 1, | 2841 | 1, |
@@ -2367,7 +2854,7 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} | |||
2367 | }, | 2854 | }, |
2368 | }, | 2855 | }, |
2369 | HoverGotoTypeData { | 2856 | HoverGotoTypeData { |
2370 | mod_path: "B", | 2857 | mod_path: "test::B", |
2371 | nav: NavigationTarget { | 2858 | nav: NavigationTarget { |
2372 | file_id: FileId( | 2859 | file_id: FileId( |
2373 | 1, | 2860 | 1, |
@@ -2386,7 +2873,7 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} | |||
2386 | }, | 2873 | }, |
2387 | }, | 2874 | }, |
2388 | HoverGotoTypeData { | 2875 | HoverGotoTypeData { |
2389 | mod_path: "DynTrait", | 2876 | mod_path: "test::DynTrait", |
2390 | nav: NavigationTarget { | 2877 | nav: NavigationTarget { |
2391 | file_id: FileId( | 2878 | file_id: FileId( |
2392 | 1, | 2879 | 1, |
@@ -2405,7 +2892,7 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} | |||
2405 | }, | 2892 | }, |
2406 | }, | 2893 | }, |
2407 | HoverGotoTypeData { | 2894 | HoverGotoTypeData { |
2408 | mod_path: "S", | 2895 | mod_path: "test::S", |
2409 | nav: NavigationTarget { | 2896 | nav: NavigationTarget { |
2410 | file_id: FileId( | 2897 | file_id: FileId( |
2411 | 1, | 2898 | 1, |
@@ -2453,7 +2940,7 @@ fn main() { let s<|>t = test().get(); } | |||
2453 | GoToType( | 2940 | GoToType( |
2454 | [ | 2941 | [ |
2455 | HoverGotoTypeData { | 2942 | HoverGotoTypeData { |
2456 | mod_path: "Foo", | 2943 | mod_path: "test::Foo", |
2457 | nav: NavigationTarget { | 2944 | nav: NavigationTarget { |
2458 | file_id: FileId( | 2945 | file_id: FileId( |
2459 | 1, | 2946 | 1, |
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index e3af6d5bc..570790384 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -43,6 +43,7 @@ mod status; | |||
43 | mod syntax_highlighting; | 43 | mod syntax_highlighting; |
44 | mod syntax_tree; | 44 | mod syntax_tree; |
45 | mod typing; | 45 | mod typing; |
46 | mod link_rewrite; | ||
46 | 47 | ||
47 | use std::sync::Arc; | 48 | use std::sync::Arc; |
48 | 49 | ||
diff --git a/crates/ide/src/link_rewrite.rs b/crates/ide/src/link_rewrite.rs new file mode 100644 index 000000000..ff3200eef --- /dev/null +++ b/crates/ide/src/link_rewrite.rs | |||
@@ -0,0 +1,81 @@ | |||
1 | //! Resolves and rewrites links in markdown documentation. | ||
2 | //! | ||
3 | //! Most of the implementation can be found in [`hir::doc_links`]. | ||
4 | |||
5 | use pulldown_cmark::{CowStr, Event, Options, Parser, Tag}; | ||
6 | use pulldown_cmark_to_cmark::{cmark_with_options, Options as CmarkOptions}; | ||
7 | |||
8 | use hir::resolve_doc_link; | ||
9 | use ide_db::{defs::Definition, RootDatabase}; | ||
10 | |||
11 | /// Rewrite documentation links in markdown to point to an online host (e.g. docs.rs) | ||
12 | pub fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) -> String { | ||
13 | let doc = Parser::new_with_broken_link_callback( | ||
14 | markdown, | ||
15 | Options::empty(), | ||
16 | Some(&|label, _| Some((/*url*/ label.to_string(), /*title*/ label.to_string()))), | ||
17 | ); | ||
18 | |||
19 | let doc = map_links(doc, |target, title: &str| { | ||
20 | // This check is imperfect, there's some overlap between valid intra-doc links | ||
21 | // and valid URLs so we choose to be too eager to try to resolve what might be | ||
22 | // a URL. | ||
23 | if target.contains("://") { | ||
24 | (target.to_string(), title.to_string()) | ||
25 | } else { | ||
26 | // Two posibilities: | ||
27 | // * path-based links: `../../module/struct.MyStruct.html` | ||
28 | // * module-based links (AKA intra-doc links): `super::super::module::MyStruct` | ||
29 | let resolved = match definition { | ||
30 | Definition::ModuleDef(t) => resolve_doc_link(db, t, title, target), | ||
31 | Definition::Macro(t) => resolve_doc_link(db, t, title, target), | ||
32 | Definition::Field(t) => resolve_doc_link(db, t, title, target), | ||
33 | Definition::SelfType(t) => resolve_doc_link(db, t, title, target), | ||
34 | Definition::Local(t) => resolve_doc_link(db, t, title, target), | ||
35 | Definition::TypeParam(t) => resolve_doc_link(db, t, title, target), | ||
36 | }; | ||
37 | |||
38 | match resolved { | ||
39 | Some((target, title)) => (target, title), | ||
40 | None => (target.to_string(), title.to_string()), | ||
41 | } | ||
42 | } | ||
43 | }); | ||
44 | let mut out = String::new(); | ||
45 | let mut options = CmarkOptions::default(); | ||
46 | options.code_block_backticks = 3; | ||
47 | cmark_with_options(doc, &mut out, None, options).ok(); | ||
48 | out | ||
49 | } | ||
50 | |||
51 | // Rewrites a markdown document, resolving links using `callback` and additionally striping prefixes/suffixes on link titles. | ||
52 | fn map_links<'e>( | ||
53 | events: impl Iterator<Item = Event<'e>>, | ||
54 | callback: impl Fn(&str, &str) -> (String, String), | ||
55 | ) -> impl Iterator<Item = Event<'e>> { | ||
56 | let mut in_link = false; | ||
57 | let mut link_target: Option<CowStr> = None; | ||
58 | |||
59 | events.map(move |evt| match evt { | ||
60 | Event::Start(Tag::Link(_link_type, ref target, _)) => { | ||
61 | in_link = true; | ||
62 | link_target = Some(target.clone()); | ||
63 | evt | ||
64 | } | ||
65 | Event::End(Tag::Link(link_type, _target, _)) => { | ||
66 | in_link = false; | ||
67 | Event::End(Tag::Link(link_type, link_target.take().unwrap(), CowStr::Borrowed(""))) | ||
68 | } | ||
69 | Event::Text(s) if in_link => { | ||
70 | let (link_target_s, link_name) = callback(&link_target.take().unwrap(), &s); | ||
71 | link_target = Some(CowStr::Boxed(link_target_s.into())); | ||
72 | Event::Text(CowStr::Boxed(link_name.into())) | ||
73 | } | ||
74 | Event::Code(s) if in_link => { | ||
75 | let (link_target_s, link_name) = callback(&link_target.take().unwrap(), &s); | ||
76 | link_target = Some(CowStr::Boxed(link_target_s.into())); | ||
77 | Event::Code(CowStr::Boxed(link_name.into())) | ||
78 | } | ||
79 | _ => evt, | ||
80 | }) | ||
81 | } | ||
diff --git a/crates/ide/src/mock_analysis.rs b/crates/ide/src/mock_analysis.rs index 363e6d27e..235796dbc 100644 --- a/crates/ide/src/mock_analysis.rs +++ b/crates/ide/src/mock_analysis.rs | |||
@@ -115,7 +115,7 @@ impl MockAnalysis { | |||
115 | root_crate = Some(crate_graph.add_crate_root( | 115 | root_crate = Some(crate_graph.add_crate_root( |
116 | file_id, | 116 | file_id, |
117 | edition, | 117 | edition, |
118 | None, | 118 | Some("test".to_string()), |
119 | cfg, | 119 | cfg, |
120 | env, | 120 | env, |
121 | Default::default(), | 121 | Default::default(), |