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