private DataMatch MatchInternal(DataVisitNode node1, DataVisitNode node2) { // Check if nodes are null if ((ReferenceEquals(node1, null) || ReferenceEquals(node2, null) || node1.GetType() != node2.GetType())) { return(node1 == node2 ? DataMatch.Empty : UnMatched(node1, node2)); } var match = new DataMatch(); if (node1 is DataVisitRootNode) { if (node1.Instance == null || node2.Instance == null || node1.Instance.GetType() != node2.Instance.GetType()) { return(ReferenceEquals(node1.Instance, node2.Instance) ? DataMatch.MatchOne : UnMatched(node1, node2)); } } else if (node1 is DataVisitMember) { match += MatchValue(node1, ((DataVisitMember)node1).Value, node2, ((DataVisitMember)node2).Value); } else if (node1 is DataVisitListItem) { match += MatchValue(node1, ((DataVisitListItem)node1).Item, node2, ((DataVisitListItem)node2).Item); } match += MatchValues(node1, node1.Members, node2, node2.Members, true); match += MatchValues(node1, node1.Items, node2, node2.Items, false); return(match); }
private DataMatch MatchValues(DataVisitNode node1Parent, List <IDataVisitNode> nodes1, DataVisitNode node2Parent, List <IDataVisitNode> nodes2, bool expectSameCount) { if (nodes1 == null || nodes2 == null || (expectSameCount && nodes1.Count != nodes2.Count)) { return(ReferenceEquals(nodes1, nodes2) ? DataMatch.Empty : UnMatched(node1Parent, node2Parent)); } var match = new DataMatch(); if (expectSameCount) { for (int i = 0; i < nodes1.Count; i++) { match += Match((DataVisitNode)nodes1[i], (DataVisitNode)nodes2[i]); } } else { var alignedDiffs = Diff2.CompareAndAlign(nodes1, nodes2, modelNodeComparer, modelNodeSimilarityComparer, modelNodeCanAlign).ToList(); foreach (var alignedDiffChange in alignedDiffs) { switch (alignedDiffChange.Change) { case ChangeType.Same: case ChangeType.Changed: match += Match((DataVisitNode)nodes1[alignedDiffChange.Index1], (DataVisitNode)nodes2[alignedDiffChange.Index2]); break; case ChangeType.Added: match += new DataMatch(0, nodes2[alignedDiffChange.Index2].CountNodes()); break; case ChangeType.Deleted: match += new DataMatch(0, nodes1[alignedDiffChange.Index1].CountNodes()); break; } } } return(match); }