Reputation: 341
I am trying to write code transformation using Roslyn that changes return type of interface methods from T
to Task<T>
(assuming no void returns). Following is the code I came up with.
CODE
InterfaceDeclarationSyntax asyncInterface = syncInterface.ReplaceNodes(
syncInterface.Members.OfType<MethodDeclarationSyntax>(),
(a, m) => m.ReplaceNode(
m.ReturnType,
SF.GenericName(SF.Identifier("Task"), SF.TypeArgumentList(new SeparatedSyntaxList<TypeSyntax>().Add(m.ReturnType)))));
Firstly is this the right approach?
Secondly this messes up the indentation when formatted. How should I fix that?
Edit
I was able to solve second problem by preserving Trivia. Here is the updated code (I also migrated it to use rewriter).
Code
sealed class AsyncMethodRewriter : CSharpSyntaxRewriter
{
public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax m)
{
var newReturnType = SF.GenericName(SF.Identifier("Task"), SF.TypeArgumentList(new SeparatedSyntaxList<TypeSyntax>().Add(m.ReturnType.WithoutTrivia())));
newReturnType = newReturnType.InsertTriviaBefore(newReturnType.GetLeadingTrivia().First(), m.ReturnType.GetLeadingTrivia().AsEnumerable());
newReturnType = newReturnType.InsertTriviaAfter(newReturnType.GetTrailingTrivia().First(), m.ReturnType.GetTrailingTrivia().AsEnumerable());
return m.ReplaceNode(m.ReturnType, newReturnType);
}
}
Upvotes: 1
Views: 1634
Reputation: 572
WithReturnType
method for MethodDeclarationSyntax
and AddTypeArgumentListArguments
method for GenericNameSyntax
classNormalizeWhitespace()
method for format leading and trailing triviastry this code:
syncInterface
.ReplaceNodes(
syncInterface.Members.OfType<MethodDeclarationSyntax>(),
(a, b) =>
b.WithReturnType(
SyntaxFactory.GenericName("Task").AddTypeArgumentListArguments(b.ReturnType)))
.NormalizeWhitespace();
Upvotes: 2