Skip to content

Commit 9ae17c9

Browse files
committed
RestrictedClassNameUsageExtension
1 parent 5de0b2c commit 9ae17c9

File tree

63 files changed

+202
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+202
-2
lines changed

src/Rules/ClassNameCheck.php

+30
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,18 @@
33
namespace PHPStan\Rules;
44

55
use PHPStan\Analyser\Scope;
6+
use PHPStan\DependencyInjection\Container;
7+
use PHPStan\Reflection\ReflectionProvider;
8+
use PHPStan\Rules\RestrictedUsage\RestrictedClassNameUsageExtension;
69

710
final class ClassNameCheck
811
{
912

1013
public function __construct(
1114
private ClassCaseSensitivityCheck $classCaseSensitivityCheck,
1215
private ClassForbiddenNameCheck $classForbiddenNameCheck,
16+
private ReflectionProvider $reflectionProvider,
17+
private Container $container,
1318
)
1419
{
1520
}
@@ -36,6 +41,31 @@ public function checkClassNames(
3641
$errors[] = $error;
3742
}
3843

44+
/** @var RestrictedClassNameUsageExtension[] $extensions */
45+
$extensions = $this->container->getServicesByTag(RestrictedClassNameUsageExtension::CLASS_NAME_EXTENSION_TAG);
46+
if ($extensions === []) {
47+
return $errors;
48+
}
49+
50+
foreach ($pairs as $pair) {
51+
if (!$this->reflectionProvider->hasClass($pair->getClassName())) {
52+
continue;
53+
}
54+
55+
$classReflection = $this->reflectionProvider->getClass($pair->getClassName());
56+
foreach ($extensions as $extension) {
57+
$restrictedUsage = $extension->isRestrictedClassNameUsage($classReflection, $scope, $location);
58+
if ($restrictedUsage === null) {
59+
continue;
60+
}
61+
62+
$errors[] = RuleErrorBuilder::message($restrictedUsage->errorMessage)
63+
->identifier($restrictedUsage->identifier)
64+
->line($pair->getNode()->getStartLine())
65+
->build();
66+
}
67+
}
68+
3969
return $errors;
4070
}
4171

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\RestrictedUsage;
4+
5+
use PHPStan\Analyser\Scope;
6+
use PHPStan\Reflection\ClassReflection;
7+
use PHPStan\Rules\ClassNameUsageLocation;
8+
9+
/**
10+
* Extensions implementing this interface are called for each analysed class name usage.
11+
*
12+
* Extension can decide to create RestrictedUsage object
13+
* with error message & error identifier to be reported for this method call.
14+
*
15+
* Typical usage is to report errors for class names marked as @-deprecated or @-internal.
16+
*
17+
* Extension can take advantage of the usage location information in the ClassNameUsageLocation object.
18+
*
19+
* To register the extension in the configuration file use the following tag:
20+
*
21+
* ```
22+
* services:
23+
* -
24+
* class: App\PHPStan\MyExtension
25+
* tags:
26+
* - phpstan.restrictedClassNameUsageExtension
27+
* ```
28+
*
29+
* @api
30+
*/
31+
interface RestrictedClassNameUsageExtension
32+
{
33+
34+
public const CLASS_NAME_EXTENSION_TAG = 'phpstan.restrictedClassNameUsageExtension';
35+
36+
public function isRestrictedClassNameUsage(
37+
ClassReflection $classReflection,
38+
Scope $scope,
39+
ClassNameUsageLocation $location,
40+
): ?RestrictedUsage;
41+
42+
}

tests/PHPStan/Rules/Classes/ClassAttributesRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ protected function getRule(): Rule
4444
new ClassNameCheck(
4545
new ClassCaseSensitivityCheck($reflectionProvider, false),
4646
new ClassForbiddenNameCheck(self::getContainer()),
47+
$reflectionProvider,
48+
self::getContainer(),
4749
),
4850
true,
4951
),

tests/PHPStan/Rules/Classes/ClassConstantAttributesRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ protected function getRule(): Rule
3939
new ClassNameCheck(
4040
new ClassCaseSensitivityCheck($reflectionProvider, false),
4141
new ClassForbiddenNameCheck(self::getContainer()),
42+
$reflectionProvider,
43+
self::getContainer(),
4244
),
4345
true,
4446
),

tests/PHPStan/Rules/Classes/ClassConstantRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ protected function getRule(): Rule
2828
new ClassNameCheck(
2929
new ClassCaseSensitivityCheck($reflectionProvider, true),
3030
new ClassForbiddenNameCheck(self::getContainer()),
31+
$reflectionProvider,
32+
self::getContainer(),
3133
),
3234
new PhpVersion($this->phpVersion),
3335
);

tests/PHPStan/Rules/Classes/ExistingClassInClassExtendsRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ protected function getRule(): Rule
2222
new ClassNameCheck(
2323
new ClassCaseSensitivityCheck($reflectionProvider, true),
2424
new ClassForbiddenNameCheck(self::getContainer()),
25+
$reflectionProvider,
26+
self::getContainer(),
2527
),
2628
$reflectionProvider,
2729
true,

tests/PHPStan/Rules/Classes/ExistingClassInInstanceOfRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ protected function getRule(): Rule
2525
new ClassNameCheck(
2626
new ClassCaseSensitivityCheck($reflectionProvider, true),
2727
new ClassForbiddenNameCheck(self::getContainer()),
28+
$reflectionProvider,
29+
self::getContainer(),
2830
),
2931
true,
3032
true,

tests/PHPStan/Rules/Classes/ExistingClassInTraitUseRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ protected function getRule(): Rule
2222
new ClassNameCheck(
2323
new ClassCaseSensitivityCheck($reflectionProvider, true),
2424
new ClassForbiddenNameCheck(self::getContainer()),
25+
$reflectionProvider,
26+
self::getContainer(),
2527
),
2628
$reflectionProvider,
2729
true,

tests/PHPStan/Rules/Classes/ExistingClassesInClassImplementsRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ protected function getRule(): Rule
2222
new ClassNameCheck(
2323
new ClassCaseSensitivityCheck($reflectionProvider, true),
2424
new ClassForbiddenNameCheck(self::getContainer()),
25+
$reflectionProvider,
26+
self::getContainer(),
2527
),
2628
$reflectionProvider,
2729
true,

tests/PHPStan/Rules/Classes/ExistingClassesInEnumImplementsRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ protected function getRule(): Rule
2323
new ClassNameCheck(
2424
new ClassCaseSensitivityCheck($reflectionProvider, true),
2525
new ClassForbiddenNameCheck(self::getContainer()),
26+
$reflectionProvider,
27+
self::getContainer(),
2628
),
2729
$reflectionProvider,
2830
true,

tests/PHPStan/Rules/Classes/ExistingClassesInInterfaceExtendsRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ protected function getRule(): Rule
2222
new ClassNameCheck(
2323
new ClassCaseSensitivityCheck($reflectionProvider, true),
2424
new ClassForbiddenNameCheck(self::getContainer()),
25+
$reflectionProvider,
26+
self::getContainer(),
2527
),
2628
$reflectionProvider,
2729
true,

tests/PHPStan/Rules/Classes/ForbiddenNameCheckExtensionRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ protected function getRule(): Rule
2929
new ClassNameCheck(
3030
new ClassCaseSensitivityCheck($reflectionProvider, true),
3131
new ClassForbiddenNameCheck(self::getContainer()),
32+
$reflectionProvider,
33+
self::getContainer(),
3234
),
3335
true,
3436
);

tests/PHPStan/Rules/Classes/InstantiationRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ protected function getRule(): Rule
2929
new ClassNameCheck(
3030
new ClassCaseSensitivityCheck($reflectionProvider, true),
3131
new ClassForbiddenNameCheck(self::getContainer()),
32+
$reflectionProvider,
33+
self::getContainer(),
3234
),
3335
true,
3436
);

tests/PHPStan/Rules/Classes/LocalTypeAliasesRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ protected function getRule(): Rule
3232
new ClassNameCheck(
3333
new ClassCaseSensitivityCheck($reflectionProvider, true),
3434
new ClassForbiddenNameCheck(self::getContainer()),
35+
$reflectionProvider,
36+
self::getContainer(),
3537
),
3638
new UnresolvableTypeHelper(),
3739
new GenericObjectTypeCheck(),

tests/PHPStan/Rules/Classes/LocalTypeTraitAliasesRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ protected function getRule(): Rule
3131
new ClassNameCheck(
3232
new ClassCaseSensitivityCheck($reflectionProvider, true),
3333
new ClassForbiddenNameCheck(self::getContainer()),
34+
$reflectionProvider,
35+
self::getContainer(),
3436
),
3537
new UnresolvableTypeHelper(),
3638
new GenericObjectTypeCheck(),

tests/PHPStan/Rules/Classes/LocalTypeTraitUseAliasesRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ protected function getRule(): Rule
3131
new ClassNameCheck(
3232
new ClassCaseSensitivityCheck($reflectionProvider, true),
3333
new ClassForbiddenNameCheck(self::getContainer()),
34+
$reflectionProvider,
35+
self::getContainer(),
3436
),
3537
new UnresolvableTypeHelper(),
3638
new GenericObjectTypeCheck(),

tests/PHPStan/Rules/Classes/MethodTagRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ protected function getRule(): TRule
2727
new ClassNameCheck(
2828
new ClassCaseSensitivityCheck($reflectionProvider, true),
2929
new ClassForbiddenNameCheck(self::getContainer()),
30+
$reflectionProvider,
31+
self::getContainer(),
3032
),
3133
new GenericObjectTypeCheck(),
3234
new MissingTypehintCheck(true, []),

tests/PHPStan/Rules/Classes/MethodTagTraitRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ protected function getRule(): TRule
2727
new ClassNameCheck(
2828
new ClassCaseSensitivityCheck($reflectionProvider, true),
2929
new ClassForbiddenNameCheck(self::getContainer()),
30+
$reflectionProvider,
31+
self::getContainer(),
3032
),
3133
new GenericObjectTypeCheck(),
3234
new MissingTypehintCheck(true, []),

tests/PHPStan/Rules/Classes/MethodTagTraitUseRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ protected function getRule(): TRule
2828
new ClassNameCheck(
2929
new ClassCaseSensitivityCheck($reflectionProvider, true),
3030
new ClassForbiddenNameCheck(self::getContainer()),
31+
$reflectionProvider,
32+
self::getContainer(),
3133
),
3234
new GenericObjectTypeCheck(),
3335
new MissingTypehintCheck(true, []),

tests/PHPStan/Rules/Classes/MixinRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ protected function getRule(): Rule
2828
new ClassNameCheck(
2929
new ClassCaseSensitivityCheck($reflectionProvider, true),
3030
new ClassForbiddenNameCheck(self::getContainer()),
31+
$reflectionProvider,
32+
self::getContainer(),
3133
),
3234
new GenericObjectTypeCheck(),
3335
new MissingTypehintCheck(true, []),

tests/PHPStan/Rules/Classes/MixinTraitRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ protected function getRule(): Rule
2727
new ClassNameCheck(
2828
new ClassCaseSensitivityCheck($reflectionProvider, true),
2929
new ClassForbiddenNameCheck(self::getContainer()),
30+
$reflectionProvider,
31+
self::getContainer(),
3032
),
3133
new GenericObjectTypeCheck(),
3234
new MissingTypehintCheck(true, []),

tests/PHPStan/Rules/Classes/MixinTraitUseRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ protected function getRule(): Rule
2727
new ClassNameCheck(
2828
new ClassCaseSensitivityCheck($reflectionProvider, true),
2929
new ClassForbiddenNameCheck(self::getContainer()),
30+
$reflectionProvider,
31+
self::getContainer(),
3032
),
3133
new GenericObjectTypeCheck(),
3234
new MissingTypehintCheck(true, []),

tests/PHPStan/Rules/Classes/PropertyTagRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ protected function getRule(): TRule
2727
new ClassNameCheck(
2828
new ClassCaseSensitivityCheck($reflectionProvider, true),
2929
new ClassForbiddenNameCheck(self::getContainer()),
30+
$reflectionProvider,
31+
self::getContainer(),
3032
),
3133
new GenericObjectTypeCheck(),
3234
new MissingTypehintCheck(true, []),

tests/PHPStan/Rules/Classes/PropertyTagTraitRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ protected function getRule(): TRule
2727
new ClassNameCheck(
2828
new ClassCaseSensitivityCheck($reflectionProvider, true),
2929
new ClassForbiddenNameCheck(self::getContainer()),
30+
$reflectionProvider,
31+
self::getContainer(),
3032
),
3133
new GenericObjectTypeCheck(),
3234
new MissingTypehintCheck(true, []),

tests/PHPStan/Rules/Classes/PropertyTagTraitUseRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ protected function getRule(): TRule
2727
new ClassNameCheck(
2828
new ClassCaseSensitivityCheck($reflectionProvider, true),
2929
new ClassForbiddenNameCheck(self::getContainer()),
30+
$reflectionProvider,
31+
self::getContainer(),
3032
),
3133
new GenericObjectTypeCheck(),
3234
new MissingTypehintCheck(true, []),

tests/PHPStan/Rules/EnumCases/EnumCaseAttributesRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ protected function getRule(): Rule
4040
new ClassNameCheck(
4141
new ClassCaseSensitivityCheck($reflectionProvider, false),
4242
new ClassForbiddenNameCheck(self::getContainer()),
43+
$reflectionProvider,
44+
self::getContainer(),
4345
),
4446
true,
4547
),

tests/PHPStan/Rules/Exceptions/CaughtExceptionExistenceRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ protected function getRule(): Rule
2222
new ClassNameCheck(
2323
new ClassCaseSensitivityCheck($reflectionProvider, true),
2424
new ClassForbiddenNameCheck(self::getContainer()),
25+
$reflectionProvider,
26+
self::getContainer(),
2527
),
2628
true,
2729
true,

tests/PHPStan/Rules/Functions/ArrowFunctionAttributesRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ protected function getRule(): Rule
3939
new ClassNameCheck(
4040
new ClassCaseSensitivityCheck($reflectionProvider, false),
4141
new ClassForbiddenNameCheck(self::getContainer()),
42+
$reflectionProvider,
43+
self::getContainer(),
4244
),
4345
true,
4446
),

tests/PHPStan/Rules/Functions/ClosureAttributesRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ protected function getRule(): Rule
3939
new ClassNameCheck(
4040
new ClassCaseSensitivityCheck($reflectionProvider, false),
4141
new ClassForbiddenNameCheck(self::getContainer()),
42+
$reflectionProvider,
43+
self::getContainer(),
4244
),
4345
true,
4446
),

tests/PHPStan/Rules/Functions/ExistingClassesInArrowFunctionTypehintsRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ protected function getRule(): Rule
2929
new ClassNameCheck(
3030
new ClassCaseSensitivityCheck($reflectionProvider, true),
3131
new ClassForbiddenNameCheck(self::getContainer()),
32+
$reflectionProvider,
33+
self::getContainer(),
3234
),
3335
new UnresolvableTypeHelper(),
3436
new PhpVersion($this->phpVersionId),

tests/PHPStan/Rules/Functions/ExistingClassesInClosureTypehintsRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ protected function getRule(): Rule
2929
new ClassNameCheck(
3030
new ClassCaseSensitivityCheck($reflectionProvider, true),
3131
new ClassForbiddenNameCheck(self::getContainer()),
32+
$reflectionProvider,
33+
self::getContainer(),
3234
),
3335
new UnresolvableTypeHelper(),
3436
new PhpVersion($this->phpVersionId),

tests/PHPStan/Rules/Functions/ExistingClassesInTypehintsRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ protected function getRule(): Rule
2929
new ClassNameCheck(
3030
new ClassCaseSensitivityCheck($reflectionProvider, true),
3131
new ClassForbiddenNameCheck(self::getContainer()),
32+
$reflectionProvider,
33+
self::getContainer(),
3234
),
3335
new UnresolvableTypeHelper(),
3436
new PhpVersion($this->phpVersionId),

tests/PHPStan/Rules/Functions/FunctionAttributesRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ protected function getRule(): Rule
3939
new ClassNameCheck(
4040
new ClassCaseSensitivityCheck($reflectionProvider, false),
4141
new ClassForbiddenNameCheck(self::getContainer()),
42+
$reflectionProvider,
43+
self::getContainer(),
4244
),
4345
true,
4446
),

tests/PHPStan/Rules/Functions/ParamAttributesRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ protected function getRule(): Rule
3939
new ClassNameCheck(
4040
new ClassCaseSensitivityCheck($reflectionProvider, false),
4141
new ClassForbiddenNameCheck(self::getContainer()),
42+
$reflectionProvider,
43+
self::getContainer(),
4244
),
4345
true,
4446
),

tests/PHPStan/Rules/Generics/ClassTemplateTypeRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ protected function getRule(): Rule
2626
new ClassNameCheck(
2727
new ClassCaseSensitivityCheck($reflectionProvider, true),
2828
new ClassForbiddenNameCheck(self::getContainer()),
29+
$reflectionProvider,
30+
self::getContainer(),
2931
),
3032
new GenericObjectTypeCheck(),
3133
$typeAliasResolver,

tests/PHPStan/Rules/Generics/FunctionTemplateTypeRuleTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ protected function getRule(): Rule
2727
new ClassNameCheck(
2828
new ClassCaseSensitivityCheck($reflectionProvider, true),
2929
new ClassForbiddenNameCheck(self::getContainer()),
30+
$reflectionProvider,
31+
self::getContainer(),
3032
),
3133
new GenericObjectTypeCheck(),
3234
$typeAliasResolver,

0 commit comments

Comments
 (0)