Completed
Push — master ( 368282...c4d7dc )
by Gytis
03:56
created

CompositeCodeElementSniff::run()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 2
dl 0
loc 8
ccs 0
cts 6
cp 0
crap 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Gskema\TypeSniff\Sniffs;
4
5
use PHP_CodeSniffer\Files\File;
6
use Gskema\TypeSniff\Core\CodeElement\CodeElementDetector;
7
use Gskema\TypeSniff\Sniffs\CodeElement\CodeElementSniffInterface;
8
use Gskema\TypeSniff\Sniffs\CodeElement\FqcnConstSniff;
9
use Gskema\TypeSniff\Sniffs\CodeElement\FqcnMethodSniff;
10
use Gskema\TypeSniff\Sniffs\CodeElement\FqcnPropSniff;
11
12
class CompositeCodeElementSniff extends AbstractConfigurableSniff
13
{
14
    /** @var bool */
15
    protected $useReflection = false;
16
17
    /** @var CodeElementSniffInterface[][] */
18
    protected $sniffs = [];
19
20
    /**
21
     * @inheritDoc
22
     */
23
    protected function configure(array $config): void
24
    {
25
        // 1. CompositeCodeElementSniff configuration
26
        $this->useReflection = $config['useReflection'] ?? false;
27
28
        // 2. CodeElementSniff(s) configuration
29
        // Default sniffs. They can be removed by specifying <property name="FqcnMethodSniff.enabled" value="false"/>
30
        $config['sniffs'][] = FqcnMethodSniff::class;
31
        $config['sniffs'][] = FqcnPropSniff::class;
32
        $config['sniffs'][] = FqcnConstSniff::class;
33
34
        // CodeElementSniff(s) are saved by their short name, meaning you can't have 2 instances of same sniff.
35
        $rawSniffs = [];
36
        foreach ($config['sniffs'] as $class) {
37
            $bits = explode('\\', $class);
38
            $shortClass = end($bits);
39
            if (!isset($rawSniffs[$shortClass])) {
40
                $rawSniffs[$shortClass] = ['class' => $class, 'config' => []];
41
            }
42
        }
43
44
        // Property keys for CodeElementSniff(s) are applied by the short class name.
45
        // E.g. FqcnMethodSniff.usefulTags
46
        foreach ($config as $key => $val) {
47
            if ('sniffs'!== $key && false !== strpos($key, '.')) {
48
                [$shortClass, $cfgKey] = explode('.', $key, 2);
49
                if (isset($rawSniffs[$shortClass])) {
50
                    $rawSniffs[$shortClass]['config'][$cfgKey] = $val;
51
                }
52
            }
53
        }
54
55
        foreach ($rawSniffs as $rawSniff) {
56
            $enabled = $rawSniff['enabled'] ?? true;
57
            if (!$enabled) {
58
                continue;
59
            }
60
            /** @var CodeElementSniffInterface $sniff */
61
            $sniff = new $rawSniff['class'];
62
            $sniff->configure($rawSniff['config']);
63
64
            $codeElementClasses = $sniff->register();
65
            foreach ($codeElementClasses as $codeElementClass) {
66
                $this->sniffs[$codeElementClass][] = $sniff;
67
            }
68
        }
69
    }
70
71
    /**
72
     * @inheritDoc
73
     */
74 10
    public function register()
75
    {
76
        return [
77 10
            T_OPEN_TAG,
78
        ];
79
    }
80
81
    /**
82
     * @inheritDoc
83
     */
84
    protected function run(File $file, int $openTagPtr): void
85
    {
86
        $elements = CodeElementDetector::detectFromTokens($file, $this->useReflection);
87
88
        foreach ($elements as $element) {
89
            $className = get_class($element);
90
            foreach ($this->sniffs[$className] ?? [] as $sniff) {
91
                $sniff->process($file, $element);
92
            }
93
        }
94
    }
95
}
96