Skip to content

Commit 32061e1

Browse files
Merge branch '4.4' into 5.1
* 4.4: [DependencyInjection] Support PHP 8 builtin types in CheckTypeDeclarationsPass [DependencyInjection] Fix InvalidParameterTypeException for function parameters [VarDumper] fix mutating $GLOBALS while cloning it
2 parents c84a2d3 + 2343b4d commit 32061e1

File tree

5 files changed

+150
-7
lines changed

5 files changed

+150
-7
lines changed

Compiler/CheckTypeDeclarationsPass.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,15 +280,26 @@ private function checkType(Definition $checkedDefinition, $value, \ReflectionPar
280280
return;
281281
}
282282

283-
if (is_a($class, $type, true)) {
283+
if ('mixed' === $type) {
284284
return;
285285
}
286286

287-
$checkFunction = sprintf('is_%s', $type);
287+
if (is_a($class, $type, true)) {
288+
return;
289+
}
288290

289-
if (!$reflectionType->isBuiltin() || !$checkFunction($value)) {
290-
throw new InvalidParameterTypeException($this->currentId, \is_object($value) ? $class : get_debug_type($value), $parameter);
291+
if ('false' === $type) {
292+
if (false === $value) {
293+
return;
294+
}
295+
} elseif ($reflectionType->isBuiltin()) {
296+
$checkFunction = sprintf('is_%s', $type);
297+
if ($checkFunction($value)) {
298+
return;
299+
}
291300
}
301+
302+
throw new InvalidParameterTypeException($this->currentId, \is_object($value) ? $class : get_debug_type($value), $parameter);
292303
}
293304

294305
private function getExpressionLanguage(): ExpressionLanguage

Exception/InvalidParameterTypeException.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ public function __construct(string $serviceId, string $type, \ReflectionParamete
2525
$acceptedType = $acceptedType instanceof \ReflectionNamedType ? $acceptedType->getName() : (string) $acceptedType;
2626
$this->code = $type;
2727

28-
parent::__construct(sprintf('Invalid definition for service "%s": argument %d of "%s::%s()" accepts "%s", "%s" passed.', $serviceId, 1 + $parameter->getPosition(), $parameter->getDeclaringClass()->getName(), $parameter->getDeclaringFunction()->getName(), $acceptedType, $type));
28+
$function = $parameter->getDeclaringFunction();
29+
$functionName = $function instanceof \ReflectionMethod
30+
? sprintf('%s::%s', $function->getDeclaringClass()->getName(), $function->getName())
31+
: $function->getName();
32+
33+
parent::__construct(sprintf('Invalid definition for service "%s": argument %d of "%s()" accepts "%s", "%s" passed.', $serviceId, 1 + $parameter->getPosition(), $functionName, $acceptedType, $type));
2934
}
3035
}

Tests/Compiler/CheckTypeDeclarationsPassTest.php

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,22 @@ public function testUnionTypePassesWithBuiltin()
836836
$this->addToAssertionCount(1);
837837
}
838838

839+
/**
840+
* @requires PHP 8
841+
*/
842+
public function testUnionTypePassesWithFalse()
843+
{
844+
$container = new ContainerBuilder();
845+
846+
$container->register('union', UnionConstructor::class)
847+
->setFactory([UnionConstructor::class, 'create'])
848+
->setArguments([false]);
849+
850+
(new CheckTypeDeclarationsPass(true))->process($container);
851+
852+
$this->addToAssertionCount(1);
853+
}
854+
839855
/**
840856
* @requires PHP 8
841857
*/
@@ -851,8 +867,6 @@ public function testUnionTypeFailsWithReference()
851867
$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.');
852868

853869
(new CheckTypeDeclarationsPass(true))->process($container);
854-
855-
$this->addToAssertionCount(1);
856870
}
857871

858872
/**
@@ -869,6 +883,57 @@ public function testUnionTypeFailsWithBuiltin()
869883
$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.');
870884

871885
(new CheckTypeDeclarationsPass(true))->process($container);
886+
}
887+
888+
/**
889+
* @requires PHP 8
890+
*/
891+
public function testUnionTypeWithFalseFailsWithReference()
892+
{
893+
$container = new ContainerBuilder();
894+
895+
$container->register('waldo', Waldo::class);
896+
$container->register('union', UnionConstructor::class)
897+
->setFactory([UnionConstructor::class, 'create'])
898+
->setArguments([new Reference('waldo')]);
899+
900+
$this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
901+
$this->expectExceptionMessage('Invalid definition for service "union": argument 1 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\UnionConstructor::create()" accepts "array|false", "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\Waldo" passed.');
902+
903+
(new CheckTypeDeclarationsPass(true))->process($container);
904+
}
905+
906+
/**
907+
* @requires PHP 8
908+
*/
909+
public function testUnionTypeWithFalseFailsWithTrue()
910+
{
911+
$container = new ContainerBuilder();
912+
913+
$container->register('waldo', Waldo::class);
914+
$container->register('union', UnionConstructor::class)
915+
->setFactory([UnionConstructor::class, 'create'])
916+
->setArguments([true]);
917+
918+
$this->expectException(\Symfony\Component\DependencyInjection\Exception\InvalidArgumentException::class);
919+
$this->expectExceptionMessage('Invalid definition for service "union": argument 1 of "Symfony\Component\DependencyInjection\Tests\Fixtures\CheckTypeDeclarationsPass\UnionConstructor::create()" accepts "array|false", "boolean" passed.');
920+
921+
(new CheckTypeDeclarationsPass(true))->process($container);
922+
}
923+
924+
/**
925+
* @requires PHP 8
926+
*/
927+
public function testReferencePassesMixed()
928+
{
929+
$container = new ContainerBuilder();
930+
931+
$container->register('waldo', Waldo::class);
932+
$container->register('union', UnionConstructor::class)
933+
->setFactory([UnionConstructor::class, 'make'])
934+
->setArguments([new Reference('waldo')]);
935+
936+
(new CheckTypeDeclarationsPass(true))->process($container);
872937

873938
$this->addToAssertionCount(1);
874939
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Tests\Exception;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\DependencyInjection\Exception\InvalidParameterTypeException;
16+
17+
final class InvalidParameterTypeExceptionTest extends TestCase
18+
{
19+
/**
20+
* @dataProvider provideReflectionParameters
21+
*/
22+
public function testExceptionMessage(\ReflectionParameter $parameter, string $expectedMessage)
23+
{
24+
$exception = new InvalidParameterTypeException('my_service', 'int', $parameter);
25+
26+
self::assertSame($expectedMessage, $exception->getMessage());
27+
}
28+
29+
public function provideReflectionParameters(): iterable
30+
{
31+
yield 'static method' => [
32+
new \ReflectionParameter([MyClass::class, 'doSomething'], 0),
33+
'Invalid definition for service "my_service": argument 1 of "Symfony\Component\DependencyInjection\Tests\Exception\MyClass::doSomething()" accepts "array", "int" passed.',
34+
];
35+
36+
yield 'function' => [
37+
new \ReflectionParameter(__NAMESPACE__.'\\myFunction', 0),
38+
'Invalid definition for service "my_service": argument 1 of "Symfony\Component\DependencyInjection\Tests\Exception\myFunction()" accepts "array", "int" passed.',
39+
];
40+
}
41+
}
42+
43+
class MyClass
44+
{
45+
public static function doSomething(array $arguments): void
46+
{
47+
}
48+
}
49+
50+
function myFunction(array $arguments): void
51+
{
52+
}

Tests/Fixtures/CheckTypeDeclarationsPass/UnionConstructor.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,14 @@ class UnionConstructor
77
public function __construct(Foo|int $arg)
88
{
99
}
10+
11+
public static function create(array|false $arg): static
12+
{
13+
return new static(0);
14+
}
15+
16+
public static function make(mixed $arg): static
17+
{
18+
return new static(0);
19+
}
1020
}

0 commit comments

Comments
 (0)