@@ -58,7 +58,7 @@ pub enum HoverDocFormat {
58
58
PlainText ,
59
59
}
60
60
61
- #[ derive( Debug , Clone ) ]
61
+ #[ derive( Debug , Clone , Hash , PartialEq , Eq ) ]
62
62
pub enum HoverAction {
63
63
Runnable ( Runnable ) ,
64
64
Implementation ( FilePosition ) ,
@@ -97,7 +97,7 @@ pub struct HoverGotoTypeData {
97
97
}
98
98
99
99
/// Contains the results when hovering over an item
100
- #[ derive( Debug , Default ) ]
100
+ #[ derive( Clone , Debug , Default , Hash , PartialEq , Eq ) ]
101
101
pub struct HoverResult {
102
102
pub markup : Markup ,
103
103
pub actions : Vec < HoverAction > ,
@@ -200,21 +200,24 @@ fn hover_simple(
200
200
| ( ( no_tt_parent as usize ) << 3 )
201
201
} ) ;
202
202
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: {
218
221
let node = token. parent ( ) ?;
219
222
220
223
// special case macro calls, we wanna render the invoked arm index
@@ -229,11 +232,11 @@ fn hover_simple(
229
232
. and_then ( ast:: MacroCall :: cast)
230
233
{
231
234
if let Some ( macro_) = sema. resolve_macro_call ( & macro_call) {
232
- return Some ( vec ! [ (
235
+ break ' a vec ! [ (
233
236
Definition :: Macro ( macro_) ,
234
237
sema. resolve_macro_call_arm( & macro_call) ,
235
238
node,
236
- ) ] ) ;
239
+ ) ] ;
237
240
}
238
241
}
239
242
}
@@ -242,88 +245,96 @@ fn hover_simple(
242
245
match IdentClass :: classify_node ( sema, & node) ? {
243
246
// It's better for us to fall back to the keyword hover here,
244
247
// rendering poll is very confusing
245
- IdentClass :: Operator ( OperatorClass :: Await ( _) ) => None ,
248
+ IdentClass :: Operator ( OperatorClass :: Await ( _) ) => return None ,
246
249
247
250
IdentClass :: NameRefClass ( NameRefClass :: ExternCrateShorthand {
248
251
decl,
249
252
..
250
- } ) => Some ( vec ! [ ( Definition :: ExternCrateDecl ( decl) , None , node) ] ) ,
253
+ } ) => {
254
+ vec ! [ ( Definition :: ExternCrateDecl ( decl) , None , node) ]
255
+ }
251
256
252
- class => Some (
257
+ class => {
253
258
multizip ( ( class. definitions ( ) , iter:: repeat ( None ) , iter:: repeat ( node) ) )
254
- . collect :: < Vec < _ > > ( ) ,
255
- ) ,
259
+ . collect :: < Vec < _ > > ( )
260
+ }
256
261
}
257
- } )
258
- . flatten ( )
262
+ }
263
+ . into_iter ( )
259
264
. unique_by ( |& ( def, _, _) | def)
260
265
. map ( |( def, macro_arm, node) | {
261
266
hover_for_definition ( sema, file_id, def, & node, macro_arm, config, edition)
262
267
} )
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
+ }
279
281
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) ?;
283
285
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) ?;
286
288
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 ,
312
301
}
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 = || {
319
313
render:: literal ( sema, original_token. clone ( ) , edition)
320
314
. 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
+ }
322
326
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
+ } )
327
338
}
328
339
329
340
fn hover_ranged (
0 commit comments