1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Type\Constant;
4:
5: use PHPStan\PhpDocParser\Ast\ConstExpr\ConstExprIntegerNode;
6: use PHPStan\PhpDocParser\Ast\Type\ConstTypeNode;
7: use PHPStan\PhpDocParser\Ast\Type\TypeNode;
8: use PHPStan\TrinaryLogic;
9: use PHPStan\Type\CompoundType;
10: use PHPStan\Type\ConstantScalarType;
11: use PHPStan\Type\GeneralizePrecision;
12: use PHPStan\Type\IntegerRangeType;
13: use PHPStan\Type\IntegerType;
14: use PHPStan\Type\Traits\ConstantNumericComparisonTypeTrait;
15: use PHPStan\Type\Traits\ConstantScalarTypeTrait;
16: use PHPStan\Type\Type;
17: use PHPStan\Type\VerbosityLevel;
18: use function sprintf;
19:
20: /** @api */
21: class ConstantIntegerType extends IntegerType implements ConstantScalarType
22: {
23:
24: use ConstantScalarTypeTrait;
25: use ConstantScalarToBooleanTrait;
26: use ConstantNumericComparisonTypeTrait;
27:
28: /** @api */
29: public function __construct(private int $value)
30: {
31: parent::__construct();
32: }
33:
34: public function getValue(): int
35: {
36: return $this->value;
37: }
38:
39: public function isSuperTypeOf(Type $type): TrinaryLogic
40: {
41: if ($type instanceof self) {
42: return $this->value === $type->value ? TrinaryLogic::createYes() : TrinaryLogic::createNo();
43: }
44:
45: if ($type instanceof IntegerRangeType) {
46: $min = $type->getMin();
47: $max = $type->getMax();
48: if (($min === null || $min <= $this->value) && ($max === null || $this->value <= $max)) {
49: return TrinaryLogic::createMaybe();
50: }
51:
52: return TrinaryLogic::createNo();
53: }
54:
55: if ($type instanceof parent) {
56: return TrinaryLogic::createMaybe();
57: }
58:
59: if ($type instanceof CompoundType) {
60: return $type->isSubTypeOf($this);
61: }
62:
63: return TrinaryLogic::createNo();
64: }
65:
66: public function describe(VerbosityLevel $level): string
67: {
68: return $level->handle(
69: static fn (): string => 'int',
70: fn (): string => sprintf('%s', $this->value),
71: );
72: }
73:
74: public function toFloat(): Type
75: {
76: return new ConstantFloatType($this->value);
77: }
78:
79: public function toString(): Type
80: {
81: return new ConstantStringType((string) $this->value);
82: }
83:
84: public function toArrayKey(): Type
85: {
86: return $this;
87: }
88:
89: public function generalize(GeneralizePrecision $precision): Type
90: {
91: return new IntegerType();
92: }
93:
94: /**
95: * @return ConstTypeNode
96: */
97: public function toPhpDocNode(): TypeNode
98: {
99: return new ConstTypeNode(new ConstExprIntegerNode((string) $this->value));
100: }
101:
102: /**
103: * @param mixed[] $properties
104: */
105: public static function __set_state(array $properties): Type
106: {
107: return new self($properties['value']);
108: }
109:
110: }
111: