Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dc961e2

Browse files
[FrameworkBundle] Fix compiler passes processing a container twice when it's loaded from the debug dump
1 parent 4ae613e commit dc961e2

File tree

6 files changed

+100
-7
lines changed

6 files changed

+100
-7
lines changed

src/Symfony/Bundle/FrameworkBundle/Command/BuildDebugContainerTrait.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Command;
1313

14+
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilderDebugDumpPass;
1415
use Symfony\Component\Config\ConfigCache;
1516
use Symfony\Component\Config\FileLocator;
1617
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
@@ -53,6 +54,11 @@ protected function getContainerBuilder(KernelInterface $kernel): ContainerBuilde
5354
(new XmlFileLoader($container = new ContainerBuilder(), new FileLocator()))->load($kernel->getContainer()->getParameter('debug.container.dump'));
5455
$locatorPass = new ServiceLocatorTagPass();
5556
$locatorPass->process($container);
57+
58+
$container->getCompilerPassConfig()->removePassesBeforeAndIncluding(
59+
ContainerBuilderDebugDumpPass::TYPE,
60+
ContainerBuilderDebugDumpPass::PRIORITY
61+
);
5662
}
5763

5864
return $this->containerBuilder = $container;

src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Command;
1313

14+
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ContainerBuilderDebugDumpPass;
1415
use Symfony\Component\Config\ConfigCache;
1516
use Symfony\Component\Config\FileLocator;
1617
use Symfony\Component\Console\Command\Command;
@@ -118,6 +119,11 @@ private function getContainerBuilder(): ContainerBuilder
118119
$skippedIds[$serviceId] = true;
119120
}
120121
}
122+
123+
$container->getCompilerPassConfig()->removePassesBeforeAndIncluding(
124+
ContainerBuilderDebugDumpPass::TYPE,
125+
ContainerBuilderDebugDumpPass::PRIORITY
126+
);
121127
}
122128

123129
$container->setParameter('container.build_hash', 'lint_container');

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/ContainerBuilderDebugDumpPass.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Config\ConfigCache;
1515
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16+
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
1617
use Symfony\Component\DependencyInjection\ContainerBuilder;
1718
use Symfony\Component\DependencyInjection\Dumper\XmlDumper;
1819

@@ -25,6 +26,9 @@
2526
*/
2627
class ContainerBuilderDebugDumpPass implements CompilerPassInterface
2728
{
29+
public const TYPE = PassConfig::TYPE_BEFORE_REMOVING;
30+
public const PRIORITY = -255;
31+
2832
public function process(ContainerBuilder $container)
2933
{
3034
$cache = new ConfigCache($container->getParameter('debug.container.dump'), true);

src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,11 @@ public function build(ContainerBuilder $container)
164164
if ($container->getParameter('kernel.debug')) {
165165
$container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 2);
166166
$container->addCompilerPass(new UnusedTagsPass(), PassConfig::TYPE_AFTER_REMOVING);
167-
$container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_BEFORE_REMOVING, -255);
167+
$container->addCompilerPass(
168+
new ContainerBuilderDebugDumpPass(),
169+
ContainerBuilderDebugDumpPass::TYPE,
170+
ContainerBuilderDebugDumpPass::PRIORITY
171+
);
168172
$container->addCompilerPass(new CacheCollectorPass(), PassConfig::TYPE_BEFORE_REMOVING);
169173
}
170174
}

src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,7 @@ public function getPasses()
120120
*/
121121
public function addPass(CompilerPassInterface $pass, string $type = self::TYPE_BEFORE_OPTIMIZATION, int $priority = 0)
122122
{
123-
$property = $type.'Passes';
124-
if (!isset($this->$property)) {
125-
throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type));
126-
}
127-
128-
$passes = &$this->$property;
123+
$passes = &$this->getPropertyFromType($type);
129124

130125
if (!isset($passes[$priority])) {
131126
$passes[$priority] = [];
@@ -248,6 +243,35 @@ public function setRemovingPasses(array $passes)
248243
$this->removingPasses = [$passes];
249244
}
250245

246+
/**
247+
* @param string $targetType self::TYPE_*
248+
*/
249+
public function removePassesBeforeAndIncluding(string $targetType, int $targetPriority): void
250+
{
251+
$types = [
252+
self::TYPE_BEFORE_OPTIMIZATION,
253+
self::TYPE_OPTIMIZE,
254+
self::TYPE_BEFORE_REMOVING,
255+
self::TYPE_REMOVE,
256+
self::TYPE_AFTER_REMOVING,
257+
];
258+
259+
foreach ($types as $type) {
260+
$passesGroup = &$this->getPropertyFromType($type);
261+
foreach (array_keys($passesGroup) as $priority) {
262+
unset($passesGroup[$priority]);
263+
264+
if ($type === $targetType && $priority <= $targetPriority) {
265+
return;
266+
}
267+
}
268+
269+
if ($type === $targetType) {
270+
return;
271+
}
272+
}
273+
}
274+
251275
/**
252276
* Sort passes by priority.
253277
*
@@ -266,4 +290,19 @@ private function sortPasses(array $passes): array
266290
// Flatten the array
267291
return array_merge(...$passes);
268292
}
293+
294+
/**
295+
* @param string $type self::TYPE_*
296+
*
297+
* @return CompilerPassInterface[]
298+
*/
299+
private function &getPropertyFromType(string $type): array
300+
{
301+
$property = $type.'Passes';
302+
if (!isset($this->$property)) {
303+
throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type));
304+
}
305+
306+
return $this->$property;
307+
}
269308
}

src/Symfony/Component/DependencyInjection/Tests/Compiler/PassConfigTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,38 @@ public function testPassOrderingWithoutPasses()
5151
$this->assertEmpty($config->getOptimizationPasses());
5252
$this->assertEmpty($config->getRemovingPasses());
5353
}
54+
55+
public function testRemovePassesBeforeAndIncluding()
56+
{
57+
$config = new PassConfig();
58+
$config->setBeforeOptimizationPasses([]);
59+
$config->setOptimizationPasses([]);
60+
$config->setBeforeRemovingPasses([]);
61+
$config->setRemovingPasses([]);
62+
$config->setAfterRemovingPasses([]);
63+
64+
$pass1 = $this->createMock(CompilerPassInterface::class);
65+
$config->addPass($pass1, PassConfig::TYPE_BEFORE_OPTIMIZATION);
66+
67+
$pass2 = $this->createMock(CompilerPassInterface::class);
68+
$config->addPass($pass2, PassConfig::TYPE_OPTIMIZE);
69+
70+
$pass3 = $this->createMock(CompilerPassInterface::class);
71+
$config->addPass($pass3, PassConfig::TYPE_BEFORE_REMOVING);
72+
73+
$pass4 = $this->createMock(CompilerPassInterface::class);
74+
$config->addPass($pass4, PassConfig::TYPE_AFTER_REMOVING, 100);
75+
76+
$pass5 = $this->createMock(CompilerPassInterface::class);
77+
$config->addPass($pass5, PassConfig::TYPE_AFTER_REMOVING, 0);
78+
79+
$pass6 = $this->createMock(CompilerPassInterface::class);
80+
$config->addPass($pass6, PassConfig::TYPE_AFTER_REMOVING, -100);
81+
82+
$config->removePassesBeforeAndIncluding(PassConfig::TYPE_AFTER_REMOVING, 0);
83+
$passes = $config->getPasses();
84+
85+
$this->assertCount(2, $passes);
86+
$this->assertSame($pass6, $passes[1]);
87+
}
5488
}

0 commit comments

Comments
 (0)