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

IntoKeywords::parse()   D

Complexity

Conditions 23
Paths 9

Size

Total Lines 94
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 49
CRAP Score 23

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 23
eloc 47
nc 9
nop 3
dl 0
loc 94
ccs 49
cts 49
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\Components\IntoKeyword;
8
use PhpMyAdmin\SqlParser\Parseable;
9
use PhpMyAdmin\SqlParser\Parser;
10
use PhpMyAdmin\SqlParser\Token;
11
use PhpMyAdmin\SqlParser\TokensList;
12
use PhpMyAdmin\SqlParser\TokenType;
13
14
/**
15
 * `INTO` keyword parser.
16
 */
17
final class IntoKeywords implements Parseable
18
{
19
    /**
20
     * @param Parser               $parser  the parser that serves as context
21
     * @param TokensList           $list    the list of tokens that are being parsed
22
     * @param array<string, mixed> $options parameters for parsing
23
     */
24 106
    public static function parse(Parser $parser, TokensList $list, array $options = []): IntoKeyword
25
    {
26 106
        $ret = new IntoKeyword();
27
28
        /**
29
         * The state of the parser.
30
         *
31
         * Below are the states of the parser.
32
         *
33
         *      0 -----------------------[ name ]----------------------> 1
34
         *      0 ---------------------[ OUTFILE ]---------------------> 2
35
         *
36
         *      1 ------------------------[ ( ]------------------------> (END)
37
         *
38
         *      2 ---------------------[ filename ]--------------------> 1
39
         */
40 106
        $state = 0;
41
42 106
        for (; $list->idx < $list->count; ++$list->idx) {
43
            /**
44
             * Token parsed at this moment.
45
             */
46 106
            $token = $list->tokens[$list->idx];
47
48
            // End of statement.
49 106
            if ($token->type === TokenType::Delimiter) {
50 14
                break;
51
            }
52
53
            // Skipping whitespaces and comments.
54 106
            if (($token->type === TokenType::Whitespace) || ($token->type === TokenType::Comment)) {
55 100
                continue;
56
            }
57
58 106
            if (($token->type === TokenType::Keyword) && ($token->flags & Token::FLAG_KEYWORD_RESERVED)) {
59 58
                if (($state === 0) && ($token->keyword === 'OUTFILE')) {
60 22
                    $ret->type = 'OUTFILE';
61 22
                    $state = 2;
62 22
                    continue;
63
                }
64
65
                // No other keyword is expected except for $state = 4, which expects `LINES`
66 48
                if ($state !== 4) {
67 44
                    break;
68
                }
69
            }
70
71 104
            if ($state === 0) {
72
                if (
73 84
                    (isset($options['fromInsert'])
74 48
                    && $options['fromInsert'])
75 84
                    || (isset($options['fromReplace'])
76 84
                    && $options['fromReplace'])
77
                ) {
78 80
                    $ret->dest = Expressions::parse(
79 80
                        $parser,
80 80
                        $list,
81 80
                        [
82 80
                            'parseField' => 'table',
83 80
                            'breakOnAlias' => true,
84 80
                        ],
85 80
                    );
86
                } else {
87 4
                    $ret->values = ExpressionArray::parse($parser, $list);
88
                }
89
90 84
                $state = 1;
91 68
            } elseif ($state === 1) {
92 48
                if (($token->type === TokenType::Operator) && ($token->value === '(')) {
93 44
                    $ret->columns = ArrayObjs::parse($parser, $list)->values;
94 44
                    ++$list->idx;
95
                }
96
97 48
                break;
98 20
            } elseif ($state === 2) {
99 20
                $ret->dest = $token->value;
100
101 20
                $state = 3;
102 10
            } elseif ($state === 3) {
103 10
                $ret->parseFileOptions($parser, $list, $token->keyword);
104 10
                $state = 4;
105 10
            } elseif ($state === 4) {
106 10
                if ($token->type === TokenType::Keyword && $token->keyword !== 'LINES') {
107 4
                    break;
108
                }
109
110 6
                $ret->parseFileOptions($parser, $list, $token->keyword);
111 6
                $state = 5;
112
            }
113
        }
114
115 106
        --$list->idx;
116
117 106
        return $ret;
118
    }
119
}
120