Skip to content

Commit

Permalink
chore: initial change on struct
Browse files Browse the repository at this point in the history
  • Loading branch information
jpedroh committed Oct 27, 2023
1 parent 3f1cd4f commit 7986e5d
Show file tree
Hide file tree
Showing 9 changed files with 333 additions and 247 deletions.
31 changes: 31 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/rust
{
"name": "Rust",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/rust:1-1-bullseye"

// Use 'mounts' to make the cargo cache persistent in a Docker Volume.
// "mounts": [
// {
// "source": "devcontainer-cargo-cache-${devcontainerId}",
// "target": "/usr/local/cargo",
// "type": "volume"
// }
// ]

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "rustc --version",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
227 changes: 123 additions & 104 deletions bin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,31 @@ use merge::merge;
use model::{CSTNode, Language};
use parsing::ParserConfiguration;

fn run_semi_structured_merge_on_revisions(
language: Language,
base: &str,
left: &str,
right: &str,
) -> Result<CSTNode, &'static str> {
let base_tree = parsing::parse_string(base, ParserConfiguration::from_language(language))?;
let left_tree = parsing::parse_string(left, ParserConfiguration::from_language(language))?;
let right_tree = parsing::parse_string(right, ParserConfiguration::from_language(language))?;

let matchings_left_base = ordered_tree_matching(&left_tree, &base_tree);
let matchings_right_base = ordered_tree_matching(&right_tree, &base_tree);
let matchings_left_right = ordered_tree_matching(&left_tree, &right_tree);

Ok(merge(
&base_tree,
&left_tree,
&right_tree,
&matchings_left_base,
&matchings_right_base,
&matchings_left_right,
))
}
// fn run_semi_structured_merge_on_revisions<'a>(
// language: Language,
// base: &'a str,
// left: &'a str,
// right: &'a str,
// ) -> Result<CSTNode<'a>, &'static str> {
// let parser_configuration = ParserConfiguration::from_language(language);

// let base_tree = parsing::parse_string(base, &parser_configuration)?;
// let left_tree = parsing::parse_string(left, &parser_configuration)?;
// let right_tree = parsing::parse_string(right, &parser_configuration)?;

// let matchings_left_base = ordered_tree_matching(&left_tree, &base_tree);
// let matchings_right_base = ordered_tree_matching(&right_tree, &base_tree);
// let matchings_left_right = ordered_tree_matching(&left_tree, &right_tree);

// Ok(merge(
// &base_tree,
// &left_tree,
// &right_tree,
// &matchings_left_base,
// &matchings_right_base,
// &matchings_left_right,
// ))
// }

fn main() {
let base = r#"
Expand All @@ -46,9 +48,25 @@ fn main() {
}
"#;

let result = run_semi_structured_merge_on_revisions(Language::Java, base, left, right);
let parser_configuration = ParserConfiguration::from_language(Language::Java);
let base_tree = parsing::parse_string(base, &parser_configuration).unwrap();
let left_tree = parsing::parse_string(left, &parser_configuration).unwrap();
let right_tree = parsing::parse_string(right, &parser_configuration).unwrap();

println!("{:#?}", pretty_print(result.unwrap()))
let matchings_left_base = ordered_tree_matching(&left_tree, &base_tree);
let matchings_right_base = ordered_tree_matching(&right_tree, &base_tree);
let matchings_left_right = ordered_tree_matching(&left_tree, &right_tree);

let result = merge(
&base_tree,
&left_tree,
&right_tree,
&matchings_left_base,
&matchings_right_base,
&matchings_left_right,
);

println!("{:#?}", pretty_print(result))
}

pub fn pretty_print(node: CSTNode) -> String {
Expand All @@ -66,82 +84,83 @@ pub fn pretty_print(node: CSTNode) -> String {
}
}

#[cfg(test)]
mod tests {
use model::language::Language;
use model::CSTNode;
use parsing::ParserConfiguration;

use crate::run_semi_structured_merge_on_revisions;

fn parse_java_string(contents: &str) -> CSTNode {
parsing::parse_string(contents, ParserConfiguration::from_language(Language::Java)).unwrap()
}

#[test]
fn it_merges_three_java_revisions_that_are_equal() {
let code = r#"
public static interface HelloWorld {
void sayHello(String name);
void sayBye(String name);
}
"#;

let result = run_semi_structured_merge_on_revisions(Language::Java, code, code, code);

assert_eq!(parse_java_string(code), result.unwrap())
}

#[test]
fn it_merges_three_java_revisions_that_adds_the_same_node() {
let base = r#"
public static interface HelloWorld {
void sayBye(String name);
}
"#;

let parents = r#"
public static interface HelloWorld {
void sayHello(String name);
void sayBye(String name);
}
"#;

let merge = r#"
public static interface HelloWorld {
void sayHello(String name);
void sayBye(String name);
}
"#;

let result = run_semi_structured_merge_on_revisions(Language::Java, base, parents, parents);

assert_eq!(parse_java_string(merge), result.unwrap())
}

#[test]
fn it_merges_three_java_revisions_that_removes_the_same_node() {
let base = r#"
public static interface HelloWorld {
void sayHello(String name);
void sayBye(String name);
}
"#;

let parents = r#"
public static interface HelloWorld {
void sayBye(String name);
}
"#;

let merge = r#"
public static interface HelloWorld {
void sayBye(String name);
}
"#;

let result = run_semi_structured_merge_on_revisions(Language::Java, base, parents, parents);

assert_eq!(parse_java_string(merge), result.unwrap())
}
}
// #[cfg(test)]
// mod tests {
// use model::language::Language;
// use model::CSTNode;
// use parsing::ParserConfiguration;

// use crate::run_semi_structured_merge_on_revisions;

// fn parse_java_string<'a>(contents: &'a str) -> CSTNode<'a> {
// let parser_configuration = ParserConfiguration::from_language(Language::Java);
// parsing::parse_string(contents, &parser_configuration).unwrap()
// }

// #[test]
// fn it_merges_three_java_revisions_that_are_equal() {
// let code = r#"
// public static interface HelloWorld {
// void sayHello(String name);
// void sayBye(String name);
// }
// "#;

// let result = run_semi_structured_merge_on_revisions(Language::Java, code, code, code);

// assert_eq!(parse_java_string(code), result.unwrap())
// }

// #[test]
// fn it_merges_three_java_revisions_that_adds_the_same_node() {
// let base = r#"
// public static interface HelloWorld {
// void sayBye(String name);
// }
// "#;

// let parents = r#"
// public static interface HelloWorld {
// void sayHello(String name);
// void sayBye(String name);
// }
// "#;

// let merge = r#"
// public static interface HelloWorld {
// void sayHello(String name);
// void sayBye(String name);
// }
// "#;

// let result = run_semi_structured_merge_on_revisions(Language::Java, base, parents, parents);

// assert_eq!(parse_java_string(merge), result.unwrap())
// }

// #[test]
// fn it_merges_three_java_revisions_that_removes_the_same_node() {
// let base = r#"
// public static interface HelloWorld {
// void sayHello(String name);
// void sayBye(String name);
// }
// "#;

// let parents = r#"
// public static interface HelloWorld {
// void sayBye(String name);
// }
// "#;

// let merge = r#"
// public static interface HelloWorld {
// void sayBye(String name);
// }
// "#;

// let result = run_semi_structured_merge_on_revisions(Language::Java, base, parents, parents);

// assert_eq!(parse_java_string(merge), result.unwrap())
// }
// }
2 changes: 1 addition & 1 deletion matching/src/matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use model::CSTNode;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Matching<'a> {
pub matching_node: &'a CSTNode,
pub matching_node: &'a CSTNode<'a>,
pub score: usize,
pub is_perfect_match: bool,
}
56 changes: 49 additions & 7 deletions matching/src/matchings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,27 @@ use crate::matching::Matching;
use crate::matching_entry::MatchingEntry;

#[derive(Debug)]
pub struct Matchings {
matching_entries: HashMap<UnorderedPair<CSTNode>, MatchingEntry>,
pub struct Matchings<'a> {
matching_entries: HashMap<UnorderedPair<&'a CSTNode<'a>>, MatchingEntry>,
}

impl Matchings {
impl<'a> Matchings<'a> {
pub fn empty() -> Self {
Matchings {
matching_entries: HashMap::new(),
}
}

pub fn new(matching_entries: HashMap<UnorderedPair<CSTNode>, MatchingEntry>) -> Self {
pub fn new(matching_entries: HashMap<UnorderedPair<&'a CSTNode<'a>>, MatchingEntry>) -> Self {
Matchings { matching_entries }
}

pub fn find_matching_for(&self, a_node: &CSTNode) -> Option<Matching> {
self.matching_entries
.iter()
.find(|(UnorderedPair(left, right), ..)| left == a_node || right == a_node)
.find(|(UnorderedPair(left, right), ..)| left == &a_node || right == &a_node)
.map(|(UnorderedPair(left, right), matching)| {
let matching_node = if left == a_node { right } else { left };
let matching_node = if left == &a_node { right } else { left };
Matching {
matching_node,
score: matching.score,
Expand All @@ -36,7 +36,11 @@ impl Matchings {
})
}

pub fn get_matching_entry(&self, left: CSTNode, right: CSTNode) -> Option<&MatchingEntry> {
pub fn get_matching_entry(
&self,
left: &'a CSTNode<'a>,
right: &'a CSTNode<'a>,
) -> Option<&MatchingEntry> {
self.matching_entries.get(&UnorderedPair(left, right))
}
}
Expand Down Expand Up @@ -77,4 +81,42 @@ mod tests {
Matchings::new(matchings).find_matching_for(&a_node)
)
}

#[test]
fn returns_a_match_if_a_matching_for_the_node_is_found() {
let a_node = CSTNode::Terminal {
kind: "kind_b".into(),
value: "value_b".into(),
};
let b_node = CSTNode::Terminal {
kind: "kind_a".into(),
value: "value_a".into(),
};

let mut matchings_map = HashMap::new();
matchings_map.insert(
UnorderedPair(a_node.clone(), b_node.clone()),
MatchingEntry::new(1, false),
);

let matchings = Matchings::new(matchings_map);

assert_eq!(
Some(Matching {
matching_node: &b_node,
score: 1,
is_perfect_match: false
}),
matchings.find_matching_for(&a_node)
);

assert_eq!(
Some(Matching {
matching_node: &a_node,
score: 1,
is_perfect_match: false
}),
matchings.find_matching_for(&b_node)
)
}
}
Loading

0 comments on commit 7986e5d

Please sign in to comment.