Skip to content

Commit dffa364

Browse files
committed
Test ReadingWriteOnlyPropertiesRule for hooked properties
1 parent 3ad2fd1 commit dffa364

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

src/Reflection/Php/PhpPropertyReflection.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,15 @@ public function getNativeType(): Type
174174

175175
public function isReadable(): bool
176176
{
177-
return true;
177+
if ($this->isStatic()) {
178+
return true;
179+
}
180+
181+
if (!$this->isVirtual()->yes()) {
182+
return true;
183+
}
184+
185+
return $this->hasHook('get');
178186
}
179187

180188
public function isWritable(): bool

tests/PHPStan/Rules/Properties/ReadingWriteOnlyPropertiesRuleTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPStan\Rules\Rule;
66
use PHPStan\Rules\RuleLevelHelper;
77
use PHPStan\Testing\RuleTestCase;
8+
use const PHP_VERSION_ID;
89

910
/**
1011
* @extends RuleTestCase<ReadingWriteOnlyPropertiesRule>
@@ -88,4 +89,23 @@ public function testConflictingAnnotationProperty(): void
8889
$this->analyse([__DIR__ . '/data/conflicting-annotation-property.php'], []);
8990
}
9091

92+
public function testPropertyHooks(): void
93+
{
94+
if (PHP_VERSION_ID < 80400) {
95+
$this->markTestSkipped('Test requires PHP 8.4.');
96+
}
97+
98+
$this->checkThisOnly = false;
99+
$this->analyse([__DIR__ . '/data/reading-write-only-hooked-properties.php'], [
100+
[
101+
'Property ReadingWriteOnlyHookedProperties\Foo::$i is not readable.',
102+
16,
103+
],
104+
[
105+
'Property ReadingWriteOnlyHookedProperties\Bar::$i is not readable.',
106+
34,
107+
],
108+
]);
109+
}
110+
91111
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php // lint >= 8.4
2+
3+
namespace ReadingWriteOnlyHookedProperties;
4+
5+
interface Foo
6+
{
7+
8+
public int $i {
9+
// virtual, not readable
10+
set;
11+
}
12+
13+
}
14+
15+
function (Foo $f): void {
16+
echo $f->i;
17+
};
18+
19+
class Bar
20+
{
21+
22+
public int $other;
23+
24+
public int $i {
25+
// virtual, not readable
26+
set {
27+
$this->other = 1;
28+
}
29+
}
30+
31+
}
32+
33+
function (Bar $b): void {
34+
echo $b->i;
35+
};
36+
37+
class Baz
38+
{
39+
40+
public int $i {
41+
// backed, readable
42+
set {
43+
$this->i = 1;
44+
}
45+
}
46+
47+
}
48+
49+
function (Baz $b): void {
50+
$b->i = 1;
51+
};

0 commit comments

Comments
 (0)