Completed
Push — master ( 578d3a...04a929 )
by Maurício
34s queued 14s
created

ExpressionArray::parse()   D

Complexity

Conditions 21
Paths 36

Size

Total Lines 82
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 21

Importance

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

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
declare(strict_types=1);
4
5
namespace PhpMyAdmin\SqlParser\Components\Parsers;
6
7
use PhpMyAdmin\SqlParser\Components\CaseExpression;
8
use PhpMyAdmin\SqlParser\Components\Expression;
9
use PhpMyAdmin\SqlParser\Exceptions\ParserException;
10
use PhpMyAdmin\SqlParser\Parseable;
11
use PhpMyAdmin\SqlParser\Parser;
12
use PhpMyAdmin\SqlParser\Token;
13
use PhpMyAdmin\SqlParser\TokensList;
14
use PhpMyAdmin\SqlParser\TokenType;
15
16
use function count;
17
use function implode;
18
use function preg_match;
19
use function strlen;
20
use function substr;
21
22
/**
23
 * Parses a list of expressions delimited by a comma.
24
 */
25
final class ExpressionArray implements Parseable
26
{
27
    /**
28
     * @param Parser               $parser  the parser that serves as context
29
     * @param TokensList           $list    the list of tokens that are being parsed
30
     * @param array<string, mixed> $options parameters for parsing
31
     *
32
     * @return Expression[]
33
     *
34
     * @throws ParserException
35
     */
36 522
    public static function parse(Parser $parser, TokensList $list, array $options = []): array
37
    {
38 522
        $ret = [];
39
40
        /**
41
         * The state of the parser.
42
         *
43
         * Below are the states of the parser.
44
         *
45
         *      0 ----------------------[ array ]---------------------> 1
46
         *
47
         *      1 ------------------------[ , ]------------------------> 0
48
         *      1 -----------------------[ else ]----------------------> (END)
49
         */
50 522
        $state = 0;
51
52 522
        for (; $list->idx < $list->count; ++$list->idx) {
53
            /**
54
             * Token parsed at this moment.
55
             */
56 522
            $token = $list->tokens[$list->idx];
57
58
            // End of statement.
59 522
            if ($token->type === TokenType::Delimiter) {
60 234
                break;
61
            }
62
63
            // Skipping whitespaces and comments.
64 516
            if (($token->type === TokenType::Whitespace) || ($token->type === TokenType::Comment)) {
65 392
                continue;
66
            }
67
68
            if (
69 516
                ($token->type === TokenType::Keyword)
70 516
                && ($token->flags & Token::FLAG_KEYWORD_RESERVED)
71 516
                && ((~$token->flags & Token::FLAG_KEYWORD_FUNCTION))
72 516
                && ($token->value !== 'DUAL')
73 516
                && ($token->value !== 'NULL')
74 516
                && ($token->value !== 'CASE')
75 516
                && ($token->value !== 'NOT')
76
            ) {
77
                // No keyword is expected.
78 434
                break;
79
            }
80
81 504
            if ($state === 0) {
82 504
                if ($token->type === TokenType::Keyword && $token->value === 'CASE') {
83 38
                    $expr = CaseExpression::parse($parser, $list, $options);
84
                } else {
85 502
                    $expr = Expression::parse($parser, $list, $options);
86
                }
87
88 504
                if ($expr === null) {
89 2
                    break;
90
                }
91
92 502
                $ret[] = $expr;
93 502
                $state = 1;
94 194
            } elseif ($state === 1) {
95 194
                if ($token->value !== ',') {
96 20
                    break;
97
                }
98
99 184
                $state = 0;
100
            }
101
        }
102
103 522
        if ($state === 0) {
0 ignored issues
show
introduced by
The condition $state === 0 is always true.
Loading history...
104 22
            $parser->error('An expression was expected.', $list->tokens[$list->idx]);
105
        }
106
107 522
        --$list->idx;
108 522
        $retIndex = count($ret) - 1;
109 522
        if (isset($ret[$retIndex])) {
110 502
            $expr = $ret[$retIndex]->expr;
111 502
            if (preg_match('/\s*--\s.*$/', $expr, $matches)) {
112 4
                $found = $matches[0];
113 4
                $ret[$retIndex]->expr = substr($expr, 0, strlen($expr) - strlen($found));
114
            }
115
        }
116
117 522
        return $ret;
118
    }
119
120
    /** @param Expression[] $component the component to be built */
121 66
    public static function buildAll(array $component): string
122
    {
123 66
        return implode(', ', $component);
124
    }
125
}
126