ruby_parser 3.17.0 → 3.19.0

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 (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +109 -0
  4. data/Manifest.txt +5 -0
  5. data/README.rdoc +9 -6
  6. data/Rakefile +85 -24
  7. data/bin/ruby_parse_extract_error +1 -1
  8. data/compare/normalize.rb +6 -1
  9. data/gauntlet.md +108 -0
  10. data/lib/rp_extensions.rb +15 -36
  11. data/lib/rp_stringscanner.rb +20 -51
  12. data/lib/ruby20_parser.rb +7430 -3528
  13. data/lib/ruby20_parser.y +328 -257
  14. data/lib/ruby21_parser.rb +7408 -3572
  15. data/lib/ruby21_parser.y +323 -254
  16. data/lib/ruby22_parser.rb +7543 -3601
  17. data/lib/ruby22_parser.y +327 -256
  18. data/lib/ruby23_parser.rb +7549 -3612
  19. data/lib/ruby23_parser.y +327 -256
  20. data/lib/ruby24_parser.rb +7640 -3624
  21. data/lib/ruby24_parser.y +327 -256
  22. data/lib/ruby25_parser.rb +7640 -3623
  23. data/lib/ruby25_parser.y +327 -256
  24. data/lib/ruby26_parser.rb +7649 -3632
  25. data/lib/ruby26_parser.y +326 -255
  26. data/lib/ruby27_parser.rb +10132 -4545
  27. data/lib/ruby27_parser.y +871 -262
  28. data/lib/ruby30_parser.rb +10504 -4655
  29. data/lib/ruby30_parser.y +1065 -333
  30. data/lib/ruby31_parser.rb +13622 -0
  31. data/lib/ruby31_parser.y +3481 -0
  32. data/lib/ruby3_parser.yy +3536 -0
  33. data/lib/ruby_lexer.rb +261 -609
  34. data/lib/ruby_lexer.rex +27 -20
  35. data/lib/ruby_lexer.rex.rb +59 -23
  36. data/lib/ruby_lexer_strings.rb +638 -0
  37. data/lib/ruby_parser.rb +2 -0
  38. data/lib/ruby_parser.yy +903 -272
  39. data/lib/ruby_parser_extras.rb +333 -113
  40. data/test/test_ruby_lexer.rb +181 -129
  41. data/test/test_ruby_parser.rb +1529 -288
  42. data/tools/munge.rb +34 -6
  43. data/tools/ripper.rb +15 -10
  44. data.tar.gz.sig +0 -0
  45. metadata +27 -23
  46. 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
@@ -824,7 +833,7 @@ module TestRubyParserShared
824
833
  def test_eq_begin_line_numbers
825
834
  rb = "1\n=begin\ncomment\ncomment\n=end\n2"
826
835
  pt = s(:block,
827
- s(:lit, 1).line(1),
836
+ s(:lit, 1),
828
837
  s(:lit, 2).line(6))
829
838
 
830
839
  assert_parse rb, pt
@@ -832,7 +841,9 @@ module TestRubyParserShared
832
841
 
833
842
  def test_eq_begin_why_wont_people_use_their_spacebar?
834
843
  rb = "h[k]=begin\n 42\n end"
835
- pt = s(:attrasgn, s(:call, nil, :h), :[]=, s(:call, nil, :k), s(:lit, 42))
844
+ pt = s(:attrasgn,
845
+ s(:call, nil, :h), :[]=, s(:call, nil, :k),
846
+ s(:lit, 42).line(2))
836
847
 
837
848
  assert_parse rb, pt
838
849
  end
@@ -881,6 +892,29 @@ module TestRubyParserShared
881
892
  assert_parse rb, pt
882
893
  end
883
894
 
895
+ def test_heredoc_lineno
896
+ rb = "c = <<'CCC'\nline2\nline3\nline4\nCCC\n\nd = 42"
897
+ pt = s(:block,
898
+ s(:lasgn, :c, s(:str, "line2\nline3\nline4\n")),
899
+ s(:lasgn, :d, s(:lit, 42).line(7)).line(7))
900
+
901
+ assert_parse rb, pt
902
+ end
903
+
904
+ def test_pctW_lineno
905
+ rb = "%W(a\\nb\nc\ d\ne\\\nf\ng\y h\\y i\\\y)"
906
+ pt = s(:array,
907
+ s(:str, "a\nb"),
908
+ s(:str, "c").line(2),
909
+ s(:str, "d").line(2),
910
+ s(:str, "e\nf").line(3),
911
+ s(:str, "gy").line(5),
912
+ s(:str, "hy").line(5),
913
+ s(:str, "iy").line(5))
914
+
915
+ assert_parse rb, pt
916
+ end
917
+
884
918
  def test_heredoc_bad_oct_escape
885
919
  rb = "s = <<-EOS\na\\247b\ncöd\nEOS\n"
886
920
  pt = s(:lasgn, :s, s(:str, "a\xa7b\nc\xc3\xb6d\n".b))
@@ -932,14 +966,17 @@ module TestRubyParserShared
932
966
 
933
967
  def test_heredoc_with_interpolation_and_carriage_return_escapes
934
968
  rb = "<<EOS\nfoo\\r\#@bar\nEOS\n"
935
- pt = s(:dstr, "foo\r", s(:evstr, s(:ivar, :@bar)), s(:str, "\n"))
969
+ pt = s(:dstr, "foo\r", s(:evstr, s(:ivar, :@bar).line(2)).line(2), s(:str, "\n").line(2))
936
970
 
937
971
  assert_parse rb, pt
938
972
  end
939
973
 
940
974
  def test_heredoc_with_interpolation_and_carriage_return_escapes_windows
941
975
  rb = "<<EOS\r\nfoo\\r\#@bar\r\nEOS\r\n"
942
- pt = s(:dstr, "foo\r", s(:evstr, s(:ivar, :@bar)), s(:str, "\n"))
976
+ pt = s(:dstr,
977
+ "foo\r",
978
+ s(:evstr, s(:ivar, :@bar).line(2)).line(2),
979
+ s(:str, "\n").line(2))
943
980
 
944
981
  assert_parse rb, pt
945
982
  end
@@ -981,7 +1018,7 @@ module TestRubyParserShared
981
1018
  end
982
1019
  END
983
1020
 
984
- pt = s(:if, s(:true).line(1),
1021
+ pt = s(:if, s(:true),
985
1022
  s(:block,
986
1023
  s(:call, nil, :p, s(:lit, 1).line(2)).line(2),
987
1024
  s(:call, s(:call, nil, :a).line(3), :b,
@@ -1001,7 +1038,7 @@ module TestRubyParserShared
1001
1038
  s(:lit, 5).line(10)).line(10),
1002
1039
  s(:call, s(:call, nil, :g).line(11), :h,
1003
1040
  s(:lit, 6).line(11), s(:lit, 7).line(11)).line(11)).line(2),
1004
- nil).line(1)
1041
+ nil)
1005
1042
 
1006
1043
  assert_parse rb, pt
1007
1044
  end
@@ -1018,14 +1055,14 @@ module TestRubyParserShared
1018
1055
  EOM
1019
1056
 
1020
1057
  pt = s(:block,
1021
- s(:if, s(:true).line(1),
1058
+ s(:if, s(:true),
1022
1059
  s(:block,
1023
1060
  s(:call, nil, :p, s(:str, "a").line(2)).line(2),
1024
1061
  s(:lasgn, :b, s(:lit, 1).line(3)).line(3),
1025
1062
  s(:call, nil, :p, s(:lvar, :b).line(4)).line(4),
1026
1063
  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)
1064
+ nil),
1065
+ s(:call, nil, :a).line(7))
1029
1066
 
1030
1067
  assert_parse rb, pt
1031
1068
  end
@@ -1056,7 +1093,7 @@ module TestRubyParserShared
1056
1093
  pt = s(:block,
1057
1094
  s(:array,
1058
1095
  s(:str, "a").line(2),
1059
- s(:str, "b").line(3)).line(1),
1096
+ s(:str, "b").line(3)),
1060
1097
  s(:lit, 1).line(5))
1061
1098
  assert_parse rb, pt
1062
1099
  end
@@ -1217,14 +1254,14 @@ module TestRubyParserShared
1217
1254
  def test_logical_op_12
1218
1255
  lhs = s(:lit, 1).line 1
1219
1256
  rhs = s(:lit, 2).line 2
1220
- exp = s(:and, s(:lit, 1).line(1), s(:lit, 2).line(2)).line 1
1257
+ exp = s(:and, s(:lit, 1), s(:lit, 2).line(2)).line 1
1221
1258
 
1222
1259
  assert_equal exp, processor.logical_op(:and, lhs, rhs)
1223
1260
  end
1224
1261
 
1225
1262
  def test_logical_op_1234_5
1226
1263
  lhs = s(:and,
1227
- s(:lit, 1).line(1),
1264
+ s(:lit, 1),
1228
1265
  s(:and,
1229
1266
  s(:lit, 2).line(2),
1230
1267
  s(:and,
@@ -1232,7 +1269,7 @@ module TestRubyParserShared
1232
1269
  s(:lit, 4).line(4)).line(3)).line(2)).line 1
1233
1270
  rhs = s(:lit, 5).line(5)
1234
1271
  exp = s(:and,
1235
- s(:lit, 1).line(1),
1272
+ s(:lit, 1),
1236
1273
  s(:and,
1237
1274
  s(:lit, 2).line(2),
1238
1275
  s(:and,
@@ -1246,13 +1283,13 @@ module TestRubyParserShared
1246
1283
 
1247
1284
  def test_logical_op_123_4
1248
1285
  lhs = s(:and,
1249
- s(:lit, 1).line(1),
1286
+ s(:lit, 1),
1250
1287
  s(:and,
1251
1288
  s(:lit, 2).line(2),
1252
1289
  s(:lit, 3).line(3)).line(2)).line 1
1253
1290
  rhs = s(:lit, 4).line 4
1254
1291
  exp = s(:and,
1255
- s(:lit, 1).line(1),
1292
+ s(:lit, 1),
1256
1293
  s(:and,
1257
1294
  s(:lit, 2).line(2),
1258
1295
  s(:and,
@@ -1264,11 +1301,11 @@ module TestRubyParserShared
1264
1301
 
1265
1302
  def test_logical_op_12_3
1266
1303
  lhs = s(:and,
1267
- s(:lit, 1).line(1),
1304
+ s(:lit, 1),
1268
1305
  s(:lit, 2).line(2)).line 1
1269
1306
  rhs = s(:lit, 3).line 3
1270
1307
  exp = s(:and,
1271
- s(:lit, 1).line(1),
1308
+ s(:lit, 1),
1272
1309
  s(:and,
1273
1310
  s(:lit, 2).line(2),
1274
1311
  s(:lit, 3).line(3)).line(2)).line 1
@@ -1278,15 +1315,15 @@ module TestRubyParserShared
1278
1315
 
1279
1316
  def test_logical_op_nested_mix
1280
1317
  lhs = s(:or,
1281
- s(:call, nil, :a).line(1),
1318
+ s(:call, nil, :a),
1282
1319
  s(:call, nil, :b).line(2)).line 1
1283
1320
  rhs = s(:and,
1284
1321
  s(:call, nil, :c).line(3),
1285
1322
  s(:call, nil, :d).line(4)).line 3
1286
1323
  exp = s(:or,
1287
1324
  s(:or,
1288
- s(:call, nil, :a).line(1),
1289
- s(:call, nil, :b).line(2)).line(1),
1325
+ s(:call, nil, :a),
1326
+ s(:call, nil, :b).line(2)),
1290
1327
  s(:and,
1291
1328
  s(:call, nil, :c).line(3),
1292
1329
  s(:call, nil, :d).line(4)).line(3)).line 1
@@ -1307,8 +1344,8 @@ module TestRubyParserShared
1307
1344
  # TODO: globals
1308
1345
 
1309
1346
  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"))))
1347
+ s(:defs, s(:self).line(2), :"\303\250", s(:args).line(2),
1348
+ s(:lasgn, :"cos\303\254", s(:lit, :"per\303\262").line(2)).line(2)).line(2)).line(2)
1312
1349
 
1313
1350
  err = RUBY_VERSION =~ /^1\.8/ ? "Skipping magic encoding comment\n" : ""
1314
1351
 
@@ -1319,14 +1356,14 @@ module TestRubyParserShared
1319
1356
 
1320
1357
  def test_magic_encoding_comment__bad
1321
1358
  rb = "#encoding: bunk\n0"
1322
- pt = s(:lit, 0)
1359
+ pt = s(:lit, 0).line(2)
1323
1360
 
1324
1361
  assert_parse rb, pt
1325
1362
  end
1326
1363
 
1327
1364
  def test_utf8_bom
1328
1365
  rb = "\xEF\xBB\xBF#!/usr/bin/env ruby -w\np 0\n"
1329
- pt = s(:call, nil, :p, s(:lit, 0))
1366
+ pt = s(:call, nil, :p, s(:lit, 0).line(2)).line(2)
1330
1367
 
1331
1368
  assert_parse rb, pt
1332
1369
  end
@@ -1335,12 +1372,12 @@ module TestRubyParserShared
1335
1372
  rb = "a, b::c = d"
1336
1373
  pt = s(:masgn,
1337
1374
  s(:array,
1338
- s(:lasgn, :a).line(1),
1375
+ s(:lasgn, :a),
1339
1376
  s(:attrasgn,
1340
- s(:call, nil, :b).line(1),
1341
- :c=).line(1)).line(1),
1377
+ s(:call, nil, :b),
1378
+ :c=)),
1342
1379
  s(:to_ary,
1343
- s(:call, nil, :d).line(1)).line(1)).line(1)
1380
+ s(:call, nil, :d)))
1344
1381
 
1345
1382
  assert_parse rb, pt
1346
1383
  end
@@ -1420,7 +1457,7 @@ module TestRubyParserShared
1420
1457
  def test_module_comments
1421
1458
  rb = "# blah 1\n \n # blah 2\n\nmodule X\n # blah 3\n def blah\n # blah 4\n end\nend"
1422
1459
  pt = s(:module, :X,
1423
- s(:defn, :blah, s(:args), s(:nil)))
1460
+ s(:defn, :blah, s(:args).line(7), s(:nil).line(7)).line(7)).line(5)
1424
1461
 
1425
1462
  assert_parse rb, pt
1426
1463
  assert_equal "# blah 1\n\n# blah 2\n\n", result.comments
@@ -1432,7 +1469,7 @@ module TestRubyParserShared
1432
1469
  pt = s(:block,
1433
1470
  s(:array,
1434
1471
  s(:str, "a").line(2),
1435
- s(:str, "b").line(3)).line(1),
1472
+ s(:str, "b").line(3)),
1436
1473
  s(:lit, 1).line(5))
1437
1474
  assert_parse rb, pt
1438
1475
  end
@@ -1557,17 +1594,11 @@ module TestRubyParserShared
1557
1594
  rb = "a = 42\np a"
1558
1595
  pt = s(:block,
1559
1596
  s(:lasgn, :a, s(:lit, 42)),
1560
- s(:call, nil, :p, s(:lvar, :a)))
1597
+ s(:call, nil, :p, s(:lvar, :a).line(2)).line(2))
1561
1598
 
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
1599
+ assert_parse rb, pt
1570
1600
 
1601
+ assert_equal "(string)", result.file
1571
1602
  assert_same result.file, result.lasgn.file
1572
1603
  assert_same result.file, result.call.file
1573
1604
  end
@@ -1575,7 +1606,7 @@ module TestRubyParserShared
1575
1606
  def test_parse_line_block_inline_comment
1576
1607
  rb = "a\nb # comment\nc"
1577
1608
  pt = s(:block,
1578
- s(:call, nil, :a).line(1),
1609
+ s(:call, nil, :a),
1579
1610
  s(:call, nil, :b).line(2),
1580
1611
  s(:call, nil, :c).line(3))
1581
1612
 
@@ -1595,23 +1626,23 @@ module TestRubyParserShared
1595
1626
  def test_parse_line_block_inline_multiline_comment
1596
1627
  rb = "a\nb # comment\n# another comment\nc"
1597
1628
  pt = s(:block,
1598
- s(:call, nil, :a).line(1),
1629
+ s(:call, nil, :a),
1599
1630
  s(:call, nil, :b).line(2),
1600
- s(:call, nil, :c).line(4)).line(1)
1631
+ s(:call, nil, :c).line(4))
1601
1632
 
1602
1633
  assert_parse rb, pt
1603
1634
  end
1604
1635
 
1605
1636
  def test_parse_line_call_ivar_arg_no_parens_line_break
1606
1637
  rb = "a @b\n"
1607
- pt = s(:call, nil, :a, s(:ivar, :@b).line(1)).line(1)
1638
+ pt = s(:call, nil, :a, s(:ivar, :@b))
1608
1639
 
1609
1640
  assert_parse rb, pt
1610
1641
  end
1611
1642
 
1612
1643
  def test_parse_line_call_ivar_line_break_paren
1613
1644
  rb = "a(@b\n)"
1614
- pt = s(:call, nil, :a, s(:ivar, :@b).line(1)).line(1)
1645
+ pt = s(:call, nil, :a, s(:ivar, :@b))
1615
1646
 
1616
1647
  assert_parse rb, pt
1617
1648
  end
@@ -1622,9 +1653,9 @@ module TestRubyParserShared
1622
1653
  pt = s(:iter,
1623
1654
  s(:call, nil, :f),
1624
1655
  s(:args, :x, :y),
1625
- s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
1656
+ s(:call, s(:lvar, :x).line(2), :+, s(:lvar, :y).line(2)).line(2))
1626
1657
 
1627
- assert_parse_line rb, pt, 1
1658
+ assert_parse rb, pt
1628
1659
 
1629
1660
  _, a, b, c, = result
1630
1661
 
@@ -1635,19 +1666,19 @@ module TestRubyParserShared
1635
1666
 
1636
1667
  def test_parse_line_defn_no_parens_args
1637
1668
  rb = "def f a\nend"
1638
- pt = s(:defn, :f, s(:args, :a).line(1), s(:nil).line(2)).line(1)
1669
+ pt = s(:defn, :f, s(:args, :a), s(:nil))
1639
1670
 
1640
- assert_parse_line rb, pt, 1
1671
+ assert_parse rb, pt
1641
1672
  end
1642
1673
 
1643
1674
  def test_parse_line_defn_complex
1644
1675
  rb = "def x(y)\n p(y)\n y *= 2\n return y;\nend" # TODO: remove () & ;
1645
1676
  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)))
1677
+ s(:call, nil, :p, s(:lvar, :y).line(2)).line(2),
1678
+ s(:lasgn, :y, s(:call, s(:lvar, :y).line(3), :*, s(:lit, 2).line(3)).line(3)).line(3),
1679
+ s(:return, s(:lvar, :y).line(4)).line(4))
1649
1680
 
1650
- assert_parse_line rb, pt, 1
1681
+ assert_parse rb, pt
1651
1682
 
1652
1683
  body = result
1653
1684
  assert_equal 2, body.call.line, "call should have line number"
@@ -1656,61 +1687,65 @@ module TestRubyParserShared
1656
1687
  end
1657
1688
 
1658
1689
  def test_parse_line_defn_no_parens
1659
- pt = s(:defn, :f, s(:args).line(1), s(:nil)).line(1)
1690
+ pt = s(:defn, :f, s(:args), s(:nil))
1660
1691
 
1661
1692
  rb = "def f\nend"
1662
- assert_parse_line rb, pt, 1
1693
+ assert_parse rb, pt
1663
1694
 
1664
1695
  processor.reset
1665
1696
 
1666
1697
  rb = "def f\n\nend"
1667
- assert_parse_line rb, pt, 1
1698
+ assert_parse rb, pt
1668
1699
  end
1669
1700
 
1670
1701
  def test_parse_line_dot2
1671
1702
  rb = "0..\n4\na..\nb\nc"
1672
1703
  pt = s(:block,
1673
- s(:lit, 0..4).line(1),
1704
+ s(:lit, 0..4),
1674
1705
  s(:dot2,
1675
1706
  s(:call, nil, :a).line(3),
1676
1707
  s(:call, nil, :b).line(4)).line(3),
1677
- s(:call, nil, :c).line(5)).line(1)
1708
+ s(:call, nil, :c).line(5))
1678
1709
 
1679
- assert_parse_line rb, pt, 1
1710
+ assert_parse rb, pt
1680
1711
  end
1681
1712
 
1682
1713
  def test_parse_line_dot3
1683
1714
  rb = "0...\n4\na...\nb\nc"
1684
1715
  pt = s(:block,
1685
- s(:lit, 0...4).line(1),
1716
+ s(:lit, 0...4),
1686
1717
  s(:dot3,
1687
1718
  s(:call, nil, :a).line(3),
1688
1719
  s(:call, nil, :b).line(4)).line(3),
1689
- s(:call, nil, :c).line(5)).line(1)
1720
+ s(:call, nil, :c).line(5))
1690
1721
 
1691
- assert_parse_line rb, pt, 1
1722
+ assert_parse rb, pt
1692
1723
  end
1693
1724
 
1694
- def test_parse_line_dstr_newline
1695
- rb = <<-'CODE'
1696
- "a\n#{
1697
- }"
1698
- true
1699
- CODE
1700
-
1725
+ def test_parse_line_dstr_escaped_newline
1726
+ rb = "\"a\\n\#{\n}\"\ntrue"
1701
1727
  pt = s(:block,
1702
1728
  s(:dstr, "a\n",
1703
- s(:evstr)).line(1),
1729
+ s(:evstr)),
1704
1730
  s(:true).line(3))
1705
1731
 
1706
1732
  assert_parse rb, pt
1707
1733
  end
1708
1734
 
1735
+ def test_parse_line_dstr_soft_newline
1736
+ rb = "\"a\n#\{\n}\"\ntrue"
1737
+ pt = s(:block,
1738
+ s(:dstr, "a\n", s(:evstr).line(2)),
1739
+ s(:true).line(4))
1740
+
1741
+ assert_parse rb, pt
1742
+ end
1743
+
1709
1744
  def test_parse_line_evstr_after_break
1710
1745
  rb = "\"a\"\\\n\"\#{b}\""
1711
1746
  pt = s(:dstr, "a",
1712
1747
  s(:evstr,
1713
- s(:call, nil, :b).line(2)).line(2)).line(1)
1748
+ s(:call, nil, :b).line(2)).line(2))
1714
1749
 
1715
1750
  assert_parse rb, pt
1716
1751
  end
@@ -1719,14 +1754,14 @@ module TestRubyParserShared
1719
1754
  rb = "{\n:s1 => 1,\n}"
1720
1755
  pt = s(:hash,
1721
1756
  s(:lit, :s1).line(2), s(:lit, 1).line(2),
1722
- ).line(1)
1757
+ )
1723
1758
 
1724
1759
  assert_parse rb, pt
1725
1760
  end
1726
1761
 
1727
1762
  def test_parse_line_heredoc
1728
1763
  rb = <<-CODE
1729
- string = <<-HEREDOC
1764
+ string = <<-HEREDOC.strip
1730
1765
  very long string
1731
1766
  HEREDOC
1732
1767
  puts string
@@ -1734,20 +1769,23 @@ module TestRubyParserShared
1734
1769
 
1735
1770
  pt = s(:block,
1736
1771
  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)
1772
+ s(:call,
1773
+ s(:str, " very long string\n"),
1774
+ :strip),
1775
+ ),
1776
+ s(:call, nil, :puts,
1777
+ s(:lvar, :string).line(4)).line(4)
1778
+ )
1739
1779
 
1740
1780
  assert_parse rb, pt
1741
1781
  end
1742
1782
 
1743
1783
  def test_parse_line_heredoc_evstr
1744
- skip "heredoc line numbers are just gonna be screwed for a while..."
1745
-
1746
1784
  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)
1785
+ pt = s(:dstr,
1786
+ "a\n",
1787
+ s(:evstr, s(:call, nil, :b).line(3)).line(3), s(:str, "\n").line(3)
1788
+ )
1751
1789
 
1752
1790
  assert_parse rb, pt
1753
1791
  end
@@ -1762,8 +1800,8 @@ module TestRubyParserShared
1762
1800
 
1763
1801
  pt = s(:block,
1764
1802
  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)
1803
+ s(:str, " very long string\n")),
1804
+ s(:call, nil, :puts, s(:lvar, :string).line(4)).line(4))
1767
1805
 
1768
1806
  assert_parse rb, pt
1769
1807
  end
@@ -1772,10 +1810,10 @@ module TestRubyParserShared
1772
1810
  rb = "f a do |x, y|\n x + y\nend"
1773
1811
 
1774
1812
  pt = s(:iter,
1775
- s(:call, nil, :f, s(:call, nil, :a).line(1)).line(1),
1776
- s(:args, :x, :y).line(1),
1813
+ s(:call, nil, :f, s(:call, nil, :a)),
1814
+ s(:args, :x, :y),
1777
1815
  s(:call, s(:lvar, :x).line(2), :+,
1778
- s(:lvar, :y).line(2)).line(2)).line(1)
1816
+ s(:lvar, :y).line(2)).line(2))
1779
1817
 
1780
1818
  assert_parse rb, pt
1781
1819
  end
@@ -1786,9 +1824,9 @@ module TestRubyParserShared
1786
1824
  pt = s(:iter,
1787
1825
  s(:call, nil, :f, s(:call, nil, :a)),
1788
1826
  s(:args, :x, :y),
1789
- s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
1827
+ s(:call, s(:lvar, :x).line(2), :+, s(:lvar, :y).line(2)).line(2))
1790
1828
 
1791
- assert_parse_line rb, pt, 1
1829
+ assert_parse rb, pt
1792
1830
 
1793
1831
  _, a, b, c, = result
1794
1832
 
@@ -1800,8 +1838,8 @@ module TestRubyParserShared
1800
1838
  def test_parse_line_multiline_str
1801
1839
  rb = "\"a\nb\"\n1"
1802
1840
  pt = s(:block,
1803
- s(:str, "a\nb").line(1),
1804
- s(:lit, 1).line(3)).line(1)
1841
+ s(:str, "a\nb"),
1842
+ s(:lit, 1).line(3))
1805
1843
 
1806
1844
  assert_parse rb, pt
1807
1845
  end
@@ -1809,8 +1847,8 @@ module TestRubyParserShared
1809
1847
  def test_parse_line_multiline_str_literal_n
1810
1848
  rb = "\"a\\nb\"\n1"
1811
1849
  pt = s(:block,
1812
- s(:str, "a\nb").line(1),
1813
- s(:lit, 1).line(2)).line(1)
1850
+ s(:str, "a\nb"),
1851
+ s(:lit, 1).line(2))
1814
1852
 
1815
1853
  assert_parse rb, pt
1816
1854
  end
@@ -1819,7 +1857,7 @@ module TestRubyParserShared
1819
1857
  rb = "true\n\n"
1820
1858
  pt = s(:true)
1821
1859
 
1822
- assert_parse_line rb, pt, 1
1860
+ assert_parse rb, pt
1823
1861
  end
1824
1862
 
1825
1863
  def test_parse_line_op_asgn
@@ -1832,30 +1870,30 @@ module TestRubyParserShared
1832
1870
  pt = s(:block,
1833
1871
  s(:lasgn, :foo,
1834
1872
  s(:call,
1835
- s(:lvar, :foo).line(1),
1873
+ s(:lvar, :foo),
1836
1874
  :+,
1837
- s(:call, nil, :bar).line(2)).line(1)).line(1),
1838
- s(:call, nil, :baz).line(3)).line(1)
1875
+ s(:call, nil, :bar).line(2))),
1876
+ s(:call, nil, :baz).line(3))
1839
1877
 
1840
- assert_parse_line rb, pt, 1
1878
+ assert_parse rb, pt
1841
1879
  end
1842
1880
 
1843
1881
  def test_parse_line_postexe
1844
1882
  rb = "END {\nfoo\n}"
1845
1883
  pt = s(:iter,
1846
- s(:postexe).line(1), 0,
1847
- s(:call, nil, :foo).line(2)).line(1)
1884
+ s(:postexe), 0,
1885
+ s(:call, nil, :foo).line(2))
1848
1886
 
1849
- assert_parse_line rb, pt, 1
1887
+ assert_parse rb, pt
1850
1888
  end
1851
1889
 
1852
1890
  def test_parse_line_preexe
1853
1891
  rb = "BEGIN {\nfoo\n}"
1854
1892
  pt = s(:iter,
1855
- s(:preexe).line(1), 0,
1856
- s(:call, nil, :foo).line(2)).line(1)
1893
+ s(:preexe), 0,
1894
+ s(:call, nil, :foo).line(2))
1857
1895
 
1858
- assert_parse_line rb, pt, 1
1896
+ assert_parse rb, pt
1859
1897
  end
1860
1898
 
1861
1899
  def test_parse_line_rescue
@@ -1867,7 +1905,7 @@ module TestRubyParserShared
1867
1905
  s(:resbody, s(:array).line(5),
1868
1906
  s(:call, nil, :c).line(6)).line(5)).line(2)
1869
1907
 
1870
- assert_parse_line rb, pt, 2
1908
+ assert_parse rb, pt
1871
1909
  end
1872
1910
 
1873
1911
  def test_parse_line_return
@@ -1880,11 +1918,11 @@ module TestRubyParserShared
1880
1918
  RUBY
1881
1919
 
1882
1920
  pt = s(:defn, :blah, s(:args),
1883
- s(:if, s(:true),
1884
- s(:return, s(:lit, 42)),
1885
- nil))
1921
+ s(:if, s(:true).line(2),
1922
+ s(:return, s(:lit, 42).line(3)).line(3),
1923
+ nil).line(2))
1886
1924
 
1887
- assert_parse_line rb, pt, 1
1925
+ assert_parse rb, pt
1888
1926
 
1889
1927
  assert_equal 3, result.if.return.line
1890
1928
  assert_equal 3, result.if.return.lit.line
@@ -1893,8 +1931,8 @@ module TestRubyParserShared
1893
1931
  def test_parse_line_str_with_newline_escape
1894
1932
  rb = 'a("\n", true)'
1895
1933
  pt = s(:call, nil, :a,
1896
- s(:str, "\n").line(1),
1897
- s(:true).line(1))
1934
+ s(:str, "\n"),
1935
+ s(:true))
1898
1936
 
1899
1937
  assert_parse rb, pt
1900
1938
  end
@@ -1903,18 +1941,18 @@ module TestRubyParserShared
1903
1941
  rb = "a,\nb = c\nd"
1904
1942
  pt = s(:block,
1905
1943
  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)
1944
+ s(:array, s(:lasgn, :a), s(:lasgn, :b).line(2)),
1945
+ s(:to_ary, s(:call, nil, :c).line(2)).line(2)),
1946
+ s(:call, nil, :d).line(3))
1909
1947
 
1910
- assert_parse_line rb, pt, 1
1948
+ assert_parse rb, pt
1911
1949
  end
1912
1950
 
1913
1951
  def test_parse_line_trailing_newlines
1914
1952
  rb = "a \nb"
1915
1953
  pt = s(:block,
1916
- s(:call, nil, :a).line(1),
1917
- s(:call, nil, :b).line(2)).line(1)
1954
+ s(:call, nil, :a),
1955
+ s(:call, nil, :b).line(2))
1918
1956
 
1919
1957
  assert_parse rb, pt
1920
1958
  end
@@ -2026,7 +2064,9 @@ module TestRubyParserShared
2026
2064
 
2027
2065
  def test_str_heredoc_interp
2028
2066
  rb = "<<\"\"\n\#{x}\nblah2\n\n"
2029
- pt = s(:dstr, "", s(:evstr, s(:call, nil, :x)), s(:str, "\nblah2\n"))
2067
+ pt = s(:dstr, "",
2068
+ s(:evstr, s(:call, nil, :x).line(2)).line(2),
2069
+ s(:str, "\nblah2\n").line(2))
2030
2070
 
2031
2071
  assert_parse rb, pt
2032
2072
  end
@@ -2049,19 +2089,19 @@ module TestRubyParserShared
2049
2089
 
2050
2090
  def test_str_newline_hash_line_number
2051
2091
  rb = "\"\\n\\n\\n\\n#\"\n1"
2052
- pt = s(:block, s(:str, "\n\n\n\n#").line(1),
2092
+ pt = s(:block, s(:str, "\n\n\n\n#"),
2053
2093
  s(:lit, 1).line(2))
2054
2094
 
2055
2095
  assert_parse rb, pt
2056
2096
  end
2057
2097
 
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
2098
+ def test_str_pct_nested_nested
2099
+ rb = "%{ { #\{ \"#\{1}\" } } }"
2100
+ assert_equal " { 1 } ", eval(rb)
2101
+ pt = s(:dstr, " { ", s(:evstr, s(:lit, 1)), s(:str, " } "))
2102
+
2103
+ assert_parse rb, pt
2104
+ end
2065
2105
 
2066
2106
  def test_str_pct_Q_nested
2067
2107
  rb = "%Q[before [#\{nest}] after]"
@@ -2077,6 +2117,60 @@ module TestRubyParserShared
2077
2117
  assert_parse rb, pt
2078
2118
  end
2079
2119
 
2120
+ def test_str_single_newline
2121
+ rp = "a '\n';b"
2122
+ pt = s(:block,
2123
+ s(:call, nil, :a, s(:str, "\n")),
2124
+ s(:call, nil, :b).line(2))
2125
+
2126
+ assert_parse rp, pt
2127
+ end
2128
+
2129
+ def test_str_single_escaped_newline
2130
+ rp = "a '\\n';b"
2131
+ pt = s(:block,
2132
+ s(:call, nil, :a, s(:str, "\\n")),
2133
+ s(:call, nil, :b))
2134
+
2135
+ assert_parse rp, pt
2136
+ end
2137
+
2138
+ def test_str_single_double_escaped_newline
2139
+ rp = "a '\\\\n';b"
2140
+ pt = s(:block,
2141
+ s(:call, nil, :a, s(:str, "\\n")),
2142
+ s(:call, nil, :b))
2143
+
2144
+ assert_parse rp, pt
2145
+ end
2146
+
2147
+ def test_str_double_newline
2148
+ rp = "a \"\n\";b"
2149
+ pt = s(:block,
2150
+ s(:call, nil, :a, s(:str, "\n")),
2151
+ s(:call, nil, :b).line(2))
2152
+
2153
+ assert_parse rp, pt
2154
+ end
2155
+
2156
+ def test_str_double_escaped_newline
2157
+ rp = "a \"\\n\";b"
2158
+ pt = s(:block,
2159
+ s(:call, nil, :a, s(:str, "\n")),
2160
+ s(:call, nil, :b))
2161
+
2162
+ assert_parse rp, pt
2163
+ end
2164
+
2165
+ def test_str_double_double_escaped_newline
2166
+ rp = "a \"\\\\n\";b"
2167
+ pt = s(:block,
2168
+ s(:call, nil, :a, s(:str, "\\n")),
2169
+ s(:call, nil, :b))
2170
+
2171
+ assert_parse rp, pt
2172
+ end
2173
+
2080
2174
  def test_str_str
2081
2175
  rb = "\"a #\{'b'}\""
2082
2176
  pt = s(:str, "a b")
@@ -2464,7 +2558,7 @@ module TestRubyParserShared19Plus
2464
2558
  nil,
2465
2559
  :private,
2466
2560
  s(:defn, :f, s(:args),
2467
- s(:iter, s(:call, s(:call, nil, :a), :b), 0)))
2561
+ s(:iter, s(:call, s(:call, nil, :a).line(2), :b).line(2), 0).line(2)))
2468
2562
 
2469
2563
  assert_parse rb, pt
2470
2564
  end
@@ -2542,7 +2636,10 @@ module TestRubyParserShared19Plus
2542
2636
 
2543
2637
  def test_call_assoc_new_if_multiline
2544
2638
  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))))
2639
+ pt = s(:call, nil, :a,
2640
+ s(:hash,
2641
+ s(:lit, :b),
2642
+ s(:if, s(:lit, :c), s(:lit, 1).line(2), s(:lit, 2).line(4))))
2546
2643
 
2547
2644
  assert_parse rb, pt
2548
2645
  end
@@ -2631,8 +2728,8 @@ module TestRubyParserShared19Plus
2631
2728
  def test_defn_opt_last_arg
2632
2729
  rb = "def m arg = false\nend"
2633
2730
  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)
2731
+ s(:args, s(:lasgn, :arg, s(:false))),
2732
+ s(:nil))
2636
2733
 
2637
2734
  assert_parse rb, pt
2638
2735
  end
@@ -2689,7 +2786,7 @@ module TestRubyParserShared19Plus
2689
2786
  rb = "1 ? b('') : 2\na d: 3"
2690
2787
  pt = s(:block,
2691
2788
  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))))
2789
+ s(:call, nil, :a, s(:hash, s(:lit, :d).line(2), s(:lit, 3).line(2)).line(2)).line(2))
2693
2790
 
2694
2791
  assert_parse rb, pt
2695
2792
  end
@@ -3079,9 +3176,32 @@ module TestRubyParserShared19Plus
3079
3176
  assert_parse rb, pt
3080
3177
  end
3081
3178
 
3082
- def test_motherfuckin_leading_dots
3083
- skip if processor.class.version >= 27
3179
+ def test_call_leading_dots
3180
+ rb = "a\n.b\n.c"
3181
+ pt = s(:call, s(:call, s(:call, nil, :a), :b), :c)
3182
+
3183
+ assert_parse rb, pt
3184
+ end
3084
3185
 
3186
+ def test_call_leading_dots_comment
3187
+ rb = "a\n.b\n#.c\n.d"
3188
+ pt = s(:call,
3189
+ s(:call,
3190
+ s(:call, nil, :a),
3191
+ :b),
3192
+ :d) # TODO: fix linenos: 1, 2, 4
3193
+
3194
+ assert_parse rb, pt
3195
+ end
3196
+
3197
+ def test_call_trailing_dots
3198
+ rb = "a.\nb.\nc"
3199
+ pt = s(:call, s(:call, s(:call, nil, :a), :b), :c)
3200
+
3201
+ assert_parse rb, pt
3202
+ end
3203
+
3204
+ def test_motherfuckin_leading_dots
3085
3205
  rb = "a\n.b"
3086
3206
  pt = s(:call, s(:call, nil, :a), :b)
3087
3207
 
@@ -3089,11 +3209,15 @@ module TestRubyParserShared19Plus
3089
3209
  end
3090
3210
 
3091
3211
  def test_motherfuckin_leading_dots2
3092
- skip if processor.class.version >= 27
3093
-
3094
- rb = "a\n..b"
3212
+ rb = "1\n..3"
3213
+ pt = s(:block, s(:lit, 1),
3214
+ s(:dot2, nil, s(:lit, 3).line(2)).line(2))
3095
3215
 
3096
- assert_parse_error rb, '(string):2 :: parse error on value ".." (tDOT2)'
3216
+ if processor.class.version >= 27
3217
+ assert_parse rb, pt
3218
+ else
3219
+ assert_parse_error rb, '(string):2 :: parse error on value ".." (tDOT2)'
3220
+ end
3097
3221
  end
3098
3222
 
3099
3223
  def test_multiline_hash_declaration
@@ -3101,6 +3225,8 @@ module TestRubyParserShared19Plus
3101
3225
 
3102
3226
  assert_parse "f(state: {})", pt
3103
3227
  assert_parse "f(state: {\n})", pt
3228
+
3229
+ pt = s(:call, nil, :f, s(:hash, s(:lit, :state), s(:hash).line(2)))
3104
3230
  assert_parse "f(state:\n {\n})", pt
3105
3231
  end
3106
3232
 
@@ -3163,7 +3289,7 @@ module TestRubyParserShared19Plus
3163
3289
  rb = "until not var.nil?\n 'foo'\nend"
3164
3290
  pt = s(:until,
3165
3291
  s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
3166
- s(:str, "foo"), true)
3292
+ s(:str, "foo").line(2), true)
3167
3293
 
3168
3294
  assert_parse rb, pt
3169
3295
  end
@@ -3172,7 +3298,7 @@ module TestRubyParserShared19Plus
3172
3298
  rb = "until not var.nil?\n 'foo'\nend"
3173
3299
  pt = s(:until,
3174
3300
  s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
3175
- s(:str, "foo"), true)
3301
+ s(:str, "foo").line(2), true)
3176
3302
 
3177
3303
  processor.canonicalize_conditions = false
3178
3304
 
@@ -3183,7 +3309,7 @@ module TestRubyParserShared19Plus
3183
3309
  rb = "while not var.nil?\n 'foo'\nend"
3184
3310
  pt = s(:while,
3185
3311
  s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
3186
- s(:str, "foo"), true)
3312
+ s(:str, "foo").line(2), true)
3187
3313
 
3188
3314
  assert_parse rb, pt
3189
3315
  end
@@ -3192,7 +3318,7 @@ module TestRubyParserShared19Plus
3192
3318
  rb = "while not var.nil?\n 'foo'\nend"
3193
3319
  pt = s(:while,
3194
3320
  s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
3195
- s(:str, "foo"), true)
3321
+ s(:str, "foo").line(2), true)
3196
3322
 
3197
3323
  processor.canonicalize_conditions = false
3198
3324
 
@@ -3356,14 +3482,16 @@ module TestRubyParserShared19Plus
3356
3482
  RUBY
3357
3483
 
3358
3484
  pt = s(:hash,
3359
- s(:lit, :a),
3485
+ s(:lit, :a).line(2),
3360
3486
  s(:iter,
3361
- s(:call, nil, :lambda),
3487
+ s(:call, nil, :lambda).line(2),
3362
3488
  0,
3363
- s(:if, s(:call, nil, :b), s(:call, nil, :c), s(:call, nil, :d))),
3489
+ s(:if, s(:call, nil, :b).line(2),
3490
+ s(:call, nil, :c).line(2),
3491
+ s(:call, nil, :d).line(2)).line(2)).line(2),
3364
3492
 
3365
- s(:lit, :e),
3366
- s(:nil))
3493
+ s(:lit, :e).line(3),
3494
+ s(:nil).line(3))
3367
3495
 
3368
3496
  assert_parse rb, pt
3369
3497
  end
@@ -3372,6 +3500,100 @@ end
3372
3500
  module TestRubyParserShared20Plus
3373
3501
  include TestRubyParserShared19Plus
3374
3502
 
3503
+ def test_read_escape_unicode_h4
3504
+ rb = '?\u00a0'
3505
+ pt = s(:str, ?\u00a0)
3506
+
3507
+ assert_parse rb, pt
3508
+ end
3509
+
3510
+ def test_read_escape_unicode_curlies
3511
+ rb = '?\u{00a0}'
3512
+ pt = s(:str, ?\u00a0)
3513
+
3514
+ assert_parse rb, pt
3515
+ end
3516
+
3517
+ def test_regexp_unicode_curlies
3518
+ rb = '/\u{df}/'
3519
+ pt = s(:lit, /\u{df}/)
3520
+
3521
+ assert_parse rb, pt
3522
+
3523
+ rb = '/\u{c0de babe}/'
3524
+ pt = s(:lit, /\u{c0de babe}/)
3525
+
3526
+ assert_parse rb, pt
3527
+ end
3528
+
3529
+ def test_qw_escape
3530
+ rb = "%q(\1\\\')"
3531
+ pt = s(:str, "\001\\'")
3532
+
3533
+ assert_parse rb, pt
3534
+ end
3535
+
3536
+ def test_pct_nl
3537
+ rb = "x = %\n\n"
3538
+ pt = s(:lasgn, :x, s(:str, ""))
3539
+
3540
+ assert_parse rb, pt
3541
+ end
3542
+
3543
+ def test_regexp_esc_C_slash
3544
+ skip "https://bugs.ruby-lang.org/issues/18449" if RUBY_VERSION == "3.1.0"
3545
+
3546
+ rb = "/\\cC\\d/"
3547
+ pt = s(:lit, /\cC\d/)
3548
+
3549
+ assert_parse rb, pt
3550
+ end
3551
+
3552
+ def test_heredoc_wtf_I_hate_you
3553
+ rb = "p <<-END+'b\n a\n END\n c'+'d'"
3554
+ pt = s(:call, nil, :p,
3555
+ s(:call,
3556
+ s(:call, s(:str, " a\n"), :+,
3557
+ s(:str, "b\n c")),
3558
+ :+, s(:str, "d").line(4)))
3559
+
3560
+ assert_parse rb, pt
3561
+ end
3562
+
3563
+ def test_heredoc_nested
3564
+ rb = "[<<A,\n\#{<<B}\nb\nB\na\nA\n0]"
3565
+ pt = s(:array, s(:str, "b\n\na\n"),
3566
+ s(:lit, 0).line(7))
3567
+
3568
+ assert_parse rb, pt
3569
+ end
3570
+
3571
+ def test_pct_w_heredoc_interp_nested
3572
+ rb = "%W( 1 \#{<<A} 3\n2\nA\n 4 5 )"
3573
+ pt = s(:array,
3574
+ s(:str, "1"),
3575
+ s(:str, "2\n"),
3576
+ s(:str, "3"),
3577
+ s(:str, "4").line(4),
3578
+ s(:str, "5").line(4))
3579
+
3580
+ assert_parse rb, pt
3581
+ end
3582
+
3583
+ def test_regexp_esc_u
3584
+ rb = "/[\\u0021-\\u0027]/"
3585
+ pt = s(:lit, /[\u0021-\u0027]/)
3586
+
3587
+ assert_parse rb, pt
3588
+ end
3589
+
3590
+ def test_qw_escape_term
3591
+ rb = "%q|blah blah \\| blah blah|"
3592
+ pt = s(:str, "blah blah | blah blah")
3593
+
3594
+ assert_parse rb, pt
3595
+ end
3596
+
3375
3597
  def test_args_kw_block
3376
3598
  rb = "def f(a: 1, &b); end"
3377
3599
  pt = s(:defn, :f, s(:args, s(:kwarg, :a, s(:lit, 1)), :"&b"), s(:nil))
@@ -3379,6 +3601,49 @@ module TestRubyParserShared20Plus
3379
3601
  assert_parse rb, pt
3380
3602
  end
3381
3603
 
3604
+ def test_heredoc_backslash_nl
3605
+ rb = %Q(" why would someone do this? \\\n blah\n")
3606
+ pt = s(:str, " why would someone do this? blah\n")
3607
+
3608
+ assert_parse rb, pt
3609
+
3610
+ rb = "<<-DESC\n why would someone do this? \\\n blah\nDESC"
3611
+
3612
+ assert_parse rb, pt
3613
+ end
3614
+
3615
+ def test_heredoc_comma_arg
3616
+ rb = "[\" some text\n\",]"
3617
+ pt = s(:array, s(:str, " some text\n"))
3618
+
3619
+ assert_parse rb, pt
3620
+
3621
+ rb = "[<<-FILE,\n some text\nFILE\n]"
3622
+
3623
+ assert_parse rb, pt
3624
+ end
3625
+
3626
+ def test_heredoc_trailing_slash_continued_call
3627
+ rb = "<<END\\\nblah\nEND\n.strip"
3628
+ pt = s(:call, s(:str, "blah\n"), :strip)
3629
+
3630
+ assert_parse rb, pt
3631
+ end
3632
+
3633
+ def test_pct_q_backslash_nl
3634
+ rb = "%q{ \\\n}"
3635
+ pt = s(:str, " \\\n")
3636
+
3637
+ assert_parse rb, pt
3638
+ end
3639
+
3640
+ def test_pct_Q_backslash_nl
3641
+ rb = "%Q{ \\\n}"
3642
+ pt = s(:str, " ")
3643
+
3644
+ assert_parse rb, pt
3645
+ end
3646
+
3382
3647
  def test_block_arg_kwsplat
3383
3648
  rb = "a { |**b| }"
3384
3649
  pt = s(:iter, s(:call, nil, :a), s(:args, :"**b"))
@@ -3415,7 +3680,7 @@ module TestRubyParserShared20Plus
3415
3680
  rb = "a (b)\nc.d do end"
3416
3681
  pt = s(:block,
3417
3682
  s(:call, nil, :a, s(:call, nil, :b)),
3418
- s(:iter, s(:call, s(:call, nil, :c), :d), 0))
3683
+ s(:iter, s(:call, s(:call, nil, :c).line(2), :d).line(2), 0).line(2))
3419
3684
 
3420
3685
 
3421
3686
  assert_parse rb, pt
@@ -3425,8 +3690,9 @@ module TestRubyParserShared20Plus
3425
3690
  rb = "a def b(c)\n d\n end\n e.f do end"
3426
3691
  pt = s(:block,
3427
3692
  s(:call, nil, :a,
3428
- s(:defn, :b, s(:args, :c), s(:call, nil, :d))),
3429
- s(:iter, s(:call, s(:call, nil, :e), :f), 0))
3693
+ s(:defn, :b, s(:args, :c),
3694
+ s(:call, nil, :d).line(2))),
3695
+ s(:iter, s(:call, s(:call, nil, :e).line(4), :f).line(4), 0).line(4))
3430
3696
 
3431
3697
  assert_parse rb, pt
3432
3698
  end
@@ -3444,7 +3710,9 @@ module TestRubyParserShared20Plus
3444
3710
  def test_call_begin_call_block_call
3445
3711
  rb = "a begin\nb.c do end\nend"
3446
3712
  pt = s(:call, nil, :a,
3447
- s(:iter, s(:call, s(:call, nil, :b), :c), 0))
3713
+ s(:iter,
3714
+ s(:call, s(:call, nil, :b).line(2), :c).line(2),
3715
+ 0).line(2))
3448
3716
 
3449
3717
  assert_parse rb, pt
3450
3718
  end
@@ -3455,7 +3723,7 @@ module TestRubyParserShared20Plus
3455
3723
  s(:op_asgn, s(:const, :B),
3456
3724
  s(:call, nil, :d, s(:call, nil, :e)),
3457
3725
  :C,
3458
- :*)).line(1)
3726
+ :*))
3459
3727
 
3460
3728
  assert_parse rb, pt
3461
3729
  end
@@ -3513,9 +3781,9 @@ module TestRubyParserShared20Plus
3513
3781
  s(:iter,
3514
3782
  s(:call, s(:const, :Class), :new),
3515
3783
  0,
3516
- s(:defn, :initialize, s(:args), s(:nil))),
3784
+ s(:defn, :initialize, s(:args).line(2), s(:nil).line(2)).line(2)),
3517
3785
  :new),
3518
- s(:hash, s(:lit, :at), s(:str, "endpoint")))
3786
+ s(:hash, s(:lit, :at).line(4), s(:str, "endpoint").line(4)).line(4))
3519
3787
 
3520
3788
  assert_parse rb, pt
3521
3789
  end
@@ -3622,20 +3890,23 @@ module TestRubyParserShared20Plus
3622
3890
  pt = s(:block,
3623
3891
  s(:array,
3624
3892
  s(:lit, :a).line(2),
3625
- s(:lit, :b).line(3)).line(1),
3893
+ s(:lit, :b).line(3)),
3626
3894
  s(:lit, 1).line(5))
3627
3895
  assert_parse rb, pt
3628
3896
  end
3629
3897
 
3630
3898
  def test_iter_array_curly
3631
- skip if processor.class.version >= 25
3632
-
3633
3899
  rb = "f :a, [:b] { |c, d| }" # yes, this is bad code... that's their problem
3634
3900
  pt = s(:iter,
3635
3901
  s(:call, nil, :f, s(:lit, :a), s(:array, s(:lit, :b))),
3636
3902
  s(:args, :c, :d))
3637
3903
 
3638
- assert_parse rb, pt
3904
+ if processor.class.version >= 25 then
3905
+ msg = /parse error on value "\{" \(tLCURLY\)/
3906
+ assert_syntax_error rb, msg, Racc::ParseError
3907
+ else
3908
+ assert_parse rb, pt
3909
+ end
3639
3910
  end
3640
3911
 
3641
3912
  def test_iter_kwarg
@@ -3657,7 +3928,7 @@ module TestRubyParserShared20Plus
3657
3928
  pt = s(:block,
3658
3929
  s(:array,
3659
3930
  s(:lit, :a).line(2),
3660
- s(:lit, :b).line(3)).line(1),
3931
+ s(:lit, :b).line(3)),
3661
3932
  s(:lit, 1).line(5))
3662
3933
  assert_parse rb, pt
3663
3934
  end
@@ -3699,7 +3970,7 @@ module TestRubyParserShared20Plus
3699
3970
  s(:iter,
3700
3971
  s(:lambda),
3701
3972
  s(:args),
3702
- s(:iter, s(:call, s(:call, nil, :a), :b), 0)))
3973
+ s(:iter, s(:call, s(:call, nil, :a).line(2), :b).line(2), 0).line(2)))
3703
3974
 
3704
3975
  assert_parse rb, pt
3705
3976
  end
@@ -3712,7 +3983,7 @@ module TestRubyParserShared20Plus
3712
3983
  s(:args),
3713
3984
  s(:iter,
3714
3985
  s(:call, nil, :a,
3715
- s(:lit, 1)), 0)))
3986
+ s(:lit, 1).line(2)).line(2), 0).line(2)))
3716
3987
 
3717
3988
  assert_parse rb, pt
3718
3989
  end
@@ -3749,6 +4020,17 @@ end
3749
4020
  module TestRubyParserShared21Plus
3750
4021
  include TestRubyParserShared20Plus
3751
4022
 
4023
+ def test_array_lits_trailing_calls
4024
+ rb = "[].b"
4025
+ pt = s(:call, s(:array), :b)
4026
+
4027
+ assert_parse rb, pt
4028
+
4029
+ rb = "%w[].b"
4030
+
4031
+ assert_parse rb, pt
4032
+ end
4033
+
3752
4034
  def test_block_kw
3753
4035
  rb = "blah { |k:42| }"
3754
4036
  pt = s(:iter, s(:call, nil, :blah), s(:args, s(:kwarg, :k, s(:lit, 42))))
@@ -3771,7 +4053,7 @@ module TestRubyParserShared21Plus
3771
4053
 
3772
4054
  def test_bug162__21plus
3773
4055
  rb = %q(<<E\nfoo\nE\rO)
3774
- emsg = "can't match /E(\\r*\\n|\\z)/ anywhere in . near line 1: \"\""
4056
+ emsg = "can't match /E(?=\\r?\\n|\\z)/ anywhere in . near line 1: \"\""
3775
4057
 
3776
4058
  assert_syntax_error rb, emsg
3777
4059
  end
@@ -3808,8 +4090,8 @@ module TestRubyParserShared21Plus
3808
4090
  CODE
3809
4091
 
3810
4092
  pt = s(:block,
3811
- s(:str, "\n\n\n\n\n\n\n\n\n\n").line(1),
3812
- s(:class, :Foo, nil).line(5)).line(1)
4093
+ s(:str, "\n\n\n\n\n\n\n\n\n\n"),
4094
+ s(:class, :Foo, nil).line(5))
3813
4095
 
3814
4096
  assert_parse rb, pt
3815
4097
  end
@@ -3938,8 +4220,8 @@ module TestRubyParserShared23Plus
3938
4220
  def test_heredoc_squiggly_interp
3939
4221
  rb = "a = <<~EOF\n w\n x#\{42} y\n z\n EOF"
3940
4222
  pt = s(:lasgn, :a, s(:dstr, " w\nx",
3941
- s(:evstr, s(:lit, 42)),
3942
- s(:str, " y\n z\n")))
4223
+ s(:evstr, s(:lit, 42).line(3)).line(3),
4224
+ s(:str, " y\n z\n").line(3)))
3943
4225
 
3944
4226
  assert_parse rb, pt
3945
4227
  end
@@ -3967,6 +4249,27 @@ module TestRubyParserShared23Plus
3967
4249
  assert_parse rb, pt
3968
4250
  end
3969
4251
 
4252
+ def test_heredoc_squiggly_blank_lines
4253
+ rb = "a = <<~EOF\n x\n\n z\nEOF\n\n"
4254
+ pt = s(:lasgn, :a, s(:str, "x\n\nz\n"))
4255
+
4256
+ assert_parse rb, pt
4257
+ end
4258
+
4259
+ def test_heredoc_squiggly_visually_blank_lines
4260
+ rb = "a = <<~EOF\n x\n \n z\nEOF\n\n"
4261
+ pt = s(:lasgn, :a, s(:str, "x\n\nz\n"))
4262
+
4263
+ assert_parse rb, pt
4264
+ end
4265
+
4266
+ def test_heredoc_squiggly_empty
4267
+ rb = "<<~A\nA"
4268
+ pt = s(:str, "")
4269
+
4270
+ assert_parse rb, pt
4271
+ end
4272
+
3970
4273
  def test_integer_with_if_modifier
3971
4274
  rb = "1_234if true"
3972
4275
  pt = s(:if, s(:true), s(:lit, 1234), nil)
@@ -4036,7 +4339,7 @@ module TestRubyParserShared23Plus
4036
4339
 
4037
4340
  def test_safe_call_operator
4038
4341
  rb = "a&.> 1"
4039
- pt = s(:safe_call, s(:call, nil, :a), :>, s(:lit, 1)).line(1)
4342
+ pt = s(:safe_call, s(:call, nil, :a), :>, s(:lit, 1))
4040
4343
 
4041
4344
  assert_parse rb, pt
4042
4345
  end
@@ -4056,15 +4359,16 @@ module TestRubyParserShared23Plus
4056
4359
  end
4057
4360
 
4058
4361
  def test_safe_op_asgn
4059
- rb = "a&.b += x 1\n"
4060
- pt = s(:safe_op_asgn, s(:call, nil, :a), s(:call, nil, :x, s(:lit, 1)), :b, :+).line(1)
4362
+ rb = "a&.b += x 1"
4363
+ pt = s(:safe_op_asgn, s(:call, nil, :a), s(:call, nil, :x, s(:lit, 1)), :b, :+)
4061
4364
 
4062
4365
  assert_parse rb, pt
4063
4366
  end
4064
4367
 
4065
4368
  def test_safe_op_asgn2
4066
4369
  rb = "a&.b ||=\nx;"
4067
- pt = s(:safe_op_asgn2, s(:call, nil, :a), :b=, :"||", s(:call, nil, :x)).line(1)
4370
+ pt = s(:safe_op_asgn2,
4371
+ s(:call, nil, :a), :b=, :"||", s(:call, nil, :x).line(2))
4068
4372
 
4069
4373
  assert_parse rb, pt
4070
4374
  end
@@ -4079,11 +4383,11 @@ a + b
4079
4383
  )
4080
4384
 
4081
4385
  pt = s(:block,
4082
- s(:call, nil, :puts, s(:str, "hello my dear friend").line(1)).line(1),
4386
+ s(:call, nil, :puts, s(:str, "hello my dear friend")),
4083
4387
  s(:call, s(:call, nil, :a).line(6),
4084
4388
  :+,
4085
4389
  s(:call, nil, :b).line(6)).line(6)
4086
- ).line(1)
4390
+ )
4087
4391
 
4088
4392
  assert_parse rb, pt
4089
4393
  end
@@ -4119,6 +4423,18 @@ module TestRubyParserShared26Plus
4119
4423
  assert_parse rb, pt
4120
4424
  end
4121
4425
 
4426
+ def test_begin_else_return_value # overrides above, warns < 2.6
4427
+ rb = "begin; else 2; end"
4428
+
4429
+ assert_syntax_error rb, "else without rescue is useless"
4430
+ end
4431
+
4432
+ def test_bug_begin_else # overrides above, warns < 2.6
4433
+ rb = "begin 1; else; 2 end"
4434
+
4435
+ assert_syntax_error rb, "else without rescue is useless"
4436
+ end
4437
+
4122
4438
  def test_dot3_nil__26
4123
4439
  rb = "a..."
4124
4440
  pt = s(:dot3, s(:call, nil, :a), nil)
@@ -4129,30 +4445,683 @@ module TestRubyParserShared26Plus
4129
4445
  def test_symbol_list
4130
4446
  rb = '%I[#{a} #{b}]'
4131
4447
  pt = s(:array,
4132
- s(:dsym, "", s(:evstr, s(:call, nil, :a)).line(1)).line(1),
4133
- s(:dsym, "", s(:evstr, s(:call, nil, :b)).line(1)).line(1)).line 1
4448
+ s(:dsym, "", s(:evstr, s(:call, nil, :a))),
4449
+ s(:dsym, "", s(:evstr, s(:call, nil, :b)))).line 1
4134
4450
 
4135
4451
  assert_parse rb, pt
4136
4452
  end
4137
4453
  end
4138
4454
 
4139
- module TestRubyParserShared27Plus
4140
- include TestRubyParserShared26Plus
4455
+ module TestPatternMatching
4456
+ def rip rb
4457
+ require "ripper"
4458
+ puts
4459
+ pp Sexp.from_array Ripper.sexp rb
4460
+ end
4141
4461
 
4142
- def test_defn_forward_args
4143
- rb = "def a(...); b(...); end"
4144
- pt = s(:defn, :a, s(:args, s(:forward_args)),
4145
- s(:call, nil, :b, s(:forward_args)))
4462
+ def assert_case_in lit, exp_pt
4463
+ rb = "case :a\nin #{lit}\nend"
4146
4464
 
4147
- assert_parse_line rb, pt, 1
4148
- end
4465
+ if ENV["VERBOSE_TEST"] then
4466
+ puts
4467
+ puts rb
4468
+ end
4149
4469
 
4150
- def test_defn_arg_forward_args
4151
- rb = "def a(x, ...); b(x, ...); end"
4470
+ pt = s(:case, s(:lit, :a),
4471
+ s(:in, exp_pt, nil).line(2),
4472
+ nil)
4473
+
4474
+ assert_parse rb, pt
4475
+ end
4476
+
4477
+ def test_case_in_09
4478
+ assert_case_in(":b, [:c]",
4479
+ s(:array_pat, nil,
4480
+ s(:lit, :b).line(2),
4481
+ s(:array_pat, nil, s(:lit, :c).line(2)).line(2)).line(2))
4482
+ end
4483
+
4484
+ def test_case_in_10
4485
+ assert_case_in "nil, nil, nil", s(:array_pat,
4486
+ nil,
4487
+ s(:nil).line(2),
4488
+ s(:nil).line(2),
4489
+ s(:nil).line(2)).line(2)
4490
+ end
4491
+
4492
+ def test_case_in_21
4493
+ assert_case_in "Symbol()", s(:array_pat, s(:const, :Symbol).line(2)).line(2)
4494
+ end
4495
+
4496
+ def test_case_in_26
4497
+ assert_case_in "(42)", s(:lit, 42).line(2)
4498
+ end
4499
+
4500
+ def test_case_in_27
4501
+ assert_case_in("[A, *, B]",
4502
+ s(:array_pat, nil,
4503
+ s(:const, :A).line(2),
4504
+ :*,
4505
+ s(:const, :B).line(2)).line(2))
4506
+ end
4507
+
4508
+ def test_case_in_28_2
4509
+ assert_case_in '{ "b": }', s(:hash_pat, nil, s(:lit, :b).line(2), nil).line(2)
4510
+ end
4511
+
4512
+ def test_case_in_28
4513
+ assert_case_in "[]", s(:array_pat).line(2)
4514
+ end
4515
+
4516
+ def test_case_in_29
4517
+ assert_case_in "**nil", s(:hash_pat, nil, s(:kwrest, :"**nil").line(2)).line(2)
4518
+ end
4519
+
4520
+ def test_case_in_30
4521
+ assert_case_in "{}", s(:hash_pat, nil).line(2)
4522
+ end
4523
+
4524
+ def test_case_in_31?
4525
+ rb = "case :a\nin [:b, *c]\n :d\nend"
4526
+ pt = s(:case, s(:lit, :a),
4527
+ s(:in,
4528
+ s(:array_pat, nil, s(:lit, :b).line(2), :"*c").line(2),
4529
+ s(:lit, :d).line(3)).line(2),
4530
+ nil)
4531
+
4532
+ assert_parse rb, pt
4533
+ end
4534
+
4535
+ def test_case_in_32
4536
+ assert_case_in "(1...3)", s(:dot3, s(:lit, 1).line(2), s(:lit, 3).line(2)).line(2)
4537
+ end
4538
+
4539
+ def test_case_in_33
4540
+ assert_case_in "(1...)", s(:dot3, s(:lit, 1).line(2), nil).line(2)
4541
+ end
4542
+
4543
+ def test_case_in_34
4544
+ assert_case_in "(..10)", s(:dot2, nil, s(:lit, 10).line(2)).line(2)
4545
+ end
4546
+
4547
+ def test_case_in_35
4548
+ assert_case_in "(...10)", s(:dot3, nil, s(:lit, 10).line(2)).line(2)
4549
+ end
4550
+
4551
+ def test_case_in_36
4552
+ rb = "[:a, b, c, [:d, *e, nil]]"
4553
+ pt = s(:array_pat,
4554
+ nil,
4555
+ s(:lit, :a).line(2),
4556
+ s(:lvar, :b).line(2),
4557
+ s(:lvar, :c).line(2),
4558
+ s(:array_pat,
4559
+ nil,
4560
+ s(:lit, :d).line(2),
4561
+ :"*e",
4562
+ s(:nil).line(2)).line(2)).line(2)
4563
+
4564
+ assert_case_in rb, pt
4565
+ end
4566
+
4567
+ def test_case_in_37
4568
+ rb = "case :a\nin { b: [Hash, *] }\n :c\nend"
4569
+ pt = s(:case, s(:lit, :a),
4570
+ s(:in,
4571
+ s(:hash_pat,
4572
+ nil,
4573
+ s(:lit, :b).line(2),
4574
+ s(:array_pat, nil, s(:const, :Hash).line(2), :"*").line(2)
4575
+ ).line(2),
4576
+ s(:lit, :c).line(3)).line(2),
4577
+ nil)
4578
+
4579
+ assert_parse rb, pt
4580
+ end
4581
+
4582
+ def test_case_in_42
4583
+ rb = "case :a\nin :b, *_ then nil\nend"
4584
+ pt = s(:case, s(:lit, :a),
4585
+ s(:in,
4586
+ s(:array_pat,
4587
+ nil,
4588
+ s(:lit, :b).line(2),
4589
+ :"*_",
4590
+ ).line(2),
4591
+ s(:nil).line(2)).line(2),
4592
+ nil)
4593
+
4594
+ assert_parse rb, pt
4595
+ end
4596
+
4597
+ def test_case_in_42_2
4598
+ rb = "case :a\nin A(*list) then nil\nend"
4599
+ pt = s(:case, s(:lit, :a),
4600
+ s(:in,
4601
+ s(:array_pat,
4602
+ s(:const, :A).line(2),
4603
+ :"*list").line(2),
4604
+ s(:nil).line(2)).line(2),
4605
+ nil)
4606
+
4607
+ assert_parse rb, pt
4608
+ end
4609
+
4610
+ def test_case_in_42_3
4611
+ assert_case_in ":b, *_, :c", s(:array_pat, nil,
4612
+ s(:lit, :b).line(2),
4613
+ :"*_",
4614
+ s(:lit, :c).line(2)).line(2)
4615
+ end
4616
+
4617
+
4618
+ def test_case_in_47
4619
+ rb = "case :a\nin [*, :b, :c]\n :d\nend"
4620
+ pt = s(:case, s(:lit, :a),
4621
+ s(:in,
4622
+ s(:array_pat, nil, :*,
4623
+ s(:lit, :b).line(2), s(:lit, :c).line(2)).line(2),
4624
+ s(:lit, :d).line(3)).line(2),
4625
+ nil)
4626
+
4627
+ assert_parse rb, pt
4628
+ end
4629
+
4630
+ def test_case_in_67
4631
+ rb = "case :a\nin 1.. then nil\nend"
4632
+ pt = s(:case,
4633
+ s(:lit, :a),
4634
+ s(:in, s(:dot2, s(:lit, 1).line(2), nil).line(2),
4635
+ s(:nil).line(2)).line(2),
4636
+ nil)
4637
+
4638
+ assert_parse rb, pt
4639
+ end
4640
+
4641
+ def test_case_in_76
4642
+ assert_case_in "`echo hi`", s(:xstr, "echo hi").line(2)
4643
+ end
4644
+
4645
+ def test_case_in_77
4646
+ assert_case_in "/regexp/", s(:lit, /regexp/).line(2)
4647
+ end
4648
+
4649
+ def test_case_in_78
4650
+ assert_case_in "%W[a b]", s(:array, s(:str, "a").line(2), s(:str, "b").line(2)).line(2)
4651
+ end
4652
+
4653
+ def test_case_in_79
4654
+ assert_case_in "%w[a b]", s(:array, s(:str, "a").line(2), s(:str, "b").line(2)).line(2)
4655
+ end
4656
+
4657
+ def test_case_in_80
4658
+ assert_case_in "%I[a b]", s(:array, s(:lit, :a).line(2), s(:lit, :b).line(2)).line(2)
4659
+ end
4660
+
4661
+ def test_case_in_81
4662
+ assert_case_in "%i[a b]", s(:array, s(:lit, :a).line(2), s(:lit, :b).line(2)).line(2)
4663
+ end
4664
+
4665
+ def test_case_in_83
4666
+ rb = "[->(b) { true }, c]"
4667
+ pt = s(:array_pat, nil,
4668
+ s(:iter, s(:lambda).line(2), s(:args, :b).line(2),
4669
+ s(:true).line(2)).line(2),
4670
+ s(:lvar, :c).line(2)).line(2)
4671
+
4672
+ assert_case_in rb, pt
4673
+ end
4674
+
4675
+ def test_case_in_85
4676
+ rb = "[[:b, c], [:d, ^e]]"
4677
+ pt = s(:array_pat, nil,
4678
+ s(:array_pat, nil,
4679
+ s(:lit, :b).line(2),
4680
+ s(:lvar, :c).line(2)).line(2),
4681
+ s(:array_pat,
4682
+ nil,
4683
+ s(:lit, :d).line(2),
4684
+ s(:lvar, :e).line(2)).line(2),
4685
+ ).line(2)
4686
+
4687
+ assert_case_in rb, pt
4688
+ end
4689
+
4690
+ def test_case_in_86
4691
+ rb = "case [:a, :b]\nin ::NilClass, * then nil\nend"
4692
+ pt = s(:case,
4693
+ s(:array, s(:lit, :a), s(:lit, :b)),
4694
+ s(:in,
4695
+ s(:array_pat,
4696
+ nil,
4697
+ s(:colon3, :NilClass).line(2),
4698
+ :*).line(2),
4699
+ s(:nil).line(2)).line(2),
4700
+ nil)
4701
+
4702
+ assert_parse rb, pt
4703
+ end
4704
+
4705
+ def test_case_in_86_2
4706
+ rb = "case [:a, :b]\nin *, ::NilClass then nil\nend"
4707
+ pt = s(:case,
4708
+ s(:array, s(:lit, :a), s(:lit, :b)),
4709
+ s(:in,
4710
+ s(:array_pat,
4711
+ nil,
4712
+ :*,
4713
+ s(:colon3, :NilClass).line(2)).line(2),
4714
+ s(:nil).line(2)).line(2),
4715
+ nil)
4716
+
4717
+ assert_parse rb, pt
4718
+ end
4719
+
4720
+ def test_case_in_array_pat_const
4721
+ rb = "case :a\nin B[c]\n :d\nend"
4722
+ pt = s(:case, s(:lit, :a),
4723
+ s(:in,
4724
+ s(:array_pat,
4725
+ s(:const, :B).line(2),
4726
+ s(:lvar, :c).line(2)).line(2),
4727
+ s(:lit, :d).line(3)).line(2),
4728
+ nil)
4729
+
4730
+ assert_parse rb, pt
4731
+ end
4732
+
4733
+ def test_case_in_array_pat_const2
4734
+ rb = "case :a\nin B::C[d]\n :e\nend"
4735
+ pt = s(:case, s(:lit, :a),
4736
+ s(:in,
4737
+ s(:array_pat,
4738
+ s(:const, s(:colon2, s(:const, :B).line(2), :C).line(2)).line(2),
4739
+ s(:lvar, :d).line(2)).line(2),
4740
+ s(:lit, :e).line(3)).line(2),
4741
+ nil)
4742
+
4743
+ assert_parse rb, pt
4744
+ end
4745
+
4746
+ def test_case_in_array_pat_paren_assign
4747
+ rb = "case :a\nin B(C => d)\n :d\nend"
4748
+ pt = s(:case, s(:lit, :a),
4749
+ s(:in,
4750
+ s(:array_pat,
4751
+ s(:const, :B).line(2),
4752
+ s(:lasgn, :d, s(:const, :C).line(2)).line(2)).line(2),
4753
+ s(:lit, :d).line(3)).line(2),
4754
+ nil)
4755
+
4756
+ assert_parse rb, pt
4757
+ end
4758
+
4759
+ def test_case_in_const
4760
+ rb = "case Array\nin Class\n :b\nend"
4761
+ pt = s(:case, s(:const, :Array),
4762
+ s(:in, s(:const, :Class).line(2),
4763
+ s(:lit, :b).line(3)).line(2),
4764
+ nil).line 1
4765
+
4766
+ assert_parse rb, pt
4767
+ end
4768
+
4769
+ def test_case_in_else
4770
+ rb = "case Array\nin Class\n :b\nelse\n :c\nend\n"
4771
+ pt = s(:case, s(:const, :Array),
4772
+ s(:in, s(:const, :Class).line(2),
4773
+ s(:lit, :b).line(3)).line(2),
4774
+ s(:lit, :c).line(5)).line 1
4775
+
4776
+ assert_parse rb, pt
4777
+ end
4778
+
4779
+ def test_case_in_hash_pat
4780
+ rb = "case :a\nin { b: 'c', d: \"e\" } then\n :f\nend\n"
4781
+ pt = s(:case, s(:lit, :a),
4782
+ s(:in,
4783
+ s(:hash_pat,
4784
+ nil,
4785
+ s(:lit, :b).line(2), s(:str, "c").line(2),
4786
+ s(:lit, :d).line(2), s(:str, "e").line(2)).line(2),
4787
+ s(:lit, :f).line(3)
4788
+ ).line(2),
4789
+ nil)
4790
+
4791
+ assert_parse rb, pt
4792
+ end
4793
+
4794
+ def test_case_in_hash_pat_assign
4795
+ rb = "case :a\nin { b: Integer => x, d: \"e\", f: } then\n :g\nend"
4796
+ pt = s(:case, s(:lit, :a),
4797
+ s(:in,
4798
+ s(:hash_pat,
4799
+ nil,
4800
+ s(:lit, :b).line(2), # =>
4801
+ s(:lasgn, :x, s(:const, :Integer).line(2)).line(2),
4802
+ s(:lit, :d).line(2), s(:str, "e").line(2),
4803
+ s(:lit, :f).line(2), nil).line(2),
4804
+ s(:lit, :g).line(3)).line(2),
4805
+ nil)
4806
+
4807
+ assert_parse rb, pt
4808
+ end
4809
+
4810
+ def test_case_in_hash_pat_paren_assign
4811
+ rb = "case :a\nin B(a: 42)\n :d\nend"
4812
+ pt = s(:case, s(:lit, :a),
4813
+ s(:in,
4814
+ s(:hash_pat,
4815
+ s(:const, :B).line(2),
4816
+ s(:lit, :a).line(2), s(:lit, 42).line(2)).line(2),
4817
+ s(:lit, :d).line(3)).line(2),
4818
+ nil)
4819
+
4820
+ assert_parse rb, pt
4821
+ end
4822
+
4823
+ def test_case_in_hash_pat_paren_true
4824
+ rb = "case :a\nin b: true then\n :c\nend\n"
4825
+ pt = s(:case, s(:lit, :a),
4826
+ s(:in,
4827
+ s(:hash_pat,
4828
+ nil,
4829
+ s(:lit, :b).line(2), s(:true).line(2)).line(2),
4830
+ s(:lit, :c).line(3)).line(2),
4831
+ nil)
4832
+
4833
+ assert_parse rb, pt
4834
+ end
4835
+
4836
+ def test_case_in_hash_pat_rest
4837
+ rb = "case :a\nin b: c, **rest then :d\nend"
4838
+ pt = s(:case,
4839
+ s(:lit, :a),
4840
+ s(:in,
4841
+ s(:hash_pat,
4842
+ nil,
4843
+ s(:lit, :b).line(2),
4844
+ s(:lvar, :c).line(2),
4845
+ s(:kwrest, :"**rest").line(2)).line(2),
4846
+ s(:lit, :d).line(2)).line(2),
4847
+ nil)
4848
+
4849
+ assert_parse rb, pt
4850
+ end
4851
+
4852
+ def test_case_in_hash_pat_rest_solo
4853
+ rb = "case :a\nin **rest then :d\nend"
4854
+ pt = s(:case,
4855
+ s(:lit, :a),
4856
+ s(:in,
4857
+ s(:hash_pat,
4858
+ nil,
4859
+ s(:kwrest, :"**rest").line(2)).line(2),
4860
+ s(:lit, :d).line(2)).line(2),
4861
+ nil)
4862
+
4863
+ assert_parse rb, pt
4864
+ end
4865
+
4866
+ def test_case_in_if_unless_post_mod
4867
+ rb = "case :a\nin A if true\n :C\nin D unless false\n :E\nend"
4868
+ pt = s(:case,
4869
+ s(:lit, :a),
4870
+ s(:in,
4871
+ s(:if, s(:true).line(2), s(:const, :A).line(2), nil).line(2),
4872
+ s(:lit, :C).line(3)).line(2),
4873
+ s(:in,
4874
+ s(:if, s(:false).line(4), nil, s(:const, :D).line(4)).line(4),
4875
+ s(:lit, :E).line(5)).line(4),
4876
+ nil)
4877
+
4878
+ assert_parse rb, pt
4879
+ end
4880
+
4881
+ def test_case_in_multiple
4882
+ rb = "case :a\nin A::B\n :C\nin D::E\n :F\nend"
4883
+ pt = s(:case,
4884
+ s(:lit, :a),
4885
+ s(:in,
4886
+ s(:const, s(:colon2, s(:const, :A).line(2), :B).line(2)).line(2),
4887
+ s(:lit, :C).line(3)).line(2),
4888
+ s(:in,
4889
+ s(:const, s(:colon2, s(:const, :D).line(4), :E).line(4)).line(4),
4890
+ s(:lit, :F).line(5)).line(4),
4891
+ nil)
4892
+
4893
+ assert_parse rb, pt
4894
+ end
4895
+
4896
+ def test_case_in_or
4897
+ rb = "case :a\nin B | C\n :d\nend\n"
4898
+ pt = s(:case, s(:lit, :a),
4899
+ s(:in,
4900
+ s(:or,
4901
+ s(:const, :B).line(2),
4902
+ s(:const, :C).line(2)).line(2),
4903
+ s(:lit, :d).line(3)).line(2),
4904
+ nil)
4905
+
4906
+ assert_parse rb, pt
4907
+ end
4908
+
4909
+ def test_in_expr_no_case
4910
+ rb = "'woot' in String"
4911
+ pt = s(:case, s(:str, "woot"),
4912
+ s(:in, s(:const, :String),
4913
+ nil),
4914
+ nil)
4915
+
4916
+ assert_parse rb, pt
4917
+ end
4918
+
4919
+ def test_parse_pattern_019
4920
+ rb = <<~RUBY
4921
+ case 0
4922
+ in -1..1
4923
+ true
4924
+ end
4925
+ RUBY
4926
+
4927
+ pt = s(:case,
4928
+ s(:lit, 0),
4929
+ s(:in, s(:dot2, s(:lit, -1).line(2), s(:lit, 1).line(2)).line(2),
4930
+ s(:true).line(3)).line(2),
4931
+ nil)
4932
+
4933
+ assert_parse rb, pt
4934
+ end
4935
+
4936
+ def test_parse_pattern_044
4937
+ rb = <<~RUBY
4938
+ case obj
4939
+ in Object[]
4940
+ true
4941
+ end
4942
+ RUBY
4943
+ pt = s(:case,
4944
+ s(:call, nil, :obj),
4945
+ s(:in, s(:array_pat, s(:const, :Object).line(2)).line(2),
4946
+ s(:true).line(3)).line(2),
4947
+ nil)
4948
+
4949
+ assert_parse rb, pt
4950
+ end
4951
+
4952
+ def test_parse_pattern_051
4953
+ rb = <<~RUBY
4954
+ case [0, 1, 2]
4955
+ in [0, 1,]
4956
+ true
4957
+ end
4958
+ RUBY
4959
+ pt = s(:case,
4960
+ s(:array,
4961
+ s(:lit, 0),
4962
+ s(:lit, 1),
4963
+ s(:lit, 2)),
4964
+ s(:in,
4965
+ s(:array_pat,
4966
+ nil,
4967
+ s(:lit, 0).line(2),
4968
+ s(:lit, 1).line(2),
4969
+ :*).line(666),
4970
+ s(:true).line(3)).line(2),
4971
+ nil)
4972
+
4973
+ assert_parse rb, pt
4974
+ end
4975
+
4976
+ def test_parse_pattern_058
4977
+ rb = <<~RUBY
4978
+ case {a: 0}
4979
+ in {a:, **rest}
4980
+ [a, rest]
4981
+ end
4982
+ RUBY
4983
+ pt = s(:case,
4984
+ s(:hash,
4985
+ s(:lit, :a),
4986
+ s(:lit, 0)),
4987
+ s(:in,
4988
+ s(:hash_pat, nil, s(:lit, :a).line(2), nil,
4989
+ s(:kwrest, :"**rest").line(2)).line(2),
4990
+ s(:array,
4991
+ s(:lvar, :a).line(3),
4992
+ s(:lvar, :rest).line(3)).line(3)).line(2),
4993
+ nil)
4994
+
4995
+ assert_parse rb, pt
4996
+ end
4997
+
4998
+ def test_parse_pattern_058_2
4999
+ rb = <<~RUBY
5000
+ case {a: 0}
5001
+ in {a:, **}
5002
+ [a]
5003
+ end
5004
+ RUBY
5005
+ pt = s(:case,
5006
+ s(:hash,
5007
+ s(:lit, :a),
5008
+ s(:lit, 0)),
5009
+ s(:in,
5010
+ s(:hash_pat, nil, s(:lit, :a).line(2), nil,
5011
+ s(:kwrest, :"**").line(2)).line(2),
5012
+ s(:array,
5013
+ s(:lvar, :a).line(3)).line(3)).line(2),
5014
+ nil)
5015
+
5016
+ assert_parse rb, pt
5017
+ end
5018
+
5019
+ def test_parse_pattern_069
5020
+ rb = <<~RUBY
5021
+ case :a
5022
+ in Object[b: 1]
5023
+ 1
5024
+ end
5025
+ RUBY
5026
+ pt = s(:case,
5027
+ s(:lit, :a),
5028
+ s(:in,
5029
+ s(:hash_pat, s(:const, :Object).line(2),
5030
+ s(:lit, :b).line(2), s(:lit, 1).line(2)).line(2),
5031
+ s(:lit, 1).line(3)).line(2),
5032
+ nil)
5033
+
5034
+
5035
+ assert_parse rb, pt
5036
+ end
5037
+
5038
+ def test_parse_pattern_076
5039
+ rb = <<~RUBY
5040
+ case {a: 1}
5041
+ in {a: 1, **nil}
5042
+ true
5043
+ end
5044
+ RUBY
5045
+ pt = s(:case,
5046
+ s(:hash, s(:lit, :a), s(:lit, 1)),
5047
+ s(:in,
5048
+ s(:hash_pat, nil,
5049
+ s(:lit, :a).line(2), s(:lit, 1).line(2),
5050
+ s(:kwrest, :"**nil").line(2)).line(2),
5051
+ s(:true).line(3)).line(2),
5052
+ nil)
5053
+
5054
+ assert_parse rb, pt
5055
+ end
5056
+
5057
+ # def test_case_in_TEMPLATE
5058
+ # rb = "case :a\nin XXX then\n YYY\nend\n"
5059
+ # pt = s(:case, s(:lit, :a),
5060
+ # s(:in,
5061
+ # ZZZ,
5062
+ # WWW).line(2),
5063
+ # nil)
5064
+ #
5065
+ # assert_parse rb, pt
5066
+ # end
5067
+ end
5068
+
5069
+ module TestPatternMatching30
5070
+ def test_case_in_20
5071
+ assert_case_in("Symbol(*lhs, x, *rhs)",
5072
+ s(:find_pat,
5073
+ s(:const, :Symbol).line(2),
5074
+ :"*lhs",
5075
+ s(:array_pat, s(:lvar, :x).line(2)).line(2),
5076
+ :"*rhs").line(2))
5077
+ end
5078
+
5079
+ def test_case_in_22
5080
+ assert_case_in("Symbol[*lhs, x, *rhs]",
5081
+ s(:find_pat, s(:const, :Symbol).line(2),
5082
+ :"*lhs",
5083
+ s(:array_pat, s(:lvar, :x).line(2)).line(2),
5084
+ :"*rhs").line(2))
5085
+ end
5086
+ end
5087
+
5088
+ module TestRubyParserShared27Plus
5089
+ include TestRubyParserShared26Plus
5090
+ include TestPatternMatching
5091
+
5092
+ def test_block_args_kwargs
5093
+ rb = "f { |**kwargs| kwargs }"
5094
+ pt = s(:iter,
5095
+ s(:call, nil, :f),
5096
+ s(:args, :"**kwargs"),
5097
+ s(:lvar, :kwargs))
5098
+
5099
+ assert_parse rb, pt
5100
+ end
5101
+
5102
+ def test_block_args_no_kwargs
5103
+ rb = "f { |**nil| }"
5104
+ pt = s(:iter,
5105
+ s(:call, nil, :f),
5106
+ s(:args, :"**nil"))
5107
+
5108
+ assert_parse rb, pt
5109
+ end
5110
+
5111
+ def test_defn_forward_args
5112
+ rb = "def a(...); b(...); end"
5113
+ pt = s(:defn, :a, s(:args, s(:forward_args)),
5114
+ s(:call, nil, :b, s(:forward_args)))
5115
+
5116
+ assert_parse rb, pt
5117
+ end
5118
+
5119
+ def test_defn_arg_forward_args
5120
+ rb = "def a(x, ...); b(x, ...); end"
4152
5121
  pt = s(:defn, :a, s(:args, :x, s(:forward_args)),
4153
5122
  s(:call, nil, :b, s(:lvar, :x), s(:forward_args)))
4154
5123
 
4155
- assert_parse_line rb, pt, 1
5124
+ assert_parse rb, pt
4156
5125
  end
4157
5126
 
4158
5127
  def test_defn_args_forward_args
@@ -4161,7 +5130,28 @@ module TestRubyParserShared27Plus
4161
5130
  s(:call, nil, :b, s(:lit, :get), s(:lvar, :z),
4162
5131
  s(:forward_args)))
4163
5132
 
4164
- assert_parse_line rb, pt, 1
5133
+ assert_parse rb, pt
5134
+ end
5135
+
5136
+ def test_defn_no_kwargs
5137
+ # def x(**nil)
5138
+ # end
5139
+ #
5140
+ # def y(**kw)
5141
+ # end
5142
+ #
5143
+ # def z()
5144
+ # end
5145
+ #
5146
+ # x arg: 42 # $!: no keywords accepted (ArgumentError)
5147
+ # y arg: 42 # fine
5148
+ # z arg: 42 # $!: wrong number of arguments (given 1, expected 0) (ArgumentError)
5149
+
5150
+ rb = "def x(**nil); end"
5151
+ pt = s(:defn, :x, s(:args, :"**nil"),
5152
+ s(:nil))
5153
+
5154
+ assert_parse rb, pt
4165
5155
  end
4166
5156
 
4167
5157
  def test_call_forward_args_outside_method_definition
@@ -4175,12 +5165,259 @@ module TestRubyParserShared27Plus
4175
5165
 
4176
5166
  assert_syntax_error rb, "Unexpected ..."
4177
5167
  end
5168
+
5169
+ def test_mlhs_rescue
5170
+ # same:
5171
+ # a = (24 rescue 42)
5172
+ # a = 24 rescue 42
5173
+
5174
+ # same:
5175
+ # a, b = (f rescue 42)
5176
+ # a, b = f rescue 42
5177
+
5178
+ rb = "a, b = f rescue 42"
5179
+ pt = s(:masgn,
5180
+ s(:array, s(:lasgn, :a), s(:lasgn, :b)),
5181
+ s(:to_ary,
5182
+ s(:rescue,
5183
+ s(:call, nil, :f),
5184
+ s(:resbody, s(:array),
5185
+ s(:lit, 42)))))
5186
+
5187
+ assert_parse rb, pt
5188
+ end
4178
5189
  end
4179
5190
 
4180
5191
  module TestRubyParserShared30Plus
4181
5192
  include TestRubyParserShared27Plus
5193
+ include TestPatternMatching30
5194
+
5195
+ def test_rhs_asgn
5196
+ rb = "42 => n"
5197
+ pt = s(:case,
5198
+ s(:lit, 42),
5199
+ s(:in, s(:lvar, :n), nil), nil)
5200
+
5201
+ assert_parse rb, pt
5202
+ end
5203
+
5204
+ def test_case_in_find
5205
+ rb = "case :a\n in *a, :+, *b\nend"
5206
+ pt = s(:case,
5207
+ s(:lit, :a),
5208
+ s(:in,
5209
+ s(:find_pat, nil,
5210
+ :"*a",
5211
+ s(:array_pat, s(:lit, :+).line(2)).line(2),
5212
+ :"*b").line(2),
5213
+ nil).line(2),
5214
+ nil)
5215
+
5216
+ assert_parse rb, pt
5217
+ end
5218
+
5219
+ def test_case_in_find_array
5220
+ rb = "case :a\nin [*, :b, c, *]\nend"
5221
+ pt = s(:case,
5222
+ s(:lit, :a),
5223
+ s(:in,
5224
+ s(:find_pat, nil,
5225
+ :*,
5226
+ s(:array_pat, s(:lit, :b).line(2), s(:lvar, :c).line(2)).line(2),
5227
+ :*).line(2),
5228
+ nil).line(2),
5229
+ nil)
5230
+
5231
+ assert_parse rb, pt
5232
+ end
5233
+
5234
+ def test_defn_oneliner
5235
+ rb = "def exec(cmd) = system(cmd)"
5236
+ pt = s(:defn, :exec, s(:args, :cmd),
5237
+ s(:call, nil, :system, s(:lvar, :cmd)))
5238
+
5239
+ assert_parse rb, pt
5240
+ end
5241
+
5242
+ def test_defn_oneliner_noargs_parentheses
5243
+ rb = "def exec() = system"
5244
+ pt = s(:defn, :exec, s(:args),
5245
+ s(:call, nil, :system))
5246
+
5247
+ assert_parse rb, pt
5248
+ end
5249
+
5250
+ def test_defn_oneliner_noargs
5251
+ rb = "def exec = system"
5252
+ pt = s(:defn, :exec, s(:args),
5253
+ s(:call, nil, :system))
5254
+
5255
+ assert_parse rb, pt
5256
+ end
5257
+
5258
+ def test_defn_oneliner_rescue
5259
+ rb = "def exec(cmd)\n system(cmd)\nrescue\n nil\nend\n"
5260
+ pt = s(:defn, :exec, s(:args, :cmd),
5261
+ s(:rescue,
5262
+ s(:call, nil, :system, s(:lvar, :cmd).line(2)).line(2),
5263
+ s(:resbody, s(:array).line(3),
5264
+ s(:nil).line(4)).line(3)).line(2))
5265
+
5266
+ assert_parse rb, pt
5267
+
5268
+ rb = "def exec(cmd)\n system(cmd) rescue nil\nend\n"
5269
+ assert_parse rb, pt.deep_each { |s| s.line = 2 if s.line && s.line > 1 }
5270
+
5271
+ rb = "def exec(cmd) = system(cmd) rescue nil"
5272
+ assert_parse rb, pt.deep_each { |s| s.line = 1 }
5273
+ end
5274
+
5275
+ def test_defs_oneliner
5276
+ rb = "def self.exec(cmd) = system(cmd)"
5277
+ pt = s(:defs, s(:self), :exec, s(:args, :cmd),
5278
+ s(:call, nil, :system, s(:lvar, :cmd)))
5279
+
5280
+ assert_parse rb, pt
5281
+ end
5282
+
5283
+ def test_defs_oneliner_rescue
5284
+ rb = "def self.exec(cmd)\n system(cmd)\nrescue\n nil\nend\n"
5285
+ pt = s(:defs, s(:self), :exec, s(:args, :cmd),
5286
+ s(:rescue,
5287
+ s(:call, nil, :system, s(:lvar, :cmd).line(2)).line(2),
5288
+ s(:resbody, s(:array).line(3), s(:nil).line(4)).line(3)).line(2))
5289
+ assert_parse rb, pt
5290
+
5291
+ rb = "def self.exec(cmd)\n system(cmd) rescue nil\nend\n"
5292
+ assert_parse rb, pt.deep_each { |s| s.line = 2 if s.line && s.line > 1 }
5293
+
5294
+ rb = "def self.exec(cmd) = system(cmd) rescue nil"
5295
+ assert_parse rb, pt.deep_each { |s| s.line = 1 }
5296
+ end
5297
+
5298
+ def test_defn_oneliner_setter
5299
+ rb = "class X\n def x=(o) = 42\nend"
5300
+
5301
+ assert_syntax_error rb, /setter method cannot be defined/
5302
+ end
5303
+
5304
+ def test_defs_oneliner_setter
5305
+ rb = "class X\n def self.x= = 42\nend"
5306
+
5307
+ assert_syntax_error rb, /setter method cannot be defined/
5308
+ end
5309
+ end
5310
+
5311
+ module TestRubyParserShared31Plus
5312
+ include TestRubyParserShared30Plus
5313
+
5314
+ def test_assoc__bare
5315
+ rb = "{ y: }"
5316
+ pt = s(:hash, s(:lit, :y), nil)
5317
+
5318
+ assert_parse rb, pt
5319
+ end
5320
+
5321
+ def test_block_arg__bare
5322
+ rb = "def x(&); end"
5323
+ pt = s(:defn, :x, s(:args, :&).line(1),
5324
+ s(:nil).line(1)).line(1)
5325
+
5326
+ assert_parse rb, pt
5327
+ end
5328
+
5329
+ def test_case_in_carat_parens
5330
+ processor.env[:a] = :lvar
5331
+
5332
+ rb = "[^(a)]"
5333
+ pt = s(:array_pat, nil,
5334
+ s(:lvar, :a).line(2)).line(2)
5335
+
5336
+ assert_case_in rb, pt
5337
+ end
5338
+
5339
+ def test_case_in_carat_nonlocal_vars
5340
+ processor.env[:a] = :lvar
5341
+
5342
+ rb = "[^@a, ^$b, ^@@c]"
5343
+ pt = s(:array_pat,
5344
+ nil,
5345
+ s(:ivar, :@a).line(2),
5346
+ s(:gvar, :$b).line(2),
5347
+ s(:cvar, :@@c).line(2)).line(2)
5348
+
5349
+ assert_case_in rb, pt
5350
+ end
5351
+
5352
+ def test_case_in_quoted_label
5353
+ rb = " \"b\": "
5354
+ pt = s(:hash_pat, nil, s(:lit, :b).line(2), nil).line(2)
5355
+
5356
+ assert_case_in rb, pt
5357
+ end
5358
+
5359
+ def test_call_block_arg_named
5360
+ processor.env[:blk] = :lvar
5361
+ rb = "x(&blk)"
5362
+ pt = s(:call, nil, :x,
5363
+ s(:block_pass, s(:lvar, :blk).line(1)).line(1)).line(1)
5364
+
5365
+ assert_parse rb, pt
5366
+ end
5367
+
5368
+ def test_call_block_arg_unnamed
5369
+ rb = "x(&)"
5370
+ pt = s(:call, nil, :x,
5371
+ s(:block_pass).line(1)).line(1)
5372
+
5373
+ assert_parse rb, pt
5374
+ end
5375
+
5376
+ def test_defn_endless_command
5377
+ rb = "def some_method = other_method 42"
5378
+ pt = s(:defn, :some_method, s(:args).line(1),
5379
+ s(:call, nil, :other_method, s(:lit, 42).line(1)).line(1)).line(1)
5380
+
5381
+ assert_parse rb, pt
5382
+ end
5383
+
5384
+ def test_defn_endless_command_rescue
5385
+ rb = "def some_method = other_method 42 rescue 24"
5386
+ pt = s(:defn, :some_method, s(:args).line(1),
5387
+ s(:rescue,
5388
+ s(:call, nil, :other_method, s(:lit, 42).line(1)).line(1),
5389
+ s(:resbody, s(:array).line(1),
5390
+ s(:lit, 24).line(1)).line(1)).line(1)).line(1)
5391
+
5392
+ assert_parse rb, pt
5393
+ end
5394
+
5395
+ def test_defs_endless_command
5396
+ rb = "def x.some_method = other_method 42"
5397
+ pt = s(:defs, s(:call, nil, :x).line(1), :some_method, s(:args).line(1),
5398
+ s(:call, nil, :other_method, s(:lit, 42).line(1)).line(1)).line(1)
5399
+
5400
+ assert_parse rb, pt
5401
+ end
5402
+
5403
+ def test_defs_endless_command_rescue
5404
+ rb = "def x.some_method = other_method 42 rescue 24"
5405
+ pt = s(:defs, s(:call, nil, :x).line(1), :some_method, s(:args).line(1),
5406
+ s(:rescue,
5407
+ s(:call, nil, :other_method, s(:lit, 42).line(1)).line(1),
5408
+ s(:resbody, s(:array).line(1),
5409
+ s(:lit, 24).line(1)).line(1)).line(1)).line(1)
5410
+
5411
+ assert_parse rb, pt
5412
+ end
4182
5413
  end
4183
5414
 
5415
+ class Minitest::Test
5416
+ def skip s = "blah"
5417
+ warn "ignoring skip for %s: %s" % [name, s]
5418
+ end
5419
+ end if ENV["NOSKIP"]
5420
+
4184
5421
  class TestRubyParser < Minitest::Test
4185
5422
  def test_cls_version
4186
5423
  assert_equal 23, RubyParser::V23.version
@@ -4204,7 +5441,7 @@ class TestRubyParser < Minitest::Test
4204
5441
  end
4205
5442
  end
4206
5443
 
4207
- assert_includes e.message, 'parse error on value false ($end)'
5444
+ assert_includes e.message, 'parse error on value "$" ($end)'
4208
5445
  end
4209
5446
 
4210
5447
  def test_parse_error_from_first
@@ -4217,7 +5454,7 @@ class TestRubyParser < Minitest::Test
4217
5454
  end
4218
5455
 
4219
5456
  # This is a 2.x error, will fail on 1.8/1.9.
4220
- assert_includes e.message, 'parse error on value false ($end)'
5457
+ assert_includes e.message, 'parse error on value "$" ($end)'
4221
5458
  end
4222
5459
  end
4223
5460
 
@@ -4239,8 +5476,18 @@ class RubyParserTestCase < ParseTreeTestCase
4239
5476
  super
4240
5477
  end
4241
5478
 
5479
+ attr_accessor :assert_parse_ran
5480
+
4242
5481
  def assert_parse rb, pt
4243
- self.result = processor.parse rb
5482
+ self.processor.reset if assert_parse_ran # allows multiple calls
5483
+ self.assert_parse_ran = true
5484
+
5485
+ timeout = (ENV["RP_TIMEOUT"] || 10).to_i
5486
+
5487
+ pt.deep_each { |s| s.line ||= 1 }
5488
+ pt.line ||= 1
5489
+
5490
+ self.result = processor.parse rb, "(string)", timeout
4244
5491
  assert_equal pt, result
4245
5492
  end
4246
5493
 
@@ -4259,25 +5506,20 @@ class RubyParserTestCase < ParseTreeTestCase
4259
5506
  end
4260
5507
  end
4261
5508
 
4262
- def assert_parse_line rb, pt, line
4263
- old_env = ENV["VERBOSE"]
4264
- ENV["VERBOSE"] = "1"
4265
-
4266
- assert_parse rb, pt
4267
- assert_equal line, result.line, "call should have line number"
4268
- ensure
4269
- ENV["VERBOSE"] = old_env
4270
- end
4271
-
4272
- def assert_syntax_error rb, emsg
5509
+ def assert_syntax_error rb, emsg, klass = RubyParser::SyntaxError
4273
5510
  e = nil
4274
5511
  assert_silent do
4275
- e = assert_raises RubyParser::SyntaxError do
5512
+ e = assert_raises klass do
4276
5513
  processor.parse rb
4277
5514
  end
4278
5515
  end
4279
5516
 
4280
- assert_equal emsg, e.message
5517
+ case emsg
5518
+ when String
5519
+ assert_equal emsg, e.message
5520
+ else
5521
+ assert_match emsg, e.message
5522
+ end
4281
5523
  end
4282
5524
 
4283
5525
  def refute_parse rb
@@ -4294,17 +5536,6 @@ class TestRubyParserV20 < RubyParserTestCase
4294
5536
 
4295
5537
  self.processor = RubyParser::V20.new
4296
5538
  end
4297
-
4298
- def test_bug162__20
4299
- skip "not ready for this yet"
4300
-
4301
- # Ignore everything after \r in heredoc marker in <= 2.0 #162
4302
-
4303
- rb = %q(<<E\nfoo\nE\rO)
4304
- pt = s(:str, "foo\n")
4305
-
4306
- assert_parse rb, pt
4307
- end
4308
5539
  end
4309
5540
 
4310
5541
  class TestRubyParserV21 < RubyParserTestCase
@@ -4363,7 +5594,7 @@ class TestRubyParserV24 < RubyParserTestCase
4363
5594
 
4364
5595
  assert_parse rb, pt
4365
5596
 
4366
- assert_parse_error "a(b rescue c)", /parse error on value ..rescue/
5597
+ assert_parse_error "a(b rescue c)", /parse error on value .rescue/
4367
5598
  end
4368
5599
  end
4369
5600
 
@@ -4380,11 +5611,10 @@ class TestRubyParserV25 < RubyParserTestCase
4380
5611
  rb = "proc do\n :begin\nensure\n :ensure\nend.call"
4381
5612
  pt = s(:call,
4382
5613
  s(:iter,
4383
- s(:call, nil, :proc),
4384
- 0,
5614
+ s(:call, nil, :proc), 0,
4385
5615
  s(:ensure,
4386
- s(:lit, :begin),
4387
- s(:lit, :ensure))),
5616
+ s(:lit, :begin).line(2),
5617
+ s(:lit, :ensure).line(4)).line(2)),
4388
5618
  :call)
4389
5619
 
4390
5620
  assert_parse rb, pt
@@ -4393,16 +5623,14 @@ class TestRubyParserV25 < RubyParserTestCase
4393
5623
  def test_rescue_do_end_no_raise
4394
5624
  rb = "tap do\n :begin\nrescue\n :rescue\nelse\n :else\nensure\n :ensure\nend"
4395
5625
  pt = s(:iter,
4396
- s(:call, nil, :tap),
4397
- 0,
5626
+ s(:call, nil, :tap), 0,
4398
5627
  s(:ensure,
4399
5628
  s(:rescue,
4400
- s(:lit, :begin),
4401
- s(:resbody,
4402
- s(:array),
4403
- s(:lit, :rescue)),
4404
- s(:lit, :else)),
4405
- s(:lit, :ensure)))
5629
+ s(:lit, :begin).line(2),
5630
+ s(:resbody, s(:array).line(3),
5631
+ s(:lit, :rescue).line(4)).line(3),
5632
+ s(:lit, :else).line(6)).line(2),
5633
+ s(:lit, :ensure).line(8)).line(2))
4406
5634
 
4407
5635
  assert_parse rb, pt
4408
5636
  end
@@ -4410,11 +5638,10 @@ class TestRubyParserV25 < RubyParserTestCase
4410
5638
  def test_rescue_do_end_raised
4411
5639
  rb = "tap do\n raise\nensure\n :ensure\nend"
4412
5640
  pt = s(:iter,
4413
- s(:call, nil, :tap),
4414
- 0,
5641
+ s(:call, nil, :tap), 0,
4415
5642
  s(:ensure,
4416
- s(:call, nil, :raise),
4417
- s(:lit, :ensure)))
5643
+ s(:call, nil, :raise).line(2),
5644
+ s(:lit, :ensure).line(4)).line(2))
4418
5645
 
4419
5646
  assert_parse rb, pt
4420
5647
  end
@@ -4426,12 +5653,12 @@ class TestRubyParserV25 < RubyParserTestCase
4426
5653
  0,
4427
5654
  s(:ensure,
4428
5655
  s(:rescue,
4429
- s(:call, nil, :raise),
5656
+ s(:call, nil, :raise).line(2),
4430
5657
  s(:resbody,
4431
- s(:array),
4432
- s(:lit, :rescue)),
4433
- s(:lit, :else)),
4434
- s(:lit, :ensure)))
5658
+ s(:array).line(3),
5659
+ s(:lit, :rescue).line(4)).line(3),
5660
+ s(:lit, :else).line(6)).line(2),
5661
+ s(:lit, :ensure).line(8)).line(2))
4435
5662
 
4436
5663
  assert_parse rb, pt
4437
5664
  end
@@ -4439,9 +5666,11 @@ class TestRubyParserV25 < RubyParserTestCase
4439
5666
  def test_rescue_in_block
4440
5667
  rb = "blah do\nrescue\n stuff\nend"
4441
5668
  pt = s(:iter,
4442
- s(:call, nil, :blah),
4443
- 0,
4444
- s(:rescue, s(:resbody, s(:array), s(:call, nil, :stuff))))
5669
+ s(:call, nil, :blah), 0,
5670
+ s(:rescue,
5671
+ s(:resbody, s(:array).line(2),
5672
+ s(:call, nil, :stuff).line(3)).line(2)).line(2))
5673
+
4445
5674
  assert_parse rb, pt
4446
5675
  end
4447
5676
  end
@@ -4458,25 +5687,27 @@ class TestRubyParserV26 < RubyParserTestCase
4458
5687
  def test_parse_line_dot2_open
4459
5688
  rb = "0..\n; a..\n; c"
4460
5689
  pt = s(:block,
4461
- s(:dot2, s(:lit, 0).line(1), nil).line(1),
5690
+ s(:dot2, s(:lit, 0), nil),
4462
5691
  s(:dot2, s(:call, nil, :a).line(2), nil).line(2),
4463
- s(:call, nil, :c).line(3)).line(1)
5692
+ s(:call, nil, :c).line(3))
4464
5693
 
4465
- assert_parse_line rb, pt, 1
5694
+ assert_parse rb, pt
4466
5695
  end
4467
5696
 
4468
5697
  def test_parse_line_dot3_open
4469
5698
  rb = "0...\n; a...\n; c"
4470
5699
  pt = s(:block,
4471
- s(:dot3, s(:lit, 0).line(1), nil).line(1),
5700
+ s(:dot3, s(:lit, 0), nil),
4472
5701
  s(:dot3, s(:call, nil, :a).line(2), nil).line(2),
4473
- s(:call, nil, :c).line(3)).line(1)
5702
+ s(:call, nil, :c).line(3))
4474
5703
 
4475
- assert_parse_line rb, pt, 1
5704
+ assert_parse rb, pt
4476
5705
  end
4477
5706
  end
4478
5707
 
4479
5708
  class TestRubyParserV27 < RubyParserTestCase
5709
+ make_my_diffs_pretty!
5710
+
4480
5711
  include TestRubyParserShared27Plus
4481
5712
 
4482
5713
  def setup
@@ -4488,21 +5719,21 @@ class TestRubyParserV27 < RubyParserTestCase
4488
5719
  def test_bdot2
4489
5720
  rb = "..10\n; ..a\n; c"
4490
5721
  pt = s(:block,
4491
- s(:dot2, nil, s(:lit, 10).line(1)).line(1),
5722
+ s(:dot2, nil, s(:lit, 10)),
4492
5723
  s(:dot2, nil, s(:call, nil, :a).line(2)).line(2),
4493
- s(:call, nil, :c).line(3)).line(1)
5724
+ s(:call, nil, :c).line(3))
4494
5725
 
4495
- assert_parse_line rb, pt, 1
5726
+ assert_parse rb, pt
4496
5727
  end
4497
5728
 
4498
5729
  def test_bdot3
4499
5730
  rb = "...10\n; ...a\n; c"
4500
5731
  pt = s(:block,
4501
- s(:dot3, nil, s(:lit, 10).line(1)).line(1),
5732
+ s(:dot3, nil, s(:lit, 10)),
4502
5733
  s(:dot3, nil, s(:call, nil, :a).line(2)).line(2),
4503
- s(:call, nil, :c).line(3)).line(1)
5734
+ s(:call, nil, :c).line(3))
4504
5735
 
4505
- assert_parse_line rb, pt, 1
5736
+ assert_parse rb, pt
4506
5737
  end
4507
5738
  end
4508
5739
 
@@ -4516,6 +5747,16 @@ class TestRubyParserV30 < RubyParserTestCase
4516
5747
  end
4517
5748
  end
4518
5749
 
5750
+ class TestRubyParserV31 < RubyParserTestCase
5751
+ include TestRubyParserShared31Plus
5752
+
5753
+ def setup
5754
+ super
5755
+
5756
+ self.processor = RubyParser::V31.new
5757
+ end
5758
+ end
5759
+
4519
5760
  RubyParser::VERSIONS.each do |klass|
4520
5761
  v = klass.version
4521
5762
  describe "block args arity #{v}" do