public TreeNodeDiff(TreeNodeDump node, DiffStatus status) { if (node == null) { throw new ArgumentNullException(nameof(node)); } if (status != DiffStatus.Added && status != DiffStatus.Deleted) { throw new ArgumentException(nameof(status)); } Name = node.Name ?? throw new ArgumentNullException(nameof(node.Name)); string type = node.Type ?? throw new ArgumentNullException(nameof(node.Type)); LeftType = status == DiffStatus.Added ? string.Empty : type; RightType = status == DiffStatus.Added ? type : string.Empty; LeftVersion = status == DiffStatus.Added ? 0 : node.Version; RightVersion = status == DiffStatus.Added ? node.Version : 0; LeftAlign = status == DiffStatus.Added ? false : node.IsAlign; RightAlign = status == DiffStatus.Added ? node.IsAlign : false; int childNodeCount = node.GetNodeCount() - 1; TreeNodeDiff emptyElement = childNodeCount == 0 ? null : new TreeNodeDiff(status); TreeNodeDiff[] children = node.Children.Select(t => new TreeNodeDiff(t, status)).ToArray(); TreeNodeDiff[] emptyChildren = Enumerable.Repeat(emptyElement, childNodeCount).ToArray(); LeftChildren = status == DiffStatus.Added ? emptyChildren : children; RightChildren = status == DiffStatus.Added ? children : emptyChildren; Status = DeepStatus = status; }
private TreeNodeDiff(DiffStatus status) { Name = string.Empty; LeftType = RightType = string.Empty; LeftChildren = RightChildren = new TreeNodeDiff[0]; Status = DeepStatus = status; }
private static TreeNodeDiff[] CreateChildren(TreeNodeDump left, TreeNodeDump right) { List <TreeNodeDiff> children = new List <TreeNodeDiff>(); for (int li = 0, ri = 0; li < left.Children.Count || ri < right.Children.Count;) { if (li == left.Children.Count) { TreeNodeDiff node = new TreeNodeDiff(right.Children[ri], DiffStatus.Added); children.Add(node); ri++; continue; } if (ri == right.Children.Count) { TreeNodeDiff node = new TreeNodeDiff(left.Children[li], DiffStatus.Deleted); children.Add(node); li++; continue; } TreeNodeDump leftChild = left.Children[li]; TreeNodeDump rightChild = right.Children[ri]; if (IsNodeSame(leftChild, rightChild)) { TreeNodeDiff node = new TreeNodeDiff(leftChild, rightChild); children.Add(node); li++; ri++; continue; } if (IsNodePresent(leftChild, right, ri)) { do { TreeNodeDiff node = new TreeNodeDiff(rightChild, DiffStatus.Added); children.Add(node); ri++; rightChild = right.Children[ri]; } while (!IsNodeSame(leftChild, rightChild)); } else { TreeNodeDiff node = new TreeNodeDiff(leftChild, DiffStatus.Deleted); children.Add(node); li++; continue; } } return(children.ToArray()); }
private TreeNodeDiff(TreeNodeDump left, TreeNodeDump right, bool forceMerge) { if (left == null) { throw new ArgumentNullException(nameof(left)); } if (right == null) { throw new ArgumentNullException(nameof(right)); } if (left.Name != right.Name) { throw new ArgumentException("Left and right names aren't equal"); } Name = left.Name ?? throw new ArgumentNullException(nameof(left.Name)); LeftType = left.Type ?? throw new ArgumentNullException(nameof(left.Type)); RightType = right.Type ?? throw new ArgumentNullException(nameof(left.Type)); LeftVersion = left.Version; RightVersion = right.Version; LeftAlign = left.IsAlign; RightAlign = right.IsAlign; Status = (LeftType == RightType && LeftVersion == RightVersion && LeftAlign == RightAlign) ? DiffStatus.Unchanged : DiffStatus.Changed; if (LeftType == RightType || forceMerge) { TreeNodeDiff[] children = CreateChildren(left, right); LeftChildren = RightChildren = children; DeepStatus = children.All(t => t.DeepStatus == DiffStatus.Unchanged) ? Status : DiffStatus.Changed; } else { int leftNodeCount = left.GetNodeCount(); int rightNodeCount = right.GetNodeCount(); int extraLeft = Math.Max(rightNodeCount - leftNodeCount, 0); int extraRight = Math.Max(leftNodeCount - rightNodeCount, 0); TreeNodeDiff extraElement = leftNodeCount == rightNodeCount ? null : new TreeNodeDiff(DiffStatus.Changed); IEnumerable <TreeNodeDiff> extraLeftChildren = Enumerable.Repeat(extraElement, extraLeft); IEnumerable <TreeNodeDiff> extraRightChildren = Enumerable.Repeat(extraElement, extraRight); LeftChildren = left.Children.Select(t => new TreeNodeDiff(t, false)).Concat(extraLeftChildren).ToArray(); RightChildren = right.Children.Select(t => new TreeNodeDiff(t, true)).Concat(extraRightChildren).ToArray(); DeepStatus = DiffStatus.Changed; } }
private void FillTypeTreeItems(List <TreeNodeInfo> items, TreeNodeDiff node, int indent) { TreeNodeInfo info = new TreeNodeInfo(); info.Indent = indent; info.Type = DiffPosition == Position.Left ? node.LeftType : node.RightType; info.Name = node.Name; info.Version = DiffPosition == Position.Left ? node.LeftVersion : node.RightVersion; info.Align = DiffPosition == Position.Left ? node.LeftAlign : node.RightAlign; info.Status = node.Status; items.Add(info); IReadOnlyList <TreeNodeDiff> children = DiffPosition == Position.Left ? node.LeftChildren : node.RightChildren; foreach (TreeNodeDiff child in children) { FillTypeTreeItems(items, child, indent + 1); } }
public TreeDiff(TreeDump left, TreeDump right) { if (left == null) { throw new ArgumentNullException(nameof(left)); } if (right == null) { throw new ArgumentNullException(nameof(right)); } if (left.ClassID != right.ClassID) { throw new ArgumentException($"Left class ID {left.ClassID} doesn't match to right {right.ClassID}"); } ClassID = left.ClassID; LeftClassName = left.ClassName ?? throw new ArgumentNullException(nameof(left.ClassName)); RightClassName = right.ClassName ?? throw new ArgumentNullException(nameof(right.ClassName)); LeftBaseName = left.Inheritance.Count == 0 ? string.Empty : left.Inheritance[0] ?? throw new ArgumentNullException("BaseName"); RightBaseName = right.Inheritance.Count == 0 ? string.Empty : right.Inheritance[0] ?? throw new ArgumentNullException("BaseName"); if (left.IsValid && right.IsValid) { if (left.IsAbstract || right.IsAbstract) { Status = (LeftClassName == RightClassName && LeftBaseName == RightBaseName) ? DiffStatus.Unchanged : DiffStatus.Changed; } else { Node = new TreeNodeDiff(left, right); Status = (LeftClassName == RightClassName && LeftBaseName == RightBaseName) ? Node.DeepStatus : DiffStatus.Changed; } } else { Status = DiffStatus.Invalid; } }