/** * Generate a digraph reduced to all calls to concrete method */ public function createReducedGraph() { $reducedGraph = new \Trismegiste\Mondrian\Graph\Digraph(); $edgeSet = $this->getEdgeSet(); foreach ($this->getVertexSet() as $cls) { if ($cls instanceof ClassVertex) { // for each class foreach ($this->getEdgeIterator($cls) as $methodVertex) { if ($methodVertex instanceof MethodVertex) { // we have a method first declared in a class // we search for calls to that method foreach ($edgeSet as $call) { if ($call->getSource() instanceof ImplVertex && $call->getTarget() === $methodVertex) { $impl = $call->getSource(); preg_match('#^([^:]+)::#', $impl->getName(), $extract); $owningClass = $extract[1]; // we search for the owning class of that impl foreach ($this->getSuccessor($impl) as $succ) { if ($succ instanceof ClassVertex && $succ->getName() == $owningClass) { // we found the owning class vertex of $impl // add edges to reduced graph $reducedGraph->addEdge($methodVertex, $cls); $reducedGraph->addEdge($succ, $methodVertex); } } } } } } } } // arf return $reducedGraph; }
public function createReducedGraph() { $reduced = new \Trismegiste\Mondrian\Graph\Digraph(); foreach ($this->getEdgeSet() as $declaring) { // we search for methods declared in interfaces if ($declaring->getSource() instanceof InterfaceVertex && $declaring->getTarget() instanceof MethodVertex) { $method = $declaring->getTarget(); // scan for all parameters foreach ($this->getEdgeIterator($method) as $param) { if ($param instanceof ParamVertex) { // we find a param, we scan for type hint foreach ($this->getEdgeIterator($param) as $typeHint) { if ($typeHint instanceof ClassVertex) { // we find a typed parameter with a class : evil // we add the shortcut path (skip the parameter, not relevant) $reduced->addEdge($declaring->getSource(), $method); $reduced->addEdge($method, $typeHint); } } } } } } // I love this ^o^ return $reduced; }
/** * Generate a digraph reduced to the hidden coupled vertices * * Since all vertices need to be scanned, go for the Floyd–Warshall algorithm * http://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm * in O(n³) * */ public function createReducedGraph() { $reducedGraph = new \Trismegiste\Mondrian\Graph\Digraph(); $dependency = $this->getEdgeSet(); foreach ($dependency as $edge) { if ($edge->getSource() instanceof ImplVertex && $edge->getTarget() instanceof MethodVertex) { $this->resetVisited(); $edge->visited = true; $otherPath = $this->searchPath($edge->getSource(), $edge->getTarget()); if (count($otherPath) == 0) { // not found => hidden coupling : // source is impl and target is method $reducedGraph->addEdge($edge->getSource(), $edge->getTarget()); $reducedGraph->addEdge($this->findOwningClassVertex($edge->getSource()), $edge->getSource()); $reducedGraph->addEdge($this->findDeclaringVertex($edge->getTarget()), $edge->getTarget()); } } } return $reducedGraph; }