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

Skip to content

Commit 1a7afbf

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

File tree

4 files changed

+73
-12
lines changed

4 files changed

+73
-12
lines changed

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

Lines changed: 67 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,89 @@
2024
*/
2125
final class AttributeAutoconfigurationPass extends AbstractRecursivePass
2226
{
27+
private $classAttributeConfigurators = [];
28+
private $parameterAttributeConfigurators = [];
29+
30+
private $parameterAttributeAutowirings = [];
31+
2332
public function process(ContainerBuilder $container): void
2433
{
25-
if (80000 > \PHP_VERSION_ID || !$container->getAutoconfiguredAttributes()) {
34+
if (80000 > \PHP_VERSION_ID) {
2635
return;
2736
}
2837

38+
$this->classAttributeConfigurators = $container->getAutoconfiguredAttributes();
39+
40+
$this->parameterAttributeAutowirings = [
41+
TaggedIterator::class => static function (ChildDefinition $definition, TaggedIterator $attribute, \ReflectionParameter $reflector) {
42+
$definition->setArgument($reflector->getPosition(), new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, null, false));
43+
},
44+
TaggedLocator::class => static function (ChildDefinition $definition, TaggedLocator $attribute, \ReflectionParameter $reflector) {
45 10000 +
$definition->setArgument($reflector->getPosition(), new ServiceLocatorArgument(new TaggedIteratorArgument($attribute->tag, $attribute->indexAttribute, null, true)));
46+
},
47+
];
48+
2949
parent::process($container);
3050
}
3151

3252
protected function processValue($value, bool $isRoot = false)
3353
{
3454
if (!$value instanceof Definition
35-
|| !$value->isAutoconfigured()
55+
|| !($value->isAutowired() || $value->isAutoconfigured())
3656
|| $value->isAbstract()
3757
|| $value->hasTag('container.ignore_attributes')
38-
|| !($reflector = $this->container->getReflectionClass($value->getClass(), false))
58+
|| !($classReflector = $this->container->getReflectionClass($value->getClass(), false))
3959
) {
4060
return parent::processValue($value, $isRoot);
4161
}
4262

43-
$autoconfiguredAttributes = $this->container->getAutoconfiguredAttributes();
63+
$classAttributeConfigurators = $value->isAutoconfigured() ? $this->classAttributeConfigurators : [];
64+
$parameterAttributeConfigurators = array_merge(
65+
$value->isAutoconfigured() ? $this->parameterAttributeConfigurators : [],
66+
$value->isAutowired() ? $this->parameterAttributeAutowirings : []
67+
);
68+
4469
$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);
70+
$conditionals = $instanceof[$classReflector->getName()] ?? new ChildDefinition('');
71+
72+
if ($classAttributeConfigurators) {
73+
foreach ($classReflector->getAttributes() as $attribute) {
74+
if ($configurator = $classAttributeConfigurators[$attribute->getName()] ?? null) {
75+
$configurator($conditionals, $attribute->newInstance(), $classReflector);
76+
}
77+
}
78+
}
79+
80+
if ($parameterAttributeConfigurators && $constructorReflector = $this->getConstructor($value, false)) {
81+
foreach ($constructorReflector->getParameters() as $parameterReflector) {
82+
foreach ($parameterReflector->getAttributes() as $attribute) {
83+
if ($configurator = $parameterAttributeConfigurators[$attribute->getName()] ?? null) {
84+
$configurator($conditionals, $attribute->newInstance(), $parameterReflector);
85+
}
86+
}
4987
}
5088
}
51-
if (!isset($instanceof[$reflector->getName()]) && new ChildDefinition('') != $conditionals) {
52-
$instanceof[$reflector->getName()] = $conditionals;
89+
90+
if ($parameterAttributeConfigurators) {
91+
foreach ($classReflector->getMethods(\ReflectionMethod::IS_PUBLIC) as $methodReflector) {
92+
if ($methodReflector->isStatic() || $methodReflector->isConstructor() || $methodReflector->isDestructor()) {
93+
continue;
94+
}
95+
96+
if ($parameterAttributeConfigurators) {
97+
foreach ($methodReflector->getParameters() as $parameterReflector) {
98+
foreach ($parameterReflector->getAttributes() as $attribute) {
99+
if ($configurator = $parameterAttributeConfigurators[$attribute->getName()] ?? null) {
100+
$configurator($conditionals, $attribute->newInstance(), $parameterReflector);
101+
}
102+
}
103+
}
104+
}
105+
}
106+
}
107+
108+
if (!isset($instanceof[$classReflector->getName()]) && new ChildDefinition('') != $conditionals) {
109+
$instanceof[$classReflector->getName()] = $conditionals;
53110
$value->setInstanceofConditionals($instanceof);
54111
}
55112

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