Completed
Pull Request — master (#208)
by Christoffer
02:35
created

Printer::printStringValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Digia\GraphQL\Language;
4
5
use Digia\GraphQL\Error\LanguageException;
6
use Digia\GraphQL\Language\Node\ArgumentNode;
7
use Digia\GraphQL\Language\Node\BooleanValueNode;
8
use Digia\GraphQL\Language\Node\DirectiveNode;
9
use Digia\GraphQL\Language\Node\DocumentNode;
10
use Digia\GraphQL\Language\Node\EnumValueNode;
11
use Digia\GraphQL\Language\Node\FieldNode;
12
use Digia\GraphQL\Language\Node\FloatValueNode;
13
use Digia\GraphQL\Language\Node\FragmentDefinitionNode;
14
use Digia\GraphQL\Language\Node\FragmentSpreadNode;
15
use Digia\GraphQL\Language\Node\InlineFragmentNode;
16
use Digia\GraphQL\Language\Node\IntValueNode;
17
use Digia\GraphQL\Language\Node\ListTypeNode;
18
use Digia\GraphQL\Language\Node\ListValueNode;
19
use Digia\GraphQL\Language\Node\NamedTypeNode;
20
use Digia\GraphQL\Language\Node\NameNode;
21
use Digia\GraphQL\Language\Node\NodeInterface;
22
use Digia\GraphQL\Language\Node\NonNullTypeNode;
23
use Digia\GraphQL\Language\Node\NullValueNode;
24
use Digia\GraphQL\Language\Node\ObjectFieldNode;
25
use Digia\GraphQL\Language\Node\ObjectValueNode;
26
use Digia\GraphQL\Language\Node\OperationDefinitionNode;
27
use Digia\GraphQL\Language\Node\SelectionSetNode;
28
use Digia\GraphQL\Language\Node\StringValueNode;
29
use Digia\GraphQL\Language\Node\VariableDefinitionNode;
30
use Digia\GraphQL\Language\Node\VariableNode;
31
use function Digia\GraphQL\Util\toString;
32
33
class Printer implements PrinterInterface
34
{
35
    /**
36
     * @inheritdoc
37
     * @throws LanguageException
38
     */
39
    public function print(NodeInterface $node): string
40
    {
41
        if ($node instanceof NameNode) {
42
            return $this->printName($node);
43
        }
44
        if ($node instanceof VariableNode) {
45
            return $this->printVariable($node);
46
        }
47
        if ($node instanceof DocumentNode) {
48
            return $this->printDocument($node);
49
        }
50
        if ($node instanceof OperationDefinitionNode) {
51
            return $this->printOperationDefinition($node);
52
        }
53
        if ($node instanceof VariableDefinitionNode) {
54
            return $this->printVariableDefinition($node);
55
        }
56
        if ($node instanceof SelectionSetNode) {
57
            return $this->printSelectionSet($node);
58
        }
59
        if ($node instanceof FieldNode) {
60
            return $this->printField($node);
61
        }
62
        if ($node instanceof ArgumentNode) {
63
            return $this->printArgument($node);
64
        }
65
        if ($node instanceof FragmentSpreadNode) {
66
            return $this->printFragmentSpread($node);
67
        }
68
        if ($node instanceof InlineFragmentNode) {
69
            return $this->printInlineFragment($node);
70
        }
71
        if ($node instanceof FragmentDefinitionNode) {
72
            return $this->printFragmentDefinition($node);
73
        }
74
        if ($node instanceof IntValueNode) {
75
            return $this->printIntValue($node);
76
        }
77
        if ($node instanceof FloatValueNode) {
78
            return $this->printFloatValue($node);
79
        }
80
        if ($node instanceof StringValueNode) {
81
            return $this->printStringValue($node);
82
        }
83
        if ($node instanceof BooleanValueNode) {
84
            return $this->printBooleanValue($node);
85
        }
86
        if ($node instanceof NullValueNode) {
87
            return $this->printNullValue($node);
88
        }
89
        if ($node instanceof EnumValueNode) {
90
            return $this->printEnumValue($node);
91
        }
92
        if ($node instanceof ListValueNode) {
93
            return $this->printListValue($node);
94
        }
95
        if ($node instanceof ObjectValueNode) {
96
            return $this->printObjectValue($node);
97
        }
98
        if ($node instanceof ObjectFieldNode) {
99
            return $this->printObjectField($node);
100
        }
101
        if ($node instanceof DirectiveNode) {
102
            return $this->printDirective($node);
103
        }
104
        if ($node instanceof NamedTypeNode) {
105
            return $this->printNamedType($node);
106
        }
107
        if ($node instanceof ListTypeNode) {
108
            return $this->printListType($node);
109
        }
110
        if ($node instanceof NonNullTypeNode) {
111
            return $this->printNonNullType($node);
112
        }
113
114
        throw new LanguageException(\sprintf('Invalid AST Node: %s.', toString($node)));
115
    }
116
117
    /**
118
     * @param NameNode $node
119
     * @return string
120
     */
121
    protected function printName(NameNode $node): string
122
    {
123
        return $node->getValue();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $node->getValue() could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
124
    }
125
126
    /**
127
     * @param VariableNode $node
128
     * @return string
129
     */
130
    protected function printVariable(VariableNode $node): string
131
    {
132
        return '$' . $node->getName();
133
    }
134
135
    // Document
136
137
    /**
138
     * @param DocumentNode $node
139
     * @return string
140
     */
141
    protected function printDocument(DocumentNode $node): string
142
    {
143
        return \implode("\n\n", $node->getDefinitions()) . "\n";
144
    }
145
146
    /**
147
     * @param OperationDefinitionNode $node
148
     * @return string
149
     * @throws LanguageException
150
     */
151
    protected function printOperationDefinition(OperationDefinitionNode $node): string
152
    {
153
        $operation            = $node->getOperation();
154
        $name                 = $this->one($node->getName());
155
        $variablesDefinitions = $this->many($node->getVariableDefinitions());
156
        $directives           = $this->many($node->getDirectives());
157
        $selectionSet         = $this->one($node->getSelectionSet());
158
159
        // Anonymous queries with no directives or variable definitions can use
160
        // the query short form.
161
        return null === $name && empty($directives) && empty($variablesDefinitions) && $operation === 'query'
0 ignored issues
show
introduced by
The condition null === $name is always false.
Loading history...
162
            ? $selectionSet
163
            : \implode(' ', [
164
                $operation,
165
                $name . wrap('(', \implode(', ', $variablesDefinitions), ')'),
166
                \implode(' ', $directives),
167
                $selectionSet,
168
            ]);
169
    }
170
171
    /**
172
     * @param VariableDefinitionNode $node
173
     * @return string
174
     * @throws LanguageException
175
     */
176
    protected function printVariableDefinition(VariableDefinitionNode $node): string
177
    {
178
        $variable     = $this->one($node->getVariable());
179
        $type         = $this->one($node->getType());
180
        $defaultValue = $this->one($node->getDefaultValue());
181
182
        return $variable . ': ' . $type . wrap(' = ', $defaultValue);
183
    }
184
185
    /**
186
     * @param SelectionSetNode $node
187
     * @return string
188
     */
189
    protected function printSelectionSet(SelectionSetNode $node): string
190
    {
191
        return block($this->many($node->getSelections()));
192
    }
193
194
    /**
195
     * @param FieldNode $node
196
     * @return string
197
     * @throws LanguageException
198
     */
199
    protected function printField(FieldNode $node): string
200
    {
201
        $alias        = $this->one($node->getAlias());
202
        $name         = $this->one($node->getName());
203
        $arguments    = $this->many($node->getArguments());
204
        $directives   = $this->many($node->getDirectives());
205
        $selectionSet = $this->one($node->getSelectionSet());
206
207
        return \implode(' ', [
208
            wrap('', $alias, ': ') . $name . wrap('(', \implode(', ', $arguments), ')'),
209
            \implode(' ', $directives),
210
            $selectionSet,
211
        ]);
212
    }
213
214
    /**
215
     * @param ArgumentNode $node
216
     * @return string
217
     * @throws LanguageException
218
     */
219
    protected function printArgument(ArgumentNode $node): string
220
    {
221
        $name  = $this->one($node->getName());
222
        $value = $this->one($node->getValue());
223
224
        return $name . ': ' . $value;
225
    }
226
227
    // Fragments
228
229
    /**
230
     * @param FragmentSpreadNode $node
231
     * @return string
232
     * @throws LanguageException
233
     */
234
    protected function printFragmentSpread(FragmentSpreadNode $node): string
235
    {
236
        $name       = $this->one($node->getName());
237
        $directives = $this->many($node->getDirectives());
238
239
        return '...' . $name . wrap(' ', \implode(' ', $directives));
240
    }
241
242
    /**
243
     * @param InlineFragmentNode $node
244
     * @return string
245
     * @throws LanguageException
246
     */
247
    protected function printInlineFragment(InlineFragmentNode $node): string
248
    {
249
        $typeCondition = $this->one($node->getTypeCondition());
250
        $directives    = $this->many($node->getDirectives());
251
        $selectionSet  = $this->one($node->getSelectionSet());
252
253
        return \implode(' ', [
254
            '...', wrap('on ', $typeCondition),
255
            \implode(' ', $directives),
256
            $selectionSet
257
        ]);
258
    }
259
260
    /**
261
     * @param FragmentDefinitionNode $node
262
     * @return string
263
     * @throws LanguageException
264
     */
265
    protected function printFragmentDefinition(FragmentDefinitionNode $node): string
266
    {
267
        $name                = $this->one($node->getName());
268
        $typeCondition       = $this->one($node->getTypeCondition());
269
        $variableDefinitions = $this->many($node->getVariableDefinitions());
270
        $directives          = $this->many($node->getDirectives());
271
        $selectionSet        = $this->one($node->getSelectionSet());
272
273
        // Note: fragment variable definitions are experimental and may be changed
274
        // or removed in the future.
275
        return \implode(' ', [
276
            'fragment ' . $name . wrap('(', \implode(', ', $variableDefinitions), ')'),
277
            'on ' . $typeCondition . ' ' . \implode(' ', $directives),
278
            $selectionSet
279
        ]);
280
    }
281
282
    // Value
283
284
    /**
285
     * @param IntValueNode $node
286
     * @return string
287
     */
288
    protected function printIntValue(IntValueNode $node): string
289
    {
290
        return $node->getValue();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $node->getValue() could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
291
    }
292
293
    /**
294
     * @param FloatValueNode $node
295
     * @return string
296
     */
297
    protected function printFloatValue(FloatValueNode $node): string
298
    {
299
        return $node->getValue();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $node->getValue() could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
300
    }
301
302
    /**
303
     * @param StringValueNode $node
304
     * @return string
305
     */
306
    protected function printStringValue(StringValueNode $node): string
307
    {
308
        $value = $node->getValue();
309
310
        return $node->isBlock()
0 ignored issues
show
Bug Best Practice introduced by
The expression return $node->isBlock() ...JSON_UNESCAPED_UNICODE) could return the type null|string[] which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
311
            ? printBlockString($value, false)
312
            : \json_encode($value, JSON_UNESCAPED_UNICODE);
313
    }
314
315
    /**
316
     * @param BooleanValueNode $node
317
     * @return string
318
     */
319
    protected function printBooleanValue(BooleanValueNode $node): string
320
    {
321
        return $node->getValue() ? 'true' : 'false';
322
    }
323
324
    /**
325
     * @param NullValueNode $node
326
     * @return string
327
     */
328
    protected function printNullValue(NullValueNode $node): string
0 ignored issues
show
Unused Code introduced by
The parameter $node is not used and could be removed. ( Ignorable by Annotation )

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

328
    protected function printNullValue(/** @scrutinizer ignore-unused */ NullValueNode $node): string

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
329
    {
330
        return 'null';
331
    }
332
333
    /**
334
     * @param EnumValueNode $node
335
     * @return string
336
     */
337
    protected function printEnumValue(EnumValueNode $node): string
338
    {
339
        return $node->getValue();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $node->getValue() could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
340
    }
341
342
    /**
343
     * @param ListValueNode $node
344
     * @return string
345
     */
346
    protected function printListValue(ListValueNode $node): string
347
    {
348
        $values = $this->many($node->getValues());
349
        return wrap('[', \implode(', ', $values), ']');
350
    }
351
352
    /**
353
     * @param ObjectValueNode $node
354
     * @return string
355
     */
356
    protected function printObjectValue(ObjectValueNode $node): string
357
    {
358
        $fields = $this->many($node->getFields());
359
        return wrap('{', \implode(', ', $fields), '}');
360
    }
361
362
    /**
363
     * @param ObjectFieldNode $node
364
     * @return string
365
     * @throws LanguageException
366
     */
367
    protected function printObjectField(ObjectFieldNode $node): string
368
    {
369
        $name  = $this->one($node->getName());
370
        $value = $this->one($node->getValue());
371
372
        return $name . ': ' . $value;
373
    }
374
375
    // Directive
376
377
    /**
378
     * @param DirectiveNode $node
379
     * @return string
380
     * @throws LanguageException
381
     */
382
    protected function printDirective(DirectiveNode $node): string
383
    {
384
        $name      = $this->one($node->getName());
385
        $arguments = $this->many($node->getArguments());
386
387
        return '@' . $name . wrap('(', \implode(', ', $arguments), ')');
388
    }
389
390
    // Type
391
392
    /**
393
     * @param NamedTypeNode $node
394
     * @return string
395
     * @throws LanguageException
396
     */
397
    protected function printNamedType(NamedTypeNode $node): string
398
    {
399
        return $this->one($node->getName());
400
    }
401
402
    /**
403
     * @param ListTypeNode $node
404
     * @return string
405
     * @throws LanguageException
406
     */
407
    protected function printListType(ListTypeNode $node): string
408
    {
409
        return wrap('[', $this->one($node->getType()), ']');
410
    }
411
412
    /**
413
     * @param NonNullTypeNode $node
414
     * @return string
415
     * @throws LanguageException
416
     */
417
    protected function printNonNullType(NonNullTypeNode $node): string
418
    {
419
        return $this->one($node->getType()) . '!';
420
    }
421
422
    /**
423
     * @param NodeInterface|null $node
424
     * @return string
425
     * @throws LanguageException
426
     */
427
    protected function one(?NodeInterface $node): string
428
    {
429
        return null !== $node ? $this->print($node) : '';
430
    }
431
432
    /**
433
     * @param array $nodes
434
     * @return array
435
     */
436
    protected function many(array $nodes): array
437
    {
438
        return \array_map(function ($node) {
439
            return $this->print($node);
440
        }, $nodes);
441
    }
442
}
443