From ff168a9c7ac155346e70cfee0aafe50cf014dda9 Mon Sep 17 00:00:00 2001 From: kkmuffme <11071985+kkmuffme@users.noreply.github.com> Date: Sat, 16 Mar 2024 21:43:36 +0100 Subject: [PATCH] Fix undefined parent not reported in callable Fix https://github.com/vimeo/psalm/issues/10836 --- .../Expression/Call/ArgumentAnalyzer.php | 11 ++++++ tests/CallableTest.php | 34 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php index 262935153..e89cd6faf 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentAnalyzer.php @@ -38,6 +38,7 @@ use Psalm\Issue\MixedArgumentTypeCoercion; use Psalm\Issue\NamedArgumentNotAllowed; use Psalm\Issue\NoValue; use Psalm\Issue\NullArgument; +use Psalm\Issue\ParentNotFound; use Psalm\Issue\PossiblyFalseArgument; use Psalm\Issue\PossiblyInvalidArgument; use Psalm\Issue\PossiblyNullArgument; @@ -1297,6 +1298,16 @@ final class ArgumentAnalyzer if ($callable_fq_class_name === 'parent') { $container_class = $statements_analyzer->getParentFQCLN(); + if ($container_class === null) { + IssueBuffer::accepts( + new ParentNotFound( + 'Cannot call method on parent' + . ' as this class does not extend another', + $arg_location, + ), + $statements_analyzer->getSuppressedIssues(), + ); + } } if (!$container_class) { diff --git a/tests/CallableTest.php b/tests/CallableTest.php index e10784b0b..c70020a80 100644 --- a/tests/CallableTest.php +++ b/tests/CallableTest.php @@ -2518,6 +2518,40 @@ class CallableTest extends TestCase 'ignored_issues' => [], 'php_version' => '8.0', ], + 'parentCallableArrayWithoutParent' => [ + 'code' => 'run(["parent", "hello"]); + } + + /** + * @param callable $callable + * @return void + */ + public function run($callable) { + call_user_func($callable); + } + }', + 'error_message' => 'ParentNotFound', + ], + 'parentCallableWithoutParent' => [ + 'code' => 'run("parent::hello"); + } + + /** + * @param callable $callable + * @return void + */ + public function run($callable) { + call_user_func($callable); + } + }', + 'error_message' => 'ParentNotFound', + ], ]; } }