1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Testing;
4:
5: use PhpParser\Node;
6: use PHPStan\Analyser\CollectedDataEmitter;
7: use PHPStan\Analyser\NodeCallbackInvoker;
8: use PHPStan\Analyser\Scope;
9: use PHPStan\Rules\DirectRegistry;
10: use PHPStan\Rules\Rule;
11: use function get_class;
12:
13: /**
14: * Allows testing of rules which delegate work to NodeCallbackInvoker.
15: *
16: * @implements Rule<Node>
17: *
18: * @api
19: */
20: final class CompositeRule implements Rule
21: {
22:
23: private DirectRegistry $registry;
24:
25: /**
26: * @template T of Node
27: * @param array<Rule<T>> $rules
28: *
29: * @api
30: */
31: public function __construct(array $rules)
32: {
33: $this->registry = new DirectRegistry($rules);
34: }
35:
36: public function getNodeType(): string
37: {
38: return Node::class;
39: }
40:
41: public function processNode(Node $node, Scope&NodeCallbackInvoker&CollectedDataEmitter $scope): array
42: {
43: $errors = [];
44:
45: $nodeType = get_class($node);
46: foreach ($this->registry->getRules($nodeType) as $rule) {
47: foreach ($rule->processNode($node, $scope) as $error) {
48: $errors[] = $error;
49: }
50: }
51:
52: return $errors;
53: }
54:
55: }
56: