Exemplo n.º 1
0
        internal static void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context, FormattingProvider formattingProvider, DiagnosticDescriptor descriptor, SyntaxFormattingOptions options)
        {
            var tree = context.Tree;
            var cancellationToken = context.CancellationToken;

            var oldText = tree.GetText(cancellationToken);

            var formattingChanges = Formatter.GetFormattedTextChanges(tree.GetRoot(cancellationToken), formattingProvider, options, cancellationToken);

            // formattingChanges could include changes that impact a larger section of the original document than
            // necessary. Before reporting diagnostics, process the changes to minimize the span of individual
            // diagnostics.
            foreach (var formattingChange in formattingChanges)
            {
                var change = formattingChange;
                if (change.NewText.Length > 0 && !change.Span.IsEmpty)
                {
                    // Handle cases where the change is a substring removal from the beginning. In these cases, we want
                    // the diagnostic span to cover the unwanted leading characters (which should be removed), and
                    // nothing more.
                    var offset = change.Span.Length - change.NewText.Length;
                    if (offset >= 0)
                    {
                        if (oldText.GetSubText(new TextSpan(change.Span.Start + offset, change.NewText.Length)).ContentEquals(SourceText.From(change.NewText)))
                        {
                            change = new TextChange(new TextSpan(change.Span.Start, offset), "");
                        }
                        else
                        {
                            // Handle cases where the change is a substring removal from the end. In these cases, we want
                            // the diagnostic span to cover the unwanted trailing characters (which should be removed), and
                            // nothing more.
                            if (oldText.GetSubText(new TextSpan(change.Span.Start, change.NewText.Length)).ContentEquals(SourceText.From(change.NewText)))
                            {
                                change = new TextChange(new TextSpan(change.Span.Start + change.NewText.Length, offset), "");
                            }
                        }
                    }
                }

                if (change.NewText.Length == 0 && change.Span.IsEmpty)
                {
                    // No actual change (allows for the formatter to report a NOP change without triggering a
                    // diagnostic that can't be fixed).
                    continue;
                }

                var location = Location.Create(tree, change.Span);
                context.ReportDiagnostic(Diagnostic.Create(
                                             descriptor,
                                             location,
                                             additionalLocations: null,
                                             properties: null));
            }
        }
        internal static async Task <SyntaxTree> FixOneAsync(SyntaxTree syntaxTree, FormattingProvider formattingProvider, SyntaxFormattingOptions options, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            // The span to format is the full line(s) containing the diagnostic
            var text = await syntaxTree.GetTextAsync(cancellationToken).ConfigureAwait(false);

            var diagnosticSpan             = diagnostic.Location.SourceSpan;
            var diagnosticLinePositionSpan = text.Lines.GetLinePositionSpan(diagnosticSpan);
            var spanToFormat = TextSpan.FromBounds(
                text.Lines[diagnosticLinePositionSpan.Start.Line].Start,
                text.Lines[diagnosticLinePositionSpan.End.Line].End);

            var root = await syntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);

            var formattedRoot = Formatter.Format(root, spanToFormat, formattingProvider, options, cancellationToken);

            return(syntaxTree.WithRootAndOptions(formattedRoot, syntaxTree.Options));
        }