简体   繁体   English

Roslyn重写方法调用以使用await修饰符

[英]Roslyn Rewrite Method Calls to use await Modifier

I a bunch of C# Files that I want to migrate to a new version of an internal framework we use for development. 我有一堆C#文件,我想迁移到用于开发的内部框架的新版本。 So far I have been able to accomplish certain things But there is a particular method invocation that i have to modify to use await modifier and the method calls come in different flavors like so 到目前为止,我已经能够完成某些事情,但是有一个特殊的方法调用,我必须对其进行修改才能使用await修饰符,并且方法调用具有不同的风味,如下所示

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

I have to modify the above method calls so that they use the following syntax 我必须修改上述方法调用,以便它们使用以下语法

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

I am using Roslyn CSharpSyntaxWriter to traverse the syntax tree. 我正在使用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);
}

My problem here is the output in Console is somewhat duplicative 我的问题是控制台中的输出有些重复

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

Both refer to same InvocationExpression but because of the FirstOrDefault() it shows up twice in the console output 两者都引用相同的InvocationExpression但是由于FirstOrDefault()它在控制台输出中显示两次

I would like for a way to filter the results so that they contain only unique Method Invocations and perform the actual modification of the method call by adding the await modifier and updating the node. 我想要一种过滤结果的方法,以便它们仅包含唯一的方法调用,并通过添加await修饰符并更新节点来执行方法调用的实际修改。

first of all, why override VisitLocalDeclarationStatement ? 首先,为什么要覆盖VisitLocalDeclarationStatement Looks like you should be overriding VisitInvocationExpression . 看来您应该重写VisitInvocationExpression

You shouldn't be doing this: 您不应该这样做:

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

Instead, it should be something like: 相反,它应该类似于:

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

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

Assuming the invocation expression is called node , your new expression is probably 假设调用表达式称为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