Passed
Pull Request — master (#184)
by Christoffer
02:16
created

isSpread()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 3
nc 3
nop 3
1
<?php
2
3
namespace Digia\GraphQL\Language;
4
5
/**
6
 * @param int $code
7
 * @return string
8
 */
9
function chrUTF8(int $code)
10
{
11
    return \mb_convert_encoding(\pack('N', $code), 'UTF-8', 'UCS-4BE');
12
}
13
14
/**
15
 * @param string $string
16
 * @param string $encoding
17
 * @return int
18
 */
19
function ordUTF8(string $string)
20
{
21
//    if (!$string) {
22
//        return 0;
23
//    }
24
25
    if (!isset($string[1])) {
26
        return \ord($string);
27
    }
28
29
    [, $ord] = \unpack('N', \mb_convert_encoding($string, 'UCS-4BE', 'UTF-8'));
30
31
    return $ord;
32
}
33
34
/**
35
 * @param string $string
36
 * @param int    $position
37
 * @return int
38
 */
39
function charCodeAt(string $string, int $position): int
40
{
41
    return ordUTF8(\mb_substr($string, $position, 1, 'UTF-8'));
42
}
43
44
/**
45
 * @param int $code
46
 * @return string
47
 */
48
function printCharCode(int $code): string
49
{
50
    if ($code === 0x0000) {
51
        return '<EOF>';
52
    }
53
54
    return $code < 0x007F
55
        // Trust JSON for ASCII.
56
        ? \json_encode($code < 255 ? \chr($code) : chrUTF8($code))
57
        // Otherwise print the escaped form.
58
        : '"\\u' . \dechex($code) . '"';
59
}
60
61
/**
62
 * @param string   $string
63
 * @param int      $start
64
 * @param int|null $end
65
 * @return string
66
 */
67
function sliceString(string $string, int $start, int $end = null): string
68
{
69
    $length = $end !== null ? $end - $start : \mb_strlen($string) - $start;
70
    return \mb_substr($string, $start, $length);
71
}
72
73
/**
74
 * @param int $code
75
 * @return bool
76
 */
77
function isLetter(int $code): bool
78
{
79
    return ($code >= 65 && $code <= 90) || ($code >= 97 && $code <= 122); // a-z or A-Z
80
}
81
82
/**
83
 * @param int $code
84
 * @return bool
85
 */
86
function isNumber(int $code): bool
87
{
88
    return $code >= 48 && $code <= 57; // 0-9
89
}
90
91
/**
92
 * @param int $code
93
 * @return bool
94
 */
95
function isUnderscore(int $code): bool
96
{
97
    return $code === 95; // _
98
}
99
100
/**
101
 * @param int $code
102
 * @return bool
103
 */
104
function isAlphaNumeric(int $code): bool
105
{
106
    return isLetter($code) || isNumber($code) || isUnderscore($code);
107
}
108
109
/**
110
 * @param int $code
111
 * @return bool
112
 */
113
function isLineTerminator(int $code): bool
114
{
115
    return $code === 0x000a || $code === 0x000d;
116
}
117
118
/**
119
 * @param int $code
120
 * @return bool
121
 */
122
function isSourceCharacter(int $code): bool
123
{
124
    return $code < 0x0020 && $code !== 0x0009; // any source character EXCEPT HT (Horizontal Tab)
125
}
126
127
/**
128
 * @param string $body
129
 * @param int    $code
130
 * @param int    $pos
131
 * @return bool
132
 */
133
function isSpread(string $body, int $code, int $pos): bool
134
{
135
    return $code === 46 &&
136
        charCodeAt($body, $pos + 1) === 46 &&
137
        charCodeAt($body, $pos + 2) === 46; // ...
138
}
139
140
/**
141
 * @param string $body
142
 * @param int    $code
143
 * @param int    $pos
144
 * @return bool
145
 */
146
function isString(string $body, int $code, int $pos): bool
147
{
148
    return $code === 34 && charCodeAt($body, $pos + 1) !== 34;
149
}
150
151
/**
152
 * @param string $body
153
 * @param int    $code
154
 * @param int    $pos
155
 * @return bool
156
 */
157
function isTripleQuote(string $body, int $code, int $pos): bool
158
{
159
    return $code === 34 &&
160
        charCodeAt($body, $pos + 1) === 34 &&
161
        charCodeAt($body, $pos + 2) === 34; // """
162
}
163
164
/**
165
 * @param string $body
166
 * @param int    $code
167
 * @param int    $pos
168
 * @return bool
169
 */
170
function isEscapedTripleQuote(
171
    string $body,
172
    int $code,
173
    int $pos
174
): bool {
175
    return $code === 92 &&
176
        charCodeAt($body, $pos + 1) === 34 &&
177
        charCodeAt($body, $pos + 2) === 34 &&
178
        charCodeAt($body, $pos + 3) === 34;
179
}
180
181
/**
182
 * Converts four hexidecimal chars to the integer that the
183
 * string represents. For example, uniCharCode('0','0','0','f')
184
 * will return 15, and uniCharCode('0','0','f','f') returns 255.
185
 *
186
 * @param string $a
187
 * @param string $b
188
 * @param string $c
189
 * @param string $d
190
 * @return string
191
 */
192
function uniCharCode(string $a, string $b, string $c, string $d): string
193
{
194
    return (\dechex(ordUTF8($a)) << 12) |
195
        (\dechex(ordUTF8($b)) << 8) |
196
        (\dechex(ordUTF8($c)) << 4) |
197
        \dechex(ordUTF8($d));
198
}
199
200
/**
201
 * @param string $value
202
 * @return bool
203
 */
204
function isOperation(string $value): bool
205
{
206
    // TODO: Benchmark
207
    return \in_array($value, ['query', 'mutation', 'subscription'], true);
208
}
209
210
/**
211
 * @param array $location
212
 * @return array|null
213
 */
214
function locationShorthandToArray(array $location): ?array
215
{
216
    return isset($location[0], $location[1]) ? ['line' => $location[0], 'column' => $location[1]] : null;
217
}
218
219
/**
220
 * @param array $locations
221
 * @return array
222
 */
223
function locationsShorthandToArray(array $locations): array
224
{
225
    return array_map(function ($shorthand) {
226
        return locationShorthandToArray($shorthand);
227
    }, $locations);
228
}
229
230
/**
231
 * @param array $array
232
 * @return string
233
 */
234
function block(array $array): string
235
{
236
    return !empty($array) ? "{\n" . indent(implode("\n", $array)) . "\n}" : '';
237
}
238
239
/**
240
 * @param string      $start
241
 * @param null|string $maybeString
242
 * @param null|string $end
243
 * @return string
244
 */
245
function wrap(string $start, ?string $maybeString = null, ?string $end = null): string
246
{
247
    return null !== $maybeString ? ($start . $maybeString . ($end ?? '')) : '';
248
}
249
250
/**
251
 * @param null|string $maybeString
252
 * @return string
253
 */
254
function indent(?string $maybeString): string
255
{
256
    return null !== $maybeString ? '  ' . preg_replace("/\n/", "\n  ", $maybeString) : '';
257
}
258
259
/**
260
 * @param string $str
261
 * @return string
262
 */
263
function dedent(string $str): string
264
{
265
    $trimmed = \preg_replace("/^\n*|[ \t]*$/", '', $str); // Remove leading newline and trailing whitespace
266
    $matches = [];
267
    \preg_match("/^[ \t]*/", $trimmed, $matches); // Figure out indent
268
    $indent = $matches[0];
269
    return \str_replace($indent, '', $trimmed); // Remove indent
270
}
271