Skip to content

Commit c3ebe44

Browse files
committed
feat: add InternalClassExtendsRule with tests
1 parent 900b1e7 commit c3ebe44

4 files changed

Lines changed: 85 additions & 0 deletions

File tree

rules.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ rules:
66
- Shopware\PhpStan\Rule\SetForeignKeyRule
77
- Shopware\PhpStan\Rule\MethodBecomesAbstractRule
88
- Shopware\PhpStan\Rule\ScheduledTaskTooLowIntervalRule
9+
- Shopware\PhpStan\Rule\InternalClassExtendsRule
910

1011
services:
1112
-
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
namespace Shopware\PhpStan\Rule;
4+
5+
use PhpParser\Node;
6+
use PhpParser\Node\Stmt\Class_;
7+
use PHPStan\Analyser\Scope;
8+
use PHPStan\Reflection\ReflectionProvider;
9+
use PHPStan\Rules\Rule;
10+
use PHPStan\Rules\RuleErrorBuilder;
11+
12+
/**
13+
* @implements Rule<Class_>
14+
*
15+
* @internal
16+
*/
17+
class InternalClassExtendsRule implements Rule
18+
{
19+
private ReflectionProvider $reflectionProvider;
20+
21+
public function __construct(ReflectionProvider $reflectionProvider)
22+
{
23+
$this->reflectionProvider = $reflectionProvider;
24+
}
25+
26+
public function getNodeType(): string
27+
{
28+
return Class_::class;
29+
}
30+
31+
public function processNode(Node $node, Scope $scope): array
32+
{
33+
if ($node->extends === null) {
34+
return [];
35+
}
36+
37+
$parentClassName = (string) $node->extends;
38+
$parentClassReflection = $this->reflectionProvider->getClass($parentClassName);
39+
40+
if ($parentClassReflection->isInternal()) {
41+
return [
42+
RuleErrorBuilder::message(sprintf('Class %s extends internal class %s. Please refrain from extending classes which are annotated with @internal.', (string) $node->name, $parentClassName))
43+
->line($node->getLine())
44+
->identifier('shopware.internal.class.extends')
45+
->build(),
46+
];
47+
}
48+
49+
return [];
50+
}
51+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Shopware\PhpStan\Tests\Rule;
4+
5+
use PHPStan\Rules\Rule;
6+
use PHPStan\Testing\RuleTestCase;
7+
use Shopware\PhpStan\Rule\InternalClassExtendsRule;
8+
9+
class InternalClassExtendsRuleTest extends RuleTestCase
10+
{
11+
protected function getRule(): Rule
12+
{
13+
return new InternalClassExtendsRule($this->createReflectionProvider());
14+
}
15+
16+
public function testInternalClassExtendsRule(): void
17+
{
18+
$this->analyse([__DIR__ . '/../data/InternalClassExtendsRule/internal-class.php'], [
19+
[
20+
'Class PublicController extends internal class InternalController. Please refrain from extending classes which are annotated with @internal.',
21+
8,
22+
],
23+
]);
24+
}
25+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
/**
4+
* @internal
5+
*/
6+
class InternalController {}
7+
8+
class PublicController extends InternalController {}

0 commit comments

Comments
 (0)