Unable to parse code snippet in roslyn

2019-08-02 12:06发布

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 :)

0条回答
登录 后发表回答