Skip to content

Commit 6366066

Browse files
committed
AttributesCheck - do not report named arguments in attributes
1 parent 2652f2d commit 6366066

File tree

4 files changed

+46
-3
lines changed

4 files changed

+46
-3
lines changed

src/Rules/AttributesCheck.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,14 @@ public function check(
9393

9494
$attributeClassName = SprintfHelper::escapeFormatString($attributeClass->getDisplayName());
9595

96+
$nodeAttributes = $attribute->getAttributes();
97+
$nodeAttributes['isAttribute'] = true;
98+
9699
$parameterErrors = $this->functionCallParametersCheck->check(
97100
ParametersAcceptorSelector::selectSingle($attributeConstructor->getVariants()),
98101
$scope,
99102
$attributeConstructor->getDeclaringClass()->isBuiltin(),
100-
new New_($attribute->name, $attribute->args, $attribute->getAttributes()),
103+
new New_($attribute->name, $attribute->args, $nodeAttributes),
101104
[
102105
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameter, %d required.',
103106
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameters, %d required.',

src/Rules/FunctionCallParametersCheck.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public function check(
169169
];
170170
}
171171

172-
if ($hasNamedArguments && !$this->phpVersion->supportsNamedArguments()) {
172+
if ($hasNamedArguments && !$this->phpVersion->supportsNamedArguments() && !$funcCall->getAttribute('isAttribute', false)) {
173173
$errors[] = RuleErrorBuilder::message('Named arguments are supported only on PHP 8.0 and later.')->line($funcCall->getLine())->nonIgnorable()->build();
174174
}
175175

tests/PHPStan/Rules/Methods/MethodAttributesRuleTest.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
class MethodAttributesRuleTest extends RuleTestCase
1919
{
2020

21+
/** @var int */
22+
private $phpVersion;
23+
2124
protected function getRule(): Rule
2225
{
2326
$reflectionProvider = $this->createReflectionProvider();
@@ -27,7 +30,7 @@ protected function getRule(): Rule
2730
new FunctionCallParametersCheck(
2831
new RuleLevelHelper($reflectionProvider, true, false, true, false),
2932
new NullsafeCheck(),
30-
new PhpVersion(80000),
33+
new PhpVersion($this->phpVersion),
3134
new UnresolvableTypeHelper(),
3235
true,
3336
true,
@@ -45,6 +48,8 @@ public function testRule(): void
4548
$this->markTestSkipped('Test requires PHP 8.0.');
4649
}
4750

51+
$this->phpVersion = 80000;
52+
4853
$this->analyse([__DIR__ . '/data/method-attributes.php'], [
4954
[
5055
'Attribute class MethodAttributes\Foo does not have the method target.',
@@ -53,4 +58,14 @@ public function testRule(): void
5358
]);
5459
}
5560

61+
public function testBug5898(): void
62+
{
63+
if (!self::$useStaticReflectionProvider && PHP_VERSION_ID < 80000) {
64+
$this->markTestSkipped('Test requires PHP 8.0.');
65+
}
66+
67+
$this->phpVersion = 70400;
68+
$this->analyse([__DIR__ . '/data/bug-5898.php'], []);
69+
}
70+
5671
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug5898;
4+
5+
#[\Attribute(\Attribute::TARGET_METHOD)]
6+
class Route
7+
{
8+
9+
public function __construct(string $name)
10+
{
11+
12+
}
13+
14+
}
15+
16+
class Sit
17+
{
18+
19+
#[Route(name: 'test')]
20+
public function doFoo()
21+
{
22+
23+
}
24+
25+
}

0 commit comments

Comments
 (0)