diff options
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r-- | crates/ra_ide/src/hover.rs | 88 |
1 files changed, 37 insertions, 51 deletions
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index eaba2b61e..61359c770 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs | |||
@@ -77,10 +77,6 @@ impl HoverResult { | |||
77 | Self::default() | 77 | Self::default() |
78 | } | 78 | } |
79 | 79 | ||
80 | pub fn extend(&mut self, item: Option<String>) { | ||
81 | self.results.extend(item); | ||
82 | } | ||
83 | |||
84 | pub fn is_empty(&self) -> bool { | 80 | pub fn is_empty(&self) -> bool { |
85 | self.results.is_empty() | 81 | self.results.is_empty() |
86 | } | 82 | } |
@@ -89,22 +85,9 @@ impl HoverResult { | |||
89 | self.results.len() | 85 | self.results.len() |
90 | } | 86 | } |
91 | 87 | ||
92 | pub fn first(&self) -> Option<&str> { | ||
93 | self.results.first().map(String::as_str) | ||
94 | } | ||
95 | |||
96 | pub fn results(&self) -> &[String] { | ||
97 | &self.results | ||
98 | } | ||
99 | |||
100 | pub fn actions(&self) -> &[HoverAction] { | 88 | pub fn actions(&self) -> &[HoverAction] { |
101 | &self.actions | 89 | &self.actions |
102 | } | 90 | } |
103 | |||
104 | pub fn push_action(&mut self, action: HoverAction) { | ||
105 | self.actions.push(action); | ||
106 | } | ||
107 | |||
108 | /// Returns the results converted into markup | 91 | /// Returns the results converted into markup |
109 | /// for displaying in a UI | 92 | /// for displaying in a UI |
110 | /// | 93 | /// |
@@ -112,6 +95,10 @@ impl HoverResult { | |||
112 | pub fn to_markup(&self) -> String { | 95 | pub fn to_markup(&self) -> String { |
113 | self.results.join("\n\n___\n") | 96 | self.results.join("\n\n___\n") |
114 | } | 97 | } |
98 | |||
99 | fn push_action(&mut self, action: HoverAction) { | ||
100 | self.actions.push(action); | ||
101 | } | ||
115 | } | 102 | } |
116 | 103 | ||
117 | // Feature: Hover | 104 | // Feature: Hover |
@@ -126,30 +113,33 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
126 | 113 | ||
127 | let mut res = HoverResult::new(); | 114 | let mut res = HoverResult::new(); |
128 | 115 | ||
129 | if let Some((node, name_kind)) = match_ast! { | 116 | let node = token.parent(); |
130 | match (token.parent()) { | 117 | let definition = match_ast! { |
118 | match node { | ||
131 | ast::NameRef(name_ref) => { | 119 | ast::NameRef(name_ref) => { |
132 | classify_name_ref(&sema, &name_ref).map(|d| (name_ref.syntax().clone(), d.definition())) | 120 | classify_name_ref(&sema, &name_ref).map(|d| d.definition()) |
133 | }, | 121 | }, |
134 | ast::Name(name) => { | 122 | ast::Name(name) => { |
135 | classify_name(&sema, &name).map(|d| (name.syntax().clone(), d.definition())) | 123 | classify_name(&sema, &name).map(|d| d.definition()) |
136 | }, | 124 | }, |
137 | _ => None, | 125 | _ => None, |
138 | } | 126 | } |
139 | } { | 127 | }; |
128 | if let Some(definition) = definition { | ||
140 | let range = sema.original_range(&node).range; | 129 | let range = sema.original_range(&node).range; |
141 | res.extend(hover_text_from_name_kind(db, name_kind)); | 130 | if let Some(text) = hover_text_from_name_kind(db, definition) { |
142 | 131 | res.results.push(text); | |
132 | } | ||
143 | if !res.is_empty() { | 133 | if !res.is_empty() { |
144 | if let Some(action) = show_implementations_action(db, name_kind) { | 134 | if let Some(action) = show_implementations_action(db, definition) { |
145 | res.push_action(action); | 135 | res.push_action(action); |
146 | } | 136 | } |
147 | 137 | ||
148 | if let Some(action) = runnable_action(&sema, name_kind, position.file_id) { | 138 | if let Some(action) = runnable_action(&sema, definition, position.file_id) { |
149 | res.push_action(action); | 139 | res.push_action(action); |
150 | } | 140 | } |
151 | 141 | ||
152 | if let Some(action) = goto_type_action(db, name_kind) { | 142 | if let Some(action) = goto_type_action(db, definition) { |
153 | res.push_action(action); | 143 | res.push_action(action); |
154 | } | 144 | } |
155 | 145 | ||
@@ -178,7 +168,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn | |||
178 | } | 168 | } |
179 | }?; | 169 | }?; |
180 | 170 | ||
181 | res.extend(Some(rust_code_markup(&ty.display(db)))); | 171 | res.results.push(rust_code_markup(&ty.display(db))); |
182 | let range = sema.original_range(&node).range; | 172 | let range = sema.original_range(&node).range; |
183 | Some(RangeInfo::new(range, res)) | 173 | Some(RangeInfo::new(range, res)) |
184 | } | 174 | } |
@@ -405,10 +395,6 @@ mod tests { | |||
405 | s.trim_start_matches("```rust\n").trim_end_matches("\n```") | 395 | s.trim_start_matches("```rust\n").trim_end_matches("\n```") |
406 | } | 396 | } |
407 | 397 | ||
408 | fn trim_markup_opt(s: Option<&str>) -> Option<&str> { | ||
409 | s.map(trim_markup) | ||
410 | } | ||
411 | |||
412 | fn assert_impl_action(action: &HoverAction, position: u32) { | 398 | fn assert_impl_action(action: &HoverAction, position: u32) { |
413 | let offset = match action { | 399 | let offset = match action { |
414 | HoverAction::Implementaion(pos) => pos.offset, | 400 | HoverAction::Implementaion(pos) => pos.offset, |
@@ -420,7 +406,7 @@ mod tests { | |||
420 | fn check_hover_result(ra_fixture: &str, expected: &[&str]) -> (String, Vec<HoverAction>) { | 406 | fn check_hover_result(ra_fixture: &str, expected: &[&str]) -> (String, Vec<HoverAction>) { |
421 | let (analysis, position) = analysis_and_position(ra_fixture); | 407 | let (analysis, position) = analysis_and_position(ra_fixture); |
422 | let hover = analysis.hover(position).unwrap().unwrap(); | 408 | let hover = analysis.hover(position).unwrap().unwrap(); |
423 | let mut results = Vec::from(hover.info.results()); | 409 | let mut results = hover.info.results.clone(); |
424 | results.sort(); | 410 | results.sort(); |
425 | 411 | ||
426 | for (markup, expected) in | 412 | for (markup, expected) in |
@@ -453,7 +439,7 @@ fn main() { | |||
453 | ); | 439 | ); |
454 | let hover = analysis.hover(position).unwrap().unwrap(); | 440 | let hover = analysis.hover(position).unwrap().unwrap(); |
455 | assert_eq!(hover.range, TextRange::new(58.into(), 63.into())); | 441 | assert_eq!(hover.range, TextRange::new(58.into(), 63.into())); |
456 | assert_eq!(trim_markup_opt(hover.info.first()), Some("u32")); | 442 | assert_eq!(trim_markup(&hover.info.results[0]), ("u32")); |
457 | } | 443 | } |
458 | 444 | ||
459 | #[test] | 445 | #[test] |
@@ -652,7 +638,7 @@ fn main() { | |||
652 | ", | 638 | ", |
653 | ); | 639 | ); |
654 | let hover = analysis.hover(position).unwrap().unwrap(); | 640 | let hover = analysis.hover(position).unwrap().unwrap(); |
655 | assert_eq!(trim_markup_opt(hover.info.first()), Some("Option\n```\n\n```rust\nSome")); | 641 | assert_eq!(trim_markup(&hover.info.results[0]), ("Option\n```\n\n```rust\nSome")); |
656 | 642 | ||
657 | let (analysis, position) = analysis_and_position( | 643 | let (analysis, position) = analysis_and_position( |
658 | " | 644 | " |
@@ -665,7 +651,7 @@ fn main() { | |||
665 | ", | 651 | ", |
666 | ); | 652 | ); |
667 | let hover = analysis.hover(position).unwrap().unwrap(); | 653 | let hover = analysis.hover(position).unwrap().unwrap(); |
668 | assert_eq!(trim_markup_opt(hover.info.first()), Some("Option<i32>")); | 654 | assert_eq!(trim_markup(&hover.info.results[0]), ("Option<i32>")); |
669 | } | 655 | } |
670 | 656 | ||
671 | #[test] | 657 | #[test] |
@@ -722,14 +708,14 @@ The Some variant | |||
722 | fn hover_for_local_variable() { | 708 | fn hover_for_local_variable() { |
723 | let (analysis, position) = analysis_and_position("fn func(foo: i32) { fo<|>o; }"); | 709 | let (analysis, position) = analysis_and_position("fn func(foo: i32) { fo<|>o; }"); |
724 | let hover = analysis.hover(position).unwrap().unwrap(); | 710 | let hover = analysis.hover(position).unwrap().unwrap(); |
725 | assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); | 711 | assert_eq!(trim_markup(&hover.info.results[0]), "i32"); |
726 | } | 712 | } |
727 | 713 | ||
728 | #[test] | 714 | #[test] |
729 | fn hover_for_local_variable_pat() { | 715 | fn hover_for_local_variable_pat() { |
730 | let (analysis, position) = analysis_and_position("fn func(fo<|>o: i32) {}"); | 716 | let (analysis, position) = analysis_and_position("fn func(fo<|>o: i32) {}"); |
731 | let hover = analysis.hover(position).unwrap().unwrap(); | 717 | let hover = analysis.hover(position).unwrap().unwrap(); |
732 | assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); | 718 | assert_eq!(trim_markup(&hover.info.results[0]), "i32"); |
733 | } | 719 | } |
734 | 720 | ||
735 | #[test] | 721 | #[test] |
@@ -740,14 +726,14 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
740 | ", | 726 | ", |
741 | ); | 727 | ); |
742 | let hover = analysis.hover(position).unwrap().unwrap(); | 728 | let hover = analysis.hover(position).unwrap().unwrap(); |
743 | assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); | 729 | assert_eq!(trim_markup(&hover.info.results[0]), "i32"); |
744 | } | 730 | } |
745 | 731 | ||
746 | #[test] | 732 | #[test] |
747 | fn hover_for_param_edge() { | 733 | fn hover_for_param_edge() { |
748 | let (analysis, position) = analysis_and_position("fn func(<|>foo: i32) {}"); | 734 | let (analysis, position) = analysis_and_position("fn func(<|>foo: i32) {}"); |
749 | let hover = analysis.hover(position).unwrap().unwrap(); | 735 | let hover = analysis.hover(position).unwrap().unwrap(); |
750 | assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); | 736 | assert_eq!(trim_markup(&hover.info.results[0]), "i32"); |
751 | } | 737 | } |
752 | 738 | ||
753 | #[test] | 739 | #[test] |
@@ -768,7 +754,7 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
768 | ", | 754 | ", |
769 | ); | 755 | ); |
770 | let hover = analysis.hover(position).unwrap().unwrap(); | 756 | let hover = analysis.hover(position).unwrap().unwrap(); |
771 | assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing")); | 757 | assert_eq!(trim_markup(&hover.info.results[0]), ("Thing")); |
772 | } | 758 | } |
773 | 759 | ||
774 | #[test] | 760 | #[test] |
@@ -792,8 +778,8 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
792 | ); | 778 | ); |
793 | let hover = analysis.hover(position).unwrap().unwrap(); | 779 | let hover = analysis.hover(position).unwrap().unwrap(); |
794 | assert_eq!( | 780 | assert_eq!( |
795 | trim_markup_opt(hover.info.first()), | 781 | trim_markup(&hover.info.results[0]), |
796 | Some("wrapper::Thing\n```\n\n```rust\nfn new() -> Thing") | 782 | ("wrapper::Thing\n```\n\n```rust\nfn new() -> Thing") |
797 | ); | 783 | ); |
798 | } | 784 | } |
799 | 785 | ||
@@ -816,7 +802,7 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
816 | ", | 802 | ", |
817 | ); | 803 | ); |
818 | let hover = analysis.hover(position).unwrap().unwrap(); | 804 | let hover = analysis.hover(position).unwrap().unwrap(); |
819 | assert_eq!(trim_markup_opt(hover.info.first()), Some("const C: u32")); | 805 | assert_eq!(trim_markup(&hover.info.results[0]), ("const C: u32")); |
820 | } | 806 | } |
821 | 807 | ||
822 | #[test] | 808 | #[test] |
@@ -832,7 +818,7 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
832 | ", | 818 | ", |
833 | ); | 819 | ); |
834 | let hover = analysis.hover(position).unwrap().unwrap(); | 820 | let hover = analysis.hover(position).unwrap().unwrap(); |
835 | assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing")); | 821 | assert_eq!(trim_markup(&hover.info.results[0]), ("Thing")); |
836 | 822 | ||
837 | /* FIXME: revive these tests | 823 | /* FIXME: revive these tests |
838 | let (analysis, position) = analysis_and_position( | 824 | let (analysis, position) = analysis_and_position( |
@@ -847,7 +833,7 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
847 | ); | 833 | ); |
848 | 834 | ||
849 | let hover = analysis.hover(position).unwrap().unwrap(); | 835 | let hover = analysis.hover(position).unwrap().unwrap(); |
850 | assert_eq!(trim_markup_opt(hover.info.first()), Some("Thing")); | 836 | assert_eq!(trim_markup(&hover.info.results[0]), ("Thing")); |
851 | 837 | ||
852 | let (analysis, position) = analysis_and_position( | 838 | let (analysis, position) = analysis_and_position( |
853 | " | 839 | " |
@@ -860,7 +846,7 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
860 | ", | 846 | ", |
861 | ); | 847 | ); |
862 | let hover = analysis.hover(position).unwrap().unwrap(); | 848 | let hover = analysis.hover(position).unwrap().unwrap(); |
863 | assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing")); | 849 | assert_eq!(trim_markup(&hover.info.results[0]), ("enum Thing")); |
864 | 850 | ||
865 | let (analysis, position) = analysis_and_position( | 851 | let (analysis, position) = analysis_and_position( |
866 | " | 852 | " |
@@ -872,7 +858,7 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
872 | ", | 858 | ", |
873 | ); | 859 | ); |
874 | let hover = analysis.hover(position).unwrap().unwrap(); | 860 | let hover = analysis.hover(position).unwrap().unwrap(); |
875 | assert_eq!(trim_markup_opt(hover.info.first()), Some("enum Thing")); | 861 | assert_eq!(trim_markup(&hover.info.results[0]), ("enum Thing")); |
876 | */ | 862 | */ |
877 | } | 863 | } |
878 | 864 | ||
@@ -889,7 +875,7 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
889 | ", | 875 | ", |
890 | ); | 876 | ); |
891 | let hover = analysis.hover(position).unwrap().unwrap(); | 877 | let hover = analysis.hover(position).unwrap().unwrap(); |
892 | assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); | 878 | assert_eq!(trim_markup(&hover.info.results[0]), "i32"); |
893 | } | 879 | } |
894 | 880 | ||
895 | #[test] | 881 | #[test] |
@@ -906,7 +892,7 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
906 | ", | 892 | ", |
907 | ); | 893 | ); |
908 | let hover = analysis.hover(position).unwrap().unwrap(); | 894 | let hover = analysis.hover(position).unwrap().unwrap(); |
909 | assert_eq!(trim_markup_opt(hover.info.first()), Some("macro_rules! foo")); | 895 | assert_eq!(trim_markup(&hover.info.results[0]), ("macro_rules! foo")); |
910 | } | 896 | } |
911 | 897 | ||
912 | #[test] | 898 | #[test] |
@@ -917,7 +903,7 @@ fn func(foo: i32) { if true { <|>foo; }; } | |||
917 | ", | 903 | ", |
918 | ); | 904 | ); |
919 | let hover = analysis.hover(position).unwrap().unwrap(); | 905 | let hover = analysis.hover(position).unwrap().unwrap(); |
920 | assert_eq!(trim_markup_opt(hover.info.first()), Some("i32")); | 906 | assert_eq!(trim_markup(&hover.info.results[0]), "i32"); |
921 | } | 907 | } |
922 | 908 | ||
923 | #[test] | 909 | #[test] |