Search code examples
c#.netcurly-bracesroslyn

Strange parsing behavior of single closing braces using Roslyn-CTP


We're writing a code generator with roslyn. Among other things the user should be able to specify the single statements of a method body or the body of a getter/setter of a property. Therefore he passes a list of strings to a translation method. When passing single curly braces as statements the closing brace gets swallowed somehow.

The method:

internal static SyntaxList<StatementSyntax> GetSyntaxListOfStatementSyntaxs(IEnumerable<string> statements)
{
    if (statements.Any())
    {
        var statementSyntaxs = statements.Select(s => Syntax.ParseStatement(s));
        return Syntax.List(statementSyntaxs);
    }
    return Syntax.List<StatementSyntax>();
}

The input:

var list = new List<string>
{
    "if (this.field != null)",
    "{",
    "this.field = new MyType();",
    "}",
    "return this.field;"
};

The SyntaxList would be used in a new method declaration (last parameter):

 var methodDeclarationSyntax = Syntax.MethodDeclaration(
                Syntax.List<AttributeDeclarationSyntax>(),
                Syntax.TokenList(),
                Syntax.IdentifierName("MyType"),
                null,
                Syntax.Identifier("MethodIdentifier"),
                null,
                Syntax.ParameterList(),
                Syntax.List<TypeParameterConstraintClauseSyntax>(),
                Syntax.Block(statementSyntaxList));

I also tried to process the single closing brace separately but I didn't manage to create a statement with only one closing brace.

The weird thing is the single opening brace gets parsed as a syntax block (correctly or not) but it seems impossible to create that syntax block manually. Neither for the opening nor for the closing brace.

I don't want to add custom parsing of these statements because we decided for Roslyn to be free of parsing tasks. Does someone know how to deal with these special statements? Or maybe somebody can come with another way to treat this issue. Any help appreciated. Thanks in advance.


Solution

  • The problem is that neither an opening brace nor a closing brace are statements, so you can't parse them as such.

    Roslyn tries to parse even invalid code, which is why you're getting a BlockSyntax when you parse {. But it's an incomplete block, with the closing brace missing.

    I think you should parse the whole method body at once. You could do that by joining the lines together into one string and adding an opening and closing brace.

    So, the string that you would actually parse as a statement would look like:

    {
    if (this.field != null)
    {
    this.field = new MyType();
    }
    return this.field;
    }