From 5de10a1f2ae013a2265316cd1702319064b7334d Mon Sep 17 00:00:00 2001 From: David Grudl Date: Tue, 18 Jun 2024 20:47:06 +0200 Subject: [PATCH] support for PHP 8.4 --- .github/workflows/tests.yml | 2 +- composer.json | 2 +- readme.md | 2 +- src/Utils/Callback.php | 2 +- src/Utils/Reflection.php | 8 +++++--- tests/Utils/Callback.closure.phpt | 8 ++++---- tests/Utils/Reflection.toString.phpt | 1 + 7 files changed, 14 insertions(+), 11 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8aaab4b13..afbcd7632 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - php: ['8.0', '8.1', '8.2', '8.3'] + php: ['8.0', '8.1', '8.2', '8.3', '8.4'] fail-fast: false diff --git a/composer.json b/composer.json index d08757947..74bd6183c 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ } ], "require": { - "php": "8.0 - 8.3" + "php": "8.0 - 8.4" }, "require-dev": { "nette/tester": "^2.5", diff --git a/readme.md b/readme.md index d7528c09c..8d7a6a801 100644 --- a/readme.md +++ b/readme.md @@ -41,7 +41,7 @@ The recommended way to install is via Composer: composer require nette/utils ``` -Nette Utils 4.0 is compatible with PHP 8.0 to 8.3. +Nette Utils 4.0 is compatible with PHP 8.0 to 8.4.   diff --git a/src/Utils/Callback.php b/src/Utils/Callback.php index 732af9670..1777428fd 100644 --- a/src/Utils/Callback.php +++ b/src/Utils/Callback.php @@ -94,7 +94,7 @@ public static function toReflection($callable): \ReflectionMethod|\ReflectionFun } if (is_string($callable) && str_contains($callable, '::')) { - return new ReflectionMethod($callable); + return new ReflectionMethod(...explode('::', $callable, 2)); } elseif (is_array($callable)) { return new ReflectionMethod($callable[0], $callable[1]); } elseif (is_object($callable) && !$callable instanceof \Closure) { diff --git a/src/Utils/Reflection.php b/src/Utils/Reflection.php index 5a4f2ab75..87889be36 100644 --- a/src/Utils/Reflection.php +++ b/src/Utils/Reflection.php @@ -100,7 +100,7 @@ public static function getMethodDeclaringMethod(\ReflectionMethod $method): \Ref $hash = [$method->getFileName(), $method->getStartLine(), $method->getEndLine()]; if (($alias = $decl->getTraitAliases()[$method->name] ?? null) - && ($m = new \ReflectionMethod($alias)) + && ($m = new \ReflectionMethod(...explode('::', $alias, 2))) && $hash === [$m->getFileName(), $m->getStartLine(), $m->getEndLine()] ) { return self::getMethodDeclaringMethod($m); @@ -125,7 +125,7 @@ public static function getMethodDeclaringMethod(\ReflectionMethod $method): \Ref public static function areCommentsAvailable(): bool { static $res; - return $res ?? $res = (bool) (new \ReflectionMethod(__METHOD__))->getDocComment(); + return $res ?? $res = (bool) (new \ReflectionMethod(self::class, __FUNCTION__))->getDocComment(); } @@ -136,7 +136,9 @@ public static function toString(\Reflector $ref): string } elseif ($ref instanceof \ReflectionMethod) { return $ref->getDeclaringClass()->name . '::' . $ref->name . '()'; } elseif ($ref instanceof \ReflectionFunction) { - return $ref->name . '()'; + return PHP_VERSION_ID >= 80200 && $ref->isAnonymous() + ? '{closure}()' + : $ref->name . '()'; } elseif ($ref instanceof \ReflectionProperty) { return self::getPropertyDeclaringClass($ref)->name . '::$' . $ref->name; } elseif ($ref instanceof \ReflectionParameter) { diff --git a/tests/Utils/Callback.closure.phpt b/tests/Utils/Callback.closure.phpt index eeb608411..84fa0a8f4 100644 --- a/tests/Utils/Callback.closure.phpt +++ b/tests/Utils/Callback.closure.phpt @@ -87,7 +87,7 @@ class TestChild extends Test function getName($ref) { if ($ref instanceof ReflectionFunction) { - return $ref->getName(); + return $ref->getShortName(); } elseif ($ref instanceof ReflectionMethod) { return $ref->getDeclaringClass()->getName() . '::' . $ref->getName(); } @@ -121,9 +121,9 @@ test('closure', function () { Assert::same($closure, Closure::fromCallable($closure)); Assert::same($closure, Callback::unwrap($closure)); Assert::same('{closure}', Callback::toString($closure)); - Assert::same('{closure}', getName(Callback::toReflection($closure))); - Assert::same('{closure}', Closure::fromCallable($closure)(...[&$res])); - Assert::same('{closure}', $res); + Assert::match('{closure%a?%}', getName(Callback::toReflection($closure))); + Assert::match('{closure%a?%}', Closure::fromCallable($closure)(...[&$res])); + Assert::match('{closure%a?%}', $res); }); diff --git a/tests/Utils/Reflection.toString.phpt b/tests/Utils/Reflection.toString.phpt index 82e265db2..ef612ed3c 100644 --- a/tests/Utils/Reflection.toString.phpt +++ b/tests/Utils/Reflection.toString.phpt @@ -34,3 +34,4 @@ Assert::same('$param in Foo::method()', Reflection::toString(new ReflectionParam Assert::same('Foo::$var', Reflection::toString(new ReflectionProperty('Foo', 'var'))); Assert::same('func()', Reflection::toString(new ReflectionFunction('func'))); Assert::same('$param in func()', Reflection::toString(new ReflectionParameter('func', 'param'))); +Assert::same('$param in {closure}()', Reflection::toString((new ReflectionFunction(function ($param) {}))->getParameters()[0]));