8000 [DependencyInjection] Use AttributeAutoconfigurationPass for #40406 · okhoshi/symfony@ff5dfc5 · GitHub
[go: up one dir, main page]

Skip to content

Commit ff5dfc5

Browse files
committed
[DependencyInjection] Use AttributeAutoconfigurationPass for symfony#40406
1 parent 5aa773c commit ff5dfc5

File tree

4 files changed

+68
-12
lines changed

4 files changed

+68
-12
lines changed

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

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

1212
namespace Symfony\Component\DependencyInjection\Compiler;
1313

14+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
15+
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
16+
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
17+
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
1418
use Symfony\Component\DependencyInjection\ChildDefinition;
1519
use Symfony\Component\DependencyInjection\ContainerBuilder;
1620
use Symfony\Component\DependencyInjection\Definition;
@@ -20,36 +24,84 @@
2024
*/
2125
final class AttributeAutoconfigurationPass extends AbstractRecursivePass
2226
{
27+
private $classAttributeConfigurators = [];
28+
private $parameterAttributeConfigurators = [];
29+
2330
public function process(ContainerBuilder $container): void
2431
{
25-
if (80000 > \PHP_VERSION_ID || !$container->getAutoconfiguredAttributes()) {
32+
if (80000 > \PHP_VERSION_ID) {
2633
return;
2734
}
2835

36+
$this->classAttributeConfigurators = $container->getAutoconfiguredAttributes();
37+
2938
parent::process($container);
3039
}
3140

3241
protected function processValue($value, bool $isRoot = false)
3342
{
3443
if (!$value instanceof Definition
35-
|| !$value->isAutoconfigured()
3644
|| $value->isAbstract()
3745
|| $value->hasTag('container.ignore_attributes')
38-
|| !($reflector = $this->container->getReflectionClass($value->getClass(), false))
46+
|| !($classReflector = $this->container->getReflectionClass($value->getClass(), false))
3947
) {
4048
return parent::processValue($value, $isRoot);
4149
}
4250

43-
$autoconfiguredAttributes = $this->container->getAutoconfiguredAttributes();
51+
$classAttributeConfigurators = $value->isAutoconfigured() ? $this->classAttributeConfigurators : [];
52+
$parameterAttributeConfigurators = array_merge(
53+
$value->isAutoconfigured() ? $this->parameterAttributeConfigurators : [],
54+
[
55+
TaggedIterator::class => static function (ChildDefinition $definition, TaggedIterator $attribute, \ReflectionParameter $reflector) {
56+
$definition->setArgument($reflector->getPosition(), new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, null, false));
57+
},
58+
TaggedLocator::class => static function (ChildDefinition $definition, TaggedLocator $attribute, \ReflectionParameter $reflector) {
59+
$definition->setArgument($reflector->getPosition(), new ServiceLocatorArgument(new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, null, true)));
60+
},
61+
]
62+
);
63+
4464
$instanceof = $value->getInstanceofConditionals();
45-
$conditionals = $instanceof[$reflector->getName()] ?? new ChildDefinition('');
46-
foreach ($reflector->getAttributes() as $attribute) {
47-
if ($configurator = $autoconfiguredAttributes[$attribute->getName()] ?? null) {
48-
$configurator($conditionals, $attribute->newInstance(), $reflector);
65+
$conditionals = $instanceof[$classReflector->getName()] ?? new ChildDefinition('');
66+
67+
if ($classAttributeConfigurators) {
68+
foreach ($classReflector->getAttributes() as $attribute) {
69+
if ($configurator = $classAttributeConfigurators[$attribute->getName()] ?? null) {
70+
$configurator($conditionals, $attribute->newInstance(), $classReflector);
71+
}
72+
}
73+
}
74+
75+
if ($parameterAttributeConfigurators && $constructorReflector = $this->getConstructor($value, false)) {
76+
foreach ($constructorReflector->getParameters() as $parameterReflector) {
77+
foreach ($parameterReflector->getAttributes() as $attribute) {
78+
if ($configurator = $parameterAttributeConfigurators[$attribute->getName()] ?? null) {
79+
$configurator($conditionals, $attribute->newInstance(), $parameterReflector);
80+
}
81+
}
82+
}
83+
}
84+
85+
if ($parameterAttributeConfigurators) {
86+
foreach ($classReflector->getMethods(\ReflectionMethod::IS_PUBLIC) as $methodReflector) {
87+
if ($methodReflector->isStatic() || $methodReflector->isConstructor() || $methodReflector->isDestructor()) {
88+
continue;
89+
}
90+
91+
if ($parameterAttributeConfigurators) {
92+
foreach ($methodReflector->getParameters() as $parameterReflector) {
93+
foreach ($parameterReflector->getAttributes() as $attribute) {
94+
if ($configurator = $parameterAttributeConfigurators[$attribute->getName()] ?? null) {
95+
$configurator($conditionals, $attribute->newInstance(), $parameterReflector);
96+
}
97+
}
98+
}
99+
}
49100
}
50101
}
51-
if (!isset($instanceof[$reflector->getName()]) && new ChildDefinition('') != $conditionals) {
52-
$instanceof[$reflector->getName()] = $conditionals;
102+
103+
if (!isset($instanceof[$classReflector->getName()]) && new ChildDefinition('') != $conditionals) {
104+
$instanceof[$classReflector->getName()] = $conditionals;
53105
$value->setInstanceofConditionals($instanceof);
54106
}
55107

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ public function process(ContainerBuilder $container)
5252

5353
private function processDefinition(ContainerBuilder $container, string $id, Definition $definition, array $tagsToKeep): Definition
5454
{
55+
foreach ($definition->getArguments() as $key => $argument) {
56+
if ($argument instanceof Definition) {
57+
$definition->setArgument($key, $this->processDefinition($container, $argument->getClass() ?? $id.'.'.$key, $argument, $tagsToKeep));
58+
}
59+
}
60+
5561
$instanceofConditionals = $definition->getInstanceofConditionals();
5662
$autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : [];
5763
if (!$instanceofConditionals && !$autoconfiguredInstanceof) {

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public function getRemovedIds(): array
4646
return [
4747
'.service_locator.DlIAmAe' => true,
4848
'.service_locator.DlIAmAe.foo_service' => true,
49-
'.service_locator.t5IGRMW' => true,
5049
'Psr\\Container\\ContainerInterface' => true,
5150
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
5251
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true,

src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_subscriber_php81.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public function getRemovedIds(): array
4646
return [
4747
'.service_locator.JmEob1b' => true,
4848
'.service_locator.JmEob1b.foo_service' => true,
49-
'.service_locator.KIgkoLM' => true,
5049
'Psr\\Container\\ContainerInterface' => true,
5150
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
5251
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => true,

0 commit comments

Comments
 (0)
0