Skip to content

Commit 5a2d441

Browse files
committed
Bleeding edge - call GenericObjectTypeCheck from LocalTypeAliasesCheck
1 parent 5f7d12b commit 5a2d441

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

src/Rules/Classes/LocalTypeAliasesCheck.php

+32
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44

55
use PhpParser\Node\Stmt\ClassLike;
66
use PHPStan\Analyser\NameScope;
7+
use PHPStan\Internal\SprintfHelper;
78
use PHPStan\PhpDoc\TypeNodeResolver;
89
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
910
use PHPStan\Reflection\ClassReflection;
1011
use PHPStan\Reflection\ReflectionProvider;
1112
use PHPStan\Rules\ClassNameCheck;
1213
use PHPStan\Rules\ClassNameNodePair;
14+
use PHPStan\Rules\Generics\GenericObjectTypeCheck;
1315
use PHPStan\Rules\IdentifierRuleError;
1416
use PHPStan\Rules\MissingTypehintCheck;
1517
use PHPStan\Rules\PhpDoc\UnresolvableTypeHelper;
@@ -39,6 +41,7 @@ public function __construct(
3941
private MissingTypehintCheck $missingTypehintCheck,
4042
private ClassNameCheck $classCheck,
4143
private UnresolvableTypeHelper $unresolvableTypeHelper,
44+
private GenericObjectTypeCheck $genericObjectTypeCheck,
4245
private bool $checkMissingTypehints,
4346
private bool $checkClassCaseSensitivity,
4447
private bool $absentTypeChecks,
@@ -256,6 +259,35 @@ public function check(ClassReflection $reflection, ClassLike $node): array
256259
->identifier('typeAlias.unresolvableType')
257260
->build();
258261
}
262+
263+
$escapedTypeAlias = SprintfHelper::escapeFormatString($aliasName);
264+
$errors = array_merge($errors, $this->genericObjectTypeCheck->check(
265+
$resolvedType,
266+
sprintf(
267+
'Type alias %s contains generic type %%s but %%s %%s is not generic.',
268+
$escapedTypeAlias,
269+
),
270+
sprintf(
271+
'Generic type %%s in type alias %s does not specify all template types of %%s %%s: %%s',
272+
$escapedTypeAlias,
273+
),
274+
sprintf(
275+
'Generic type %%s in type alias %s specifies %%d template types, but %%s %%s supports only %%d: %%s',
276+
$escapedTypeAlias,
277+
),
278+
sprintf(
279+
'Type %%s in generic type %%s in type alias %s is not subtype of template type %%s of %%s %%s.',
280+
$escapedTypeAlias,
281+
),
282+
sprintf(
283+
'Call-site variance of %%s in generic type %%s in type alias %s is in conflict with %%s template type %%s of %%s %%s.',
284+
$escapedTypeAlias,
285+
),
286+
sprintf(
287+
'Call-site variance of %%s in generic type %%s in type alias %s is redundant, template type %%s of %%s %%s has the same variance.',
288+
$escapedTypeAlias,
289+
),
290+
));
259291
}
260292

261293
return $errors;

tests/PHPStan/Rules/Classes/LocalTypeAliasesRuleTest.php

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Rules\ClassCaseSensitivityCheck;
77
use PHPStan\Rules\ClassForbiddenNameCheck;
88
use PHPStan\Rules\ClassNameCheck;
9+
use PHPStan\Rules\Generics\GenericObjectTypeCheck;
910
use PHPStan\Rules\MissingTypehintCheck;
1011
use PHPStan\Rules\PhpDoc\UnresolvableTypeHelper;
1112
use PHPStan\Rules\Rule;
@@ -33,6 +34,7 @@ protected function getRule(): Rule
3334
new ClassForbiddenNameCheck(self::getContainer()),
3435
),
3536
new UnresolvableTypeHelper(),
37+
new GenericObjectTypeCheck(),
3638
true,
3739
true,
3840
true,
@@ -137,6 +139,10 @@ public function testRule(): void
137139
'Type alias A contains unresolvable type.',
138140
95,
139141
],
142+
[
143+
'Type alias A contains generic type Exception<int> but class Exception is not generic.',
144+
103,
145+
],
140146
]);
141147
}
142148

tests/PHPStan/Rules/Classes/LocalTypeTraitAliasesRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\Rules\ClassCaseSensitivityCheck;
77
use PHPStan\Rules\ClassForbiddenNameCheck;
88
use PHPStan\Rules\ClassNameCheck;
9+
use PHPStan\Rules\Generics\GenericObjectTypeCheck;
910
use PHPStan\Rules\MissingTypehintCheck;
1011
use PHPStan\Rules\PhpDoc\UnresolvableTypeHelper;
1112
use PHPStan\Rules\Rule;
@@ -32,6 +33,7 @@ protected function getRule(): Rule
3233
new ClassForbiddenNameCheck(self::getContainer()),
3334
),
3435
new UnresolvableTypeHelper(),
36+
new GenericObjectTypeCheck(),
3537
true,
3638
true,
3739
true,

tests/PHPStan/Rules/Classes/data/local-type-aliases.php

+8
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,11 @@ class UnresolvableExample
9696
{
9797

9898
}
99+
100+
/**
101+
* @phpstan-type A = \Exception<int>
102+
*/
103+
class GenericsCheck
104+
{
105+
106+
}

0 commit comments

Comments
 (0)