Passed
Push — master ( b16987...8b6d77 )
by Maurício
03:49 queued 13s
created

ArrayObjs::parse()   D

Complexity

Conditions 23
Paths 20

Size

Total Lines 102
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 47
CRAP Score 23

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 23
eloc 46
nc 20
nop 3
dl 0
loc 102
ccs 47
cts 47
cp 1
crap 23
rs 4.1666
c 1
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\Parsers;
6
7
use PhpMyAdmin\SqlParser\Component;
8
use PhpMyAdmin\SqlParser\Components\ArrayObj;
9
use PhpMyAdmin\SqlParser\Parseable;
10
use PhpMyAdmin\SqlParser\Parser;
11
use PhpMyAdmin\SqlParser\TokensList;
12
use PhpMyAdmin\SqlParser\TokenType;
13
14
use function implode;
15
use function strlen;
16
use function trim;
17
18
/**
19
 * Parses an array.
20
 */
21
final class ArrayObjs implements Parseable
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<string, mixed> $options parameters for parsing
27
     *
28
     * @return ArrayObj|Component[]
29
     */
30 268
    public static function parse(Parser $parser, TokensList $list, array $options = []): ArrayObj|array
31
    {
32 268
        $ret = empty($options['type']) ? new ArrayObj() : [];
33
34
        /**
35
         * The last raw expression.
36
         */
37 268
        $lastRaw = '';
38
39
        /**
40
         * The last value.
41
         */
42 268
        $lastValue = '';
43
44
        /**
45
         * Counts brackets.
46
         */
47 268
        $brackets = 0;
48
49
        /**
50
         * Last separator (bracket or comma).
51
         */
52 268
        $isCommaLast = false;
53
54 268
        for (; $list->idx < $list->count; ++$list->idx) {
55
            /**
56
             * Token parsed at this moment.
57
             */
58 268
            $token = $list->tokens[$list->idx];
59
60
            // End of statement.
61 268
            if ($token->type === TokenType::Delimiter) {
62 4
                if ($brackets > 0) {
63 4
                    $parser->error('A closing bracket was expected.', $token);
64
                }
65
66 4
                break;
67
            }
68
69
            // Skipping whitespaces and comments.
70 268
            if (($token->type === TokenType::Whitespace) || ($token->type === TokenType::Comment)) {
71 106
                $lastRaw .= $token->token;
72 106
                $lastValue = trim($lastValue) . ' ';
73 106
                continue;
74
            }
75
76 268
            if (($brackets === 0) && (($token->type !== TokenType::Operator) || ($token->value !== '('))) {
77 2
                $parser->error('An opening bracket was expected.', $token);
78 2
                break;
79
            }
80
81 266
            if ($token->type === TokenType::Operator) {
82 266
                if ($token->value === '(') {
83 266
                    if (++$brackets === 1) { // 1 is the base level.
84 266
                        continue;
85
                    }
86 264
                } elseif ($token->value === ')') {
87 262
                    if (--$brackets === 0) { // Array ended.
88 262
                        break;
89
                    }
90 118
                } elseif ($token->value === ',') {
91 118
                    if ($brackets === 1) {
92 116
                        $isCommaLast = true;
93 116
                        if (empty($options['type'])) {
94 94
                            $ret->raw[] = trim($lastRaw);
95 94
                            $ret->values[] = trim($lastValue);
96 94
                            $lastRaw = $lastValue = '';
97
                        }
98
99 116
                        continue;
100
                    }
101
                }
102
            }
103
104 252
            if (empty($options['type'])) {
105 240
                $lastRaw .= $token->token;
106 240
                $lastValue .= $token->value;
107
            } else {
108 22
                $ret[] = $options['type']::parse(
109 22
                    $parser,
110 22
                    $list,
111 22
                    empty($options['typeOptions']) ? [] : $options['typeOptions'],
112 22
                );
113
            }
114
        }
115
116
        // Handling last element.
117
        //
118
        // This is treated differently to treat the following cases:
119
        //
120
        //           => []
121
        //      [,]  => ['', '']
122
        //      []   => []
123
        //      [a,] => ['a', '']
124
        //      [a]  => ['a']
125 268
        $lastRaw = trim($lastRaw);
126 268
        if (empty($options['type']) && ((strlen($lastRaw) > 0) || ($isCommaLast))) {
127 240
            $ret->raw[] = $lastRaw;
128 240
            $ret->values[] = trim($lastValue);
129
        }
130
131 268
        return $ret;
132
    }
133
134
    /** @param ArrayObj[] $component the component to be built */
135 12
    public static function buildAll(array $component): string
136
    {
137 12
        return implode(', ', $component);
138
    }
139
}
140