Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\DependencyInjection\Compiler; Chris@0: Chris@0: use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; Chris@0: Chris@0: /** Chris@0: * This is a directed graph of your services. Chris@0: * Chris@0: * This information can be used by your compiler passes instead of collecting Chris@0: * it themselves which improves performance quite a lot. Chris@0: * Chris@0: * @author Johannes M. Schmitt Chris@14: * Chris@14: * @final since version 3.4 Chris@0: */ Chris@0: class ServiceReferenceGraph Chris@0: { Chris@0: /** Chris@0: * @var ServiceReferenceGraphNode[] Chris@0: */ Chris@17: private $nodes = []; Chris@0: Chris@0: /** Chris@0: * Checks if the graph has a specific node. Chris@0: * Chris@0: * @param string $id Id to check Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function hasNode($id) Chris@0: { Chris@0: return isset($this->nodes[$id]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets a node by identifier. Chris@0: * Chris@0: * @param string $id The id to retrieve Chris@0: * Chris@0: * @return ServiceReferenceGraphNode Chris@0: * Chris@0: * @throws InvalidArgumentException if no node matches the supplied identifier Chris@0: */ Chris@0: public function getNode($id) Chris@0: { Chris@0: if (!isset($this->nodes[$id])) { Chris@0: throw new InvalidArgumentException(sprintf('There is no node with id "%s".', $id)); Chris@0: } Chris@0: Chris@0: return $this->nodes[$id]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns all nodes. Chris@0: * Chris@0: * @return ServiceReferenceGraphNode[] Chris@0: */ Chris@0: public function getNodes() Chris@0: { Chris@0: return $this->nodes; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Clears all nodes. Chris@0: */ Chris@0: public function clear() Chris@0: { Chris@14: foreach ($this->nodes as $node) { Chris@14: $node->clear(); Chris@14: } Chris@17: $this->nodes = []; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Connects 2 nodes together in the Graph. Chris@0: * Chris@0: * @param string $sourceId Chris@14: * @param mixed $sourceValue Chris@0: * @param string $destId Chris@14: * @param mixed $destValue Chris@0: * @param string $reference Chris@14: * @param bool $lazy Chris@14: * @param bool $weak Chris@17: * @param bool $byConstructor Chris@0: */ Chris@17: public function connect($sourceId, $sourceValue, $destId, $destValue = null, $reference = null/*, bool $lazy = false, bool $weak = false, bool $byConstructor = false*/) Chris@0: { Chris@17: $lazy = \func_num_args() >= 6 ? func_get_arg(5) : false; Chris@17: $weak = \func_num_args() >= 7 ? func_get_arg(6) : false; Chris@17: $byConstructor = \func_num_args() >= 8 ? func_get_arg(7) : false; Chris@14: Chris@14: if (null === $sourceId || null === $destId) { Chris@14: return; Chris@14: } Chris@14: Chris@0: $sourceNode = $this->createNode($sourceId, $sourceValue); Chris@0: $destNode = $this->createNode($destId, $destValue); Chris@17: $edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference, $lazy, $weak, $byConstructor); Chris@0: Chris@0: $sourceNode->addOutEdge($edge); Chris@0: $destNode->addInEdge($edge); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Creates a graph node. Chris@0: * Chris@0: * @param string $id Chris@14: * @param mixed $value Chris@0: * Chris@0: * @return ServiceReferenceGraphNode Chris@0: */ Chris@0: private function createNode($id, $value) Chris@0: { Chris@0: if (isset($this->nodes[$id]) && $this->nodes[$id]->getValue() === $value) { Chris@0: return $this->nodes[$id]; Chris@0: } Chris@0: Chris@0: return $this->nodes[$id] = new ServiceReferenceGraphNode($id, $value); Chris@0: } Chris@0: }