Simplify and update tests to account for access

This commit is contained in:
kjeremy 2020-01-09 16:01:43 -05:00
parent 6c89d86ade
commit cc96ddfe69

View file

@ -55,7 +55,7 @@ pub enum ReferenceKind {
Other, Other,
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
pub enum ReferenceAccess { pub enum ReferenceAccess {
Read, Read,
Write, Write,
@ -225,10 +225,13 @@ fn process_definition(
} }
fn access_mode(kind: NameKind, name_ref: &ast::NameRef) -> Option<ReferenceAccess> { fn access_mode(kind: NameKind, name_ref: &ast::NameRef) -> Option<ReferenceAccess> {
// Only Locals and Fields have accesses for now.
match kind { match kind {
NameKind::Local(_) | NameKind::Field(_) => { NameKind::Local(_) | NameKind::Field(_) => {}
//LetExpr or BinExpr _ => return None,
name_ref.syntax().ancestors().find_map(|node| { };
let mode = name_ref.syntax().ancestors().find_map(|node| {
match_ast! { match_ast! {
match (node) { match (node) {
ast::BinExpr(expr) => { ast::BinExpr(expr) => {
@ -238,36 +241,25 @@ fn access_mode(kind: NameKind, name_ref: &ast::NameRef) -> Option<ReferenceAcces
if let Some(lhs) = expr.lhs() { if let Some(lhs) = expr.lhs() {
if lhs.syntax().text_range().end() == name_ref.syntax().text_range().end() { if lhs.syntax().text_range().end() == name_ref.syntax().text_range().end() {
return Some(ReferenceAccess::Write); return Some(ReferenceAccess::Write);
} else if name_ref.syntax().text_range().is_subrange(&lhs.syntax().text_range()) { }
}
}
return Some(ReferenceAccess::Read); 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);
}
}
}
// Cannot determine access
None
}, },
_ => {None} _ => {None}
} }
} }
}) });
}
_ => None, // Default Locals and Fields to read
} mode.or(Some(ReferenceAccess::Read))
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::{ use crate::{
mock_analysis::{analysis_and_position, single_file_with_position, MockAnalysis}, mock_analysis::{analysis_and_position, single_file_with_position, MockAnalysis},
Reference, ReferenceAccess, ReferenceKind, ReferenceSearchResult, SearchScope, Reference, ReferenceKind, ReferenceSearchResult, SearchScope,
}; };
#[test] #[test]
@ -314,10 +306,10 @@ mod tests {
"i BIND_PAT FileId(1) [33; 34)", "i BIND_PAT FileId(1) [33; 34)",
ReferenceKind::Other, ReferenceKind::Other,
&[ &[
"FileId(1) [67; 68) Other", "FileId(1) [67; 68) Other Write",
"FileId(1) [71; 72) Other", "FileId(1) [71; 72) Other Read",
"FileId(1) [101; 102) Other", "FileId(1) [101; 102) Other Write",
"FileId(1) [127; 128) Other", "FileId(1) [127; 128) Other Write",
], ],
); );
} }
@ -334,7 +326,7 @@ mod tests {
refs, refs,
"i BIND_PAT FileId(1) [12; 13)", "i BIND_PAT FileId(1) [12; 13)",
ReferenceKind::Other, ReferenceKind::Other,
&["FileId(1) [38; 39) Other"], &["FileId(1) [38; 39) Other Read"],
); );
} }
@ -350,7 +342,7 @@ mod tests {
refs, refs,
"i BIND_PAT FileId(1) [12; 13)", "i BIND_PAT FileId(1) [12; 13)",
ReferenceKind::Other, ReferenceKind::Other,
&["FileId(1) [38; 39) Other"], &["FileId(1) [38; 39) Other Read"],
); );
} }
@ -372,7 +364,7 @@ mod tests {
refs, refs,
"spam RECORD_FIELD_DEF FileId(1) [66; 79) [70; 74)", "spam RECORD_FIELD_DEF FileId(1) [66; 79) [70; 74)",
ReferenceKind::Other, ReferenceKind::Other,
&["FileId(1) [152; 156) Other"], &["FileId(1) [152; 156) Other Read"],
); );
} }
@ -577,9 +569,12 @@ mod tests {
}"#; }"#;
let refs = get_all_refs(code); let refs = get_all_refs(code);
assert_eq!(refs.len(), 3); check_result(
assert_eq!(refs.references[0].access, Some(ReferenceAccess::Write)); refs,
assert_eq!(refs.references[1].access, Some(ReferenceAccess::Read)); "i BIND_PAT FileId(1) [36; 37)",
ReferenceKind::Other,
&["FileId(1) [55; 56) Other Write", "FileId(1) [59; 60) Other Read"],
);
} }
#[test] #[test]
@ -595,9 +590,12 @@ mod tests {
}"#; }"#;
let refs = get_all_refs(code); let refs = get_all_refs(code);
assert_eq!(refs.len(), 3); check_result(
//assert_eq!(refs.references[0].access, Some(ReferenceAccess::Write)); refs,
assert_eq!(refs.references[1].access, Some(ReferenceAccess::Write)); "f RECORD_FIELD_DEF FileId(1) [32; 38) [32; 33)",
ReferenceKind::Other,
&["FileId(1) [96; 97) Other Read", "FileId(1) [117; 118) Other Write"],
);
} }
fn get_all_refs(text: &str) -> ReferenceSearchResult { fn get_all_refs(text: &str) -> ReferenceSearchResult {
@ -620,7 +618,14 @@ mod tests {
impl Reference { impl Reference {
fn debug_render(&self) -> String { fn debug_render(&self) -> String {
format!("{:?} {:?} {:?}", self.file_range.file_id, self.file_range.range, self.kind) let mut s = format!(
"{:?} {:?} {:?}",
self.file_range.file_id, self.file_range.range, self.kind
);
if let Some(access) = self.access {
s.push_str(&format!(" {:?}", access));
}
s
} }
fn assert_match(&self, expected: &str) { fn assert_match(&self, expected: &str) {