Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions src/Testing/CompositeRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php declare(strict_types = 1);

namespace PHPStan\Testing;

use PhpParser\Node;
use PHPStan\Analyser\NodeCallbackInvoker;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\DirectRegistry;
use PHPStan\Rules\Rule;
use function get_class;

/**
* Allows testing of rules which delegate work to NodeCallbackInvoker.
*
* @implements Rule<Node>
*
* @api
*/
final class CompositeRule implements Rule
{

private DirectRegistry $registry;

/**
* @param array<Rule<Node>> $rules
*
* @api
*/
public function __construct(array $rules)
{
$this->registry = new DirectRegistry($rules);
}

public function getNodeType(): string
{
return Node::class;
}

public function processNode(Node $node, Scope&NodeCallbackInvoker $scope): array
{
$errors = [];

$nodeType = get_class($node);
foreach ($this->registry->getRules($nodeType) as $rule) {
foreach ($rule->processNode($node, $scope) as $error) {
$errors[] = $error;
}
}

return $errors;
}

}
98 changes: 98 additions & 0 deletions tests/PHPStan/Testing/CompositeRuleTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<?php declare(strict_types = 1);

namespace PHPStan\Testing;

use PhpParser\Node;
use PhpParser\Node\Scalar\Int_;
use PhpParser\Node\Scalar\String_;
use PHPStan\Analyser\NodeCallbackInvoker;
use PHPStan\Analyser\Scope;
use PHPStan\Rules\Rule;
use PHPStan\Rules\RuleErrorBuilder;
use function ctype_digit;

/**
* @extends RuleTestCase<CompositeRule>
*/
final class CompositeRuleTest extends RuleTestCase
{

protected function getRule(): Rule
{
return new CompositeRule([
/**
* @implements Rule<String_>
*/
new class implements Rule {

public function getNodeType(): string
{
return String_::class;
}

/**
* @param String_ $node
*/
public function processNode(Node $node, Scope&NodeCallbackInvoker $scope): array
{
if (ctype_digit($node->value)) {
$scope->invokeNodeCallback(
new Int_((int) $node->value, ['startLine' => $node->getStartLine()]),
);

return [];
}

return [
RuleErrorBuilder::message('Error from String_ Rule.')->identifier('CompositeRuleString')->build(),
];
}

},
/**
* @implements Rule<Int_>
*/
new class implements Rule {

public function getNodeType(): string
{
return Int_::class;
}

/**
* @param Int_ $node
*/
public function processNode(Node $node, Scope $scope): array
{
return [
RuleErrorBuilder::message('Error from Int_ Rule.')->identifier('CompositeRuleInt')->build(),
];
}

},
]);
}

public function testRule(): void
{
$this->analyse([__DIR__ . '/data/composite-rule.php'], [
[
'Error from String_ Rule.',
6,
],
[
'Error from Int_ Rule.',
7,
],
[
'Error from Int_ Rule.',
9,
],
[
'Error from Int_ Rule.',
13,
],
]);
}

}
14 changes: 14 additions & 0 deletions tests/PHPStan/Testing/data/composite-rule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace CompositeRule;

function doFoo() {
echo "hi";
$x = 1;
doBar();
$x = 2;
}

function doBar() {
echo "123";
}
Loading