Skip to content

Commit 5ef8716

Browse files
herndlmondrejmirtes
authored andcommitted
Improve HasOffsetValueType::flipArray()
1 parent 9d6854a commit 5ef8716

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

src/Type/Accessory/HasOffsetValueType.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PHPStan\ShouldNotHappenException;
66
use PHPStan\TrinaryLogic;
7+
use PHPStan\Type\ArrayType;
78
use PHPStan\Type\CompoundType;
89
use PHPStan\Type\Constant\ConstantIntegerType;
910
use PHPStan\Type\Constant\ConstantStringType;
@@ -165,6 +166,16 @@ public function getValuesArray(): Type
165166
return new NonEmptyArrayType();
166167
}
167168

169+
public function flipArray(): Type
170+
{
171+
$valueType = ArrayType::castToArrayKeyType($this->valueType);
172+
if ($valueType instanceof ConstantIntegerType || $valueType instanceof ConstantStringType) {
173+
return new self($valueType, $this->offsetType);
174+
}
175+
176+
return new MixedType();
177+
}
178+
168179
public function shuffleArray(): Type
169180
{
170181
return new NonEmptyArrayType();

tests/PHPStan/Analyser/data/array-flip.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,30 @@ function foo9($mixed)
7676
assertType('*ERROR*', array_flip($mixed));
7777
}
7878
}
79+
80+
/** @param array<string, int> $array */
81+
function foo10(array $array)
82+
{
83+
if (array_key_exists('foo', $array)) {
84+
assertType('array<string, int>&hasOffset(\'foo\')', $array);
85+
assertType('array<int, string>', array_flip($array));
86+
}
87+
88+
if (array_key_exists('foo', $array) && is_int($array['foo'])) {
89+
assertType("array<string, int>&hasOffsetValue('foo', int)", $array);
90+
assertType('array<int, string>', array_flip($array));
91+
}
92+
93+
if (array_key_exists('foo', $array) && $array['foo'] === 17) {
94+
assertType("array<string, int>&hasOffsetValue('foo', 17)", $array);
95+
assertType("array<int, string>&hasOffsetValue(17, 'foo')", array_flip($array));
96+
}
97+
98+
if (
99+
array_key_exists('foo', $array) && $array['foo'] === 17
100+
&& array_key_exists('bar', $array) && $array['bar'] === 17
101+
) {
102+
assertType("array<string, int>&hasOffsetValue('bar', 17)&hasOffsetValue('foo', 17)", $array);
103+
assertType("*NEVER*", array_flip($array)); // this could be array<string, int>&hasOffsetValue(17, 'bar') according to https://3v4l.org/1TAFk
104+
}
105+
}

0 commit comments

Comments
 (0)