Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 1c01253

Browse files
Merge branch '1.8.x' into 1.9.x
2 parents 1982880 + 3552fe3 commit 1c01253

File tree

5 files changed

+81
-1
lines changed

5 files changed

+81
-1
lines changed

‎src/Type/Php/ArrayKeyExistsFunctionTypeSpecifyingExtension.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use PHPStan\Type\MixedType;
2222
use PHPStan\Type\TypeCombinator;
2323
use function count;
24+
use function in_array;
2425

2526
class ArrayKeyExistsFunctionTypeSpecifyingExtension implements FunctionTypeSpecifyingExtension, TypeSpecifierAwareExtension
2627
{
@@ -38,7 +39,7 @@ public function isFunctionSupported(
3839
TypeSpecifierContext $context,
3940
): bool
4041
{
41-
return $functionReflection->getName() === 'array_key_exists'
42+
return in_array($functionReflection->getName(), ['array_key_exists', 'key_exists'], true)
4243
&& !$context->null();
4344
}
4445

‎src/Type/Php/TypeSpecifyingFunctionsDynamicReturnTypeExtension.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public function isFunctionSupported(FunctionReflection $functionReflection): boo
3939
{
4040
return in_array($functionReflection->getName(), [
4141
'array_key_exists',
42+
'key_exists',
4243
'in_array',
4344
'is_numeric',
4445
'is_int',

‎tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,7 @@ public function dataFileAsserts(): iterable
10111011
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-6170.php');
10121012
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/slevomat-foreach-array-key-exists-bug.php');
10131013
yield from $this->gatherAssertTypes(__DIR__ . '/data/array-key-exists.php');
1014+
yield from $this->gatherAssertTypes(__DIR__ . '/data/key-exists.php');
10141015
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7909.php');
10151016

10161017
if (PHP_VERSION_ID >= 80000) {

‎tests/PHPStan/Analyser/TypeSpecifierTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,54 @@ public function dataCondition(): array
954954
'$array' => '~hasOffset(\'foo\')',
955955
],
956956
],
957+
[
958+
new Expr\BinaryOp\BooleanOr(
959+
new FuncCall(new Name('key_exists'), [
960+
new Arg(new String_('foo')),
961+
new Arg(new Variable('array')),
962+
]),
963+
new FuncCall(new Name('key_exists'), [
964+
new Arg(new String_('bar')),
965+
new Arg(new Variable('array')),
966+
]),
967+
),
968+
[
969+
'$array' => 'array',
970+
],
971+
[
972+
'$array' => '~hasOffset(\'bar\')|hasOffset(\'foo\')',
973+
],
974+
],
975+
[
976+
new BooleanNot(new Expr\BinaryOp\BooleanOr(
977+
new FuncCall(new Name('key_exists'), [
978+
new Arg(new String_('foo')),
979+
new Arg(new Variable('array')),
980+
]),
981+
new FuncCall(new Name('key_exists'), [
982+
new Arg(new String_('bar')),
983+
new Arg(new Variable('array')),
984+
]),
985+
)),
986+
[
987+
'$array' => '~hasOffset(\'bar\')|hasOffset(\'foo\')',
988+
],
989+
[
990+
'$array' => 'array',
991+
],
992+
],
993+
[
994+
new FuncCall(new Name('key_exists'), [
995+
new Arg(new String_('foo')),
996+
new Arg(new Variable('array')),
997+
]),
998+
[
999+
'$array' => 'array&hasOffset(\'foo\')',
1000+
],
1001+
[
1002+
'$array' => '~hasOffset(\'foo\')',
1003+
],
1004+
],
9571005
[
9581006
new FuncCall(new Name('is_subclass_of'), [
9591007
new Arg(new Variable('string')),
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
namespace KeyExists;
4+
5+
use function key_exists;
6+
use function PHPStan\Testing\assertType;
7+
8+
class KeyExists
9+
{
10+
/**
11+
* @param array<string, string> $a
12+
* @return void
13+
*/
14+
public function doFoo(array $a, string $key): void
15+
{
16+
assertType('false', key_exists(2, $a));
17+
assertType('bool', key_exists('foo', $a));
18+
assertType('false', key_exists('2', $a));
19+
20+
$a = ['foo' => 2, 3 => 'bar'];
21+
assertType('true', key_exists('foo', $a));
22+
assertType('true', key_exists('3', $a));
23+
assertType('false', key_exists(4, $a));
24+
25+
$empty = [];
26+
assertType('false', key_exists('foo', $empty));
27+
assertType('false', key_exists($key, $empty));
28+
}
29+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /