James Ko
James Ko

Reputation: 34609

How do I insert a statement into a block with normalized whitespace using Roslyn?

I'm new to Roslyn. I'm writing a code fix provider that transforms foreach blocks that iterate through the results of a Select, e.g.

foreach (var item in new int[0].Select(i => i.ToString()))
{
    ...
}

to

foreach (int i in new int[0])
{
    var item = i.ToString();
    ...
}

To do this, I need to insert a statement at the beginning of the BlockSyntax inside the ForEachStatementSyntax that represents the foreach block. Here is my code for that:

var blockStatement = forEach.Statement as BlockSyntax;
if (blockStatement == null)
{
    return document;
}
forEach = forEach.WithStatement(
    blockStatment.WithStatements(
        blockStatement.Statements.Insert(0, selectorStatement));

Unfortunately, doing that results in the whitespace being off:

            foreach (int i in new int[0])
            {
var item = i.ToString();
                ...
            }

I Googled solutions for this. I came across this answer, which recommended using either Formatter.Format or SyntaxNode.NormalizeWhitespace.

So is it possible to simply insert the statement with the correct indentation in the first place, without having to format other code?

Thanks.

Upvotes: 5

Views: 1089

Answers (1)

Jonathon Marolf
Jonathon Marolf

Reputation: 2089

You can add the Formatter Annotation to the nodes that you want the formatter to run on using WithAdditionalAnnotations

blockStatement.Statements.Insert(0, selectorStatement.WithAdditionalAnnotations(Formatter.Annotation))

Upvotes: 4

Related Questions