1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Node;
4:
5: use Override;
6: use PhpParser\Modifiers;
7: use PhpParser\Node;
8: use PhpParser\Node\Expr;
9: use PhpParser\NodeAbstract;
10: use PHPStan\Reflection\ClassReflection;
11: use PHPStan\Turbo\ReferencedByTurboExtension;
12: use PHPStan\Type\Type;
13:
14: /**
15: * @api
16: */
17: #[ReferencedByTurboExtension(key: 'classPropertyNode')]
18: final class ClassPropertyNode extends NodeAbstract implements VirtualNode
19: {
20:
21: /**
22: * @param non-empty-string $name
23: */
24: public function __construct(
25: private string $name,
26: private int $flags,
27: private ?Type $type,
28: private ?Expr $default,
29: private ?string $phpDoc,
30: private ?Type $phpDocType,
31: private bool $isPromoted,
32: private bool $isPromotedFromTrait,
33: private Node\Stmt\Property|Node\Param $originalNode,
34: private bool $isReadonlyByPhpDoc,
35: private bool $isDeclaredInTrait,
36: private bool $isReadonlyClass,
37: private bool $isAllowedPrivateMutation,
38: private ClassReflection $classReflection,
39: )
40: {
41: parent::__construct($originalNode->getAttributes());
42: }
43:
44: /** @return non-empty-string */
45: public function getName(): string
46: {
47: return $this->name;
48: }
49:
50: public function getFlags(): int
51: {
52: return $this->flags;
53: }
54:
55: public function getDefault(): ?Expr
56: {
57: return $this->default;
58: }
59:
60: public function isPromoted(): bool
61: {
62: return $this->isPromoted;
63: }
64:
65: public function isPromotedFromTrait(): bool
66: {
67: return $this->isPromotedFromTrait;
68: }
69:
70: public function getOriginalNode(): Node\Stmt\Property|Node\Param
71: {
72: return $this->originalNode;
73: }
74:
75: public function getPhpDoc(): ?string
76: {
77: return $this->phpDoc;
78: }
79:
80: public function getPhpDocType(): ?Type
81: {
82: return $this->phpDocType;
83: }
84:
85: public function isPublic(): bool
86: {
87: return ($this->flags & Modifiers::PUBLIC) !== 0
88: || ($this->flags & Modifiers::VISIBILITY_MASK) === 0;
89: }
90:
91: public function isProtected(): bool
92: {
93: return (bool) ($this->flags & Modifiers::PROTECTED);
94: }
95:
96: public function isPrivate(): bool
97: {
98: return (bool) ($this->flags & Modifiers::PRIVATE);
99: }
100:
101: public function isPrivateSet(): bool
102: {
103: return (bool) ($this->flags & Modifiers::PRIVATE_SET);
104: }
105:
106: public function isProtectedSet(): bool
107: {
108: return (bool) ($this->flags & Modifiers::PROTECTED_SET);
109: }
110:
111: public function isPublicSet(): bool
112: {
113: return (bool) ($this->flags & Modifiers::PUBLIC_SET);
114: }
115:
116: public function isFinal(): bool
117: {
118: return (bool) ($this->flags & Modifiers::FINAL);
119: }
120:
121: public function isStatic(): bool
122: {
123: return (bool) ($this->flags & Modifiers::STATIC);
124: }
125:
126: public function isReadOnly(): bool
127: {
128: return (bool) ($this->flags & Modifiers::READONLY) || $this->isReadonlyClass;
129: }
130:
131: public function isReadOnlyByPhpDoc(): bool
132: {
133: return $this->isReadonlyByPhpDoc;
134: }
135:
136: public function isDeclaredInTrait(): bool
137: {
138: return $this->isDeclaredInTrait;
139: }
140:
141: public function isAllowedPrivateMutation(): bool
142: {
143: return $this->isAllowedPrivateMutation;
144: }
145:
146: public function isAbstract(): bool
147: {
148: return (bool) ($this->flags & Modifiers::ABSTRACT);
149: }
150:
151: public function getNativeType(): ?Type
152: {
153: return $this->type;
154: }
155:
156: /**
157: * @return Node\Identifier|Node\Name|Node\ComplexType|null
158: */
159: public function getNativeTypeNode()
160: {
161: return $this->originalNode->type;
162: }
163:
164: public function getClassReflection(): ClassReflection
165: {
166: return $this->classReflection;
167: }
168:
169: #[Override]
170: public function getType(): string
171: {
172: return 'PHPStan_Node_ClassPropertyNode';
173: }
174:
175: /**
176: * @return string[]
177: */
178: #[Override]
179: public function getSubNodeNames(): array
180: {
181: return [];
182: }
183:
184: public function hasHooks(): bool
185: {
186: return $this->getHooks() !== [];
187: }
188:
189: /**
190: * @return Node\PropertyHook[]
191: */
192: public function getHooks(): array
193: {
194: return $this->originalNode->hooks;
195: }
196:
197: public function isVirtual(): bool
198: {
199: return $this->classReflection->getNativeProperty($this->name)->isVirtual()->yes();
200: }
201:
202: public function isWritable(): bool
203: {
204: return $this->classReflection->getNativeProperty($this->name)->isWritable();
205: }
206:
207: public function isReadable(): bool
208: {
209: return $this->classReflection->getNativeProperty($this->name)->isReadable();
210: }
211:
212: /**
213: * @return Node\AttributeGroup[]
214: */
215: public function getAttrGroups(): array
216: {
217: return $this->originalNode->attrGroups;
218: }
219:
220: }
221: