private bool TryGetSimpleCaseStatementType(SwitchCase theCase, out StatementType statementType, out string gotoLabel) { gotoLabel = null; statementType = StatementType.None; if (theCase.Body.Statements.Count != 1 || !string.IsNullOrEmpty(theCase.Body.Statements[0].Label)) { return false; } Statement statement = theCase.Body.Statements[0]; if (statement is GotoStatement) { statementType = StatementType.Goto; gotoLabel = (statement as GotoStatement).TargetLabel; } else if (statement is BreakStatement) { statementType = StatementType.Break; } else if (statement is ContinueStatement) { statementType = StatementType.Continue; } return statementType != StatementType.None; }
public void AddCase(SwitchCase @case) { cases.Add(@case); @case.Parent = this; needsRefreshing = true; }
/// <summary> /// Contains the logic for moving a goto inside the case of switch statement. For more information /// see Chapter "2.2.2 Inward-movement Transformations : Moving a goto into a switch statement" from /// <see cref="Taming Control Flow A Structured Approach to Eliminating Goto Statements.pdf"/>. /// </summary> /// <param name="gotoStatement">The goto statement to be moved in.</param> /// <param name="switchCase">The switch case that contains the target of the goto statement.</param> /// <param name="label">The label of the target.</param> private void MoveInCase(IfStatement gotoStatement, SwitchCase switchCase, string label) { VariableReferenceExpression conditionVariable = new VariableReferenceExpression(GetLabelVariable(label), null); BlockStatement containingBlock = GetOuterBlock(gotoStatement); SwitchStatement switchStatement = switchCase.Parent as SwitchStatement; int gotoIndex = containingBlock.Statements.IndexOf(gotoStatement); int switchIndex = containingBlock.Statements.IndexOf(switchStatement); /// Generate variable and extract the switch condition string switchVariableName = "switch" + switchStatement.ConditionBlock.First.Offset; TypeReference switchVariableType = GetSwitchType(switchStatement); VariableDefinition switchVariable = new VariableDefinition(switchVariableName, switchVariableType); switchVariables.Add(switchVariable); VariableReferenceExpression switchVarEx = new VariableReferenceExpression(switchVariable, null); ExtractConditionIntoVariable(switchVarEx, switchStatement, containingBlock); BlockStatement thenBlock = CollectStatements(gotoIndex + 1, switchIndex + 1, containingBlock); BlockStatement elseBlock = new BlockStatement(); /// Adds swCond = caseCond; in the last part of else. BinaryExpression assignSwitchVariable = new BinaryExpression(BinaryOperator.Assign, switchVarEx.CloneExpressionOnly(), GetCaseConditionExpression(switchCase), typeSystem, null); elseBlock.AddStatement(new ExpressionStatement(assignSwitchVariable)); IfStatement precedingIf = new IfStatement(new UnaryExpression(UnaryOperator.LogicalNot, conditionVariable, null), thenBlock, elseBlock); /// Attach new if and move the goto conditional. /// Attach it only if the then block is not empty. if (precedingIf.Then.Statements.Count != 0) { containingBlock.AddStatementAt(gotoIndex, precedingIf); } containingBlock.Statements.Remove(gotoStatement); switchCase.Body.AddStatementAt(0, gotoStatement); }
/// <summary> /// Gets the condition that is representing the supplied case. /// </summary> /// <param name="switchCase">The switch case, whose condition is being needed.</param> /// <returns>Returns expression, evaluating so that the switch jumps to <paramref name="switchCase"/>.</returns> private Expression GetCaseConditionExpression(SwitchCase switchCase) { if (switchCase is ConditionCase) { return (switchCase as ConditionCase).Condition; } else { /// SwitchCase is the default case SwitchStatement switchStatement = switchCase.Parent as SwitchStatement; //TypeReference switchType = GetSwitchType(switchCase.Parent as SwitchStatement); /// this could possibly be long instead of int, but this case should be quite rare int result = 1; foreach (SwitchCase @case in switchStatement.Cases) { if (@case is DefaultCase) { continue; } result += (int)(((@case as ConditionCase).Condition as LiteralExpression).Value); } return GetLiteralExpression(result); } }
public CaseGotoStatement(GotoStatement transformedGoto, SwitchCase targetedCase) : base(transformedGoto.Label, transformedGoto.UnderlyingSameMethodInstructions) { this.TargetedSwitchCase = targetedCase; }
/// <summary> /// Copy-constructor for cloning purposes. /// </summary> /// <param name="toClone">The statement to clone.</param> private CaseGotoStatement(CaseGotoStatement toClone, IEnumerable<Instruction> instructions) : base(toClone.Label, instructions) { this.TargetedSwitchCase = toClone.TargetedSwitchCase; }
public CaseGotoStatement(GotoStatement transformedGoto, SwitchCase targetedCase) { base(transformedGoto.get_Label(), transformedGoto.get_UnderlyingSameMethodInstructions()); this.set_TargetedSwitchCase(targetedCase); return; }