aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src')
-rw-r--r--crates/ra_ide/src/hover.rs88
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]