Skip to content

Commit 2d30213

Browse files
Merge pull request #23 from DaveLiddament/feature/add-rule-to-check-rules-in-extension-neon
Internal: Add rule to check rules in extension neon
2 parents 8b1cf40 + ce41804 commit 2d30213

File tree

5 files changed

+167
-4
lines changed

5 files changed

+167
-4
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
namespace DaveLiddament\PhpstanPhpLanguageExtensions\Build\PHPStan\Rules;
4+
5+
use Nette\Neon\Neon;
6+
use PhpParser\Node;
7+
use PHPStan\Analyser\Scope;
8+
use PHPStan\Node\InClassNode;
9+
use PHPStan\Rules\Rule;
10+
use PHPStan\Rules\RuleErrorBuilder;
11+
12+
/** @implements Rule<InClassNode> */
13+
final class CheckRuleIsInExtension implements Rule
14+
{
15+
/** @var list<string> */
16+
private array $classes;
17+
18+
public function __construct()
19+
{
20+
$file = Neon::decodeFile(__DIR__.'/../../../extension.neon');
21+
22+
if (!is_array($file)) {
23+
throw new \Exception('Expecting neon file to be parseable');
24+
}
25+
26+
$services = $file['services'] ?? [];
27+
28+
$classes = [];
29+
foreach ($services as $service) {
30+
$class = $service['class'] ?? null;
31+
if (null === $class) {
32+
continue;
33+
}
34+
$classes[] = $class;
35+
}
36+
37+
$this->classes = $classes;
38+
}
39+
40+
public function getNodeType(): string
41+
{
42+
return InClassNode::class;
43+
}
44+
45+
public function processNode(Node $node, Scope $scope): array
46+
{
47+
$classReflection = $scope->getClassReflection();
48+
if (null === $classReflection) {
49+
return [];
50+
}
51+
52+
if (!$classReflection->isSubclassOf(Rule::class)) {
53+
return [];
54+
}
55+
56+
if ($classReflection->isAbstract()) {
57+
return [];
58+
}
59+
60+
$className = $classReflection->getName();
61+
62+
if (str_starts_with(haystack: $className, needle: 'DaveLiddament\PhpstanPhpLanguageExtensions\Build')) {
63+
return [];
64+
}
65+
66+
if (in_array($className, $this->classes)) {
67+
return [];
68+
}
69+
70+
return [
71+
RuleErrorBuilder::message("Rule [$className] not in extension.neon.")->build(),
72+
];
73+
}
74+
}

composer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"phpunit/phpunit": "^9.6.12",
1313
"friendsofphp/php-cs-fixer": "^3.26.1",
1414
"php-parallel-lint/php-parallel-lint": "^1.3.2",
15-
"dave-liddament/phpstan-rule-test-helper": "^0.3.0"
15+
"dave-liddament/phpstan-rule-test-helper": "^0.3.0",
16+
"nette/neon": "^3.4"
1617
},
1718
"license": "MIT",
1819
"autoload": {
@@ -22,7 +23,8 @@
2223
},
2324
"autoload-dev": {
2425
"psr-4": {
25-
"DaveLiddament\\PhpstanPhpLanguageExtensions\\Tests\\": "tests/"
26+
"DaveLiddament\\PhpstanPhpLanguageExtensions\\Tests\\": "tests/",
27+
"DaveLiddament\\PhpstanPhpLanguageExtensions\\Build\\": "build/"
2628
},
2729
"classmap": [
2830
"tests/Rules/data"

composer.lock

Lines changed: 69 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extension.neon

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ services:
8181
tags:
8282
- phpstan.rules.rule
8383

84+
-
85+
class: DaveLiddament\PhpstanPhpLanguageExtensions\Rules\MustUseResultRule
86+
tags:
87+
- phpstan.rules.rule
88+
89+
-
90+
class: DaveLiddament\PhpstanPhpLanguageExtensions\Rules\RestrictTraitToRule
91+
tags:
92+
- phpstan.rules.rule
93+
94+
8495

8596
parametersSchema:
8697
phpLanguageExtensions: structure([

phpstan.neon

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,13 @@ parameters:
33
paths:
44
- src
55
- tests
6+
- build
67
excludePaths:
7-
- tests/Rules/data
8+
- tests/Rules/data
9+
10+
services:
11+
12+
-
13+
class: DaveLiddament\PhpstanPhpLanguageExtensions\Build\PHPStan\Rules\CheckRuleIsInExtension
14+
tags:
15+
- phpstan.rules.rule

0 commit comments

Comments
 (0)