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)); }
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)); }
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);
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()); }
protected abstract Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document);
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); }
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); } }
private static Task <Solution> GetProjectFixesAsync(FixAllContext fixAllContext) { return(GetSolutionFixesAsync(fixAllContext, fixAllContext.Project.Documents.ToImmutableArray())); }
/// <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); }
public virtual Task AddProjectFixesAsync(Project project, IEnumerable <Diagnostic> diagnostics, Action <CodeAction> addFix, FixAllContext fixAllContext) { throw new NotImplementedException(); }
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); }
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); }
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); }
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)); }
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);