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