Skip to content

Commit

Permalink
Error on refernces of PHPStan internal class names
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm committed Feb 22, 2024
1 parent 039a3dc commit bc19a7d
Show file tree
Hide file tree
Showing 65 changed files with 644 additions and 188 deletions.
6 changes: 6 additions & 0 deletions conf/config.neon
Original file line number Diff line number Diff line change
Expand Up @@ -833,11 +833,17 @@ services:
reportMaybes: %reportMaybes%
bleedingEdge: %featureToggles.bleedingEdge%

-
class: PHPStan\Rules\ClassNameCheck

-
class: PHPStan\Rules\ClassCaseSensitivityCheck
arguments:
checkInternalClassCaseSensitivity: %checkInternalClassCaseSensitivity%

-
class: PHPStan\Rules\ClassForbiddenNameCheck

-
class: PHPStan\Rules\Classes\LocalTypeAliasesCheck
arguments:
Expand Down
14 changes: 7 additions & 7 deletions src/PhpDoc/StubValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use PHPStan\Reflection\PhpVersionStaticAccessor;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Reflection\ReflectionProviderStaticAccessor;
use PHPStan\Rules\ClassCaseSensitivityCheck;
use PHPStan\Rules\Classes\DuplicateClassDeclarationRule;
use PHPStan\Rules\Classes\DuplicateDeclarationRule;
use PHPStan\Rules\Classes\ExistingClassesInClassImplementsRule;
Expand All @@ -26,6 +25,7 @@
use PHPStan\Rules\Classes\LocalTypeAliasesCheck;
use PHPStan\Rules\Classes\LocalTypeAliasesRule;
use PHPStan\Rules\Classes\LocalTypeTraitAliasesRule;
use PHPStan\Rules\ClassNameCheck;
use PHPStan\Rules\DirectRegistry as DirectRuleRegistry;
use PHPStan\Rules\FunctionDefinitionCheck;
use PHPStan\Rules\Functions\DuplicateFunctionDeclarationRule;
Expand Down Expand Up @@ -148,7 +148,7 @@ private function getRuleRegistry(Container $container): RuleRegistry
$templateTypeCheck = $container->getByType(TemplateTypeCheck::class);
$varianceCheck = $container->getByType(VarianceCheck::class);
$reflectionProvider = $container->getByType(ReflectionProvider::class);
$classCaseSensitivityCheck = $container->getByType(ClassCaseSensitivityCheck::class);
$classNameCheck = $container->getByType(ClassNameCheck::class);
$functionDefinitionCheck = $container->getByType(FunctionDefinitionCheck::class);
$missingTypehintCheck = $container->getByType(MissingTypehintCheck::class);
$unresolvableTypeHelper = $container->getByType(UnresolvableTypeHelper::class);
Expand All @@ -159,13 +159,13 @@ private function getRuleRegistry(Container $container): RuleRegistry

$rules = [
// level 0
new ExistingClassesInClassImplementsRule($classCaseSensitivityCheck, $reflectionProvider),
new ExistingClassesInInterfaceExtendsRule($classCaseSensitivityCheck, $reflectionProvider),
new ExistingClassInClassExtendsRule($classCaseSensitivityCheck, $reflectionProvider),
new ExistingClassInTraitUseRule($classCaseSensitivityCheck, $reflectionProvider),
new ExistingClassesInClassImplementsRule($classNameCheck, $reflectionProvider),
new ExistingClassesInInterfaceExtendsRule($classNameCheck, $reflectionProvider),
new ExistingClassInClassExtendsRule($classNameCheck, $reflectionProvider),
new ExistingClassInTraitUseRule($classNameCheck, $reflectionProvider),
new ExistingClassesInTypehintsRule($functionDefinitionCheck),
new \PHPStan\Rules\Functions\ExistingClassesInTypehintsRule($functionDefinitionCheck),
new ExistingClassesInPropertiesRule($reflectionProvider, $classCaseSensitivityCheck, $unresolvableTypeHelper, $phpVersion, true, false),
new ExistingClassesInPropertiesRule($reflectionProvider, $classNameCheck, $unresolvableTypeHelper, $phpVersion, true, false),
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')),
new DuplicateDeclarationRule(),
new LocalTypeAliasesRule($localTypeAliasesCheck),
Expand Down
4 changes: 2 additions & 2 deletions src/Rules/AttributesCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class AttributesCheck
public function __construct(
private ReflectionProvider $reflectionProvider,
private FunctionCallParametersCheck $functionCallParametersCheck,
private ClassCaseSensitivityCheck $classCaseSensitivityCheck,
private ClassNameCheck $classCheck,
private bool $deprecationRulesInstalled,
)
{
Expand Down Expand Up @@ -67,7 +67,7 @@ public function check(
$errors[] = RuleErrorBuilder::message(sprintf('Attribute class %s is abstract.', $name))->line($attribute->getLine())->build();
}

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

Expand Down
34 changes: 34 additions & 0 deletions src/Rules/ClassForbiddenNameCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules;

use function sprintf;
use function str_starts_with;

class ClassForbiddenNameCheck
{

/**
* @param ClassNameNodePair[] $pairs
* @return RuleError[]
*/
public function checkClassNames(array $pairs): array
{
$errors = [];
foreach ($pairs as $pair) {
$className = $pair->getClassName();

if (!str_starts_with($className, '_PHPStan_')) {
continue;
}

$errors[] = RuleErrorBuilder::message(sprintf(
'Internal PHPStan Class cannot be referenced: %s.',
$className,
))->line($pair->getNode()->getLine())->build();
}

return $errors;
}

}
31 changes: 31 additions & 0 deletions src/Rules/ClassNameCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php declare(strict_types = 1);

namespace PHPStan\Rules;

class ClassNameCheck
{

public function __construct(
private ClassCaseSensitivityCheck $classCaseSensitivityCheck,
private ClassForbiddenNameCheck $classForbiddenNameCheck,
)
{
}

/**
* @param ClassNameNodePair[] $pairs
* @return RuleError[]
*/
public function checkClassNames(array $pairs, bool $checkClassCaseSensitivity = true): array
{
$errors = [];

if ($checkClassCaseSensitivity) {
$errors += $this->classCaseSensitivityCheck->checkClassNames($pairs);
}
$errors += $this->classForbiddenNameCheck->checkClassNames($pairs);

return $errors;
}

}
6 changes: 3 additions & 3 deletions src/Rules/Classes/ClassConstantRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use PHPStan\Internal\SprintfHelper;
use PHPStan\Php\PhpVersion;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\ClassCaseSensitivityCheck;
use PHPStan\Rules\ClassNameCheck;
use PHPStan\Rules\ClassNameNodePair;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
Expand All @@ -34,7 +34,7 @@ class ClassConstantRule implements Rule
public function __construct(
private ReflectionProvider $reflectionProvider,
private RuleLevelHelper $ruleLevelHelper,
private ClassCaseSensitivityCheck $classCaseSensitivityCheck,
private ClassNameCheck $classCheck,
private PhpVersion $phpVersion,
)
{
Expand Down Expand Up @@ -101,7 +101,7 @@ public function processNode(Node $node, Scope $scope): array
];
}

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

$classType = $scope->resolveTypeByName($class);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Rules/Classes/ExistingClassInClassExtendsRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\ClassCaseSensitivityCheck;
use PHPStan\Rules\ClassNameCheck;
use PHPStan\Rules\ClassNameNodePair;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
Expand All @@ -18,7 +18,7 @@ class ExistingClassInClassExtendsRule implements Rule
{

public function __construct(
private ClassCaseSensitivityCheck $classCaseSensitivityCheck,
private ClassNameCheck $classCheck,
private ReflectionProvider $reflectionProvider,
)
{
Expand All @@ -35,7 +35,7 @@ public function processNode(Node $node, Scope $scope): array
return [];
}
$extendedClassName = (string) $node->extends;
$messages = $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($extendedClassName, $node->extends)]);
$messages = $this->classCheck->checkClassNames([new ClassNameNodePair($extendedClassName, $node->extends)]);
$currentClassName = null;
if (isset($node->namespacedName)) {
$currentClassName = (string) $node->namespacedName;
Expand Down
17 changes: 10 additions & 7 deletions src/Rules/Classes/ExistingClassInInstanceOfRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use PhpParser\Node\Expr\Instanceof_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\ClassCaseSensitivityCheck;
use PHPStan\Rules\ClassNameCheck;
use PHPStan\Rules\ClassNameNodePair;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
Expand All @@ -24,7 +24,7 @@ class ExistingClassInInstanceOfRule implements Rule

public function __construct(
private ReflectionProvider $reflectionProvider,
private ClassCaseSensitivityCheck $classCaseSensitivityCheck,
private ClassNameCheck $classCheck,
private bool $checkClassCaseSensitivity,
)
{
Expand Down Expand Up @@ -69,13 +69,16 @@ public function processNode(Node $node, Scope $scope): array
return [
RuleErrorBuilder::message(sprintf('Class %s not found.', $name))->line($class->getLine())->discoveringSymbolsTip()->build(),
];
} elseif ($this->checkClassCaseSensitivity) {
$errors = array_merge(
$errors,
$this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($name, $class)]),
);
}

$errors = array_merge(
$errors,
$this->classCheck->checkClassNames(
[new ClassNameNodePair($name, $class)],
$this->checkClassCaseSensitivity,
),
);

$classReflection = $this->reflectionProvider->getClass($name);

if ($classReflection->isTrait()) {
Expand Down
6 changes: 3 additions & 3 deletions src/Rules/Classes/ExistingClassInTraitUseRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\ClassCaseSensitivityCheck;
use PHPStan\Rules\ClassNameCheck;
use PHPStan\Rules\ClassNameNodePair;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
Expand All @@ -20,7 +20,7 @@ class ExistingClassInTraitUseRule implements Rule
{

public function __construct(
private ClassCaseSensitivityCheck $classCaseSensitivityCheck,
private ClassNameCheck $classCheck,
private ReflectionProvider $reflectionProvider,
)
{
Expand All @@ -33,7 +33,7 @@ public function getNodeType(): string

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

Expand Down
6 changes: 3 additions & 3 deletions src/Rules/Classes/ExistingClassesInClassImplementsRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\ClassCaseSensitivityCheck;
use PHPStan\Rules\ClassNameCheck;
use PHPStan\Rules\ClassNameNodePair;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
Expand All @@ -19,7 +19,7 @@ class ExistingClassesInClassImplementsRule implements Rule
{

public function __construct(
private ClassCaseSensitivityCheck $classCaseSensitivityCheck,
private ClassNameCheck $classCheck,
private ReflectionProvider $reflectionProvider,
)
{
Expand All @@ -32,7 +32,7 @@ public function getNodeType(): string

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

Expand Down
6 changes: 3 additions & 3 deletions src/Rules/Classes/ExistingClassesInEnumImplementsRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\ClassCaseSensitivityCheck;
use PHPStan\Rules\ClassNameCheck;
use PHPStan\Rules\ClassNameNodePair;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
Expand All @@ -19,7 +19,7 @@ class ExistingClassesInEnumImplementsRule implements Rule
{

public function __construct(
private ClassCaseSensitivityCheck $classCaseSensitivityCheck,
private ClassNameCheck $classCheck,
private ReflectionProvider $reflectionProvider,
)
{
Expand All @@ -32,7 +32,7 @@ public function getNodeType(): string

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

Expand Down
6 changes: 3 additions & 3 deletions src/Rules/Classes/ExistingClassesInInterfaceExtendsRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\ClassCaseSensitivityCheck;
use PHPStan\Rules\ClassNameCheck;
use PHPStan\Rules\ClassNameNodePair;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
Expand All @@ -19,7 +19,7 @@ class ExistingClassesInInterfaceExtendsRule implements Rule
{

public function __construct(
private ClassCaseSensitivityCheck $classCaseSensitivityCheck,
private ClassNameCheck $classCheck,
private ReflectionProvider $reflectionProvider,
)
{
Expand All @@ -32,7 +32,7 @@ public function getNodeType(): string

public function processNode(Node $node, Scope $scope): array
{
$messages = $this->classCaseSensitivityCheck->checkClassNames(
$messages = $this->classCheck->checkClassNames(
array_map(static fn (Node\Name $interfaceName): ClassNameNodePair => new ClassNameNodePair((string) $interfaceName, $interfaceName), $node->extends),
);

Expand Down
6 changes: 3 additions & 3 deletions src/Rules/Classes/InstantiationRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Reflection\Php\PhpMethodReflection;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Rules\ClassCaseSensitivityCheck;
use PHPStan\Rules\ClassNameCheck;
use PHPStan\Rules\ClassNameNodePair;
use PHPStan\Rules\FunctionCallParametersCheck;
use PHPStan\Rules\Rule;
Expand All @@ -32,7 +32,7 @@ class InstantiationRule implements Rule
public function __construct(
private ReflectionProvider $reflectionProvider,
private FunctionCallParametersCheck $check,
private ClassCaseSensitivityCheck $classCaseSensitivityCheck,
private ClassNameCheck $classCheck,
)
{
}
Expand Down Expand Up @@ -119,7 +119,7 @@ private function checkClassName(string $class, bool $isName, Node $node, Scope $
];
}

$messages = $this->classCaseSensitivityCheck->checkClassNames([
$messages = $this->classCheck->checkClassNames([
new ClassNameNodePair($class, $node->class),
]);

Expand Down

0 comments on commit bc19a7d

Please sign in to comment.