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