1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Type;
4:
5: use PHPStan\ShouldNotHappenException;
6: use PHPStan\TrinaryLogic;
7: use function array_map;
8: use function array_merge;
9:
10: /** @api */
11: class AcceptsResult
12: {
13:
14: /**
15: * @param list<string> $reasons
16: */
17: public function __construct(
18: public readonly TrinaryLogic $result,
19: public readonly array $reasons,
20: )
21: {
22: }
23:
24: public function yes(): bool
25: {
26: return $this->result->yes();
27: }
28:
29: public function maybe(): bool
30: {
31: return $this->result->maybe();
32: }
33:
34: public function no(): bool
35: {
36: return $this->result->no();
37: }
38:
39: public static function createYes(): self
40: {
41: return new self(TrinaryLogic::createYes(), []);
42: }
43:
44: public static function createNo(): self
45: {
46: return new self(TrinaryLogic::createNo(), []);
47: }
48:
49: public static function createMaybe(): self
50: {
51: return new self(TrinaryLogic::createMaybe(), []);
52: }
53:
54: public static function createFromBoolean(bool $value): self
55: {
56: return new self(TrinaryLogic::createFromBoolean($value), []);
57: }
58:
59: public function and(self $other): self
60: {
61: return new self(
62: $this->result->and($other->result),
63: array_merge($this->reasons, $other->reasons),
64: );
65: }
66:
67: public function or(self $other): self
68: {
69: return new self(
70: $this->result->or($other->result),
71: array_merge($this->reasons, $other->reasons),
72: );
73: }
74:
75: /**
76: * @param callable(string): string $cb
77: */
78: public function decorateReasons(callable $cb): self
79: {
80: $reasons = [];
81: foreach ($this->reasons as $reason) {
82: $reasons[] = $cb($reason);
83: }
84:
85: return new self($this->result, $reasons);
86: }
87:
88: public static function extremeIdentity(self ...$operands): self
89: {
90: if ($operands === []) {
91: throw new ShouldNotHappenException();
92: }
93:
94: $result = TrinaryLogic::extremeIdentity(...array_map(static fn (self $result) => $result->result, $operands));
95: $reasons = [];
96: foreach ($operands as $operand) {
97: foreach ($operand->reasons as $reason) {
98: $reasons[] = $reason;
99: }
100: }
101:
102: return new self($result, $reasons);
103: }
104:
105: public static function maxMin(self ...$operands): self
106: {
107: if ($operands === []) {
108: throw new ShouldNotHappenException();
109: }
110:
111: $result = TrinaryLogic::maxMin(...array_map(static fn (self $result) => $result->result, $operands));
112: $reasons = [];
113: foreach ($operands as $operand) {
114: foreach ($operand->reasons as $reason) {
115: $reasons[] = $reason;
116: }
117: }
118:
119: return new self($result, $reasons);
120: }
121:
122: }
123: