aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-02-19 10:46:00 +0000
committerGitHub <[email protected]>2020-02-19 10:46:00 +0000
commiteb804261dce7f13056566377148a41f460feed28 (patch)
tree0ed558c9654d41b66b7a80143d8fe378c29a567f /crates/ra_ide
parentd07f043ef1c99491cb172f3c3474b31c97501d7a (diff)
parentb9d94d73a2682be4418cb5de4f77cbd8db7b6901 (diff)
Merge #3228
3228: Use proper range for hover on macro arguments r=matklad a=edwin0cheng This PR use `original_range` to remap the range of found syntax node in `hover` and thus it should return the proper text range now. fixed #3000 fixed #3135 Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_ide')
-rw-r--r--crates/ra_ide/src/hover.rs26
1 files changed, 17 insertions, 9 deletions
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index 1de3cb579..6d4416c0b 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -13,7 +13,7 @@ use ra_syntax::{
13 13
14use crate::{ 14use crate::{
15 display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel}, 15 display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel},
16 expand::descend_into_macros, 16 expand::{descend_into_macros, original_range},
17 references::{classify_name, classify_name_ref, NameKind, NameKind::*}, 17 references::{classify_name, classify_name_ref, NameKind, NameKind::*},
18 FilePosition, FileRange, RangeInfo, 18 FilePosition, FileRange, RangeInfo,
19}; 19};
@@ -148,17 +148,18 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
148 let mut res = HoverResult::new(); 148 let mut res = HoverResult::new();
149 149
150 let mut sb = SourceBinder::new(db); 150 let mut sb = SourceBinder::new(db);
151 if let Some((range, name_kind)) = match_ast! { 151 if let Some((node, name_kind)) = match_ast! {
152 match (token.value.parent()) { 152 match (token.value.parent()) {
153 ast::NameRef(name_ref) => { 153 ast::NameRef(name_ref) => {
154 classify_name_ref(&mut sb, token.with_value(&name_ref)).map(|d| (name_ref.syntax().text_range(), d.kind)) 154 classify_name_ref(&mut sb, token.with_value(&name_ref)).map(|d| (name_ref.syntax().clone(), d.kind))
155 }, 155 },
156 ast::Name(name) => { 156 ast::Name(name) => {
157 classify_name(&mut sb, token.with_value(&name)).map(|d| (name.syntax().text_range(), d.kind)) 157 classify_name(&mut sb, token.with_value(&name)).map(|d| (name.syntax().clone(), d.kind))
158 }, 158 },
159 _ => None, 159 _ => None,
160 } 160 }
161 } { 161 } {
162 let range = original_range(db, token.with_value(&node)).range;
162 res.extend(hover_text_from_name_kind(db, name_kind)); 163 res.extend(hover_text_from_name_kind(db, name_kind));
163 164
164 if !res.is_empty() { 165 if !res.is_empty() {
@@ -171,8 +172,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
171 .ancestors() 172 .ancestors()
172 .find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())?; 173 .find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())?;
173 174
174 // The following logic will not work if token is coming from a macro 175 let frange = original_range(db, token.with_value(&node));
175 let frange = FileRange { file_id: position.file_id, range: node.text_range() };
176 res.extend(type_of(db, frange).map(rust_code_markup)); 176 res.extend(type_of(db, frange).map(rust_code_markup));
177 if res.is_empty() { 177 if res.is_empty() {
178 return None; 178 return None;
@@ -220,6 +220,7 @@ mod tests {
220 use crate::mock_analysis::{ 220 use crate::mock_analysis::{
221 analysis_and_position, single_file_with_position, single_file_with_range, 221 analysis_and_position, single_file_with_position, single_file_with_range,
222 }; 222 };
223 use ra_db::FileLoader;
223 use ra_syntax::TextRange; 224 use ra_syntax::TextRange;
224 225
225 fn trim_markup(s: &str) -> &str { 226 fn trim_markup(s: &str) -> &str {
@@ -230,7 +231,7 @@ mod tests {
230 s.map(trim_markup) 231 s.map(trim_markup)
231 } 232 }
232 233
233 fn check_hover_result(fixture: &str, expected: &[&str]) { 234 fn check_hover_result(fixture: &str, expected: &[&str]) -> String {
234 let (analysis, position) = analysis_and_position(fixture); 235 let (analysis, position) = analysis_and_position(fixture);
235 let hover = analysis.hover(position).unwrap().unwrap(); 236 let hover = analysis.hover(position).unwrap().unwrap();
236 let mut results = Vec::from(hover.info.results()); 237 let mut results = Vec::from(hover.info.results());
@@ -243,6 +244,9 @@ mod tests {
243 } 244 }
244 245
245 assert_eq!(hover.info.len(), expected.len()); 246 assert_eq!(hover.info.len(), expected.len());
247
248 let content = analysis.db.file_text(position.file_id);
249 content[hover.range].to_string()
246 } 250 }
247 251
248 #[test] 252 #[test]
@@ -711,7 +715,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
711 715
712 #[test] 716 #[test]
713 fn test_hover_through_macro() { 717 fn test_hover_through_macro() {
714 check_hover_result( 718 let hover_on = check_hover_result(
715 " 719 "
716 //- /lib.rs 720 //- /lib.rs
717 macro_rules! id { 721 macro_rules! id {
@@ -726,11 +730,13 @@ fn func(foo: i32) { if true { <|>foo; }; }
726 ", 730 ",
727 &["fn foo()"], 731 &["fn foo()"],
728 ); 732 );
733
734 assert_eq!(hover_on, "foo")
729 } 735 }
730 736
731 #[test] 737 #[test]
732 fn test_hover_through_expr_in_macro() { 738 fn test_hover_through_expr_in_macro() {
733 check_hover_result( 739 let hover_on = check_hover_result(
734 " 740 "
735 //- /lib.rs 741 //- /lib.rs
736 macro_rules! id { 742 macro_rules! id {
@@ -742,6 +748,8 @@ fn func(foo: i32) { if true { <|>foo; }; }
742 ", 748 ",
743 &["u32"], 749 &["u32"],
744 ); 750 );
751
752 assert_eq!(hover_on, "bar")
745 } 753 }
746 754
747 #[test] 755 #[test]