Skip to content

Commit

Permalink
Fix resolving class constant type using self:: in a class attribute…
Browse files Browse the repository at this point in the history
… argument
  • Loading branch information
ondrejmirtes committed Nov 12, 2024
1 parent fd6a0f2 commit 3447391
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
9 changes: 6 additions & 3 deletions src/Rules/Classes/ClassAttributesRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
use Attribute;
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Node\InClassNode;
use PHPStan\Rules\AttributesCheck;
use PHPStan\Rules\Rule;

/**
* @implements Rule<Node\Stmt\ClassLike>
* @implements Rule<InClassNode>
*/
final class ClassAttributesRule implements Rule
{
Expand All @@ -20,14 +21,16 @@ public function __construct(private AttributesCheck $attributesCheck)

public function getNodeType(): string
{
return Node\Stmt\ClassLike::class;
return InClassNode::class;
}

public function processNode(Node $node, Scope $scope): array
{
$classLikeNode = $node->getOriginalNode();

return $this->attributesCheck->check(
$scope,
$node->attrGroups,
$classLikeNode->attrGroups,
Attribute::TARGET_CLASS,
'class',
);
Expand Down
22 changes: 21 additions & 1 deletion tests/PHPStan/Rules/Classes/ClassAttributesRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,18 @@
class ClassAttributesRuleTest extends RuleTestCase
{

private bool $checkExplicitMixed = false;

private bool $checkImplicitMixed = false;

protected function getRule(): Rule
{
$reflectionProvider = $this->createReflectionProvider();
return new ClassAttributesRule(
new AttributesCheck(
$reflectionProvider,
new FunctionCallParametersCheck(
new RuleLevelHelper($reflectionProvider, true, false, true, false, false, true, false),
new RuleLevelHelper($reflectionProvider, true, false, true, $this->checkExplicitMixed, $this->checkImplicitMixed, true, false),
new NullsafeCheck(),
new PhpVersion(80000),
new UnresolvableTypeHelper(),
Expand Down Expand Up @@ -148,4 +152,20 @@ public function testAllowDynamicPropertiesAttribute(): void
$this->analyse([__DIR__ . '/data/allow-dynamic-properties-attribute.php'], []);
}

public function testBug12011(): void
{
if (PHP_VERSION_ID < 80300) {
$this->markTestSkipped('Test requires PHP 8.3.');
}

$this->checkExplicitMixed = true;
$this->checkImplicitMixed = true;
$this->analyse([__DIR__ . '/data/bug-12011.php'], [
[
'Parameter #1 $name of attribute class Bug12011\Table constructor expects string|null, int given.',
23,
],
]);
}

}
27 changes: 27 additions & 0 deletions tests/PHPStan/Rules/Classes/data/bug-12011.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace Bug12011;

use Attribute;

#[Table(self::TABLE_NAME)]
class HelloWorld
{
private const string TABLE_NAME = 'table';
}

#[Attribute(Attribute::TARGET_CLASS)]
final class Table
{
public function __construct(
public readonly string|null $name = null,
public readonly string|null $schema = null,
) {
}
}

#[Table(self::TABLE_NAME)]
class HelloWorld2
{
private const int TABLE_NAME = 1;
}

0 comments on commit 3447391

Please sign in to comment.