public ForStatement TransformFor(ExpressionStatement node)
        {
            Match m1 = variableAssignPattern.Match(node);

            if (!m1.Success)
            {
                return(null);
            }
            var     variable = m1.Get <IdentifierExpression>("variable").Single().GetILVariable();
            AstNode next     = node.NextSibling;

            if (next is ForStatement forStatement && ForStatementUsesVariable(forStatement, variable))
            {
                node.Remove();
                next.InsertChildAfter(null, node, ForStatement.InitializerRole);
                return((ForStatement)next);
            }
            Match m3 = forPattern.Match(next);

            if (!m3.Success)
            {
                return(null);
            }
            // ensure the variable in the for pattern is the same as in the declaration
            if (variable != m3.Get <IdentifierExpression>("ident").Single().GetILVariable())
            {
                return(null);
            }
            WhileStatement loop = (WhileStatement)next;

            // Cannot convert to for loop, because that would change the semantics of the program.
            // continue in while jumps to the condition block.
            // Whereas continue in for jumps to the increment block.
            if (loop.DescendantNodes(DescendIntoStatement).OfType <Statement>().Any(s => s is ContinueStatement))
            {
                return(null);
            }
            node.Remove();
            BlockStatement newBody = new BlockStatement();

            foreach (Statement stmt in m3.Get <Statement>("statement"))
            {
                newBody.Add(stmt.Detach());
            }
            forStatement = new ForStatement();
            forStatement.CopyAnnotationsFrom(loop);
            forStatement.Initializers.Add(node);
            forStatement.Condition = loop.Condition.Detach();
            forStatement.Iterators.Add(m3.Get <Statement>("increment").Single().Detach());
            forStatement.EmbeddedStatement = newBody;
            loop.ReplaceWith(forStatement);
            return(forStatement);
        }
        public ForStatement TransformFor(ExpressionStatement node)
        {
            Match m1 = variableAssignPattern.Match(node);

            if (!m1.Success)
            {
                return(null);
            }
            var     variableName = m1.Get <IdentifierExpression>("variable").Single().Identifier;
            AstNode next         = node.NextSibling;

            if (next is ForStatement forStatement)
            {
                if ((forStatement.Iterators.FirstOrDefault() is ExpressionStatement stmt &&
                     stmt.Expression is AssignmentExpression assign &&
                     variableName == assign.Left.ToString()) ||
                    (forStatement.Condition is BinaryOperatorExpression cond &&
                     variableName == cond.Left.ToString()))
                {
                    node.Remove();
                    forStatement.InsertChildAfter(null, node, ForStatement.InitializerRole);
                    return(forStatement);
                }
            }
            Match m3 = forPattern.Match(next);

            if (!m3.Success)
            {
                return(null);
            }
            // ensure the variable in the for pattern is the same as in the declaration
            if (variableName != m3.Get <IdentifierExpression>("ident").Single().Identifier)
            {
                return(null);
            }
            WhileStatement loop = (WhileStatement)next;

            node.Remove();
            BlockStatement newBody = new BlockStatement();

            foreach (Statement stmt in m3.Get <Statement>("statement"))
            {
                newBody.Add(stmt.Detach());
            }
            forStatement = new ForStatement();
            forStatement.CopyAnnotationsFrom(loop);
            forStatement.Initializers.Add(node);
            forStatement.Condition = loop.Condition.Detach();
            forStatement.Iterators.Add(m3.Get <Statement>("increment").Single().Detach());
            forStatement.EmbeddedStatement = newBody;
            loop.ReplaceWith(forStatement);
            return(forStatement);
        }
        public ForStatement TransformFor(ExpressionStatement node)
        {
            Match m1 = variableAssignPattern.Match(node);

            if (!m1.Success)
            {
                return(null);
            }
            var     variable = m1.Get <IdentifierExpression>("variable").Single().GetILVariable();
            AstNode next     = node.NextSibling;

            if (next is ForStatement forStatement && ForStatementUsesVariable(forStatement, variable))
            {
                node.Remove();
                next.InsertChildAfter(null, node, ForStatement.InitializerRole);
                return((ForStatement)next);
            }
            Match m3 = forPattern.Match(next);

            if (!m3.Success)
            {
                return(null);
            }
            // ensure the variable in the for pattern is the same as in the declaration
            if (variable != m3.Get <IdentifierExpression>("ident").Single().GetILVariable())
            {
                return(null);
            }
            WhileStatement loop = (WhileStatement)next;

            node.Remove();
            BlockStatement newBody = new BlockStatement();

            foreach (Statement stmt in m3.Get <Statement>("statement"))
            {
                newBody.Add(stmt.Detach());
            }
            forStatement = new ForStatement();
            forStatement.CopyAnnotationsFrom(loop);
            forStatement.Initializers.Add(node);
            forStatement.Condition = loop.Condition.Detach();
            forStatement.Iterators.Add(m3.Get <Statement>("increment").Single().Detach());
            forStatement.EmbeddedStatement = newBody;
            loop.ReplaceWith(forStatement);
            return(forStatement);
        }