Skip to content

Commit 924a7a2

Browse files
committed
Overriding property - when overriding readable property, the property has to be readable (same for writable)
1 parent d3909c7 commit 924a7a2

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

src/Rules/Properties/OverridingPropertyRule.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,32 @@ public function processNode(Node $node, Scope $scope): array
8888
}
8989
}
9090

91+
$propertyReflection = $classReflection->getNativeProperty($node->getName());
92+
if ($this->phpVersion->supportsPropertyHooks()) {
93+
if ($prototype->isReadable()) {
94+
if (!$propertyReflection->isReadable()) {
95+
$errors[] = RuleErrorBuilder::message(sprintf(
96+
'Property %s::$%s overriding readable property %s::$%s also has to be readable.',
97+
$classReflection->getDisplayName(),
98+
$node->getName(),
99+
$prototype->getDeclaringClass()->getDisplayName(),
100+
$node->getName(),
101+
))->identifier('property.notReadable')->nonIgnorable()->build();
102+
}
103+
}
104+
if ($prototype->isWritable()) {
105+
if (!$propertyReflection->isWritable()) {
106+
$errors[] = RuleErrorBuilder::message(sprintf(
107+
'Property %s::$%s overriding writable property %s::$%s also has to be writable.',
108+
$classReflection->getDisplayName(),
109+
$node->getName(),
110+
$prototype->getDeclaringClass()->getDisplayName(),
111+
$node->getName(),
112+
))->identifier('property.notWritable')->nonIgnorable()->build();
113+
}
114+
}
115+
}
116+
91117
if ($prototype->isPublic()) {
92118
if (!$node->isPublic()) {
93119
$errors[] = RuleErrorBuilder::message(sprintf(
@@ -198,7 +224,6 @@ public function processNode(Node $node, Scope $scope): array
198224
return $errors;
199225
}
200226

201-
$propertyReflection = $classReflection->getNativeProperty($node->getName());
202227
if ($prototype->getReadableType()->equals($propertyReflection->getReadableType())) {
203228
return $errors;
204229
}

tests/PHPStan/Rules/Properties/OverridingPropertyRuleTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,18 @@ public function testPropertyPrototypeFromInterface(): void
216216
'Type string of property Bug12466\Bar::$a is not the same as type int of overridden property Bug12466\Foo::$a.',
217217
15,
218218
],
219+
[
220+
'Property Bug12466\TestMoreProps::$a overriding writable property Bug12466\MoreProps::$a also has to be writable.',
221+
34,
222+
],
223+
[
224+
'Property Bug12466\TestMoreProps::$b overriding readable property Bug12466\MoreProps::$b also has to be readable.',
225+
41,
226+
],
227+
[
228+
'Property Bug12466\TestMoreProps::$c overriding writable property Bug12466\MoreProps::$c also has to be writable.',
229+
48,
230+
],
219231
]);
220232
}
221233

tests/PHPStan/Rules/Properties/data/property-prototype-from-interface.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,40 @@ class Bar implements Foo
1515
public string $a;
1616

1717
}
18+
19+
interface MoreProps
20+
{
21+
22+
public int $a { get; set; }
23+
24+
public int $b { get; }
25+
26+
public int $c { set; }
27+
28+
}
29+
30+
class TestMoreProps implements MoreProps
31+
{
32+
33+
// not writable
34+
public int $a {
35+
get {
36+
return 1;
37+
}
38+
}
39+
40+
// not readable
41+
public int $b {
42+
set {
43+
$this->a = 1;
44+
}
45+
}
46+
47+
// not writable
48+
public int $c {
49+
get {
50+
return 1;
51+
}
52+
}
53+
54+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy