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; // 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 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 ForStatement TransformFor(ExpressionStatement node) { Match m1 = variableAssignPattern.Match(node); if (m1 == null) { return(null); } AstNode next = node.NextSibling; Match m2 = forPattern.Match(next); if (m2 == null) { return(null); } // ensure the variable in the for pattern is the same as in the declaration if (m1.Get <IdentifierExpression>("variable").Single().Identifier != m2.Get <IdentifierExpression>("ident").Single().Identifier) { return(null); } WhileStatement loop = (WhileStatement)next; node.Remove(); BlockStatement newBody = new BlockStatement(); foreach (Statement stmt in m2.Get <Statement>("statement")) { newBody.Add(stmt.Detach()); } ForStatement forStatement = new ForStatement(); forStatement.Initializers.Add(node); forStatement.Condition = loop.Condition.Detach(); forStatement.Iterators.Add(m2.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); }
public override void VisitWhileStatement(WhileStatement node) { VisitChildren(node); var condition = node.Condition; var body = node.EmbeddedStatement; condition.Remove(); body.Remove(); // Special-case constant conditions var constant = BoolConstant(condition); if (constant == true) { condition = null; // Convert "while (true)" => "for(;;)" } else if (constant == false) { node.Remove(); // Remove "while (false)" return; } // Convert "while (x)" => "for (;x;)" since it's shorter and compresses better var loop = new ForStatement(); loop.Condition = condition; loop.EmbeddedStatement = body; node.ReplaceWith(loop); ReplaceBlockWithSingleStatement(body); }