/// <summary> /// Generates the Merged CodeRoot object. /// </summary> /// <exception cref="InvalidOperationException">If no code roots have been added, or there is a conflict.</exception> /// <returns></returns> public ICodeRoot GetMergedCodeRoot() { ICodeRoot originalCodeRoot = coderoots.GetFirstNonNullObject(); if (originalCodeRoot == null) { throw new InvalidOperationException("Cannot merge code roots when none have been added"); } ICodeRoot newCodeRoot = originalCodeRoot.NewInstance(); originalCodeRoot.ShallowCloneInto(newCodeRoot); foreach (CodeRootMapNode child in children) { MissingObject missingObjects = child.DetermineMissingConstructs(); if ((missingObjects & MissingObject.User) != 0 && (missingObjects & MissingObject.NewGen) != 0) { // Only PrevGen here. Ignore it. continue; } newCodeRoot.AddChild(child.GetMergedBaseConstruct()); } return(newCodeRoot); }
/// <summary> /// Constructs the form using the given map info as the source of constructs to match, /// and the given file information as a source of constructs to use as matches /// </summary> /// <param name="fileInfo"></param> /// <param name="node"></param> public FormSelectMatch(TextFileInformation fileInfo, CodeRootMapNode node) { InitializeComponent(); FormSelectMatchHeading.Text = ""; ArchAngel.Interfaces.Events.ShadeMainForm(); fileInformation = fileInfo; currentNode = node; if (fileInformation.CodeRootMap == null) { throw new ArgumentException("Cannot match constructs if the diff has not or cannot be performed."); } if (node.ContainsBaseConstruct == false) { throw new ArgumentException( "Cannot match constructs when there are no constucts set in the MapInfoType given. " + "Please set at least one of these constructs before starting the Select Match Form."); } missingObjects = node.DetermineMissingConstructs(); FillOptionsForConstructs(); FillComboBoxes(); SetDefaultSelectedConstruct(); }
/// <summary> /// Constructs the form using the given map info as the source of constructs to match, /// and the given file information as a source of constructs to use as matches /// </summary> /// <param name="fileInfo"></param> /// <param name="node"></param> public FormSelectMatch(TextFileInformation fileInfo, CodeRootMapNode node) { InitializeComponent(); FormSelectMatchHeading.Text = ""; ArchAngel.Interfaces.Events.ShadeMainForm(); fileInformation = fileInfo; currentNode = node; if(fileInformation.CodeRootMap == null) { throw new ArgumentException("Cannot match constructs if the diff has not or cannot be performed."); } if (node.ContainsBaseConstruct == false) { throw new ArgumentException( "Cannot match constructs when there are no constucts set in the MapInfoType given. " + "Please set at least one of these constructs before starting the Select Match Form."); } missingObjects = node.DetermineMissingConstructs(); FillOptionsForConstructs(); FillComboBoxes(); SetDefaultSelectedConstruct(); }
/// <summary> /// Returns a MissingObject enum with flags set for each constuct that is missing. /// </summary> /// <returns>A MissingObject enum with flags set for each constuct that is missing.</returns> public MissingObject DetermineMissingConstructs() { MissingObject missing = MissingObject.None; if (User == null) { missing |= MissingObject.User; } if (PrevGen == null) { missing |= MissingObject.PrevGen; } if (NewGen == null) { missing |= MissingObject.NewGen; } return(missing); }
/// <summary> /// Returns a IBaseConstruct which is the result of merging the BaseConstructs in this subtree. /// </summary> /// <returns>A IBaseConstruct which is the result of merging the BaseConstructs in this subtree.</returns> /// <exception cref="InvalidOperationException">Thrown if there are no BaseConstructs in this node /// or any of its children.</exception> public virtual IBaseConstruct GetMergedBaseConstruct() { if (mergedObj != null) { return(mergedObj); } IBaseConstruct newBc = baseConstructs.GetFirstNonNullObject(); if (newBc == null) { throw new InvalidOperationException( "Cannot create a merged IBaseConstruct because this node contains no data"); } newBc = newBc.Clone(); if (baseConstructs.DetermineMissingConstructs() == MissingObject.None) { bool result = newBc.CustomMergeStep(baseConstructs.User, baseConstructs.NewGen, baseConstructs.PrevGen); if (result == false) { // Need to notify the user of this issue. throw new MergeException("Could not perform automatic merge, CustomMergeStep failed. ", GetFirstValidBaseConstruct().FullyQualifiedIdentifer, GetFirstValidBaseConstruct().GetType().ToString()); } } if (newBc is IBody) { IBody bodyNode = (IBody)newBc; string userText = GetBodyText(UserObj); string newgenText = GetBodyText(NewGenObj); string prevgenText = GetBodyText(PrevGenObj); if (UserObj == null && NewGenObj != null) { bodyNode.BodyText = newgenText; } else if (NewGenObj == null && UserObj != null) { bodyNode.BodyText = userText; } else { string mergedText; TypeOfDiff result = SlyceMerge.Perform3wayDiff(userText, prevgenText, newgenText, out mergedText).DiffType; if (result == TypeOfDiff.Conflict) { throw new InvalidOperationException("Cannot merge BaseConstructs if there is a conflict in their body text."); } bodyNode.BodyText = mergedText; } } foreach (CodeRootMapNode child in children) { MissingObject missingObjects = child.DetermineMissingConstructs(); if ((missingObjects & MissingObject.NewGen) != 0 && (missingObjects & MissingObject.User) != 0) { continue; } IBaseConstruct childBC = child.GetMergedBaseConstruct(); newBc.AddChild(childBC); } return(newBc); }