Completed
Push — master ( d291df...b0e701 )
by brian
01:56
created

src/Parse/VersionRangeParser.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
 * @todo Correctly validate versions
21
 */
22
final class VersionRangeParser
23
{
24
    /** @var RangeParserInterface[] */
25
    private $rangeParserList;
26
27
28
    /**
29
     * Constructor.
30
     *
31
     * @param RangeParserInterface[] $rangeParserList
32
     */
33 32
    public function __construct(array $rangeParserList)
34
    {
35 32
        $this->rangeParserList = $rangeParserList;
36 32
    }
37
38
    /**
39
     * Parse a version range.
40
     *
41
     * @param Token[] $tokenList
42
     *
43
     * @return VersionRangeInterface
44
     */
45 32
    public function parseRange(array $tokenList)
46
    {
47 32
        $clusteredTokenList = $this->clusterTokens($tokenList);
48
49
        $operatorList = [
50 32
            Token::LOGICAL_AND,
51
            Token::LOGICAL_OR
52
        ];
53
54 32
        $realResultList = [];
55 32
        foreach ($clusteredTokenList as $clusteredTokens) {
56
57 32
            $parsed = null;
58 32
            foreach ($this->rangeParserList as $rangeParser) {
59 32
                if ($rangeParser->canParse($clusteredTokens)) {
60 31
                    $parsed = $rangeParser->parse($clusteredTokens);
61 32
                    break;
62
                }
63
            }
64
65 32
            if (is_null($parsed)) {
66
67 7
                if (in_array($clusteredTokens[0]->getType(), $operatorList)) {
68 6
                    $realResultList[] = $clusteredTokens[0];
69
70
1 ignored issue
show
Blank line found at end of control structure
Loading history...
71
                } else {
72 7
                    throw new \RuntimeException('Unable to parse version string');
73
                }
74
            } else {
75 31
                $realResultList[] = $parsed;
76
            }
77
1 ignored issue
show
Blank line found at end of control structure
Loading history...
78
        }
79
80 31
        $buildRange = new LogicalOperatorProcessor();
81
82 31
        return $buildRange->run($realResultList);
83
    }
84
85
    /**
86
     * Clusters the tokens, breaking them up upon finding a logical AND / OR.
87
     *
88
     * @param Token[] $tokenList
89
     *
90
     * @return Token[][] $tokenList
91
     */
92 32
    private function clusterTokens(array $tokenList)
93
    {
94
        $comparatorTokenList = [
95 32
            Token::LOGICAL_AND,
96
            Token::LOGICAL_OR
97
        ];
98
99 32
        $tokenClusterList = [];
100
101
        // Stores tokens not yet parcelled out
102 32
        $tokenAccumulator = [];
103 32
        $tokenListCount = count($tokenList);
104 32
        for ($i = 0; $i < $tokenListCount; $i++) {
105 32
            $currentToken = $tokenList[$i];
106
107 32
            if (in_array($currentToken->getType(), $comparatorTokenList)) {
108 6
                $tokenClusterList[] = $tokenAccumulator;
109 6
                $tokenClusterList[] = [$currentToken];
110 6
                $tokenAccumulator = [];
111
1 ignored issue
show
Blank line found at end of control structure
Loading history...
112
            } else {
113 32
                $tokenAccumulator[] = $currentToken;
114
            }
115
        }
116
117
        // Add any remaining tokens
118 32
        if (count($tokenAccumulator)) {
119 32
            $tokenClusterList[] = $tokenAccumulator;
120
        }
121
122 32
        return $tokenClusterList;
123
    }
124
}
125