@@ -6,7 +6,6 @@ use ra_ide_db::{
66 RootDatabase ,
77} ;
88use ra_syntax:: {
9- algo:: find_covering_element,
109 ast:: { self , DocCommentsOwner } ,
1110 match_ast, AstNode ,
1211 SyntaxKind :: * ,
@@ -16,7 +15,7 @@ use ra_syntax::{
1615use crate :: {
1716 display:: { macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel } ,
1817 references:: classify_name_ref,
19- FilePosition , FileRange , RangeInfo ,
18+ FilePosition , RangeInfo ,
2019} ;
2120
2221/// Contains the results when hovering over an item
@@ -174,23 +173,25 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
174173 . ancestors ( )
175174 . find ( |n| ast:: Expr :: cast ( n. clone ( ) ) . is_some ( ) || ast:: Pat :: cast ( n. clone ( ) ) . is_some ( ) ) ?;
176175
177- // if this node is a MACRO_CALL, it means that `descend_into_macros` is failed to resolve.
178- // (e.g expanding a builtin macro). So we give up here.
179- if node . kind ( ) == MACRO_CALL {
180- return None ;
181- }
182-
183- // FIXME: Currently `hover::typeof` do not work inside
184- // macro expansion such that if the hover range is pointing to
185- // a string literal, the following type_of will return None.
186- // See also `test_hover_through_literal_string_in_macro`
187- let frange = sema . original_range ( & node ) ;
188- res . extend ( type_of ( db , frange ) . map ( rust_code_markup ) ) ;
189- if res . is_empty ( ) {
190- return None ;
191- }
192- let range = node . text_range ( ) ;
176+ let ty = match_ast ! {
177+ match node {
178+ ast :: MacroCall ( _it ) => {
179+ // If this node is a MACRO_CALL, it means that `descend_into_macros` failed to resolve.
180+ // (e.g expanding a builtin macro). So we give up here.
181+ return None ;
182+ } ,
183+ ast :: Expr ( it ) => {
184+ sema . type_of_expr ( & it )
185+ } ,
186+ ast :: Pat ( it ) => {
187+ sema . type_of_pat ( & it )
188+ } ,
189+ _ => None ,
190+ }
191+ } ? ;
193192
193+ res. extend ( Some ( rust_code_markup ( ty. display_truncated ( db, None ) . to_string ( ) ) ) ) ;
194+ let range = sema. original_range ( & node) . range ;
194195 Some ( RangeInfo :: new ( range, res) )
195196}
196197
@@ -206,33 +207,12 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
206207 }
207208}
208209
209- pub ( crate ) fn type_of ( db : & RootDatabase , frange : FileRange ) -> Option < String > {
210- let sema = Semantics :: new ( db) ;
211- let source_file = sema. parse ( frange. file_id ) ;
212- let leaf_node = find_covering_element ( source_file. syntax ( ) , frange. range ) ;
213- // if we picked identifier, expand to pattern/expression
214- let node = leaf_node
215- . ancestors ( )
216- . take_while ( |it| it. text_range ( ) == leaf_node. text_range ( ) )
217- . find ( |it| ast:: Expr :: cast ( it. clone ( ) ) . is_some ( ) || ast:: Pat :: cast ( it. clone ( ) ) . is_some ( ) ) ?;
218- let ty = if let Some ( ty) = ast:: Expr :: cast ( node. clone ( ) ) . and_then ( |e| sema. type_of_expr ( & e) ) {
219- ty
220- } else if let Some ( ty) = ast:: Pat :: cast ( node) . and_then ( |p| sema. type_of_pat ( & p) ) {
221- ty
222- } else {
223- return None ;
224- } ;
225- Some ( ty. display_truncated ( db, None ) . to_string ( ) )
226- }
227-
228210#[ cfg( test) ]
229211mod tests {
230212 use ra_db:: FileLoader ;
231213 use ra_syntax:: TextRange ;
232214
233- use crate :: mock_analysis:: {
234- analysis_and_position, single_file_with_position, single_file_with_range,
235- } ;
215+ use crate :: mock_analysis:: { analysis_and_position, single_file_with_position} ;
236216
237217 fn trim_markup ( s : & str ) -> & str {
238218 s. trim_start_matches ( "```rust\n " ) . trim_end_matches ( "\n ```" )
@@ -524,37 +504,6 @@ fn func(foo: i32) { if true { <|>foo; }; }
524504 assert_eq ! ( trim_markup_opt( hover. info. first( ) ) , Some ( "i32" ) ) ;
525505 }
526506
527- #[ test]
528- fn test_type_of_for_function ( ) {
529- let ( analysis, range) = single_file_with_range (
530- "
531- pub fn foo() -> u32 { 1 };
532-
533- fn main() {
534- let foo_test = <|>foo()<|>;
535- }
536- " ,
537- ) ;
538-
539- let type_name = analysis. type_of ( range) . unwrap ( ) . unwrap ( ) ;
540- assert_eq ! ( "u32" , & type_name) ;
541- }
542-
543- #[ test]
544- fn test_type_of_for_expr ( ) {
545- let ( analysis, range) = single_file_with_range (
546- "
547- fn main() {
548- let foo: usize = 1;
549- let bar = <|>1 + foo<|>;
550- }
551- " ,
552- ) ;
553-
554- let type_name = analysis. type_of ( range) . unwrap ( ) . unwrap ( ) ;
555- assert_eq ! ( "usize" , & type_name) ;
556- }
557-
558507 #[ test]
559508 fn test_hover_infer_associated_method_result ( ) {
560509 let ( analysis, position) = single_file_with_position (
@@ -791,9 +740,7 @@ fn func(foo: i32) { if true { <|>foo; }; }
791740
792741 #[ test]
793742 fn test_hover_through_literal_string_in_macro ( ) {
794- // FIXME: Currently `hover::type_of` do not work inside
795- // macro expansion
796- check_hover_no_result (
743+ let hover_on = check_hover_result (
797744 r#"
798745 //- /lib.rs
799746 macro_rules! arr {
@@ -804,7 +751,10 @@ fn func(foo: i32) { if true { <|>foo; }; }
804751 let _ = arr!("Tr<|>acks", &mastered_for_itunes);
805752 }
806753 "# ,
754+ & [ "&str" ] ,
807755 ) ;
756+
757+ assert_eq ! ( hover_on, "\" Tracks\" " ) ;
808758 }
809759
810760 #[ test]
0 commit comments