Skip to content

Commit 4314243

Browse files
herndlmondrejmirtes
authored andcommitted
Use TypeUtils::getOldConstantArrays in array_key_first and array_key_last extensions
1 parent 7cb0d37 commit 4314243

5 files changed

+65
-11
lines changed

src/Type/Constant/ConstantArrayType.php

+28-2
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,32 @@ public function getKeyTypes(): array
212212
return $this->keyTypes;
213213
}
214214

215+
public function getFirstKeyType(): Type
216+
{
217+
$keyTypes = [];
218+
foreach ($this->keyTypes as $i => $keyType) {
219+
$keyTypes[] = $keyType;
220+
if (!$this->isOptionalKey($i)) {
221+
break;
222+
}
223+
}
224+
225+
return TypeCombinator::union(...$keyTypes);
226+
}
227+
228+
public function getLastKeyType(): Type
229+
{
230+
$keyTypes = [];
231+
for ($i = count($this->keyTypes) - 1; $i >= 0; $i--) {
232+
$keyTypes[] = $this->keyTypes[$i];
233+
if (!$this->isOptionalKey($i)) {
234+
break;
235+
}
236+
}
237+
238+
return TypeCombinator::union(...$keyTypes);
239+
}
240+
215241
/**
216242
* @return array<int, Type>
217243
*/
@@ -223,8 +249,8 @@ public function getValueTypes(): array
223249
public function getFirstValueType(): Type
224250
{
225251
$valueTypes = [];
226-
for ($i = 0, $keyTypesCount = count($this->keyTypes); $i < $keyTypesCount; $i++) {
227-
$valueTypes[] = $this->valueTypes[$i];
252+
foreach ($this->valueTypes as $i => $valueType) {
253+
$valueTypes[] = $valueType;
228254
if (!$this->isOptionalKey($i)) {
229255
break;
230256
}

src/Type/Php/ArrayKeyFirstDynamicReturnTypeExtension.php

+3-4
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,16 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
3333
return new NullType();
3434
}
3535

36-
$constantArrays = TypeUtils::getConstantArrays($argType);
36+
$constantArrays = TypeUtils::getOldConstantArrays($argType);
3737
if (count($constantArrays) > 0) {
3838
$keyTypes = [];
3939
foreach ($constantArrays as $constantArray) {
40-
$arrayKeyTypes = $constantArray->getKeyTypes();
41-
if (count($arrayKeyTypes) === 0) {
40+
if ($constantArray->isEmpty()) {
4241
$keyTypes[] = new NullType();
4342
continue;
4443
}
4544

46-
$keyTypes[] = $arrayKeyTypes[0];
45+
$keyTypes[] = $constantArray->getFirstKeyType();
4746
}
4847

4948
return TypeCombinator::union(...$keyTypes);

src/Type/Php/ArrayKeyLastDynamicReturnTypeExtension.php

+3-4
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,16 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
3333
return new NullType();
3434
}
3535

36-
$constantArrays = TypeUtils::getConstantArrays($argType);
36+
$constantArrays = TypeUtils::getOldConstantArrays($argType);
3737
if (count($constantArrays) > 0) {
3838
$keyTypes = [];
3939
foreach ($constantArrays as $constantArray) {
40-
$arrayKeyTypes = $constantArray->getKeyTypes();
41-
if (count($arrayKeyTypes) === 0) {
40+
if ($constantArray->isEmpty()) {
4241
$keyTypes[] = new NullType();
4342
continue;
4443
}
4544

46-
$keyTypes[] = $arrayKeyTypes[count($arrayKeyTypes) - 1];
45+
$keyTypes[] = $constantArray->getLastKeyType();
4746
}
4847

4948
return TypeCombinator::union(...$keyTypes);

tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php

+24
Original file line numberDiff line numberDiff line change
@@ -8772,6 +8772,30 @@ public function dataPhp73Functions(): array
87728772
'2|3',
87738773
'array_key_last($anotherLiteralArray)',
87748774
],
8775+
[
8776+
"'a'|'b'",
8777+
'array_key_first($constantArrayOptionalKeys1)',
8778+
],
8779+
[
8780+
"'c'",
8781+
'array_key_last($constantArrayOptionalKeys1)',
8782+
],
8783+
[
8784+
"'a'",
8785+
'array_key_first($constantArrayOptionalKeys2)',
8786+
],
8787+
[
8788+
"'c'",
8789+
'array_key_last($constantArrayOptionalKeys2)',
8790+
],
8791+
[
8792+
"'a'",
8793+
'array_key_first($constantArrayOptionalKeys3)',
8794+
],
8795+
[
8796+
"'b'|'c'",
8797+
'array_key_last($constantArrayOptionalKeys3)',
8798+
],
87758799
[
87768800
'array{int, int}',
87778801
'$hrtime1',

tests/PHPStan/Analyser/data/php73_functions.php

+7-1
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@ class Foo
1111
* @param array $mixedArray
1212
* @param array $nonEmptyArray
1313
* @param array<string, mixed> $arrayWithStringKeys
14+
* @param array{a?: 0, b: 1, c: 2} $constantArrayOptionalKeys1
15+
* @param array{a: 0, b?: 1, c: 2} $constantArrayOptionalKeys2
16+
* @param array{a: 0, b: 1, c?: 2} $constantArrayOptionalKeys3
1417
*/
1518
public function doFoo(
1619
$mixed,
1720
int $integer,
1821
array $mixedArray,
1922
array $nonEmptyArray,
20-
array $arrayWithStringKeys
23+
array $arrayWithStringKeys,
24+
array $constantArrayOptionalKeys1,
25+
array $constantArrayOptionalKeys2,
26+
array $constantArrayOptionalKeys3
2127
)
2228
{
2329
if (count($nonEmptyArray) === 0) {

0 commit comments

Comments
 (0)