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 +4 -4
- data/.github/workflows/ci.yml +2 -2
- data/Gemfile +0 -1
- data/lib/tinygql/lexer.rb +71 -18
- data/lib/tinygql/version.rb +1 -1
- data/lib/tinygql/visitors.rb +272 -0
- data/lib/tinygql/visitors.rb.erb +14 -0
- data/test/lexer_test.rb +1 -1
- data/test/parser_test.rb +48 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a68b5713ff3ff9e39df6e5eb89f7eec5fc74f524df33f9840f58cd8ac5027ec
|
4
|
+
data.tar.gz: f823e82df55af3ca0327889627e99f6d896242327369b698d505b921bba819a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0b4cd65e5c017f820e7198479a54dde8f676eb52fac56d9672a173ef282b21862a028f4a685d59c49c6dbfbd2d213148eff27674b071cff561e1cd6fe685251
|
7
|
+
data.tar.gz: 266db1a7ad62bae36b375403286ec1a08b774f2fad5dc1808bacbac5e86e89ea165d9dc9d1a7598e9e4d059a7e55e0a88396df786f17aba2c6c011534a201e14
|
data/.github/workflows/ci.yml
CHANGED
@@ -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
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
|
-
|
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
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
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
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
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
|
-
|
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
|
-
|
127
|
-
|
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.
|
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
|
data/lib/tinygql/version.rb
CHANGED
data/lib/tinygql/visitors.rb
CHANGED
@@ -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
|
data/lib/tinygql/visitors.rb.erb
CHANGED
@@ -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
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.
|
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-
|
11
|
+
date: 2023-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|