diff options
Diffstat (limited to 'crates/ide/src')
-rw-r--r-- | crates/ide/src/display/short_label.rs | 11 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 91 |
2 files changed, 88 insertions, 14 deletions
diff --git a/crates/ide/src/display/short_label.rs b/crates/ide/src/display/short_label.rs index ea49d9f97..990f740b8 100644 --- a/crates/ide/src/display/short_label.rs +++ b/crates/ide/src/display/short_label.rs | |||
@@ -87,6 +87,17 @@ impl ShortLabel for ast::Variant { | |||
87 | } | 87 | } |
88 | } | 88 | } |
89 | 89 | ||
90 | impl ShortLabel for ast::ConstParam { | ||
91 | fn short_label(&self) -> Option<String> { | ||
92 | let mut buf = "const ".to_owned(); | ||
93 | buf.push_str(self.name()?.text().as_str()); | ||
94 | if let Some(type_ref) = self.ty() { | ||
95 | format_to!(buf, ": {}", type_ref.syntax()); | ||
96 | } | ||
97 | Some(buf) | ||
98 | } | ||
99 | } | ||
100 | |||
90 | fn short_label_from_ty<T>(node: &T, ty: Option<ast::Type>, prefix: &str) -> Option<String> | 101 | fn short_label_from_ty<T>(node: &T, ty: Option<ast::Type>, prefix: &str) -> Option<String> |
91 | where | 102 | where |
92 | T: NameOwner + VisibilityOwner, | 103 | T: NameOwner + VisibilityOwner, |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 2737c900f..c0786eb51 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -70,7 +70,7 @@ impl HoverConfig { | |||
70 | #[derive(Debug, Clone)] | 70 | #[derive(Debug, Clone)] |
71 | pub enum HoverAction { | 71 | pub enum HoverAction { |
72 | Runnable(Runnable), | 72 | Runnable(Runnable), |
73 | Implementaion(FilePosition), | 73 | Implementation(FilePosition), |
74 | GoToType(Vec<HoverGotoTypeData>), | 74 | GoToType(Vec<HoverGotoTypeData>), |
75 | } | 75 | } |
76 | 76 | ||
@@ -116,12 +116,13 @@ pub(crate) fn hover( | |||
116 | }; | 116 | }; |
117 | if let Some(definition) = definition { | 117 | if let Some(definition) = definition { |
118 | if let Some(markup) = hover_for_definition(db, definition) { | 118 | if let Some(markup) = hover_for_definition(db, definition) { |
119 | let markup = markup.as_str(); | ||
119 | let markup = if !markdown { | 120 | let markup = if !markdown { |
120 | remove_markdown(&markup.as_str()) | 121 | remove_markdown(markup) |
121 | } else if links_in_hover { | 122 | } else if links_in_hover { |
122 | rewrite_links(db, &markup.as_str(), &definition) | 123 | rewrite_links(db, markup, &definition) |
123 | } else { | 124 | } else { |
124 | remove_links(&markup.as_str()) | 125 | remove_links(markup) |
125 | }; | 126 | }; |
126 | res.markup = Markup::from(markup); | 127 | res.markup = Markup::from(markup); |
127 | if let Some(action) = show_implementations_action(db, definition) { | 128 | if let Some(action) = show_implementations_action(db, definition) { |
@@ -175,7 +176,7 @@ pub(crate) fn hover( | |||
175 | 176 | ||
176 | fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { | 177 | fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { |
177 | fn to_action(nav_target: NavigationTarget) -> HoverAction { | 178 | fn to_action(nav_target: NavigationTarget) -> HoverAction { |
178 | HoverAction::Implementaion(FilePosition { | 179 | HoverAction::Implementation(FilePosition { |
179 | file_id: nav_target.file_id, | 180 | file_id: nav_target.file_id, |
180 | offset: nav_target.focus_or_full_range().start(), | 181 | offset: nav_target.focus_or_full_range().start(), |
181 | }) | 182 | }) |
@@ -370,10 +371,8 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
370 | } | 371 | } |
371 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), | 372 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), |
372 | Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), | 373 | Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), |
373 | Definition::TypeParam(_) | Definition::ConstParam(_) => { | 374 | Definition::TypeParam(type_param) => Some(Markup::fenced_block(&type_param.display(db))), |
374 | // FIXME: Hover for generic param | 375 | Definition::ConstParam(it) => from_def_source(db, it, None), |
375 | None | ||
376 | } | ||
377 | }; | 376 | }; |
378 | 377 | ||
379 | fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> | 378 | fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> |
@@ -1393,7 +1392,7 @@ fn bar() { fo<|>o(); } | |||
1393 | r"unsafe trait foo<|>() {}", | 1392 | r"unsafe trait foo<|>() {}", |
1394 | expect![[r#" | 1393 | expect![[r#" |
1395 | [ | 1394 | [ |
1396 | Implementaion( | 1395 | Implementation( |
1397 | FilePosition { | 1396 | FilePosition { |
1398 | file_id: FileId( | 1397 | file_id: FileId( |
1399 | 0, | 1398 | 0, |
@@ -2105,7 +2104,7 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2105 | r#"trait foo<|>() {}"#, | 2104 | r#"trait foo<|>() {}"#, |
2106 | expect![[r#" | 2105 | expect![[r#" |
2107 | [ | 2106 | [ |
2108 | Implementaion( | 2107 | Implementation( |
2109 | FilePosition { | 2108 | FilePosition { |
2110 | file_id: FileId( | 2109 | file_id: FileId( |
2111 | 0, | 2110 | 0, |
@@ -2124,7 +2123,7 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2124 | r"struct foo<|>() {}", | 2123 | r"struct foo<|>() {}", |
2125 | expect![[r#" | 2124 | expect![[r#" |
2126 | [ | 2125 | [ |
2127 | Implementaion( | 2126 | Implementation( |
2128 | FilePosition { | 2127 | FilePosition { |
2129 | file_id: FileId( | 2128 | file_id: FileId( |
2130 | 0, | 2129 | 0, |
@@ -2143,7 +2142,7 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2143 | r#"union foo<|>() {}"#, | 2142 | r#"union foo<|>() {}"#, |
2144 | expect![[r#" | 2143 | expect![[r#" |
2145 | [ | 2144 | [ |
2146 | Implementaion( | 2145 | Implementation( |
2147 | FilePosition { | 2146 | FilePosition { |
2148 | file_id: FileId( | 2147 | file_id: FileId( |
2149 | 0, | 2148 | 0, |
@@ -2162,7 +2161,7 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2162 | r"enum foo<|>() { A, B }", | 2161 | r"enum foo<|>() { A, B }", |
2163 | expect![[r#" | 2162 | expect![[r#" |
2164 | [ | 2163 | [ |
2165 | Implementaion( | 2164 | Implementation( |
2166 | FilePosition { | 2165 | FilePosition { |
2167 | file_id: FileId( | 2166 | file_id: FileId( |
2168 | 0, | 2167 | 0, |
@@ -3257,4 +3256,68 @@ fn foo() { | |||
3257 | "#]], | 3256 | "#]], |
3258 | ); | 3257 | ); |
3259 | } | 3258 | } |
3259 | |||
3260 | #[test] | ||
3261 | fn hover_type_param() { | ||
3262 | check( | ||
3263 | r#" | ||
3264 | struct Foo<T>(T); | ||
3265 | trait Copy {} | ||
3266 | trait Clone {} | ||
3267 | trait Sized {} | ||
3268 | impl<T: Copy + Clone> Foo<T<|>> where T: Sized {} | ||
3269 | "#, | ||
3270 | expect![[r#" | ||
3271 | *T* | ||
3272 | |||
3273 | ```rust | ||
3274 | T: Copy + Clone + Sized | ||
3275 | ``` | ||
3276 | "#]], | ||
3277 | ); | ||
3278 | check( | ||
3279 | r#" | ||
3280 | struct Foo<T>(T); | ||
3281 | impl<T> Foo<T<|>> {} | ||
3282 | "#, | ||
3283 | expect![[r#" | ||
3284 | *T* | ||
3285 | |||
3286 | ```rust | ||
3287 | T | ||
3288 | ``` | ||
3289 | "#]], | ||
3290 | ); | ||
3291 | // lifetimes aren't being substituted yet | ||
3292 | check( | ||
3293 | r#" | ||
3294 | struct Foo<T>(T); | ||
3295 | impl<T: 'static> Foo<T<|>> {} | ||
3296 | "#, | ||
3297 | expect![[r#" | ||
3298 | *T* | ||
3299 | |||
3300 | ```rust | ||
3301 | T: {error} | ||
3302 | ``` | ||
3303 | "#]], | ||
3304 | ); | ||
3305 | } | ||
3306 | |||
3307 | #[test] | ||
3308 | fn hover_const_param() { | ||
3309 | check( | ||
3310 | r#" | ||
3311 | struct Foo<const LEN: usize>; | ||
3312 | impl<const LEN: usize> Foo<LEN<|>> {} | ||
3313 | "#, | ||
3314 | expect![[r#" | ||
3315 | *LEN* | ||
3316 | |||
3317 | ```rust | ||
3318 | const LEN: usize | ||
3319 | ``` | ||
3320 | "#]], | ||
3321 | ); | ||
3322 | } | ||
3260 | } | 3323 | } |