@@ -13,7 +13,7 @@ use ra_syntax::{
13
13
14
14
use crate :: {
15
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
17
references:: { classify_name, classify_name_ref, NameKind , NameKind :: * } ,
18
18
FilePosition , FileRange , RangeInfo ,
19
19
} ;
@@ -148,17 +148,18 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
148
148
let mut res = HoverResult :: new ( ) ;
149
149
150
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
152
match ( token. value. parent( ) ) {
153
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
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
159
_ => None ,
160
160
}
161
161
} {
162
+ let range = original_range ( db, token. with_value ( & node) ) . range ;
162
163
res. extend ( hover_text_from_name_kind ( db, name_kind) ) ;
163
164
164
165
if !res. is_empty ( ) {
@@ -171,8 +172,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
171
172
. ancestors ( )
172
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 = FileRange { file_id : position. file_id , range : node. text_range ( ) } ;
175
+ let frange = original_range ( db, token. with_value ( & node) ) ;
176
176
res. extend ( type_of ( db, frange) . map ( rust_code_markup) ) ;
177
177
if res. is_empty ( ) {
178
178
return None ;
@@ -220,6 +220,7 @@ mod tests {
220
220
use crate :: mock_analysis:: {
221
221
analysis_and_position, single_file_with_position, single_file_with_range,
222
222
} ;
223
+ use ra_db:: FileLoader ;
223
224
use ra_syntax:: TextRange ;
224
225
225
226
fn trim_markup ( s : & str ) -> & str {
@@ -230,7 +231,7 @@ mod tests {
230
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
235
let ( analysis, position) = analysis_and_position ( fixture) ;
235
236
let hover = analysis. hover ( position) . unwrap ( ) . unwrap ( ) ;
236
237
let mut results = Vec :: from ( hover. info . results ( ) ) ;
@@ -243,6 +244,9 @@ mod tests {
243
244
}
244
245
245
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
252
#[ test]
@@ -711,7 +715,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
711
715
712
716
#[ test]
713
717
fn test_hover_through_macro ( ) {
714
- check_hover_result (
718
+ let hover_on = check_hover_result (
715
719
"
716
720
//- /lib.rs
717
721
macro_rules! id {
@@ -726,11 +730,13 @@ fn func(foo: i32) { if true { <|>foo; }; }
726
730
" ,
727
731
& [ "fn foo()" ] ,
728
732
) ;
733
+
734
+ assert_eq ! ( hover_on, "foo" )
729
735
}
730
736
731
737
#[ test]
732
738
fn test_hover_through_expr_in_macro ( ) {
733
- check_hover_result (
739
+ let hover_on = check_hover_result (
734
740
"
735
741
//- /lib.rs
736
742
macro_rules! id {
@@ -742,5 +748,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
742
748
" ,
743
749
& [ "u32" ] ,
744
750
) ;
751
+
752
+ assert_eq ! ( hover_on, "bar" )
745
753
}
746
754
}
0 commit comments