Skip to content

Commit

Permalink
feat: Add initial API for customize matching behavior (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
jpedroh authored Jan 5, 2024
1 parent c3c68f1 commit 1fcf6d6
Show file tree
Hide file tree
Showing 21 changed files with 286 additions and 193 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
members = [
"bin",
"matching",
"matching_handlers",
"merge",
"parsing",
"model"
Expand Down
1 change: 1 addition & 0 deletions bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ merge = { path = "../merge" }
model = { path = "../model" }
parsing = { path = "../parsing" }
matching = { path = "../matching" }
matching_handlers = { path = "../matching_handlers" }
assert_cmd = "2.0.12"
clap = { version = "4.4.8", features = ["derive"] }

Expand Down
10 changes: 7 additions & 3 deletions bin/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,13 @@ pub fn run_tool_on_merge_scenario(
let right_tree = parsing::parse_string(right, &parser_configuration)
.map_err(ExecutionError::ParsingError)?;

let matchings_left_base = matching::calculate_matchings(&left_tree, &base_tree);
let matchings_right_base = matching::calculate_matchings(&right_tree, &base_tree);
let matchings_left_right = matching::calculate_matchings(&left_tree, &right_tree);
let matching_handlers = matching_handlers::MatchingHandlers::from(language);
let matchings_left_base =
matching::calculate_matchings(&left_tree, &base_tree, &matching_handlers);
let matchings_right_base =
matching::calculate_matchings(&right_tree, &base_tree, &matching_handlers);
let matchings_left_right =
matching::calculate_matchings(&left_tree, &right_tree, &matching_handlers);

let result = merge::merge(
&base_tree,
Expand Down
7 changes: 7 additions & 0 deletions bin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ use clap::Parser;
fn main() {
let args = cli_args::CliArgs::parse();

// let args = cli_args::CliArgs {
// base_path: "/Users/jpedroh/Projetos/jFSTMerge/testfiles/shelltests/big/base/src/main/java/com/pa/util/EnumPublicationLocalType.java".into(),
// left_path: "/Users/jpedroh/Projetos/jFSTMerge/testfiles/shelltests/big/left/src/main/java/com/pa/util/EnumPublicationLocalType.java".into(),
// right_path: "/Users/jpedroh/Projetos/jFSTMerge/testfiles/shelltests/big/right/src/main/java/com/pa/util/EnumPublicationLocalType.java".into(),
// merge_path: "EnumPublicationLocalType.java".into()
// };

let base = std::fs::read_to_string(&args.base_path).unwrap_or_else(|error| {
println!("Error reading file: {}", error);
std::process::exit(cli_exit_codes::READING_FILE_ERROR)
Expand Down
10 changes: 8 additions & 2 deletions bin/tests/scenarios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@ fn all_java_samples_work_correctly() -> Result<(), Box<dyn std::error::Error>> {
let right = std::fs::read_to_string(format!("{}/right.java", sample_path.display()))?;

let expected = std::fs::read_to_string(format!("{}/merge.java", sample_path.display()))?;
let result = bin::run_tool_on_merge_scenario(model::Language::Java, &base, &left, &right)?;
let result = bin::run_tool_on_merge_scenario(model::Language::Java, &base, &left, &right)
.unwrap_or_else(|_| panic!("Failed on {}", sample_path.display()));

assert_eq!(expected, result.to_string())
assert_eq!(
expected,
result.to_string(),
"Failed on {}",
sample_path.display()
);
}

Ok(())
Expand Down
1 change: 1 addition & 0 deletions matching/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ edition = "2021"

[dependencies]
model = { path = "../model" }
matching_handlers = { path = "../matching_handlers" }
unordered-pair = "0.2.4"
21 changes: 14 additions & 7 deletions matching/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod ordered_tree_matching;
mod unordered_tree_matching;

pub use matching_entry::MatchingEntry;
use matching_handlers::MatchingHandlers;
pub use matchings::Matchings;
use model::cst_node::Terminal;
pub use ordered_tree_matching::ordered_tree_matching;
Expand All @@ -14,6 +15,7 @@ pub use unordered_tree_matching::unordered_tree_matching;
pub fn calculate_matchings<'a>(
left: &'a model::CSTNode,
right: &'a model::CSTNode,
matching_handlers: &'a MatchingHandlers<'a>,
) -> Matchings<'a> {
match (left, right) {
(
Expand All @@ -22,9 +24,9 @@ pub fn calculate_matchings<'a>(
) => {
if non_terminal_left.are_children_unordered && non_terminal_right.are_children_unordered
{
unordered_tree_matching::unordered_tree_matching(left, right)
unordered_tree_matching::unordered_tree_matching(left, right, matching_handlers)
} else {
ordered_tree_matching::ordered_tree_matching(left, right)
ordered_tree_matching::ordered_tree_matching(left, right, matching_handlers)
}
}
(
Expand All @@ -51,7 +53,8 @@ pub fn calculate_matchings<'a>(

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

use crate::{calculate_matchings, MatchingEntry};

Expand All @@ -72,7 +75,8 @@ mod tests {
is_block_end_delimiter: false,
});

let matchings = calculate_matchings(&left, &right);
let binding = MatchingHandlers::from(Language::Java);
let matchings = calculate_matchings(&left, &right, &binding);

assert_eq!(
Some(&MatchingEntry::new(1, true)),
Expand All @@ -97,7 +101,8 @@ mod tests {
is_block_end_delimiter: false,
});

let matchings = calculate_matchings(&left, &right);
let binding = MatchingHandlers::from(Language::Java);
let matchings = calculate_matchings(&left, &right, &binding);

assert_eq!(
Some(&MatchingEntry::new(0, false)),
Expand All @@ -122,7 +127,8 @@ mod tests {
is_block_end_delimiter: false,
});

let matchings = calculate_matchings(&left, &right);
let binding = MatchingHandlers::from(Language::Java);
let matchings = calculate_matchings(&left, &right, &binding);

assert_eq!(
Some(&MatchingEntry::new(0, false)),
Expand All @@ -147,7 +153,8 @@ mod tests {
is_block_end_delimiter: false,
});

let matchings = calculate_matchings(&left, &right);
let binding = MatchingHandlers::from(Language::Java);
let matchings = calculate_matchings(&left, &right, &binding);

assert_eq!(
Some(&MatchingEntry::new(0, false)),
Expand Down
32 changes: 22 additions & 10 deletions matching/src/ordered_tree_matching.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{calculate_matchings, matching_entry::MatchingEntry, Matchings};
use crate::{calculate_matchings, matching_entry::MatchingEntry, MatchingHandlers, Matchings};
use model::{cst_node::NonTerminal, CSTNode};
use unordered_pair::UnorderedPair;

Expand All @@ -18,7 +18,11 @@ impl<'a> Default for Entry<'a> {
}
}

pub fn ordered_tree_matching<'a>(left: &'a CSTNode, right: &'a CSTNode) -> Matchings<'a> {
pub fn ordered_tree_matching<'a>(
left: &'a CSTNode,
right: &'a CSTNode,
matching_handlers: &'a MatchingHandlers<'a>,
) -> Matchings<'a> {
match (left, right) {
(
CSTNode::NonTerminal(NonTerminal {
Expand All @@ -45,7 +49,7 @@ pub fn ordered_tree_matching<'a>(left: &'a CSTNode, right: &'a CSTNode) -> Match
let left_child = children_left.get(i - 1).unwrap();
let right_child = children_right.get(j - 1).unwrap();

let w = calculate_matchings(left_child, right_child);
let w = calculate_matchings(left_child, right_child, matching_handlers);
let matching = w
.get_matching_entry(left_child, right_child)
.unwrap_or_default();
Expand Down Expand Up @@ -73,7 +77,10 @@ pub fn ordered_tree_matching<'a>(left: &'a CSTNode, right: &'a CSTNode) -> Match

let mut matchings = Matchings::from_single(
UnorderedPair(left, right),
MatchingEntry::new(matrix_m[m][n] + root_matching, left.contents() == right.contents()),
MatchingEntry::new(
matrix_m[m][n] + root_matching,
left.contents() == right.contents(),
),
);

while i >= 1 && j >= 1 {
Expand Down Expand Up @@ -101,7 +108,7 @@ mod tests {
use crate::{matching_entry::MatchingEntry, *};
use model::{
cst_node::{NonTerminal, Terminal},
CSTNode, Point,
language, CSTNode, Point,
};

#[test]
Expand All @@ -128,7 +135,8 @@ mod tests {
children: vec![child.clone()],
});

let matchings = ordered_tree_matching(&left, &right);
let binding = MatchingHandlers::from(language::Language::Java);
let matchings = ordered_tree_matching(&left, &right, &binding);

assert_eq!(
Some(&MatchingEntry::new(1, true)),
Expand Down Expand Up @@ -168,7 +176,8 @@ mod tests {
end_position: Point { row: 0, column: 7 },
});

let matchings = ordered_tree_matching(&left, &right);
let binding = MatchingHandlers::from(language::Language::Java);
let matchings = ordered_tree_matching(&left, &right, &binding);

assert_eq!(
None,
Expand Down Expand Up @@ -208,7 +217,8 @@ mod tests {
children: vec![common_child.clone(), unique_right_child],
});

let matchings = ordered_tree_matching(&left, &right);
let binding = MatchingHandlers::from(language::Language::Java);
let matchings = ordered_tree_matching(&left, &right, &binding);

assert_eq!(
Some(&MatchingEntry::new(2, false)),
Expand Down Expand Up @@ -241,7 +251,8 @@ mod tests {
children: vec![common_child.clone()],
});

let matchings = ordered_tree_matching(&left, &right);
let binding = MatchingHandlers::from(language::Language::Java);
let matchings = ordered_tree_matching(&left, &right, &binding);

assert_eq!(
Some(&MatchingEntry::new(2, true)),
Expand Down Expand Up @@ -282,7 +293,8 @@ mod tests {
children: vec![intermediate.clone()],
});

let matchings = ordered_tree_matching(&left, &right);
let binding = MatchingHandlers::from(language::Language::Java);
let matchings = ordered_tree_matching(&left, &right, &binding);

assert_eq!(
Some(&MatchingEntry::new(2, true)),
Expand Down
Loading

0 comments on commit 1fcf6d6

Please sign in to comment.