psalm
psalm copied to clipboard
First class callable analysis crashes when method name is passed as a string
Issue reproduction: https://psalm.dev/r/44f1037001
Context
$eventListeners values are constructed within Symfony's Dependency Injection. Unfortunately First class callable syntax is not available to define event listeners within that Symfony component, so this is an alternative way to define those listeners as callables.
Let me know if you need further information and/or context.
Edit: the version of Psalm in use at the moment of finding the issue is dev-master 4b2935f
I found these snippets:
https://psalm.dev/r/44f1037001
<?php
declare(strict_types=1);
final class DomainEventBus
{
/**
* @param array<class-string<object>, Closure(object): void> $eventListeners
*/
private function __construct(
private readonly array $eventListeners,
) {
}
/**
* @param array<class-string<object>, array{instance: object, method: string}> $eventListeners
*/
public static function withEventListeners(array $eventListeners): self
{
$callables = [];
foreach ($eventListeners as $eventClassName => ['instance' => $instance, 'method' => $method]) {
if (method_exists($instance, $method) === false) {
throw new \Exception('method does not exist.');
}
$callables[$eventClassName] = $instance->$method(...);
}
return new self($callables);
}
}
Psalm encountered an internal error:
/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php: Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::evaluateArbitraryParam(): Argument #2 ($arg) must be of type PhpParser\Node\Arg, PhpParser\Node\VariadicPlaceholder given, called in /vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php on line 127
Simplified: https://psalm.dev/r/13761b6983
I found these snippets:
https://psalm.dev/r/13761b6983
<?php
function f(object $o, string $m): void
{
$o->$m(...);
}
Psalm encountered an internal error:
/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php: Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::evaluateArbitraryParam(): Argument #2 ($arg) must be of type PhpParser\Node\Arg, PhpParser\Node\VariadicPlaceholder given, called in /vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php on line 127