I'm trying to dynamically build a c# class from small pieces of code. We have a window where a user can enter c# code (valid or not), and we parse these strings into roslyn. I recently found an issue when i was using this :
public override IEnumerable<StatementSyntax> GenerateStatements()
{
var result = new List<StatementSyntax>();
if (!string.IsNullOrWhiteSpace(this.Tag.Code))
{
result.Add(SyntaxFactory.ParseStatement(this.Tag.Code));
}
return result;
}
Turns out when compiling in VB, if the statement is multiline, it would inline all the text, even in c#.
I then made an helper class to parse it into a dummy class and method to get a list of parsed statements.
public override IEnumerable<StatementSyntax> GenerateStatements()
{
var result = new List<StatementSyntax>();
if (!string.IsNullOrWhiteSpace(this.Tag.Code))
{
foreach (var statement in SyntaxFactoryHelper.ParseStatements(this.Tag.Code))
{
result.Add(statement);
}
}
return result;
}
public static StatementSyntax[] ParseStatements(string code)
{
var blockCode = string.Format(CultureInfo.InvariantCulture, "public class C {{ public void M() {{ {0} }} }}", code);
var compilationUnit = SyntaxFactory.ParseCompilationUnit(blockCode);
return compilationUnit
.ChildNodes().OfType<ClassDeclarationSyntax>().First(c => c.Identifier.Text == "C")
.ChildNodes().OfType<MethodDeclarationSyntax>().First(m => m.Identifier.Text == "M")
.ChildNodes().OfType<BlockSyntax>().First()
.Statements.ToArray();
}
Here's my issue.
If i have 3 statements in my applications.
for (var i = 0; i < 10; i++)
{
then
i.ToString()
and finally
}
It auto-closes the curly braces of the first statement, so I lose my scope.
Is there a way to parse invalid code and avoid this kind of behavior?
I know inlined code is valid in c#, but we are facing the same issue with VB.
Thanks for your help :)