Ejemplo n.º 1
0
        static CommandInfoSet CreateFixMenu(TextEditor editor, DocumentContext ctx, CodeActionContainer container)
        {
            if (editor == null)
            {
                throw new ArgumentNullException("editor");
            }
            if (ctx == null)
            {
                throw new ArgumentNullException("ctx");
            }
            if (container == null)
            {
                throw new ArgumentNullException("container");
            }
            var result = new CommandInfoSet();

            result.Text = GettextCatalog.GetString("Fix");
            foreach (var diagnostic in container.CodeFixActions)
            {
                var info = new CommandInfo(diagnostic.CodeAction.Title);
                result.CommandInfos.Add(info, new Action(async() => await new CodeActionEditorExtension.ContextActionRunner(diagnostic.CodeAction, editor, ctx).Run()));
            }
            if (result.CommandInfos.Count == 0)
            {
                return(result);
            }
            bool firstDiagnosticOption = true;

            foreach (var fix in container.DiagnosticsAtCaret)
            {
                var inspector = BuiltInCodeDiagnosticProvider.GetCodeDiagnosticDescriptor(fix.Id);
                if (inspector == null)
                {
                    continue;
                }

                if (firstDiagnosticOption)
                {
                    result.CommandInfos.AddSeparator();
                    firstDiagnosticOption = false;
                }

                var label   = GettextCatalog.GetString("_Options for \"{0}\"", fix.GetMessage());
                var subMenu = new CommandInfoSet();
                subMenu.Text = label;

//				if (inspector.CanSuppressWithAttribute) {
//					var menuItem = new FixMenuEntry (GettextCatalog.GetString ("_Suppress with attribute"),
//						delegate {
//
//							inspector.SuppressWithAttribute (Editor, DocumentContext, GetTextSpan (fix.Item2));
//						});
//					subMenu.Add (menuItem);
//				}

                if (inspector.CanDisableWithPragma)
                {
                    var info = new CommandInfo(GettextCatalog.GetString("_Suppress with #pragma"));
                    subMenu.CommandInfos.Add(info, new Action(() => inspector.DisableWithPragma(editor, ctx, fix)));

                    info = new CommandInfo(GettextCatalog.GetString("_Suppress with file"));
                    subMenu.CommandInfos.Add(info, new Action(() => inspector.DisableWithFile(editor, ctx, fix)));
                }

                var configInfo = new CommandInfo(GettextCatalog.GetString("_Configure Rule"));
                subMenu.CommandInfos.Add(configInfo, new Action(() => {
                    IdeApp.Workbench.ShowGlobalPreferencesDialog(null, "C#", dialog => {
                        var panel = dialog.GetPanel <CodeIssuePanel> ("C#");
                        if (panel == null)
                        {
                            return;
                        }
                        panel.Widget.SelectCodeIssue(inspector.IdString);
                    });
                }));

                foreach (var fix2 in container.CodeFixActions)
                {
                    var provider = fix2.Diagnostic.GetCodeFixProvider().GetFixAllProvider();
                    if (provider == null)
                    {
                        continue;
                    }
                    if (!provider.GetSupportedFixAllScopes().Contains(FixAllScope.Document))
                    {
                        continue;
                    }
                    var subMenu2 = new CommandInfoSet();
                    subMenu2.Text = GettextCatalog.GetString("Fix all");
                    var diagnosticAnalyzer = fix2.Diagnostic.GetCodeDiagnosticDescriptor(LanguageNames.CSharp).GetProvider();
                    if (!diagnosticAnalyzer.SupportedDiagnostics.Contains(fix.Descriptor))
                    {
                        continue;
                    }

                    var info = new CommandInfo(GettextCatalog.GetString("In _Document"));
                    subMenu2.CommandInfos.Add(info, new Action(async delegate {
                        var fixAllDiagnosticProvider = new CodeActionEditorExtension.FixAllDiagnosticProvider(diagnosticAnalyzer.SupportedDiagnostics.Select(d => d.Id).ToImmutableHashSet(), async(Microsoft.CodeAnalysis.Document doc, ImmutableHashSet <string> diagnostics, CancellationToken token) => {
                            var model = await doc.GetSemanticModelAsync(token);
                            var compilationWithAnalyzer = model.Compilation.WithAnalyzers(new [] { diagnosticAnalyzer }.ToImmutableArray(), null, token);

                            return(await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync(model, null, token));
                        }, (arg1, arg2, arg3, arg4) => {
                            return(Task.FromResult((IEnumerable <Diagnostic>) new Diagnostic[] { }));
                        });
                        var ctx2 = new FixAllContext(
                            ctx.AnalysisDocument,
                            fix2.Diagnostic.GetCodeFixProvider(),
                            FixAllScope.Document,
                            fix2.CodeAction.EquivalenceKey,
                            diagnosticAnalyzer.SupportedDiagnostics.Select(d => d.Id),
                            fixAllDiagnosticProvider,
                            default(CancellationToken)
                            );
                        var fixAll = await provider.GetFixAsync(ctx2);
                        using (var undo = editor.OpenUndoGroup()) {
                            CodeDiagnosticDescriptor.RunAction(ctx, fixAll, default(CancellationToken));
                        }
                    }));
                    subMenu.CommandInfos.Add(subMenu2);
                }
                result.CommandInfos.Add(subMenu);
            }

            return(result);
        }
Ejemplo n.º 2
0
        void PopulateFixes(FixMenuDescriptor menu, ref int items)
        {
            int  mnemonic = 1;
            bool gotImportantFix = false, addedSeparator = false;

            foreach (var fix_ in GetCurrentFixes().CodeFixActions.OrderByDescending(i => Tuple.Create(IsAnalysisOrErrorFix(i.CodeAction), (int)0, GetUsage(i.CodeAction.EquivalenceKey))))
            {
                // filter out code actions that are already resolutions of a code issue
                if (IsAnalysisOrErrorFix(fix_.CodeAction))
                {
                    gotImportantFix = true;
                }
                if (!addedSeparator && gotImportantFix && !IsAnalysisOrErrorFix(fix_.CodeAction))
                {
                    menu.Add(FixMenuEntry.Separator);
                    addedSeparator = true;
                }

                var fix   = fix_;
                var label = CreateLabel(fix.CodeAction.Title, ref mnemonic);
                var thisInstanceMenuItem = new FixMenuEntry(label, async delegate {
                    await new ContextActionRunner(fix.CodeAction, Editor, DocumentContext).Run();
                    ConfirmUsage(fix.CodeAction.EquivalenceKey);
                });
                menu.Add(thisInstanceMenuItem);
                items++;
            }

            bool first = true;

            foreach (var fix in GetCurrentFixes().CodeRefactoringActions)
            {
                if (first)
                {
                    if (items > 0)
                    {
                        menu.Add(FixMenuEntry.Separator);
                    }
                    first = false;
                }

                var label = CreateLabel(fix.CodeAction.Title, ref mnemonic);
                var thisInstanceMenuItem = new FixMenuEntry(label, async delegate {
                    await new ContextActionRunner(fix.CodeAction, Editor, DocumentContext).Run();
                    ConfirmUsage(fix.CodeAction.EquivalenceKey);
                });
                menu.Add(thisInstanceMenuItem);
                items++;
            }

            first = false;
            foreach (var fix_ in GetCurrentFixes().DiagnosticsAtCaret)
            {
                var fix     = fix_;
                var label   = GettextCatalog.GetString("_Options for \"{0}\"", fix.GetMessage());
                var subMenu = new FixMenuDescriptor(label);

                CodeDiagnosticDescriptor descriptor = BuiltInCodeDiagnosticProvider.GetCodeDiagnosticDescriptor(fix.Id);
                if (descriptor == null)
                {
                    continue;
                }
                if (first)
                {
                    menu.Add(FixMenuEntry.Separator);
                    first = false;
                }
                //				if (inspector.CanSuppressWithAttribute) {
                //					var menuItem = new FixMenuEntry (GettextCatalog.GetString ("_Suppress with attribute"),
                //						delegate {
                //
                //							inspector.SuppressWithAttribute (Editor, DocumentContext, GetTextSpan (fix.Item2));
                //						});
                //					subMenu.Add (menuItem);
                //				}

                if (descriptor.CanDisableWithPragma)
                {
                    var menuItem = new FixMenuEntry(GettextCatalog.GetString("_Suppress with #pragma"),
                                                    delegate {
                        descriptor.DisableWithPragma(Editor, DocumentContext, fix);
                    });
                    subMenu.Add(menuItem);
                    menuItem = new FixMenuEntry(GettextCatalog.GetString("_Suppress with file"),
                                                delegate {
                        descriptor.DisableWithFile(Editor, DocumentContext, fix);
                    });
                    subMenu.Add(menuItem);
                }
                var optionsMenuItem = new FixMenuEntry(GettextCatalog.GetString("_Configure Rule"),
                                                       delegate {
                    IdeApp.Workbench.ShowGlobalPreferencesDialog(null, "C#", dialog => {
                        var panel = dialog.GetPanel <CodeIssuePanel> ("C#");
                        if (panel == null)
                        {
                            return;
                        }
                        panel.Widget.SelectCodeIssue(descriptor.IdString);
                    });
                });
                subMenu.Add(optionsMenuItem);


                foreach (var fix2 in GetCurrentFixes().CodeFixActions.OrderByDescending(i => Tuple.Create(IsAnalysisOrErrorFix(i.CodeAction), (int)0, GetUsage(i.CodeAction.EquivalenceKey))))
                {
                    var provider = fix2.Diagnostic.GetCodeFixProvider().GetFixAllProvider();
                    if (provider == null)
                    {
                        continue;
                    }
                    if (!provider.GetSupportedFixAllScopes().Contains(FixAllScope.Document))
                    {
                        continue;
                    }
                    var subMenu2           = new FixMenuDescriptor(GettextCatalog.GetString("Fix all"));
                    var diagnosticAnalyzer = fix2.Diagnostic.GetCodeDiagnosticDescriptor(LanguageNames.CSharp).GetProvider();
                    if (!diagnosticAnalyzer.SupportedDiagnostics.Contains(fix.Descriptor))
                    {
                        continue;
                    }

                    var menuItem = new FixMenuEntry(
                        GettextCatalog.GetString("In _Document"),
                        async delegate {
                        var fixAllDiagnosticProvider = new FixAllDiagnosticProvider(diagnosticAnalyzer.SupportedDiagnostics.Select(d => d.Id).ToImmutableHashSet(), async(Microsoft.CodeAnalysis.Document doc, ImmutableHashSet <string> diagnostics, CancellationToken token) => {
                            var model = await doc.GetSemanticModelAsync(token);
                            var compilationWithAnalyzer = model.Compilation.WithAnalyzers(new [] { diagnosticAnalyzer }.ToImmutableArray(), null, token);

                            return(await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync(model, null, token));
                        }, (Project arg1, bool arg2, ImmutableHashSet <string> arg3, CancellationToken arg4) => {
                            return(Task.FromResult((IEnumerable <Diagnostic>) new Diagnostic [] { }));
                        });
                        var ctx = new FixAllContext(
                            this.DocumentContext.AnalysisDocument,
                            fix2.Diagnostic.GetCodeFixProvider(),
                            FixAllScope.Document,
                            fix2.CodeAction.EquivalenceKey,
                            diagnosticAnalyzer.SupportedDiagnostics.Select(d => d.Id),
                            fixAllDiagnosticProvider,
                            default(CancellationToken)
                            );
                        var fixAll = await provider.GetFixAsync(ctx);
                        using (var undo = Editor.OpenUndoGroup()) {
                            CodeDiagnosticDescriptor.RunAction(DocumentContext, fixAll, default(CancellationToken));
                        }
                    });
                    subMenu2.Add(menuItem);
                    subMenu.Add(FixMenuEntry.Separator);
                    subMenu.Add(subMenu2);
                }

                menu.Add(subMenu);
                items++;
            }
        }
Ejemplo n.º 3
0
        public static async Task <CodeFixMenu> CreateFixMenu(TextEditor editor, CodeActionContainer fixes, CancellationToken cancellationToken = default(CancellationToken))
        {
            var menu = new CodeFixMenu();

            if (editor.DocumentContext.AnalysisDocument == null)
            {
                return(menu);
            }

            int mnemonic = 1;

            foreach (var fix in fixes.CodeFixActions.OrderByDescending(i => GetUsage(i.CodeAction.EquivalenceKey)))
            {
                AddFixMenuItem(editor, menu, ref mnemonic, fix.CodeAction);
            }

            bool first = true;

            foreach (var fix in fixes.CodeRefactoringActions)
            {
                if (first)
                {
                    if (menu.Items.Count > 0)
                    {
                        menu.Add(CodeFixMenuEntry.Separator);
                    }
                    first = false;
                }

                AddFixMenuItem(editor, menu, ref mnemonic, fix.CodeAction);
            }

            var warningsAtCaret = (await editor.DocumentContext.AnalysisDocument.GetSemanticModelAsync(cancellationToken))
                                  .GetDiagnostics(new TextSpan(editor.CaretOffset, 0))
                                  .Where(diag => diag.Severity == DiagnosticSeverity.Warning).ToList();

            var caretSpan = new TextSpan(editor.CaretOffset, 0);

            first = true;
            foreach (var warning in warningsAtCaret)
            {
                var label   = GettextCatalog.GetString("_Options for \u2018{0}\u2019", warning.Descriptor.Title);
                var subMenu = new CodeFixMenu(label);

                await AddSuppressionMenuItems(subMenu, editor, warning, caretSpan);

                if (subMenu.Items.Count > 0)
                {
                    if (first)
                    {
                        menu.Add(CodeFixMenuEntry.Separator);
                        first = false;
                    }

                    menu.Add(subMenu);
                }
            }

            first = true;
            foreach (var diag in fixes.DiagnosticsAtCaret)
            {
                var notConfigurable = DescriptorHasTag(diag.Descriptor, WellKnownDiagnosticTags.NotConfigurable);

                var label   = GettextCatalog.GetString("_Options for \u2018{0}\u2019", diag.Descriptor.Title);
                var subMenu = new CodeFixMenu(label);

                if (first)
                {
                    menu.Add(CodeFixMenuEntry.Separator);
                    first = false;
                }

                await AddSuppressionMenuItems(subMenu, editor, diag, caretSpan);

                var descriptor = BuiltInCodeDiagnosticProvider.GetCodeDiagnosticDescriptor(diag.Id);

                if (descriptor != null && IsConfigurable(diag.Descriptor))
                {
                    var optionsMenuItem = new CodeFixMenuEntry(GettextCatalog.GetString("_Configure Rule"),
                                                               delegate {
                        IdeApp.Workbench.ShowGlobalPreferencesDialog(null, "C#", dialog => {
                            var panel = dialog.GetPanel <CodeIssuePanel> ("C#");
                            if (panel == null)
                            {
                                return;
                            }
                            panel.Widget.SelectCodeIssue(diag.Descriptor.Id);
                        });
                    });
                    subMenu.Add(optionsMenuItem);
                }

                foreach (var fix in fixes.CodeFixActions.OrderByDescending(i => GetUsage(i.CodeAction.EquivalenceKey)))
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return(null);
                    }
                    var provider = fix.Diagnostic.GetCodeFixProvider().GetFixAllProvider();
                    if (provider == null)
                    {
                        continue;
                    }

                    if (!provider.GetSupportedFixAllScopes().Contains(FixAllScope.Document))
                    {
                        continue;
                    }

                    var language = editor.DocumentContext.AnalysisDocument.Project.Language;
                    var diagnosticdDescriptor = fix.Diagnostic?.GetCodeDiagnosticDescriptor(language);
                    if (diagnosticdDescriptor == null)
                    {
                        continue;
                    }

                    var subMenu2 = new CodeFixMenu(GettextCatalog.GetString("Fix all"));

                    var diagnosticAnalyzer = diagnosticdDescriptor.GetProvider();
                    if (!diagnosticAnalyzer.SupportedDiagnostics.Contains(diag.Descriptor))
                    {
                        continue;
                    }

                    var menuItem = new CodeFixMenuEntry(
                        GettextCatalog.GetString("In _Document"),
                        async delegate { await FixAll(editor, fix, provider, diagnosticAnalyzer); }
                        );
                    subMenu2.Add(menuItem);
                    subMenu.Add(CodeFixMenuEntry.Separator);
                    subMenu.Add(subMenu2);
                }

                menu.Add(subMenu);
            }
            return(menu);
        }