diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index b8508809ae..2e4ae15a4e 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -4,7 +4,7 @@ CHANGELOG 4.4.0 ----- - * Added `lint:container` to check that services wiring matches type declarations + * Added `lint:container` command to check that services wiring matches type declarations * Added `MailerAssertionsTrait` * Deprecated support for `templating` engine in `TemplateController`, use Twig instead * Deprecated the `$parser` argument of `ControllerResolver::__construct()` and `DelegatingLoader::__construct()` diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php index 04ecff767f..c5cba6c9a5 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/ContainerLintCommand.php @@ -15,7 +15,6 @@ use Symfony\Component\Config\ConfigCache; use Symfony\Component\Config\FileLocator; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\DependencyInjection\Compiler\CheckTypeDeclarationsPass; use Symfony\Component\DependencyInjection\Compiler\PassConfig; @@ -39,7 +38,6 @@ final class ContainerLintCommand extends Command $this ->setDescription('Ensures that arguments injected into services match type declarations') ->setHelp('This command parses service definitions and ensures that injected values match the type declarations of each services\' class.') - ->addOption('ignore-unused-services', 'o', InputOption::VALUE_NONE, 'Ignore unused services') ; } @@ -50,13 +48,11 @@ final class ContainerLintCommand extends Command { $container = $this->getContainerBuilder(); + $container->setParameter('container.build_hash', 'lint_container'); + $container->setParameter('container.build_time', time()); $container->setParameter('container.build_id', 'lint_container'); - $container->addCompilerPass( - new CheckTypeDeclarationsPass(true), - $input->getOption('ignore-unused-services') ? PassConfig::TYPE_AFTER_REMOVING : PassConfig::TYPE_OPTIMIZE, - -5 - ); + $container->addCompilerPass(new CheckTypeDeclarationsPass(true), PassConfig::TYPE_AFTER_REMOVING, -100); $container->compile(); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml index f3f73a9c2a..f2d0e9e2a6 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/validator.xml @@ -17,7 +17,7 @@ - + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.php index d90041213c..ab0b06ffb3 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/TestBundle.php @@ -14,6 +14,8 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle; use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\DependencyInjection\AnnotationReaderPass; use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\DependencyInjection\Config\CustomConfig; use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\DependencyInjection\TranslationDebugPass; +use Symfony\Component\DependencyInjection\Compiler\CheckTypeDeclarationsPass; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\Compiler\PassConfig; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -31,5 +33,15 @@ class TestBundle extends Bundle $container->addCompilerPass(new AnnotationReaderPass(), PassConfig::TYPE_AFTER_REMOVING); $container->addCompilerPass(new TranslationDebugPass()); + + $container->addCompilerPass(new class() implements CompilerPassInterface { + public function process(ContainerBuilder $container) + { + $container->removeDefinition('twig.controller.exception'); + $container->removeDefinition('twig.controller.preview_error'); + } + }); + + $container->addCompilerPass(new CheckTypeDeclarationsPass(true), PassConfig::TYPE_AFTER_REMOVING, -100); } } diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/TestBundle.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/TestBundle.php new file mode 100644 index 0000000000..5197a16195 --- /dev/null +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/TestBundle.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle; + +use Symfony\Component\DependencyInjection\Compiler\CheckTypeDeclarationsPass; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PassConfig; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpKernel\Bundle\Bundle; + +class TestBundle extends Bundle +{ + public function build(ContainerBuilder $container) + { + $container->setParameter('container.build_hash', 'test_bundle'); + $container->setParameter('container.build_time', time()); + $container->setParameter('container.build_id', 'test_bundle'); + + $container->addCompilerPass(new class() implements CompilerPassInterface { + public function process(ContainerBuilder $container) + { + $container->removeDefinition('twig.controller.exception'); + $container->removeDefinition('twig.controller.preview_error'); + } + }); + + $container->addCompilerPass(new CheckTypeDeclarationsPass(true), PassConfig::TYPE_AFTER_REMOVING, -100); + } +} diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AbstractTokenCompareRoles/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AbstractTokenCompareRoles/bundles.php index bedfbb1bd8..054405274e 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AbstractTokenCompareRoles/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AbstractTokenCompareRoles/bundles.php @@ -12,9 +12,11 @@ use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\SecurityBundle\SecurityBundle; use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\SecuredPageBundle\SecuredPageBundle; +use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle; return [ new FrameworkBundle(), new SecurityBundle(), new SecuredPageBundle(), + new TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AliasedEvents/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AliasedEvents/bundles.php index d7b7c498f8..115dd2c357 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AliasedEvents/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AliasedEvents/bundles.php @@ -12,9 +12,11 @@ use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\SecurityBundle\SecurityBundle; use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\EventBundle\EventBundle; +use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle; return [ new FrameworkBundle(), new SecurityBundle(), new EventBundle(), + new TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AutowiringTypes/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AutowiringTypes/bundles.php index 535a4bf517..794461855c 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AutowiringTypes/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/AutowiringTypes/bundles.php @@ -13,4 +13,5 @@ return [ new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), new Symfony\Bundle\SecurityBundle\SecurityBundle(), new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\AutowiringBundle\AutowiringBundle(), + new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/bundles.php index 65a38200e7..81f9c48b64 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/CsrfFormLogin/bundles.php @@ -14,4 +14,5 @@ return [ new Symfony\Bundle\SecurityBundle\SecurityBundle(), new Symfony\Bundle\TwigBundle\TwigBundle(), new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\CsrfFormLoginBundle\CsrfFormLoginBundle(), + new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/bundles.php index 7928a468da..b77f03be27 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/bundles.php @@ -13,4 +13,5 @@ return [ new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), new Symfony\Bundle\SecurityBundle\SecurityBundle(), new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\FirewallEntryPointBundle\FirewallEntryPointBundle(), + new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLogin/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLogin/bundles.php index cd367a95b4..bbb9107456 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLogin/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLogin/bundles.php @@ -13,4 +13,5 @@ return [ new Symfony\Bundle\SecurityBundle\SecurityBundle(), new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\JsonLoginBundle\JsonLoginBundle(), + new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLoginLdap/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLoginLdap/bundles.php index bcfd17425c..edf6dae14c 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLoginLdap/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/JsonLoginLdap/bundles.php @@ -12,4 +12,5 @@ return [ new Symfony\Bundle\SecurityBundle\SecurityBundle(), new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), + new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/bundles.php index 9a26fb163a..a52ae15f6d 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutAccess/bundles.php @@ -11,8 +11,10 @@ use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\SecurityBundle\SecurityBundle; +use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle; return [ new FrameworkBundle(), new SecurityBundle(), + new TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutWithoutSessionInvalidation/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutWithoutSessionInvalidation/bundles.php index 9a26fb163a..a52ae15f6d 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutWithoutSessionInvalidation/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/LogoutWithoutSessionInvalidation/bundles.php @@ -11,8 +11,10 @@ use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\SecurityBundle\SecurityBundle; +use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle; return [ new FrameworkBundle(), new SecurityBundle(), + new TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/bundles.php index ccff0d356c..0e34621a35 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/MissingUserProvider/bundles.php @@ -12,9 +12,11 @@ use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\SecurityBundle\SecurityBundle; use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\MissingUserProviderBundle\MissingUserProviderBundle; +use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle; return [ new FrameworkBundle(), new SecurityBundle(), new MissingUserProviderBundle(), + new TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/PasswordEncode/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/PasswordEncode/bundles.php index bcfd17425c..edf6dae14c 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/PasswordEncode/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/PasswordEncode/bundles.php @@ -12,4 +12,5 @@ return [ new Symfony\Bundle\SecurityBundle\SecurityBundle(), new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), + new Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/bundles.php index 9a26fb163a..a52ae15f6d 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/RememberMeLogout/bundles.php @@ -11,8 +11,10 @@ use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\SecurityBundle\SecurityBundle; +use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle; return [ new FrameworkBundle(), new SecurityBundle(), + new TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/SecurityHelper/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/SecurityHelper/bundles.php index 9a26fb163a..a52ae15f6d 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/SecurityHelper/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/SecurityHelper/bundles.php @@ -11,8 +11,10 @@ use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\SecurityBundle\SecurityBundle; +use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle; return [ new FrameworkBundle(), new SecurityBundle(), + new TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/bundles.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/bundles.php index 95041e7ad4..cef48bfcc4 100644 --- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/bundles.php +++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/bundles.php @@ -12,6 +12,7 @@ use Symfony\Bundle\FrameworkBundle\FrameworkBundle; use Symfony\Bundle\SecurityBundle\SecurityBundle; use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\FormLoginBundle\FormLoginBundle; +use Symfony\Bundle\SecurityBundle\Tests\Functional\Bundle\TestBundle; use Symfony\Bundle\TwigBundle\TwigBundle; return [ @@ -19,4 +20,5 @@ return [ new SecurityBundle(), new TwigBundle(), new FormLoginBundle(), + new TestBundle(), ]; diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json index 77bd4a0cfb..7ecd3a12c1 100644 --- a/src/Symfony/Bundle/SecurityBundle/composer.json +++ b/src/Symfony/Bundle/SecurityBundle/composer.json @@ -19,7 +19,7 @@ "php": "^7.1.3", "ext-xml": "*", "symfony/config": "^4.2|^5.0", - "symfony/dependency-injection": "^4.2|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", "symfony/http-kernel": "^4.4", "symfony/security-core": "^4.4", "symfony/security-csrf": "^4.2|^5.0", diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php index 8453e4e62a..ad3cb5295c 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php @@ -133,9 +133,12 @@ abstract class AbstractRecursivePass implements CompilerPassInterface list($class, $method) = $factory; if ($class instanceof Reference) { $class = $this->container->findDefinition((string) $class)->getClass(); + } elseif ($class instanceof Definition) { + $class = $class->getClass(); } elseif (null === $class) { $class = $definition->getClass(); } + if ('__construct' === $method) { throw new RuntimeException(sprintf('Invalid service "%s": "__construct()" cannot be used as a factory method.', $this->currentId)); } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php index 0dfd9ae6f6..9bc57539f4 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/CheckTypeDeclarationsPass.php @@ -12,6 +12,7 @@ namespace Symfony\Component\DependencyInjection\Compiler; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; use Symfony\Component\DependencyInjection\Exception\InvalidParameterTypeException; @@ -79,27 +80,27 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass /** * @throws InvalidArgumentException When not enough parameters are defined for the method */ - private function checkTypeDeclarations(Definition $checkedDefinition, \ReflectionFunctionAbstract $reflectionFunction, array $configurationArguments): void + private function checkTypeDeclarations(Definition $checkedDefinition, \ReflectionFunctionAbstract $reflectionFunction, array $values): void { $numberOfRequiredParameters = $reflectionFunction->getNumberOfRequiredParameters(); - if (\count($configurationArguments) < $numberOfRequiredParameters) { - throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": "%s::%s()" requires %d arguments, %d passed.', $this->currentId, $reflectionFunction->class, $reflectionFunction->name, $numberOfRequiredParameters, \count($configurationArguments))); + if (\count($values) < $numberOfRequiredParameters) { + throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": "%s::%s()" requires %d arguments, %d passed.', $this->currentId, $reflectionFunction->class, $reflectionFunction->name, $numberOfRequiredParameters, \count($values))); } $reflectionParameters = $reflectionFunction->getParameters(); - $checksCount = min($reflectionFunction->getNumberOfParameters(), \count($configurationArguments)); + $checksCount = min($reflectionFunction->getNumberOfParameters(), \count($values)); for ($i = 0; $i < $checksCount; ++$i) { if (!$reflectionParameters[$i]->hasType() || $reflectionParameters[$i]->isVariadic()) { continue; } - $this->checkType($checkedDefinition, $configurationArguments[$i], $reflectionParameters[$i]); + $this->checkType($checkedDefinition, $values[$i], $reflectionParameters[$i]); } if ($reflectionFunction->isVariadic() && ($lastParameter = end($reflectionParameters))->hasType()) { - $variadicParameters = \array_slice($configurationArguments, $lastParameter->getPosition()); + $variadicParameters = \array_slice($values, $lastParameter->getPosition()); foreach ($variadicParameters as $variadicParameter) { $this->checkType($checkedDefinition, $variadicParameter, $lastParameter); @@ -110,63 +111,82 @@ final class CheckTypeDeclarationsPass extends AbstractRecursivePass /** * @throws InvalidParameterTypeException When a parameter is not compatible with the declared type */ - private function checkType(Definition $checkedDefinition, $configurationArgument, \ReflectionParameter $parameter): void + private function checkType(Definition $checkedDefinition, $value, \ReflectionParameter $parameter): void { - $parameterTypeName = $parameter->getType()->getName(); + $type = $parameter->getType()->getName(); - $referencedDefinition = $configurationArgument; - - if ($referencedDefinition instanceof Reference) { - if (!$this->container->has($referencedDefinition)) { + if ($value instanceof Reference) { + if (!$this->container->has($value = (string) $value)) { return; } - $referencedDefinition = $this->container->findDefinition((string) $referencedDefinition); + if ('service_container' === $value && is_a($type, Container::class, true)) { + return; + } + + $value = $this->container->findDefinition($value); } - if ('self' === $parameterTypeName) { - $parameterTypeName = $parameter->getDeclaringClass()->getName(); - } - if ('static' === $parameterTypeName) { - $parameterTypeName = $checkedDefinition->getClass(); + if ('self' === $type) { + $type = $parameter->getDeclaringClass()->getName(); } - if ($referencedDefinition instanceof Definition) { - $class = $referencedDefinition->getClass(); + if ('static' === $type) { + $type = $checkedDefinition->getClass(); + } + + if ($value instanceof Definition) { + $class = $value->getClass(); if (!$class || (!$this->autoload && !class_exists($class, false) && !interface_exists($class, false))) { return; } - if (!is_a($class, $parameterTypeName, true)) { - throw new InvalidParameterTypeException($this->currentId, $class, $parameter); - } - } else { - if (null === $configurationArgument && $parameter->allowsNull()) { + if ('callable' === $type && method_exists($class, '__invoke')) { return; } - if (\in_array($parameterTypeName, self::SCALAR_TYPES, true) && is_scalar($configurationArgument)) { + if ('iterable' === $type && is_subclass_of($class, 'Traversable')) { return; } - if ('iterable' === $parameterTypeName && $configurationArgument instanceof IteratorArgument) { + if (is_a($class, $type, true)) { return; } - if ('Traversable' === $parameterTypeName && $configurationArgument instanceof IteratorArgument) { - return; - } + throw new InvalidParameterTypeException($this->currentId, $class, $parameter); + } - if ($configurationArgument instanceof Parameter) { - return; - } + if ($value instanceof Parameter) { + $value = $this->container->getParameter($value); + } elseif (\is_string($value) && '%' === ($value[0] ?? '') && preg_match('/^%([^%]+)%$/', $value, $match)) { + $value = $this->container->getParameter($match[1]); + } - $checkFunction = sprintf('is_%s', $parameter->getType()->getName()); + if (null === $value && $parameter->allowsNull()) { + return; + } - if (!$parameter->getType()->isBuiltin() || !$checkFunction($configurationArgument)) { - throw new InvalidParameterTypeException($this->currentId, \gettype($configurationArgument), $parameter); - } + if (\in_array($type, self::SCALAR_TYPES, true) && is_scalar($value)) { + return; + } + + if ('callable' === $type && \is_array($value) && isset($value[0]) && ($value[0] instanceof Reference || $value[0] instanceof Definition)) { + return; + } + + if ('iterable' === $type && (\is_array($value) || $value instanceof \Traversable || $value instanceof IteratorArgument)) { + return; + } + + if ('Traversable' === $type && ($value instanceof \Traversable || $value instanceof IteratorArgument)) { + return; + } + + $checkFunction = sprintf('is_%s', $parameter->getType()->getName()); + + if (!$parameter->getType()->isBuiltin() || !$checkFunction($value)) { + throw new InvalidParameterTypeException($this->currentId, \gettype($value), $parameter); } } }