Skip to content

Commit 90e2775

Browse files
committed
Updated Rector to commit 4b78d1229d48cb05a472f7c7895d10a2e090f9a6
rectorphp/rector-src@4b78d12 [fix] Fix PrivatizeFinalClassMethodRector in case of parent dynamic call (#7730)
1 parent 5f6cdb5 commit 90e2775

File tree

12 files changed

+245
-68
lines changed

12 files changed

+245
-68
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
declare (strict_types=1);
4+
namespace Rector\Privatization\Guard;
5+
6+
use PhpParser\PrettyPrinterAbstract;
7+
use PhpParser\Node\Expr;
8+
use PhpParser\Node\Expr\MethodCall;
9+
use PhpParser\Node\Name;
10+
use PhpParser\Node\Stmt\Class_;
11+
use PhpParser\PrettyPrinter\Standard;
12+
use Rector\NodeNameResolver\NodeNameResolver;
13+
use Rector\PhpParser\AstResolver;
14+
use Rector\PhpParser\Node\BetterNodeFinder;
15+
final class ParentClassMagicCallGuard
16+
{
17+
/**
18+
* @readonly
19+
*/
20+
private NodeNameResolver $nodeNameResolver;
21+
/**
22+
* @readonly
23+
*/
24+
private AstResolver $astResolver;
25+
/**
26+
* @readonly
27+
*/
28+
private BetterNodeFinder $betterNodeFinder;
29+
/**
30+
* To speed up analysis
31+
* @var string[]
32+
*/
33+
private const KNOWN_DYNAMIC_CALL_CLASSES = [Standard::class, PrettyPrinterAbstract::class];
34+
/**
35+
* @var array<string, bool>
36+
*/
37+
private array $cachedContainsByClassName = [];
38+
public function __construct(NodeNameResolver $nodeNameResolver, AstResolver $astResolver, BetterNodeFinder $betterNodeFinder)
39+
{
40+
$this->nodeNameResolver = $nodeNameResolver;
41+
$this->astResolver = $astResolver;
42+
$this->betterNodeFinder = $betterNodeFinder;
43+
foreach (self::KNOWN_DYNAMIC_CALL_CLASSES as $knownDynamicCallClass) {
44+
$this->cachedContainsByClassName[$knownDynamicCallClass] = \true;
45+
}
46+
}
47+
/**
48+
* E.g. parent class has $this->{$magicName} call that might call the protected method
49+
* If we make it private, it will break the code
50+
*/
51+
public function containsParentClassMagicCall(Class_ $class): bool
52+
{
53+
if (!$class->extends instanceof Name) {
54+
return \false;
55+
}
56+
// cache as heavy AST parsing here
57+
$className = $this->nodeNameResolver->getName($class);
58+
if (isset($this->cachedContainsByClassName[$className])) {
59+
return $this->cachedContainsByClassName[$className];
60+
}
61+
$parentClassName = $this->nodeNameResolver->getName($class->extends);
62+
if (isset($this->cachedContainsByClassName[$parentClassName])) {
63+
return $this->cachedContainsByClassName[$parentClassName];
64+
}
65+
$parentClass = $this->astResolver->resolveClassFromName($parentClassName);
66+
if (!$parentClass instanceof Class_) {
67+
$this->cachedContainsByClassName[$parentClassName] = \false;
68+
return \false;
69+
}
70+
foreach ($parentClass->getMethods() as $classMethod) {
71+
if ($classMethod->isAbstract()) {
72+
continue;
73+
}
74+
/** @var MethodCall[] $methodCalls */
75+
$methodCalls = $this->betterNodeFinder->findInstancesOfScoped((array) $classMethod->stmts, MethodCall::class);
76+
foreach ($methodCalls as $methodCall) {
77+
if ($methodCall->name instanceof Expr) {
78+
$this->cachedContainsByClassName[$parentClassName] = \true;
79+
return \true;
80+
}
81+
}
82+
}
83+
return $this->containsParentClassMagicCall($parentClass);
84+
}
85+
}

rules/Privatization/Rector/ClassMethod/PrivatizeFinalClassMethodRector.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Rector\PHPStan\ScopeFetcher;
1313
use Rector\Privatization\Guard\LaravelModelGuard;
1414
use Rector\Privatization\Guard\OverrideByParentClassGuard;
15+
use Rector\Privatization\Guard\ParentClassMagicCallGuard;
1516
use Rector\Privatization\NodeManipulator\VisibilityManipulator;
1617
use Rector\Privatization\VisibilityGuard\ClassMethodVisibilityGuard;
1718
use Rector\Rector\AbstractRector;
@@ -42,13 +43,18 @@ final class PrivatizeFinalClassMethodRector extends AbstractRector
4243
* @readonly
4344
*/
4445
private LaravelModelGuard $laravelModelGuard;
45-
public function __construct(ClassMethodVisibilityGuard $classMethodVisibilityGuard, VisibilityManipulator $visibilityManipulator, OverrideByParentClassGuard $overrideByParentClassGuard, BetterNodeFinder $betterNodeFinder, LaravelModelGuard $laravelModelGuard)
46+
/**
47+
* @readonly
48+
*/
49+
private ParentClassMagicCallGuard $parentClassMagicCallGuard;
50+
public function __construct(ClassMethodVisibilityGuard $classMethodVisibilityGuard, VisibilityManipulator $visibilityManipulator, OverrideByParentClassGuard $overrideByParentClassGuard, BetterNodeFinder $betterNodeFinder, LaravelModelGuard $laravelModelGuard, ParentClassMagicCallGuard $parentClassMagicCallGuard)
4651
{
4752
$this->classMethodVisibilityGuard = $classMethodVisibilityGuard;
4853
$this->visibilityManipulator = $visibilityManipulator;
4954
$this->overrideByParentClassGuard = $overrideByParentClassGuard;
5055
$this->betterNodeFinder = $betterNodeFinder;
5156
$this->laravelModelGuard = $laravelModelGuard;
57+
$this->parentClassMagicCallGuard = $parentClassMagicCallGuard;
5258
}
5359
public function getRuleDefinition(): RuleDefinition
5460
{
@@ -107,6 +113,9 @@ public function refactor(Node $node): ?Node
107113
if ($this->classMethodVisibilityGuard->isClassMethodVisibilityGuardedByTrait($classMethod, $classReflection)) {
108114
continue;
109115
}
116+
if ($this->parentClassMagicCallGuard->containsParentClassMagicCall($node)) {
117+
continue;
118+
}
110119
$this->visibilityManipulator->makePrivate($classMethod);
111120
$hasChanged = \true;
112121
}

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 = '885ba026b944ca24983e705bf74281dc06df5664';
22+
public const PACKAGE_VERSION = '4b78d1229d48cb05a472f7c7895d10a2e090f9a6';
2323
/**
2424
* @api
2525
* @var string
2626
*/
27-
public const RELEASE_DATE = '2025-12-07 12:11:20';
27+
public const RELEASE_DATE = '2025-12-07 22:08:54';
2828
/**
2929
* @var int
3030
*/

vendor/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2325,6 +2325,7 @@
23252325
'Rector\\PostRector\\ValueObject\\PropertyMetadata' => $baseDir . '/src/PostRector/ValueObject/PropertyMetadata.php',
23262326
'Rector\\Privatization\\Guard\\LaravelModelGuard' => $baseDir . '/rules/Privatization/Guard/LaravelModelGuard.php',
23272327
'Rector\\Privatization\\Guard\\OverrideByParentClassGuard' => $baseDir . '/rules/Privatization/Guard/OverrideByParentClassGuard.php',
2328+
'Rector\\Privatization\\Guard\\ParentClassMagicCallGuard' => $baseDir . '/rules/Privatization/Guard/ParentClassMagicCallGuard.php',
23282329
'Rector\\Privatization\\Guard\\ParentPropertyLookupGuard' => $baseDir . '/rules/Privatization/Guard/ParentPropertyLookupGuard.php',
23292330
'Rector\\Privatization\\NodeManipulator\\VisibilityManipulator' => $baseDir . '/rules/Privatization/NodeManipulator/VisibilityManipulator.php',
23302331
'Rector\\Privatization\\Rector\\ClassMethod\\PrivatizeFinalClassMethodRector' => $baseDir . '/rules/Privatization/Rector/ClassMethod/PrivatizeFinalClassMethodRector.php',

vendor/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2585,6 +2585,7 @@ class ComposerStaticInit9382e835eeb0e1e0bafb04fcb204a42a
25852585
'Rector\\PostRector\\ValueObject\\PropertyMetadata' => __DIR__ . '/../..' . '/src/PostRector/ValueObject/PropertyMetadata.php',
25862586
'Rector\\Privatization\\Guard\\LaravelModelGuard' => __DIR__ . '/../..' . '/rules/Privatization/Guard/LaravelModelGuard.php',
25872587
'Rector\\Privatization\\Guard\\OverrideByParentClassGuard' => __DIR__ . '/../..' . '/rules/Privatization/Guard/OverrideByParentClassGuard.php',
2588+
'Rector\\Privatization\\Guard\\ParentClassMagicCallGuard' => __DIR__ . '/../..' . '/rules/Privatization/Guard/ParentClassMagicCallGuard.php',
25882589
'Rector\\Privatization\\Guard\\ParentPropertyLookupGuard' => __DIR__ . '/../..' . '/rules/Privatization/Guard/ParentPropertyLookupGuard.php',
25892590
'Rector\\Privatization\\NodeManipulator\\VisibilityManipulator' => __DIR__ . '/../..' . '/rules/Privatization/NodeManipulator/VisibilityManipulator.php',
25902591
'Rector\\Privatization\\Rector\\ClassMethod\\PrivatizeFinalClassMethodRector' => __DIR__ . '/../..' . '/rules/Privatization/Rector/ClassMethod/PrivatizeFinalClassMethodRector.php',

vendor/composer/installed.json

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2011,17 +2011,17 @@
20112011
},
20122012
{
20132013
"name": "symfony\/console",
2014-
"version": "v6.4.27",
2015-
"version_normalized": "6.4.27.0",
2014+
"version": "v6.4.30",
2015+
"version_normalized": "6.4.30.0",
20162016
"source": {
20172017
"type": "git",
20182018
"url": "https:\/\/github.com\/symfony\/console.git",
2019-
"reference": "13d3176cf8ad8ced24202844e9f95af11e2959fc"
2019+
"reference": "1b2813049506b39eb3d7e64aff033fd5ca26c97e"
20202020
},
20212021
"dist": {
20222022
"type": "zip",
2023-
"url": "https:\/\/api.github.com\/repos\/symfony\/console\/zipball\/13d3176cf8ad8ced24202844e9f95af11e2959fc",
2024-
"reference": "13d3176cf8ad8ced24202844e9f95af11e2959fc",
2023+
"url": "https:\/\/api.github.com\/repos\/symfony\/console\/zipball\/1b2813049506b39eb3d7e64aff033fd5ca26c97e",
2024+
"reference": "1b2813049506b39eb3d7e64aff033fd5ca26c97e",
20252025
"shasum": ""
20262026
},
20272027
"require": {
@@ -2054,7 +2054,7 @@
20542054
"symfony\/stopwatch": "^5.4|^6.0|^7.0",
20552055
"symfony\/var-dumper": "^5.4|^6.0|^7.0"
20562056
},
2057-
"time": "2025-10-06T10:25:16+00:00",
2057+
"time": "2025-12-05T13:47:41+00:00",
20582058
"type": "library",
20592059
"installation-source": "dist",
20602060
"autoload": {
@@ -2088,7 +2088,7 @@
20882088
"terminal"
20892089
],
20902090
"support": {
2091-
"source": "https:\/\/github.com\/symfony\/console\/tree\/v6.4.27"
2091+
"source": "https:\/\/github.com\/symfony\/console\/tree\/v6.4.30"
20922092
},
20932093
"funding": [
20942094
{
@@ -2182,17 +2182,17 @@
21822182
},
21832183
{
21842184
"name": "symfony\/filesystem",
2185-
"version": "v6.4.24",
2186-
"version_normalized": "6.4.24.0",
2185+
"version": "v6.4.30",
2186+
"version_normalized": "6.4.30.0",
21872187
"source": {
21882188
"type": "git",
21892189
"url": "https:\/\/github.com\/symfony\/filesystem.git",
2190-
"reference": "75ae2edb7cdcc0c53766c30b0a2512b8df574bd8"
2190+
"reference": "441c6b69f7222aadae7cbf5df588496d5ee37789"
21912191
},
21922192
"dist": {
21932193
"type": "zip",
2194-
"url": "https:\/\/api.github.com\/repos\/symfony\/filesystem\/zipball\/75ae2edb7cdcc0c53766c30b0a2512b8df574bd8",
2195-
"reference": "75ae2edb7cdcc0c53766c30b0a2512b8df574bd8",
2194+
"url": "https:\/\/api.github.com\/repos\/symfony\/filesystem\/zipball\/441c6b69f7222aadae7cbf5df588496d5ee37789",
2195+
"reference": "441c6b69f7222aadae7cbf5df588496d5ee37789",
21962196
"shasum": ""
21972197
},
21982198
"require": {
@@ -2203,7 +2203,7 @@
22032203
"require-dev": {
22042204
"symfony\/process": "^5.4|^6.4|^7.0"
22052205
},
2206-
"time": "2025-07-10T08:14:14+00:00",
2206+
"time": "2025-11-26T14:43:45+00:00",
22072207
"type": "library",
22082208
"installation-source": "dist",
22092209
"autoload": {
@@ -2231,7 +2231,7 @@
22312231
"description": "Provides basic utilities for the filesystem",
22322232
"homepage": "https:\/\/symfony.com",
22332233
"support": {
2234-
"source": "https:\/\/github.com\/symfony\/filesystem\/tree\/v6.4.24"
2234+
"source": "https:\/\/github.com\/symfony\/filesystem\/tree\/v6.4.30"
22352235
},
22362236
"funding": [
22372237
{
@@ -3091,17 +3091,17 @@
30913091
},
30923092
{
30933093
"name": "symfony\/yaml",
3094-
"version": "v7.4.0",
3095-
"version_normalized": "7.4.0.0",
3094+
"version": "v7.4.1",
3095+
"version_normalized": "7.4.1.0",
30963096
"source": {
30973097
"type": "git",
30983098
"url": "https:\/\/github.com\/symfony\/yaml.git",
3099-
"reference": "6c84a4b55aee4cd02034d1c528e83f69ddf63810"
3099+
"reference": "24dd4de28d2e3988b311751ac49e684d783e2345"
31003100
},
31013101
"dist": {
31023102
"type": "zip",
3103-
"url": "https:\/\/api.github.com\/repos\/symfony\/yaml\/zipball\/6c84a4b55aee4cd02034d1c528e83f69ddf63810",
3104-
"reference": "6c84a4b55aee4cd02034d1c528e83f69ddf63810",
3103+
"url": "https:\/\/api.github.com\/repos\/symfony\/yaml\/zipball\/24dd4de28d2e3988b311751ac49e684d783e2345",
3104+
"reference": "24dd4de28d2e3988b311751ac49e684d783e2345",
31053105
"shasum": ""
31063106
},
31073107
"require": {
@@ -3115,7 +3115,7 @@
31153115
"require-dev": {
31163116
"symfony\/console": "^6.4|^7.0|^8.0"
31173117
},
3118-
"time": "2025-11-16T10:14:42+00:00",
3118+
"time": "2025-12-04T18:11:45+00:00",
31193119
"bin": [
31203120
"Resources\/bin\/yaml-lint"
31213121
],
@@ -3146,7 +3146,7 @@
31463146
"description": "Loads and dumps YAML files",
31473147
"homepage": "https:\/\/symfony.com",
31483148
"support": {
3149-
"source": "https:\/\/github.com\/symfony\/yaml\/tree\/v7.4.0"
3149+
"source": "https:\/\/github.com\/symfony\/yaml\/tree\/v7.4.1"
31503150
},
31513151
"funding": [
31523152
{

0 commit comments

Comments
 (0)