Reputation: 34609
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
.
I can't use Formatter.Format
because that takes a Workspace
parameter, and it looks I don't have access to a Workspace
per Roslyn: Current Workspace in Diagnostic with code fix project.
I tried using NormalizeWhitespace()
on the syntax root of the document, but that invasively formatted other code not related to the fix. I tried using it on just the ForEachStatementSyntax
associated with the foreach
block, and then calling syntaxRoot = syntaxRoot.ReplaceNode(oldForEach, newForEach)
, but that results in the entire foreach
block not being properly indented.
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
var array = new int[0];
int length = array.Length;
foreach (int i in array)
{
string item = i.ToString();
} }
}
}
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
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