mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 13:51:54 +01:00
Fix array_column with object and column name null
This commit is contained in:
parent
9ed9c4b64c
commit
602e26edd4
@ -36,7 +36,7 @@ class ArrayColumnReturnTypeProvider implements FunctionReturnTypeProviderInterfa
|
||||
return Type::getMixed();
|
||||
}
|
||||
|
||||
$row_shape = null;
|
||||
$row_type = $row_shape = null;
|
||||
$input_array_not_empty = false;
|
||||
|
||||
// calculate row shape
|
||||
@ -45,7 +45,6 @@ class ArrayColumnReturnTypeProvider implements FunctionReturnTypeProviderInterfa
|
||||
&& $first_arg_type->hasArray()
|
||||
) {
|
||||
$input_array = $first_arg_type->getAtomicTypes()['array'];
|
||||
$row_type = null;
|
||||
if ($input_array instanceof TKeyedArray) {
|
||||
$row_type = $input_array->getGenericArrayType()->type_params[1];
|
||||
} elseif ($input_array instanceof TArray) {
|
||||
@ -104,7 +103,7 @@ class ArrayColumnReturnTypeProvider implements FunctionReturnTypeProviderInterfa
|
||||
}
|
||||
|
||||
$result_key_type = Type::getArrayKey();
|
||||
$result_element_type = null;
|
||||
$result_element_type = null !== $row_type && $value_column_name_is_null ? $row_type : null;
|
||||
$have_at_least_one_res = false;
|
||||
// calculate results
|
||||
if ($row_shape instanceof TKeyedArray) {
|
||||
@ -116,9 +115,7 @@ class ArrayColumnReturnTypeProvider implements FunctionReturnTypeProviderInterfa
|
||||
}
|
||||
//array_column skips undefined elements so resulting type is necessarily defined
|
||||
$result_element_type->possibly_undefined = false;
|
||||
} elseif ($value_column_name_is_null) {
|
||||
$result_element_type = new Union([$row_shape]);
|
||||
} else {
|
||||
} elseif (!$value_column_name_is_null) {
|
||||
$result_element_type = Type::getMixed();
|
||||
}
|
||||
|
||||
|
@ -3,10 +3,12 @@
|
||||
namespace Psalm\Tests\ReturnTypeProvider;
|
||||
|
||||
use Psalm\Tests\TestCase;
|
||||
use Psalm\Tests\Traits\InvalidCodeAnalysisTestTrait;
|
||||
use Psalm\Tests\Traits\ValidCodeAnalysisTestTrait;
|
||||
|
||||
class ArrayColumnTest extends TestCase
|
||||
{
|
||||
use InvalidCodeAnalysisTestTrait;
|
||||
use ValidCodeAnalysisTestTrait;
|
||||
|
||||
public function providerValidCodeParse(): iterable
|
||||
@ -61,5 +63,95 @@ class ArrayColumnTest extends TestCase
|
||||
}
|
||||
',
|
||||
];
|
||||
|
||||
yield 'arrayColumnWithObjectsAndColumnNameNull' => [
|
||||
'<?php
|
||||
class C {
|
||||
/** @var string */
|
||||
public $name = "";
|
||||
public function foo(): void {}
|
||||
}
|
||||
|
||||
foreach (array_column([new C, new C], null, "name") as $instance) {
|
||||
$instance->foo();
|
||||
}
|
||||
',
|
||||
];
|
||||
|
||||
yield 'arrayColumnWithIntersectionAndColumnNameNull' => [
|
||||
'<?php
|
||||
interface I {
|
||||
public function foo(): void;
|
||||
}
|
||||
abstract class A {
|
||||
/** @var string */
|
||||
public $name = "";
|
||||
abstract public function bar(): void;
|
||||
}
|
||||
class C extends A implements I {
|
||||
public function foo(): void {}
|
||||
public function bar(): void {}
|
||||
}
|
||||
|
||||
/** @var (A&I)[] $instances */
|
||||
$instances = [];
|
||||
foreach (array_column($instances, null, "name") as $instance) {
|
||||
$instance->foo();
|
||||
$instance->bar();
|
||||
}
|
||||
',
|
||||
];
|
||||
|
||||
yield 'arrayColumnWithArrayAndColumnNameNull' => [
|
||||
'<?php
|
||||
class C {
|
||||
/** @var string */
|
||||
public $name = "";
|
||||
public function foo(): void {}
|
||||
}
|
||||
|
||||
foreach (array_column([["name" => "", "instance" => new C]], null, "name") as $array) {
|
||||
$array["instance"]->foo();
|
||||
}
|
||||
',
|
||||
];
|
||||
|
||||
yield 'arrayColumnWithListOfObject' => [
|
||||
'<?php
|
||||
function foo(object $object): void {}
|
||||
|
||||
/** @var list<object> $instances */
|
||||
$instances = [];
|
||||
foreach (array_column($instances, null, "name") as $instance) {
|
||||
foo($instance);
|
||||
}
|
||||
',
|
||||
];
|
||||
|
||||
yield 'arrayColumnWithListOfArrays' => [
|
||||
'<?php
|
||||
function foo(array $array): void {}
|
||||
|
||||
/** @var list<array> $arrays */
|
||||
$arrays = [];
|
||||
foreach (array_column($arrays, null, "name") as $array) {
|
||||
foo($array);
|
||||
}
|
||||
',
|
||||
];
|
||||
}
|
||||
|
||||
public function providerInvalidCodeParse(): iterable
|
||||
{
|
||||
yield 'arrayColumnWithArrayAndColumnNameNull' => [
|
||||
'<?php
|
||||
/** @var list<array{name: string, instance: object}> $arrays */
|
||||
$arrays = [];
|
||||
foreach (array_column($arrays, null, "name") as $array) {
|
||||
$array["instance"]->foo();
|
||||
}
|
||||
',
|
||||
'error_message' => 'MixedMethodCall',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user