Skip to content

Commit d1c4c6d

Browse files
committed
Fix methods in IntersectionTypePropertyReflection
1 parent d267e51 commit d1c4c6d

File tree

4 files changed

+58
-78
lines changed

4 files changed

+58
-78
lines changed

Diff for: src/Reflection/Type/IntersectionTypePropertyReflection.php

+16-39
Original file line numberDiff line numberDiff line change
@@ -28,35 +28,17 @@ public function getDeclaringClass(): ClassReflection
2828

2929
public function isStatic(): bool
3030
{
31-
foreach ($this->properties as $property) {
32-
if ($property->isStatic()) {
33-
return true;
34-
}
35-
}
36-
37-
return false;
31+
return $this->computeResult(static fn (PropertyReflection $property) => $property->isStatic());
3832
}
3933

4034
public function isPrivate(): bool
4135
{
42-
foreach ($this->properties as $property) {
43-
if (!$property->isPrivate()) {
44-
return false;
45-
}
46-
}
47-
48-
return true;
36+
return $this->computeResult(static fn (PropertyReflection $property) => $property->isPrivate());
4937
}
5038

5139
public function isPublic(): bool
5240
{
53-
foreach ($this->properties as $property) {
54-
if ($property->isPublic()) {
55-
return true;
56-
}
57-
}
58-
59-
return false;
41+
return $this->computeResult(static fn (PropertyReflection $property) => $property->isPublic());
6042
}
6143

6244
public function isDeprecated(): TrinaryLogic
@@ -108,35 +90,30 @@ public function getWritableType(): Type
10890

10991
public function canChangeTypeAfterAssignment(): bool
11092
{
111-
foreach ($this->properties as $property) {
112-
if (!$property->canChangeTypeAfterAssignment()) {
113-
return false;
114-
}
115-
}
116-
117-
return true;
93+
return $this->computeResult(static fn (PropertyReflection $property) => $property->canChangeTypeAfterAssignment());
11894
}
11995

12096
public function isReadable(): bool
12197
{
122-
foreach ($this->properties as $property) {
123-
if (!$property->isReadable()) {
124-
return false;
125-
}
126-
}
127-
128-
return true;
98+
return $this->computeResult(static fn (PropertyReflection $property) => $property->isReadable());
12999
}
130100

131101
public function isWritable(): bool
132102
{
103+
return $this->computeResult(static fn (PropertyReflection $property) => $property->isWritable());
104+
}
105+
106+
/**
107+
* @param callable(PropertyReflection): bool $cb
108+
*/
109+
private function computeResult(callable $cb): bool
110+
{
111+
$result = false;
133112
foreach ($this->properties as $property) {
134-
if (!$property->isWritable()) {
135-
return false;
136-
}
113+
$result = $result || $cb($property);
137114
}
138115

139-
return true;
116+
return $result;
140117
}
141118

142119
}

Diff for: src/Reflection/Type/UnionTypePropertyReflection.php

+16-39
Original file line numberDiff line numberDiff line change
@@ -28,35 +28,17 @@ public function getDeclaringClass(): ClassReflection
2828

2929
public function isStatic(): bool
3030
{
31-
foreach ($this->properties as $property) {
32-
if (!$property->isStatic()) {
33-
return false;
34-
}
35-
}
36-
37-
return true;
31+
return $this->computeResult(static fn (PropertyReflection $property) => $property->isStatic());
3832
}
3933

4034
public function isPrivate(): bool
4135
{
42-
foreach ($this->properties as $property) {
43-
if ($property->isPrivate()) {
44-
return true;
45-
}
46-
}
47-
48-
return false;
36+
return $this->computeResult(static fn (PropertyReflection $property) => $property->isPrivate());
4937
}
5038

5139
public function isPublic(): bool
5240
{
53-
foreach ($this->properties as $property) {
54-
if (!$property->isPublic()) {
55-
return false;
56-
}
57-
}
58-
59-
return true;
41+
return $this->computeResult(static fn (PropertyReflection $property) => $property->isPublic());
6042
}
6143

6244
public function isDeprecated(): TrinaryLogic
@@ -108,35 +90,30 @@ public function getWritableType(): Type
10890

10991
public function canChangeTypeAfterAssignment(): bool
11092
{
111-
foreach ($this->properties as $property) {
112-
if (!$property->canChangeTypeAfterAssignment()) {
113-
return false;
114-
}
115-
}
116-
117-
return true;
93+
return $this->computeResult(static fn (PropertyReflection $property) => $property->canChangeTypeAfterAssignment());
11894
}
11995

12096
public function isReadable(): bool
12197
{
122-
foreach ($this->properties as $property) {
123-
if (!$property->isReadable()) {
124-
return false;
125-
}
126-
}
127-
128-
return true;
98+
return $this->computeResult(static fn (PropertyReflection $property) => $property->isReadable());
12999
}
130100

131101
public function isWritable(): bool
132102
{
103+
return $this->computeResult(static fn (PropertyReflection $property) => $property->isWritable());
104+
}
105+
106+
/**
107+
* @param callable(PropertyReflection): bool $cb
108+
*/
109+
private function computeResult(callable $cb): bool
110+
{
111+
$result = true;
133112
foreach ($this->properties as $property) {
134-
if (!$property->isWritable()) {
135-
return false;
136-
}
113+
$result = $result && $cb($property);
137114
}
138115

139-
return true;
116+
return $result;
140117
}
141118

142119
}

Diff for: tests/PHPStan/Rules/Properties/WritingToReadOnlyPropertiesRuleTest.php

+4
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ public function testObjectShapes(): void
6969
'Property object{foo: int, bar?: string}::$foo is not writable.',
7070
18,
7171
],
72+
[
73+
'Property object{foo: int}|stdClass::$foo is not writable.',
74+
42,
75+
],
7276
]);
7377
}
7478

Diff for: tests/PHPStan/Rules/Properties/data/properties-object-shapes.php

+22
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,26 @@ public function doFoo(object $o): void
2020
$o->baz = 3;
2121
}
2222

23+
/**
24+
* @param object{foo: int}&\stdClass $o
25+
* @return void
26+
*/
27+
public function doIntersection(object $o): void
28+
{
29+
echo $o->foo;
30+
31+
$o->foo = 1;
32+
}
33+
34+
/**
35+
* @param object{foo: int}|\stdClass $o
36+
* @return void
37+
*/
38+
public function doUnion(object $o): void
39+
{
40+
echo $o->foo;
41+
42+
$o->foo = 1;
43+
}
44+
2345
}

0 commit comments

Comments
 (0)