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); }
public DoWhileStatement TransformDoWhile(WhileStatement whileLoop) { Match m = doWhilePattern.Match(whileLoop); if (m.Success) { DoWhileStatement doLoop = new DoWhileStatement(); doLoop.Condition = new UnaryOperatorExpression(UnaryOperatorType.Not, m.Get <Expression>("condition").Single().Detach()); //doLoop.Condition.AcceptVisitor(new PushNegation(), null); BlockStatement block = (BlockStatement)whileLoop.EmbeddedStatement; block.Statements.Last().Remove(); // remove if statement doLoop.EmbeddedStatement = block.Detach(); doLoop.CopyAnnotationsFrom(whileLoop); whileLoop.ReplaceWith(doLoop); // we may have to extract variable definitions out of the loop if they were used in the condition: foreach (var varDecl in block.Statements.OfType <VariableDeclarationStatement>()) { VariableInitializer v = varDecl.Variables.Single(); if (doLoop.Condition.DescendantsAndSelf.OfType <IdentifierExpression>().Any(i => i.Identifier == v.Name)) { AssignmentExpression assign = new AssignmentExpression(new IdentifierExpression(v.Name), v.Initializer.Detach()); // move annotations from v to assign: assign.CopyAnnotationsFrom(v); v.RemoveAnnotations <object>(); // remove varDecl with assignment; and move annotations from varDecl to the ExpressionStatement: varDecl.ReplaceWith(new ExpressionStatement(assign).CopyAnnotationsFrom(varDecl)); varDecl.RemoveAnnotations <object>(); // insert the varDecl above the do-while loop: doLoop.Parent.InsertChildBefore(doLoop, varDecl, BlockStatement.StatementRole); } } return(doLoop); } return(null); }