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