Repository navigation
Expand file tree
/
Copy pathConstantIntegerType.php
More file actions
130 lines (106 loc) · 3 KB
/
Copy pathConstantIntegerType.php
File metadata and controls
130 lines (106 loc) · 3 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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?php declare(strict_types = 1);
namespace PHPStan\Type\Constant;
use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode;
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
use PHPStan\Type\CompoundType;
use PHPStan\Type\ConstantScalarType;
use PHPStan\Type\GeneralizePrecision;
use PHPStan\Type\IntegerRangeType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\IsSuperTypeOfResult;
use PHPStan\Type\Traits\ConstantNumericComparisonTypeTrait;
use PHPStan\Type\Traits\ConstantScalarTypeTrait;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\VerbosityLevel;
use function abs;
use function is_int;
use function sprintf;
/** @api */
class ConstantIntegerType extends IntegerType implements ConstantScalarType
{
use ConstantScalarTypeTrait;
use ConstantScalarToBooleanTrait;
use ConstantNumericComparisonTypeTrait;
/** @api */
public function __construct(private int $value)
{
parent::__construct();
}
public function getValue(): int
{
return $this->value;
}
public function isSuperTypeOf(Type $type): IsSuperTypeOfResult
{
if ($type instanceof self) {
return $this->value === $type->value ? IsSuperTypeOfResult::createYes() : IsSuperTypeOfResult::createNo();
}
if ($type instanceof IntegerRangeType) {
$min = $type->getMin();
$max = $type->getMax();
if (($min === null || $min <= $this->value) && ($max === null || $this->value <= $max)) {
return IsSuperTypeOfResult::createMaybe();
}
return IsSuperTypeOfResult::createNo();
}
if ($type instanceof parent) {
return IsSuperTypeOfResult::createMaybe();
}
if ($type instanceof CompoundType) {
return $type->isSubTypeOf($this);
}
return IsSuperTypeOfResult::createNo();
}
public function describe(VerbosityLevel $level): string
{
return $level->handle(
static fn (): string => 'int',
fn (): string => sprintf('%s', $this->value),
);
}
public function toFloat(): Type
{
return new ConstantFloatType($this->value);
}
public function toBitwiseNotType(): Type
{
return new self(~$this->value);
}
public function toAbsoluteNumber(): Type
{
$absoluteValue = abs($this->value);
if (!is_int($absoluteValue)) {
// The absolute value of the smallest integer is not representable as an int.
return new ConstantFloatType($absoluteValue);
}
return new self($absoluteValue);
}
public function toString(): Type
{
return new ConstantStringType((string) $this->value);
}
public function toArrayKey(): Type
{
return $this;
}
public function toCoercedArgumentType(bool $strictTypes): Type
{
if (!$strictTypes) {
return TypeCombinator::union($this, $this->toFloat(), $this->toString(), $this->toBoolean());
}
return TypeCombinator::union($this, $this->toFloat());
}
public function generalize(GeneralizePrecision $precision): Type
{
return new IntegerType();
}
/**
* @return ConstTypeNode
*/
public function toPhpDocNode(): TypeNode
{
return new ConstTypeNode(new ConstExprIntegerNode((string) $this->value));
}
}