NodePrinter   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 341
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 82
dl 0
loc 341
rs 9.6
c 0
b 0
f 0
wmc 35

27 Methods

Rating   Name   Duplication   Size   Complexity  
A printFragmentDefinition() 0 14 1
A printBooleanValue() 0 3 2
A printField() 0 12 1
A printStringValue() 0 7 2
A printObjectValue() 0 4 1
A printVariable() 0 3 1
A printInlineFragment() 0 10 1
A print() 0 9 2
A printDirective() 0 6 1
A printMany() 0 5 1
A printSelectionSet() 0 3 1
A printVariableDefinition() 0 7 1
A printNamedType() 0 3 1
A printFloatValue() 0 3 1
A printDocument() 0 3 1
A printObjectField() 0 6 1
A printNullValue() 0 3 1
A printListValue() 0 4 1
A printListType() 0 3 1
A printIntValue() 0 3 1
A printFragmentSpread() 0 6 1
A printArgument() 0 6 1
A printOne() 0 3 2
A printEnumValue() 0 3 1
A printName() 0 3 1
A printNonNullType() 0 3 1
A printOperationDefinition() 0 17 5
1
<?php
2
3
namespace Digia\GraphQL\Language;
4
5
use Digia\GraphQL\Language\Node\ArgumentNode;
6
use Digia\GraphQL\Language\Node\BooleanValueNode;
7
use Digia\GraphQL\Language\Node\DirectiveNode;
8
use Digia\GraphQL\Language\Node\DocumentNode;
9
use Digia\GraphQL\Language\Node\EnumValueNode;
10
use Digia\GraphQL\Language\Node\FieldNode;
11
use Digia\GraphQL\Language\Node\FloatValueNode;
12
use Digia\GraphQL\Language\Node\FragmentDefinitionNode;
13
use Digia\GraphQL\Language\Node\FragmentSpreadNode;
14
use Digia\GraphQL\Language\Node\InlineFragmentNode;
15
use Digia\GraphQL\Language\Node\IntValueNode;
16
use Digia\GraphQL\Language\Node\ListTypeNode;
17
use Digia\GraphQL\Language\Node\ListValueNode;
18
use Digia\GraphQL\Language\Node\NamedTypeNode;
19
use Digia\GraphQL\Language\Node\NameNode;
20
use Digia\GraphQL\Language\Node\NodeInterface;
21
use Digia\GraphQL\Language\Node\NonNullTypeNode;
22
use Digia\GraphQL\Language\Node\NullValueNode;
23
use Digia\GraphQL\Language\Node\ObjectFieldNode;
24
use Digia\GraphQL\Language\Node\ObjectValueNode;
25
use Digia\GraphQL\Language\Node\OperationDefinitionNode;
26
use Digia\GraphQL\Language\Node\SelectionSetNode;
27
use Digia\GraphQL\Language\Node\StringValueNode;
28
use Digia\GraphQL\Language\Node\VariableDefinitionNode;
29
use Digia\GraphQL\Language\Node\VariableNode;
30
use function Digia\GraphQL\Util\toString;
31
32
class NodePrinter implements NodePrinterInterface
33
{
34
    /**
35
     * @inheritdoc
36
     * @throws PrintException
37
     */
38
    public function print(NodeInterface $node): string
39
    {
40
        $printMethod = 'print' . $node->getKind();
41
42
        if (\method_exists($this, $printMethod)) {
43
            return $this->{$printMethod}($node);
44
        }
45
46
        throw new PrintException(\sprintf('Invalid AST Node: %s.', toString($node)));
47
    }
48
49
    /**
50
     * @param NameNode $node
51
     * @return null|string
52
     */
53
    protected function printName(NameNode $node): ?string
54
    {
55
        return $node->getValue();
56
    }
57
58
    /**
59
     * @param VariableNode $node
60
     * @return string
61
     */
62
    protected function printVariable(VariableNode $node): string
63
    {
64
        return '$' . $node->getName();
65
    }
66
67
    // Document
68
69
    /**
70
     * @param DocumentNode $node
71
     * @return string
72
     */
73
    protected function printDocument(DocumentNode $node): string
74
    {
75
        return \implode("\n\n", $node->getDefinitions()) . "\n";
76
    }
77
78
    /**
79
     * @param OperationDefinitionNode $node
80
     * @return string
81
     * @throws PrintException
82
     */
83
    protected function printOperationDefinition(OperationDefinitionNode $node): string
84
    {
85
        $operation            = $node->getOperation();
86
        $name                 = $this->printOne($node->getName());
87
        $variablesDefinitions = $this->printMany($node->getVariableDefinitions());
88
        $directives           = $this->printMany($node->getDirectives());
89
        $selectionSet         = $this->printOne($node->getSelectionSet());
90
91
        // Anonymous queries with no directives or variable definitions can use
92
        // the query short form.
93
        return empty($name) && empty($directives) && empty($variablesDefinitions) && $operation === 'query'
94
            ? $selectionSet
95
            : \implode(' ', [
96
                $operation,
97
                $name . wrap('(', \implode(', ', $variablesDefinitions), ')'),
98
                \implode(' ', $directives),
99
                $selectionSet,
100
            ]);
101
    }
102
103
    /**
104
     * @param VariableDefinitionNode $node
105
     * @return string
106
     * @throws PrintException
107
     */
108
    protected function printVariableDefinition(VariableDefinitionNode $node): string
109
    {
110
        $variable     = $this->printOne($node->getVariable());
111
        $type         = $this->printOne($node->getType());
112
        $defaultValue = $this->printOne($node->getDefaultValue());
113
114
        return $variable . ': ' . $type . wrap(' = ', $defaultValue);
115
    }
116
117
    /**
118
     * @param SelectionSetNode $node
119
     * @return string
120
     */
121
    protected function printSelectionSet(SelectionSetNode $node): string
122
    {
123
        return block($this->printMany($node->getSelections()));
124
    }
125
126
    /**
127
     * @param FieldNode $node
128
     * @return string
129
     * @throws PrintException
130
     */
131
    protected function printField(FieldNode $node): string
132
    {
133
        $alias        = $this->printOne($node->getAlias());
134
        $name         = $this->printOne($node->getName());
135
        $arguments    = $this->printMany($node->getArguments());
136
        $directives   = $this->printMany($node->getDirectives());
137
        $selectionSet = $this->printOne($node->getSelectionSet());
138
139
        return \implode(' ', [
140
            wrap('', $alias, ': ') . $name . wrap('(', \implode(', ', $arguments), ')'),
141
            \implode(' ', $directives),
142
            $selectionSet,
143
        ]);
144
    }
145
146
    /**
147
     * @param ArgumentNode $node
148
     * @return string
149
     * @throws PrintException
150
     */
151
    protected function printArgument(ArgumentNode $node): string
152
    {
153
        $name  = $this->printOne($node->getName());
154
        $value = $this->printOne($node->getValue());
155
156
        return $name . ': ' . $value;
157
    }
158
159
    // Fragments
160
161
    /**
162
     * @param FragmentSpreadNode $node
163
     * @return string
164
     * @throws PrintException
165
     */
166
    protected function printFragmentSpread(FragmentSpreadNode $node): string
167
    {
168
        $name       = $this->printOne($node->getName());
169
        $directives = $this->printMany($node->getDirectives());
170
171
        return '...' . $name . wrap(' ', \implode(' ', $directives));
172
    }
173
174
    /**
175
     * @param InlineFragmentNode $node
176
     * @return string
177
     * @throws PrintException
178
     */
179
    protected function printInlineFragment(InlineFragmentNode $node): string
180
    {
181
        $typeCondition = $this->printOne($node->getTypeCondition());
182
        $directives    = $this->printMany($node->getDirectives());
183
        $selectionSet  = $this->printOne($node->getSelectionSet());
184
185
        return \implode(' ', [
186
            '...', wrap('on ', $typeCondition),
187
            \implode(' ', $directives),
188
            $selectionSet
189
        ]);
190
    }
191
192
    /**
193
     * @param FragmentDefinitionNode $node
194
     * @return string
195
     * @throws PrintException
196
     */
197
    protected function printFragmentDefinition(FragmentDefinitionNode $node): string
198
    {
199
        $name                = $this->printOne($node->getName());
200
        $typeCondition       = $this->printOne($node->getTypeCondition());
201
        $variableDefinitions = $this->printMany($node->getVariableDefinitions());
202
        $directives          = $this->printMany($node->getDirectives());
203
        $selectionSet        = $this->printOne($node->getSelectionSet());
204
205
        // Note: fragment variable definitions are experimental and may be changed
206
        // or removed in the future.
207
        return \implode(' ', [
208
            'fragment ' . $name . wrap('(', \implode(', ', $variableDefinitions), ')'),
209
            'on ' . $typeCondition . ' ' . \implode(' ', $directives),
210
            $selectionSet
211
        ]);
212
    }
213
214
    // Value
215
216
    /**
217
     * @param IntValueNode $node
218
     * @return string
219
     */
220
    protected function printIntValue(IntValueNode $node): string
221
    {
222
        return (string)$node->getValue();
223
    }
224
225
    /**
226
     * @param FloatValueNode $node
227
     * @return string
228
     */
229
    protected function printFloatValue(FloatValueNode $node): string
230
    {
231
        return (string)$node->getValue();
232
    }
233
234
    /**
235
     * @param StringValueNode $node
236
     * @return string
237
     */
238
    protected function printStringValue(StringValueNode $node): string
239
    {
240
        $value = $node->getValue();
241
242
        return $node->isBlock()
243
            ? printBlockString($value, false)
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type null; however, parameter $value of Digia\GraphQL\Language\printBlockString() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

243
            ? printBlockString(/** @scrutinizer ignore-type */ $value, false)
Loading history...
Bug introduced by
false of type false is incompatible with the type string expected by parameter $indentation of Digia\GraphQL\Language\printBlockString(). ( Ignorable by Annotation )

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

243
            ? printBlockString($value, /** @scrutinizer ignore-type */ false)
Loading history...
244
            : \json_encode($value, JSON_UNESCAPED_UNICODE);
245
    }
246
247
    /**
248
     * @param BooleanValueNode $node
249
     * @return string
250
     */
251
    protected function printBooleanValue(BooleanValueNode $node): string
252
    {
253
        return $node->getValue() ? 'true' : 'false';
254
    }
255
256
    /**
257
     * @param NullValueNode $node
258
     * @return string
259
     */
260
    protected function printNullValue(NullValueNode $node): string
261
    {
262
        return 'null';
263
    }
264
265
    /**
266
     * @param EnumValueNode $node
267
     * @return string
268
     */
269
    protected function printEnumValue(EnumValueNode $node): string
270
    {
271
        return (string)$node->getValue();
272
    }
273
274
    /**
275
     * @param ListValueNode $node
276
     * @return string
277
     */
278
    protected function printListValue(ListValueNode $node): string
279
    {
280
        $values = $this->printMany($node->getValues());
281
        return wrap('[', \implode(', ', $values), ']');
282
    }
283
284
    /**
285
     * @param ObjectValueNode $node
286
     * @return string
287
     */
288
    protected function printObjectValue(ObjectValueNode $node): string
289
    {
290
        $fields = $this->printMany($node->getFields());
291
        return wrap('{', \implode(', ', $fields), '}');
292
    }
293
294
    /**
295
     * @param ObjectFieldNode $node
296
     * @return string
297
     * @throws PrintException
298
     */
299
    protected function printObjectField(ObjectFieldNode $node): string
300
    {
301
        $name  = $this->printOne($node->getName());
302
        $value = $this->printOne($node->getValue());
303
304
        return $name . ': ' . $value;
305
    }
306
307
    // Directive
308
309
    /**
310
     * @param DirectiveNode $node
311
     * @return string
312
     * @throws PrintException
313
     */
314
    protected function printDirective(DirectiveNode $node): string
315
    {
316
        $name      = $this->printOne($node->getName());
317
        $arguments = $this->printMany($node->getArguments());
318
319
        return '@' . $name . wrap('(', \implode(', ', $arguments), ')');
320
    }
321
322
    // Type
323
324
    /**
325
     * @param NamedTypeNode $node
326
     * @return string
327
     * @throws PrintException
328
     */
329
    protected function printNamedType(NamedTypeNode $node): string
330
    {
331
        return $this->printOne($node->getName());
332
    }
333
334
    /**
335
     * @param ListTypeNode $node
336
     * @return string
337
     * @throws PrintException
338
     */
339
    protected function printListType(ListTypeNode $node): string
340
    {
341
        return wrap('[', $this->printOne($node->getType()), ']');
342
    }
343
344
    /**
345
     * @param NonNullTypeNode $node
346
     * @return string
347
     * @throws PrintException
348
     */
349
    protected function printNonNullType(NonNullTypeNode $node): string
350
    {
351
        return $this->printOne($node->getType()) . '!';
352
    }
353
354
    /**
355
     * @param NodeInterface|null $node
356
     * @return string
357
     * @throws PrintException
358
     */
359
    protected function printOne(?NodeInterface $node): string
360
    {
361
        return null !== $node ? $this->print($node) : '';
362
    }
363
364
    /**
365
     * @param array $nodes
366
     * @return array
367
     */
368
    protected function printMany(array $nodes): array
369
    {
370
        return \array_map(function ($node) {
371
            return $this->print($node);
372
        }, $nodes);
373
    }
374
}
375