1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Type;
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\Constant\ConstantArrayType;
11: use PHPStan\Type\Constant\ConstantBooleanType;
12: use PHPStan\Type\Constant\ConstantFloatType;
13: use PHPStan\Type\Constant\ConstantIntegerType;
14: use PHPStan\Type\Constant\ConstantStringType;
15: use PHPStan\Type\Traits\NonArrayTypeTrait;
16: use PHPStan\Type\Traits\NonCallableTypeTrait;
17: use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
18: use PHPStan\Type\Traits\NonGenericTypeTrait;
19: use PHPStan\Type\Traits\NonIterableTypeTrait;
20: use PHPStan\Type\Traits\NonObjectTypeTrait;
21: use PHPStan\Type\Traits\NonOffsetAccessibleTypeTrait;
22: use PHPStan\Type\Traits\UndecidedBooleanTypeTrait;
23: use PHPStan\Type\Traits\UndecidedComparisonTypeTrait;
24:
25: /** @api */
26: #[ReferencedByTurboExtension(key: 'booleanType')]
27: #[InstanceofDeprecated(insteadUse: 'Type::isBoolean()')]
28: class BooleanType implements Type
29: {
30:
31: use JustNullableTypeTrait;
32: use NonArrayTypeTrait;
33: use NonCallableTypeTrait;
34: use NonIterableTypeTrait;
35: use NonObjectTypeTrait;
36: use UndecidedBooleanTypeTrait;
37: use UndecidedComparisonTypeTrait;
38: use NonGenericTypeTrait;
39: use NonOffsetAccessibleTypeTrait;
40: use NonGeneralizableTypeTrait;
41:
42: /** @api */
43: public function __construct()
44: {
45: }
46:
47: public function getConstantStrings(): array
48: {
49: return [];
50: }
51:
52: public function getConstantScalarTypes(): array
53: {
54: return [new ConstantBooleanType(true), new ConstantBooleanType(false)];
55: }
56:
57: public function getConstantScalarValues(): array
58: {
59: return [true, false];
60: }
61:
62: public function describe(VerbosityLevel $level): string
63: {
64: return 'bool';
65: }
66:
67: public function toNumber(): Type
68: {
69: return $this->toInteger();
70: }
71:
72: public function toBitwiseNotType(): Type
73: {
74: return new ErrorType();
75: }
76:
77: public function toAbsoluteNumber(): Type
78: {
79: return $this->toNumber()->toAbsoluteNumber();
80: }
81:
82: public function toString(): Type
83: {
84: return new UnionType([
85: new ConstantStringType(''),
86: new ConstantStringType('1'),
87: ]);
88: }
89:
90: public function toInteger(): Type
91: {
92: return new UnionType([
93: new ConstantIntegerType(0),
94: new ConstantIntegerType(1),
95: ]);
96: }
97:
98: public function toFloat(): Type
99: {
100: return new UnionType([
101: new ConstantFloatType(0.0),
102: new ConstantFloatType(1.0),
103: ]);
104: }
105:
106: public function toArray(): Type
107: {
108: return new ConstantArrayType(
109: [new ConstantIntegerType(0)],
110: [$this],
111: [1],
112: isList: TrinaryLogic::createYes(),
113: );
114: }
115:
116: public function toArrayKey(): Type
117: {
118: return new UnionType([new ConstantIntegerType(0), new ConstantIntegerType(1)]);
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 isOffsetAccessLegal(): TrinaryLogic
131: {
132: return TrinaryLogic::createYes();
133: }
134:
135: public function isNull(): TrinaryLogic
136: {
137: return TrinaryLogic::createNo();
138: }
139:
140: public function isTrue(): TrinaryLogic
141: {
142: return TrinaryLogic::createMaybe();
143: }
144:
145: public function isFalse(): TrinaryLogic
146: {
147: return TrinaryLogic::createMaybe();
148: }
149:
150: public function isBoolean(): TrinaryLogic
151: {
152: return TrinaryLogic::createYes();
153: }
154:
155: public function isScalar(): TrinaryLogic
156: {
157: return TrinaryLogic::createYes();
158: }
159:
160: public function looseCompare(Type $type, PhpVersion $phpVersion): BooleanType
161: {
162: return new BooleanType();
163: }
164:
165: public function tryRemove(Type $typeToRemove): ?Type
166: {
167: if ($typeToRemove instanceof ConstantBooleanType) {
168: return new ConstantBooleanType(!$typeToRemove->getValue());
169: }
170:
171: return null;
172: }
173:
174: public function getFiniteTypes(): array
175: {
176: return [
177: new ConstantBooleanType(true),
178: new ConstantBooleanType(false),
179: ];
180: }
181:
182: public function exponentiate(Type $exponent): Type
183: {
184: return ExponentiateHelper::exponentiate($this, $exponent);
185: }
186:
187: public function toPhpDocNode(): TypeNode
188: {
189: return new IdentifierTypeNode('bool');
190: }
191:
192: public function toTrinaryLogic(): TrinaryLogic
193: {
194: if ($this->isTrue()->yes()) {
195: return TrinaryLogic::createYes();
196: }
197: if ($this->isFalse()->yes()) {
198: return TrinaryLogic::createNo();
199: }
200:
201: return TrinaryLogic::createMaybe();
202: }
203:
204: public function hasTemplateOrLateResolvableType(): bool
205: {
206: return false;
207: }
208:
209: }
210: