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