static function construct_cfg($stmts) { $prettyPrinter = new PhpParser\PrettyPrinter\Standard(); // Creating an empty entry node. $cfg = new CFG(); $entry = new CFGNode(); $cfg->entry = $entry; $current_node = $entry; foreach ($stmts as $stmt) { print "Processing statement:\n"; printStmts(array($stmt)); // Assignment statement. if ($stmt instanceof PhpParser\Node\Expr\Assign) { print "Found assignment statement\n"; $assign_node = CFG::processExprAssign($stmt); $current_node->successors[] = $assign_node; $assign_node->parents[] = $current_node; $current_node = $assign_node; print "Constructed assignment node\n"; } else { if ($stmt instanceof PhpParser\Node\Expr\AssignOp) { print "Found assignment with operation statement\n"; $assign_op_node = CFG::processExprAssignOp($stmt); $current_node->successors[] = $assign_op_node; $assign_op_node->parents[] = $current_node; $current_node = $assign_op_node; print "Constructed assignment with operation node\n"; } else { if ($stmt instanceof PhpParser\Node\Expr\PreDec) { print "Found a pre-decrement expression\n"; $predec_node = CFG::processExprPreDec($stmt); $current_node->successors[] = $predec_node; $predec_node->parents[] = $current_node; $current_node = $predec_node; print "Constructed pre-decrement expression.\n"; } else { if ($stmt instanceof PhpParser\Node\Stmt\Unset_) { print "Found unset statement\n"; $unset_node = CFG::processStmtUnset($stmt); $current_node->successors[] = $unset_node; $unset_node->parents[] = $current_node; $current_node = $unset_node; print "Constructed unset node\n"; } else { if ($stmt instanceof PhpParser\Node\Stmt\Global_) { print "Found global statement\n"; $global_node = CFG::processStmtGlobal($stmt); $current_node->successors[] = $global_node; $global_node->parents[] = $current_node; $current_node = $global_node; print "Constructed global node\n"; } else { if ($stmt instanceof PhpParser\Node\Stmt\Break_) { print "Found break statement\n"; $break_node = CFG::processStmtBreak($stmt); $current_node->successors[] = $break_node; $break_node->parents[] = $current_node; $current_node = $break_node; print "Constructed break node\n"; } else { if ($stmt instanceof PhpParser\Node\Stmt\Return_) { print "Found return statement\n"; $return_node = CFG::processStmtReturn($stmt); $current_node->successors[] = $return_node; $return_node->parents[] = $current_node; $current_node = $return_node; print "Constructed return node\n"; } else { if ($stmt instanceof PhpParser\Node\Stmt\If_) { // Note: What happens on if-elsif-elsif-else ? print "Found conditional statement\n"; $if_nodes = CFG::processStmtIf($stmt); // Connect the current node with the // conditional node of the if. $current_node->successors[] = $if_nodes[0]; // The previously processed node is the parent of // the conditional node. $if_nodes[0]->parents[] = $current_node; // Make the current node, the node that // joins the branches of the if. $current_node = $if_nodes[1]; print "Constructed conditional node\n"; // Method call statement. } else { if ($stmt instanceof PhpParser\Node\Expr\MethodCall) { print "Found method call statement\n"; $method_call_node = CFG::processExprMethodCall($stmt); $current_node->successors[] = $method_call_node; $method_call_node->parents[] = $current_node; $current_node = $method_call_node; print "Constructed method call node\n"; // Function call statement. } else { if ($stmt instanceof PhpParser\Node\Expr\FuncCall) { print "Found function call statement\n"; $function_call_node = CFG::processExprFuncCall($stmt); $current_node->successors[] = $function_call_node; $function_call_node->parents[] = $current_node; $current_node = $function_call_node; print "Constructed function call node\n"; // Static function call statement. } else { if ($stmt instanceof PhpParser\Node\Expr\StaticCall) { print "Found static call statement\n"; $static_call_node = CFG::processExprStaticCall($stmt); $current_node->successors[] = $static_call_node; $static_call_node->parents[] = $current_node; $current_node = $static_call_node; print "Constructed static call node\n"; // Loops: Foreach, For or While statement. } else { if ($stmt instanceof PhpParser\Node\Stmt\Foreach_ || $stmt instanceof PhpParser\Node\Stmt\For_ || $stmt instanceof PhpParser\Node\Stmt\While_) { print "Found " . gettype($stmt) . " statement\n"; // Returns a pair with the loop header // and a dummy exit node that follows the // loop. $loop_nodes = CFG::processStmtLoop($stmt); // Connect the current node to the loop header. $current_node->successors[] = $loop_nodes[0]; $loop_nodes[0]->parents[] = $current_node; // Make the dummy exit node of the loop // the current node. $current_node = $loop_nodes[1]; print "Constructed " . gettype($stmt) . " node\n"; } else { print "WARNING: Couldn't construct CFG node.\n"; print "The statement is of class " . get_class($stmt) . "\n"; print "Has keys\n"; /* foreach($stmt as $key => $value) { print "Key=".($key)."\n"; } */ // Constructing dummy node. $dummy_node = new CFGNode(); $current_node->successors[] = $dummy_node; $dummy_node->parents[] = $current_node; $current_node = $dummy_node; } } } } } } } } } } } } } // Create a dummy exit node, and make a pointer // from the last processed node to the exit node. $cfg->exit = new CFGNode(); $current_node->successors[] = $cfg->exit; $cfg->exit->parents[] = $current_node; return $cfg; }