ruby_parser 3.14.2 → 3.15.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,5 @@
1
1
  # encoding: ASCII-8BIT
2
+ # TODO: remove
2
3
 
3
4
  require "sexp"
4
5
  require "ruby_lexer"
@@ -28,7 +29,7 @@ class Sexp
28
29
  end
29
30
 
30
31
  module RubyParserStuff
31
- VERSION = "3.14.2"
32
+ VERSION = "3.15.0"
32
33
 
33
34
  attr_accessor :lexer, :in_def, :in_single, :file
34
35
  attr_accessor :in_kwarg
@@ -45,6 +46,11 @@ module RubyParserStuff
45
46
 
46
47
  attr_accessor :canonicalize_conditions
47
48
 
49
+ ##
50
+ # The last token type returned from #next_token
51
+
52
+ attr_accessor :last_token_type
53
+
48
54
  $good20 = []
49
55
 
50
56
  %w[
@@ -493,6 +499,8 @@ module RubyParserStuff
493
499
  str.encode! Encoding::UTF_8
494
500
  break
495
501
  end
502
+ rescue ArgumentError # unknown encoding name
503
+ # do nothing
496
504
  rescue Encoding::InvalidByteSequenceError
497
505
  # do nothing
498
506
  rescue Encoding::UndefinedConversionError
@@ -532,7 +540,7 @@ module RubyParserStuff
532
540
  header.map! { |s| s.force_encoding "ASCII-8BIT" } if has_enc
533
541
 
534
542
  first = header.first || ""
535
- encoding, str = "utf-8", str[3..-1] if first =~ /\A\xEF\xBB\xBF/
543
+ encoding, str = "utf-8", str.b[3..-1] if first =~ /\A\xEF\xBB\xBF/
536
544
 
537
545
  encoding = $1.strip if header.find { |s|
538
546
  s[/^#.*?-\*-.*?coding:\s*([^ ;]+).*?-\*-/, 1] ||
@@ -592,7 +600,9 @@ module RubyParserStuff
592
600
  case ttype
593
601
  when :str then
594
602
  if htype == :str
595
- head.last << tail.last
603
+ a, b = head.last, tail.last
604
+ b = b.dup.force_encoding a.encoding unless Encoding.compatible?(a, b)
605
+ a << b
596
606
  elsif htype == :dstr and head.size == 2 then
597
607
  head.last << tail.last
598
608
  else
@@ -696,6 +706,15 @@ module RubyParserStuff
696
706
  result
697
707
  end
698
708
 
709
+ def new_begin val
710
+ _, lineno, body, _ = val
711
+
712
+ result = body ? s(:begin, body) : s(:nil)
713
+ result.line lineno
714
+
715
+ result
716
+ end
717
+
699
718
  def new_body val
700
719
  body, resbody, elsebody, ensurebody = val
701
720
 
@@ -723,7 +742,10 @@ module RubyParserStuff
723
742
  result = block_append(result, elsebody)
724
743
  end
725
744
 
726
- result = s(:ensure, result, ensurebody).compact.line result.line if ensurebody
745
+ if ensurebody
746
+ lineno = (result || ensurebody).line
747
+ result = s(:ensure, result, ensurebody).compact.line lineno
748
+ end
727
749
 
728
750
  result
729
751
  end
@@ -843,14 +865,17 @@ module RubyParserStuff
843
865
  end
844
866
 
845
867
  def new_defs val
846
- recv, (name, _line), args, body = val[1], val[4], val[6], val[7]
847
- line, _ = val[5]
868
+ _, recv, _, _, name, (_in_def, line), args, body, _ = val
869
+
848
870
  body ||= s(:nil).line line
849
871
 
850
872
  args.line line
851
873
 
852
874
  result = s(:defs, recv, name.to_sym, args)
853
875
 
876
+ # TODO: remove_begin
877
+ # TODO: reduce_nodes
878
+
854
879
  if body then
855
880
  if body.sexp_type == :block then
856
881
  result.push(*body.sexp_body)
@@ -875,7 +900,9 @@ module RubyParserStuff
875
900
  end
876
901
 
877
902
  def new_hash val
878
- s(:hash, *val[2].values).line(val[1])
903
+ _, line, assocs = val
904
+
905
+ s(:hash).line(line).concat assocs.values
879
906
  end
880
907
 
881
908
  def new_if c, t, f
@@ -1134,6 +1161,7 @@ module RubyParserStuff
1134
1161
  def new_string val
1135
1162
  str, = val
1136
1163
  str.force_encoding("UTF-8")
1164
+ # TODO: remove:
1137
1165
  str.force_encoding("ASCII-8BIT") unless str.valid_encoding?
1138
1166
  result = s(:str, str).line lexer.lineno
1139
1167
  self.lexer.fixup_lineno str.count("\n")
@@ -1228,20 +1256,23 @@ module RubyParserStuff
1228
1256
  result
1229
1257
  end
1230
1258
 
1231
- def new_xstring str
1232
- if str then
1233
- case str.sexp_type
1259
+ def new_xstring val
1260
+ _, node = val
1261
+
1262
+ node ||= s(:str, "").line lexer.lineno
1263
+
1264
+ if node then
1265
+ case node.sexp_type
1234
1266
  when :str
1235
- str.sexp_type = :xstr
1267
+ node.sexp_type = :xstr
1236
1268
  when :dstr
1237
- str.sexp_type = :dxstr
1269
+ node.sexp_type = :dxstr
1238
1270
  else
1239
- str = s(:dxstr, "", str).line str.line
1271
+ node = s(:dxstr, "", node).line node.line
1240
1272
  end
1241
- str
1242
- else
1243
- s(:xstr, "")
1244
1273
  end
1274
+
1275
+ node
1245
1276
  end
1246
1277
 
1247
1278
  def new_yield args = nil
@@ -1262,6 +1293,7 @@ module RubyParserStuff
1262
1293
  token = self.lexer.next_token
1263
1294
 
1264
1295
  if token and token.first != RubyLexer::EOF then
1296
+ self.last_token_type = token
1265
1297
  return token
1266
1298
  else
1267
1299
  return [false, false]
@@ -1320,6 +1352,7 @@ module RubyParserStuff
1320
1352
  self.in_single = 0
1321
1353
  self.env.reset
1322
1354
  self.comments.clear
1355
+ self.last_token_type = nil
1323
1356
  end
1324
1357
 
1325
1358
  def ret_args node
@@ -1,7 +1,3 @@
1
- # encoding: US-ASCII
2
-
3
- # TODO: work this out
4
-
5
1
  require "minitest/autorun"
6
2
  require "ruby_lexer"
7
3
  require "ruby_parser"
@@ -84,10 +80,12 @@ class TestRubyLexer < Minitest::Test
84
80
  assert_in_epsilon value, act_value, 0.001, msg
85
81
  when NilClass then
86
82
  assert_nil act_value, msg
83
+ when String then
84
+ assert_equal value, act_value.b.force_encoding(value.encoding), msg
87
85
  else
88
86
  assert_equal value, act_value, msg
89
87
  end
90
- assert_equal state, @lex.lex_state, msg if state
88
+ assert_match state, @lex.lex_state, msg if state
91
89
  assert_equal paren, @lex.paren_nest, msg if paren
92
90
  assert_equal brace, @lex.brace_nest, msg if brace
93
91
  end
@@ -98,7 +96,8 @@ class TestRubyLexer < Minitest::Test
98
96
 
99
97
  def assert_read_escape expected, input
100
98
  @lex.ss.string = input.dup
101
- assert_equal expected, @lex.read_escape.b, input
99
+ enc = expected.encoding
100
+ assert_equal expected, @lex.read_escape.b.force_encoding(enc), input
102
101
  end
103
102
 
104
103
  def assert_read_escape_bad input # TODO: rename refute_read_escape
@@ -146,7 +145,7 @@ class TestRubyLexer < Minitest::Test
146
145
  yield
147
146
 
148
147
  lexer.lex_state = EXPR_ENDARG
149
- assert_next_lexeme :tSTRING_DEND, "}", EXPR_END, 0
148
+ assert_next_lexeme :tSTRING_DEND, "}", EXPR_END|EXPR_ENDARG, 0
150
149
 
151
150
  lexer.lex_strterm = lex_strterm
152
151
  lexer.lex_state = EXPR_BEG
@@ -720,7 +719,7 @@ class TestRubyLexer < Minitest::Test
720
719
 
721
720
  assert_lex3("do 42 end",
722
721
  nil,
723
- :kDO_BLOCK, "do", EXPR_BEG,
722
+ :kDO, "do", EXPR_BEG,
724
723
  :tINTEGER, 42, EXPR_NUM,
725
724
  :kEND, "end", EXPR_END)
726
725
  end
@@ -926,6 +925,14 @@ class TestRubyLexer < Minitest::Test
926
925
  assert_lex3("$1234", nil, :tGVAR, "$1234", EXPR_END)
927
926
  end
928
927
 
928
+ def test_yylex_global_I_have_no_words
929
+ assert_lex3("$x\xE2\x80\x8B = 42", # zero width space?!?!?
930
+ nil,
931
+ :tGVAR, "$x\xE2\x80\x8B", EXPR_END,
932
+ :tEQL, "=", EXPR_BEG,
933
+ :tINTEGER, 42, EXPR_NUM)
934
+ end
935
+
929
936
  def test_yylex_global_other
930
937
  assert_lex3("[$~, $*, $$, $?, $!, $@, $/, $\\, $;, $,, $., $=, $:, $<, $>, $\"]",
931
938
  nil,
@@ -1109,11 +1116,11 @@ class TestRubyLexer < Minitest::Test
1109
1116
  :tEQL, "=", EXPR_BEG,
1110
1117
  :tSTRING_BEG, "\"", EXPR_BEG,
1111
1118
  :tSTRING_CONTENT, "#x a ", EXPR_BEG,
1112
- :tSTRING_DVAR, "\#@", EXPR_BEG,
1119
+ :tSTRING_DVAR, "#", EXPR_BEG,
1113
1120
  :tSTRING_CONTENT, "@a b ", EXPR_BEG, # HUH?
1114
- :tSTRING_DVAR, "\#$", EXPR_BEG,
1121
+ :tSTRING_DVAR, "#", EXPR_BEG,
1115
1122
  :tSTRING_CONTENT, "$b c ", EXPR_BEG, # HUH?
1116
- :tSTRING_DVAR, "\#@", EXPR_BEG,
1123
+ :tSTRING_DVAR, "#", EXPR_BEG,
1117
1124
  :tSTRING_CONTENT, "@@d ", EXPR_BEG, # HUH?
1118
1125
  :tSTRING_DBEG, "\#{", EXPR_BEG,
1119
1126
  :tSTRING_CONTENT, "3} \n", EXPR_BEG,
@@ -2099,6 +2106,10 @@ class TestRubyLexer < Minitest::Test
2099
2106
  assert_lex3("?\\M-\\C-a", nil, :tSTRING, "\M-\C-a", EXPR_END)
2100
2107
  end
2101
2108
 
2109
+ def test_yylex_question_control_escape
2110
+ assert_lex3('?\C-\]', nil, :tSTRING, ?\C-\], EXPR_END)
2111
+ end
2112
+
2102
2113
  def test_yylex_question_ws
2103
2114
  assert_lex3("? ", nil, :tEH, "?", EXPR_BEG)
2104
2115
  assert_lex3("?\n", nil, :tEH, "?", EXPR_BEG)
@@ -2549,11 +2560,7 @@ class TestRubyLexer < Minitest::Test
2549
2560
  end
2550
2561
 
2551
2562
  def test_yylex_string_double_escape_c_backslash
2552
- assert_lex3("\"\\c\\\"",
2553
- nil,
2554
- :tSTRING_BEG, "\"", EXPR_BEG,
2555
- :tSTRING_CONTENT, "\034", EXPR_BEG,
2556
- :tSTRING_END, "\"", EXPR_LIT)
2563
+ refute_lex("\"\\c\\\"", :tSTRING_BEG, '"')
2557
2564
  end
2558
2565
 
2559
2566
  def test_yylex_string_double_escape_c_escape
@@ -2847,6 +2854,15 @@ class TestRubyLexer < Minitest::Test
2847
2854
  :tSTRING_END, '"')
2848
2855
  end
2849
2856
 
2857
+ def test_yylex_string_utf8_bad_encoding_with_escapes
2858
+ str = "\"\\xBADπ\""
2859
+ exp = "\xBADπ".b
2860
+
2861
+ assert_lex(str,
2862
+ s(:str, exp),
2863
+ :tSTRING, exp, EXPR_END)
2864
+ end
2865
+
2850
2866
  def test_yylex_string_utf8_complex_trailing_hex
2851
2867
  chr = [0x3024].pack("U")
2852
2868
  str = "#{chr}abz"
@@ -185,6 +185,57 @@ module TestRubyParserShared
185
185
  assert_syntax_error rb, "else without rescue is useless"
186
186
  end
187
187
 
188
+ def test_begin_ensure_no_bodies
189
+ rb = "begin\nensure\nend"
190
+ pt = s(:ensure, s(:nil).line(2)).line(2)
191
+
192
+ assert_parse rb, pt
193
+ end
194
+
195
+ def test_begin_rescue_ensure_no_bodies
196
+ rb = "begin\nrescue\nensure\nend"
197
+ pt = s(:ensure,
198
+ s(:rescue,
199
+ s(:resbody, s(:array).line(2),
200
+ nil).line(2)
201
+ ).line(2),
202
+ s(:nil).line(3)
203
+ ).line(2)
204
+
205
+ assert_parse rb, pt
206
+ end
207
+
208
+ def test_begin_rescue_else_ensure_bodies
209
+ rb = "begin\n 1\nrescue\n 2\nelse\n 3\nensure\n 4\nend"
210
+ pt = s(:ensure,
211
+ s(:rescue,
212
+ s(:lit, 1).line(2),
213
+ s(:resbody, s(:array).line(3),
214
+ s(:lit, 2).line(4)).line(3),
215
+ s(:lit, 3).line(6)).line(2),
216
+ s(:lit, 4).line(8)).line(2)
217
+
218
+ s(:ensure, s(:rescue, s(:resbody, s(:array), nil)), s(:nil))
219
+
220
+ assert_parse rb, pt
221
+ end
222
+
223
+ def test_begin_rescue_else_ensure_no_bodies
224
+ rb = "begin\n\nrescue\n\nelse\n\nensure\n\nend"
225
+ pt = s(:ensure,
226
+ s(:rescue,
227
+ s(:resbody, s(:array).line(3),
228
+ # TODO: s(:nil)
229
+ nil
230
+ ).line(3),
231
+ ).line(3),
232
+ s(:nil).line(7)).line(3)
233
+
234
+ s(:ensure, s(:rescue, s(:resbody, s(:array), nil)), s(:nil))
235
+
236
+ assert_parse rb, pt
237
+ end
238
+
188
239
  def test_block_append
189
240
  head = s(:args).line 1
190
241
  tail = s(:zsuper).line 2
@@ -290,7 +341,7 @@ module TestRubyParserShared
290
341
  def test_bug190
291
342
  skip "not ready for this yet"
292
343
 
293
- rb = %{%r'\\''}
344
+ rb = %{%r'\\\''} # stupid emacs
294
345
 
295
346
  assert_parse rb, :FUCK
296
347
  assert_syntax_error rb, "FUCK"
@@ -872,6 +923,13 @@ module TestRubyParserShared
872
923
  assert_parse rb, pt
873
924
  end
874
925
 
926
+ def test_heredoc_with_extra_carriage_horrible_mix?
927
+ rb = "<<'eot'\r\nbody\r\neot\n"
928
+ pt = s(:str, "body\r\n")
929
+
930
+ assert_parse rb, pt
931
+ end
932
+
875
933
  def test_heredoc_with_interpolation_and_carriage_return_escapes
876
934
  rb = "<<EOS\nfoo\\r\#@bar\nEOS\n"
877
935
  pt = s(:dstr, "foo\r", s(:evstr, s(:ivar, :@bar)), s(:str, "\n"))
@@ -900,6 +958,13 @@ module TestRubyParserShared
900
958
  assert_parse rb, pt
901
959
  end
902
960
 
961
+ def test_heredoc_with_not_global_interpolation
962
+ rb = "<<-HEREDOC\n#${\nHEREDOC"
963
+ pt = s(:str, "\#${\n")
964
+
965
+ assert_parse rb, pt
966
+ end
967
+
903
968
  def test_i_fucking_hate_line_numbers
904
969
  rb = <<-END.gsub(/^ {6}/, "")
905
970
  if true
@@ -1252,6 +1317,20 @@ module TestRubyParserShared
1252
1317
  end
1253
1318
  end
1254
1319
 
1320
+ def test_magic_encoding_comment__bad
1321
+ rb = "#encoding: bunk\n0"
1322
+ pt = s(:lit, 0)
1323
+
1324
+ assert_parse rb, pt
1325
+ end
1326
+
1327
+ def test_utf8_bom
1328
+ rb = "\xEF\xBB\xBF#!/usr/bin/env ruby -w\np 0\n"
1329
+ pt = s(:call, nil, :p, s(:lit, 0))
1330
+
1331
+ assert_parse rb, pt
1332
+ end
1333
+
1255
1334
  def test_masgn_arg_colon_arg
1256
1335
  rb = "a, b::c = d"
1257
1336
  pt = s(:masgn,
@@ -1383,13 +1462,43 @@ module TestRubyParserShared
1383
1462
  assert_parse rb, pt
1384
1463
  end
1385
1464
 
1386
- def test_op_asgn_primary_colon_identifier
1465
+ def test_op_asgn_primary_colon_identifier1
1387
1466
  rb = "A::b += 1"
1388
1467
  pt = s(:op_asgn, s(:const, :A), s(:lit, 1), :b, :+) # TODO: check? looks wack
1389
1468
 
1390
1469
  assert_parse rb, pt
1391
1470
  end
1392
1471
 
1472
+ def test_lasgn_middle_splat
1473
+ rb = "a = b, *c, d"
1474
+ pt = s(:lasgn, :a,
1475
+ s(:svalue,
1476
+ s(:array,
1477
+ s(:call, nil, :b),
1478
+ s(:splat, s(:call, nil, :c)),
1479
+ s(:call, nil, :d))))
1480
+
1481
+ assert_parse rb, pt
1482
+ end
1483
+
1484
+ def test_op_asgn_primary_colon_const_command_call
1485
+ rb = "A::B *= c d"
1486
+ pt = s(:op_asgn, s(:const, :A),
1487
+ s(:call, nil, :c, s(:call, nil, :d)),
1488
+ :B, :*)
1489
+
1490
+ assert_parse rb, pt
1491
+ end
1492
+
1493
+ def test_op_asgn_primary_colon_identifier_command_call
1494
+ rb = "A::b *= c d"
1495
+ pt = s(:op_asgn, s(:const, :A),
1496
+ s(:call, nil, :c, s(:call, nil, :d)),
1497
+ :b, :*)
1498
+
1499
+ assert_parse rb, pt
1500
+ end
1501
+
1393
1502
  def test_op_asgn_val_dot_ident_command_call
1394
1503
  rb = "a.b ||= c 1"
1395
1504
  pt = s(:op_asgn, s(:call, nil, :a), s(:call, nil, :c, s(:lit, 1)), :b, :"||")
@@ -3288,6 +3397,76 @@ module TestRubyParserShared20Plus
3288
3397
  assert_parse rb, pt
3289
3398
  end
3290
3399
 
3400
+ def test_call_array_block_call
3401
+ rb = "a [ nil, b do end ]"
3402
+ pt = s(:call, nil, :a,
3403
+ s(:array,
3404
+ s(:nil),
3405
+ s(:iter, s(:call, nil, :b), 0)))
3406
+
3407
+ assert_parse rb, pt
3408
+ end
3409
+
3410
+ def test_block_call_paren_call_block_call
3411
+ rb = "a (b)\nc.d do end"
3412
+ pt = s(:block,
3413
+ s(:call, nil, :a, s(:call, nil, :b)),
3414
+ s(:iter, s(:call, s(:call, nil, :c), :d), 0))
3415
+
3416
+
3417
+ assert_parse rb, pt
3418
+ end
3419
+
3420
+ def test_block_call_defn_call_block_call
3421
+ rb = "a def b(c)\n d\n end\n e.f do end"
3422
+ pt = s(:block,
3423
+ s(:call, nil, :a,
3424
+ s(:defn, :b, s(:args, :c), s(:call, nil, :d))),
3425
+ s(:iter, s(:call, s(:call, nil, :e), :f), 0))
3426
+
3427
+ assert_parse rb, pt
3428
+ end
3429
+
3430
+ def test_call_array_lambda_block_call
3431
+ rb = "a [->() {}] do\nend"
3432
+ pt = s(:iter,
3433
+ s(:call, nil, :a,
3434
+ s(:array, s(:iter, s(:lambda), s(:args)))),
3435
+ 0)
3436
+
3437
+ assert_parse rb, pt
3438
+ end
3439
+
3440
+ def test_call_begin_call_block_call
3441
+ rb = "a begin\nb.c do end\nend"
3442
+ pt = s(:call, nil, :a,
3443
+ s(:iter, s(:call, s(:call, nil, :b), :c), 0))
3444
+
3445
+ assert_parse rb, pt
3446
+ end
3447
+
3448
+ def test_messy_op_asgn_lineno
3449
+ rb = "a (B::C *= d e)"
3450
+ pt = s(:call, nil, :a,
3451
+ s(:op_asgn, s(:const, :B),
3452
+ s(:call, nil, :d, s(:call, nil, :e)),
3453
+ :C,
3454
+ :*)).line(1)
3455
+
3456
+ assert_parse rb, pt
3457
+ end
3458
+
3459
+ def test_str_lit_concat_bad_encodings
3460
+ rb = '"\xE3\xD3\x8B\xE3\x83\xBC\x83\xE3\x83\xE3\x82\xB3\xA3\x82\x99" \
3461
+ "\xE3\x83\xB3\xE3\x83\x8F\xE3\x82\x9A\xC3\xBD;foo@bar.com"'.b
3462
+ pt = s(:str, "\xE3\xD3\x8B\xE3\x83\xBC\x83\xE3\x83\xE3\x82\xB3\xA3\x82\x99\xE3\x83\xB3\xE3\x83\x8F\xE3\x82\x9A\xC3\xBD;foo@bar.com".b)
3463
+
3464
+ assert_parse rb, pt
3465
+
3466
+ sexp = processor.parse rb
3467
+ assert_equal Encoding::ASCII_8BIT, sexp.last.encoding
3468
+ end
3469
+
3291
3470
  def test_block_call_dot_op2_cmd_args_do_block
3292
3471
  rb = "a.b c() do d end.e f do |g| h end"
3293
3472
  pt = s(:iter,
@@ -3588,7 +3767,7 @@ module TestRubyParserShared21Plus
3588
3767
 
3589
3768
  def test_bug162__21plus
3590
3769
  rb = %q(<<E\nfoo\nE\rO)
3591
- emsg = "can't match /E(\n|\\z)/ anywhere in . near line 1: \"\""
3770
+ emsg = "can't match /E(\\r*\\n|\\z)/ anywhere in . near line 1: \"\""
3592
3771
 
3593
3772
  assert_syntax_error rb, emsg
3594
3773
  end
@@ -3738,6 +3917,13 @@ module TestRubyParserShared23Plus
3738
3917
  assert_parse rb, pt
3739
3918
  end
3740
3919
 
3920
+ def test_heredoc__backslash_dos_format
3921
+ rb = "str = <<-XXX\r\nbefore\\\r\nafter\r\nXXX\r\n"
3922
+ pt = s(:lasgn, :str, s(:str, "before\nafter\n"))
3923
+
3924
+ assert_parse rb, pt
3925
+ end
3926
+
3741
3927
  def test_heredoc_squiggly
3742
3928
  rb = "a = <<~\"EOF\"\n x\n y\n z\n EOF\n\n"
3743
3929
  pt = s(:lasgn, :a, s(:str, "x\ny\nz\n"))
@@ -3946,6 +4132,10 @@ module TestRubyParserShared26Plus
3946
4132
  end
3947
4133
  end
3948
4134
 
4135
+ module TestRubyParserShared27Plus
4136
+ include TestRubyParserShared26Plus
4137
+ end
4138
+
3949
4139
  class TestRubyParser < Minitest::Test
3950
4140
  def test_cls_version
3951
4141
  assert_equal 23, RubyParser::V23.version
@@ -4242,6 +4432,17 @@ class TestRubyParserV26 < RubyParserTestCase
4242
4432
 
4243
4433
  end
4244
4434
 
4435
+ class TestRubyParserV27 < RubyParserTestCase
4436
+ include TestRubyParserShared27Plus
4437
+
4438
+ def setup
4439
+ super
4440
+
4441
+ self.processor = RubyParser::V27.new
4442
+ end
4443
+ end
4444
+
4445
+
4245
4446
  RubyParser::VERSIONS.each do |klass|
4246
4447
  v = klass.version
4247
4448
  describe "block args arity #{v}" do