/// <summary> /// Replaces the goto statement with its target, if the target is goto statement. /// </summary> /// <param name="labeledStatement"></param> /// <param name="gotoStatement"></param> /// <returns></returns> private bool TryRemoveChainedGoto(Statement labeledStatement, GotoStatement gotoStatement) { if (!(labeledStatement is GotoStatement)) { return false; } BlockStatement parent = gotoStatement.Parent as BlockStatement; int index = parent.Statements.IndexOf(gotoStatement); /// Clone of labeled statement needed here Statement clone = labeledStatement.CloneStatementOnly(); clone.Label = string.Empty; parent.Statements.RemoveAt(index); parent.AddStatementAt(index, clone); methodContext.GotoStatements.Remove(gotoStatement); methodContext.GotoStatements.Add(clone as GotoStatement); if (!Targeted(labeledStatement.Label)) { UpdateUntargetedStatement(labeledStatement, new Statement[] { labeledStatement }); } return true; }
/// <summary> /// Coppies the block that is targeted from the goto if it matches the case /// /// ... some code /// goto: label0; /// /// ... /// ... /// label0: statement1 /// *statements* /// return; /// ... /// </summary> /// <param name="labeledStatement">The targeted statement.</param> /// <param name="gotoStatement">The goto statement.</param> /// <returns>Returns True if the targeted block was coppied.</returns> private bool TryCopyTargetedBlock(Statement labeledStatement, GotoStatement gotoStatement) { StatementCollection toCopy = new StatementCollection(); StatementCollection originalStatements = new StatementCollection(); BlockStatement targetParent = labeledStatement.Parent as BlockStatement; if (targetParent == null) { return false; } int targetIndex = targetParent.Statements.IndexOf(labeledStatement); originalStatements.Add(labeledStatement); Statement labeledClone = labeledStatement.CloneStatementOnly(); labeledClone.Label = string.Empty; toCopy.Add(labeledClone); int maxStatementsToCopy = MaximumStatementsToCopy; if (ContainsLabel(labeledClone)) { return false; } maxStatementsToCopy -= GetStatementsCount(labeledClone); if (maxStatementsToCopy < 0) { return false; } if (!IsReturnStatement(labeledClone) && !IsThrowStatement(labeledClone)) { ///Collect all statements, until a return is reached. int index; for (index = targetIndex + 1; index < targetParent.Statements.Count; index++) { Statement nextStatement = targetParent.Statements[index]; if (ContainsLabel(nextStatement)) { return false; } maxStatementsToCopy -= GetStatementsCount(nextStatement); if (maxStatementsToCopy < 0) { return false; } originalStatements.Add(nextStatement); Statement clone = nextStatement.CloneStatementOnly(); toCopy.Add(clone); if (IsReturnStatement(nextStatement) || IsThrowStatement(nextStatement)) { break; } } if (index == targetParent.Statements.Count) { ///all the statements were traversed and no 'return' statement was found return false; } } ///Move the coppied statements on the place of the goto statement. MoveStatements(gotoStatement, toCopy); ///Clean up the label from the targeted statement if possible, and remove the targeted statement if it cannot be reached anymore if (!Targeted(labeledStatement.Label)) { UpdateUntargetedStatement(labeledStatement, originalStatements); } return true; }