Skip to content

Commit

Permalink
add a check for variable names that might match by word
Browse files Browse the repository at this point in the history
  • Loading branch information
cjkenn committed Jan 3, 2020
1 parent 0ec3706 commit 91334e0
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
33 changes: 28 additions & 5 deletions src/libsyntax/util/lev_distance.rs
Expand Up @@ -52,14 +52,15 @@ where
T: Iterator<Item = &'a Symbol>,
{
let max_dist = dist.map_or_else(|| cmp::max(lookup.len(), 3) / 3, |d| d);
let name_vec: Vec<&Symbol> = iter_names.collect();

let (case_insensitive_match, levenstein_match) = iter_names
let (case_insensitive_match, levenshtein_match) = name_vec.iter()
.filter_map(|&name| {
let dist = lev_distance(lookup, &name.as_str());
if dist <= max_dist { Some((name, dist)) } else { None }
})
// Here we are collecting the next structure:
// (case_insensitive_match, (levenstein_match, levenstein_distance))
// (case_insensitive_match, (levenshtein_match, levenshtein_distance))
.fold((None, None), |result, (candidate, dist)| {
(
if candidate.as_str().to_uppercase() == lookup.to_uppercase() {
Expand All @@ -73,10 +74,32 @@ where
},
)
});


// Priority of matches:
// 1. Exact case insensitive match
// 2. Levenshtein distance match
// 3. Sorted word match
if let Some(candidate) = case_insensitive_match {
Some(candidate) // exact case insensitive match has a higher priority
Some(*candidate)
} else if levenshtein_match.is_some() {
levenshtein_match.map(|(candidate, _)| *candidate)
} else {
levenstein_match.map(|(candidate, _)| candidate)
find_match_by_sorted_words(name_vec, lookup)
}
}

fn find_match_by_sorted_words<'a>(iter_names: Vec<&'a Symbol>, lookup: &str) -> Option<Symbol> {
iter_names.iter().fold(None, |result, candidate| {
if sort_by_words(&candidate.as_str()) == sort_by_words(lookup) {
Some(**candidate)
} else {
result
}
})
}

fn sort_by_words(name: &str) -> String {
let mut split_words: Vec<&str> = name.split('_').collect();
split_words.sort();
split_words.join("_")
}
6 changes: 6 additions & 0 deletions src/libsyntax/util/lev_distance/tests.rs
Expand Up @@ -46,5 +46,11 @@ fn test_find_best_match_for_name() {
find_best_match_for_name(input.iter(), "aaaa", Some(4)),
Some(Symbol::intern("AAAA"))
);

let input = vec![Symbol::intern("a_longer_variable_name")];
assert_eq!(
find_best_match_for_name(input.iter(), "a_variable_longer_name", None),
Some(Symbol::intern("a_longer_variable_name"))
);
})
}

0 comments on commit 91334e0

Please sign in to comment.