diff --git a/src/DI/Resolver.php b/src/DI/Resolver.php index 24c00ab74..b3fe42812 100644 --- a/src/DI/Resolver.php +++ b/src/DI/Resolver.php @@ -548,10 +548,24 @@ public static function autowireArguments( 'Cannot use positional argument after named or omitted argument in %s.', Reflection::toString($param) )); + + } elseif (array_key_exists($paramName, $arguments)) { + if (!is_array($arguments[$paramName])) { + throw new ServiceCreationException(sprintf( + 'Parameter %s must be array, %s given.', + Reflection::toString($param), + gettype($arguments[$paramName]) + )); + } + + $res = array_merge($res, $arguments[$paramName]); + unset($arguments[$paramName]); + + } else { + $res = array_merge($res, $arguments); + $arguments = []; } - $res = array_merge($res, $arguments); - $arguments = []; $optCount = 0; break; diff --git a/tests/DI/Resolver.autowireArguments.errors.phpt b/tests/DI/Resolver.autowireArguments.errors.phpt index 89d4295a7..7678a9720 100644 --- a/tests/DI/Resolver.autowireArguments.errors.phpt +++ b/tests/DI/Resolver.autowireArguments.errors.phpt @@ -52,6 +52,25 @@ Assert::exception(function () { ); }, Nette\DI\ServiceCreationException::class, 'Parameter $x in {closure}%a?% has no class type or default value, so its value must be specified.'); +// non-array named variadics +Assert::exception(function () { + Resolver::autowireArguments( + new ReflectionFunction(function (...$args) {}), + ['args' => 1], + function () {} + ); +}, Nette\DI\ServiceCreationException::class, 'Parameter $args in {closure}() must be array, integer given.'); + + +// bad variadics (this is actually what PHP allows) +Assert::exception(function () { + Resolver::autowireArguments( + new ReflectionFunction(function (...$args) {}), + [1, 'args' => []], + function () {} + ); +}, Nette\DI\ServiceCreationException::class, 'Unable to pass specified arguments to {closure}%a?%.'); + // bad variadics if (PHP_VERSION_ID >= 80000) { diff --git a/tests/DI/Resolver.autowireArguments.phpt b/tests/DI/Resolver.autowireArguments.phpt index f674a7e14..766170482 100644 --- a/tests/DI/Resolver.autowireArguments.phpt +++ b/tests/DI/Resolver.autowireArguments.phpt @@ -108,7 +108,7 @@ Assert::equal( ) ); -// variadics +// positional variadics Assert::equal( [1, 2, 3], Resolver::autowireArguments( @@ -118,9 +118,9 @@ Assert::equal( ) ); -// name of variadics is ignored +// named variadics Assert::equal( - ['args' => [1, 2, 3]], + [1, 2, 3], Resolver::autowireArguments( new ReflectionFunction(function (...$args) {}), ['args' => [1, 2, 3]],