1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Analyser;
4:
5: use PHPStan\ShouldNotHappenException;
6:
7: /**
8: * @api
9: * @final
10: */
11: class TypeSpecifierContext
12: {
13:
14: public const CONTEXT_TRUE = 0b0001;
15: public const CONTEXT_TRUTHY_BUT_NOT_TRUE = 0b0010;
16: public const CONTEXT_TRUTHY = self::CONTEXT_TRUE | self::CONTEXT_TRUTHY_BUT_NOT_TRUE;
17: public const CONTEXT_FALSE = 0b0100;
18: public const CONTEXT_FALSEY_BUT_NOT_FALSE = 0b1000;
19: public const CONTEXT_FALSEY = self::CONTEXT_FALSE | self::CONTEXT_FALSEY_BUT_NOT_FALSE;
20: public const CONTEXT_BITMASK = 0b1111;
21:
22: /** @var self[] */
23: private static array $registry;
24:
25: private function __construct(private ?int $value)
26: {
27: }
28:
29: private static function create(?int $value): self
30: {
31: self::$registry[$value] ??= new self($value);
32: return self::$registry[$value];
33: }
34:
35: public static function createTrue(): self
36: {
37: return self::create(self::CONTEXT_TRUE);
38: }
39:
40: public static function createTruthy(): self
41: {
42: return self::create(self::CONTEXT_TRUTHY);
43: }
44:
45: public static function createFalse(): self
46: {
47: return self::create(self::CONTEXT_FALSE);
48: }
49:
50: public static function createFalsey(): self
51: {
52: return self::create(self::CONTEXT_FALSEY);
53: }
54:
55: public static function createNull(): self
56: {
57: return self::create(null);
58: }
59:
60: public function negate(): self
61: {
62: if ($this->value === null) {
63: throw new ShouldNotHappenException();
64: }
65: return self::create(~$this->value & self::CONTEXT_BITMASK);
66: }
67:
68: public function true(): bool
69: {
70: return $this->value !== null && (bool) ($this->value & self::CONTEXT_TRUE);
71: }
72:
73: public function truthy(): bool
74: {
75: return $this->value !== null && (bool) ($this->value & self::CONTEXT_TRUTHY);
76: }
77:
78: public function false(): bool
79: {
80: return $this->value !== null && (bool) ($this->value & self::CONTEXT_FALSE);
81: }
82:
83: public function falsey(): bool
84: {
85: return $this->value !== null && (bool) ($this->value & self::CONTEXT_FALSEY);
86: }
87:
88: public function null(): bool
89: {
90: return $this->value === null;
91: }
92:
93: }
94: