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 aWorkspace
parameter, and it looks I don't have access to aWorkspace
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 theForEachStatementSyntax
associated with theforeach
block, and then callingsyntaxRoot = syntaxRoot.ReplaceNode(oldForEach, newForEach)
, but that results in the entireforeach
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.