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