Reputation: 6198
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
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
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
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
Reputation: 6420
You could use .WithAdditionalAnnotations(Formatter.Annotation)
to format the syntax nodes that you generate.
Upvotes: 3