Completed
Push — master ( e05c46...93167f )
by Dan
03:50
created

ParameterDefinition::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 3
crap 1
1
<?php
2
3
/**
4
 * The definition of a parameter of a function or procedure.
5
 */
6
7
namespace PhpMyAdmin\SqlParser\Components;
8
9
use PhpMyAdmin\SqlParser\Component;
10
use PhpMyAdmin\SqlParser\Context;
11
use PhpMyAdmin\SqlParser\Parser;
12
use PhpMyAdmin\SqlParser\Token;
13
use PhpMyAdmin\SqlParser\TokensList;
14
15
/**
16
 * The definition of a parameter of a function or procedure.
17
 *
18
 * @category   Components
19
 *
20
 * @license    https://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
21
 */
22
class ParameterDefinition extends Component
23
{
24
    /**
25
     * The name of the new column.
26
     *
27
     * @var string
28
     */
29
    public $name;
30
31
    /**
32
     * Parameter's direction (IN, OUT or INOUT).
33
     *
34
     * @var string
35
     */
36
    public $inOut;
37
38
    /**
39
     * The data type of thew new column.
40
     *
41
     * @var DataType
42
     */
43
    public $type;
44
45
    /**
46
     * Constructor.
47
     *
48
     * @param string $name  Parameter's name.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $name not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
49
     * @param string $inOut Parameter's directional type (IN / OUT or None).
0 ignored issues
show
Documentation introduced by
Should the type for parameter $inOut not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
50
     * @param DataType $type Parameter's type.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $type not be DataType|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
51
     */
52 19
    public function __construct($name = null, $inOut = null, $type = null)
53
    {
54 19
        $this->name = $name;
55 19
        $this->inOut = $inOut;
56 19
        $this->type = $type;
57 19
    }
58
59
    /**
60
     * @param Parser     $parser  the parser that serves as context
61
     * @param TokensList $list    the list of tokens that are being parsed
62
     * @param array      $options parameters for parsing
63
     *
64
     * @return ParameterDefinition[]
65
     */
66 19
    public static function parse(Parser $parser, TokensList $list, array $options = array())
67
    {
68 19
        $ret = array();
69
70 19
        $expr = new self();
71
72
        /**
73
         * The state of the parser.
74
         *
75
         * Below are the states of the parser.
76
         *
77
         *      0 -----------------------[ ( ]------------------------> 1
78
         *
79
         *      1 ----------------[ IN / OUT / INOUT ]----------------> 1
80
         *      1 ----------------------[ name ]----------------------> 2
81
         *
82
         *      2 -------------------[ data type ]--------------------> 3
83
         *
84
         *      3 ------------------------[ , ]-----------------------> 1
85
         *      3 ------------------------[ ) ]-----------------------> (END)
86
         *
87
         * @var int
88
         */
89 19
        $state = 0;
90
91 19
        for (; $list->idx < $list->count; ++$list->idx) {
92
            /**
93
             * Token parsed at this moment.
94
             *
95
             * @var Token
96
             */
97 19
            $token = $list->tokens[$list->idx];
98
99
            // End of statement.
100 19
            if ($token->type === Token::TYPE_DELIMITER) {
101 1
                break;
102
            }
103
104
            // Skipping whitespaces and comments.
105 19
            if (($token->type === Token::TYPE_WHITESPACE) || ($token->type === Token::TYPE_COMMENT)) {
106 16
                continue;
107
            }
108
109 19
            if ($state === 0) {
110 19
                if (($token->type === Token::TYPE_OPERATOR) && ($token->value === '(')) {
111 19
                    $state = 1;
112
                }
113 19
                continue;
114 19
            } elseif ($state === 1) {
115 19
                if (($token->value === 'IN') || ($token->value === 'OUT') || ($token->value === 'INOUT')) {
116 7
                    $expr->inOut = $token->value;
117 7
                    ++$list->idx;
118 19
                } elseif ($token->value === ')') {
119 3
                    ++$list->idx;
120 3
                    break;
121
                } else {
122 16
                    $expr->name = $token->value;
123 16
                    $state = 2;
124
                }
125 16
            } elseif ($state === 2) {
126 16
                $expr->type = DataType::parse($parser, $list);
127 16
                $state = 3;
128 16
            } elseif ($state === 3) {
129 16
                $ret[] = $expr;
130 16
                $expr = new self();
131 16
                if ($token->value === ',') {
132 3
                    $state = 1;
133 15
                } elseif ($token->value === ')') {
134 15
                    ++$list->idx;
135 15
                    break;
136
                }
137
            }
138
        }
139
140
        // Last iteration was not saved.
141 19
        if ((isset($expr->name)) && ($expr->name !== '')) {
142 1
            $ret[] = $expr;
143
        }
144
145 19
        --$list->idx;
146
147 19
        return $ret;
148
    }
149
150
    /**
151
     * @param ParameterDefinition[] $component the component to be built
152
     * @param array                 $options   parameters for building
153
     *
154
     * @return string
155
     */
156 1
    public static function build($component, array $options = array())
157
    {
158 1
        if (is_array($component)) {
159 1
            return '(' . implode(', ', $component) . ')';
160
        }
161
162 1
        $tmp = '';
163 1
        if (!empty($component->inOut)) {
164 1
            $tmp .= $component->inOut . ' ';
165
        }
166
167 1
        return trim(
168 1
            $tmp . Context::escape($component->name) . ' ' . $component->type
169
        );
170
    }
171
}
172