public override void VisitForStatement(ForStatementSyntax node) { if (!YieldChecker.HasSpecialStatement(node)) { currentState.Add(YieldThisFixer.Fix(node)); } else { var semanticModel = compilation.GetSemanticModel(node.SyntaxTree); // Convert the variable declarations in the for loop if (node.Declaration != null) { foreach (var variable in node.Declaration.Variables.Where(x => x.Initializer != null)) { var assignment = SyntaxFactory.IdentifierName(variable.Identifier.ToString()).Assign(variable.Initializer.Value); currentState.Add(Cs.Express(assignment)); var symbol = (ILocalSymbol)ModelExtensions.GetDeclaredSymbol(semanticModel, variable); // Hoist the variable into a field node = (ForStatementSyntax)HoistVariable(node, variable.Identifier, SyntaxFactory.ParseTypeName(symbol.Type.GetFullName())); } } foreach (var initializer in node.Initializers) { currentState.Add(Cs.Express(YieldThisFixer.Fix(initializer))); } MaybeCreateNewState(); var nextState = GetNextState(node); var iterationState = currentState; // postState determines where the flow goes after each iteration. If there are incrementors, it goes // to a state that handles the incrementing, then goes back to the iteration state. Otherwise, the // iteration state just points back to itself like the while loop. State postState; if (node.Incrementors.Any()) { postState = new State(this); postState.NextState = iterationState; foreach (var incrementor in node.Incrementors) { postState.Add(Cs.Express(YieldThisFixer.Fix(incrementor))); } Close(postState); } else { postState = iterationState; } iterationState.NextState = nextState; iterationState.BreakState = nextState; var forStatement = SyntaxFactory.WhileStatement(node.Condition ?? Cs.True(), SyntaxFactory.Block(CaptureState(node.Statement, postState, nextState))); iterationState.Statements.Add(forStatement); Close(iterationState); currentState = nextState; } }
public static StatementSyntax ChangeState(State newState) { return(Cs.Express(Cs.This().Member(state).Assign(Cs.Integer(newState.Index)))); }