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              
2             use 5.014;
3 21     21   427 use strict;
  21         69  
4 21     21   110 use warnings;
  21         51  
  21         418  
5 21     21   91 use base 'Pegex::Receiver';
  21         45  
  21         557  
6 21     21   108 use Types::Standard -all;
  21         43  
  21         7617  
7 21     21   28804 use GraphQL::MaybeTypeCheck;
  21         64  
  21         168  
8 21     21   835074 use JSON::MaybeXS;
  21         152  
  21         502  
9 21     21   513 use Carp;
  21         3505  
  263         3595  
10 263     21   542  
  263         1167  
  263         11758  
11             my $JSON = JSON::MaybeXS->new->allow_nonref->canonical;
12              
13             my @KINDHASH = qw(
14             scalar
15             union
16             field
17             inline_fragment
18             fragment_spread
19             fragment
20             directive
21             );
22             my %KINDHASH21 = map { ($_ => 1) } @KINDHASH;
23              
24             my @KINDFIELDS = qw(
25             type
26             input
27             interface
28             );
29             my %KINDFIELDS21 = map { ($_ => 1) } @KINDFIELDS;
30              
31             =head1 NAME
32              
33             GraphQL::Language::Receiver - GraphQL Pegex AST constructor
34              
35             =head1 VERSION
36              
37             Version 0.02
38              
39             =cut
40              
41             our $VERSION = '0.02';
42              
43             =head1 SYNOPSIS
44              
45             # this class used internally by:
46             use GraphQL::Language::Parser qw(parse);
47             my $parsed = parse($source);
48              
49             =head1 DESCRIPTION
50              
51             Subclass of L<Pegex::Receiver> to turn Pegex parsing events into data
52             usable by GraphQL.
53              
54             =cut
55              
56             method gotrule (Any $param = undef) {
57 10492 50   10492 1 1865267 return unless defined $param;
  10492 50       16143  
  10492 50       12604  
  10492         14235  
  10492         21411  
  10492         60460  
58 10492 100       21321 if ($KINDHASH21{$self->{parser}{rule}}) {
59 4399 100       12759 return {kind => $self->{parser}{rule}, %{$self->_locate_hash(_merge_hash($param))}};
    100          
60 878         1682 } elsif ($KINDFIELDS21{$self->{parser}{rule}}) {
  878         2052  
61             return {kind => $self->{parser}{rule}, %{$self->_locate_hash(_merge_hash($param, 'fields'))}};
62 107         268 }
  107         234  
63             return {$self->{parser}{rule} => $param};
64 3414         11585 }
65              
66             method _locate_hash(HashRef $hash) {
67 1321 50   1321   2647 my ($line, $column) = @{$self->{parser}->line_column($self->{parser}{farthest})};
  1321 50       2398  
  1321 50       1753  
  1321         1977  
  1321         2570  
  1079         7656  
68 1079         1350 +{ %$hash, location => { line => $line, column => $column } };
  1079         3584  
69 1079         37376 }
70              
71             fun _merge_hash (Any $param = undef, Any $arraykey = undef) {
72 1625 50   1625   3190 my %def = map %$_, grep ref eq 'HASH', @$param;
  1625 50       2782  
  1625 50       3006  
  1625         9465  
  1625         8181  
73 1625         10031 if ($arraykey) {
74 1625 100       3748 my @arrays = grep ref eq 'ARRAY', @$param;
75 107         415 Carp::confess "More than one array found\n" if @arrays > 1;
76 107 50       303 Carp::confess "No arrays found but \$arraykey given\n" if !@arrays;
77 107 50       250 my %fields = map %$_, @{$arrays[0]};
78 107         153 $def{$arraykey} = \%fields;
  107         404  
79 107         386 }
80             \%def;
81 1625         4507 }
82              
83             fun _unescape (Str $str) {
84 65 50   65   163 # https://facebook.github.io/graphql/June2018/#EscapedCharacter
  65 50       153  
  65 50       131  
  65         168  
  65         705  
85             $str =~ s|\\(["\\/bfnrt])|"qq!\\$1!"|gee;
86 65         179 return $str;
  1         133  
87 65         221 }
88              
89             fun _blockstring_value (Str $str) {
90 14 50   14   33 # https://facebook.github.io/graphql/June2018/#BlockStringValue()
  14 50       36  
  14 50       30  
  14         45  
  14         139  
91             my @lines = split(/(?:\n|\r(?!\r)|\r\n)/s, $str);
92 14         137 if (1 < @lines) {
93 14 100       41 my $common_indent;
94 12         40 for my $line (@lines[1..$#lines]) {
95 12         45 my $length = length($line);
96 46         60 my $indent = length(($line =~ /^([\t ]*)/)[0] || '');
97 46   100     154 if ($indent < $length && (!defined($common_indent) || $indent < $common_indent)) {
98 46 100 100     181 $common_indent = $indent;
      100        
99 13         24 }
100             }
101             if (defined $common_indent) {
102 12 50       34 for my $line (@lines[1..$#lines]) {
103 12         30 $line =~ s/^[\t ]{$common_indent}//;
104 46         324 }
105             }
106             }
107             my ($start, $end);
108 14         26 for ($start = 0; $start < @lines && $lines[$start] =~ /^[\t ]*$/; ++$start) {}
109 14   66     139 for ($end = $#lines; $end >= 0 && $lines[$end] =~ /^[\t ]*$/; --$end) {}
110 14   66     128 @lines = @lines[$start..$end];
111 14         56 my $formatted = join("\n", @lines);
112 14         45 $formatted =~ s/\\"""/"""/g;
113 14         40 return $formatted;
114 14         64 }
115              
116             method got_arguments (Any $param = undef) {
117 185 50   185 0 24586 return unless defined $param;
  185 50       448  
  185 50       319  
  185         372  
  185         534  
  185         1203  
118 185 50       606 my %args = map { ($_->[0]{name} => $_->[1]) } @$param;
119 185         358 return {$self->{parser}{rule} => \%args};
  196         921  
120 185         965 }
121              
122             method got_argument (Any $param = undef) {
123 201 50   201 0 7034 return unless defined $param;
  201 50       460  
  201 50       356  
  201         439  
  201         537  
  201         1189  
124 201 50       424 $param;
125 201         492 }
126              
127             method got_objectField (Any $param = undef) {
128 27 50   27 0 787 return unless defined $param;
  27 50       77  
  27 50       41  
  27         44  
  27         75  
  27         162  
129 27 50       60 return {$param->[0]{name} => $param->[1]};
130 27         120 }
131              
132             method got_objectValue (Any $param = undef) {
133 14 50   14 0 1781 return unless defined $param;
  14 50       37  
  14 50       21  
  14         26  
  14         39  
  14         158  
134 14 50       40 _merge_hash($param);
135 14         51 }
136              
137             method got_objectField_const (Any $param = undef) {
138 4 50   4 0 152 unshift @_, $self; goto &got_objectField;
  4 50       12  
  4 50       7  
  4         17  
  4         13  
  4         27  
139 4         9 }
  4         13  
140              
141             method got_objectValue_const (Any $param = undef) {
142 2 50   2 0 284 unshift @_, $self; goto &got_objectValue;
  2 50       21  
  2 50       3  
  2         6  
  2         7  
  2         15  
143 2         6 }
  2         5  
144              
145             method got_listValue (Any $param = undef) {
146 9 50   9 0 4251 return unless defined $param;
  9 50       28  
  9 50       18  
  9         16  
  9         54  
  9         63  
147 9 50       24 return $param;
148 9         24 }
149              
150             method got_listValue_const (Any $param = undef) {
151 2 50   2 0 1152 unshift @_, $self; goto &got_listValue;
  2 50       7  
  2 50       5  
  2         4  
  2         9  
  2         17  
152 2         6 }
  2         8  
153              
154             method got_directiveactual (Any $param = undef) {
155 74 50   74 0 4750 return unless defined $param;
  74 50       156  
  74 50       120  
  74         119  
  74         188  
  74         439  
156 74 50       229 _merge_hash($param);
157 74         177 }
158              
159             method got_inputValueDefinition (Any $param = undef) {
160 66 50   66 0 2216 return unless defined $param;
  66 50       222  
  66 50       105  
  66         124  
  66         156  
  66         406  
161 66 50       148 my $def = _merge_hash($param);
162 66         164 my $name = delete $def->{name};
163 66         185 return { $name => $def };
164 66         350 }
165              
166             method got_directiveLocations (Any $param = undef) {
167 12 50   12 0 1267 return unless defined $param;
  12 50       49  
  12 50       24  
  12         21  
  12         38  
  12         85  
168 12 50       36 return {locations => [ map $_->{name}, @$param ]};
169 12         104 }
170              
171             method got_namedType (Any $param = undef) {
172 597 50   597 0 19020 return unless defined $param;
  597 50       1219  
  597 50       811  
  597         851  
  597         1280  
  597         3322  
173 597 50       1118 return $param->{name};
174 597         1942 }
175              
176             method got_enumValueDefinition (Any $param = undef) {
177 28 50   28 0 3174 return unless defined $param;
  28 50       57  
  28 50       38  
  28         48  
  28         71  
  28         171  
178 28 50       65 my @copy = @$param;
179 28         67 my $rest = pop @copy;
180 28         44 my $value = pop @copy;
181 28         55 my $description = $copy[0] // {};
182 28   100     112 $rest = ref $rest eq 'HASH' ? [ $rest ] : $rest;
183 28 100       77 my %def = (%$description, value => $value, map %$_, @$rest);
184 28         107 return \%def;
185 28         104 }
186              
187             method got_defaultValue (Any $param = undef) {
188 16 50   16 0 624 # the value can be undef
  16 50       70  
  16 50       30  
  16         32  
  16         58  
  16         104  
189             return { default_value => $param };
190 16         92 }
191              
192             method got_implementsInterfaces (Any $param = undef) {
193 8 50   8 0 868 return unless defined $param;
  8 50       49  
  8 50       20  
  8         17  
  8         29  
  8         55  
194 8 50       25 return { interfaces => $param };
195 8         33 }
196              
197             method got_argumentsDefinition (Any $param = undef) {
198 46 50   46 0 5743 return unless defined $param;
  46 50       126  
  46 50       76  
  46         132  
  46         134  
  46         309  
199 46 50       114 return { args => _merge_hash($param) };
200 46         111 }
201              
202             method got_fieldDefinition (Any $param = undef) {
203 118 50   118 0 12579 return unless defined $param;
  118 50       249  
  118 50       181  
  118         202  
  118         353  
  118         774  
204 118 50       234 my $def = _merge_hash($param);
205 118         282 my $name = delete $def->{name};
206 118         318 return { $name => $def };
207 118         544 }
208              
209             method got_typeExtensionDefinition (Any $param = undef) {
210 14 50   14 0 604 return unless defined $param;
  14 50       31  
  14 50       17  
  14         19  
  14         29  
  14         76  
211 14 50       24 return {kind => 'extend', %{$self->_locate_hash($param)}};
212 14         17 }
  14         24  
213              
214             method got_enumTypeDefinition (Any $param = undef) {
215 17 50   17 0 3310 return unless defined $param;
  17 50       41  
  17 50       32  
  17         39  
  17         61  
  17         112  
216 17 50       45 my $def = _merge_hash($param);
217 17         59 my %values;
218 17         30 map {
219             my $name = ${${delete $_->{value}}};
220 28         37 $values{$name} = $_;
  28         36  
  28         63  
221 28         81 } @{(grep ref eq 'ARRAY', @$param)[0]};
222 17         32 $def->{values} = \%values;
  17         56  
223 17         46 return {kind => 'enum', %{$self->_locate_hash($def)}};
224 17         32 }
  17         57  
225              
226             method got_unionMembers (Any $param = undef) {
227 11 50   11 0 1098 return unless defined $param;
  11 50       32  
  11 50       18  
  11         23  
  11         32  
  11         73  
228 11 50       34 return { types => $param };
229 11         42 }
230              
231             method got_boolean (Any $param = undef) {
232 42 50   42 0 15209 return unless defined $param;
  42 50       124  
  42 50       82  
  42         85  
  42         130  
  42         295  
233 42 50       114 return $param eq 'true' ? JSON->true : JSON->false;
234 42 100       247 }
235              
236             method got_null (Any $param = undef) {
237 6 50   6 0 2164 return unless defined $param;
  6 50       17  
  6 50       20  
  6         15  
  6         18  
  6         45  
238 6 50       15 return undef;
239 6         18 }
240              
241             method got_string (Any $param = undef) {
242 79 50   79 0 2470 return unless defined $param;
  79 50       200  
  79 50       133  
  79         152  
  79         230  
  79         500  
243 79 50       166 return $param;
244 79         203 }
245              
246             method got_stringValue (Any $param = undef) {
247 65 50   65 0 22129 return unless defined $param;
  65 50       168  
  65 50       114  
  65         133  
  65         226  
  65         498  
248 65 50       197 return _unescape($param);
249 65         242 }
250              
251             method got_blockStringValue (Any $param = undef) {
252 14 50   14 0 4067 return unless defined $param;
  14 50       48  
  14 50       25  
  14         28  
  14         49  
  14         97  
253 14 50       33 return _blockstring_value($param);
254 14         41 }
255              
256             method got_int (Any $param = undef) {
257 27 50   27 0 7321 $param+0;
  27 50       90  
  27 50       56  
  27         72  
  27         126  
  27         230  
258 27         144 }
259              
260             method got_float (Any $param = undef) {
261 15 50   15 0 3309 $param+0;
  15 50       71  
  15 50       42  
  15         64  
  15         93  
  15         155  
262 15         135 }
263              
264             method got_enumValue (Any $param = undef) {
265 45 50   45 0 1320 return unless defined $param;
  45 50       118  
  45 50       76  
  45         88  
  45         108  
  45         278  
266 45 50       118 my $varname = $param->{name};
267 45         88 return \\$varname;
268 45         153 }
269              
270             # not returning empty list if undef
271             method got_value_const (Any $param = undef) {
272 1080 50   1080 0 3128 return $param;
  1080 50       1951  
  1080 50       1445  
  1080         1675  
  1080         2085  
  1080         6081  
273 1080         2831 }
274              
275             method got_value (Any $param = undef) {
276 237 50   237 0 7989 unshift @_, $self; goto &got_value_const;
  237 50       585  
  237 50       425  
  237         402  
  237         553  
  237         1400  
277 237         479 }
  237         829  
278              
279             method got_variableDefinitions (Any $param = undef) {
280 54 50   54 0 8598 return unless defined $param;
  54 50       119  
  54 50       94  
  54         87  
  54         141  
  54         338  
281 54 50       112 my %def;
282 54         79 map {
283             my $name = ${ shift @$_ };
284 54         100 $def{$name} = { map %$_, @$_ }; # merge
  55         71  
  55         129  
285 55         385 } @$param;
286             return {variables => \%def};
287 54         300 }
288              
289             method got_variableDefinition (Any $param = undef) {
290 55 50   55 0 1726 return unless defined $param;
  55 50       142  
  55 50       87  
  55         91  
  55         129  
  55         335  
291 55 50       137 return $param;
292 55         129 }
293              
294             method got_selection (Any $param = undef) {
295 820 50   820 0 25840 unshift @_, $self; goto &got_value_const;
  820 50       1655  
  820 50       1157  
  820         1223  
  820         1652  
  820         4447  
296 820         1393 }
  820         2376  
297              
298             method got_typedef (Any $param = undef) {
299 278 50   278 0 8123 return unless defined $param;
  278 50       557  
  278 50       384  
  278         497  
  278         648  
  278         1522  
300 278 50       535 $param = $param->{name} if ref($param) eq 'HASH';
301 278 50       622 return {type => $param};
302 278         1282 }
303              
304             method got_alias (Any $param = undef) {
305 30 50   30 0 2102 return unless defined $param;
  30 50       83  
  30 50       54  
  30         57  
  30         87  
  30         202  
306 30 50       115 return {$self->{parser}{rule} => $param->{name}};
307 30         146 }
308              
309             method got_typeCondition (Any $param = undef) {
310 50 50   50 0 1714 return unless defined $param;
  50 50       133  
  50 50       88  
  50         97  
  50         224  
  50         311  
311 50 50       139 return {on => $param};
312 50         184 }
313              
314             method got_fragmentName (Any $param = undef) {
315 66 50   66 0 1952 return unless defined $param;
  66 50       160  
  66 50       115  
  66         115  
  66         146  
  66         400  
316 66 50       154 return $param;
317 66         152 }
318              
319             method got_selectionSet (Any $param = undef) {
320 563 50   563 0 247913 return unless defined $param;
  563 50       1240  
  563 50       850  
  563         951  
  563         1600  
  563         3610  
321 563 50       1158 return {selections => $param};
322 563         1908 }
323              
324             method got_operationDefinition (Any $param = undef) {
325 264 50   264 0 10595 return unless defined $param;
  264 50       643  
  264 50       445  
  264         526  
  264         646  
  264         1642  
326 264 50       698 $param = [ $param ] unless ref $param eq 'ARRAY'; # bare selectionSet
327 264 100       787 return {kind => 'operation', %{$self->_locate_hash(_merge_hash($param))}};
328 264         478 }
  264         677  
329              
330             method got_directives (Any $param = undef) {
331 71 50   71 0 4834 return unless defined $param;
  71 50       166  
  71 50       111  
  71         126  
  71         171  
  71         449  
332 71 50       180 return {$self->{parser}{rule} => $param};
333 71         253 }
334              
335             method got_graphql (Any $param = undef) {
336 323 50   323 0 199980 return unless defined $param;
  323 50       822  
  323 50       577  
  323         618  
  323         978  
  323         2267  
337 323 50       778 return $param;
338 323         960 }
339              
340             method got_definition (Any $param = undef) {
341 590 50   590 0 18119 return unless defined $param;
  590 50       1299  
  590 50       926  
  590         1025  
  590         1424  
  590         3618  
342 590 100       1313 return $param;
343 487         1176 }
344              
345             method got_operationTypeDefinition (Any $param = undef) {
346 54 50   54 0 1865 return unless defined $param;
  54 50       162  
  54 50       109  
  54         103  
  54         134  
  54         325  
347 54 50       117 return { map { ref($_) ? values %$_ : $_ } @$param };
348 54 100       103 }
  108         519  
349              
350             method got_comment (Any $param = undef) {
351 0 0   0 0 0 return unless defined $param;
  0 0       0  
  0 0       0  
  0         0  
  0         0  
  0         0  
352 0 0       0 return $param;
353 0         0 }
354              
355             method got_description (Any $param = undef) {
356 1026 50   1026 0 29921 return unless defined $param;
  1026 50       1925  
  1026 50       1426  
  1026         1483  
  1026         2051  
  1026         5874  
357 1026 100       2716 my $string = ref($param) eq 'ARRAY' ? join("\n", @$param) : $param;
358 16 50       42 return $string ? {$self->{parser}{rule} => $string} : {};
359 16 50       82 }
360              
361             method got_schema (Any $param = undef) {
362 44 50   44 0 6596 return unless defined $param;
  44 50       153  
  44 50       98  
  44         115  
  44         163  
  44         364  
363 44 50       105 my $directives = {};
364 44         98 if (ref $param->[1] eq 'ARRAY') {
365 44 100       170 # got directives
366             $directives = shift @$param;
367 3         9 }
368             my %type2count;
369 44         87 $type2count{(keys %$_)[0]}++ for @{$param->[0]};
370 44         85 $type2count{$_} > 1 and die "Must provide only one $_ type in schema.\n"
  44         271  
371             for keys %type2count;
372 44   100     332 return {kind => $self->{parser}{rule}, %{$self->_locate_hash(_merge_hash($param->[0]))}, %$directives};
373 41         147 }
  41         215  
374              
375             method got_typeSystemDefinition (Any $param = undef) {
376 196 50   196 0 9279 return unless defined $param;
  196 50       446  
  196 50       318  
  196         329  
  196         519  
  196         1192  
377 196 50       435 my @copy = @$param;
378 196         430 my $node = pop @copy;
379 196         305 my $description = $copy[0] // {};
380 196   100     790 +{ %$node, %$description };
381 196         1206 }
382              
383             method got_typeDefinition (Any $param = undef) {
384 143 50   143 0 4738 return unless defined $param;
  143 50       350  
  143 50       265  
  143         259  
  143         433  
  143         985  
385 143 50       323 return $param;
386 143         321 }
387              
388             method got_variable (Any $param = undef) {
389 123 50   123 0 4110 return unless defined $param;
  123 50       252  
  123 50       191  
  123         227  
  123         274  
  123         706  
390 123 50       248 my $varname = $param->{name};
391 123         208 return \$varname;
392 123         391 }
393              
394             method got_nonNullType (Any $param = undef) {
395 54 50   54 0 4257 return unless defined $param;
  54 50       107  
  54 50       89  
  54         93  
  54         137  
  54         327  
396 54 50       108 $param = $param->[0]; # zap first useless layer
397 54         100 $param = { type => $param } if ref $param ne 'HASH';
398 54 50       177 return [ 'non_null', $param ];
399 54         202 }
400              
401             method got_listType (Any $param = undef) {
402 38 50   38 0 1223 return unless defined $param;
  38 50       82  
  38 50       54  
  38         52  
  38         82  
  38         235  
403 38 50       86 $param = $param->[0]; # zap first useless layer
404 38         68 $param = { type => $param } if ref $param ne 'HASH';
405 38 50       100 return [ 'list', $param ];
406 38         109 }
407              
408             1;