1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace PHPStan\BetterReflection\Reflection\Adapter;
6:
7: use OutOfBoundsException;
8: use ReflectionEnumUnitCase as CoreReflectionEnumUnitCase;
9: use PHPStan\BetterReflection\Reflection\ReflectionAttribute as BetterReflectionAttribute;
10: use PHPStan\BetterReflection\Reflection\ReflectionEnumCase as BetterReflectionEnumCase;
11: use UnitEnum;
12: use ValueError;
13:
14: use function array_map;
15: use function sprintf;
16:
17: /**
18: * @psalm-suppress PropertyNotSetInConstructor
19: * @psalm-immutable
20: */
21: final class ReflectionEnumUnitCase extends CoreReflectionEnumUnitCase
22: {
23: public function __construct(private BetterReflectionEnumCase $betterReflectionEnumCase)
24: {
25: unset($this->name);
26: unset($this->class);
27: }
28:
29: /**
30: * Get the name of the reflection (e.g. if this is a ReflectionClass this
31: * will be the class name).
32: */
33: public function getName(): string
34: {
35: return $this->betterReflectionEnumCase->getName();
36: }
37:
38: public function hasType(): bool
39: {
40: return false;
41: }
42:
43: public function getType(): ReflectionUnionType|ReflectionNamedType|ReflectionIntersectionType|null
44: {
45: return null;
46: }
47:
48: public function getValue(): UnitEnum
49: {
50: throw new Exception\NotImplemented('Not implemented');
51: }
52:
53: public function isPublic(): bool
54: {
55: return true;
56: }
57:
58: public function isPrivate(): bool
59: {
60: return false;
61: }
62:
63: public function isProtected(): bool
64: {
65: return false;
66: }
67:
68: public function getModifiers(): int
69: {
70: return self::IS_PUBLIC;
71: }
72:
73: public function getDeclaringClass(): ReflectionClass
74: {
75: return new ReflectionClass($this->betterReflectionEnumCase->getDeclaringClass());
76: }
77:
78: public function getDocComment(): string|false
79: {
80: return $this->betterReflectionEnumCase->getDocComment() ?? false;
81: }
82:
83: /** @return non-empty-string */
84: public function __toString(): string
85: {
86: return $this->betterReflectionEnumCase->__toString();
87: }
88:
89: /**
90: * @param class-string|null $name
91: *
92: * @return list<ReflectionAttribute|FakeReflectionAttribute>
93: */
94: public function getAttributes(string|null $name = null, int $flags = 0): array
95: {
96: if ($flags !== 0 && $flags !== ReflectionAttribute::IS_INSTANCEOF) {
97: throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag');
98: }
99:
100: if ($name !== null && $flags !== 0) {
101: $attributes = $this->betterReflectionEnumCase->getAttributesByInstance($name);
102: } elseif ($name !== null) {
103: $attributes = $this->betterReflectionEnumCase->getAttributesByName($name);
104: } else {
105: $attributes = $this->betterReflectionEnumCase->getAttributes();
106: }
107:
108: /** @psalm-suppress ImpureFunctionCall */
109: return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute): ReflectionAttribute|FakeReflectionAttribute => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes);
110: }
111:
112: public function isFinal(): bool
113: {
114: return true;
115: }
116:
117: public function isEnumCase(): bool
118: {
119: return true;
120: }
121:
122: public function getEnum(): ReflectionEnum
123: {
124: return new ReflectionEnum($this->betterReflectionEnumCase->getDeclaringEnum());
125: }
126:
127: public function __get(string $name): mixed
128: {
129: if ($name === 'name') {
130: return $this->betterReflectionEnumCase->getName();
131: }
132:
133: if ($name === 'class') {
134: return $this->betterReflectionEnumCase->getDeclaringClass()->getName();
135: }
136:
137: throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name));
138: }
139: }
140: