Skip to content

Commit ff9faa5

Browse files
committed
Updated Rector to commit 26a142f6e5c0d4289b3d4a72fda8245cad6fa254
rectorphp/rector-src@26a142f [code-quality] Add AttributeNamedArgsRector (#8079)
1 parent 323ffba commit ff9faa5

5 files changed

Lines changed: 117 additions & 3 deletions

File tree

config/set/named-args.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
declare (strict_types=1);
44
namespace RectorPrefix202606;
55

6+
use Rector\CodeQuality\Rector\Attribute\ExplicitAttributeNamedArgsRector;
67
use Rector\CodeQuality\Rector\Attribute\SortAttributeNamedArgsRector;
78
use Rector\CodeQuality\Rector\CallLike\AddNameToBooleanArgumentRector;
89
use Rector\CodeQuality\Rector\CallLike\AddNameToNullArgumentRector;
@@ -11,5 +12,5 @@
1112
use Rector\DeadCode\Rector\MethodCall\RemoveNullNamedArgOnNullDefaultParamRector;
1213
use Rector\NetteUtils\Rector\StaticCall\UtilsJsonStaticCallNamedArgRector;
1314
return static function (RectorConfig $rectorConfig): void {
14-
$rectorConfig->rules([AddNameToNullArgumentRector::class, AddNameToBooleanArgumentRector::class, RemoveNullNamedArgOnNullDefaultParamRector::class, SortCallLikeNamedArgsRector::class, SortAttributeNamedArgsRector::class, UtilsJsonStaticCallNamedArgRector::class]);
15+
$rectorConfig->rules([AddNameToNullArgumentRector::class, AddNameToBooleanArgumentRector::class, RemoveNullNamedArgOnNullDefaultParamRector::class, SortCallLikeNamedArgsRector::class, SortAttributeNamedArgsRector::class, ExplicitAttributeNamedArgsRector::class, UtilsJsonStaticCallNamedArgRector::class]);
1516
};
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<?php
2+
3+
declare (strict_types=1);
4+
namespace Rector\CodeQuality\Rector\Attribute;
5+
6+
use PhpParser\Node;
7+
use PhpParser\Node\Arg;
8+
use PhpParser\Node\Attribute;
9+
use PhpParser\Node\Identifier;
10+
use PHPStan\Reflection\MethodReflection;
11+
use PHPStan\Reflection\ParameterReflection;
12+
use PHPStan\Reflection\ParametersAcceptorSelector;
13+
use Rector\Rector\AbstractRector;
14+
use Rector\Reflection\ReflectionResolver;
15+
use Rector\ValueObject\PhpVersionFeature;
16+
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
17+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
18+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
19+
/**
20+
* @see \Rector\Tests\CodeQuality\Rector\Attribute\ExplicitAttributeNamedArgsRector\ExplicitAttributeNamedArgsRectorTest
21+
*/
22+
final class ExplicitAttributeNamedArgsRector extends AbstractRector implements MinPhpVersionInterface
23+
{
24+
/**
25+
* @readonly
26+
*/
27+
private ReflectionResolver $reflectionResolver;
28+
public function __construct(ReflectionResolver $reflectionResolver)
29+
{
30+
$this->reflectionResolver = $reflectionResolver;
31+
}
32+
public function getRuleDefinition(): RuleDefinition
33+
{
34+
return new RuleDefinition('Convert positional arguments on attributes into named arguments, using the attribute constructor parameter names', [new CodeSample(<<<'CODE_SAMPLE'
35+
#[SomeAttribute(SomeClass::class, null, ['home'])]
36+
class SomeClass
37+
{
38+
}
39+
CODE_SAMPLE
40+
, <<<'CODE_SAMPLE'
41+
#[SomeAttribute(value: SomeClass::class, only: null, except: ['home'])]
42+
class SomeClass
43+
{
44+
}
45+
CODE_SAMPLE
46+
)]);
47+
}
48+
/**
49+
* @return array<class-string<Node>>
50+
*/
51+
public function getNodeTypes(): array
52+
{
53+
return [Attribute::class];
54+
}
55+
/**
56+
* @param Attribute $node
57+
*/
58+
public function refactor(Node $node): ?Node
59+
{
60+
$methodReflection = $this->reflectionResolver->resolveConstructorReflectionFromAttribute($node);
61+
if (!$methodReflection instanceof MethodReflection) {
62+
return null;
63+
}
64+
$extendedParametersAcceptor = ParametersAcceptorSelector::combineAcceptors($methodReflection->getVariants());
65+
$parameters = $extendedParametersAcceptor->getParameters();
66+
$namesToApply = $this->resolveArgNamesToApply($node->args, $parameters);
67+
if ($namesToApply === []) {
68+
return null;
69+
}
70+
foreach ($namesToApply as $position => $name) {
71+
$node->args[$position]->name = new Identifier($name);
72+
}
73+
return $node;
74+
}
75+
public function provideMinPhpVersion(): int
76+
{
77+
return PhpVersionFeature::NAMED_ARGUMENTS;
78+
}
79+
/**
80+
* Resolve the positional arguments to name, as a position => parameter-name map, or [] when
81+
* nothing should change. Naming an argument forces every later positional argument to be named
82+
* too (PHP forbids a positional argument after a named one). So if any argument maps to a
83+
* variadic parameter, or to no parameter at all (overflow past a variadic), the whole attribute
84+
* is left untouched rather than producing invalid PHP.
85+
*
86+
* @param Arg[] $args
87+
* @param ParameterReflection[] $parameters
88+
* @return array<int, string>
89+
*/
90+
private function resolveArgNamesToApply(array $args, array $parameters): array
91+
{
92+
$namesToApply = [];
93+
foreach ($args as $position => $arg) {
94+
// already named
95+
if ($arg->name instanceof Identifier) {
96+
continue;
97+
}
98+
$parameter = $parameters[$position] ?? null;
99+
// no matching parameter, e.g. overflow past a variadic
100+
if ($parameter === null) {
101+
return [];
102+
}
103+
// naming a variadic would rebind it or strand later positional arguments
104+
if ($parameter->isVariadic()) {
105+
return [];
106+
}
107+
$namesToApply[$position] = $parameter->getName();
108+
}
109+
return $namesToApply;
110+
}
111+
}

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 = '80f067637a6cc61f11791798dc4832949c97747a';
22+
public const PACKAGE_VERSION = '26a142f6e5c0d4289b3d4a72fda8245cad6fa254';
2323
/**
2424
* @api
2525
* @var string
2626
*/
27-
public const RELEASE_DATE = '2026-06-27 14:42:30';
27+
public const RELEASE_DATE = '2026-06-27 14:54:13';
2828
/**
2929
* @var int
3030
*/

vendor/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,7 @@
11921192
'Rector\\CodeQuality\\NodeManipulator\\NamedArgsSorter' => $baseDir . '/rules/CodeQuality/NodeManipulator/NamedArgsSorter.php',
11931193
'Rector\\CodeQuality\\Rector\\AssignOp\\NewArrayItemConcatAssignToAssignRector' => $baseDir . '/rules/CodeQuality/Rector/AssignOp/NewArrayItemConcatAssignToAssignRector.php',
11941194
'Rector\\CodeQuality\\Rector\\Assign\\CombinedAssignRector' => $baseDir . '/rules/CodeQuality/Rector/Assign/CombinedAssignRector.php',
1195+
'Rector\\CodeQuality\\Rector\\Attribute\\ExplicitAttributeNamedArgsRector' => $baseDir . '/rules/CodeQuality/Rector/Attribute/ExplicitAttributeNamedArgsRector.php',
11951196
'Rector\\CodeQuality\\Rector\\Attribute\\SortAttributeNamedArgsRector' => $baseDir . '/rules/CodeQuality/Rector/Attribute/SortAttributeNamedArgsRector.php',
11961197
'Rector\\CodeQuality\\Rector\\BooleanAnd\\RemoveUselessIsObjectCheckRector' => $baseDir . '/rules/CodeQuality/Rector/BooleanAnd/RemoveUselessIsObjectCheckRector.php',
11971198
'Rector\\CodeQuality\\Rector\\BooleanAnd\\RepeatedAndNotEqualToNotInArrayRector' => $baseDir . '/rules/CodeQuality/Rector/BooleanAnd/RepeatedAndNotEqualToNotInArrayRector.php',

vendor/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,7 @@ class ComposerStaticInite7732782e781a0db6ef2f014a417d492
14571457
'Rector\\CodeQuality\\NodeManipulator\\NamedArgsSorter' => __DIR__ . '/../..' . '/rules/CodeQuality/NodeManipulator/NamedArgsSorter.php',
14581458
'Rector\\CodeQuality\\Rector\\AssignOp\\NewArrayItemConcatAssignToAssignRector' => __DIR__ . '/../..' . '/rules/CodeQuality/Rector/AssignOp/NewArrayItemConcatAssignToAssignRector.php',
14591459
'Rector\\CodeQuality\\Rector\\Assign\\CombinedAssignRector' => __DIR__ . '/../..' . '/rules/CodeQuality/Rector/Assign/CombinedAssignRector.php',
1460+
'Rector\\CodeQuality\\Rector\\Attribute\\ExplicitAttributeNamedArgsRector' => __DIR__ . '/../..' . '/rules/CodeQuality/Rector/Attribute/ExplicitAttributeNamedArgsRector.php',
14601461
'Rector\\CodeQuality\\Rector\\Attribute\\SortAttributeNamedArgsRector' => __DIR__ . '/../..' . '/rules/CodeQuality/Rector/Attribute/SortAttributeNamedArgsRector.php',
14611462
'Rector\\CodeQuality\\Rector\\BooleanAnd\\RemoveUselessIsObjectCheckRector' => __DIR__ . '/../..' . '/rules/CodeQuality/Rector/BooleanAnd/RemoveUselessIsObjectCheckRector.php',
14621463
'Rector\\CodeQuality\\Rector\\BooleanAnd\\RepeatedAndNotEqualToNotInArrayRector' => __DIR__ . '/../..' . '/rules/CodeQuality/Rector/BooleanAnd/RepeatedAndNotEqualToNotInArrayRector.php',

0 commit comments

Comments
 (0)