Skip to content

Commit 08ea87b

Browse files
committed
bug #54908 [DependencyInjection] Fix "Cannot replace arguments" errors caused by ResolveAutowireInlineAttributesPass (nicolas-grekas)
This PR was merged into the 7.1 branch. Discussion ---------- [DependencyInjection] Fix "Cannot replace arguments" errors caused by ResolveAutowireInlineAttributesPass | Q | A | ------------- | --- | Branch? | 7.1 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | Fix #54823 | License | MIT Commits ------- 3b18228 [DependencyInjection] Fix "Cannot replace arguments" errors caused by ResolveAutowireInlineAttributesPass
2 parents 5f26022 + 3b18228 commit 08ea87b

File tree

2 files changed

+19
-16
lines changed

2 files changed

+19
-16
lines changed

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

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,13 @@ protected function processValue(mixed $value, bool $isRoot = false): mixed
5252
}
5353
}
5454

55-
$dummy = $value;
56-
while (null === $dummy->getClass() && $dummy instanceof ChildDefinition) {
57-
$dummy = $this->container->findDefinition($dummy->getParent());
58-
}
59-
6055
$methodCalls = $value->getMethodCalls();
6156

6257
foreach ($methodCalls as $i => $call) {
6358
[$method, $arguments] = $call;
6459

6560
try {
66-
$method = $this->getReflectionMethod($dummy, $method);
61+
$method = $this->getReflectionMethod($value, $method);
6762
} catch (RuntimeException) {
6863
continue;
6964
}
@@ -89,19 +84,14 @@ private function registerAutowireInlineAttributes(\ReflectionFunctionAbstract $m
8984
if ($method->isVariadic()) {
9085
array_pop($parameters);
9186
}
92-
$dummyContainer = new ContainerBuilder($this->container->getParameterBag());
87+
$paramResolverContainer = new ContainerBuilder($this->container->getParameterBag());
9388

9489
foreach ($parameters as $index => $parameter) {
9590
if ($isChildDefinition) {
9691
$index = 'index_'.$index;
9792
}
9893

99-
$name = '$'.$parameter->name;
100-
if (\array_key_exists($name, $arguments)) {
101-
$arguments[$index] = $arguments[$name];
102-
unset($arguments[$name]);
103-
}
104-
if (\array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
94+
if (\array_key_exists('$'.$parameter->name, $arguments) || (\array_key_exists($index, $arguments) && '' !== $arguments[$index])) {
10595
continue;
10696
}
10797
if (!$attribute = $parameter->getAttributes(AutowireInline::class, \ReflectionAttribute::IS_INSTANCEOF)[0] ?? null) {
@@ -117,13 +107,13 @@ private function registerAutowireInlineAttributes(\ReflectionFunctionAbstract $m
117107
$attribute = $attribute->newInstance();
118108
$definition = $attribute->buildDefinition($attribute->value, $type, $parameter);
119109

120-
$dummyContainer->setDefinition('.autowire_inline', $definition);
121-
(new ResolveParameterPlaceHoldersPass(false, false))->process($dummyContainer);
110+
$paramResolverContainer->setDefinition('.autowire_inline', $definition);
111+
(new ResolveParameterPlaceHoldersPass(false, false))->process($paramResolverContainer);
122112

123113
$id = '.autowire_inline.'.ContainerBuilder::hash([$this->currentId, $method->class ?? null, $method->name, (string) $parameter]);
124114

125115
$this->container->setDefinition($id, $definition);
126-
$arguments[$index] = new Reference($id);
116+
$arguments[$isChildDefinition ? '$'.$parameter->name : $index] = new Reference($id);
127117

128118
if ($definition->isAutowired()) {
129119
$currentId = $this->currentId;

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\DependencyInjection\ChildDefinition;
1516
use Symfony\Component\DependencyInjection\Compiler\AutowirePass;
1617
use Symfony\Component\DependencyInjection\Compiler\ResolveAutowireInlineAttributesPass;
1718
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
@@ -53,4 +54,16 @@ public function testAttribute()
5354
self::assertInstanceOf(AutowireInlineAttributes2::class, $a->inlined);
5455
self::assertSame(345, $a->inlined->bar);
5556
}
57+
58+
public function testChildDefinition()
59+
{
60+
$container = new ContainerBuilder();
61+
62+
$container->setDefinition('autowire_inline1', (new ChildDefinition('parent'))->setClass(AutowireInlineAttributes1::class))
63+
->setAutowired(true);
64+
65+
(new ResolveAutowireInlineAttributesPass())->process($container);
66+
67+
$this->assertSame(['$inlined'], array_keys($container->getDefinition('autowire_inline1')->getArguments()));
68+
}
5669
}

0 commit comments

Comments
 (0)