Completed
Pull Request — master (#201)
by
unknown
11:32 queued 19s
created

JsFunctionsScanner::prepareArgument()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 2
nop 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Gettext\Utils;
4
5
class JsFunctionsScanner extends FunctionsScanner
6
{
7
    protected $code;
8
    protected $status = [];
9
10
    /**
11
     * Constructor.
12
     *
13
     * @param string $code The php code to scan
14
     */
15
    public function __construct($code)
16
    {
17
        // Normalize newline characters
18
        $this->code = str_replace(["\r\n", "\n\r", "\r"], "\n", $code);
19
    }
20
21
    /**
22
     * {@inheritdoc}
23
     */
24
    public function getFunctions(array $constants = [])
25
    {
26
        $length = strlen($this->code);
27
        $line = 1;
28
        $buffer = '';
29
        $functions = [];
30
        $bufferFunctions = [];
31
        $char = null;
32
33
        for ($pos = 0; $pos < $length; ++$pos) {
34
            $prev = $char;
35
            $char = $this->code[$pos];
36
            $next = isset($this->code[$pos + 1]) ? $this->code[$pos + 1] : null;
37
38
            switch ($char) {
39
                case '\\':
40
                    $pos++;
41
42
                    if ($next !== 'n') {
43
                        $prev = $char;
0 ignored issues
show
Unused Code introduced by
$prev is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
44
                        $char = $next;
45
                        $next = isset($this->code[$pos]) ? $this->code[$pos] : null;
0 ignored issues
show
Unused Code introduced by
$next is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
46
47
                        break;
48
                    }
49
50
                    $char = "\n";
51
                    $next = isset($this->code[$pos]) ? $this->code[$pos] : null;
0 ignored issues
show
Unused Code introduced by
$next is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
52
53
                case "\n":
54
                    ++$line;
55
56
                    if ($this->status('line-comment')) {
57
                        $this->upStatus();
58
                    }
59
                    break;
60
61
                case '/':
62
                    switch ($this->status()) {
63
                        case 'simple-quote':
64
                        case 'double-quote':
65
                        case 'line-comment':
66
                            break;
67
68
                        case 'block-comment':
69
                            if ($prev === '*') {
70
                                $this->upStatus();
71
                            }
72
                            break;
73
74
                        default:
75
                            if ($next === '/') {
76
                                $this->downStatus('line-comment');
77
                            } elseif ($next === '*') {
78
                                $this->downStatus('block-comment');
79
                            }
80
                            break;
81
                    }
82
                    break;
83
84 View Code Duplication
                case "'":
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
85
                    switch ($this->status()) {
86
                        case 'simple-quote':
87
                            $this->upStatus();
88
                            break;
89
90
                        case 'line-comment':
91
                        case 'block-comment':
92
                        case 'double-quote':
93
                            break;
94
95
                        default:
96
                            $this->downStatus('simple-quote');
97
                            break;
98
                    }
99
                    break;
100
101 View Code Duplication
                case '"':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
102
                    switch ($this->status()) {
103
                        case 'double-quote':
104
                            $this->upStatus();
105
                            break;
106
107
                        case 'line-comment':
108
                        case 'block-comment':
109
                        case 'simple-quote':
110
                            break;
111
112
                        default:
113
                            $this->downStatus('double-quote');
114
                            break;
115
                    }
116
                    break;
117
118
                case '(':
119
                    switch ($this->status()) {
120
                        case 'simple-quote':
121
                        case 'double-quote':
122
                        case 'line-comment':
123
                        case 'block-comment':
124
                        case 'line-comment':
125
                            break;
126
127
                        default:
128
                            if ($buffer && preg_match('/(\w+)$/', $buffer, $matches)) {
129
                                $this->downStatus('function');
130
                                array_unshift($bufferFunctions, [$matches[1], $line, []]);
131
                                $buffer = '';
132
                                continue 3;
133
                            }
134
                            break;
135
                    }
136
                    break;
137
138
                case ')':
139
                    switch ($this->status()) {
140
                        case 'function':
141
                            if (($argument = self::prepareArgument($buffer))) {
142
                                $bufferFunctions[0][2][] = $argument;
143
                            }
144
145
                            if (!empty($bufferFunctions)) {
146
                                $functions[] = array_shift($bufferFunctions);
147
                            }
148
149
                            $this->upStatus();
150
                            $buffer = '';
151
                            continue 3;
152
                    }
153
                    break;
154
155
                case ',':
156
                    switch ($this->status()) {
157
                        case 'function':
158
                            if (($argument = self::prepareArgument($buffer))) {
159
                                $bufferFunctions[0][2][] = $argument;
160
                            }
161
162
                            $buffer = '';
163
                            continue 3;
164
                    }
165
                    break;
166
167
                case ' ':
168
                case '\t':
169
                    switch ($this->status()) {
170
                        case 'double-quote':
171
                        case 'simple-quote':
172
                            break;
173
174
                        default:
175
                            $buffer = '';
176
                            continue 3;
177
                    }
178
                    break;
179
            }
180
181
            switch ($this->status()) {
182
                case 'line-comment':
183
                case 'block-comment':
184
                    break;
185
186
                default:
187
                    $buffer .= $char;
188
                    break;
189
            }
190
        }
191
192
        return $functions;
193
    }
194
195
    /**
196
     * Get the current context of the scan.
197
     *
198
     * @param null|string $match To check whether the current status is this value
199
     *
200
     * @return string|bool
201
     */
202
    protected function status($match = null)
203
    {
204
        $status = isset($this->status[0]) ? $this->status[0] : null;
205
206
        if ($match !== null) {
207
            return $status === $match;
208
        }
209
210
        return $status;
211
    }
212
213
    /**
214
     * Add a new status to the stack.
215
     *
216
     * @param string $status
217
     */
218
    protected function downStatus($status)
219
    {
220
        array_unshift($this->status, $status);
221
    }
222
223
    /**
224
     * Removes and return the current status.
225
     *
226
     * @return string|null
227
     */
228
    protected function upStatus()
229
    {
230
        return array_shift($this->status);
231
    }
232
233
    /**
234
     * Prepares the arguments found in functions.
235
     *
236
     * @param string $argument
237
     *
238
     * @return string
239
     */
240
    protected static function prepareArgument($argument)
241
    {
242
        if ($argument && ($argument[0] === '"' || $argument[0] === "'")) {
243
            return substr($argument, 1, -1);
244
        }
245
    }
246
}
247