Example #1
0
        public override async Task <Document> RemoveUnnecessaryImportsAsync(
            Document document,
            Func <SyntaxNode, bool> predicate,
            SyntaxFormattingOptions formattingOptions,
            CancellationToken cancellationToken)
        {
            predicate ??= Functions <SyntaxNode> .True;
            using (Logger.LogBlock(FunctionId.Refactoring_RemoveUnnecessaryImports_CSharp, cancellationToken))
            {
                var unnecessaryImports = await GetCommonUnnecessaryImportsOfAllContextAsync(
                    document, predicate, cancellationToken).ConfigureAwait(false);

                if (unnecessaryImports == null || unnecessaryImports.Any(import => import.OverlapsHiddenPosition(cancellationToken)))
                {
                    return(document);
                }

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

                var oldRoot = (CompilationUnitSyntax)root;
                var newRoot = (CompilationUnitSyntax) new Rewriter(document, unnecessaryImports, cancellationToken).Visit(oldRoot);

                cancellationToken.ThrowIfCancellationRequested();
#if CODE_STYLE
                var provider = GetSyntaxFormatting();
#else
                var provider = document.Project.Solution.Workspace.Services;
#endif
                var spans = new List <TextSpan>();
                AddFormattingSpans(newRoot, spans, cancellationToken);
                var formattedRoot = Formatter.Format(newRoot, spans, provider, formattingOptions, rules: null, cancellationToken);

                return(document.WithSyntaxRoot(formattedRoot));
            }
        }
        protected override async Task FixAllAsync(Document document, ImmutableArray <Diagnostic> diagnostics, SyntaxEditor editor, CodeActionOptionsProvider options, CancellationToken cancellationToken)
        {
            var formattingOptions = await GetOptionsAsync(document, cancellationToken).ConfigureAwait(false);

            var updatedRoot = Formatter.Format(editor.OriginalRoot, SyntaxFormatting, formattingOptions, cancellationToken);

            editor.ReplaceNode(editor.OriginalRoot, updatedRoot);
        }
 public sealed override FixAllProvider GetFixAllProvider()
 => FixAllProvider.Create(async(context, document, diagnostics) =>
 {
     var cancellationToken = context.CancellationToken;
     var options           = await GetOptionsAsync(document, cancellationToken).ConfigureAwait(false);
     var syntaxRoot        = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
     var updatedSyntaxRoot = Formatter.Format(syntaxRoot, this.SyntaxFormatting, options, cancellationToken);
     return(document.WithSyntaxRoot(updatedSyntaxRoot));
 });
            protected override async Task <SyntaxNode> FixAllInDocumentAsync(FixAllContext fixAllContext, Document document, ImmutableArray <Diagnostic> diagnostics)
            {
                var options = await GetOptionsAsync(document, fixAllContext.CancellationToken).ConfigureAwait(false);

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

                var updatedSyntaxRoot = Formatter.Format(syntaxRoot, _formattingCodeFixProvider.SyntaxFormattingService, options, fixAllContext.CancellationToken);

                return(updatedSyntaxRoot);
            }
        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));
        }
        protected override async Task FixAllAsync(
            Document document, ImmutableArray <Diagnostic> diagnostics, SyntaxEditor editor,
            CodeActionOptionsProvider fallbackOptions, CancellationToken cancellationToken)
        {
            var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            // Defer to our callback to actually make the edits for each diagnostic. In turn, it
            // will return 'true' if it made a multi-line conditional expression. In that case,
            // we'll need to explicitly format this node so we can get our special multi-line
            // formatting in VB and C#.
            var nestedEditor = document.GetSyntaxEditor(root);

            foreach (var diagnostic in diagnostics)
            {
                await FixOneAsync(
                    document, diagnostic, nestedEditor, fallbackOptions, cancellationToken).ConfigureAwait(false);
            }

            var changedRoot = nestedEditor.GetChangedRoot();

            // Get the language specific rule for formatting this construct and call into the
            // formatted to explicitly format things.  Note: all we will format is the new
            // conditional expression as that's the only node that has the appropriate
            // annotation on it.
            var rules = new List <AbstractFormattingRule> {
                GetMultiLineFormattingRule()
            };

#if CODE_STYLE
            var provider = GetSyntaxFormatting();
#else
            var provider = document.Project.Solution.Services;
#endif
            var options = await document.GetCodeFixOptionsAsync(fallbackOptions, cancellationToken).ConfigureAwait(false);

            var formattingOptions = options.GetFormattingOptions(GetSyntaxFormatting());
            var formattedRoot     = Formatter.Format(changedRoot, SpecializedFormattingAnnotation, provider, formattingOptions, rules, cancellationToken);

            changedRoot = formattedRoot;

            editor.ReplaceNode(root, changedRoot);
        }
Example #8
0
        internal static async Task <SyntaxTree> FixOneAsync(
            SyntaxTree syntaxTree,
            FormatterState formatterState,
            OptionSet 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);

#if CODE_STYLE
            var formattedRoot = Formatter.Format(
                root,
                formatterState,
                new[] { spanToFormat },
                options,
                Formatter.GetDefaultFormattingRules(formatterState),
                cancellationToken
                );
#else
            var formattedRoot = Formatter.Format(
                root,
                spanToFormat,
                formatterState,
                options,
                cancellationToken
                );
#endif

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