@@ -232,22 +232,26 @@ fn access_mode(kind: NameKind, name_ref: &ast::NameRef) -> Option<ReferenceAcces
232232 match_ast ! {
233233 match ( node) {
234234 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 ) ;
241243 }
244+ }
242245
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 ) ;
247250 }
248- } ,
249- _ => { return Some ( ReferenceAccess :: Read ) } ,
251+ }
250252 }
253+
254+ // Cannot determine access
251255 None
252256 } ,
253257 _ => { None }
@@ -565,7 +569,7 @@ mod tests {
565569 }
566570
567571 #[ test]
568- fn test_basic_highlight_read ( ) {
572+ fn test_basic_highlight_read_write ( ) {
569573 let code = r#"
570574 fn foo() {
571575 let i<|> = 0;
@@ -578,6 +582,24 @@ mod tests {
578582 assert_eq ! ( refs. references[ 1 ] . access, Some ( ReferenceAccess :: Read ) ) ;
579583 }
580584
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+
581603 fn get_all_refs ( text : & str ) -> ReferenceSearchResult {
582604 let ( analysis, position) = single_file_with_position ( text) ;
583605 analysis. find_all_refs ( position, None ) . unwrap ( ) . unwrap ( )
0 commit comments