Skip to content

Commit

Permalink
AttributesCheck - do not report named arguments in attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Nov 16, 2021
1 parent 2652f2d commit 6366066
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 3 deletions.
5 changes: 4 additions & 1 deletion src/Rules/AttributesCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,14 @@ public function check(

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

$nodeAttributes = $attribute->getAttributes();
$nodeAttributes['isAttribute'] = true;

$parameterErrors = $this->functionCallParametersCheck->check(
ParametersAcceptorSelector::selectSingle($attributeConstructor->getVariants()),
$scope,
$attributeConstructor->getDeclaringClass()->isBuiltin(),
new New_($attribute->name, $attribute->args, $attribute->getAttributes()),
new New_($attribute->name, $attribute->args, $nodeAttributes),
[
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameter, %d required.',
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameters, %d required.',
Expand Down
2 changes: 1 addition & 1 deletion src/Rules/FunctionCallParametersCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public function check(
];
}

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

Expand Down
17 changes: 16 additions & 1 deletion tests/PHPStan/Rules/Methods/MethodAttributesRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
class MethodAttributesRuleTest extends RuleTestCase
{

/** @var int */
private $phpVersion;

protected function getRule(): Rule
{
$reflectionProvider = $this->createReflectionProvider();
Expand All @@ -27,7 +30,7 @@ protected function getRule(): Rule
new FunctionCallParametersCheck(
new RuleLevelHelper($reflectionProvider, true, false, true, false),
new NullsafeCheck(),
new PhpVersion(80000),
new PhpVersion($this->phpVersion),
new UnresolvableTypeHelper(),
true,
true,
Expand All @@ -45,6 +48,8 @@ public function testRule(): void
$this->markTestSkipped('Test requires PHP 8.0.');
}

$this->phpVersion = 80000;

$this->analyse([__DIR__ . '/data/method-attributes.php'], [
[
'Attribute class MethodAttributes\Foo does not have the method target.',
Expand All @@ -53,4 +58,14 @@ public function testRule(): void
]);
}

public function testBug5898(): void
{
if (!self::$useStaticReflectionProvider && PHP_VERSION_ID < 80000) {
$this->markTestSkipped('Test requires PHP 8.0.');
}

$this->phpVersion = 70400;
$this->analyse([__DIR__ . '/data/bug-5898.php'], []);
}

}
25 changes: 25 additions & 0 deletions tests/PHPStan/Rules/Methods/data/bug-5898.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php declare(strict_types = 1);

namespace Bug5898;

#[\Attribute(\Attribute::TARGET_METHOD)]
class Route
{

public function __construct(string $name)
{

}

}

class Sit
{

#[Route(name: 'test')]
public function doFoo()
{

}

}

0 comments on commit 6366066

Please sign in to comment.