ruby_parser 3.15.0 → 3.19.2

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +151 -0
  4. data/Manifest.txt +7 -0
  5. data/README.rdoc +9 -6
  6. data/Rakefile +141 -31
  7. data/bin/ruby_parse_extract_error +1 -1
  8. data/compare/normalize.rb +8 -3
  9. data/debugging.md +133 -0
  10. data/gauntlet.md +107 -0
  11. data/lib/rp_extensions.rb +15 -36
  12. data/lib/rp_stringscanner.rb +20 -51
  13. data/lib/ruby20_parser.rb +7544 -3633
  14. data/lib/ruby20_parser.y +335 -257
  15. data/lib/ruby21_parser.rb +7518 -3678
  16. data/lib/ruby21_parser.y +330 -254
  17. data/lib/ruby22_parser.rb +7652 -3689
  18. data/lib/ruby22_parser.y +334 -256
  19. data/lib/ruby23_parser.rb +7659 -3702
  20. data/lib/ruby23_parser.y +334 -256
  21. data/lib/ruby24_parser.rb +7748 -3721
  22. data/lib/ruby24_parser.y +334 -256
  23. data/lib/ruby25_parser.rb +7748 -3721
  24. data/lib/ruby25_parser.y +334 -256
  25. data/lib/ruby26_parser.rb +7755 -3726
  26. data/lib/ruby26_parser.y +334 -255
  27. data/lib/ruby27_parser.rb +10290 -4518
  28. data/lib/ruby27_parser.y +933 -254
  29. data/lib/ruby30_parser.rb +13258 -0
  30. data/lib/ruby30_parser.y +3459 -0
  31. data/lib/ruby31_parser.rb +13638 -0
  32. data/lib/ruby31_parser.y +3493 -0
  33. data/lib/ruby3_parser.yy +3548 -0
  34. data/lib/ruby_lexer.rb +277 -599
  35. data/lib/ruby_lexer.rex +28 -21
  36. data/lib/ruby_lexer.rex.rb +60 -24
  37. data/lib/ruby_lexer_strings.rb +638 -0
  38. data/lib/ruby_parser.rb +4 -0
  39. data/lib/ruby_parser.yy +974 -261
  40. data/lib/ruby_parser_extras.rb +355 -114
  41. data/test/test_ruby_lexer.rb +226 -129
  42. data/test/test_ruby_parser.rb +1653 -267
  43. data/tools/munge.rb +36 -8
  44. data/tools/ripper.rb +15 -10
  45. data.tar.gz.sig +0 -0
  46. metadata +55 -37
  47. metadata.gz.sig +0 -0
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- # ENV["VERBOSE"] = "1"
3
+ ENV["VERBOSE"] = "1"
4
4
 
5
5
  require "minitest/autorun"
6
6
  require "ruby_parser"
@@ -34,12 +34,15 @@ module TestRubyParserShared
34
34
  skip "not ready for this yet"
35
35
 
36
36
  rb = "def f; if /(?<foo>bar)/ =~ 'bar' && p(foo); foo; end; end; f"
37
- pt = s(:if,
38
- s(:and,
39
- s(:match2, s(:lit, /(?<foo>bar)/), s(:str, "bar")),
40
- s(:call, nil, :p, s(:lvar, :foo))),
41
- s(:lvar, :foo),
42
- nil)
37
+ pt = s(:block,
38
+ s(:defn, :f, s(:args),
39
+ s(:if,
40
+ s(:and,
41
+ s(:match2, s(:lit, /(?<foo>bar)/), s(:str, "bar")),
42
+ s(:call, nil, :p, s(:lvar, :foo))),
43
+ s(:lvar, :foo),
44
+ nil)),
45
+ s(:call, nil, :f))
43
46
 
44
47
  assert_parse rb, pt
45
48
  end
@@ -86,10 +89,10 @@ module TestRubyParserShared
86
89
  def test_and_multi
87
90
  rb = "true and\nnot false and\ntrue"
88
91
  pt = s(:and,
89
- s(:true).line(1),
92
+ s(:true),
90
93
  s(:and,
91
94
  s(:call, s(:false).line(2), :!).line(2),
92
- s(:true).line(3)).line(2)).line(1)
95
+ s(:true).line(3)).line(2))
93
96
 
94
97
  assert_parse rb, pt
95
98
  end
@@ -117,7 +120,7 @@ module TestRubyParserShared
117
120
  pt = s(:block,
118
121
  s(:array,
119
122
  s(:str, "a").line(2),
120
- s(:str, "b").line(3)).line(1),
123
+ s(:str, "b").line(3)),
121
124
  s(:lit, 1).line(4)).line 1
122
125
  assert_parse rb, pt
123
126
  end
@@ -167,7 +170,7 @@ module TestRubyParserShared
167
170
  pt = s(:call, nil, :x,
168
171
  s(:dxstr, "",
169
172
  s(:evstr,
170
- s(:call, nil, :y).line(1)).line(1))).line(1)
173
+ s(:call, nil, :y))))
171
174
 
172
175
  assert_parse rb, pt
173
176
  end
@@ -179,10 +182,13 @@ module TestRubyParserShared
179
182
  assert_parse rb, pt
180
183
  end
181
184
 
182
- def test_begin_else_return_value
185
+ def test_begin_else_return_value # overridden below, warns < 2.6
183
186
  rb = "begin; else 2; end"
187
+ pt = s(:lit, 2)
184
188
 
185
- assert_syntax_error rb, "else without rescue is useless"
189
+ assert_output "", "else without rescue is useless\n" do
190
+ assert_parse rb, pt
191
+ end
186
192
  end
187
193
 
188
194
  def test_begin_ensure_no_bodies
@@ -240,26 +246,26 @@ module TestRubyParserShared
240
246
  head = s(:args).line 1
241
247
  tail = s(:zsuper).line 2
242
248
  expected = s(:block,
243
- s(:args).line(1),
249
+ s(:args),
244
250
  s(:zsuper).line(2)).line 1
245
251
  assert_equal expected, processor.block_append(head, tail)
246
252
  end
247
253
 
248
254
  def test_block_append_begin_begin
249
- head = s(:begin, s(:args).line(1)).line 1
255
+ head = s(:begin, s(:args)).line 1
250
256
  tail = s(:begin, s(:args).line(2)).line 2
251
257
  expected = s(:block,
252
- s(:args).line(1),
258
+ s(:args),
253
259
  s(:begin,
254
260
  s(:args).line(2)).line(2)).line 1
255
261
  assert_equal expected, processor.block_append(head, tail)
256
262
  end
257
263
 
258
264
  def test_block_append_block
259
- head = s(:block, s(:args).line(1)).line(1)
265
+ head = s(:block, s(:args))
260
266
  tail = s(:zsuper).line(2)
261
267
  expected = s(:block,
262
- s(:args).line(1),
268
+ s(:args),
263
269
  s(:zsuper).line(2)).line 1
264
270
  assert_equal expected, processor.block_append(head, tail)
265
271
  end
@@ -284,7 +290,7 @@ module TestRubyParserShared
284
290
  s(:undef, s(:lit, :x)).line(2),
285
291
  s(:undef, s(:lit, :y)).line(3)).line 2
286
292
  expected = s(:block,
287
- s(:call, nil, :f1).line(1),
293
+ s(:call, nil, :f1),
288
294
  s(:block,
289
295
  s(:undef, s(:lit, :x)).line(2),
290
296
  s(:undef, s(:lit, :y)).line(3)).line(2)).line 1
@@ -322,13 +328,14 @@ module TestRubyParserShared
322
328
  end
323
329
 
324
330
  def test_bug170
325
- skip "not ready for this yet"
326
-
327
- # TODO: needs to fail on 2.1 and up
328
331
  rb = '$-'
329
332
  pt = s(:gvar, :"$-")
330
333
 
331
- assert_parse rb, pt
334
+ if processor.class.version >= 21
335
+ assert_syntax_error rb, /unexpected \$undefined/
336
+ else
337
+ assert_parse rb, pt
338
+ end
332
339
  end
333
340
 
334
341
  def test_bug179
@@ -339,12 +346,9 @@ module TestRubyParserShared
339
346
  end
340
347
 
341
348
  def test_bug190
342
- skip "not ready for this yet"
343
-
344
349
  rb = %{%r'\\\''} # stupid emacs
345
350
 
346
- assert_parse rb, :FUCK
347
- assert_syntax_error rb, "FUCK"
351
+ assert_parse rb, s(:lit, %r%'%)
348
352
 
349
353
  rb = %{%r'\\''}
350
354
  pt = s(:lit, /'/)
@@ -366,7 +370,7 @@ module TestRubyParserShared
366
370
  rb = "$测试 = 1\n测试 = 1"
367
371
  pt = s(:block,
368
372
  s(:gasgn, :$测试, s(:lit, 1)),
369
- s(:lasgn, :测试, s(:lit, 1)))
373
+ s(:lasgn, :测试, s(:lit, 1).line(2)).line(2))
370
374
 
371
375
  assert_parse rb, pt
372
376
  end
@@ -397,7 +401,7 @@ module TestRubyParserShared
397
401
  assert_parse rb, pt
398
402
 
399
403
  rb = "true and\ntrue"
400
- pt = s(:and, s(:true), s(:true))
404
+ pt = s(:and, s(:true), s(:true).line(2))
401
405
 
402
406
  assert_parse rb, pt
403
407
  end
@@ -420,10 +424,13 @@ module TestRubyParserShared
420
424
  assert_parse rb, pt
421
425
  end
422
426
 
423
- def test_bug_begin_else
427
+ def test_bug_begin_else # overridden below, warns < 2.6
424
428
  rb = "begin 1; else; 2 end"
429
+ pt = s(:block, s(:lit, 1), s(:lit, 2))
425
430
 
426
- assert_syntax_error rb, "else without rescue is useless"
431
+ assert_output "", "else without rescue is useless\n" do
432
+ assert_parse rb, pt
433
+ end
427
434
  end
428
435
 
429
436
  def test_bug_call_arglist_parens
@@ -439,7 +446,7 @@ module TestRubyParserShared
439
446
  CODE
440
447
 
441
448
  pt = s(:defn, :f, s(:args),
442
- s(:call, nil, :g, s(:lit, 1), s(:lit, 2)))
449
+ s(:call, nil, :g, s(:lit, 1).line(2), s(:lit, 2).line(2)).line(2))
443
450
 
444
451
  assert_parse rb, pt
445
452
 
@@ -667,7 +674,7 @@ module TestRubyParserShared
667
674
  def test_class_comments
668
675
  rb = "# blah 1\n# blah 2\n\nclass X\n # blah 3\n def blah\n # blah 4\n end\nend"
669
676
  pt = s(:class, :X, nil,
670
- s(:defn, :blah, s(:args), s(:nil)))
677
+ s(:defn, :blah, s(:args).line(6), s(:nil).line(6)).line(6)).line(4)
671
678
 
672
679
  assert_parse rb, pt
673
680
 
@@ -688,12 +695,13 @@ module TestRubyParserShared
688
695
  s(:call, nil, :a),
689
696
  0,
690
697
  s(:block,
691
- s(:lasgn, :v, s(:nil)),
698
+ s(:lasgn, :v, s(:nil).line(2)).line(2),
692
699
  s(:rescue,
693
- s(:yield),
700
+ s(:yield).line(4),
694
701
  s(:resbody,
695
- s(:array, s(:const, :Exception), s(:lasgn, :v, s(:gvar, :$!))),
696
- s(:break)))))
702
+ s(:array, s(:const, :Exception).line(5),
703
+ s(:lasgn, :v, s(:gvar, :$!).line(5)).line(5)).line(5),
704
+ s(:break).line(6)).line(5)).line(4)).line(2))
697
705
 
698
706
  assert_parse rb, pt
699
707
  end
@@ -707,7 +715,7 @@ module TestRubyParserShared
707
715
 
708
716
  def test_defn_comments
709
717
  rb = "# blah 1\n# blah 2\n\ndef blah\nend"
710
- pt = s(:defn, :blah, s(:args), s(:nil))
718
+ pt = s(:defn, :blah, s(:args).line(4), s(:nil).line(4)).line(4)
711
719
 
712
720
  assert_parse rb, pt
713
721
  assert_equal "# blah 1\n# blah 2\n\n", result.comments
@@ -733,7 +741,8 @@ module TestRubyParserShared
733
741
 
734
742
  def test_defs_comments
735
743
  rb = "# blah 1\n# blah 2\n\ndef self.blah\nend"
736
- pt = s(:defs, s(:self), :blah, s(:args), s(:nil))
744
+ pt = s(:defs, s(:self).line(4), :blah, s(:args).line(4),
745
+ s(:nil).line(4)).line(4)
737
746
 
738
747
  assert_parse rb, pt
739
748
  assert_equal "# blah 1\n# blah 2\n\n", result.comments
@@ -744,8 +753,8 @@ module TestRubyParserShared
744
753
  pt = s(:block,
745
754
  s(:call, nil, :a, s(:lit, 1)),
746
755
  s(:iter,
747
- s(:call, s(:call, nil, :a), :b),
748
- s(:args, :c)))
756
+ s(:call, s(:call, nil, :a).line(2), :b).line(2),
757
+ s(:args, :c).line(2)).line(2))
749
758
 
750
759
  assert_parse rb, pt
751
760
  end
@@ -817,6 +826,13 @@ module TestRubyParserShared
817
826
  assert_parse rb, pt
818
827
  end
819
828
 
829
+ def test_dsym_esc_to_sym
830
+ rb = ':"Variet\303\240"'
831
+ pt = s(:lit, :Varietà)
832
+
833
+ assert_parse rb, pt
834
+ end
835
+
820
836
  def test_empty
821
837
  refute_parse ""
822
838
  end
@@ -824,7 +840,7 @@ module TestRubyParserShared
824
840
  def test_eq_begin_line_numbers
825
841
  rb = "1\n=begin\ncomment\ncomment\n=end\n2"
826
842
  pt = s(:block,
827
- s(:lit, 1).line(1),
843
+ s(:lit, 1),
828
844
  s(:lit, 2).line(6))
829
845
 
830
846
  assert_parse rb, pt
@@ -832,7 +848,9 @@ module TestRubyParserShared
832
848
 
833
849
  def test_eq_begin_why_wont_people_use_their_spacebar?
834
850
  rb = "h[k]=begin\n 42\n end"
835
- pt = s(:attrasgn, s(:call, nil, :h), :[]=, s(:call, nil, :k), s(:lit, 42))
851
+ pt = s(:attrasgn,
852
+ s(:call, nil, :h), :[]=, s(:call, nil, :k),
853
+ s(:lit, 42).line(2))
836
854
 
837
855
  assert_parse rb, pt
838
856
  end
@@ -881,6 +899,29 @@ module TestRubyParserShared
881
899
  assert_parse rb, pt
882
900
  end
883
901
 
902
+ def test_heredoc_lineno
903
+ rb = "c = <<'CCC'\nline2\nline3\nline4\nCCC\n\nd = 42"
904
+ pt = s(:block,
905
+ s(:lasgn, :c, s(:str, "line2\nline3\nline4\n")),
906
+ s(:lasgn, :d, s(:lit, 42).line(7)).line(7))
907
+
908
+ assert_parse rb, pt
909
+ end
910
+
911
+ def test_pctW_lineno
912
+ rb = "%W(a\\nb\nc\ d\ne\\\nf\ng\y h\\y i\\\y)"
913
+ pt = s(:array,
914
+ s(:str, "a\nb"),
915
+ s(:str, "c").line(2),
916
+ s(:str, "d").line(2),
917
+ s(:str, "e\nf").line(3),
918
+ s(:str, "gy").line(5),
919
+ s(:str, "hy").line(5),
920
+ s(:str, "iy").line(5))
921
+
922
+ assert_parse rb, pt
923
+ end
924
+
884
925
  def test_heredoc_bad_oct_escape
885
926
  rb = "s = <<-EOS\na\\247b\ncöd\nEOS\n"
886
927
  pt = s(:lasgn, :s, s(:str, "a\xa7b\nc\xc3\xb6d\n".b))
@@ -932,14 +973,17 @@ module TestRubyParserShared
932
973
 
933
974
  def test_heredoc_with_interpolation_and_carriage_return_escapes
934
975
  rb = "<<EOS\nfoo\\r\#@bar\nEOS\n"
935
- pt = s(:dstr, "foo\r", s(:evstr, s(:ivar, :@bar)), s(:str, "\n"))
976
+ pt = s(:dstr, "foo\r", s(:evstr, s(:ivar, :@bar).line(2)).line(2), s(:str, "\n").line(2))
936
977
 
937
978
  assert_parse rb, pt
938
979
  end
939
980
 
940
981
  def test_heredoc_with_interpolation_and_carriage_return_escapes_windows
941
982
  rb = "<<EOS\r\nfoo\\r\#@bar\r\nEOS\r\n"
942
- pt = s(:dstr, "foo\r", s(:evstr, s(:ivar, :@bar)), s(:str, "\n"))
983
+ pt = s(:dstr,
984
+ "foo\r",
985
+ s(:evstr, s(:ivar, :@bar).line(2)).line(2),
986
+ s(:str, "\n").line(2))
943
987
 
944
988
  assert_parse rb, pt
945
989
  end
@@ -981,7 +1025,7 @@ module TestRubyParserShared
981
1025
  end
982
1026
  END
983
1027
 
984
- pt = s(:if, s(:true).line(1),
1028
+ pt = s(:if, s(:true),
985
1029
  s(:block,
986
1030
  s(:call, nil, :p, s(:lit, 1).line(2)).line(2),
987
1031
  s(:call, s(:call, nil, :a).line(3), :b,
@@ -1001,7 +1045,7 @@ module TestRubyParserShared
1001
1045
  s(:lit, 5).line(10)).line(10),
1002
1046
  s(:call, s(:call, nil, :g).line(11), :h,
1003
1047
  s(:lit, 6).line(11), s(:lit, 7).line(11)).line(11)).line(2),
1004
- nil).line(1)
1048
+ nil)
1005
1049
 
1006
1050
  assert_parse rb, pt
1007
1051
  end
@@ -1018,14 +1062,14 @@ module TestRubyParserShared
1018
1062
  EOM
1019
1063
 
1020
1064
  pt = s(:block,
1021
- s(:if, s(:true).line(1),
1065
+ s(:if, s(:true),
1022
1066
  s(:block,
1023
1067
  s(:call, nil, :p, s(:str, "a").line(2)).line(2),
1024
1068
  s(:lasgn, :b, s(:lit, 1).line(3)).line(3),
1025
1069
  s(:call, nil, :p, s(:lvar, :b).line(4)).line(4),
1026
1070
  s(:lasgn, :c, s(:lit, 1).line(5)).line(5)).line(2),
1027
- nil).line(1),
1028
- s(:call, nil, :a).line(7)).line(1)
1071
+ nil),
1072
+ s(:call, nil, :a).line(7))
1029
1073
 
1030
1074
  assert_parse rb, pt
1031
1075
  end
@@ -1056,7 +1100,7 @@ module TestRubyParserShared
1056
1100
  pt = s(:block,
1057
1101
  s(:array,
1058
1102
  s(:str, "a").line(2),
1059
- s(:str, "b").line(3)).line(1),
1103
+ s(:str, "b").line(3)),
1060
1104
  s(:lit, 1).line(5))
1061
1105
  assert_parse rb, pt
1062
1106
  end
@@ -1217,14 +1261,14 @@ module TestRubyParserShared
1217
1261
  def test_logical_op_12
1218
1262
  lhs = s(:lit, 1).line 1
1219
1263
  rhs = s(:lit, 2).line 2
1220
- exp = s(:and, s(:lit, 1).line(1), s(:lit, 2).line(2)).line 1
1264
+ exp = s(:and, s(:lit, 1), s(:lit, 2).line(2)).line 1
1221
1265
 
1222
1266
  assert_equal exp, processor.logical_op(:and, lhs, rhs)
1223
1267
  end
1224
1268
 
1225
1269
  def test_logical_op_1234_5
1226
1270
  lhs = s(:and,
1227
- s(:lit, 1).line(1),
1271
+ s(:lit, 1),
1228
1272
  s(:and,
1229
1273
  s(:lit, 2).line(2),
1230
1274
  s(:and,
@@ -1232,7 +1276,7 @@ module TestRubyParserShared
1232
1276
  s(:lit, 4).line(4)).line(3)).line(2)).line 1
1233
1277
  rhs = s(:lit, 5).line(5)
1234
1278
  exp = s(:and,
1235
- s(:lit, 1).line(1),
1279
+ s(:lit, 1),
1236
1280
  s(:and,
1237
1281
  s(:lit, 2).line(2),
1238
1282
  s(:and,
@@ -1246,13 +1290,13 @@ module TestRubyParserShared
1246
1290
 
1247
1291
  def test_logical_op_123_4
1248
1292
  lhs = s(:and,
1249
- s(:lit, 1).line(1),
1293
+ s(:lit, 1),
1250
1294
  s(:and,
1251
1295
  s(:lit, 2).line(2),
1252
1296
  s(:lit, 3).line(3)).line(2)).line 1
1253
1297
  rhs = s(:lit, 4).line 4
1254
1298
  exp = s(:and,
1255
- s(:lit, 1).line(1),
1299
+ s(:lit, 1),
1256
1300
  s(:and,
1257
1301
  s(:lit, 2).line(2),
1258
1302
  s(:and,
@@ -1264,11 +1308,11 @@ module TestRubyParserShared
1264
1308
 
1265
1309
  def test_logical_op_12_3
1266
1310
  lhs = s(:and,
1267
- s(:lit, 1).line(1),
1311
+ s(:lit, 1),
1268
1312
  s(:lit, 2).line(2)).line 1
1269
1313
  rhs = s(:lit, 3).line 3
1270
1314
  exp = s(:and,
1271
- s(:lit, 1).line(1),
1315
+ s(:lit, 1),
1272
1316
  s(:and,
1273
1317
  s(:lit, 2).line(2),
1274
1318
  s(:lit, 3).line(3)).line(2)).line 1
@@ -1278,15 +1322,15 @@ module TestRubyParserShared
1278
1322
 
1279
1323
  def test_logical_op_nested_mix
1280
1324
  lhs = s(:or,
1281
- s(:call, nil, :a).line(1),
1325
+ s(:call, nil, :a),
1282
1326
  s(:call, nil, :b).line(2)).line 1
1283
1327
  rhs = s(:and,
1284
1328
  s(:call, nil, :c).line(3),
1285
1329
  s(:call, nil, :d).line(4)).line 3
1286
1330
  exp = s(:or,
1287
1331
  s(:or,
1288
- s(:call, nil, :a).line(1),
1289
- s(:call, nil, :b).line(2)).line(1),
1332
+ s(:call, nil, :a),
1333
+ s(:call, nil, :b).line(2)),
1290
1334
  s(:and,
1291
1335
  s(:call, nil, :c).line(3),
1292
1336
  s(:call, nil, :d).line(4)).line(3)).line 1
@@ -1307,8 +1351,8 @@ module TestRubyParserShared
1307
1351
  # TODO: globals
1308
1352
 
1309
1353
  pt = s(:class, :"ExampleUTF8ClassNameVariet\303\240", nil,
1310
- s(:defs, s(:self), :"\303\250", s(:args),
1311
- s(:lasgn, :"cos\303\254", s(:lit, :"per\303\262"))))
1354
+ s(:defs, s(:self).line(2), :"\303\250", s(:args).line(2),
1355
+ s(:lasgn, :"cos\303\254", s(:lit, :"per\303\262").line(2)).line(2)).line(2)).line(2)
1312
1356
 
1313
1357
  err = RUBY_VERSION =~ /^1\.8/ ? "Skipping magic encoding comment\n" : ""
1314
1358
 
@@ -1319,14 +1363,14 @@ module TestRubyParserShared
1319
1363
 
1320
1364
  def test_magic_encoding_comment__bad
1321
1365
  rb = "#encoding: bunk\n0"
1322
- pt = s(:lit, 0)
1366
+ pt = s(:lit, 0).line(2)
1323
1367
 
1324
1368
  assert_parse rb, pt
1325
1369
  end
1326
1370
 
1327
1371
  def test_utf8_bom
1328
1372
  rb = "\xEF\xBB\xBF#!/usr/bin/env ruby -w\np 0\n"
1329
- pt = s(:call, nil, :p, s(:lit, 0))
1373
+ pt = s(:call, nil, :p, s(:lit, 0).line(2)).line(2)
1330
1374
 
1331
1375
  assert_parse rb, pt
1332
1376
  end
@@ -1335,12 +1379,12 @@ module TestRubyParserShared
1335
1379
  rb = "a, b::c = d"
1336
1380
  pt = s(:masgn,
1337
1381
  s(:array,
1338
- s(:lasgn, :a).line(1),
1382
+ s(:lasgn, :a),
1339
1383
  s(:attrasgn,
1340
- s(:call, nil, :b).line(1),
1341
- :c=).line(1)).line(1),
1384
+ s(:call, nil, :b),
1385
+ :c=)),
1342
1386
  s(:to_ary,
1343
- s(:call, nil, :d).line(1)).line(1)).line(1)
1387
+ s(:call, nil, :d)))
1344
1388
 
1345
1389
  assert_parse rb, pt
1346
1390
  end
@@ -1420,7 +1464,7 @@ module TestRubyParserShared
1420
1464
  def test_module_comments
1421
1465
  rb = "# blah 1\n \n # blah 2\n\nmodule X\n # blah 3\n def blah\n # blah 4\n end\nend"
1422
1466
  pt = s(:module, :X,
1423
- s(:defn, :blah, s(:args), s(:nil)))
1467
+ s(:defn, :blah, s(:args).line(7), s(:nil).line(7)).line(7)).line(5)
1424
1468
 
1425
1469
  assert_parse rb, pt
1426
1470
  assert_equal "# blah 1\n\n# blah 2\n\n", result.comments
@@ -1432,7 +1476,7 @@ module TestRubyParserShared
1432
1476
  pt = s(:block,
1433
1477
  s(:array,
1434
1478
  s(:str, "a").line(2),
1435
- s(:str, "b").line(3)).line(1),
1479
+ s(:str, "b").line(3)),
1436
1480
  s(:lit, 1).line(5))
1437
1481
  assert_parse rb, pt
1438
1482
  end
@@ -1557,17 +1601,11 @@ module TestRubyParserShared
1557
1601
  rb = "a = 42\np a"
1558
1602
  pt = s(:block,
1559
1603
  s(:lasgn, :a, s(:lit, 42)),
1560
- s(:call, nil, :p, s(:lvar, :a)))
1604
+ s(:call, nil, :p, s(:lvar, :a).line(2)).line(2))
1561
1605
 
1562
- assert_parse_line rb, pt, 1
1563
- assert_equal 1, result.lasgn.line, "lasgn should have line number"
1564
- assert_equal 2, result.call.line, "call should have line number"
1565
-
1566
- expected = "(string)"
1567
- assert_equal expected, result.file
1568
- assert_equal expected, result.lasgn.file
1569
- assert_equal expected, result.call.file
1606
+ assert_parse rb, pt
1570
1607
 
1608
+ assert_equal "(string)", result.file
1571
1609
  assert_same result.file, result.lasgn.file
1572
1610
  assert_same result.file, result.call.file
1573
1611
  end
@@ -1575,7 +1613,7 @@ module TestRubyParserShared
1575
1613
  def test_parse_line_block_inline_comment
1576
1614
  rb = "a\nb # comment\nc"
1577
1615
  pt = s(:block,
1578
- s(:call, nil, :a).line(1),
1616
+ s(:call, nil, :a),
1579
1617
  s(:call, nil, :b).line(2),
1580
1618
  s(:call, nil, :c).line(3))
1581
1619
 
@@ -1595,23 +1633,23 @@ module TestRubyParserShared
1595
1633
  def test_parse_line_block_inline_multiline_comment
1596
1634
  rb = "a\nb # comment\n# another comment\nc"
1597
1635
  pt = s(:block,
1598
- s(:call, nil, :a).line(1),
1636
+ s(:call, nil, :a),
1599
1637
  s(:call, nil, :b).line(2),
1600
- s(:call, nil, :c).line(4)).line(1)
1638
+ s(:call, nil, :c).line(4))
1601
1639
 
1602
1640
  assert_parse rb, pt
1603
1641
  end
1604
1642
 
1605
1643
  def test_parse_line_call_ivar_arg_no_parens_line_break
1606
1644
  rb = "a @b\n"
1607
- pt = s(:call, nil, :a, s(:ivar, :@b).line(1)).line(1)
1645
+ pt = s(:call, nil, :a, s(:ivar, :@b))
1608
1646
 
1609
1647
  assert_parse rb, pt
1610
1648
  end
1611
1649
 
1612
1650
  def test_parse_line_call_ivar_line_break_paren
1613
1651
  rb = "a(@b\n)"
1614
- pt = s(:call, nil, :a, s(:ivar, :@b).line(1)).line(1)
1652
+ pt = s(:call, nil, :a, s(:ivar, :@b))
1615
1653
 
1616
1654
  assert_parse rb, pt
1617
1655
  end
@@ -1622,9 +1660,9 @@ module TestRubyParserShared
1622
1660
  pt = s(:iter,
1623
1661
  s(:call, nil, :f),
1624
1662
  s(:args, :x, :y),
1625
- s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
1663
+ s(:call, s(:lvar, :x).line(2), :+, s(:lvar, :y).line(2)).line(2))
1626
1664
 
1627
- assert_parse_line rb, pt, 1
1665
+ assert_parse rb, pt
1628
1666
 
1629
1667
  _, a, b, c, = result
1630
1668
 
@@ -1635,19 +1673,19 @@ module TestRubyParserShared
1635
1673
 
1636
1674
  def test_parse_line_defn_no_parens_args
1637
1675
  rb = "def f a\nend"
1638
- pt = s(:defn, :f, s(:args, :a).line(1), s(:nil).line(2)).line(1)
1676
+ pt = s(:defn, :f, s(:args, :a), s(:nil))
1639
1677
 
1640
- assert_parse_line rb, pt, 1
1678
+ assert_parse rb, pt
1641
1679
  end
1642
1680
 
1643
1681
  def test_parse_line_defn_complex
1644
1682
  rb = "def x(y)\n p(y)\n y *= 2\n return y;\nend" # TODO: remove () & ;
1645
1683
  pt = s(:defn, :x, s(:args, :y),
1646
- s(:call, nil, :p, s(:lvar, :y)),
1647
- s(:lasgn, :y, s(:call, s(:lvar, :y), :*, s(:lit, 2))),
1648
- s(:return, s(:lvar, :y)))
1684
+ s(:call, nil, :p, s(:lvar, :y).line(2)).line(2),
1685
+ s(:lasgn, :y, s(:call, s(:lvar, :y).line(3), :*, s(:lit, 2).line(3)).line(3)).line(3),
1686
+ s(:return, s(:lvar, :y).line(4)).line(4))
1649
1687
 
1650
- assert_parse_line rb, pt, 1
1688
+ assert_parse rb, pt
1651
1689
 
1652
1690
  body = result
1653
1691
  assert_equal 2, body.call.line, "call should have line number"
@@ -1656,61 +1694,65 @@ module TestRubyParserShared
1656
1694
  end
1657
1695
 
1658
1696
  def test_parse_line_defn_no_parens
1659
- pt = s(:defn, :f, s(:args).line(1), s(:nil)).line(1)
1697
+ pt = s(:defn, :f, s(:args), s(:nil))
1660
1698
 
1661
1699
  rb = "def f\nend"
1662
- assert_parse_line rb, pt, 1
1700
+ assert_parse rb, pt
1663
1701
 
1664
1702
  processor.reset
1665
1703
 
1666
1704
  rb = "def f\n\nend"
1667
- assert_parse_line rb, pt, 1
1705
+ assert_parse rb, pt
1668
1706
  end
1669
1707
 
1670
1708
  def test_parse_line_dot2
1671
1709
  rb = "0..\n4\na..\nb\nc"
1672
1710
  pt = s(:block,
1673
- s(:lit, 0..4).line(1),
1711
+ s(:lit, 0..4),
1674
1712
  s(:dot2,
1675
1713
  s(:call, nil, :a).line(3),
1676
1714
  s(:call, nil, :b).line(4)).line(3),
1677
- s(:call, nil, :c).line(5)).line(1)
1715
+ s(:call, nil, :c).line(5))
1678
1716
 
1679
- assert_parse_line rb, pt, 1
1717
+ assert_parse rb, pt
1680
1718
  end
1681
1719
 
1682
1720
  def test_parse_line_dot3
1683
1721
  rb = "0...\n4\na...\nb\nc"
1684
1722
  pt = s(:block,
1685
- s(:lit, 0...4).line(1),
1723
+ s(:lit, 0...4),
1686
1724
  s(:dot3,
1687
1725
  s(:call, nil, :a).line(3),
1688
1726
  s(:call, nil, :b).line(4)).line(3),
1689
- s(:call, nil, :c).line(5)).line(1)
1727
+ s(:call, nil, :c).line(5))
1690
1728
 
1691
- assert_parse_line rb, pt, 1
1729
+ assert_parse rb, pt
1692
1730
  end
1693
1731
 
1694
- def test_parse_line_dstr_newline
1695
- rb = <<-'CODE'
1696
- "a\n#{
1697
- }"
1698
- true
1699
- CODE
1700
-
1732
+ def test_parse_line_dstr_escaped_newline
1733
+ rb = "\"a\\n\#{\n}\"\ntrue"
1701
1734
  pt = s(:block,
1702
1735
  s(:dstr, "a\n",
1703
- s(:evstr)).line(1),
1736
+ s(:evstr)),
1704
1737
  s(:true).line(3))
1705
1738
 
1706
1739
  assert_parse rb, pt
1707
1740
  end
1708
1741
 
1742
+ def test_parse_line_dstr_soft_newline
1743
+ rb = "\"a\n#\{\n}\"\ntrue"
1744
+ pt = s(:block,
1745
+ s(:dstr, "a\n", s(:evstr).line(2)),
1746
+ s(:true).line(4))
1747
+
1748
+ assert_parse rb, pt
1749
+ end
1750
+
1709
1751
  def test_parse_line_evstr_after_break
1710
1752
  rb = "\"a\"\\\n\"\#{b}\""
1711
1753
  pt = s(:dstr, "a",
1712
1754
  s(:evstr,
1713
- s(:call, nil, :b).line(2)).line(2)).line(1)
1755
+ s(:call, nil, :b).line(2)).line(2))
1714
1756
 
1715
1757
  assert_parse rb, pt
1716
1758
  end
@@ -1719,14 +1761,14 @@ module TestRubyParserShared
1719
1761
  rb = "{\n:s1 => 1,\n}"
1720
1762
  pt = s(:hash,
1721
1763
  s(:lit, :s1).line(2), s(:lit, 1).line(2),
1722
- ).line(1)
1764
+ )
1723
1765
 
1724
1766
  assert_parse rb, pt
1725
1767
  end
1726
1768
 
1727
1769
  def test_parse_line_heredoc
1728
1770
  rb = <<-CODE
1729
- string = <<-HEREDOC
1771
+ string = <<-HEREDOC.strip
1730
1772
  very long string
1731
1773
  HEREDOC
1732
1774
  puts string
@@ -1734,20 +1776,23 @@ module TestRubyParserShared
1734
1776
 
1735
1777
  pt = s(:block,
1736
1778
  s(:lasgn, :string,
1737
- s(:str, " very long string\n").line(1)).line(1),
1738
- s(:call, nil, :puts, s(:lvar, :string).line(4)).line(4)).line(1)
1779
+ s(:call,
1780
+ s(:str, " very long string\n"),
1781
+ :strip),
1782
+ ),
1783
+ s(:call, nil, :puts,
1784
+ s(:lvar, :string).line(4)).line(4)
1785
+ )
1739
1786
 
1740
1787
  assert_parse rb, pt
1741
1788
  end
1742
1789
 
1743
1790
  def test_parse_line_heredoc_evstr
1744
- skip "heredoc line numbers are just gonna be screwed for a while..."
1745
-
1746
1791
  rb = "<<-A\na\n\#{b}\nA"
1747
- pt = s(:dstr, "a\n",
1748
- s(:evstr,
1749
- s(:call, nil, :b).line(3)),
1750
- s(:str, "\n")).line(1)
1792
+ pt = s(:dstr,
1793
+ "a\n",
1794
+ s(:evstr, s(:call, nil, :b).line(3)).line(3), s(:str, "\n").line(3)
1795
+ )
1751
1796
 
1752
1797
  assert_parse rb, pt
1753
1798
  end
@@ -1762,8 +1807,8 @@ module TestRubyParserShared
1762
1807
 
1763
1808
  pt = s(:block,
1764
1809
  s(:lasgn, :string,
1765
- s(:str, " very long string\n").line(1)).line(1),
1766
- s(:call, nil, :puts, s(:lvar, :string).line(4)).line(4)).line(1)
1810
+ s(:str, " very long string\n")),
1811
+ s(:call, nil, :puts, s(:lvar, :string).line(4)).line(4))
1767
1812
 
1768
1813
  assert_parse rb, pt
1769
1814
  end
@@ -1772,10 +1817,10 @@ module TestRubyParserShared
1772
1817
  rb = "f a do |x, y|\n x + y\nend"
1773
1818
 
1774
1819
  pt = s(:iter,
1775
- s(:call, nil, :f, s(:call, nil, :a).line(1)).line(1),
1776
- s(:args, :x, :y).line(1),
1820
+ s(:call, nil, :f, s(:call, nil, :a)),
1821
+ s(:args, :x, :y),
1777
1822
  s(:call, s(:lvar, :x).line(2), :+,
1778
- s(:lvar, :y).line(2)).line(2)).line(1)
1823
+ s(:lvar, :y).line(2)).line(2))
1779
1824
 
1780
1825
  assert_parse rb, pt
1781
1826
  end
@@ -1786,9 +1831,9 @@ module TestRubyParserShared
1786
1831
  pt = s(:iter,
1787
1832
  s(:call, nil, :f, s(:call, nil, :a)),
1788
1833
  s(:args, :x, :y),
1789
- s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
1834
+ s(:call, s(:lvar, :x).line(2), :+, s(:lvar, :y).line(2)).line(2))
1790
1835
 
1791
- assert_parse_line rb, pt, 1
1836
+ assert_parse rb, pt
1792
1837
 
1793
1838
  _, a, b, c, = result
1794
1839
 
@@ -1800,8 +1845,8 @@ module TestRubyParserShared
1800
1845
  def test_parse_line_multiline_str
1801
1846
  rb = "\"a\nb\"\n1"
1802
1847
  pt = s(:block,
1803
- s(:str, "a\nb").line(1),
1804
- s(:lit, 1).line(3)).line(1)
1848
+ s(:str, "a\nb"),
1849
+ s(:lit, 1).line(3))
1805
1850
 
1806
1851
  assert_parse rb, pt
1807
1852
  end
@@ -1809,8 +1854,8 @@ module TestRubyParserShared
1809
1854
  def test_parse_line_multiline_str_literal_n
1810
1855
  rb = "\"a\\nb\"\n1"
1811
1856
  pt = s(:block,
1812
- s(:str, "a\nb").line(1),
1813
- s(:lit, 1).line(2)).line(1)
1857
+ s(:str, "a\nb"),
1858
+ s(:lit, 1).line(2))
1814
1859
 
1815
1860
  assert_parse rb, pt
1816
1861
  end
@@ -1819,7 +1864,7 @@ module TestRubyParserShared
1819
1864
  rb = "true\n\n"
1820
1865
  pt = s(:true)
1821
1866
 
1822
- assert_parse_line rb, pt, 1
1867
+ assert_parse rb, pt
1823
1868
  end
1824
1869
 
1825
1870
  def test_parse_line_op_asgn
@@ -1832,30 +1877,30 @@ module TestRubyParserShared
1832
1877
  pt = s(:block,
1833
1878
  s(:lasgn, :foo,
1834
1879
  s(:call,
1835
- s(:lvar, :foo).line(1),
1880
+ s(:lvar, :foo),
1836
1881
  :+,
1837
- s(:call, nil, :bar).line(2)).line(1)).line(1),
1838
- s(:call, nil, :baz).line(3)).line(1)
1882
+ s(:call, nil, :bar).line(2))),
1883
+ s(:call, nil, :baz).line(3))
1839
1884
 
1840
- assert_parse_line rb, pt, 1
1885
+ assert_parse rb, pt
1841
1886
  end
1842
1887
 
1843
1888
  def test_parse_line_postexe
1844
1889
  rb = "END {\nfoo\n}"
1845
1890
  pt = s(:iter,
1846
- s(:postexe).line(1), 0,
1847
- s(:call, nil, :foo).line(2)).line(1)
1891
+ s(:postexe), 0,
1892
+ s(:call, nil, :foo).line(2))
1848
1893
 
1849
- assert_parse_line rb, pt, 1
1894
+ assert_parse rb, pt
1850
1895
  end
1851
1896
 
1852
1897
  def test_parse_line_preexe
1853
1898
  rb = "BEGIN {\nfoo\n}"
1854
1899
  pt = s(:iter,
1855
- s(:preexe).line(1), 0,
1856
- s(:call, nil, :foo).line(2)).line(1)
1900
+ s(:preexe), 0,
1901
+ s(:call, nil, :foo).line(2))
1857
1902
 
1858
- assert_parse_line rb, pt, 1
1903
+ assert_parse rb, pt
1859
1904
  end
1860
1905
 
1861
1906
  def test_parse_line_rescue
@@ -1867,7 +1912,7 @@ module TestRubyParserShared
1867
1912
  s(:resbody, s(:array).line(5),
1868
1913
  s(:call, nil, :c).line(6)).line(5)).line(2)
1869
1914
 
1870
- assert_parse_line rb, pt, 2
1915
+ assert_parse rb, pt
1871
1916
  end
1872
1917
 
1873
1918
  def test_parse_line_return
@@ -1880,11 +1925,11 @@ module TestRubyParserShared
1880
1925
  RUBY
1881
1926
 
1882
1927
  pt = s(:defn, :blah, s(:args),
1883
- s(:if, s(:true),
1884
- s(:return, s(:lit, 42)),
1885
- nil))
1928
+ s(:if, s(:true).line(2),
1929
+ s(:return, s(:lit, 42).line(3)).line(3),
1930
+ nil).line(2))
1886
1931
 
1887
- assert_parse_line rb, pt, 1
1932
+ assert_parse rb, pt
1888
1933
 
1889
1934
  assert_equal 3, result.if.return.line
1890
1935
  assert_equal 3, result.if.return.lit.line
@@ -1893,8 +1938,8 @@ module TestRubyParserShared
1893
1938
  def test_parse_line_str_with_newline_escape
1894
1939
  rb = 'a("\n", true)'
1895
1940
  pt = s(:call, nil, :a,
1896
- s(:str, "\n").line(1),
1897
- s(:true).line(1))
1941
+ s(:str, "\n"),
1942
+ s(:true))
1898
1943
 
1899
1944
  assert_parse rb, pt
1900
1945
  end
@@ -1903,18 +1948,18 @@ module TestRubyParserShared
1903
1948
  rb = "a,\nb = c\nd"
1904
1949
  pt = s(:block,
1905
1950
  s(:masgn,
1906
- s(:array, s(:lasgn, :a).line(1), s(:lasgn, :b).line(2)).line(1),
1907
- s(:to_ary, s(:call, nil, :c).line(2)).line(2)).line(1),
1908
- s(:call, nil, :d).line(3)).line(1)
1951
+ s(:array, s(:lasgn, :a), s(:lasgn, :b).line(2)),
1952
+ s(:to_ary, s(:call, nil, :c).line(2)).line(2)),
1953
+ s(:call, nil, :d).line(3))
1909
1954
 
1910
- assert_parse_line rb, pt, 1
1955
+ assert_parse rb, pt
1911
1956
  end
1912
1957
 
1913
1958
  def test_parse_line_trailing_newlines
1914
1959
  rb = "a \nb"
1915
1960
  pt = s(:block,
1916
- s(:call, nil, :a).line(1),
1917
- s(:call, nil, :b).line(2)).line(1)
1961
+ s(:call, nil, :a),
1962
+ s(:call, nil, :b).line(2))
1918
1963
 
1919
1964
  assert_parse rb, pt
1920
1965
  end
@@ -2026,7 +2071,9 @@ module TestRubyParserShared
2026
2071
 
2027
2072
  def test_str_heredoc_interp
2028
2073
  rb = "<<\"\"\n\#{x}\nblah2\n\n"
2029
- pt = s(:dstr, "", s(:evstr, s(:call, nil, :x)), s(:str, "\nblah2\n"))
2074
+ pt = s(:dstr, "",
2075
+ s(:evstr, s(:call, nil, :x).line(2)).line(2),
2076
+ s(:str, "\nblah2\n").line(2))
2030
2077
 
2031
2078
  assert_parse rb, pt
2032
2079
  end
@@ -2049,19 +2096,19 @@ module TestRubyParserShared
2049
2096
 
2050
2097
  def test_str_newline_hash_line_number
2051
2098
  rb = "\"\\n\\n\\n\\n#\"\n1"
2052
- pt = s(:block, s(:str, "\n\n\n\n#").line(1),
2099
+ pt = s(:block, s(:str, "\n\n\n\n#"),
2053
2100
  s(:lit, 1).line(2))
2054
2101
 
2055
2102
  assert_parse rb, pt
2056
2103
  end
2057
2104
 
2058
- # def test_str_pct_nested_nested
2059
- # rb = "%{ { #\{ \"#\{1}\" } } }"
2060
- # assert_equal " { 1 } ", eval(rb)
2061
- # pt = s(:dstr, " { ", s(:evstr, s(:lit, 1)), s(:str, " } "))
2062
- #
2063
- # assert_parse rb, pt
2064
- # end
2105
+ def test_str_pct_nested_nested
2106
+ rb = "%{ { #\{ \"#\{1}\" } } }"
2107
+ assert_equal " { 1 } ", eval(rb)
2108
+ pt = s(:dstr, " { ", s(:evstr, s(:lit, 1)), s(:str, " } "))
2109
+
2110
+ assert_parse rb, pt
2111
+ end
2065
2112
 
2066
2113
  def test_str_pct_Q_nested
2067
2114
  rb = "%Q[before [#\{nest}] after]"
@@ -2077,6 +2124,60 @@ module TestRubyParserShared
2077
2124
  assert_parse rb, pt
2078
2125
  end
2079
2126
 
2127
+ def test_str_single_newline
2128
+ rp = "a '\n';b"
2129
+ pt = s(:block,
2130
+ s(:call, nil, :a, s(:str, "\n")),
2131
+ s(:call, nil, :b).line(2))
2132
+
2133
+ assert_parse rp, pt
2134
+ end
2135
+
2136
+ def test_str_single_escaped_newline
2137
+ rp = "a '\\n';b"
2138
+ pt = s(:block,
2139
+ s(:call, nil, :a, s(:str, "\\n")),
2140
+ s(:call, nil, :b))
2141
+
2142
+ assert_parse rp, pt
2143
+ end
2144
+
2145
+ def test_str_single_double_escaped_newline
2146
+ rp = "a '\\\\n';b"
2147
+ pt = s(:block,
2148
+ s(:call, nil, :a, s(:str, "\\n")),
2149
+ s(:call, nil, :b))
2150
+
2151
+ assert_parse rp, pt
2152
+ end
2153
+
2154
+ def test_str_double_newline
2155
+ rp = "a \"\n\";b"
2156
+ pt = s(:block,
2157
+ s(:call, nil, :a, s(:str, "\n")),
2158
+ s(:call, nil, :b).line(2))
2159
+
2160
+ assert_parse rp, pt
2161
+ end
2162
+
2163
+ def test_str_double_escaped_newline
2164
+ rp = "a \"\\n\";b"
2165
+ pt = s(:block,
2166
+ s(:call, nil, :a, s(:str, "\n")),
2167
+ s(:call, nil, :b))
2168
+
2169
+ assert_parse rp, pt
2170
+ end
2171
+
2172
+ def test_str_double_double_escaped_newline
2173
+ rp = "a \"\\\\n\";b"
2174
+ pt = s(:block,
2175
+ s(:call, nil, :a, s(:str, "\\n")),
2176
+ s(:call, nil, :b))
2177
+
2178
+ assert_parse rp, pt
2179
+ end
2180
+
2080
2181
  def test_str_str
2081
2182
  rb = "\"a #\{'b'}\""
2082
2183
  pt = s(:str, "a b")
@@ -2464,7 +2565,7 @@ module TestRubyParserShared19Plus
2464
2565
  nil,
2465
2566
  :private,
2466
2567
  s(:defn, :f, s(:args),
2467
- s(:iter, s(:call, s(:call, nil, :a), :b), 0)))
2568
+ s(:iter, s(:call, s(:call, nil, :a).line(2), :b).line(2), 0).line(2)))
2468
2569
 
2469
2570
  assert_parse rb, pt
2470
2571
  end
@@ -2542,7 +2643,10 @@ module TestRubyParserShared19Plus
2542
2643
 
2543
2644
  def test_call_assoc_new_if_multiline
2544
2645
  rb = "a(b: if :c\n1\nelse\n2\nend)"
2545
- pt = s(:call, nil, :a, s(:hash, s(:lit, :b), s(:if, s(:lit, :c), s(:lit, 1), s(:lit, 2))))
2646
+ pt = s(:call, nil, :a,
2647
+ s(:hash,
2648
+ s(:lit, :b),
2649
+ s(:if, s(:lit, :c), s(:lit, 1).line(2), s(:lit, 2).line(4))))
2546
2650
 
2547
2651
  assert_parse rb, pt
2548
2652
  end
@@ -2631,8 +2735,8 @@ module TestRubyParserShared19Plus
2631
2735
  def test_defn_opt_last_arg
2632
2736
  rb = "def m arg = false\nend"
2633
2737
  pt = s(:defn, :m,
2634
- s(:args, s(:lasgn, :arg, s(:false).line(1)).line(1)).line(1),
2635
- s(:nil).line(2)).line(1)
2738
+ s(:args, s(:lasgn, :arg, s(:false))),
2739
+ s(:nil))
2636
2740
 
2637
2741
  assert_parse rb, pt
2638
2742
  end
@@ -2689,7 +2793,7 @@ module TestRubyParserShared19Plus
2689
2793
  rb = "1 ? b('') : 2\na d: 3"
2690
2794
  pt = s(:block,
2691
2795
  s(:if, s(:lit, 1), s(:call, nil, :b, s(:str, "")), s(:lit, 2)),
2692
- s(:call, nil, :a, s(:hash, s(:lit, :d), s(:lit, 3))))
2796
+ s(:call, nil, :a, s(:hash, s(:lit, :d).line(2), s(:lit, 3).line(2)).line(2)).line(2))
2693
2797
 
2694
2798
  assert_parse rb, pt
2695
2799
  end
@@ -3079,6 +3183,31 @@ module TestRubyParserShared19Plus
3079
3183
  assert_parse rb, pt
3080
3184
  end
3081
3185
 
3186
+ def test_call_leading_dots
3187
+ rb = "a\n.b\n.c"
3188
+ pt = s(:call, s(:call, s(:call, nil, :a), :b), :c)
3189
+
3190
+ assert_parse rb, pt
3191
+ end
3192
+
3193
+ def test_call_leading_dots_comment
3194
+ rb = "a\n.b\n#.c\n.d"
3195
+ pt = s(:call,
3196
+ s(:call,
3197
+ s(:call, nil, :a),
3198
+ :b),
3199
+ :d) # TODO: fix linenos: 1, 2, 4
3200
+
3201
+ assert_parse rb, pt
3202
+ end
3203
+
3204
+ def test_call_trailing_dots
3205
+ rb = "a.\nb.\nc"
3206
+ pt = s(:call, s(:call, s(:call, nil, :a), :b), :c)
3207
+
3208
+ assert_parse rb, pt
3209
+ end
3210
+
3082
3211
  def test_motherfuckin_leading_dots
3083
3212
  rb = "a\n.b"
3084
3213
  pt = s(:call, s(:call, nil, :a), :b)
@@ -3087,9 +3216,15 @@ module TestRubyParserShared19Plus
3087
3216
  end
3088
3217
 
3089
3218
  def test_motherfuckin_leading_dots2
3090
- rb = "a\n..b"
3219
+ rb = "1\n..3"
3220
+ pt = s(:block, s(:lit, 1),
3221
+ s(:dot2, nil, s(:lit, 3).line(2)).line(2))
3091
3222
 
3092
- assert_parse_error rb, '(string):2 :: parse error on value ".." (tDOT2)'
3223
+ if processor.class.version >= 27
3224
+ assert_parse rb, pt
3225
+ else
3226
+ assert_parse_error rb, '(string):2 :: parse error on value ".." (tDOT2)'
3227
+ end
3093
3228
  end
3094
3229
 
3095
3230
  def test_multiline_hash_declaration
@@ -3097,6 +3232,8 @@ module TestRubyParserShared19Plus
3097
3232
 
3098
3233
  assert_parse "f(state: {})", pt
3099
3234
  assert_parse "f(state: {\n})", pt
3235
+
3236
+ pt = s(:call, nil, :f, s(:hash, s(:lit, :state), s(:hash).line(2)))
3100
3237
  assert_parse "f(state:\n {\n})", pt
3101
3238
  end
3102
3239
 
@@ -3159,7 +3296,7 @@ module TestRubyParserShared19Plus
3159
3296
  rb = "until not var.nil?\n 'foo'\nend"
3160
3297
  pt = s(:until,
3161
3298
  s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
3162
- s(:str, "foo"), true)
3299
+ s(:str, "foo").line(2), true)
3163
3300
 
3164
3301
  assert_parse rb, pt
3165
3302
  end
@@ -3168,7 +3305,7 @@ module TestRubyParserShared19Plus
3168
3305
  rb = "until not var.nil?\n 'foo'\nend"
3169
3306
  pt = s(:until,
3170
3307
  s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
3171
- s(:str, "foo"), true)
3308
+ s(:str, "foo").line(2), true)
3172
3309
 
3173
3310
  processor.canonicalize_conditions = false
3174
3311
 
@@ -3179,7 +3316,7 @@ module TestRubyParserShared19Plus
3179
3316
  rb = "while not var.nil?\n 'foo'\nend"
3180
3317
  pt = s(:while,
3181
3318
  s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
3182
- s(:str, "foo"), true)
3319
+ s(:str, "foo").line(2), true)
3183
3320
 
3184
3321
  assert_parse rb, pt
3185
3322
  end
@@ -3188,7 +3325,7 @@ module TestRubyParserShared19Plus
3188
3325
  rb = "while not var.nil?\n 'foo'\nend"
3189
3326
  pt = s(:while,
3190
3327
  s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
3191
- s(:str, "foo"), true)
3328
+ s(:str, "foo").line(2), true)
3192
3329
 
3193
3330
  processor.canonicalize_conditions = false
3194
3331
 
@@ -3352,14 +3489,16 @@ module TestRubyParserShared19Plus
3352
3489
  RUBY
3353
3490
 
3354
3491
  pt = s(:hash,
3355
- s(:lit, :a),
3492
+ s(:lit, :a).line(2),
3356
3493
  s(:iter,
3357
- s(:call, nil, :lambda),
3494
+ s(:call, nil, :lambda).line(2),
3358
3495
  0,
3359
- s(:if, s(:call, nil, :b), s(:call, nil, :c), s(:call, nil, :d))),
3496
+ s(:if, s(:call, nil, :b).line(2),
3497
+ s(:call, nil, :c).line(2),
3498
+ s(:call, nil, :d).line(2)).line(2)).line(2),
3360
3499
 
3361
- s(:lit, :e),
3362
- s(:nil))
3500
+ s(:lit, :e).line(3),
3501
+ s(:nil).line(3))
3363
3502
 
3364
3503
  assert_parse rb, pt
3365
3504
  end
@@ -3368,6 +3507,98 @@ end
3368
3507
  module TestRubyParserShared20Plus
3369
3508
  include TestRubyParserShared19Plus
3370
3509
 
3510
+ def test_read_escape_unicode_h4
3511
+ rb = '?\u00a0'
3512
+ pt = s(:str, ?\u00a0)
3513
+
3514
+ assert_parse rb, pt
3515
+ end
3516
+
3517
+ def test_read_escape_unicode_curlies
3518
+ rb = '?\u{00a0}'
3519
+ pt = s(:str, ?\u00a0)
3520
+
3521
+ assert_parse rb, pt
3522
+ end
3523
+
3524
+ def test_regexp_unicode_curlies
3525
+ rb = '/\u{df}/'
3526
+ pt = s(:lit, /\u{df}/)
3527
+
3528
+ assert_parse rb, pt
3529
+
3530
+ rb = '/\u{c0de babe}/'
3531
+ pt = s(:lit, /\u{c0de babe}/)
3532
+
3533
+ assert_parse rb, pt
3534
+ end
3535
+
3536
+ def test_qw_escape
3537
+ rb = "%q(\1\\\')"
3538
+ pt = s(:str, "\001\\'")
3539
+
3540
+ assert_parse rb, pt
3541
+ end
3542
+
3543
+ def test_pct_nl
3544
+ rb = "x = %\n\n"
3545
+ pt = s(:lasgn, :x, s(:str, ""))
3546
+
3547
+ assert_parse rb, pt
3548
+ end
3549
+
3550
+ def test_regexp_esc_C_slash
3551
+ rb = "/\\cC\\d/"
3552
+ pt = s(:lit, Regexp.new('\cC\d')) # https://bugs.ruby-lang.org/issues/18449
3553
+
3554
+ assert_parse rb, pt
3555
+ end
3556
+
3557
+ def test_heredoc_wtf_I_hate_you
3558
+ rb = "p <<-END+'b\n a\n END\n c'+'d'"
3559
+ pt = s(:call, nil, :p,
3560
+ s(:call,
3561
+ s(:call, s(:str, " a\n"), :+,
3562
+ s(:str, "b\n c")),
3563
+ :+, s(:str, "d").line(4)))
3564
+
3565
+ assert_parse rb, pt
3566
+ end
3567
+
3568
+ def test_heredoc_nested
3569
+ rb = "[<<A,\n\#{<<B}\nb\nB\na\nA\n0]"
3570
+ pt = s(:array, s(:str, "b\n\na\n"),
3571
+ s(:lit, 0).line(7))
3572
+
3573
+ assert_parse rb, pt
3574
+ end
3575
+
3576
+ def test_pct_w_heredoc_interp_nested
3577
+ rb = "%W( 1 \#{<<A} 3\n2\nA\n 4 5 )"
3578
+ pt = s(:array,
3579
+ s(:str, "1"),
3580
+ s(:str, "2\n"),
3581
+ s(:str, "3"),
3582
+ s(:str, "4").line(4),
3583
+ s(:str, "5").line(4))
3584
+
3585
+ assert_parse rb, pt
3586
+ end
3587
+
3588
+ def test_regexp_esc_u
3589
+ rb = "/[\\u0021-\\u0027]/"
3590
+ pt = s(:lit, /[\u0021-\u0027]/)
3591
+
3592
+ assert_parse rb, pt
3593
+ end
3594
+
3595
+ def test_qw_escape_term
3596
+ rb = "%q|blah blah \\| blah blah|"
3597
+ pt = s(:str, "blah blah | blah blah")
3598
+
3599
+ assert_parse rb, pt
3600
+ end
3601
+
3371
3602
  def test_args_kw_block
3372
3603
  rb = "def f(a: 1, &b); end"
3373
3604
  pt = s(:defn, :f, s(:args, s(:kwarg, :a, s(:lit, 1)), :"&b"), s(:nil))
@@ -3375,6 +3606,49 @@ module TestRubyParserShared20Plus
3375
3606
  assert_parse rb, pt
3376
3607
  end
3377
3608
 
3609
+ def test_heredoc_backslash_nl
3610
+ rb = %Q(" why would someone do this? \\\n blah\n")
3611
+ pt = s(:str, " why would someone do this? blah\n")
3612
+
3613
+ assert_parse rb, pt
3614
+
3615
+ rb = "<<-DESC\n why would someone do this? \\\n blah\nDESC"
3616
+
3617
+ assert_parse rb, pt
3618
+ end
3619
+
3620
+ def test_heredoc_comma_arg
3621
+ rb = "[\" some text\n\",]"
3622
+ pt = s(:array, s(:str, " some text\n"))
3623
+
3624
+ assert_parse rb, pt
3625
+
3626
+ rb = "[<<-FILE,\n some text\nFILE\n]"
3627
+
3628
+ assert_parse rb, pt
3629
+ end
3630
+
3631
+ def test_heredoc_trailing_slash_continued_call
3632
+ rb = "<<END\\\nblah\nEND\n.strip"
3633
+ pt = s(:call, s(:str, "blah\n"), :strip)
3634
+
3635
+ assert_parse rb, pt
3636
+ end
3637
+
3638
+ def test_pct_q_backslash_nl
3639
+ rb = "%q{ \\\n}"
3640
+ pt = s(:str, " \\\n")
3641
+
3642
+ assert_parse rb, pt
3643
+ end
3644
+
3645
+ def test_pct_Q_backslash_nl
3646
+ rb = "%Q{ \\\n}"
3647
+ pt = s(:str, " ")
3648
+
3649
+ assert_parse rb, pt
3650
+ end
3651
+
3378
3652
  def test_block_arg_kwsplat
3379
3653
  rb = "a { |**b| }"
3380
3654
  pt = s(:iter, s(:call, nil, :a), s(:args, :"**b"))
@@ -3411,7 +3685,7 @@ module TestRubyParserShared20Plus
3411
3685
  rb = "a (b)\nc.d do end"
3412
3686
  pt = s(:block,
3413
3687
  s(:call, nil, :a, s(:call, nil, :b)),
3414
- s(:iter, s(:call, s(:call, nil, :c), :d), 0))
3688
+ s(:iter, s(:call, s(:call, nil, :c).line(2), :d).line(2), 0).line(2))
3415
3689
 
3416
3690
 
3417
3691
  assert_parse rb, pt
@@ -3421,8 +3695,9 @@ module TestRubyParserShared20Plus
3421
3695
  rb = "a def b(c)\n d\n end\n e.f do end"
3422
3696
  pt = s(:block,
3423
3697
  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))
3698
+ s(:defn, :b, s(:args, :c),
3699
+ s(:call, nil, :d).line(2))),
3700
+ s(:iter, s(:call, s(:call, nil, :e).line(4), :f).line(4), 0).line(4))
3426
3701
 
3427
3702
  assert_parse rb, pt
3428
3703
  end
@@ -3440,7 +3715,9 @@ module TestRubyParserShared20Plus
3440
3715
  def test_call_begin_call_block_call
3441
3716
  rb = "a begin\nb.c do end\nend"
3442
3717
  pt = s(:call, nil, :a,
3443
- s(:iter, s(:call, s(:call, nil, :b), :c), 0))
3718
+ s(:iter,
3719
+ s(:call, s(:call, nil, :b).line(2), :c).line(2),
3720
+ 0).line(2))
3444
3721
 
3445
3722
  assert_parse rb, pt
3446
3723
  end
@@ -3451,7 +3728,7 @@ module TestRubyParserShared20Plus
3451
3728
  s(:op_asgn, s(:const, :B),
3452
3729
  s(:call, nil, :d, s(:call, nil, :e)),
3453
3730
  :C,
3454
- :*)).line(1)
3731
+ :*))
3455
3732
 
3456
3733
  assert_parse rb, pt
3457
3734
  end
@@ -3509,9 +3786,9 @@ module TestRubyParserShared20Plus
3509
3786
  s(:iter,
3510
3787
  s(:call, s(:const, :Class), :new),
3511
3788
  0,
3512
- s(:defn, :initialize, s(:args), s(:nil))),
3789
+ s(:defn, :initialize, s(:args).line(2), s(:nil).line(2)).line(2)),
3513
3790
  :new),
3514
- s(:hash, s(:lit, :at), s(:str, "endpoint")))
3791
+ s(:hash, s(:lit, :at).line(4), s(:str, "endpoint").line(4)).line(4))
3515
3792
 
3516
3793
  assert_parse rb, pt
3517
3794
  end
@@ -3618,20 +3895,23 @@ module TestRubyParserShared20Plus
3618
3895
  pt = s(:block,
3619
3896
  s(:array,
3620
3897
  s(:lit, :a).line(2),
3621
- s(:lit, :b).line(3)).line(1),
3898
+ s(:lit, :b).line(3)),
3622
3899
  s(:lit, 1).line(5))
3623
3900
  assert_parse rb, pt
3624
3901
  end
3625
3902
 
3626
3903
  def test_iter_array_curly
3627
- skip if processor.class.version >= 25
3628
-
3629
3904
  rb = "f :a, [:b] { |c, d| }" # yes, this is bad code... that's their problem
3630
3905
  pt = s(:iter,
3631
3906
  s(:call, nil, :f, s(:lit, :a), s(:array, s(:lit, :b))),
3632
3907
  s(:args, :c, :d))
3633
3908
 
3634
- assert_parse rb, pt
3909
+ if processor.class.version >= 25 then
3910
+ msg = /parse error on value "\{" \(tLCURLY\)/
3911
+ assert_syntax_error rb, msg, Racc::ParseError
3912
+ else
3913
+ assert_parse rb, pt
3914
+ end
3635
3915
  end
3636
3916
 
3637
3917
  def test_iter_kwarg
@@ -3653,7 +3933,7 @@ module TestRubyParserShared20Plus
3653
3933
  pt = s(:block,
3654
3934
  s(:array,
3655
3935
  s(:lit, :a).line(2),
3656
- s(:lit, :b).line(3)).line(1),
3936
+ s(:lit, :b).line(3)),
3657
3937
  s(:lit, 1).line(5))
3658
3938
  assert_parse rb, pt
3659
3939
  end
@@ -3695,7 +3975,7 @@ module TestRubyParserShared20Plus
3695
3975
  s(:iter,
3696
3976
  s(:lambda),
3697
3977
  s(:args),
3698
- s(:iter, s(:call, s(:call, nil, :a), :b), 0)))
3978
+ s(:iter, s(:call, s(:call, nil, :a).line(2), :b).line(2), 0).line(2)))
3699
3979
 
3700
3980
  assert_parse rb, pt
3701
3981
  end
@@ -3708,7 +3988,7 @@ module TestRubyParserShared20Plus
3708
3988
  s(:args),
3709
3989
  s(:iter,
3710
3990
  s(:call, nil, :a,
3711
- s(:lit, 1)), 0)))
3991
+ s(:lit, 1).line(2)).line(2), 0).line(2)))
3712
3992
 
3713
3993
  assert_parse rb, pt
3714
3994
  end
@@ -3745,6 +4025,17 @@ end
3745
4025
  module TestRubyParserShared21Plus
3746
4026
  include TestRubyParserShared20Plus
3747
4027
 
4028
+ def test_array_lits_trailing_calls
4029
+ rb = "[].b"
4030
+ pt = s(:call, s(:array), :b)
4031
+
4032
+ assert_parse rb, pt
4033
+
4034
+ rb = "%w[].b"
4035
+
4036
+ assert_parse rb, pt
4037
+ end
4038
+
3748
4039
  def test_block_kw
3749
4040
  rb = "blah { |k:42| }"
3750
4041
  pt = s(:iter, s(:call, nil, :blah), s(:args, s(:kwarg, :k, s(:lit, 42))))
@@ -3767,7 +4058,7 @@ module TestRubyParserShared21Plus
3767
4058
 
3768
4059
  def test_bug162__21plus
3769
4060
  rb = %q(<<E\nfoo\nE\rO)
3770
- emsg = "can't match /E(\\r*\\n|\\z)/ anywhere in . near line 1: \"\""
4061
+ emsg = "can't match /E(?=\\r?\\n|\\z)/ anywhere in . near line 1: \"\""
3771
4062
 
3772
4063
  assert_syntax_error rb, emsg
3773
4064
  end
@@ -3804,8 +4095,8 @@ module TestRubyParserShared21Plus
3804
4095
  CODE
3805
4096
 
3806
4097
  pt = s(:block,
3807
- s(:str, "\n\n\n\n\n\n\n\n\n\n").line(1),
3808
- s(:class, :Foo, nil).line(5)).line(1)
4098
+ s(:str, "\n\n\n\n\n\n\n\n\n\n"),
4099
+ s(:class, :Foo, nil).line(5))
3809
4100
 
3810
4101
  assert_parse rb, pt
3811
4102
  end
@@ -3934,8 +4225,8 @@ module TestRubyParserShared23Plus
3934
4225
  def test_heredoc_squiggly_interp
3935
4226
  rb = "a = <<~EOF\n w\n x#\{42} y\n z\n EOF"
3936
4227
  pt = s(:lasgn, :a, s(:dstr, " w\nx",
3937
- s(:evstr, s(:lit, 42)),
3938
- s(:str, " y\n z\n")))
4228
+ s(:evstr, s(:lit, 42).line(3)).line(3),
4229
+ s(:str, " y\n z\n").line(3)))
3939
4230
 
3940
4231
  assert_parse rb, pt
3941
4232
  end
@@ -3963,6 +4254,42 @@ module TestRubyParserShared23Plus
3963
4254
  assert_parse rb, pt
3964
4255
  end
3965
4256
 
4257
+ def test_heredoc_squiggly_blank_lines
4258
+ rb = "a = <<~EOF\n x\n\n z\nEOF\n\n"
4259
+ pt = s(:lasgn, :a, s(:str, "x\n\nz\n"))
4260
+
4261
+ assert_parse rb, pt
4262
+ end
4263
+
4264
+ def test_heredoc_squiggly_visually_blank_lines
4265
+ rb = "a = <<~EOF\n x\n \n z\nEOF\n\n"
4266
+ pt = s(:lasgn, :a, s(:str, "x\n\nz\n"))
4267
+
4268
+ assert_parse rb, pt
4269
+ end
4270
+
4271
+ def test_heredoc_squiggly_empty
4272
+ rb = "<<~A\nA"
4273
+ pt = s(:str, "")
4274
+
4275
+ assert_parse rb, pt
4276
+ end
4277
+
4278
+ def test_heredoc_squiggly_blank_line_plus_interpolation
4279
+ rb = "a = foo(<<~EOF.chop)\n\n #\{bar}baz\n EOF"
4280
+ pt = s(:lasgn, :a,
4281
+ s(:call,
4282
+ nil,
4283
+ :foo,
4284
+ s(:call,
4285
+ s(:dstr, "\n",
4286
+ s(:evstr, s(:call, nil, :bar).line(3)).line(3),
4287
+ s(:str, "baz\n").line(3)).line(1),
4288
+ :chop).line(1)).line(1)).line(1)
4289
+
4290
+ assert_parse rb, pt
4291
+ end
4292
+
3966
4293
  def test_integer_with_if_modifier
3967
4294
  rb = "1_234if true"
3968
4295
  pt = s(:if, s(:true), s(:lit, 1234), nil)
@@ -4032,7 +4359,7 @@ module TestRubyParserShared23Plus
4032
4359
 
4033
4360
  def test_safe_call_operator
4034
4361
  rb = "a&.> 1"
4035
- pt = s(:safe_call, s(:call, nil, :a), :>, s(:lit, 1)).line(1)
4362
+ pt = s(:safe_call, s(:call, nil, :a), :>, s(:lit, 1))
4036
4363
 
4037
4364
  assert_parse rb, pt
4038
4365
  end
@@ -4052,15 +4379,16 @@ module TestRubyParserShared23Plus
4052
4379
  end
4053
4380
 
4054
4381
  def test_safe_op_asgn
4055
- rb = "a&.b += x 1\n"
4056
- pt = s(:safe_op_asgn, s(:call, nil, :a), s(:call, nil, :x, s(:lit, 1)), :b, :+).line(1)
4382
+ rb = "a&.b += x 1"
4383
+ pt = s(:safe_op_asgn, s(:call, nil, :a), s(:call, nil, :x, s(:lit, 1)), :b, :+)
4057
4384
 
4058
4385
  assert_parse rb, pt
4059
4386
  end
4060
4387
 
4061
4388
  def test_safe_op_asgn2
4062
4389
  rb = "a&.b ||=\nx;"
4063
- pt = s(:safe_op_asgn2, s(:call, nil, :a), :b=, :"||", s(:call, nil, :x)).line(1)
4390
+ pt = s(:safe_op_asgn2,
4391
+ s(:call, nil, :a), :b=, :"||", s(:call, nil, :x).line(2))
4064
4392
 
4065
4393
  assert_parse rb, pt
4066
4394
  end
@@ -4075,11 +4403,11 @@ a + b
4075
4403
  )
4076
4404
 
4077
4405
  pt = s(:block,
4078
- s(:call, nil, :puts, s(:str, "hello my dear friend").line(1)).line(1),
4406
+ s(:call, nil, :puts, s(:str, "hello my dear friend")),
4079
4407
  s(:call, s(:call, nil, :a).line(6),
4080
4408
  :+,
4081
4409
  s(:call, nil, :b).line(6)).line(6)
4082
- ).line(1)
4410
+ )
4083
4411
 
4084
4412
  assert_parse rb, pt
4085
4413
  end
@@ -4115,6 +4443,18 @@ module TestRubyParserShared26Plus
4115
4443
  assert_parse rb, pt
4116
4444
  end
4117
4445
 
4446
+ def test_begin_else_return_value # overrides above, warns < 2.6
4447
+ rb = "begin; else 2; end"
4448
+
4449
+ assert_syntax_error rb, "else without rescue is useless"
4450
+ end
4451
+
4452
+ def test_bug_begin_else # overrides above, warns < 2.6
4453
+ rb = "begin 1; else; 2 end"
4454
+
4455
+ assert_syntax_error rb, "else without rescue is useless"
4456
+ end
4457
+
4118
4458
  def test_dot3_nil__26
4119
4459
  rb = "a..."
4120
4460
  pt = s(:dot3, s(:call, nil, :a), nil)
@@ -4125,17 +4465,1025 @@ module TestRubyParserShared26Plus
4125
4465
  def test_symbol_list
4126
4466
  rb = '%I[#{a} #{b}]'
4127
4467
  pt = s(:array,
4128
- s(:dsym, "", s(:evstr, s(:call, nil, :a)).line(1)).line(1),
4129
- s(:dsym, "", s(:evstr, s(:call, nil, :b)).line(1)).line(1)).line 1
4468
+ s(:dsym, "", s(:evstr, s(:call, nil, :a))),
4469
+ s(:dsym, "", s(:evstr, s(:call, nil, :b)))).line 1
4130
4470
 
4131
4471
  assert_parse rb, pt
4132
4472
  end
4133
4473
  end
4134
4474
 
4475
+ module TestPatternMatching
4476
+ def rip rb
4477
+ require "ripper"
4478
+ puts
4479
+ pp Sexp.from_array Ripper.sexp rb
4480
+ end
4481
+
4482
+ def assert_case_in lit, exp_pt
4483
+ rb = "case :a\nin #{lit}\nend"
4484
+
4485
+ if ENV["VERBOSE_TEST"] then
4486
+ puts
4487
+ puts rb
4488
+ end
4489
+
4490
+ pt = s(:case, s(:lit, :a),
4491
+ s(:in, exp_pt, nil).line(2),
4492
+ nil)
4493
+
4494
+ assert_parse rb, pt
4495
+ end
4496
+
4497
+ def test_case_in_09
4498
+ assert_case_in(":b, [:c]",
4499
+ s(:array_pat, nil,
4500
+ s(:lit, :b).line(2),
4501
+ s(:array_pat, nil, s(:lit, :c).line(2)).line(2)).line(2))
4502
+ end
4503
+
4504
+ def test_case_in_10
4505
+ assert_case_in "nil, nil, nil", s(:array_pat,
4506
+ nil,
4507
+ s(:nil).line(2),
4508
+ s(:nil).line(2),
4509
+ s(:nil).line(2)).line(2)
4510
+ end
4511
+
4512
+ def test_case_in_21
4513
+ assert_case_in "Symbol()", s(:array_pat, s(:const, :Symbol).line(2)).line(2)
4514
+ end
4515
+
4516
+ def test_case_in_26
4517
+ assert_case_in "(42)", s(:lit, 42).line(2)
4518
+ end
4519
+
4520
+ def test_case_in_27
4521
+ assert_case_in("[A, *, B]",
4522
+ s(:array_pat, nil,
4523
+ s(:const, :A).line(2),
4524
+ :*,
4525
+ s(:const, :B).line(2)).line(2))
4526
+ end
4527
+
4528
+ def test_case_in_28_2
4529
+ assert_case_in '{ "b": }', s(:hash_pat, nil, s(:lit, :b).line(2), nil).line(2)
4530
+ end
4531
+
4532
+ def test_case_in_28
4533
+ assert_case_in "[]", s(:array_pat).line(2)
4534
+ end
4535
+
4536
+ def test_case_in_29
4537
+ assert_case_in "**nil", s(:hash_pat, nil, s(:kwrest, :"**nil").line(2)).line(2)
4538
+ end
4539
+
4540
+ def test_case_in_30
4541
+ assert_case_in "{}", s(:hash_pat, nil).line(2)
4542
+ end
4543
+
4544
+ def test_case_in_31?
4545
+ rb = "case :a\nin [:b, *c]\n :d\nend"
4546
+ pt = s(:case, s(:lit, :a),
4547
+ s(:in,
4548
+ s(:array_pat, nil, s(:lit, :b).line(2), :"*c").line(2),
4549
+ s(:lit, :d).line(3)).line(2),
4550
+ nil)
4551
+
4552
+ assert_parse rb, pt
4553
+ end
4554
+
4555
+ def test_case_in_32
4556
+ assert_case_in "(1...3)", s(:dot3, s(:lit, 1).line(2), s(:lit, 3).line(2)).line(2)
4557
+ end
4558
+
4559
+ def test_case_in_33
4560
+ assert_case_in "(1...)", s(:dot3, s(:lit, 1).line(2), nil).line(2)
4561
+ end
4562
+
4563
+ def test_case_in_34
4564
+ assert_case_in "(..10)", s(:dot2, nil, s(:lit, 10).line(2)).line(2)
4565
+ end
4566
+
4567
+ def test_case_in_35
4568
+ assert_case_in "(...10)", s(:dot3, nil, s(:lit, 10).line(2)).line(2)
4569
+ end
4570
+
4571
+ def test_case_in_36
4572
+ rb = "[:a, b, c, [:d, *e, nil]]"
4573
+ pt = s(:array_pat,
4574
+ nil,
4575
+ s(:lit, :a).line(2),
4576
+ s(:lasgn, :b).line(2),
4577
+ s(:lasgn, :c).line(2),
4578
+ s(:array_pat,
4579
+ nil,
4580
+ s(:lit, :d).line(2),
4581
+ :"*e",
4582
+ s(:nil).line(2)).line(2)).line(2)
4583
+
4584
+ assert_case_in rb, pt
4585
+ end
4586
+
4587
+ def test_case_in_37
4588
+ rb = "case :a\nin { b: [Hash, *] }\n :c\nend"
4589
+ pt = s(:case, s(:lit, :a),
4590
+ s(:in,
4591
+ s(:hash_pat,
4592
+ nil,
4593
+ s(:lit, :b).line(2),
4594
+ s(:array_pat, nil, s(:const, :Hash).line(2), :"*").line(2)
4595
+ ).line(2),
4596
+ s(:lit, :c).line(3)).line(2),
4597
+ nil)
4598
+
4599
+ assert_parse rb, pt
4600
+ end
4601
+
4602
+ def test_case_in_42
4603
+ rb = "case :a\nin :b, *_ then nil\nend"
4604
+ pt = s(:case, s(:lit, :a),
4605
+ s(:in,
4606
+ s(:array_pat,
4607
+ nil,
4608
+ s(:lit, :b).line(2),
4609
+ :"*_",
4610
+ ).line(2),
4611
+ s(:nil).line(2)).line(2),
4612
+ nil)
4613
+
4614
+ assert_parse rb, pt
4615
+ end
4616
+
4617
+ def test_case_in_42_2
4618
+ rb = "case :a\nin A(*list) then nil\nend"
4619
+ pt = s(:case, s(:lit, :a),
4620
+ s(:in,
4621
+ s(:array_pat,
4622
+ s(:const, :A).line(2),
4623
+ :"*list").line(2),
4624
+ s(:nil).line(2)).line(2),
4625
+ nil)
4626
+
4627
+ assert_parse rb, pt
4628
+ end
4629
+
4630
+ def test_case_in_42_3
4631
+ assert_case_in ":b, *_, :c", s(:array_pat, nil,
4632
+ s(:lit, :b).line(2),
4633
+ :"*_",
4634
+ s(:lit, :c).line(2)).line(2)
4635
+ end
4636
+
4637
+
4638
+ def test_case_in_47
4639
+ rb = "case :a\nin [*, :b, :c]\n :d\nend"
4640
+ pt = s(:case, s(:lit, :a),
4641
+ s(:in,
4642
+ s(:array_pat, nil, :*,
4643
+ s(:lit, :b).line(2), s(:lit, :c).line(2)).line(2),
4644
+ s(:lit, :d).line(3)).line(2),
4645
+ nil)
4646
+
4647
+ assert_parse rb, pt
4648
+ end
4649
+
4650
+ def test_case_in_67
4651
+ rb = "case :a\nin 1.. then nil\nend"
4652
+ pt = s(:case,
4653
+ s(:lit, :a),
4654
+ s(:in, s(:dot2, s(:lit, 1).line(2), nil).line(2),
4655
+ s(:nil).line(2)).line(2),
4656
+ nil)
4657
+
4658
+ assert_parse rb, pt
4659
+ end
4660
+
4661
+ def test_case_in_76
4662
+ assert_case_in "`echo hi`", s(:xstr, "echo hi").line(2)
4663
+ end
4664
+
4665
+ def test_case_in_77
4666
+ assert_case_in "/regexp/", s(:lit, /regexp/).line(2)
4667
+ end
4668
+
4669
+ def test_case_in_78
4670
+ assert_case_in "%W[a b]", s(:array_pat, nil, s(:str, "a").line(2), s(:str, "b").line(2)).line(2)
4671
+ end
4672
+
4673
+ def test_case_in_79
4674
+ assert_case_in "%w[a b]", s(:array_pat, nil, s(:str, "a").line(2), s(:str, "b").line(2)).line(2)
4675
+ end
4676
+
4677
+ def test_case_in_80
4678
+ assert_case_in "%I[a b]", s(:array_pat, nil, s(:lit, :a).line(2), s(:lit, :b).line(2)).line(2)
4679
+ end
4680
+
4681
+ def test_case_in_81
4682
+ assert_case_in "%i[a b]", s(:array_pat, nil, s(:lit, :a).line(2), s(:lit, :b).line(2)).line(2)
4683
+ end
4684
+
4685
+ def test_case_in_83
4686
+ rb = "[->(b) { true }, c]"
4687
+ pt = s(:array_pat, nil,
4688
+ s(:iter, s(:lambda).line(2), s(:args, :b).line(2),
4689
+ s(:true).line(2)).line(2),
4690
+ s(:lasgn, :c).line(2)).line(2)
4691
+
4692
+ assert_case_in rb, pt
4693
+ end
4694
+
4695
+ def test_case_in_85
4696
+ rb = "[[:b, c], [:d, ^e]]"
4697
+ pt = s(:array_pat, nil,
4698
+ s(:array_pat, nil,
4699
+ s(:lit, :b).line(2),
4700
+ s(:lasgn, :c).line(2)).line(2),
4701
+ s(:array_pat,
4702
+ nil,
4703
+ s(:lit, :d).line(2),
4704
+ s(:lvar, :e).line(2)).line(2),
4705
+ ).line(2)
4706
+
4707
+ assert_case_in rb, pt
4708
+ end
4709
+
4710
+ def test_case_in_86
4711
+ rb = "case [:a, :b]\nin ::NilClass, * then nil\nend"
4712
+ pt = s(:case,
4713
+ s(:array, s(:lit, :a), s(:lit, :b)),
4714
+ s(:in,
4715
+ s(:array_pat,
4716
+ nil,
4717
+ s(:colon3, :NilClass).line(2),
4718
+ :*).line(2),
4719
+ s(:nil).line(2)).line(2),
4720
+ nil)
4721
+
4722
+ assert_parse rb, pt
4723
+ end
4724
+
4725
+ def test_case_in_86_2
4726
+ rb = "case [:a, :b]\nin *, ::NilClass then nil\nend"
4727
+ pt = s(:case,
4728
+ s(:array, s(:lit, :a), s(:lit, :b)),
4729
+ s(:in,
4730
+ s(:array_pat,
4731
+ nil,
4732
+ :*,
4733
+ s(:colon3, :NilClass).line(2)).line(2),
4734
+ s(:nil).line(2)).line(2),
4735
+ nil)
4736
+
4737
+ assert_parse rb, pt
4738
+ end
4739
+
4740
+ def test_case_in_array_pat_const
4741
+ rb = "case :a\nin B[c]\n :d\nend"
4742
+ pt = s(:case, s(:lit, :a),
4743
+ s(:in,
4744
+ s(:array_pat,
4745
+ s(:const, :B).line(2),
4746
+ s(:lasgn, :c).line(2)).line(2),
4747
+ s(:lit, :d).line(3)).line(2),
4748
+ nil)
4749
+
4750
+ assert_parse rb, pt
4751
+ end
4752
+
4753
+ def test_case_in_array_pat_const2
4754
+ rb = "case :a\nin B::C[d]\n :e\nend"
4755
+ pt = s(:case, s(:lit, :a),
4756
+ s(:in,
4757
+ s(:array_pat,
4758
+ s(:const, s(:colon2, s(:const, :B).line(2), :C).line(2)).line(2),
4759
+ s(:lasgn, :d).line(2)).line(2),
4760
+ s(:lit, :e).line(3)).line(2),
4761
+ nil)
4762
+
4763
+ assert_parse rb, pt
4764
+ end
4765
+
4766
+ def test_case_in_array_pat_paren_assign
4767
+ rb = "case :a\nin B(C => d)\n :d\nend"
4768
+ pt = s(:case, s(:lit, :a),
4769
+ s(:in,
4770
+ s(:array_pat,
4771
+ s(:const, :B).line(2),
4772
+ s(:lasgn, :d, s(:const, :C).line(2)).line(2)).line(2),
4773
+ s(:lit, :d).line(3)).line(2),
4774
+ nil)
4775
+
4776
+ assert_parse rb, pt
4777
+ end
4778
+
4779
+ def test_case_in_const
4780
+ rb = "case Array\nin Class\n :b\nend"
4781
+ pt = s(:case, s(:const, :Array),
4782
+ s(:in, s(:const, :Class).line(2),
4783
+ s(:lit, :b).line(3)).line(2),
4784
+ nil).line 1
4785
+
4786
+ assert_parse rb, pt
4787
+ end
4788
+
4789
+ def test_case_in_else
4790
+ rb = "case Array\nin Class\n :b\nelse\n :c\nend\n"
4791
+ pt = s(:case, s(:const, :Array),
4792
+ s(:in, s(:const, :Class).line(2),
4793
+ s(:lit, :b).line(3)).line(2),
4794
+ s(:lit, :c).line(5)).line 1
4795
+
4796
+ assert_parse rb, pt
4797
+ end
4798
+
4799
+ def test_case_in_hash_pat
4800
+ rb = "case :a\nin { b: 'c', d: \"e\" } then\n :f\nend\n"
4801
+ pt = s(:case, s(:lit, :a),
4802
+ s(:in,
4803
+ s(:hash_pat,
4804
+ nil,
4805
+ s(:lit, :b).line(2), s(:str, "c").line(2),
4806
+ s(:lit, :d).line(2), s(:str, "e").line(2)).line(2),
4807
+ s(:lit, :f).line(3)
4808
+ ).line(2),
4809
+ nil)
4810
+
4811
+ assert_parse rb, pt
4812
+ end
4813
+
4814
+ def test_case_in_hash_pat_assign
4815
+ rb = "case :a\nin { b: Integer => x, d: \"e\", f: } then\n :g\nend"
4816
+ pt = s(:case, s(:lit, :a),
4817
+ s(:in,
4818
+ s(:hash_pat,
4819
+ nil,
4820
+ s(:lit, :b).line(2), # =>
4821
+ s(:lasgn, :x, s(:const, :Integer).line(2)).line(2),
4822
+ s(:lit, :d).line(2), s(:str, "e").line(2),
4823
+ s(:lit, :f).line(2), nil).line(2),
4824
+ s(:lit, :g).line(3)).line(2),
4825
+ nil)
4826
+
4827
+ assert_parse rb, pt
4828
+ end
4829
+
4830
+ def test_case_in_hash_pat_paren_assign
4831
+ rb = "case :a\nin B(a: 42)\n :d\nend"
4832
+ pt = s(:case, s(:lit, :a),
4833
+ s(:in,
4834
+ s(:hash_pat,
4835
+ s(:const, :B).line(2),
4836
+ s(:lit, :a).line(2), s(:lit, 42).line(2)).line(2),
4837
+ s(:lit, :d).line(3)).line(2),
4838
+ nil)
4839
+
4840
+ assert_parse rb, pt
4841
+ end
4842
+
4843
+ def test_case_in_hash_pat_paren_true
4844
+ rb = "case :a\nin b: true then\n :c\nend\n"
4845
+ pt = s(:case, s(:lit, :a),
4846
+ s(:in,
4847
+ s(:hash_pat,
4848
+ nil,
4849
+ s(:lit, :b).line(2), s(:true).line(2)).line(2),
4850
+ s(:lit, :c).line(3)).line(2),
4851
+ nil)
4852
+
4853
+ assert_parse rb, pt
4854
+ end
4855
+
4856
+ def test_case_in_hash_pat_rest
4857
+ rb = "case :a\nin b: c, **rest then :d\nend"
4858
+ pt = s(:case,
4859
+ s(:lit, :a),
4860
+ s(:in,
4861
+ s(:hash_pat,
4862
+ nil,
4863
+ s(:lit, :b).line(2),
4864
+ s(:lasgn, :c).line(2),
4865
+ s(:kwrest, :"**rest").line(2)).line(2),
4866
+ s(:lit, :d).line(2)).line(2),
4867
+ nil)
4868
+
4869
+ assert_parse rb, pt
4870
+ end
4871
+
4872
+ def test_case_in_hash_pat_rest_solo
4873
+ rb = "case :a\nin **rest then :d\nend"
4874
+ pt = s(:case,
4875
+ s(:lit, :a),
4876
+ s(:in,
4877
+ s(:hash_pat,
4878
+ nil,
4879
+ s(:kwrest, :"**rest").line(2)).line(2),
4880
+ s(:lit, :d).line(2)).line(2),
4881
+ nil)
4882
+
4883
+ assert_parse rb, pt
4884
+ end
4885
+
4886
+ def test_case_in_if_unless_post_mod
4887
+ rb = "case :a\nin A if true\n :C\nin D unless false\n :E\nend"
4888
+ pt = s(:case,
4889
+ s(:lit, :a),
4890
+ s(:in,
4891
+ s(:if, s(:true).line(2), s(:const, :A).line(2), nil).line(2),
4892
+ s(:lit, :C).line(3)).line(2),
4893
+ s(:in,
4894
+ s(:if, s(:false).line(4), nil, s(:const, :D).line(4)).line(4),
4895
+ s(:lit, :E).line(5)).line(4),
4896
+ nil)
4897
+
4898
+ assert_parse rb, pt
4899
+ end
4900
+
4901
+ def test_case_in_multiple
4902
+ rb = "case :a\nin A::B\n :C\nin D::E\n :F\nend"
4903
+ pt = s(:case,
4904
+ s(:lit, :a),
4905
+ s(:in,
4906
+ s(:const, s(:colon2, s(:const, :A).line(2), :B).line(2)).line(2),
4907
+ s(:lit, :C).line(3)).line(2),
4908
+ s(:in,
4909
+ s(:const, s(:colon2, s(:const, :D).line(4), :E).line(4)).line(4),
4910
+ s(:lit, :F).line(5)).line(4),
4911
+ nil)
4912
+
4913
+ assert_parse rb, pt
4914
+ end
4915
+
4916
+ def test_case_in_or
4917
+ rb = "case :a\nin B | C\n :d\nend\n"
4918
+ pt = s(:case, s(:lit, :a),
4919
+ s(:in,
4920
+ s(:or,
4921
+ s(:const, :B).line(2),
4922
+ s(:const, :C).line(2)).line(2),
4923
+ s(:lit, :d).line(3)).line(2),
4924
+ nil)
4925
+
4926
+ assert_parse rb, pt
4927
+ end
4928
+
4929
+ def test_in_expr_no_case
4930
+ rb = "'woot' in String"
4931
+ pt = s(:case, s(:str, "woot"),
4932
+ s(:in, s(:const, :String),
4933
+ nil),
4934
+ nil)
4935
+
4936
+ assert_parse rb, pt
4937
+ end
4938
+
4939
+ def test_parse_pattern_019
4940
+ rb = <<~RUBY
4941
+ case 0
4942
+ in -1..1
4943
+ true
4944
+ end
4945
+ RUBY
4946
+
4947
+ pt = s(:case,
4948
+ s(:lit, 0),
4949
+ s(:in, s(:dot2, s(:lit, -1).line(2), s(:lit, 1).line(2)).line(2),
4950
+ s(:true).line(3)).line(2),
4951
+ nil)
4952
+
4953
+ assert_parse rb, pt
4954
+ end
4955
+
4956
+ def test_parse_pattern_044
4957
+ rb = <<~RUBY
4958
+ case obj
4959
+ in Object[]
4960
+ true
4961
+ end
4962
+ RUBY
4963
+ pt = s(:case,
4964
+ s(:call, nil, :obj),
4965
+ s(:in, s(:array_pat, s(:const, :Object).line(2)).line(2),
4966
+ s(:true).line(3)).line(2),
4967
+ nil)
4968
+
4969
+ assert_parse rb, pt
4970
+ end
4971
+
4972
+ def test_parse_pattern_051
4973
+ rb = <<~RUBY
4974
+ case [0, 1, 2]
4975
+ in [0, 1,]
4976
+ true
4977
+ end
4978
+ RUBY
4979
+ pt = s(:case,
4980
+ s(:array,
4981
+ s(:lit, 0),
4982
+ s(:lit, 1),
4983
+ s(:lit, 2)),
4984
+ s(:in,
4985
+ s(:array_pat,
4986
+ nil,
4987
+ s(:lit, 0).line(2),
4988
+ s(:lit, 1).line(2),
4989
+ :*).line(666),
4990
+ s(:true).line(3)).line(2),
4991
+ nil)
4992
+
4993
+ assert_parse rb, pt
4994
+ end
4995
+
4996
+ def test_parse_pattern_058
4997
+ rb = <<~RUBY
4998
+ case {a: 0}
4999
+ in {a:, **rest}
5000
+ [a, rest]
5001
+ end
5002
+ RUBY
5003
+ pt = s(:case,
5004
+ s(:hash,
5005
+ s(:lit, :a),
5006
+ s(:lit, 0)),
5007
+ s(:in,
5008
+ s(:hash_pat, nil, s(:lit, :a).line(2), nil,
5009
+ s(:kwrest, :"**rest").line(2)).line(2),
5010
+ s(:array,
5011
+ s(:lvar, :a).line(3),
5012
+ s(:lvar, :rest).line(3)).line(3)).line(2),
5013
+ nil)
5014
+
5015
+ assert_parse rb, pt
5016
+ end
5017
+
5018
+ def test_parse_pattern_058_2
5019
+ rb = <<~RUBY
5020
+ case {a: 0}
5021
+ in {a:, **}
5022
+ [a]
5023
+ end
5024
+ RUBY
5025
+ pt = s(:case,
5026
+ s(:hash,
5027
+ s(:lit, :a),
5028
+ s(:lit, 0)),
5029
+ s(:in,
5030
+ s(:hash_pat, nil, s(:lit, :a).line(2), nil,
5031
+ s(:kwrest, :"**").line(2)).line(2),
5032
+ s(:array,
5033
+ s(:lvar, :a).line(3)).line(3)).line(2),
5034
+ nil)
5035
+
5036
+ assert_parse rb, pt
5037
+ end
5038
+
5039
+ def test_parse_pattern_069
5040
+ rb = <<~RUBY
5041
+ case :a
5042
+ in Object[b: 1]
5043
+ 1
5044
+ end
5045
+ RUBY
5046
+ pt = s(:case,
5047
+ s(:lit, :a),
5048
+ s(:in,
5049
+ s(:hash_pat, s(:const, :Object).line(2),
5050
+ s(:lit, :b).line(2), s(:lit, 1).line(2)).line(2),
5051
+ s(:lit, 1).line(3)).line(2),
5052
+ nil)
5053
+
5054
+
5055
+ assert_parse rb, pt
5056
+ end
5057
+
5058
+ def test_parse_pattern_076
5059
+ rb = <<~RUBY
5060
+ case {a: 1}
5061
+ in {a: 1, **nil}
5062
+ true
5063
+ end
5064
+ RUBY
5065
+ pt = s(:case,
5066
+ s(:hash, s(:lit, :a), s(:lit, 1)),
5067
+ s(:in,
5068
+ s(:hash_pat, nil,
5069
+ s(:lit, :a).line(2), s(:lit, 1).line(2),
5070
+ s(:kwrest, :"**nil").line(2)).line(2),
5071
+ s(:true).line(3)).line(2),
5072
+ nil)
5073
+
5074
+ assert_parse rb, pt
5075
+ end
5076
+
5077
+ # def test_case_in_TEMPLATE
5078
+ # rb = "case :a\nin XXX then\n YYY\nend\n"
5079
+ # pt = s(:case, s(:lit, :a),
5080
+ # s(:in,
5081
+ # ZZZ,
5082
+ # WWW).line(2),
5083
+ # nil)
5084
+ #
5085
+ # assert_parse rb, pt
5086
+ # end
5087
+ end
5088
+
5089
+ module TestPatternMatching30
5090
+ def test_case_in_20
5091
+ assert_case_in("Symbol(*lhs, x, *rhs)",
5092
+ s(:find_pat,
5093
+ s(:const, :Symbol).line(2),
5094
+ :"*lhs",
5095
+ s(:lasgn, :x).line(2),
5096
+ :"*rhs").line(2))
5097
+ end
5098
+
5099
+ def test_case_in_22
5100
+ assert_case_in("Symbol[*lhs, x, *rhs]",
5101
+ s(:find_pat, s(:const, :Symbol).line(2),
5102
+ :"*lhs",
5103
+ s(:lasgn, :x).line(2),
5104
+ :"*rhs").line(2))
5105
+ end
5106
+ end
5107
+
4135
5108
  module TestRubyParserShared27Plus
4136
5109
  include TestRubyParserShared26Plus
5110
+ include TestPatternMatching
5111
+
5112
+ def test_block_args_kwargs
5113
+ rb = "f { |**kwargs| kwargs }"
5114
+ pt = s(:iter,
5115
+ s(:call, nil, :f),
5116
+ s(:args, :"**kwargs"),
5117
+ s(:lvar, :kwargs))
5118
+
5119
+ assert_parse rb, pt
5120
+ end
5121
+
5122
+ def test_block_args_no_kwargs
5123
+ rb = "f { |**nil| }"
5124
+ pt = s(:iter,
5125
+ s(:call, nil, :f),
5126
+ s(:args, :"**nil"))
5127
+
5128
+ assert_parse rb, pt
5129
+ end
5130
+
5131
+ def test_defn_forward_args
5132
+ rb = "def a(...); b(...); end"
5133
+ pt = s(:defn, :a, s(:args, s(:forward_args)),
5134
+ s(:call, nil, :b, s(:forward_args)))
5135
+
5136
+ assert_parse rb, pt
5137
+ end
5138
+
5139
+ def test_defn_arg_forward_args
5140
+ rb = "def a(x, ...); b(x, ...); end"
5141
+ pt = s(:defn, :a, s(:args, :x, s(:forward_args)),
5142
+ s(:call, nil, :b, s(:lvar, :x), s(:forward_args)))
5143
+
5144
+ assert_parse rb, pt
5145
+ end
5146
+
5147
+ def test_defn_args_forward_args
5148
+ rb = "def a(x, y, z, ...); b(:get, z, ...); end"
5149
+ pt = s(:defn, :a, s(:args, :x, :y, :z, s(:forward_args)),
5150
+ s(:call, nil, :b, s(:lit, :get), s(:lvar, :z),
5151
+ s(:forward_args)))
5152
+
5153
+ assert_parse rb, pt
5154
+ end
5155
+
5156
+ def test_defn_no_kwargs
5157
+ # def x(**nil)
5158
+ # end
5159
+ #
5160
+ # def y(**kw)
5161
+ # end
5162
+ #
5163
+ # def z()
5164
+ # end
5165
+ #
5166
+ # x arg: 42 # $!: no keywords accepted (ArgumentError)
5167
+ # y arg: 42 # fine
5168
+ # z arg: 42 # $!: wrong number of arguments (given 1, expected 0) (ArgumentError)
5169
+
5170
+ rb = "def x(**nil); end"
5171
+ pt = s(:defn, :x, s(:args, :"**nil"),
5172
+ s(:nil))
5173
+
5174
+ assert_parse rb, pt
5175
+ end
5176
+
5177
+ def test_call_forward_args_outside_method_definition
5178
+ rb = "b(...)"
5179
+
5180
+ assert_syntax_error rb, "Unexpected ..."
5181
+ end
5182
+
5183
+ def test_call_arg_forward_args_outside_method_definition
5184
+ rb = "b(x, ...)"
5185
+
5186
+ assert_syntax_error rb, "Unexpected ..."
5187
+ end
5188
+
5189
+ def test_mlhs_rescue
5190
+ # same:
5191
+ # a = (24 rescue 42)
5192
+ # a = 24 rescue 42
5193
+
5194
+ # same:
5195
+ # a, b = (f rescue 42)
5196
+ # a, b = f rescue 42
5197
+
5198
+ rb = "a, b = f rescue 42"
5199
+ pt = s(:masgn,
5200
+ s(:array, s(:lasgn, :a), s(:lasgn, :b)),
5201
+ s(:to_ary,
5202
+ s(:rescue,
5203
+ s(:call, nil, :f),
5204
+ s(:resbody, s(:array),
5205
+ s(:lit, 42)))))
5206
+
5207
+ assert_parse rb, pt
5208
+ end
4137
5209
  end
4138
5210
 
5211
+ module TestRubyParserShared30Plus
5212
+ include TestRubyParserShared27Plus
5213
+ include TestPatternMatching30
5214
+
5215
+ def test_rhs_asgn
5216
+ rb = "42 => n"
5217
+ pt = s(:case,
5218
+ s(:lit, 42),
5219
+ s(:in, s(:lasgn, :n), nil), nil)
5220
+
5221
+ assert_parse rb, pt
5222
+ end
5223
+
5224
+ def test_case_in_find
5225
+ rb = "case :a\n in *a, :+, *b\nend"
5226
+ pt = s(:case,
5227
+ s(:lit, :a),
5228
+ s(:in,
5229
+ s(:find_pat, nil,
5230
+ :"*a",
5231
+ s(:lit, :+).line(2),
5232
+ :"*b").line(2),
5233
+ nil).line(2),
5234
+ nil)
5235
+
5236
+ assert_parse rb, pt
5237
+ end
5238
+
5239
+ def test_case_in_find_array
5240
+ rb = "case :a\nin [*, :b, c, *]\nend"
5241
+ pt = s(:case,
5242
+ s(:lit, :a),
5243
+ s(:in,
5244
+ s(:find_pat, nil,
5245
+ :*,
5246
+ s(:lit, :b).line(2), s(:lasgn, :c).line(2),
5247
+ :*).line(2),
5248
+ nil).line(2),
5249
+ nil)
5250
+
5251
+ assert_parse rb, pt
5252
+ end
5253
+
5254
+ def test_defn_oneliner
5255
+ rb = "def exec(cmd) = system(cmd)"
5256
+ pt = s(:defn, :exec, s(:args, :cmd),
5257
+ s(:call, nil, :system, s(:lvar, :cmd)))
5258
+
5259
+ assert_parse rb, pt
5260
+ end
5261
+
5262
+ def test_defn_oneliner_noargs_parentheses
5263
+ rb = "def exec() = system"
5264
+ pt = s(:defn, :exec, s(:args),
5265
+ s(:call, nil, :system))
5266
+
5267
+ assert_parse rb, pt
5268
+ end
5269
+
5270
+ def test_defn_oneliner_noargs
5271
+ rb = "def exec = system"
5272
+ pt = s(:defn, :exec, s(:args),
5273
+ s(:call, nil, :system))
5274
+
5275
+ assert_parse rb, pt
5276
+ end
5277
+
5278
+ def test_defn_oneliner_rescue
5279
+ rb = "def exec(cmd)\n system(cmd)\nrescue\n nil\nend\n"
5280
+ pt = s(:defn, :exec, s(:args, :cmd),
5281
+ s(:rescue,
5282
+ s(:call, nil, :system, s(:lvar, :cmd).line(2)).line(2),
5283
+ s(:resbody, s(:array).line(3),
5284
+ s(:nil).line(4)).line(3)).line(2))
5285
+
5286
+ assert_parse rb, pt
5287
+
5288
+ rb = "def exec(cmd)\n system(cmd) rescue nil\nend\n"
5289
+ assert_parse rb, pt.deep_each { |s| s.line = 2 if s.line && s.line > 1 }
5290
+
5291
+ rb = "def exec(cmd) = system(cmd) rescue nil"
5292
+ assert_parse rb, pt.deep_each { |s| s.line = 1 }
5293
+ end
5294
+
5295
+ def test_defn_oneliner_comment
5296
+ p = RubyParser.new
5297
+ rb = "# blah\ndef exec(cmd) = system(cmd)"
5298
+ sexp = p.parse rb
5299
+
5300
+ assert_equal :defn, sexp.sexp_type
5301
+ assert_equal "# blah\n", sexp.comments
5302
+ end
5303
+
5304
+ def test_defs_oneliner
5305
+ rb = "def self.exec(cmd) = system(cmd)"
5306
+ pt = s(:defs, s(:self), :exec, s(:args, :cmd),
5307
+ s(:call, nil, :system, s(:lvar, :cmd)))
5308
+
5309
+ assert_parse rb, pt
5310
+ end
5311
+
5312
+ def test_defs_oneliner_rescue
5313
+ rb = "def self.exec(cmd)\n system(cmd)\nrescue\n nil\nend\n"
5314
+ pt = s(:defs, s(:self), :exec, s(:args, :cmd),
5315
+ s(:rescue,
5316
+ s(:call, nil, :system, s(:lvar, :cmd).line(2)).line(2),
5317
+ s(:resbody, s(:array).line(3), s(:nil).line(4)).line(3)).line(2))
5318
+ assert_parse rb, pt
5319
+
5320
+ rb = "def self.exec(cmd)\n system(cmd) rescue nil\nend\n"
5321
+ assert_parse rb, pt.deep_each { |s| s.line = 2 if s.line && s.line > 1 }
5322
+
5323
+ rb = "def self.exec(cmd) = system(cmd) rescue nil"
5324
+ assert_parse rb, pt.deep_each { |s| s.line = 1 }
5325
+ end
5326
+
5327
+ def test_defs_oneliner_comment
5328
+ p = RubyParser.new
5329
+ rb = "# blah\ndef self.exec(cmd) = system(cmd)"
5330
+ sexp = p.parse rb
5331
+
5332
+ assert_equal :defs, sexp.sexp_type
5333
+ assert_equal "# blah\n", sexp.comments
5334
+ end
5335
+
5336
+ def test_defn_oneliner_setter
5337
+ rb = "class X\n def x=(o) = 42\nend"
5338
+
5339
+ assert_syntax_error rb, /setter method cannot be defined/
5340
+
5341
+ rb = "class X\n def []=(k, v) = 42\nend"
5342
+
5343
+ assert_syntax_error rb, /setter method cannot be defined/
5344
+ end
5345
+
5346
+ def test_defs_oneliner_setter
5347
+ rb = "class X\n def self.x=(o) = 42\nend"
5348
+
5349
+ assert_syntax_error rb, /setter method cannot be defined/
5350
+
5351
+ rb = "class X\n def self.[]=(k, v) = 42\nend"
5352
+
5353
+ assert_syntax_error rb, /setter method cannot be defined/
5354
+ end
5355
+
5356
+ def test_defn_oneliner_eq2
5357
+ rb = "class X\n def ==(o) = 42\nend"
5358
+ pt = s(:class, :X, nil,
5359
+ s(:defn, :==, s(:args, :o).line(2),
5360
+ s(:lit, 42).line(2)).line(2)
5361
+ ).line(1)
5362
+
5363
+ assert_parse rb, pt
5364
+ end
5365
+
5366
+ def test_defs_oneliner_eq2
5367
+ rb = "class X\n def self.==(o) = 42\nend"
5368
+ pt = s(:class, :X, nil,
5369
+ s(:defs, s(:self).line(2), :==, s(:args, :o).line(2),
5370
+ s(:lit, 42).line(2)).line(2)
5371
+ ).line(1)
5372
+
5373
+ assert_parse rb, pt
5374
+ end
5375
+ end
5376
+
5377
+ module TestRubyParserShared31Plus
5378
+ include TestRubyParserShared30Plus
5379
+
5380
+ def test_assoc__bare
5381
+ rb = "{ y: }"
5382
+ pt = s(:hash, s(:lit, :y), nil)
5383
+
5384
+ assert_parse rb, pt
5385
+ end
5386
+
5387
+ def test_block_arg__bare
5388
+ rb = "def x(&); end"
5389
+ pt = s(:defn, :x, s(:args, :&).line(1),
5390
+ s(:nil).line(1)).line(1)
5391
+
5392
+ assert_parse rb, pt
5393
+ end
5394
+
5395
+ def test_case_in_carat_parens
5396
+ processor.env[:a] = :lvar
5397
+
5398
+ rb = "[^(a)]"
5399
+ pt = s(:array_pat, nil,
5400
+ s(:lvar, :a).line(2)).line(2)
5401
+
5402
+ assert_case_in rb, pt
5403
+ end
5404
+
5405
+ def test_case_in_carat_nonlocal_vars
5406
+ processor.env[:a] = :lvar
5407
+
5408
+ rb = "[^@a, ^$b, ^@@c]"
5409
+ pt = s(:array_pat,
5410
+ nil,
5411
+ s(:ivar, :@a).line(2),
5412
+ s(:gvar, :$b).line(2),
5413
+ s(:cvar, :@@c).line(2)).line(2)
5414
+
5415
+ assert_case_in rb, pt
5416
+ end
5417
+
5418
+ def test_case_in_quoted_label
5419
+ rb = " \"b\": "
5420
+ pt = s(:hash_pat, nil, s(:lit, :b).line(2), nil).line(2)
5421
+
5422
+ assert_case_in rb, pt
5423
+ end
5424
+
5425
+ def test_call_block_arg_named
5426
+ processor.env[:blk] = :lvar
5427
+ rb = "x(&blk)"
5428
+ pt = s(:call, nil, :x,
5429
+ s(:block_pass, s(:lvar, :blk).line(1)).line(1)).line(1)
5430
+
5431
+ assert_parse rb, pt
5432
+ end
5433
+
5434
+ def test_call_block_arg_unnamed
5435
+ rb = "x(&)"
5436
+ pt = s(:call, nil, :x,
5437
+ s(:block_pass).line(1)).line(1)
5438
+
5439
+ assert_parse rb, pt
5440
+ end
5441
+
5442
+ def test_defn_endless_command
5443
+ rb = "def some_method = other_method 42"
5444
+ pt = s(:defn, :some_method, s(:args).line(1),
5445
+ s(:call, nil, :other_method, s(:lit, 42).line(1)).line(1)).line(1)
5446
+
5447
+ assert_parse rb, pt
5448
+ end
5449
+
5450
+ def test_defn_endless_command_rescue
5451
+ rb = "def some_method = other_method 42 rescue 24"
5452
+ pt = s(:defn, :some_method, s(:args).line(1),
5453
+ s(:rescue,
5454
+ s(:call, nil, :other_method, s(:lit, 42).line(1)).line(1),
5455
+ s(:resbody, s(:array).line(1),
5456
+ s(:lit, 24).line(1)).line(1)).line(1)).line(1)
5457
+
5458
+ assert_parse rb, pt
5459
+ end
5460
+
5461
+ def test_defs_endless_command
5462
+ rb = "def x.some_method = other_method 42"
5463
+ pt = s(:defs, s(:call, nil, :x).line(1), :some_method, s(:args).line(1),
5464
+ s(:call, nil, :other_method, s(:lit, 42).line(1)).line(1)).line(1)
5465
+
5466
+ assert_parse rb, pt
5467
+ end
5468
+
5469
+ def test_defs_endless_command_rescue
5470
+ rb = "def x.some_method = other_method 42 rescue 24"
5471
+ pt = s(:defs, s(:call, nil, :x).line(1), :some_method, s(:args).line(1),
5472
+ s(:rescue,
5473
+ s(:call, nil, :other_method, s(:lit, 42).line(1)).line(1),
5474
+ s(:resbody, s(:array).line(1),
5475
+ s(:lit, 24).line(1)).line(1)).line(1)).line(1)
5476
+
5477
+ assert_parse rb, pt
5478
+ end
5479
+ end
5480
+
5481
+ class Minitest::Test
5482
+ def skip s = "blah"
5483
+ warn "ignoring skip for %s: %s" % [name, s]
5484
+ end
5485
+ end if ENV["NOSKIP"]
5486
+
4139
5487
  class TestRubyParser < Minitest::Test
4140
5488
  def test_cls_version
4141
5489
  assert_equal 23, RubyParser::V23.version
@@ -4159,7 +5507,7 @@ class TestRubyParser < Minitest::Test
4159
5507
  end
4160
5508
  end
4161
5509
 
4162
- assert_includes e.message, 'parse error on value false ($end)'
5510
+ assert_includes e.message, 'parse error on value "$" ($end)'
4163
5511
  end
4164
5512
 
4165
5513
  def test_parse_error_from_first
@@ -4172,7 +5520,7 @@ class TestRubyParser < Minitest::Test
4172
5520
  end
4173
5521
 
4174
5522
  # This is a 2.x error, will fail on 1.8/1.9.
4175
- assert_includes e.message, 'parse error on value false ($end)'
5523
+ assert_includes e.message, 'parse error on value "$" ($end)'
4176
5524
  end
4177
5525
  end
4178
5526
 
@@ -4194,8 +5542,24 @@ class RubyParserTestCase < ParseTreeTestCase
4194
5542
  super
4195
5543
  end
4196
5544
 
5545
+ attr_accessor :assert_parse_ran
5546
+
5547
+ require "ruby2ruby" if ENV["R2R"]
5548
+
4197
5549
  def assert_parse rb, pt
4198
- self.result = processor.parse rb
5550
+ self.processor.reset if assert_parse_ran # allows multiple calls
5551
+ self.assert_parse_ran = true
5552
+
5553
+ timeout = (ENV["RP_TIMEOUT"] || 10).to_i
5554
+
5555
+ pt.deep_each { |s| s.line ||= 1 }
5556
+ pt.line ||= 1
5557
+
5558
+ self.result = processor.parse rb, "(string)", timeout
5559
+
5560
+ # just try it for now:
5561
+ Ruby2Ruby.new.process(result.deep_clone) if ENV["R2R"]
5562
+
4199
5563
  assert_equal pt, result
4200
5564
  end
4201
5565
 
@@ -4214,25 +5578,20 @@ class RubyParserTestCase < ParseTreeTestCase
4214
5578
  end
4215
5579
  end
4216
5580
 
4217
- def assert_parse_line rb, pt, line
4218
- old_env = ENV["VERBOSE"]
4219
- ENV["VERBOSE"] = "1"
4220
-
4221
- assert_parse rb, pt
4222
- assert_equal line, result.line, "call should have line number"
4223
- ensure
4224
- ENV["VERBOSE"] = old_env
4225
- end
4226
-
4227
- def assert_syntax_error rb, emsg
5581
+ def assert_syntax_error rb, emsg, klass = RubyParser::SyntaxError
4228
5582
  e = nil
4229
5583
  assert_silent do
4230
- e = assert_raises RubyParser::SyntaxError do
5584
+ e = assert_raises klass do
4231
5585
  processor.parse rb
4232
5586
  end
4233
5587
  end
4234
5588
 
4235
- assert_equal emsg, e.message
5589
+ case emsg
5590
+ when String
5591
+ assert_equal emsg, e.message
5592
+ else
5593
+ assert_match emsg, e.message
5594
+ end
4236
5595
  end
4237
5596
 
4238
5597
  def refute_parse rb
@@ -4249,17 +5608,6 @@ class TestRubyParserV20 < RubyParserTestCase
4249
5608
 
4250
5609
  self.processor = RubyParser::V20.new
4251
5610
  end
4252
-
4253
- def test_bug162__20
4254
- skip "not ready for this yet"
4255
-
4256
- # Ignore everything after \r in heredoc marker in <= 2.0 #162
4257
-
4258
- rb = %q(<<E\nfoo\nE\rO)
4259
- pt = s(:str, "foo\n")
4260
-
4261
- assert_parse rb, pt
4262
- end
4263
5611
  end
4264
5612
 
4265
5613
  class TestRubyParserV21 < RubyParserTestCase
@@ -4318,7 +5666,7 @@ class TestRubyParserV24 < RubyParserTestCase
4318
5666
 
4319
5667
  assert_parse rb, pt
4320
5668
 
4321
- assert_parse_error "a(b rescue c)", /parse error on value ..rescue/
5669
+ assert_parse_error "a(b rescue c)", /parse error on value .rescue/
4322
5670
  end
4323
5671
  end
4324
5672
 
@@ -4335,11 +5683,10 @@ class TestRubyParserV25 < RubyParserTestCase
4335
5683
  rb = "proc do\n :begin\nensure\n :ensure\nend.call"
4336
5684
  pt = s(:call,
4337
5685
  s(:iter,
4338
- s(:call, nil, :proc),
4339
- 0,
5686
+ s(:call, nil, :proc), 0,
4340
5687
  s(:ensure,
4341
- s(:lit, :begin),
4342
- s(:lit, :ensure))),
5688
+ s(:lit, :begin).line(2),
5689
+ s(:lit, :ensure).line(4)).line(2)),
4343
5690
  :call)
4344
5691
 
4345
5692
  assert_parse rb, pt
@@ -4348,16 +5695,14 @@ class TestRubyParserV25 < RubyParserTestCase
4348
5695
  def test_rescue_do_end_no_raise
4349
5696
  rb = "tap do\n :begin\nrescue\n :rescue\nelse\n :else\nensure\n :ensure\nend"
4350
5697
  pt = s(:iter,
4351
- s(:call, nil, :tap),
4352
- 0,
5698
+ s(:call, nil, :tap), 0,
4353
5699
  s(:ensure,
4354
5700
  s(:rescue,
4355
- s(:lit, :begin),
4356
- s(:resbody,
4357
- s(:array),
4358
- s(:lit, :rescue)),
4359
- s(:lit, :else)),
4360
- s(:lit, :ensure)))
5701
+ s(:lit, :begin).line(2),
5702
+ s(:resbody, s(:array).line(3),
5703
+ s(:lit, :rescue).line(4)).line(3),
5704
+ s(:lit, :else).line(6)).line(2),
5705
+ s(:lit, :ensure).line(8)).line(2))
4361
5706
 
4362
5707
  assert_parse rb, pt
4363
5708
  end
@@ -4365,11 +5710,10 @@ class TestRubyParserV25 < RubyParserTestCase
4365
5710
  def test_rescue_do_end_raised
4366
5711
  rb = "tap do\n raise\nensure\n :ensure\nend"
4367
5712
  pt = s(:iter,
4368
- s(:call, nil, :tap),
4369
- 0,
5713
+ s(:call, nil, :tap), 0,
4370
5714
  s(:ensure,
4371
- s(:call, nil, :raise),
4372
- s(:lit, :ensure)))
5715
+ s(:call, nil, :raise).line(2),
5716
+ s(:lit, :ensure).line(4)).line(2))
4373
5717
 
4374
5718
  assert_parse rb, pt
4375
5719
  end
@@ -4381,12 +5725,12 @@ class TestRubyParserV25 < RubyParserTestCase
4381
5725
  0,
4382
5726
  s(:ensure,
4383
5727
  s(:rescue,
4384
- s(:call, nil, :raise),
5728
+ s(:call, nil, :raise).line(2),
4385
5729
  s(:resbody,
4386
- s(:array),
4387
- s(:lit, :rescue)),
4388
- s(:lit, :else)),
4389
- s(:lit, :ensure)))
5730
+ s(:array).line(3),
5731
+ s(:lit, :rescue).line(4)).line(3),
5732
+ s(:lit, :else).line(6)).line(2),
5733
+ s(:lit, :ensure).line(8)).line(2))
4390
5734
 
4391
5735
  assert_parse rb, pt
4392
5736
  end
@@ -4394,9 +5738,11 @@ class TestRubyParserV25 < RubyParserTestCase
4394
5738
  def test_rescue_in_block
4395
5739
  rb = "blah do\nrescue\n stuff\nend"
4396
5740
  pt = s(:iter,
4397
- s(:call, nil, :blah),
4398
- 0,
4399
- s(:rescue, s(:resbody, s(:array), s(:call, nil, :stuff))))
5741
+ s(:call, nil, :blah), 0,
5742
+ s(:rescue,
5743
+ s(:resbody, s(:array).line(2),
5744
+ s(:call, nil, :stuff).line(3)).line(2)).line(2))
5745
+
4400
5746
  assert_parse rb, pt
4401
5747
  end
4402
5748
  end
@@ -4413,26 +5759,27 @@ class TestRubyParserV26 < RubyParserTestCase
4413
5759
  def test_parse_line_dot2_open
4414
5760
  rb = "0..\n; a..\n; c"
4415
5761
  pt = s(:block,
4416
- s(:dot2, s(:lit, 0).line(1), nil).line(1),
5762
+ s(:dot2, s(:lit, 0), nil),
4417
5763
  s(:dot2, s(:call, nil, :a).line(2), nil).line(2),
4418
- s(:call, nil, :c).line(3)).line(1)
5764
+ s(:call, nil, :c).line(3))
4419
5765
 
4420
- assert_parse_line rb, pt, 1
5766
+ assert_parse rb, pt
4421
5767
  end
4422
5768
 
4423
5769
  def test_parse_line_dot3_open
4424
5770
  rb = "0...\n; a...\n; c"
4425
5771
  pt = s(:block,
4426
- s(:dot3, s(:lit, 0).line(1), nil).line(1),
5772
+ s(:dot3, s(:lit, 0), nil),
4427
5773
  s(:dot3, s(:call, nil, :a).line(2), nil).line(2),
4428
- s(:call, nil, :c).line(3)).line(1)
5774
+ s(:call, nil, :c).line(3))
4429
5775
 
4430
- assert_parse_line rb, pt, 1
5776
+ assert_parse rb, pt
4431
5777
  end
4432
-
4433
5778
  end
4434
5779
 
4435
5780
  class TestRubyParserV27 < RubyParserTestCase
5781
+ make_my_diffs_pretty!
5782
+
4436
5783
  include TestRubyParserShared27Plus
4437
5784
 
4438
5785
  def setup
@@ -4440,8 +5787,47 @@ class TestRubyParserV27 < RubyParserTestCase
4440
5787
 
4441
5788
  self.processor = RubyParser::V27.new
4442
5789
  end
5790
+
5791
+ def test_bdot2
5792
+ rb = "..10\n; ..a\n; c"
5793
+ pt = s(:block,
5794
+ s(:dot2, nil, s(:lit, 10)),
5795
+ s(:dot2, nil, s(:call, nil, :a).line(2)).line(2),
5796
+ s(:call, nil, :c).line(3))
5797
+
5798
+ assert_parse rb, pt
5799
+ end
5800
+
5801
+ def test_bdot3
5802
+ rb = "...10\n; ...a\n; c"
5803
+ pt = s(:block,
5804
+ s(:dot3, nil, s(:lit, 10)),
5805
+ s(:dot3, nil, s(:call, nil, :a).line(2)).line(2),
5806
+ s(:call, nil, :c).line(3))
5807
+
5808
+ assert_parse rb, pt
5809
+ end
4443
5810
  end
4444
5811
 
5812
+ class TestRubyParserV30 < RubyParserTestCase
5813
+ include TestRubyParserShared30Plus
5814
+
5815
+ def setup
5816
+ super
5817
+
5818
+ self.processor = RubyParser::V30.new
5819
+ end
5820
+ end
5821
+
5822
+ class TestRubyParserV31 < RubyParserTestCase
5823
+ include TestRubyParserShared31Plus
5824
+
5825
+ def setup
5826
+ super
5827
+
5828
+ self.processor = RubyParser::V31.new
5829
+ end
5830
+ end
4445
5831
 
4446
5832
  RubyParser::VERSIONS.each do |klass|
4447
5833
  v = klass.version