@@ -232,22 +232,26 @@ fn access_mode(kind: NameKind, name_ref: &ast::NameRef) -> Option<ReferenceAcces
232
232
match_ast ! {
233
233
match ( node) {
234
234
ast:: BinExpr ( expr) => {
235
- match expr. op_kind( ) {
236
- Some ( kind) if kind. is_assignment( ) => {
237
- if let Some ( lhs) = expr. lhs( ) {
238
- if lhs. syntax( ) . text_range( ) == name_ref. syntax( ) . text_range( ) {
239
- return Some ( ReferenceAccess :: Write ) ;
240
- }
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 ) ;
241
243
}
244
+ }
242
245
243
- if let Some ( rhs ) = expr . rhs ( ) {
244
- if rhs . syntax ( ) . text_range ( ) . is_subrange ( & name_ref . syntax ( ) . text_range ( ) ) {
245
- return Some ( ReferenceAccess :: Read ) ;
246
- }
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 ) ;
247
250
}
248
- } ,
249
- _ => { return Some ( ReferenceAccess :: Read ) } ,
251
+ }
250
252
}
253
+
254
+ // Cannot determine access
251
255
None
252
256
} ,
253
257
_ => { None }
@@ -565,7 +569,7 @@ mod tests {
565
569
}
566
570
567
571
#[ test]
568
- fn test_basic_highlight_read ( ) {
572
+ fn test_basic_highlight_read_write ( ) {
569
573
let code = r#"
570
574
fn foo() {
571
575
let i<|> = 0;
@@ -578,6 +582,24 @@ mod tests {
578
582
assert_eq ! ( refs. references[ 1 ] . access, Some ( ReferenceAccess :: Read ) ) ;
579
583
}
580
584
585
+ #[ test]
586
+ fn test_basic_highlight_field_read_write ( ) {
587
+ let code = r#"
588
+ struct S {
589
+ f: u32,
590
+ }
591
+
592
+ fn foo() {
593
+ let mut s = S{f: 0};
594
+ s.f<|> = 0;
595
+ }"# ;
596
+
597
+ 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 ) ) ;
601
+ }
602
+
581
603
fn get_all_refs ( text : & str ) -> ReferenceSearchResult {
582
604
let ( analysis, position) = single_file_with_position ( text) ;
583
605
analysis. find_all_refs ( position, None ) . unwrap ( ) . unwrap ( )
0 commit comments