@@ -12,8 +12,9 @@ use once_cell::unsync::Lazy;
1212use rustc_hash:: FxHashMap ;
1313use syntax:: { ast, match_ast, AstNode , TextRange , TextSize } ;
1414
15+ use crate :: defs:: NameClass ;
1516use crate :: {
16- defs:: { classify_name_ref, Definition , NameRefClass } ,
17+ defs:: { classify_name , classify_name_ref, Definition , NameRefClass } ,
1718 RootDatabase ,
1819} ;
1920
@@ -226,9 +227,9 @@ impl<'a> FindUsages<'a> {
226227
227228 let search_scope = {
228229 let base = self . def . search_scope ( sema. db ) ;
229- match self . scope {
230+ match & self . scope {
230231 None => base,
231- Some ( scope) => base. intersection ( & scope) ,
232+ Some ( scope) => base. intersection ( scope) ,
232233 }
233234 } ;
234235
@@ -251,54 +252,83 @@ impl<'a> FindUsages<'a> {
251252 continue ;
252253 }
253254
254- let name_ref: ast:: NameRef =
255- match sema. find_node_at_offset_with_descend ( & tree, offset) {
256- Some ( it) => it,
257- None => continue ,
258- } ;
259-
260- match classify_name_ref ( & sema, & name_ref) {
261- Some ( NameRefClass :: Definition ( def) ) if & def == self . def => {
262- let kind = if is_record_lit_name_ref ( & name_ref)
263- || is_call_expr_name_ref ( & name_ref)
264- {
265- ReferenceKind :: StructLiteral
266- } else {
267- ReferenceKind :: Other
268- } ;
269-
270- let reference = Reference {
271- file_range : sema. original_range ( name_ref. syntax ( ) ) ,
272- kind,
273- access : reference_access ( & def, & name_ref) ,
274- } ;
275- if sink ( reference) {
255+ match sema. find_node_at_offset_with_descend ( & tree, offset) {
256+ Some ( name_ref) => {
257+ if self . found_name_ref ( & name_ref, sink) {
276258 return ;
277259 }
278260 }
279- Some ( NameRefClass :: FieldShorthand { local, field } ) => {
280- let reference = match self . def {
281- Definition :: Field ( _) if & field == self . def => Reference {
282- file_range : self . sema . original_range ( name_ref. syntax ( ) ) ,
283- kind : ReferenceKind :: FieldShorthandForField ,
284- access : reference_access ( & field, & name_ref) ,
285- } ,
286- Definition :: Local ( l) if & local == l => Reference {
287- file_range : self . sema . original_range ( name_ref. syntax ( ) ) ,
288- kind : ReferenceKind :: FieldShorthandForLocal ,
289- access : reference_access ( & Definition :: Local ( local) , & name_ref) ,
290- } ,
291- _ => continue , // not a usage
292- } ;
293- if sink ( reference) {
294- return ;
261+ None => match sema. find_node_at_offset_with_descend ( & tree, offset) {
262+ Some ( name) => {
263+ if self . found_name ( & name, sink) {
264+ return ;
265+ }
295266 }
296- }
297- _ => { } // not a usage
267+ None => { }
268+ } ,
298269 }
299270 }
300271 }
301272 }
273+
274+ fn found_name_ref (
275+ & self ,
276+ name_ref : & ast:: NameRef ,
277+ sink : & mut dyn FnMut ( Reference ) -> bool ,
278+ ) -> bool {
279+ match classify_name_ref ( self . sema , & name_ref) {
280+ Some ( NameRefClass :: Definition ( def) ) if & def == self . def => {
281+ let kind = if is_record_lit_name_ref ( & name_ref) || is_call_expr_name_ref ( & name_ref)
282+ {
283+ ReferenceKind :: StructLiteral
284+ } else {
285+ ReferenceKind :: Other
286+ } ;
287+
288+ let reference = Reference {
289+ file_range : self . sema . original_range ( name_ref. syntax ( ) ) ,
290+ kind,
291+ access : reference_access ( & def, & name_ref) ,
292+ } ;
293+ sink ( reference)
294+ }
295+ Some ( NameRefClass :: FieldShorthand { local, field } ) => {
296+ let reference = match self . def {
297+ Definition :: Field ( _) if & field == self . def => Reference {
298+ file_range : self . sema . original_range ( name_ref. syntax ( ) ) ,
299+ kind : ReferenceKind :: FieldShorthandForField ,
300+ access : reference_access ( & field, & name_ref) ,
301+ } ,
302+ Definition :: Local ( l) if & local == l => Reference {
303+ file_range : self . sema . original_range ( name_ref. syntax ( ) ) ,
304+ kind : ReferenceKind :: FieldShorthandForLocal ,
305+ access : reference_access ( & Definition :: Local ( local) , & name_ref) ,
306+ } ,
307+ _ => return false , // not a usage
308+ } ;
309+ sink ( reference)
310+ }
311+ _ => false , // not a usage
312+ }
313+ }
314+
315+ fn found_name ( & self , name : & ast:: Name , sink : & mut dyn FnMut ( Reference ) -> bool ) -> bool {
316+ match classify_name ( self . sema , name) {
317+ Some ( NameClass :: FieldShorthand { local : _, field } ) => {
318+ let reference = match self . def {
319+ Definition :: Field ( _) if & field == self . def => Reference {
320+ file_range : self . sema . original_range ( name. syntax ( ) ) ,
321+ kind : ReferenceKind :: FieldShorthandForField ,
322+ // FIXME: mutable patterns should have `Write` access
323+ access : Some ( ReferenceAccess :: Read ) ,
324+ } ,
325+ _ => return false , // not a usage
326+ } ;
327+ sink ( reference)
328+ }
329+ _ => false , // not a usage
330+ }
331+ }
302332}
303333
304334fn reference_access ( def : & Definition , name_ref : & ast:: NameRef ) -> Option < ReferenceAccess > {
0 commit comments