簡體   English   中英

Roslyn重寫方法調用以使用await修飾符

[英]Roslyn Rewrite Method Calls to use await Modifier

我有一堆C#文件,我想遷移到用於開發的內部框架的新版本。 到目前為止,我已經能夠完成某些事情,但是有一個特殊的方法調用,我必須對其進行修改才能使用await修飾符,並且方法調用具有不同的風味,如下所示

 var a = EntityService.GetBy(Entities.INSTANT_ISSUANCE_REQUEST, requestFilter);
 var b = EntityService.GetBy(Entities.ISSUANCE_SETTINGS, new DejaVuObject()).FirstOrDefault();

我必須修改上述方法調用,以便它們使用以下語法

 var a = await EntityService.GetBy(Entities.INSTANT_ISSUANCE_REQUEST, requestFilter);
 var b = await EntityService.GetBy(Entities.ISSUANCE_SETTINGS, new DejaVuObject()).FirstOrDefault();

我正在使用Roslyn CSharpSyntaxWriter遍歷語法樹。

public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
{
    var variableDeclarations = 
        from i in node.DescendantNodes().OfType<VariableDeclaratorSyntax>()
        where i.DescendantNodes().OfType<EqualsValueClauseSyntax>().Any<EqualsValueClauseSyntax>(
            p => p.DescendantNodes().OfType<InvocationExpressionSyntax>().Any<InvocationExpressionSyntax>())
        select i;

    foreach (var syntax in variableDeclarations)
    {
        var equalsToken = syntax.DescendantNodes();
        //now we have the equals token 
        foreach (var syntaxNode in equalsToken)
        {
            if (syntaxNode is EqualsValueClauseSyntax)
            {
                var equalsValueSyntax = syntaxNode.DescendantNodes().OfType<InvocationExpressionSyntax>();
                foreach (var invocationExpressionSyntax in equalsValueSyntax)
                {
                    var simpleMemberAcessExpressions = invocationExpressionSyntax
                        .DescendantNodes()
                        .OfType<IdentifierNameSyntax>()
                        .Where(i => i.Identifier.Text == "EntityService");
                    foreach (var simpleMemberAcessExpression in simpleMemberAcessExpressions)
                    {
                        var newExpression = $"{invocationExpressionSyntax.ToFullString()}";
                        Console.WriteLine(newExpression);
                        //TODO: Modify the Node
                    }
                }
            }
        }
    }
    return base.VisitLocalDeclarationStatement(node);
}

我的問題是控制台中的輸出有些重復

EntityService.GetBy(Entities.ISSUANCE_SETTINGS, new DejaVuObject()).FirstOrDefault();
EntityService.GetBy(Entities.ISSUANCE_SETTINGS, new DejaVuObject())

兩者都引用相同的InvocationExpression但是由於FirstOrDefault()它在控制台輸出中顯示兩次

我想要一種過濾結果的方法,以便它們僅包含唯一的方法調用,並通過添加await修飾符並更新節點來執行方法調用的實際修改。

首先,為什么要覆蓋VisitLocalDeclarationStatement 看來您應該重寫VisitInvocationExpression

您不應該這樣做:

var simpleMemberAcessExpressions = 
    invocationExpressionSyntax.DescendantNodes().OfType<IdentifierNameSyntax>()

相反,它應該類似於:

var identifier = 
    (node.Expression as MemberAccessExpressionSyntax)?.Expression as IdentifierNameSyntax;

if (identifier != null && identifier.Identifier.Text == "EntityService")
{
    // process the invocation expression
}

假設調用表達式稱為node ,則新表達式可能是

var newExpression = 
    SyntaxFactory.ParenthesizedExpression(SyntaxFactory.AwaitExpression(node))
    .WithAdditionalAnnotations(Simplifier.Annotation)
    .WithAdditionalAnnotations(Formatter.Annotation);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM