Exemple #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);
        }
        /// <summary>
        /// The write out process involves the following steps:
        /// 1. Back up the files currently in the user's project directory.
        /// 2. Write the template files that are being used to the temporary prevgen directory.
        /// 3. Write the merged files to the user's project directory.
        /// 4. Copy those temporary prevgen files over to the user's prevgen directory.
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="tempController"></param>
        /// <param name="files"></param>
        /// <param name="projectTree"></param>
        public void WriteAllFiles(TaskProgressHelper helper, IController tempController, List <IFileInformation> files, ProjectFileTree projectTree, bool overwriteExistingFiles)
        {
            controller = tempController;

            // Calculate which folders need backing up.
            List <string> directories = new List <string>();

            directories.Add("");             // The root folder.
            foreach (ProjectFileTreeNode node in projectTree.AllNodes)
            {
                if (node.IsFolder == false)
                {
                    continue;
                }
                string path = node.Path;
                if (directories.Contains(path) == false)
                {
                    directories.Add(path);
                }
            }

            //BackupUtility backupUtility = new BackupUtility();
            //string timeString = BackupUtility.GetTimeString();
            //foreach(string dir in directories)
            //{
            //    backupUtility.CreateBackup(
            //    Path.Combine(controller.CurrentProject.ProjectSettings.ProjectPath, dir),
            //    tempController.CurrentProject.ProjectSettings.ProjectGuid,
            //    Path.GetFileNameWithoutExtension(tempController.CurrentProject.ProjectSettings.TemplateFileName),
            //    Path.Combine(controller.CurrentProject.ProjectSettings.ProjectPath, dir),
            //    timeString);
            //}

            foreach (IFileInformation file in files)
            {
                if (file.CurrentDiffResult.DiffType == TypeOfDiff.Conflict)
                {
                    throw new WriteOutException(string.Format("Cannot write out files where a conflict exists! The file {0} has a conflict.", file.RelativeFilePath));
                }
            }

            foreach (IFileInformation file in files)
            {
                WriteSingleFile(file, overwriteExistingFiles);
                // Write the newly generated file to the temporary directory so we can copy it to the prevgen directory in the
                // user's project directory. We do this instead of copying the whole newgen directory so we avoid changing the
                // timestamps on the prevgen files.
                string prevgenPath = controller.GetTempFilePathForComponent(ComponentKey.Workbench_FileGeneratorOutput);
                file.WriteNewGenFile(prevgenPath);

                // TODO: Need to copy the Manifest file over from the temporary prevgen folder to the new one.
                //CopyAllManifestFiles(controller.GetTempFilePathForComponent(ComponentKey.SlyceMerge_PrevGen),
                //                     controller.GetTempFilePathForComponent(ComponentKey.Workbench_FileGeneratorOutput));

                if (file.CodeRootMap != null)
                {
                    CodeRootMapMatchProcessor processor = new CodeRootMapMatchProcessor();
                    string      manifestFilename        = Path.Combine(prevgenPath, ManifestConstants.MANIFEST_FILENAME);
                    XmlDocument doc = ManifestConstants.LoadManifestDocument(manifestFilename);
                    processor.SaveCustomMappings(doc, file.CodeRootMap, Path.GetFileName(file.RelativeFilePath));
                }
            }
            // Copy the temporary files we just created to the user's prevgen directory.
            CreatePrevGenFiles();
        }