tinygql 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -84,7 +84,7 @@ nodes:
84
84
  - name: Directive
85
85
  fields:
86
86
  - name: literal
87
- - arguments: list
87
+ - arguments?: list
88
88
 
89
89
  - name: TypeCondition
90
90
  fields:
@@ -98,19 +98,19 @@ nodes:
98
98
 
99
99
  - name: FragmentSpread
100
100
  fields:
101
- - fragment_name
101
+ - fragment_name: literal
102
102
  - directives?: list
103
103
 
104
104
  - name: FragmentDefinition
105
105
  fields:
106
- - fragment_name
106
+ - fragment_name: literal
107
107
  - type_condition
108
108
  - directives?: list
109
109
  - selection_set: list
110
110
 
111
111
  - name: RootOperationTypeDefinition
112
112
  fields:
113
- - operation_type
113
+ - operation_type: literal
114
114
  - named_type
115
115
 
116
116
  - name: SchemaDefinition
@@ -204,3 +204,33 @@ nodes:
204
204
  - name: literal
205
205
  - arguments_definition?: list
206
206
  - directive_locations: list
207
+
208
+ - name: ScalarTypeExtension
209
+ fields:
210
+ - name: literal
211
+ - directives?: list
212
+
213
+ - name: InterfaceTypeExtension
214
+ fields:
215
+ - name: literal
216
+ - implements_interfaces?: list
217
+ - directives?: list
218
+ - fields_definition?: list
219
+
220
+ - name: UnionTypeExtension
221
+ fields:
222
+ - name: literal
223
+ - directives?: list
224
+ - union_member_types?: list
225
+
226
+ - name: EnumTypeExtension
227
+ fields:
228
+ - name: literal
229
+ - directives?: list
230
+ - enum_value_definition?: list
231
+
232
+ - name: InputObjectTypeExtension
233
+ fields:
234
+ - name: literal
235
+ - directives?: list
236
+ - input_fields_definition?: list
@@ -13,8 +13,7 @@ module TinyGQL
13
13
 
14
14
  def initialize doc
15
15
  @lexer = Lexer.new doc
16
- @lexer.advance
17
- @token_name = @lexer.token_name
16
+ @token_name = @lexer.advance
18
17
  end
19
18
 
20
19
  def parse
@@ -25,8 +24,13 @@ module TinyGQL
25
24
 
26
25
  attr_reader :token_name
27
26
 
27
+ def pos
28
+ @lexer.pos
29
+ end
30
+
28
31
  def document
29
- Nodes::Document.new definition_list
32
+ loc = pos
33
+ Nodes::Document.new loc, definition_list
30
34
  end
31
35
 
32
36
  def definition_list
@@ -53,19 +57,70 @@ module TinyGQL
53
57
  def type_system_extension
54
58
  expect_token :EXTEND
55
59
  case token_name
60
+ when :SCALAR then scalar_type_extension
56
61
  when :TYPE then object_type_extension
62
+ when :INTERFACE then interface_type_extension
63
+ when :UNION then union_type_extension
64
+ when :ENUM then enum_type_extension
65
+ when :INPUT then input_object_type_extension
57
66
  else
58
- expect_token :FAIL
67
+ expect_token :SCALAR
59
68
  end
60
69
  end
61
70
 
71
+ def input_object_type_extension
72
+ loc = pos
73
+ expect_token :INPUT
74
+ name = self.name
75
+ directives = if at?(:DIR_SIGN); self.directives; end
76
+ input_fields_definition = if at?(:LCURLY); self.input_fields_definition; end
77
+ Nodes::InputObjectTypeExtension.new(loc, name, directives, input_fields_definition)
78
+ end
79
+
80
+ def enum_type_extension
81
+ loc = pos
82
+ expect_token :ENUM
83
+ name = self.name
84
+ directives = if at?(:DIR_SIGN); self.directives; end
85
+ enum_values_definition = if at?(:LCURLY); self.enum_values_definition; end
86
+ Nodes::EnumTypeExtension.new(loc, name, directives, enum_values_definition)
87
+ end
88
+
89
+ def union_type_extension
90
+ loc = pos
91
+ expect_token :UNION
92
+ name = self.name
93
+ directives = if at?(:DIR_SIGN); self.directives; end
94
+ union_member_types = if at?(:EQUALS); self.union_member_types; end
95
+ Nodes::UnionTypeExtension.new(loc, name, directives, union_member_types)
96
+ end
97
+
98
+ def interface_type_extension
99
+ loc = pos
100
+ expect_token :INTERFACE
101
+ name = self.name
102
+ implements_interfaces = if at?(:IMPLEMENTS); self.implements_interfaces; end
103
+ directives = if at?(:DIR_SIGN); self.directives; end
104
+ fields_definition = if at?(:LCURLY); self.fields_definition; end
105
+ Nodes::InterfaceTypeExtension.new(loc, name, implements_interfaces, directives, fields_definition)
106
+ end
107
+
108
+ def scalar_type_extension
109
+ loc = pos
110
+ expect_token :SCALAR
111
+ name = self.name
112
+ directives = if at?(:DIR_SIGN); self.directives; end
113
+ Nodes::ScalarTypeExtension.new(loc, name, directives)
114
+ end
115
+
62
116
  def object_type_extension
117
+ loc = pos
63
118
  expect_token :TYPE
64
119
  name = self.name
65
120
  implements_interfaces = if at?(:IMPLEMENTS); self.implements_interfaces; end
66
121
  directives = if at?(:DIR_SIGN); self.directives; end
67
122
  fields_definition = if at?(:LCURLY); self.fields_definition; end
68
- Nodes::ObjectTypeExtension.new(name, implements_interfaces, directives, fields_definition)
123
+ Nodes::ObjectTypeExtension.new(loc, name, implements_interfaces, directives, fields_definition)
69
124
  end
70
125
 
71
126
  def type_system_definition desc
@@ -78,13 +133,14 @@ module TinyGQL
78
133
  end
79
134
 
80
135
  def directive_defintion desc
136
+ loc = pos
81
137
  expect_token :DIRECTIVE
82
138
  expect_token :DIR_SIGN
83
139
  name = self.name
84
140
  arguments_definition = if at?(:LPAREN); self.arguments_definition; end
85
141
  expect_token :ON
86
142
  directive_locations = self.directive_locations
87
- Nodes::DirectiveDefinition.new(desc, name, arguments_definition, directive_locations)
143
+ Nodes::DirectiveDefinition.new(loc, desc, name, arguments_definition, directive_locations)
88
144
  end
89
145
 
90
146
  def directive_locations
@@ -97,11 +153,12 @@ module TinyGQL
97
153
  end
98
154
 
99
155
  def directive_location
156
+ loc = pos
100
157
  directive = expect_token_value :IDENTIFIER
101
158
 
102
159
  case directive
103
160
  when "QUERY", "MUTATION", "SUBSCRIPTION", "FIELD", "FRAGMENT_DEFINITION", "FRAGMENT_SPREAD", "INLINE_FRAGMENT"
104
- Nodes::ExecutableDirectiveLocation.new(directive)
161
+ Nodes::ExecutableDirectiveLocation.new(loc, directive)
105
162
  when "SCHEMA",
106
163
  "SCALAR",
107
164
  "OBJECT",
@@ -113,7 +170,7 @@ module TinyGQL
113
170
  "ENUM_VALUE",
114
171
  "INPUT_OBJECT",
115
172
  "INPUT_FIELD_DEFINITION"
116
- Nodes::TypeSystemDirectiveLocation.new(directive)
173
+ Nodes::TypeSystemDirectiveLocation.new(loc, directive)
117
174
  else
118
175
  raise UnexpectedToken, "Expected directive #{directive}"
119
176
  end
@@ -128,16 +185,17 @@ module TinyGQL
128
185
  when :ENUM then enum_type_definition(desc)
129
186
  when :INPUT then input_object_type_definition(desc)
130
187
  else
131
- expect_token :FAIL
188
+ expect_token :TYPE
132
189
  end
133
190
  end
134
191
 
135
192
  def input_object_type_definition desc
193
+ loc = pos
136
194
  expect_token :INPUT
137
195
  name = self.name
138
196
  directives = if at?(:DIR_SIGN); self.directives; end
139
197
  input_fields_definition = if at?(:LCURLY); self.input_fields_definition; end
140
- Nodes::InputObjectTypeDefinition.new(desc, name, directives, input_fields_definition)
198
+ Nodes::InputObjectTypeDefinition.new(loc, desc, name, directives, input_fields_definition)
141
199
  end
142
200
 
143
201
  def input_fields_definition
@@ -151,11 +209,12 @@ module TinyGQL
151
209
  end
152
210
 
153
211
  def enum_type_definition desc
212
+ loc = pos
154
213
  expect_token :ENUM
155
214
  name = self.name
156
215
  directives = if at?(:DIR_SIGN); self.directives; end
157
216
  enum_values_definition = if at?(:LCURLY); self.enum_values_definition; end
158
- Nodes::EnumTypeDefinition.new(desc, name, directives, enum_values_definition)
217
+ Nodes::EnumTypeDefinition.new(loc, desc, name, directives, enum_values_definition)
159
218
  end
160
219
 
161
220
  def enum_values_definition
@@ -169,25 +228,28 @@ module TinyGQL
169
228
  end
170
229
 
171
230
  def enum_value_definition
231
+ loc = pos
172
232
  description = if at?(:STRING); string_value; end
173
233
  enum_value = self.enum_value
174
234
  directives = if at?(:DIR_SIGN); self.directives; end
175
- Nodes::EnumValueDefinition.new(description, enum_value, directives)
235
+ Nodes::EnumValueDefinition.new(loc, description, enum_value, directives)
176
236
  end
177
237
 
178
238
  def scalar_type_definition desc
239
+ loc = pos
179
240
  expect_token :SCALAR
180
241
  name = self.name
181
242
  directives = if at?(:DIR_SIGN); self.directives; end
182
- Nodes::ScalarTypeDefinition.new(desc, name, directives)
243
+ Nodes::ScalarTypeDefinition.new(loc, desc, name, directives)
183
244
  end
184
245
 
185
246
  def union_type_definition desc
247
+ loc = pos
186
248
  expect_token :UNION
187
249
  name = self.name
188
250
  directives = if at?(:DIR_SIGN); self.directives; end
189
251
  union_member_types = if at?(:EQUALS); self.union_member_types; end
190
- Nodes::UnionTypeDefinition.new(desc, name, directives, union_member_types)
252
+ Nodes::UnionTypeDefinition.new(loc, desc, name, directives, union_member_types)
191
253
  end
192
254
 
193
255
  def union_member_types
@@ -201,21 +263,23 @@ module TinyGQL
201
263
  end
202
264
 
203
265
  def interface_type_definition desc
266
+ loc = pos
204
267
  expect_token :INTERFACE
205
268
  name = self.name
206
269
  directives = if at?(:DIR_SIGN); self.directives; end
207
270
  fields_definition = if at?(:LCURLY); self.fields_definition; end
208
- Nodes::InterfaceTypeDefinition.new(desc, name, directives, fields_definition)
271
+ Nodes::InterfaceTypeDefinition.new(loc, desc, name, directives, fields_definition)
209
272
  end
210
273
 
211
274
  def object_type_definition desc
275
+ loc = pos
212
276
  expect_token :TYPE
213
277
  name = self.name
214
278
  implements_interfaces = if at?(:IMPLEMENTS); self.implements_interfaces; end
215
279
  directives = if at?(:DIR_SIGN); self.directives; end
216
280
  fields_definition = if at?(:LCURLY); self.fields_definition; end
217
281
 
218
- Nodes::ObjectTypeDefinition.new(desc, name, implements_interfaces, directives, fields_definition)
282
+ Nodes::ObjectTypeDefinition.new(loc, desc, name, implements_interfaces, directives, fields_definition)
219
283
  end
220
284
 
221
285
  def fields_definition
@@ -229,6 +293,7 @@ module TinyGQL
229
293
  end
230
294
 
231
295
  def field_definition
296
+ loc = pos
232
297
  description = if at?(:STRING); string_value; end
233
298
  name = self.name
234
299
  arguments_definition = if at?(:LPAREN); self.arguments_definition; end
@@ -236,7 +301,7 @@ module TinyGQL
236
301
  type = self.type
237
302
  directives = if at?(:DIR_SIGN); self.directives; end
238
303
 
239
- Nodes::FieldDefinition.new(description, name, arguments_definition, type, directives)
304
+ Nodes::FieldDefinition.new(loc, description, name, arguments_definition, type, directives)
240
305
  end
241
306
 
242
307
  def arguments_definition
@@ -250,13 +315,14 @@ module TinyGQL
250
315
  end
251
316
 
252
317
  def input_value_definition
318
+ loc = pos
253
319
  description = if at?(:STRING); string_value; end
254
320
  name = self.name
255
321
  expect_token :COLON
256
322
  type = self.type
257
323
  default_value = if at?(:EQUALS); self.default_value; end
258
324
  directives = if at?(:DIR_SIGN); self.directives; end
259
- Nodes::InputValueDefinition.new(description, name, type, default_value, directives)
325
+ Nodes::InputValueDefinition.new(loc, description, name, type, default_value, directives)
260
326
  end
261
327
 
262
328
  def implements_interfaces
@@ -271,21 +337,23 @@ module TinyGQL
271
337
  end
272
338
 
273
339
  def schema_definition desc
340
+ loc = pos
274
341
  expect_token :SCHEMA
275
342
 
276
343
  directives = if at?(:DIR_SIGN); self.directives; end
277
344
  expect_token :LCURLY
278
345
  defs = root_operation_type_definition
279
346
  expect_token :RCURLY
280
- Nodes::SchemaDefinition.new(desc, directives, defs)
347
+ Nodes::SchemaDefinition.new(loc, desc, directives, defs)
281
348
  end
282
349
 
283
350
  def root_operation_type_definition
284
351
  list = []
285
352
  while !at?(:RCURLY)
353
+ loc = pos
286
354
  operation_type = self.operation_type
287
355
  expect_token :COLON
288
- list << Nodes::RootOperationTypeDefinition.new(operation_type, named_type)
356
+ list << Nodes::RootOperationTypeDefinition.new(loc, operation_type, named_type)
289
357
  end
290
358
  list
291
359
  end
@@ -299,18 +367,20 @@ module TinyGQL
299
367
  end
300
368
 
301
369
  def fragment_definition
370
+ loc = pos
302
371
  expect_token :FRAGMENT
303
- expect_token(:FAIL) if at?(:ON)
372
+ expect_token(:IDENTIFIER) if at?(:ON)
304
373
  name = self.name
305
374
  tc = self.type_condition
306
375
  directives = if at?(:DIR_SIGN)
307
376
  self.directives
308
377
  end
309
378
 
310
- Nodes::FragmentDefinition.new(name, tc, directives, selection_set)
379
+ Nodes::FragmentDefinition.new(loc, name, tc, directives, selection_set)
311
380
  end
312
381
 
313
382
  def operation_definition
383
+ loc = pos
314
384
  case token_name
315
385
  when :QUERY, :MUTATION, :SUBSCRIPTION
316
386
  type = self.operation_type
@@ -320,6 +390,7 @@ module TinyGQL
320
390
  end
321
391
 
322
392
  Nodes::OperationDefinition.new(
393
+ loc,
323
394
  type,
324
395
  ident,
325
396
  variable_definitions,
@@ -353,20 +424,22 @@ module TinyGQL
353
424
  when :ON, :DIR_SIGN, :LCURLY then inline_fragment
354
425
  when :IDENTIFIER then fragment_spread
355
426
  else
356
- expect_token :FAIL
427
+ expect_token :IDENTIFIER
357
428
  end
358
429
  end
359
430
 
360
431
  def fragment_spread
432
+ loc = pos
361
433
  name = self.name
362
- directives = if at?(:DIR_SIGN)
363
- self.directives
364
- end
434
+ directives = if at?(:DIR_SIGN); self.directives; end
365
435
 
366
- Nodes::FragmentSpread.new(name, directives)
436
+ expect_token(:IDENTIFIER) if at?(:ON)
437
+
438
+ Nodes::FragmentSpread.new(loc, name, directives)
367
439
  end
368
440
 
369
441
  def inline_fragment
442
+ loc = pos
370
443
  type_condition = if at?(:ON)
371
444
  self.type_condition
372
445
  end
@@ -375,15 +448,17 @@ module TinyGQL
375
448
  self.directives
376
449
  end
377
450
 
378
- Nodes::InlineFragment.new(type_condition, directives, selection_set)
451
+ Nodes::InlineFragment.new(loc, type_condition, directives, selection_set)
379
452
  end
380
453
 
381
454
  def type_condition
455
+ loc = pos
382
456
  expect_token :ON
383
- Nodes::TypeCondition.new(named_type)
457
+ Nodes::TypeCondition.new(loc, named_type)
384
458
  end
385
459
 
386
460
  def field
461
+ loc = pos
387
462
  name = self.name
388
463
 
389
464
  aliaz = nil
@@ -398,7 +473,7 @@ module TinyGQL
398
473
  directives = if at?(:DIR_SIGN); self.directives; end
399
474
  selection_set = if at?(:LCURLY); self.selection_set; end
400
475
 
401
- Nodes::Field.new(aliaz, name, arguments, directives, selection_set)
476
+ Nodes::Field.new(loc, aliaz, name, arguments, directives, selection_set)
402
477
  end
403
478
 
404
479
  def operation_type
@@ -414,13 +489,14 @@ module TinyGQL
414
489
  end
415
490
 
416
491
  def directive
492
+ loc = pos
417
493
  expect_token(:DIR_SIGN)
418
494
  name = self.name
419
495
  arguments = if at?(:LPAREN)
420
496
  self.arguments
421
497
  end
422
498
 
423
- Nodes::Directive.new(name, arguments)
499
+ Nodes::Directive.new(loc, name, arguments)
424
500
  end
425
501
 
426
502
  def arguments
@@ -434,9 +510,10 @@ module TinyGQL
434
510
  end
435
511
 
436
512
  def argument
513
+ loc = pos
437
514
  name = self.name
438
515
  expect_token(:COLON)
439
- Nodes::Argument.new(name, value)
516
+ Nodes::Argument.new(loc, name, value)
440
517
  end
441
518
 
442
519
  def variable_definitions
@@ -450,6 +527,7 @@ module TinyGQL
450
527
  end
451
528
 
452
529
  def variable_definition
530
+ loc = pos
453
531
  var = variable
454
532
  expect_token(:COLON)
455
533
  type = self.type
@@ -457,7 +535,7 @@ module TinyGQL
457
535
  self.default_value
458
536
  end
459
537
 
460
- Nodes::VariableDefinition.new(var, type, default_value)
538
+ Nodes::VariableDefinition.new(loc, var, type, default_value)
461
539
  end
462
540
 
463
541
  def default_value
@@ -477,54 +555,66 @@ module TinyGQL
477
555
  when :LCURLY then object_value
478
556
  when :VAR_SIGN then variable
479
557
  else
480
- expect_token :FAIL
558
+ expect_token :INT
481
559
  end
482
560
  end
483
561
 
484
562
  def object_value
563
+ start = pos
485
564
  expect_token(:LCURLY)
486
565
  list = []
487
566
  while !at?(:RCURLY)
567
+ loc = pos
488
568
  n = name
489
569
  expect_token(:COLON)
490
- list << Nodes::ObjectField.new(n, value)
570
+ list << Nodes::ObjectField.new(loc, n, value)
491
571
  end
492
572
  expect_token(:RCURLY)
493
- Nodes::ObjectValue.new(list)
573
+ Nodes::ObjectValue.new(start, list)
494
574
  end
495
575
 
496
576
  def list_value
577
+ loc = pos
497
578
  expect_token(:LBRACKET)
498
579
  list = []
499
580
  while !at?(:RBRACKET)
500
581
  list << value
501
582
  end
502
583
  expect_token(:RBRACKET)
503
- Nodes::ListValue.new(list)
584
+ Nodes::ListValue.new(loc, list)
504
585
  end
505
586
 
506
587
  def enum_value
507
- Nodes::EnumValue.new(expect_token_value(:IDENTIFIER))
588
+ Nodes::EnumValue.new(pos, expect_token_value(:IDENTIFIER))
508
589
  end
509
590
 
510
591
  def float_value
511
- Nodes::FloatValue.new(expect_token_value(:FLOAT))
592
+ Nodes::FloatValue.new(pos, expect_token_value(:FLOAT))
512
593
  end
513
594
 
514
595
  def int_value
515
- Nodes::IntValue.new(expect_token_value(:INT))
596
+ Nodes::IntValue.new(pos, expect_token_value(:INT))
516
597
  end
517
598
 
518
599
  def string_value
519
- Nodes::StringValue.new(expect_token_value(:STRING))
600
+ Nodes::StringValue.new(pos, expect_string_value)
520
601
  end
521
602
 
522
603
  def boolean_value
523
- Nodes::BooleanValue.new(expect_tokens([:TRUE, :FALSE]))
604
+ if at?(:TRUE)
605
+ accept_token
606
+ Nodes::BooleanValue.new(pos, "true")
607
+ elsif at?(:FALSE)
608
+ accept_token
609
+ Nodes::BooleanValue.new(pos, "false")
610
+ else
611
+ expect_tokens([:TRUE, :FALSE])
612
+ end
524
613
  end
525
614
 
526
615
  def null_value
527
- Nodes::NullValue.new(expect_token_value(:NULL))
616
+ expect_token :NULL
617
+ Nodes::NullValue.new(pos, "null")
528
618
  end
529
619
 
530
620
  def type
@@ -534,40 +624,50 @@ module TinyGQL
534
624
  end
535
625
 
536
626
  if at?(:BANG)
537
- Nodes::NotNullType.new type
627
+ Nodes::NotNullType.new pos, type
538
628
  expect_token(:BANG)
539
629
  end
540
630
  type
541
631
  end
542
632
 
543
633
  def list_type
634
+ loc = pos
544
635
  expect_token(:LBRACKET)
545
- type = Nodes::ListType.new(self.type)
636
+ type = Nodes::ListType.new(loc, self.type)
546
637
  expect_token(:RBRACKET)
547
638
  type
548
639
  end
549
640
 
550
641
  def named_type
551
- Nodes::NamedType.new(name)
642
+ Nodes::NamedType.new(pos, name)
552
643
  end
553
644
 
554
645
  def variable
555
646
  return unless at?(:VAR_SIGN)
647
+ loc = pos
556
648
  accept_token
557
- Nodes::Variable.new name
649
+ Nodes::Variable.new loc, name
558
650
  end
559
651
 
560
652
  def name
561
653
  case token_name
562
- when :IDENTIFIER, :INPUT, :QUERY, :TYPE then accept_token_value
654
+ when :IDENTIFIER then accept_token_value
655
+ when :TYPE then
656
+ accept_token
657
+ "type"
658
+ when :QUERY then
659
+ accept_token
660
+ "query"
661
+ when :INPUT then
662
+ accept_token
663
+ "input"
563
664
  else
564
665
  expect_token_value(:IDENTIFIER)
565
666
  end
566
667
  end
567
668
 
568
669
  def accept_token
569
- @lexer.advance
570
- @token_name = @lexer.token_name
670
+ @token_name = @lexer.advance
571
671
  end
572
672
 
573
673
  # Only use when we care about the accepted token's value
@@ -591,6 +691,12 @@ module TinyGQL
591
691
  token_value
592
692
  end
593
693
 
694
+ def expect_string_value
695
+ token_value = @lexer.string_value
696
+ expect_token :STRING
697
+ token_value
698
+ end
699
+
594
700
  def expect_tokens toks
595
701
  token_value = @lexer.token_value
596
702
  unless toks.any? { |tok| at?(tok) }
@@ -1,3 +1,3 @@
1
1
  module TinyGQL
2
- VERSION = '0.1.3'
2
+ VERSION = '0.2.0'
3
3
  end