bug #26086 [FrameworkBundle] Fix using annotation_reader in compiler pass to inject configured cache provider

This commit is contained in:
Dmitri Petmanson 2018-02-08 11:42:56 +02:00 committed by Nicolas Grekas
parent 39e88ed312
commit dfd93da236
4 changed files with 32 additions and 9 deletions

View File

@ -26,16 +26,16 @@ class AddAnnotationsCachedReaderPass implements CompilerPassInterface
{ {
// "annotations.cached_reader" is wired late so that any passes using // "annotations.cached_reader" is wired late so that any passes using
// "annotation_reader" at build time don't get any cache // "annotation_reader" at build time don't get any cache
if ($container->hasDefinition('annotations.cached_reader')) { foreach ($container->findTaggedServiceIds('annotations.cached_reader') as $id => $tags) {
$reader = $container->getDefinition('annotations.cached_reader'); $reader = $container->getDefinition($id);
$properties = $reader->getProperties(); $properties = $reader->getProperties();
if (isset($properties['cacheProviderBackup'])) { if (isset($properties['cacheProviderBackup'])) {
$provider = $properties['cacheProviderBackup']->getValues()[0]; $provider = $properties['cacheProviderBackup']->getValues()[0];
unset($properties['cacheProviderBackup']); unset($properties['cacheProviderBackup']);
$reader->setProperties($properties); $reader->setProperties($properties);
$container->set('annotations.cached_reader', null); $container->set($id, null);
$container->setDefinition('annotations.cached_reader', $reader->replaceArgument(1, $provider)); $container->setDefinition($id, $reader->replaceArgument(1, $provider));
} }
} }
} }

View File

@ -22,6 +22,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
class UnusedTagsPass implements CompilerPassInterface class UnusedTagsPass implements CompilerPassInterface
{ {
private $whitelist = array( private $whitelist = array(
'annotations.cached_reader',
'cache.pool.clearer', 'cache.pool.clearer',
'console.command', 'console.command',
'container.hot_path', 'container.hot_path',

View File

@ -1395,7 +1395,9 @@ class FrameworkExtension extends Extension
->replaceArgument(2, $config['debug']) ->replaceArgument(2, $config['debug'])
// temporary property to lazy-reference the cache provider without using it until AddAnnotationsCachedReaderPass runs // temporary property to lazy-reference the cache provider without using it until AddAnnotationsCachedReaderPass runs
->setProperty('cacheProviderBackup', new ServiceClosureArgument(new Reference($cacheService))) ->setProperty('cacheProviderBackup', new ServiceClosureArgument(new Reference($cacheService)))
->addTag('annotations.cached_reader')
; ;
$container->setAlias('annotation_reader', 'annotations.cached_reader')->setPrivate(true); $container->setAlias('annotation_reader', 'annotations.cached_reader')->setPrivate(true);
$container->setAlias(Reader::class, new Alias('annotations.cached_reader', false)); $container->setAlias(Reader::class, new Alias('annotations.cached_reader', false));
} else { } else {

View File

@ -25,6 +25,7 @@ use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\ProxyAdapter; use Symfony\Component\Cache\Adapter\ProxyAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter; use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\DependencyInjection\ChildDefinition; use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Loader\ClosureLoader; use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
@ -589,10 +590,12 @@ abstract class FrameworkExtensionTest extends TestCase
public function testAnnotations() public function testAnnotations()
{ {
$container = $this->createContainerFromFile('full'); $container = $this->createContainerFromFile('full', array(), true, false);
$container->addCompilerPass(new TestAnnotationsPass());
$container->compile();
$this->assertEquals($container->getParameter('kernel.cache_dir').'/annotations', $container->getDefinition('annotations.filesystem_cache')->getArgument(0)); $this->assertEquals($container->getParameter('kernel.cache_dir').'/annotations', $container->getDefinition('annotations.filesystem_cache')->getArgument(0));
$this->assertSame('annotations.filesystem_cache', (string) $container->getDefinition('annotations.cached_reader')->getArgument(1)); $this->assertSame('annotations.filesystem_cache', (string) $container->getDefinition('annotation_reader')->getArgument(1));
} }
public function testFileLinkFormat() public function testFileLinkFormat()
@ -1051,10 +1054,10 @@ abstract class FrameworkExtensionTest extends TestCase
), $data))); ), $data)));
} }
protected function createContainerFromFile($file, $data = array(), $resetCompilerPasses = true) protected function createContainerFromFile($file, $data = array(), $resetCompilerPasses = true, $compile = true)
{ {
$cacheKey = md5(get_class($this).$file.serialize($data)); $cacheKey = md5(get_class($this).$file.serialize($data));
if (isset(self::$containerCache[$cacheKey])) { if ($compile && isset(self::$containerCache[$cacheKey])) {
return self::$containerCache[$cacheKey]; return self::$containerCache[$cacheKey];
} }
$container = $this->createContainer($data); $container = $this->createContainer($data);
@ -1065,7 +1068,12 @@ abstract class FrameworkExtensionTest extends TestCase
$container->getCompilerPassConfig()->setOptimizationPasses(array()); $container->getCompilerPassConfig()->setOptimizationPasses(array());
$container->getCompilerPassConfig()->setRemovingPasses(array()); $container->getCompilerPassConfig()->setRemovingPasses(array());
} }
$container->getCompilerPassConfig()->setBeforeRemovingPasses(array(new AddAnnotationsCachedReaderPass(), new AddConstraintValidatorsPass(), new TranslatorPass('translator.default', 'translation.reader'))); $container->getCompilerPassConfig()->setBeforeRemovingPasses(array(new AddConstraintValidatorsPass(), new TranslatorPass('translator.default', 'translation.reader')));
$container->getCompilerPassConfig()->setAfterRemovingPasses(array(new AddAnnotationsCachedReaderPass()));
if (!$compile) {
return $container;
}
$container->compile(); $container->compile();
return self::$containerCache[$cacheKey] = $container; return self::$containerCache[$cacheKey] = $container;
@ -1158,3 +1166,15 @@ abstract class FrameworkExtensionTest extends TestCase
} }
} }
} }
/**
* Simulates ReplaceAliasByActualDefinitionPass.
*/
class TestAnnotationsPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$container->setDefinition('annotation_reader', $container->getDefinition('annotations.cached_reader'));
$container->removeDefinition('annotations.cached_reader');
}
}