用Roslyn分割表达式

时间:2015-01-29 05:36:22

标签: c# visual-studio expression-trees roslyn

我正在使用Roslyn,我想将声明拆分如下,

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()
  5. 我已经提出了一个问题并得到了分割表达式Splitting the Expression statements with Roslyn的答案,但是这个建议将string.Concat("string1", "string2")拆分如下,

    1. string.Concat()
    2. string1
    3. string2
    4. 但我不想拆分内部表达式,我需要保持内部表达式不变。我怎么能用Roslyn做到这一点?

1 个答案:

答案 0 :(得分:1)

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

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

现在参数将是BinaryExpressionSyntax

我们可以通过访问SyntaxNodes来拆分BinaryExpressionSyntax。因此,当访问时我们可以通过识别它来避免遍历“内部表达” 语法(如InvocationExpressionSyntaxMemberAccessExpressionSyntax等)。

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

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;
    }
}

可以通过

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

nodeList 将具有以下结果。

  • [0] =“IdentifierNameSyntax IdentifierName stringVariable”
  • [1] =“SyntaxToken PlusToken +”
  • [2] =“InvocationExpressionSyntax InvocationExpression string.Concat(\“string1 \”,\“string2 \”)“
  • [3] =“SyntaxToken PlusToken +”
  • [4] =“InvocationExpressionSyntax InvocationExpression intVariable.ToString()“
相关问题