Suyog
Suyog

Reputation: 341

Roslyn syntax tree transformation - Replacing return type of methods

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

Answers (1)

Sattar Imamov
Sattar Imamov

Reputation: 572

  1. You choose right approach, but you can simplify your code with WithReturnType method for MethodDeclarationSyntax and AddTypeArgumentListArguments method for GenericNameSyntax class
  2. Try use NormalizeWhitespace() method for format leading and trailing trivias

try this code:

syncInterface
  .ReplaceNodes(
      syncInterface.Members.OfType<MethodDeclarationSyntax>(),
      (a, b) =>
          b.WithReturnType(
              SyntaxFactory.GenericName("Task").AddTypeArgumentListArguments(b.ReturnType)))
  .NormalizeWhitespace();

Upvotes: 2

Related Questions