* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Argument\ArgumentInterface; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; /** * Inline service definitions where this is possible. * * @author Johannes M. Schmitt */ class InlineServiceDefinitionsPass extends AbstractRecursivePass implements RepeatablePassInterface { private $repeatedPass; /** * {@inheritdoc} */ public function setRepeatedPass(RepeatedPass $repeatedPass) { $this->repeatedPass = $repeatedPass; } /** * {@inheritdoc} */ protected function processValue($value, $isRoot = false) { if ($value instanceof ArgumentInterface) { $this->processValue($value->getValues()); return $value; } if ($value instanceof Reference && $this->container->hasDefinition($id = (string) $value)) { $compiler = $this->container->getCompiler(); $definition = $this->container->getDefinition($id); if ($this->isInlineableDefinition($id, $definition, $compiler->getServiceReferenceGraph())) { $compiler->addLogMessage($compiler->getLoggingFormatter()->formatInlineService($this, $id, $this->currentId)); if ($definition->isShared()) { return $definition; } $value = clone $definition; } } return parent::processValue($value, $isRoot); } /** * Checks if the definition is inlineable. * * @return bool If the definition is inlineable */ private function isInlineableDefinition($id, Definition $definition, ServiceReferenceGraph $graph) { if (!$definition->isShared()) { return true; } if ($definition->isPublic() || $definition->isLazy()) { return false; } if (!$graph->hasNode($id)) { return true; } if ($this->currentId == $id) { return false; } $ids = array(); foreach ($graph->getNode($id)->getInEdges() as $edge) { $ids[] = $edge->getSourceNode()->getId(); } if (count(array_unique($ids)) > 1) { return false; } if (count($ids) > 1 && is_array($factory = $definition->getFactory()) && ($factory[0] instanceof Reference || $factory[0] instanceof Definition)) { return false; } return true; } }