From 6c89d86ade392ddd4088ecdb444ea7bd002a3cff Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Sat, 4 Jan 2020 19:25:29 -0500 Subject: Tweaks --- crates/ra_ide/src/references.rs | 48 ++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 13 deletions(-) (limited to 'crates/ra_ide/src') 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 { - match expr.op_kind() { - Some(kind) if kind.is_assignment() => { - if let Some(lhs) = expr.lhs() { - if lhs.syntax().text_range() == name_ref.syntax().text_range() { - return Some(ReferenceAccess::Write); - } + if expr.op_kind()?.is_assignment() { + // If the variable or field ends on the LHS's end then it's a Write (covers fields and locals). + // FIXME: This is not terribly accurate. + if let Some(lhs) = expr.lhs() { + if lhs.syntax().text_range().end() == name_ref.syntax().text_range().end() { + return Some(ReferenceAccess::Write); + } else if name_ref.syntax().text_range().is_subrange(&lhs.syntax().text_range()) { + return Some(ReferenceAccess::Read); } + } - if let Some(rhs) = expr.rhs() { - if rhs.syntax().text_range().is_subrange(&name_ref.syntax().text_range()) { - return Some(ReferenceAccess::Read); - } + // If the variable is on the RHS then it's a Read. + if let Some(rhs) = expr.rhs() { + if name_ref.syntax().text_range().is_subrange(&rhs.syntax().text_range()) { + return Some(ReferenceAccess::Read); } - }, - _ => { return Some(ReferenceAccess::Read) }, + } } + + // Cannot determine access None }, _ => {None} @@ -565,7 +569,7 @@ mod tests { } #[test] - fn test_basic_highlight_read() { + fn test_basic_highlight_read_write() { let code = r#" fn foo() { let i<|> = 0; @@ -578,6 +582,24 @@ mod tests { assert_eq!(refs.references[1].access, Some(ReferenceAccess::Read)); } + #[test] + fn test_basic_highlight_field_read_write() { + let code = r#" + struct S { + f: u32, + } + + fn foo() { + let mut s = S{f: 0}; + s.f<|> = 0; + }"#; + + let refs = get_all_refs(code); + assert_eq!(refs.len(), 3); + //assert_eq!(refs.references[0].access, Some(ReferenceAccess::Write)); + assert_eq!(refs.references[1].access, Some(ReferenceAccess::Write)); + } + fn get_all_refs(text: &str) -> ReferenceSearchResult { let (analysis, position) = single_file_with_position(text); analysis.find_all_refs(position, None).unwrap().unwrap() -- cgit v1.2.3