Skip to content

Commit 7b2c03b

Browse files
committed
@deprecated multiline support.
1 parent 04561aa commit 7b2c03b

File tree

2 files changed

+86
-21
lines changed

2 files changed

+86
-21
lines changed

src/Utils/SchemaPrinter.php

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use GraphQL\Language\AST\ScalarTypeDefinitionNode;
1616
use GraphQL\Language\AST\ValueNode;
1717
use GraphQL\Language\BlockString;
18+
use GraphQL\Language\Parser;
1819
use GraphQL\Language\Printer;
1920
use GraphQL\Type\Definition\Directive;
2021
use GraphQL\Type\Definition\EnumType;
@@ -42,6 +43,7 @@
4243
use function implode;
4344
use function is_callable;
4445
use function is_string;
46+
use function json_encode;
4547
use function ksort;
4648
use function ltrim;
4749
use function mb_strlen;
@@ -383,12 +385,12 @@ protected static function printField(FieldDefinition $type, array $options, stri
383385
*/
384386
protected static function printDeprecated($fieldOrEnumVal): string
385387
{
386-
$reason = $fieldOrEnumVal->deprecationReason;
388+
$reason = static::getDeprecatedReason($fieldOrEnumVal);
387389
if ($reason === null) {
388390
return '';
389391
}
390392

391-
if ($reason === '' || $reason === Directive::DEFAULT_DEPRECATION_REASON) {
393+
if ($reason === '') {
392394
return ' @deprecated';
393395
}
394396

@@ -529,41 +531,47 @@ protected static function printBlock(array $items): string
529531
protected static function printTypeDirectives($type, array $options, string $indentation = ''): string {
530532
// Enabled?
531533
$filter = $options['printDirectives'] ?? null;
534+
$deprecatable = $type instanceof EnumValueDefinition || $type instanceof FieldDefinition;
532535

533536
if (!is_callable($filter)) {
534-
if ($type instanceof EnumValueDefinition || $type instanceof FieldDefinition) {
537+
if ($deprecatable) {
535538
return static::printDeprecated($type);
536539
}
537540

538541
return '';
539542
}
540543

541-
// AST Node available and has directives?
544+
// Collect directives
542545
$node = $type->astNode;
546+
$nodeDirectives = [];
547+
548+
if ($node !== null) {
549+
$nodeDirectives = $node->directives;
550+
} elseif ($deprecatable && $type->deprecationReason !== null) {
551+
// TODO Is there a better way to create directive node?
552+
$name = Directive::DEPRECATED_NAME;
553+
$reason = json_encode(static::getDeprecatedReason($type));
554+
$nodeDirectives[] = Parser::directive("@{$name}(reason: {$reason})");
555+
} else {
556+
// empty
557+
}
543558

544-
if ($node === null) {
559+
if (count($nodeDirectives) === 0) {
545560
return '';
546561
}
547562

548563
// Print
549564
$length = 0;
550565
$directives = [];
551566

552-
foreach ($node->directives as $directive) {
553-
$string = null;
554-
555-
if ($directive->name === Directive::DEPRECATED_NAME && ($type instanceof EnumValueDefinition)) {
556-
$string = static::printDeprecated($type);
557-
} elseif ($filter($directive)) {
558-
$string = static::printTypeDirective($directive, $options, $indentation);
559-
} else {
560-
// empty
567+
foreach ($nodeDirectives as $nodeDirective) {
568+
if (!$filter($nodeDirective)) {
569+
continue;
561570
}
562571

563-
if ($string !== null) {
564-
$length = $length + mb_strlen($string);
565-
$directives[] = $string;
566-
}
572+
$directive = static::printTypeDirective($nodeDirective, $options, $indentation);
573+
$length = $length + mb_strlen($directive);
574+
$directives[] = $directive;
567575
}
568576

569577
// Multiline?
@@ -637,7 +645,7 @@ protected static function printLines(array $lines, string $begin, string $end, b
637645
$wrapped = false;
638646

639647
for ($i = 0, $c = count($lines); $i < $c; $i++) {
640-
// If line too long and contains LF we wrap it by empty lines
648+
// If line contains LF we wrap it by empty lines
641649
$line = trim($lines[$i], "\n");
642650
$wrap = mb_strpos($line, "\n") !== false;
643651

@@ -670,4 +678,18 @@ protected static function printLines(array $lines, string $begin, string $end, b
670678
protected static function isLineTooLong($string): bool {
671679
return (is_string($string) ? mb_strlen($string) : $string) > static::LINE_LENGTH;
672680
}
681+
682+
/**
683+
* @param FieldDefinition|EnumValueDefinition $fieldOrEnumVal
684+
*/
685+
protected static function getDeprecatedReason($fieldOrEnumVal): ?string
686+
{
687+
$reason = $fieldOrEnumVal->deprecationReason;
688+
689+
if ($reason === '' || $reason === Directive::DEFAULT_DEPRECATION_REASON) {
690+
$reason = '';
691+
}
692+
693+
return $reason;
694+
}
673695
}

tests/Utils/SchemaPrinterTest.php

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,7 +1277,7 @@ enum __TypeKind {
12771277
self::assertEquals($expected, $output);
12781278
}
12791279

1280-
public function testPrintDirectives(): void {
1280+
public function testPrintDirectivesAst(): void {
12811281
$text = str_pad('a', 80, 'a');
12821282
$schema = /** @lang GraphQL */ <<<GRAPHQL
12831283
directive @test(
@@ -1301,7 +1301,7 @@ public function testPrintDirectives(): void {
13011301
13021302
enum EnumA @test {
13031303
a @test @deprecated
1304-
b @test(value: "{$text}")
1304+
b @test(value: "{$text}") @deprecated(reason: "{$text}")
13051305
"{$text}"
13061306
c @test
13071307
"{$text}"
@@ -1389,6 +1389,9 @@ enum EnumA @test {
13891389
@test(
13901390
value: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
13911391
)
1392+
@deprecated(
1393+
reason: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1394+
)
13921395
13931396
"""
13941397
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -1576,4 +1579,44 @@ interface InterfaceB implements InterfaceA
15761579

15771580
self::assertEquals($expected, $actual);
15781581
}
1582+
1583+
public function testPrintDirectivesDeprecated(): void {
1584+
$text = str_pad('a', 80, 'a');
1585+
$enum = new EnumType([
1586+
'name' => 'Aaa',
1587+
'values' => [
1588+
'A' => [
1589+
'value' => 'AAA',
1590+
'description' => 'AAAAAAAAAAAAA',
1591+
'deprecationReason' => 'deprecated for tests'
1592+
],
1593+
'B' => [
1594+
'value' => 'AAA',
1595+
'deprecationReason' => $text
1596+
],
1597+
]
1598+
]);
1599+
$schema = new Schema(['types' => [$enum]]);
1600+
$actual = SchemaPrinter::doPrint($schema, [
1601+
'printDirectives' => static function(): bool {
1602+
return true;
1603+
},
1604+
]);
1605+
1606+
self::assertEquals(
1607+
<<<'GRAPHQL'
1608+
enum Aaa {
1609+
"""AAAAAAAAAAAAA"""
1610+
A @deprecated(reason: "deprecated for tests")
1611+
1612+
B
1613+
@deprecated(
1614+
reason: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
1615+
)
1616+
}
1617+
1618+
GRAPHQL,
1619+
$actual
1620+
);
1621+
}
15791622
}

0 commit comments

Comments
 (0)