bug #36108 [DI] Fix CheckTypeDeclarationPass (guillbdx)

This PR was squashed before being merged into the 4.4 branch.

Discussion
----------

[DI] Fix CheckTypeDeclarationPass

| Q             | A
| ------------- | ---
| Branch?       | 4.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Tickets       | Fix #35863 and #35972
| License       | MIT
| Doc PR        |

Bug 1: The lint container threw an error if a class buit with a factory was declared as callable while this factory method returne a callabe (#35863)

Bug 2: Sodium Exception was not caught in the CheckTypeDeclarationsPass. We have extended the exception caught to \Exception, instead of EnvNotFoundException and RuntimeException only.

Commits
-------

cbf4dfd10f [DI] Fix CheckTypeDeclarationPass
This commit is contained in:
Fabien Potencier 2020-03-18 08:18:50 +01:00
commit 7baec325fc
3 changed files with 52 additions and 3 deletions

View File

@ -17,7 +17,6 @@ use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\InvalidParameterTypeException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
@ -207,7 +206,7 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass
if ('' === preg_replace('/'.$envPlaceholderUniquePrefix.'_\w+_[a-f0-9]{32}/U', '', $value, -1, $c) && 1 === $c) {
try {
$value = $this->container->resolveEnvPlaceholders($value, true);
} catch (EnvNotFoundException | RuntimeException $e) {
} catch (\Exception $e) {
// If an env placeholder cannot be resolved, we skip the validation.
return;
}
@ -250,7 +249,11 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass
return;
}
if ('iterable' === $type && (\is_array($value) || is_subclass_of($class, \Traversable::class))) {
if ('iterable' === $type && (\is_array($value) || 'array' === $class || is_subclass_of($class, \Traversable::class))) {
return;
}
if ($type === $class) {
return;
}

View File

@ -536,6 +536,42 @@ class CheckTypeDeclarationsPassTest extends TestCase
$this->addToAssertionCount(1);
}
public function testProcessFactoryForTypeSameAsClass()
{
$container = new ContainerBuilder();
$container->register('foo', Foo::class);
$container->register('bar', 'callable')
->setFactory([
new Reference('foo'),
'createCallable',
]);
$container->register('bar_call', BarMethodCall::class)
->addMethodCall('setCallable', [new Reference('bar')]);
(new CheckTypeDeclarationsPass(true))->process($container);
$this->addToAssertionCount(1);
}
public function testProcessFactoryForIterableTypeAndArrayClass()
{
$container = new ContainerBuilder();
$container->register('foo', Foo::class);
$container->register('bar', 'array')
->setFactory([
new Reference('foo'),
'createArray',
]);
$container->register('bar_call', BarMethodCall::class)
->addMethodCall('setIterable', [new Reference('bar')]);
(new CheckTypeDeclarationsPass(true))->process($container);
$this->addToAssertionCount(1);
}
public function testProcessPassingBuiltinTypeDoesNotLoadCodeByDefault()
{
$container = new ContainerBuilder();

View File

@ -13,4 +13,14 @@ class Foo
{
return new Bar($stdClass);
}
public static function createCallable(): callable
{
return function() {};
}
public static function createArray(): array
{
return [];
}
}