Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3a21c13

Browse files
authored
Implement CompositeRule (#4438)
1 parent c8a1ae1 commit 3a21c13

File tree

3 files changed

+165
-0
lines changed

3 files changed

+165
-0
lines changed

‎src/Testing/CompositeRule.php‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Testing;
4+
5+
use PhpParser\Node;
6+
use PHPStan\Analyser\NodeCallbackInvoker;
7+
use PHPStan\Analyser\Scope;
8+
use PHPStan\Rules\DirectRegistry;
9+
use PHPStan\Rules\Rule;
10+
use function get_class;
11+
12+
/**
13+
* Allows testing of rules which delegate work to NodeCallbackInvoker.
14+
*
15+
* @implements Rule<Node>
16+
*
17+
* @api
18+
*/
19+
final class CompositeRule implements Rule
20+
{
21+
22+
private DirectRegistry $registry;
23+
24+
/**
25+
* @param array<Rule<Node>> $rules
26+
*
27+
* @api
28+
*/
29+
public function __construct(array $rules)
30+
{
31+
$this->registry = new DirectRegistry($rules);
32+
}
33+
34+
public function getNodeType(): string
35+
{
36+
return Node::class;
37+
}
38+
39+
public function processNode(Node $node, Scope&NodeCallbackInvoker $scope): array
40+
{
41+
$errors = [];
42+
43+
$nodeType = get_class($node);
44+
foreach ($this->registry->getRules($nodeType) as $rule) {
45+
foreach ($rule->processNode($node, $scope) as $error) {
46+
$errors[] = $error;
47+
}
48+
}
49+
50+
return $errors;
51+
}
52+
53+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Testing;
4+
5+
use PhpParser\Node;
6+
use PhpParser\Node\Scalar\Int_;
7+
use PhpParser\Node\Scalar\String_;
8+
use PHPStan\Analyser\NodeCallbackInvoker;
9+
use PHPStan\Analyser\Scope;
10+
use PHPStan\Rules\Rule;
11+
use PHPStan\Rules\RuleErrorBuilder;
12+
use function ctype_digit;
13+
14+
/**
15+
* @extends RuleTestCase<CompositeRule>
16+
*/
17+
final class CompositeRuleTest extends RuleTestCase
18+
{
19+
20+
protected function getRule(): Rule
21+
{
22+
return new CompositeRule([
23+
/**
24+
* @implements Rule<String_>
25+
*/
26+
new class implements Rule {
27+
28+
public function getNodeType(): string
29+
{
30+
return String_::class;
31+
}
32+
33+
/**
34+
* @param String_ $node
35+
*/
36+
public function processNode(Node $node, Scope&NodeCallbackInvoker $scope): array
37+
{
38+
if (ctype_digit($node->value)) {
39+
$scope->invokeNodeCallback(
40+
new Int_((int) $node->value, ['startLine' => $node->getStartLine()]),
41+
);
42+
43+
return [];
44+
}
45+
46+
return [
47+
RuleErrorBuilder::message('Error from String_ Rule.')->identifier('CompositeRuleString')->build(),
48+
];
49+
}
50+
51+
},
52+
/**
53+
* @implements Rule<Int_>
54+
*/
55+
new class implements Rule {
56+
57+
public function getNodeType(): string
58+
{
59+
return Int_::class;
60+
}
61+
62+
/**
63+
* @param Int_ $node
64+
*/
65+
public function processNode(Node $node, Scope $scope): array
66+
{
67+
return [
68+
RuleErrorBuilder::message('Error from Int_ Rule.')->identifier('CompositeRuleInt')->build(),
69+
];
70+
}
71+
72+
},
73+
]);
74+
}
75+
76+
public function testRule(): void
77+
{
78+
$this->analyse([__DIR__ . '/data/composite-rule.php'], [
79+
[
80+
'Error from String_ Rule.',
81+
6,
82+
],
83+
[
84+
'Error from Int_ Rule.',
85+
7,
86+
],
87+
[
88+
'Error from Int_ Rule.',
89+
9,
90+
],
91+
[
92+
'Error from Int_ Rule.',
93+
13,
94+
],
95+
]);
96+
}
97+
98+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace CompositeRule;
4+
5+
function doFoo() {
6+
echo "hi";
7+
$x = 1;
8+
doBar();
9+
$x = 2;
10+
}
11+
12+
function doBar() {
13+
echo "123";
14+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /