private ForEachStatement TraverseForeachStatement(ForEachStatementSyntax fess, ref int returnCnt, bool nested = false) { ForEachStatement foreachStm = new ForEachStatement(); foreachStm.IsNested = nested; foreachStm.ConditionCount = 1; bool skipId = false; int skipIds = 0; foreach (SyntaxNode sn in fess.ChildNodes()) { if (sn is BinaryExpressionSyntax) { foreachStm.ConditionCount++; } else if (sn is VariableDeclaratorSyntax) { foreachStm.AccessedVars.Add(TraverseVariableSyntax(sn as VariableDeclaratorSyntax, null, null)); skipId = true; } else if (sn is InvocationExpressionSyntax) { InvokedMethod invokedMethod = TraverseInvokedMethod(sn as InvocationExpressionSyntax); foreachStm.InvokedMethods.Add(invokedMethod); skipId = true; skipIds = invokedMethod.Parameters.Count; } else if (sn is IdentifierNameSyntax) { if (!skipId) { Variables variable = new Variables(); variable.IsReferenced = true; variable.Name = (sn as IdentifierNameSyntax).Identifier.ValueText; foreachStm.AccessedVars.Add(variable); } else if (skipIds == 0) { skipId = false; } else { skipIds--; } } } ForBlockSyntax fbs = fess.Parent as ForBlockSyntax; foreach (StatementSyntax ss in fbs.Statements) { if (ss is AssignmentStatementSyntax) { //TODO: need to look at more than just then name! Method tempMethod = TraverseAccessVars(ss as AssignmentStatementSyntax); foreachStm.AccessedVars.AddRange(tempMethod.AccessedVariables); foreachStm.InvokedMethods.AddRange(tempMethod.InvokedMethods); } else if (ss is LocalDeclarationStatementSyntax) { Method tempMethod = TraverseVarDecls(ss as LocalDeclarationStatementSyntax); foreachStm.AccessedVars.AddRange(tempMethod.AccessedVariables); foreachStm.InvokedMethods.AddRange(tempMethod.InvokedMethods); } else if (ss is SingleLineIfStatementSyntax) { Decisions decision = TraverseIfStatement(ss as SingleLineIfStatementSyntax, ref returnCnt, true); foreachStm.Nested.AddRange(decision.IfStatements); foreachStm.Nested.AddRange(decision.ElseStatements); } else if (ss is MultiLineIfBlockSyntax) { Decisions decisions = TraverseMultiIfStatement(ss as MultiLineIfBlockSyntax, ref returnCnt, true); foreachStm.Nested.AddRange(decisions.IfStatements); foreachStm.Nested.AddRange(decisions.ElseStatements); } else if (ss is ForBlockSyntax) { Decisions tempDecision = TraverseForStatement(ss as ForBlockSyntax, ref returnCnt, true); foreachStm.Nested.AddRange(tempDecision.IfStatements); foreachStm.Nested.AddRange(tempDecision.ElseStatements); foreachStm.Nested.AddRange(tempDecision.ForEachStatements); foreachStm.Nested.AddRange(tempDecision.ForStatements); foreachStm.Nested.AddRange(tempDecision.WhileLoops); foreachStm.Nested.AddRange(tempDecision.DoWhileLoops); foreachStm.Nested.AddRange(tempDecision.Catches); foreachStm.Nested.AddRange(tempDecision.SwitchStatements); } else if (ss is ElseStatementSyntax) { foreachStm.Nested.Add(TravsereElseStatement(ss as ElseStatementSyntax, ref returnCnt, true)); } else if (ss is SelectBlockSyntax) { foreachStm.Nested.Add(TraverseSwitchStatement(ss as SelectBlockSyntax, ref returnCnt, true)); } else if (ss is DoLoopBlockSyntax) { foreachStm.Nested.Add(TraverseDoWhileLoop(ss as DoLoopBlockSyntax, ref returnCnt, true)); } else if (ss is WhileBlockSyntax) { foreachStm.Nested.Add(TraverseWhileLoop(ss as WhileBlockSyntax, ref returnCnt, true)); } else if (ss is CallStatementSyntax) { foreachStm.InvokedMethods.Add(TraverseInvokedMethod(ss as CallStatementSyntax)); } else if (ss is ReturnStatementSyntax) { Method tempMethod = TraverseReturnStatement(ss as ReturnStatementSyntax); foreachStm.InvokedMethods.AddRange(tempMethod.InvokedMethods); foreachStm.AccessedVars.AddRange(tempMethod.AccessedVariables); returnCnt++; } } return foreachStm; }