Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit bda2dcd

Browse filesBrowse files
committed
bug #39251 [DependencyInjection] Fix container linter for union types (derrabus)
This PR was merged into the 4.4 branch. Discussion ---------- [DependencyInjection] Fix container linter for union types | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #39233 | License | MIT | Doc PR | N/A Commits ------- e26893b [DependencyInjection] Fix container linter for union types.
2 parents cf07627 + e26893b commit bda2dcd
Copy full SHA for bda2dcd

File tree

Expand file treeCollapse file tree

4 files changed

+95
-14
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+95
-14
lines changed

‎.github/patch-types.php

Copy file name to clipboardExpand all lines: .github/patch-types.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
case false !== strpos($file, '/src/Symfony/Component/Config/Tests/Fixtures/ParseError.php'):
3131
case false !== strpos($file, '/src/Symfony/Component/Debug/Tests/Fixtures/'):
3232
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Compiler/OptionalServiceClass.php'):
33+
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/CheckTypeDeclarationsPass/UnionConstructor.php'):
3334
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/autowiring_classes.php'):
3435
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/uniontype_classes.php'):
3536
case false !== strpos($file, '/src/Symfony/Component/DependencyInjection/Tests/Fixtures/ParentNotExists.php'):

‎src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php
+15-14Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -153,26 +153,27 @@ private function checkTypeDeclarations(Definition $checkedDefinition, \Reflectio
153153
/**
154154
* @throws InvalidParameterTypeException When a parameter is not compatible with the declared type
155155
*/
156-
private function checkType(Definition $checkedDefinition, $value, \ReflectionParameter $parameter, ?string $envPlaceholderUniquePrefix, string $type = null): void
156+
private function checkType(Definition $checkedDefinition, $value, \ReflectionParameter $parameter, ?string $envPlaceholderUniquePrefix, \ReflectionType $reflectionType = null): void
157157
{
158-
if (null === $type) {
159-
$type = $parameter->getType();
158+
$reflectionType = $reflectionType ?? $parameter->getType();
160159

161-
if ($type instanceof \ReflectionUnionType) {
162-
foreach ($type->getTypes() as $type) {
163-
try {
164-
$this->checkType($checkedDefinition, $value, $parameter, $envPlaceholderUniquePrefix, $type);
160+
if ($reflectionType instanceof \ReflectionUnionType) {
161+
foreach ($reflectionType->getTypes() as $t) {
162+
try {
163+
$this->checkType($checkedDefinition, $value, $parameter, $envPlaceholderUniquePrefix, $t);
165164

166-
return;
167-
} catch (InvalidParameterTypeException $e) {
168-
}
165+
return;
166+
} catch (InvalidParameterTypeException $e) {
169167
}
170-
171-
throw new InvalidParameterTypeException($this->currentId, $e->getCode(), $parameter);
172168
}
173169

174-
$type = $type->getName();
170+
throw new InvalidParameterTypeException($this->currentId, $e->getCode(), $parameter);
175171
}
172+
if (!$reflectionType instanceof \ReflectionNamedType) {
173+
return;
174+
}
175+
176+
$type = $reflectionType->getName();
176177

177178
if ($value instanceof Reference) {
178179
if (!$this->container->has($value = (string) $value)) {
@@ -285,7 +286,7 @@ private function checkType(Definition $checkedDefinition, $value, \ReflectionPar
285286

286287
$checkFunction = sprintf('is_%s', $type);
287288

288-
if (!$parameter->getType()->isBuiltin() || !$checkFunction($value)) {
289+
if (!$reflectionType->isBuiltin() || !$checkFunction($value)) {
289290
throw new InvalidParameterTypeException($this->currentId, \is_object($value) ? $class : \gettype($value), $parameter);
290291
}
291292
}

‎src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Compiler/CheckTypeDeclarationsPassTest.php
+69Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\BarOptionalArgumentNotNull;
2727
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Foo;
2828
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\FooObject;
29+
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\UnionConstructor;
2930
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Waldo;
3031
use Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Wobble;
3132
use Symfony\Component\ExpressionLanguage\Expression;
@@ -803,4 +804,72 @@ public function testProcessResolveParameters()
803804

804805
putenv('ARRAY=');
805806
}
807+
808+
/**
809+
* @requires PHP 8
810+
*/
811+
public function testUnionTypePassesWithReference()
812+
{
813+
$container = new ContainerBuilder();
814+
815+
$container->register('foo', Foo::class);
816+
$container->register('union', UnionConstructor::class)
817+
->setArguments([new Reference('foo')]);
818+
819+
(new CheckTypeDeclarationsPass(true))->process($container);
820+
821+
$this->addToAssertionCount(1);
822+
}
823+
824+
/**
825+
* @requires PHP 8
826+
*/
827+
public function testUnionTypePassesWithBuiltin()
828+
{
829+
$container = new ContainerBuilder();
830+
831+
$container->register('union', UnionConstructor::class)
832+
->setArguments([42]);
833+
834+
(new CheckTypeDeclarationsPass(true))->process($container);
835+
836+
$this->addToAssertionCount(1);
837+
}
838+
839+
/**
840+
* @requires PHP 8
841+
*/
842+
public function testUnionTypeFailsWithReference()
843+
{
844+
$container = new ContainerBuilder();
845+
846+
$container->register('waldo', Waldo::class);
847+
$container->register('union', UnionConstructor::class)
848+
->setArguments([new Reference('waldo')]);
849+
850+
$this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
851+
$this->expectExceptionMessage('Invalid definition for service "union": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\UnionConstructor::__construct" accepts "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Foo|int", "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Waldo" passed.');
852+
853+
(new CheckTypeDeclarationsPass(true))->process($container);
854+
855+
$this->addToAssertionCount(1);
856+
}
857+
858+
/**
859+
* @requires PHP 8
860+
*/
861+
public function testUnionTypeFailsWithBuiltin()
862+
{
863+
$container = new ContainerBuilder();
864+
865+
$container->register('union', UnionConstructor::class)
866+
->setArguments([[1, 2, 3]]);
867+
868+
$this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
869+
$this->expectExceptionMessage('Invalid definition for service "union": argument 1 of "Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CheckTypeDeclarationsPass\\UnionConstructor::__construct" accepts "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Foo|int", "array" passed.');
870+
871+
(new CheckTypeDeclarationsPass(true))->process($container);
872+
873+
$this->addToAssertionCount(1);
874+
}
806875
}
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass;
4+
5+
class UnionConstructor
6+
{
7+
public function __construct(Foo|int $arg)
8+
{
9+
}
10+
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.