Completed
Push — master ( 475c0f...a498f5 )
by brian
03:00
created

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