aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide')
-rw-r--r--crates/ra_ide/src/references.rs48
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()