使用Roslyn拆分Expression语句

我正在开发一个重新描述CSharp代码的应用程序。 我和Roslyn一起做这个。 我面临splitting expressions的问题。

样class

 class Program { static void Main(string[] args) { float floatVariable = 20; Int16 intVariable = 10; string str = "School"; Console.Write(str + floatVariable.ToString() + intVariable.ToString()); // Facing problem with this statement } } 

我正在使用的示例代码

 string code = new StreamReader(classPath).ReadToEnd(); var syntaxTree = CSharpSyntaxTree.ParseText(code); var syntaxRoot = syntaxTree.GetRoot(); //This will get the method and local variables declared inside the method var MyMethods = syntaxRoot.DescendantNodes().OfType(); foreach (MethodDeclarationSyntax mds in MyMethods) { syntaxTree = CSharpSyntaxTree.ParseText(mds.ToFullString()); IEnumerable nodes = syntaxTree.GetRoot().DescendantNodes(); IEnumerable variableDeclarations = nodes.OfType(); foreach (VariableDeclarationSyntax variable in variableDeclarations) { // I will collect the variable details like Datatype, variable names and initialized values here } foreach (StatementSyntax statement in mds.Body.Statements) { if (statement.CSharpKind() == SyntaxKind.ExpressionStatement) { //I want to split the expressions "Console.Write(str + floatVariable.ToString() + intVariable.ToString());" as below //1. intVariable.ToString() //2. floatVariable.ToString() //3. str //Then I have to find the whole data type from the resolved result of above 3 => string here } } } 

任何帮助将不胜感激。

编辑:我在分割参数化表达式语句时遇到问题。 我试图这样做,

 if (statement.CSharpKind() == SyntaxKind.ExpressionStatement) { ExpressionStatementSyntax expression = statement as ExpressionStatementSyntax; var expressions = expression.Expression.DescendantNodes(); } 

但是这会将每个标记分成一个单独的元素。 我只想将Console.Write(str + floatVariable.ToString() + intVariable.ToString())拆分为,

  1. Console.Write()
  2. 海峡
  3. intVariable.ToString()
  4. floatVariable.ToString()

很难说你究竟想做什么,因为你只在一个特定情况下指定了代码应该做什么,而不是一般情况下。

我解释它的方式是:

  1. 对于调用表达式,返回正在调用的表达式,并返回其参数(如果有)。
  2. 对于二元运算符,下降到两个子节点。
  3. 对于所有其他表达式,直接返回表达式。

使用此规范并使用CSharpSyntaxVisitor ,代码可能如下所示:

 public static IEnumerable Split(ExpressionSyntax expression) { return new SplitVisitor().Visit(expression); } class SplitVisitor : CSharpSyntaxVisitor> { public override IEnumerable VisitInvocationExpression( InvocationExpressionSyntax node) { yield return node.Expression; var argumentExpressions = node.ArgumentList.Arguments .SelectMany(a => Visit(a.Expression)); foreach (var expression in argumentExpressions) yield return expression; } public override IEnumerable VisitBinaryExpression( BinaryExpressionSyntax node) { foreach (var expression in Visit(node.Left)) yield return expression; foreach (var expression in Visit(node.Right)) yield return expression; } public override IEnumerable DefaultVisit(SyntaxNode node) { var expression = node as ExpressionSyntax; if (expression != null) yield return expression; } }