tinygql 0.3.0 → 0.3.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e6f2ac9d1c4531277689c6eec21fd29cd1e6fe9715284813b57c741e3e9bace2
4
- data.tar.gz: b9cd18ac29f1aeea347296f0408deadddec7a902d25495e3232b472180718695
3
+ metadata.gz: 4a68b5713ff3ff9e39df6e5eb89f7eec5fc74f524df33f9840f58cd8ac5027ec
4
+ data.tar.gz: f823e82df55af3ca0327889627e99f6d896242327369b698d505b921bba819a9
5
5
  SHA512:
6
- metadata.gz: 63c931df357b6091070a7cd0adab859f7a7489f8fa1220ffa2cfb7fc6a7af6660ede87af6c3a8b804ef1a2114594aa3086a3792b5d3ef40e20ac1a4546d13120
7
- data.tar.gz: 96e0a9164e835cb382391c9ea761cdf2405ac6f38e268034f810f8ce369d4e968ec5a2c174f22f03f50a99bd1f155449e5d9e7b46c65fc771263cbc03a8f2f8b
6
+ metadata.gz: a0b4cd65e5c017f820e7198479a54dde8f676eb52fac56d9672a173ef282b21862a028f4a685d59c49c6dbfbd2d213148eff27674b071cff561e1cd6fe685251
7
+ data.tar.gz: 266db1a7ad62bae36b375403286ec1a08b774f2fad5dc1808bacbac5e86e89ea165d9dc9d1a7598e9e4d059a7e55e0a88396df786f17aba2c6c011534a201e14
@@ -10,7 +10,7 @@ jobs:
10
10
  fail-fast: false
11
11
  matrix:
12
12
  os: [ubuntu, macos]
13
- ruby: [ head, 3.2 ]
13
+ ruby: [ head, 3.2, truffleruby, truffleruby-head, jruby ]
14
14
 
15
15
  steps:
16
16
  - uses: actions/checkout@v3
@@ -31,7 +31,7 @@ jobs:
31
31
  fail-fast: false
32
32
  matrix:
33
33
  os: [ubuntu, macos]
34
- ruby: [ head, 3.2 ]
34
+ ruby: [ head, 3.2, truffleruby, truffleruby-head ]
35
35
 
36
36
  steps:
37
37
  - uses: actions/checkout@v3
data/Gemfile CHANGED
@@ -1,6 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gem "benchmark-ips"
4
- gem "vernier"
5
4
 
6
5
  gemspec
data/lib/tinygql/lexer.rb CHANGED
@@ -71,10 +71,37 @@ module TinyGQL
71
71
  ESCAPED_QUOTE = /\\"/;
72
72
  STRING_CHAR = /#{ESCAPED_QUOTE}|[^"\\]|#{UNICODE_ESCAPE}|#{STRING_ESCAPE}/
73
73
 
74
- LIT_NAME_LUT = Literals.constants.each_with_object([]) { |n, o|
74
+ PUNCT_LUT = Literals.constants.each_with_object([]) { |n, o|
75
75
  o[Literals.const_get(n).ord] = n
76
76
  }
77
77
 
78
+ LEAD_BYTES = Array.new(255) { 0 }
79
+
80
+ module LeadBytes
81
+ INT = 1
82
+ KW = 2
83
+ ELLIPSIS = 3
84
+ STRING = 4
85
+ PUNCT = 5
86
+ IDENT = 6
87
+ end
88
+
89
+ 10.times { |i| LEAD_BYTES[i.to_s.ord] = LeadBytes::INT }
90
+
91
+ ("A".."Z").each { |chr| LEAD_BYTES[chr.ord] = LeadBytes::IDENT }
92
+ ("a".."z").each { |chr| LEAD_BYTES[chr.ord] = LeadBytes::IDENT }
93
+ LEAD_BYTES['_'.ord] = LeadBytes::IDENT
94
+
95
+ KEYWORDS.each { |kw| LEAD_BYTES[kw.getbyte(0)] = LeadBytes::KW }
96
+
97
+ LEAD_BYTES['.'.ord] = LeadBytes::ELLIPSIS
98
+
99
+ LEAD_BYTES['"'.ord] = LeadBytes::STRING
100
+
101
+ Literals.constants.each_with_object([]) { |n, o|
102
+ LEAD_BYTES[Literals.const_get(n).ord] = LeadBytes::PUNCT
103
+ }
104
+
78
105
  QUOTED_STRING = %r{#{QUOTE} ((?:#{STRING_CHAR})*) #{QUOTE}}x
79
106
  BLOCK_STRING = %r{
80
107
  #{BLOCK_QUOTE}
@@ -109,30 +136,54 @@ module TinyGQL
109
136
  def advance
110
137
  @scan.skip(IGNORE)
111
138
 
139
+ return false if @scan.eos?
140
+
112
141
  @start = @scan.pos
113
142
 
114
- case
115
- when @scan.eos? then false
116
- when @scan.skip(ELLIPSIS) then :ELLIPSIS
117
- when tok = LIT_NAME_LUT[@string.getbyte(@start)] then
143
+ lead_byte = @string.getbyte(@start)
144
+ lead_code = LEAD_BYTES[lead_byte]
145
+
146
+ if lead_code == LeadBytes::PUNCT
118
147
  @scan.pos += 1
119
- tok
120
- when len = @scan.skip(KW_RE) then
121
- return :ON if len == 2
122
- return :SUBSCRIPTION if len == 12
148
+ PUNCT_LUT[lead_byte]
149
+
150
+ elsif lead_code == LeadBytes::KW
151
+ if len = @scan.skip(KW_RE)
152
+ return :ON if len == 2
153
+ return :SUBSCRIPTION if len == 12
154
+
155
+ pos = @start
123
156
 
124
- pos = @start
157
+ # Second 2 bytes are unique, so we'll hash on those
158
+ key = (@string.getbyte(pos + 2) << 8) | @string.getbyte(pos + 1)
159
+
160
+ KW_LUT[_hash(key)]
161
+ else
162
+ @scan.skip(IDENTIFIER)
163
+ :IDENTIFIER
164
+ end
125
165
 
126
- # Second 2 bytes are unique, so we'll hash on those
127
- key = (@string.getbyte(pos + 2) << 8) | @string.getbyte(pos + 1)
166
+ elsif lead_code == LeadBytes::IDENT
167
+ @scan.skip(IDENTIFIER)
168
+ :IDENTIFIER
169
+
170
+ elsif lead_code == LeadBytes::INT
171
+ @scan.skip(NUMERIC)
172
+ @scan[1] ? :FLOAT : :INT
173
+
174
+ elsif lead_code == LeadBytes::ELLIPSIS
175
+ 2.times do |i|
176
+ raise unless @string.getbyte(@start + i + 1) == 46
177
+ end
178
+ @scan.pos += 3
179
+ :ELLIPSIS
180
+
181
+ elsif lead_code == LeadBytes::STRING
182
+ raise unless @scan.skip(BLOCK_STRING) || @scan.skip(QUOTED_STRING)
183
+ :STRING
128
184
 
129
- KW_LUT[_hash(key)]
130
- when @scan.skip(IDENTIFIER) then :IDENTIFIER
131
- when @scan.skip(BLOCK_STRING) then :STRING
132
- when @scan.skip(QUOTED_STRING) then :STRING
133
- when @scan.skip(NUMERIC) then (@scan[1] ? :FLOAT : :INT)
134
185
  else
135
- @scan.getch
186
+ @scan.pos += 1
136
187
  :UNKNOWN_CHAR
137
188
  end
138
189
  end
@@ -157,6 +208,8 @@ module TinyGQL
157
208
  return unless tok = advance
158
209
  val = case tok
159
210
  when :STRING then string_value
211
+ when :ELLIPSIS then
212
+ @string.byteslice(@scan.pos - 3, 3)
160
213
  when *Literals.constants
161
214
  @string.byteslice(@scan.pos - 1, 1)
162
215
  else
@@ -1,3 +1,3 @@
1
1
  module TinyGQL
2
- VERSION = '0.3.0'
2
+ VERSION = '0.3.1'
3
3
  end
@@ -461,5 +461,277 @@ module TinyGQL
461
461
  end
462
462
 
463
463
  end
464
+
465
+ module Null
466
+
467
+ def handle_document obj
468
+ end
469
+
470
+ def handle_operation_definition obj
471
+ end
472
+
473
+ def handle_variable obj
474
+ end
475
+
476
+ def handle_named_type obj
477
+ end
478
+
479
+ def handle_not_null_type obj
480
+ end
481
+
482
+ def handle_list_type obj
483
+ end
484
+
485
+ def handle_variable_definition obj
486
+ end
487
+
488
+ def handle_value obj
489
+ end
490
+
491
+ def handle_argument obj
492
+ end
493
+
494
+ def handle_field obj
495
+ end
496
+
497
+ def handle_object_field obj
498
+ end
499
+
500
+ def handle_int_value obj
501
+ end
502
+
503
+ def handle_float_value obj
504
+ end
505
+
506
+ def handle_string_value obj
507
+ end
508
+
509
+ def handle_boolean_value obj
510
+ end
511
+
512
+ def handle_null_value obj
513
+ end
514
+
515
+ def handle_enum_value obj
516
+ end
517
+
518
+ def handle_list_value obj
519
+ end
520
+
521
+ def handle_object_value obj
522
+ end
523
+
524
+ def handle_directive obj
525
+ end
526
+
527
+ def handle_type_condition obj
528
+ end
529
+
530
+ def handle_inline_fragment obj
531
+ end
532
+
533
+ def handle_fragment_spread obj
534
+ end
535
+
536
+ def handle_fragment_definition obj
537
+ end
538
+
539
+ def handle_root_operation_type_definition obj
540
+ end
541
+
542
+ def handle_schema_definition obj
543
+ end
544
+
545
+ def handle_field_definition obj
546
+ end
547
+
548
+ def handle_input_value_definition obj
549
+ end
550
+
551
+ def handle_object_type_definition obj
552
+ end
553
+
554
+ def handle_interface_type_definition obj
555
+ end
556
+
557
+ def handle_union_type_definition obj
558
+ end
559
+
560
+ def handle_scalar_type_definition obj
561
+ end
562
+
563
+ def handle_enum_value_definition obj
564
+ end
565
+
566
+ def handle_enum_type_definition obj
567
+ end
568
+
569
+ def handle_input_object_type_definition obj
570
+ end
571
+
572
+ def handle_object_type_extension obj
573
+ end
574
+
575
+ def handle_executable_directive_location obj
576
+ end
577
+
578
+ def handle_type_system_directive_location obj
579
+ end
580
+
581
+ def handle_directive_definition obj
582
+ end
583
+
584
+ def handle_scalar_type_extension obj
585
+ end
586
+
587
+ def handle_interface_type_extension obj
588
+ end
589
+
590
+ def handle_union_type_extension obj
591
+ end
592
+
593
+ def handle_enum_type_extension obj
594
+ end
595
+
596
+ def handle_input_object_type_extension obj
597
+ end
598
+
599
+ end
600
+
601
+ module NullFold
602
+
603
+ def handle_document obj, _
604
+ end
605
+
606
+ def handle_operation_definition obj, _
607
+ end
608
+
609
+ def handle_variable obj, _
610
+ end
611
+
612
+ def handle_named_type obj, _
613
+ end
614
+
615
+ def handle_not_null_type obj, _
616
+ end
617
+
618
+ def handle_list_type obj, _
619
+ end
620
+
621
+ def handle_variable_definition obj, _
622
+ end
623
+
624
+ def handle_value obj, _
625
+ end
626
+
627
+ def handle_argument obj, _
628
+ end
629
+
630
+ def handle_field obj, _
631
+ end
632
+
633
+ def handle_object_field obj, _
634
+ end
635
+
636
+ def handle_int_value obj, _
637
+ end
638
+
639
+ def handle_float_value obj, _
640
+ end
641
+
642
+ def handle_string_value obj, _
643
+ end
644
+
645
+ def handle_boolean_value obj, _
646
+ end
647
+
648
+ def handle_null_value obj, _
649
+ end
650
+
651
+ def handle_enum_value obj, _
652
+ end
653
+
654
+ def handle_list_value obj, _
655
+ end
656
+
657
+ def handle_object_value obj, _
658
+ end
659
+
660
+ def handle_directive obj, _
661
+ end
662
+
663
+ def handle_type_condition obj, _
664
+ end
665
+
666
+ def handle_inline_fragment obj, _
667
+ end
668
+
669
+ def handle_fragment_spread obj, _
670
+ end
671
+
672
+ def handle_fragment_definition obj, _
673
+ end
674
+
675
+ def handle_root_operation_type_definition obj, _
676
+ end
677
+
678
+ def handle_schema_definition obj, _
679
+ end
680
+
681
+ def handle_field_definition obj, _
682
+ end
683
+
684
+ def handle_input_value_definition obj, _
685
+ end
686
+
687
+ def handle_object_type_definition obj, _
688
+ end
689
+
690
+ def handle_interface_type_definition obj, _
691
+ end
692
+
693
+ def handle_union_type_definition obj, _
694
+ end
695
+
696
+ def handle_scalar_type_definition obj, _
697
+ end
698
+
699
+ def handle_enum_value_definition obj, _
700
+ end
701
+
702
+ def handle_enum_type_definition obj, _
703
+ end
704
+
705
+ def handle_input_object_type_definition obj, _
706
+ end
707
+
708
+ def handle_object_type_extension obj, _
709
+ end
710
+
711
+ def handle_executable_directive_location obj, _
712
+ end
713
+
714
+ def handle_type_system_directive_location obj, _
715
+ end
716
+
717
+ def handle_directive_definition obj, _
718
+ end
719
+
720
+ def handle_scalar_type_extension obj, _
721
+ end
722
+
723
+ def handle_interface_type_extension obj, _
724
+ end
725
+
726
+ def handle_union_type_extension obj, _
727
+ end
728
+
729
+ def handle_enum_type_extension obj, _
730
+ end
731
+
732
+ def handle_input_object_type_extension obj, _
733
+ end
734
+
735
+ end
464
736
  end
465
737
  end
@@ -28,6 +28,20 @@ module TinyGQL
28
28
  <%- end -%>
29
29
  seed
30
30
  end
31
+ <% end %>
32
+ end
33
+
34
+ module Null
35
+ <% nodes.each do |node| %>
36
+ def handle_<%= node.human_name %> obj
37
+ end
38
+ <% end %>
39
+ end
40
+
41
+ module NullFold
42
+ <% nodes.each do |node| %>
43
+ def handle_<%= node.human_name %> obj, _
44
+ end
31
45
  <% end %>
32
46
  end
33
47
  end
data/test/lexer_test.rb CHANGED
@@ -21,7 +21,7 @@ module TinyGQL
21
21
  lexer = Lexer.new punc
22
22
  token = lexer.next_token
23
23
  expected = PUNC_LUT[punc]
24
- assert_equal(expected || [:ON, "on"], token)
24
+ assert_equal(expected, token)
25
25
  end
26
26
  end
27
27
 
data/test/parser_test.rb CHANGED
@@ -165,6 +165,54 @@ eod
165
165
  assert_equal 1, node.arguments.length
166
166
  end
167
167
 
168
+ def test_null
169
+ doc = <<-eod
170
+ mutation {
171
+ a: likeStory(storyID: 12345) {
172
+ b: story {
173
+ c: likeCount
174
+ }
175
+ }
176
+ }
177
+ eod
178
+ viz = Module.new do
179
+ extend TinyGQL::Visitors::Null
180
+
181
+ def self.handle_field obj
182
+ true
183
+ end
184
+ end
185
+ parser = Parser.new doc
186
+ ast = parser.parse
187
+ ast.each { |node|
188
+ assert_equal(node.field?, !!node.accept(viz))
189
+ }
190
+ end
191
+
192
+ def test_null_fold
193
+ doc = <<-eod
194
+ mutation {
195
+ a: likeStory(storyID: 12345) {
196
+ b: story {
197
+ c: likeCount
198
+ }
199
+ }
200
+ }
201
+ eod
202
+ viz = Module.new do
203
+ extend TinyGQL::Visitors::NullFold
204
+
205
+ def self.handle_field obj, x
206
+ x
207
+ end
208
+ end
209
+ parser = Parser.new doc
210
+ ast = parser.parse
211
+ ast.each { |node|
212
+ assert_equal(node.field?, !!node.fold(viz, true))
213
+ }
214
+ end
215
+
168
216
  def test_multiple_implements
169
217
  doc = <<-eod
170
218
  type SomeType implements a, b, c {
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tinygql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-30 00:00:00.000000000 Z
11
+ date: 2023-09-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake