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