diff --git a/src/Psalm/Config.php b/src/Psalm/Config.php index da10ef51091..ac4355b557c 100644 --- a/src/Psalm/Config.php +++ b/src/Psalm/Config.php @@ -1790,11 +1790,22 @@ public function getReportingLevelForMethod(string $issue_type, string $method_id public function getReportingLevelForFunction(string $issue_type, string $function_id): ?string { + $level = null; if (isset($this->issue_handlers[$issue_type])) { - return $this->issue_handlers[$issue_type]->getReportingLevelForFunction($function_id); + $level = $this->issue_handlers[$issue_type]->getReportingLevelForFunction($function_id); + + if ($level === null && $issue_type === 'UndefinedFunction') { + // undefined functions trigger global namespace fallback + // so we should also check reporting levels for the symbol in global scope + $root_function_id = preg_replace('/.*\\\/', '', $function_id); + if ($root_function_id !== $function_id) { + /** @psalm-suppress PossiblyUndefinedStringArrayOffset https://github.com/vimeo/psalm/issues/7656 */ + $level = $this->issue_handlers[$issue_type]->getReportingLevelForFunction($root_function_id); + } + } } - return null; + return $level; } public function getReportingLevelForArgument(string $issue_type, string $function_id): ?string diff --git a/tests/Config/ConfigTest.php b/tests/Config/ConfigTest.php index 6a15f41c9ac..867099ff754 100644 --- a/tests/Config/ConfigTest.php +++ b/tests/Config/ConfigTest.php @@ -355,6 +355,36 @@ public function testIssueHandler(): void $this->assertFalse($config->reportIssueInFile('MissingReturnType', realpath('src/Psalm/Type.php'))); } + public function testGlobalUndefinedFunctionSuppression(): void + { + $this->project_analyzer = $this->getProjectAnalyzerWithConfig( + Config::loadFromXML( + dirname(__DIR__, 2), + ' + + + + + + + + + + + + + + ' + ) + ); + + $config = $this->project_analyzer->getConfig(); + $this->assertSame( + Config::REPORT_SUPPRESS, + $config->getReportingLevelForFunction('UndefinedFunction', 'Some\Namespace\zzz') + ); + } + public function testMultipleIssueHandlers(): void { $this->project_analyzer = $this->getProjectAnalyzerWithConfig(