Skip to content

Commit c78b7e9

Browse files
author
Florian Krämer
committed
Adding identifiers.
1 parent 37abef7 commit c78b7e9

6 files changed

+71
-17
lines changed

src/ControlStructureNestingRule.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use PHPStan\Analyser\Scope;
1616
use PHPStan\Rules\Rule;
1717
use PHPStan\Rules\RuleErrorBuilder;
18+
use PHPStan\ShouldNotHappenException;
1819

1920
/**
2021
* A rule to check the nesting level of control structures (if, else, elseif, try, catch).
@@ -25,6 +26,8 @@ class ControlStructureNestingRule implements Rule
2526
{
2627
private const ERROR_MESSAGE = 'Nesting level of %d exceeded. Maximum allowed is %d.';
2728

29+
private const IDENTIFIER = 'phauthentic.cleancode.controlStructureNesting';
30+
2831
private int $maxNestingLevel;
2932

3033
public function __construct(int $maxNestingLevel)
@@ -37,6 +40,9 @@ public function getNodeType(): string
3740
return Node::class; // Process all nodes
3841
}
3942

43+
/**
44+
* @throws ShouldNotHappenException
45+
*/
4046
public function processNode(Node $node, Scope $scope): array
4147
{
4248
$this->setParentAttributesToEnableCorrectNestingDetection($node);
@@ -47,6 +53,7 @@ public function processNode(Node $node, Scope $scope): array
4753

4854
$errors = [];
4955
$nestingLevel = $this->getNestingLevel($node);
56+
5057
if ($nestingLevel > $this->maxNestingLevel) {
5158
$errors = $this->addError($nestingLevel, $node, $errors);
5259
}
@@ -89,6 +96,7 @@ public function setParentAttributesToEnableCorrectNestingDetection(Node $node):
8996
* @param Else_|If_|Catch_|ElseIf_|TryCatch $node
9097
* @param array $errors
9198
* @return array
99+
* @throws ShouldNotHappenException
92100
*/
93101
public function addError(int $nestingLevel, Else_|If_|Catch_|ElseIf_|TryCatch $node, array $errors): array
94102
{
@@ -98,7 +106,10 @@ public function addError(int $nestingLevel, Else_|If_|Catch_|ElseIf_|TryCatch $n
98106
$this->maxNestingLevel
99107
);
100108

101-
$errors[] = RuleErrorBuilder::message($errorMessage)->line($node->getLine())->build();
109+
$errors[] = RuleErrorBuilder::message($errorMessage)
110+
->line($node->getLine())
111+
->identifier(self::IDENTIFIER)
112+
->build();
102113

103114
return $errors;
104115
}

src/DependencyConstraintsRule.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PHPStan\Rules\Rule;
1111
use PHPStan\Rules\RuleError;
1212
use PHPStan\Rules\RuleErrorBuilder;
13+
use PHPStan\ShouldNotHappenException;
1314

1415
/**
1516
* A PHPStan rule to enforce dependency constraints between namespaces.
@@ -22,6 +23,8 @@ class DependencyConstraintsRule implements Rule
2223
{
2324
private const ERROR_MESSAGE = 'Dependency violation: A class in namespace `%s` is not allowed to depend on `%s`.';
2425

26+
private const IDENTIFIER = 'phauthentic.architecture.dependencyConstraints';
27+
2528
/**
2629
* @var array<string, array<string>>
2730
* An array where the key is a regex for the source namespace and the value is
@@ -43,6 +46,9 @@ public function getNodeType(): string
4346
return Use_::class;
4447
}
4548

49+
/**
50+
* @throws ShouldNotHappenException
51+
*/
4652
public function processNode(Node $node, Scope $scope): array
4753
{
4854
$currentNamespace = $scope->getNamespace();
@@ -69,7 +75,7 @@ public function processNode(Node $node, Scope $scope): array
6975
* @param string $currentNamespace
7076
* @param array<RuleError> $errors
7177
* @return array<RuleError>
72-
* @throws \PHPStan\ShouldNotHappenException
78+
* @throws ShouldNotHappenException
7379
*/
7480
public function validateUseStatements(Node $node, array $disallowedDependencyPatterns, string $currentNamespace, array $errors): array
7581
{
@@ -82,6 +88,7 @@ public function validateUseStatements(Node $node, array $disallowedDependencyPat
8288
$currentNamespace,
8389
$usedClassName
8490
))
91+
->identifier(self::IDENTIFIER)
8592
->line($use->getStartLine())
8693
->build();
8794
}

src/FinalClassRule.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PHPStan\Analyser\Scope;
1010
use PHPStan\Rules\Rule;
1111
use PHPStan\Rules\RuleErrorBuilder;
12+
use PHPStan\ShouldNotHappenException;
1213

1314
/**
1415
* @implements Rule<Class_>
@@ -17,6 +18,8 @@ class FinalClassRule implements Rule
1718
{
1819
private const ERROR_MESSAGE = 'Class %s must be final.';
1920

21+
private const IDENTIFIER = 'phauthentic.architecture.finalClass';
22+
2023
/**
2124
* @var array<string> An array of regex patterns to match against class names.
2225
* e.g., ['#^App\\Domain\\.*#', '#^App\\Service\\.*#']
@@ -37,6 +40,9 @@ public function getNodeType(): string
3740
return Class_::class;
3841
}
3942

43+
/**
44+
* @throws ShouldNotHappenException
45+
*/
4046
public function processNode(Node $node, Scope $scope): array
4147
{
4248
if (!$node instanceof Class_ || !isset($node->name)) {
@@ -51,6 +57,7 @@ public function processNode(Node $node, Scope $scope): array
5157
if (preg_match($pattern, $fullClassName) && !$node->isFinal()) {
5258
return [
5359
RuleErrorBuilder::message(sprintf(self::ERROR_MESSAGE, $fullClassName))
60+
->identifier(self::IDENTIFIER)
5461
->build(),
5562
];
5663
}

src/NamespaceClassPatternRule.php

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PHPStan\Analyser\Scope;
1111
use PHPStan\Rules\Rule;
1212
use PHPStan\Rules\RuleErrorBuilder;
13+
use PHPStan\ShouldNotHappenException;
1314

1415
/**
1516
* PHPStan rule to ensure that classes inside namespaces matching a given regex
@@ -19,6 +20,10 @@
1920
*/
2021
class NamespaceClassPatternRule implements Rule
2122
{
23+
private const ERROR_MESSAGE = 'Class %s in namespace %s does not match any of the required patterns:';
24+
25+
private const IDENTIFIER = 'phauthentic.architecture.namespaceClassPattern';
26+
2227
/**
2328
* @var array{namespace: string, classPatterns: string[]}[]
2429
*/
@@ -91,7 +96,7 @@ private function classNameMatches(string $className, array $classPatterns): bool
9196
private function buildErrorMessage(string $fqcn, string $namespace, array $patterns): string
9297
{
9398
$lines = [
94-
sprintf('Class %s in namespace %s does not match any of the required patterns:', $fqcn, $namespace),
99+
sprintf(self::ERROR_MESSAGE, $fqcn, $namespace),
95100
];
96101

97102
foreach ($patterns as $pattern) {
@@ -108,13 +113,22 @@ private function buildErrorMessage(string $fqcn, string $namespace, array $patte
108113
* @param Class_ $stmt
109114
* @param array $errors
110115
* @return array
116+
* @throws ShouldNotHappenException
111117
*/
112-
public function buildRuleError(string $namespaceName, string $className, $classPatterns, Class_ $stmt, array $errors): array
113-
{
118+
public function buildRuleError(
119+
string $namespaceName,
120+
string $className,
121+
$classPatterns,
122+
Class_ $stmt,
123+
array $errors
124+
): array {
114125
$fqcn = $namespaceName ? $namespaceName . '\\' . $className : $className;
115126
$errors[] = RuleErrorBuilder::message(
116-
$this->buildErrorMessage($fqcn, $namespaceName, $classPatterns)
117-
)->line($stmt->getLine())->build();
127+
$this->buildErrorMessage($fqcn, $namespaceName, $classPatterns)
128+
)
129+
->line($stmt->getLine())
130+
->identifier(self::IDENTIFIER)
131+
->build();
118132

119133
return $errors;
120134
}

src/ReadonlyClassRule.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class ReadonlyClassRule implements Rule
1717
{
1818
private const ERROR_MESSAGE = 'Class %s must be readonly.';
1919

20+
private const IDENTIFIER = 'phauthentic.architecture.readonlyClass';
21+
2022
/**
2123
* @var string[]
2224
*/
@@ -49,6 +51,7 @@ public function processNode(Node $node, Scope $scope): array
4951
if (preg_match($pattern, $fullClassName) && !$node->isReadonly()) {
5052
return [
5153
RuleErrorBuilder::message(sprintf(self::ERROR_MESSAGE, $fullClassName))
54+
->identifier(self::IDENTIFIER)
5255
->build(),
5356
];
5457
}

src/TooManyArgumentsRule.php

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use PhpParser\Node;
88
use PhpParser\Node\Stmt\ClassMethod;
99
use PHPStan\Analyser\Scope;
10-
use PHPStan\Rules\IdentifierRuleError;
1110
use PHPStan\Rules\Rule;
1211
use PHPStan\Rules\RuleError;
1312
use PHPStan\Rules\RuleErrorBuilder;
@@ -22,6 +21,8 @@ class TooManyArgumentsRule implements Rule
2221
{
2322
private const ERROR_MESSAGE = 'Method %s::%s has too many arguments (%d). Maximum allowed is %d.';
2423

24+
private const IDENTIFIER = 'phauthentic.cleancode.tooManyArguments';
25+
2526
private int $maxArguments;
2627

2728
/**
@@ -66,16 +67,11 @@ public function processNode(Node $node, Scope $scope): array
6667
return [];
6768
}
6869

70+
$message = $this->buildErrorMessage($scope, $node);
71+
6972
return [
70-
RuleErrorBuilder::message(
71-
sprintf(
72-
self::ERROR_MESSAGE,
73-
$scope->getClassReflection()->getName(),
74-
$node->name->toString(),
75-
count($node->params),
76-
$this->maxArguments
77-
)
78-
)
73+
RuleErrorBuilder::message($message)
74+
->identifier(self::IDENTIFIER)
7975
->build()
8076
];
8177
}
@@ -103,4 +99,20 @@ private function matchesPattern(Scope $scope): bool
10399

104100
return false;
105101
}
102+
103+
/**
104+
* @param Scope $scope
105+
* @param Node $node
106+
* @return string
107+
*/
108+
public function buildErrorMessage(Scope $scope, Node $node): string
109+
{
110+
return sprintf(
111+
self::ERROR_MESSAGE,
112+
$scope->getClassReflection()->getName(),
113+
$node->name->toString(),
114+
count($node->params),
115+
$this->maxArguments
116+
);
117+
}
106118
}

0 commit comments

Comments
 (0)