-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathGuessTypeFromSwitcherAttributes.php
More file actions
74 lines (63 loc) · 2.17 KB
/
GuessTypeFromSwitcherAttributes.php
File metadata and controls
74 lines (63 loc) · 2.17 KB
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
<?php
namespace WPSyntex\Polylang\PHPStan;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\CallLike;
use PhpParser\Node\Arg;
use PHPStan\Analyser\Scope;
use PHPStan\TrinaryLogic;
use PHPStan\Type\Type;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\IntersectionType;
use PHPStan\Type\StringType;
use PHPStan\Type\ArrayType;
use PHPStan\Type\MixedType;
use PHPStan\Type\TypeCombinator;
trait GuessTypeFromSwitcherAttributes {
private function guessType(Arg $args, Scope $scope) : Type
{
$args = $args->value;
$isRaw = TrinaryLogic::createMaybe();
if ($args instanceof Expr) {
$argsType = $scope->getType($args);
$argsKeys = [];
$argsValues = [];
if ($argsType->isArray()->yes()) {
$argsKeys = $argsType->getKeysArray();
$argsValues = $argsType->getValuesArray();
}
if ($argsType instanceof IntersectionType && $argsType->isIterable()) {
// Let's look into each types to see if it contains 'raw' key.
foreach($argsType->getTypes() as $type) {
if ($type->hasOffsetValueType(new ConstantStringType('raw'))->yes()) {
$isRaw = $type->getOffsetValueType(new ConstantStringType('raw'))->getValue() ? TrinaryLogic::createYes() : TrinaryLogic::createNo();
}
}
}
if ($argsKeys->isConstantArray()->yes()) {
foreach ($argsKeys->getValueTypes() as $index => $key) {
if ($key->getValue() !== 'raw') {
// Current argument is not 'raw' parameter.
continue;
}
if ($argsValues->getValueTypes()[$index]->getValue()) {
// Current argument set 'raw' to 'true'.
$isRaw = TrinaryLogic::createYes();
break;
}
}
// If none 'raw' parameter set to 'true' is found, consider it's 'false'.
$isRaw = $isRaw->yes() ? $isRaw : TrinaryLogic::createNo();
}
}
if ($isRaw->maybe()) {
// Can't guess type precisely, return 'array<string, mixed>|string'.
return TypeCombinator::union(new ArrayType(new StringType(), new MixedType()), new StringType());
}
if ($isRaw->yes()) {
// Switcher output is raw, return 'array<string, mixed>'.
return new ArrayType(new StringType(), new MixedType());
}
// Raw is considered false, return 'string'.
return new StringType();
}
}