Completed
Push — master ( d70e65...52ffc4 )
by Maurício
21s queued 15s
created

ParameterDefinition::buildAll()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpMyAdmin\SqlParser\Components;
6
7
use PhpMyAdmin\SqlParser\Component;
8
use PhpMyAdmin\SqlParser\Context;
9
use PhpMyAdmin\SqlParser\Parser;
10
use PhpMyAdmin\SqlParser\Token;
11
use PhpMyAdmin\SqlParser\TokensList;
12
13
use function implode;
14
use function trim;
15
16
/**
17
 * The definition of a parameter of a function or procedure.
18
 */
19
final class ParameterDefinition implements Component
20
{
21
    /**
22
     * The name of the new column.
23
     *
24
     * @var string
25
     */
26
    public $name;
27
28
    /**
29
     * Parameter's direction (IN, OUT or INOUT).
30
     *
31
     * @var string
32
     */
33
    public $inOut;
34
35
    /**
36
     * The data type of thew new column.
37
     *
38
     * @var DataType
39
     */
40
    public $type;
41
42
    /**
43
     * @param string   $name  parameter's name
44
     * @param string   $inOut parameter's directional type (IN / OUT or None)
45
     * @param DataType $type  parameter's type
46
     */
47 52
    public function __construct($name = null, $inOut = null, $type = null)
48
    {
49 52
        $this->name = $name;
50 52
        $this->inOut = $inOut;
51 52
        $this->type = $type;
52
    }
53
54
    /**
55
     * @param Parser               $parser  the parser that serves as context
56
     * @param TokensList           $list    the list of tokens that are being parsed
57
     * @param array<string, mixed> $options parameters for parsing
58
     *
59
     * @return ParameterDefinition[]
60
     */
61 52
    public static function parse(Parser $parser, TokensList $list, array $options = []): array
62
    {
63 52
        $ret = [];
64
65 52
        $expr = new static();
66
67
        /**
68
         * The state of the parser.
69
         *
70
         * Below are the states of the parser.
71
         *
72
         *      0 -----------------------[ ( ]------------------------> 1
73
         *
74
         *      1 ----------------[ IN / OUT / INOUT ]----------------> 1
75
         *      1 ----------------------[ name ]----------------------> 2
76
         *
77
         *      2 -------------------[ data type ]--------------------> 3
78
         *
79
         *      3 ------------------------[ , ]-----------------------> 1
80
         *      3 ------------------------[ ) ]-----------------------> (END)
81
         *
82
         * @var int
83
         */
84 52
        $state = 0;
85
86 52
        for (; $list->idx < $list->count; ++$list->idx) {
87
            /**
88
             * Token parsed at this moment.
89
             */
90 52
            $token = $list->tokens[$list->idx];
91
92
            // End of statement.
93 52
            if ($token->type === Token::TYPE_DELIMITER) {
94 4
                break;
95
            }
96
97
            // Skipping whitespaces and comments.
98 52
            if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) {
99 44
                continue;
100
            }
101
102 52
            if ($state === 0) {
103 52
                if (($token->type === Token::TYPE_OPERATOR) && ($token->value === '(')) {
104 51
                    $state = 1;
105
                }
106 50
            } elseif ($state === 1) {
107 50
                if (($token->value === 'IN') || ($token->value === 'OUT') || ($token->value === 'INOUT')) {
108 22
                    $expr->inOut = $token->value;
109 22
                    ++$list->idx;
110 50
                } elseif ($token->value === ')') {
111 6
                    ++$list->idx;
112 6
                    break;
113
                } else {
114 44
                    $expr->name = $token->value;
115 44
                    $state = 2;
116
                }
117 44
            } elseif ($state === 2) {
118 44
                $expr->type = DataType::parse($parser, $list);
119 44
                $state = 3;
120 44
            } elseif ($state === 3) {
121 44
                $ret[] = $expr;
122 44
                $expr = new static();
123 44
                if ($token->value === ',') {
124 10
                    $state = 1;
125 42
                } elseif ($token->value === ')') {
126 42
                    ++$list->idx;
127 42
                    break;
128
                }
129
            }
130
        }
131
132
        // Last iteration was not saved.
133 52
        if (isset($expr->name) && ($expr->name !== '')) {
134 2
            $ret[] = $expr;
135
        }
136
137 52
        --$list->idx;
138
139 52
        return $ret;
140
    }
141
142
    /**
143
     * @param ParameterDefinition $component the component to be built
144
     */
145 6
    public static function build($component): string
146
    {
147 6
        $tmp = '';
148 6
        if (! empty($component->inOut)) {
149 4
            $tmp .= $component->inOut . ' ';
150
        }
151
152 6
        return trim(
153 6
            $tmp . Context::escape($component->name) . ' ' . $component->type
154 6
        );
155
    }
156
157
    /**
158
     * @param ParameterDefinition[] $component the component to be built
159
     */
160 6
    public static function buildAll(array $component): string
161
    {
162 6
        return '(' . implode(', ', $component) . ')';
163
    }
164
165 6
    public function __toString(): string
166
    {
167 6
        return static::build($this);
168
    }
169
}
170