Test Failed
Pull Request — master (#291)
by William
12:25
created

ExpressionArray::build()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.9666
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 2
1
<?php
2
3
/**
4
 * Parses a list of expressions delimited by a comma.
5
 */
6
7
namespace PhpMyAdmin\SqlParser\Components;
8
9
use PhpMyAdmin\SqlParser\Component;
10
use PhpMyAdmin\SqlParser\Parser;
11
use PhpMyAdmin\SqlParser\Token;
12
use PhpMyAdmin\SqlParser\TokensList;
13
14
/**
15
 * Parses a list of expressions delimited by a comma.
16
 *
17
 * @category   Keywords
18
 *
19
 * @license    https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
20
 */
21
class ExpressionArray extends Component
22
{
23
    /**
24
     * @param Parser     $parser  the parser that serves as context
25
     * @param TokensList $list    the list of tokens that are being parsed
26
     * @param array      $options parameters for parsing
27
     *
28
     * @return Expression[]
29
     * @throws \PhpMyAdmin\SqlParser\Exceptions\ParserException
30
     */
31 179
    public static function parse(Parser $parser, TokensList $list, array $options = array())
32
    {
33 179
        $ret = array();
34
35
        /**
36
         * The state of the parser.
37
         *
38
         * Below are the states of the parser.
39
         *
40
         *      0 ----------------------[ array ]---------------------> 1
41
         *
42
         *      1 ------------------------[ , ]------------------------> 0
43
         *      1 -----------------------[ else ]----------------------> (END)
44
         *
45
         * @var int
46
         */
47 179
        $state = 0;
48
49 179
        for (; $list->idx < $list->count; ++$list->idx) {
50
            /**
51
             * Token parsed at this moment.
52
             *
53
             * @var Token
54
             */
55 179
            $token = $list->tokens[$list->idx];
56
57
            // End of statement.
58 179
            if ($token->type === Token::TYPE_DELIMITER) {
59 75
                break;
60
            }
61
62
            // Skipping whitespaces and comments.
63 179
            if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) {
64 145
                continue;
65
            }
66
67 179
            if (($token->type === Token::TYPE_KEYWORD)
68 179
                && ($token->flags & Token::FLAG_KEYWORD_RESERVED)
69 179
                && ((~$token->flags & Token::FLAG_KEYWORD_FUNCTION))
70 179
                && ($token->value !== 'DUAL')
71 179
                && ($token->value !== 'NULL')
72 179
                && ($token->value !== 'CASE')
73
            ) {
74
                // No keyword is expected.
75 148
                break;
76
            }
77
78 179
            if ($state === 0) {
79 179
                if ($token->type === Token::TYPE_KEYWORD
80 179
                    && $token->value === 'CASE'
81
                ) {
82 18
                    $expr = CaseExpression::parse($parser, $list, $options);
83
                } else {
84 178
                    $expr = Expression::parse($parser, $list, $options);
85
                }
86
87 179
                if ($expr === null) {
88
                    break;
89
                }
90 179
                $ret[] = $expr;
91 179
                $state = 1;
92 74
            } elseif ($state === 1) {
93 74
                if ($token->value === ',') {
94 71
                    $state = 0;
95
                } else {
96 8
                    break;
97
                }
98
            }
99
        }
100
101 179
        if ($state === 0) {
102
            $parser->error(
103
                'An expression was expected.',
104
                $list->tokens[$list->idx]
105
            );
106
        }
107
108 179
        --$list->idx;
109
110
        // TODO verify #156 Hotfix
111 179
        if (is_array($ret)) {
112 179
            $expr = $ret[count($ret) - 1]->expr;
113 179
            if (preg_match('/\s*--\s.*$/', $expr, $matches)) {
114
                $found = $matches[0];
115
                $ret[count($ret) - 1]->expr = substr($expr, 0, strlen($expr) - strlen($found));
116
            }
117
        }
118
119 179
        return $ret;
120
    }
121
122
    /**
123
     * @param Expression[] $component the component to be built
124
     * @param array        $options   parameters for building
125
     *
126
     * @return string
127
     */
128 26
    public static function build($component, array $options = array())
129
    {
130 26
        $ret = array();
131 26
        foreach ($component as $frag) {
132 26
            $ret[] = $frag::build($frag);
133
        }
134
135 26
        return implode(', ', $ret);
136
    }
137
}
138