Skip to content

Commit

Permalink
Merge pull request #8491 from HypeMC/array-column-fix
Browse files Browse the repository at this point in the history
Fix array_column with object and column name null
  • Loading branch information
orklah committed Sep 18, 2022
2 parents 89b034a + 602e26e commit 5db5991
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 6 deletions.
Expand Up @@ -36,7 +36,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev
return Type::getMixed();
}

$row_shape = null;
$row_type = $row_shape = null;
$input_array_not_empty = false;

// calculate row shape
Expand All @@ -45,7 +45,6 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev
&& $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) {
Expand Down Expand Up @@ -104,7 +103,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev
}

$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) {
Expand All @@ -116,9 +115,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev
}
//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();
}

Expand Down
92 changes: 92 additions & 0 deletions tests/ReturnTypeProvider/ArrayColumnTest.php
Expand Up @@ -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
Expand Down Expand Up @@ -61,5 +63,95 @@ function f(array $shape): array {
}
',
];

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',
];
}
}

0 comments on commit 5db5991

Please sign in to comment.