graphql 2.1.15 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/graphql/dataloader/async_dataloader.rb +88 -0
- data/lib/graphql/dataloader/source.rb +5 -8
- data/lib/graphql/dataloader.rb +35 -21
- data/lib/graphql/language/lexer.rb +271 -177
- data/lib/graphql/language/nodes.rb +72 -57
- data/lib/graphql/language/parser.rb +686 -1986
- data/lib/graphql/language/printer.rb +16 -12
- data/lib/graphql/language/static_visitor.rb +33 -37
- data/lib/graphql/language/visitor.rb +55 -59
- data/lib/graphql/schema/argument.rb +5 -3
- data/lib/graphql/schema/build_from_definition.rb +7 -8
- data/lib/graphql/schema/directive.rb +1 -1
- data/lib/graphql/schema/enum_value.rb +1 -1
- data/lib/graphql/schema/field.rb +1 -1
- data/lib/graphql/schema/input_object.rb +6 -8
- data/lib/graphql/schema/interface.rb +2 -6
- data/lib/graphql/schema/member/has_directives.rb +1 -1
- data/lib/graphql/schema/member/has_fields.rb +1 -1
- data/lib/graphql/schema/member/has_interfaces.rb +1 -1
- data/lib/graphql/schema/member/scoped.rb +1 -1
- data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
- data/lib/graphql/schema.rb +6 -5
- data/lib/graphql/testing/helpers.rb +125 -0
- data/lib/graphql/testing.rb +2 -0
- data/lib/graphql/tracing/appoptics_trace.rb +0 -4
- data/lib/graphql/tracing/appsignal_trace.rb +0 -4
- data/lib/graphql/tracing/data_dog_trace.rb +34 -25
- data/lib/graphql/tracing/data_dog_tracing.rb +21 -7
- data/lib/graphql/tracing/notifications_trace.rb +0 -4
- data/lib/graphql/tracing/platform_trace.rb +0 -5
- data/lib/graphql/tracing/prometheus_trace.rb +0 -4
- data/lib/graphql/tracing/scout_trace.rb +0 -3
- data/lib/graphql/tracing/statsd_trace.rb +0 -4
- data/lib/graphql/tracing/trace.rb +1 -0
- data/lib/graphql/types/relay/connection_behaviors.rb +1 -1
- data/lib/graphql/types/relay/edge_behaviors.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +1 -0
- metadata +21 -19
- data/lib/graphql/language/parser.y +0 -560
@@ -1,560 +0,0 @@
|
|
1
|
-
class GraphQL::Language::Parser
|
2
|
-
rule
|
3
|
-
target: document
|
4
|
-
|
5
|
-
document: definitions_list { result = make_node(:Document, definitions: val[0])}
|
6
|
-
|
7
|
-
definitions_list:
|
8
|
-
definition { result = [val[0]]}
|
9
|
-
| definitions_list definition { val[0] << val[1] }
|
10
|
-
|
11
|
-
definition:
|
12
|
-
executable_definition
|
13
|
-
| type_system_definition
|
14
|
-
| type_system_extension
|
15
|
-
|
16
|
-
executable_definition:
|
17
|
-
operation_definition
|
18
|
-
| fragment_definition
|
19
|
-
|
20
|
-
operation_definition:
|
21
|
-
operation_type operation_name_opt variable_definitions_opt directives_list_opt selection_set {
|
22
|
-
result = make_node(
|
23
|
-
:OperationDefinition, {
|
24
|
-
operation_type: val[0],
|
25
|
-
name: val[1],
|
26
|
-
variables: val[2],
|
27
|
-
directives: val[3],
|
28
|
-
selections: val[4],
|
29
|
-
position_source: val[0],
|
30
|
-
}
|
31
|
-
)
|
32
|
-
}
|
33
|
-
| LCURLY selection_list RCURLY {
|
34
|
-
result = make_node(
|
35
|
-
:OperationDefinition, {
|
36
|
-
operation_type: "query",
|
37
|
-
selections: val[1],
|
38
|
-
position_source: val[0],
|
39
|
-
}
|
40
|
-
)
|
41
|
-
}
|
42
|
-
| LCURLY RCURLY {
|
43
|
-
result = make_node(
|
44
|
-
:OperationDefinition, {
|
45
|
-
operation_type: "query",
|
46
|
-
selections: [],
|
47
|
-
position_source: val[0],
|
48
|
-
}
|
49
|
-
)
|
50
|
-
}
|
51
|
-
|
52
|
-
operation_type:
|
53
|
-
QUERY
|
54
|
-
| MUTATION
|
55
|
-
| SUBSCRIPTION
|
56
|
-
|
57
|
-
operation_name_opt:
|
58
|
-
/* none */ { result = nil }
|
59
|
-
| name
|
60
|
-
|
61
|
-
variable_definitions_opt:
|
62
|
-
/* none */ { result = EMPTY_ARRAY }
|
63
|
-
| LPAREN variable_definitions_list RPAREN { result = val[1] }
|
64
|
-
|
65
|
-
variable_definitions_list:
|
66
|
-
variable_definition { result = [val[0]] }
|
67
|
-
| variable_definitions_list variable_definition { val[0] << val[1] }
|
68
|
-
|
69
|
-
variable_definition:
|
70
|
-
VAR_SIGN name COLON type default_value_opt {
|
71
|
-
result = make_node(:VariableDefinition, {
|
72
|
-
name: val[1],
|
73
|
-
type: val[3],
|
74
|
-
default_value: val[4],
|
75
|
-
position_source: val[0],
|
76
|
-
})
|
77
|
-
}
|
78
|
-
|
79
|
-
type:
|
80
|
-
nullable_type { result = val[0] }
|
81
|
-
| nullable_type BANG { result = make_node(:NonNullType, of_type: val[0]) }
|
82
|
-
|
83
|
-
nullable_type:
|
84
|
-
name { result = make_node(:TypeName, name: val[0])}
|
85
|
-
| LBRACKET type RBRACKET { result = make_node(:ListType, of_type: val[1]) }
|
86
|
-
|
87
|
-
default_value_opt:
|
88
|
-
/* none */ { result = nil }
|
89
|
-
| EQUALS literal_value { result = val[1] }
|
90
|
-
|
91
|
-
selection_set:
|
92
|
-
LCURLY selection_list RCURLY { result = val[1] }
|
93
|
-
|
94
|
-
selection_set_opt:
|
95
|
-
/* none */ { result = EMPTY_ARRAY }
|
96
|
-
| selection_set { result = val[0] }
|
97
|
-
|
98
|
-
selection_list:
|
99
|
-
selection { result = [result] }
|
100
|
-
| selection_list selection { val[0] << val[1] }
|
101
|
-
|
102
|
-
selection:
|
103
|
-
field
|
104
|
-
| fragment_spread
|
105
|
-
| inline_fragment
|
106
|
-
|
107
|
-
field:
|
108
|
-
name arguments_opt directives_list_opt selection_set_opt {
|
109
|
-
result = make_node(
|
110
|
-
:Field, {
|
111
|
-
name: val[0],
|
112
|
-
arguments: val[1],
|
113
|
-
directives: val[2],
|
114
|
-
selections: val[3],
|
115
|
-
position_source: val[0],
|
116
|
-
}
|
117
|
-
)
|
118
|
-
}
|
119
|
-
| name COLON name arguments_opt directives_list_opt selection_set_opt {
|
120
|
-
result = make_node(
|
121
|
-
:Field, {
|
122
|
-
alias: val[0],
|
123
|
-
name: val[2],
|
124
|
-
arguments: val[3],
|
125
|
-
directives: val[4],
|
126
|
-
selections: val[5],
|
127
|
-
position_source: val[0],
|
128
|
-
}
|
129
|
-
)
|
130
|
-
}
|
131
|
-
|
132
|
-
name:
|
133
|
-
name_without_on
|
134
|
-
| ON
|
135
|
-
|
136
|
-
schema_keyword:
|
137
|
-
SCHEMA
|
138
|
-
| SCALAR
|
139
|
-
| TYPE
|
140
|
-
| IMPLEMENTS
|
141
|
-
| INTERFACE
|
142
|
-
| UNION
|
143
|
-
| ENUM
|
144
|
-
| INPUT
|
145
|
-
| DIRECTIVE
|
146
|
-
|
147
|
-
name_without_on:
|
148
|
-
IDENTIFIER
|
149
|
-
| FRAGMENT
|
150
|
-
| REPEATABLE
|
151
|
-
| TRUE
|
152
|
-
| FALSE
|
153
|
-
| NULL
|
154
|
-
| operation_type
|
155
|
-
| schema_keyword
|
156
|
-
|
157
|
-
enum_name: /* any identifier, but not "true", "false" or "null" */
|
158
|
-
IDENTIFIER
|
159
|
-
| FRAGMENT
|
160
|
-
| REPEATABLE
|
161
|
-
| ON
|
162
|
-
| operation_type
|
163
|
-
| schema_keyword
|
164
|
-
|
165
|
-
enum_value_definition:
|
166
|
-
description_opt enum_name directives_list_opt { result = make_node(:EnumValueDefinition, name: val[1], directives: val[2], description: val[0] || get_description(val[1]), definition_line: val[1][1], position_source: val[0] || val[1]) }
|
167
|
-
|
168
|
-
enum_value_definitions:
|
169
|
-
enum_value_definition { result = [val[0]] }
|
170
|
-
| enum_value_definitions enum_value_definition { result = val[0] << val[1] }
|
171
|
-
|
172
|
-
arguments_opt:
|
173
|
-
/* none */ { result = EMPTY_ARRAY }
|
174
|
-
| LPAREN arguments_list RPAREN { result = val[1] }
|
175
|
-
|
176
|
-
arguments_list:
|
177
|
-
argument { result = [val[0]] }
|
178
|
-
| arguments_list argument { val[0] << val[1] }
|
179
|
-
|
180
|
-
argument:
|
181
|
-
name COLON input_value { result = make_node(:Argument, name: val[0], value: val[2], position_source: val[0])}
|
182
|
-
|
183
|
-
literal_value:
|
184
|
-
FLOAT { result = val[0][3].to_f }
|
185
|
-
| INT { result = val[0][3].to_i }
|
186
|
-
| STRING { result = val[0][3] }
|
187
|
-
| TRUE { result = true }
|
188
|
-
| FALSE { result = false }
|
189
|
-
| null_value
|
190
|
-
| enum_value
|
191
|
-
| list_value
|
192
|
-
| object_literal_value
|
193
|
-
|
194
|
-
input_value:
|
195
|
-
literal_value
|
196
|
-
| variable
|
197
|
-
| object_value
|
198
|
-
|
199
|
-
null_value: NULL { result = make_node(:NullValue, name: val[0], position_source: val[0]) }
|
200
|
-
variable: VAR_SIGN name { result = make_node(:VariableIdentifier, name: val[1], position_source: val[0]) }
|
201
|
-
|
202
|
-
list_value:
|
203
|
-
LBRACKET RBRACKET { result = EMPTY_ARRAY }
|
204
|
-
| LBRACKET list_value_list RBRACKET { result = val[1] }
|
205
|
-
|
206
|
-
list_value_list:
|
207
|
-
input_value { result = [val[0]] }
|
208
|
-
| list_value_list input_value { val[0] << val[1] }
|
209
|
-
|
210
|
-
object_value:
|
211
|
-
LCURLY RCURLY { result = make_node(:InputObject, arguments: [], position_source: val[0])}
|
212
|
-
| LCURLY object_value_list RCURLY { result = make_node(:InputObject, arguments: val[1], position_source: val[0])}
|
213
|
-
|
214
|
-
object_value_list:
|
215
|
-
object_value_field { result = [val[0]] }
|
216
|
-
| object_value_list object_value_field { val[0] << val[1] }
|
217
|
-
|
218
|
-
object_value_field:
|
219
|
-
name COLON input_value { result = make_node(:Argument, name: val[0], value: val[2], position_source: val[0])}
|
220
|
-
|
221
|
-
/* like the previous, but with literals only: */
|
222
|
-
object_literal_value:
|
223
|
-
LCURLY RCURLY { result = make_node(:InputObject, arguments: [], position_source: val[0])}
|
224
|
-
| LCURLY object_literal_value_list RCURLY { result = make_node(:InputObject, arguments: val[1], position_source: val[0])}
|
225
|
-
|
226
|
-
object_literal_value_list:
|
227
|
-
object_literal_value_field { result = [val[0]] }
|
228
|
-
| object_literal_value_list object_literal_value_field { val[0] << val[1] }
|
229
|
-
|
230
|
-
object_literal_value_field:
|
231
|
-
name COLON literal_value { result = make_node(:Argument, name: val[0], value: val[2], position_source: val[0])}
|
232
|
-
|
233
|
-
enum_value: enum_name { result = make_node(:Enum, name: val[0], position_source: val[0]) }
|
234
|
-
|
235
|
-
directives_list_opt:
|
236
|
-
/* none */ { result = EMPTY_ARRAY }
|
237
|
-
| directives_list
|
238
|
-
|
239
|
-
directives_list:
|
240
|
-
directive { result = [val[0]] }
|
241
|
-
| directives_list directive { val[0] << val[1] }
|
242
|
-
|
243
|
-
directive: DIR_SIGN name arguments_opt { result = make_node(:Directive, name: val[1], arguments: val[2], position_source: val[0]) }
|
244
|
-
|
245
|
-
fragment_spread:
|
246
|
-
ELLIPSIS name_without_on directives_list_opt { result = make_node(:FragmentSpread, name: val[1], directives: val[2], position_source: val[0]) }
|
247
|
-
|
248
|
-
inline_fragment:
|
249
|
-
ELLIPSIS ON type directives_list_opt selection_set {
|
250
|
-
result = make_node(:InlineFragment, {
|
251
|
-
type: val[2],
|
252
|
-
directives: val[3],
|
253
|
-
selections: val[4],
|
254
|
-
position_source: val[0]
|
255
|
-
})
|
256
|
-
}
|
257
|
-
| ELLIPSIS directives_list_opt selection_set {
|
258
|
-
result = make_node(:InlineFragment, {
|
259
|
-
type: nil,
|
260
|
-
directives: val[1],
|
261
|
-
selections: val[2],
|
262
|
-
position_source: val[0]
|
263
|
-
})
|
264
|
-
}
|
265
|
-
|
266
|
-
fragment_definition:
|
267
|
-
FRAGMENT fragment_name_opt ON type directives_list_opt selection_set {
|
268
|
-
result = make_node(:FragmentDefinition, {
|
269
|
-
name: val[1],
|
270
|
-
type: val[3],
|
271
|
-
directives: val[4],
|
272
|
-
selections: val[5],
|
273
|
-
position_source: val[0],
|
274
|
-
}
|
275
|
-
)
|
276
|
-
}
|
277
|
-
|
278
|
-
fragment_name_opt:
|
279
|
-
/* none */ { result = nil }
|
280
|
-
| name_without_on
|
281
|
-
|
282
|
-
type_system_definition:
|
283
|
-
schema_definition
|
284
|
-
| type_definition
|
285
|
-
| directive_definition
|
286
|
-
|
287
|
-
schema_definition:
|
288
|
-
SCHEMA directives_list_opt operation_type_definition_list_opt { result = make_node(:SchemaDefinition, position_source: val[0], definition_line: val[0][1], directives: val[1], **val[2]) }
|
289
|
-
|
290
|
-
operation_type_definition_list_opt:
|
291
|
-
/* none */ { result = {} }
|
292
|
-
| LCURLY operation_type_definition_list RCURLY { result = val[1] }
|
293
|
-
|
294
|
-
operation_type_definition_list:
|
295
|
-
operation_type_definition
|
296
|
-
| operation_type_definition_list operation_type_definition { result = val[0].merge(val[1]) }
|
297
|
-
|
298
|
-
operation_type_definition:
|
299
|
-
operation_type COLON name { result = { val[0][3].to_sym => val[2] } }
|
300
|
-
|
301
|
-
type_definition:
|
302
|
-
scalar_type_definition
|
303
|
-
| object_type_definition
|
304
|
-
| interface_type_definition
|
305
|
-
| union_type_definition
|
306
|
-
| enum_type_definition
|
307
|
-
| input_object_type_definition
|
308
|
-
|
309
|
-
type_system_extension:
|
310
|
-
schema_extension
|
311
|
-
| type_extension
|
312
|
-
|
313
|
-
schema_extension:
|
314
|
-
EXTEND SCHEMA directives_list_opt LCURLY operation_type_definition_list RCURLY { result = make_node(:SchemaExtension, position_source: val[0], directives: val[2], **val[4]) }
|
315
|
-
| EXTEND SCHEMA directives_list { result = make_node(:SchemaExtension, position_source: val[0], directives: val[2]) }
|
316
|
-
|
317
|
-
type_extension:
|
318
|
-
scalar_type_extension
|
319
|
-
| object_type_extension
|
320
|
-
| interface_type_extension
|
321
|
-
| union_type_extension
|
322
|
-
| enum_type_extension
|
323
|
-
| input_object_type_extension
|
324
|
-
|
325
|
-
scalar_type_extension: EXTEND SCALAR name directives_list { result = make_node(:ScalarTypeExtension, name: val[2], directives: val[3], position_source: val[0]) }
|
326
|
-
|
327
|
-
object_type_extension:
|
328
|
-
/* TODO - This first one shouldn't be necessary but parser is getting confused */
|
329
|
-
EXTEND TYPE name implements field_definition_list_opt { result = make_node(:ObjectTypeExtension, name: val[2], interfaces: val[3], directives: [], fields: val[4], position_source: val[0]) }
|
330
|
-
| EXTEND TYPE name implements_opt directives_list_opt field_definition_list_opt { result = make_node(:ObjectTypeExtension, name: val[2], interfaces: val[3], directives: val[4], fields: val[5], position_source: val[0]) }
|
331
|
-
| EXTEND TYPE name implements_opt directives_list { result = make_node(:ObjectTypeExtension, name: val[2], interfaces: val[3], directives: val[4], fields: [], position_source: val[0]) }
|
332
|
-
| EXTEND TYPE name implements { result = make_node(:ObjectTypeExtension, name: val[2], interfaces: val[3], directives: [], fields: [], position_source: val[0]) }
|
333
|
-
|
334
|
-
interface_type_extension:
|
335
|
-
EXTEND INTERFACE name implements_opt directives_list_opt field_definition_list_opt { result = make_node(:InterfaceTypeExtension, name: val[2], interfaces: val[3], directives: val[4], fields: val[5], position_source: val[0]) }
|
336
|
-
| EXTEND INTERFACE name implements_opt directives_list { result = make_node(:InterfaceTypeExtension, name: val[2], interfaces: val[3], directives: val[4], fields: [], position_source: val[0]) }
|
337
|
-
| EXTEND INTERFACE name implements { result = make_node(:InterfaceTypeExtension, name: val[2], interfaces: val[3], directives: [], fields: [], position_source: val[0]) }
|
338
|
-
|
339
|
-
union_type_extension:
|
340
|
-
EXTEND UNION name directives_list_opt EQUALS union_members { result = make_node(:UnionTypeExtension, name: val[2], directives: val[3], types: val[5], position_source: val[0]) }
|
341
|
-
| EXTEND UNION name directives_list { result = make_node(:UnionTypeExtension, name: val[2], directives: val[3], types: [], position_source: val[0]) }
|
342
|
-
|
343
|
-
enum_type_extension:
|
344
|
-
EXTEND ENUM name directives_list_opt LCURLY enum_value_definitions RCURLY { result = make_node(:EnumTypeExtension, name: val[2], directives: val[3], values: val[5], position_source: val[0]) }
|
345
|
-
| EXTEND ENUM name directives_list { result = make_node(:EnumTypeExtension, name: val[2], directives: val[3], values: [], position_source: val[0]) }
|
346
|
-
|
347
|
-
input_object_type_extension:
|
348
|
-
EXTEND INPUT name directives_list_opt LCURLY input_value_definition_list RCURLY { result = make_node(:InputObjectTypeExtension, name: val[2], directives: val[3], fields: val[5], position_source: val[0]) }
|
349
|
-
| EXTEND INPUT name directives_list { result = make_node(:InputObjectTypeExtension, name: val[2], directives: val[3], fields: [], position_source: val[0]) }
|
350
|
-
|
351
|
-
description: STRING
|
352
|
-
|
353
|
-
description_opt:
|
354
|
-
/* none */
|
355
|
-
| description
|
356
|
-
|
357
|
-
scalar_type_definition:
|
358
|
-
description_opt SCALAR name directives_list_opt {
|
359
|
-
result = make_node(:ScalarTypeDefinition, name: val[2], directives: val[3], description: val[0] || get_description(val[1]), definition_line: val[1][1], position_source: val[0] || val[1])
|
360
|
-
}
|
361
|
-
|
362
|
-
object_type_definition:
|
363
|
-
description_opt TYPE name implements_opt directives_list_opt field_definition_list_opt {
|
364
|
-
result = make_node(:ObjectTypeDefinition, name: val[2], interfaces: val[3], directives: val[4], fields: val[5], description: val[0] || get_description(val[1]), definition_line: val[1][1], position_source: val[0] || val[1])
|
365
|
-
}
|
366
|
-
|
367
|
-
implements_opt:
|
368
|
-
/* none */ { result = EMPTY_ARRAY }
|
369
|
-
| implements
|
370
|
-
|
371
|
-
implements:
|
372
|
-
IMPLEMENTS AMP interfaces_list { result = val[2] }
|
373
|
-
| IMPLEMENTS interfaces_list { result = val[1] }
|
374
|
-
| IMPLEMENTS legacy_interfaces_list { result = val[1] }
|
375
|
-
|
376
|
-
interfaces_list:
|
377
|
-
name { result = [make_node(:TypeName, name: val[0], position_source: val[0])] }
|
378
|
-
| interfaces_list AMP name { val[0] << make_node(:TypeName, name: val[2], position_source: val[2]) }
|
379
|
-
|
380
|
-
legacy_interfaces_list:
|
381
|
-
name { result = [make_node(:TypeName, name: val[0], position_source: val[0])] }
|
382
|
-
| legacy_interfaces_list name { val[0] << make_node(:TypeName, name: val[1], position_source: val[1]) }
|
383
|
-
|
384
|
-
input_value_definition:
|
385
|
-
description_opt name COLON type default_value_opt directives_list_opt {
|
386
|
-
result = make_node(:InputValueDefinition, name: val[1], type: val[3], default_value: val[4], directives: val[5], description: val[0] || get_description(val[1]), definition_line: val[1][1], position_source: val[0] || val[1])
|
387
|
-
}
|
388
|
-
|
389
|
-
input_value_definition_list:
|
390
|
-
input_value_definition { result = [val[0]] }
|
391
|
-
| input_value_definition_list input_value_definition { val[0] << val[1] }
|
392
|
-
|
393
|
-
arguments_definitions_opt:
|
394
|
-
/* none */ { result = EMPTY_ARRAY }
|
395
|
-
| LPAREN input_value_definition_list RPAREN { result = val[1] }
|
396
|
-
|
397
|
-
field_definition:
|
398
|
-
description_opt name arguments_definitions_opt COLON type directives_list_opt {
|
399
|
-
result = make_node(:FieldDefinition, name: val[1], arguments: val[2], type: val[4], directives: val[5], description: val[0] || get_description(val[1]), definition_line: val[1][1], position_source: val[0] || val[1])
|
400
|
-
}
|
401
|
-
|
402
|
-
field_definition_list_opt:
|
403
|
-
/* none */ { result = EMPTY_ARRAY }
|
404
|
-
| LCURLY field_definition_list RCURLY { result = val[1] }
|
405
|
-
|
406
|
-
field_definition_list:
|
407
|
-
/* none - this is not actually valid but graphql-ruby used to print this */ { result = EMPTY_ARRAY }
|
408
|
-
| field_definition { result = [val[0]] }
|
409
|
-
| field_definition_list field_definition { val[0] << val[1] }
|
410
|
-
|
411
|
-
interface_type_definition:
|
412
|
-
description_opt INTERFACE name implements_opt directives_list_opt field_definition_list_opt {
|
413
|
-
result = make_node(:InterfaceTypeDefinition, name: val[2], interfaces: val[3], directives: val[4], fields: val[5], description: val[0] || get_description(val[1]), definition_line: val[1][1], position_source: val[0] || val[1])
|
414
|
-
}
|
415
|
-
|
416
|
-
union_members:
|
417
|
-
name { result = [make_node(:TypeName, name: val[0], position_source: val[0])]}
|
418
|
-
| union_members PIPE name { val[0] << make_node(:TypeName, name: val[2], position_source: val[2]) }
|
419
|
-
|
420
|
-
union_type_definition:
|
421
|
-
description_opt UNION name directives_list_opt EQUALS union_members {
|
422
|
-
result = make_node(:UnionTypeDefinition, name: val[2], directives: val[3], types: val[5], description: val[0] || get_description(val[1]), definition_line: val[1][1], position_source: val[0] || val[1])
|
423
|
-
}
|
424
|
-
|
425
|
-
enum_type_definition:
|
426
|
-
description_opt ENUM name directives_list_opt LCURLY enum_value_definitions RCURLY {
|
427
|
-
result = make_node(:EnumTypeDefinition, name: val[2], directives: val[3], values: val[5], description: val[0] || get_description(val[1]), definition_line: val[1][1], position_source: val[0] || val[1])
|
428
|
-
}
|
429
|
-
|
430
|
-
input_object_type_definition:
|
431
|
-
description_opt INPUT name directives_list_opt LCURLY input_value_definition_list RCURLY {
|
432
|
-
result = make_node(:InputObjectTypeDefinition, name: val[2], directives: val[3], fields: val[5], description: val[0] || get_description(val[1]), definition_line: val[1][1], position_source: val[0] || val[1])
|
433
|
-
}
|
434
|
-
|
435
|
-
directive_definition:
|
436
|
-
description_opt DIRECTIVE DIR_SIGN name arguments_definitions_opt directive_repeatable_opt ON directive_locations {
|
437
|
-
result = make_node(:DirectiveDefinition, name: val[3], arguments: val[4], locations: val[7], repeatable: !!val[5], description: val[0] || get_description(val[1]), definition_line: val[1][1], position_source: val[0] || val[1])
|
438
|
-
}
|
439
|
-
|
440
|
-
directive_repeatable_opt:
|
441
|
-
/* nothing */
|
442
|
-
| REPEATABLE
|
443
|
-
|
444
|
-
directive_locations:
|
445
|
-
name { result = [make_node(:DirectiveLocation, name: val[0][3], position_source: val[0])] }
|
446
|
-
| directive_locations PIPE name { val[0] << make_node(:DirectiveLocation, name: val[2][3], position_source: val[2]) }
|
447
|
-
end
|
448
|
-
|
449
|
-
---- header ----
|
450
|
-
|
451
|
-
|
452
|
-
---- inner ----
|
453
|
-
|
454
|
-
EMPTY_ARRAY = [].freeze
|
455
|
-
|
456
|
-
def initialize(query_string, filename:, trace: Tracing::NullTrace)
|
457
|
-
raise GraphQL::ParseError.new("No query string was present", nil, nil, query_string) if query_string.nil?
|
458
|
-
@query_string = query_string
|
459
|
-
@filename = filename
|
460
|
-
@trace = trace
|
461
|
-
@reused_next_token = [nil, nil]
|
462
|
-
end
|
463
|
-
|
464
|
-
def parse_document
|
465
|
-
@document ||= begin
|
466
|
-
# Break the string into tokens
|
467
|
-
@trace.lex(query_string: @query_string) do
|
468
|
-
@tokens ||= GraphQL::Language::Lexer.tokenize(@query_string)
|
469
|
-
end
|
470
|
-
# From the tokens, build an AST
|
471
|
-
@trace.parse(query_string: @query_string) do
|
472
|
-
if @tokens.empty?
|
473
|
-
raise GraphQL::ParseError.new("Unexpected end of document", nil, nil, @query_string)
|
474
|
-
else
|
475
|
-
do_parse
|
476
|
-
end
|
477
|
-
end
|
478
|
-
end
|
479
|
-
end
|
480
|
-
|
481
|
-
class << self
|
482
|
-
attr_accessor :cache
|
483
|
-
|
484
|
-
def parse(query_string, filename: nil, trace: GraphQL::Tracing::NullTrace)
|
485
|
-
new(query_string, filename: filename, trace: trace).parse_document
|
486
|
-
end
|
487
|
-
|
488
|
-
def parse_file(filename, trace: GraphQL::Tracing::NullTrace)
|
489
|
-
if cache
|
490
|
-
cache.fetch(filename) do
|
491
|
-
parse(File.read(filename), filename: filename, trace: trace)
|
492
|
-
end
|
493
|
-
else
|
494
|
-
parse(File.read(filename), filename: filename, trace: trace)
|
495
|
-
end
|
496
|
-
end
|
497
|
-
end
|
498
|
-
|
499
|
-
private
|
500
|
-
|
501
|
-
def next_token
|
502
|
-
lexer_token = @tokens.shift
|
503
|
-
if lexer_token.nil?
|
504
|
-
nil
|
505
|
-
else
|
506
|
-
@reused_next_token[0] = lexer_token[0]
|
507
|
-
@reused_next_token[1] = lexer_token
|
508
|
-
@reused_next_token
|
509
|
-
end
|
510
|
-
end
|
511
|
-
|
512
|
-
def get_description(token)
|
513
|
-
comments = []
|
514
|
-
|
515
|
-
loop do
|
516
|
-
prev_token = token
|
517
|
-
token = token[4]
|
518
|
-
|
519
|
-
break if token.nil?
|
520
|
-
break if token[0] != :COMMENT
|
521
|
-
break if prev_token[1] != token[1] + 1
|
522
|
-
|
523
|
-
comments.unshift(token[3].sub(/^#\s*/, ""))
|
524
|
-
end
|
525
|
-
|
526
|
-
return nil if comments.empty?
|
527
|
-
|
528
|
-
comments.join("\n")
|
529
|
-
end
|
530
|
-
|
531
|
-
def on_error(parser_token_id, lexer_token, vstack)
|
532
|
-
if lexer_token == "$" || lexer_token == nil
|
533
|
-
raise GraphQL::ParseError.new("Unexpected end of document", nil, nil, @query_string, filename: @filename)
|
534
|
-
else
|
535
|
-
parser_token_name = token_to_str(parser_token_id)
|
536
|
-
if parser_token_name.nil?
|
537
|
-
raise GraphQL::ParseError.new("Parse Error on unknown token: {token_id: #{parser_token_id}, lexer_token: #{lexer_token}} from #{@query_string}", nil, nil, @query_string, filename: @filename)
|
538
|
-
else
|
539
|
-
line = lexer_token[1]
|
540
|
-
col = lexer_token[2]
|
541
|
-
if lexer_token[0] == :BAD_UNICODE_ESCAPE
|
542
|
-
raise GraphQL::ParseError.new("Parse error on bad Unicode escape sequence: #{lexer_token[3].inspect} (#{parser_token_name}) at [#{line}, #{col}]", line, col, @query_string, filename: @filename)
|
543
|
-
else
|
544
|
-
raise GraphQL::ParseError.new("Parse error on #{lexer_token[3].inspect} (#{parser_token_name}) at [#{line}, #{col}]", line, col, @query_string, filename: @filename)
|
545
|
-
end
|
546
|
-
end
|
547
|
-
end
|
548
|
-
end
|
549
|
-
|
550
|
-
def make_node(node_name, assigns)
|
551
|
-
assigns.each do |key, value|
|
552
|
-
if key != :position_source && value.is_a?(Array) && value[0].is_a?(Symbol)
|
553
|
-
assigns[key] = value[3]
|
554
|
-
end
|
555
|
-
end
|
556
|
-
|
557
|
-
assigns[:filename] = @filename
|
558
|
-
|
559
|
-
GraphQL::Language::Nodes.const_get(node_name).new(assigns)
|
560
|
-
end
|