From eaf9e87a15f01b34fc78d25bf1bfdf77c298db10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Henrique?= Date: Mon, 11 Mar 2024 22:40:35 -0300 Subject: [PATCH] feat(matching_handlers): Add comparators for class like elements (#43) In a few cases it may be needed to calculate a matching score between the roots of different classes/interfaces. This will use the identifier to calculate the score for these type of elements and will return 0 if their identifiers do not match. --- .../src/java/class_like_declaration.rs | 61 +++++++++++++++++++ matching_handlers/src/java/mod.rs | 10 +++ 2 files changed, 71 insertions(+) create mode 100644 matching_handlers/src/java/class_like_declaration.rs diff --git a/matching_handlers/src/java/class_like_declaration.rs b/matching_handlers/src/java/class_like_declaration.rs new file mode 100644 index 0000000..37d3fc9 --- /dev/null +++ b/matching_handlers/src/java/class_like_declaration.rs @@ -0,0 +1,61 @@ +use super::utils::find_child_of_kind; +use model::{cst_node::NonTerminal, CSTNode}; + +pub fn compute_matching_score_for_class_like_declaration<'a>( + left: &'a CSTNode, + right: &'a CSTNode, +) -> usize { + match (left, right) { + ( + CSTNode::NonTerminal(NonTerminal { + children: children_left, + .. + }), + CSTNode::NonTerminal(NonTerminal { + children: children_right, + .. + }), + ) => { + let identifier_left = + find_child_of_kind(children_left, "identifier").map(|node| node.contents()); + let identifier_right = + find_child_of_kind(children_right, "identifier").map(|node| node.contents()); + + (identifier_left.is_some() && identifier_left == identifier_right).into() + } + (_, _) => 0, + } +} + +#[cfg(test)] +mod tests { + #[test] + fn classes_with_the_same_name_match_with_score_one() { + let result = super::compute_matching_score_for_class_like_declaration( + &make_class_like_declaration("ABC"), + &make_class_like_declaration("ABC"), + ); + assert_eq!(1, result); + } + + #[test] + fn classes_of_different_names_do_not_match() { + let result = super::compute_matching_score_for_class_like_declaration( + &make_class_like_declaration("ABC"), + &make_class_like_declaration("DEF"), + ); + assert_eq!(0, result); + } + + fn make_class_like_declaration(identifier: &str) -> model::CSTNode { + model::CSTNode::NonTerminal(model::cst_node::NonTerminal { + kind: "class_declaration", + children: vec![model::CSTNode::Terminal(model::cst_node::Terminal { + kind: "identifier", + value: identifier, + ..Default::default() + })], + ..Default::default() + }) + } +} diff --git a/matching_handlers/src/java/mod.rs b/matching_handlers/src/java/mod.rs index e633454..3e1f1c6 100644 --- a/matching_handlers/src/java/mod.rs +++ b/matching_handlers/src/java/mod.rs @@ -1,3 +1,4 @@ +mod class_like_declaration; mod field_declaration; mod import_declaration; mod method_declaration; @@ -6,6 +7,7 @@ mod utils; use crate::MatchingHandlers; use self::{ + class_like_declaration::compute_matching_score_for_class_like_declaration, field_declaration::compute_matching_score_for_field_declaration, import_declaration::compute_matching_score_for_import_declaration, method_declaration::compute_matching_score_for_method_declaration, @@ -29,5 +31,13 @@ pub fn get_default_java_matching_handlers<'a>() -> MatchingHandlers<'a> { "import_declaration", compute_matching_score_for_import_declaration, ); + matching_handlers.register( + "class_declaration", + compute_matching_score_for_class_like_declaration, + ); + matching_handlers.register( + "interface_declaration", + compute_matching_score_for_class_like_declaration, + ); matching_handlers }