コード例 #1
0
        private async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
        {
            var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);

            DocumentEditor editor = await DocumentEditor.CreateAsync(document, fixAllContext.CancellationToken).ConfigureAwait(false);

            SyntaxNode root = editor.GetChangedRoot();

            ImmutableList<SyntaxNode> nodesToChange = ImmutableList.Create<SyntaxNode>();

            // Make sure all nodes we care about are tracked
            foreach (var diagnostic in await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false))
            {
                var location = diagnostic.Location;
                var syntaxNode = root.FindNode(location.SourceSpan);
                if (syntaxNode != null)
                {
                    editor.TrackNode(syntaxNode);
                    nodesToChange = nodesToChange.Add(syntaxNode);
                }
            }

            foreach (var node in nodesToChange)
            {
                editor.ReplaceNode(node, node.WithLeadingTrivia(SyntaxFactory.ElasticCarriageReturnLineFeed));
            }

            return editor.GetChangedRoot();
        }
コード例 #2
0
        protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
        {
            var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
            if (diagnostics.IsEmpty)
            {
                return null;
            }

            var newDocument = document;

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

            // First annotate all expressions that need parenthesis with a temporary annotation.
            // With this annotation we can find the nodes that need parenthesis even if
            // the source span changes.
            foreach (var diagnostic in diagnostics)
            {
                SyntaxNode node = root.FindNode(diagnostic.Location.SourceSpan);
                if (node.IsMissing)
                {
                    continue;
                }

                root = root.ReplaceNode(node, node.WithAdditionalAnnotations(NeedsParenthesisAnnotation));
            }

            return root.ReplaceNodes(root.GetAnnotatedNodes(NeedsParenthesisAnnotation), this.AddParentheses);
        }
コード例 #3
0
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

                SyntaxNode syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);
                List<SyntaxNode> nodesNeedingQualification = new List<SyntaxNode>(diagnostics.Length);

                foreach (Diagnostic diagnostic in diagnostics)
                {
                    var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan, false, true) as SimpleNameSyntax;
                    if (node == null || node.IsMissing)
                    {
                        continue;
                    }

                    nodesNeedingQualification.Add(node);
                }

                return syntaxRoot.ReplaceNodes(nodesNeedingQualification, (originalNode, rewrittenNode) =>
                SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ThisExpressionSyntax, (SimpleNameSyntax)rewrittenNode.WithoutTrivia().WithoutFormatting())
                .WithTriviaFrom(rewrittenNode)
                .WithoutFormatting());
            }
コード例 #4
0
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

                SyntaxNode syntaxRoot = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);

                var replaceMap = new Dictionary<SyntaxNode, SyntaxNode>();

                foreach (Diagnostic diagnostic in diagnostics)
                {
                    var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan, false, true) as ThisExpressionSyntax;
                    if (node == null || node.IsMissing)
                    {
                        continue;
                    }

                    replaceMap[node.Parent] = GenerateReplacementNode(node);
                }

                return syntaxRoot.ReplaceNodes(replaceMap.Keys, (originalNode, rewrittenNode) => replaceMap[originalNode]);
            }
コード例 #5
0
        /// <summary>
        /// Determines all the diagnostics we should be fixing for the given <paramref name="fixAllContext"/>.
        /// </summary>
        private static async Task <ImmutableArray <Diagnostic> > DetermineDiagnosticsAsync(FixAllContext fixAllContext, IProgressTracker progressTracker)
        {
            using var _ = progressTracker.ItemCompletedScope();

            return(fixAllContext.Document != null
                ? await fixAllContext.GetDocumentDiagnosticsAsync(fixAllContext.Document).ConfigureAwait(false)
                : await fixAllContext.GetAllDiagnosticsAsync(fixAllContext.Project).ConfigureAwait(false));
        }
コード例 #6
0
 private static async Task<DiagnosticsInDoc> GetDiagnosticsInDocAsync(FixAllContext fixAllContext, Document document)
 {
     var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
     if (!diagnostics.Any()) return DiagnosticsInDoc.Empty;
     var root = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
     var doc = DiagnosticsInDoc.Create(document.Id, diagnostics, root);
     return doc;
 }
コード例 #7
0
        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);
        }
        private static async Task<SyntaxNode> CreateNewDocumentSyntaxRootAsync(FixAllContext fixAllContext, Document document, CancellationToken cancellationToken)
        {
            var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);

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

            var nodesToFix = diagnostics.Select(diagnostic => DefaulIfNullExpressionHelper.GetTargetExpression(diagnostic, root));

            return root.ReplaceNodes(nodesToFix,
                (orignalNode, rewritten) => DefaulIfNullExpressionHelper.CreateRelacementNode(rewritten));
        }
コード例 #9
0
 private async static Task<Solution> GetFixedProjectAsync(FixAllContext fixAllContext, Project project)
 {
     var solution = project.Solution;
     foreach (var document in project.Documents)
     {
         var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
         var newRoot = await GetFixedDocumentAsync(document, diagnostics, fixAllContext.CancellationToken).ConfigureAwait(false);
         solution = solution.WithDocumentSyntaxRoot(document.Id, newRoot);
     }
     return solution;
 }
コード例 #10
0
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

                var settings = SettingsHelper.GetStyleCopSettings(document.Project.AnalyzerOptions, fixAllContext.CancellationToken);
                Document updatedDocument = await FixEndOfFileAsync(document, diagnostics[0], settings.LayoutRules.NewlineAtEndOfFile, fixAllContext.CancellationToken).ConfigureAwait(false);
                return await updatedDocument.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
            }
コード例 #11
0
        private static async Task<Solution> FixDocumentAsync(FixAllContext fixAllContext, Document document)
        {
            Solution solution = document.Project.Solution;
            var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);

            if (diagnostics.Length == 0 || fixAllContext.CodeActionEquivalenceKey != await SA1412CodeFixProvider.GetEquivalenceKeyForDocumentAsync(document).ConfigureAwait(false))
            {
                return solution;
            }

            return await SA1412CodeFixProvider.GetTransformedSolutionAsync(document).ConfigureAwait(false);
        }
コード例 #12
0
        protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
        {
            var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
            SyntaxNode root = await document.GetSyntaxRootAsync().ConfigureAwait(false);

            var nodesToRemove = diagnostics.Select(d => root.FindNode(d.Location.SourceSpan, findInsideTrivia: true))
                .Where(node => node != null && !node.IsMissing)
                .OfType<RegionDirectiveTriviaSyntax>()
                .SelectMany(node => node.GetRelatedDirectives())
                .Where(node => !node.IsMissing);

            return root.RemoveNodes(nodesToRemove, SyntaxRemoveOptions.AddElasticMarker);
        }
コード例 #13
0
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

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

                var nodes = diagnostics.Select(diagnostic => syntaxRoot.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true));

                return syntaxRoot.ReplaceNodes(nodes, (originalNode, rewrittenNode) => GetReplacementNode(rewrittenNode));
            }
コード例 #14
0
 private async static Task<SyntaxNode> GetFixedDocumentAsync(FixAllContext fixAllContext, Document document)
 {
     var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
     var root = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
     var nodes = diagnostics.Select(d => root.FindNode(d.Location.SourceSpan)).Where(n => !n.IsMissing).ToList();
     var newRoot = root;
     while (nodes.Any())
     {
         newRoot = newRoot.ReplaceNodes(nodes, (original, rewritten) => original.WithAdditionalAnnotations(removeUnreachableCodeAnnotation));
         while (true)
         {
             var annotatedNodes = newRoot.GetAnnotatedNodes(removeUnreachableCodeAnnotation);
             var node = annotatedNodes.FirstOrDefault();
             if (node == null) break;
             newRoot = RemoveUnreachableCodeCodeFixProvider.RemoveUnreachableStatement(newRoot, node);
         }
         var newDoc = document.WithSyntaxRoot(newRoot);
         diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(newDoc).ConfigureAwait(false);
         newRoot = await newDoc.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
         nodes = diagnostics.Select(d => newRoot.FindNode(d.Location.SourceSpan)).Where(n => !n.IsMissing).ToList();
     }
     return newRoot;
 }
コード例 #15
0
 private async static Task<SyntaxNode> GetFixedDocumentAsync(FixAllContext fixAllContext, Document document)
 {
     var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
     var root = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
     var nodes = diagnostics.Select(d => root.FindNode(d.Location.SourceSpan, getInnermostNodeForTie: true).FirstAncestorOrSelfOfType<InvocationExpressionSyntax>()).Where(n => !n.IsMissing).ToList();
     var newRoot = root.ReplaceNodes(nodes, (original, rewritten) => rewritten.WithAdditionalAnnotations(stringFormatAnnotation));
     while (true)
     {
         var annotatedNodes = newRoot.GetAnnotatedNodes(stringFormatAnnotation);
         var node = annotatedNodes.FirstOrDefault();
         if (node == null) break;
         newRoot = StringFormatCodeFixProvider.CreateNewStringInterpolation(newRoot, (InvocationExpressionSyntax)node);
     }
     return newRoot;
 }
コード例 #16
0
 private async static Task<SyntaxNode> GetFixedDocumentAsync(FixAllContext fixAllContext, Document document)
 {
     var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
     var root = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
     var nodes = diagnostics.Select(d => root.FindNode(d.Location.SourceSpan)).Where(n => !n.IsMissing);
     var newRoot = root.ReplaceNodes(nodes, (original, rewritten) => original.WithAdditionalAnnotations(nestedIfAnnotation));
     while (true)
     {
         var annotatedNodes = newRoot.GetAnnotatedNodes(nestedIfAnnotation);
         var condition = (BinaryExpressionSyntax)annotatedNodes.FirstOrDefault();
         if (condition == null) break;
         var ifStatement = condition.FirstAncestorOfType<IfStatementSyntax>();
         newRoot = SplitIntoNestedIfCodeFixProvider.CreateNestedIf(condition, newRoot);
     }
     return newRoot;
 }
コード例 #17
0
        private static async Task<Solution> FixDocumentAsync(FixAllContext fixAllContext, Document document)
        {
            Solution solution = document.Project.Solution;
            var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
            if (diagnostics.Length == 0)
            {
                return solution;
            }

            string equivalenceKey = nameof(SA1412CodeFixProvider) + "." + diagnostics[0].Properties[SA1412StoreFilesAsUtf8.EncodingProperty];
            if (fixAllContext.CodeActionEquivalenceKey != equivalenceKey)
            {
                return solution;
            }

            return await SA1412CodeFixProvider.GetTransformedSolutionAsync(document, fixAllContext.CancellationToken).ConfigureAwait(false);
        }
 private async static Task<SyntaxNode> GetFixedDocumentAsync(FixAllContext fixAllContext, Document document)
 {
     var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
     var root = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
     var nodes = diagnostics.Select(d => root.FindNode(d.Location.SourceSpan)).Where(n => !n.IsMissing);
     var newRoot = root.ReplaceNodes(nodes, (original, rewritten) => original.WithAdditionalAnnotations(disposeAnnotation));
     var semanticModel = await document.GetSemanticModelAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
     while (true)
     {
         var annotatedNodes = newRoot.GetAnnotatedNodes(disposeAnnotation);
         var node = annotatedNodes.FirstOrDefault();
         if (node == null) break;
         newRoot = DisposableVariableNotDisposedCodeFixProvider.CreateUsing(newRoot, (ObjectCreationExpressionSyntax)node, semanticModel);
         node = newRoot.GetAnnotatedNodes(disposeAnnotation).First();
         newRoot = newRoot.ReplaceNode(node, node.WithoutAnnotations(disposeAnnotation));
     }
     return newRoot;
 }
コード例 #19
0
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

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

                List<SyntaxNode> expressions = new List<SyntaxNode>();
                foreach (var diagnostic in diagnostics)
                {
                    var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true);
                    expressions.Add(node);
                }

                return syntaxRoot.ReplaceNodes(
                    expressions,
                    (originalNode, rewrittenNode) => StringEmptyExpression.WithTriviaFrom(rewrittenNode));
            }
        private async static Task<SyntaxNode> GetFixedDocumentAsync(FixAllContext fixAllContext, Document document)
        {
            var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
            var root = await document.GetSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
            var nodes = diagnostics.Select(d => root.FindNode(d.Location.SourceSpan)).Where(n => !n.IsMissing);
            var newRoot = root.ReplaceNodes(nodes, (original, rewritten) => original.WithAdditionalAnnotations(introduceFieldAnnotation));
            var semanticModel = await document.GetSemanticModelAsync(fixAllContext.CancellationToken).ConfigureAwait(false);
            while (true)
            {
                var annotatedNodes = newRoot.GetAnnotatedNodes(introduceFieldAnnotation);
                var node = annotatedNodes.FirstOrDefault();
                if (node == null) break;

                var constructorMethod = (ConstructorDeclarationSyntax)node.Parent.Parent;
                var parameter = (ParameterSyntax)node;
                newRoot = IntroduceFieldFromConstructorCodeFixProvider.IntroduceFieldFromConstructor(newRoot, constructorMethod, parameter);
                node = newRoot.GetAnnotatedNodes(introduceFieldAnnotation).First();
                newRoot = newRoot.ReplaceNode(node, node.WithoutAnnotations(introduceFieldAnnotation));
            }
            return newRoot;
        }
コード例 #21
0
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

                var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);

                List<SyntaxTrivia> tokensToFix = new List<SyntaxTrivia>();
                foreach (var diagnostic in diagnostics)
                {
                    SyntaxTrivia whitespace = syntaxRoot.FindTrivia(diagnostic.Location.SourceSpan.Start, findInsideTrivia: true);
                    if (whitespace.Span.Length > 1)
                    {
                        tokensToFix.Add(whitespace);
                    }
                }

                return syntaxRoot.ReplaceTrivia(tokensToFix, (originalTrivia, rewrittenTrivia) => SyntaxFactory.Space);
            }
コード例 #22
0
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

                var text = await document.GetTextAsync().ConfigureAwait(false);

                List<TextChange> changes = new List<TextChange>();

                foreach (var diagnostic in diagnostics)
                {
                    changes.Add(new TextChange(diagnostic.Location.SourceSpan, string.Empty));
                }

                changes.Sort((left, right) => left.Span.Start.CompareTo(right.Span.Start));

                var tree = await document.GetSyntaxTreeAsync().ConfigureAwait(false);
                return await tree.WithChangedText(text.WithChanges(changes)).GetRootAsync().ConfigureAwait(false);
            }
コード例 #23
0
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

                var newLine = fixAllContext.Document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp);
                var text = await document.GetTextAsync().ConfigureAwait(false);

                List<TextChange> changes = new List<TextChange>();

                foreach (var diagnostic in diagnostics)
                {
                    changes.Add(new TextChange(diagnostic.Location.SourceSpan, newLine));
                }

                changes.Sort((left, right) => left.Span.Start.CompareTo(right.Span.Start));

                var tree = await document.GetSyntaxTreeAsync().ConfigureAwait(false);
                return await tree.WithChangedText(text.WithChanges(changes)).GetRootAsync().ConfigureAwait(false);
            }
コード例 #24
0
        protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
        {
            var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
            if (diagnostics.IsEmpty)
            {
                return null;
            }

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

            List<SyntaxNode> nodes = new List<SyntaxNode>();
            foreach (var diagnostic in diagnostics)
            {
                SyntaxNode node = root.FindNode(diagnostic.Location.SourceSpan);
                if (node.IsMissing)
                {
                    continue;
                }

                nodes.Add(node);
            }

            return root.ReplaceNodes(nodes, (originalNode, rewrittenNode) => AddParentheses(originalNode, rewrittenNode));
        }
コード例 #25
0
        public virtual async Task<ImmutableDictionary<Document, ImmutableArray<Diagnostic>>> GetDocumentDiagnosticsToFixAsync(FixAllContext fixAllContext)
        {
            using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Diagnostics, fixAllContext.CancellationToken))
            {
                var allDiagnostics = ImmutableArray<Diagnostic>.Empty;
                var projectsToFix = ImmutableArray<Project>.Empty;

                var document = fixAllContext.Document;
                var project = fixAllContext.Project;
                var generatedCodeServices = project.Solution.Workspace.Services.GetService<IGeneratedCodeRecognitionService>();

                switch (fixAllContext.Scope)
                {
                    case FixAllScope.Document:
                        if (document != null && !generatedCodeServices.IsGeneratedCode(document))
                        {
                            var documentDiagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                            var kvp = SpecializedCollections.SingletonEnumerable(KeyValuePair.Create(document, documentDiagnostics));
                            return ImmutableDictionary.CreateRange(kvp);
                        }

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

                        var diagnostics = new ConcurrentBag<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 fixAllContext.GetAllDiagnosticsAsync(projectToFix).ConfigureAwait(false);
                                foreach (var diagnostic in projectDiagnostics)
                                {
                                    fixAllContext.CancellationToken.ThrowIfCancellationRequested();
                                    diagnostics.Add(diagnostic);
                                }
                            }, fixAllContext.CancellationToken);
                        }

                        await Task.WhenAll(tasks).ConfigureAwait(false);
                        allDiagnostics = allDiagnostics.AddRange(diagnostics);
                        break;
                }

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

                return await GetDocumentDiagnosticsToFixAsync(allDiagnostics, projectsToFix, generatedCodeServices.IsGeneratedCode, fixAllContext.CancellationToken).ConfigureAwait(false);
            }
        }
コード例 #26
0
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

                var indentationOptions = IndentationOptions.FromDocument(document);
                var orderingChecks = await GetEnabledRulesForDocumentAsync(document, fixAllContext.CancellationToken).ConfigureAwait(false);
                var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);

                var trackedDiagnosticMembers = new List<MemberDeclarationSyntax>();
                foreach (var diagnostic in diagnostics)
                {
                    var memberDeclaration = syntaxRoot.FindNode(diagnostic.Location.SourceSpan).FirstAncestorOrSelf<MemberDeclarationSyntax>();
                    if (memberDeclaration == null)
                    {
                        continue;
                    }

                    trackedDiagnosticMembers.Add(memberDeclaration);
                }

                syntaxRoot = syntaxRoot.TrackNodes(trackedDiagnosticMembers);

                foreach (var member in trackedDiagnosticMembers)
                {
                    var memberDeclaration = syntaxRoot.GetCurrentNode(member);
                    syntaxRoot = UpdateSyntaxRoot(memberDeclaration, orderingChecks, syntaxRoot, indentationOptions);
                }

                return syntaxRoot;
            }
コード例 #27
0
            public override async Task<CodeAction> GetFixAsync(FixAllContext fixAllContext)
            {
                var diagnosticsToFix = new List<KeyValuePair<Project, ImmutableArray<Diagnostic>>>();
                string titleFormat = "Add all items in {0} {1} to the public API";
                string title = null;

                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));
                        title = string.Format(titleFormat, "document", fixAllContext.Document.Name);
                        break;
                    }

                case FixAllScope.Project:
                    {
                        var project = fixAllContext.Project;
                        ImmutableArray<Diagnostic> diagnostics = await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false);
                        diagnosticsToFix.Add(new KeyValuePair<Project, ImmutableArray<Diagnostic>>(fixAllContext.Project, diagnostics));
                        title = string.Format(titleFormat, "project", fixAllContext.Project.Name);
                        break;
                    }

                case FixAllScope.Solution:
                    {
                        foreach (var project in fixAllContext.Solution.Projects)
                        {
                            ImmutableArray<Diagnostic> diagnostics = await fixAllContext.GetAllDiagnosticsAsync(project).ConfigureAwait(false);
                            diagnosticsToFix.Add(new KeyValuePair<Project, ImmutableArray<Diagnostic>>(project, diagnostics));
                        }

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

                case FixAllScope.Custom:
                    return null;

                default:
                    break;
                }

                return new FixAllAdditionalDocumentChangeAction(title, fixAllContext.Solution, diagnosticsToFix);
            }
コード例 #28
0
            internal virtual async Task <ImmutableDictionary <Document, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixWorkerAsync(
                FixAllContext fixAllContext)
            {
                var cancellationToken = fixAllContext.CancellationToken;

                using (Logger.LogBlock(
                           FunctionId.CodeFixes_FixAllOccurrencesComputation_Document_Diagnostics,
                           FixAllLogger.CreateCorrelationLogMessage(fixAllContext.State.CorrelationId),
                           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 && !document.IsGeneratedCode(cancellationToken))
                        {
                            var documentDiagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);

                            var kvp = SpecializedCollections.SingletonEnumerable(KeyValuePair.Create(document, documentDiagnostics));
                            return(ImmutableDictionary.CreateRange(kvp));
                        }

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

                        var progressTracker = fixAllContext.ProgressTracker;
                        progressTracker.AddItems(projectsToFix.Length);

                        var diagnostics = new ConcurrentBag <Diagnostic>();
                        var tasks       = new Task[projectsToFix.Length];
                        for (int 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);
                                foreach (var diagnostic in projectDiagnostics)
                                {
                                    cancellationToken.ThrowIfCancellationRequested();
                                    diagnostics.Add(diagnostic);
                                }

                                progressTracker.ItemCompleted();
                            }, cancellationToken);
                        }

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

                        allDiagnostics = allDiagnostics.AddRange(diagnostics);
                        break;
                    }

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

                    return(await GetDocumentDiagnosticsToFixAsync(
                               allDiagnostics, projectsToFix, fixAllContext.CancellationToken).ConfigureAwait(false));
                }
            }
コード例 #29
0
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

                var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);

                List<SyntaxToken> tokensToReplace = new List<SyntaxToken>(diagnostics.Length);
                foreach (var diagnostic in diagnostics)
                {
                    tokensToReplace.Add(GetBaseKeywordToken(syntaxRoot, diagnostic.Location.SourceSpan));
                }

                return syntaxRoot.ReplaceTokens(tokensToReplace, (originalToken, rewrittenToken) => RewriteBaseAsThis(rewrittenToken));
            }
コード例 #30
0
        public static async Task <ImmutableDictionary <Document, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixAsync(
            FixAllContext fixAllContext,
            IProgressTracker?progressTrackerOpt)
        {
            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 && !await document.IsGeneratedCodeAsync(cancellationToken).ConfigureAwait(false))
                {
                    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, fixAllContext.CancellationToken).ConfigureAwait(false));
        }
コード例 #31
0
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

                var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);

                List<SyntaxTrivia> trivias = new List<SyntaxTrivia>();

                foreach (var diagnostic in diagnostics)
                {
                    trivias.Add(syntaxRoot.FindTrivia(diagnostic.Location.SourceSpan.Start));
                }

                var tokensWithTrivia = trivias.GroupBy(x => x.Token);

                Dictionary<SyntaxToken, SyntaxToken> replacements = new Dictionary<SyntaxToken, SyntaxToken>();

                foreach (var tokenWithTrivia in tokensWithTrivia)
                {
                    var token = tokenWithTrivia.Key;
                    var newLeadingTrivia = FixTriviaList(token.LeadingTrivia, tokenWithTrivia);
                    var newTrailingTrivia = FixTriviaList(token.TrailingTrivia, tokenWithTrivia);

                    replacements.Add(token, token.WithLeadingTrivia(newLeadingTrivia).WithTrailingTrivia(newTrailingTrivia));
                }

                return syntaxRoot.ReplaceTokens(replacements.Keys, (oldToken, newToken) => replacements[oldToken]);
            }
コード例 #32
0
ファイル: BatchFixAllProvider.cs プロジェクト: yicong/roslyn
        public virtual async Task <ImmutableDictionary <Document, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixAsync(FixAllContext fixAllContext)
        {
            using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Diagnostics, fixAllContext.CancellationToken))
            {
                IEnumerable <Document> documentsToFix = null;
                var document = fixAllContext.Document;
                var project  = fixAllContext.Project;

                var generatedCodeServices = project.Solution.Workspace.Services.GetService <IGeneratedCodeRecognitionService>();

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

                        var kvp = SpecializedCollections.SingletonEnumerable(KeyValuePair.Create(document, diagnostics));
                        return(ImmutableDictionary.CreateRange(kvp));
                    }

                    break;

                case FixAllScope.Project:
                    documentsToFix = project.Documents;
                    break;

                case FixAllScope.Solution:
                    documentsToFix = project.Solution.Projects
                                     .Where(p => p.Language == project.Language)
                                     .SelectMany(p => p.Documents);
                    break;
                }

                if (documentsToFix != null && documentsToFix.Any())
                {
                    var documentAndDiagnostics = new ConcurrentDictionary <Document, ImmutableArray <Diagnostic> >();
                    var options = new ParallelOptions()
                    {
                        CancellationToken = fixAllContext.CancellationToken
                    };
                    Parallel.ForEach(documentsToFix, options, doc =>
                    {
                        fixAllContext.CancellationToken.ThrowIfCancellationRequested();

                        if (!generatedCodeServices.IsGeneratedCode(doc))
                        {
                            var documentDiagnostics = fixAllContext.GetDocumentDiagnosticsAsync(doc).WaitAndGetResult(fixAllContext.CancellationToken);
                            if (documentDiagnostics.Any())
                            {
                                documentAndDiagnostics.TryAdd(doc, documentDiagnostics);
                            }
                        }
                    });

                    return(documentAndDiagnostics.ToImmutableDictionary());
                }

                return(ImmutableDictionary <Document, ImmutableArray <Diagnostic> > .Empty);
            }
        }
コード例 #33
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);
                    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);
        }
コード例 #34
0
        public virtual async Task <ImmutableDictionary <Document, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixAsync(FixAllContext fixAllContext)
        {
            using (Logger.LogBlock(FunctionId.CodeFixes_FixAllOccurrencesComputation_Diagnostics, fixAllContext.CancellationToken))
            {
                var allDiagnostics = ImmutableArray <Diagnostic> .Empty;
                var projectsToFix  = ImmutableArray <Project> .Empty;

                var document = fixAllContext.Document;
                var project  = fixAllContext.Project;
                var generatedCodeServices = project.Solution.Workspace.Services.GetService <IGeneratedCodeRecognitionService>();

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

                        var kvp = SpecializedCollections.SingletonEnumerable(KeyValuePair.Create(document, documentDiagnostics));
                        return(ImmutableDictionary.CreateRange(kvp));
                    }

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

                    var diagnostics = new ConcurrentBag <Diagnostic>();
                    var tasks       = new Task[projectsToFix.Length];
                    for (int i = 0; i < projectsToFix.Length; i++)
                    {
                        var projectToFix = projectsToFix[i];
                        tasks[i] = Task.Run(async() =>
                        {
                            var projectDiagnostics = await fixAllContext.GetAllDiagnosticsAsync(projectToFix).ConfigureAwait(false);
                            foreach (var diagnostic in projectDiagnostics)
                            {
                                diagnostics.Add(diagnostic);
                            }
                        }, fixAllContext.CancellationToken);
                    }

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

                    allDiagnostics = allDiagnostics.AddRange(diagnostics);
                    break;
                }

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

                return(await GetDocumentDiagnosticsToFixAsync(allDiagnostics, projectsToFix, generatedCodeServices.IsGeneratedCode, fixAllContext.CancellationToken).ConfigureAwait(false));
            }
        }
コード例 #35
0
        public static async Task <ImmutableDictionary <Document, ImmutableArray <Diagnostic> > > GetDocumentDiagnosticsToFixAsync(FixAllContext fixAllContext)
        {
            var cancellationToken = fixAllContext.CancellationToken;

            var allDiagnostics = ImmutableArray <Diagnostic> .Empty;

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

            var progressTracker = fixAllContext.GetProgressTracker();

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

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

                break;

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

                break;

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

                // Update the progress dialog with the count of projects to actually fix. We'll update the progress
                // bar as we get all the documents in AddDocumentDiagnosticsAsync.

                progressTracker.AddItems(projectsToFix.Length);

                var diagnostics = new ConcurrentDictionary <ProjectId, ImmutableArray <Diagnostic> >();
                using (var _ = ArrayBuilder <Task> .GetInstance(projectsToFix.Length, out var tasks))
                {
                    foreach (var projectToFix in projectsToFix)
                    {
                        tasks.Add(Task.Run(async() => await AddDocumentDiagnosticsAsync(diagnostics, projectToFix).ConfigureAwait(false), 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(
                       fixAllContext.Solution, allDiagnostics, fixAllContext.CancellationToken).ConfigureAwait(false));

            async Task AddDocumentDiagnosticsAsync(ConcurrentDictionary <ProjectId, ImmutableArray <Diagnostic> > diagnostics, Project projectToFix)
            {
                try
                {
                    var projectDiagnostics = await fixAllContext.GetAllDiagnosticsAsync(projectToFix).ConfigureAwait(false);

                    diagnostics.TryAdd(projectToFix.Id, projectDiagnostics);
                }
                finally
                {
                    progressTracker.ItemCompleted();
                }
            }
        }
コード例 #36
0
            protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document)
            {
                var diagnostics = await fixAllContext.GetDocumentDiagnosticsAsync(document).ConfigureAwait(false);
                if (diagnostics.IsEmpty)
                {
                    return null;
                }

                SyntaxNode syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);
                List<SyntaxNode> nodesNeedingBlocks = new List<SyntaxNode>(diagnostics.Length);

                foreach (Diagnostic diagnostic in diagnostics)
                {
                    var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan, false, true) as StatementSyntax;
                    if (node == null || node.IsMissing)
                    {
                        continue;
                    }

                    // If the parent of the statement contains a conditional directive, stuff will be really hard to fix correctly, so don't offer a code fix.
                    if (ContainsConditionalDirectiveTrivia(node.Parent))
                    {
                        continue;
                    }

                    nodesNeedingBlocks.Add(node);
                }

                return syntaxRoot.ReplaceNodes(nodesNeedingBlocks, (originalNode, rewrittenNode) => SyntaxFactory.Block((StatementSyntax)rewrittenNode));
            }