MatcherSelector::setMatcher()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Remorhaz\Lexer\Runtime\Token;
6
7
use function array_shift;
8
use function array_unshift;
9
use function count;
10
use function is_string;
11
12
final class MatcherSelector implements MatcherSelectorInterface
13
{
14
15
    /**
16
     * @var MatcherInterface[]
17
     * @psalm-var array<string,MatcherInterface>
18
     */
19
    private $matchers = [];
20
21
    /**
22
     * @var string[]
23
     * @psalm-var array<int,string>
24
     */
25
    private $matcherKeys = [];
26
27
    /**
28
     * @param MatcherInterface[] $matchers
29
     * @psalm-param array<array-key, MatcherInterface> $matchers
30
     * @param string|null        $startMatcherKey
31
     */
32 8
    public function __construct(array $matchers, ?string $startMatcherKey = null)
33
    {
34 8
        if (empty($matchers)) {
35 1
            throw new Exception\MatchersNotFoundException();
36
        }
37 7
        foreach ($matchers as $matcherKey => $matcher) {
38 7
            if (!is_string($matcherKey)) {
39 1
                throw new Exception\InvalidMatcherKeyException($startMatcherKey);
40
            }
41 6
            $this->matchers[$matcherKey] = $matcher;
42 6
            if (!isset($startMatcherKey)) {
43 1
                $startMatcherKey = $matcherKey;
44
            }
45
        }
46
47 6
        $this->setMatcher($startMatcherKey);
0 ignored issues
show
Bug introduced by
It seems like $startMatcherKey can also be of type null; however, parameter $matcherKey of Remorhaz\Lexer\Runtime\T...rSelector::setMatcher() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

47
        $this->setMatcher(/** @scrutinizer ignore-type */ $startMatcherKey);
Loading history...
48 6
    }
49
50
    /**
51
     * @param string $matcherKey
52
     * @return MatcherInterface
53
     * @psalm-pure
54
     */
55 4
    private function getMatcherByKey(string $matcherKey): MatcherInterface
56
    {
57 4
        if (isset($this->matchers[$matcherKey])) {
58 4
            return $this->matchers[$matcherKey];
59
        }
60
        // @codeCoverageIgnoreStart
61
        throw new Exception\MatcherNotFoundException($matcherKey);
62
        // @codeCoverageIgnoreEnd
63
    }
64
65
    /**
66
     * {@inheritDoc}
67
     *
68
     * @return MatcherInterface
69
     * @psalm-pure
70
     */
71 4
    public function getMatcher(): MatcherInterface
72
    {
73 4
        if (isset($this->matcherKeys[0])) {
74 4
            return $this->getMatcherByKey($this->matcherKeys[0]);
75
        }
76
77
        // @codeCoverageIgnoreStart
78
        throw new Exception\MatcherKeyNotFoundException();
79
        // @codeCoverageIgnoreEnd
80
    }
81
82
    /**
83
     * {@inheritDoc}
84
     *
85
     * @param string $matcherKey
86
     */
87 6
    public function setMatcher(string $matcherKey): void
88
    {
89 6
        if (!isset($this->matchers[$matcherKey])) {
90 1
            throw new Exception\MatcherNotFoundException($matcherKey);
91
        }
92 6
        array_unshift($this->matcherKeys, $matcherKey);
93 6
    }
94
95
    /**
96
     * {@inheritDoc}
97
     */
98 2
    public function restoreMatcher(): void
99
    {
100 2
        if (count($this->matcherKeys) == 1) {
101 1
            throw new Exception\MatcherNotRestoredException();
102
        }
103 1
        array_shift($this->matcherKeys);
104 1
    }
105
}
106