Why are params arrays and optional parameters not generated by the roslyn SyntaxGenerator?

Viewed 83

The roslyn SyntaxGenerator generates Syntax based on symbols. I've used these APIs quite extensively so far without any problems, but recently I came across one specific case which is not working as expected:

  • When using SyntaxGenerator.MethodDeclaration(IMethodSymbol), certain parameter properties are not generated properly in the SyntaxNodes although they are present in the orginal symbol. So far this was the case for:
    • params arrays (=> instead, an ordinary array parameter is created)
    • optional parameters (=> the initializer expression is missing)
  • This is true for generated C# code as well as for VB.NET (so regardless of the output language, params arrays and optional parameters are not generated properly).

Sample code:

public class GenerationDemo
{
    public static string GenerateMethod()
    {
        using var workspace = new AdhocWorkspace();
        var project = GetProject(workspace);

        var type = project.GetCompilationAsync().Result?.GetTypeByMetadataName(typeof(GenerationDemo).FullName);
        var method = type.GetMembers(nameof(Test)).Cast<IMethodSymbol>().Single();
        var generator = SyntaxGenerator.GetGenerator(project);

        return generator.MethodDeclaration(method).NormalizeWhitespace().ToFullString();
    }

    public void Test(bool something = true, params int[] numbers)
    {
    }

    private static Project GetProject(AdhocWorkspace workspace)
    {
        const string projectName = "TestProject";
        var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), projectName,
            projectName, LanguageNames.CSharp,
            metadataReferences: new[]
            {
                MetadataReference.CreateFromFile(typeof(GenerationDemo).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(string).Assembly.Location)
            });
        return workspace.AddProject(projectInfo);
    }
}

Expected behaviour:

GenerationDemo.GenerateMethod() returns:

public void Test(global::System.Boolean something = false, params global::System.Int32[] numbers)
{
}

Actual behaviour:

GenerationDemo.GenerateMethod() returns:

public void Test(global::System.Boolean something, global::System.Int32[] numbers)
{
}

Questions:

  • Why are specific pieces like params arrays and optional parameters not generated by the roslyn SyntaxGenerator?
  • Is there a way to achieve the desired result with the help of the SyntaxGenerator (besides of just adjusting the generated syntax manually afterwards for the specific cases)
  • ...or is this just not supported by the SyntaxGenerator? If so, is this documented somewhere and what else is not generated?
1 Answers

This might just be a bug. I'd recommend filing one on GitHub if you didn't already.

Related