Completed
Push — master ( d366a2...854d4a )
by brian
01:55
created

VersionRangeParser::clusterTokens()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 12
cts 12
cp 1
rs 8.9197
c 0
b 0
f 0
cc 4
eloc 13
nc 6
nop 1
crap 4
1
<?php
2
3
/**
4
 * @copyright   (c) 2014-2017 brian ridley
5
 * @author      brian ridley <[email protected]>
6
 * @license     http://opensource.org/licenses/MIT MIT
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ptlis\SemanticVersion\Parse;
13
14
use ptlis\SemanticVersion\Parse\RangeMatcher\RangeParserInterface;
15
use ptlis\SemanticVersion\VersionRange\VersionRangeInterface;
16
17
/**
18
 * Parser accepting array of tokens and returning an array of comparators & versions.
19
 */
20
final class VersionRangeParser
21
{
22
    use ChunkBySeparator;
23
24
    /** @var LogicalOperatorProcessor */
25
    private $logicalOperatorProcessor;
26
27
    /** @var RangeParserInterface[] */
28
    private $rangeParserList;
29
30
    /** @var string[] Array of tokens representing logical operators */
31
    private $operatorTokenList = [
32
        Token::LOGICAL_AND,
33
        Token::LOGICAL_OR
34
    ];
35
36
37
    /**
38
     * Constructor
39
     *
40
     * @param LogicalOperatorProcessor $logicalOperatorProcessor
41
     */
42 32
    public function __construct(
43
        LogicalOperatorProcessor $logicalOperatorProcessor,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $logicalOperatorProcessor exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
44
        array $rangeParserList
45
    ) {
46 32
        $this->logicalOperatorProcessor = $logicalOperatorProcessor;
47 32
        $this->rangeParserList = $rangeParserList;
48 32
    }
49
50
    /**
51
     * Parse a version range.
52
     *
53
     * @param Token[] $tokenList
54
     *
55
     * @return VersionRangeInterface
56
     */
57 32
    public function parseRange(array $tokenList)
58
    {
59 32
        $realResultList = [];
60 32
        $tokenClusterList = $this->chunk($tokenList, $this->operatorTokenList, true);
61 32
        foreach ($tokenClusterList as $tokenCluster) {
62 32
            $parsed = $this->attemptParse($tokenCluster);
63
64 32
            if (is_null($parsed)) {
65 7
                if (in_array($tokenCluster[0]->getType(), $this->operatorTokenList)) {
66 6
                    $realResultList[] = $tokenCluster[0];
67
                } else {
68 7
                    throw new \RuntimeException('Unable to parse version string');
69
                }
70
            } else {
71 31
                $realResultList[] = $parsed;
72
            }
73
        }
74
75 31
        return $this->logicalOperatorProcessor->run($realResultList);
76
    }
77
78
    /**
79
     * Attempt to parse the token list as a version range into an object implementing VersionRangeInterface
80
     *
81
     * Iterates through the provided range parsers checking to see if they can parse the token list. If they can then we
82
     * call the parse method and return a version range object, otherwise return null.
83
     *
84
     * @param Token[] $tokenList
85
     *
86
     * @return VersionRangeInterface|null
87
     */
88 32
    private function attemptParse(array $tokenList)
89
    {
90 32
        $parsed = null;
91 32
        foreach ($this->rangeParserList as $rangeParser) {
92 32
            if ($rangeParser->canParse($tokenList)) {
93 31
                $parsed = $rangeParser->parse($tokenList);
94 32
                break;
95
            }
96
        }
97
98 32
        return $parsed;
99
    }
100
}
101