使用Roslyn分割表达式 [英] Splitting the expressions with Roslyn

查看:209
本文介绍了使用Roslyn分割表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Roslyn,我想按如下所示拆分语句,

I am using Roslyn and I want to split the statement as below,

string stringVariable = "string";
int intVariable = 10;
Console.Write(stringVariable + string.Concat("string1","string2") + intVariable.ToString()) 

  1. Console.Write()
  2. stringVariable
  3. string.Concat("string1","string2")
  4. intVariable.ToString()
  1. Console.Write()
  2. stringVariable
  3. string.Concat("string1","string2")
  4. intVariable.ToString()

我问了一个问题,并得到了将表达式拆分的答案用罗斯林(Roslyn),但此建议将string.Concat("string1", "string2")分为以下部分,

I have asked a question and got answer for splitting the expressions Splitting the Expression statements with Roslyn but this suggestion splits the string.Concat("string1", "string2") as below,

  1. string.Concat()
  2. string1
  3. string2
  1. string.Concat()
  2. string1
  3. string2

但是我不想拆分内部表达式,我需要保持内部表达式原样.如何使用罗斯林(Roslyn)做到这一点?

But i dont want to split the inner expressions, I need to keep the inner expressions as it is. How can I do this with Roslyn?

推荐答案

表达式Console.Write(stringVariable + string.Concat("string1","string2") + intVariable.ToString())InvocationExpressionSyntax. InvocationExpressionSyntax可以进一步分为表达式参数.

The expression Console.Write(stringVariable + string.Concat("string1","string2") + intVariable.ToString()) is a InvocationExpressionSyntax. The InvocationExpressionSyntax can be further splitted into expression and arguments.

此处,表达式部分将具有Console.Write和 参数部分将具有stringVariable + string.Concat("string1","string2") + intVariable.ToString().

Here the expression part will have Console.Write and the argument part will have stringVariable + string.Concat("string1","string2") + intVariable.ToString() .

现在,参数将为BinaryExpressionSyntax.

我们可以通过访问SyntaxNodes来拆分BinaryExpressionSyntax.因此,在访问时,我们可以通过识别内在表达"来避免遍历内在表达" 语法(例如InvocationExpressionSyntaxMemberAccessExpressionSyntax .. etc).

We can split the BinaryExpressionSyntax by visiting the SyntaxNodes. So when Visiting we can just avoid traversing the "inner expressions" by identifyning its syntax( like InvocationExpressionSyntax, MemberAccessExpressionSyntax..etc) .

访问上述二进制表达式的代码将是

The code for visiting the Binary expression as above will be.

public class BinaryExpressionVisitor : CSharpSyntaxRewriter
{
    List<string> restrictedTokens = new List<string>();
    internal List<object> binaryExpressionNodes = new List<object>();

    public BinaryExpressionVisitor()
    {
        restrictedTokens.Add("IdentifierToken");
        restrictedTokens.Add("NumericLiteralToken");
        restrictedTokens.Add("StringLiteralToken");
    }

    public override SyntaxNode VisitBinaryExpression(BinaryExpressionSyntax node)
    {
        return base.VisitBinaryExpression(node);
    }

    public override SyntaxNode Visit(SyntaxNode node)
    {
        if (node.GetType().Name != "BinaryExpressionSyntax" && node.GetType().Name != "ParenthesizedExpressionSyntax")
            binaryExpressionNodes.Add(node);
        return base.Visit(node);
    }

    public override SyntaxToken VisitToken(SyntaxToken token)
    {
        if (!restrictedTokens.Contains(token.CSharpKind().ToString().Trim()))
            binaryExpressionNodes.Add(token);
        SyntaxToken baseToken = base.VisitToken(token);
        return baseToken;
    }

    public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
    {
        return node;//Bypassing the expression instead of base.Visit(node)
    }

    public override SyntaxToken VisitListSeparator(SyntaxToken separator)
    {
        SyntaxToken baseToken = base.VisitListSeparator(separator);
        return baseToken;
    }
}

可以通过以下方式调用该类

The class can be invoked by,

BinaryExpressionVisitor expressionVisitor = new BinaryExpressionVisitor();
expressionVisitor.VisitBinaryExpression(binaryExpressions);
List<object> nodeList = expressionVisitor.binaryExpressionNodes;

nodeList 将得到以下结果.

  • [0] ="IdentifierNameSyntax IdentifierName stringVariable"
  • [1] ="SyntaxToken PlusToken +"
  • [2] ="InvocationExpression语法InvocationExpression string.Concat(\"string1 \",\"string2 \")"
  • [3] ="SyntaxToken PlusToken +"
  • [4] ="InvocationExpression语法InvocationExpression intVariable.ToString()"
  • [0] = "IdentifierNameSyntax IdentifierName stringVariable"
  • [1] = "SyntaxToken PlusToken +"
  • [2] = "InvocationExpressionSyntax InvocationExpression string.Concat(\"string1\", \"string2\")"
  • [3] = "SyntaxToken PlusToken +"
  • [4] = "InvocationExpressionSyntax InvocationExpression intVariable.ToString()"

这篇关于使用Roslyn分割表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆