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