Skip to content

Commit a800970

Browse files
committed
Updated Rector to commit eebd08648851e64a18c19c62710546c14729da00
rectorphp/rector-src@eebd086 [Php81] Skip readonly on property returned by reference in ReadOnlyPropertyRector (#8108)
1 parent 9bdd3b4 commit a800970

2 files changed

Lines changed: 30 additions & 2 deletions

File tree

rules/Php81/Rector/Property/ReadOnlyPropertyRector.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use PhpParser\Node\Stmt\Class_;
1414
use PhpParser\Node\Stmt\ClassMethod;
1515
use PhpParser\Node\Stmt\Property;
16+
use PhpParser\Node\Stmt\Return_;
1617
use PhpParser\NodeVisitor;
1718
use PHPStan\Analyser\Scope;
1819
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
@@ -176,6 +177,10 @@ private function refactorProperty(Class_ $class, Property $property, Scope $scop
176177
if ($this->propertyFetchAssignManipulator->isAssignedMultipleTimesInConstructor($class, $property)) {
177178
return null;
178179
}
180+
// returned by reference can be mutated outside the class, so it cannot be readonly
181+
if ($this->isPropertyReturnedByRef($class, (string) $this->getName($property))) {
182+
return null;
183+
}
179184
$this->visibilityManipulator->makeReadonly($property);
180185
$this->removeReadOnlyDoc($property);
181186
return $property;
@@ -226,10 +231,33 @@ private function refactorParam(Class_ $class, ClassMethod $classMethod, Param $p
226231
if ($this->isPromotedPropertyAssigned($class, $param)) {
227232
return null;
228233
}
234+
// returned by reference can be mutated outside the class, so it cannot be readonly
235+
if ($this->isPropertyReturnedByRef($class, (string) $this->getName($param))) {
236+
return null;
237+
}
229238
$this->visibilityManipulator->makeReadonly($param);
230239
$this->removeReadOnlyDoc($param);
231240
return $param;
232241
}
242+
private function isPropertyReturnedByRef(Class_ $class, string $propertyName): bool
243+
{
244+
foreach ($class->getMethods() as $classMethod) {
245+
if (!$classMethod->byRef) {
246+
continue;
247+
}
248+
$returns = $this->betterNodeFinder->findInstanceOf($classMethod, Return_::class);
249+
foreach ($returns as $return) {
250+
if (!$return->expr instanceof Expr) {
251+
continue;
252+
}
253+
$propertyFetch = $this->betterNodeFinder->findFirst($return->expr, fn(Node $subNode): bool => $subNode instanceof PropertyFetch && $this->isName($subNode->var, 'this') && $this->isName($subNode, $propertyName));
254+
if ($propertyFetch instanceof PropertyFetch) {
255+
return \true;
256+
}
257+
}
258+
}
259+
return \false;
260+
}
233261
private function isPromotedPropertyAssigned(Class_ $class, Param $param): bool
234262
{
235263
$constructClassMethod = $class->getMethod(MethodName::CONSTRUCT);

src/Application/VersionResolver.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ final class VersionResolver
1919
* @api
2020
* @var string
2121
*/
22-
public const PACKAGE_VERSION = '0180e9bb149b532f2864c60bf255b04bf75107f0';
22+
public const PACKAGE_VERSION = 'eebd08648851e64a18c19c62710546c14729da00';
2323
/**
2424
* @api
2525
* @var string
2626
*/
27-
public const RELEASE_DATE = '2026-06-29 11:16:35';
27+
public const RELEASE_DATE = '2026-06-29 11:18:40';
2828
/**
2929
* @var int
3030
*/

0 commit comments

Comments
 (0)