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

GroupKeywords   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 29
dl 0
loc 79
ccs 28
cts 28
cp 1
rs 10
c 0
b 0
f 0
wmc 14

2 Methods

Rating   Name   Duplication   Size   Complexity  
C parse() 0 64 13
A buildAll() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpMyAdmin\SqlParser\Parsers;
6
7
use PhpMyAdmin\SqlParser\Components\GroupKeyword;
8
use PhpMyAdmin\SqlParser\Parseable;
9
use PhpMyAdmin\SqlParser\Parser;
10
use PhpMyAdmin\SqlParser\TokensList;
11
use PhpMyAdmin\SqlParser\TokenType;
12
13
use function implode;
14
15
/**
16
 * `GROUP BY` keyword parser.
17
 */
18
final class GroupKeywords implements Parseable
19
{
20
    /**
21
     * @param Parser               $parser  the parser that serves as context
22
     * @param TokensList           $list    the list of tokens that are being parsed
23
     * @param array<string, mixed> $options parameters for parsing
24
     *
25
     * @return GroupKeyword[]
26
     */
27 38
    public static function parse(Parser $parser, TokensList $list, array $options = []): array
28
    {
29 38
        $ret = [];
30
31 38
        $expr = new GroupKeyword();
32
33
        /**
34
         * The state of the parser.
35
         *
36
         * Below are the states of the parser.
37
         *
38
         *      0 --------------------[ expression ]-------------------> 1
39
         *
40
         *      1 ------------------------[ , ]------------------------> 0
41
         *      1 -------------------[ ASC / DESC ]--------------------> 1
42
         */
43 38
        $state = 0;
44
45 38
        for (; $list->idx < $list->count; ++$list->idx) {
46
            /**
47
             * Token parsed at this moment.
48
             */
49 38
            $token = $list->tokens[$list->idx];
50
51
            // End of statement.
52 38
            if ($token->type === TokenType::Delimiter) {
53 16
                break;
54
            }
55
56
            // Skipping whitespaces and comments.
57 38
            if (($token->type === TokenType::Whitespace) || ($token->type === TokenType::Comment)) {
58 38
                continue;
59
            }
60
61 38
            if ($state === 0) {
62 38
                $expr->expr = Expressions::parse($parser, $list);
63 38
                $state = 1;
64
            } else {
65
                if (
66 30
                    ($token->type === TokenType::Keyword)
67 30
                    && (($token->keyword === 'ASC') || ($token->keyword === 'DESC'))
68
                ) {
69 2
                    $expr->type = $token->keyword;
70 30
                } elseif (($token->type === TokenType::Operator) && ($token->value === ',')) {
71 14
                    if (! empty($expr->expr)) {
72 14
                        $ret[] = $expr;
73
                    }
74
75 14
                    $expr = new GroupKeyword();
76 14
                    $state = 0;
77
                } else {
78 24
                    break;
79
                }
80
            }
81
        }
82
83
        // Last iteration was not processed.
84 38
        if (! empty($expr->expr)) {
85 38
            $ret[] = $expr;
86
        }
87
88 38
        --$list->idx;
89
90 38
        return $ret;
91
    }
92
93
    /** @param GroupKeyword[] $component the component to be built */
94 32
    public static function buildAll(array $component): string
95
    {
96 32
        return implode(', ', $component);
97
    }
98
}
99