Skip to content

Commit 361e064

Browse files
committed
Fix checking of generic attributes
1 parent 790f4fb commit 361e064

File tree

3 files changed

+84
-1
lines changed

3 files changed

+84
-1
lines changed

src/Rules/AttributesCheck.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,11 @@ public function check(
102102
$nodeAttributes['isAttribute'] = true;
103103

104104
$parameterErrors = $this->functionCallParametersCheck->check(
105-
ParametersAcceptorSelector::selectSingle($attributeConstructor->getVariants()),
105+
ParametersAcceptorSelector::selectFromArgs(
106+
$scope,
107+
$attribute->args,
108+
$attributeConstructor->getVariants(),
109+
),
106110
$scope,
107111
$attributeConstructor->getDeclaringClass()->isBuiltin(),
108112
new New_($attribute->name, $attribute->args, $nodeAttributes),

tests/PHPStan/Rules/Classes/ClassAttributesRuleTest.php

+10
Original file line numberDiff line numberDiff line change
@@ -126,4 +126,14 @@ public function testRuleForEnums(): void
126126
]);
127127
}
128128

129+
public function testBug7171(): void
130+
{
131+
$this->analyse([__DIR__ . '/data/bug-7171.php'], [
132+
[
133+
'Parameter $repositoryClass of attribute class Bug7171\Entity constructor expects class-string<Bug7171\EntityRepository<T of object>>|null, \'stdClass\' given.',
134+
66,
135+
],
136+
]);
137+
}
138+
129139
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug7171;
4+
5+
/**
6+
* @template T of object
7+
*/
8+
class EntityRepository
9+
{
10+
}
11+
12+
/**
13+
* @template T of object
14+
* @template-extends EntityRepository<T>
15+
*/
16+
class ServiceEntityRepository extends EntityRepository
17+
{
18+
}
19+
20+
/**
21+
* @extends ServiceEntityRepository<MyEntityAttribute>
22+
*/
23+
class MyRepositoryAttribute extends ServiceEntityRepository
24+
{
25+
}
26+
27+
/**
28+
* @extends ServiceEntityRepository<MyEntityExtend>
29+
*/
30+
class MyRepositoryExtend extends ServiceEntityRepository
31+
{
32+
}
33+
34+
/**
35+
* @template T of object
36+
*/
37+
#[\Attribute(\Attribute::TARGET_CLASS)]
38+
class Entity
39+
{
40+
/**
41+
* @param class-string<EntityRepository<T>>|null $repositoryClass
42+
*/
43+
public function __construct(?string $repositoryClass = null)
44+
{
45+
// Logic
46+
echo $repositoryClass;
47+
}
48+
}
49+
50+
#[Entity(repositoryClass: MyRepositoryAttribute::class)]
51+
class MyEntityAttribute
52+
{
53+
}
54+
55+
/**
56+
* @extends Entity<MyEntityExtend>
57+
*/
58+
class MyEntityExtend extends Entity
59+
{
60+
public function __construct()
61+
{
62+
parent::__construct(repositoryClass: MyRepositoryExtend::class);
63+
}
64+
}
65+
66+
#[Entity(repositoryClass: \stdClass::class)]
67+
class WrongEntity
68+
{
69+
}

0 commit comments

Comments
 (0)