Passed
Push — master ( bae44d...d7f6ab )
by William
02:55 queued 11s
created

ExpressionArray::parse()   D

Complexity

Conditions 21
Paths 48

Size

Total Lines 88
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 21

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 21
eloc 40
nc 48
nop 3
dl 0
loc 88
rs 4.1666
c 1
b 0
f 0
ccs 39
cts 39
cp 1
crap 21

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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