public override async Task AddDocumentFixesAsync(Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext)
            {
                var pragmaActionsBuilder = ImmutableArray.CreateBuilder<IPragmaBasedCodeAction>();
                var pragmaDiagnosticsBuilder = ImmutableArray.CreateBuilder<Diagnostic>();

                foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && !d.IsSuppressed))
                {
                    var span = diagnostic.Location.SourceSpan;
                    var pragmaSuppressions = await _suppressionFixProvider.GetPragmaSuppressionsAsync(document, span, SpecializedCollections.SingletonEnumerable(diagnostic), fixAllContext.CancellationToken).ConfigureAwait(false);
                    var pragmaSuppression = pragmaSuppressions.SingleOrDefault();
                    if (pragmaSuppression != null)
                    {
                        if (fixAllContext is FixMultipleContext)
                        {
                            pragmaSuppression = pragmaSuppression.CloneForFixMultipleContext();
                        }

                        pragmaActionsBuilder.Add(pragmaSuppression);
                        pragmaDiagnosticsBuilder.Add(diagnostic);
                    }
                }

                // Get the pragma batch fix.
                if (pragmaActionsBuilder.Count > 0)
                {
                    var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix(_suppressionFixProvider, document,
                        pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(), fixAllContext);

                    addFix(pragmaBatchFix);
                }
            }
            public async override Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
            {
                var batchFixer = (BatchFixAllProvider)WellKnownFixAllProviders.BatchFixer;
                var fixMultipleContext = fixAllContext as FixMultipleContext;
                var suppressionFixer = (AbstractSuppressionCodeFixProvider)((WrapperCodeFixProvider)fixAllContext.CodeFixProvider).SuppressionFixProvider;
                var isGlobalSuppression = NestedSuppressionCodeAction.IsEquivalenceKeyForGlobalSuppression(fixAllContext.CodeActionEquivalenceKey);
                if (!isGlobalSuppression)
                {
                    // Pragma warning fix all.
                    batchFixer = new PragmaWarningBatchFixAllProvider(suppressionFixer);
                }

                var title = fixAllContext.CodeActionEquivalenceKey;
                if (fixAllContext.Document != null)
                {
                    var documentsAndDiagnosticsToFixMap = fixMultipleContext != null ?
                        fixMultipleContext.DocumentDiagnosticsToFix :
                        await batchFixer.GetDocumentDiagnosticsToFixAsync(fixAllContext).ConfigureAwait(false);

                    return !isGlobalSuppression ?
                        await batchFixer.GetFixAsync(documentsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false) :
                        CreateGlobalSuppressionFixAllAction(title, suppressionFixer, fixAllContext.Document, documentsAndDiagnosticsToFixMap);
                }
                else
                {
                    var projectsAndDiagnosticsToFixMap = fixMultipleContext != null ?
                        fixMultipleContext.ProjectDiagnosticsToFix :
                        await batchFixer.GetProjectDiagnosticsToFixAsync(fixAllContext).ConfigureAwait(false);

                    return !isGlobalSuppression ?
                        await batchFixer.GetFixAsync(projectsAndDiagnosticsToFixMap, fixAllContext).ConfigureAwait(false) :
                        CreateGlobalSuppressionFixAllAction(title, suppressionFixer, fixAllContext.Project, projectsAndDiagnosticsToFixMap);
                }
            }
 public override async Task AddDocumentFixesAsync(Document document, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext)
 {
     foreach (var diagnosticsForSpan in diagnostics.Where(d => d.Location.IsInSource).GroupBy(d => d.Location.SourceSpan))
     {
         var span = diagnosticsForSpan.First().Location.SourceSpan;
         var pragmaSuppressions = await _suppressionFixProvider.GetPragmaSuppressionsAsync(document, span, diagnosticsForSpan, fixAllContext.CancellationToken).ConfigureAwait(false);
         foreach (var pragmaSuppression in pragmaSuppressions)
         {
             addFix(pragmaSuppression);
         }
     }
 }
                public override async Task<CodeAction> TryGetMergedFixAsync(IEnumerable<CodeAction> batchOfFixes, FixAllContext fixAllContext)
                {
                    // Batch all the attribute removal fixes into a single fix.
                    // Pragma removal fixes have already been batch for each document AddDocumentFixes method.
                    // This ensures no merge conflicts in merging all fixes by our base implementation.

                    var cancellationToken = fixAllContext.CancellationToken;
                    var oldSolution = fixAllContext.Document.Project.Solution;
                    var currentSolution = oldSolution;

                    var attributeRemoveFixes = new List<AttributeRemoveAction>();
                    var newBatchOfFixes = new List<CodeAction>();
                    foreach (var codeAction in batchOfFixes)
                    {
                        var attributeRemoveFix = codeAction as AttributeRemoveAction;
                        if (attributeRemoveFix != null)
                        {
                            attributeRemoveFixes.Add(attributeRemoveFix);
                        }
                        else
                        {
                            newBatchOfFixes.Add(codeAction);
                        }
                    }

                    if (attributeRemoveFixes.Count > 0)
                    {
                        // Batch all of attribute removal fixes.
                        foreach (var removeSuppressionFixesForTree in attributeRemoveFixes.GroupBy(fix => fix.SyntaxTreeToModify))
                        {
                            var tree = removeSuppressionFixesForTree.Key;

                            var attributeRemoveFixesForTree = removeSuppressionFixesForTree.OfType<AttributeRemoveAction>().ToImmutableArray();
                            var attributesToRemove = await GetAttributeNodesToFixAsync(attributeRemoveFixesForTree, cancellationToken).ConfigureAwait(false);
                            var document = oldSolution.GetDocument(tree);
                            var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
                            var newRoot = root.RemoveNodes(attributesToRemove, SyntaxRemoveOptions.KeepLeadingTrivia);
                            currentSolution = currentSolution.WithDocumentSyntaxRoot(document.Id, newRoot);
                        }

                        // This is a temporary generated code action, which doesn't need telemetry, hence suppressing RS0005.
#pragma warning disable RS0005 // Do not use generic CodeAction.Create to create CodeAction
                        var batchAttributeRemoveFix = Create(
                            attributeRemoveFixes.First().Title,
                            createChangedSolution: ct => Task.FromResult(currentSolution),
                            equivalenceKey: fixAllContext.CodeActionEquivalenceKey);
#pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction

                        newBatchOfFixes.Insert(0, batchAttributeRemoveFix);
                    }

                    return await base.TryGetMergedFixAsync(newBatchOfFixes, fixAllContext).ConfigureAwait(false);
                }
            public static CodeAction CreateBatchPragmaFix(
                AbstractSuppressionCodeFixProvider suppressionFixProvider,
                Document document,
                ImmutableArray<IPragmaBasedCodeAction> pragmaActions,
                ImmutableArray<Diagnostic> pragmaDiagnostics,
                FixAllContext fixAllContext)
            {
                // This is a temporary generated code action, which doesn't need telemetry, hence suppressing RS0005.
#pragma warning disable RS0005 // Do not use generic CodeAction.Create to create CodeAction
                return CodeAction.Create(
                    ((CodeAction)pragmaActions[0]).Title,
                    createChangedDocument: ct =>
                        BatchPragmaFixesAsync(suppressionFixProvider, document, pragmaActions, pragmaDiagnostics, fixAllContext.CancellationToken),
                    equivalenceKey: fixAllContext.CodeActionEquivalenceKey);
#pragma warning restore RS0005 // Do not use generic CodeAction.Create to create CodeAction
            }
                public async override Task AddProjectFixesAsync(Project project, ImmutableArray<Diagnostic> diagnostics, Action<CodeAction> addFix, FixAllContext fixAllContext)
                {
                    foreach (var diagnostic in diagnostics.Where(d => !d.Location.IsInSource && d.IsSuppressed))
                    {
                        var removeSuppressionFixes = await _suppressionFixProvider.GetSuppressionsAsync(project, SpecializedCollections.SingletonEnumerable(diagnostic), fixAllContext.CancellationToken).ConfigureAwait(false);
                        var removeSuppressionCodeAction = removeSuppressionFixes.SingleOrDefault()?.Action as RemoveSuppressionCodeAction;
                        if (removeSuppressionCodeAction != null)
                        {
                            if (fixAllContext is FixMultipleContext)
                            {
                                removeSuppressionCodeAction = removeSuppressionCodeAction.CloneForFixMultipleContext();
                            }

                            addFix(removeSuppressionCodeAction);
                        }
                    }
                }
            public async override Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
            {
                var batchFixer = WellKnownFixAllProviders.BatchFixer;
                var suppressionFixer = (AbstractSuppressionCodeFixProvider)((WrapperCodeFixProvider)fixAllContext.CodeFixProvider).SuppressionFixProvider;
                var isGlobalSuppression = NestedSuppressionCodeAction.IsEquivalenceKeyForGlobalSuppression(fixAllContext.CodeActionEquivalenceKey);
                if (!isGlobalSuppression)
                {
                    var isPragmaWarningSuppression = NestedSuppressionCodeAction.IsEquivalenceKeyForPragmaWarning(fixAllContext.CodeActionEquivalenceKey);
                    Contract.ThrowIfFalse(isPragmaWarningSuppression || NestedSuppressionCodeAction.IsEquivalenceKeyForRemoveSuppression(fixAllContext.CodeActionEquivalenceKey));

                    batchFixer = isPragmaWarningSuppression ?
                        new PragmaWarningBatchFixAllProvider(suppressionFixer) :
                        RemoveSuppressionCodeAction.GetBatchFixer(suppressionFixer);
                }

                var title = fixAllContext.CodeActionEquivalenceKey;
                if (fixAllContext.Document != null)
                {
                    var documentsAndDiagnosticsToFixMap = 
                        await fixAllContext.GetDocumentDiagnosticsToFixAsync().ConfigureAwait(false);

                    return !isGlobalSuppression 
                        ? await batchFixer.GetFixAsync(
                            documentsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false)
                        : GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Document, documentsAndDiagnosticsToFixMap);
                }
                else
                {
                    var projectsAndDiagnosticsToFixMap =
                        await fixAllContext.GetProjectDiagnosticsToFixAsync().ConfigureAwait(false);

                    return !isGlobalSuppression
                        ? await batchFixer.GetFixAsync(
                            projectsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false)
                        : GlobalSuppressMessageFixAllCodeAction.Create(title, suppressionFixer, fixAllContext.Project, projectsAndDiagnosticsToFixMap);
                }
            }
            /// <exception cref="ArgumentException">Unknown scope</exception>
            public override async Task <CodeAction> GetFixAsync([NotNull] FixAllContext fixAllContext)
            {
                var          diagnosticsToFix = new List <KeyValuePair <Project, ImmutableArray <Diagnostic> > >();
                const string TitleFormat      = "Convert all messages in {0} {1} to diagnostic constants";
                string       fixAllTitle;

                switch (fixAllContext.Scope)
                {
                case FixAllScope.Document:
                {
                    var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(fixAllContext.Document).ConfigureAwait(false);

                    diagnosticsToFix.Add(new KeyValuePair <Project, ImmutableArray <Diagnostic> >(fixAllContext.Project, diagnostics));
                    fixAllTitle = string.Format(TitleFormat, "document", fixAllContext.Document.Name);
                    break;
                }

                case FixAllScope.Project:
                {
                    var project     = fixAllContext.Project;
                    var diagnostics = await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false);

                    diagnosticsToFix.Add(new KeyValuePair <Project, ImmutableArray <Diagnostic> >(fixAllContext.Project, diagnostics));
                    fixAllTitle = string.Format(TitleFormat, "project", fixAllContext.Project.Name);
                    break;
                }

                case FixAllScope.Solution:
                {
                    foreach (var project in fixAllContext.Solution.Projects)
                    {
                        var diagnostics = await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false);

                        diagnosticsToFix.Add(new KeyValuePair <Project, ImmutableArray <Diagnostic> >(project, diagnostics));
                    }

                    fixAllTitle = "Add all items in the solution to the public API";
                    break;
                }

                case FixAllScope.Custom:
                    return(null);

                default:
                    throw new ArgumentException("Unknown scope", nameof(fixAllContext));
                }

                var severity = Severities
                               .FirstOrDefault(sev => string.Format(Title, sev) == fixAllContext.CodeActionEquivalenceKey)
                               ?? DefaultSeverity;

                foreach (var sev in Severities)
                {
                    if (string.Format(Title, sev) == fixAllContext.CodeActionEquivalenceKey)
                    {
                        severity = sev;
                        break;
                    }
                }

                return(CodeAction.Create(
                           title: fixAllTitle,
                           createChangedSolution: async c =>
                {
                    var diagsByDocument = from ds in diagnosticsToFix
                                          from d in ds.Value
                                          where d.Location.IsInSource
                                          let document = fixAllContext.Solution.GetDocument(d.Location.SourceTree)
                                                         group d by document;

                    async Task <KeyValuePair <DocumentId, Invocation[]> > GetInvocations(Document doc, IEnumerable <Diagnostic> diags)
                    {
                        var root = await doc.GetSyntaxRootAsync(c).ConfigureAwait(false);
                        var semanticModel = await doc.GetSemanticModelAsync(c).ConfigureAwait(false);
                        var creationExprs = from d in diags
                                            let span = d.Location.SourceSpan
                                                       let ancestors = root.FindToken(span.Start).Parent.AncestorsAndSelf()
                                                                       select ancestors.OfType <ObjectCreationExpressionSyntax>().First();
                        var literalCreations = MatchLiteralCreations(creationExprs, semanticModel);
                        var invocations = PlanInvocations(literalCreations.ToArray(), severity);
                        return new KeyValuePair <DocumentId, Invocation[]>(doc.Id, invocations);
                    }

                    var results = await Task.WhenAll(from grouping in diagsByDocument
                                                     select GetInvocations(grouping.Key, grouping));

                    return await ApplyInvocationsAsync(fixAllContext.Solution, results, c);
                },
                           equivalenceKey: fixAllTitle));
            }
Exemplo n.º 9
0
        private static async Task <SyntaxNode> GetFixedDocumentAsync(FixAllContext fixAllContext, Document document)
        {
            var annotationKind = Guid.NewGuid().ToString();

            var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);

            var root = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);

            var elementDiagnosticPairs = diagnostics
                                         .Select(d => new KeyValuePair <SyntaxNodeOrToken, Diagnostic>(GetReportedElement(d, root), d))
                                         .Where(n => !n.Key.IsMissing)
                                         .ToDictionary(kv => kv.Key, kv => kv.Value);

            var diagnosticAnnotationPairs = new BidirectionalDictionary <Diagnostic, SyntaxAnnotation>();

            CreateAnnotationForDiagnostics(diagnostics, annotationKind, diagnosticAnnotationPairs);
            root = GetRootWithAnnotatedElements(root, elementDiagnosticPairs, diagnosticAnnotationPairs);

            var currentDocument   = document.WithSyntaxRoot(root);
            var annotatedElements = root.GetAnnotatedNodesAndTokens(annotationKind).ToList();

            while (annotatedElements.Any())
            {
                var element    = annotatedElements.First();
                var annotation = element.GetAnnotations(annotationKind).First();
                var diagnostic = diagnosticAnnotationPairs.GetByB(annotation);
                var location   = root.GetAnnotatedNodesAndTokens(annotation).FirstOrDefault().GetLocation();
                if (location == null)
                {
                    //annotation is already removed from the tree
                    continue;
                }

                var newDiagnostic = Diagnostic.Create(
                    diagnostic.Descriptor,
                    location,
                    diagnostic.AdditionalLocations,
                    diagnostic.Properties);

                var fixes   = new List <CodeAction>();
                var context = new CodeFixContext(currentDocument, newDiagnostic, (a, d) =>
                {
                    lock (fixes)
                    {
                        fixes.Add(a);
                    }
                }, fixAllContext.CancellationToken);
                await fixAllContext.CodeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false);

                var action = fixes.FirstOrDefault(fix => fix.EquivalenceKey == fixAllContext.CodeActionEquivalenceKey);
                if (action != null)
                {
                    var operations = await action.GetOperationsAsync(fixAllContext.CancellationToken).ConfigureAwait(false);

                    var solution = operations.OfType <ApplyChangesOperation>().Single().ChangedSolution;
                    currentDocument = solution.GetDocument(document.Id);
                    root            = await currentDocument.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
                }
                root              = RemoveAnnotationIfExists(root, annotation);
                currentDocument   = document.WithSyntaxRoot(root);
                annotatedElements = root.GetAnnotatedNodesAndTokens(annotationKind).ToList();
            }

            return(await currentDocument.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false));
        }
Exemplo n.º 10
0
        public static async Task <ImmutableDictionary <Document, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixAsync(
            FixAllContext fixAllContext,
            IProgressTracker progressTrackerOpt,
            Func <Document, CancellationToken, bool> isGeneratedCode)
        {
            var cancellationToken = fixAllContext.CancellationToken;

            var allDiagnostics = ImmutableArray <Diagnostic> .Empty;
            var projectsToFix  = ImmutableArray <Project> .Empty;

            var document = fixAllContext.Document;
            var project  = fixAllContext.Project;

            switch (fixAllContext.Scope)
            {
            case FixAllScope.Document:
                if (document != null && !isGeneratedCode(document, cancellationToken))
                {
                    var documentDiagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);

                    return(ImmutableDictionary <Document, ImmutableArray <Diagnostic> > .Empty.SetItem(document, documentDiagnostics));
                }

                break;

            case FixAllScope.Project:
                projectsToFix  = ImmutableArray.Create(project);
                allDiagnostics = await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false);

                break;

            case FixAllScope.Solution:
                projectsToFix = project.Solution.Projects
                                .Where(p => p.Language == project.Language)
                                .ToImmutableArray();

                progressTrackerOpt?.AddItems(projectsToFix.Length);

                var diagnostics = new ConcurrentDictionary <ProjectId, ImmutableArray <Diagnostic> >();
                var tasks       = new Task[projectsToFix.Length];
                for (var i = 0; i < projectsToFix.Length; i++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    var projectToFix = projectsToFix[i];
                    tasks[i] = Task.Run(async() =>
                    {
                        var projectDiagnostics = await fixAllContext.GetAllDiagnosticsAsync(projectToFix).ConfigureAwait(false);
                        diagnostics.TryAdd(projectToFix.Id, projectDiagnostics);
                        progressTrackerOpt?.ItemCompleted();
                    }, cancellationToken);
                }

                await Task.WhenAll(tasks).ConfigureAwait(false);

                allDiagnostics = allDiagnostics.AddRange(diagnostics.SelectMany(i => i.Value));
                break;
            }

            if (allDiagnostics.IsEmpty)
            {
                return(ImmutableDictionary <Document, ImmutableArray <Diagnostic> > .Empty);
            }

            return(await GetDocumentDiagnosticsToFixAsync(
                       allDiagnostics, projectsToFix, isGeneratedCode, fixAllContext.CancellationToken).ConfigureAwait(false));
        }
        private Task <Solution> GetSolutionFixesAsync(FixAllContext fixAllContext)
        {
            ImmutableArray <Document> documents = fixAllContext.Solution.Projects.SelectMany(i => i.Documents).ToImmutableArray();

            return(this.GetSolutionFixesAsync(fixAllContext, documents));
        }
 /// <summary>
 /// Fixes all occurrences of a diagnostic in a specific document.
 /// </summary>
 /// <param name="fixAllContext">The context for the Fix All operation.</param>
 /// <param name="document">The document to fix.</param>
 /// <param name="diagnostics">The diagnostics to fix in the document.</param>
 /// <returns>
 /// <para>The new <see cref="SyntaxNode"/> representing the root of the fixed document.</para>
 /// <para>-or-</para>
 /// <para><see langword="null"/>, if no changes were made to the document.</para>
 /// </returns>
 protected abstract Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document, ImmutableArray <Diagnostic> diagnostics);
Exemplo n.º 13
0
 private static ImmutableArray <DiagnosticAnalyzer> GetDiagnosticAnalyzersForContext(FixAllContext fixAllContext)
 {
     return(DiagnosticAnalyzers
            .Where(x => fixAllContext.DiagnosticIds.Contains(x.Key))
            .SelectMany(x => x.Value)
            .Distinct()
            .Select(type => (DiagnosticAnalyzer)Activator.CreateInstance(type))
            .ToImmutableArray());
 }
Exemplo n.º 14
0
 protected abstract Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document);
Exemplo n.º 15
0
        private static async Task <Project> FixAllAnalyerDiagnosticsInScopeAsync(FixAllScope scope, ImmutableArray <DiagnosticAnalyzer> analyzers, CodeFixProvider codeFixProvider, int?codeFixIndex, Project project, int numberOfIterations, CancellationToken cancellationToken)
        {
            var expectedNumberOfIterations = numberOfIterations;

            if (numberOfIterations < 0)
            {
                numberOfIterations = -numberOfIterations;
            }

            var previousDiagnostics = ImmutableArray.Create <Diagnostic>();

            var fixAllProvider = codeFixProvider.GetFixAllProvider();

            if (fixAllProvider == null)
            {
                return(null);
            }

            bool done;

            do
            {
                var analyzerDiagnostics = await GetSortedDiagnosticsFromDocumentsAsync(analyzers, project.Documents.ToArray(), cancellationToken).ConfigureAwait(false);

                if (analyzerDiagnostics.Length == 0)
                {
                    break;
                }

                if (!AreDiagnosticsDifferent(analyzerDiagnostics, previousDiagnostics))
                {
                    break;
                }

                if (--numberOfIterations < 0)
                {
                    Assert.True(false, "The upper limit for the number of fix all iterations was exceeded");
                }

                Diagnostic firstDiagnostic = null;
                string     equivalenceKey  = null;
                foreach (var diagnostic in analyzerDiagnostics)
                {
                    if (!codeFixProvider.FixableDiagnosticIds.Contains(diagnostic.Id))
                    {
                        // do not pass unsupported diagnostics to a code fix provider
                        continue;
                    }

                    var actions = new List <CodeAction>();
                    var context = new CodeFixContext(project.GetDocument(diagnostic.Location.SourceTree), diagnostic, (a, d) => actions.Add(a), cancellationToken);
                    await codeFixProvider.RegisterCodeFixesAsync(context).ConfigureAwait(false);

                    if (actions.Count > (codeFixIndex ?? 0))
                    {
                        firstDiagnostic = diagnostic;
                        equivalenceKey  = actions[codeFixIndex ?? 0].EquivalenceKey;
                        break;
                    }
                }

                if (firstDiagnostic == null)
                {
                    return(project);
                }

                previousDiagnostics = analyzerDiagnostics;

                done = true;

                FixAllContext.DiagnosticProvider fixAllDiagnosticProvider = TestDiagnosticProvider.Create(analyzerDiagnostics);

                var analyzerDiagnosticIds = analyzers.SelectMany(x => x.SupportedDiagnostics).Select(x => x.Id);
                var compilerDiagnosticIds = codeFixProvider.FixableDiagnosticIds.Where(x => x.StartsWith("CS", StringComparison.Ordinal));
                var disabledDiagnosticIds = project.CompilationOptions.SpecificDiagnosticOptions.Where(x => x.Value == ReportDiagnostic.Suppress).Select(x => x.Key);
                var relevantIds           = analyzerDiagnosticIds.Concat(compilerDiagnosticIds).Except(disabledDiagnosticIds).Distinct();
                var fixAllContext         = new FixAllContext(project.GetDocument(firstDiagnostic.Location.SourceTree), codeFixProvider, scope, equivalenceKey, relevantIds, fixAllDiagnosticProvider, cancellationToken);

                var action = await fixAllProvider.GetFixAsync(fixAllContext).ConfigureAwait(false);

                if (action == null)
                {
                    return(project);
                }

                var fixedProject = await ApplyFixAsync(project, action, cancellationToken).ConfigureAwait(false);

                if (fixedProject != project)
                {
                    done = false;

                    project = await RecreateProjectDocumentsAsync(fixedProject, cancellationToken).ConfigureAwait(false);
                }
            } while (!done);

            if (expectedNumberOfIterations >= 0)
            {
                Assert.AreEqual($"{expectedNumberOfIterations} iterations", $"{expectedNumberOfIterations - numberOfIterations} iterations");
            }

            return(project);
        }
Exemplo n.º 16
0
        private static async Task <Dictionary <Document, List <SyntaxNode> > > CollectSolutionDiagnostics(Solution solution, FixAllContext context)
        {
            Dictionary <Document, List <SyntaxNode> > result = new Dictionary <Document, List <SyntaxNode> >();

            foreach (var proj in solution.Projects)
            {
                var projDiag = await CollectProjectDiagnostics(proj, context);

                foreach (var diag in projDiag)
                {
                    result.Add(diag.Key, diag.Value);
                }
            }

            return(result);
        }
        public async override Task <RunFixAllResponse> Handle(RunFixAllRequest request)
        {
            if (request.Scope != FixAllScope.Document && request.FixAllFilter == null)
            {
                throw new NotImplementedException($"Only scope '{nameof(FixAllScope.Document)}' is currently supported when filter '{nameof(request.FixAllFilter)}' is not set.");
            }

            var solutionBeforeChanges = Workspace.CurrentSolution;

            var mappedProvidersWithDiagnostics = await GetDiagnosticsMappedWithFixAllProviders(request.Scope, request.FileName);

            var filteredProvidersWithFix = mappedProvidersWithDiagnostics
                                           .Where(diagWithFix =>
            {
                if (request.FixAllFilter == null)
                {
                    return(true);
                }

                return(request.FixAllFilter.Any(x => diagWithFix.HasFixForId(x.Id)));
            });

            var cancellationSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(request.Timeout));

            foreach (var singleFixableProviderWithDocument in filteredProvidersWithFix)
            {
                try
                {
                    var document = Workspace.CurrentSolution.GetDocument(singleFixableProviderWithDocument.DocumentId);

                    var fixer = singleFixableProviderWithDocument.FixAllProvider;

                    var(action, fixableDiagnosticIds) = await singleFixableProviderWithDocument.RegisterCodeFixesOrDefault(document);

                    if (action == null)
                    {
                        continue;
                    }

                    var fixAllContext = new FixAllContext(
                        document,
                        singleFixableProviderWithDocument.CodeFixProvider,
                        Microsoft.CodeAnalysis.CodeFixes.FixAllScope.Project,
                        action.EquivalenceKey,
                        fixableDiagnosticIds,
                        _fixAllDiagnosticProvider,
                        cancellationSource.Token
                        );

                    var fixes = await singleFixableProviderWithDocument.FixAllProvider.GetFixAsync(fixAllContext);

                    if (fixes == null)
                    {
                        continue;
                    }

                    var operations = await fixes.GetOperationsAsync(cancellationSource.Token);

                    foreach (var o in operations)
                    {
                        _logger.LogInformation($"Applying operation {o.ToString()} from fix all with fix provider {singleFixableProviderWithDocument.CodeFixProvider} to workspace document {document.FilePath}.");

                        if (o is ApplyChangesOperation applyChangesOperation)
                        {
                            applyChangesOperation.Apply(Workspace, cancellationSource.Token);
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError($"Running fix all action {singleFixableProviderWithDocument} in document {singleFixableProviderWithDocument.DocumentPath} prevented by error: {ex}");
                }
            }

            var changes = await GetFileChangesAsync(Workspace.CurrentSolution, solutionBeforeChanges, Path.GetDirectoryName(request.FileName), request.WantsTextChanges, request.WantsAllCodeActionOperations);

            return(new RunFixAllResponse
            {
                Changes = changes.FileChanges
            });
        }
 private static async Task <ImmutableArray <Diagnostic> > GetAllDiagnosticsAsync(FixAllContext fixAllContext, Project project)
 {
     return(await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false));
 }
            public override async Task AddDocumentFixesAsync(Document document, ImmutableArray <Diagnostic> diagnostics, Action <CodeAction> addFix, FixAllContext fixAllContext)
            {
                var pragmaActionsBuilder     = ImmutableArray.CreateBuilder <IPragmaBasedCodeAction>();
                var pragmaDiagnosticsBuilder = ImmutableArray.CreateBuilder <Diagnostic>();

                foreach (var diagnostic in diagnostics.Where(d => d.Location.IsInSource && !d.IsSuppressed))
                {
                    var span = diagnostic.Location.SourceSpan;
                    var pragmaSuppressions = await _suppressionFixProvider.GetPragmaSuppressionsAsync(document, span, SpecializedCollections.SingletonEnumerable(diagnostic), fixAllContext.CancellationToken).ConfigureAwait(false);

                    var pragmaSuppression = pragmaSuppressions.SingleOrDefault();
                    if (pragmaSuppression != null)
                    {
                        if (fixAllContext is FixMultipleContext)
                        {
                            pragmaSuppression = pragmaSuppression.CloneForFixMultipleContext();
                        }

                        pragmaActionsBuilder.Add(pragmaSuppression);
                        pragmaDiagnosticsBuilder.Add(diagnostic);
                    }
                }

                // Get the pragma batch fix.
                if (pragmaActionsBuilder.Count > 0)
                {
                    var pragmaBatchFix = PragmaBatchFixHelpers.CreateBatchPragmaFix(_suppressionFixProvider, document,
                                                                                    pragmaActionsBuilder.ToImmutable(), pragmaDiagnosticsBuilder.ToImmutable(), fixAllContext);

                    addFix(pragmaBatchFix);
                }
            }
Exemplo n.º 20
0
 private static Task <Solution> GetProjectFixesAsync(FixAllContext fixAllContext)
 {
     return(GetSolutionFixesAsync(fixAllContext, fixAllContext.Project.Documents.ToImmutableArray()));
 }
Exemplo n.º 21
0
        /// <summary>
        /// Gets all <see cref="Diagnostic"/> instances within a specific <see cref="Project"/> which are relevant to a
        /// <see cref="FixAllContext"/>.
        /// </summary>
        /// <param name="fixAllContext">The context for the Fix All operation.</param>
        /// <param name="project">The project.</param>
        /// <returns>A <see cref="Task{TResult}"/> representing the asynchronous operation. When the task completes
        /// successfully, the <see cref="Task{TResult}.Result"/> will contain the requested diagnostics.</returns>
        private static async Task <ImmutableArray <Diagnostic> > GetAllDiagnosticsAsync(FixAllContext fixAllContext, Project project)
        {
            if (GetAnalyzerSyntaxDiagnosticsAsync == null || GetAnalyzerSemanticDiagnosticsAsync == null)
            {
                return(await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false));
            }

            /*
             * The rest of this method is workaround code for issues with Roslyn 1.1...
             */

            var analyzers = GetDiagnosticAnalyzersForContext(fixAllContext);

            // Most code fixes in this project operate on diagnostics reported by analyzers in this project. However, a
            // few code fixes also operate on standard warnings produced by the C# compiler. Special handling is
            // required for the latter case since these warnings are not considered "analyzer diagnostics".
            bool includeCompilerDiagnostics = fixAllContext.DiagnosticIds.Any(x => x.StartsWith("CS", StringComparison.Ordinal));

            // Use a single CompilationWithAnalyzers for the entire operation. This allows us to use the
            // GetDeclarationDiagnostics workaround for dotnet/roslyn#7446 a single time, rather than once per document.
            var compilation = await project.GetCompilationAsync(fixAllContext.CancellationToken).ConfigureAwait(false);

            var compilationWithAnalyzers            = compilation.WithAnalyzers(analyzers, project.AnalyzerOptions, fixAllContext.CancellationToken);
            ImmutableArray <Diagnostic> diagnostics = await GetAllDiagnosticsAsync(compilation, compilationWithAnalyzers, analyzers, project.Documents, includeCompilerDiagnostics, fixAllContext.CancellationToken).ConfigureAwait(false);

            // Make sure to filter the results to the set requested for the Fix All operation, since analyzers can
            // report diagnostics with different IDs.
            diagnostics = diagnostics.RemoveAll(x => !fixAllContext.DiagnosticIds.Contains(x.Id));
            return(diagnostics);
        }
Exemplo n.º 22
0
 public virtual Task AddProjectFixesAsync(Project project, IEnumerable <Diagnostic> diagnostics, Action <CodeAction> addFix, FixAllContext fixAllContext)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 23
0
 public sealed override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
 {
     var documentsAndDiagnosticsToFixMap = await fixAllContext.GetDocumentDiagnosticsToFixAsync().ConfigureAwait(false);
     return await GetFixAsync(documentsAndDiagnosticsToFixMap, fixAllContext.State, fixAllContext.CancellationToken).ConfigureAwait(false);
 }
Exemplo n.º 24
0
        private static async Task <Dictionary <Document, List <SyntaxNode> > > CollectProjectDiagnostics(Project project, FixAllContext context)
        {
            Dictionary <SyntaxTree, Document> syntaxTreeToDocMap = new Dictionary <SyntaxTree, Document>();

            foreach (var doc in project.Documents)
            {
                var tree = await doc.GetSyntaxTreeAsync(context.CancellationToken).ConfigureAwait(false);

                syntaxTreeToDocMap.Add(tree, doc);
            }

            Dictionary <Document, List <SyntaxNode> > result = new Dictionary <Document, List <SyntaxNode> >();

            var allProjectDiags = await context.GetAllDiagnosticsAsync(project).ConfigureAwait(false);

            foreach (var resDiag in allProjectDiags)
            {
                if (!syntaxTreeToDocMap.TryGetValue(resDiag.Location.SourceTree, out Document curDoc))
                {
                    continue;
                }

                var root = await resDiag.Location.SourceTree.GetRootAsync(context.CancellationToken);

                var nodeToReplace = root.FindNode(resDiag.Location.SourceSpan, getInnermostNodeForTie: true);

                if (!result.TryGetValue(curDoc, out List <SyntaxNode> curDocNodes))
                {
                    curDocNodes = new List <SyntaxNode>();
                    result.Add(curDoc, curDocNodes);
                }

                curDocNodes.Add(nodeToReplace);
            }

            return(result);
        }
Exemplo n.º 25
0
        public static async Task <ImmutableDictionary <Project, ImmutableArray <Diagnostic> > > GetProjectDiagnosticsToFixAsync(FixAllContext fixAllContext)
        {
            var project = fixAllContext.Project;

            if (project != null)
            {
                switch (fixAllContext.Scope)
                {
                case FixAllScope.Project:
                    var diagnostics = await fixAllContext.GetProjectDiagnosticsAsync(project).ConfigureAwait(false);

                    return(ImmutableDictionary <Project, ImmutableArray <Diagnostic> > .Empty.SetItem(project, diagnostics));

                case FixAllScope.Solution:
                    var projectsAndDiagnostics = new ConcurrentDictionary <Project, ImmutableArray <Diagnostic> >();
                    var options = new ParallelOptions()
                    {
                        CancellationToken = fixAllContext.CancellationToken
                    };
                    Parallel.ForEach(project.Solution.Projects, options, proj =>
                    {
                        fixAllContext.CancellationToken.ThrowIfCancellationRequested();
                        var projectDiagnosticsTask = fixAllContext.GetProjectDiagnosticsAsync(proj);
                        projectDiagnosticsTask.Wait(fixAllContext.CancellationToken);
                        var projectDiagnostics = projectDiagnosticsTask.Result;
                        if (projectDiagnostics.Any())
                        {
                            projectsAndDiagnostics.TryAdd(proj, projectDiagnostics);
                        }
                    });

                    return(projectsAndDiagnostics.ToImmutableDictionary());
                }
            }

            return(ImmutableDictionary <Project, ImmutableArray <Diagnostic> > .Empty);
        }
Exemplo n.º 26
0
        static CommandInfoSet CreateFixMenu(TextEditor editor, DocumentContext ctx, SemanticModel semanticModel, CodeActionContainer container)
        {
            if (editor == null)
            {
                throw new ArgumentNullException(nameof(editor));
            }
            if (ctx == null)
            {
                throw new ArgumentNullException(nameof(ctx));
            }
            if (container == null)
            {
                throw new ArgumentNullException(nameof(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()));
            }
            bool firstDiagnosticOption = result.CommandInfos.Count != 0;

            var warningsAtCaret = semanticModel
                                  .GetDiagnostics(new TextSpan(editor.CaretOffset, 0))
                                  .Where(diag => diag.Severity == DiagnosticSeverity.Warning).ToList();

            foreach (var warning in warningsAtCaret)
            {
                if (firstDiagnosticOption)
                {
                    result.CommandInfos.AddSeparator();
                    firstDiagnosticOption = false;
                }

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

                var info = new CommandInfo(GettextCatalog.GetString("_Suppress with #pragma"));
                subMenu.CommandInfos.Add(info, new Action(async delegate {
                    var fixes = await CSharpSuppressionFixProvider.Instance.GetSuppressionsAsync(ctx.AnalysisDocument, new TextSpan(editor.CaretOffset, 0), new [] { warning }, default(CancellationToken)).ConfigureAwait(false);
                    foreach (var f in fixes)
                    {
                        CodeDiagnosticDescriptor.RunAction(ctx, f.Action, default(CancellationToken));
                    }
                }));

                result.CommandInfos.Add(subMenu);
            }

            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);
        }
 private Task <Solution> GetProjectFixesAsync(FixAllContext fixAllContext, Project project)
 {
     return(this.GetSolutionFixesAsync(fixAllContext, project.Documents.ToImmutableArray()));
 }
        public static async Task <ImmutableDictionary <Document?, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixAsync(FixAllContext fixAllContext)
        {
            var allDiagnostics = ImmutableArray <Diagnostic> .Empty;
            var projectsToFix  = ImmutableArray <Project> .Empty;

            var document = fixAllContext.Document;
            var project  = fixAllContext.Project;

            switch (fixAllContext.Scope)
            {
            case FixAllScope.Document:
                if (document != null)
                {
                    var documentDiagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);

                    return(ImmutableDictionary <Document?, ImmutableArray <Diagnostic> > .Empty.SetItem(document, documentDiagnostics));
                }

                break;

            case FixAllScope.Project:
                projectsToFix  = ImmutableArray.Create(project);
                allDiagnostics = await GetAllDiagnosticsAsync(fixAllContext, project).ConfigureAwait(false);

                break;

            case FixAllScope.Solution:
                projectsToFix = project.Solution.Projects
                                .Where(p => p.Language == project.Language)
                                .ToImmutableArray();

                var diagnostics = new ConcurrentDictionary <ProjectId, ImmutableArray <Diagnostic> >();
                var tasks       = new Task[projectsToFix.Length];
                for (int i = 0; i < projectsToFix.Length; i++)
                {
                    fixAllContext.CancellationToken.ThrowIfCancellationRequested();
                    var projectToFix = projectsToFix[i];
                    tasks[i] = Task.Run(
                        async() =>
                    {
                        var projectDiagnostics = await GetAllDiagnosticsAsync(fixAllContext, projectToFix).ConfigureAwait(false);
                        diagnostics.TryAdd(projectToFix.Id, projectDiagnostics);
                    }, fixAllContext.CancellationToken);
                }

                await Task.WhenAll(tasks).ConfigureAwait(false);

                allDiagnostics = allDiagnostics.AddRange(diagnostics.SelectMany(i => i.Value.Where(x => fixAllContext.DiagnosticIds.Contains(x.Id))));
                break;
            }

            if (allDiagnostics.IsEmpty)
            {
                return(ImmutableDictionary <Document?, ImmutableArray <Diagnostic> > .Empty);
            }

            return(await GetDocumentDiagnosticsToFixAsync(allDiagnostics, projectsToFix, fixAllContext.CancellationToken).ConfigureAwait(false));
        }
Exemplo n.º 29
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);
                });

                thisInstanceMenuItem.ShowPreviewTooltip = delegate(Xwt.Rectangle rect) {
                    HidePreviewTooltip();
                    currentPreviewWindow = new RefactoringPreviewTooltipWindow(this.Editor, this.DocumentContext, fix.CodeAction);
                    currentPreviewWindow.RequestPopup(rect);
                };

                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);
                });

                thisInstanceMenuItem.ShowPreviewTooltip = delegate(Xwt.Rectangle rect) {
                    HidePreviewTooltip();
                    currentPreviewWindow = new RefactoringPreviewTooltipWindow(this.Editor, this.DocumentContext, fix.CodeAction);
                    currentPreviewWindow.RequestPopup(rect);
                };

                menu.Add(thisInstanceMenuItem);
                items++;
            }

            first = false;

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

            foreach (var warning in warningsAtCaret)
            {
                var label   = GettextCatalog.GetString("_Options for \u2018{0}\u2019", warning.Descriptor.Title);
                var subMenu = new FixMenuDescriptor(label);
                if (first)
                {
                    menu.Add(FixMenuEntry.Separator);
                    first = false;
                }
                var menuItem = new FixMenuEntry(GettextCatalog.GetString("_Suppress with #pragma"),
                                                async delegate {
                    var fixes = await CSharpSuppressionFixProvider.Instance.GetSuppressionsAsync(DocumentContext.AnalysisDocument, new TextSpan(Editor.CaretOffset, 0), new [] { warning }, default(CancellationToken)).ConfigureAwait(false);
                    foreach (var f in fixes)
                    {
                        CodeDiagnosticDescriptor.RunAction(DocumentContext, f.Action, default(CancellationToken));
                    }
                }
                                                );
                menuItem.ShowPreviewTooltip = async delegate(Xwt.Rectangle rect) {
                    var fixes = await CSharpSuppressionFixProvider.Instance.GetSuppressionsAsync(DocumentContext.AnalysisDocument, new TextSpan (Editor.CaretOffset, 0), new [] { warning }, default(CancellationToken)).ConfigureAwait(false);

                    HidePreviewTooltip();
                    var fix = fixes.FirstOrDefault();
                    if (fix == null)
                    {
                        return;
                    }
                    currentPreviewWindow = new RefactoringPreviewTooltipWindow(this.Editor, this.DocumentContext, fix.Action);
                    currentPreviewWindow.RequestPopup(rect);
                };

                subMenu.Add(menuItem);
                menu.Add(subMenu);
                items++;
            }

            foreach (var fix_ in GetCurrentFixes().DiagnosticsAtCaret)
            {
                var fix     = fix_;
                var label   = GettextCatalog.GetString("_Options for \u2018{0}\u2019", 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);
                    });
                    menuItem.ShowPreviewTooltip = async delegate(Xwt.Rectangle rect) {
                        var fixes = await CSharpSuppressionFixProvider.Instance.GetSuppressionsAsync(DocumentContext.AnalysisDocument, new TextSpan (Editor.CaretOffset, 0), new [] { fix }, default(CancellationToken)).ConfigureAwait(false);

                        HidePreviewTooltip();
                        var fix2 = fixes.FirstOrDefault();
                        if (fix2 == null)
                        {
                            return;
                        }
                        currentPreviewWindow = new RefactoringPreviewTooltipWindow(this.Editor, this.DocumentContext, fix2.Action);
                        currentPreviewWindow.RequestPopup(rect);
                    };
                    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++;
            }
        }
        public static async Task <ImmutableDictionary <Project, ImmutableArray <Diagnostic> > > GetProjectDiagnosticsToFixAsync(FixAllContext fixAllContext)
        {
            var project = fixAllContext.Project;

            if (project != null)
            {
                switch (fixAllContext.Scope)
                {
                case FixAllScope.Project:
                    var diagnostics = await fixAllContext.GetProjectDiagnosticsAsync(project).ConfigureAwait(false);

                    return(ImmutableDictionary <Project, ImmutableArray <Diagnostic> > .Empty.SetItem(project, diagnostics));

                case FixAllScope.Solution:
                    var projectsAndDiagnostics = new ConcurrentDictionary <Project, ImmutableArray <Diagnostic> >();
                    var tasks = new List <Task>(project.Solution.ProjectIds.Count);
                    Func <Project, Task> projectAction =
                        async proj =>
                    {
                        if (fixAllContext.CancellationToken.IsCancellationRequested)
                        {
                            return;
                        }

                        var projectDiagnostics = await fixAllContext.GetProjectDiagnosticsAsync(proj).ConfigureAwait(false);

                        if (projectDiagnostics.Any())
                        {
                            projectsAndDiagnostics.TryAdd(proj, projectDiagnostics);
                        }
                    };

                    foreach (var proj in project.Solution.Projects)
                    {
                        if (fixAllContext.CancellationToken.IsCancellationRequested)
                        {
                            break;
                        }

                        tasks.Add(projectAction(proj));
                    }

                    await Task.WhenAll(tasks).ConfigureAwait(false);

                    return(projectsAndDiagnostics.ToImmutableDictionary());
                }
            }

            return(ImmutableDictionary <Project, ImmutableArray <Diagnostic> > .Empty);
        }
 protected override async Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document, ImmutableArray <Diagnostic> diagnostics)
 => await GetTransformedDocumentAsync(document, diagnostics, fixAllContext.CancellationToken).ConfigureAwait(false);