Skip to content

Commit

Permalink
[DI][DX] Throw exception on some ContainerBuilder methods used from e…
Browse files Browse the repository at this point in the history
…xtensions
  • Loading branch information
ogizanagi committed Sep 24, 2017
1 parent 2e0cb60 commit 88549ff
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
Expand Up @@ -12,10 +12,13 @@
namespace Symfony\Component\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;

/**
* Merges extension configs into the container builder.
Expand Down Expand Up @@ -52,7 +55,7 @@ public function process(ContainerBuilder $container)
}
$config = $resolvingBag->resolveValue($config);

$tmpContainer = new ContainerBuilder($resolvingBag);
$tmpContainer = new MergeExtensionConfigurationContainerBuilder($extension, $resolvingBag);
$tmpContainer->setResourceTracking($container->isTrackingResources());
$tmpContainer->addObjectResource($extension);
if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) {
Expand Down Expand Up @@ -121,3 +124,44 @@ public function getEnvPlaceholders()
return null !== $this->processedEnvPlaceholders ? $this->processedEnvPlaceholders : parent::getEnvPlaceholders();
}
}

/**
* A container builder preventing using methods that wouldn't have any effect from extensions.
*
* @internal
*/
class MergeExtensionConfigurationContainerBuilder extends ContainerBuilder
{
private $extensionClass;

public function __construct(ExtensionInterface $extension, ParameterBagInterface $parameterBag = null)
{
parent::__construct($parameterBag);

$this->extensionClass = get_class($extension);
}

/**
* {@inheritdoc}
*/
public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/)
{
throw new LogicException(sprintf('You cannot add compiler pass "%s" from extension "%s". Compiler passes must be registered before the container is compiled.', get_class($pass), $this->extensionClass));
}

/**
* {@inheritdoc}
*/
public function registerExtension(ExtensionInterface $extension)
{
throw new LogicException(sprintf('You cannot register extension "%s" from "%s". Extensions must be registered before the container is compiled.', get_class($extension), $this->extensionClass));
}

/**
* {@inheritdoc}
*/
public function compile($resolveEnvPlaceholders = false)
{
throw new LogicException(sprintf('Cannot compile the container in extension "%s".', $this->extensionClass));
}
}
Expand Up @@ -16,6 +16,7 @@
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationPass;
use Symfony\Component\DependencyInjection\Compiler\MergeExtensionConfigurationContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
Expand Down Expand Up @@ -54,6 +55,22 @@ public function testExpressionLanguageProviderForwarding()
$this->assertEquals(array($provider), $tmpProviders);
}

public function testExtensionLoadGetAMergeExtensionConfigurationContainerBuilderInstance()
{
$extension = $this->getMockBuilder(FooExtension::class)->setMethods(array('load'))->getMock();
$extension->expects($this->once())
->method('load')
->with($this->isType('array'), $this->isInstanceOf(MergeExtensionConfigurationContainerBuilder::class))
;

$container = new ContainerBuilder(new ParameterBag());
$container->registerExtension($extension);
$container->prependExtensionConfig('foo', array());

$pass = new MergeExtensionConfigurationPass();
$pass->process($container);
}

public function testExtensionConfigurationIsTrackedByDefault()
{
$extension = $this->getMockBuilder(FooExtension::class)->setMethods(array('getConfiguration'))->getMock();
Expand Down

0 comments on commit 88549ff

Please sign in to comment.