File tree Expand file tree Collapse file tree 4 files changed +84
-3
lines changed Expand file tree Collapse file tree 4 files changed +84
-3
lines changed Original file line number Diff line number Diff line change @@ -425,11 +425,10 @@ private function createProperty(
425425 $ includingAnnotations
426426 && !$ declaringClassReflection ->isEnum ()
427427 && !$ propertyReflection ->isStatic ()
428- && ($ classReflection ->allowsDynamicProperties () || ! $ propertyReflection -> isPrivate ( ))
428+ && ($ classReflection ->allowsDynamicProperties () || $ scope -> canReadProperty ( $ nativeProperty ))
429429 && $ this ->annotationsPropertiesClassReflectionExtension ->hasProperty ($ classReflection , $ propertyName )
430430 && (
431- !$ scope ->canReadProperty ($ nativeProperty )
432- || $ nativeProperty ->isPublic ()
431+ $ nativeProperty ->isPublic ()
433432 || ($ scope ->isInClass () && $ scope ->getClassReflection ()->getName () !== $ declaringClassReflection ->getName ())
434433 )
435434 ) {
Original file line number Diff line number Diff line change @@ -187,6 +187,8 @@ private static function findTestFiles(): iterable
187187 yield __DIR__ . '/../Rules/Classes/data/bug-5333.php ' ;
188188 yield __DIR__ . '/../Rules/Methods/data/bug-8174.php ' ;
189189
190+ yield __DIR__ . '/../Rules/Properties/data/bug-13537.php ' ;
191+
190192 if (PHP_VERSION_ID >= 80000 ) {
191193 yield __DIR__ . '/../Rules/Comparison/data/bug-8169.php ' ;
192194 }
Original file line number Diff line number Diff line change @@ -1216,4 +1216,21 @@ public function testPrivatePropertyWithAllowedPropertyTagIsPublic(): void
12161216 $ this ->analyse ([__DIR__ . '/data/private-property-with-allowed-property-tag-is-public.php ' ], []);
12171217 }
12181218
1219+ public function testBug13537 (): void
1220+ {
1221+ $ this ->checkThisOnly = false ;
1222+ $ this ->checkUnionTypes = true ;
1223+ $ this ->checkDynamicProperties = true ;
1224+ $ this ->analyse ([__DIR__ . '/data/bug-13537.php ' ], [
1225+ [
1226+ 'Cannot access property $bob on array<string, mixed>. ' ,
1227+ 25 ,
1228+ ],
1229+ [
1230+ 'Access to protected property Bug13537\Bar::$test. ' ,
1231+ 25 ,
1232+ ],
1233+ ]);
1234+ }
1235+
12191236}
Original file line number Diff line number Diff line change 1+ <?php
2+
3+ namespace Bug13537 ;
4+
5+ use stdClass ;
6+ use function PHPStan \Testing \assertType ;
7+
8+ class Foo
9+ {
10+ /**
11+ * @var array<non-empty-string, mixed>
12+ */
13+ protected array $ test = [];
14+ }
15+
16+ /**
17+ * @property stdClass $test
18+ */
19+ class Bar extends Foo
20+ {
21+
22+ }
23+
24+ function (): void {
25+ $ bob = new Bar ()->test ->bob ;
26+ };
27+
28+ class BaseModel
29+ {
30+ /**
31+ * @var array<non-empty-string, mixed>
32+ */
33+ protected array $ attributes = [];
34+
35+ public function __get (string $ key ): mixed {
36+ return $ this ->attributes [$ key ] ?? null ;
37+ }
38+
39+ public function __isset (string $ key ): bool {
40+ return isset ($ this ->attributes [$ key ]);
41+ }
42+ }
43+
44+ /**
45+ * @property stdClass $attributes
46+ * @property bool $other
47+ */
48+ class Bar2 extends BaseModel
49+ {
50+ public function __constructor (): void {
51+ $ this ->attributes = [
52+ 'attributes ' => (object ) array ('foo ' => 'bar ' ),
53+ 'other ' => true
54+ ];
55+ }
56+ }
57+
58+ function (): void {
59+ $ bar = new Bar2 ();
60+ echo $ bar ->attributes ->foo ;
61+
62+ assertType (stdClass::class, $ bar ->attributes );
63+ };
You can’t perform that action at this time.
0 commit comments