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?