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