@@ -6,6 +6,7 @@ use ide_db::{
66 search:: { FileReference , ReferenceAccess , SearchScope } ,
77 RootDatabase ,
88} ;
9+ use itertools:: Itertools ;
910use syntax:: {
1011 ast:: { self , LoopBodyOwner } ,
1112 match_ast, AstNode , SyntaxNode , SyntaxToken , TextRange , TextSize , T ,
@@ -70,7 +71,7 @@ fn highlight_references(
7071 syntax : & SyntaxNode ,
7172 FilePosition { offset, file_id } : FilePosition ,
7273) -> Option < Vec < HighlightedRange > > {
73- let defs = find_defs ( sema, syntax, offset) ? ;
74+ let defs = find_defs ( sema, syntax, offset) ;
7475 let usages = defs
7576 . iter ( )
7677 . flat_map ( |& d| {
@@ -99,7 +100,12 @@ fn highlight_references(
99100 } )
100101 } ) ;
101102
102- Some ( declarations. chain ( usages) . collect ( ) )
103+ let res: Vec < _ > = declarations. chain ( usages) . collect ( ) ;
104+ if res. is_empty ( ) {
105+ None
106+ } else {
107+ Some ( res)
108+ }
103109}
104110
105111fn highlight_exit_points (
@@ -270,29 +276,41 @@ fn find_defs(
270276 sema : & Semantics < RootDatabase > ,
271277 syntax : & SyntaxNode ,
272278 offset : TextSize ,
273- ) -> Option < Vec < Definition > > {
274- let defs = match sema. find_node_at_offset_with_descend ( syntax, offset) ? {
275- ast:: NameLike :: NameRef ( name_ref) => match NameRefClass :: classify ( sema, & name_ref) ? {
276- NameRefClass :: Definition ( def) => vec ! [ def] ,
277- NameRefClass :: FieldShorthand { local_ref, field_ref } => {
278- vec ! [ Definition :: Local ( local_ref) , Definition :: Field ( field_ref) ]
279- }
280- } ,
281- ast:: NameLike :: Name ( name) => match NameClass :: classify ( sema, & name) ? {
282- NameClass :: Definition ( it) | NameClass :: ConstReference ( it) => vec ! [ it] ,
283- NameClass :: PatFieldShorthand { local_def, field_ref } => {
284- vec ! [ Definition :: Local ( local_def) , Definition :: Field ( field_ref) ]
285- }
286- } ,
287- ast:: NameLike :: Lifetime ( lifetime) => NameRefClass :: classify_lifetime ( sema, & lifetime)
288- . and_then ( |class| match class {
289- NameRefClass :: Definition ( it) => Some ( it) ,
290- _ => None ,
279+ ) -> Vec < Definition > {
280+ sema. find_nodes_at_offset_with_descend ( syntax, offset)
281+ . flat_map ( |name_like| {
282+ Some ( match name_like {
283+ ast:: NameLike :: NameRef ( name_ref) => {
284+ match NameRefClass :: classify ( sema, & name_ref) ? {
285+ NameRefClass :: Definition ( def) => vec ! [ def] ,
286+ NameRefClass :: FieldShorthand { local_ref, field_ref } => {
287+ vec ! [ Definition :: Local ( local_ref) , Definition :: Field ( field_ref) ]
288+ }
289+ }
290+ }
291+ ast:: NameLike :: Name ( name) => match NameClass :: classify ( sema, & name) ? {
292+ NameClass :: Definition ( it) | NameClass :: ConstReference ( it) => vec ! [ it] ,
293+ NameClass :: PatFieldShorthand { local_def, field_ref } => {
294+ vec ! [ Definition :: Local ( local_def) , Definition :: Field ( field_ref) ]
295+ }
296+ } ,
297+ ast:: NameLike :: Lifetime ( lifetime) => {
298+ NameRefClass :: classify_lifetime ( sema, & lifetime)
299+ . and_then ( |class| match class {
300+ NameRefClass :: Definition ( it) => Some ( it) ,
301+ _ => None ,
302+ } )
303+ . or_else ( || {
304+ NameClass :: classify_lifetime ( sema, & lifetime)
305+ . and_then ( NameClass :: defined)
306+ } )
307+ . map ( |it| vec ! [ it] ) ?
308+ }
291309 } )
292- . or_else ( || NameClass :: classify_lifetime ( sema , & lifetime ) . and_then ( NameClass :: defined ) )
293- . map ( |it| vec ! [ it ] ) ? ,
294- } ;
295- Some ( defs )
310+ } )
311+ . flatten ( )
312+ . unique ( )
313+ . collect ( )
296314}
297315
298316#[ cfg( test) ]
@@ -392,6 +410,46 @@ fn foo() {
392410 ) ;
393411 }
394412
413+ #[ test]
414+ fn test_multi_macro_usage ( ) {
415+ check (
416+ r#"
417+ macro_rules! foo {
418+ ($ident:ident) => {
419+ fn $ident() -> $ident { loop {} }
420+ struct $ident;
421+ }
422+ }
423+
424+ foo!(bar$0);
425+ // ^^^
426+ // ^^^
427+ fn foo() {
428+ let bar: bar = bar();
429+ // ^^^
430+ // ^^^
431+ }
432+ "# ,
433+ ) ;
434+ check (
435+ r#"
436+ macro_rules! foo {
437+ ($ident:ident) => {
438+ fn $ident() -> $ident { loop {} }
439+ struct $ident;
440+ }
441+ }
442+
443+ foo!(bar);
444+ // ^^^
445+ fn foo() {
446+ let bar: bar$0 = bar();
447+ // ^^^
448+ }
449+ "# ,
450+ ) ;
451+ }
452+
395453 #[ test]
396454 fn test_hl_yield_points ( ) {
397455 check (
0 commit comments