Passed
Pull Request — master (#196)
by Christoffer
02:26
created

mbChr()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 4
nop 1
dl 0
loc 13
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
namespace Digia\GraphQL\Language;
4
5
/**
6
 * @param string $string
7
 * @param int    $position
8
 * @return int
9
 */
10
function charCodeAt(string $string, int $position): int
11
{
12
    static $cache = [];
13
14
    $char = \mb_substr($string, $position, 1, 'UTF-8');
15
16
    if (!isset($cache[$char])) {
17
        $cache[$char] = \mb_ord($char);
0 ignored issues
show
Bug introduced by
The call to mb_ord() has too few arguments starting with encoding. ( Ignorable by Annotation )

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

17
        $cache[$char] = /** @scrutinizer ignore-call */ \mb_ord($char);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
18
    }
19
20
    return $cache[$char];
21
}
22
23
/**
24
 * @param int $code
25
 * @return string
26
 */
27
function printCharCode(int $code): string
28
{
29
    if ($code === 0x0000) {
30
        return '<EOF>';
31
    }
32
33
    return $code < 0x007F
34
        // Trust JSON for ASCII.
35
        ? \json_encode(\mb_chr($code))
0 ignored issues
show
Bug introduced by
The call to mb_chr() has too few arguments starting with encoding. ( Ignorable by Annotation )

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

35
        ? \json_encode(/** @scrutinizer ignore-call */ \mb_chr($code))

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
36
        // Otherwise print the escaped form.
37
        : '"\\u' . \dechex($code) . '"';
38
}
39
40
/**
41
 * @param string   $string
42
 * @param int      $start
43
 * @param int|null $end
44
 * @return string
45
 */
46
function sliceString(string $string, int $start, int $end = null): string
47
{
48
    $length = $end !== null ? $end - $start : \mb_strlen($string) - $start;
49
    return \mb_substr($string, $start, $length);
50
}
51
52
/**
53
 * @param int $code
54
 * @return bool
55
 */
56
function isLetter(int $code): bool
57
{
58
    return ($code >= 65 && $code <= 90) || ($code >= 97 && $code <= 122); // a-z or A-Z
59
}
60
61
/**
62
 * @param int $code
63
 * @return bool
64
 */
65
function isNumber(int $code): bool
66
{
67
    return $code >= 48 && $code <= 57; // 0-9
68
}
69
70
/**
71
 * @param int $code
72
 * @return bool
73
 */
74
function isUnderscore(int $code): bool
75
{
76
    return $code === 95; // _
77
}
78
79
/**
80
 * @param int $code
81
 * @return bool
82
 */
83
function isAlphaNumeric(int $code): bool
84
{
85
    return isLetter($code) || isNumber($code) || isUnderscore($code);
86
}
87
88
/**
89
 * @param int $code
90
 * @return bool
91
 */
92
function isLineTerminator(int $code): bool
93
{
94
    return $code === 0x000a || $code === 0x000d;
95
}
96
97
/**
98
 * @param int $code
99
 * @return bool
100
 */
101
function isSourceCharacter(int $code): bool
102
{
103
    return $code < 0x0020 && $code !== 0x0009; // any source character EXCEPT HT (Horizontal Tab)
104
}
105
106
/**
107
 * @param string $body
108
 * @param int    $code
109
 * @param int    $pos
110
 * @return bool
111
 */
112
function isSpread(string $body, int $code, int $pos): bool
113
{
114
    return $code === 46 &&
115
        charCodeAt($body, $pos + 1) === 46 &&
116
        charCodeAt($body, $pos + 2) === 46; // ...
117
}
118
119
/**
120
 * @param string $body
121
 * @param int    $code
122
 * @param int    $pos
123
 * @return bool
124
 */
125
function isString(string $body, int $code, int $pos): bool
126
{
127
    return $code === 34 && charCodeAt($body, $pos + 1) !== 34;
128
}
129
130
/**
131
 * @param string $body
132
 * @param int    $code
133
 * @param int    $pos
134
 * @return bool
135
 */
136
function isTripleQuote(string $body, int $code, int $pos): bool
137
{
138
    return $code === 34 &&
139
        charCodeAt($body, $pos + 1) === 34 &&
140
        charCodeAt($body, $pos + 2) === 34; // """
141
}
142
143
/**
144
 * @param string $body
145
 * @param int    $code
146
 * @param int    $pos
147
 * @return bool
148
 */
149
function isEscapedTripleQuote(
150
    string $body,
151
    int $code,
152
    int $pos
153
): bool {
154
    return $code === 92 &&
155
        charCodeAt($body, $pos + 1) === 34 &&
156
        charCodeAt($body, $pos + 2) === 34 &&
157
        charCodeAt($body, $pos + 3) === 34; // \"""
158
}
159
160
/**
161
 * @param string $value
162
 * @return bool
163
 */
164
function isOperation(string $value): bool
165
{
166
    return $value === 'query' || $value === 'mutation' || $value === 'subscription';
167
}
168
169
/**
170
 * @param array $location
171
 * @return array|null
172
 */
173
function locationShorthandToArray(array $location): ?array
174
{
175
    return isset($location[0], $location[1]) ? ['line' => $location[0], 'column' => $location[1]] : null;
176
}
177
178
/**
179
 * @param array $locations
180
 * @return array
181
 */
182
function locationsShorthandToArray(array $locations): array
183
{
184
    return array_map(function ($shorthand) {
185
        return locationShorthandToArray($shorthand);
186
    }, $locations);
187
}
188
189
/**
190
 * @param array $array
191
 * @return string
192
 */
193
function block(array $array): string
194
{
195
    return !empty($array) ? "{\n" . indent(implode("\n", $array)) . "\n}" : '';
196
}
197
198
/**
199
 * @param string      $start
200
 * @param null|string $maybeString
201
 * @param null|string $end
202
 * @return string
203
 */
204
function wrap(string $start, ?string $maybeString = null, ?string $end = null): string
205
{
206
    return null !== $maybeString ? ($start . $maybeString . ($end ?? '')) : '';
207
}
208
209
/**
210
 * @param null|string $maybeString
211
 * @return string
212
 */
213
function indent(?string $maybeString): string
214
{
215
    return null !== $maybeString ? '  ' . preg_replace("/\n/", "\n  ", $maybeString) : '';
216
}
217
218
/**
219
 * @param string $str
220
 * @return string
221
 */
222
function dedent(string $str): string
223
{
224
    $trimmed = \preg_replace("/^\n*|[ \t]*$/", '', $str); // Remove leading newline and trailing whitespace
225
    $matches = [];
226
    \preg_match("/^[ \t]*/", $trimmed, $matches); // Figure out indent
227
    $indent = $matches[0];
228
    return \str_replace($indent, '', $trimmed); // Remove indent
229
}
230