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 getBetterReflection(): BetterReflectionEnumCase
39: {
40: return $this->betterReflectionEnumCase;
41: }
42:
43: public function hasType(): bool
44: {
45: return false;
46: }
47:
48: public function getType(): ?ReflectionType
49: {
50: return null;
51: }
52:
53: /** @return never */
54: public function getValue(): UnitEnum
55: {
56: throw Exception\NotImplementedBecauseItTriggersAutoloading::create();
57: }
58:
59: public function isPublic(): bool
60: {
61: return true;
62: }
63:
64: public function isPrivate(): bool
65: {
66: return false;
67: }
68:
69: public function isProtected(): bool
70: {
71: return false;
72: }
73:
74: public function getModifiers(): int
75: {
76: return self::IS_PUBLIC;
77: }
78:
79: public function getDeclaringClass(): ReflectionClass
80: {
81: return new ReflectionClass($this->betterReflectionEnumCase->getDeclaringClass());
82: }
83:
84: public function getDocComment(): string|false
85: {
86: return $this->betterReflectionEnumCase->getDocComment() ?? false;
87: }
88:
89: /** @return non-empty-string */
90: public function __toString(): string
91: {
92: return $this->betterReflectionEnumCase->__toString();
93: }
94:
95: /**
96: * @param class-string|null $name
97: *
98: * @return list<ReflectionAttribute|FakeReflectionAttribute>
99: */
100: public function getAttributes(string|null $name = null, int $flags = 0): array
101: {
102: if ($flags !== 0 && $flags !== ReflectionAttribute::IS_INSTANCEOF) {
103: throw new ValueError('Argument #2 ($flags) must be a valid attribute filter flag');
104: }
105:
106: if ($name !== null && $flags !== 0) {
107: $attributes = $this->betterReflectionEnumCase->getAttributesByInstance($name);
108: } elseif ($name !== null) {
109: $attributes = $this->betterReflectionEnumCase->getAttributesByName($name);
110: } else {
111: $attributes = $this->betterReflectionEnumCase->getAttributes();
112: }
113:
114: /** @psalm-suppress ImpureFunctionCall */
115: return array_map(static fn (BetterReflectionAttribute $betterReflectionAttribute): ReflectionAttribute|FakeReflectionAttribute => ReflectionAttributeFactory::create($betterReflectionAttribute), $attributes);
116: }
117:
118: public function isFinal(): bool
119: {
120: return true;
121: }
122:
123: public function isEnumCase(): bool
124: {
125: return true;
126: }
127:
128: public function getEnum(): ReflectionEnum
129: {
130: return new ReflectionEnum($this->betterReflectionEnumCase->getDeclaringEnum());
131: }
132:
133: public function isDeprecated(): bool
134: {
135: return $this->betterReflectionEnumCase->isDeprecated();
136: }
137:
138: public function __get(string $name): mixed
139: {
140: if ($name === 'name') {
141: return $this->betterReflectionEnumCase->getName();
142: }
143:
144: if ($name === 'class') {
145: return $this->betterReflectionEnumCase->getDeclaringClass()->getName();
146: }
147:
148: throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name));
149: }
150: }
151: