|   1:  | <?php declare(strict_types = 1); | 
|   2:  |  | 
|   3:  | namespace PHPStan\Reflection; | 
|   4:  |  | 
|   5:  | use PHPStan\PhpDoc\ResolvedPhpDocBlock; | 
|   6:  | use PHPStan\PhpDoc\Tag\AssertTag; | 
|   7:  | use PHPStan\Type\Type; | 
|   8:  | use function array_filter; | 
|   9:  | use function array_map; | 
|  10:  | use function array_merge; | 
|  11:  | use function count; | 
|  12:  |  | 
|  13:  |  | 
|  14:  |  | 
|  15:  |  | 
|  16:  |  | 
|  17:  | class Assertions | 
|  18:  | { | 
|  19:  |  | 
|  20:  | 	private static ?self $empty = null; | 
|  21:  |  | 
|  22:  | 	 | 
|  23:  |  | 
|  24:  |  | 
|  25:  | 	private function __construct(private array $asserts) | 
|  26:  | 	{ | 
|  27:  | 	} | 
|  28:  |  | 
|  29:  | 	 | 
|  30:  |  | 
|  31:  |  | 
|  32:  | 	public function getAll(): array | 
|  33:  | 	{ | 
|  34:  | 		return $this->asserts; | 
|  35:  | 	} | 
|  36:  |  | 
|  37:  | 	 | 
|  38:  |  | 
|  39:  |  | 
|  40:  | 	public function getAsserts(): array | 
|  41:  | 	{ | 
|  42:  | 		return array_filter($this->asserts, static fn (AssertTag $assert) => $assert->getIf() === AssertTag::NULL); | 
|  43:  | 	} | 
|  44:  |  | 
|  45:  | 	 | 
|  46:  |  | 
|  47:  |  | 
|  48:  | 	public function getAssertsIfTrue(): array | 
|  49:  | 	{ | 
|  50:  | 		return array_merge( | 
|  51:  | 			array_filter($this->asserts, static fn (AssertTag $assert) => $assert->getIf() === AssertTag::IF_TRUE), | 
|  52:  | 			array_map( | 
|  53:  | 				static fn (AssertTag $assert) => $assert->negate(), | 
|  54:  | 				array_filter($this->asserts, static fn (AssertTag $assert) => $assert->getIf() === AssertTag::IF_FALSE && !$assert->isEquality()), | 
|  55:  | 			), | 
|  56:  | 		); | 
|  57:  | 	} | 
|  58:  |  | 
|  59:  | 	 | 
|  60:  |  | 
|  61:  |  | 
|  62:  | 	public function getAssertsIfFalse(): array | 
|  63:  | 	{ | 
|  64:  | 		return array_merge( | 
|  65:  | 			array_filter($this->asserts, static fn (AssertTag $assert) => $assert->getIf() === AssertTag::IF_FALSE), | 
|  66:  | 			array_map( | 
|  67:  | 				static fn (AssertTag $assert) => $assert->negate(), | 
|  68:  | 				array_filter($this->asserts, static fn (AssertTag $assert) => $assert->getIf() === AssertTag::IF_TRUE && !$assert->isEquality()), | 
|  69:  | 			), | 
|  70:  | 		); | 
|  71:  | 	} | 
|  72:  |  | 
|  73:  | 	 | 
|  74:  |  | 
|  75:  |  | 
|  76:  | 	public function mapTypes(callable $callable): self | 
|  77:  | 	{ | 
|  78:  | 		$assertTagsCallback = static fn (AssertTag $tag): AssertTag => $tag->withType($callable($tag->getType())); | 
|  79:  |  | 
|  80:  | 		return new self(array_map($assertTagsCallback, $this->asserts)); | 
|  81:  | 	} | 
|  82:  |  | 
|  83:  | 	public function intersectWith(Assertions $other): self | 
|  84:  | 	{ | 
|  85:  | 		return new self(array_merge($this->getAll(), $other->getAll())); | 
|  86:  | 	} | 
|  87:  |  | 
|  88:  | 	public static function createEmpty(): self | 
|  89:  | 	{ | 
|  90:  | 		$empty = self::$empty; | 
|  91:  |  | 
|  92:  | 		if ($empty !== null) { | 
|  93:  | 			return $empty; | 
|  94:  | 		} | 
|  95:  |  | 
|  96:  | 		$empty = new self([]); | 
|  97:  | 		self::$empty = $empty; | 
|  98:  |  | 
|  99:  | 		return $empty; | 
| 100:  | 	} | 
| 101:  |  | 
| 102:  | 	public static function createFromResolvedPhpDocBlock(ResolvedPhpDocBlock $phpDocBlock): self | 
| 103:  | 	{ | 
| 104:  | 		$tags = $phpDocBlock->getAssertTags(); | 
| 105:  | 		if (count($tags) === 0) { | 
| 106:  | 			return self::createEmpty(); | 
| 107:  | 		} | 
| 108:  |  | 
| 109:  | 		return new self($tags); | 
| 110:  | 	} | 
| 111:  |  | 
| 112:  | } | 
| 113:  |  |