diff --git a/src/Application/LinkGenerator.php b/src/Application/LinkGenerator.php index 2354b2e1a..ca2809441 100644 --- a/src/Application/LinkGenerator.php +++ b/src/Application/LinkGenerator.php @@ -59,7 +59,7 @@ public function link(string $dest, array $params = []): string } if ($method = $class::getReflection()->getActionRenderMethod($action)) { - UI\LinkBuilder::argsToParams($class, $method->getName(), $params, [], $missing); + UI\LinkBuilder::argsToParams($method, $params, [], $missing); if ($missing) { $rp = $missing[0]; throw new UI\InvalidLinkException("Missing parameter \${$rp->getName()} required by $class::{$method->getName()}()"); diff --git a/src/Application/UI/ComponentReflection.php b/src/Application/UI/ComponentReflection.php index 50c6fc911..05cccfb5e 100644 --- a/src/Application/UI/ComponentReflection.php +++ b/src/Application/UI/ComponentReflection.php @@ -10,6 +10,7 @@ namespace Nette\Application\UI; use Nette; +use Nette\Utils\Reflection; /** @@ -22,7 +23,6 @@ final class ComponentReflection extends \ReflectionClass { private static array $ppCache = []; private static array $pcCache = []; - private static array $mcCache = []; private static array $armCache = []; @@ -148,18 +148,10 @@ public function saveState(Component $component, array &$params): void */ public function hasCallableMethod(string $method): bool { - $class = $this->getName(); - $cache = &self::$mcCache[strtolower($class . ':' . $method)]; - if ($cache === null) { - try { - $cache = false; - $rm = new \ReflectionMethod($class, $method); - $cache = $this->isInstantiable() && $rm->isPublic() && !$rm->isAbstract() && !$rm->isStatic(); - } catch (\ReflectionException) { - } - } - - return $cache; + return $this->isInstantiable() + && $this->hasMethod($method) + && ($rm = $this->getMethod($method)) + && $rm->isPublic() && !$rm->isAbstract() && !$rm->isStatic(); } @@ -173,9 +165,9 @@ public static function combineArgs(\ReflectionFunctionAbstract $method, array $a $res[$i] = $args[$name]; if (!self::convertType($res[$i], $type)) { throw new Nette\InvalidArgumentException(sprintf( - 'Argument $%s passed to %s() must be %s, %s given.', + 'Argument $%s passed to %s must be %s, %s given.', $name, - ($method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' : '') . $method->getName(), + Reflection::toString($method), $type, get_debug_type($args[$name]), )); @@ -188,9 +180,9 @@ public static function combineArgs(\ReflectionFunctionAbstract $method, array $a $res[$i] = []; } else { throw new Nette\InvalidArgumentException(sprintf( - 'Missing parameter $%s required by %s()', + 'Missing parameter $%s required by %s', $name, - ($method instanceof \ReflectionMethod ? $method->getDeclaringClass()->getName() . '::' : '') . $method->getName(), + Reflection::toString($method), )); } } diff --git a/src/Application/UI/LinkBuilder.php b/src/Application/UI/LinkBuilder.php index a1c96cc22..ed1f14459 100644 --- a/src/Application/UI/LinkBuilder.php +++ b/src/Application/UI/LinkBuilder.php @@ -14,6 +14,7 @@ use Nette\Application\Attributes; use Nette\Application\Helpers; use Nette\Http; +use Nette\Utils\Reflection; /** @internal */ @@ -120,7 +121,7 @@ public function generateUrl( } // convert indexed parameters to named - static::argsToParams($component::class, $method->getName(), $args, [], $missing); + static::argsToParams($method, $args, [], $missing); } // counterpart of StatePersistent @@ -161,7 +162,7 @@ public function generateUrl( trigger_error("Link to deprecated action '$presenter:$action' from '{$this->presenter->getName()}:{$this->presenter->getAction()}'.", E_USER_DEPRECATED); } - static::argsToParams($presenterClass, $method->getName(), $args, $path === 'this' ? $this->presenter->getParameters() : [], $missing); + static::argsToParams($method, $args, $path === 'this' ? $this->presenter->getParameters() : [], $missing); } elseif (array_key_exists(0, $args)) { throw new InvalidLinkException("Unable to pass parameters to action '$presenter:$action', missing corresponding method $presenterClass::{$presenterClass::formatRenderMethod($action)}()."); @@ -189,7 +190,7 @@ public function generateUrl( if ($mode !== 'test' && !empty($missing)) { foreach ($missing as $rp) { if (!array_key_exists($rp->getName(), $args)) { - throw new InvalidLinkException("Missing parameter \${$rp->getName()} required by {$rp->getDeclaringClass()->getName()}::{$rp->getDeclaringFunction()->getName()}()"); + throw new InvalidLinkException("Missing parameter \${$rp->getName()} required by " . Reflection::toString($rp->getDeclaringFunction())); } } } @@ -250,16 +251,14 @@ public static function parseDestination(string $destination): array * @internal */ public static function argsToParams( - string $class, - string $method, + \ReflectionMethod $method, array &$args, array $supplemental = [], ?array &$missing = null, ): void { $i = 0; - $rm = new \ReflectionMethod($class, $method); - foreach ($rm->getParameters() as $param) { + foreach ($method->getParameters() as $param) { $type = ComponentReflection::getType($param); $name = $param->getName(); @@ -292,9 +291,9 @@ public static function argsToParams( if (!ComponentReflection::convertType($args[$name], $type)) { throw new InvalidLinkException(sprintf( - 'Argument $%s passed to %s() must be %s, %s given.', + 'Argument $%s passed to %s must be %s, %s given.', $name, - $rm->getDeclaringClass()->getName() . '::' . $rm->getName(), + Reflection::toString($method), $type, get_debug_type($args[$name]), )); @@ -309,7 +308,7 @@ public static function argsToParams( } if (array_key_exists($i, $args)) { - throw new InvalidLinkException("Passed more parameters than method $class::{$rm->getName()}() expects."); + throw new InvalidLinkException('Passed more parameters than method ' . Reflection::toString($method) . ' expects.'); } } diff --git a/src/Application/UI/Presenter.php b/src/Application/UI/Presenter.php index cc2066f35..56aac1000 100644 --- a/src/Application/UI/Presenter.php +++ b/src/Application/UI/Presenter.php @@ -866,7 +866,7 @@ public static function argsToParams( ?array &$missing = null, ): void { - LinkBuilder::argsToParams($class, $method, $args, $supplemental, $missing); + LinkBuilder::argsToParams(new \ReflectionMethod($class, $method), $args, $supplemental, $missing); }