Splitting the Expression statements with Roslyn

◇◆丶佛笑我妖孽 提交于 2019-12-10 09:36:38

问题


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()

回答1:


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


来源:https://stackoverflow.com/questions/27860876/splitting-the-expression-statements-with-roslyn

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!