Пример #1
0
        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;
        }
Пример #2
0
 private TreeNodeDiff(DiffStatus status)
 {
     Name         = string.Empty;
     LeftType     = RightType = string.Empty;
     LeftChildren = RightChildren = new TreeNodeDiff[0];
     Status       = DeepStatus = status;
 }
Пример #3
0
        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());
        }
Пример #4
0
        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;
            }
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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;
            }
        }