Skip to content

Commit 4da59a5

Browse files
committed
Updated Rector to commit 5be8f82d019842fb56fd0338da0b0569dbdf0bcb
rectorphp/rector-src@5be8f82 [injection] If parent class has dependency via promoted property, but its private, add a new one to child class deps (#7996)
1 parent 4c6535f commit 4da59a5

2 files changed

Lines changed: 25 additions & 8 deletions

File tree

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 = '27c0087701a3668d9418f063f186ecdc3e561aa1';
22+
public const PACKAGE_VERSION = '5be8f82d019842fb56fd0338da0b0569dbdf0bcb';
2323
/**
2424
* @api
2525
* @var string
2626
*/
27-
public const RELEASE_DATE = '2026-05-18 08:22:07';
27+
public const RELEASE_DATE = '2026-05-18 12:15:58';
2828
/**
2929
* @var int
3030
*/

src/NodeManipulator/ClassDependencyManipulator.php

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
declare (strict_types=1);
44
namespace Rector\NodeManipulator;
55

6+
use PhpParser\Modifiers;
67
use PhpParser\Node\Arg;
78
use PhpParser\Node\Expr\Assign;
89
use PhpParser\Node\Expr\StaticCall;
910
use PhpParser\Node\Expr\Variable;
1011
use PhpParser\Node\Name;
12+
use PhpParser\Node\Param;
1113
use PhpParser\Node\Stmt;
1214
use PhpParser\Node\Stmt\Class_;
1315
use PhpParser\Node\Stmt\ClassLike;
@@ -200,12 +202,27 @@ private function addPromotedProperty(Class_ $class, PropertyMetadata $propertyMe
200202
{
201203
$param = $this->nodeFactory->createPromotedPropertyParam($propertyMetadata);
202204
if ($constructClassMethod instanceof ClassMethod) {
203-
// parameter is already added
204-
if ($this->hasMethodParameter($constructClassMethod, $propertyMetadata->getName())) {
205+
$hasOwnConstruct = $class->getMethod(MethodName::CONSTRUCT) instanceof ClassMethod;
206+
$matchedParam = $this->matchMethodParameter($constructClassMethod, $propertyMetadata->getName());
207+
if ($matchedParam instanceof Param) {
208+
// own constructor already has this param → nothing to do
209+
if ($hasOwnConstruct) {
210+
return;
211+
}
212+
// parent constructor has a same-named param; if it is a private promoted
213+
// property, the child cannot access it via $this — add a fresh constructor
214+
// on the child instead of trying to extend the parent signature
215+
if (($matchedParam->flags & Modifiers::PRIVATE) !== 0) {
216+
$childConstructClassMethod = $this->nodeFactory->createPublicMethod(MethodName::CONSTRUCT);
217+
$childConstructClassMethod->params[] = $param;
218+
$this->classInsertManipulator->addAsFirstMethod($class, $childConstructClassMethod);
219+
return;
220+
}
221+
// parent's matching param is protected/public — accessible from child, no add needed
205222
return;
206223
}
207224
// found construct, but only on parent, add to current class
208-
if (!$class->getMethod(MethodName::CONSTRUCT) instanceof ClassMethod) {
225+
if (!$hasOwnConstruct) {
209226
$parentArgs = [];
210227
foreach ($constructClassMethod->params as $originalParam) {
211228
$parentArgs[] = new Arg(new Variable((string) $this->nodeNameResolver->getName($originalParam->var)));
@@ -265,14 +282,14 @@ private function hasClassPropertyAndDependency(Class_ $class, PropertyMetadata $
265282
// is inject/autowired property?
266283
return $property instanceof Property;
267284
}
268-
private function hasMethodParameter(ClassMethod $classMethod, string $name): bool
285+
private function matchMethodParameter(ClassMethod $classMethod, string $name): ?Param
269286
{
270287
foreach ($classMethod->params as $param) {
271288
if ($this->nodeNameResolver->isName($param->var, $name)) {
272-
return \true;
289+
return $param;
273290
}
274291
}
275-
return \false;
292+
return null;
276293
}
277294
private function shouldAddPromotedProperty(Class_ $class, PropertyMetadata $propertyMetadata): bool
278295
{

0 commit comments

Comments
 (0)