File Coverage

blib/lib/GraphQL/Language/Receiver.pm
Criterion Covered Total %
statement 536 544 98.5
branch 238 458 51.9
condition 18 20 90.0
subroutine 63 64 98.4
pod 1 52 1.9
total 856 1138 75.2


line stmt bran cond sub pod time code
1             package GraphQL::Language::Receiver;
2              
3 21     21   459 use 5.014;
  21         76  
4 21     21   114 use strict;
  21         47  
  21         462  
5 21     21   105 use warnings;
  21         51  
  21         595  
6 21     21   112 use base 'Pegex::Receiver';
  21         51  
  21         8392  
7 21     21   32096 use Types::Standard -all;
  21         55  
  21         212  
8 21     21   915919 use GraphQL::MaybeTypeCheck;
  21         174  
  21         589  
9 21     21   687 use JSON::MaybeXS;
  21         3750  
  263         3301  
10 263     21   510 use Carp;
  263         864  
  263         11162  
11              
12             my $JSON = JSON::MaybeXS->new->allow_nonref->canonical;
13              
14             my @KINDHASH = qw(
15             scalar
16             union
17             field
18             inline_fragment
19             fragment_spread
20             fragment
21             directive
22             );
23             my %KINDHASH21 = map { ($_ => 1) } @KINDHASH;
24              
25             my @KINDFIELDS = qw(
26             type
27             input
28             interface
29             );
30             my %KINDFIELDS21 = map { ($_ => 1) } @KINDFIELDS;
31              
32             =head1 NAME
33              
34             GraphQL::Language::Receiver - GraphQL Pegex AST constructor
35              
36             =head1 VERSION
37              
38             Version 0.02
39              
40             =cut
41              
42             our $VERSION = '0.02';
43              
44             =head1 SYNOPSIS
45              
46             # this class used internally by:
47             use GraphQL::Language::Parser qw(parse);
48             my $parsed = parse($source);
49              
50             =head1 DESCRIPTION
51              
52             Subclass of L<Pegex::Receiver> to turn Pegex parsing events into data
53             usable by GraphQL.
54              
55             =cut
56              
57 10492 50   10492 1 2033376 method gotrule (Any $param = undef) {
  10492 50       18044  
  10492 50       13718  
  10492         15069  
  10492         22937  
  10492         66272  
58 10492 100       22851 return unless defined $param;
59 4399 100       13676 if ($KINDHASH21{$self->{parser}{rule}}) {
    100          
60 878         1685 return {kind => $self->{parser}{rule}, %{$self->_locate_hash(_merge_hash($param))}};
  878         2144  
61             } elsif ($KINDFIELDS21{$self->{parser}{rule}}) {
62 107         216 return {kind => $self->{parser}{rule}, %{$self->_locate_hash(_merge_hash($param, 'fields'))}};
  107         277  
63             }
64 3414         12494 return {$self->{parser}{rule} => $param};
65             }
66              
67 1321 50   1321   2809 method _locate_hash(HashRef $hash) {
  1321 50       2684  
  1321 50       1890  
  1321         2044  
  1321         2823  
  1079         8659  
68 1079         1503 my ($line, $column) = @{$self->{parser}->line_column($self->{parser}{farthest})};
  1079         4616  
69 1079         41378 +{ %$hash, location => { line => $line, column => $column } };
70             }
71              
72 1625 50   1625   3466 fun _merge_hash (Any $param = undef, Any $arraykey = undef) {
  1625 50       3004  
  1625 50       3172  
  1625         10281  
  1625         9090  
73 1625         10889 my %def = map %$_, grep ref eq 'HASH', @$param;
74 1625 100       4110 if ($arraykey) {
75 107         420 my @arrays = grep ref eq 'ARRAY', @$param;
76 107 50       371 Carp::confess "More than one array found\n" if @arrays > 1;
77 107 50       345 Carp::confess "No arrays found but \$arraykey given\n" if !@arrays;
78 107         187 my %fields = map %$_, @{$arrays[0]};
  107         449  
79 107         372 $def{$arraykey} = \%fields;
80             }
81 1625         4997 \%def;
82             }
83              
84 65 50   65   224 fun _unescape (Str $str) {
  65 50       211  
  65 50       153  
  65         201  
  65         766  
85             # https://facebook.github.io/graphql/June2018/#EscapedCharacter
86 65         189 $str =~ s|\\(["\\/bfnrt])|"qq!\\$1!"|gee;
  1         84  
87 65         247 return $str;
88             }
89              
90 14 50   14   44 fun _blockstring_value (Str $str) {
  14 50       30  
  14 50       32  
  14         31  
  14         142  
91             # https://facebook.github.io/graphql/June2018/#BlockStringValue()
92 14         152 my @lines = split(/(?:\n|\r(?!\r)|\r\n)/s, $str);
93 14 100       42 if (1 < @lines) {
94 12         18 my $common_indent;
95 12         42 for my $line (@lines[1..$#lines]) {
96 46         60 my $length = length($line);
97 46   100     174 my $indent = length(($line =~ /^([\t ]*)/)[0] || '');
98 46 100 100     158 if ($indent < $length && (!defined($common_indent) || $indent < $common_indent)) {
      100        
99 13         27 $common_indent = $indent;
100             }
101             }
102 12 50       71 if (defined $common_indent) {
103 12         35 for my $line (@lines[1..$#lines]) {
104 46         389 $line =~ s/^[\t ]{$common_indent}//;
105             }
106             }
107             }
108 14         31 my ($start, $end);
109 14   66     146 for ($start = 0; $start < @lines && $lines[$start] =~ /^[\t ]*$/; ++$start) {}
110 14   66     112 for ($end = $#lines; $end >= 0 && $lines[$end] =~ /^[\t ]*$/; --$end) {}
111 14         50 @lines = @lines[$start..$end];
112 14         46 my $formatted = join("\n", @lines);
113 14         36 $formatted =~ s/\\"""/"""/g;
114 14         58 return $formatted;
115             }
116              
117 185 50   185 0 25330 method got_arguments (Any $param = undef) {
  185 50       461  
  185 50       312  
  185         358  
  185         518  
  185         1197  
118 185 50       432 return unless defined $param;
119 185         424 my %args = map { ($_->[0]{name} => $_->[1]) } @$param;
  196         1269  
120 185         1032 return {$self->{parser}{rule} => \%args};
121             }
122              
123 201 50   201 0 7246 method got_argument (Any $param = undef) {
  201 50       597  
  201 50       340  
  201         457  
  201         563  
  201         1208  
124 201 50       459 return unless defined $param;
125 201         565 $param;
126             }
127              
128 27 50   27 0 847 method got_objectField (Any $param = undef) {
  27 50       89  
  27 50       51  
  27         56  
  27         65  
  27         184  
129 27 50       62 return unless defined $param;
130 27         154 return {$param->[0]{name} => $param->[1]};
131             }
132              
133 14 50   14 0 1906 method got_objectValue (Any $param = undef) {
  14 50       53  
  14 50       34  
  14         29  
  14         47  
  14         105  
134 14 50       50 return unless defined $param;
135 14         54 _merge_hash($param);
136             }
137              
138 4 50   4 0 155 method got_objectField_const (Any $param = undef) {
  4 50       12  
  4 50       9  
  4         8  
  4         36  
  4         31  
139 4         9 unshift @_, $self; goto &got_objectField;
  4         17  
140             }
141              
142 2 50   2 0 315 method got_objectValue_const (Any $param = undef) {
  2 50       9  
  2 50       4  
  2         5  
  2         8  
  2         17  
143 2         3 unshift @_, $self; goto &got_objectValue;
  2         8  
144             }
145              
146 9 50   9 0 4727 method got_listValue (Any $param = undef) {
  9 50       31  
  9 50       27  
  9         40  
  9         44  
  9         71  
147 9 50       27 return unless defined $param;
148 9         41 return $param;
149             }
150              
151 2 50   2 0 1271 method got_listValue_const (Any $param = undef) {
  2 50       10  
  2 50       5  
  2         5  
  2         8  
  2         17  
152 2         5 unshift @_, $self; goto &got_listValue;
  2         10  
153             }
154              
155 74 50   74 0 4915 method got_directiveactual (Any $param = undef) {
  74 50       172  
  74 50       107  
  74         119  
  74         169  
  74         464  
156 74 50       150 return unless defined $param;
157 74         174 _merge_hash($param);
158             }
159              
160 66 50   66 0 2363 method got_inputValueDefinition (Any $param = undef) {
  66 50       184  
  66 50       109  
  66         115  
  66         170  
  66         438  
161 66 50       148 return unless defined $param;
162 66         187 my $def = _merge_hash($param);
163 66         191 my $name = delete $def->{name};
164 66         358 return { $name => $def };
165             }
166              
167 12 50   12 0 1459 method got_directiveLocations (Any $param = undef) {
  12 50       49  
  12 50       28  
  12         27  
  12         43  
  12         106  
168 12 50       42 return unless defined $param;
169 12         101 return {locations => [ map $_->{name}, @$param ]};
170             }
171              
172 597 50   597 0 21392 method got_namedType (Any $param = undef) {
  597 50       1359  
  597 50       940  
  597         1023  
  597         1303  
  597         3662  
173 597 50       1270 return unless defined $param;
174 597         2305 return $param->{name};
175             }
176              
177 28 50   28 0 3577 method got_enumValueDefinition (Any $param = undef) {
  28 50       79  
  28 50       50  
  28         49  
  28         87  
  28         199  
178 28 50       73 return unless defined $param;
179 28         67 my @copy = @$param;
180 28         51 my $rest = pop @copy;
181 28         44 my $value = pop @copy;
182 28   100     107 my $description = $copy[0] // {};
183 28 100       86 $rest = ref $rest eq 'HASH' ? [ $rest ] : $rest;
184 28         118 my %def = (%$description, value => $value, map %$_, @$rest);
185 28         119 return \%def;
186             }
187              
188 16 50   16 0 551 method got_defaultValue (Any $param = undef) {
  16 50       42  
  16 50       28  
  16         46  
  16         58  
  16         119  
189             # the value can be undef
190 16         66 return { default_value => $param };
191             }
192              
193 8 50   8 0 908 method got_implementsInterfaces (Any $param = undef) {
  8 50       32  
  8 50       19  
  8         20  
  8         222  
  8         75  
194 8 50       29 return unless defined $param;
195 8         38 return { interfaces => $param };
196             }
197              
198 46 50   46 0 6501 method got_argumentsDefinition (Any $param = undef) {
  46 50       132  
  46 50       82  
  46         88  
  46         130  
  46         326  
199 46 50       137 return unless defined $param;
200 46         110 return { args => _merge_hash($param) };
201             }
202              
203 118 50   118 0 14357 method got_fieldDefinition (Any $param = undef) {
  118 50       309  
  118 50       225  
  118         214  
  118         365  
  118         861  
204 118 50       365 return unless defined $param;
205 118         436 my $def = _merge_hash($param);
206 118         332 my $name = delete $def->{name};
207 118         710 return { $name => $def };
208             }
209              
210 14 50   14 0 627 method got_typeExtensionDefinition (Any $param = undef) {
  14 50       28  
  14 50       17  
  14         35  
  14         33  
  14         82  
211 14 50       24 return unless defined $param;
212 14         16 return {kind => 'extend', %{$self->_locate_hash($param)}};
  14         26  
213             }
214              
215 17 50   17 0 3913 method got_enumTypeDefinition (Any $param = undef) {
  17 50       42  
  17 50       30  
  17         33  
  17         53  
  17         120  
216 17 50       51 return unless defined $param;
217 17         49 my $def = _merge_hash($param);
218 17         34 my %values;
219             map {
220 28         40 my $name = ${${delete $_->{value}}};
  28         37  
  28         64  
221 28         88 $values{$name} = $_;
222 17         27 } @{(grep ref eq 'ARRAY', @$param)[0]};
  17         64  
223 17         50 $def->{values} = \%values;
224 17         31 return {kind => 'enum', %{$self->_locate_hash($def)}};
  17         52  
225             }
226              
227 11 50   11 0 1273 method got_unionMembers (Any $param = undef) {
  11 50       42  
  11 50       40  
  11         24  
  11         35  
  11         95  
228 11 50       35 return unless defined $param;
229 11         47 return { types => $param };
230             }
231              
232 42 50   42 0 14722 method got_boolean (Any $param = undef) {
  42 50       121  
  42 50       88  
  42         76  
  42         119  
  42         268  
233 42 50       114 return unless defined $param;
234 42 100       219 return $param eq 'true' ? JSON->true : JSON->false;
235             }
236              
237 6 50   6 0 2459 method got_null (Any $param = undef) {
  6 50       31  
  6 50       13  
  6         17  
  6         20  
  6         45  
238 6 50       17 return unless defined $param;
239 6         18 return undef;
240             }
241              
242 79 50   79 0 2760 method got_string (Any $param = undef) {
  79 50       216  
  79 50       153  
  79         178  
  79         251  
  79         577  
243 79 50       200 return unless defined $param;
244 79         236 return $param;
245             }
246              
247 65 50   65 0 25712 method got_stringValue (Any $param = undef) {
  65 50       197  
  65 50       138  
  65         156  
  65         227  
  65         523  
248 65 50       181 return unless defined $param;
249 65         221 return _unescape($param);
250             }
251              
252 14 50   14 0 4157 method got_blockStringValue (Any $param = undef) {
  14 50       39  
  14 50       22  
  14         25  
  14         47  
  14         96  
253 14 50       32 return unless defined $param;
254 14         82 return _blockstring_value($param);
255             }
256              
257 27 50   27 0 7469 method got_int (Any $param = undef) {
  27 50       96  
  27 50       60  
  27         80  
  27         112  
  27         211  
258 27         144 $param+0;
259             }
260              
261 15 50   15 0 2585 method got_float (Any $param = undef) {
  15 50       45  
  15 50       20  
  15         22  
  15         50  
  15         95  
262 15         71 $param+0;
263             }
264              
265 45 50   45 0 1387 method got_enumValue (Any $param = undef) {
  45 50       140  
  45 50       69  
  45         83  
  45         120  
  45         282  
266 45 50       96 return unless defined $param;
267 45         94 my $varname = $param->{name};
268 45         163 return \\$varname;
269             }
270              
271             # not returning empty list if undef
272 1080 50   1080 0 3051 method got_value_const (Any $param = undef) {
  1080 50       2050  
  1080 50       1536  
  1080         1848  
  1080         2308  
  1080         6038  
273 1080         2926 return $param;
274             }
275              
276 237 50   237 0 7974 method got_value (Any $param = undef) {
  237 50       623  
  237 50       378  
  237         465  
  237         545  
  237         1441  
277 237         619 unshift @_, $self; goto &got_value_const;
  237         893  
278             }
279              
280 54 50   54 0 9531 method got_variableDefinitions (Any $param = undef) {
  54 50       173  
  54 50       126  
  54         166  
  54         185  
  54         386  
281 54 50       158 return unless defined $param;
282 54         103 my %def;
283             map {
284 54         126 my $name = ${ shift @$_ };
  55         92  
  55         139  
285 55         486 $def{$name} = { map %$_, @$_ }; # merge
286             } @$param;
287 54         343 return {variables => \%def};
288             }
289              
290 55 50   55 0 1912 method got_variableDefinition (Any $param = undef) {
  55 50       191  
  55 50       110  
  55         122  
  55         174  
  55         360  
291 55 50       170 return unless defined $param;
292 55         157 return $param;
293             }
294              
295 820 50   820 0 27302 method got_selection (Any $param = undef) {
  820 50       1699  
  820 50       1234  
  820         1341  
  820         2205  
  820         4889  
296 820         1508 unshift @_, $self; goto &got_value_const;
  820         2406  
297             }
298              
299 278 50   278 0 9150 method got_typedef (Any $param = undef) {
  278 50       653  
  278 50       440  
  278         580  
  278         761  
  278         1866  
300 278 50       648 return unless defined $param;
301 278 50       790 $param = $param->{name} if ref($param) eq 'HASH';
302 278         997 return {type => $param};
303             }
304              
305 30 50   30 0 2157 method got_alias (Any $param = undef) {
  30 50       89  
  30 50       50  
  30         63  
  30         84  
  30         200  
306 30 50       86 return unless defined $param;
307 30         134 return {$self->{parser}{rule} => $param->{name}};
308             }
309              
310 50 50   50 0 1722 method got_typeCondition (Any $param = undef) {
  50 50       160  
  50 50       89  
  50         91  
  50         118  
  50         317  
311 50 50       145 return unless defined $param;
312 50         178 return {on => $param};
313             }
314              
315 66 50   66 0 1984 method got_fragmentName (Any $param = undef) {
  66 50       142  
  66 50       104  
  66         117  
  66         158  
  66         386  
316 66 50       195 return unless defined $param;
317 66         191 return $param;
318             }
319              
320 563 50   563 0 265467 method got_selectionSet (Any $param = undef) {
  563 50       1294  
  563 50       972  
  563         1032  
  563         1633  
  563         3842  
321 563 50       1203 return unless defined $param;
322 563         2044 return {selections => $param};
323             }
324              
325 264 50   264 0 10895 method got_operationDefinition (Any $param = undef) {
  264 50       703  
  264 50       508  
  264         496  
  264         756  
  264         1690  
326 264 50       664 return unless defined $param;
327 264 100       968 $param = [ $param ] unless ref $param eq 'ARRAY'; # bare selectionSet
328 264         546 return {kind => 'operation', %{$self->_locate_hash(_merge_hash($param))}};
  264         654  
329             }
330              
331 71 50   71 0 5211 method got_directives (Any $param = undef) {
  71 50       148  
  71 50       103  
  71         132  
  71         185  
  71         562  
332 71 50       139 return unless defined $param;
333 71         252 return {$self->{parser}{rule} => $param};
334             }
335              
336 323 50   323 0 219966 method got_graphql (Any $param = undef) {
  323 50       1026  
  323 50       618  
  323         682  
  323         1057  
  323         2376  
337 323 50       899 return unless defined $param;
338 323         1110 return $param;
339             }
340              
341 590 50   590 0 20365 method got_definition (Any $param = undef) {
  590 50       1581  
  590 50       1047  
  590         1160  
  590         1560  
  590         3938  
342 590 100       1720 return unless defined $param;
343 487         1356 return $param;
344             }
345              
346 54 50   54 0 2188 method got_operationTypeDefinition (Any $param = undef) {
  54 50       228  
  54 50       100  
  54         118  
  54         173  
  54         419  
347 54 50       188 return unless defined $param;
348 54 100       134 return { map { ref($_) ? values %$_ : $_ } @$param };
  108         685  
349             }
350              
351 0 0   0 0 0 method got_comment (Any $param = undef) {
  0 0       0  
  0 0       0  
  0         0  
  0         0  
  0         0  
352 0 0       0 return unless defined $param;
353 0         0 return $param;
354             }
355              
356 1026 50   1026 0 33078 method got_description (Any $param = undef) {
  1026 50       2267  
  1026 50       1621  
  1026         1774  
  1026         2285  
  1026         6318  
357 1026 100       3144 return unless defined $param;
358 16 50       46 my $string = ref($param) eq 'ARRAY' ? join("\n", @$param) : $param;
359 16 50       81 return $string ? {$self->{parser}{rule} => $string} : {};
360             }
361              
362 44 50   44 0 7795 method got_schema (Any $param = undef) {
  44 50       160  
  44 50       108  
  44         122  
  44         168  
  44         351  
363 44 50       154 return unless defined $param;
364 44         169 my $directives = {};
365 44 100       217 if (ref $param->[1] eq 'ARRAY') {
366             # got directives
367 3         8 $directives = shift @$param;
368             }
369 44         140 my %type2count;
370 44         82 $type2count{(keys %$_)[0]}++ for @{$param->[0]};
  44         390  
371             $type2count{$_} > 1 and die "Must provide only one $_ type in schema.\n"
372 44   100     488 for keys %type2count;
373 41         121 return {kind => $self->{parser}{rule}, %{$self->_locate_hash(_merge_hash($param->[0]))}, %$directives};
  41         170  
374             }
375              
376 196 50   196 0 10641 method got_typeSystemDefinition (Any $param = undef) {
  196 50       581  
  196 50       447  
  196         361  
  196         525  
  196         1387  
377 196 50       449 return unless defined $param;
378 196         497 my @copy = @$param;
379 196         340 my $node = pop @copy;
380 196   100     1049 my $description = $copy[0] // {};
381 196         1459 +{ %$node, %$description };
382             }
383              
384 143 50   143 0 5127 method got_typeDefinition (Any $param = undef) {
  143 50       407  
  143 50       282  
  143         259  
  143         378  
  143         1044  
385 143 50       350 return unless defined $param;
386 143         424 return $param;
387             }
388              
389 123 50   123 0 4468 method got_variable (Any $param = undef) {
  123 50       355  
  123 50       211  
  123         313  
  123         309  
  123         1082  
390 123 50       318 return unless defined $param;
391 123         293 my $varname = $param->{name};
392 123         446 return \$varname;
393             }
394              
395 54 50   54 0 4723 method got_nonNullType (Any $param = undef) {
  54 50       151  
  54 50       110  
  54         128  
  54         164  
  54         382  
396 54 50       141 return unless defined $param;
397 54         129 $param = $param->[0]; # zap first useless layer
398 54 50       210 $param = { type => $param } if ref $param ne 'HASH';
399 54         200 return [ 'non_null', $param ];
400             }
401              
402 38 50   38 0 1344 method got_listType (Any $param = undef) {
  38 50       100  
  38 50       65  
  38         80  
  38         107  
  38         231  
403 38 50       99 return unless defined $param;
404 38         75 $param = $param->[0]; # zap first useless layer
405 38 50       111 $param = { type => $param } if ref $param ne 'HASH';
406 38         149 return [ 'list', $param ];
407             }
408              
409             1;