1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace PHPStan\BetterReflection\Reflection\Adapter;
6:
7: use Attribute;
8: use OutOfBoundsException;
9: use PhpParser\Node\Expr;
10: use ReflectionAttribute as CoreReflectionAttribute;
11: use PHPStan\BetterReflection\Reflection\ReflectionAttribute as BetterReflectionAttribute;
12:
13: use function sprintf;
14:
15: /** @template-extends CoreReflectionAttribute<object> */
16: final class ReflectionAttribute extends CoreReflectionAttribute
17: {
18: private BetterReflectionAttribute $betterReflectionAttribute;
19: public const TARGET_CONSTANT_COMPATIBILITY = 64;
20:
21: public function __construct(BetterReflectionAttribute $betterReflectionAttribute)
22: {
23: $this->betterReflectionAttribute = $betterReflectionAttribute;
24: unset($this->name);
25: }
26:
27: public function getBetterReflection(): BetterReflectionAttribute
28: {
29: return $this->betterReflectionAttribute;
30: }
31:
32: /** @psalm-mutation-free */
33: public function getName(): string
34: {
35: return $this->betterReflectionAttribute->getName();
36: }
37:
38: /** @psalm-mutation-free */
39: public function getShortName(): string
40: {
41: return $this->betterReflectionAttribute->getShortName();
42: }
43:
44: /** @psalm-mutation-free */
45: public function getNamespaceName(): string
46: {
47: return $this->betterReflectionAttribute->getNamespaceName() ?? '';
48: }
49:
50: /** @psalm-mutation-free */
51: public function inNamespace(): bool
52: {
53: return $this->betterReflectionAttribute->inNamespace();
54: }
55:
56: /**
57: * @return int-mask-of<Attribute::TARGET_*>|self::TARGET_CONSTANT_COMPATIBILITY
58: *
59: * @psalm-mutation-free
60: * @psalm-suppress ImplementedReturnTypeMismatch
61: */
62: public function getTarget(): int
63: {
64: return $this->betterReflectionAttribute->getTarget();
65: }
66:
67: /** @psalm-mutation-free */
68: public function isRepeated(): bool
69: {
70: return $this->betterReflectionAttribute->isRepeated();
71: }
72:
73: /** @return array<int|string, mixed> */
74: public function getArguments(): array
75: {
76: return $this->betterReflectionAttribute->getArguments();
77: }
78:
79: /** @return array<int|string, Expr> */
80: public function getArgumentsExpressions(): array
81: {
82: return $this->betterReflectionAttribute->getArgumentsExpressions();
83: }
84:
85: public function newInstance(): object
86: {
87: $class = $this->getName();
88:
89: return new $class(...$this->getArguments());
90: }
91:
92: /** @return non-empty-string */
93: public function __toString(): string
94: {
95: return $this->betterReflectionAttribute->__toString();
96: }
97:
98: /**
99: * @return mixed
100: */
101: public function __get(string $name)
102: {
103: if ($name === 'name') {
104: return $this->betterReflectionAttribute->getName();
105: }
106:
107: throw new OutOfBoundsException(sprintf('Property %s::$%s does not exist.', self::class, $name));
108: }
109: }
110: