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: * @template T of Node
26: * @param array<Rule<T>> $rules
27: *
28: * @api
29: */
30: public function __construct(array $rules)
31: {
32: $this->registry = new DirectRegistry($rules);
33: }
34:
35: public function getNodeType(): string
36: {
37: return Node::class;
38: }
39:
40: public function processNode(Node $node, Scope&NodeCallbackInvoker $scope): array
41: {
42: $errors = [];
43:
44: $nodeType = get_class($node);
45: foreach ($this->registry->getRules($nodeType) as $rule) {
46: foreach ($rule->processNode($node, $scope) as $error) {
47: $errors[] = $error;
48: }
49: }
50:
51: return $errors;
52: }
53:
54: }
55: