slight compiler refactoring (RFC)
This commit is contained in:
parent
5e94807668
commit
a2105d44aa
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface that must be implemented by compilation passes
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
interface CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* You can modify the container here before it is dumped to PHP code.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
* @return void
|
||||
*/
|
||||
function process(ContainerBuilder $container);
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Merges extension configs into the container builder
|
||||
*
|
||||
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*/
|
||||
class MergeExtensionConfigurationPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$parameters = $container->getParameterBag()->all();
|
||||
$definitions = $container->getDefinitions();
|
||||
$aliases = $container->getAliases();
|
||||
|
||||
foreach ($container->getExtensionConfigs() as $name => $configs) {
|
||||
list($namespace, $tag) = explode(':', $name);
|
||||
|
||||
$extension = $container->getExtension($namespace);
|
||||
|
||||
$tmpContainer = new ContainerBuilder($container->getParameterBag());
|
||||
$tmpContainer->addObjectResource($extension);
|
||||
foreach ($configs as $config) {
|
||||
$extension->load($tag, $config, $tmpContainer);
|
||||
}
|
||||
|
||||
$container->merge($tmpContainer);
|
||||
}
|
||||
|
||||
$container->setExtensionConfigs(array());
|
||||
$container->addDefinitions($definitions);
|
||||
$container->addAliases($aliases);
|
||||
$container->getParameterBag()->add($parameters);
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Resolves interface injectors and inlines them as method calls
|
||||
*
|
||||
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*/
|
||||
class ResolveInterfaceInjectorsPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
foreach ($container->getDefinitions() as $definition) {
|
||||
foreach ($container->getInterfaceInjectors() as $injector) {
|
||||
if (null !== $definition->getFactoryService()) {
|
||||
continue;
|
||||
}
|
||||
$defClass = $container->getParameterBag()->resolveValue($definition->getClass());
|
||||
$definition->setClass($defClass);
|
||||
if ($injector->supports($defClass)) {
|
||||
$injector->processDefinition($definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,10 +2,14 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\ResolveInterfaceInjectorsPass;
|
||||
use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
|
||||
use Symfony\Component\DependencyInjection\Resource\ResourceInterface;
|
||||
use Symfony\Component\DependencyInjection\Resource\FileResource;
|
||||
use Symfony\Component\DependencyInjection\InterfaceInjector;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\DependencyInjection\Resource\FileResource;
|
||||
use Symfony\Component\DependencyInjection\Resource\ResourceInterface;
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
@ -31,6 +35,21 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
protected $resources = array();
|
||||
protected $extensionConfigs = array();
|
||||
protected $injectors = array();
|
||||
protected $compilerPasses;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param ParameterBagInterface $parameterBag
|
||||
*/
|
||||
public function __construct(ParameterBagInterface $parameterBag = null)
|
||||
{
|
||||
parent::__construct($parameterBag);
|
||||
|
||||
$passes = array();
|
||||
$passes[] = new MergeExtensionConfigurationPass();
|
||||
$passes[] = new ResolveInterfaceInjectorsPass();
|
||||
$this->compilerPasses = $passes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an extension.
|
||||
@ -127,6 +146,38 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a compiler pass at the end of the current passes
|
||||
*
|
||||
* @param CompilerPassInterface $pass
|
||||
* @return void
|
||||
*/
|
||||
public function addCompilerPass(CompilerPassInterface $pass)
|
||||
{
|
||||
$this->compilerPasses[] = $pass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered compiler passes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getCompilerPasses()
|
||||
{
|
||||
return $this->compilerPasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites all existing passes
|
||||
*
|
||||
* @param array $passes
|
||||
* @return void
|
||||
*/
|
||||
public function setCompilerPasses(array $passes)
|
||||
{
|
||||
$this->compilerPasses = $passes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a service.
|
||||
*
|
||||
@ -267,6 +318,17 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
return $this->extensionConfigs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the extension configs array
|
||||
*
|
||||
* @param array $config
|
||||
* @return void
|
||||
*/
|
||||
public function setExtensionConfigs(array $config)
|
||||
{
|
||||
$this->extensionConfigs = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Freezes the container.
|
||||
*
|
||||
@ -279,40 +341,8 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
*/
|
||||
public function freeze()
|
||||
{
|
||||
$parameters = $this->parameterBag->all();
|
||||
$definitions = $this->definitions;
|
||||
$aliases = $this->aliases;
|
||||
|
||||
foreach ($this->extensionConfigs as $name => $configs) {
|
||||
list($namespace, $tag) = explode(':', $name);
|
||||
|
||||
$extension = $this->getExtension($namespace);
|
||||
|
||||
$container = new self($this->parameterBag);
|
||||
$container->addObjectResource($extension);
|
||||
foreach ($configs as $config) {
|
||||
$extension->load($tag, $config, $container);
|
||||
}
|
||||
|
||||
$this->merge($container);
|
||||
}
|
||||
|
||||
$this->extensionConfigs = array();
|
||||
$this->addDefinitions($definitions);
|
||||
$this->addAliases($aliases);
|
||||
$this->parameterBag->add($parameters);
|
||||
|
||||
foreach ($this->definitions as $definition) {
|
||||
foreach ($this->injectors as $injector) {
|
||||
if (null !== $definition->getFactoryService()) {
|
||||
continue;
|
||||
}
|
||||
$defClass = $this->parameterBag->resolveValue($definition->getClass());
|
||||
$definition->setClass($defClass);
|
||||
if ($injector->supports($defClass)) {
|
||||
$injector->processDefinition($definition);
|
||||
}
|
||||
}
|
||||
foreach ($this->compilerPasses as $pass) {
|
||||
$pass->process($this);
|
||||
}
|
||||
|
||||
parent::freeze();
|
||||
|
@ -16,7 +16,7 @@ use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
/**
|
||||
* InterfaceInjector is used for Interface Injection.
|
||||
*
|
||||
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
|
||||
*/
|
||||
class InterfaceInjector
|
||||
{
|
||||
|
Reference in New Issue
Block a user