Skip to content

Commit

Permalink
refactor: Split nodes into different structs (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpedroh authored Dec 6, 2023
1 parent 2e3952a commit 4b3cff9
Show file tree
Hide file tree
Showing 10 changed files with 610 additions and 564 deletions.
52 changes: 29 additions & 23 deletions matching/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod unordered_tree_matching;

pub use matching_entry::MatchingEntry;
pub use matchings::Matchings;
use model::cst_node::Terminal;
pub use ordered_tree_matching::ordered_tree_matching;
use unordered_pair::UnorderedPair;
pub use unordered_tree_matching::unordered_tree_matching;
Expand All @@ -15,24 +16,29 @@ pub fn calculate_matchings<'a>(
right: &'a model::CSTNode,
) -> Matchings<'a> {
match (left, right) {
(model::CSTNode::NonTerminal { .. }, model::CSTNode::NonTerminal { .. }) => {
if left.are_children_unordered() && right.are_children_unordered() {
(
model::CSTNode::NonTerminal(non_terminal_left),
model::CSTNode::NonTerminal(non_terminal_right),
) => {
if non_terminal_left.are_children_unordered()
&& non_terminal_right.are_children_unordered()
{
unordered_tree_matching::unordered_tree_matching(left, right)
} else {
ordered_tree_matching::ordered_tree_matching(left, right)
}
}
(
model::CSTNode::Terminal {
model::CSTNode::Terminal(Terminal {
kind: kind_left,
value: value_left,
..
},
model::CSTNode::Terminal {
}),
model::CSTNode::Terminal(Terminal {
kind: kind_right,
value: value_right,
..
},
}),
) => {
let is_perfetch_match = kind_left == kind_right && value_left == value_right;
Matchings::from_single(
Expand All @@ -46,24 +52,24 @@ pub fn calculate_matchings<'a>(

#[cfg(test)]
mod tests {
use model::{CSTNode, Point};
use model::{cst_node::Terminal, CSTNode, Point};

use crate::{calculate_matchings, MatchingEntry};

#[test]
fn two_terminal_nodes_matches_with_a_score_of_one_if_they_have_the_same_kind_and_value() {
let left = CSTNode::Terminal {
let left = CSTNode::Terminal(Terminal {
kind: "kind",
value: "value",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 5 },
};
let right = CSTNode::Terminal {
});
let right = CSTNode::Terminal(Terminal {
kind: "kind",
value: "value",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 5 },
};
});

let matchings = calculate_matchings(&left, &right);

Expand All @@ -75,18 +81,18 @@ mod tests {

#[test]
fn two_terminal_nodes_have_a_match_with_score_zero_if_they_have_different_value() {
let left = CSTNode::Terminal {
let left = CSTNode::Terminal(Terminal {
kind: "kind",
value: "value_a",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
};
let right = CSTNode::Terminal {
});
let right = CSTNode::Terminal(Terminal {
kind: "kind",
value: "value_b",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
};
});

let matchings = calculate_matchings(&left, &right);

Expand All @@ -98,18 +104,18 @@ mod tests {

#[test]
fn two_terminal_nodes_have_a_match_with_score_zero_if_they_have_different_kind() {
let left = CSTNode::Terminal {
let left = CSTNode::Terminal(Terminal {
kind: "kind_a",
value: "value",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 5 },
};
let right = CSTNode::Terminal {
});
let right = CSTNode::Terminal(Terminal {
kind: "kind_b",
value: "value",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 5 },
};
});

let matchings = calculate_matchings(&left, &right);

Expand All @@ -121,18 +127,18 @@ mod tests {

#[test]
fn two_terminal_nodes_have_a_match_with_score_zero_if_they_have_different_kind_and_value() {
let left = CSTNode::Terminal {
let left = CSTNode::Terminal(Terminal {
kind: "kind_a",
value: "value_a",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
};
let right = CSTNode::Terminal {
});
let right = CSTNode::Terminal(Terminal {
kind: "kind_b",
value: "value_a",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
};
});

let matchings = calculate_matchings(&left, &right);

Expand Down
10 changes: 5 additions & 5 deletions matching/src/matchings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,30 +82,30 @@ impl<'a> IntoIterator for Matchings<'a> {

#[cfg(test)]
mod tests {
use model::Point;
use model::{cst_node::Terminal, Point};

use super::*;

#[test]
fn returns_none_if_a_matching_for_the_node_is_not_found() {
let a_node = CSTNode::Terminal {
let a_node = CSTNode::Terminal(Terminal {
kind: "kind",
value: "value",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 5 },
};
});

assert_eq!(None, Matchings::empty().find_matching_for(&a_node))
}

#[test]
fn returns_some_match_if_a_matching_for_the_node_is_found() {
let a_node = CSTNode::Terminal {
let a_node = CSTNode::Terminal(Terminal {
kind: "kind",
value: "value",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 5 },
};
});

let mut matchings = HashMap::new();
matchings.insert(UnorderedPair(&a_node, &a_node), MatchingEntry::new(1, true));
Expand Down
87 changes: 45 additions & 42 deletions matching/src/ordered_tree_matching.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{calculate_matchings, matching_entry::MatchingEntry, Matchings};
use model::CSTNode;
use model::{cst_node::NonTerminal, CSTNode};
use unordered_pair::UnorderedPair;

#[derive(PartialEq, Eq, Debug, Clone)]
Expand All @@ -21,16 +21,16 @@ impl<'a> Default for Entry<'a> {
pub fn ordered_tree_matching<'a>(left: &'a CSTNode, right: &'a CSTNode) -> Matchings<'a> {
match (left, right) {
(
CSTNode::NonTerminal {
CSTNode::NonTerminal(NonTerminal {
kind: kind_left,
children: children_left,
..
},
CSTNode::NonTerminal {
}),
CSTNode::NonTerminal(NonTerminal {
kind: kind_right,
children: children_right,
..
},
}),
) => {
let root_matching: usize = (kind_left == kind_right).into();

Expand Down Expand Up @@ -99,28 +99,31 @@ pub fn ordered_tree_matching<'a>(left: &'a CSTNode, right: &'a CSTNode) -> Match
#[cfg(test)]
mod tests {
use crate::{matching_entry::MatchingEntry, *};
use model::{CSTNode, Point};
use model::{
cst_node::{NonTerminal, Terminal},
CSTNode, Point,
};

#[test]
fn it_matches_deep_nodes_as_well() {
let child = CSTNode::Terminal {
let child = CSTNode::Terminal(Terminal {
kind: "kind_b",
value: "value_b",
start_position: Point { row: 1, column: 0 },
end_position: Point { row: 1, column: 7 },
};
let left = CSTNode::NonTerminal {
});
let left = CSTNode::NonTerminal(NonTerminal {
kind: "kind_a",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 1, column: 7 },
children: vec![child.clone()],
};
let right = CSTNode::NonTerminal {
});
let right = CSTNode::NonTerminal(NonTerminal {
kind: "kind_a",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 1, column: 7 },
children: vec![child.clone()],
};
});

let matchings = ordered_tree_matching(&left, &right);

Expand All @@ -132,31 +135,31 @@ mod tests {

#[test]
fn if_no_match_is_found_it_returns_none() {
let left_child = CSTNode::Terminal {
let left_child = CSTNode::Terminal(Terminal {
kind: "kind_b",
value: "value_b",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
};
let right_child = CSTNode::Terminal {
});
let right_child = CSTNode::Terminal(Terminal {
kind: "kind_c",
value: "value_c",
start_position: Point { row: 1, column: 0 },
end_position: Point { row: 1, column: 7 },
};
});

let left = CSTNode::NonTerminal {
let left = CSTNode::NonTerminal(NonTerminal {
kind: "kind_a",
children: vec![left_child.clone()],
start_position: Point { row: 1, column: 0 },
end_position: Point { row: 0, column: 7 },
};
let right = CSTNode::NonTerminal {
});
let right = CSTNode::NonTerminal(NonTerminal {
kind: "kind_a",
children: vec![right_child.clone()],
start_position: Point { row: 1, column: 0 },
end_position: Point { row: 0, column: 7 },
};
});

let matchings = ordered_tree_matching(&left, &right);

Expand All @@ -168,31 +171,31 @@ mod tests {

#[test]
fn the_matching_between_two_subtrees_is_the_sum_of_the_matchings_plus_the_root() {
let common_child = CSTNode::Terminal {
let common_child = CSTNode::Terminal(Terminal {
kind: "kind_b",
value: "value_b",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
};
let unique_right_child = CSTNode::Terminal {
});
let unique_right_child = CSTNode::Terminal(Terminal {
kind: "kind_c",
value: "value_c",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
};
});

let left = CSTNode::NonTerminal {
let left = CSTNode::NonTerminal(NonTerminal {
kind: "kind_a",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
children: vec![common_child.clone()],
};
let right = CSTNode::NonTerminal {
});
let right = CSTNode::NonTerminal(NonTerminal {
kind: "kind_a",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
children: vec![common_child.clone(), unique_right_child],
};
});

let matchings = ordered_tree_matching(&left, &right);

Expand All @@ -204,25 +207,25 @@ mod tests {

#[test]
fn perfect_matching_deep_nodes() {
let common_child = CSTNode::Terminal {
let common_child = CSTNode::Terminal(Terminal {
kind: "kind_b",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
value: "value_b",
};
});

let left = CSTNode::NonTerminal {
let left = CSTNode::NonTerminal(NonTerminal {
kind: "kind_a",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
children: vec![common_child.clone()],
};
let right = CSTNode::NonTerminal {
});
let right = CSTNode::NonTerminal(NonTerminal {
kind: "kind_a",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
children: vec![common_child.clone()],
};
});

let matchings = ordered_tree_matching(&left, &right);

Expand All @@ -234,32 +237,32 @@ mod tests {

#[test]
fn perfect_matching_deeper_nodes() {
let leaf = CSTNode::Terminal {
let leaf = CSTNode::Terminal(Terminal {
kind: "kind_b",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
value: "value_b",
};
});

let intermediate = CSTNode::NonTerminal {
let intermediate = CSTNode::NonTerminal(NonTerminal {
kind: "intermediate",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
children: vec![leaf],
};
});

let left = CSTNode::NonTerminal {
let left = CSTNode::NonTerminal(NonTerminal {
kind: "kind_a",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
children: vec![intermediate.clone()],
};
let right = CSTNode::NonTerminal {
});
let right = CSTNode::NonTerminal(NonTerminal {
kind: "kind_a",
start_position: Point { row: 0, column: 0 },
end_position: Point { row: 0, column: 7 },
children: vec![intermediate.clone()],
};
});

let matchings = ordered_tree_matching(&left, &right);

Expand Down
Loading

0 comments on commit 4b3cff9

Please sign in to comment.