Skip to content

Commit 8d4f035

Browse files
committed
Updated Rector to commit 7625651d236a332b8412a19195b7c6153b52d961
rectorphp/rector-src@7625651 [Php81] Skip NullToStrictStringFuncCallArgRector for magic __get() property access resolving to ErrorType (#7992)
1 parent ebed387 commit 8d4f035

6 files changed

Lines changed: 75 additions & 9 deletions

File tree

rules/Php81/NodeManipulator/NullToStrictStringIntConverter.php

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PhpParser\Node\Expr\Cast\String_ as CastString_;
1010
use PhpParser\Node\Expr\FuncCall;
1111
use PhpParser\Node\Expr\MethodCall;
12+
use PhpParser\Node\Expr\PropertyFetch;
1213
use PhpParser\Node\Expr\Ternary;
1314
use PhpParser\Node\Expr\Variable;
1415
use PhpParser\Node\Scalar\Int_;
@@ -18,9 +19,11 @@
1819
use PHPStan\Analyser\Scope;
1920
use PHPStan\Reflection\Native\ExtendedNativeParameterReflection;
2021
use PHPStan\Reflection\ParametersAcceptor;
22+
use PHPStan\Reflection\ReflectionProvider;
2123
use PHPStan\Type\ErrorType;
2224
use PHPStan\Type\MixedType;
2325
use PHPStan\Type\NullType;
26+
use PHPStan\Type\ObjectType;
2427
use PHPStan\Type\Type;
2528
use PHPStan\Type\UnionType;
2629
use Rector\NodeAnalyzer\PropertyFetchAnalyzer;
@@ -41,11 +44,16 @@ final class NullToStrictStringIntConverter
4144
* @readonly
4245
*/
4346
private PropertyFetchAnalyzer $propertyFetchAnalyzer;
44-
public function __construct(ValueResolver $valueResolver, NodeTypeResolver $nodeTypeResolver, PropertyFetchAnalyzer $propertyFetchAnalyzer)
47+
/**
48+
* @readonly
49+
*/
50+
private ReflectionProvider $reflectionProvider;
51+
public function __construct(ValueResolver $valueResolver, NodeTypeResolver $nodeTypeResolver, PropertyFetchAnalyzer $propertyFetchAnalyzer, ReflectionProvider $reflectionProvider)
4552
{
4653
$this->valueResolver = $valueResolver;
4754
$this->nodeTypeResolver = $nodeTypeResolver;
4855
$this->propertyFetchAnalyzer = $propertyFetchAnalyzer;
56+
$this->reflectionProvider = $reflectionProvider;
4957
}
5058
/**
5159
* @param Arg[] $args
@@ -101,6 +109,9 @@ public function convertIfNull(FuncCall $funcCall, array $args, int $position, bo
101109
}
102110
private function shouldSkipValue(Expr $expr, Scope $scope, bool $isTrait, string $targetType): bool
103111
{
112+
if ($this->isPropertyFetchOnClassWithMagicGet($expr)) {
113+
return \true;
114+
}
104115
$type = $this->nodeTypeResolver->getType($expr);
105116
if ($type->isString()->yes() && $targetType === 'string') {
106117
return \true;
@@ -129,6 +140,20 @@ private function shouldSkipValue(Expr $expr, Scope $scope, bool $isTrait, string
129140
}
130141
return $this->shouldSkipTrait($expr, $type, $isTrait);
131142
}
143+
private function isPropertyFetchOnClassWithMagicGet(Expr $expr): bool
144+
{
145+
if (!$expr instanceof PropertyFetch) {
146+
return \false;
147+
}
148+
$varType = $this->nodeTypeResolver->getType($expr->var);
149+
if (!$varType instanceof ObjectType) {
150+
return \false;
151+
}
152+
if (!$this->reflectionProvider->hasClass($varType->getClassName())) {
153+
return \false;
154+
}
155+
return $this->reflectionProvider->getClass($varType->getClassName())->hasMethod('__get');
156+
}
132157
private function isValidUnionType(Type $type): bool
133158
{
134159
if (!$type instanceof UnionType) {

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 = '89d191b0be1446e24ebc0b213f3b99a4261be246';
22+
public const PACKAGE_VERSION = '7625651d236a332b8412a19195b7c6153b52d961';
2323
/**
2424
* @api
2525
* @var string
2626
*/
27-
public const RELEASE_DATE = '2026-05-16 01:47:27';
27+
public const RELEASE_DATE = '2026-05-16 22:57:27';
2828
/**
2929
* @var int
3030
*/

vendor/composer/installed.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1867,12 +1867,12 @@
18671867
"source": {
18681868
"type": "git",
18691869
"url": "https:\/\/github.com\/rectorphp\/rector-symfony.git",
1870-
"reference": "e69bd32bea0dc330a0c79b919945abe67851d887"
1870+
"reference": "55ece61bcc1e1bb830da9c21c724652392e63f49"
18711871
},
18721872
"dist": {
18731873
"type": "zip",
1874-
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-symfony\/zipball\/e69bd32bea0dc330a0c79b919945abe67851d887",
1875-
"reference": "e69bd32bea0dc330a0c79b919945abe67851d887",
1874+
"url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-symfony\/zipball\/55ece61bcc1e1bb830da9c21c724652392e63f49",
1875+
"reference": "55ece61bcc1e1bb830da9c21c724652392e63f49",
18761876
"shasum": ""
18771877
},
18781878
"require": {
@@ -1906,7 +1906,7 @@
19061906
"tomasvotruba\/unused-public": "^2.2",
19071907
"tracy\/tracy": "^2.11"
19081908
},
1909-
"time": "2026-05-08T13:38:57+00:00",
1909+
"time": "2026-05-16T20:52:49+00:00",
19101910
"default-branch": true,
19111911
"type": "rector-extension",
19121912
"extra": {

vendor/composer/installed.php

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

vendor/rector/extension-installer/src/GeneratedConfig.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
final class GeneratedConfig
1111
{
12-
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main fb71542'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main 364fbdb'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main d4fd79d'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main e69bd32'));
12+
public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main fb71542'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main 364fbdb'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main d4fd79d'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main 55ece61'));
1313
private function __construct()
1414
{
1515
}

vendor/rector/rector-symfony/rules/CodeQuality/Rector/Class_/ControllerMethodInjectionToConstructorRector.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Exception;
77
use PhpParser\Node;
88
use PhpParser\Node\Expr\Closure;
9+
use PhpParser\Node\Expr\MethodCall;
910
use PhpParser\Node\Expr\PropertyFetch;
1011
use PhpParser\Node\Expr\Variable;
1112
use PhpParser\Node\Name\FullyQualified;
@@ -142,6 +143,8 @@ public function refactor(Node $node): ?Node
142143
$paramsToRemove = [];
143144
/** @var array<string, string[]> $methodParamNamesToReplace */
144145
$methodParamNamesToReplace = [];
146+
/** @var array<string, int[]> $removedMethodArgPositions */
147+
$removedMethodArgPositions = [];
145148
foreach ($node->getMethods() as $classMethod) {
146149
if ($this->shouldSkipClassMethod($classMethod)) {
147150
continue;
@@ -188,6 +191,7 @@ public function refactor(Node $node): ?Node
188191
$paramsToRemove[] = [$classMethod, $key];
189192
$propertyMetadatas[$paramName] = new PropertyMetadata($paramName, $paramType);
190193
$methodParamNamesToReplace[$classMethod->name->toString()][] = $paramName;
194+
$removedMethodArgPositions[$classMethod->name->toString()][] = $key;
191195
}
192196
}
193197
// nothing to move
@@ -212,8 +216,45 @@ public function refactor(Node $node): ?Node
212216
}
213217
$this->replaceParamUseWithPropertyFetch($classMethod, $methodParamNamesToReplace[$methodName]);
214218
}
219+
$this->updateCallSitesForRemovedParams($node, $removedMethodArgPositions);
215220
return $node;
216221
}
222+
/**
223+
* @param array<string, int[]> $removedArgPositionsByMethod
224+
*/
225+
private function updateCallSitesForRemovedParams(Class_ $class, array $removedArgPositionsByMethod): void
226+
{
227+
if ($removedArgPositionsByMethod === []) {
228+
return;
229+
}
230+
foreach ($class->getMethods() as $classMethod) {
231+
if ($classMethod->stmts === null) {
232+
continue;
233+
}
234+
$this->traverseNodesWithCallable($classMethod->stmts, function (Node $node) use ($removedArgPositionsByMethod): ?MethodCall {
235+
if (!$node instanceof MethodCall) {
236+
return null;
237+
}
238+
if (!$node->var instanceof Variable) {
239+
return null;
240+
}
241+
if (!$this->isName($node->var, 'this')) {
242+
return null;
243+
}
244+
$methodName = $this->getName($node->name);
245+
if ($methodName === null || !isset($removedArgPositionsByMethod[$methodName])) {
246+
return null;
247+
}
248+
$removedPositions = $removedArgPositionsByMethod[$methodName];
249+
rsort($removedPositions);
250+
foreach ($removedPositions as $removedPosition) {
251+
unset($node->args[$removedPosition]);
252+
}
253+
$node->args = array_values($node->args);
254+
return $node;
255+
});
256+
}
257+
}
217258
private function shouldSkipClassMethod(ClassMethod $classMethod): bool
218259
{
219260
if ($classMethod->isMagic() && !$this->isName($classMethod->name, MethodName::INVOKE)) {

0 commit comments

Comments
 (0)