/// <summary> /// Constructs the control-flow graph of the node. /// </summary> /// <param name="stmtList">List of statements</param> /// <param name="successor">ControlFlowNode</param> /// <param name="innerLoopHead">LoopHeadControlFlowNode</param> private void Construct(List <StatementSyntax> stmtList, ControlFlowNode successor, LoopHeadControlFlowNode innerLoopHead) { while (stmtList.Count > 0) { if (stmtList[0] is IfStatementSyntax) { this.ConstructIfThenElseBranch(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is ForStatementSyntax) { this.ConstructForLoop(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is WhileStatementSyntax) { this.ConstructWhileLoop(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is ForEachStatementSyntax) { this.ConstructForeachLoop(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is DoStatementSyntax) { this.ConstructDoWhileLoop(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is SwitchStatementSyntax) { this.ConstructSwitchBlock(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is UsingStatementSyntax) { this.ConstructUsingBlock(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is BlockSyntax) { this.ConstructNakedCodeBlock(stmtList, successor, innerLoopHead); return; } else if (stmtList[0] is ReturnStatementSyntax) { this.Statements.Add(Statement.Create(stmtList[0], this, this.Summary)); stmtList.RemoveAt(0); return; } else if (stmtList[0] is ContinueStatementSyntax) { stmtList.RemoveAt(0); this.ISuccessors.Add(innerLoopHead); innerLoopHead.IPredecessors.Add(this); return; } else if (stmtList[0] is BreakStatementSyntax) { stmtList.RemoveAt(0); if (innerLoopHead != null) { this.ISuccessors.Add(innerLoopHead.LoopExitNode); innerLoopHead.LoopExitNode.IPredecessors.Add(this); return; } else { stmtList.Clear(); } } else if (stmtList[0] is ExpressionStatementSyntax || stmtList[0] is LocalDeclarationStatementSyntax) { this.Statements.Add(Statement.Create(stmtList[0], this, this.Summary)); stmtList.RemoveAt(0); } // NOTE: exceptions not supported yet else if (stmtList[0] is ThrowStatementSyntax) { this.Statements.Add(Statement.Create(stmtList[0], this, this.Summary)); stmtList.RemoveAt(0); } else if (stmtList[0] is EmptyStatementSyntax) { stmtList.RemoveAt(0); } else { throw new NotSupportedException($"CFG construction for statement '{stmtList[0]}' " + "is not yet supported. Please report this to the developers."); } } if (stmtList.Count == 0 && successor != null) { this.ISuccessors.Add(successor); successor.IPredecessors.Add(this); } }
/// <summary> /// Constructor. /// </summary> /// <param name="summary">MethodSummary</param> internal ControlFlowGraph(MethodSummary summary) : base() { base.EntryNode = ControlFlowNode.Create(this, summary); base.MergeEmptyNodes(); }