Esempio n. 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();
            }
        }
Esempio n. 2
0
        private void UpdateVisibility(object sender, EventArgs e)
        {
            // Check whether any includes are selected.
            var viewHost      = VSUtils.GetCurrentTextViewHost();
            var selectionSpan = GetSelectionSpan(viewHost);
            var lines         = Formatter.IncludeLineInfo.ParseIncludes(selectionSpan.GetText(), Formatter.ParseOptions.RemoveEmptyLines);

            menuCommand.Visible = lines.Any(x => x.ContainsActiveInclude);
        }
Esempio n. 3
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);
        }
Esempio n. 4
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>
        /// 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);
        }