ripper_ruby_parser 1.4.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -1
  3. data/README.md +41 -9
  4. data/Rakefile +2 -0
  5. data/lib/ripper_ruby_parser.rb +2 -0
  6. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +23 -45
  7. data/lib/ripper_ruby_parser/parser.rb +11 -1
  8. data/lib/ripper_ruby_parser/sexp_handlers.rb +2 -6
  9. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +49 -35
  10. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +78 -39
  11. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +16 -15
  12. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +19 -15
  13. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +138 -30
  14. data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +10 -6
  15. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +59 -14
  16. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +56 -32
  17. data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +20 -27
  18. data/lib/ripper_ruby_parser/sexp_processor.rb +40 -10
  19. data/lib/ripper_ruby_parser/syntax_error.rb +2 -0
  20. data/lib/ripper_ruby_parser/unescape.rb +32 -11
  21. data/lib/ripper_ruby_parser/version.rb +3 -1
  22. data/test/end_to_end/comments_test.rb +2 -0
  23. data/test/end_to_end/comparison_test.rb +2 -0
  24. data/test/end_to_end/lib_comparison_test.rb +2 -0
  25. data/test/end_to_end/line_numbering_test.rb +2 -0
  26. data/test/end_to_end/samples_comparison_test.rb +5 -29
  27. data/test/end_to_end/test_comparison_test.rb +2 -0
  28. data/test/pt_testcase/pt_test.rb +2 -0
  29. data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +16 -2
  30. data/test/ripper_ruby_parser/parser_test.rb +17 -688
  31. data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +459 -26
  32. data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +152 -82
  33. data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +91 -0
  34. data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +331 -24
  35. data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +88 -0
  36. data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +58 -5
  37. data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +392 -0
  38. data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +174 -12
  39. data/test/ripper_ruby_parser/sexp_processor_test.rb +8 -18
  40. data/test/ripper_ruby_parser/version_test.rb +2 -0
  41. data/test/samples/comments.rb +13 -0
  42. data/test/samples/conditionals.rb +23 -0
  43. data/test/samples/loops.rb +36 -0
  44. data/test/samples/misc.rb +157 -5
  45. data/test/samples/number.rb +7 -0
  46. data/test/samples/strings.rb +39 -0
  47. data/test/test_helper.rb +22 -1
  48. metadata +18 -12
  49. data/lib/ripper_ruby_parser/sexp_handlers/arguments.rb +0 -29
  50. data/lib/ripper_ruby_parser/sexp_handlers/arrays.rb +0 -21
  51. data/lib/ripper_ruby_parser/sexp_handlers/hashes.rb +0 -48
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../../test_helper.rb', File.dirname(__FILE__))
2
4
 
3
5
  describe RipperRubyParser::Parser do
@@ -58,6 +60,34 @@ describe RipperRubyParser::Parser do
58
60
  s(:call, s(:call, nil, :foo), :=~, s(:call, nil, :bar)),
59
61
  s(:call, nil, :baz), true)
60
62
  end
63
+
64
+ it 'cleans up begin..end block in condition' do
65
+ 'while begin foo end; bar; end'.
66
+ must_be_parsed_as s(:while,
67
+ s(:call, nil, :foo),
68
+ s(:call, nil, :bar), true)
69
+ end
70
+
71
+ it 'cleans up begin..end block in condition in the postfix case' do
72
+ 'foo while begin bar end'.
73
+ must_be_parsed_as s(:while,
74
+ s(:call, nil, :bar),
75
+ s(:call, nil, :foo), true)
76
+ end
77
+
78
+ it 'works with do and an empty body' do
79
+ 'while foo do; end'.
80
+ must_be_parsed_as s(:while,
81
+ s(:call, nil, :foo),
82
+ nil, true)
83
+ end
84
+
85
+ it 'works without do and with an empty body' do
86
+ 'while foo; end'.
87
+ must_be_parsed_as s(:while,
88
+ s(:call, nil, :foo),
89
+ nil, true)
90
+ end
61
91
  end
62
92
 
63
93
  describe 'for the until statement' do
@@ -116,6 +146,64 @@ describe RipperRubyParser::Parser do
116
146
  s(:call, s(:call, nil, :foo), :=~, s(:call, nil, :bar)),
117
147
  s(:call, nil, :baz), true)
118
148
  end
149
+
150
+ it 'cleans up begin..end block in condition' do
151
+ 'until begin foo end; bar; end'.
152
+ must_be_parsed_as s(:until,
153
+ s(:call, nil, :foo),
154
+ s(:call, nil, :bar), true)
155
+ end
156
+
157
+ it 'cleans up begin..end block in condition in the postfix case' do
158
+ 'foo until begin bar end'.
159
+ must_be_parsed_as s(:until,
160
+ s(:call, nil, :bar),
161
+ s(:call, nil, :foo), true)
162
+ end
163
+ end
164
+
165
+ describe 'for the for statement' do
166
+ it 'works with do' do
167
+ 'for foo in bar do; baz; end'.
168
+ must_be_parsed_as s(:for,
169
+ s(:call, nil, :bar),
170
+ s(:lasgn, :foo),
171
+ s(:call, nil, :baz))
172
+ end
173
+
174
+ it 'works without do' do
175
+ 'for foo in bar; baz; end'.
176
+ must_be_parsed_as s(:for,
177
+ s(:call, nil, :bar),
178
+ s(:lasgn, :foo),
179
+ s(:call, nil, :baz))
180
+ end
181
+
182
+ it 'works with an empty body' do
183
+ 'for foo in bar; end'.
184
+ must_be_parsed_as s(:for,
185
+ s(:call, nil, :bar),
186
+ s(:lasgn, :foo))
187
+ end
188
+
189
+ it 'works with explicit multiple assignment' do
190
+ 'for foo, bar in baz; end'.
191
+ must_be_parsed_as s(:for,
192
+ s(:call, nil, :baz),
193
+ s(:masgn,
194
+ s(:array,
195
+ s(:lasgn, :foo),
196
+ s(:lasgn, :bar))))
197
+ end
198
+
199
+ it 'works with multiple assignment with trailing comma' do
200
+ 'for foo, in bar; end'.
201
+ must_be_parsed_as s(:for,
202
+ s(:call, nil, :bar),
203
+ s(:masgn,
204
+ s(:array,
205
+ s(:lasgn, :foo))))
206
+ end
119
207
  end
120
208
  end
121
209
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../../test_helper.rb', File.dirname(__FILE__))
2
4
 
3
- describe RipperRubyParser::Parser do
4
- describe '#parse' do
5
+ describe RipperRubyParser::SexpHandlers::MethodCalls do
6
+ describe 'when parsing with RipperRubyParser::Parser#parse' do
5
7
  describe 'for method calls' do
6
8
  describe 'without a receiver' do
7
9
  it 'works without parentheses' do
@@ -135,13 +137,34 @@ describe RipperRubyParser::Parser do
135
137
  s(:call, nil, :baz,
136
138
  s(:call, nil, :qux)))
137
139
  end
140
+
141
+ it 'does not keep :begin around a method receiver' do
142
+ 'begin; foo; end.bar'.
143
+ must_be_parsed_as s(:call, s(:call, nil, :foo), :bar)
144
+ end
138
145
  end
139
146
 
140
- describe 'safe call' do
141
- before do
142
- skip 'This is not valid syntax below Ruby 2.3' if RUBY_VERSION < '2.3.0'
147
+ describe 'for collection indexing' do
148
+ it 'works in the simple case' do
149
+ 'foo[bar]'.
150
+ must_be_parsed_as s(:call,
151
+ s(:call, nil, :foo),
152
+ :[],
153
+ s(:call, nil, :bar))
154
+ end
155
+
156
+ it 'works without any indexes' do
157
+ 'foo[]'.must_be_parsed_as s(:call, s(:call, nil, :foo),
158
+ :[])
159
+ end
160
+
161
+ it 'works with self[]' do
162
+ 'self[foo]'.must_be_parsed_as s(:call, s(:self), :[],
163
+ s(:call, nil, :foo))
143
164
  end
165
+ end
144
166
 
167
+ describe 'safe call' do
145
168
  it 'works without arguments' do
146
169
  'foo&.bar'.must_be_parsed_as s(:safe_call, s(:call, nil, :foo), :bar)
147
170
  end
@@ -211,4 +234,34 @@ describe RipperRubyParser::Parser do
211
234
  must_be_parsed_as s(:call, s(:call, nil, :foo), :call)
212
235
  end
213
236
  end
237
+
238
+ describe 'when processing a Sexp' do
239
+ let(:processor) { RipperRubyParser::SexpProcessor.new }
240
+
241
+ describe '#process_command_call' do
242
+ it 'processes a Ruby 2.5 style period Sexp' do
243
+ sexp = s(:call,
244
+ s(:vcall, s(:@ident, 'foo', s(1, 0))),
245
+ :'.',
246
+ s(:@ident, 'bar', s(1, 4)))
247
+ processor.process(sexp).must_equal s(:call, s(:call, nil, :foo), :bar)
248
+ end
249
+
250
+ it 'processes a Ruby 2.6 style period Sexp' do
251
+ sexp = s(:call,
252
+ s(:vcall, s(:@ident, 'foo', s(1, 0))),
253
+ s(:@period, '.', s(1, 3)),
254
+ s(:@ident, 'bar', s(1, 4)))
255
+ processor.process(sexp).must_equal s(:call, s(:call, nil, :foo), :bar)
256
+ end
257
+
258
+ it 'raises an error for an unknown call operator' do
259
+ sexp = s(:call,
260
+ s(:vcall, s(:@ident, 'foo', s(1, 0))),
261
+ :'>.',
262
+ s(:@ident, 'bar', s(1, 4)))
263
+ -> { processor.process(sexp) }.must_raise
264
+ end
265
+ end
266
+ end
214
267
  end
@@ -0,0 +1,392 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../../test_helper.rb', File.dirname(__FILE__))
4
+
5
+ describe RipperRubyParser::Parser do
6
+ describe '#parse' do
7
+ describe 'for instance method definitions' do
8
+ it 'treats kwargs as a local variable' do
9
+ 'def foo(**bar); bar; end'.
10
+ must_be_parsed_as s(:defn,
11
+ :foo,
12
+ s(:args, :"**bar"),
13
+ s(:lvar, :bar))
14
+ end
15
+
16
+ it 'treats kwargs as a local variable when other arguments are present' do
17
+ 'def foo(bar, **baz); baz; end'.
18
+ must_be_parsed_as s(:defn,
19
+ :foo,
20
+ s(:args, :bar, :"**baz"),
21
+ s(:lvar, :baz))
22
+ end
23
+
24
+ it 'treats kwargs as a local variable when an explicit block is present' do
25
+ 'def foo(**bar, &baz); bar; end'.
26
+ must_be_parsed_as s(:defn,
27
+ :foo,
28
+ s(:args, :"**bar", :"&baz"),
29
+ s(:lvar, :bar))
30
+ end
31
+
32
+ it 'treats block kwargs as lvars' do
33
+ 'def foo(**bar); baz { |**qux| bar; qux }; end'.
34
+ must_be_parsed_as s(:defn, :foo,
35
+ s(:args, :"**bar"),
36
+ s(:iter,
37
+ s(:call, nil, :baz),
38
+ s(:args, :"**qux"),
39
+ s(:block,
40
+ s(:lvar, :bar),
41
+ s(:lvar, :qux))))
42
+ end
43
+
44
+ it 'works with a method argument with a default value' do
45
+ 'def foo bar=nil; end'.
46
+ must_be_parsed_as s(:defn,
47
+ :foo,
48
+ s(:args, s(:lasgn, :bar, s(:nil))),
49
+ s(:nil))
50
+ end
51
+
52
+ it 'works with several method arguments with default values' do
53
+ 'def foo bar=1, baz=2; end'.
54
+ must_be_parsed_as s(:defn,
55
+ :foo,
56
+ s(:args,
57
+ s(:lasgn, :bar, s(:lit, 1)),
58
+ s(:lasgn, :baz, s(:lit, 2))),
59
+ s(:nil))
60
+ end
61
+
62
+ it 'works with parentheses around the parameter list' do
63
+ 'def foo(bar); end'.
64
+ must_be_parsed_as s(:defn, :foo, s(:args, :bar), s(:nil))
65
+ end
66
+
67
+ it 'works with a simple splat' do
68
+ 'def foo *bar; end'.
69
+ must_be_parsed_as s(:defn, :foo, s(:args, :"*bar"), s(:nil))
70
+ end
71
+
72
+ it 'works with a regular argument plus splat' do
73
+ 'def foo bar, *baz; end'.
74
+ must_be_parsed_as s(:defn, :foo, s(:args, :bar, :"*baz"), s(:nil))
75
+ end
76
+
77
+ it 'works with a nameless splat' do
78
+ 'def foo *; end'.
79
+ must_be_parsed_as s(:defn,
80
+ :foo,
81
+ s(:args, :"*"),
82
+ s(:nil))
83
+ end
84
+
85
+ it 'works for a simple case with explicit block parameter' do
86
+ 'def foo &bar; end'.
87
+ must_be_parsed_as s(:defn,
88
+ :foo,
89
+ s(:args, :"&bar"),
90
+ s(:nil))
91
+ end
92
+
93
+ it 'works with a regular argument plus explicit block parameter' do
94
+ 'def foo bar, &baz; end'.
95
+ must_be_parsed_as s(:defn,
96
+ :foo,
97
+ s(:args, :bar, :"&baz"),
98
+ s(:nil))
99
+ end
100
+
101
+ it 'works with a default value plus explicit block parameter' do
102
+ 'def foo bar=1, &baz; end'.
103
+ must_be_parsed_as s(:defn,
104
+ :foo,
105
+ s(:args,
106
+ s(:lasgn, :bar, s(:lit, 1)),
107
+ :"&baz"),
108
+ s(:nil))
109
+ end
110
+
111
+ it 'works with a default value plus mandatory argument' do
112
+ 'def foo bar=1, baz; end'.
113
+ must_be_parsed_as s(:defn,
114
+ :foo,
115
+ s(:args,
116
+ s(:lasgn, :bar, s(:lit, 1)),
117
+ :baz),
118
+ s(:nil))
119
+ end
120
+
121
+ it 'works with a splat plus explicit block parameter' do
122
+ 'def foo *bar, &baz; end'.
123
+ must_be_parsed_as s(:defn,
124
+ :foo,
125
+ s(:args, :"*bar", :"&baz"),
126
+ s(:nil))
127
+ end
128
+
129
+ it 'works with a default value plus splat' do
130
+ 'def foo bar=1, *baz; end'.
131
+ must_be_parsed_as s(:defn,
132
+ :foo,
133
+ s(:args,
134
+ s(:lasgn, :bar, s(:lit, 1)),
135
+ :"*baz"),
136
+ s(:nil))
137
+ end
138
+
139
+ it 'works with a default value, splat, plus final mandatory arguments' do
140
+ 'def foo bar=1, *baz, qux, quuz; end'.
141
+ must_be_parsed_as s(:defn,
142
+ :foo,
143
+ s(:args,
144
+ s(:lasgn, :bar, s(:lit, 1)),
145
+ :"*baz", :qux, :quuz),
146
+ s(:nil))
147
+ end
148
+
149
+ it 'works with a named argument with a default value' do
150
+ 'def foo bar: 1; end'.
151
+ must_be_parsed_as s(:defn,
152
+ :foo,
153
+ s(:args,
154
+ s(:kwarg, :bar, s(:lit, 1))),
155
+ s(:nil))
156
+ end
157
+
158
+ it 'works with a named argument with no default value' do
159
+ 'def foo bar:; end'.
160
+ must_be_parsed_as s(:defn,
161
+ :foo,
162
+ s(:args,
163
+ s(:kwarg, :bar)),
164
+ s(:nil))
165
+ end
166
+
167
+ it 'works with a double splat' do
168
+ 'def foo **bar; end'.
169
+ must_be_parsed_as s(:defn,
170
+ :foo,
171
+ s(:args, :'**bar'),
172
+ s(:nil))
173
+ end
174
+
175
+ it 'works when the method name is an operator' do
176
+ 'def +; end'.
177
+ must_be_parsed_as s(:defn, :+, s(:args),
178
+ s(:nil))
179
+ end
180
+ end
181
+
182
+ describe 'for singleton method definitions' do
183
+ it 'works with empty body' do
184
+ 'def foo.bar; end'.
185
+ must_be_parsed_as s(:defs,
186
+ s(:call, nil, :foo),
187
+ :bar,
188
+ s(:args),
189
+ s(:nil))
190
+ end
191
+
192
+ it 'works with a body with multiple statements' do
193
+ 'def foo.bar; baz; qux; end'.
194
+ must_be_parsed_as s(:defs,
195
+ s(:call, nil, :foo),
196
+ :bar,
197
+ s(:args),
198
+ s(:call, nil, :baz),
199
+ s(:call, nil, :qux))
200
+ end
201
+
202
+ it 'works with a simple splat' do
203
+ 'def foo.bar *baz; end'.
204
+ must_be_parsed_as s(:defs,
205
+ s(:call, nil, :foo),
206
+ :bar,
207
+ s(:args, :"*baz"),
208
+ s(:nil))
209
+ end
210
+ end
211
+
212
+ describe 'for the alias statement' do
213
+ it 'works with regular barewords' do
214
+ 'alias foo bar'.
215
+ must_be_parsed_as s(:alias,
216
+ s(:lit, :foo), s(:lit, :bar))
217
+ end
218
+
219
+ it 'works with symbols' do
220
+ 'alias :foo :bar'.
221
+ must_be_parsed_as s(:alias,
222
+ s(:lit, :foo), s(:lit, :bar))
223
+ end
224
+
225
+ it 'works with operator barewords' do
226
+ 'alias + -'.
227
+ must_be_parsed_as s(:alias,
228
+ s(:lit, :+), s(:lit, :-))
229
+ end
230
+
231
+ it 'treats keywords as symbols' do
232
+ 'alias next foo'.
233
+ must_be_parsed_as s(:alias, s(:lit, :next), s(:lit, :foo))
234
+ end
235
+
236
+ it 'works with global variables' do
237
+ 'alias $foo $bar'.
238
+ must_be_parsed_as s(:valias, :$foo, :$bar)
239
+ end
240
+ end
241
+
242
+ describe 'for the undef statement' do
243
+ it 'works with a single bareword identifier' do
244
+ 'undef foo'.
245
+ must_be_parsed_as s(:undef, s(:lit, :foo))
246
+ end
247
+
248
+ it 'works with a single symbol' do
249
+ 'undef :foo'.
250
+ must_be_parsed_as s(:undef, s(:lit, :foo))
251
+ end
252
+
253
+ it 'works with multiple bareword identifiers' do
254
+ 'undef foo, bar'.
255
+ must_be_parsed_as s(:block,
256
+ s(:undef, s(:lit, :foo)),
257
+ s(:undef, s(:lit, :bar)))
258
+ end
259
+
260
+ it 'works with multiple bareword symbols' do
261
+ 'undef :foo, :bar'.
262
+ must_be_parsed_as s(:block,
263
+ s(:undef, s(:lit, :foo)),
264
+ s(:undef, s(:lit, :bar)))
265
+ end
266
+ end
267
+
268
+ describe 'for the return statement' do
269
+ it 'works with no arguments' do
270
+ 'return'.
271
+ must_be_parsed_as s(:return)
272
+ end
273
+
274
+ it 'works with one argument' do
275
+ 'return foo'.
276
+ must_be_parsed_as s(:return,
277
+ s(:call, nil, :foo))
278
+ end
279
+
280
+ it 'works with a splat argument' do
281
+ 'return *foo'.
282
+ must_be_parsed_as s(:return,
283
+ s(:svalue,
284
+ s(:splat,
285
+ s(:call, nil, :foo))))
286
+ end
287
+
288
+ it 'works with multiple arguments' do
289
+ 'return foo, bar'.
290
+ must_be_parsed_as s(:return,
291
+ s(:array,
292
+ s(:call, nil, :foo),
293
+ s(:call, nil, :bar)))
294
+ end
295
+
296
+ it 'works with a regular argument and a splat argument' do
297
+ 'return foo, *bar'.
298
+ must_be_parsed_as s(:return,
299
+ s(:array,
300
+ s(:call, nil, :foo),
301
+ s(:splat,
302
+ s(:call, nil, :bar))))
303
+ end
304
+
305
+ it 'works with a function call with parentheses' do
306
+ 'return foo(bar)'.
307
+ must_be_parsed_as s(:return,
308
+ s(:call, nil, :foo,
309
+ s(:call, nil, :bar)))
310
+ end
311
+
312
+ it 'works with a function call without parentheses' do
313
+ 'return foo bar'.
314
+ must_be_parsed_as s(:return,
315
+ s(:call, nil, :foo,
316
+ s(:call, nil, :bar)))
317
+ end
318
+ end
319
+
320
+ describe 'for yield' do
321
+ it 'works with no arguments and no parentheses' do
322
+ 'yield'.
323
+ must_be_parsed_as s(:yield)
324
+ end
325
+
326
+ it 'works with parentheses but no arguments' do
327
+ 'yield()'.
328
+ must_be_parsed_as s(:yield)
329
+ end
330
+
331
+ it 'works with one argument and no parentheses' do
332
+ 'yield foo'.
333
+ must_be_parsed_as s(:yield, s(:call, nil, :foo))
334
+ end
335
+
336
+ it 'works with one argument and parentheses' do
337
+ 'yield(foo)'.
338
+ must_be_parsed_as s(:yield, s(:call, nil, :foo))
339
+ end
340
+
341
+ it 'works with multiple arguments and no parentheses' do
342
+ 'yield foo, bar'.
343
+ must_be_parsed_as s(:yield,
344
+ s(:call, nil, :foo),
345
+ s(:call, nil, :bar))
346
+ end
347
+
348
+ it 'works with multiple arguments and parentheses' do
349
+ 'yield(foo, bar)'.
350
+ must_be_parsed_as s(:yield,
351
+ s(:call, nil, :foo),
352
+ s(:call, nil, :bar))
353
+ end
354
+
355
+ it 'works with splat' do
356
+ 'yield foo, *bar'.
357
+ must_be_parsed_as s(:yield,
358
+ s(:call, nil, :foo),
359
+ s(:splat, s(:call, nil, :bar)))
360
+ end
361
+
362
+ it 'works with a function call with parentheses' do
363
+ 'yield foo(bar)'.
364
+ must_be_parsed_as s(:yield,
365
+ s(:call, nil, :foo,
366
+ s(:call, nil, :bar)))
367
+ end
368
+
369
+ it 'works with a function call without parentheses' do
370
+ 'yield foo bar'.
371
+ must_be_parsed_as s(:yield,
372
+ s(:call, nil, :foo,
373
+ s(:call, nil, :bar)))
374
+ end
375
+ end
376
+
377
+ describe 'when extra compatibility is turned on' do
378
+ it 'treats block kwargs as calls' do
379
+ 'def foo(**bar); baz { |**qux| bar; qux }; end'.
380
+ must_be_parsed_as s(:defn, :foo,
381
+ s(:args, :"**bar"),
382
+ s(:iter,
383
+ s(:call, nil, :baz),
384
+ s(:args, :"**qux"),
385
+ s(:block,
386
+ s(:lvar, :bar),
387
+ s(:call, nil, :qux)))),
388
+ extra_compatible: true
389
+ end
390
+ end
391
+ end
392
+ end