tinygql 0.1.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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