@@ -55,7 +55,7 @@ pub enum ReferenceKind {
5555 Other ,
5656}
5757
58- #[ derive( Debug , Clone , PartialEq ) ]
58+ #[ derive( Debug , Copy , Clone , PartialEq ) ]
5959pub enum ReferenceAccess {
6060 Read ,
6161 Write ,
@@ -225,49 +225,41 @@ fn process_definition(
225225}
226226
227227fn access_mode ( kind : NameKind , name_ref : & ast:: NameRef ) -> Option < ReferenceAccess > {
228+ // Only Locals and Fields have accesses for now.
228229 match kind {
229- NameKind :: Local ( _) | NameKind :: Field ( _) => {
230- //LetExpr or BinExpr
231- name_ref. syntax ( ) . ancestors ( ) . find_map ( |node| {
232- match_ast ! {
233- match ( node) {
234- ast:: BinExpr ( expr) => {
235- if expr. op_kind( ) ?. is_assignment( ) {
236- // If the variable or field ends on the LHS's end then it's a Write (covers fields and locals).
237- // FIXME: This is not terribly accurate.
238- if let Some ( lhs) = expr. lhs( ) {
239- if lhs. syntax( ) . text_range( ) . end( ) == name_ref. syntax( ) . text_range( ) . end( ) {
240- return Some ( ReferenceAccess :: Write ) ;
241- } else if name_ref. syntax( ) . text_range( ) . is_subrange( & lhs. syntax( ) . text_range( ) ) {
242- return Some ( ReferenceAccess :: Read ) ;
243- }
244- }
245-
246- // If the variable is on the RHS then it's a Read.
247- if let Some ( rhs) = expr. rhs( ) {
248- if name_ref. syntax( ) . text_range( ) . is_subrange( & rhs. syntax( ) . text_range( ) ) {
249- return Some ( ReferenceAccess :: Read ) ;
250- }
251- }
252- }
230+ NameKind :: Local ( _) | NameKind :: Field ( _) => { }
231+ _ => return None ,
232+ } ;
253233
254- // Cannot determine access
255- None
256- } ,
257- _ => { None }
234+ let mode = name_ref. syntax ( ) . ancestors ( ) . find_map ( |node| {
235+ match_ast ! {
236+ match ( node) {
237+ ast:: BinExpr ( expr) => {
238+ if expr. op_kind( ) ?. is_assignment( ) {
239+ // If the variable or field ends on the LHS's end then it's a Write (covers fields and locals).
240+ // FIXME: This is not terribly accurate.
241+ if let Some ( lhs) = expr. lhs( ) {
242+ if lhs. syntax( ) . text_range( ) . end( ) == name_ref. syntax( ) . text_range( ) . end( ) {
243+ return Some ( ReferenceAccess :: Write ) ;
244+ }
245+ }
258246 }
259- }
260- } )
247+ return Some ( ReferenceAccess :: Read ) ;
248+ } ,
249+ _ => { None }
250+ }
261251 }
262- _ => None ,
263- }
252+ } ) ;
253+
254+ // Default Locals and Fields to read
255+ mode. or ( Some ( ReferenceAccess :: Read ) )
264256}
265257
266258#[ cfg( test) ]
267259mod tests {
268260 use crate :: {
269261 mock_analysis:: { analysis_and_position, single_file_with_position, MockAnalysis } ,
270- Reference , ReferenceAccess , ReferenceKind , ReferenceSearchResult , SearchScope ,
262+ Reference , ReferenceKind , ReferenceSearchResult , SearchScope ,
271263 } ;
272264
273265 #[ test]
@@ -314,10 +306,10 @@ mod tests {
314306 "i BIND_PAT FileId(1) [33; 34)" ,
315307 ReferenceKind :: Other ,
316308 & [
317- "FileId(1) [67; 68) Other" ,
318- "FileId(1) [71; 72) Other" ,
319- "FileId(1) [101; 102) Other" ,
320- "FileId(1) [127; 128) Other" ,
309+ "FileId(1) [67; 68) Other Write " ,
310+ "FileId(1) [71; 72) Other Read " ,
311+ "FileId(1) [101; 102) Other Write " ,
312+ "FileId(1) [127; 128) Other Write " ,
321313 ] ,
322314 ) ;
323315 }
@@ -334,7 +326,7 @@ mod tests {
334326 refs,
335327 "i BIND_PAT FileId(1) [12; 13)" ,
336328 ReferenceKind :: Other ,
337- & [ "FileId(1) [38; 39) Other" ] ,
329+ & [ "FileId(1) [38; 39) Other Read " ] ,
338330 ) ;
339331 }
340332
@@ -350,7 +342,7 @@ mod tests {
350342 refs,
351343 "i BIND_PAT FileId(1) [12; 13)" ,
352344 ReferenceKind :: Other ,
353- & [ "FileId(1) [38; 39) Other" ] ,
345+ & [ "FileId(1) [38; 39) Other Read " ] ,
354346 ) ;
355347 }
356348
@@ -372,7 +364,7 @@ mod tests {
372364 refs,
373365 "spam RECORD_FIELD_DEF FileId(1) [66; 79) [70; 74)" ,
374366 ReferenceKind :: Other ,
375- & [ "FileId(1) [152; 156) Other" ] ,
367+ & [ "FileId(1) [152; 156) Other Read " ] ,
376368 ) ;
377369 }
378370
@@ -577,9 +569,12 @@ mod tests {
577569 }"# ;
578570
579571 let refs = get_all_refs ( code) ;
580- assert_eq ! ( refs. len( ) , 3 ) ;
581- assert_eq ! ( refs. references[ 0 ] . access, Some ( ReferenceAccess :: Write ) ) ;
582- assert_eq ! ( refs. references[ 1 ] . access, Some ( ReferenceAccess :: Read ) ) ;
572+ check_result (
573+ refs,
574+ "i BIND_PAT FileId(1) [36; 37)" ,
575+ ReferenceKind :: Other ,
576+ & [ "FileId(1) [55; 56) Other Write" , "FileId(1) [59; 60) Other Read" ] ,
577+ ) ;
583578 }
584579
585580 #[ test]
@@ -595,9 +590,12 @@ mod tests {
595590 }"# ;
596591
597592 let refs = get_all_refs ( code) ;
598- assert_eq ! ( refs. len( ) , 3 ) ;
599- //assert_eq!(refs.references[0].access, Some(ReferenceAccess::Write));
600- assert_eq ! ( refs. references[ 1 ] . access, Some ( ReferenceAccess :: Write ) ) ;
593+ check_result (
594+ refs,
595+ "f RECORD_FIELD_DEF FileId(1) [32; 38) [32; 33)" ,
596+ ReferenceKind :: Other ,
597+ & [ "FileId(1) [96; 97) Other Read" , "FileId(1) [117; 118) Other Write" ] ,
598+ ) ;
601599 }
602600
603601 fn get_all_refs ( text : & str ) -> ReferenceSearchResult {
@@ -620,7 +618,14 @@ mod tests {
620618
621619 impl Reference {
622620 fn debug_render ( & self ) -> String {
623- format ! ( "{:?} {:?} {:?}" , self . file_range. file_id, self . file_range. range, self . kind)
621+ let mut s = format ! (
622+ "{:?} {:?} {:?}" ,
623+ self . file_range. file_id, self . file_range. range, self . kind
624+ ) ;
625+ if let Some ( access) = self . access {
626+ s. push_str ( & format ! ( " {:?}" , access) ) ;
627+ }
628+ s
624629 }
625630
626631 fn assert_match ( & self , expected : & str ) {
0 commit comments