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; }
private Decisions TraverseForEachStatements(ForEachStatementSyntax fes, ref int exitPoints, bool nested = false) { Decisions retDecision = new Decisions(); ForEachStatement retForEach = new ForEachStatement(); if (fes.HasLeadingTrivia) { SetOuterComments(retForEach, fes.GetLeadingTrivia().ToFullString()); } if (fes.HasTrailingTrivia) { SetInnerComments(retForEach, fes.GetTrailingTrivia().ToFullString()); } var binaryExpressions = from aBinaryExpression in fes.ChildNodes().OfType<BinaryExpressionSyntax>() select aBinaryExpression; retForEach.ConditionCount = binaryExpressions.Count(); foreach (BinaryExpressionSyntax bes in binaryExpressions) { Method tempMethod = TraverseBinaryExpression(bes); retForEach.AccessedVars.AddRange(tempMethod.AccessedVariables); retForEach.InvokedMethods.AddRange(tempMethod.InvokedMethods); } var catches = from aCatch in fes.ChildNodes().OfType<CatchClauseSyntax>() select aCatch; foreach (CatchClauseSyntax ccs in catches) { Decisions tempCatch = TraverseCatchClauses(ccs, ref exitPoints, true); retForEach.Nested.AddRange(tempCatch.Catches); } var statements = from aStatement in fes.Statement.ChildNodes().OfType<StatementSyntax>() select aStatement; List<BaseDecisions> retBd = new List<BaseDecisions>(); List<InvokedMethod> retIm = new List<InvokedMethod>(); #region Nested and Invoked Methods and accessed vars foreach (StatementSyntax ss in statements) { //if (ss is BreakStatementSyntax) //{ //} //else if (ss is CheckedStatementSyntax) //{ //} //else if (ss is ContinueStatementSyntax) //{ //} if (ss is DoStatementSyntax) { Decisions dwl = TraverseDoStatements(ss as DoStatementSyntax, ref exitPoints, true); retForEach.Nested.AddRange(dwl.DoWhileLoops); //dwl.IsNested = true; //retForEach.Nested.Add(dwl); } //else if (ss is EmptyStatementSyntax) //{ //} else if (ss is ExpressionStatementSyntax) { var vars = from aVar in ss.ChildNodes().OfType<BinaryExpressionSyntax>() select aVar; foreach (BinaryExpressionSyntax bes in vars) { Method tempMethod = TraverseBinaryExpression(bes); retForEach.AccessedVars.AddRange(tempMethod.AccessedVariables); retForEach.InvokedMethods.AddRange(tempMethod.InvokedMethods); } var invokedMethods = from aInvokedMethod in ss.ChildNodes().OfType<InvocationExpressionSyntax>() select aInvokedMethod; foreach (InvocationExpressionSyntax ies in invokedMethods) { Method tempMethod = TraverseInvocationExpression(ies); retForEach.AccessedVars.AddRange(tempMethod.AccessedVariables); retForEach.InvokedMethods.AddRange(tempMethod.InvokedMethods); } } //else if (ss is FixedStatementSyntax) //{ //} else if (ss is ForEachStatementSyntax) { Decisions forES = TraverseForEachStatements(ss as ForEachStatementSyntax, ref exitPoints, true); retForEach.Nested.AddRange(forES.ForEachStatements); //forES.IsNested = true; //retForEach.Nested.Add(forES); } else if (ss is ForStatementSyntax) { Decisions fs = TraverseForStatements(ss as ForStatementSyntax, ref exitPoints, true); retForEach.Nested.AddRange(fs.ForStatements); //fs.IsNested = true; //retForEach.Nested.Add(fs); } //else if (ss is GotoStatementSyntax) //{ //} else if (ss is IfStatementSyntax) { Decisions ifstm = TraverseIfStatements(ss as IfStatementSyntax, ref exitPoints, true); retForEach.Nested.AddRange(ifstm.IfStatements); //ifstm.IsNested = true; //retForEach.Nested.Add(ifstm); } //else if (ss is LabeledStatementSyntax) //{ // BaseDecisions bd = new BaseDecisions(); // bd.IsNested = true; // bd.Nested.Add(TraverseLabelStatements(ss as LabeledStatementSyntax)); // retIf.Nested.Add(bd); //} else if (ss is LocalDeclarationStatementSyntax) { Method tempMethod = TransverseAccessVars(ss as LocalDeclarationStatementSyntax); retForEach.AccessedVars.AddRange(tempMethod.AccessedVariables); retForEach.InvokedMethods.AddRange(tempMethod.InvokedMethods); } //else if (ss is LockStatementSyntax) //{ //} //else if (ss is ReturnStatementSyntax) //{ //} else if (ss is SwitchStatementSyntax) { Decisions switchStm = TraverseSwitchStatements(ss as SwitchStatementSyntax, ref exitPoints, true); retForEach.Nested.AddRange(switchStm.SwitchStatements); //switchStm.IsNested = true; //retForEach.Nested.Add(switchStm); } //else if (ss is ThrowStatementSyntax) //{ //} //else if (ss is TryStatementSyntax) //{ //} //else if (ss is UnsafeStatementSyntax) //{ //} //else if (ss is UsingStatementSyntax) //{ // //using list? //} else if (ss is WhileStatementSyntax) { Decisions wl = TraverseWhileLoops(ss as WhileStatementSyntax, ref exitPoints, true); retForEach.Nested.AddRange(wl.WhileLoops); //wl.IsNested = true; //retForEach.Nested.Add(wl); } //else if (ss is YieldStatementSyntax) //{ //} } #endregion retDecision.ForEachStatements.Add(retForEach); return retDecision; }