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