Skip to content

Commit d1279c0

Browse files
committed
Rule for checking whether a class extends Nette\Object
1 parent 062a2e3 commit d1279c0

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ This extension provides following features:
1313
* Magic [Nette\Object and Nette\SmartObject](https://doc.nette.org/en/2.4/php-language-enhancements) properties
1414
* Event listeners through the `on*` properties
1515

16+
It also contains this framework-specific rule (can be enabled separately):
17+
18+
* Do not extend Nette\Object, use Nette\SmartObject trait instead
19+
1620
## Usage
1721

1822
To use this extension, require it in [Composer](https://getcomposer.org/):
@@ -27,3 +31,9 @@ And include extension.neon in your project's PHPStan config:
2731
includes:
2832
- vendor/phpstan/phpstan-nette/extension.neon
2933
```
34+
35+
To perform framework-specific checks, include also this file:
36+
37+
```
38+
- vendor/phpstan/phpstan-nette/rules.neon
39+
```

rules.neon

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
services:
2+
-
3+
class: PHPStan\Rule\Nette\DoNotExtendNetteObjectRule
4+
tags:
5+
- phpstan.rules.rule
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\Rule\Nette;
4+
5+
use PhpParser\Node;
6+
use PhpParser\Node\Stmt\Class_;
7+
use PHPStan\Analyser\Scope;
8+
use PHPStan\Broker\Broker;
9+
10+
class DoNotExtendNetteObjectRule implements \PHPStan\Rules\Rule
11+
{
12+
13+
/** @var \PHPStan\Broker\Broker */
14+
private $broker;
15+
16+
public function __construct(Broker $broker)
17+
{
18+
$this->broker = $broker;
19+
}
20+
21+
public function getNodeType(): string
22+
{
23+
return Class_::class;
24+
}
25+
26+
/**
27+
* @param \PhpParser\Node\Stmt\Class_ $node
28+
* @param \PHPStan\Analyser\Scope $scope
29+
* @return string[] errors
30+
*/
31+
public function processNode(Node $node, Scope $scope): array
32+
{
33+
if (!isset($node->namespacedName)) {
34+
// anonymous class - will be possible to inspect
35+
// with node visitor and special ClassBody node
36+
// because $scope will contain the anonymous class reflection
37+
return [];
38+
}
39+
40+
$className = (string) $node->namespacedName;
41+
if (!$this->broker->hasClass($className)) {
42+
return [];
43+
}
44+
45+
$classReflection = $this->broker->getClass($className);
46+
if ($classReflection->isSubclassOf(\Nette\Object::class)) {
47+
return [
48+
sprintf(
49+
"Class %s extends %s - it's better to use %s trait.",
50+
$className,
51+
\Nette\Object::class,
52+
\Nette\SmartObject::class
53+
),
54+
];
55+
}
56+
57+
return [];
58+
}
59+
60+
}

0 commit comments

Comments
 (0)