diff options
Diffstat (limited to 'crates/ra_ide')
-rw-r--r-- | crates/ra_ide/src/references.rs | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs index b9d8a6b1e..7d31ef6bd 100644 --- a/crates/ra_ide/src/references.rs +++ b/crates/ra_ide/src/references.rs | |||
@@ -232,22 +232,26 @@ fn access_mode(kind: NameKind, name_ref: &ast::NameRef) -> Option<ReferenceAcces | |||
232 | match_ast! { | 232 | match_ast! { |
233 | match (node) { | 233 | match (node) { |
234 | ast::BinExpr(expr) => { | 234 | ast::BinExpr(expr) => { |
235 | match expr.op_kind() { | 235 | if expr.op_kind()?.is_assignment() { |
236 | Some(kind) if 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 | if let Some(lhs) = expr.lhs() { | 237 | // FIXME: This is not terribly accurate. |
238 | if lhs.syntax().text_range() == name_ref.syntax().text_range() { | 238 | if let Some(lhs) = expr.lhs() { |
239 | return Some(ReferenceAccess::Write); | 239 | if lhs.syntax().text_range().end() == name_ref.syntax().text_range().end() { |
240 | } | 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() { | 246 | // If the variable is on the RHS then it's a Read. |
244 | if rhs.syntax().text_range().is_subrange(&name_ref.syntax().text_range()) { | 247 | if let Some(rhs) = expr.rhs() { |
245 | return Some(ReferenceAccess::Read); | 248 | if name_ref.syntax().text_range().is_subrange(&rhs.syntax().text_range()) { |
246 | } | 249 | return Some(ReferenceAccess::Read); |
247 | } | 250 | } |
248 | }, | 251 | } |
249 | _ => { return Some(ReferenceAccess::Read) }, | ||
250 | } | 252 | } |
253 | |||
254 | // Cannot determine access | ||
251 | None | 255 | None |
252 | }, | 256 | }, |
253 | _ => {None} | 257 | _ => {None} |
@@ -565,7 +569,7 @@ mod tests { | |||
565 | } | 569 | } |
566 | 570 | ||
567 | #[test] | 571 | #[test] |
568 | fn test_basic_highlight_read() { | 572 | fn test_basic_highlight_read_write() { |
569 | let code = r#" | 573 | let code = r#" |
570 | fn foo() { | 574 | fn foo() { |
571 | let i<|> = 0; | 575 | let i<|> = 0; |
@@ -578,6 +582,24 @@ mod tests { | |||
578 | assert_eq!(refs.references[1].access, Some(ReferenceAccess::Read)); | 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 | fn get_all_refs(text: &str) -> ReferenceSearchResult { | 603 | fn get_all_refs(text: &str) -> ReferenceSearchResult { |
582 | let (analysis, position) = single_file_with_position(text); | 604 | let (analysis, position) = single_file_with_position(text); |
583 | analysis.find_all_refs(position, None).unwrap().unwrap() | 605 | analysis.find_all_refs(position, None).unwrap().unwrap() |