Exemple #1
0
        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        protected override void MenuItemCallback(object sender, EventArgs e)
        {
            var settings = (FormatterOptionsPage)Package.GetDialogPage(typeof(FormatterOptionsPage));

            // Try to find absolute paths
            var document = VSUtils.GetDTE().ActiveDocument;
            var project  = document.ProjectItem?.ContainingProject;

            if (project == null)
            {
                Output.Instance.WriteLine("The document '{0}' is not part of a project.", document.Name);
            }
            var includeDirectories = VSUtils.GetProjectIncludeDirectories(project);

            // Read.
            var viewHost      = VSUtils.GetCurrentTextViewHost();
            var selectionSpan = GetSelectionSpan(viewHost);

            // Format
            string formatedText = Formatter.IncludeFormatter.FormatIncludes(selectionSpan.GetText(), document.FullName, includeDirectories, settings);

            // Overwrite.
            using (var edit = viewHost.TextView.TextBuffer.CreateEdit())
            {
                edit.Replace(selectionSpan, formatedText);
                edit.Apply();
            }
        }
        private void UpdateVisibility(object sender, EventArgs e)
        {
            // Needs to be part of a VCProject to be applicable.
            var document = VSUtils.GetDTE()?.ActiveDocument;

            menuCommand.Visible = VSUtils.VCUtils.IsVCProject(document?.ProjectItem?.ContainingProject);
        }
Exemple #3
0
        public static async Task <BoolWithReason> CanPerformShowIncludeCompilation(Document document)
        {
            if (CompilationOngoing)
            {
                return(new BoolWithReason
                {
                    Result = false,
                    Reason = "Can't compile while another file is being compiled.",
                });
            }

            var dte = VSUtils.GetDTE();

            if (dte == null)
            {
                return(new BoolWithReason
                {
                    Result = false,
                    Reason = "Failed to acquire dte object.",
                });
            }

            var result = await VSUtils.VCUtils.IsCompilableFile(document);

            if (result.Result == false)
            {
                result.Reason = $"Can't extract include graph since current file '{document?.FullName ?? "<no file>"}' can't be compiled: {result.Reason}.";
                return(result);
            }

            return(new BoolWithReason {
                Result = true, Reason = ""
            });
        }
        static Project GetSelectedCppProject(out string reasonForFailure)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            reasonForFailure = "";

            var selectedItems = VSUtils.GetDTE().SelectedItems;

            if (selectedItems.Count < 1)
            {
                reasonForFailure = "Selection is empty!";
                return(null);
            }

            // Reading .Item(object) behaves weird, but iterating works.
            foreach (SelectedItem item in selectedItems)
            {
                Project vcProject = item?.Project;
                if (VSUtils.VCUtils.IsVCProject(vcProject))
                {
                    return(vcProject);
                }
            }

            reasonForFailure = "Selection does not contain a C++ project!";
            return(null);
        }
Exemple #5
0
        private async Task PerformanceTrialAndErrorRemovel()
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            List <string> proNames = new List <string>();

            vcProjects.Clear();
            Projects allProjs = VSUtils.GetDTE().Solution.Projects;

            foreach (Project proj in allProjs)
            {
                if (VSUtils.VCUtils.IsVCProject(proj))
                {
                    proNames.Add(proj.Name);
                    vcProjects.Enqueue(proj);
                }
            }
            {// to delete
                Utils.SaveProjectsConfig(proNames);
            }

            if (await Output.Instance.YesNoMsg("Attention! Trial and error include removal on large solution make take up to several hours! In this time you will not be able to use Visual Studio. Are you sure you want to continue?")
                != Output.MessageResult.Yes)
            {
                return;
            }

            numTotoalProcessedFiles = 0;
            numTotalRemovedIncludes = 0;

            await ProcessNextProject();
        }
        private void UpdateVisibility(object sender, EventArgs e)
        {
            string reason;
            bool   isHeader;
            var    config = CompileUnityFile.GetFileConfig(VSUtils.GetDTE().ActiveDocument, out reason, out isHeader);

            menuCommand.Visible = (config != null) && !isHeader;
        }
Exemple #7
0
        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        protected override async Task MenuItemCallback(object sender, EventArgs e)
        {
            var document = VSUtils.GetDTE().ActiveDocument;

            if (document != null)
            {
                await impl.PerformTrialAndErrorIncludeRemoval(document, (TrialAndErrorRemovalOptionsPage)Package.GetDialogPage(typeof(TrialAndErrorRemovalOptionsPage)));
            }
        }
        private static void ResetPendingCompilationInfo()
        {
            string reasonForFailure;

            VSUtils.VCUtils.SetCompilerSetting_ShowIncludes(documentBeingCompiled.ProjectItem?.ContainingProject, showIncludeSettingBefore, out reasonForFailure);

            onCompleted           = null;
            documentBeingCompiled = null;
            graphBeingExtended    = null;

            VSUtils.GetDTE().Events.BuildEvents.OnBuildDone -= OnBuildConfigFinished;
        }
        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        protected override void MenuItemCallback(object sender, EventArgs e)
        {
            var document = VSUtils.GetDTE().ActiveDocument;

            if (document != null)
            {
                try
                {
                    impl.PerformCompileUnityFile(document);
                }
                catch (Exception ex)
                {
                    Output.Instance.WriteLine("Unexpected error: {0}", ex);
                }
            }
        }
Exemple #10
0
        private static async Task ResetPendingCompilationInfo()
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            try
            {
                VSUtils.VCUtils.SetCompilerSetting_ShowIncludes(documentBeingCompiled.ProjectItem?.ContainingProject, showIncludeSettingBefore);
            }
            catch (VCQueryFailure) { }

            onCompleted           = null;
            documentBeingCompiled = null;
            graphBeingExtended    = null;

            VSUtils.GetDTE().Events.BuildEvents.OnBuildDone -= OnBuildConfigFinished;
        }
        public static bool CanPerformShowIncludeCompilation(Document document, out string reasonForFailure)
        {
            if (CompilationOngoing)
            {
                reasonForFailure = "Can't compile while another file is being compiled.";
                return(false);
            }

            var dte = VSUtils.GetDTE();

            if (dte == null)
            {
                reasonForFailure = "Failed to acquire dte object.";
                return(false);
            }

            if (VSUtils.VCUtils.IsCompilableFile(document, out reasonForFailure) == false)
            {
                reasonForFailure = string.Format("Can't extract BuildTime graph since current file '{0}' can't be compiled: {1}.", document?.FullName ?? "<no file>", reasonForFailure);
                return(false);
            }

            return(true);
        }
Exemple #12
0
        /// <summary>
        /// Parses a given source file using cl.exe with the /showIncludes option and adds the output to the original graph.
        /// </summary>
        /// <remarks>
        /// If this is the first file, the graph is necessarily a tree after this operation.
        /// </remarks>
        /// <returns>true if successful, false otherwise.</returns>
        public static async Task <bool> AddIncludesRecursively_ShowIncludesCompilation(this IncludeGraph graph, Document document, OnCompleteCallback onCompleted)
        {
            var canPerformShowIncludeCompilation = await CanPerformShowIncludeCompilation(document);

            if (!canPerformShowIncludeCompilation.Result)
            {
                await Output.Instance.ErrorMsg(canPerformShowIncludeCompilation.Reason);

                return(false);
            }

            try
            {
                var dte = VSUtils.GetDTE();
                if (dte == null)
                {
                    await Output.Instance.ErrorMsg("Failed to acquire dte object.");

                    return(false);
                }

                try
                {
                    await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                    showIncludeSettingBefore = VSUtils.VCUtils.GetCompilerSetting_ShowIncludes(document.ProjectItem?.ContainingProject);
                    VSUtils.VCUtils.SetCompilerSetting_ShowIncludes(document.ProjectItem?.ContainingProject, true);
                }
                catch (VCQueryFailure queryFailure)
                {
                    await Output.Instance.ErrorMsg("Can't compile with show includes: {0}.", queryFailure.Message);

                    return(false);
                }

                // Only after we're through all early out error cases, set static compilation infos.
                dte.Events.BuildEvents.OnBuildDone               += OnBuildConfigFinished;
                CompilationBasedGraphParser.onCompleted           = onCompleted;
                CompilationBasedGraphParser.documentBeingCompiled = document;
                CompilationBasedGraphParser.graphBeingExtended    = graph;

                // Even with having the config changed and having compile force==true, we still need to make a dummy change in order to enforce recompilation of this file.
                {
                    document.Activate();
                    var documentTextView = VSUtils.GetCurrentTextViewHost();
                    var textBuffer       = documentTextView.TextView.TextBuffer;
                    using (var edit = textBuffer.CreateEdit())
                    {
                        edit.Insert(0, " ");
                        edit.Apply();
                    }
                    using (var edit = textBuffer.CreateEdit())
                    {
                        edit.Replace(new Microsoft.VisualStudio.Text.Span(0, 1), "");
                        edit.Apply();
                    }
                }

                await VSUtils.VCUtils.CompileSingleFile(document);
            }
            catch (Exception e)
            {
                await ResetPendingCompilationInfo();

                await Output.Instance.ErrorMsg("Compilation of file '{0}' with /showIncludes failed: {1}.", document.FullName, e);

                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Parses a given source file using cl.exe with the /showIncludes option and adds the output to the original graph.
        /// </summary>
        /// <remarks>
        /// If this is the first file, the graph is necessarily a tree after this operation.
        /// </remarks>
        /// <returns>true if successful, false otherwise.</returns>
        public static bool AddIncludesRecursively_ShowIncludesCompilation(this IncludeGraph graph, Document document, OnCompleteCallback onCompleted)
        {
            if (!CanPerformShowIncludeCompilation(document, out string reasonForFailure))
            {
                Output.Instance.ErrorMsg(reasonForFailure);
                return(false);
            }

            try
            {
                var dte = VSUtils.GetDTE();
                if (dte == null)
                {
                    Output.Instance.ErrorMsg("Failed to acquire dte object.");
                    return(false);
                }

                {
                    bool?setting = VSUtils.VCUtils.GetCompilerSetting_ShowIncludes(document.ProjectItem?.ContainingProject, out reasonForFailure);
                    if (!setting.HasValue)
                    {
                        Output.Instance.ErrorMsg("Can't compile with show includes: {0}.", reasonForFailure);
                        return(false);
                    }
                    else
                    {
                        showIncludeSettingBefore = setting.Value;
                    }

                    VSUtils.VCUtils.SetCompilerSetting_ShowIncludes(document.ProjectItem?.ContainingProject, true, out reasonForFailure);
                    if (!string.IsNullOrEmpty(reasonForFailure))
                    {
                        Output.Instance.ErrorMsg("Can't compile with show includes: {0}.", reasonForFailure);
                        return(false);
                    }
                }

                // Only after we're through all early out error cases, set static compilation infos.
                dte.Events.BuildEvents.OnBuildDone               += OnBuildConfigFinished;
                CompilationBasedGraphParser.onCompleted           = onCompleted;
                CompilationBasedGraphParser.documentBeingCompiled = document;
                CompilationBasedGraphParser.graphBeingExtended    = graph;

                // Even with having the config changed and having compile force==true, we still need to make a dummy change in order to enforce recompilation of this file.
                {
                    document.Activate();
                    var documentTextView = VSUtils.GetCurrentTextViewHost();
                    var textBuffer       = documentTextView.TextView.TextBuffer;
                    using (var edit = textBuffer.CreateEdit())
                    {
                        edit.Insert(0, " ");
                        edit.Apply();
                    }
                    using (var edit = textBuffer.CreateEdit())
                    {
                        edit.Replace(new Microsoft.VisualStudio.Text.Span(0, 1), "");
                        edit.Apply();
                    }
                }

                VSUtils.VCUtils.CompileSingleFile(document);
            }
            catch (Exception e)
            {
                ResetPendingCompilationInfo();
                Output.Instance.ErrorMsg("Compilation of file '{0}' with /showIncludes failed: {1}.", document.FullName, e);
                return(false);
            }

            return(true);
        }
        private void UpdateVisibility(object sender, EventArgs e)
        {
            string reason;

            menuCommand.Visible = VSUtils.VCUtils.IsCompilableFile(VSUtils.GetDTE().ActiveDocument, out reason);
        }
Exemple #15
0
 private async void UpdateVisibility(object sender, EventArgs e)
 {
     menuCommand.Visible = (await VSUtils.VCUtils.IsCompilableFile(VSUtils.GetDTE().ActiveDocument)).Result;
 }
Exemple #16
0
        static private void ApplyTasks(Dictionary <string, FormatTask> tasks, bool applyFormatting, FormatterOptionsPage formatSettings)
        {
            var dte = VSUtils.GetDTE();

            foreach (KeyValuePair <string, FormatTask> entry in tasks)
            {
                string        filename   = entry.Key.Replace('/', '\\'); // Classy. But Necessary.
                EnvDTE.Window fileWindow = dte.ItemOperations.OpenFile(filename);
                if (fileWindow == null)
                {
                    Output.Instance.ErrorMsg("Failed to open File {0}", filename);
                    continue;
                }
                fileWindow.Activate();

                var viewHost = VSUtils.GetCurrentTextViewHost();
                using (var edit = viewHost.TextView.TextBuffer.CreateEdit())
                {
                    var originalLines = edit.Snapshot.Lines.ToArray();

                    // Determine which line ending to use by majority.
                    string lineEndingToBeUsed = Utils.GetDominantNewLineSeparator(edit.Snapshot.GetText());

                    // Add lines.
                    {
                        // Find last include.
                        // Will find even if commented out, but we don't care.
                        int lastIncludeLine = -1;
                        for (int line = originalLines.Length - 1; line >= 0; --line)
                        {
                            if (originalLines[line].GetText().Contains("#include"))
                            {
                                lastIncludeLine = line;
                                break;
                            }
                        }

                        // Build replacement string
                        StringBuilder stringToInsertBuilder = new StringBuilder();
                        foreach (string lineToAdd in entry.Value.linesToAdd)
                        {
                            stringToInsertBuilder.Append(lineToAdd);
                            stringToInsertBuilder.Append(lineEndingToBeUsed);
                        }
                        string stringToInsert = stringToInsertBuilder.ToString();


                        // optional, format before adding.
                        if (applyFormatting)
                        {
                            var includeDirectories = VSUtils.GetProjectIncludeDirectories(fileWindow.Document.ProjectItem?.ContainingProject);
                            stringToInsert = Formatter.IncludeFormatter.FormatIncludes(stringToInsert, fileWindow.Document.FullName, includeDirectories, formatSettings);

                            // Add a newline if we removed it.
                            if (formatSettings.RemoveEmptyLines)
                            {
                                stringToInsert += lineEndingToBeUsed;
                            }
                        }

                        // Insert.
                        int insertPosition = 0;
                        if (lastIncludeLine >= 0 && lastIncludeLine < originalLines.Length)
                        {
                            insertPosition = originalLines[lastIncludeLine].EndIncludingLineBreak;
                        }
                        edit.Insert(insertPosition, stringToInsert.ToString());
                    }

                    // Remove lines.
                    // It should safe to do that last since we added includes at the bottom, this way there is no confusion with the text snapshot.
                    {
                        foreach (int lineToRemove in entry.Value.linesToRemove.Reverse())
                        {
                            if (!Formatter.IncludeLineInfo.ContainsPreserveFlag(originalLines[lineToRemove].GetText()))
                            {
                                edit.Delete(originalLines[lineToRemove].ExtentIncludingLineBreak);
                            }
                        }
                    }

                    edit.Apply();
                }

                // For Debugging:
                //Output.Instance.WriteLine("");
                //Output.Instance.WriteLine(entry.Key);
                //Output.Instance.WriteLine(entry.Value.ToString());
            }
        }
        /// <summary>
        /// This function is the callback used to execute the command when the menu item is clicked.
        /// See the constructor to see how the menu item is associated with this function using
        /// OleMenuCommandService service and MenuCommand class.
        /// </summary>
        /// <param name="sender">Event sender.</param>
        /// <param name="e">Event args.</param>
        protected override async Task MenuItemCallback(object sender, EventArgs e)
        {
            await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

            var settingsIwyu = (IncludeWhatYouUseOptionsPage)Package.GetDialogPage(typeof(IncludeWhatYouUseOptionsPage));

            Output.Instance.Clear();

            var document = VSUtils.GetDTE().ActiveDocument;

            if (document == null)
            {
                Output.Instance.WriteLine("No active document!");
                return;
            }
            var project = document.ProjectItem?.ContainingProject;

            if (project == null)
            {
                Output.Instance.WriteLine("The document {0} is not part of a project.", document.Name);
                return;
            }

            var dialogFactory = ServiceProvider.GetService(typeof(SVsThreadedWaitDialogFactory)) as IVsThreadedWaitDialogFactory;

            if (dialogFactory == null)
            {
                Output.Instance.WriteLine("Failed to get IVsThreadedWaitDialogFactory service.");
                return;
            }

            await OptionalDownloadOrUpdate(settingsIwyu, dialogFactory);

            // We should really have it now, but just in case our update or download method screwed up.
            if (!File.Exists(settingsIwyu.ExecutablePath))
            {
                await Output.Instance.ErrorMsg("Unexpected error: Can't find include-what-you-use.exe after download/update.");

                return;
            }
            checkedForUpdatesThisSession = true;

            // Save all documents.
            try
            {
                document.DTE.Documents.SaveAll();
            }
            catch (Exception saveException)
            {
                Output.Instance.WriteLine("Failed to get save all documents: {0}", saveException);
            }

            // Start wait dialog.
            {
                IVsThreadedWaitDialog2 dialog = null;
                dialogFactory.CreateInstance(out dialog);
                dialog?.StartWaitDialog("Include Toolbox", "Running include-what-you-use", null, null, "Running include-what-you-use", 0, false, true);

                string output = await IWYU.RunIncludeWhatYouUse(document.FullName, project, settingsIwyu);

                if (settingsIwyu.ApplyProposal && output != null)
                {
                    var settingsFormatting = (FormatterOptionsPage)Package.GetDialogPage(typeof(FormatterOptionsPage));
                    await IWYU.Apply(output, settingsIwyu.RunIncludeFormatter, settingsFormatting);
                }

                dialog?.EndWaitDialog();
            }
        }