Skip to content

Commit 95a8777

Browse files
jtojnarondrejmirtes
authored andcommitted
AnnotationsPropertiesClassReflectionExtension: More specific property prevail
Restore the behaviour from before asymmetric properties were introduced, when `@property-read` and `@property-write` would shadow `@property`. This is slightly more intuitive since those tags are more specific.
1 parent 82fa54b commit 95a8777

File tree

3 files changed

+11
-25
lines changed

3 files changed

+11
-25
lines changed

Diff for: src/PhpDoc/PhpDocNodeResolver.php

+8-22
Original file line numberDiff line numberDiff line change
@@ -110,20 +110,20 @@ public function resolvePropertyTags(PhpDocNode $phpDocNode, NameScope $nameScope
110110
}
111111
}
112112

113-
$readable = [];
114113
foreach (['@property-read', '@phpstan-property-read'] as $tagName) {
115114
foreach ($phpDocNode->getPropertyReadTagValues($tagName) as $tagValue) {
116115
$propertyName = substr($tagValue->propertyName, 1);
117116
$propertyType = $this->typeNodeResolver->resolve($tagValue->type, $nameScope);
118117

118+
$writableType = null;
119119
if (array_key_exists($propertyName, $resolved)) {
120-
continue;
120+
$writableType = $resolved[$propertyName]->getWritableType();
121121
}
122122

123-
$readable[$propertyName] = new PropertyTag(
123+
$resolved[$propertyName] = new PropertyTag(
124124
$propertyType,
125125
$propertyType,
126-
null,
126+
$writableType,
127127
);
128128
}
129129
}
@@ -133,33 +133,19 @@ public function resolvePropertyTags(PhpDocNode $phpDocNode, NameScope $nameScope
133133
$propertyName = substr($tagValue->propertyName, 1);
134134
$propertyType = $this->typeNodeResolver->resolve($tagValue->type, $nameScope);
135135

136+
$readableType = null;
136137
if (array_key_exists($propertyName, $resolved)) {
137-
continue;
138-
}
139-
140-
if (array_key_exists($propertyName, $readable)) {
141-
$readableProperty = $readable[$propertyName];
142-
$resolved[$propertyName] = new PropertyTag(
143-
$propertyType,
144-
$readableProperty->getReadableType(),
145-
$propertyType,
146-
);
147-
unset($readable[$propertyName]);
148-
continue;
138+
$readableType = $resolved[$propertyName]->getReadableType();
149139
}
150140

151141
$resolved[$propertyName] = new PropertyTag(
152-
$propertyType,
153-
null,
142+
$readableType ?? $propertyType,
143+
$readableType,
154144
$propertyType,
155145
);
156146
}
157147
}
158148

159-
foreach ($readable as $propertyName => $tag) {
160-
$resolved[$propertyName] = $tag;
161-
}
162-
163149
return $resolved;
164150
}
165151

Diff for: tests/PHPStan/Analyser/data/asymmetric-properties.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public function doFoo(): void
2323
{
2424
assertType('int', $this->asymmetricPropertyRw);
2525
assertType('int', $this->asymmetricPropertyXw);
26-
assertType('int|string', $this->asymmetricPropertyRx);
26+
assertType('int', $this->asymmetricPropertyRx);
2727
}
2828

2929
}

Diff for: tests/PHPStan/Reflection/Annotations/AnnotationsPropertiesClassReflectionExtensionTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -255,13 +255,13 @@ public function dataProperties(): array
255255
'asymmetricPropertyXw' => [
256256
'class' => Asymmetric::class,
257257
'readableType' => 'int',
258-
'writableType' => 'int',
258+
'writableType' => 'int|string',
259259
'writable' => true,
260260
'readable' => true,
261261
],
262262
'asymmetricPropertyRx' => [
263263
'class' => Asymmetric::class,
264-
'readableType' => 'int|string',
264+
'readableType' => 'int',
265265
'writableType' => 'int|string',
266266
'writable' => true,
267267
'readable' => true,

0 commit comments

Comments
 (0)