使用Roslyn分割表达式 [英] Splitting the expressions with 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())
-
Console.Write()
-
stringVariable
-
string.Concat("string1","string2")
-
intVariable.ToString()
Console.Write()
stringVariable
string.Concat("string1","string2")
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,
-
string.Concat()
-
string1
-
string2
string.Concat()
string1
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.因此,在访问时,我们可以通过识别内在表达"来避免遍历内在表达"
语法(例如InvocationExpressionSyntax
,MemberAccessExpressionSyntax
.. 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屋!