Roslyn C# rebuild incorrect expression for to for statement











up vote
4
down vote

favorite












I have problem with rebuild for statement. I want to rebuild fragment code:



FOR(j, variable or integer, integer, > or < or <= or >=, - or +);


to



for(var j = variable or integer; j > or < or >= or <= 15; j-- or j++){}


For example FOR(j, k, >, -); -> for(var j = k; j > 15; j--){}. Besides I don't know how can separate elements on list <ArgumentListSyntax> to IdentifierNameSyntax or LiteralExpressionSyntax,when there will be two IdentifierNameSyntax or LiteralExpressionSyntax on list. So I don't know if my attempt to solve is correct.



public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
{
// FOR(j, k, 10, >, -);

if (node.Kind() == SyntaxKind.InvocationExpression)
{
InvocationExpressionSyntax invocationExpression = node;

if (invocationExpression.GetFirstToken().ToString() == "FOR")
{
//List<ArgumentSyntax> argumentList = new List<ArgumentSyntax>();
//List<IdentifierNameSyntax> test = new List<IdentifierNameSyntax>();
var tmp = node.ChildNodes().OfType<ArgumentListSyntax>().FirstOrDefault();
var tmp1 = tmp.ChildNodes().OfType<ArgumentSyntax>().FirstOrDefault();
var tmp2 = tmp1.ChildNodes().OfType<IdentifierNameSyntax>().FirstOrDefault();
var tmp3 = tmp.Arguments.ElementAt(1);
var tmp4 = tmp3.ChildNodes().OfType<IdentifierNameSyntax>().FirstOrDefault();

Console.WriteLine(tmp.Arguments.ElementAt(0));
Console.WriteLine(tmp.Arguments);
Console.WriteLine(tmp2.GetFirstToken());
Console.WriteLine(tmp4);


node = node.ReplaceNode(node, SyntaxFactory.ForStatement(SyntaxKind.ForKeyword, SyntaxKind.OpenParenToken,
SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName("var"), )));
}

}
return base.VisitInvocationExpression(node);
}









share|improve this question




























    up vote
    4
    down vote

    favorite












    I have problem with rebuild for statement. I want to rebuild fragment code:



    FOR(j, variable or integer, integer, > or < or <= or >=, - or +);


    to



    for(var j = variable or integer; j > or < or >= or <= 15; j-- or j++){}


    For example FOR(j, k, >, -); -> for(var j = k; j > 15; j--){}. Besides I don't know how can separate elements on list <ArgumentListSyntax> to IdentifierNameSyntax or LiteralExpressionSyntax,when there will be two IdentifierNameSyntax or LiteralExpressionSyntax on list. So I don't know if my attempt to solve is correct.



    public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
    {
    // FOR(j, k, 10, >, -);

    if (node.Kind() == SyntaxKind.InvocationExpression)
    {
    InvocationExpressionSyntax invocationExpression = node;

    if (invocationExpression.GetFirstToken().ToString() == "FOR")
    {
    //List<ArgumentSyntax> argumentList = new List<ArgumentSyntax>();
    //List<IdentifierNameSyntax> test = new List<IdentifierNameSyntax>();
    var tmp = node.ChildNodes().OfType<ArgumentListSyntax>().FirstOrDefault();
    var tmp1 = tmp.ChildNodes().OfType<ArgumentSyntax>().FirstOrDefault();
    var tmp2 = tmp1.ChildNodes().OfType<IdentifierNameSyntax>().FirstOrDefault();
    var tmp3 = tmp.Arguments.ElementAt(1);
    var tmp4 = tmp3.ChildNodes().OfType<IdentifierNameSyntax>().FirstOrDefault();

    Console.WriteLine(tmp.Arguments.ElementAt(0));
    Console.WriteLine(tmp.Arguments);
    Console.WriteLine(tmp2.GetFirstToken());
    Console.WriteLine(tmp4);


    node = node.ReplaceNode(node, SyntaxFactory.ForStatement(SyntaxKind.ForKeyword, SyntaxKind.OpenParenToken,
    SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName("var"), )));
    }

    }
    return base.VisitInvocationExpression(node);
    }









    share|improve this question


























      up vote
      4
      down vote

      favorite









      up vote
      4
      down vote

      favorite











      I have problem with rebuild for statement. I want to rebuild fragment code:



      FOR(j, variable or integer, integer, > or < or <= or >=, - or +);


      to



      for(var j = variable or integer; j > or < or >= or <= 15; j-- or j++){}


      For example FOR(j, k, >, -); -> for(var j = k; j > 15; j--){}. Besides I don't know how can separate elements on list <ArgumentListSyntax> to IdentifierNameSyntax or LiteralExpressionSyntax,when there will be two IdentifierNameSyntax or LiteralExpressionSyntax on list. So I don't know if my attempt to solve is correct.



      public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
      {
      // FOR(j, k, 10, >, -);

      if (node.Kind() == SyntaxKind.InvocationExpression)
      {
      InvocationExpressionSyntax invocationExpression = node;

      if (invocationExpression.GetFirstToken().ToString() == "FOR")
      {
      //List<ArgumentSyntax> argumentList = new List<ArgumentSyntax>();
      //List<IdentifierNameSyntax> test = new List<IdentifierNameSyntax>();
      var tmp = node.ChildNodes().OfType<ArgumentListSyntax>().FirstOrDefault();
      var tmp1 = tmp.ChildNodes().OfType<ArgumentSyntax>().FirstOrDefault();
      var tmp2 = tmp1.ChildNodes().OfType<IdentifierNameSyntax>().FirstOrDefault();
      var tmp3 = tmp.Arguments.ElementAt(1);
      var tmp4 = tmp3.ChildNodes().OfType<IdentifierNameSyntax>().FirstOrDefault();

      Console.WriteLine(tmp.Arguments.ElementAt(0));
      Console.WriteLine(tmp.Arguments);
      Console.WriteLine(tmp2.GetFirstToken());
      Console.WriteLine(tmp4);


      node = node.ReplaceNode(node, SyntaxFactory.ForStatement(SyntaxKind.ForKeyword, SyntaxKind.OpenParenToken,
      SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName("var"), )));
      }

      }
      return base.VisitInvocationExpression(node);
      }









      share|improve this question















      I have problem with rebuild for statement. I want to rebuild fragment code:



      FOR(j, variable or integer, integer, > or < or <= or >=, - or +);


      to



      for(var j = variable or integer; j > or < or >= or <= 15; j-- or j++){}


      For example FOR(j, k, >, -); -> for(var j = k; j > 15; j--){}. Besides I don't know how can separate elements on list <ArgumentListSyntax> to IdentifierNameSyntax or LiteralExpressionSyntax,when there will be two IdentifierNameSyntax or LiteralExpressionSyntax on list. So I don't know if my attempt to solve is correct.



      public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
      {
      // FOR(j, k, 10, >, -);

      if (node.Kind() == SyntaxKind.InvocationExpression)
      {
      InvocationExpressionSyntax invocationExpression = node;

      if (invocationExpression.GetFirstToken().ToString() == "FOR")
      {
      //List<ArgumentSyntax> argumentList = new List<ArgumentSyntax>();
      //List<IdentifierNameSyntax> test = new List<IdentifierNameSyntax>();
      var tmp = node.ChildNodes().OfType<ArgumentListSyntax>().FirstOrDefault();
      var tmp1 = tmp.ChildNodes().OfType<ArgumentSyntax>().FirstOrDefault();
      var tmp2 = tmp1.ChildNodes().OfType<IdentifierNameSyntax>().FirstOrDefault();
      var tmp3 = tmp.Arguments.ElementAt(1);
      var tmp4 = tmp3.ChildNodes().OfType<IdentifierNameSyntax>().FirstOrDefault();

      Console.WriteLine(tmp.Arguments.ElementAt(0));
      Console.WriteLine(tmp.Arguments);
      Console.WriteLine(tmp2.GetFirstToken());
      Console.WriteLine(tmp4);


      node = node.ReplaceNode(node, SyntaxFactory.ForStatement(SyntaxKind.ForKeyword, SyntaxKind.OpenParenToken,
      SyntaxFactory.VariableDeclaration(SyntaxFactory.IdentifierName("var"), )));
      }

      }
      return base.VisitInvocationExpression(node);
      }






      c# for-loop roslyn






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 19 at 18:53









      Xiaoy312

      10.9k12033




      10.9k12033










      asked Nov 19 at 18:49









      A.Kowalski

      212




      212
























          1 Answer
          1






          active

          oldest

          votes

















          up vote
          1
          down vote













          You don't need to separate elements in the ArgumentListSyntax to the literals or identifiers, because you actually have a formal structure of supporting invocation: FOR(j, variable|integer, variable|integer, >|<|<=|>=, -|+); so you assume that the second and third arguments may be literal or identifier, fourth is comparison element and so on. Therefore, you need to check that the input arguments satisfy these conditions and if are satisfiable do something useful:





          ...
          // FOR(j, variable | integer, variable | integer, > | < | <= | >=, - | +);
          if (node.Expression is IdentifierNameSyntax identifier && identifier.Identifier.ValueText.Equals("FOR"))
          {
          var arguments = node.ArgumentList.Arguments;
          if (arguments.Count != 5) return node;
          var second = arguments[1].Expression;
          switch (second)
          {
          case IdentifierNameSyntax variable:
          // and some sepcific logic for identifier
          break;

          case LiteralExpressionSyntax literal when literal.Kind() == SyntaxKind.NumericLiteralExpression:
          // and some sepcific logic for literals and check,
          // that the input literal is integer and is not rational value
          break;

          default:
          // current argument isn't literal or identifier you can not do anything
          return node;
          }

          // do the similar check for the other arguments
          // and replace node as you wish
          ...
          }


          If you still assume that your invocation can contains a couple of another nodes as arguments, for example for(j, "foo", "foo", method(), initValue, method(), 15, >, >, >, -, "foo") you will need to take arguments by different logic, for example take the first literal or identifier or something else:





          ...
          // the same code from the example above

          // here you can use an another logic to retrieve expression that you want
          var second = arguments.First(x => x.IsKind(SyntaxKind.NumericLiteralExpression) || x.IsKind(SyntaxKind.IdentifierName)).Expression;
          switch (second)
          {
          // the same code from the example above
          }
          // the same code from the example above

          ...
          }





          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53380917%2froslyn-c-sharp-rebuild-incorrect-expression-for-to-for-statement%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            1 Answer
            1






            active

            oldest

            votes








            1 Answer
            1






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            1
            down vote













            You don't need to separate elements in the ArgumentListSyntax to the literals or identifiers, because you actually have a formal structure of supporting invocation: FOR(j, variable|integer, variable|integer, >|<|<=|>=, -|+); so you assume that the second and third arguments may be literal or identifier, fourth is comparison element and so on. Therefore, you need to check that the input arguments satisfy these conditions and if are satisfiable do something useful:





            ...
            // FOR(j, variable | integer, variable | integer, > | < | <= | >=, - | +);
            if (node.Expression is IdentifierNameSyntax identifier && identifier.Identifier.ValueText.Equals("FOR"))
            {
            var arguments = node.ArgumentList.Arguments;
            if (arguments.Count != 5) return node;
            var second = arguments[1].Expression;
            switch (second)
            {
            case IdentifierNameSyntax variable:
            // and some sepcific logic for identifier
            break;

            case LiteralExpressionSyntax literal when literal.Kind() == SyntaxKind.NumericLiteralExpression:
            // and some sepcific logic for literals and check,
            // that the input literal is integer and is not rational value
            break;

            default:
            // current argument isn't literal or identifier you can not do anything
            return node;
            }

            // do the similar check for the other arguments
            // and replace node as you wish
            ...
            }


            If you still assume that your invocation can contains a couple of another nodes as arguments, for example for(j, "foo", "foo", method(), initValue, method(), 15, >, >, >, -, "foo") you will need to take arguments by different logic, for example take the first literal or identifier or something else:





            ...
            // the same code from the example above

            // here you can use an another logic to retrieve expression that you want
            var second = arguments.First(x => x.IsKind(SyntaxKind.NumericLiteralExpression) || x.IsKind(SyntaxKind.IdentifierName)).Expression;
            switch (second)
            {
            // the same code from the example above
            }
            // the same code from the example above

            ...
            }





            share|improve this answer

























              up vote
              1
              down vote













              You don't need to separate elements in the ArgumentListSyntax to the literals or identifiers, because you actually have a formal structure of supporting invocation: FOR(j, variable|integer, variable|integer, >|<|<=|>=, -|+); so you assume that the second and third arguments may be literal or identifier, fourth is comparison element and so on. Therefore, you need to check that the input arguments satisfy these conditions and if are satisfiable do something useful:





              ...
              // FOR(j, variable | integer, variable | integer, > | < | <= | >=, - | +);
              if (node.Expression is IdentifierNameSyntax identifier && identifier.Identifier.ValueText.Equals("FOR"))
              {
              var arguments = node.ArgumentList.Arguments;
              if (arguments.Count != 5) return node;
              var second = arguments[1].Expression;
              switch (second)
              {
              case IdentifierNameSyntax variable:
              // and some sepcific logic for identifier
              break;

              case LiteralExpressionSyntax literal when literal.Kind() == SyntaxKind.NumericLiteralExpression:
              // and some sepcific logic for literals and check,
              // that the input literal is integer and is not rational value
              break;

              default:
              // current argument isn't literal or identifier you can not do anything
              return node;
              }

              // do the similar check for the other arguments
              // and replace node as you wish
              ...
              }


              If you still assume that your invocation can contains a couple of another nodes as arguments, for example for(j, "foo", "foo", method(), initValue, method(), 15, >, >, >, -, "foo") you will need to take arguments by different logic, for example take the first literal or identifier or something else:





              ...
              // the same code from the example above

              // here you can use an another logic to retrieve expression that you want
              var second = arguments.First(x => x.IsKind(SyntaxKind.NumericLiteralExpression) || x.IsKind(SyntaxKind.IdentifierName)).Expression;
              switch (second)
              {
              // the same code from the example above
              }
              // the same code from the example above

              ...
              }





              share|improve this answer























                up vote
                1
                down vote










                up vote
                1
                down vote









                You don't need to separate elements in the ArgumentListSyntax to the literals or identifiers, because you actually have a formal structure of supporting invocation: FOR(j, variable|integer, variable|integer, >|<|<=|>=, -|+); so you assume that the second and third arguments may be literal or identifier, fourth is comparison element and so on. Therefore, you need to check that the input arguments satisfy these conditions and if are satisfiable do something useful:





                ...
                // FOR(j, variable | integer, variable | integer, > | < | <= | >=, - | +);
                if (node.Expression is IdentifierNameSyntax identifier && identifier.Identifier.ValueText.Equals("FOR"))
                {
                var arguments = node.ArgumentList.Arguments;
                if (arguments.Count != 5) return node;
                var second = arguments[1].Expression;
                switch (second)
                {
                case IdentifierNameSyntax variable:
                // and some sepcific logic for identifier
                break;

                case LiteralExpressionSyntax literal when literal.Kind() == SyntaxKind.NumericLiteralExpression:
                // and some sepcific logic for literals and check,
                // that the input literal is integer and is not rational value
                break;

                default:
                // current argument isn't literal or identifier you can not do anything
                return node;
                }

                // do the similar check for the other arguments
                // and replace node as you wish
                ...
                }


                If you still assume that your invocation can contains a couple of another nodes as arguments, for example for(j, "foo", "foo", method(), initValue, method(), 15, >, >, >, -, "foo") you will need to take arguments by different logic, for example take the first literal or identifier or something else:





                ...
                // the same code from the example above

                // here you can use an another logic to retrieve expression that you want
                var second = arguments.First(x => x.IsKind(SyntaxKind.NumericLiteralExpression) || x.IsKind(SyntaxKind.IdentifierName)).Expression;
                switch (second)
                {
                // the same code from the example above
                }
                // the same code from the example above

                ...
                }





                share|improve this answer












                You don't need to separate elements in the ArgumentListSyntax to the literals or identifiers, because you actually have a formal structure of supporting invocation: FOR(j, variable|integer, variable|integer, >|<|<=|>=, -|+); so you assume that the second and third arguments may be literal or identifier, fourth is comparison element and so on. Therefore, you need to check that the input arguments satisfy these conditions and if are satisfiable do something useful:





                ...
                // FOR(j, variable | integer, variable | integer, > | < | <= | >=, - | +);
                if (node.Expression is IdentifierNameSyntax identifier && identifier.Identifier.ValueText.Equals("FOR"))
                {
                var arguments = node.ArgumentList.Arguments;
                if (arguments.Count != 5) return node;
                var second = arguments[1].Expression;
                switch (second)
                {
                case IdentifierNameSyntax variable:
                // and some sepcific logic for identifier
                break;

                case LiteralExpressionSyntax literal when literal.Kind() == SyntaxKind.NumericLiteralExpression:
                // and some sepcific logic for literals and check,
                // that the input literal is integer and is not rational value
                break;

                default:
                // current argument isn't literal or identifier you can not do anything
                return node;
                }

                // do the similar check for the other arguments
                // and replace node as you wish
                ...
                }


                If you still assume that your invocation can contains a couple of another nodes as arguments, for example for(j, "foo", "foo", method(), initValue, method(), 15, >, >, >, -, "foo") you will need to take arguments by different logic, for example take the first literal or identifier or something else:





                ...
                // the same code from the example above

                // here you can use an another logic to retrieve expression that you want
                var second = arguments.First(x => x.IsKind(SyntaxKind.NumericLiteralExpression) || x.IsKind(SyntaxKind.IdentifierName)).Expression;
                switch (second)
                {
                // the same code from the example above
                }
                // the same code from the example above

                ...
                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 23 at 17:38









                George Alexandria

                2,02421121




                2,02421121






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53380917%2froslyn-c-sharp-rebuild-incorrect-expression-for-to-for-statement%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Wiesbaden

                    Marschland

                    Dieringhausen