diff --git a/matching/src/lib.rs b/matching/src/lib.rs index bda7aa1..4cb4f26 100644 --- a/matching/src/lib.rs +++ b/matching/src/lib.rs @@ -47,10 +47,10 @@ pub fn calculate_matchings<'a>( let is_perfect_match = kind_left == kind_right && value_left == value_right; Matchings::from_single( UnorderedPair(left, right), - MatchingEntry::new(is_perfect_match.into(), is_perfect_match), + MatchingEntry::new(left, right, is_perfect_match.into()), ) } - (_, _) => Matchings::from_single(UnorderedPair(left, right), MatchingEntry::new(0, false)), + (_, _) => Matchings::empty(), } } @@ -85,7 +85,7 @@ mod tests { let matchings = calculate_matchings(&left, &right, &matching_configuration); assert_eq!( - Some(&MatchingEntry::new(1, true)), + Some(&MatchingEntry::new(&left, &right, 1)), matchings.get_matching_entry(&left, &right) ) } @@ -112,9 +112,8 @@ mod tests { let matching_configuration = MatchingConfiguration::default(); let matchings = calculate_matchings(&left, &right, &matching_configuration); - assert_eq!( - Some(&MatchingEntry::new(0, false)), - matchings.get_matching_entry(&left, &right) - ) + let left_right_matching = matchings.get_matching_entry(&left, &right).unwrap(); + assert_eq!(0, left_right_matching.score); + assert!(!left_right_matching.is_perfect_match); } } diff --git a/matching/src/matching_entry.rs b/matching/src/matching_entry.rs index a2757e8..1f06b34 100644 --- a/matching/src/matching_entry.rs +++ b/matching/src/matching_entry.rs @@ -1,3 +1,5 @@ +use model::CSTNode; + #[derive(Clone, Debug, PartialEq, Eq)] pub struct MatchingEntry { pub score: usize, @@ -5,10 +7,10 @@ pub struct MatchingEntry { } impl MatchingEntry { - pub fn new(score: usize, is_perfect_match: bool) -> Self { + pub fn new(left: &CSTNode, right: &CSTNode, score: usize) -> Self { MatchingEntry { score, - is_perfect_match, + is_perfect_match: (2 * score) == (left.get_tree_size() + right.get_tree_size()), } } } diff --git a/matching/src/matchings.rs b/matching/src/matchings.rs index 2435fc0..e100740 100644 --- a/matching/src/matchings.rs +++ b/matching/src/matchings.rs @@ -118,7 +118,10 @@ mod tests { }); let mut matchings = HashMap::new(); - matchings.insert(UnorderedPair(&a_node, &a_node), MatchingEntry::new(1, true)); + matchings.insert( + UnorderedPair(&a_node, &a_node), + MatchingEntry::new(&a_node, &a_node, 1), + ); assert_eq!( Some(Matching { diff --git a/matching/src/ordered/mod.rs b/matching/src/ordered/mod.rs index b4b8810..cbe27bf 100644 --- a/matching/src/ordered/mod.rs +++ b/matching/src/ordered/mod.rs @@ -80,10 +80,7 @@ pub fn calculate_matchings<'a>( let mut matchings = Matchings::from_single( UnorderedPair(left, right), - MatchingEntry::new( - matrix_m[m][n] + root_matching, - left.contents() == right.contents(), - ), + MatchingEntry::new(left, right, matrix_m[m][n] + root_matching), ); while i >= 1 && j >= 1 { @@ -108,7 +105,7 @@ pub fn calculate_matchings<'a>( #[cfg(test)] mod tests { - use crate::{matching_entry::MatchingEntry, *}; + use crate::MatchingConfiguration; use model::{ cst_node::{NonTerminal, Terminal}, language, CSTNode, Language, Point, @@ -144,10 +141,10 @@ mod tests { let matching_configuration = MatchingConfiguration::default(); let matchings = super::calculate_matchings(&left, &right, &matching_configuration); - assert_eq!( - Some(&MatchingEntry::new(1, true)), - matchings.get_matching_entry(&child, &child) - ) + let child_matching = matchings.get_matching_entry(&child, &child); + assert!(child_matching.is_some()); + assert_eq!(1, child_matching.unwrap().score); + assert!(child_matching.unwrap().is_perfect_match) } #[test] @@ -188,11 +185,9 @@ mod tests { let matching_configuration = MatchingConfiguration::from(Language::Java); let matchings = super::calculate_matchings(&left, &right, &matching_configuration); - - assert_eq!( - None, - matchings.get_matching_entry(&left_child, &right_child) - ) + assert!(matchings + .get_matching_entry(&left_child, &right_child) + .is_none()) } #[test] @@ -234,10 +229,9 @@ mod tests { let matching_configuration = MatchingConfiguration::from(language::Language::Java); let matchings = super::calculate_matchings(&left, &right, &matching_configuration); - assert_eq!( - Some(&MatchingEntry::new(2, false)), - matchings.get_matching_entry(&left, &right) - ) + let left_right_matchings = matchings.get_matching_entry(&left, &right).unwrap(); + assert_eq!(2, left_right_matchings.score); + assert!(!left_right_matchings.is_perfect_match); } #[test] @@ -271,10 +265,9 @@ mod tests { let matching_configuration = MatchingConfiguration::from(language::Language::Java); let matchings = super::calculate_matchings(&left, &right, &matching_configuration); - assert_eq!( - Some(&MatchingEntry::new(2, true)), - matchings.get_matching_entry(&left, &right) - ) + let left_right_matchings = matchings.get_matching_entry(&left, &right).unwrap(); + assert_eq!(2, left_right_matchings.score); + assert!(left_right_matchings.is_perfect_match); } #[test] @@ -317,14 +310,14 @@ mod tests { let matching_configuration = MatchingConfiguration::default(); let matchings = super::calculate_matchings(&left, &right, &matching_configuration); - assert_eq!( - Some(&MatchingEntry::new(2, true)), - matchings.get_matching_entry(&intermediate, &intermediate) - ); + let intermediate_matching = matchings + .get_matching_entry(&intermediate, &intermediate) + .unwrap(); + assert_eq!(2, intermediate_matching.score); + assert!(intermediate_matching.is_perfect_match); - assert_eq!( - Some(&MatchingEntry::new(3, true)), - matchings.get_matching_entry(&left, &right) - ) + let left_right_matching = matchings.get_matching_entry(&left, &right).unwrap(); + assert_eq!(3, left_right_matching.score); + assert!(left_right_matching.is_perfect_match); } } diff --git a/matching/src/unordered/assignment_problem.rs b/matching/src/unordered/assignment_problem.rs index bba1ec0..eb0d973 100644 --- a/matching/src/unordered/assignment_problem.rs +++ b/matching/src/unordered/assignment_problem.rs @@ -84,10 +84,7 @@ fn solve_assignment_problem<'a>( result.extend(Matchings::from_single( UnorderedPair(left, right), - MatchingEntry { - score: max_matching as usize + 1, - is_perfect_match: left.contents() == right.contents(), - }, + MatchingEntry::new(left, right, max_matching as usize + 1), )); result diff --git a/matching/src/unordered/unique_label.rs b/matching/src/unordered/unique_label.rs index cafc136..5c961f8 100644 --- a/matching/src/unordered/unique_label.rs +++ b/matching/src/unordered/unique_label.rs @@ -51,10 +51,7 @@ pub fn calculate_matchings<'a>( result.extend(Matchings::from_single( UnorderedPair(left, right), - MatchingEntry { - score: sum + root_matching, - is_perfect_match: left.contents() == right.contents(), - }, + MatchingEntry::new(left, right, sum + root_matching), )); result diff --git a/model/src/cst_node.rs b/model/src/cst_node.rs index e8c99f5..26e63ae 100644 --- a/model/src/cst_node.rs +++ b/model/src/cst_node.rs @@ -48,6 +48,22 @@ impl CSTNode<'_> { CSTNode::NonTerminal(node) => node.end_position, } } + + fn get_subtree_size(&self) -> usize { + match self { + CSTNode::Terminal(_) => 0, + CSTNode::NonTerminal(node) => node + .children + .iter() + .fold(node.children.len(), |acc, child| { + acc + child.get_subtree_size() + }), + } + } + + pub fn get_tree_size(&self) -> usize { + return self.get_subtree_size() + 1; + } } #[derive(Debug, Default, Clone)]