From 1f24e4900bf08c29171ffd38993ba56280b6116b Mon Sep 17 00:00:00 2001 From: staabm <120441+staabm@users.noreply.github.com> Date: Sun, 15 Feb 2026 10:07:46 +0000 Subject: [PATCH 1/2] Remove callable.nonNativeMethod --- src/Rules/Methods/MethodCallableRule.php | 20 +----------- .../Methods/StaticMethodCallableRule.php | 20 +----------- .../Rules/Methods/MethodCallableRuleTest.php | 6 ++++ .../PHPStan/Rules/Methods/data/bug-13596.php | 31 +++++++++++++++++++ 4 files changed, 39 insertions(+), 38 deletions(-) create mode 100644 tests/PHPStan/Rules/Methods/data/bug-13596.php diff --git a/src/Rules/Methods/MethodCallableRule.php b/src/Rules/Methods/MethodCallableRule.php index 395089046f..25166a91a6 100644 --- a/src/Rules/Methods/MethodCallableRule.php +++ b/src/Rules/Methods/MethodCallableRule.php @@ -5,12 +5,10 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; use PHPStan\DependencyInjection\RegisteredRule; -use PHPStan\Internal\SprintfHelper; use PHPStan\Node\MethodCallableNode; use PHPStan\Php\PhpVersion; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; -use function sprintf; /** * @implements Rule @@ -46,23 +44,7 @@ public function processNode(Node $node, Scope $scope): array $methodNameName = $methodName->toString(); - [$errors, $methodReflection] = $this->methodCallCheck->check($scope, $methodNameName, $node->getVar(), $node->getName()); - if ($methodReflection === null) { - return $errors; - } - - $declaringClass = $methodReflection->getDeclaringClass(); - if ($declaringClass->hasNativeMethod($methodNameName)) { - return $errors; - } - - $messagesMethodName = SprintfHelper::escapeFormatString($declaringClass->getDisplayName() . '::' . $methodReflection->getName() . '()'); - - $errors[] = RuleErrorBuilder::message(sprintf('Creating callable from a non-native method %s.', $messagesMethodName)) - ->identifier('callable.nonNativeMethod') - ->build(); - - return $errors; + return $this->methodCallCheck->check($scope, $methodNameName, $node->getVar(), $node->getName())[0]; } } diff --git a/src/Rules/Methods/StaticMethodCallableRule.php b/src/Rules/Methods/StaticMethodCallableRule.php index 5f10168c19..15433c0e48 100644 --- a/src/Rules/Methods/StaticMethodCallableRule.php +++ b/src/Rules/Methods/StaticMethodCallableRule.php @@ -5,12 +5,10 @@ use PhpParser\Node; use PHPStan\Analyser\Scope; use PHPStan\DependencyInjection\RegisteredRule; -use PHPStan\Internal\SprintfHelper; use PHPStan\Node\StaticMethodCallableNode; use PHPStan\Php\PhpVersion; use PHPStan\Rules\Rule; use PHPStan\Rules\RuleErrorBuilder; -use function sprintf; /** * @implements Rule @@ -46,23 +44,7 @@ public function processNode(Node $node, Scope $scope): array $methodNameName = $methodName->toString(); - [$errors, $methodReflection] = $this->methodCallCheck->check($scope, $methodNameName, $node->getClass(), $node->getName()); - if ($methodReflection === null) { - return $errors; - } - - $declaringClass = $methodReflection->getDeclaringClass(); - if ($declaringClass->hasNativeMethod($methodNameName)) { - return $errors; - } - - $messagesMethodName = SprintfHelper::escapeFormatString($declaringClass->getDisplayName() . '::' . $methodReflection->getName() . '()'); - - $errors[] = RuleErrorBuilder::message(sprintf('Creating callable from a non-native static method %s.', $messagesMethodName)) - ->identifier('callable.nonNativeMethod') - ->build(); - - return $errors; + return $this->methodCallCheck->check($scope, $methodNameName, $node->getClass(), $node->getName())[0]; } } diff --git a/tests/PHPStan/Rules/Methods/MethodCallableRuleTest.php b/tests/PHPStan/Rules/Methods/MethodCallableRuleTest.php index 6dcf45e242..60511e6b15 100644 --- a/tests/PHPStan/Rules/Methods/MethodCallableRuleTest.php +++ b/tests/PHPStan/Rules/Methods/MethodCallableRuleTest.php @@ -39,6 +39,12 @@ public function testNotSupportedOnOlderVersions(): void ]); } + #[RequiresPhp('>= 8.1')] + public function testBug13596(): void + { + $this->analyse([__DIR__ . '/data/bug-13596.php'], []); + } + #[RequiresPhp('>= 8.1')] public function testRule(): void { diff --git a/tests/PHPStan/Rules/Methods/data/bug-13596.php b/tests/PHPStan/Rules/Methods/data/bug-13596.php new file mode 100644 index 0000000000..f633248c0c --- /dev/null +++ b/tests/PHPStan/Rules/Methods/data/bug-13596.php @@ -0,0 +1,31 @@ += 8.1 + +namespace Bug13596; + +use Closure; + +class BaseClass +{ + public function getCallable(): ?Closure + { + return method_exists($this, 'myCallable') ? $this->myCallable(...) : null; + } + + public function getCallableWithIsCallable(): ?Closure + { + return is_callable([$this, 'myCallable']) ? $this->myCallable(...) : null; + } +} + +class ChildOne extends BaseClass +{ + // +} + +class ChildTwo extends BaseClass +{ + public function myCallable(): string + { + return 'I exist on child two.'; + } +} From 1092e24dcb3c22ffc661ce7cd9e2d2821977676d Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Thu, 19 Feb 2026 20:58:55 +0100 Subject: [PATCH 2/2] Update tests --- tests/PHPStan/Rules/Methods/MethodCallableRuleTest.php | 8 -------- .../Rules/Methods/StaticMethodCallableRuleTest.php | 8 -------- 2 files changed, 16 deletions(-) diff --git a/tests/PHPStan/Rules/Methods/MethodCallableRuleTest.php b/tests/PHPStan/Rules/Methods/MethodCallableRuleTest.php index 60511e6b15..e1f6964a12 100644 --- a/tests/PHPStan/Rules/Methods/MethodCallableRuleTest.php +++ b/tests/PHPStan/Rules/Methods/MethodCallableRuleTest.php @@ -74,14 +74,6 @@ public function testRule(): void 'Call to private method doFoo() of class MethodCallable\ParentClass.', 53, ], - [ - 'Creating callable from a non-native method MethodCallable\Lorem::doBar().', - 66, - ], - [ - 'Creating callable from a non-native method MethodCallable\Ipsum::doBar().', - 85, - ], ]); } diff --git a/tests/PHPStan/Rules/Methods/StaticMethodCallableRuleTest.php b/tests/PHPStan/Rules/Methods/StaticMethodCallableRuleTest.php index de79d04034..5bcbf93fe1 100644 --- a/tests/PHPStan/Rules/Methods/StaticMethodCallableRuleTest.php +++ b/tests/PHPStan/Rules/Methods/StaticMethodCallableRuleTest.php @@ -93,14 +93,6 @@ public function testRule(): void 'Cannot call static method doFoo() on int.', 22, ], - [ - 'Creating callable from a non-native static method StaticMethodCallable\Lorem::doBar().', - 47, - ], - [ - 'Creating callable from a non-native static method StaticMethodCallable\Ipsum::doBar().', - 66, - ], ]); }