Skip to content

Commit c4600c5

Browse files
[DependencyInjection] Fix parsing nested AutowireInline attributes
1 parent 2c31863 commit c4600c5

File tree

3 files changed

+48
-12
lines changed

3 files changed

+48
-12
lines changed

Compiler/ResolveAutowireInlineAttributesPass.php

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class ResolveAutowireInlineAttributesPass extends AbstractRecursivePass
2828
{
2929
protected bool $skipScalars = true;
3030

31+
private int $counter;
32+
3133
protected function processValue(mixed $value, bool $isRoot = false): mixed
3234
{
3335
$value = parent::processValue($value, $isRoot);
@@ -36,6 +38,10 @@ protected function processValue(mixed $value, bool $isRoot = false): mixed
3638
return $value;
3739
}
3840

41+
if ($isRoot) {
42+
$this->counter = 0;
43+
}
44+
3945
$isChildDefinition = $value instanceof ChildDefinition;
4046

4147
try {
@@ -92,10 +98,14 @@ private function registerAutowireInlineAttributes(\ReflectionFunctionAbstract $m
9298
}
9399

94100
if (\array_key_exists('$'.$parameter->name, $arguments) || (\array_key_exists($index, $arguments) && '' !== $arguments[$index])) {
101+
$attribute = \array_key_exists('$'.$parameter->name, $arguments) ? $arguments['$'.$parameter->name] : $arguments[$index];
102+
if (!$attribute instanceof AutowireInline) {
103+
continue;
104+
}
105+
} elseif (!$attribute = $parameter->getAttributes(AutowireInline::class, \ReflectionAttribute::IS_INSTANCEOF)[0] ?? null) {
95106
continue;
96-
}
97-
if (!$attribute = $parameter->getAttributes(AutowireInline::class, \ReflectionAttribute::IS_INSTANCEOF)[0] ?? null) {
98-
continue;
107+
} else {
108+
$attribute = $attribute->newInstance();
99109
}
100110

101111
$type = ProxyHelper::exportType($parameter, true);
@@ -104,25 +114,18 @@ private function registerAutowireInlineAttributes(\ReflectionFunctionAbstract $m
104114
continue;
105115
}
106116

107-
$attribute = $attribute->newInstance();
108117
$definition = $attribute->buildDefinition($attribute->value, $type, $parameter);
109118

110119
$paramResolverContainer->setDefinition('.autowire_inline', $definition);
111120
(new ResolveParameterPlaceHoldersPass(false, false))->process($paramResolverContainer);
112121

113-
$id = '.autowire_inline.'.ContainerBuilder::hash([$this->currentId, $method->class ?? null, $method->name, (string) $parameter]);
122+
$id = '.autowire_inline.'.$this->currentId.'.'.++$this->counter;
114123

115124
$this->container->setDefinition($id, $definition);
116125
$arguments[$isChildDefinition ? '$'.$parameter->name : $index] = new Reference($id);
117126

118127
if ($definition->isAutowired()) {
119-
$currentId = $this->currentId;
120-
try {
121-
$this->currentId = $id;
122-
$this->processValue($definition, true);
123-
} finally {
124-
$this->currentId = $currentId;
125-
}
128+
$this->processValue($definition);
126129
}
127130
}
128131

Tests/Compiler/ResolveAutowireInlineAttributesPassTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
1919
use Symfony\Component\DependencyInjection\Compiler\ResolveNamedArgumentsPass;
2020
use Symfony\Component\DependencyInjection\ContainerBuilder;
21+
use Symfony\Component\DependencyInjection\Definition;
22+
use Symfony\Component\DependencyInjection\Reference;
2123

2224
require_once __DIR__.'/../Fixtures/includes/autowiring_classes.php';
2325

@@ -66,4 +68,20 @@ public function testChildDefinition()
6668

6769
$this->assertSame(['$inlined'], array_keys($container->getDefinition('autowire_inline1')->getArguments()));
6870
}
71+
72+
public function testNestedAttribute()
73+
{
74+
$container = new ContainerBuilder();
75+
76+
$container->register('nested_autowire_inline', NestedAutowireInlineAttribute::class)
77+
->setAutowired(true);
78+
79+
(new ResolveAutowireInlineAttributesPass())->process($container);
80+
81+
$this->assertEquals([new Reference('.autowire_inline.nested_autowire_inline.1')], $container->getDefinition('nested_autowire_inline')->getArguments());
82+
$this->assertSame(AutowireInlineAttributesBar::class, $container->getDefinition('.autowire_inline.nested_autowire_inline.1')->getClass());
83+
84+
$this->assertEquals([new Reference('.autowire_inline.nested_autowire_inline.2'), 'testString'], $container->getDefinition('.autowire_inline.nested_autowire_inline.1')->getArguments());
85+
$this->assertSame(Foo::class, $container->getDefinition('.autowire_inline.nested_autowire_inline.2')->getClass());
86+
}
6987
}

Tests/Fixtures/includes/autowiring_classes_80.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,18 @@ public function __construct(
198198
) {
199199
}
200200
}
201+
202+
class NestedAutowireInlineAttribute
203+
{
204+
public function __construct(
205+
#[AutowireInline(
206+
AutowireInlineAttributesBar::class,
207+
arguments: [
208+
new AutowireInline(Foo::class),
209+
'testString',
210+
],
211+
)]
212+
public AutowireInlineAttributesBar $inlined,
213+
) {
214+
}
215+
}

0 commit comments

Comments
 (0)