private void EliminateViaDoWhile(IfStatement gotoStatement, Statement labeledStatement) { V_0 = new List <BreakStatement>(); V_1 = new List <ContinueStatement>(); V_2 = this.GetOuterBlock(labeledStatement); V_3 = V_2.get_Statements().IndexOf(labeledStatement); V_4 = V_2.get_Statements().IndexOf(gotoStatement); V_5 = this.CollectStatements(V_3, V_4, V_2); if (this.ShouldCheck(gotoStatement)) { stackVariable127 = new ContinueAndBreakFinder(); stackVariable127.Visit(V_5); V_0 = stackVariable127.get_Breaks(); V_1 = stackVariable127.get_Continues(); } V_7 = V_0.GetEnumerator(); try { while (V_7.MoveNext()) { V_8 = V_7.get_Current(); stackVariable29 = this.GetOuterBlock(V_8); V_9 = stackVariable29.get_Statements().IndexOf(V_8); this.usedBreakVariable = true; V_10 = new ExpressionStatement(new BinaryExpression(26, new VariableReferenceExpression(this.breakVariable, null), this.GetLiteralExpression(true), this.typeSystem, null, false)); stackVariable29.AddStatementAt(V_9, V_10); } } finally { if (V_7 != null) { V_7.Dispose(); } } V_11 = V_1.GetEnumerator(); try { while (V_11.MoveNext()) { V_12 = V_11.get_Current(); stackVariable60 = this.GetOuterBlock(V_12); V_13 = stackVariable60.get_Statements().IndexOf(V_12); this.usedContinueVariable = true; V_14 = new ExpressionStatement(new BinaryExpression(26, new VariableReferenceExpression(this.continueVariable, null), this.GetLiteralExpression(true), this.typeSystem, null, false)); stackVariable60.get_Statements().RemoveAt(V_13); stackVariable60.AddStatementAt(V_13, new BreakStatement(null)); stackVariable60.AddStatementAt(V_13, V_14); } } finally { if (V_11 != null) { V_11.Dispose(); } } V_6 = new DoWhileStatement(gotoStatement.get_Condition(), V_5); V_4 = V_2.get_Statements().IndexOf(gotoStatement); V_2.AddStatementAt(V_4, V_6); dummyVar0 = V_2.get_Statements().Remove(gotoStatement); if (V_0.get_Count() > 0) { this.AddBreakContinueConditional(V_4 + 1, V_2, new BreakStatement(null), this.breakVariable); } if (V_1.get_Count() > 0) { this.AddBreakContinueConditional(V_4 + 1, V_2, new ContinueStatement(null), this.continueVariable); } return; }
/// <summary> /// Eliminates the goto statement via introducing do-while. Should be used when the goto comes after the label. /// </summary> /// <param name="gotoStatement">The goto statement.</param> /// <param name="labeledStatement">The labeled statement.</param> private void EliminateViaDoWhile(IfStatement gotoStatement, Statement labeledStatement) { ICollection<BreakStatement> breaks = new List<BreakStatement>(); ICollection<ContinueStatement> continues = new List<ContinueStatement>(); BlockStatement containingBlock = GetOuterBlock(labeledStatement); int labelIndex = containingBlock.Statements.IndexOf(labeledStatement); int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement); BlockStatement loopBody = CollectStatements(labelIndex, gotoIndex, containingBlock); /// Checks if the gotoStatement is inside a loop/switch statement. /// If so, then some breaks might be enclosed in the new do-while. Additional breaks need to be included in this case if (ShouldCheck(gotoStatement)) { ContinueAndBreakFinder finder = new ContinueAndBreakFinder(); finder.Visit(loopBody); breaks = finder.Breaks; continues = finder.Continues; } /// Add condition = true before each enclosed break statement. foreach (BreakStatement statement in breaks) { BlockStatement breakBlock = GetOuterBlock(statement); int breakIndex = breakBlock.Statements.IndexOf(statement); BinaryExpression assign = new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(breakVariable, null), GetLiteralExpression(true), typeSystem, null); usedBreakVariable = true; ExpressionStatement assignment = new ExpressionStatement(assign); breakBlock.AddStatementAt(breakIndex, assignment); } /// Add condition = true before each enclosed continue statement /// and replace the continue statement with break statement foreach (ContinueStatement statement in continues) { BlockStatement continueBlock = GetOuterBlock(statement); int continueIndex = continueBlock.Statements.IndexOf(statement); BinaryExpression assign = new BinaryExpression(BinaryOperator.Assign, new VariableReferenceExpression(continueVariable, null), GetLiteralExpression(true), typeSystem, null); usedContinueVariable = true; ExpressionStatement assignment = new ExpressionStatement(assign); continueBlock.Statements.RemoveAt(continueIndex); continueBlock.AddStatementAt(continueIndex, new BreakStatement(null)); continueBlock.AddStatementAt(continueIndex, assignment); } /// Replace the goto with do-while loop. DoWhileStatement doWhileLoop = new DoWhileStatement(gotoStatement.Condition, loopBody); gotoIndex = containingBlock.Statements.IndexOf(gotoStatement); containingBlock.AddStatementAt(gotoIndex, doWhileLoop); containingBlock.Statements.Remove(gotoStatement); if (breaks.Count > 0) { /// Add condition for the outer break, accounting for the enclosed breaks. AddBreakContinueConditional(gotoIndex + 1, containingBlock, new BreakStatement(null), breakVariable);//gotoindex + 1 should be the place after the newly inserted do-while loop } if (continues.Count > 0) { /// Add condition for the outer break, accounting for the enclosed continues. AddBreakContinueConditional(gotoIndex + 1, containingBlock, new ContinueStatement(null), continueVariable); } }