Skip to content

Commit 477e843

Browse files
bug symfony#34223 [DI] Suggest typed argument when binding fails with untyped argument (gudfar)
This PR was merged into the 4.3 branch. Discussion ---------- [DI] Suggest typed argument when binding fails with untyped argument | Q | A | ------------- | --- | Branch? | 4.3 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | symfony#33470 | License | MIT I've added a condition that looks for arguments and if the typehint doesn’t match, throws an `InvalidArgumentException` Commits ------- 0e92399 [DI] Suggest typed argument when binding fails with untyped argument
2 parents 6b95ea6 + 0e92399 commit 477e843

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ protected function processValue($value, $isRoot = false)
112112
return parent::processValue($value, $isRoot);
113113
}
114114

115+
$bindingNames = [];
116+
115117
foreach ($bindings as $key => $binding) {
116118
list($bindingValue, $bindingId, $used, $bindingType, $file) = $binding->getValues();
117119
if ($used) {
@@ -121,7 +123,11 @@ protected function processValue($value, $isRoot = false)
121123
$this->unusedBindings[$bindingId] = [$key, $this->currentId, $bindingType, $file];
122124
}
123125

124-
if (preg_match('/^(?:(?:array|bool|float|int|string) )?\$/', $key)) {
126+
if (preg_match('/^(?:(?:array|bool|float|int|string|([^ $]++)) )\$/', $key, $m)) {
127+
$bindingNames[substr($key, \strlen($m[0]))] = $binding;
128+
}
129+
130+
if (!isset($m[1])) {
125131
continue;
126132
}
127133

@@ -182,11 +188,17 @@ protected function processValue($value, $isRoot = false)
182188
continue;
183189
}
184190

185-
if (!$typeHint || '\\' !== $typeHint[0] || !isset($bindings[$typeHint = substr($typeHint, 1)])) {
191+
if ($typeHint && '\\' === $typeHint[0] && isset($bindings[$typeHint = substr($typeHint, 1)])) {
192+
$arguments[$key] = $this->getBindingValue($bindings[$typeHint]);
193+
186194
continue;
187195
}
188196

189-
$arguments[$key] = $this->getBindingValue($bindings[$typeHint]);
197+
if (isset($bindingNames[$parameter->name])) {
198+
$bindingKey = array_search($binding, $bindings, true);
199+
$argumentType = substr($bindingKey, 0, strpos($bindingKey, ' '));
200+
$this->errorMessages[] = sprintf('Did you forget to add the type "%s" to argument "$%s" of method "%s::%s()"?', $argumentType, $parameter->name, $reflectionMethod->class, $reflectionMethod->name);
201+
}
190202
}
191203

192204
if ($arguments !== $call[1]) {

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
1919
use Symfony\Component\DependencyInjection\ContainerBuilder;
2020
use Symfony\Component\DependencyInjection\Definition;
21+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
2122
use Symfony\Component\DependencyInjection\Reference;
2223
use Symfony\Component\DependencyInjection\Tests\Fixtures\CaseSensitiveClass;
2324
use Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy;
@@ -157,4 +158,19 @@ public function testSyntheticServiceWithBind()
157158

158159
$this->assertSame([1 => 'bar'], $container->getDefinition(NamedArgumentsDummy::class)->getArguments());
159160
}
161+
162+
public function testEmptyBindingTypehint()
163+
{
164+
$this->expectException(InvalidArgumentException::class);
165+
$this->expectExceptionMessage('Did you forget to add the type "string" to argument "$apiKey" of method "Symfony\Component\DependencyInjection\Tests\Fixtures\NamedArgumentsDummy::__construct()"?');
166+
167+
$container = new ContainerBuilder();
168+
$bindings = [
169+
'string $apiKey' => new BoundArgument('foo'),
170+
];
171+
$definition = $container->register(NamedArgumentsDummy::class, NamedArgumentsDummy::class);
172+
$definition->setBindings($bindings);
173+
$pass = new ResolveBindingsPass();
174+
$pass->process($container);
175+
}
160176
}

0 commit comments

Comments
 (0)