Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ca55346

Browse files
authored
Error on references of prefixed internal class names from PHAR files
1 parent 3f31056 commit ca55346

File tree

65 files changed

+719
-188
lines changed

Some content is hidden

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

65 files changed

+719
-188
lines changed

‎conf/config.neon‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,11 +833,17 @@ services:
833833
reportMaybes: %reportMaybes%
834834
bleedingEdge: %featureToggles.bleedingEdge%
835835

836+
-
837+
class: PHPStan\Rules\ClassNameCheck
838+
836839
-
837840
class: PHPStan\Rules\ClassCaseSensitivityCheck
838841
arguments:
839842
checkInternalClassCaseSensitivity: %checkInternalClassCaseSensitivity%
840843

844+
-
845+
class: PHPStan\Rules\ClassForbiddenNameCheck
846+
841847
-
842848
class: PHPStan\Rules\Classes\LocalTypeAliasesCheck
843849
arguments:

‎src/PhpDoc/StubValidator.php‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
use PHPStan\Reflection\PhpVersionStaticAccessor;
1717
use PHPStan\Reflection\ReflectionProvider;
1818
use PHPStan\Reflection\ReflectionProviderStaticAccessor;
19-
use PHPStan\Rules\ClassCaseSensitivityCheck;
2019
use PHPStan\Rules\Classes\DuplicateClassDeclarationRule;
2120
use PHPStan\Rules\Classes\DuplicateDeclarationRule;
2221
use PHPStan\Rules\Classes\ExistingClassesInClassImplementsRule;
@@ -26,6 +25,7 @@
2625
use PHPStan\Rules\Classes\LocalTypeAliasesCheck;
2726
use PHPStan\Rules\Classes\LocalTypeAliasesRule;
2827
use PHPStan\Rules\Classes\LocalTypeTraitAliasesRule;
28+
use PHPStan\Rules\ClassNameCheck;
2929
use PHPStan\Rules\DirectRegistry as DirectRuleRegistry;
3030
use PHPStan\Rules\FunctionDefinitionCheck;
3131
use PHPStan\Rules\Functions\DuplicateFunctionDeclarationRule;
@@ -148,7 +148,7 @@ private function getRuleRegistry(Container $container): RuleRegistry
148148
$templateTypeCheck = $container->getByType(TemplateTypeCheck::class);
149149
$varianceCheck = $container->getByType(VarianceCheck::class);
150150
$reflectionProvider = $container->getByType(ReflectionProvider::class);
151-
$classCaseSensitivityCheck = $container->getByType(ClassCaseSensitivityCheck::class);
151+
$classNameCheck = $container->getByType(ClassNameCheck::class);
152152
$functionDefinitionCheck = $container->getByType(FunctionDefinitionCheck::class);
153153
$missingTypehintCheck = $container->getByType(MissingTypehintCheck::class);
154154
$unresolvableTypeHelper = $container->getByType(UnresolvableTypeHelper::class);
@@ -159,13 +159,13 @@ private function getRuleRegistry(Container $container): RuleRegistry
159159

160160
$rules = [
161161
// level 0
162-
new ExistingClassesInClassImplementsRule($classCaseSensitivityCheck, $reflectionProvider),
163-
new ExistingClassesInInterfaceExtendsRule($classCaseSensitivityCheck, $reflectionProvider),
164-
new ExistingClassInClassExtendsRule($classCaseSensitivityCheck, $reflectionProvider),
165-
new ExistingClassInTraitUseRule($classCaseSensitivityCheck, $reflectionProvider),
162+
new ExistingClassesInClassImplementsRule($classNameCheck, $reflectionProvider),
163+
new ExistingClassesInInterfaceExtendsRule($classNameCheck, $reflectionProvider),
164+
new ExistingClassInClassExtendsRule($classNameCheck, $reflectionProvider),
165+
new ExistingClassInTraitUseRule($classNameCheck, $reflectionProvider),
166166
new ExistingClassesInTypehintsRule($functionDefinitionCheck),
167167
new \PHPStan\Rules\Functions\ExistingClassesInTypehintsRule($functionDefinitionCheck),
168-
new ExistingClassesInPropertiesRule($reflectionProvider, $classCaseSensitivityCheck, $unresolvableTypeHelper, $phpVersion, true, false),
168+
new ExistingClassesInPropertiesRule($reflectionProvider, $classNameCheck, $unresolvableTypeHelper, $phpVersion, true, false),
169169
new OverridingMethodRule($phpVersion, new MethodSignatureRule($phpClassReflectionExtension, true, true, $container->getParameter('featureToggles')['abstractTraitMethod']), true, new MethodParameterComparisonHelper($phpVersion, $container->getParameter('featureToggles')['genericPrototypeMessage']), $phpClassReflectionExtension, $container->getParameter('featureToggles')['genericPrototypeMessage'], $container->getParameter('featureToggles')['finalByPhpDoc'], $container->getParameter('checkMissingOverrideMethodAttribute')),
170170
new DuplicateDeclarationRule(),
171171
new LocalTypeAliasesRule($localTypeAliasesCheck),

‎src/Rules/AttributesCheck.php‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class AttributesCheck
2020
public function __construct(
2121
private ReflectionProvider $reflectionProvider,
2222
private FunctionCallParametersCheck $functionCallParametersCheck,
23-
private ClassCaseSensitivityCheck$classCaseSensitivityCheck,
23+
private ClassNameCheck$classCheck,
2424
private bool $deprecationRulesInstalled,
2525
)
2626
{
@@ -67,7 +67,7 @@ public function check(
6767
$errors[] = RuleErrorBuilder::message(sprintf('Attribute class %s is abstract.', $name))->line($attribute->getLine())->build();
6868
}
6969

70-
foreach ($this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($name, $attribute)]) as $caseSensitivityError) {
70+
foreach ($this->classCheck->checkClassNames([new ClassNameNodePair($name, $attribute)]) as $caseSensitivityError) {
7171
$errors[] = $caseSensitivityError;
7272
}
7373

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules;
4+
5+
use function sprintf;
6+
use function str_starts_with;
7+
use function strpos;
8+
use function substr;
9+
10+
class ClassForbiddenNameCheck
11+
{
12+
13+
private const INTERNAL_CLASS_PREFIXES = [
14+
'PHPStan' => '_PHPStan_',
15+
'Rector' => 'RectorPrefix',
16+
'PHP-Scoper' => '_PhpScoper',
17+
];
18+
19+
/**
20+
* @param ClassNameNodePair[] $pairs
21+
* @return RuleError[]
22+
*/
23+
public function checkClassNames(array $pairs): array
24+
{
25+
$errors = [];
26+
foreach ($pairs as $pair) {
27+
$className = $pair->getClassName();
28+
29+
$projectName = null;
30+
foreach (self::INTERNAL_CLASS_PREFIXES as $project => $prefix) {
31+
if (str_starts_with($className, $prefix)) {
32+
$projectName = $project;
33+
break;
34+
}
35+
}
36+
37+
if ($projectName === null) {
38+
continue;
39+
}
40+
41+
$error = RuleErrorBuilder::message(sprintf(
42+
'Referencing prefixed %s class: %s.',
43+
$projectName,
44+
$className,
45+
))->line($pair->getNode()->getLine())->nonIgnorable();
46+
47+
if (strpos($className, '\\') !== false) {
48+
$error->tip(sprintf(
49+
'This is most likely unintentional. Did you mean to type %s?',
50+
substr($className, strpos($className, '\\')),
51+
));
52+
}
53+
54+
$errors[] = $error->build();
55+
}
56+
57+
return $errors;
58+
}
59+
60+
}

‎src/Rules/ClassNameCheck.php‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules;
4+
5+
class ClassNameCheck
6+
{
7+
8+
public function __construct(
9+
private ClassCaseSensitivityCheck $classCaseSensitivityCheck,
10+
private ClassForbiddenNameCheck $classForbiddenNameCheck,
11+
)
12+
{
13+
}
14+
15+
/**
16+
* @param ClassNameNodePair[] $pairs
17+
* @return RuleError[]
18+
*/
19+
public function checkClassNames(array $pairs, bool $checkClassCaseSensitivity = true): array
20+
{
21+
$errors = [];
22+
23+
if ($checkClassCaseSensitivity) {
24+
foreach ($this->classCaseSensitivityCheck->checkClassNames($pairs) as $error) {
25+
$errors[] = $error;
26+
}
27+
}
28+
foreach ($this->classForbiddenNameCheck->checkClassNames($pairs) as $error) {
29+
$errors[] = $error;
30+
}
31+
32+
return $errors;
33+
}
34+
35+
}

‎src/Rules/Classes/ClassConstantRule.php‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use PHPStan\Internal\SprintfHelper;
1010
use PHPStan\Php\PhpVersion;
1111
use PHPStan\Reflection\ReflectionProvider;
12-
use PHPStan\Rules\ClassCaseSensitivityCheck;
12+
use PHPStan\Rules\ClassNameCheck;
1313
use PHPStan\Rules\ClassNameNodePair;
1414
use PHPStan\Rules\Rule;
1515
use PHPStan\Rules\RuleErrorBuilder;
@@ -34,7 +34,7 @@ class ClassConstantRule implements Rule
3434
public function __construct(
3535
private ReflectionProvider $reflectionProvider,
3636
private RuleLevelHelper $ruleLevelHelper,
37-
private ClassCaseSensitivityCheck$classCaseSensitivityCheck,
37+
private ClassNameCheck$classCheck,
3838
private PhpVersion $phpVersion,
3939
)
4040
{
@@ -101,7 +101,7 @@ public function processNode(Node $node, Scope $scope): array
101101
];
102102
}
103103

104-
$messages = $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($className, $class)]);
104+
$messages = $this->classCheck->checkClassNames([new ClassNameNodePair($className, $class)]);
105105

106106
$classType = $scope->resolveTypeByName($class);
107107
}

‎src/Rules/Classes/ExistingClassInClassExtendsRule.php‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use PhpParser\Node;
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Reflection\ReflectionProvider;
8-
use PHPStan\Rules\ClassCaseSensitivityCheck;
8+
use PHPStan\Rules\ClassNameCheck;
99
use PHPStan\Rules\ClassNameNodePair;
1010
use PHPStan\Rules\Rule;
1111
use PHPStan\Rules\RuleErrorBuilder;
@@ -18,7 +18,7 @@ class ExistingClassInClassExtendsRule implements Rule
1818
{
1919

2020
public function __construct(
21-
private ClassCaseSensitivityCheck$classCaseSensitivityCheck,
21+
private ClassNameCheck$classCheck,
2222
private ReflectionProvider $reflectionProvider,
2323
)
2424
{
@@ -35,7 +35,7 @@ public function processNode(Node $node, Scope $scope): array
3535
return [];
3636
}
3737
$extendedClassName = (string) $node->extends;
38-
$messages = $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($extendedClassName, $node->extends)]);
38+
$messages = $this->classCheck->checkClassNames([new ClassNameNodePair($extendedClassName, $node->extends)]);
3939
$currentClassName = null;
4040
if (isset($node->namespacedName)) {
4141
$currentClassName = (string) $node->namespacedName;

‎src/Rules/Classes/ExistingClassInInstanceOfRule.php‎

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use PhpParser\Node\Expr\Instanceof_;
77
use PHPStan\Analyser\Scope;
88
use PHPStan\Reflection\ReflectionProvider;
9-
use PHPStan\Rules\ClassCaseSensitivityCheck;
9+
use PHPStan\Rules\ClassNameCheck;
1010
use PHPStan\Rules\ClassNameNodePair;
1111
use PHPStan\Rules\Rule;
1212
use PHPStan\Rules\RuleErrorBuilder;
@@ -24,7 +24,7 @@ class ExistingClassInInstanceOfRule implements Rule
2424

2525
public function __construct(
2626
private ReflectionProvider $reflectionProvider,
27-
private ClassCaseSensitivityCheck$classCaseSensitivityCheck,
27+
private ClassNameCheck$classCheck,
2828
private bool $checkClassCaseSensitivity,
2929
)
3030
{
@@ -69,13 +69,16 @@ public function processNode(Node $node, Scope $scope): array
6969
return [
7070
RuleErrorBuilder::message(sprintf('Class %s not found.', $name))->line($class->getLine())->discoveringSymbolsTip()->build(),
7171
];
72-
} elseif ($this->checkClassCaseSensitivity) {
73-
$errors = array_merge(
74-
$errors,
75-
$this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($name, $class)]),
76-
);
7772
}
7873

74+
$errors = array_merge(
75+
$errors,
76+
$this->classCheck->checkClassNames(
77+
[new ClassNameNodePair($name, $class)],
78+
$this->checkClassCaseSensitivity,
79+
),
80+
);
81+
7982
$classReflection = $this->reflectionProvider->getClass($name);
8083

8184
if ($classReflection->isTrait()) {

‎src/Rules/Classes/ExistingClassInTraitUseRule.php‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use PhpParser\Node;
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Reflection\ReflectionProvider;
8-
use PHPStan\Rules\ClassCaseSensitivityCheck;
8+
use PHPStan\Rules\ClassNameCheck;
99
use PHPStan\Rules\ClassNameNodePair;
1010
use PHPStan\Rules\Rule;
1111
use PHPStan\Rules\RuleErrorBuilder;
@@ -20,7 +20,7 @@ class ExistingClassInTraitUseRule implements Rule
2020
{
2121

2222
public function __construct(
23-
private ClassCaseSensitivityCheck$classCaseSensitivityCheck,
23+
private ClassNameCheck$classCheck,
2424
private ReflectionProvider $reflectionProvider,
2525
)
2626
{
@@ -33,7 +33,7 @@ public function getNodeType(): string
3333

3434
public function processNode(Node $node, Scope $scope): array
3535
{
36-
$messages = $this->classCaseSensitivityCheck->checkClassNames(
36+
$messages = $this->classCheck->checkClassNames(
3737
array_map(static fn (Node\Name $traitName): ClassNameNodePair => new ClassNameNodePair((string) $traitName, $traitName), $node->traits),
3838
);
3939

‎src/Rules/Classes/ExistingClassesInClassImplementsRule.php‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use PhpParser\Node;
66
use PHPStan\Analyser\Scope;
77
use PHPStan\Reflection\ReflectionProvider;
8-
use PHPStan\Rules\ClassCaseSensitivityCheck;
8+
use PHPStan\Rules\ClassNameCheck;
99
use PHPStan\Rules\ClassNameNodePair;
1010
use PHPStan\Rules\Rule;
1111
use PHPStan\Rules\RuleErrorBuilder;
@@ -19,7 +19,7 @@ class ExistingClassesInClassImplementsRule implements Rule
1919
{
2020

2121
public function __construct(
22-
private ClassCaseSensitivityCheck$classCaseSensitivityCheck,
22+
private ClassNameCheck$classCheck,
2323
private ReflectionProvider $reflectionProvider,
2424
)
2525
{
@@ -32,7 +32,7 @@ public function getNodeType(): string
3232

3333
public function processNode(Node $node, Scope $scope): array
3434
{
35-
$messages = $this->classCaseSensitivityCheck->checkClassNames(
35+
$messages = $this->classCheck->checkClassNames(
3636
array_map(static fn (Node\Name $interfaceName): ClassNameNodePair => new ClassNameNodePair((string) $interfaceName, $interfaceName), $node->implements),
3737
);
3838

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /