diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php
index a0581ff21fb6f..d7db6ebf050a4 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/AddAnnotationsCachedReaderPass.php
@@ -29,7 +29,6 @@ public function process(ContainerBuilder $container)
// "annotation_reader" at build time don't get any cache
foreach ($container->findTaggedServiceIds('annotations.cached_reader') as $id => $tags) {
$reader = $container->getDefinition($id);
- $reader->setPublic(false);
$properties = $reader->getProperties();
if (isset($properties['cacheProviderBackup'])) {
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php
index 888a5ea8d64c1..669d331c062f3 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/UnusedTagsPass.php
@@ -28,6 +28,7 @@ class UnusedTagsPass implements CompilerPassInterface
'cache.pool.clearer',
'config_cache.resource_checker',
'console.command',
+ 'container.do_not_inline',
'container.env_var_loader',
'container.env_var_processor',
'container.hot_path',
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index 6f55ad6c38f39..ca338fc2054db 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -469,6 +469,8 @@ public function load(array $configs, ContainerBuilder $container)
->addTag('routing.route_loader');
$container->setParameter('container.behavior_describing_tags', [
+ 'annotations.cached_reader',
+ 'container.do_not_inline',
'container.service_locator',
'container.service_subscriber',
'kernel.event_subscriber',
@@ -1463,11 +1465,9 @@ private function registerAnnotationsConfiguration(array $config, ContainerBuilde
$container
->getDefinition('annotations.cached_reader')
- ->setPublic(true) // set to false in AddAnnotationsCachedReaderPass
->replaceArgument(2, $config['debug'])
// reference the cache provider without using it until AddAnnotationsCachedReaderPass runs
->addArgument(new ServiceClosureArgument(new Reference($cacheService)))
- ->addTag('annotations.cached_reader')
;
$container->setAlias('annotation_reader', 'annotations.cached_reader')->setPrivate(true);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.xml
index 4420dfbf00db1..1fb375ea3c472 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/annotations.xml
@@ -31,6 +31,8 @@
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
index b66d0837c3a37..c2c7bc6b851cc 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
@@ -1699,6 +1699,8 @@ public function testRegisterParameterCollectingBehaviorDescribingTags()
$this->assertTrue($container->hasParameter('container.behavior_describing_tags'));
$this->assertEquals([
+ 'annotations.cached_reader',
+ 'container.do_not_inline',
'container.service_locator',
'container.service_subscriber',
'kernel.event_subscriber',
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php
index af7c957a308a2..3b8086d0931e6 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/DecoratorServicePass.php
@@ -40,6 +40,10 @@ public function process(ContainerBuilder $container)
}
$decoratingDefinitions = [];
+ $tagsToKeep = $container->hasParameter('container.behavior_describing_tags')
+ ? $container->getParameter('container.behavior_describing_tags')
+ : ['container.do_not_inline', 'container.service_locator', 'container.service_subscriber'];
+
foreach ($definitions as [$id, $definition]) {
$decoratedService = $definition->getDecoratedService();
[$inner, $renamedId] = $decoratedService;
@@ -89,8 +93,8 @@ public function process(ContainerBuilder $container)
$decoratingTags = $decoratingDefinition->getTags();
$resetTags = [];
- // container.service_locator and container.service_subscriber have special logic and they must not be transferred out to decorators
- foreach (['container.service_locator', 'container.service_subscriber'] as $containerTag) {
+ // Behavior-describing tags must not be transferred out to decorators
+ foreach ($tagsToKeep as $containerTag) {
if (isset($decoratingTags[$containerTag])) {
$resetTags[$containerTag] = $decoratingTags[$containerTag];
unset($decoratingTags[$containerTag]);
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php
index 358b750f2a376..7935983ff5c2e 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php
@@ -177,7 +177,7 @@ protected function processValue($value, $isRoot = false)
*/
private function isInlineableDefinition(string $id, Definition $definition): bool
{
- if ($definition->hasErrors() || $definition->isDeprecated() || $definition->isLazy() || $definition->isSynthetic()) {
+ if ($definition->hasErrors() || $definition->isDeprecated() || $definition->isLazy() || $definition->isSynthetic() || $definition->hasTag('container.do_not_inline')) {
return false;
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php
index 4f01d33c4923d..ac4269753525c 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/InlineServiceDefinitionsPassTest.php
@@ -325,6 +325,34 @@ public function testProcessDoesNotSetLazyArgumentValuesAfterInlining()
$this->assertSame('inline', (string) $values[0]);
}
+ public function testDoNotInline()
+ {
+ $container = new ContainerBuilder();
+ $container->register('decorated1', 'decorated1')->addTag('container.do_not_inline');
+ $container->register('decorated2', 'decorated2')->addTag('container.do_not_inline');
+ $container->setAlias('alias2', 'decorated2');
+
+ $container
+ ->register('s1', 's1')
+ ->setDecoratedService('decorated1')
+ ->setPublic(true)
+ ->setProperties(['inner' => new Reference('s1.inner')]);
+
+ $container
+ ->register('s2', 's2')
+ ->setDecoratedService('alias2')
+ ->setPublic(true)
+ ->setProperties(['inner' => new Reference('s2.inner')]);
+
+ $container->compile();
+
+ $this->assertFalse($container->hasAlias('alias2'));
+ $this->assertEquals(new Reference('decorated2'), $container->getDefinition('s2')->getProperties()['inner']);
+ $this->assertEquals(new Reference('s1.inner'), $container->getDefinition('s1')->getProperties()['inner']);
+ $this->assertSame('decorated2', $container->getDefinition('decorated2')->getClass());
+ $this->assertSame('decorated1', $container->getDefinition('s1.inner')->getClass());
+ }
+
protected function process(ContainerBuilder $container)
{
(new InlineServiceDefinitionsPass(new AnalyzeServiceReferencesPass()))->process($container);