forked from phpstan/phpstan-src
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAllowedArrayKeysTypes.php
86 lines (72 loc) · 2.26 KB
/
AllowedArrayKeysTypes.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<?php declare(strict_types = 1);
namespace PHPStan\Rules\Arrays;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
use PHPStan\Type\Constant\ConstantBooleanType;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\MixedType;
use PHPStan\Type\NullType;
use PHPStan\Type\ObjectWithoutClassType;
use PHPStan\Type\ResourceType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\UnionType;
final class AllowedArrayKeysTypes
{
public static function getType(): Type
{
return new UnionType([
new IntegerType(),
new StringType(),
new FloatType(),
new BooleanType(),
new NullType(),
]);
}
public static function narrowOffsetKeyType(Type $varType, Type $keyType): ?Type
{
if (!$varType->isArray()->yes() || $varType->isIterableAtLeastOnce()->no()) {
return null;
}
$varIterableKeyType = $varType->getIterableKeyType();
if ($varIterableKeyType->isConstantScalarValue()->yes()) {
$narrowedKey = TypeCombinator::union(
$varIterableKeyType,
TypeCombinator::remove($varIterableKeyType->toString(), new ConstantStringType('')),
);
if (!$varType->hasOffsetValueType(new ConstantIntegerType(0))->no()) {
$narrowedKey = TypeCombinator::union(
$narrowedKey,
new ConstantBooleanType(false),
);
}
if (!$varType->hasOffsetValueType(new ConstantIntegerType(1))->no()) {
$narrowedKey = TypeCombinator::union(
$narrowedKey,
new ConstantBooleanType(true),
);
}
if (!$varType->hasOffsetValueType(new ConstantStringType(''))->no()) {
$narrowedKey = TypeCombinator::addNull($narrowedKey);
}
if (!$varIterableKeyType->isNumericString()->no() || !$varIterableKeyType->isInteger()->no()) {
$narrowedKey = TypeCombinator::union($narrowedKey, new FloatType());
}
return $narrowedKey;
} elseif ($varIterableKeyType->isInteger()->yes() && $keyType->isString()->yes()) {
return TypeCombinator::intersect($varIterableKeyType->toString(), $keyType);
}
return new MixedType(
false,
new UnionType([
new ArrayType(new MixedType(), new MixedType()),
new ObjectWithoutClassType(),
new ResourceType(),
]),
);
}
}