Passed
Pull Request — master (#347)
by Christoffer
06:07
created

printBlockString2()   A

Complexity

Conditions 5
Paths 12

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 4
c 0
b 0
f 0
nc 12
nop 2
dl 0
loc 6
rs 9.6111
1
<?php
2
3
namespace Digia\GraphQL\Language;
4
5
use function Digia\GraphQL\Schema\escapeQuotes;
6
7
/**
8
 * @param int $code
9
 * @return string
10
 */
11
function printCharCode(int $code): string
12
{
13
    if ($code === 0x0000) {
14
        return '<EOF>';
15
    }
16
17
    return $code < 0x007F
18
        // Trust JSON for ASCII.
19
        ? \json_encode(\mb_chr($code, 'UTF-8'))
20
        // Otherwise print the escaped form.
21
        : '"\\u' . \dechex($code) . '"';
22
}
23
24
/**
25
 * @param string   $string
26
 * @param int      $start
27
 * @param int|null $end
28
 * @return string
29
 */
30
function sliceString(string $string, int $start, int $end = null): string
31
{
32
    $length = $end !== null ? $end - $start : \mb_strlen($string) - $start;
33
    return \mb_substr($string, $start, $length);
34
}
35
36
/**
37
 * @param int $code
38
 * @return bool
39
 */
40
function isLetter(int $code): bool
41
{
42
    return ($code >= 65 && $code <= 90) || ($code >= 97 && $code <= 122); // a-z or A-Z
43
}
44
45
/**
46
 * @param int $code
47
 * @return bool
48
 */
49
function isNumber(int $code): bool
50
{
51
    return $code >= 48 && $code <= 57; // 0-9
52
}
53
54
/**
55
 * @param int $code
56
 * @return bool
57
 */
58
function isUnderscore(int $code): bool
59
{
60
    return $code === 95; // _
61
}
62
63
/**
64
 * @param int $code
65
 * @return bool
66
 */
67
function isAlphaNumeric(int $code): bool
68
{
69
    return isLetter($code) || isNumber($code) || isUnderscore($code);
70
}
71
72
/**
73
 * @param int $code
74
 * @return bool
75
 */
76
function isLineTerminator(int $code): bool
77
{
78
    return $code === 0x000a || $code === 0x000d;
79
}
80
81
/**
82
 * @param int $code
83
 * @return bool
84
 */
85
function isSourceCharacter(int $code): bool
86
{
87
    return $code < 0x0020 && $code !== 0x0009; // any source character EXCEPT HT (Horizontal Tab)
88
}
89
90
/**
91
 * @param string $value
92
 * @return bool
93
 */
94
function isOperation(string $value): bool
95
{
96
    return $value === 'query' || $value === 'mutation' || $value === 'subscription';
97
}
98
99
/**
100
 * @param array $location
101
 * @return array|null
102
 */
103
function locationShorthandToArray(array $location): ?array
104
{
105
    return isset($location[0], $location[1]) ? ['line' => $location[0], 'column' => $location[1]] : null;
106
}
107
108
/**
109
 * @param array $locations
110
 * @return array
111
 */
112
function locationsShorthandToArray(array $locations): array
113
{
114
    return array_map(function ($shorthand) {
115
        return locationShorthandToArray($shorthand);
116
    }, $locations);
117
}
118
119
/**
120
 * @param array $array
121
 * @return string
122
 */
123
function block(array $array): string
124
{
125
    return !empty($array) ? "{\n" . indent(implode("\n", $array)) . "\n}" : '';
126
}
127
128
/**
129
 * @param string      $start
130
 * @param null|string $maybeString
131
 * @param null|string $end
132
 * @return string
133
 */
134
function wrap(string $start, ?string $maybeString = null, ?string $end = null): string
135
{
136
    return null !== $maybeString ? ($start . $maybeString . ($end ?? '')) : '';
137
}
138
139
/**
140
 * @param null|string $maybeString
141
 * @return string
142
 */
143
function indent(?string $maybeString): string
144
{
145
    return null !== $maybeString ? '  ' . preg_replace("/\n/", "\n  ", $maybeString) : '';
146
}
147
148
/**
149
 * @param string $str
150
 * @return string
151
 */
152
function dedent(string $str): string
153
{
154
    $trimmed = \preg_replace("/^\n*|[ \t]*$/", '', $str); // Remove leading newline and trailing whitespace
155
    $matches = [];
156
    \preg_match("/^[ \t]*/", $trimmed, $matches); // Figure out indent
157
    $indent = $matches[0];
158
    return \str_replace($indent, '', $trimmed); // Remove indent
159
}
160
161
/**
162
 * @param string $value
163
 * @param bool   $isDescription
164
 * @return string
165
 */
166
function printBlockString2(string $value, bool $isDescription): string
167
{
168
    $escaped = escapeQuotes($value);
169
    return ($value{0} === ' ' || ($value{0} === "\t" && false === \strpos($value, "\n")))
170
        ? '"""' . \preg_replace('/"$/', "\"\n", $escaped) . '"""'
171
        : '"""' . $isDescription ? $escaped : indent($escaped) . "\n" . '"""';
172
}
173
174
/**
175
 * @param string $value
176
 * @param string $indentation
177
 * @param bool   $preferMultipleLines
178
 * @return string
179
 */
180
function printBlockString(string $value, string $indentation = '', bool $preferMultipleLines = false): string {
181
    $isSingleLine = false === \strpos($value, "\n");
182
    $hasLeadingSpace = $value{0} === ' ' || $value{0} === "\t";
183
    $hasTrailingQuote = $value[\strlen($value) - 1] === '"';
184
    $printAsMultipleLines = !$isSingleLine || $hasTrailingQuote || $preferMultipleLines;
185
186
    $result = '';
187
188
    // Format a multi-line block quote to account for leading space.
189
    if ($printAsMultipleLines && !($isSingleLine && $hasLeadingSpace)) {
190
        $result .= "\n" . $indentation;
191
    }
192
193
    $result .= \strlen($indentation) > 0
194
        ? preg_replace("/\n/", "\n" . $indentation, $value)
195
        : $value;
196
197
    if ($printAsMultipleLines) {
198
        $result .= "\n";
199
    }
200
201
    return '"""' . escapeQuotes($result) . '"""';
202
}