Skip to content

Commit a5b5090

Browse files
herndlmondrejmirtes
authored andcommitted
Refactor options handling in FilterVarDynamicReturnTypeExtension
1 parent 5a0d736 commit a5b5090

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

src/Type/Php/FilterVarDynamicReturnTypeExtension.php

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,16 @@
88
use PHPStan\Reflection\FunctionReflection;
99
use PHPStan\Reflection\ReflectionProvider;
1010
use PHPStan\ShouldNotHappenException;
11+
use PHPStan\TrinaryLogic;
1112
use PHPStan\Type\Accessory\AccessoryNonEmptyStringType;
1213
use PHPStan\Type\Accessory\AccessoryNonFalsyStringType;
1314
use PHPStan\Type\ArrayType;
1415
use PHPStan\Type\BooleanType;
15-
use PHPStan\Type\Constant\ConstantArrayType;
1616
use PHPStan\Type\Constant\ConstantBooleanType;
1717
use PHPStan\Type\Constant\ConstantIntegerType;
1818
use PHPStan\Type\Constant\ConstantStringType;
1919
use PHPStan\Type\ConstantScalarType;
2020
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
21-
use PHPStan\Type\ErrorType;
2221
use PHPStan\Type\FloatType;
2322
use PHPStan\Type\IntegerRangeType;
2423
use PHPStan\Type\IntegerType;
@@ -27,6 +26,7 @@
2726
use PHPStan\Type\StringType;
2827
use PHPStan\Type\Type;
2928
use PHPStan\Type\TypeCombinator;
29+
use function array_merge;
3030
use function hexdec;
3131
use function is_int;
3232
use function octdec;
@@ -160,8 +160,8 @@ public function getTypeFromFunctionCall(
160160
$exactType = $this->determineExactType($inputType, $filterValue, $defaultType, $flagsType);
161161
$type = $exactType ?? $this->getFilterTypeMap()[$filterValue] ?? $mixedType;
162162

163-
$typeOptionNames = $this->getFilterTypeOptions()[$filterValue] ?? [];
164-
$otherTypes = $this->getOtherTypes($flagsType, $typeOptionNames, $defaultType);
163+
$options = $flagsType !== null && $this->hasOptions($flagsType)->yes() ? $this->getOptions($flagsType, $filterValue) : [];
164+
$otherTypes = $this->getOtherTypes($flagsType, $options, $defaultType);
165165

166166
if ($inputType->isNonEmptyString()->yes()
167167
&& $type->isString()->yes()
@@ -234,17 +234,16 @@ private function determineExactType(Type $in, int $filterValue, Type $defaultTyp
234234
}
235235

236236
/**
237-
* @param list<string> $typeOptionNames
237+
* @param array<string, ?Type> $typeOptions
238238
* @return array{default: Type, range?: Type}
239239
*/
240-
private function getOtherTypes(?Type $flagsType, array $typeOptionNames, Type $defaultType): array
240+
private function getOtherTypes(?Type $flagsType, array $typeOptions, Type $defaultType): array
241241
{
242242
$falseType = new ConstantBooleanType(false);
243243
if ($flagsType === null) {
244244
return ['default' => $falseType];
245245
}
246246

247-
$typeOptions = $this->getOptions($flagsType, 'default', ...$typeOptionNames);
248247
$defaultType = $typeOptions['default'] ?? $defaultType;
249248
$otherTypes = ['default' => $defaultType];
250249
$range = [];
@@ -272,25 +271,31 @@ private function getOtherTypes(?Type $flagsType, array $typeOptionNames, Type $d
272271
return $otherTypes;
273272
}
274273

275-
/**
276-
* @return array<string, ?Type>
277-
*/
278-
private function getOptions(Type $flagsType, string ...$optionNames): array
274+
private function hasOptions(Type $flagsType): TrinaryLogic
279275
{
280-
$options = [];
276+
return $flagsType->isConstantArray()
277+
->and($flagsType->hasOffsetValueType(new ConstantStringType('options')));
278+
}
281279

282-
if (!$flagsType instanceof ConstantArrayType) {
283-
return $options;
284-
}
280+
/** @return array<string, ?Type> */
281+
private function getOptions(Type $flagsType, int $filterValue): array
282+
{
283+
$options = [];
285284

286285
$optionsType = $flagsType->getOffsetValueType(new ConstantStringType('options'));
287-
if (!$optionsType instanceof ConstantArrayType) {
286+
if (!$optionsType->isConstantArray()->yes()) {
288287
return $options;
289288
}
290289

290+
$optionNames = array_merge(['default'], $this->getFilterTypeOptions()[$filterValue] ?? []);
291291
foreach ($optionNames as $optionName) {
292-
$type = $optionsType->getOffsetValueType(new ConstantStringType($optionName));
293-
$options[$optionName] = $type instanceof ErrorType ? null : $type;
292+
$optionaNameType = new ConstantStringType($optionName);
293+
if (!$optionsType->hasOffsetValueType($optionaNameType)->yes()) {
294+
$options[$optionName] = null;
295+
continue;
296+
}
297+
298+
$options[$optionName] = $optionsType->getOffsetValueType($optionaNameType);
294299
}
295300

296301
return $options;
@@ -309,7 +314,7 @@ private function hasFlag(int $flag, ?Type $flagsType): bool
309314

310315
private function getFlagsValue(Type $exprType): Type
311316
{
312-
if (!$exprType instanceof ConstantArrayType) {
317+
if (!$exprType->isConstantArray()->yes()) {
313318
return $exprType;
314319
}
315320

0 commit comments

Comments
 (0)