vendredi 31 mars 2023

Roslyn: generate method optional parameters from reflected interface

Given SomeInterfaceType that has a method with optional parameters:

interface SomeInterface
{
    void SomeMethod(int a = 1, string c = "foo",
                    SomeType e = default, SomeType f = null);
}

SomeInterfaceType = typeof(SomeInterface);

How do I create a MethodDeclarationSyntax from the reflected type?

I'm retrieving the list of parameters from the MethodInfo like this:

private ParameterListSyntax GenerateParameterListSyntax(MethodInfo info)
{ 
    var parameters = info.GetParameters();
    var parameterList = new SeparatedSyntaxList<ParameterSyntax>();

    foreach (var parameter in parameters)
    {
        var parameterSyntax = SyntaxFactory.Parameter(SyntaxFactory.Identifier(parameter.Name))
                    .WithType(SyntaxFactory.ParseTypeName(TypeNameOrAlias(parameter.ParameterType)));

        if (parameter.IsOptional)
        {
            parameterSyntax = parameterSyntax.WithDefault( <<< WHAT DO I DO HERE?>>> );
        }

        parameterList.Add(parameterSyntax);
    }

    return SyntaxFactory.ParameterList(parameterList);
}

How do I autogenerate the EqualsValueClause to complete the WithDefault method ?

I leave here the output of RoslynQuoter for SomeInterface as reference.

CompilationUnit()
.WithMembers(
    SingletonList<MemberDeclarationSyntax>(
        InterfaceDeclaration("SomeInterface")
        .WithMembers(
            SingletonList<MemberDeclarationSyntax>(
                MethodDeclaration(
                    PredefinedType(
                        Token(SyntaxKind.VoidKeyword)),
                    Identifier("SomeMethod"))
                .WithParameterList(
                    ParameterList(
                        SeparatedList<ParameterSyntax>(
                            new SyntaxNodeOrToken[]{
                                Parameter(
                                    Identifier("a"))
                                .WithType(
                                    PredefinedType(
                                        Token(SyntaxKind.IntKeyword)))
                                .WithDefault(
                                    EqualsValueClause(
                                        LiteralExpression(
                                            SyntaxKind.NumericLiteralExpression,
                                            Literal(1)))),
                                Token(SyntaxKind.CommaToken),
                                Parameter(
                                    Identifier("c"))
                                .WithType(
                                    PredefinedType(
                                        Token(SyntaxKind.StringKeyword)))
                                .WithDefault(
                                    EqualsValueClause(
                                        LiteralExpression(
                                            SyntaxKind.StringLiteralExpression,
                                            Literal("foo")))),
                                Token(SyntaxKind.CommaToken),
                                Parameter(
                                    Identifier("e"))
                                .WithType(
                                    IdentifierName("SomeType"))
                                .WithDefault(
                                    EqualsValueClause(
                                        LiteralExpression(
                                            SyntaxKind.DefaultLiteralExpression,
                                            Token(SyntaxKind.DefaultKeyword)))),
                                Token(SyntaxKind.CommaToken),
                                Parameter(
                                    Identifier("f"))
                                .WithType(
                                    IdentifierName("SomeType"))
                                .WithDefault(
                                    EqualsValueClause(
                                        LiteralExpression(
                                            SyntaxKind.NullLiteralExpression)))})))
                .WithSemicolonToken(
                    Token(SyntaxKind.SemicolonToken))))))
.NormalizeWhitespace()




Aucun commentaire:

Enregistrer un commentaire