internal static TNode RemoveSingleLineDocumentationComment <TNode>(TNode node, DocumentationCommentTriviaSyntax documentationComment) where TNode : SyntaxNode
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            if (!documentationComment.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia))
            {
                throw new ArgumentException($"Documentation comment's kind must be '{nameof(SyntaxKind.SingleLineDocumentationCommentTrivia)}'.", nameof(documentationComment));
            }

            SyntaxTrivia trivia = documentationComment.ParentTrivia;

            SyntaxToken token = trivia.Token;

            SyntaxTriviaList leadingTrivia = token.LeadingTrivia;

            int index = leadingTrivia.IndexOf(trivia);

            if (index >= 0 &&
                index < leadingTrivia.Count - 1 &&
                leadingTrivia[index + 1].IsWhitespaceTrivia())
            {
                SyntaxTriviaList newLeadingTrivia = leadingTrivia.RemoveRange(index, 2);

                SyntaxToken newToken = token.WithLeadingTrivia(newLeadingTrivia);

                return(node.ReplaceToken(token, newToken));
            }

            return(node.RemoveNode(documentationComment, SyntaxRemoveOptions.KeepNoTrivia));
        }
Beispiel #2
0
        public static Task <Document> RemoveEmptyLinesBeforeAsync(
            Document document,
            SyntaxToken token,
            CancellationToken cancellationToken = default)
        {
            SyntaxTriviaList leadingTrivia = token.LeadingTrivia;

            int count = 0;

            SyntaxTriviaList.Enumerator en = leadingTrivia.GetEnumerator();
            while (en.MoveNext())
            {
                if (en.Current.IsWhitespaceTrivia())
                {
                    if (!en.MoveNext())
                    {
                        break;
                    }

                    if (!en.Current.IsEndOfLineTrivia())
                    {
                        break;
                    }

                    count += 2;
                }
                else if (en.Current.IsEndOfLineTrivia())
                {
                    count++;
                }
                else
                {
                    break;
                }
            }

            SyntaxToken newToken = token.WithLeadingTrivia(leadingTrivia.RemoveRange(0, count));

            return(document.ReplaceTokenAsync(token, newToken, cancellationToken));
        }
        private static SyntaxNode AddHeader(Document document, SyntaxNode root, string name, StyleCopSettings settings)
        {
            string newLineText   = document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp);
            var    newLineTrivia = SyntaxFactory.EndOfLine(newLineText);
            var    newTrivia     = CreateNewHeader("//", name, settings, newLineText).Add(newLineTrivia).Add(newLineTrivia);

            // Skip blank lines already at the beginning of the document, since we add our own
            SyntaxTriviaList leadingTrivia = root.GetLeadingTrivia();
            int skipCount = 0;

            for (int i = 0; i < leadingTrivia.Count; i++)
            {
                bool done = false;
                switch (leadingTrivia[i].Kind())
                {
                case SyntaxKind.WhitespaceTrivia:
                    break;

                case SyntaxKind.EndOfLineTrivia:
                    skipCount = i + 1;
                    break;

                default:
                    done = true;
                    break;
                }

                if (done)
                {
                    break;
                }
            }

            newTrivia = newTrivia.AddRange(leadingTrivia.RemoveRange(0, skipCount));

            return(root.WithLeadingTrivia(newTrivia));
        }
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out CompilationUnitSyntax compilationUnit))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.NormalizeWhitespaceAtBeginningOfFile:
            {
                SyntaxToken token = compilationUnit.EndOfFileToken;

                if (token.FullSpan.Start > 0)
                {
                    token = compilationUnit.GetFirstToken();
                }

                SyntaxTriviaList leading = token.LeadingTrivia;

                string title;
                if (leading[0].IsWhitespaceTrivia() &&
                    (leading.Count == 1 ||
                     leading[1].IsEndOfLineTrivia()))
                {
                    title = "Remove whitespace";
                }
                else
                {
                    title = CodeFixTitles.RemoveNewLine;
                }

                CodeAction codeAction = CodeAction.Create(
                    title,
                    ct =>
                    {
                        SyntaxToken token = compilationUnit.EndOfFileToken;

                        if (token.FullSpan.Start > 0)
                        {
                            token = compilationUnit.GetFirstToken();
                        }

                        SyntaxTriviaList leading = token.LeadingTrivia;

                        int count = leading.TakeWhile(f => f.IsWhitespaceOrEndOfLineTrivia()).Count();

                        SyntaxToken newToken = token.WithLeadingTrivia(leading.RemoveRange(0, count));

                        return(document.ReplaceTokenAsync(token, newToken, ct));
                    },
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
                break;
            }
            }
        }
Beispiel #5
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out CompilationUnitSyntax compilationUnit))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.NormalizeWhitespaceAtEndOfFile:
            {
                bool preferNewLineAtEndOfFile = document.GetConfigOptions(compilationUnit.SyntaxTree).PreferNewLineAtEndOfFile() ?? false;

                CodeAction codeAction = CodeAction.Create(
                    (preferNewLineAtEndOfFile) ? CodeFixTitles.AddNewLine : CodeFixTitles.RemoveNewLine,
                    ct =>
                    {
                        SyntaxToken endOfFile    = compilationUnit.EndOfFileToken;
                        SyntaxTriviaList leading = endOfFile.LeadingTrivia;
                        SyntaxToken oldToken;
                        SyntaxToken newToken;

                        if (!preferNewLineAtEndOfFile)
                        {
                            if (leading.Any())
                            {
                                SyntaxTrivia last = leading.Last();

                                if (last.GetStructure() is DirectiveTriviaSyntax directive)
                                {
                                    SyntaxTriviaList trailing = directive.GetTrailingTrivia();

                                    DirectiveTriviaSyntax newDirective = directive.WithTrailingTrivia(trailing.RemoveAt(trailing.Count - 1));

                                    return(document.ReplaceNodeAsync(directive, newDirective, ct));
                                }
                                else
                                {
                                    oldToken  = endOfFile;
                                    int index = leading.Count - 1;

                                    for (int i = leading.Count - 2; i >= 0; i--)
                                    {
                                        if (leading[i].IsWhitespaceOrEndOfLineTrivia())
                                        {
                                            index--;
                                        }
                                    }

                                    newToken = oldToken.WithLeadingTrivia(leading.RemoveRange(index, leading.Count - index));
                                }
                            }
                            else
                            {
                                oldToken = endOfFile.GetPreviousToken();
                                SyntaxTriviaList trailing = oldToken.TrailingTrivia;
                                newToken = oldToken.WithTrailingTrivia(trailing.RemoveAt(trailing.Count - 1));
                            }
                        }
                        else if (leading.Any())
                        {
                            oldToken = endOfFile;

                            if (leading.Span.Start == 0 &&
                                leading.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                            {
                                newToken = oldToken.WithoutLeadingTrivia();
                            }
                            else
                            {
                                newToken = oldToken.AppendEndOfLineToLeadingTrivia();
                            }
                        }
                        else
                        {
                            oldToken = endOfFile.GetPreviousToken();
                            newToken = oldToken.AppendEndOfLineToTrailingTrivia();
                        }

                        return(document.ReplaceTokenAsync(oldToken, newToken, ct));
                    },
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
                break;
            }
            }
        }