Exemplo n.º 1
0
        /// <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>
        /// <remarks>
        /// I've put some Thread.Sleep(1) calls in here to ensure that this processing doesn't bring a single core machine
        /// to its knees. This should ensure that any GUI or other background threads can still get some CPU time,
        /// as there is not much in here that could cause a context switch.
        /// </remarks>
        public bool PerformSuperDiff()
        {
            SetupPerformDiff();

            try
            {
                switch (IntelliMerge)
                {
                case IntelliMergeType.CSharp:
                    CSharpParser formatter = new CSharpParser();

                    try
                    {
                        // Reset the DiffType
                        CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;

                        if (diffCodeRootMap.PrevGenCodeRoot == null && PrevGenFile.HasContents || ReloadFiles)
                        {
                            formatter.Reset();
                            string filename = string.IsNullOrEmpty(PrevGenFile.FilePath) ? "Prev Gen File" : PrevGenFile.FilePath;
                            formatter.ParseCode(filename, PrevGenFile.GetContents());
                            if (formatter.ErrorOccurred)
                            {
                                return(false);
                            }

                            diffCodeRootMap.AddCodeRoot(formatter.CreatedCodeRoot, Version.PrevGen);
                        }
                        // Force a context switch
                        Thread.Sleep(1);

                        if (diffCodeRootMap.NewGenCodeRoot == null && NewGenFile.HasContents || ReloadFiles)
                        {
                            formatter.Reset();
                            string filename = string.IsNullOrEmpty(NewGenFile.FilePath) ? "New Gen File" : NewGenFile.FilePath;
                            formatter.ParseCode(filename, NewGenFile.GetContents());
                            if (formatter.ErrorOccurred)
                            {
                                return(false);
                            }
                            diffCodeRootMap.AddCodeRoot(formatter.CreatedCodeRoot, Version.NewGen);
                        }

                        // Force a context switch
                        Thread.Sleep(1);

                        if (diffCodeRootMap.UserCodeRoot == null && UserFile.HasContents || ReloadFiles)
                        {
                            formatter.Reset();
                            string filename = string.IsNullOrEmpty(UserFile.FilePath) ? "User File" : UserFile.FilePath;
                            formatter.ParseCode(filename, UserFile.GetContents());
                            if (formatter.ErrorOccurred)
                            {
                                return(false);
                            }
                            diffCodeRootMap.AddCodeRoot(formatter.CreatedCodeRoot, Version.User);
                        }

                        // Force a context switch
                        Thread.Sleep(1);

                        // Set this back to false. If it was true, we have reloaded the files, if it was already false this
                        // does nothing.
                        ReloadFiles = false;
                    }
                    catch (Exception ex)
                    {
                        CurrentDiffResult.ParserWarningDescription = ex.Message;
                        return(false);
                    }
                    finally
                    {
                        if (formatter.ErrorOccurred)
                        {
                            CurrentDiffResult.ParserWarningDescription = formatter.GetFormattedErrors();
                        }
                    }

                    if (string.IsNullOrEmpty(temporaryManifestFile) == false && manifestFileApplied == false)
                    {
                        CodeRootMapMatchProcessor processor = new CodeRootMapMatchProcessor();
                        processor.LoadCustomMappings(ManifestConstants.LoadManifestDocument(temporaryManifestFile), diffCodeRootMap, Path.GetFileName(RelativeFilePath));
                        manifestFileApplied = true;
                    }

                    CurrentDiffResult.DiffType = diffCodeRootMap.Diff();

                    if (CurrentDiffResult.DiffType != TypeOfDiff.Conflict && CurrentDiffResult.DiffType != TypeOfDiff.Warning)
                    {
                        //mergedFile = new TextFile(CodeRootMap.GetMergedCodeRoot().ToString());
                        //    Slyce.Common.Utility.WriteToFile(newFile, userFile.GetContents());
                    }



                    break;

                default:
                    // No SuperDiff available for this type of file (no parser created yet).
                    break;
                }
            }
            catch (Exception ex)
            {
                throw new DiffException(ex);
            }

            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Performs the diff between the 3 files, even if some of them do not exist.
        /// </summary>
        protected override bool PerformDiffInternal()
        {
            //////////////////////////
            MergedFile = NewGenFile;

            if (!UserFile.IsFileOnDisk)
            {
                CurrentDiffResult.DiffType = TypeOfDiff.NewFile;
            }
            else if (UserFile.HexStringMD5() == NewGenFile.HexStringMD5())
            {
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
            }
            else
            {
                CurrentDiffResult.DiffType = TypeOfDiff.TemplateChangeOnly;
            }

            return(true);

            ///////////////////////////
            if (IntelliMerge == IntelliMergeType.Overwrite)
            {
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                MergedFile = NewGenFile;
                return(true);
            }

            if (IntelliMerge == IntelliMergeType.CreateOnly)
            {
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                MergedFile = UserFile.HasContents ? UserFile : NewGenFile;

                return(true);
            }

            if (UserFile.HasContents == false && PrevGenFile.HasContents == false && NewGenFile.HasContents == false)
            {
                throw new InvalidOperationException("Cannot perform a diff if there are no files!");
            }

            if (MergedFileExists)
            {
                CurrentDiffResult.DiffPerformedSuccessfully = true;
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                CurrentDiffResult.DiffWarningDescription = CurrentDiffResult.ParserWarningDescription = "";

                return(true);
            }

            if (PrevGenFile.HasContents &&
                UserFile.HasContents &&
                NewGenFile.HasContents)
            {
                // Perform 3-way diff
                string fileBodyParent = PrevGenFile.GetContents();
                string fileBodyUser   = UserFile.GetContents();
                // Template code is not formatted until it is needed. Do the formatting here.

                string           fileBodyGenerated;
                string           mergedText;
                SlyceMergeResult slyceMerge;
                if (IntelliMerge == IntelliMergeType.CSharp)
                {
                    if (NewGenFile.GetContents().Trim() == string.Empty)
                    {
                        fileBodyGenerated = "";
                    }
                    else
                    {
                        CSharpParser formatter = new CSharpParser();
                        formatter.ParseCode(NewGenFile.FilePath, NewGenFile.GetContents());
                        if (formatter.ErrorOccurred)
                        {
                            CurrentDiffResult.ParserWarningDescription = formatter.GetFormattedErrors();
                            return(false);
                        }
                        CodeRoot codeRoot = (CodeRoot)formatter.CreatedCodeRoot;
                        fileBodyGenerated = codeRoot.ToString();
                    }
                    slyceMerge = SlyceMerge.Perform3wayDiff(fileBodyUser, fileBodyParent, fileBodyGenerated, out mergedText, false);
                }
                else
                {
                    fileBodyGenerated = NewGenFile.GetContents();
                    slyceMerge        = SlyceMerge.Perform3wayDiff(fileBodyUser, fileBodyParent, fileBodyGenerated, out mergedText, true);
                    MergedFile        = new TextFile(mergedText);
                }
                CurrentDiffResult.DiffType = slyceMerge.DiffType;

                if (slyceMerge.DiffType == TypeOfDiff.Warning)
                {
                    // TODO: What should be done here?
                    throw new Exception(
                              "There was a warning during the diff process when there shouldn't have been. Please report this to Slyce.");
                }

                if (slyceMerge.DiffType != TypeOfDiff.ExactCopy)
                {
                    return(PerformSuperDiff());
                }

                // File was exact copy - use user version
                MergedFile = new TextFile(fileBodyUser);
            }
            else if (PrevGenFile.HasContents &&
                     UserFile.HasContents == false &&
                     NewGenFile.HasContents)
            {
                // No user file, just use the template file
                CurrentDiffResult.DiffType = TypeOfDiff.Warning;
                CurrentDiffResult.DiffWarningDescription =
                    "The User's version of this file has been deleted or renamed, but the Template and previous version of this file still exist.";
                MergedFile = new TextFile(NewGenFile.GetContents());
            }
            else if (PrevGenFile.HasContents == false &&
                     UserFile.HasContents &&
                     NewGenFile.HasContents)
            {
                //CurrentDiffResult.DiffType = TypeOfDiff.Warning;
                //CurrentDiffResult.DiffWarningDescription =
                //    "User version of a file clashes with a new file the template is trying to create.";

                // Perform 2-way diff
                string fileBodyNewGen = NewGenFile.GetContents();
                string fileBodyUser   = UserFile.GetContents();
                CurrentDiffResult.DiffType = SlyceMerge.PerformTwoWayDiff(fileBodyNewGen, fileBodyUser);

                if (CurrentDiffResult.DiffType != TypeOfDiff.ExactCopy)
                {
                    // Also perform a super diff
                    return(PerformSuperDiff());
                }
                MergedFile = new TextFile(fileBodyUser);
            }
            else if (PrevGenFile.HasContents == false &&
                     UserFile.HasContents == false &&
                     NewGenFile.HasContents)
            {
                // The template has added a new file.
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                MergedFile = new TextFile(NewGenFile.GetContents());
            }
            else
            {
                // Cases covered by this else:
                // * User and prevgen file exist, no template
                // * Prevgen, no user or template.
                // * User file, no template or prevgen
                // TODO: Shouldn't really be a warning...
                CurrentDiffResult.DiffType = TypeOfDiff.Warning;
                throw new Exception(string.Format("TODO: determine course of action, what should be copied to staging folder, because no file exists: \nparent file path:\"{0}\" : {1}\nuser file path:\"{2}\" : {3}\ntemplate file path:\"{4}\" : {5}", PrevGenFile.FilePath, PrevGenFile.HasContents, UserFile.FilePath, UserFile.HasContents, NewGenFile.FilePath, NewGenFile.HasContents));
            }

            return(true);
        }
        /// <summary>
        /// Performs the diff between the 3 files, even if some of them do not exist.
        /// </summary>
        protected override bool PerformDiffInternal()
        {
            MergedFile = NewGenFile;

            if (!UserFile.IsFileOnDisk)
            {
                CurrentDiffResult.DiffType = TypeOfDiff.NewFile;
            }
            else if (UserFile.HexStringMD5() == NewGenFile.HexStringMD5())
            {
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
            }
            else
            {
                CurrentDiffResult.DiffType = TypeOfDiff.TemplateChangeOnly;
            }

            return(true);

            if (IntelliMerge == IntelliMergeType.Overwrite)
            {
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                MergedFile = NewGenFile;
                return(true);
            }

            string crcParent   = PrevGenFile.HasContents ? Common.Utility.GetMD5HashString(PrevGenFile.GetContents()) : "";
            string crcTemplate = NewGenFile.HasContents ? Common.Utility.GetMD5HashString(NewGenFile.GetContents()) : "";
            string crcUser     = UserFile.HasContents ? Common.Utility.GetMD5HashString(UserFile.GetContents()) : "";

            if (!string.IsNullOrEmpty(crcParent) &&
                !string.IsNullOrEmpty(crcTemplate) &&
                !string.IsNullOrEmpty(crcUser))
            {
                if (crcParent == crcUser &&
                    crcUser == crcTemplate)
                {
                    // Nothing has changed. Copy the user file.
                    CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                    MergedFile = new BinaryFile(UserFile.GetContents());
                }
                else if (crcParent == crcUser &&
                         crcParent != crcTemplate)
                {
                    // The template file has changed. Copy the template file.
                    CurrentDiffResult.DiffType = TypeOfDiff.TemplateChangeOnly;
                    MergedFile = new BinaryFile(NewGenFile.GetContents());
                }
                else if (crcParent != crcUser &&
                         crcParent == crcTemplate)
                {
                    // The user file has changed. Copy the user file.
                    CurrentDiffResult.DiffType = TypeOfDiff.UserChangeOnly;
                    MergedFile = new BinaryFile(UserFile.GetContents());
                }
                else if (crcParent != crcUser &&
                         crcUser == crcTemplate)
                {
                    //There are changes in the user and template files that do not conflict
                    CurrentDiffResult.DiffType = TypeOfDiff.UserAndTemplateChange;
                    MergedFile = new BinaryFile(UserFile.GetContents());
                }
                else if (crcParent != crcUser && crcUser != crcTemplate)
                {
                    //There are conflicting changes in the user and template files
                    CurrentDiffResult.DiffType = TypeOfDiff.Conflict;
                }
            }
            else if (string.IsNullOrEmpty(crcParent) &&
                     !string.IsNullOrEmpty(crcTemplate) &&
                     !string.IsNullOrEmpty(crcUser))
            {
                if (crcTemplate == crcUser)
                {
                    CurrentDiffResult.DiffType = TypeOfDiff.UserAndTemplateChange;
                    MergedFile = new BinaryFile(UserFile.GetContents());
                }
                else
                {
                    CurrentDiffResult.DiffType = TypeOfDiff.Conflict;
                }
            }
            else if (!string.IsNullOrEmpty(crcParent) &&
                     !string.IsNullOrEmpty(crcTemplate) &&
                     string.IsNullOrEmpty(crcUser))
            {
                // User file missing. Use new template file.
                if (crcParent == crcTemplate)
                {
                    CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                }
                else
                {
                    CurrentDiffResult.DiffType = TypeOfDiff.TemplateChangeOnly;
                }
                MergedFile = new BinaryFile(NewGenFile.GetContents());
            }
            else if (!string.IsNullOrEmpty(crcParent) &&
                     string.IsNullOrEmpty(crcTemplate) &&
                     !string.IsNullOrEmpty(crcUser))
            {
                // The newgen file is missing but user and prevgen are the same. Mark as ExactCopy
                if (crcUser == crcParent)
                {
                    CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                }
                else
                {
                    CurrentDiffResult.DiffType = TypeOfDiff.UserChangeOnly;
                }
                MergedFile = new BinaryFile(UserFile.GetContents());
            }
            else if (string.IsNullOrEmpty(crcParent) &&
                     !string.IsNullOrEmpty(crcTemplate) &&
                     string.IsNullOrEmpty(crcUser))
            {
                // This is a new file that has been generated
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                MergedFile = new BinaryFile(NewGenFile.GetContents());
            }
            else if (!string.IsNullOrEmpty(crcParent) &&
                     string.IsNullOrEmpty(crcTemplate) &&
                     string.IsNullOrEmpty(crcUser))
            {
                // Only an old template exists
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                MergedFile = new BinaryFile(PrevGenFile.GetContents());
            }
            else if (string.IsNullOrEmpty(crcParent) &&
                     string.IsNullOrEmpty(crcTemplate) &&
                     !string.IsNullOrEmpty(crcUser))
            {
                // Only a user file exists
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                MergedFile = new BinaryFile(UserFile.GetContents());
            }
            else
            {
                throw new NotImplementedException("Not coded yet. Seems like only one version of binary file exists. Probably just need to copy as-is.");
            }

            return(true);
        }