拆分与罗斯林的表达式语句 [英] Splitting the Expression statements with Roslyn

查看:195
本文介绍了拆分与罗斯林的表达式语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在开发rephrases CSHARP 代码的应用程序工作。我与罗斯林这样做。我现在面临一个问题,分裂表达



Sample类

 类节目
{
静态无效的主要(字串[] args)
{
浮动floatVariable = 20;
的Int16了IntVariable = 10;
字符串str =学校;
Console.Write(STR + floatVariable.ToString()+ intVariable.ToString()); //这个说法
}
}



示例代码,我面临的问题使用

 串码=新的StreamReader(CLASSPATH).ReadToEnd(); 
VAR syntaxTree = CSharpSyntaxTree.ParseText(代码);
VAR syntaxRoot = syntaxTree.GetRoot();

//这会得到一个方法,并且该方法
变种MyMethods = syntaxRoot.DescendantNodes内声明()OfType&所述局部变量。MethodDeclarationSyntax>();
的foreach(在MyMethods MethodDeclarationSyntax MDS)
{
syntaxTree = CSharpSyntaxTree.ParseText(mds.ToFullString());
IEnumerable的< SyntaxNode> 。节点= syntaxTree.GetRoot()DescendantNodes();
IEnumerable的< VariableDeclarationSyntax> variableDeclarations = nodes.OfType< VariableDeclarationSyntax>();
的foreach(在variableDeclarations VariableDeclarationSyntax变量)
{
//我会收集变量的细节,如数据类型,变量名和初始值这里
}


的foreach(在mds.Body.Statements StatementSyntax语句)
{
如果(statement.CSharpKind()== SyntaxKind.ExpressionStatement)
{
//我想分裂表达式Console.Write(STR + floatVariable.ToString()+ intVariable.ToString());如下

// 1。 intVariable.ToString()
// 2。 floatVariable.ToString()
// 3。 STR

//然后,我必须找到从上述3解决结果整个数据类型=>这里串
}
}
}



任何帮助将是。感谢



编辑:我有分裂参数化的表达式语句的麻烦
。我试图做到这一点,

 如果(statement.CSharpKind()== SyntaxKind.ExpressionStatement)
{
ExpressionStatementSyntax表达=语句ExpressionStatementSyntax;
变种表达式= expression.Expression.DescendantNodes();
}



但这种分割每个令牌作为一个单独的元素。我只是想分裂的 Console.Write(STR + floatVariable.ToString()+ intVariable.ToString())




  1. Console.Write()

  2. STR

  3. intVariable.ToString( )

  4. floatVariable.ToString()


解决方案

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



我理解它的方式是:




  1. 对于调用表达式,返回的被调用,也陷入它的参数,如果有的话表达

  2. 对于二元运算符,陷入两个孩子。

  3. 对于所有其他表达式,直接返回表达式。



通过本规范,并使用 CSharpSyntaxVisitor ,代码看起来是这样的:

 公共静态的IEnumerable< ExpressionSyntax>斯普利特(ExpressionSyntax表达式)
{
返回新SplitVisitor()访问(表达)。
}

类SplitVisitor:CSharpSyntaxVisitor<&IEnumerable的LT; ExpressionSyntax>>
{
公共覆盖的IEnumerable< ExpressionSyntax> VisitInvocationExpression(
InvocationExpressionSyntax节点)
{
收益率的回报node.Expression;

VAR argumentExpressions = node.ArgumentList.Arguments
.SelectMany(A =>参观(a.Expression));
的foreach(在argumentExpressions VAR表达式)
收益率的回报表现;
}

公共覆盖的IEnumerable< ExpressionSyntax> VisitBinaryExpression(
BinaryExpressionSyntax节点)
{
的foreach
收益率的回报一个表达式(var在访问(node.Left)的表达);
的foreach(在访问(node.Right VAR表达式))
收益率的回报表现;
}

公共覆盖的IEnumerable< ExpressionSyntax> DefaultVisit(SyntaxNode节点)
{
VAR表达式=节点ExpressionSyntax;
如果(表达式!= NULL)
收益率的回报表现;
}
}


I am working in developing an application that rephrases CSharp code. I am doing this with Roslyn. I am facing a problem with splitting expressions.

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

Sample code I am using

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<MethodDeclarationSyntax>();
foreach (MethodDeclarationSyntax mds in MyMethods)
{
    syntaxTree = CSharpSyntaxTree.ParseText(mds.ToFullString());
    IEnumerable<SyntaxNode> nodes = syntaxTree.GetRoot().DescendantNodes();
    IEnumerable<VariableDeclarationSyntax> variableDeclarations =       nodes.OfType<VariableDeclarationSyntax>();
    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            
        }
    }
}

Any help will be appreciated.

Edit: I am having trouble in splitting the parameterized expression statements. I am trying to do this by,

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

But this splits each and every token as a seperate elements. I just want to split the Console.Write(str + floatVariable.ToString() + intVariable.ToString()) into,

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

解决方案

It's hard to tell what exactly do you want to do, because you specified what the code should do only in one specific case, not in general.

The way I interpret it is:

  1. For invocation expression, return the expression that's being invoked and also descend into its arguments, if any.
  2. For binary operators, descend into both children.
  3. For all other expressions, return the expression directly.

With this specification and using CSharpSyntaxVisitor, the code could look like this:

public static IEnumerable<ExpressionSyntax> Split(ExpressionSyntax expression)
{
    return new SplitVisitor().Visit(expression);
}

class SplitVisitor : CSharpSyntaxVisitor<IEnumerable<ExpressionSyntax>>
{
    public override IEnumerable<ExpressionSyntax> 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<ExpressionSyntax> 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<ExpressionSyntax> DefaultVisit(SyntaxNode node)
    {
        var expression = node as ExpressionSyntax;
        if (expression != null)
            yield return expression;
    }
}

这篇关于拆分与罗斯林的表达式语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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