Skip to content

Commit df66449

Browse files
jiripudilondrejmirtes
authored andcommitted
LocalTypeAliasesRule: report invalid type alias names
1 parent ca47eeb commit df66449

File tree

3 files changed

+40
-13
lines changed

3 files changed

+40
-13
lines changed

src/Rules/Classes/LocalTypeAliasesRule.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Node\InClassNode;
88
use PHPStan\PhpDoc\TypeNodeResolver;
9+
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
910
use PHPStan\Reflection\ReflectionProvider;
1011
use PHPStan\Rules\Rule;
1112
use PHPStan\Rules\RuleErrorBuilder;
1213
use PHPStan\Type\ErrorType;
14+
use PHPStan\Type\Generic\TemplateType;
15+
use PHPStan\Type\ObjectType;
1316
use PHPStan\Type\TypeTraverser;
1417

1518
/**
@@ -115,6 +118,17 @@ public function processNode(Node $node, Scope $scope): array
115118
continue;
116119
}
117120

121+
if ($nameScope !== null) {
122+
$aliasNameResolvedType = $this->typeNodeResolver->resolve(new IdentifierTypeNode($aliasName), $nameScope);
123+
if (!($aliasNameResolvedType instanceof ObjectType)
124+
&& !($aliasNameResolvedType instanceof TemplateType) // aliases take precedence over type parameters, this is reported by other rules using TemplateTypeCheck
125+
|| in_array($aliasName, ['self', 'parent'], true)
126+
) {
127+
$errors[] = RuleErrorBuilder::message(sprintf('Type alias has an invalid name: %s.', $aliasName))->build();
128+
continue;
129+
}
130+
}
131+
118132
$resolvedType = $typeAliasTag->getTypeAlias()->resolve($this->typeNodeResolver);
119133
$foundError = false;
120134
TypeTraverser::map($resolvedType, static function (\PHPStan\Type\Type $type, callable $traverse) use (&$errors, &$foundError, $aliasName): \PHPStan\Type\Type {

tests/PHPStan/Rules/Classes/LocalTypeAliasesRuleTest.php

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,55 +26,59 @@ public function testRule(): void
2626
$this->analyse([__DIR__ . '/data/local-type-aliases.php'], [
2727
[
2828
'Type alias ExistingClassAlias already exists as a class in scope of LocalTypeAliases\Bar.',
29-
22,
29+
23,
3030
],
3131
[
3232
'Type alias GlobalTypeAlias already exists as a global type alias.',
33-
22,
33+
23,
34+
],
35+
[
36+
'Type alias has an invalid name: int.',
37+
23,
3438
],
3539
[
3640
'Circular definition detected in type alias RecursiveTypeAlias.',
37-
22,
41+
23,
3842
],
3943
[
4044
'Circular definition detected in type alias CircularTypeAlias1.',
41-
22,
45+
23,
4246
],
4347
[
4448
'Circular definition detected in type alias CircularTypeAlias2.',
45-
22,
49+
23,
4650
],
4751
[
4852
'Cannot import type alias ImportedAliasFromNonClass: class LocalTypeAliases\int does not exist.',
49-
37,
53+
38,
5054
],
5155
[
5256
'Cannot import type alias ImportedAliasFromUnknownClass: class LocalTypeAliases\UnknownClass does not exist.',
53-
37,
57+
38,
5458
],
5559
[
5660
'Cannot import type alias ImportedUnknownAlias: type alias does not exist in LocalTypeAliases\Foo.',
57-
37,
61+
38,
5862
],
5963
[
6064
'Type alias ExistingClassAlias already exists as a class in scope of LocalTypeAliases\Baz.',
61-
37,
65+
38,
6266
],
6367
[
6468
'Type alias GlobalTypeAlias already exists as a global type alias.',
65-
37,
69+
38,
6670
],
6771
[
6872
'Type alias OverwrittenTypeAlias overwrites an imported type alias of the same name.',
69-
37,
73+
38,
7074
],
7175
[
7276
'Circular definition detected in type alias CircularTypeAliasImport2.',
73-
37,
77+
38,
7478
],
7579
[
7680
'Circular definition detected in type alias CircularTypeAliasImport1.',
77-
45,
81+
46,
7882
],
7983
]);
8084
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class Foo
1515
* @phpstan-type LocalTypeAlias int
1616
* @phpstan-type ExistingClassAlias \stdClass
1717
* @phpstan-type GlobalTypeAlias bool
18+
* @phpstan-type int \stdClass
1819
* @phpstan-type RecursiveTypeAlias RecursiveTypeAlias[]
1920
* @phpstan-type CircularTypeAlias1 CircularTypeAlias2
2021
* @phpstan-type CircularTypeAlias2 CircularTypeAlias1
@@ -45,3 +46,11 @@ class Baz
4546
class Qux
4647
{
4748
}
49+
50+
/**
51+
* @phpstan-template T
52+
* @phpstan-type T never
53+
*/
54+
class Generic
55+
{
56+
}

0 commit comments

Comments
 (0)