mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Fix #609 - fix callable coercion in reconciliation step
This commit is contained in:
parent
b8a8e9bc5b
commit
24490aac0e
@ -540,22 +540,6 @@ class TypeChecker
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($input_type_part instanceof TCallable &&
|
||||
(
|
||||
$container_type_part instanceof TString ||
|
||||
$container_type_part instanceof TArray ||
|
||||
$container_type_part instanceof ObjectLike ||
|
||||
(
|
||||
$container_type_part instanceof TNamedObject &&
|
||||
$codebase->classExists($container_type_part->value) &&
|
||||
$codebase->methodExists($container_type_part->value . '::__invoke')
|
||||
)
|
||||
)
|
||||
) {
|
||||
// @todo add value checks if possible here
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($input_type_part instanceof TNumeric) {
|
||||
if ($container_type_part->isNumericType()) {
|
||||
$has_scalar_match = true;
|
||||
|
@ -14,6 +14,7 @@ use Psalm\Issue\TypeDoesNotContainNull;
|
||||
use Psalm\Issue\TypeDoesNotContainType;
|
||||
use Psalm\IssueBuffer;
|
||||
use Psalm\Type;
|
||||
use Psalm\Type\Atomic\ObjectLike;
|
||||
use Psalm\Type\Atomic\Scalar;
|
||||
use Psalm\Type\Atomic\TArray;
|
||||
use Psalm\Type\Atomic\TBool;
|
||||
@ -27,6 +28,7 @@ use Psalm\Type\Atomic\TNumeric;
|
||||
use Psalm\Type\Atomic\TNumericString;
|
||||
use Psalm\Type\Atomic\TObject;
|
||||
use Psalm\Type\Atomic\TResource;
|
||||
use Psalm\Type\Atomic\TString;
|
||||
use Psalm\Type\Atomic\TTrue;
|
||||
|
||||
class Reconciler
|
||||
@ -809,6 +811,22 @@ class Reconciler
|
||||
$has_local_match = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if ($new_type_part instanceof TCallable &&
|
||||
(
|
||||
$existing_var_type_part instanceof TString ||
|
||||
$existing_var_type_part instanceof TArray ||
|
||||
$existing_var_type_part instanceof ObjectLike ||
|
||||
(
|
||||
$existing_var_type_part instanceof TNamedObject &&
|
||||
$codebase->classExists($existing_var_type_part->value) &&
|
||||
$codebase->methodExists($existing_var_type_part->value . '::__invoke')
|
||||
)
|
||||
)
|
||||
) {
|
||||
$has_local_match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$has_local_match) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?php
|
||||
namespace Psalm\Tests;
|
||||
|
||||
class ClosureTest extends TestCase
|
||||
class CallableTest extends TestCase
|
||||
{
|
||||
use Traits\FileCheckerInvalidCodeParseTestTrait;
|
||||
use Traits\FileCheckerValidCodeParseTestTrait;
|
||||
@ -227,7 +227,7 @@ class ClosureTest extends TestCase
|
||||
|
||||
passes("asd");',
|
||||
],
|
||||
'SKIPPED-callableWithInvokable' => [
|
||||
'callableWithInvokable' => [
|
||||
'<?php
|
||||
function asd(): void {}
|
||||
class A { public function __invoke(): void {} }
|
||||
@ -239,6 +239,36 @@ class ClosureTest extends TestCase
|
||||
|
||||
fails("asd");',
|
||||
],
|
||||
'isCallableArray' => [
|
||||
'<?php
|
||||
class A
|
||||
{
|
||||
public function callMeMaybe(string $method): void
|
||||
{
|
||||
$handleMethod = [$this, $method];
|
||||
|
||||
if (is_callable($handleMethod)) {
|
||||
$handleMethod();
|
||||
}
|
||||
}
|
||||
|
||||
public function foo(): void {}
|
||||
}
|
||||
$a = new A();
|
||||
$a->callMeMaybe("foo");',
|
||||
],
|
||||
'isCallableString' => [
|
||||
'<?php
|
||||
function foo(): void {}
|
||||
|
||||
function callMeMaybe(string $method): void {
|
||||
if (is_callable($method)) {
|
||||
$method();
|
||||
}
|
||||
}
|
||||
|
||||
callMeMaybe("foo");',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
@ -599,24 +599,6 @@ class TypeReconciliationTest extends TestCase
|
||||
return "backup";
|
||||
}',
|
||||
],
|
||||
'isCallableArray' => [
|
||||
'<?php
|
||||
class A
|
||||
{
|
||||
public function callMeMaybe(string $method): void
|
||||
{
|
||||
$handleMethod = [$this, $method];
|
||||
|
||||
if (is_callable($handleMethod)) {
|
||||
$handleMethod();
|
||||
}
|
||||
}
|
||||
|
||||
public function foo(): void {}
|
||||
}
|
||||
$a = new A();
|
||||
$a->callMeMaybe("foo");',
|
||||
],
|
||||
'stringOrCallableArg' => [
|
||||
'<?php
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user