Passed
Push — master ( 0efc01...ef206b )
by Maurício
02:53
created

ExpressionArray::parse()   D

Complexity

Conditions 21
Paths 48

Size

Total Lines 88
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 37
CRAP Score 21.0595

Importance

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

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 780
    public static function parse(Parser $parser, TokensList $list, array $options = [])
38
    {
39 780
        $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 780
        $state = 0;
54
55 780
        for (; $list->idx < $list->count; ++$list->idx) {
56
            /**
57
             * Token parsed at this moment.
58
             *
59
             * @var Token
60
             */
61 780
            $token = $list->tokens[$list->idx];
62
63
            // End of statement.
64 780
            if ($token->type === Token::TYPE_DELIMITER) {
65 348
                break;
66
            }
67
68
            // Skipping whitespaces and comments.
69 768
            if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) {
70 600
                continue;
71
            }
72
73
            if (
74 768
                ($token->type === Token::TYPE_KEYWORD)
75 768
                && ($token->flags & Token::FLAG_KEYWORD_RESERVED)
76 768
                && ((~$token->flags & Token::FLAG_KEYWORD_FUNCTION))
77 768
                && ($token->value !== 'DUAL')
78 768
                && ($token->value !== 'NULL')
79 768
                && ($token->value !== 'CASE')
80
            ) {
81
                // No keyword is expected.
82 632
                break;
83
            }
84
85 752
            if ($state === 0) {
86 752
                if ($token->type === Token::TYPE_KEYWORD && $token->value === 'CASE') {
87 72
                    $expr = CaseExpression::parse($parser, $list, $options);
88
                } else {
89 748
                    $expr = Expression::parse($parser, $list, $options);
90
                }
91
92 752
                if ($expr === null) {
93 4
                    break;
94
                }
95
96 748
                $ret[] = $expr;
97 748
                $state = 1;
98 312
            } elseif ($state === 1) {
99 312
                if ($token->value !== ',') {
100 32
                    break;
101
                }
102
103 300
                $state = 0;
104
            }
105
        }
106
107 780
        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 780
        --$list->idx;
112
113 780
        if (is_array($ret)) {
0 ignored issues
show
introduced by
The condition is_array($ret) is always true.
Loading history...
114 780
            $retIndex = count($ret) - 1;
115 780
            if (isset($ret[$retIndex])) {
116 748
                $expr = $ret[$retIndex]->expr;
117 748
                if (preg_match('/\s*--\s.*$/', $expr, $matches)) {
118
                    $found = $matches[0];
119
                    $ret[$retIndex]->expr = substr($expr, 0, strlen($expr) - strlen($found));
120
                }
121
            }
122
        }
123
124 780
        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 104
    public static function build($component, array $options = [])
134
    {
135 104
        $ret = [];
136 104
        foreach ($component as $frag) {
137 104
            $ret[] = $frag::build($frag);
138
        }
139
140 104
        return implode(', ', $ret);
141
    }
142
}
143