简体   繁体   中英

Consistent line endings in a Roslyn CodeFixProvider

I'm currently working on a CodeFixProvider using the Roslyn SDK provided in Visual Studio 2015. The goal of the provider is to add missing <exception> documentation for throw statements.

I'm building the syntax like this:

var newNodes = new XmlNodeSyntax[]
{
    SyntaxFactory.XmlText(
        SyntaxFactory.TokenList(
            SyntaxFactory.XmlTextLiteral(
                SyntaxFactory.TriviaList(SyntaxFactory.DocumentationCommentExterior("///")),
                string.Empty,
                string.Empty,
                SyntaxFactory.TriviaList()
            ),
            SyntaxFactory.XmlTextNewLine(SyntaxFactory.TriviaList(), "\n", "\n", SyntaxFactory.TriviaList()),
            SyntaxFactory.XmlTextLiteral(
                SyntaxFactory.TriviaList(SyntaxFactory.DocumentationCommentExterior("///")),
                " ",
                " ",
                SyntaxFactory.TriviaList()
            )
        )
    ),
    SyntaxFactory.XmlElement(
        SyntaxFactory.XmlElementStartTag(SyntaxFactory.XmlName("exception"))
            .WithAttributes(SyntaxFactory.SingletonList<XmlAttributeSyntax>(
                SyntaxFactory.XmlCrefAttribute(
                    SyntaxFactory.XmlName("cref"),
                    SyntaxFactory.Token(SyntaxKind.DoubleQuoteToken),
                    SyntaxFactory.NameMemberCref(
                        SyntaxFactory.IdentifierName(thrownTypeSymbol.ToMinimalDisplayString(semanticModel, throwSyntax.GetLocation().SourceSpan.Start))
                    ),
                    SyntaxFactory.Token(SyntaxKind.DoubleQuoteToken)
                ).WithLeadingTrivia(
                    SyntaxFactory.TriviaList(
                        SyntaxFactory.Whitespace(" ")
                    )
                )
            )),
        SyntaxFactory.XmlElementEndTag(SyntaxFactory.XmlName("exception"))
    ).WithContent(
        SyntaxFactory.List<XmlNodeSyntax>(new[] {
            SyntaxFactory.XmlText()
                .WithTextTokens(
                    SyntaxFactory.TokenList(
                        SyntaxFactory.XmlTextNewLine(SyntaxFactory.TriviaList(), "\n", "\n", SyntaxFactory.TriviaList()),
                        SyntaxFactory.XmlTextLiteral(
                            SyntaxFactory.TriviaList(SyntaxFactory.DocumentationCommentExterior("///")),
                            " ",
                            " ",
                            SyntaxFactory.TriviaList()
                        ),
                        SyntaxFactory.XmlTextNewLine(SyntaxFactory.TriviaList(), "\n", "\n", SyntaxFactory.TriviaList()),
                        SyntaxFactory.XmlTextLiteral(
                            SyntaxFactory.TriviaList(SyntaxFactory.DocumentationCommentExterior("///")),
                            " ",
                            " ",
                            SyntaxFactory.TriviaList()
                        )
                    )
                )  
        })
    ),
    SyntaxFactory.XmlText(
        SyntaxFactory.TokenList(    
            SyntaxFactory.XmlTextNewLine(
                SyntaxFactory.TriviaList(),
                Environment.NewLine,
                Environment.NewLine,
                SyntaxFactory.TriviaList()
            )   
        )
    )
};

And then later appending the nodes to an existing DocumentationCommentTriviaSyntax node.

newTrivia = xmlTrivia.AddContent(newNodes);

The problem
This does add the missing <exception> documentation comments, but sadly using the wrong line endings. I could change the hardcoded \\n to Environment.NewLine but that still might not match the line endings of the file.

Is there a way to use the line endings of the document the fix is applied in?

You could detect which linebreak is used like this

    private SyntaxTrivia _detectLineBreakTrivia(SyntaxNode root)
    {
       var result = root.DescendantTokens()
                        .SelectMany(token => token.TrailingTrivia)
                         .FirstOrDefault(trivia => trivia.IsKind(SyntaxKind.EndOfLineTrivia));
       if(Equals(result, default(SyntaxTrivia))
           resut = SyntaxFactory.CarriageReturnLineFeed;
       return result;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM