Roslyn C# rebuild incorrect expression for to for statement












4















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





























    4















    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



























      4












      4








      4








      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 '18 at 18:53









      Xiaoy312

      11.4k12133




      11.4k12133










      asked Nov 19 '18 at 18:49









      A.KowalskiA.Kowalski

      212




      212
























          1 Answer
          1






          active

          oldest

          votes


















          2














          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',
            autoActivateHeartbeat: false,
            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









            2














            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




























              2














              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


























                2












                2








                2







                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 '18 at 17:38









                George AlexandriaGeorge Alexandria

                2,05421121




                2,05421121
































                    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.




                    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







                    這個網誌中的熱門文章

                    Xamarin.form Move up view when keyboard appear

                    Post-Redirect-Get with Spring WebFlux and Thymeleaf

                    Anylogic : not able to use stopDelay()