diff options
-rw-r--r-- | Cargo.lock | 246 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 6 | ||||
-rw-r--r-- | crates/ra_ide/Cargo.toml | 5 | ||||
-rw-r--r-- | crates/ra_ide/src/hover.rs | 333 | ||||
-rw-r--r-- | crates/rust-analyzer/src/handlers.rs | 2 |
5 files changed, 285 insertions, 307 deletions
diff --git a/Cargo.lock b/Cargo.lock index 0c1d2e8b9..c0a9494e5 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -52,17 +52,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
52 | checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" | 52 | checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" |
53 | 53 | ||
54 | [[package]] | 54 | [[package]] |
55 | name = "atty" | ||
56 | version = "0.2.14" | ||
57 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
58 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" | ||
59 | dependencies = [ | ||
60 | "hermit-abi", | ||
61 | "libc", | ||
62 | "winapi 0.3.9", | ||
63 | ] | ||
64 | |||
65 | [[package]] | ||
66 | name = "autocfg" | 55 | name = "autocfg" |
67 | version = "1.0.0" | 56 | version = "1.0.0" |
68 | source = "registry+https://github.com/rust-lang/crates.io-index" | 57 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -95,27 +84,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
95 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" | 84 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" |
96 | 85 | ||
97 | [[package]] | 86 | [[package]] |
98 | name = "block-buffer" | ||
99 | version = "0.7.3" | ||
100 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
101 | checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" | ||
102 | dependencies = [ | ||
103 | "block-padding", | ||
104 | "byte-tools", | ||
105 | "byteorder", | ||
106 | "generic-array", | ||
107 | ] | ||
108 | |||
109 | [[package]] | ||
110 | name = "block-padding" | ||
111 | version = "0.1.5" | ||
112 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
113 | checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" | ||
114 | dependencies = [ | ||
115 | "byte-tools", | ||
116 | ] | ||
117 | |||
118 | [[package]] | ||
119 | name = "bstr" | 87 | name = "bstr" |
120 | version = "0.2.13" | 88 | version = "0.2.13" |
121 | source = "registry+https://github.com/rust-lang/crates.io-index" | 89 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -125,12 +93,6 @@ dependencies = [ | |||
125 | ] | 93 | ] |
126 | 94 | ||
127 | [[package]] | 95 | [[package]] |
128 | name = "byte-tools" | ||
129 | version = "0.3.1" | ||
130 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
131 | checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" | ||
132 | |||
133 | [[package]] | ||
134 | name = "byteorder" | 96 | name = "byteorder" |
135 | version = "1.3.4" | 97 | version = "1.3.4" |
136 | source = "registry+https://github.com/rust-lang/crates.io-index" | 98 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -223,21 +185,6 @@ dependencies = [ | |||
223 | ] | 185 | ] |
224 | 186 | ||
225 | [[package]] | 187 | [[package]] |
226 | name = "clap" | ||
227 | version = "2.33.1" | ||
228 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
229 | checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" | ||
230 | dependencies = [ | ||
231 | "ansi_term", | ||
232 | "atty", | ||
233 | "bitflags", | ||
234 | "strsim", | ||
235 | "textwrap", | ||
236 | "unicode-width", | ||
237 | "vec_map", | ||
238 | ] | ||
239 | |||
240 | [[package]] | ||
241 | name = "cloudabi" | 188 | name = "cloudabi" |
242 | version = "0.1.0" | 189 | version = "0.1.0" |
243 | source = "registry+https://github.com/rust-lang/crates.io-index" | 190 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -247,23 +194,6 @@ dependencies = [ | |||
247 | ] | 194 | ] |
248 | 195 | ||
249 | [[package]] | 196 | [[package]] |
250 | name = "comrak" | ||
251 | version = "0.7.0" | ||
252 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
253 | checksum = "e17058cc536cf290563e88787d7b9e6030ce4742943017cc2ffb71f88034021c" | ||
254 | dependencies = [ | ||
255 | "clap", | ||
256 | "entities", | ||
257 | "lazy_static", | ||
258 | "pest", | ||
259 | "pest_derive", | ||
260 | "regex", | ||
261 | "twoway", | ||
262 | "typed-arena", | ||
263 | "unicode_categories", | ||
264 | ] | ||
265 | |||
266 | [[package]] | ||
267 | name = "console" | 197 | name = "console" |
268 | version = "0.11.3" | 198 | version = "0.11.3" |
269 | source = "registry+https://github.com/rust-lang/crates.io-index" | 199 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -356,15 +286,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
356 | checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" | 286 | checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" |
357 | 287 | ||
358 | [[package]] | 288 | [[package]] |
359 | name = "digest" | ||
360 | version = "0.8.1" | ||
361 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
362 | checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" | ||
363 | dependencies = [ | ||
364 | "generic-array", | ||
365 | ] | ||
366 | |||
367 | [[package]] | ||
368 | name = "drop_bomb" | 289 | name = "drop_bomb" |
369 | version = "0.1.4" | 290 | version = "0.1.4" |
370 | source = "registry+https://github.com/rust-lang/crates.io-index" | 291 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -398,12 +319,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
398 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" | 319 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" |
399 | 320 | ||
400 | [[package]] | 321 | [[package]] |
401 | name = "entities" | ||
402 | version = "1.0.1" | ||
403 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
404 | checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" | ||
405 | |||
406 | [[package]] | ||
407 | name = "env_logger" | 322 | name = "env_logger" |
408 | version = "0.7.1" | 323 | version = "0.7.1" |
409 | source = "registry+https://github.com/rust-lang/crates.io-index" | 324 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -413,12 +328,6 @@ dependencies = [ | |||
413 | ] | 328 | ] |
414 | 329 | ||
415 | [[package]] | 330 | [[package]] |
416 | name = "fake-simd" | ||
417 | version = "0.1.2" | ||
418 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
419 | checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" | ||
420 | |||
421 | [[package]] | ||
422 | name = "filetime" | 331 | name = "filetime" |
423 | version = "0.2.10" | 332 | version = "0.2.10" |
424 | source = "registry+https://github.com/rust-lang/crates.io-index" | 333 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -502,12 +411,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
502 | checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" | 411 | checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" |
503 | 412 | ||
504 | [[package]] | 413 | [[package]] |
505 | name = "generic-array" | 414 | name = "getopts" |
506 | version = "0.12.3" | 415 | version = "0.2.21" |
507 | source = "registry+https://github.com/rust-lang/crates.io-index" | 416 | source = "registry+https://github.com/rust-lang/crates.io-index" |
508 | checksum = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" | 417 | checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" |
509 | dependencies = [ | 418 | dependencies = [ |
510 | "typenum", | 419 | "unicode-width", |
511 | ] | 420 | ] |
512 | 421 | ||
513 | [[package]] | 422 | [[package]] |
@@ -964,12 +873,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
964 | checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" | 873 | checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" |
965 | 874 | ||
966 | [[package]] | 875 | [[package]] |
967 | name = "opaque-debug" | ||
968 | version = "0.2.3" | ||
969 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
970 | checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" | ||
971 | |||
972 | [[package]] | ||
973 | name = "parking_lot" | 876 | name = "parking_lot" |
974 | version = "0.11.0" | 877 | version = "0.11.0" |
975 | source = "registry+https://github.com/rust-lang/crates.io-index" | 878 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1025,49 +928,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1025 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" | 928 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" |
1026 | 929 | ||
1027 | [[package]] | 930 | [[package]] |
1028 | name = "pest" | ||
1029 | version = "2.1.3" | ||
1030 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1031 | checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" | ||
1032 | dependencies = [ | ||
1033 | "ucd-trie", | ||
1034 | ] | ||
1035 | |||
1036 | [[package]] | ||
1037 | name = "pest_derive" | ||
1038 | version = "2.1.0" | ||
1039 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1040 | checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" | ||
1041 | dependencies = [ | ||
1042 | "pest", | ||
1043 | "pest_generator", | ||
1044 | ] | ||
1045 | |||
1046 | [[package]] | ||
1047 | name = "pest_generator" | ||
1048 | version = "2.1.3" | ||
1049 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1050 | checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" | ||
1051 | dependencies = [ | ||
1052 | "pest", | ||
1053 | "pest_meta", | ||
1054 | "proc-macro2", | ||
1055 | "quote", | ||
1056 | "syn", | ||
1057 | ] | ||
1058 | |||
1059 | [[package]] | ||
1060 | name = "pest_meta" | ||
1061 | version = "2.1.3" | ||
1062 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1063 | checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" | ||
1064 | dependencies = [ | ||
1065 | "maplit", | ||
1066 | "pest", | ||
1067 | "sha-1", | ||
1068 | ] | ||
1069 | |||
1070 | [[package]] | ||
1071 | name = "petgraph" | 931 | name = "petgraph" |
1072 | version = "0.5.1" | 932 | version = "0.5.1" |
1073 | source = "registry+https://github.com/rust-lang/crates.io-index" | 933 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1111,6 +971,27 @@ dependencies = [ | |||
1111 | ] | 971 | ] |
1112 | 972 | ||
1113 | [[package]] | 973 | [[package]] |
974 | name = "pulldown-cmark" | ||
975 | version = "0.7.1" | ||
976 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
977 | checksum = "3e142c3b8f49d2200605ee6ba0b1d757310e9e7a72afe78c36ee2ef67300ee00" | ||
978 | dependencies = [ | ||
979 | "bitflags", | ||
980 | "getopts", | ||
981 | "memchr", | ||
982 | "unicase", | ||
983 | ] | ||
984 | |||
985 | [[package]] | ||
986 | name = "pulldown-cmark-to-cmark" | ||
987 | version = "4.0.2" | ||
988 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
989 | checksum = "cffb594e453d29e238ac190362a4a291daec00396717a8d1670863121ac56958" | ||
990 | dependencies = [ | ||
991 | "pulldown-cmark", | ||
992 | ] | ||
993 | |||
994 | [[package]] | ||
1114 | name = "quote" | 995 | name = "quote" |
1115 | version = "1.0.7" | 996 | version = "1.0.7" |
1116 | source = "registry+https://github.com/rust-lang/crates.io-index" | 997 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1264,20 +1145,21 @@ dependencies = [ | |||
1264 | name = "ra_ide" | 1145 | name = "ra_ide" |
1265 | version = "0.1.0" | 1146 | version = "0.1.0" |
1266 | dependencies = [ | 1147 | dependencies = [ |
1267 | "comrak", | ||
1268 | "either", | 1148 | "either", |
1269 | "indexmap", | 1149 | "indexmap", |
1270 | "insta", | 1150 | "insta", |
1271 | "itertools", | 1151 | "itertools", |
1152 | "lazy_static", | ||
1272 | "log", | 1153 | "log", |
1273 | "maplit", | 1154 | "maplit", |
1155 | "pulldown-cmark", | ||
1156 | "pulldown-cmark-to-cmark", | ||
1274 | "ra_assists", | 1157 | "ra_assists", |
1275 | "ra_cfg", | 1158 | "ra_cfg", |
1276 | "ra_db", | 1159 | "ra_db", |
1277 | "ra_fmt", | 1160 | "ra_fmt", |
1278 | "ra_hir", | 1161 | "ra_hir", |
1279 | "ra_hir_def", | 1162 | "ra_hir_def", |
1280 | "ra_hir_expand", | ||
1281 | "ra_ide_db", | 1163 | "ra_ide_db", |
1282 | "ra_parser", | 1164 | "ra_parser", |
1283 | "ra_prof", | 1165 | "ra_prof", |
@@ -1794,18 +1676,6 @@ dependencies = [ | |||
1794 | ] | 1676 | ] |
1795 | 1677 | ||
1796 | [[package]] | 1678 | [[package]] |
1797 | name = "sha-1" | ||
1798 | version = "0.8.2" | ||
1799 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1800 | checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" | ||
1801 | dependencies = [ | ||
1802 | "block-buffer", | ||
1803 | "digest", | ||
1804 | "fake-simd", | ||
1805 | "opaque-debug", | ||
1806 | ] | ||
1807 | |||
1808 | [[package]] | ||
1809 | name = "sharded-slab" | 1679 | name = "sharded-slab" |
1810 | version = "0.0.9" | 1680 | version = "0.0.9" |
1811 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1681 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1840,12 +1710,6 @@ name = "stdx" | |||
1840 | version = "0.1.0" | 1710 | version = "0.1.0" |
1841 | 1711 | ||
1842 | [[package]] | 1712 | [[package]] |
1843 | name = "strsim" | ||
1844 | version = "0.8.0" | ||
1845 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1846 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" | ||
1847 | |||
1848 | [[package]] | ||
1849 | name = "superslice" | 1713 | name = "superslice" |
1850 | version = "1.0.0" | 1714 | version = "1.0.0" |
1851 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1715 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -1925,15 +1789,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
1925 | checksum = "f03e7efdedc3bc78cb2337f1e2785c39e45f5ef762d9e4ebb137fff7380a6d8a" | 1789 | checksum = "f03e7efdedc3bc78cb2337f1e2785c39e45f5ef762d9e4ebb137fff7380a6d8a" |
1926 | 1790 | ||
1927 | [[package]] | 1791 | [[package]] |
1928 | name = "textwrap" | ||
1929 | version = "0.11.0" | ||
1930 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
1931 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" | ||
1932 | dependencies = [ | ||
1933 | "unicode-width", | ||
1934 | ] | ||
1935 | |||
1936 | [[package]] | ||
1937 | name = "thin-dst" | 1792 | name = "thin-dst" |
1938 | version = "1.1.0" | 1793 | version = "1.1.0" |
1939 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1794 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -2046,40 +1901,15 @@ dependencies = [ | |||
2046 | ] | 1901 | ] |
2047 | 1902 | ||
2048 | [[package]] | 1903 | [[package]] |
2049 | name = "twoway" | 1904 | name = "unicase" |
2050 | version = "0.2.1" | 1905 | version = "2.6.0" |
2051 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1906 | source = "registry+https://github.com/rust-lang/crates.io-index" |
2052 | checksum = "6b40075910de3a912adbd80b5d8bad6ad10a23eeb1f5bf9d4006839e899ba5bc" | 1907 | checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" |
2053 | dependencies = [ | 1908 | dependencies = [ |
2054 | "memchr", | 1909 | "version_check", |
2055 | "unchecked-index", | ||
2056 | ] | 1910 | ] |
2057 | 1911 | ||
2058 | [[package]] | 1912 | [[package]] |
2059 | name = "typed-arena" | ||
2060 | version = "1.7.0" | ||
2061 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
2062 | checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d" | ||
2063 | |||
2064 | [[package]] | ||
2065 | name = "typenum" | ||
2066 | version = "1.12.0" | ||
2067 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
2068 | checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" | ||
2069 | |||
2070 | [[package]] | ||
2071 | name = "ucd-trie" | ||
2072 | version = "0.1.3" | ||
2073 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
2074 | checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" | ||
2075 | |||
2076 | [[package]] | ||
2077 | name = "unchecked-index" | ||
2078 | version = "0.2.2" | ||
2079 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
2080 | checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c" | ||
2081 | |||
2082 | [[package]] | ||
2083 | name = "unicode-bidi" | 1913 | name = "unicode-bidi" |
2084 | version = "0.3.4" | 1914 | version = "0.3.4" |
2085 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1915 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -2116,12 +1946,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
2116 | checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" | 1946 | checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" |
2117 | 1947 | ||
2118 | [[package]] | 1948 | [[package]] |
2119 | name = "unicode_categories" | ||
2120 | version = "0.1.1" | ||
2121 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
2122 | checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" | ||
2123 | |||
2124 | [[package]] | ||
2125 | name = "url" | 1949 | name = "url" |
2126 | version = "2.1.1" | 1950 | version = "2.1.1" |
2127 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1951 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -2134,10 +1958,10 @@ dependencies = [ | |||
2134 | ] | 1958 | ] |
2135 | 1959 | ||
2136 | [[package]] | 1960 | [[package]] |
2137 | name = "vec_map" | 1961 | name = "version_check" |
2138 | version = "0.8.2" | 1962 | version = "0.9.2" |
2139 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1963 | source = "registry+https://github.com/rust-lang/crates.io-index" |
2140 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" | 1964 | checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" |
2141 | 1965 | ||
2142 | [[package]] | 1966 | [[package]] |
2143 | name = "vfs" | 1967 | name = "vfs" |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 3364a822f..fe34b30bc 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -66,12 +66,14 @@ pub use hir_def::{ | |||
66 | body::scope::ExprScopes, | 66 | body::scope::ExprScopes, |
67 | builtin_type::BuiltinType, | 67 | builtin_type::BuiltinType, |
68 | docs::Documentation, | 68 | docs::Documentation, |
69 | item_scope::ItemInNs, | ||
69 | nameres::ModuleSource, | 70 | nameres::ModuleSource, |
70 | path::{ModPath, Path, PathKind}, | 71 | path::{ModPath, Path, PathKind}, |
71 | type_ref::Mutability, | 72 | type_ref::Mutability, |
72 | }; | 73 | }; |
73 | pub use hir_expand::{ | 74 | pub use hir_expand::{ |
74 | hygiene::Hygiene, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, | 75 | hygiene::Hygiene, |
75 | MacroFile, Origin, | 76 | name::{AsName, Name}, |
77 | HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Origin, | ||
76 | }; | 78 | }; |
77 | pub use hir_ty::{display::HirDisplay, CallableDef}; | 79 | pub use hir_ty::{display::HirDisplay, CallableDef}; |
diff --git a/crates/ra_ide/Cargo.toml b/crates/ra_ide/Cargo.toml index 1bc095c5b..642b71937 100644 --- a/crates/ra_ide/Cargo.toml +++ b/crates/ra_ide/Cargo.toml | |||
@@ -17,9 +17,11 @@ itertools = "0.9.0" | |||
17 | log = "0.4.8" | 17 | log = "0.4.8" |
18 | rustc-hash = "1.1.0" | 18 | rustc-hash = "1.1.0" |
19 | rand = { version = "0.7.3", features = ["small_rng"] } | 19 | rand = { version = "0.7.3", features = ["small_rng"] } |
20 | comrak = "0.7.0" | ||
21 | url = "*" | 20 | url = "*" |
22 | maplit = "*" | 21 | maplit = "*" |
22 | lazy_static = "*" | ||
23 | pulldown-cmark-to-cmark = "4.0.2" | ||
24 | pulldown-cmark = "0.7.0" | ||
23 | 25 | ||
24 | stdx = { path = "../stdx" } | 26 | stdx = { path = "../stdx" } |
25 | 27 | ||
@@ -36,7 +38,6 @@ ra_ssr = { path = "../ra_ssr" } | |||
36 | ra_project_model = { path = "../ra_project_model" } | 38 | ra_project_model = { path = "../ra_project_model" } |
37 | ra_hir_def = { path = "../ra_hir_def" } | 39 | ra_hir_def = { path = "../ra_hir_def" } |
38 | ra_tt = { path = "../ra_tt" } | 40 | ra_tt = { path = "../ra_tt" } |
39 | ra_hir_expand = { path = "../ra_hir_expand" } | ||
40 | ra_parser = { path = "../ra_parser" } | 41 | ra_parser = { path = "../ra_parser" } |
41 | 42 | ||
42 | # ra_ide should depend only on the top-level `hir` package. if you need | 43 | # ra_ide should depend only on the top-level `hir` package. if you need |
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index 34fc36a1f..82aa24f4f 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs | |||
@@ -1,23 +1,25 @@ | |||
1 | use std::collections::{HashMap, HashSet}; | ||
1 | use std::iter::once; | 2 | use std::iter::once; |
2 | 3 | ||
3 | use hir::{ | 4 | use hir::{ |
4 | Adt, AsAssocItem, AssocItemContainer, FieldSource, HasSource, HirDisplay, ModuleDef, | 5 | db::DefDatabase, Adt, AsAssocItem, AsName, AssocItemContainer, AttrDef, Crate, Documentation, |
5 | ModuleSource, Semantics, Documentation, AttrDef, Crate, ModPath, Hygiene | 6 | FieldSource, HasSource, HirDisplay, Hygiene, ItemInNs, ModPath, ModuleDef, ModuleSource, |
7 | Semantics, Module | ||
6 | }; | 8 | }; |
7 | use itertools::Itertools; | 9 | use itertools::Itertools; |
10 | use lazy_static::lazy_static; | ||
11 | use maplit::{hashmap, hashset}; | ||
12 | use pulldown_cmark::{CowStr, Event, Options, Parser, Tag}; | ||
13 | use pulldown_cmark_to_cmark::cmark; | ||
8 | use ra_db::SourceDatabase; | 14 | use ra_db::SourceDatabase; |
9 | use ra_ide_db::{ | 15 | use ra_ide_db::{ |
10 | defs::{classify_name, classify_name_ref, Definition}, | 16 | defs::{classify_name, classify_name_ref, Definition}, |
11 | RootDatabase, | 17 | RootDatabase, |
12 | }; | 18 | }; |
13 | use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, SyntaxNode, TokenAtOffset, ast::Path}; | 19 | use ra_syntax::{ |
14 | use ra_hir_def::{item_scope::ItemInNs, db::DefDatabase, resolver::HasResolver}; | 20 | ast, ast::Path, match_ast, AstNode, SyntaxKind::*, SyntaxNode, SyntaxToken, TokenAtOffset, |
15 | use ra_tt::{Literal, Ident, Punct, TokenTree, Leaf}; | 21 | }; |
16 | use ra_hir_expand::name::AsName; | 22 | use ra_tt::{Ident, Leaf, Literal, Punct, TokenTree}; |
17 | use maplit::{hashset, hashmap}; | ||
18 | |||
19 | use comrak::{parse_document,format_commonmark, ComrakOptions, Arena}; | ||
20 | use comrak::nodes::NodeValue; | ||
21 | use url::Url; | 23 | use url::Url; |
22 | 24 | ||
23 | use crate::{ | 25 | use crate::{ |
@@ -389,80 +391,143 @@ fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option<Strin | |||
389 | } | 391 | } |
390 | } | 392 | } |
391 | 393 | ||
394 | // Rewrites a markdown document, resolving links using `callback` and additionally striping prefixes/suffixes on link titles. | ||
395 | fn map_links<'e>( | ||
396 | events: impl Iterator<Item = Event<'e>>, | ||
397 | callback: impl Fn(&str, &str) -> String, | ||
398 | ) -> impl Iterator<Item = Event<'e>> { | ||
399 | let mut in_link = false; | ||
400 | let mut link_text = CowStr::Borrowed(""); | ||
401 | events.map(move |evt| match evt { | ||
402 | Event::Start(Tag::Link(..)) => { | ||
403 | in_link = true; | ||
404 | evt | ||
405 | } | ||
406 | Event::End(Tag::Link(link_type, target, _)) => { | ||
407 | in_link = false; | ||
408 | let target = callback(&target, &link_text); | ||
409 | Event::End(Tag::Link(link_type, CowStr::Boxed(target.into()), CowStr::Borrowed(""))) | ||
410 | } | ||
411 | Event::Text(s) if in_link => { | ||
412 | link_text = s.clone(); | ||
413 | Event::Text(CowStr::Boxed(strip_prefixes_suffixes(&s).into())) | ||
414 | } | ||
415 | Event::Code(s) if in_link => { | ||
416 | link_text = s.clone(); | ||
417 | Event::Code(CowStr::Boxed(strip_prefixes_suffixes(&s).into())) | ||
418 | } | ||
419 | _ => evt, | ||
420 | }) | ||
421 | } | ||
422 | |||
392 | /// Rewrite documentation links in markdown to point to local documentation/docs.rs | 423 | /// Rewrite documentation links in markdown to point to local documentation/docs.rs |
393 | fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) -> Option<String> { | 424 | fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Definition) -> Option<String> { |
394 | let arena = Arena::new(); | 425 | let doc = Parser::new_with_broken_link_callback( |
395 | let doc = parse_document(&arena, markdown, &ComrakOptions::default()); | 426 | markdown, |
396 | 427 | Options::empty(), | |
397 | iter_nodes(doc, &|node| { | 428 | Some(&|label, _| Some((/*url*/ label.to_string(), /*title*/ label.to_string()))), |
398 | match &mut node.data.borrow_mut().value { | 429 | ); |
399 | &mut NodeValue::Link(ref mut link) => { | 430 | |
400 | match Url::parse(&String::from_utf8(link.url.clone()).unwrap()) { | 431 | let doc = map_links(doc, |target, title: &str| { |
401 | // If this is a valid absolute URL don't touch it | 432 | match Url::parse(target) { |
402 | Ok(_) => (), | 433 | // If this is a valid absolute URL don't touch it |
403 | // Otherwise there are two main possibilities | 434 | Ok(_) => target.to_string(), |
404 | // path-based links: `../../module/struct.MyStruct.html` | 435 | // Otherwise there are two main possibilities |
405 | // module-based links (AKA intra-doc links): `super::super::module::MyStruct` | 436 | // path-based links: `../../module/struct.MyStruct.html` |
406 | Err(_) => { | 437 | // module-based links (AKA intra-doc links): `super::super::module::MyStruct` |
407 | let link_str = String::from_utf8(link.url.clone()).unwrap(); | 438 | Err(_) => { |
408 | let link_text = String::from_utf8(link.title.clone()).unwrap(); | 439 | let resolved = try_resolve_intra(db, definition, title, &target) |
409 | let resolved = try_resolve_intra(db, definition, &link_text, &link_str) | 440 | .or_else(|| try_resolve_path(db, definition, &target)); |
410 | .or_else(|| try_resolve_path(db, definition, &link_str)); | 441 | |
411 | 442 | if let Some(resolved) = resolved { | |
412 | if let Some(resolved) = resolved { | 443 | resolved |
413 | link.url = resolved.as_bytes().to_vec(); | 444 | } else { |
414 | } | 445 | target.to_string() |
415 | |||
416 | } | ||
417 | } | 446 | } |
418 | }, | 447 | } |
419 | _ => () | ||
420 | } | 448 | } |
421 | }); | 449 | }); |
422 | let mut out = Vec::new(); | 450 | let mut out = String::new(); |
423 | format_commonmark(doc, &ComrakOptions::default(), &mut out).ok()?; | 451 | cmark(doc, &mut out, None).ok(); |
424 | Some(String::from_utf8(out).unwrap().trim().to_string()) | 452 | Some(out) |
425 | } | 453 | } |
426 | 454 | ||
427 | #[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)] | 455 | #[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)] |
428 | enum Namespace { | 456 | enum Namespace { |
429 | Types, | 457 | Types, |
430 | Values, | 458 | Values, |
431 | Macros | 459 | Macros, |
432 | } | 460 | } |
433 | 461 | ||
462 | lazy_static!( | ||
463 | /// Map of namespaces to identifying prefixes and suffixes as defined by RFC1946. | ||
464 | static ref NS_MAP: HashMap<Namespace, (HashSet<&'static str>, HashSet<&'static str>)> = hashmap!{ | ||
465 | Namespace::Types => (hashset!{"type", "struct", "enum", "mod", "trait", "union", "module"}, hashset!{}), | ||
466 | Namespace::Values => (hashset!{"value", "function", "fn", "method", "const", "static", "mod", "module"}, hashset!{"()"}), | ||
467 | Namespace::Macros => (hashset!{"macro"}, hashset!{"!"}) | ||
468 | }; | ||
469 | ); | ||
470 | |||
434 | impl Namespace { | 471 | impl Namespace { |
435 | /// Extract the specified namespace from an intra-doc-link if one exists. | 472 | /// Extract the specified namespace from an intra-doc-link if one exists. |
436 | fn from_intra_spec(s: &str) -> Option<Self> { | 473 | fn from_intra_spec(s: &str) -> Option<Self> { |
437 | let ns_map = hashmap!{ | 474 | NS_MAP |
438 | Self::Types => (hashset!{"type", "struct", "enum", "mod", "trait", "union", "module"}, hashset!{}), | ||
439 | Self::Values => (hashset!{"value", "function", "fn", "method", "const", "static", "mod", "module"}, hashset!{"()"}), | ||
440 | Self::Macros => (hashset!{"macro"}, hashset!{"!"}) | ||
441 | }; | ||
442 | |||
443 | ns_map | ||
444 | .iter() | 475 | .iter() |
445 | .filter(|(_ns, (prefixes, suffixes))| { | 476 | .filter(|(_ns, (prefixes, suffixes))| { |
446 | prefixes.iter().map(|prefix| s.starts_with(prefix) && s.chars().nth(prefix.len()+1).map(|c| c == '@' || c == ' ').unwrap_or(false)).any(|cond| cond) || | 477 | prefixes |
447 | suffixes.iter().map(|suffix| s.starts_with(suffix) && s.chars().nth(suffix.len()+1).map(|c| c == '@' || c == ' ').unwrap_or(false)).any(|cond| cond) | 478 | .iter() |
479 | .map(|prefix| { | ||
480 | s.starts_with(prefix) | ||
481 | && s.chars() | ||
482 | .nth(prefix.len() + 1) | ||
483 | .map(|c| c == '@' || c == ' ') | ||
484 | .unwrap_or(false) | ||
485 | }) | ||
486 | .any(|cond| cond) | ||
487 | || suffixes | ||
488 | .iter() | ||
489 | .map(|suffix| { | ||
490 | s.starts_with(suffix) | ||
491 | && s.chars() | ||
492 | .nth(suffix.len() + 1) | ||
493 | .map(|c| c == '@' || c == ' ') | ||
494 | .unwrap_or(false) | ||
495 | }) | ||
496 | .any(|cond| cond) | ||
448 | }) | 497 | }) |
449 | .map(|(ns, (_, _))| *ns) | 498 | .map(|(ns, (_, _))| *ns) |
450 | .next() | 499 | .next() |
451 | } | 500 | } |
452 | } | 501 | } |
453 | 502 | ||
503 | // Strip prefixes, suffixes, and inline code marks from the given string. | ||
504 | fn strip_prefixes_suffixes(mut s: &str) -> &str { | ||
505 | s = s.trim_matches('`'); | ||
506 | NS_MAP.iter().for_each(|(_, (prefixes, suffixes))| { | ||
507 | prefixes.iter().for_each(|prefix| s = s.trim_start_matches(prefix)); | ||
508 | suffixes.iter().for_each(|suffix| s = s.trim_end_matches(suffix)); | ||
509 | }); | ||
510 | s.trim_start_matches("@").trim() | ||
511 | } | ||
512 | |||
454 | /// Try to resolve path to local documentation via intra-doc-links (i.e. `super::gateway::Shard`). | 513 | /// Try to resolve path to local documentation via intra-doc-links (i.e. `super::gateway::Shard`). |
455 | /// | 514 | /// |
456 | /// See [RFC1946](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md). | 515 | /// See [RFC1946](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md). |
457 | fn try_resolve_intra(db: &RootDatabase, definition: &Definition, link_text: &str, link_target: &str) -> Option<String> { | 516 | fn try_resolve_intra( |
458 | eprintln!("try_resolve_intra"); | 517 | db: &RootDatabase, |
459 | 518 | definition: &Definition, | |
519 | link_text: &str, | ||
520 | link_target: &str, | ||
521 | ) -> Option<String> { | ||
460 | // Set link_target for implied shortlinks | 522 | // Set link_target for implied shortlinks |
461 | let link_target = if link_target.is_empty() { | 523 | let link_target = |
462 | link_text.trim_matches('`') | 524 | if link_target.is_empty() { link_text.trim_matches('`') } else { link_target }; |
463 | } else { | 525 | |
464 | link_target | 526 | // Namespace disambiguation |
465 | }; | 527 | let namespace = Namespace::from_intra_spec(link_target); |
528 | |||
529 | // Strip prefixes/suffixes | ||
530 | let link_target = strip_prefixes_suffixes(link_target); | ||
466 | 531 | ||
467 | // Parse link as a module path | 532 | // Parse link as a module path |
468 | // This expects a full document, which a single path isn't, but we can just ignore the errors. | 533 | // This expects a full document, which a single path isn't, but we can just ignore the errors. |
@@ -473,17 +538,17 @@ fn try_resolve_intra(db: &RootDatabase, definition: &Definition, link_text: &str | |||
473 | // Resolve it relative to symbol's location (according to the RFC this should consider small scopes | 538 | // Resolve it relative to symbol's location (according to the RFC this should consider small scopes |
474 | let resolver = definition.resolver(db)?; | 539 | let resolver = definition.resolver(db)?; |
475 | 540 | ||
476 | // Namespace disambiguation | ||
477 | let namespace = Namespace::from_intra_spec(link_target); | ||
478 | |||
479 | let resolved = resolver.resolve_module_path_in_items(db, &modpath); | 541 | let resolved = resolver.resolve_module_path_in_items(db, &modpath); |
480 | let (defid, namespace) = match namespace { | 542 | let (defid, namespace) = match namespace { |
481 | // TODO: .or(resolved.macros) | 543 | // TODO: .or(resolved.macros) |
482 | None => resolved.types.map(|t| (t.0, Namespace::Types)).or(resolved.values.map(|t| (t.0, Namespace::Values)))?, | 544 | None => resolved |
545 | .types | ||
546 | .map(|t| (t.0, Namespace::Types)) | ||
547 | .or(resolved.values.map(|t| (t.0, Namespace::Values)))?, | ||
483 | Some(ns @ Namespace::Types) => (resolved.types?.0, ns), | 548 | Some(ns @ Namespace::Types) => (resolved.types?.0, ns), |
484 | Some(ns @ Namespace::Values) => (resolved.values?.0, ns), | 549 | Some(ns @ Namespace::Values) => (resolved.values?.0, ns), |
485 | // TODO: | 550 | // TODO: |
486 | Some(Namespace::Macros) => None? | 551 | Some(Namespace::Macros) => None?, |
487 | }; | 552 | }; |
488 | 553 | ||
489 | // Get the filepath of the final symbol | 554 | // Get the filepath of the final symbol |
@@ -494,23 +559,28 @@ fn try_resolve_intra(db: &RootDatabase, definition: &Definition, link_text: &str | |||
494 | Namespace::Types => ItemInNs::Types(defid), | 559 | Namespace::Types => ItemInNs::Types(defid), |
495 | Namespace::Values => ItemInNs::Values(defid), | 560 | Namespace::Values => ItemInNs::Values(defid), |
496 | // TODO: | 561 | // TODO: |
497 | Namespace::Macros => None? | 562 | Namespace::Macros => None?, |
498 | }; | 563 | }; |
499 | let import_map = db.import_map(krate.into()); | 564 | let import_map = db.import_map(krate.into()); |
500 | let path = import_map.path_of(ns)?; | 565 | let path = import_map.path_of(ns)?; |
501 | 566 | ||
502 | Some( | 567 | Some( |
503 | get_doc_url(db, &krate)? | 568 | get_doc_url(db, &krate)? |
504 | .join(&format!("{}/", krate.display_name(db)?)).ok()? | 569 | .join(&format!("{}/", krate.display_name(db)?)) |
505 | .join(&path.segments.iter().map(|name| format!("{}", name)).join("/")).ok()? | 570 | .ok()? |
506 | .join(&get_symbol_filename(db, &Definition::ModuleDef(def))?).ok()? | 571 | .join(&path.segments.iter().map(|name| format!("{}", name)).join("/")) |
507 | .into_string() | 572 | .ok()? |
573 | .join(&get_symbol_filename(db, &Definition::ModuleDef(def))?) | ||
574 | .ok()? | ||
575 | .into_string(), | ||
508 | ) | 576 | ) |
509 | } | 577 | } |
510 | 578 | ||
511 | /// Try to resolve path to local documentation via path-based links (i.e. `../gateway/struct.Shard.html`). | 579 | /// Try to resolve path to local documentation via path-based links (i.e. `../gateway/struct.Shard.html`). |
512 | fn try_resolve_path(db: &RootDatabase, definition: &Definition, link: &str) -> Option<String> { | 580 | fn try_resolve_path(db: &RootDatabase, definition: &Definition, link: &str) -> Option<String> { |
513 | eprintln!("try_resolve_path"); | 581 | if !link.contains("#") && !link.contains(".html") { |
582 | return None; | ||
583 | } | ||
514 | let ns = if let Definition::ModuleDef(moddef) = definition { | 584 | let ns = if let Definition::ModuleDef(moddef) = definition { |
515 | ItemInNs::Types(moddef.clone().into()) | 585 | ItemInNs::Types(moddef.clone().into()) |
516 | } else { | 586 | } else { |
@@ -522,11 +592,15 @@ fn try_resolve_path(db: &RootDatabase, definition: &Definition, link: &str) -> O | |||
522 | // TODO: It should be possible to fall back to not-necessarilly-public paths if we can't find a public one, | 592 | // TODO: It should be possible to fall back to not-necessarilly-public paths if we can't find a public one, |
523 | // then hope rustdoc was run locally with `--document-private-items` | 593 | // then hope rustdoc was run locally with `--document-private-items` |
524 | let base = import_map.path_of(ns)?; | 594 | let base = import_map.path_of(ns)?; |
525 | let base = once(format!("{}", krate.display_name(db)?)).chain(base.segments.iter().map(|name| format!("{}", name))).join("/"); | 595 | let base = once(format!("{}", krate.display_name(db)?)) |
596 | .chain(base.segments.iter().map(|name| format!("{}", name))) | ||
597 | .join("/"); | ||
526 | 598 | ||
527 | get_doc_url(db, &krate) | 599 | get_doc_url(db, &krate) |
528 | .and_then(|url| url.join(&base).ok()) | 600 | .and_then(|url| url.join(&base).ok()) |
529 | .and_then(|url| get_symbol_filename(db, definition).as_deref().map(|f| url.join(f).ok()).flatten()) | 601 | .and_then(|url| { |
602 | get_symbol_filename(db, definition).as_deref().map(|f| url.join(f).ok()).flatten() | ||
603 | }) | ||
530 | .and_then(|url| url.join(link).ok()) | 604 | .and_then(|url| url.join(link).ok()) |
531 | .map(|url| url.into_string()) | 605 | .map(|url| url.into_string()) |
532 | } | 606 | } |
@@ -566,31 +640,25 @@ fn get_symbol_filename(db: &RootDatabase, definition: &Definition) -> Option<Str | |||
566 | ModuleDef::Adt(adt) => match adt { | 640 | ModuleDef::Adt(adt) => match adt { |
567 | Adt::Struct(s) => format!("struct.{}.html", s.name(db)), | 641 | Adt::Struct(s) => format!("struct.{}.html", s.name(db)), |
568 | Adt::Enum(e) => format!("enum.{}.html", e.name(db)), | 642 | Adt::Enum(e) => format!("enum.{}.html", e.name(db)), |
569 | Adt::Union(u) => format!("union.{}.html", u.name(db)) | 643 | Adt::Union(u) => format!("union.{}.html", u.name(db)), |
570 | }, | 644 | }, |
571 | ModuleDef::Module(_) => "index.html".to_string(), | 645 | ModuleDef::Module(_) => "index.html".to_string(), |
572 | ModuleDef::Trait(t) => format!("trait.{}.html", t.name(db)), | 646 | ModuleDef::Trait(t) => format!("trait.{}.html", t.name(db)), |
573 | ModuleDef::TypeAlias(t) => format!("type.{}.html", t.name(db)), | 647 | ModuleDef::TypeAlias(t) => format!("type.{}.html", t.name(db)), |
574 | ModuleDef::BuiltinType(t) => format!("primitive.{}.html", t.as_name()), | 648 | ModuleDef::BuiltinType(t) => format!("primitive.{}.html", t.as_name()), |
575 | ModuleDef::Function(f) => format!("fn.{}.html", f.name(db)), | 649 | ModuleDef::Function(f) => format!("fn.{}.html", f.name(db)), |
576 | ModuleDef::EnumVariant(ev) => format!("enum.{}.html#variant.{}", ev.parent_enum(db).name(db), ev.name(db)), | 650 | ModuleDef::EnumVariant(ev) => { |
651 | format!("enum.{}.html#variant.{}", ev.parent_enum(db).name(db), ev.name(db)) | ||
652 | } | ||
577 | ModuleDef::Const(c) => format!("const.{}.html", c.name(db)?), | 653 | ModuleDef::Const(c) => format!("const.{}.html", c.name(db)?), |
578 | // TODO: Check this is the right prefix | 654 | // TODO: Check this is the right prefix |
579 | ModuleDef::Static(s) => format!("static.{}.html", s.name(db)?) | 655 | ModuleDef::Static(s) => format!("static.{}.html", s.name(db)?), |
580 | }, | 656 | }, |
581 | Definition::Macro(m) => format!("macro.{}.html", m.name(db)?), | 657 | Definition::Macro(m) => format!("macro.{}.html", m.name(db)?), |
582 | _ => None? | 658 | _ => None?, |
583 | }) | 659 | }) |
584 | } | 660 | } |
585 | 661 | ||
586 | fn iter_nodes<'a, F>(node: &'a comrak::nodes::AstNode<'a>, f: &F) | ||
587 | where F : Fn(&'a comrak::nodes::AstNode<'a>) { | ||
588 | f(node); | ||
589 | for c in node.children() { | ||
590 | iter_nodes(c, f); | ||
591 | } | ||
592 | } | ||
593 | |||
594 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { | 662 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { |
595 | return tokens.max_by_key(priority); | 663 | return tokens.max_by_key(priority); |
596 | fn priority(n: &SyntaxToken) -> usize { | 664 | fn priority(n: &SyntaxToken) -> usize { |
@@ -614,12 +682,11 @@ mod tests { | |||
614 | use crate::mock_analysis::analysis_and_position; | 682 | use crate::mock_analysis::analysis_and_position; |
615 | 683 | ||
616 | fn trim_markup(s: &str) -> String { | 684 | fn trim_markup(s: &str) -> String { |
617 | s | 685 | s.trim() |
618 | .replace("``` rust", "```rust") | 686 | .replace("````", "```") |
619 | .replace("-----", "___") | 687 | .replace("---", "___") |
620 | .replace("\n\n___\n\n", "\n___\n\n") | ||
621 | .replace("\\<-", "<-") | 688 | .replace("\\<-", "<-") |
622 | .trim_start_matches("test\n```\n\n") | 689 | .replace("```\n\n___", "```\n___") |
623 | .trim_start_matches("```rust\n") | 690 | .trim_start_matches("```rust\n") |
624 | .trim_start_matches("test\n```\n\n```rust\n") | 691 | .trim_start_matches("test\n```\n\n```rust\n") |
625 | .trim_end_matches("\n```") | 692 | .trim_end_matches("\n```") |
@@ -873,7 +940,10 @@ fn main() { | |||
873 | ", | 940 | ", |
874 | ); | 941 | ); |
875 | let hover = analysis.hover(position).unwrap().unwrap(); | 942 | let hover = analysis.hover(position).unwrap().unwrap(); |
876 | assert_eq!(trim_markup_opt(hover.info.first()).as_deref(), Some("test::Option\n```\n\n```rust\nSome")); | 943 | assert_eq!( |
944 | trim_markup_opt(hover.info.first()).as_deref(), | ||
945 | Some("test::Option\n```\n\n```rust\nSome") | ||
946 | ); | ||
877 | 947 | ||
878 | let (analysis, position) = analysis_and_position( | 948 | let (analysis, position) = analysis_and_position( |
879 | " | 949 | " |
@@ -1408,7 +1478,7 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
1408 | /// [Foo](struct.Foo.html) | 1478 | /// [Foo](struct.Foo.html) |
1409 | pub struct B<|>ar | 1479 | pub struct B<|>ar |
1410 | ", | 1480 | ", |
1411 | &["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"] | 1481 | &["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"], |
1412 | ); | 1482 | ); |
1413 | } | 1483 | } |
1414 | 1484 | ||
@@ -1421,7 +1491,7 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
1421 | /// [Foo](Foo) | 1491 | /// [Foo](Foo) |
1422 | pub struct B<|>ar | 1492 | pub struct B<|>ar |
1423 | ", | 1493 | ", |
1424 | &["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"] | 1494 | &["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"], |
1425 | ); | 1495 | ); |
1426 | } | 1496 | } |
1427 | 1497 | ||
@@ -1434,7 +1504,20 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
1434 | /// [Foo] | 1504 | /// [Foo] |
1435 | pub struct B<|>ar | 1505 | pub struct B<|>ar |
1436 | ", | 1506 | ", |
1437 | &["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"] | 1507 | &["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"], |
1508 | ); | ||
1509 | } | ||
1510 | |||
1511 | #[test] | ||
1512 | fn test_hover_intra_link_shortlink_code() { | ||
1513 | check_hover_result( | ||
1514 | r" | ||
1515 | //- /lib.rs | ||
1516 | pub struct Foo; | ||
1517 | /// [`Foo`] | ||
1518 | pub struct B<|>ar | ||
1519 | ", | ||
1520 | &["pub struct Bar\n```\n___\n\n[`Foo`](https://docs.rs/test/*/test/struct.Foo.html)"], | ||
1438 | ); | 1521 | ); |
1439 | } | 1522 | } |
1440 | 1523 | ||
@@ -1448,7 +1531,75 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
1448 | /// [Foo()] | 1531 | /// [Foo()] |
1449 | pub struct B<|>ar | 1532 | pub struct B<|>ar |
1450 | ", | 1533 | ", |
1451 | &["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"] | 1534 | &["pub struct Bar\n```\n___\n\n[Foo](https://docs.rs/test/*/test/struct.Foo.html)"], |
1535 | ); | ||
1536 | } | ||
1537 | |||
1538 | #[test] | ||
1539 | fn test_hover_intra_link_shortlink_namspaced_code() { | ||
1540 | check_hover_result( | ||
1541 | r" | ||
1542 | //- /lib.rs | ||
1543 | pub struct Foo; | ||
1544 | /// [`struct Foo`] | ||
1545 | pub struct B<|>ar | ||
1546 | ", | ||
1547 | &["pub struct Bar\n```\n___\n\n[`Foo`](https://docs.rs/test/*/test/struct.Foo.html)"], | ||
1548 | ); | ||
1549 | } | ||
1550 | |||
1551 | #[test] | ||
1552 | fn test_hover_intra_link_shortlink_namspaced_code_with_at() { | ||
1553 | check_hover_result( | ||
1554 | r" | ||
1555 | //- /lib.rs | ||
1556 | pub struct Foo; | ||
1557 | /// [`struct@Foo`] | ||
1558 | pub struct B<|>ar | ||
1559 | ", | ||
1560 | &["pub struct Bar\n```\n___\n\n[`Foo`](https://docs.rs/test/*/test/struct.Foo.html)"], | ||
1561 | ); | ||
1562 | } | ||
1563 | |||
1564 | #[test] | ||
1565 | fn test_hover_intra_link_reference() { | ||
1566 | check_hover_result( | ||
1567 | r" | ||
1568 | //- /lib.rs | ||
1569 | pub struct Foo; | ||
1570 | /// [my Foo][foo] | ||
1571 | /// | ||
1572 | /// [foo]: Foo | ||
1573 | pub struct B<|>ar | ||
1574 | ", | ||
1575 | &["pub struct Bar\n```\n___\n\n[my Foo](https://docs.rs/test/*/test/struct.Foo.html)"], | ||
1576 | ); | ||
1577 | } | ||
1578 | |||
1579 | #[test] | ||
1580 | fn test_hover_external_url() { | ||
1581 | check_hover_result( | ||
1582 | r" | ||
1583 | //- /lib.rs | ||
1584 | pub struct Foo; | ||
1585 | /// [external](https://www.google.com) | ||
1586 | pub struct B<|>ar | ||
1587 | ", | ||
1588 | &["pub struct Bar\n```\n___\n\n[external](https://www.google.com)"], | ||
1589 | ); | ||
1590 | } | ||
1591 | |||
1592 | // Check that we don't rewrite links which we can't identify | ||
1593 | #[test] | ||
1594 | fn test_hover_unknown_target() { | ||
1595 | check_hover_result( | ||
1596 | r" | ||
1597 | //- /lib.rs | ||
1598 | pub struct Foo; | ||
1599 | /// [baz](Baz) | ||
1600 | pub struct B<|>ar | ||
1601 | ", | ||
1602 | &["pub struct Bar\n```\n___\n\n[baz](Baz)"], | ||
1452 | ); | 1603 | ); |
1453 | } | 1604 | } |
1454 | 1605 | ||
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 6c0d3e19c..c8c8b886d 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -547,7 +547,7 @@ pub(crate) fn handle_hover( | |||
547 | ) -> Result<Option<lsp_ext::Hover>> { | 547 | ) -> Result<Option<lsp_ext::Hover>> { |
548 | let _p = profile("handle_hover"); | 548 | let _p = profile("handle_hover"); |
549 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; | 549 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
550 | let info = match snap.analysis().hover(position)? { | 550 | let info = match snap.analysis.hover(position)? { |
551 | None => return Ok(None), | 551 | None => return Ok(None), |
552 | Some(info) => info, | 552 | Some(info) => info, |
553 | }; | 553 | }; |