/// <summary> /// Performs an in depth diff by breaking code files into their constituent parts (functions, properties /// etc, so that these elements can be diffed without regard to their ordering. /// </summary> /// <param name="diffFile"></param> private void PerformSuperDiff(ref DiffFile diffFile) { try { switch (Path.GetExtension(diffFile.Path).ToLower()) { case ".cs": Providers.CSharpFormatter formatter = new Providers.CSharpFormatter(diffFile.Path); formatter.CreateObjectModel = true; formatter.RaiseError += formatter_RaiseError; try { // TODO: get the code for each file type (user, generated, prevGen), then // break into classes, functions etc, and perform a diff3 on each entity. // We REALLY need to store these results in the objects, so that this process // happens once, when the initial population occurs, and doesn't need to happen // again when the user clicks a childTreeListNode to display the text and conflicts. // Reset the DiffType diffFile.DiffType = TypeOfDiff.ExactCopy; if (File.Exists(diffFile.FilePathPrevGen)) { formatter.Reset(); formatter.CodeFilePath = diffFile.FilePathPrevGen; formatter.GetFormattedCode(Slyce.Common.Utility.ReadTextFile(diffFile.FilePathPrevGen)); diffFile.CodeRootParent = formatter.Controller.Root; diffFile.CodeRootParent.SortAllMembers(); } if (File.Exists(diffFile.FilePathTemplate)) { formatter.Reset(); formatter.CodeFilePath = diffFile.FilePathTemplate; formatter.GetFormattedCode(Slyce.Common.Utility.ReadTextFile(diffFile.FilePathTemplate)); diffFile.CodeRootTemplate = formatter.Controller.Root; diffFile.CodeRootTemplate.SortAllMembers(); } if (File.Exists(diffFile.FilePathUser)) { formatter.Reset(); formatter.CodeFilePath = diffFile.FilePathUser; formatter.GetFormattedCode(Slyce.Common.Utility.ReadTextFile(diffFile.FilePathUser)); diffFile.CodeRootUser = formatter.Controller.Root; diffFile.CodeRootUser.SortAllMembers(); // TODO: this check of whether the code object model has been correctly created must get removed from the final build //string code = diffFile.CodeRootUser.ToString(); //formatter.Reset(); //formatter.ParseCode(code); //if (!diffFile.CodeRootUser.IsTheSame(ArchAngel.Providers.CodeProvider.Controller.Root)) //{ // throw new InvalidProgramException("The code object model has not been written correctly: " + ArchAngel.Providers.CodeProvider.CSharp.BaseConstruct.ComparisonDifference); //} } } catch (Exception ex) { diffFile.ParseErrorDescription = ex.Message; } bool ignoreAllOmits = false; if (File.Exists(diffFile.FilePathTemplate) && !File.Exists(diffFile.FilePathUser)) { // If the user file is missing, then all code objects are also going to be missing and // will therefore get marked at 'Omit = true', but infact we need to generate them. ignoreAllOmits = true; } TypeOfDiff resultingDiffType; Providers.CodeProvider.CSharp.Utility utility = new Providers.CodeProvider.CSharp.Utility(); diffFile.CodeRootAll = utility.CreateCombinedCodeRoot(diffFile.CodeRootTemplate, diffFile.CodeRootUser, diffFile.CodeRootParent, out resultingDiffType, ignoreAllOmits); diffFile.CodeRootAll.SortAllMembers(); diffFile.DiffType = resultingDiffType; break; default: // No SuperDiff available for this type of file (no parser created yet). break; } } catch (Exception ex) { Controller.ReportError(ex); } }