diff -r 000000000000 -r 7f95f8617b0b vendor/symfony/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/symfony/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,136 @@ + + * + * 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\ContainerInterface; +use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Inline service definitions where this is possible. + * + * @author Johannes M. Schmitt + */ +class InlineServiceDefinitionsPass implements RepeatablePassInterface +{ + private $repeatedPass; + private $graph; + private $compiler; + private $formatter; + private $currentId; + + /** + * {@inheritDoc} + */ + public function setRepeatedPass(RepeatedPass $repeatedPass) + { + $this->repeatedPass = $repeatedPass; + } + + /** + * Processes the ContainerBuilder for inline service definitions. + * + * @param ContainerBuilder $container + */ + public function process(ContainerBuilder $container) + { + $this->compiler = $container->getCompiler(); + $this->formatter = $this->compiler->getLoggingFormatter(); + $this->graph = $this->compiler->getServiceReferenceGraph(); + + foreach ($container->getDefinitions() as $id => $definition) { + $this->currentId = $id; + + $definition->setArguments( + $this->inlineArguments($container, $definition->getArguments()) + ); + + $definition->setMethodCalls( + $this->inlineArguments($container, $definition->getMethodCalls()) + ); + + $definition->setProperties( + $this->inlineArguments($container, $definition->getProperties()) + ); + } + } + + /** + * Processes inline arguments. + * + * @param ContainerBuilder $container The ContainerBuilder + * @param array $arguments An array of arguments + */ + private function inlineArguments(ContainerBuilder $container, array $arguments) + { + foreach ($arguments as $k => $argument) { + if (is_array($argument)) { + $arguments[$k] = $this->inlineArguments($container, $argument); + } else if ($argument instanceof Reference) { + if (!$container->hasDefinition($id = (string) $argument)) { + continue; + } + + if ($this->isInlinableDefinition($container, $id, $definition = $container->getDefinition($id))) { + $this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId)); + + if (ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope()) { + $arguments[$k] = $definition; + } else { + $arguments[$k] = clone $definition; + } + } + } else if ($argument instanceof Definition) { + $argument->setArguments($this->inlineArguments($container, $argument->getArguments())); + $argument->setMethodCalls($this->inlineArguments($container, $argument->getMethodCalls())); + $argument->setProperties($this->inlineArguments($container, $argument->getProperties())); + } + } + + return $arguments; + } + + /** + * Checks if the definition is inlineable. + * + * @param ContainerBuilder $container + * @param string $id + * @param Definition $definition + * @return Boolean If the definition is inlineable + */ + private function isInlinableDefinition(ContainerBuilder $container, $id, Definition $definition) + { + if (ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) { + return true; + } + + if ($definition->isPublic()) { + return false; + } + + if (!$this->graph->hasNode($id)) { + return true; + } + + $ids = array(); + foreach ($this->graph->getNode($id)->getInEdges() as $edge) { + $ids[] = $edge->getSourceNode()->getId(); + } + + if (count(array_unique($ids)) > 1) { + return false; + } + + return $container->getDefinition(reset($ids))->getScope() === $definition->getScope(); + } +}