WSK
WSK

Reputation: 6198

Why Roslyn is generating method code without spaces

What am I doing wrong that Roslyn is generating code without any space between identifiers and keywords? It is also putting a semicolon at the end of the method block. Here is my code:

SeparatedSyntaxList<ParameterSyntax> parametersList = new SeparatedSyntaxList<ParameterSyntax>().AddRange
(new ParameterSyntax[]
    {
        SyntaxFactory.Parameter(SyntaxFactory.Identifier("sender")).WithType(SyntaxFactory.ParseTypeName("object")),
        SyntaxFactory.Parameter(SyntaxFactory.Identifier("args")).WithType(SyntaxFactory.ParseTypeName("EventArgs"))
    }
);

MethodDeclarationSyntax newMethod = SyntaxFactory.MethodDeclaration(
    SyntaxFactory.List<AttributeListSyntax>(),
    SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)),
    SyntaxFactory.ParseName("void"),
    null,
    SyntaxFactory.Identifier("simpleButton1_Click"),
    null,
    SyntaxFactory.ParameterList(parametersList),
    SyntaxFactory.List<TypeParameterConstraintClauseSyntax>(),
    SyntaxFactory.Block(),
    SyntaxFactory.Token(SyntaxKind.SemicolonToken)
);

And here is the result that I am having:

privatevoidsimpleButton1_Click(objectsender,EventArgse){};

Upvotes: 18

Views: 3359

Answers (4)

Adam B
Adam B

Reputation: 3861

None of the above worked for me in a roslyn CodeFixProvider I'm working on.

I found on reliable solution was to change the method type name to " void " (Note the spaces).

It fixed it from privatevoidMethod() { to private void Method() {

MethodDeclarationSyntax method = SyntaxFactory.MethodDeclaration(
            SyntaxFactory.List<AttributeListSyntax>(),
            SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)),
            SyntaxFactory.ParseName(" void "), // <--------------!!!!
            null,
            SyntaxFactory.Identifier("Method"),
            null,
            SyntaxFactory.ParameterList(),
            SyntaxFactory.List<TypeParameterConstraintClauseSyntax>(),
            SyntaxFactory.Block(SyntaxFactory.ParseStatement(bodyText)),
            null)
            .WithAdditionalAnnotations(Formatter.Annotation);
        return method;

Then, I added the method to the classDeclarationSyntax, updated the root node with the new ClassDeclarationSyntax, and called:

await Formatter.FormatAsync(document)

This last bit made the correct indentation in the class etc.

For me using NormalizeWhiteSpace(); added 2 spaces instead of 1, even after calling format.

Upvotes: 0

Patrice Gahide
Patrice Gahide

Reputation: 3754

To be even more comprehensive, NormalizeWhiteSpace should be mentioned. It applies default formatting to the given node:

MethodDeclarationSyntax newMethod = SyntaxFactory.MethodDeclaration(
    SyntaxFactory.List<AttributeListSyntax>(),
    SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)),
    SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)),
    null,
    SyntaxFactory.Identifier("simpleButton1_Click"),
    null,
    SyntaxFactory.ParameterList(parametersList),
    SyntaxFactory.List<TypeParameterConstraintClauseSyntax>(),
    SyntaxFactory.Block(),
    null
  )

newMethod = newMethod.NormalizeWhitespace();

A ToString() on that will produce the expected output:

private void simpleButton1_Click(object sender, EventArgs args)
{
}

Upvotes: 15

user2697817
user2697817

Reputation: 1498

I think it's putting the semicolon there because you are passing one to the method that creates the method declaration, I'm guessing this is used when declaring an abstract method without a body.

To correctly format the output you could use the Formatter class in the Microsoft.CodeAnalysis.Formatting namespace.

Workspace workspace = MSBuildWorkspace.Create();
SyntaxNode formattedNode = Microsoft.CodeAnalysis.Formatting.Formatter.Format(newMethod, workspace);

For the return type you could do the following

SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword));   

This will give you a TypeSyntax

Upvotes: 5

Tamas
Tamas

Reputation: 6420

You could use .WithAdditionalAnnotations(Formatter.Annotation) to format the syntax nodes that you generate.

Upvotes: 3

Related Questions