1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Type\Constant;
4:
5: use PHPStan\Php\PhpVersion;
6: use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
7: use PHPStan\PhpDocParser\Ast\Type\TypeNode;
8: use PHPStan\TrinaryLogic;
9: use PHPStan\Type\BooleanType;
10: use PHPStan\Type\ConstantScalarType;
11: use PHPStan\Type\GeneralizePrecision;
12: use PHPStan\Type\MixedType;
13: use PHPStan\Type\NeverType;
14: use PHPStan\Type\StaticTypeFactory;
15: use PHPStan\Type\Traits\ConstantScalarTypeTrait;
16: use PHPStan\Type\Type;
17: use PHPStan\Type\TypeCombinator;
18: use PHPStan\Type\VerbosityLevel;
19:
20: /** @api */
21: class ConstantBooleanType extends BooleanType implements ConstantScalarType
22: {
23:
24: use ConstantScalarTypeTrait {
25: looseCompare as private scalarLooseCompare;
26: }
27:
28: /** @api */
29: public function __construct(private bool $value)
30: {
31: parent::__construct();
32: }
33:
34: public function getValue(): bool
35: {
36: return $this->value;
37: }
38:
39: public function describe(VerbosityLevel $level): string
40: {
41: return $this->value ? 'true' : 'false';
42: }
43:
44: public function getSmallerType(PhpVersion $phpVersion): Type
45: {
46: if ($this->value) {
47: return StaticTypeFactory::falsey();
48: }
49: return new NeverType();
50: }
51:
52: public function getSmallerOrEqualType(PhpVersion $phpVersion): Type
53: {
54: if ($this->value) {
55: return new MixedType();
56: }
57: return StaticTypeFactory::falsey();
58: }
59:
60: public function getGreaterType(PhpVersion $phpVersion): Type
61: {
62: if ($this->value) {
63: return new NeverType();
64: }
65: return StaticTypeFactory::truthy();
66: }
67:
68: public function getGreaterOrEqualType(PhpVersion $phpVersion): Type
69: {
70: if ($this->value) {
71: return StaticTypeFactory::truthy();
72: }
73: return new MixedType();
74: }
75:
76: public function toBoolean(): BooleanType
77: {
78: return $this;
79: }
80:
81: public function toNumber(): Type
82: {
83: return new ConstantIntegerType((int) $this->value);
84: }
85:
86: public function toAbsoluteNumber(): Type
87: {
88: return $this->toNumber()->toAbsoluteNumber();
89: }
90:
91: public function toString(): Type
92: {
93: return new ConstantStringType((string) $this->value);
94: }
95:
96: public function toInteger(): Type
97: {
98: return new ConstantIntegerType((int) $this->value);
99: }
100:
101: public function toFloat(): Type
102: {
103: return new ConstantFloatType((float) $this->value);
104: }
105:
106: public function toArrayKey(): Type
107: {
108: return new ConstantIntegerType((int) $this->value);
109: }
110:
111: public function toCoercedArgumentType(bool $strictTypes): Type
112: {
113: if (!$strictTypes) {
114: return TypeCombinator::union($this->toInteger(), $this->toFloat(), $this->toString(), $this);
115: }
116:
117: return $this;
118: }
119:
120: public function isTrue(): TrinaryLogic
121: {
122: return TrinaryLogic::createFromBoolean($this->value === true);
123: }
124:
125: public function isFalse(): TrinaryLogic
126: {
127: return TrinaryLogic::createFromBoolean($this->value === false);
128: }
129:
130: public function generalize(GeneralizePrecision $precision): Type
131: {
132: return new BooleanType();
133: }
134:
135: public function toPhpDocNode(): TypeNode
136: {
137: return new IdentifierTypeNode($this->value ? 'true' : 'false');
138: }
139:
140: public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType
141: {
142: if ($type->isObject()->yes()) {
143: return $this;
144: }
145:
146: return $this->scalarLooseCompare($type, $phpVersion);
147: }
148:
149: }
150: