protected function joinInputs(GraphNode $node)
 {
     if ($this->cfg->getEntryPoint() === $node) {
         $node->setAttribute(self::ATTR_FLOW_STATE_IN, $this->createEntryLattice());
         return;
     }
     $predNodes = $this->cfg->getDirectedPredNodes($node);
     if (!$predNodes) {
         return;
     }
     $values = array();
     foreach ($predNodes as $predNode) {
         $succNodes = $this->cfg->getDirectedSuccNodes($predNode);
         $index = array_search($node, $succNodes, true);
         $outStates = $predNode->getAttribute(self::ATTR_FLOW_STATE_OUT);
         $values[] = $outStates[$index];
     }
     if (!$values) {
         return;
     }
     $newInState = call_user_func($this->joinOp, $values);
     $node->setAttribute(self::ATTR_FLOW_STATE_IN, $newInState);
 }
 private function prioritizeFromEntryNode(GraphNode $entry)
 {
     $worklist = array();
     $worklist[] = array($entry, $entry->getAstNode()->getAttribute('position', 0));
     while (!empty($worklist)) {
         list($current, ) = array_shift($worklist);
         /** @var $current GraphNode */
         if (null !== $current->getAttribute('priority')) {
             continue;
         }
         $current->setAttribute('priority', ++$this->priorityCounter);
         foreach ($current->getOutEdges() as $edge) {
             /** @var $edge GraphEdge */
             $destNode = $edge->getDest();
             // Implicit return is always the last node.
             if ($this->graph->isImplicitReturn($destNode)) {
                 $position = $this->astPositionCounter + 1;
             } else {
                 $position = $destNode->getAstNode()->getAttribute('position');
                 if (null === $position) {
                     throw new \RuntimeException(NodeUtil::getStringRepr($destNode->getAstNode()) . ' has no position.');
                 }
             }
             $worklist[] = array($destNode, $position);
         }
         usort($worklist, function ($a, $b) {
             return $a[1] - $b[1];
         });
     }
 }
 protected function flow(GraphNode $node)
 {
     if ($this->isForward()) {
         $outBefore = $node->getAttribute(self::ATTR_FLOW_STATE_OUT);
         $outAfter = $this->flowThrough($node->getAstNode(), $node->getAttribute(self::ATTR_FLOW_STATE_IN));
         $node->setAttribute(self::ATTR_FLOW_STATE_OUT, $outAfter);
         return false === $outBefore->equals($outAfter);
     }
     $inBefore = $node->getAttribute(self::ATTR_FLOW_STATE_IN);
     $inAfter = $this->flowThrough($node->getAstNode(), $node->getAttribute(self::ATTR_FLOW_STATE_OUT));
     $node->setAttribute(self::ATTR_FLOW_STATE_IN, $inAfter);
     return false === $inBefore->equals($inAfter);
 }
 private function verifyOutHas(GraphNode $node, Variable $var, $constant)
 {
     $fState = $node->getAttribute(DataFlowAnalysis::ATTR_FLOW_STATE_OUT);
     if (null === $constant) {
         $this->assertFalse(isset($fState->constMap[$var]));
     } else {
         $this->assertTrue(isset($fState->constMap[$var]));
         $this->assertSame($constant, $fState->constMap[$var]);
     }
 }
 public function isConnected(GraphNode $a, GraphNode $b, $edgeType)
 {
     foreach ($a->getOutEdges() as $edge) {
         if ($edge->getType() !== $edgeType) {
             continue;
         }
         if ($edge->getDest() === $b) {
             return true;
         }
     }
     return false;
 }