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