Passed
Push — master ( 6c3f09...c54108 )
by William
03:43
created

Array2d   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 107
Duplicated Lines 0 %

Test Coverage

Coverage 95.24%

Importance

Changes 0
Metric Value
eloc 37
dl 0
loc 107
ccs 40
cts 42
cp 0.9524
rs 10
c 0
b 0
f 0
wmc 16

3 Methods

Rating   Name   Duplication   Size   Complexity  
C parse() 0 84 14
A build() 0 3 1
A __toString() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpMyAdmin\SqlParser\Components;
6
7
use PhpMyAdmin\SqlParser\Component;
8
use PhpMyAdmin\SqlParser\Parser;
9
use PhpMyAdmin\SqlParser\Token;
10
use PhpMyAdmin\SqlParser\TokensList;
11
use PhpMyAdmin\SqlParser\Translator;
12
13
use function count;
14
use function sprintf;
15
16
/**
17
 * `VALUES` keyword parser.
18
 */
19
final class Array2d implements Component
20
{
21
    /**
22
     * @param Parser               $parser  the parser that serves as context
23
     * @param TokensList           $list    the list of tokens that are being parsed
24
     * @param array<string, mixed> $options parameters for parsing
25
     *
26
     * @return ArrayObj[]
27
     */
28 76
    public static function parse(Parser $parser, TokensList $list, array $options = [])
29
    {
30 76
        $ret = [];
31
32
        /**
33
         * The number of values in each set.
34
         *
35
         * @var int
36
         */
37 76
        $count = -1;
38
39
        /**
40
         * The state of the parser.
41
         *
42
         * Below are the states of the parser.
43
         *
44
         *      0 ----------------------[ array ]----------------------> 1
45
         *
46
         *      1 ------------------------[ , ]------------------------> 0
47
         *      1 -----------------------[ else ]----------------------> (END)
48
         *
49
         * @var int
50
         */
51 76
        $state = 0;
52
53 76
        for (; $list->idx < $list->count; ++$list->idx) {
54
            /**
55
             * Token parsed at this moment.
56
             */
57 76
            $token = $list->tokens[$list->idx];
58
59
            // End of statement.
60 76
            if ($token->type === Token::TYPE_DELIMITER) {
61 28
                break;
62
            }
63
64
            // Skipping whitespaces and comments.
65 76
            if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) {
66 68
                continue;
67
            }
68
69
            // No keyword is expected.
70 76
            if (($token->type === Token::TYPE_KEYWORD) && ($token->flags & Token::FLAG_KEYWORD_RESERVED)) {
71 42
                break;
72
            }
73
74 74
            if ($state === 0) {
75 74
                if ($token->value !== '(') {
76 2
                    break;
77
                }
78
79 72
                $arr = ArrayObj::parse($parser, $list, $options);
80 72
                $arrCount = count($arr->values);
81 72
                if ($count === -1) {
82 72
                    $count = $arrCount;
83 10
                } elseif ($arrCount !== $count) {
84 2
                    $parser->error(
85 2
                        sprintf(
86 2
                            Translator::gettext('%1$d values were expected, but found %2$d.'),
87 2
                            $count,
88 2
                            $arrCount
89 2
                        ),
90 2
                        $token
91 2
                    );
92
                }
93
94 72
                $ret[] = $arr;
95 72
                $state = 1;
96 18
            } elseif ($state === 1) {
97 18
                if ($token->value !== ',') {
98 6
                    break;
99
                }
100
101 12
                $state = 0;
102
            }
103
        }
104
105 76
        if ($state === 0) {
0 ignored issues
show
introduced by
The condition $state === 0 is always true.
Loading history...
106 6
            $parser->error('An opening bracket followed by a set of values was expected.', $list->tokens[$list->idx]);
107
        }
108
109 76
        --$list->idx;
110
111 76
        return $ret;
112
    }
113
114
    /**
115
     * @param ArrayObj[]           $component the component to be built
116
     * @param array<string, mixed> $options   parameters for building
117
     */
118 6
    public static function build($component, array $options = []): string
119
    {
120 6
        return ArrayObj::build($component);
121
    }
122
123
    public function __toString(): string
124
    {
125
        return static::build($this);
0 ignored issues
show
Bug introduced by
$this of type PhpMyAdmin\SqlParser\Components\Array2d is incompatible with the type PhpMyAdmin\SqlParser\Components\ArrayObj[] expected by parameter $component of PhpMyAdmin\SqlParser\Components\Array2d::build(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

125
        return static::build(/** @scrutinizer ignore-type */ $this);
Loading history...
126
    }
127
}
128