From 9ec2c6c9fd2e4a04992ebcb6b61939c62fd5d235 Mon Sep 17 00:00:00 2001 From: Joao Duarte Date: Tue, 5 Dec 2023 20:19:19 -0300 Subject: [PATCH] refactor: Split nodes into different structs --- matching/src/lib.rs | 43 +-- matching/src/matchings.rs | 10 +- matching/src/ordered_tree_matching.rs | 87 ++--- matching/src/unordered_tree_matching.rs | 49 +-- merge/src/merge.rs | 66 ++-- merge/src/merged_cst_node.rs | 17 +- merge/src/ordered_merge.rs | 438 ++++++++++++------------ merge/src/unordered_merge.rs | 234 +++++++------ model/src/cst_node.rs | 82 +++-- parsing/src/parse.rs | 128 +++---- 10 files changed, 597 insertions(+), 557 deletions(-) diff --git a/matching/src/lib.rs b/matching/src/lib.rs index e46ecae..e46cc5c 100644 --- a/matching/src/lib.rs +++ b/matching/src/lib.rs @@ -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; @@ -23,16 +24,16 @@ pub fn calculate_matchings<'a>( } } ( - 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( @@ -46,24 +47,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); @@ -75,18 +76,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); @@ -98,18 +99,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); @@ -121,18 +122,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); diff --git a/matching/src/matchings.rs b/matching/src/matchings.rs index 0f52797..a6aa68a 100644 --- a/matching/src/matchings.rs +++ b/matching/src/matchings.rs @@ -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)); diff --git a/matching/src/ordered_tree_matching.rs b/matching/src/ordered_tree_matching.rs index 6e17b25..f5dce59 100644 --- a/matching/src/ordered_tree_matching.rs +++ b/matching/src/ordered_tree_matching.rs @@ -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)] @@ -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(); @@ -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); @@ -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); @@ -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); @@ -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); @@ -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); diff --git a/matching/src/unordered_tree_matching.rs b/matching/src/unordered_tree_matching.rs index 995991d..5f02a1b 100644 --- a/matching/src/unordered_tree_matching.rs +++ b/matching/src/unordered_tree_matching.rs @@ -1,4 +1,7 @@ -use model::CSTNode; +use model::{ + cst_node::{NonTerminal, Terminal}, + CSTNode, +}; use unordered_pair::UnorderedPair; use crate::{calculate_matchings, MatchingEntry, Matchings}; @@ -6,16 +9,16 @@ use crate::{calculate_matchings, MatchingEntry, Matchings}; pub fn unordered_tree_matching<'a>(left: &'a CSTNode, right: &'a CSTNode) -> crate::Matchings<'a> { match (left, right) { ( - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: kind_left, value: value_left, .. - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: kind_right, value: value_right, .. - }, + }), ) => { let is_perfetch_match = kind_left == kind_right && value_left == value_right; Matchings::from_single( @@ -24,16 +27,16 @@ pub fn unordered_tree_matching<'a>(left: &'a CSTNode, right: &'a CSTNode) -> cra ) } ( - 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(); @@ -71,35 +74,35 @@ pub fn unordered_tree_matching<'a>(left: &'a CSTNode, right: &'a CSTNode) -> cra fn compute_matching_score<'a>(left: &'a CSTNode, right: &'a CSTNode) -> usize { match (left, right) { ( - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: kind_left, value: value_left, .. - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: kind_right, value: value_right, .. - }, + }), ) => (kind_left == kind_right && value_left == value_right).into(), ( - CSTNode::NonTerminal { + CSTNode::NonTerminal(NonTerminal { children: children_left, .. - }, - CSTNode::NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { children: children_right, .. - }, + }), ) => { // Try to find an identifier on children, and compare them let identifier_left = children_left.iter().find(|node| match node { - CSTNode::Terminal { kind, .. } => kind == &"identifier", + CSTNode::Terminal(Terminal { kind, .. }) => kind == &"identifier", _ => false, }); let identifier_right = children_right.iter().find(|node| match node { - CSTNode::Terminal { kind, .. } => kind == &"identifier", + CSTNode::Terminal(Terminal { kind, .. }) => kind == &"identifier", _ => false, }); @@ -107,12 +110,12 @@ fn compute_matching_score<'a>(left: &'a CSTNode, right: &'a CSTNode) -> usize { (Some(identifier_left), Some(identifier_right)) => { match (identifier_left, identifier_right) { ( - CSTNode::Terminal { + CSTNode::Terminal(Terminal { value: value_left, .. - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { value: value_right, .. - }, + }), ) if value_left == value_right => 1, (_, _) => 0, } diff --git a/merge/src/merge.rs b/merge/src/merge.rs index aeef8e4..6a410f9 100644 --- a/merge/src/merge.rs +++ b/merge/src/merge.rs @@ -1,6 +1,7 @@ use crate::ordered_merge; use crate::unordered_merge; use matching::Matchings; +use model::cst_node::Terminal; use model::CSTNode; use crate::merged_cst_node::MergedCSTNode; @@ -15,17 +16,17 @@ pub fn merge<'a>( ) -> MergedCSTNode<'a> { match (base, left, right) { ( - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind, value: value_base, .. - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { value: value_left, .. - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { value: value_right, .. - }, + }), ) => { // Unchanged if value_left == value_base && value_right == value_base { @@ -74,7 +75,10 @@ mod tests { use std::vec; use matching::{ordered_tree_matching, Matchings}; - use model::{CSTNode, Point}; + use model::{ + cst_node::{NonTerminal, Terminal}, + CSTNode, Point, + }; use crate::MergedCSTNode; @@ -113,12 +117,12 @@ mod tests { #[test] fn if_i_am_merging_three_unchanged_nodes_it_is_a_success() { - let node = CSTNode::Terminal { + let node = CSTNode::Terminal(Terminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value", - }; + }); assert_merge_is_correct_and_idempotent_with_respect_to_parent_side( &node, @@ -130,24 +134,24 @@ mod tests { #[test] fn returns_success_if_there_are_changes_in_both_parents_and_they_are_not_conflicting() { - let base = CSTNode::Terminal { + let base = CSTNode::Terminal(Terminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "\nvalue\n", - }; - let left = CSTNode::Terminal { + }); + let left = CSTNode::Terminal(Terminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "left\nvalue\n", - }; - let right = CSTNode::Terminal { + }); + let right = CSTNode::Terminal(Terminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "\nvalue\nright", - }; + }); assert_merge_is_correct_and_idempotent_with_respect_to_parent_side( &base, @@ -162,24 +166,24 @@ mod tests { #[test] fn returns_conflict_if_there_are_changes_in_both_parents_and_they_are_conflicting() { - let base = CSTNode::Terminal { + let base = CSTNode::Terminal(Terminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value", - }; - let left = CSTNode::Terminal { + }); + let left = CSTNode::Terminal(Terminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "left_value", - }; - let right = CSTNode::Terminal { + }); + let right = CSTNode::Terminal(Terminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "right_value", - }; + }); assert_eq!( merge(&base, &left, &right, &Matchings::empty(), &Matchings::empty(), @@ -193,18 +197,18 @@ mod tests { #[test] fn if_there_is_a_change_only_in_one_parent_it_returns_the_changes_from_this_parent() { - let base_and_left = CSTNode::Terminal { + let base_and_left = CSTNode::Terminal(Terminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value", - }; - let changed_parent = CSTNode::Terminal { + }); + let changed_parent = CSTNode::Terminal(Terminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_right", - }; + }); assert_merge_is_correct_and_idempotent_with_respect_to_parent_side( &base_and_left, @@ -218,24 +222,24 @@ mod tests { #[should_panic(expected = "Can not merge Terminal with Non-Terminal")] fn test_can_not_merge_terminal_with_non_terminal() { merge( - &CSTNode::Terminal { + &CSTNode::Terminal(Terminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value", - }, - &CSTNode::Terminal { + }), + &CSTNode::Terminal(Terminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value", - }, - &CSTNode::NonTerminal { + }), + &CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![], - }, + }), &Matchings::empty(), &Matchings::empty(), &Matchings::empty(), diff --git a/merge/src/merged_cst_node.rs b/merge/src/merged_cst_node.rs index f6e0536..464786e 100644 --- a/merge/src/merged_cst_node.rs +++ b/merge/src/merged_cst_node.rs @@ -1,4 +1,7 @@ -use model::CSTNode; +use model::{ + cst_node::{NonTerminal, Terminal}, + CSTNode, +}; #[derive(Debug, PartialEq, Clone, Eq, Hash, PartialOrd, Ord)] pub enum MergedCSTNode<'a> { @@ -19,14 +22,16 @@ pub enum MergedCSTNode<'a> { impl<'a> From> for MergedCSTNode<'a> { fn from(val: CSTNode<'a>) -> Self { match val { - CSTNode::Terminal { kind, value, .. } => MergedCSTNode::Terminal { + CSTNode::Terminal(Terminal { kind, value, .. }) => MergedCSTNode::Terminal { kind, value: value.to_string(), }, - CSTNode::NonTerminal { kind, children, .. } => MergedCSTNode::NonTerminal { - kind, - children: children.into_iter().map(|node| node.into()).collect(), - }, + CSTNode::NonTerminal(NonTerminal { kind, children, .. }) => { + MergedCSTNode::NonTerminal { + kind, + children: children.into_iter().map(|node| node.into()).collect(), + } + } } } } diff --git a/merge/src/ordered_merge.rs b/merge/src/ordered_merge.rs index d9205e8..10b455e 100644 --- a/merge/src/ordered_merge.rs +++ b/merge/src/ordered_merge.rs @@ -1,5 +1,5 @@ use matching::Matchings; -use model::CSTNode; +use model::{cst_node::NonTerminal, CSTNode}; use crate::MergedCSTNode; @@ -13,15 +13,15 @@ pub fn ordered_merge<'a>( ) -> MergedCSTNode<'a> { match (base, left, right) { ( - CSTNode::NonTerminal { kind, .. }, - CSTNode::NonTerminal { + CSTNode::NonTerminal(NonTerminal { kind, .. }), + CSTNode::NonTerminal(NonTerminal { children: children_left, .. - }, - CSTNode::NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { children: children_right, .. - }, + }), ) => { let mut result_children = vec![]; @@ -220,7 +220,7 @@ mod tests { use std::vec; use matching::ordered_tree_matching; - use model::{CSTNode, Point}; + use model::{cst_node::NonTerminal, cst_node::Terminal, CSTNode, Point}; use crate::MergedCSTNode; @@ -281,25 +281,25 @@ mod tests { #[test] fn it_merges_non_terminals_if_there_are_non_changes() { - let tree = CSTNode::NonTerminal { + let tree = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }, + }), ], - }; + }); assert_merge_is_correct_and_idempotent_with_respect_to_parent_side( &tree, @@ -311,31 +311,31 @@ mod tests { #[test] fn it_merges_non_terminals_if_both_left_and_right_add_the_same_things() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![], - }; - let parent = CSTNode::NonTerminal { + }); + let parent = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }, + }), ], - }; + }); assert_merge_is_correct_and_idempotent_with_respect_to_parent_side( &base, @@ -348,31 +348,31 @@ mod tests { #[test] fn it_merges_non_terminals_if_only_one_parent_adds_a_node_in_an_initially_empty_children_list() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![], - }; + }); - let initially_empty_parent = CSTNode::NonTerminal { + let initially_empty_parent = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![], - }; + }); - let parent_that_added = CSTNode::NonTerminal { + let parent_that_added = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }], - }; + })], + }); let expected_merge = MergedCSTNode::NonTerminal { kind: "kind", @@ -392,49 +392,49 @@ mod tests { #[test] fn it_merges_non_terminals_if_only_one_parent_adds_a_node_in_non_empty_children_list() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }], - }; + })], + }); - let unchanged_parent = CSTNode::NonTerminal { + let unchanged_parent = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }], - }; + })], + }); - let parent_that_added = CSTNode::NonTerminal { + let parent_that_added = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }, + }), ], - }; + }); let merge = MergedCSTNode::NonTerminal { kind: "kind", @@ -460,41 +460,41 @@ mod tests { #[test] fn it_merges_when_one_parent_adds_a_node_and_removes_one_that_was_not_edited_in_the_other() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }], - }; + })], + }); - let changed_parent = CSTNode::NonTerminal { + let changed_parent = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }], - }; + })], + }); - let unchanged_parent = CSTNode::NonTerminal { + let unchanged_parent = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }], - }; + })], + }); let expected_merge = MergedCSTNode::NonTerminal { kind: "kind", @@ -514,56 +514,56 @@ mod tests { #[test] fn it_merges_when_one_parent_adds_a_node_and_removes_from_another_that_was_changed() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::NonTerminal { + children: vec![CSTNode::NonTerminal(NonTerminal { kind: "subtree", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }], - }], - }; + })], + })], + }); - let parent_a = CSTNode::NonTerminal { + let parent_a = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::NonTerminal { + children: vec![CSTNode::NonTerminal(NonTerminal { kind: "another_subtree", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }], - }], - }; + })], + })], + }); - let parent_b = CSTNode::NonTerminal { + let parent_b = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::NonTerminal { + children: vec![CSTNode::NonTerminal(NonTerminal { kind: "subtree", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_c", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_c", - }], - }], - }; + })], + })], + }); let matchings_base_parent_a = ordered_tree_matching(&base, &parent_a); let matchings_base_parent_b = ordered_tree_matching(&base, &parent_b); @@ -641,36 +641,36 @@ mod tests { #[test] fn if_both_parents_add_different_nodes_then_we_have_a_conflict() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![], - }; + }); - let left = CSTNode::NonTerminal { + let left = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }], - }; + })], + }); - let right = CSTNode::NonTerminal { + let right = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }], - }; + })], + }); assert_merge_output_is( &base, @@ -694,57 +694,57 @@ mod tests { #[test] fn it_merges_when_one_parent_removes_a_node_that_was_not_changed_in_another_parent() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, - CSTNode::Terminal { + }), + 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", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }, + }), ], - }; + }); - let right = CSTNode::NonTerminal { + let right = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }], - }; + })], + }); let expected_merge = MergedCSTNode::NonTerminal { kind: "kind", @@ -759,67 +759,67 @@ mod tests { #[test] fn it_detects_a_conflict_when_one_parent_removes_a_node_that_was_changed_in_another_parent() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::NonTerminal { + CSTNode::NonTerminal(NonTerminal { kind: "subtree", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }], - }, - CSTNode::Terminal { + })], + }), + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, + }), ], - }; + }); - let left = CSTNode::NonTerminal { + let left = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::NonTerminal { + CSTNode::NonTerminal(NonTerminal { kind: "subtree", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_c", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_c", - }], - }, - CSTNode::Terminal { + })], + }), + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, + }), ], - }; + }); - let right = CSTNode::NonTerminal { + let right = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }], - }; + })], + }); assert_merge_output_is( &base, @@ -874,71 +874,71 @@ mod tests { #[test] fn it_merges_when_a_parent_adds_a_node() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_c", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_c", - }, + }), ], - }; + }); - let unchanged_parent = CSTNode::NonTerminal { + let unchanged_parent = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_c", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_c", - }, + }), ], - }; + }); - let changed_parent = CSTNode::NonTerminal { + let changed_parent = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_c", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_c", - }, + }), ], - }; + }); let expected_merge = MergedCSTNode::NonTerminal { kind: "kind", @@ -968,49 +968,49 @@ mod tests { #[test] fn it_merges_when_one_parent_removes_and_add_a_node() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }], - }; + })], + }); - let parent_a = CSTNode::NonTerminal { + let parent_a = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }], - }; + })], + }); - let parent_b = CSTNode::NonTerminal { + let parent_b = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, + }), ], - }; + }); let expected_merge = MergedCSTNode::NonTerminal { kind: "kind", @@ -1030,59 +1030,59 @@ mod tests { #[test] fn it_conflicts_when_one_parent_removes_and_add_a_node() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::NonTerminal { + children: vec![CSTNode::NonTerminal(NonTerminal { kind: "subtree", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }], - }], - }; + })], + })], + }); - let parent_a = CSTNode::NonTerminal { + let parent_a = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }], - }; + })], + }); - let parent_b = CSTNode::NonTerminal { + let parent_b = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::NonTerminal { + CSTNode::NonTerminal(NonTerminal { kind: "subtree", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_c", - }], - }, - CSTNode::Terminal { + })], + }), + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, + }), ], - }; + }); assert_merge_output_is( &base, @@ -1136,44 +1136,44 @@ mod tests { #[test] fn it_merges_when_a_parent_adds_one_node() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![], - }; + }); - let parent_a = CSTNode::NonTerminal { + let parent_a = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }], - }; + })], + }); - let parent_b = CSTNode::NonTerminal { + let parent_b = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "kind_c", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_c", - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_a", - }, + }), ], - }; + }); let expected_merge = MergedCSTNode::NonTerminal { kind: "kind", @@ -1199,49 +1199,49 @@ mod tests { #[test] fn it_does_not_detect_a_conflict_if_am_merging_two_subtrees_that_have_not_changed_mutually() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_c", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_c", - }, + }), ], - }; + }); - let parent_a = CSTNode::NonTerminal { + let parent_a = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }], - }; + })], + }); - let parent_b = CSTNode::NonTerminal { + let parent_b = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_c", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_c", - }], - }; + })], + }); let expected_merge = MergedCSTNode::NonTerminal { kind: "kind", @@ -1259,69 +1259,69 @@ mod tests { #[test] fn it_detects_a_conflict_if_am_merging_two_subtrees_that_delete_a_node_that_was_changed_in_another_parent( ) { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, children: vec![ - CSTNode::NonTerminal { + CSTNode::NonTerminal(NonTerminal { kind: "subtree_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_b", - }], - }, - CSTNode::NonTerminal { + })], + }), + CSTNode::NonTerminal(NonTerminal { kind: "subtree_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_c", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_c", - }], - }, + })], + }), ], - }; + }); - let parent_a = CSTNode::NonTerminal { + let parent_a = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::NonTerminal { + children: vec![CSTNode::NonTerminal(NonTerminal { kind: "subtree_b", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_c", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_c", - }], - }], - }; + })], + })], + }); - let parent_b = CSTNode::NonTerminal { + let parent_b = CSTNode::NonTerminal(NonTerminal { kind: "kind", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::NonTerminal { + children: vec![CSTNode::NonTerminal(NonTerminal { kind: "subtree_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "kind_a", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 7 }, value: "value_c", - }], - }], - }; + })], + })], + }); assert_merge_output_is( &base, diff --git a/merge/src/unordered_merge.rs b/merge/src/unordered_merge.rs index af738c6..7423213 100644 --- a/merge/src/unordered_merge.rs +++ b/merge/src/unordered_merge.rs @@ -1,7 +1,10 @@ use std::collections::HashSet; use matching::Matchings; -use model::CSTNode; +use model::{ + cst_node::{NonTerminal, Terminal}, + CSTNode, +}; use crate::{merge, MergedCSTNode}; @@ -15,22 +18,22 @@ pub fn unordered_merge<'a>( ) -> MergedCSTNode<'a> { match (base, left, right) { ( - CSTNode::NonTerminal { kind, .. }, - CSTNode::NonTerminal { + CSTNode::NonTerminal(NonTerminal { kind, .. }), + CSTNode::NonTerminal(NonTerminal { children: children_left, .. - }, - CSTNode::NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { children: children_right, .. - }, + }), ) => { let mut result_children = vec![]; let mut processed_nodes: HashSet<&CSTNode> = HashSet::new(); for left_child in children_left.iter() { match left_child { - CSTNode::Terminal { value, .. } => { + CSTNode::Terminal(Terminal { value, .. }) => { if value == &"}" { break; } @@ -143,7 +146,10 @@ pub fn unordered_merge<'a>( #[cfg(test)] mod tests { use matching::unordered_tree_matching; - use model::CSTNode; + use model::{ + cst_node::{NonTerminal, Terminal}, + CSTNode, + }; use crate::MergedCSTNode; @@ -204,71 +210,71 @@ mod tests { #[test] fn test_merge_node_added_only_by_one_parent() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "interface_body", start_position: model::Point { row: 0, column: 0 }, end_position: model::Point { row: 0, column: 0 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: model::Point { row: 1, column: 1 }, end_position: model::Point { row: 1, column: 1 }, - }, + }), ], - }; + }); - let parent_a = CSTNode::NonTerminal { + let parent_a = CSTNode::NonTerminal(NonTerminal { kind: "interface_body", start_position: model::Point { row: 0, column: 0 }, end_position: model::Point { row: 0, column: 0 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "method_declaration", value: "main", start_position: model::Point { row: 1, column: 0 }, end_position: model::Point { row: 1, column: 4 }, - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: model::Point { row: 2, column: 1 }, end_position: model::Point { row: 2, column: 1 }, - }, + }), ], - }; + }); - let parent_b = CSTNode::NonTerminal { + let parent_b = CSTNode::NonTerminal(NonTerminal { kind: "interface_body", start_position: model::Point { row: 0, column: 0 }, end_position: model::Point { row: 0, column: 0 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: model::Point { row: 1, column: 1 }, end_position: model::Point { row: 1, column: 1 }, - }, + }), ], - }; + }); let merge = MergedCSTNode::NonTerminal { kind: "interface_body", @@ -295,87 +301,87 @@ mod tests { #[test] fn test_both_parents_add_the_same_node_and_both_subtrees_are_equal() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "interface_body", start_position: model::Point { row: 0, column: 0 }, end_position: model::Point { row: 0, column: 0 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: model::Point { row: 1, column: 1 }, end_position: model::Point { row: 1, column: 1 }, - }, + }), ], - }; + }); - let parent_a = CSTNode::NonTerminal { + let parent_a = CSTNode::NonTerminal(NonTerminal { kind: "interface_body", start_position: model::Point { row: 0, column: 0 }, end_position: model::Point { row: 0, column: 0 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { kind: "method_declaration", start_position: model::Point { row: 1, column: 0 }, end_position: model::Point { row: 1, column: 4 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "identifier", value: "main", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }], - }, - CSTNode::Terminal { + })], + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: model::Point { row: 2, column: 1 }, end_position: model::Point { row: 2, column: 1 }, - }, + }), ], - }; + }); - let parent_b = CSTNode::NonTerminal { + let parent_b = CSTNode::NonTerminal(NonTerminal { kind: "interface_body", start_position: model::Point { row: 0, column: 0 }, end_position: model::Point { row: 0, column: 0 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { kind: "method_declaration", start_position: model::Point { row: 1, column: 0 }, end_position: model::Point { row: 1, column: 4 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "identifier", value: "main", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }], - }, - CSTNode::Terminal { + })], + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: model::Point { row: 2, column: 1 }, end_position: model::Point { row: 2, column: 1 }, - }, + }), ], - }; + }); let expected_merge = MergedCSTNode::NonTerminal { kind: "interface_body", @@ -408,87 +414,87 @@ mod tests { #[test] fn test_merge_one_parent_removes_a_node_while_the_other_keeps_it_unchanged() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "interface_body", start_position: model::Point { row: 0, column: 0 }, end_position: model::Point { row: 0, column: 0 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { kind: "method_declaration", start_position: model::Point { row: 1, column: 0 }, end_position: model::Point { row: 1, column: 4 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "identifier", value: "main", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }], - }, - CSTNode::Terminal { + })], + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: model::Point { row: 1, column: 1 }, end_position: model::Point { row: 1, column: 1 }, - }, + }), ], - }; + }); - let parent_a = CSTNode::NonTerminal { + let parent_a = CSTNode::NonTerminal(NonTerminal { kind: "interface_body", start_position: model::Point { row: 0, column: 0 }, end_position: model::Point { row: 0, column: 0 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { kind: "method_declaration", start_position: model::Point { row: 1, column: 0 }, end_position: model::Point { row: 1, column: 4 }, - children: vec![CSTNode::Terminal { + children: vec![CSTNode::Terminal(Terminal { kind: "identifier", value: "main", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }], - }, - CSTNode::Terminal { + })], + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: model::Point { row: 2, column: 1 }, end_position: model::Point { row: 2, column: 1 }, - }, + }), ], - }; + }); - let parent_b = CSTNode::NonTerminal { + let parent_b = CSTNode::NonTerminal(NonTerminal { kind: "interface_body", start_position: model::Point { row: 0, column: 0 }, end_position: model::Point { row: 0, column: 0 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: model::Point { row: 2, column: 1 }, end_position: model::Point { row: 2, column: 1 }, - }, + }), ], - }; + }); let expected_merge = MergedCSTNode::NonTerminal { kind: "interface_body", @@ -514,115 +520,115 @@ mod tests { #[test] fn test_merge_one_parent_removes_a_node_while_the_other_changed_it() { - let base = CSTNode::NonTerminal { + let base = CSTNode::NonTerminal(NonTerminal { kind: "interface_body", start_position: model::Point { row: 0, column: 0 }, end_position: model::Point { row: 0, column: 0 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { kind: "method_declaration", start_position: model::Point { row: 1, column: 0 }, end_position: model::Point { row: 1, column: 4 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "identifier", value: "method", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_a", value: "value_a", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_b", value: "value_b", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, + }), ], - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: model::Point { row: 1, column: 1 }, end_position: model::Point { row: 1, column: 1 }, - }, + }), ], - }; + }); - let parent_a = CSTNode::NonTerminal { + let parent_a = CSTNode::NonTerminal(NonTerminal { kind: "interface_body", start_position: model::Point { row: 0, column: 0 }, end_position: model::Point { row: 0, column: 0 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { kind: "method_declaration", start_position: model::Point { row: 1, column: 0 }, end_position: model::Point { row: 1, column: 4 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "identifier", value: "method", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_a", value: "value_a", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "kind_b", value: "new_value_b", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, + }), ], - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: model::Point { row: 2, column: 1 }, end_position: model::Point { row: 2, column: 1 }, - }, + }), ], - }; + }); - let parent_b = CSTNode::NonTerminal { + let parent_b = CSTNode::NonTerminal(NonTerminal { kind: "interface_body", start_position: model::Point { row: 0, column: 0 }, end_position: model::Point { row: 0, column: 0 }, children: vec![ - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: model::Point { row: 0, column: 1 }, end_position: model::Point { row: 0, column: 1 }, - }, - CSTNode::Terminal { + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: model::Point { row: 2, column: 1 }, end_position: model::Point { row: 2, column: 1 }, - }, + }), ], - }; + }); assert_merge_output_is( &base, diff --git a/model/src/cst_node.rs b/model/src/cst_node.rs index 409c855..1bf4d04 100644 --- a/model/src/cst_node.rs +++ b/model/src/cst_node.rs @@ -16,18 +16,8 @@ impl Hash for Point { #[derive(Debug, PartialEq, Clone, Eq, PartialOrd, Ord)] pub enum CSTNode<'a> { - Terminal { - kind: &'a str, - value: &'a str, - start_position: Point, - end_position: Point, - }, - NonTerminal { - kind: &'a str, - children: Vec>, - start_position: Point, - end_position: Point, - }, + Terminal(Terminal<'a>), + NonTerminal(NonTerminal<'a>), } impl<'a> Hash for CSTNode<'a> { @@ -35,37 +25,61 @@ impl<'a> Hash for CSTNode<'a> { let mut hasher = std::collections::hash_map::DefaultHasher::new(); match self { - CSTNode::Terminal { - kind, - value, - start_position, - end_position, - } => { - kind.hash(&mut hasher); - value.hash(&mut hasher); - start_position.hash(&mut hasher); - end_position.hash(&mut hasher); + CSTNode::Terminal(node) => { + node.hash(&mut hasher); } - CSTNode::NonTerminal { - kind, - children, - start_position, - end_position, - } => { - kind.hash(&mut hasher); - children.hash(&mut hasher); - start_position.hash(&mut hasher); - end_position.hash(&mut hasher); + CSTNode::NonTerminal(node) => { + node.hash(&mut hasher); } } } } +#[derive(Debug, PartialEq, Clone, Eq, PartialOrd, Ord)] +pub struct NonTerminal<'a> { + pub kind: &'a str, + pub children: Vec>, + pub start_position: Point, + pub end_position: Point, +} + +impl<'a> Hash for NonTerminal<'a> { + fn hash(&self, _hasher: &mut H) { + let mut hasher = std::collections::hash_map::DefaultHasher::new(); + + self.kind.hash(&mut hasher); + self.children.hash(&mut hasher); + self.start_position.hash(&mut hasher); + self.end_position.hash(&mut hasher); + } +} + +#[derive(Debug, PartialEq, Clone, Eq, PartialOrd, Ord)] +pub struct Terminal<'a> { + pub kind: &'a str, + pub value: &'a str, + pub start_position: Point, + pub end_position: Point, +} + +impl<'a> Hash for Terminal<'a> { + fn hash(&self, _hasher: &mut H) { + let mut hasher = std::collections::hash_map::DefaultHasher::new(); + + self.kind.hash(&mut hasher); + self.value.hash(&mut hasher); + self.start_position.hash(&mut hasher); + self.end_position.hash(&mut hasher); + } +} + impl CSTNode<'_> { pub fn are_children_unordered(&self) -> bool { match self { - CSTNode::Terminal { .. } => false, - CSTNode::NonTerminal { kind, .. } => ["interface_body", "class_body"].contains(kind), + CSTNode::Terminal(_) => false, + CSTNode::NonTerminal(NonTerminal { kind, .. }) => { + ["interface_body", "class_body"].contains(kind) + } } } } diff --git a/parsing/src/parse.rs b/parsing/src/parse.rs index 3810ec1..f5a0bae 100644 --- a/parsing/src/parse.rs +++ b/parsing/src/parse.rs @@ -1,10 +1,13 @@ use crate::tree_sitter_parser::ParserConfiguration; -use model::{CSTNode, Point}; +use model::{ + cst_node::{NonTerminal, Terminal}, + CSTNode, Point, +}; use tree_sitter::Node; fn explore_node<'a>(node: Node, src: &'a str, config: &'a ParserConfiguration) -> CSTNode<'a> { if node.child_count() == 0 || config.stop_compilation_at.contains(node.kind()) { - CSTNode::Terminal { + CSTNode::Terminal(Terminal { kind: node.kind(), start_position: Point { row: node.start_position().row, @@ -15,10 +18,10 @@ fn explore_node<'a>(node: Node, src: &'a str, config: &'a ParserConfiguration) - column: node.end_position().column, }, value: &src[node.byte_range()], - } + }) } else { let mut cursor = node.walk(); - CSTNode::NonTerminal { + CSTNode::NonTerminal(NonTerminal { kind: node.kind(), start_position: Point { row: node.start_position().row, @@ -32,7 +35,7 @@ fn explore_node<'a>(node: Node, src: &'a str, config: &'a ParserConfiguration) - .children(&mut cursor) .map(|child| explore_node(child, src, config)) .collect(), - } + }) } } @@ -54,7 +57,8 @@ pub fn parse_string<'a>( #[cfg(test)] mod tests { - use model::CSTNode::{NonTerminal, Terminal}; + use model::cst_node::{NonTerminal, Terminal}; + use model::CSTNode; use model::Point; use super::*; @@ -71,79 +75,79 @@ mod tests { stop_compilation_at: [].into_iter().collect(), }; let result = parse_string(code, &parser_configuration); - let expected = NonTerminal { + let expected = CSTNode::NonTerminal(NonTerminal { kind: "program", - children: vec![NonTerminal { + children: vec![CSTNode::NonTerminal(NonTerminal { kind: "interface_declaration", children: vec![ - NonTerminal { + CSTNode::NonTerminal(NonTerminal { kind: "modifiers", children: vec![ - Terminal { + CSTNode::Terminal(Terminal { kind: "public", value: "public", start_position: Point { row: 1, column: 12 }, end_position: Point { row: 1, column: 18 }, - }, - Terminal { + }), + CSTNode::Terminal(Terminal { kind: "static", value: "static", start_position: Point { row: 1, column: 19 }, end_position: Point { row: 1, column: 25 }, - }, + }), ], start_position: Point { row: 1, column: 12 }, end_position: Point { row: 1, column: 25 }, - }, - Terminal { + }), + CSTNode::Terminal(Terminal { kind: "interface", value: "interface", start_position: Point { row: 1, column: 26 }, end_position: Point { row: 1, column: 35 }, - }, - Terminal { + }), + CSTNode::Terminal(Terminal { kind: "identifier", value: "HelloWorld", start_position: Point { row: 1, column: 36 }, end_position: Point { row: 1, column: 46 }, - }, - NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { kind: "interface_body", children: vec![ - Terminal { + CSTNode::Terminal(Terminal { kind: "{", value: "{", start_position: Point { row: 1, column: 47 }, end_position: Point { row: 1, column: 48 }, - }, - NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { kind: "method_declaration", children: vec![ - Terminal { + CSTNode::Terminal(Terminal { kind: "void_type", value: "void", start_position: Point { row: 2, column: 16 }, end_position: Point { row: 2, column: 20 }, - }, - Terminal { + }), + CSTNode::Terminal(Terminal { kind: "identifier", value: "sayHello", start_position: Point { row: 2, column: 21 }, end_position: Point { row: 2, column: 29 }, - }, - NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { kind: "formal_parameters", children: vec![ - Terminal { + CSTNode::Terminal(Terminal { kind: "(", value: "(", start_position: Point { row: 2, column: 29 }, end_position: Point { row: 2, column: 30 }, - }, - NonTerminal { + }), + CSTNode::NonTerminal(NonTerminal { kind: "formal_parameter", children: vec![ - Terminal { + CSTNode::Terminal(Terminal { kind: "type_identifier", value: "String", start_position: Point { @@ -151,8 +155,8 @@ mod tests { column: 30, }, end_position: Point { row: 2, column: 36 }, - }, - Terminal { + }), + CSTNode::Terminal(Terminal { kind: "identifier", value: "name", start_position: Point { @@ -160,48 +164,48 @@ mod tests { column: 37, }, end_position: Point { row: 2, column: 41 }, - }, + }), ], start_position: Point { row: 2, column: 30 }, end_position: Point { row: 2, column: 41 }, - }, - Terminal { + }), + CSTNode::Terminal(Terminal { kind: ")", value: ")", start_position: Point { row: 2, column: 41 }, end_position: Point { row: 2, column: 42 }, - }, + }), ], start_position: Point { row: 2, column: 29 }, end_position: Point { row: 2, column: 42 }, - }, - Terminal { + }), + CSTNode::Terminal(Terminal { kind: ";", value: ";", start_position: Point { row: 2, column: 42 }, end_position: Point { row: 2, column: 43 }, - }, + }), ], start_position: Point { row: 2, column: 16 }, end_position: Point { row: 2, column: 43 }, - }, - Terminal { + }), + CSTNode::Terminal(Terminal { kind: "}", value: "}", start_position: Point { row: 3, column: 12 }, end_position: Point { row: 3, column: 13 }, - }, + }), ], start_position: Point { row: 1, column: 47 }, end_position: Point { row: 3, column: 13 }, - }, + }), ], start_position: Point { row: 1, column: 12 }, end_position: Point { row: 3, column: 13 }, - }], + })], start_position: Point { row: 1, column: 12 }, end_position: Point { row: 4, column: 8 }, - }; + }); assert_eq!(expected, result.unwrap()) } @@ -214,55 +218,55 @@ mod tests { }; let result = parse_string(code, &parser_configuration); - let expected = NonTerminal { + let expected = CSTNode::NonTerminal(NonTerminal { kind: "program", - children: vec![NonTerminal { + children: vec![CSTNode::NonTerminal(NonTerminal { kind: "interface_declaration", children: vec![ - NonTerminal { + CSTNode::NonTerminal(NonTerminal { kind: "modifiers", children: vec![ - Terminal { + CSTNode::Terminal(Terminal { kind: "public", value: "public", start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 6 }, - }, - Terminal { + }), + CSTNode::Terminal(Terminal { kind: "static", value: "static", start_position: Point { row: 0, column: 7 }, end_position: Point { row: 0, column: 13 }, - }, + }), ], start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 13 }, - }, - Terminal { + }), + CSTNode::Terminal(Terminal { kind: "interface", value: "interface", start_position: Point { row: 0, column: 14 }, end_position: Point { row: 0, column: 23 }, - }, - Terminal { + }), + CSTNode::Terminal(Terminal { kind: "identifier", value: "HelloWorld", start_position: Point { row: 0, column: 24 }, end_position: Point { row: 0, column: 34 }, - }, - Terminal { + }), + CSTNode::Terminal(Terminal { kind: "interface_body", value: "{void sayHello(String name);}", start_position: Point { row: 0, column: 35 }, end_position: Point { row: 0, column: 64 }, - }, + }), ], start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 64 }, - }], + })], start_position: Point { row: 0, column: 0 }, end_position: Point { row: 0, column: 64 }, - }; + }); assert_eq!(expected, result.unwrap()) } }