/// <summary> /// /// </summary> /// <param name="userUID"></param> /// <param name="newgenUID"></param> /// <param name="prevgenUID"></param> /// <returns></returns> public virtual bool MatchConstructs(string userUID, string newgenUID, string prevgenUID) { if (string.IsNullOrEmpty(userUID) && string.IsNullOrEmpty(newgenUID) && string.IsNullOrEmpty(prevgenUID)) { throw new ArgumentException("Cannot match 3 null objects!"); } // Get Base Constructs. Make sure we can find the ones we are given. IBaseConstruct userBC = GetBaseConstructfromUID(userUID, UserCodeRoot); IBaseConstruct newgenBC = GetBaseConstructfromUID(newgenUID, NewGenCodeRoot); IBaseConstruct prevgenBC = GetBaseConstructfromUID(prevgenUID, PrevGenCodeRoot); if (userBC == null && newgenBC == null && prevgenBC == null) { throw new ArgumentException("Could not find any of the elements specified"); } CodeRootMapNode parent = GetExactNode(userBC ?? newgenBC ?? prevgenBC).ParentNode; if ((newgenBC != null && parent != GetExactNode(newgenBC).ParentNode) || (prevgenBC != null && parent != GetExactNode(prevgenBC).ParentNode)) { throw new ArgumentException("The 3 nodes specified do not belong to the same parent and thus cannot be matched."); } MatchConstructs(parent, userBC, newgenBC, prevgenBC); return(true); }
public CodeRootMapNode(CodeRootMap parentTree, CodeRootMapNode parentNode) { parentCRMTree = parentTree; parentCRMNode = parentNode; parentCRMNode.children.Add(this); parentCRMTree.AddNode(this); }
/// <summary> /// Matches the 3 given nodes for diff and merge purposes. Does not modify the CodeRoots, just rewires the /// CodeRootMap. Only works if the base constructs being matched have the same parent. They may have the same /// parent if their parent has been matched with somthing else. /// </summary> /// <param name="parentNode">The parent CodeRootMapNode of the 3 base constructs. If the BCs were functions, this would /// be the CodeRootMapNode that holds their parent class.</param> /// <param name="userObj">The user object to map.</param> /// <param name="newGenObj">The template object to map.</param> /// <param name="prevGenObj">The prevgen object to map.</param> public void MatchConstructs(CodeRootMapNode parentNode, IBaseConstruct userObj, IBaseConstruct newGenObj, IBaseConstruct prevGenObj) { if (userObj != null) { CodeRootMapNode childNode = parentNode.GetChildNode(userObj); if (childNode == null) { throw new Exception("UserObject not part of this tree"); } childNode.RemoveBaseConstruct(userObj, false); } if (newGenObj != null) { CodeRootMapNode childNode = parentNode.GetChildNode(newGenObj); if (childNode == null) { throw new Exception("NewGen not part of this tree"); } childNode.RemoveBaseConstruct(newGenObj, false); } if (prevGenObj != null) { CodeRootMapNode childNode = parentNode.GetChildNode(prevGenObj); if (childNode == null) { throw new Exception("PrevGen not part of this tree"); } childNode.RemoveBaseConstruct(prevGenObj, false); } CleanUpTree(); CodeRootMapNode newNode = new CodeRootMapNode(parentNode.ParentTree, parentNode); newNode.IsCustomMatch = true; if (userObj != null) { newNode.AddBaseConstruct(userObj, Version.User); } if (newGenObj != null) { newNode.AddBaseConstruct(newGenObj, Version.NewGen); } if (prevGenObj != null) { newNode.AddBaseConstruct(prevGenObj, Version.PrevGen); } }
/// <summary> /// Adds the Base Construct to this node, and processes its children to add them too. /// </summary> /// <param name="bc"></param> /// <param name="t"></param> public CodeRootMapNode AddBaseConstructAsNewChild(IBaseConstruct bc, Version t) { if (bc == null) { return(null); } CodeRootMapNode node = new CodeRootMapNode(ParentTree, this); node.SetBaseConstruct(bc, t); foreach (IBaseConstruct child in bc.WalkChildren()) { node.AddBaseConstructAsNewChild(child, t); } return(node); }
internal void RemoveChildFromTree(CodeRootMapNode node) { allNodes.Remove(node); List <CodeRootMapNode> nodesToRemove = new List <CodeRootMapNode>(); foreach (CodeRootMapNode child in node.ChildNodes) { nodesToRemove.Add(child); } node.ParentNode.RemoveChild(node); foreach (CodeRootMapNode nodeToRemove in nodesToRemove) { RemoveChildFromTree(nodeToRemove); } }
/// <summary> /// Gets a list of nodes that have custom matches. It is guaranteed /// that any custom matched child nodes will come after their ancestors, /// if any of their ancestors are custom matched. /// </summary> /// <returns></returns> public IList <CodeRootMapNode> GetCustomMatchedNodes() { List <CodeRootMapNode> nodes = new List <CodeRootMapNode>(); Queue <CodeRootMapNode> nodesToSearch = new Queue <CodeRootMapNode>(ChildNodes); // Do a breadth first search of all of the nodes in the tree. while (nodesToSearch.Count > 0) { CodeRootMapNode node = nodesToSearch.Dequeue(); if (node.IsCustomMatch) { nodes.Add(node); } foreach (CodeRootMapNode child in node.ChildNodes) { nodesToSearch.Enqueue(child); } } return(nodes); }
internal void RemoveChild(CodeRootMapNode node) { children.Remove(node); node.ParentNode = null; }
/// <summary> /// Override this in the Tree class to provide a method of adding nodes to a collection of all nodes. /// </summary> /// <param name="node">The node to add.</param> /// <exception cref="InvalidOperationException">Thrown if the base version of this method is called. It must be overridden.</exception> protected virtual void AddNode(CodeRootMapNode node) { throw new InvalidOperationException("Cannot call this on a node, must be called on the root Tree."); }
/// <summary> /// Adds node to a collection of all nodes. /// </summary> /// <param name="node">The node to add.</param> protected override void AddNode(CodeRootMapNode node) { allNodes.Add(node); }