tinygql 0.1.1 → 0.1.3

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.
data/bin/bench.rb CHANGED
@@ -1,11 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- $:.unshift(File.expand_path("../lib", __dir__))
4
3
  require "tinygql"
5
- require "benchmark"
4
+ require "benchmark/ips"
6
5
 
7
6
  source = File.read(File.expand_path("../test/kitchen-sink.graphql", __dir__))
8
7
 
9
- Benchmark.bm do |x|
10
- x.report { 10_000.times { TinyGQL::Parser.new(source).parse } }
8
+ files = Dir[File.join(File.expand_path("../benchmark", __dir__), "**/*")].select { |f| File.file? f }
9
+
10
+ Benchmark.ips do |x|
11
+ x.report "kitchen-sink" do
12
+ TinyGQL.parse source
13
+ end
14
+
15
+ files.each do |file_name|
16
+ data = File.read file_name
17
+ name = File.basename(file_name, File.extname(file_name))
18
+ x.report name do
19
+ TinyGQL.parse data
20
+ end
21
+ end
11
22
  end
data/bin/profile.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "vernier"
2
+
3
+ Vernier.trace(out: "time_profile.json") {
4
+ require_relative "bench"
5
+ }
data/lib/tinygql/lexer.rb CHANGED
@@ -4,38 +4,41 @@ require "strscan"
4
4
 
5
5
  module TinyGQL
6
6
  class Lexer
7
- IDENTIFIER = /[_A-Za-z][_0-9A-Za-z]*/
7
+ IDENTIFIER = /[_A-Za-z][_0-9A-Za-z]*\b/
8
8
  IGNORE = %r{
9
9
  (?:
10
10
  [, \c\r\n\t]+ |
11
11
  \#.*$
12
- )
12
+ )*
13
13
  }x
14
14
  INT = /[-]?(?:[0]|[1-9][0-9]*)/
15
15
  FLOAT_DECIMAL = /[.][0-9]+/
16
16
  FLOAT_EXP = /[eE][+-]?[0-9]+/
17
- FLOAT = /#{INT}(#{FLOAT_DECIMAL}#{FLOAT_EXP}|#{FLOAT_DECIMAL}|#{FLOAT_EXP})/
17
+ NUMERIC = /#{INT}(#{FLOAT_DECIMAL}#{FLOAT_EXP}|#{FLOAT_DECIMAL}|#{FLOAT_EXP})?/
18
+
19
+ KEYWORDS = {
20
+ "on" => :ON,
21
+ "fragment" => :FRAGMENT,
22
+ "true" => :TRUE,
23
+ "false" => :FALSE,
24
+ "null" => :NULL,
25
+ "query" => :QUERY,
26
+ "mutation" => :MUTATION,
27
+ "subscription" => :SUBSCRIPTION,
28
+ "schema" => :SCHEMA,
29
+ "scalar" => :SCALAR,
30
+ "type" => :TYPE,
31
+ "extend" => :EXTEND,
32
+ "implements" => :IMPLEMENTS,
33
+ "interface" => :INTERFACE,
34
+ "union" => :UNION,
35
+ "enum" => :ENUM,
36
+ "input" => :INPUT,
37
+ "directive" => :DIRECTIVE,
38
+ "repeatable" => :REPEATABLE
39
+ }.freeze
18
40
 
19
41
  module Literals
20
- ON = /on\b/
21
- FRAGMENT = /fragment\b/
22
- TRUE = /true\b/
23
- FALSE = /false\b/
24
- NULL = /null\b/
25
- QUERY = /query\b/
26
- MUTATION = /mutation\b/
27
- SUBSCRIPTION = /subscription\b/
28
- SCHEMA = /schema\b/
29
- SCALAR = /scalar\b/
30
- TYPE = /type\b/
31
- EXTEND = /extend\b/
32
- IMPLEMENTS = /implements\b/
33
- INTERFACE = /interface\b/
34
- UNION = /union\b/
35
- ENUM = /enum\b/
36
- INPUT = /input\b/
37
- DIRECTIVE = /directive\b/
38
- REPEATABLE = /repeatable\b/
39
42
  LCURLY = '{'
40
43
  RCURLY = '}'
41
44
  LPAREN = '('
@@ -66,9 +69,7 @@ module TinyGQL
66
69
  STRING_CHAR = /#{ESCAPED_QUOTE}|[^"\\]|#{UNICODE_ESCAPE}|#{STRING_ESCAPE}/
67
70
 
68
71
  LIT_NAME_LUT = Literals.constants.each_with_object({}) { |n, o|
69
- key = Literals.const_get(n)
70
- key = key.is_a?(Regexp) ? key.source.gsub(/(\\b|\\)/, '') : key
71
- o[key] = n
72
+ o[Literals.const_get(n)] = n
72
73
  }
73
74
 
74
75
  LIT = Regexp.union(Literals.constants.map { |n| Literals.const_get(n) })
@@ -86,9 +87,6 @@ module TinyGQL
86
87
  #{BLOCK_QUOTE}
87
88
  }xm
88
89
 
89
- # # catch-all for anything else. must be at the bottom for precedence.
90
- UNKNOWN_CHAR = /./
91
-
92
90
  def initialize string
93
91
  raise unless string.valid_encoding?
94
92
 
@@ -106,25 +104,17 @@ module TinyGQL
106
104
  end
107
105
 
108
106
  def advance
109
- while true
110
- if @scan.eos?
111
- emit nil, nil
112
- return false
113
- end
114
-
115
- case
116
- when @scan.skip(IGNORE) then redo
117
- when str = @scan.scan(FLOAT) then return emit(:FLOAT, str)
118
- when str = @scan.scan(INT) then return emit(:INT, str)
119
- when str = @scan.scan(LIT) then return emit(LIT_NAME_LUT[str], str)
120
- when str = @scan.scan(IDENTIFIER) then return emit(:IDENTIFIER, str)
121
- when @scan.skip(BLOCK_STRING) then return emit_block(@scan[1])
122
- when @scan.skip(QUOTED_STRING) then return emit_string(@scan[1])
123
- when str = @scan.scan(UNKNOWN_CHAR) then return emit(:UNKNOWN_CHAR, str)
124
- else
125
- # This should never happen since `UNKNOWN_CHAR` ensures we make progress
126
- raise "Unknown string?"
127
- end
107
+ @scan.skip(IGNORE)
108
+
109
+ case
110
+ when str = @scan.scan(LIT) then return emit(LIT_NAME_LUT[str], str)
111
+ when str = @scan.scan(IDENTIFIER) then return emit(KEYWORDS.fetch(str, :IDENTIFIER), str)
112
+ when @scan.skip(BLOCK_STRING) then return emit_block(@scan[1])
113
+ when @scan.skip(QUOTED_STRING) then return emit_string(@scan[1])
114
+ when str = @scan.scan(NUMERIC) then return emit(@scan[1] ? :FLOAT : :INT, str)
115
+ when @scan.eos? then emit(nil, nil) and return false
116
+ else
117
+ emit(:UNKNOWN_CHAR, @scan.getch)
128
118
  end
129
119
  end
130
120
 
data/lib/tinygql/nodes.rb CHANGED
@@ -3,48 +3,48 @@ module TinyGQL
3
3
  class Node
4
4
  include Enumerable
5
5
 
6
- def document? = false
7
- def operation_definition? = false
8
- def variable? = false
9
- def named_type? = false
10
- def not_null_type? = false
11
- def list_type? = false
12
- def variable_definition? = false
13
- def value? = false
14
- def argument? = false
15
- def field? = false
16
- def object_field? = false
17
- def int_value? = false
18
- def float_value? = false
19
- def string_value? = false
20
- def boolean_value? = false
21
- def null_value? = false
22
- def enum_value? = false
23
- def list_value? = false
24
- def object_value? = false
25
- def directive? = false
26
- def type_condition? = false
27
- def inline_fragment? = false
28
- def fragment_spread? = false
29
- def fragment_definition? = false
30
- def root_operation_type_definition? = false
31
- def schema_definition? = false
32
- def field_definition? = false
33
- def input_value_definition? = false
34
- def object_type_definition? = false
35
- def interface_type_definition? = false
36
- def union_type_definition? = false
37
- def scalar_type_definition? = false
38
- def enum_value_definition? = false
39
- def enum_type_definition? = false
40
- def input_object_type_definition? = false
41
- def object_type_extension? = false
42
- def executable_directive_location? = false
43
- def type_system_directive_location? = false
44
- def directive_definition? = false
6
+ def document?; false; end
7
+ def operation_definition?; false; end
8
+ def variable?; false; end
9
+ def named_type?; false; end
10
+ def not_null_type?; false; end
11
+ def list_type?; false; end
12
+ def variable_definition?; false; end
13
+ def value?; false; end
14
+ def argument?; false; end
15
+ def field?; false; end
16
+ def object_field?; false; end
17
+ def int_value?; false; end
18
+ def float_value?; false; end
19
+ def string_value?; false; end
20
+ def boolean_value?; false; end
21
+ def null_value?; false; end
22
+ def enum_value?; false; end
23
+ def list_value?; false; end
24
+ def object_value?; false; end
25
+ def directive?; false; end
26
+ def type_condition?; false; end
27
+ def inline_fragment?; false; end
28
+ def fragment_spread?; false; end
29
+ def fragment_definition?; false; end
30
+ def root_operation_type_definition?; false; end
31
+ def schema_definition?; false; end
32
+ def field_definition?; false; end
33
+ def input_value_definition?; false; end
34
+ def object_type_definition?; false; end
35
+ def interface_type_definition?; false; end
36
+ def union_type_definition?; false; end
37
+ def scalar_type_definition?; false; end
38
+ def enum_value_definition?; false; end
39
+ def enum_type_definition?; false; end
40
+ def input_object_type_definition?; false; end
41
+ def object_type_extension?; false; end
42
+ def executable_directive_location?; false; end
43
+ def type_system_directive_location?; false; end
44
+ def directive_definition?; false; end
45
45
  def each(&blk)
46
46
  yield self
47
- children.each { _1.each(&blk) }
47
+ children.each { |v| v.each(&blk) }
48
48
  end
49
49
  end
50
50
 
@@ -63,7 +63,7 @@ module TinyGQL
63
63
  viz.handle_document self, seed
64
64
  end
65
65
 
66
- def document? = true
66
+ def document?; true; end
67
67
 
68
68
  def children
69
69
  ary = []; ary.concat(definitions); ary
@@ -88,7 +88,7 @@ module TinyGQL
88
88
  viz.handle_operation_definition self, seed
89
89
  end
90
90
 
91
- def operation_definition? = true
91
+ def operation_definition?; true; end
92
92
 
93
93
  def children
94
94
  ary = []; ary.concat(variable_definitions) if variable_definitions; ary.concat(directives) if directives; ary.concat(selection_set); ary
@@ -109,7 +109,7 @@ module TinyGQL
109
109
  viz.handle_variable self, seed
110
110
  end
111
111
 
112
- def variable? = true
112
+ def variable?; true; end
113
113
 
114
114
  def children
115
115
  ary = []; ary
@@ -130,7 +130,7 @@ module TinyGQL
130
130
  viz.handle_named_type self, seed
131
131
  end
132
132
 
133
- def named_type? = true
133
+ def named_type?; true; end
134
134
 
135
135
  def children
136
136
  ary = []; ary
@@ -151,7 +151,7 @@ module TinyGQL
151
151
  viz.handle_not_null_type self, seed
152
152
  end
153
153
 
154
- def not_null_type? = true
154
+ def not_null_type?; true; end
155
155
 
156
156
  def children
157
157
  ary = []; ary << type; ary
@@ -172,7 +172,7 @@ module TinyGQL
172
172
  viz.handle_list_type self, seed
173
173
  end
174
174
 
175
- def list_type? = true
175
+ def list_type?; true; end
176
176
 
177
177
  def children
178
178
  ary = []; ary << type; ary
@@ -195,7 +195,7 @@ module TinyGQL
195
195
  viz.handle_variable_definition self, seed
196
196
  end
197
197
 
198
- def variable_definition? = true
198
+ def variable_definition?; true; end
199
199
 
200
200
  def children
201
201
  ary = []; ary << variable; ary << type; ary << default_value if default_value; ary
@@ -216,7 +216,7 @@ module TinyGQL
216
216
  viz.handle_value self, seed
217
217
  end
218
218
 
219
- def value? = true
219
+ def value?; true; end
220
220
 
221
221
  def children
222
222
  ary = []; ary
@@ -238,7 +238,7 @@ module TinyGQL
238
238
  viz.handle_argument self, seed
239
239
  end
240
240
 
241
- def argument? = true
241
+ def argument?; true; end
242
242
 
243
243
  def children
244
244
  ary = []; ary << value; ary
@@ -263,7 +263,7 @@ module TinyGQL
263
263
  viz.handle_field self, seed
264
264
  end
265
265
 
266
- def field? = true
266
+ def field?; true; end
267
267
 
268
268
  def children
269
269
  ary = []; ary.concat(arguments) if arguments; ary.concat(directives) if directives; ary.concat(selection_set) if selection_set; ary
@@ -285,7 +285,7 @@ module TinyGQL
285
285
  viz.handle_object_field self, seed
286
286
  end
287
287
 
288
- def object_field? = true
288
+ def object_field?; true; end
289
289
 
290
290
  def children
291
291
  ary = []; ary << value; ary
@@ -301,7 +301,7 @@ module TinyGQL
301
301
  viz.handle_int_value self, seed
302
302
  end
303
303
 
304
- def int_value? = true
304
+ def int_value?; true; end
305
305
 
306
306
  end
307
307
  class FloatValue < Value
@@ -314,7 +314,7 @@ module TinyGQL
314
314
  viz.handle_float_value self, seed
315
315
  end
316
316
 
317
- def float_value? = true
317
+ def float_value?; true; end
318
318
 
319
319
  end
320
320
  class StringValue < Value
@@ -327,7 +327,7 @@ module TinyGQL
327
327
  viz.handle_string_value self, seed
328
328
  end
329
329
 
330
- def string_value? = true
330
+ def string_value?; true; end
331
331
 
332
332
  end
333
333
  class BooleanValue < Value
@@ -340,7 +340,7 @@ module TinyGQL
340
340
  viz.handle_boolean_value self, seed
341
341
  end
342
342
 
343
- def boolean_value? = true
343
+ def boolean_value?; true; end
344
344
 
345
345
  end
346
346
  class NullValue < Value
@@ -353,7 +353,7 @@ module TinyGQL
353
353
  viz.handle_null_value self, seed
354
354
  end
355
355
 
356
- def null_value? = true
356
+ def null_value?; true; end
357
357
 
358
358
  end
359
359
  class EnumValue < Value
@@ -366,7 +366,7 @@ module TinyGQL
366
366
  viz.handle_enum_value self, seed
367
367
  end
368
368
 
369
- def enum_value? = true
369
+ def enum_value?; true; end
370
370
 
371
371
  end
372
372
  class ListValue < Value
@@ -379,7 +379,7 @@ module TinyGQL
379
379
  viz.handle_list_value self, seed
380
380
  end
381
381
 
382
- def list_value? = true
382
+ def list_value?; true; end
383
383
 
384
384
  end
385
385
  class ObjectValue < Node
@@ -397,7 +397,7 @@ module TinyGQL
397
397
  viz.handle_object_value self, seed
398
398
  end
399
399
 
400
- def object_value? = true
400
+ def object_value?; true; end
401
401
 
402
402
  def children
403
403
  ary = []; ary.concat(values); ary
@@ -419,7 +419,7 @@ module TinyGQL
419
419
  viz.handle_directive self, seed
420
420
  end
421
421
 
422
- def directive? = true
422
+ def directive?; true; end
423
423
 
424
424
  def children
425
425
  ary = []; ary.concat(arguments); ary
@@ -440,7 +440,7 @@ module TinyGQL
440
440
  viz.handle_type_condition self, seed
441
441
  end
442
442
 
443
- def type_condition? = true
443
+ def type_condition?; true; end
444
444
 
445
445
  def children
446
446
  ary = []; ary << named_type; ary
@@ -463,7 +463,7 @@ module TinyGQL
463
463
  viz.handle_inline_fragment self, seed
464
464
  end
465
465
 
466
- def inline_fragment? = true
466
+ def inline_fragment?; true; end
467
467
 
468
468
  def children
469
469
  ary = []; ary << type_condition if type_condition; ary.concat(directives) if directives; ary.concat(selection_set); ary
@@ -485,7 +485,7 @@ module TinyGQL
485
485
  viz.handle_fragment_spread self, seed
486
486
  end
487
487
 
488
- def fragment_spread? = true
488
+ def fragment_spread?; true; end
489
489
 
490
490
  def children
491
491
  ary = []; ary << fragment_name; ary.concat(directives) if directives; ary
@@ -509,7 +509,7 @@ module TinyGQL
509
509
  viz.handle_fragment_definition self, seed
510
510
  end
511
511
 
512
- def fragment_definition? = true
512
+ def fragment_definition?; true; end
513
513
 
514
514
  def children
515
515
  ary = []; ary << fragment_name; ary << type_condition; ary.concat(directives) if directives; ary.concat(selection_set); ary
@@ -531,16 +531,17 @@ module TinyGQL
531
531
  viz.handle_root_operation_type_definition self, seed
532
532
  end
533
533
 
534
- def root_operation_type_definition? = true
534
+ def root_operation_type_definition?; true; end
535
535
 
536
536
  def children
537
537
  ary = []; ary << operation_type; ary << named_type; ary
538
538
  end
539
539
  end
540
540
  class SchemaDefinition < Node
541
- attr_reader :directives, :root_operation_definitions
541
+ attr_reader :description, :directives, :root_operation_definitions
542
542
 
543
- def initialize directives, root_operation_definitions
543
+ def initialize description, directives, root_operation_definitions
544
+ @description = description
544
545
  @directives = directives
545
546
  @root_operation_definitions = root_operation_definitions
546
547
  end
@@ -553,7 +554,7 @@ module TinyGQL
553
554
  viz.handle_schema_definition self, seed
554
555
  end
555
556
 
556
- def schema_definition? = true
557
+ def schema_definition?; true; end
557
558
 
558
559
  def children
559
560
  ary = []; ary.concat(directives) if directives; ary.concat(root_operation_definitions); ary
@@ -578,7 +579,7 @@ module TinyGQL
578
579
  viz.handle_field_definition self, seed
579
580
  end
580
581
 
581
- def field_definition? = true
582
+ def field_definition?; true; end
582
583
 
583
584
  def children
584
585
  ary = []; ary.concat(arguments_definition) if arguments_definition; ary << type; ary.concat(directives) if directives; ary
@@ -603,7 +604,7 @@ module TinyGQL
603
604
  viz.handle_input_value_definition self, seed
604
605
  end
605
606
 
606
- def input_value_definition? = true
607
+ def input_value_definition?; true; end
607
608
 
608
609
  def children
609
610
  ary = []; ary << type; ary << default_value if default_value; ary.concat(directives) if directives; ary
@@ -628,7 +629,7 @@ module TinyGQL
628
629
  viz.handle_object_type_definition self, seed
629
630
  end
630
631
 
631
- def object_type_definition? = true
632
+ def object_type_definition?; true; end
632
633
 
633
634
  def children
634
635
  ary = []; ary.concat(implements_interfaces) if implements_interfaces; ary.concat(directives) if directives; ary.concat(fields_definition) if fields_definition; ary
@@ -652,7 +653,7 @@ module TinyGQL
652
653
  viz.handle_interface_type_definition self, seed
653
654
  end
654
655
 
655
- def interface_type_definition? = true
656
+ def interface_type_definition?; true; end
656
657
 
657
658
  def children
658
659
  ary = []; ary.concat(directives) if directives; ary.concat(fields_definition) if fields_definition; ary
@@ -676,7 +677,7 @@ module TinyGQL
676
677
  viz.handle_union_type_definition self, seed
677
678
  end
678
679
 
679
- def union_type_definition? = true
680
+ def union_type_definition?; true; end
680
681
 
681
682
  def children
682
683
  ary = []; ary.concat(directives) if directives; ary.concat(union_member_types) if union_member_types; ary
@@ -699,7 +700,7 @@ module TinyGQL
699
700
  viz.handle_scalar_type_definition self, seed
700
701
  end
701
702
 
702
- def scalar_type_definition? = true
703
+ def scalar_type_definition?; true; end
703
704
 
704
705
  def children
705
706
  ary = []; ary.concat(directives) if directives; ary
@@ -722,7 +723,7 @@ module TinyGQL
722
723
  viz.handle_enum_value_definition self, seed
723
724
  end
724
725
 
725
- def enum_value_definition? = true
726
+ def enum_value_definition?; true; end
726
727
 
727
728
  def children
728
729
  ary = []; ary << enum_value; ary.concat(directives) if directives; ary
@@ -746,7 +747,7 @@ module TinyGQL
746
747
  viz.handle_enum_type_definition self, seed
747
748
  end
748
749
 
749
- def enum_type_definition? = true
750
+ def enum_type_definition?; true; end
750
751
 
751
752
  def children
752
753
  ary = []; ary.concat(directives) if directives; ary.concat(enum_value_definition) if enum_value_definition; ary
@@ -770,7 +771,7 @@ module TinyGQL
770
771
  viz.handle_input_object_type_definition self, seed
771
772
  end
772
773
 
773
- def input_object_type_definition? = true
774
+ def input_object_type_definition?; true; end
774
775
 
775
776
  def children
776
777
  ary = []; ary.concat(directives) if directives; ary.concat(input_fields_definition) if input_fields_definition; ary
@@ -794,7 +795,7 @@ module TinyGQL
794
795
  viz.handle_object_type_extension self, seed
795
796
  end
796
797
 
797
- def object_type_extension? = true
798
+ def object_type_extension?; true; end
798
799
 
799
800
  def children
800
801
  ary = []; ary.concat(implements_interfaces) if implements_interfaces; ary.concat(directives) if directives; ary.concat(fields_definition) if fields_definition; ary
@@ -815,7 +816,7 @@ module TinyGQL
815
816
  viz.handle_executable_directive_location self, seed
816
817
  end
817
818
 
818
- def executable_directive_location? = true
819
+ def executable_directive_location?; true; end
819
820
 
820
821
  def children
821
822
  ary = []; ary
@@ -836,7 +837,7 @@ module TinyGQL
836
837
  viz.handle_type_system_directive_location self, seed
837
838
  end
838
839
 
839
- def type_system_directive_location? = true
840
+ def type_system_directive_location?; true; end
840
841
 
841
842
  def children
842
843
  ary = []; ary
@@ -860,7 +861,7 @@ module TinyGQL
860
861
  viz.handle_directive_definition self, seed
861
862
  end
862
863
 
863
- def directive_definition? = true
864
+ def directive_definition?; true; end
864
865
 
865
866
  def children
866
867
  ary = []; ary.concat(arguments_definition) if arguments_definition; ary.concat(directive_locations); ary
@@ -4,7 +4,7 @@ module TinyGQL
4
4
  include Enumerable
5
5
 
6
6
  <%- nodes.each do |node| -%>
7
- def <%= node.human_name %>? = false
7
+ def <%= node.human_name %>?; false; end
8
8
  <%- end -%>
9
9
  def each(&blk)
10
10
  yield self
@@ -32,7 +32,7 @@ module TinyGQL
32
32
  viz.handle_<%= node.human_name %> self, seed
33
33
  end
34
34
 
35
- def <%= node.human_name %>? = true
35
+ def <%= node.human_name %>?; true; end
36
36
 
37
37
  <%- if node.has_children? -%>
38
38
  def children