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