1
1
use std:: { iter, mem:: discriminant} ;
2
2
3
3
use crate :: {
4
- doc_links:: token_as_doc_comment, navigation_target:: ToNav , FilePosition , NavigationTarget ,
5
- RangeInfo , TryToNav ,
4
+ doc_links:: token_as_doc_comment,
5
+ navigation_target:: { self , ToNav } ,
6
+ FilePosition , NavigationTarget , RangeInfo , TryToNav , UpmappingResult ,
6
7
} ;
7
8
use hir:: {
8
- AsAssocItem , AssocItem , DescendPreference , FileRange , InFile , MacroFileIdExt , ModuleDef , Semantics
9
+ AsAssocItem , AssocItem , DescendPreference , FileRange , InFile , MacroFileIdExt , ModuleDef ,
10
+ Semantics ,
9
11
} ;
10
12
use ide_db:: {
11
13
base_db:: { AnchoredPath , FileLoader } ,
12
14
defs:: { Definition , IdentClass } ,
13
15
helpers:: pick_best_token,
14
- FileId , RootDatabase ,
16
+ RootDatabase , SymbolKind ,
15
17
} ;
16
18
use itertools:: Itertools ;
17
19
20
+ use span:: FileId ;
18
21
use syntax:: {
19
22
ast:: { self , HasLoopBody } ,
20
23
match_ast, AstNode , AstToken ,
@@ -299,19 +302,19 @@ fn nav_for_exit_points(
299
302
ast:: ClosureExpr ( c) => {
300
303
let pipe_tok = c. param_list( ) . and_then( |it| it. pipe_token( ) ) ?. text_range( ) ;
301
304
let closure_in_file = InFile :: new( file_id, c. into( ) ) ;
302
- Some ( NavigationTarget :: from_expr ( db, closure_in_file, Some ( pipe_tok) ) )
305
+ Some ( expr_to_nav ( db, closure_in_file, Some ( pipe_tok) ) )
303
306
} ,
304
307
ast:: BlockExpr ( blk) => {
305
308
match blk. modifier( ) {
306
309
Some ( ast:: BlockModifier :: Async ( _) ) => {
307
310
let async_tok = blk. async_token( ) ?. text_range( ) ;
308
311
let blk_in_file = InFile :: new( file_id, blk. into( ) ) ;
309
- Some ( NavigationTarget :: from_expr ( db, blk_in_file, Some ( async_tok) ) )
312
+ Some ( expr_to_nav ( db, blk_in_file, Some ( async_tok) ) )
310
313
} ,
311
314
Some ( ast:: BlockModifier :: Try ( _) ) if token_kind != T ![ return ] => {
312
315
let try_tok = blk. try_token( ) ?. text_range( ) ;
313
316
let blk_in_file = InFile :: new( file_id, blk. into( ) ) ;
314
- Some ( NavigationTarget :: from_expr ( db, blk_in_file, Some ( try_tok) ) )
317
+ Some ( expr_to_nav ( db, blk_in_file, Some ( try_tok) ) )
315
318
} ,
316
319
_ => None ,
317
320
}
@@ -390,7 +393,7 @@ fn nav_for_break_points(
390
393
ast:: Expr :: BlockExpr ( blk) => blk. label ( ) . unwrap ( ) . syntax ( ) . text_range ( ) ,
391
394
_ => return None ,
392
395
} ;
393
- let nav = NavigationTarget :: from_expr ( db, expr_in_file, Some ( focus_range) ) ;
396
+ let nav = expr_to_nav ( db, expr_in_file, Some ( focus_range) ) ;
394
397
Some ( nav)
395
398
} )
396
399
. flatten ( )
@@ -403,6 +406,20 @@ fn def_to_nav(db: &RootDatabase, def: Definition) -> Vec<NavigationTarget> {
403
406
def. try_to_nav ( db) . map ( |it| it. collect ( ) ) . unwrap_or_default ( )
404
407
}
405
408
409
+ fn expr_to_nav (
410
+ db : & RootDatabase ,
411
+ InFile { file_id, value } : InFile < ast:: Expr > ,
412
+ focus_range : Option < TextRange > ,
413
+ ) -> UpmappingResult < NavigationTarget > {
414
+ let kind = SymbolKind :: Label ;
415
+
416
+ let value_range = value. syntax ( ) . text_range ( ) ;
417
+ let navs = navigation_target:: orig_range_with_focus_r ( db, file_id, value_range, focus_range) ;
418
+ navs. map ( |( hir:: FileRangeWrapper { file_id, range } , focus_range) | {
419
+ NavigationTarget :: from_syntax ( file_id, "<expr>" . into ( ) , focus_range, range, kind)
420
+ } )
421
+ }
422
+
406
423
#[ cfg( test) ]
407
424
mod tests {
408
425
use ide_db:: FileRange ;
0 commit comments