Skip to content

Commit 68cdfe3

Browse files
authored
Remove deprecated instanceof (#185)
1 parent 2189394 commit 68cdfe3

File tree

2 files changed

+97
-65
lines changed

2 files changed

+97
-65
lines changed

src/GetTermsDynamicFunctionReturnTypeExtension.php

Lines changed: 26 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
use PHPStan\Type\IntegerType;
1717
use PHPStan\Type\ObjectType;
1818
use PHPStan\Type\StringType;
19-
use PHPStan\Type\Constant\ConstantArrayType;
20-
use PHPStan\Type\Constant\ConstantStringType;
21-
use PHPStan\Type\ConstantScalarType;
2219
use PHPStan\Type\TypeCombinator;
20+
use PHPStan\Type\Accessory\AccessoryNumericStringType;
21+
use PHPStan\Type\Constant\ConstantStringType;
22+
2323

2424
class GetTermsDynamicFunctionReturnTypeExtension implements \PHPStan\Type\DynamicFunctionReturnTypeExtension
2525
{
@@ -61,27 +61,35 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
6161
}
6262

6363
$argument = $scope->getType($functionCall->getArgs()[$argsParameterPosition]->value);
64+
$returnTypes = [];
6465

65-
if (!($argument instanceof ConstantArrayType)) {
66-
// Without constant array argument return default return type
66+
if ($argument->isConstantArray()->no()) {
6767
return self::defaultType();
6868
}
69-
70-
$args = self::getArgs($argument);
71-
72-
if ($args === null) {
73-
return self::defaultType();
69+
if ($argument->isConstantArray()->maybe()) {
70+
$returnTypes[] = self::defaultType();
7471
}
7572

76-
if (isset($args['count']) && $args['count'] === true) {
77-
return self::countType();
78-
}
73+
foreach ($argument->getConstantArrays() as $args) {
74+
if ($args->hasOffsetValueType(new ConstantStringType('fields'))->no()) {
75+
$returnTypes[] = self::termsType();
76+
continue;
77+
}
78+
if ($args->hasOffsetValueType(new ConstantStringType('fields'))->maybe()) {
79+
$returnTypes[] = self::defaultType();
80+
continue;
81+
}
7982

80-
if (! isset($args['fields'], $args['count']) || ! is_string($args['fields'])) {
81-
return self::defaultType();
83+
$fieldsValueTypes = $args->getOffsetValueType(new ConstantStringType('fields'))->getConstantStrings();
84+
if (count($fieldsValueTypes) === 0) {
85+
$returnTypes[] = self::defaultType();
86+
continue;
87+
}
88+
foreach ($fieldsValueTypes as $fieldsValueType) {
89+
$returnTypes[] = self::deduceTypeFromFields($fieldsValueType->getValue());
90+
}
8291
}
83-
84-
return self::deduceTypeFromFields($args['fields']);
92+
return TypeCombinator::union(...$returnTypes);
8593
}
8694

8795
protected static function deduceTypeFromFields(string $fields): Type
@@ -106,33 +114,6 @@ protected static function deduceTypeFromFields(string $fields): Type
106114
}
107115
}
108116

109-
/**
110-
* @return array<string, mixed>
111-
*/
112-
protected static function getArgs(ConstantArrayType $argument): ?array
113-
{
114-
$args = [
115-
'fields' => 'all',
116-
'count' => false,
117-
];
118-
119-
foreach ($argument->getKeyTypes() as $index => $key) {
120-
if (! $key instanceof ConstantStringType) {
121-
return null;
122-
}
123-
124-
unset($args[$key->getValue()]);
125-
$fieldsType = $argument->getValueTypes()[$index];
126-
if (!($fieldsType instanceof ConstantScalarType)) {
127-
continue;
128-
}
129-
130-
$args[$key->getValue()] = $fieldsType->getValue();
131-
}
132-
133-
return $args;
134-
}
135-
136117
protected static function countType(): Type
137118
{
138119
return TypeCombinator::union(
@@ -160,7 +141,7 @@ protected static function idsType(): Type
160141
protected static function parentsType(): Type
161142
{
162143
return TypeCombinator::union(
163-
new ArrayType(new IntegerType(), new StringType()),
144+
new ArrayType(new IntegerType(), new AccessoryNumericStringType()),
164145
new ObjectType('WP_Error')
165146
);
166147
}

tests/data/get_terms.php

Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,32 +6,13 @@
66

77
use function PHPStan\Testing\assertType;
88

9-
$fields = $_GET['fields'] ?? 'all';
10-
$key = $_GET['key'] ?? 'fields';
11-
$count = ! empty( $_GET['count'] );
12-
139
// Default argument values
1410
assertType('array<int, WP_Term>|WP_Error', get_terms());
1511
assertType('array<int, WP_Term>|WP_Error', get_terms([]));
1612

17-
// Unknown values
18-
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['fields'=>$fields]));
19-
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['foo'=>'bar','fields'=>$fields]));
20-
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['count'=>$count]));
21-
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['count'=>$count,'fields'=>'ids']));
22-
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['fields'=>$fields,'count'=>false]));
23-
24-
// Unknown keys
25-
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms([$key=>'all']));
26-
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['foo'=>'bar',$key=>'all']));
27-
2813
// Requesting a count
2914
assertType('string|WP_Error', get_terms(['fields'=>'count']));
3015
assertType('string|WP_Error', get_terms(['foo'=>'bar','fields'=>'count']));
31-
assertType('string|WP_Error', get_terms(['count'=>true]));
32-
assertType('string|WP_Error', get_terms(['foo'=>'bar','count'=>true]));
33-
assertType('string|WP_Error', get_terms(['fields'=>'ids','count'=>true]));
34-
assertType('string|WP_Error', get_terms(['fields'=>$fields,'count'=>true]));
3516

3617
// Requesting names or slugs
3718
assertType('array<int, string>|WP_Error', get_terms(['fields'=>'names']));
@@ -44,7 +25,7 @@
4425
assertType('array<int, int>|WP_Error', get_terms(['fields'=>'tt_ids']));
4526

4627
// Requesting parent IDs (numeric strings)
47-
assertType('array<int, string>|WP_Error', get_terms(['fields'=>'id=>parent']));
28+
assertType('array<int, numeric-string>|WP_Error', get_terms(['fields'=>'id=>parent']));
4829

4930
// Requesting objects
5031
assertType('array<int, WP_Term>|WP_Error', get_terms(['fields'=>'all']));
@@ -60,3 +41,73 @@
6041
assertType('array<int, WP_Term>|WP_Error', wp_get_post_categories(123));
6142
assertType('array<int, WP_Term>|WP_Error', wp_get_post_tags(123));
6243
assertType('array<int, WP_Term>|WP_Error', wp_get_post_terms(123, 'category'));
44+
45+
// Unions - nonexhaustive list
46+
$fields = $_GET['foo'] ? (string)$_GET['string'] : 'all';
47+
$key = $_GET['foo'] ? (string)$_GET['string'] : 'fields';
48+
$count = ! empty( $_GET['count'] );
49+
50+
$union = $_GET['foo'] ? ['key'=>'value'] : ['some'=>'thing'];
51+
assertType('array<int, WP_Term>|WP_Error', get_terms($union));
52+
53+
$union = $_GET['foo'] ? ['key'=>'value'] : ['fields'=>'count'];
54+
assertType('array<int, WP_Term>|string|WP_Error', get_terms($union));
55+
56+
$union = $_GET['foo'] ? ['key'=>'value'] : ['fields'=>'names'];
57+
assertType('array<int, string|WP_Term>|WP_Error', get_terms($union));
58+
59+
$union = $_GET['foo'] ? ['key'=>'value'] : ['fields'=>'ids'];
60+
assertType('array<int, int|WP_Term>|WP_Error', get_terms($union));
61+
62+
$union = $_GET['foo'] ? ['key'=>'value'] : ['fields'=>'id=>parent'];
63+
assertType('array<int, WP_Term|numeric-string>|WP_Error', get_terms($union));
64+
65+
$union = $_GET['foo'] ? ['key'=>'value'] : ['fields'=>'all'];
66+
assertType('array<int, WP_Term>|WP_Error', get_terms($union));
67+
68+
$union = $_GET['foo'] ? ['fields'=>'names'] : ['fields'=>'count'];
69+
assertType('array<int, string>|string|WP_Error', get_terms($union));
70+
71+
$union = $_GET['foo'] ? ['fields'=>'id=>parent'] : ['fields'=>'ids'];
72+
assertType('array<int, int|numeric-string>|WP_Error', get_terms($union));
73+
74+
$union = $_GET['foo'] ? ['fields'=>'all'] : ['fields'=>'count'];
75+
assertType('array<int, WP_Term>|string|WP_Error', get_terms($union));
76+
77+
// Unions with unknown fields value
78+
$union = $_GET['foo'] ? (string)$_GET['string'] : 'all';
79+
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['fields'=>$union]));
80+
81+
$union = $_GET['foo'] ? (string)$_GET['string'] : 'ids';
82+
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['fields'=>$union]));
83+
84+
$union = $_GET['foo'] ? (string)$_GET['string'] : 'id=>parent';
85+
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['fields'=>$union]));
86+
87+
$union = $_GET['foo'] ? (string)$_GET['string'] : 'count';
88+
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['fields'=>$union]));
89+
90+
$union = $_GET['foo'] ? (string)$_GET['string'] : 'names';
91+
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['fields'=>$union]));
92+
93+
$union = $_GET['foo'] ? (string)$_GET['string'] : 'all';
94+
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['foo'=>'bar','fields'=>$union]));
95+
96+
// Unions with unknown fields key - not supported
97+
$union = $_GET['foo'] ? (string)$_GET['string'] : 'fields';
98+
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms([$union=>'all']));
99+
100+
$union = $_GET['foo'] ? (string)$_GET['string'] : 'fields';
101+
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms([$union=>'ids']));
102+
103+
$union = $_GET['foo'] ? (string)$_GET['string'] : 'fields';
104+
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms([$union=>'id=>parent']));
105+
106+
$union = $_GET['foo'] ? (string)$_GET['string'] : 'fields';
107+
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms([$union=>'count']));
108+
109+
$union = $_GET['foo'] ? (string)$_GET['string'] : 'fields';
110+
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms([$union=>'names']));
111+
112+
$union = $_GET['foo'] ? (string)$_GET['string'] : 'fields';
113+
assertType('array<int, int|string|WP_Term>|string|WP_Error', get_terms(['foo'=>'bar',$union=>'all']));

0 commit comments

Comments
 (0)