Skip to content

Commit

Permalink
bug #54908 [DependencyInjection] Fix "Cannot replace arguments" error…
Browse files Browse the repository at this point in the history
…s 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
  • Loading branch information
derrabus committed May 13, 2024
2 parents 5f26022 + 3b18228 commit 08ea87b
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,13 @@ protected function processValue(mixed $value, bool $isRoot = false): mixed
}
}

$dummy = $value;
while (null === $dummy->getClass() && $dummy instanceof ChildDefinition) {
$dummy = $this->container->findDefinition($dummy->getParent());
}

$methodCalls = $value->getMethodCalls();

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

try {
$method = $this->getReflectionMethod($dummy, $method);
$method = $this->getReflectionMethod($value, $method);
} catch (RuntimeException) {
continue;
}
Expand All @@ -89,19 +84,14 @@ private function registerAutowireInlineAttributes(\ReflectionFunctionAbstract $m
if ($method->isVariadic()) {
array_pop($parameters);
}
$dummyContainer = new ContainerBuilder($this->container->getParameterBag());
$paramResolverContainer = new ContainerBuilder($this->container->getParameterBag());

foreach ($parameters as $index => $parameter) {
if ($isChildDefinition) {
$index = 'index_'.$index;
}

$name = '$'.$parameter->name;
if (\array_key_exists($name, $arguments)) {
$arguments[$index] = $arguments[$name];
unset($arguments[$name]);
}
if (\array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
if (\array_key_exists('$'.$parameter->name, $arguments) || (\array_key_exists($index, $arguments) && '' !== $arguments[$index])) {
continue;
}
if (!$attribute = $parameter->getAttributes(AutowireInline::class, \ReflectionAttribute::IS_INSTANCEOF)[0] ?? null) {
Expand All @@ -117,13 +107,13 @@ private function registerAutowireInlineAttributes(\ReflectionFunctionAbstract $m
$attribute = $attribute->newInstance();
$definition = $attribute->buildDefinition($attribute->value, $type, $parameter);

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

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

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

if ($definition->isAutowired()) {
$currentId = $this->currentId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\DependencyInjection\Tests\Compiler;

use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\AutowirePass;
use Symfony\Component\DependencyInjection\Compiler\ResolveAutowireInlineAttributesPass;
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
Expand Down Expand Up @@ -53,4 +54,16 @@ public function testAttribute()
self::assertInstanceOf(AutowireInlineAttributes2::class, $a->inlined);
self::assertSame(345, $a->inlined->bar);
}

public function testChildDefinition()
{
$container = new ContainerBuilder();

$container->setDefinition('autowire_inline1', (new ChildDefinition('parent'))->setClass(AutowireInlineAttributes1::class))
->setAutowired(true);

(new ResolveAutowireInlineAttributesPass())->process($container);

$this->assertSame(['$inlined'], array_keys($container->getDefinition('autowire_inline1')->getArguments()));
}
}

0 comments on commit 08ea87b

Please sign in to comment.