Skip to content

Commit 87414b2

Browse files
authored
Merge pull request #3 from hirokinoue/name-node-holder-find-rule
カスタムルールのサンプルを追加する
2 parents 905c8ec + 0704452 commit 87414b2

File tree

5 files changed

+154
-0
lines changed

5 files changed

+154
-0
lines changed

Rules/NameNodeHolderFindRule.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace Rules;
4+
5+
use PhpParser\Node;
6+
use PHPStan\Analyser\Scope;
7+
use PHPStan\Rules\Rule;
8+
use PHPStan\Node\InClassNode;
9+
use PHPStan\Rules\RuleErrorBuilder;
10+
use PHPStan\Type\ObjectType;
11+
12+
class NameNodeHolderFindRule implements Rule
13+
{
14+
public function getNodeType(): string
15+
{
16+
return InClassNode::class;
17+
}
18+
19+
public function processNode(Node $node, Scope $scope): array
20+
{
21+
if (!$node instanceof InClassNode) {
22+
return [];
23+
}
24+
25+
$classLike = $node->getOriginalNode();
26+
$properties = $classLike->getProperties();
27+
$classReflection = $scope->getClassReflection();
28+
foreach ($properties as $property) {
29+
foreach($property->props as $prop) {
30+
$propertyName = $prop->name->toString();
31+
$propertyReflection = $classReflection->getNativeProperty($propertyName);
32+
$propertyType = $propertyReflection->getReadableType();
33+
$trinary = $propertyType->isSuperTypeOf(new ObjectType('PhpParser\Node\Name'));
34+
if (!$trinary->no()) {
35+
return [
36+
RuleErrorBuilder::message(
37+
$classLike->namespacedName->toString()
38+
)->build(),
39+
];
40+
}
41+
}
42+
}
43+
return [];
44+
}
45+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Tests\NameNodeHolderFindRuleTest;
4+
5+
use Rules\NameNodeHolderFindRule;
6+
use PHPStan\Rules\Rule;
7+
use PHPStan\Testing\RuleTestCase;
8+
9+
/**
10+
* @extends RuleTestCase<NameNodeHolderFindRuleTest>
11+
*/
12+
class NameNodeHolderFindRuleTest extends RuleTestCase
13+
{
14+
protected function getRule(): Rule
15+
{
16+
return new NameNodeHolderFindRule();
17+
}
18+
19+
/**
20+
* @dataProvider data
21+
*/
22+
public function testRule(string $file, array $expected): void
23+
{
24+
$this->analyse([$file], $expected);
25+
}
26+
27+
public function data(): array
28+
{
29+
return [
30+
[__DIR__ . '/data/name-holder.php', [['App\DummyFuncCall', 8]]],
31+
[__DIR__ . '/data/non-name-holder.php', []],
32+
];
33+
}
34+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App;
4+
5+
use PhpParser\Node\Expr;
6+
use PhpParser\Node\Expr\CallLike;
7+
8+
class DummyFuncCall extends CallLike
9+
{
10+
/** @var Node\Name|Expr Function name */
11+
public $name;
12+
/** @var array<Node\Arg|Node\VariadicPlaceholder> Arguments */
13+
public $args;
14+
15+
/**
16+
* Constructs a function call node.
17+
*
18+
* @param Node\Name|Expr $name Function name
19+
* @param array<Node\Arg|Node\VariadicPlaceholder> $args Arguments
20+
* @param array $attributes Additional attributes
21+
*/
22+
public function __construct($name, array $args = [], array $attributes = []) {
23+
$this->attributes = $attributes;
24+
$this->name = $name;
25+
$this->args = $args;
26+
}
27+
28+
public function getSubNodeNames() : array {
29+
return ['name', 'args'];
30+
}
31+
32+
public function getType() : string {
33+
return 'Expr_FuncCall';
34+
}
35+
36+
public function getRawArgs(): array {
37+
return $this->args;
38+
}
39+
}
40+
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace App;
4+
5+
use PhpParser\Node\Expr;
6+
7+
class DummyArrayDimFetch extends Expr
8+
{
9+
/** @var Expr Variable */
10+
public $var;
11+
/** @var null|Expr Array index / dim */
12+
public $dim;
13+
14+
/**
15+
* Constructs an array index fetch node.
16+
*
17+
* @param Expr $var Variable
18+
* @param null|Expr $dim Array index / dim
19+
* @param array $attributes Additional attributes
20+
*/
21+
public function __construct(Expr $var, Expr $dim = null, array $attributes = []) {
22+
$this->attributes = $attributes;
23+
$this->var = $var;
24+
$this->dim = $dim;
25+
}
26+
27+
public function getSubNodeNames() : array {
28+
return ['var', 'dim'];
29+
}
30+
31+
public function getType() : string {
32+
return 'Expr_ArrayDimFetch';
33+
}
34+
}

phpstan.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
rules:
22
- Rules\MyRule
33
- Rules\CallStaticMethodInClassRule
4+
- Rules\NameNodeHolderFindRule

0 commit comments

Comments
 (0)