1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace PHPStan\BetterReflection\Reflection;
6:
7: use PhpParser\Node;
8: use PhpParser\Node\IntersectionType;
9: use PHPStan\BetterReflection\Reflector\Reflector;
10:
11: use function array_map;
12: use function assert;
13: use function implode;
14:
15: class ReflectionIntersectionType extends ReflectionType
16: {
17: /** @var non-empty-list<ReflectionNamedType> */
18: private $types;
19:
20: /** @internal
21: * @param \PHPStan\BetterReflection\Reflection\ReflectionParameter|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionEnum|\PHPStan\BetterReflection\Reflection\ReflectionProperty $owner */
22: public function __construct(Reflector $reflector, $owner, IntersectionType $type)
23: {
24: /** @var non-empty-list<ReflectionNamedType> $types */
25: $types = array_map(static function ($type) use ($reflector, $owner): ReflectionNamedType {
26: $type = ReflectionType::createFromNode($reflector, $owner, $type);
27: assert($type instanceof ReflectionNamedType);
28:
29: return $type;
30: }, $type->types);
31: $this->types = $types;
32: }
33:
34: /** @internal
35: * @param \PHPStan\BetterReflection\Reflection\ReflectionParameter|\PHPStan\BetterReflection\Reflection\ReflectionMethod|\PHPStan\BetterReflection\Reflection\ReflectionFunction|\PHPStan\BetterReflection\Reflection\ReflectionEnum|\PHPStan\BetterReflection\Reflection\ReflectionProperty $owner
36: * @return $this */
37: public function withOwner($owner)
38: {
39: $clone = clone $this;
40:
41: foreach ($clone->types as $typeNo => $innerType) {
42: $clone->types[$typeNo] = $innerType->withOwner($owner);
43: }
44:
45: return $clone;
46: }
47:
48: /** @return non-empty-list<ReflectionNamedType> */
49: public function getTypes(): array
50: {
51: return $this->types;
52: }
53:
54: public function allowsNull(): bool
55: {
56: return false;
57: }
58:
59: public function __toString(): string
60: {
61: // @infection-ignore-all UnwrapArrayMap: It works without array_map() as well but this is less magical
62: return implode('&', array_map(static function (ReflectionNamedType $type) : string {
63: return $type->__toString();
64: }, $this->types));
65: }
66: }
67: