@@ -58,7 +58,7 @@ pub enum HoverDocFormat {
5858 PlainText ,
5959}
6060
61- #[ derive( Debug , Clone ) ]
61+ #[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
6262pub enum HoverAction {
6363 Runnable ( Runnable ) ,
6464 Implementation ( FilePosition ) ,
@@ -97,7 +97,7 @@ pub struct HoverGotoTypeData {
9797}
9898
9999/// Contains the results when hovering over an item
100- #[ derive( Debug , Default ) ]
100+ #[ derive( Clone , Debug , Default , Hash , PartialEq , Eq ) ]
101101pub struct HoverResult {
102102 pub markup : Markup ,
103103 pub actions : Vec < HoverAction > ,
@@ -200,21 +200,24 @@ fn hover_simple(
200200 | ( ( no_tt_parent as usize ) << 3 )
201201 } ) ;
202202
203- // TODO: WE should not try these step by step, instead to accommodate for macros we should run
204- // all of these in "parallel" and rank their results
205- let result = None
206- // try lint hover
207- . or_else ( || {
208- descended ( ) . find_map ( |token| {
209- // FIXME: Definition should include known lints and the like instead of having this special case here
210- let attr = token. parent_ancestors ( ) . find_map ( ast:: Attr :: cast) ?;
211- render:: try_for_lint ( & attr, token)
212- } )
213- } )
214- // try definitions
215- . or_else ( || {
216- descended ( )
217- . filter_map ( |token| {
203+ let mut res = vec ! [ ] ;
204+ // let mut merge_result = |next: HoverResult| {
205+ // res.markup = Markup::from(format!("{}\n---\n{}", res.markup, next.markup));
206+ // res.actions.extend(next.actions);
207+ // };
208+ for token in descended {
209+ let lint_hover = ( || {
210+ // FIXME: Definition should include known lints and the like instead of having this special case here
211+ let attr = token. parent_ancestors ( ) . find_map ( ast:: Attr :: cast) ?;
212+ render:: try_for_lint ( & attr, & token)
213+ } ) ( ) ;
214+ if let Some ( lint_hover) = lint_hover {
215+ res. push ( lint_hover) ;
216+ continue ;
217+ }
218+ let definitions = ( || {
219+ Some (
220+ ' a: {
218221 let node = token. parent ( ) ?;
219222
220223 // special case macro calls, we wanna render the invoked arm index
@@ -229,11 +232,11 @@ fn hover_simple(
229232 . and_then ( ast:: MacroCall :: cast)
230233 {
231234 if let Some ( macro_) = sema. resolve_macro_call ( & macro_call) {
232- return Some ( vec ! [ (
235+ break ' a vec ! [ (
233236 Definition :: Macro ( macro_) ,
234237 sema. resolve_macro_call_arm( & macro_call) ,
235238 node,
236- ) ] ) ;
239+ ) ] ;
237240 }
238241 }
239242 }
@@ -242,88 +245,96 @@ fn hover_simple(
242245 match IdentClass :: classify_node ( sema, & node) ? {
243246 // It's better for us to fall back to the keyword hover here,
244247 // rendering poll is very confusing
245- IdentClass :: Operator ( OperatorClass :: Await ( _) ) => None ,
248+ IdentClass :: Operator ( OperatorClass :: Await ( _) ) => return None ,
246249
247250 IdentClass :: NameRefClass ( NameRefClass :: ExternCrateShorthand {
248251 decl,
249252 ..
250- } ) => Some ( vec ! [ ( Definition :: ExternCrateDecl ( decl) , None , node) ] ) ,
253+ } ) => {
254+ vec ! [ ( Definition :: ExternCrateDecl ( decl) , None , node) ]
255+ }
251256
252- class => Some (
257+ class => {
253258 multizip ( ( class. definitions ( ) , iter:: repeat ( None ) , iter:: repeat ( node) ) )
254- . collect :: < Vec < _ > > ( ) ,
255- ) ,
259+ . collect :: < Vec < _ > > ( )
260+ }
256261 }
257- } )
258- . flatten ( )
262+ }
263+ . into_iter ( )
259264 . unique_by ( |& ( def, _, _) | def)
260265 . map ( |( def, macro_arm, node) | {
261266 hover_for_definition ( sema, file_id, def, & node, macro_arm, config, edition)
262267 } )
263- . reduce ( |mut acc : HoverResult , HoverResult { markup, actions } | {
264- acc. actions . extend ( actions) ;
265- acc. markup = Markup :: from ( format ! ( "{}\n ---\n {markup}" , acc. markup) ) ;
266- acc
267- } )
268- } )
269- // try keywords
270- . or_else ( || descended ( ) . find_map ( |token| render:: keyword ( sema, config, token, edition) ) )
271- // try _ hovers
272- . or_else ( || descended ( ) . find_map ( |token| render:: underscore ( sema, config, token, edition) ) )
273- // try rest pattern hover
274- . or_else ( || {
275- descended ( ) . find_map ( |token| {
276- if token. kind ( ) != DOT2 {
277- return None ;
278- }
268+ . collect :: < Vec < _ > > ( ) ,
269+ )
270+ } ) ( ) ;
271+ if let Some ( definitions) = definitions {
272+ res. extend ( definitions) ;
273+ continue ;
274+ }
275+ let keywords = || render:: keyword ( sema, config, & token, edition) ;
276+ let underscore = || render:: underscore ( sema, config, & token, edition) ;
277+ let rest_pat = || {
278+ if token. kind ( ) != DOT2 {
279+ return None ;
280+ }
279281
280- let rest_pat = token. parent ( ) . and_then ( ast:: RestPat :: cast) ?;
281- let record_pat_field_list =
282- rest_pat. syntax ( ) . parent ( ) . and_then ( ast:: RecordPatFieldList :: cast) ?;
282+ let rest_pat = token. parent ( ) . and_then ( ast:: RestPat :: cast) ?;
283+ let record_pat_field_list =
284+ rest_pat. syntax ( ) . parent ( ) . and_then ( ast:: RecordPatFieldList :: cast) ?;
283285
284- let record_pat =
285- record_pat_field_list. syntax ( ) . parent ( ) . and_then ( ast:: RecordPat :: cast) ?;
286+ let record_pat =
287+ record_pat_field_list. syntax ( ) . parent ( ) . and_then ( ast:: RecordPat :: cast) ?;
286288
287- Some ( render:: struct_rest_pat ( sema, config, & record_pat, edition) )
288- } )
289- } )
290- // try () call hovers
291- . or_else ( || {
292- descended ( ) . find_map ( |token| {
293- if token. kind ( ) != T ! [ '(' ] && token. kind ( ) != T ! [ ')' ] {
294- return None ;
295- }
296- let arg_list = token. parent ( ) . and_then ( ast:: ArgList :: cast) ?. syntax ( ) . parent ( ) ?;
297- let call_expr = syntax:: match_ast! {
298- match arg_list {
299- ast:: CallExpr ( expr) => expr. into( ) ,
300- ast:: MethodCallExpr ( expr) => expr. into( ) ,
301- _ => return None ,
302- }
303- } ;
304- render:: type_info_of ( sema, config, & Either :: Left ( call_expr) , edition)
305- } )
306- } )
307- // try closure
308- . or_else ( || {
309- descended ( ) . find_map ( |token| {
310- if token. kind ( ) != T ! [ |] {
311- return None ;
289+ Some ( render:: struct_rest_pat ( sema, config, & record_pat, edition) )
290+ } ;
291+ let call = || {
292+ if token. kind ( ) != T ! [ '(' ] && token. kind ( ) != T ! [ ')' ] {
293+ return None ;
294+ }
295+ let arg_list = token. parent ( ) . and_then ( ast:: ArgList :: cast) ?. syntax ( ) . parent ( ) ?;
296+ let call_expr = syntax:: match_ast! {
297+ match arg_list {
298+ ast:: CallExpr ( expr) => expr. into( ) ,
299+ ast:: MethodCallExpr ( expr) => expr. into( ) ,
300+ _ => return None ,
312301 }
313- let c = token. parent ( ) . and_then ( |x| x. parent ( ) ) . and_then ( ast:: ClosureExpr :: cast) ?;
314- render:: closure_expr ( sema, config, c, edition)
315- } )
316- } )
317- // tokens
318- . or_else ( || {
302+ } ;
303+ render:: type_info_of ( sema, config, & Either :: Left ( call_expr) , edition)
304+ } ;
305+ let closure = || {
306+ if token. kind ( ) != T ! [ |] {
307+ return None ;
308+ }
309+ let c = token. parent ( ) . and_then ( |x| x. parent ( ) ) . and_then ( ast:: ClosureExpr :: cast) ?;
310+ render:: closure_expr ( sema, config, c, edition)
311+ } ;
312+ let literal = || {
319313 render:: literal ( sema, original_token. clone ( ) , edition)
320314 . map ( |markup| HoverResult { markup, actions : vec ! [ ] } )
321- } ) ;
315+ } ;
316+ if let Some ( result) = keywords ( )
317+ . or_else ( underscore)
318+ . or_else ( rest_pat)
319+ . or_else ( call)
320+ . or_else ( closure)
321+ . or_else ( literal)
322+ {
323+ res. push ( result)
324+ }
325+ }
322326
323- result. map ( |mut res : HoverResult | {
324- res. actions = dedupe_or_merge_hover_actions ( res. actions ) ;
325- RangeInfo :: new ( original_token. text_range ( ) , res)
326- } )
327+ res. into_iter ( )
328+ . unique ( )
329+ . reduce ( |mut acc : HoverResult , HoverResult { markup, actions } | {
330+ acc. actions . extend ( actions) ;
331+ acc. markup = Markup :: from ( format ! ( "{}\n ---\n {markup}" , acc. markup) ) ;
332+ acc
333+ } )
334+ . map ( |mut res : HoverResult | {
335+ res. actions = dedupe_or_merge_hover_actions ( res. actions ) ;
336+ RangeInfo :: new ( original_token. text_range ( ) , res)
337+ } )
327338}
328339
329340fn hover_ranged (
0 commit comments