@@ -12,8 +12,9 @@ use once_cell::unsync::Lazy;
12
12
use rustc_hash:: FxHashMap ;
13
13
use syntax:: { ast, match_ast, AstNode , TextRange , TextSize } ;
14
14
15
+ use crate :: defs:: NameClass ;
15
16
use crate :: {
16
- defs:: { classify_name_ref, Definition , NameRefClass } ,
17
+ defs:: { classify_name , classify_name_ref, Definition , NameRefClass } ,
17
18
RootDatabase ,
18
19
} ;
19
20
@@ -226,9 +227,9 @@ impl<'a> FindUsages<'a> {
226
227
227
228
let search_scope = {
228
229
let base = self . def . search_scope ( sema. db ) ;
229
- match self . scope {
230
+ match & self . scope {
230
231
None => base,
231
- Some ( scope) => base. intersection ( & scope) ,
232
+ Some ( scope) => base. intersection ( scope) ,
232
233
}
233
234
} ;
234
235
@@ -251,54 +252,83 @@ impl<'a> FindUsages<'a> {
251
252
continue ;
252
253
}
253
254
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) {
276
258
return ;
277
259
}
278
260
}
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
+ }
295
266
}
296
- }
297
- _ => { } // not a usage
267
+ None => { }
268
+ } ,
298
269
}
299
270
}
300
271
}
301
272
}
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
+ }
302
332
}
303
333
304
334
fn reference_access ( def : & Definition , name_ref : & ast:: NameRef ) -> Option < ReferenceAccess > {
0 commit comments