1: | <?php declare(strict_types = 1); |
2: | |
3: | namespace PHPStan\Reflection\Php; |
4: | |
5: | use PHPStan\BetterReflection\Reflection\Adapter\ReflectionIntersectionType; |
6: | use PHPStan\BetterReflection\Reflection\Adapter\ReflectionNamedType; |
7: | use PHPStan\BetterReflection\Reflection\Adapter\ReflectionProperty; |
8: | use PHPStan\BetterReflection\Reflection\Adapter\ReflectionUnionType; |
9: | use PHPStan\Reflection\ClassReflection; |
10: | use PHPStan\Reflection\ExtendedPropertyReflection; |
11: | use PHPStan\TrinaryLogic; |
12: | use PHPStan\Type\MixedType; |
13: | use PHPStan\Type\Type; |
14: | use PHPStan\Type\TypehintHelper; |
15: | |
16: | |
17: | |
18: | |
19: | |
20: | class PhpPropertyReflection implements ExtendedPropertyReflection |
21: | { |
22: | |
23: | private ?Type $finalNativeType = null; |
24: | |
25: | private ?Type $type = null; |
26: | |
27: | public function __construct( |
28: | private ClassReflection $declaringClass, |
29: | private ?ClassReflection $declaringTrait, |
30: | private ReflectionUnionType|ReflectionNamedType|ReflectionIntersectionType|null $nativeType, |
31: | private ?Type $phpDocType, |
32: | private ReflectionProperty $reflection, |
33: | private ?string $deprecatedDescription, |
34: | private bool $isDeprecated, |
35: | private bool $isInternal, |
36: | private bool $isReadOnlyByPhpDoc, |
37: | private bool $isAllowedPrivateMutation, |
38: | ) |
39: | { |
40: | } |
41: | |
42: | public function getDeclaringClass(): ClassReflection |
43: | { |
44: | return $this->declaringClass; |
45: | } |
46: | |
47: | public function getDeclaringTrait(): ?ClassReflection |
48: | { |
49: | return $this->declaringTrait; |
50: | } |
51: | |
52: | public function getDocComment(): ?string |
53: | { |
54: | $docComment = $this->reflection->getDocComment(); |
55: | if ($docComment === false) { |
56: | return null; |
57: | } |
58: | |
59: | return $docComment; |
60: | } |
61: | |
62: | public function isStatic(): bool |
63: | { |
64: | return $this->reflection->isStatic(); |
65: | } |
66: | |
67: | public function isPrivate(): bool |
68: | { |
69: | return $this->reflection->isPrivate(); |
70: | } |
71: | |
72: | public function isPublic(): bool |
73: | { |
74: | return $this->reflection->isPublic(); |
75: | } |
76: | |
77: | public function isReadOnly(): bool |
78: | { |
79: | return $this->reflection->isReadOnly(); |
80: | } |
81: | |
82: | public function isReadOnlyByPhpDoc(): bool |
83: | { |
84: | return $this->isReadOnlyByPhpDoc; |
85: | } |
86: | |
87: | public function getReadableType(): Type |
88: | { |
89: | if ($this->type === null) { |
90: | $this->type = TypehintHelper::decideTypeFromReflection( |
91: | $this->nativeType, |
92: | $this->phpDocType, |
93: | $this->declaringClass, |
94: | ); |
95: | } |
96: | |
97: | return $this->type; |
98: | } |
99: | |
100: | public function getWritableType(): Type |
101: | { |
102: | return $this->getReadableType(); |
103: | } |
104: | |
105: | public function canChangeTypeAfterAssignment(): bool |
106: | { |
107: | return true; |
108: | } |
109: | |
110: | public function isPromoted(): bool |
111: | { |
112: | return $this->reflection->isPromoted(); |
113: | } |
114: | |
115: | public function hasPhpDocType(): bool |
116: | { |
117: | return $this->phpDocType !== null; |
118: | } |
119: | |
120: | public function getPhpDocType(): Type |
121: | { |
122: | if ($this->phpDocType !== null) { |
123: | return $this->phpDocType; |
124: | } |
125: | |
126: | return new MixedType(); |
127: | } |
128: | |
129: | public function hasNativeType(): bool |
130: | { |
131: | return $this->nativeType !== null; |
132: | } |
133: | |
134: | public function getNativeType(): Type |
135: | { |
136: | if ($this->finalNativeType === null) { |
137: | $this->finalNativeType = TypehintHelper::decideTypeFromReflection( |
138: | $this->nativeType, |
139: | null, |
140: | $this->declaringClass, |
141: | ); |
142: | } |
143: | |
144: | return $this->finalNativeType; |
145: | } |
146: | |
147: | public function isReadable(): bool |
148: | { |
149: | return true; |
150: | } |
151: | |
152: | public function isWritable(): bool |
153: | { |
154: | return true; |
155: | } |
156: | |
157: | public function getDeprecatedDescription(): ?string |
158: | { |
159: | if ($this->isDeprecated) { |
160: | return $this->deprecatedDescription; |
161: | } |
162: | |
163: | return null; |
164: | } |
165: | |
166: | public function isDeprecated(): TrinaryLogic |
167: | { |
168: | return TrinaryLogic::createFromBoolean($this->isDeprecated); |
169: | } |
170: | |
171: | public function isInternal(): TrinaryLogic |
172: | { |
173: | return TrinaryLogic::createFromBoolean($this->isInternal); |
174: | } |
175: | |
176: | public function isAllowedPrivateMutation(): bool |
177: | { |
178: | return $this->isAllowedPrivateMutation; |
179: | } |
180: | |
181: | public function getNativeReflection(): ReflectionProperty |
182: | { |
183: | return $this->reflection; |
184: | } |
185: | |
186: | } |
187: | |