public override void ExitIfStatement(IfStatement ifStatement) { var block = (BlockStatement)ifStatement.Parent; var trueBranchGotoTarget = new GotoTargetStatement(ifStatement.Context); var endGotoTarget = new GotoTargetStatement(ifStatement.Context); var trueBranch = ifStatement.TrueBranch; var falseBranch = ifStatement.FalseBranch; if (falseBranch != null) { block.AddChildBefore(ifStatement, new GotoStatement(ifStatement.Context, ifStatement.Condition, trueBranchGotoTarget)); block.AddChildBefore(ifStatement, falseBranch); block.AddChildBefore(ifStatement, new GotoStatement(ifStatement.Context, endGotoTarget)); block.AddChildBefore(ifStatement, trueBranchGotoTarget); block.AddChildBefore(ifStatement, trueBranch); block.AddChildBefore(ifStatement, endGotoTarget); } else { var condition = new UnaryExpression(ifStatement.Context, new INode[] { new Token(ifStatement.Context, "!"), ifStatement.Condition }); block.AddChildBefore(ifStatement, new GotoStatement(ifStatement.Context, condition, endGotoTarget)); block.AddChildBefore(ifStatement, trueBranch); block.AddChildBefore(ifStatement, endGotoTarget); } ifStatement.Remove(); BlockFlattener.FlattenAllSubBlocks(block); }
public override void ExitMethodDeclaration(MethodDeclaration methodDeclaration) { BlockFlattener.FlattenAllSubBlocks(methodDeclaration.Body); methodDeclarations.Add(methodDeclaration); }
private void UnwrapMethodInvocation(MethodInvocationExpression invocation, MethodDeclaration declaration) { if (invocation.Parent == null) { return; } var context = invocation.Context; var parentStatement = invocation.NearestAncestorOfType <IStatement>(); var discardReturnValue = invocation.Parent is ExpressionStatement; var block = (BlockStatement)parentStatement.Parent; var addedStatements = new List <IStatement>(); VariableDeclaration returnValueVar = null; if (!discardReturnValue) { returnValueVar = new VariableDeclaration( context, declaration.Name + NumberWheel.Next(), new INode[] { AstCloner.Clone(declaration.ReturnType) }); var variableDeclarationStatement = new VariableDeclarationStatement(context, returnValueVar); block.AddChildBefore(parentStatement, variableDeclarationStatement); block.VariableDeclarations.Add(returnValueVar); invocation.ReplaceWith(new SimpleNameExpression(context, returnValueVar.Name) { Type = returnValueVar.Type, Declaration = returnValueVar }); addedStatements.Add(variableDeclarationStatement); } else { invocation.Remove(); } var clonedDeclaration = AstCloner.Clone(declaration); var parameters = clonedDeclaration.Variables.ToList(); var arguments = invocation.Arguments.ToList(); for (int i = 0; i < parameters.Count; i++) { if (arguments.Count > i) { if (parameters[i].InitExpression != null) { parameters[i].InitExpression.ReplaceWith(arguments[i]); } else { parameters[i].AddChild(arguments[i]); } } parameters[i].Remove(); parameters[i].Name += NumberWheel.Next(); var variableDeclarationStatement = new VariableDeclarationStatement(parameters[i].Context, parameters[i]); block.AddChildBefore(parentStatement, variableDeclarationStatement); block.VariableDeclarations.Add(parameters[i]); addedStatements.Add(variableDeclarationStatement); } foreach (var expression in clonedDeclaration.AllDescendantsAndSelf().OfType <SimpleNameExpression>()) { var index = parameters.IndexOf(expression.Declaration); if (index == -1) { continue; } expression.Name = parameters[index].Name; } var body = clonedDeclaration.Body; block.AddChildBefore(parentStatement, body); addedStatements.Add(body); var gotoTarget = new GotoTargetStatement(invocation.Context); block.AddChildBefore(parentStatement, gotoTarget); addedStatements.Add(gotoTarget); ReplaceReturnStatements(clonedDeclaration.Body, gotoTarget, returnValueVar); if (discardReturnValue) { parentStatement.Remove(); } foreach (var subInvocation in addedStatements.SelectMany(x => x.AllDescendantsAndSelf()).OfType <MethodInvocationExpression>().ToList()) { var subTarget = ((MethodReferenceType)subInvocation.Base.Type).Declaration; UnwrapMethodInvocation(subInvocation, subTarget); } BlockFlattener.FlattenAllSubBlocks(block); }
public override void EnterMethodDeclaration(MethodDeclaration methodDeclaration) { BlockFlattener.FlattenAllSubBlocks(methodDeclaration.Body); }