ruby_parser 3.15.1 → 3.18.1

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.
@@ -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,6 +3176,31 @@ module TestRubyParserShared19Plus
3079
3176
  assert_parse rb, pt
3080
3177
  end
3081
3178
 
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
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
+
3082
3204
  def test_motherfuckin_leading_dots
3083
3205
  rb = "a\n.b"
3084
3206
  pt = s(:call, s(:call, nil, :a), :b)
@@ -3087,9 +3209,15 @@ module TestRubyParserShared19Plus
3087
3209
  end
3088
3210
 
3089
3211
  def test_motherfuckin_leading_dots2
3090
- 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))
3091
3215
 
3092
- 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
3093
3221
  end
3094
3222
 
3095
3223
  def test_multiline_hash_declaration
@@ -3097,6 +3225,8 @@ module TestRubyParserShared19Plus
3097
3225
 
3098
3226
  assert_parse "f(state: {})", pt
3099
3227
  assert_parse "f(state: {\n})", pt
3228
+
3229
+ pt = s(:call, nil, :f, s(:hash, s(:lit, :state), s(:hash).line(2)))
3100
3230
  assert_parse "f(state:\n {\n})", pt
3101
3231
  end
3102
3232
 
@@ -3159,7 +3289,7 @@ module TestRubyParserShared19Plus
3159
3289
  rb = "until not var.nil?\n 'foo'\nend"
3160
3290
  pt = s(:until,
3161
3291
  s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
3162
- s(:str, "foo"), true)
3292
+ s(:str, "foo").line(2), true)
3163
3293
 
3164
3294
  assert_parse rb, pt
3165
3295
  end
@@ -3168,7 +3298,7 @@ module TestRubyParserShared19Plus
3168
3298
  rb = "until not var.nil?\n 'foo'\nend"
3169
3299
  pt = s(:until,
3170
3300
  s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
3171
- s(:str, "foo"), true)
3301
+ s(:str, "foo").line(2), true)
3172
3302
 
3173
3303
  processor.canonicalize_conditions = false
3174
3304
 
@@ -3179,7 +3309,7 @@ module TestRubyParserShared19Plus
3179
3309
  rb = "while not var.nil?\n 'foo'\nend"
3180
3310
  pt = s(:while,
3181
3311
  s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
3182
- s(:str, "foo"), true)
3312
+ s(:str, "foo").line(2), true)
3183
3313
 
3184
3314
  assert_parse rb, pt
3185
3315
  end
@@ -3188,7 +3318,7 @@ module TestRubyParserShared19Plus
3188
3318
  rb = "while not var.nil?\n 'foo'\nend"
3189
3319
  pt = s(:while,
3190
3320
  s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
3191
- s(:str, "foo"), true)
3321
+ s(:str, "foo").line(2), true)
3192
3322
 
3193
3323
  processor.canonicalize_conditions = false
3194
3324
 
@@ -3352,14 +3482,16 @@ module TestRubyParserShared19Plus
3352
3482
  RUBY
3353
3483
 
3354
3484
  pt = s(:hash,
3355
- s(:lit, :a),
3485
+ s(:lit, :a).line(2),
3356
3486
  s(:iter,
3357
- s(:call, nil, :lambda),
3487
+ s(:call, nil, :lambda).line(2),
3358
3488
  0,
3359
- 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),
3360
3492
 
3361
- s(:lit, :e),
3362
- s(:nil))
3493
+ s(:lit, :e).line(3),
3494
+ s(:nil).line(3))
3363
3495
 
3364
3496
  assert_parse rb, pt
3365
3497
  end
@@ -3368,6 +3500,98 @@ end
3368
3500
  module TestRubyParserShared20Plus
3369
3501
  include TestRubyParserShared19Plus
3370
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
+ rb = "/\\cC\\d/"
3545
+ pt = s(:lit, /\cC\d/)
3546
+
3547
+ assert_parse rb, pt
3548
+ end
3549
+
3550
+ def test_heredoc_wtf_I_hate_you
3551
+ rb = "p <<-END+'b\n a\n END\n c'+'d'"
3552
+ pt = s(:call, nil, :p,
3553
+ s(:call,
3554
+ s(:call, s(:str, " a\n"), :+,
3555
+ s(:str, "b\n c")),
3556
+ :+, s(:str, "d").line(4)))
3557
+
3558
+ assert_parse rb, pt
3559
+ end
3560
+
3561
+ def test_heredoc_nested
3562
+ rb = "[<<A,\n\#{<<B}\nb\nB\na\nA\n0]"
3563
+ pt = s(:array, s(:str, "b\n\na\n"),
3564
+ s(:lit, 0).line(7))
3565
+
3566
+ assert_parse rb, pt
3567
+ end
3568
+
3569
+ def test_pct_w_heredoc_interp_nested
3570
+ rb = "%W( 1 \#{<<A} 3\n2\nA\n 4 5 )"
3571
+ pt = s(:array,
3572
+ s(:str, "1"),
3573
+ s(:str, "2\n"),
3574
+ s(:str, "3"),
3575
+ s(:str, "4").line(4),
3576
+ s(:str, "5").line(4))
3577
+
3578
+ assert_parse rb, pt
3579
+ end
3580
+
3581
+ def test_regexp_esc_u
3582
+ rb = "/[\\u0021-\\u0027]/"
3583
+ pt = s(:lit, /[\u0021-\u0027]/)
3584
+
3585
+ assert_parse rb, pt
3586
+ end
3587
+
3588
+ def test_qw_escape_term
3589
+ rb = "%q|blah blah \\| blah blah|"
3590
+ pt = s(:str, "blah blah | blah blah")
3591
+
3592
+ assert_parse rb, pt
3593
+ end
3594
+
3371
3595
  def test_args_kw_block
3372
3596
  rb = "def f(a: 1, &b); end"
3373
3597
  pt = s(:defn, :f, s(:args, s(:kwarg, :a, s(:lit, 1)), :"&b"), s(:nil))
@@ -3375,6 +3599,49 @@ module TestRubyParserShared20Plus
3375
3599
  assert_parse rb, pt
3376
3600
  end
3377
3601
 
3602
+ def test_heredoc_backslash_nl
3603
+ rb = %Q(" why would someone do this? \\\n blah\n")
3604
+ pt = s(:str, " why would someone do this? blah\n")
3605
+
3606
+ assert_parse rb, pt
3607
+
3608
+ rb = "<<-DESC\n why would someone do this? \\\n blah\nDESC"
3609
+
3610
+ assert_parse rb, pt
3611
+ end
3612
+
3613
+ def test_heredoc_comma_arg
3614
+ rb = "[\" some text\n\",]"
3615
+ pt = s(:array, s(:str, " some text\n"))
3616
+
3617
+ assert_parse rb, pt
3618
+
3619
+ rb = "[<<-FILE,\n some text\nFILE\n]"
3620
+
3621
+ assert_parse rb, pt
3622
+ end
3623
+
3624
+ def test_heredoc_trailing_slash_continued_call
3625
+ rb = "<<END\\\nblah\nEND\n.strip"
3626
+ pt = s(:call, s(:str, "blah\n"), :strip)
3627
+
3628
+ assert_parse rb, pt
3629
+ end
3630
+
3631
+ def test_pct_q_backslash_nl
3632
+ rb = "%q{ \\\n}"
3633
+ pt = s(:str, " \\\n")
3634
+
3635
+ assert_parse rb, pt
3636
+ end
3637
+
3638
+ def test_pct_Q_backslash_nl
3639
+ rb = "%Q{ \\\n}"
3640
+ pt = s(:str, " ")
3641
+
3642
+ assert_parse rb, pt
3643
+ end
3644
+
3378
3645
  def test_block_arg_kwsplat
3379
3646
  rb = "a { |**b| }"
3380
3647
  pt = s(:iter, s(:call, nil, :a), s(:args, :"**b"))
@@ -3411,7 +3678,7 @@ module TestRubyParserShared20Plus
3411
3678
  rb = "a (b)\nc.d do end"
3412
3679
  pt = s(:block,
3413
3680
  s(:call, nil, :a, s(:call, nil, :b)),
3414
- s(:iter, s(:call, s(:call, nil, :c), :d), 0))
3681
+ s(:iter, s(:call, s(:call, nil, :c).line(2), :d).line(2), 0).line(2))
3415
3682
 
3416
3683
 
3417
3684
  assert_parse rb, pt
@@ -3421,8 +3688,9 @@ module TestRubyParserShared20Plus
3421
3688
  rb = "a def b(c)\n d\n end\n e.f do end"
3422
3689
  pt = s(:block,
3423
3690
  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))
3691
+ s(:defn, :b, s(:args, :c),
3692
+ s(:call, nil, :d).line(2))),
3693
+ s(:iter, s(:call, s(:call, nil, :e).line(4), :f).line(4), 0).line(4))
3426
3694
 
3427
3695
  assert_parse rb, pt
3428
3696
  end
@@ -3440,7 +3708,9 @@ module TestRubyParserShared20Plus
3440
3708
  def test_call_begin_call_block_call
3441
3709
  rb = "a begin\nb.c do end\nend"
3442
3710
  pt = s(:call, nil, :a,
3443
- s(:iter, s(:call, s(:call, nil, :b), :c), 0))
3711
+ s(:iter,
3712
+ s(:call, s(:call, nil, :b).line(2), :c).line(2),
3713
+ 0).line(2))
3444
3714
 
3445
3715
  assert_parse rb, pt
3446
3716
  end
@@ -3451,7 +3721,7 @@ module TestRubyParserShared20Plus
3451
3721
  s(:op_asgn, s(:const, :B),
3452
3722
  s(:call, nil, :d, s(:call, nil, :e)),
3453
3723
  :C,
3454
- :*)).line(1)
3724
+ :*))
3455
3725
 
3456
3726
  assert_parse rb, pt
3457
3727
  end
@@ -3509,9 +3779,9 @@ module TestRubyParserShared20Plus
3509
3779
  s(:iter,
3510
3780
  s(:call, s(:const, :Class), :new),
3511
3781
  0,
3512
- s(:defn, :initialize, s(:args), s(:nil))),
3782
+ s(:defn, :initialize, s(:args).line(2), s(:nil).line(2)).line(2)),
3513
3783
  :new),
3514
- s(:hash, s(:lit, :at), s(:str, "endpoint")))
3784
+ s(:hash, s(:lit, :at).line(4), s(:str, "endpoint").line(4)).line(4))
3515
3785
 
3516
3786
  assert_parse rb, pt
3517
3787
  end
@@ -3618,20 +3888,23 @@ module TestRubyParserShared20Plus
3618
3888
  pt = s(:block,
3619
3889
  s(:array,
3620
3890
  s(:lit, :a).line(2),
3621
- s(:lit, :b).line(3)).line(1),
3891
+ s(:lit, :b).line(3)),
3622
3892
  s(:lit, 1).line(5))
3623
3893
  assert_parse rb, pt
3624
3894
  end
3625
3895
 
3626
3896
  def test_iter_array_curly
3627
- skip if processor.class.version >= 25
3628
-
3629
3897
  rb = "f :a, [:b] { |c, d| }" # yes, this is bad code... that's their problem
3630
3898
  pt = s(:iter,
3631
3899
  s(:call, nil, :f, s(:lit, :a), s(:array, s(:lit, :b))),
3632
3900
  s(:args, :c, :d))
3633
3901
 
3634
- assert_parse rb, pt
3902
+ if processor.class.version >= 25 then
3903
+ msg = /parse error on value "\{" \(tLCURLY\)/
3904
+ assert_syntax_error rb, msg, Racc::ParseError
3905
+ else
3906
+ assert_parse rb, pt
3907
+ end
3635
3908
  end
3636
3909
 
3637
3910
  def test_iter_kwarg
@@ -3653,7 +3926,7 @@ module TestRubyParserShared20Plus
3653
3926
  pt = s(:block,
3654
3927
  s(:array,
3655
3928
  s(:lit, :a).line(2),
3656
- s(:lit, :b).line(3)).line(1),
3929
+ s(:lit, :b).line(3)),
3657
3930
  s(:lit, 1).line(5))
3658
3931
  assert_parse rb, pt
3659
3932
  end
@@ -3695,7 +3968,7 @@ module TestRubyParserShared20Plus
3695
3968
  s(:iter,
3696
3969
  s(:lambda),
3697
3970
  s(:args),
3698
- s(:iter, s(:call, s(:call, nil, :a), :b), 0)))
3971
+ s(:iter, s(:call, s(:call, nil, :a).line(2), :b).line(2), 0).line(2)))
3699
3972
 
3700
3973
  assert_parse rb, pt
3701
3974
  end
@@ -3708,7 +3981,7 @@ module TestRubyParserShared20Plus
3708
3981
  s(:args),
3709
3982
  s(:iter,
3710
3983
  s(:call, nil, :a,
3711
- s(:lit, 1)), 0)))
3984
+ s(:lit, 1).line(2)).line(2), 0).line(2)))
3712
3985
 
3713
3986
  assert_parse rb, pt
3714
3987
  end
@@ -3745,6 +4018,17 @@ end
3745
4018
  module TestRubyParserShared21Plus
3746
4019
  include TestRubyParserShared20Plus
3747
4020
 
4021
+ def test_array_lits_trailing_calls
4022
+ rb = "[].b"
4023
+ pt = s(:call, s(:array), :b)
4024
+
4025
+ assert_parse rb, pt
4026
+
4027
+ rb = "%w[].b"
4028
+
4029
+ assert_parse rb, pt
4030
+ end
4031
+
3748
4032
  def test_block_kw
3749
4033
  rb = "blah { |k:42| }"
3750
4034
  pt = s(:iter, s(:call, nil, :blah), s(:args, s(:kwarg, :k, s(:lit, 42))))
@@ -3767,7 +4051,7 @@ module TestRubyParserShared21Plus
3767
4051
 
3768
4052
  def test_bug162__21plus
3769
4053
  rb = %q(<<E\nfoo\nE\rO)
3770
- emsg = "can't match /E(\\r*\\n|\\z)/ anywhere in . near line 1: \"\""
4054
+ emsg = "can't match /E(?=\\r?\\n|\\z)/ anywhere in . near line 1: \"\""
3771
4055
 
3772
4056
  assert_syntax_error rb, emsg
3773
4057
  end
@@ -3804,8 +4088,8 @@ module TestRubyParserShared21Plus
3804
4088
  CODE
3805
4089
 
3806
4090
  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)
4091
+ s(:str, "\n\n\n\n\n\n\n\n\n\n"),
4092
+ s(:class, :Foo, nil).line(5))
3809
4093
 
3810
4094
  assert_parse rb, pt
3811
4095
  end
@@ -3934,8 +4218,8 @@ module TestRubyParserShared23Plus
3934
4218
  def test_heredoc_squiggly_interp
3935
4219
  rb = "a = <<~EOF\n w\n x#\{42} y\n z\n EOF"
3936
4220
  pt = s(:lasgn, :a, s(:dstr, " w\nx",
3937
- s(:evstr, s(:lit, 42)),
3938
- s(:str, " y\n z\n")))
4221
+ s(:evstr, s(:lit, 42).line(3)).line(3),
4222
+ s(:str, " y\n z\n").line(3)))
3939
4223
 
3940
4224
  assert_parse rb, pt
3941
4225
  end
@@ -3963,6 +4247,27 @@ module TestRubyParserShared23Plus
3963
4247
  assert_parse rb, pt
3964
4248
  end
3965
4249
 
4250
+ def test_heredoc_squiggly_blank_lines
4251
+ rb = "a = <<~EOF\n x\n\n z\nEOF\n\n"
4252
+ pt = s(:lasgn, :a, s(:str, "x\n\nz\n"))
4253
+
4254
+ assert_parse rb, pt
4255
+ end
4256
+
4257
+ def test_heredoc_squiggly_visually_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_empty
4265
+ rb = "<<~A\nA"
4266
+ pt = s(:str, "")
4267
+
4268
+ assert_parse rb, pt
4269
+ end
4270
+
3966
4271
  def test_integer_with_if_modifier
3967
4272
  rb = "1_234if true"
3968
4273
  pt = s(:if, s(:true), s(:lit, 1234), nil)
@@ -4032,7 +4337,7 @@ module TestRubyParserShared23Plus
4032
4337
 
4033
4338
  def test_safe_call_operator
4034
4339
  rb = "a&.> 1"
4035
- pt = s(:safe_call, s(:call, nil, :a), :>, s(:lit, 1)).line(1)
4340
+ pt = s(:safe_call, s(:call, nil, :a), :>, s(:lit, 1))
4036
4341
 
4037
4342
  assert_parse rb, pt
4038
4343
  end
@@ -4052,15 +4357,16 @@ module TestRubyParserShared23Plus
4052
4357
  end
4053
4358
 
4054
4359
  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)
4360
+ rb = "a&.b += x 1"
4361
+ pt = s(:safe_op_asgn, s(:call, nil, :a), s(:call, nil, :x, s(:lit, 1)), :b, :+)
4057
4362
 
4058
4363
  assert_parse rb, pt
4059
4364
  end
4060
4365
 
4061
4366
  def test_safe_op_asgn2
4062
4367
  rb = "a&.b ||=\nx;"
4063
- pt = s(:safe_op_asgn2, s(:call, nil, :a), :b=, :"||", s(:call, nil, :x)).line(1)
4368
+ pt = s(:safe_op_asgn2,
4369
+ s(:call, nil, :a), :b=, :"||", s(:call, nil, :x).line(2))
4064
4370
 
4065
4371
  assert_parse rb, pt
4066
4372
  end
@@ -4075,11 +4381,11 @@ a + b
4075
4381
  )
4076
4382
 
4077
4383
  pt = s(:block,
4078
- s(:call, nil, :puts, s(:str, "hello my dear friend").line(1)).line(1),
4384
+ s(:call, nil, :puts, s(:str, "hello my dear friend")),
4079
4385
  s(:call, s(:call, nil, :a).line(6),
4080
4386
  :+,
4081
4387
  s(:call, nil, :b).line(6)).line(6)
4082
- ).line(1)
4388
+ )
4083
4389
 
4084
4390
  assert_parse rb, pt
4085
4391
  end
@@ -4115,6 +4421,18 @@ module TestRubyParserShared26Plus
4115
4421
  assert_parse rb, pt
4116
4422
  end
4117
4423
 
4424
+ def test_begin_else_return_value # overrides above, warns < 2.6
4425
+ rb = "begin; else 2; end"
4426
+
4427
+ assert_syntax_error rb, "else without rescue is useless"
4428
+ end
4429
+
4430
+ def test_bug_begin_else # overrides above, warns < 2.6
4431
+ rb = "begin 1; else; 2 end"
4432
+
4433
+ assert_syntax_error rb, "else without rescue is useless"
4434
+ end
4435
+
4118
4436
  def test_dot3_nil__26
4119
4437
  rb = "a..."
4120
4438
  pt = s(:dot3, s(:call, nil, :a), nil)
@@ -4125,30 +4443,888 @@ module TestRubyParserShared26Plus
4125
4443
  def test_symbol_list
4126
4444
  rb = '%I[#{a} #{b}]'
4127
4445
  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
4446
+ s(:dsym, "", s(:evstr, s(:call, nil, :a))),
4447
+ s(:dsym, "", s(:evstr, s(:call, nil, :b)))).line 1
4130
4448
 
4131
4449
  assert_parse rb, pt
4132
4450
  end
4133
4451
  end
4134
4452
 
4135
- module TestRubyParserShared27Plus
4136
- include TestRubyParserShared26Plus
4137
- end
4138
-
4139
- class TestRubyParser < Minitest::Test
4140
- def test_cls_version
4141
- assert_equal 23, RubyParser::V23.version
4142
- assert_equal 24, RubyParser::V24.version
4143
- assert_equal 24, Ruby24Parser.version
4144
- refute RubyParser::Parser.version
4453
+ module TestPatternMatching
4454
+ def rip rb
4455
+ require "ripper"
4456
+ puts
4457
+ pp Sexp.from_array Ripper.sexp rb
4145
4458
  end
4146
4459
 
4147
- def test_parse
4148
- processor = RubyParser.new
4460
+ def assert_case_in lit, exp_pt
4461
+ rb = "case :a\nin #{lit}\nend"
4149
4462
 
4150
- rb = "a.()"
4151
- pt = s(:call, s(:call, nil, :a), :call)
4463
+ if ENV["VERBOSE_TEST"] then
4464
+ puts
4465
+ puts rb
4466
+ end
4467
+
4468
+ pt = s(:case, s(:lit, :a),
4469
+ s(:in, exp_pt, nil).line(2),
4470
+ nil)
4471
+
4472
+ assert_parse rb, pt
4473
+ end
4474
+
4475
+ def test_case_in_09
4476
+ assert_case_in(":b, [:c]",
4477
+ s(:array_pat, nil,
4478
+ s(:lit, :b).line(2),
4479
+ s(:array_pat, nil, s(:lit, :c).line(2)).line(2)).line(2))
4480
+ end
4481
+
4482
+ def test_case_in_10
4483
+ assert_case_in "nil, nil, nil", s(:array_pat,
4484
+ nil,
4485
+ s(:nil).line(2),
4486
+ s(:nil).line(2),
4487
+ s(:nil).line(2)).line(2)
4488
+ end
4489
+
4490
+ def test_case_in_21
4491
+ assert_case_in "Symbol()", s(:array_pat, s(:const, :Symbol).line(2)).line(2)
4492
+ end
4493
+
4494
+ def test_case_in_26
4495
+ assert_case_in "(42)", s(:lit, 42).line(2)
4496
+ end
4497
+
4498
+ def test_case_in_27
4499
+ assert_case_in("[A, *, B]",
4500
+ s(:array_pat, nil,
4501
+ s(:const, :A).line(2),
4502
+ :*,
4503
+ s(:const, :B).line(2)).line(2))
4504
+ end
4505
+
4506
+ def test_case_in_28_2
4507
+ assert_case_in '{ "b": }', s(:hash_pat, nil, s(:lit, :b).line(2), nil).line(2)
4508
+ end
4509
+
4510
+ def test_case_in_28
4511
+ assert_case_in "[]", s(:array_pat).line(2)
4512
+ end
4513
+
4514
+ def test_case_in_29
4515
+ assert_case_in "**nil", s(:hash_pat, nil, s(:kwrest, :"**nil").line(2)).line(2)
4516
+ end
4517
+
4518
+ def test_case_in_30
4519
+ assert_case_in "{}", s(:hash_pat, nil).line(2)
4520
+ end
4521
+
4522
+ def test_case_in_31?
4523
+ rb = "case :a\nin [:b, *c]\n :d\nend"
4524
+ pt = s(:case, s(:lit, :a),
4525
+ s(:in,
4526
+ s(:array_pat, nil, s(:lit, :b).line(2), :"*c").line(2),
4527
+ s(:lit, :d).line(3)).line(2),
4528
+ nil)
4529
+
4530
+ assert_parse rb, pt
4531
+ end
4532
+
4533
+ def test_case_in_32
4534
+ assert_case_in "(1...3)", s(:dot3, s(:lit, 1).line(2), s(:lit, 3).line(2)).line(2)
4535
+ end
4536
+
4537
+ def test_case_in_33
4538
+ assert_case_in "(1...)", s(:dot3, s(:lit, 1).line(2), nil).line(2)
4539
+ end
4540
+
4541
+ def test_case_in_34
4542
+ assert_case_in "(..10)", s(:dot2, nil, s(:lit, 10).line(2)).line(2)
4543
+ end
4544
+
4545
+ def test_case_in_35
4546
+ assert_case_in "(...10)", s(:dot3, nil, s(:lit, 10).line(2)).line(2)
4547
+ end
4548
+
4549
+ def test_case_in_36
4550
+ rb = "[:a, b, c, [:d, *e, nil]]"
4551
+ pt = s(:array_pat,
4552
+ nil,
4553
+ s(:lit, :a).line(2),
4554
+ s(:lvar, :b).line(2),
4555
+ s(:lvar, :c).line(2),
4556
+ s(:array_pat,
4557
+ nil,
4558
+ s(:lit, :d).line(2),
4559
+ :"*e",
4560
+ s(:nil).line(2)).line(2)).line(2)
4561
+
4562
+ assert_case_in rb, pt
4563
+ end
4564
+
4565
+ def test_case_in_37
4566
+ rb = "case :a\nin { b: [Hash, *] }\n :c\nend"
4567
+ pt = s(:case, s(:lit, :a),
4568
+ s(:in,
4569
+ s(:hash_pat,
4570
+ nil,
4571
+ s(:lit, :b).line(2),
4572
+ s(:array_pat, nil, s(:const, :Hash).line(2), :"*").line(2)
4573
+ ).line(2),
4574
+ s(:lit, :c).line(3)).line(2),
4575
+ nil)
4576
+
4577
+ assert_parse rb, pt
4578
+ end
4579
+
4580
+ def test_case_in_42
4581
+ rb = "case :a\nin :b, *_ then nil\nend"
4582
+ pt = s(:case, s(:lit, :a),
4583
+ s(:in,
4584
+ s(:array_pat,
4585
+ nil,
4586
+ s(:lit, :b).line(2),
4587
+ :"*_",
4588
+ ).line(2),
4589
+ s(:nil).line(2)).line(2),
4590
+ nil)
4591
+
4592
+ assert_parse rb, pt
4593
+ end
4594
+
4595
+ def test_case_in_42_2
4596
+ rb = "case :a\nin A(*list) then nil\nend"
4597
+ pt = s(:case, s(:lit, :a),
4598
+ s(:in,
4599
+ s(:array_pat,
4600
+ s(:const, :A).line(2),
4601
+ :"*list").line(2),
4602
+ s(:nil).line(2)).line(2),
4603
+ nil)
4604
+
4605
+ assert_parse rb, pt
4606
+ end
4607
+
4608
+ def test_case_in_42_3
4609
+ assert_case_in ":b, *_, :c", s(:array_pat, nil,
4610
+ s(:lit, :b).line(2),
4611
+ :"*_",
4612
+ s(:lit, :c).line(2)).line(2)
4613
+ end
4614
+
4615
+
4616
+ def test_case_in_47
4617
+ rb = "case :a\nin [*, :b, :c]\n :d\nend"
4618
+ pt = s(:case, s(:lit, :a),
4619
+ s(:in,
4620
+ s(:array_pat, nil, :*,
4621
+ s(:lit, :b).line(2), s(:lit, :c).line(2)).line(2),
4622
+ s(:lit, :d).line(3)).line(2),
4623
+ nil)
4624
+
4625
+ assert_parse rb, pt
4626
+ end
4627
+
4628
+ def test_case_in_67
4629
+ rb = "case :a\nin 1.. then nil\nend"
4630
+ pt = s(:case,
4631
+ s(:lit, :a),
4632
+ s(:in, s(:dot2, s(:lit, 1).line(2), nil).line(2),
4633
+ s(:nil).line(2)).line(2),
4634
+ nil)
4635
+
4636
+ assert_parse rb, pt
4637
+ end
4638
+
4639
+ def test_case_in_76
4640
+ assert_case_in "`echo hi`", s(:xstr, "echo hi").line(2)
4641
+ end
4642
+
4643
+ def test_case_in_77
4644
+ assert_case_in "/regexp/", s(:lit, /regexp/).line(2)
4645
+ end
4646
+
4647
+ def test_case_in_78
4648
+ assert_case_in "%W[a b]", s(:array, s(:str, "a").line(2), s(:str, "b").line(2)).line(2)
4649
+ end
4650
+
4651
+ def test_case_in_79
4652
+ assert_case_in "%w[a b]", s(:array, s(:str, "a").line(2), s(:str, "b").line(2)).line(2)
4653
+ end
4654
+
4655
+ def test_case_in_80
4656
+ assert_case_in "%I[a b]", s(:array, s(:lit, :a).line(2), s(:lit, :b).line(2)).line(2)
4657
+ end
4658
+
4659
+ def test_case_in_81
4660
+ assert_case_in "%i[a b]", s(:array, s(:lit, :a).line(2), s(:lit, :b).line(2)).line(2)
4661
+ end
4662
+
4663
+ def test_case_in_83
4664
+ rb = "[->(b) { true }, c]"
4665
+ pt = s(:array_pat, nil,
4666
+ s(:iter, s(:lambda).line(2), s(:args, :b).line(2),
4667
+ s(:true).line(2)).line(2),
4668
+ s(:lvar, :c).line(2)).line(2)
4669
+
4670
+ assert_case_in rb, pt
4671
+ end
4672
+
4673
+ def test_case_in_85
4674
+ rb = "[[:b, c], [:d, ^e]]"
4675
+ pt = s(:array_pat, nil,
4676
+ s(:array_pat, nil,
4677
+ s(:lit, :b).line(2),
4678
+ s(:lvar, :c).line(2)).line(2),
4679
+ s(:array_pat,
4680
+ nil,
4681
+ s(:lit, :d).line(2),
4682
+ s(:lvar, :e).line(2)).line(2),
4683
+ ).line(2)
4684
+
4685
+ assert_case_in rb, pt
4686
+ end
4687
+
4688
+ def test_case_in_86
4689
+ rb = "case [:a, :b]\nin ::NilClass, * then nil\nend"
4690
+ pt = s(:case,
4691
+ s(:array, s(:lit, :a), s(:lit, :b)),
4692
+ s(:in,
4693
+ s(:array_pat,
4694
+ nil,
4695
+ s(:colon3, :NilClass).line(2),
4696
+ :*).line(2),
4697
+ s(:nil).line(2)).line(2),
4698
+ nil)
4699
+
4700
+ assert_parse rb, pt
4701
+ end
4702
+
4703
+ def test_case_in_86_2
4704
+ rb = "case [:a, :b]\nin *, ::NilClass then nil\nend"
4705
+ pt = s(:case,
4706
+ s(:array, s(:lit, :a), s(:lit, :b)),
4707
+ s(:in,
4708
+ s(:array_pat,
4709
+ nil,
4710
+ :*,
4711
+ s(:colon3, :NilClass).line(2)).line(2),
4712
+ s(:nil).line(2)).line(2),
4713
+ nil)
4714
+
4715
+ assert_parse rb, pt
4716
+ end
4717
+
4718
+ def test_case_in_array_pat_const
4719
+ rb = "case :a\nin B[c]\n :d\nend"
4720
+ pt = s(:case, s(:lit, :a),
4721
+ s(:in,
4722
+ s(:array_pat,
4723
+ s(:const, :B).line(2),
4724
+ s(:lvar, :c).line(2)).line(2),
4725
+ s(:lit, :d).line(3)).line(2),
4726
+ nil)
4727
+
4728
+ assert_parse rb, pt
4729
+ end
4730
+
4731
+ def test_case_in_array_pat_const2
4732
+ rb = "case :a\nin B::C[d]\n :e\nend"
4733
+ pt = s(:case, s(:lit, :a),
4734
+ s(:in,
4735
+ s(:array_pat,
4736
+ s(:const, s(:colon2, s(:const, :B).line(2), :C).line(2)).line(2),
4737
+ s(:lvar, :d).line(2)).line(2),
4738
+ s(:lit, :e).line(3)).line(2),
4739
+ nil)
4740
+
4741
+ assert_parse rb, pt
4742
+ end
4743
+
4744
+ def test_case_in_array_pat_paren_assign
4745
+ rb = "case :a\nin B(C => d)\n :d\nend"
4746
+ pt = s(:case, s(:lit, :a),
4747
+ s(:in,
4748
+ s(:array_pat,
4749
+ s(:const, :B).line(2),
4750
+ s(:lasgn, :d, s(:const, :C).line(2)).line(2)).line(2),
4751
+ s(:lit, :d).line(3)).line(2),
4752
+ nil)
4753
+
4754
+ assert_parse rb, pt
4755
+ end
4756
+
4757
+ def test_case_in_const
4758
+ rb = "case Array\nin Class\n :b\nend"
4759
+ pt = s(:case, s(:const, :Array),
4760
+ s(:in, s(:const, :Class).line(2),
4761
+ s(:lit, :b).line(3)).line(2),
4762
+ nil).line 1
4763
+
4764
+ assert_parse rb, pt
4765
+ end
4766
+
4767
+ def test_case_in_else
4768
+ rb = "case Array\nin Class\n :b\nelse\n :c\nend\n"
4769
+ pt = s(:case, s(:const, :Array),
4770
+ s(:in, s(:const, :Class).line(2),
4771
+ s(:lit, :b).line(3)).line(2),
4772
+ s(:lit, :c).line(5)).line 1
4773
+
4774
+ assert_parse rb, pt
4775
+ end
4776
+
4777
+ def test_case_in_hash_pat
4778
+ rb = "case :a\nin { b: 'c', d: \"e\" } then\n :f\nend\n"
4779
+ pt = s(:case, s(:lit, :a),
4780
+ s(:in,
4781
+ s(:hash_pat,
4782
+ nil,
4783
+ s(:lit, :b).line(2), s(:str, "c").line(2),
4784
+ s(:lit, :d).line(2), s(:str, "e").line(2)).line(2),
4785
+ s(:lit, :f).line(3)
4786
+ ).line(2),
4787
+ nil)
4788
+
4789
+ assert_parse rb, pt
4790
+ end
4791
+
4792
+ def test_case_in_hash_pat_assign
4793
+ rb = "case :a\nin { b: Integer => x, d: \"e\", f: } then\n :g\nend"
4794
+ pt = s(:case, s(:lit, :a),
4795
+ s(:in,
4796
+ s(:hash_pat,
4797
+ nil,
4798
+ s(:lit, :b).line(2), # =>
4799
+ s(:lasgn, :x, s(:const, :Integer).line(2)).line(2),
4800
+ s(:lit, :d).line(2), s(:str, "e").line(2),
4801
+ s(:lit, :f).line(2), nil).line(2),
4802
+ s(:lit, :g).line(3)).line(2),
4803
+ nil)
4804
+
4805
+ assert_parse rb, pt
4806
+ end
4807
+
4808
+ def test_case_in_hash_pat_paren_assign
4809
+ rb = "case :a\nin B(a: 42)\n :d\nend"
4810
+ pt = s(:case, s(:lit, :a),
4811
+ s(:in,
4812
+ s(:hash_pat,
4813
+ s(:const, :B).line(2),
4814
+ s(:lit, :a).line(2), s(:lit, 42).line(2)).line(2),
4815
+ s(:lit, :d).line(3)).line(2),
4816
+ nil)
4817
+
4818
+ assert_parse rb, pt
4819
+ end
4820
+
4821
+ def test_case_in_hash_pat_paren_true
4822
+ rb = "case :a\nin b: true then\n :c\nend\n"
4823
+ pt = s(:case, s(:lit, :a),
4824
+ s(:in,
4825
+ s(:hash_pat,
4826
+ nil,
4827
+ s(:lit, :b).line(2), s(:true).line(2)).line(2),
4828
+ s(:lit, :c).line(3)).line(2),
4829
+ nil)
4830
+
4831
+ assert_parse rb, pt
4832
+ end
4833
+
4834
+ def test_case_in_hash_pat_rest
4835
+ rb = "case :a\nin b: c, **rest then :d\nend"
4836
+ pt = s(:case,
4837
+ s(:lit, :a),
4838
+ s(:in,
4839
+ s(:hash_pat,
4840
+ nil,
4841
+ s(:lit, :b).line(2),
4842
+ s(:lvar, :c).line(2),
4843
+ s(:kwrest, :"**rest").line(2)).line(2),
4844
+ s(:lit, :d).line(2)).line(2),
4845
+ nil)
4846
+
4847
+ assert_parse rb, pt
4848
+ end
4849
+
4850
+ def test_case_in_hash_pat_rest_solo
4851
+ rb = "case :a\nin **rest then :d\nend"
4852
+ pt = s(:case,
4853
+ s(:lit, :a),
4854
+ s(:in,
4855
+ s(:hash_pat,
4856
+ nil,
4857
+ s(:kwrest, :"**rest").line(2)).line(2),
4858
+ s(:lit, :d).line(2)).line(2),
4859
+ nil)
4860
+
4861
+ assert_parse rb, pt
4862
+ end
4863
+
4864
+ def test_case_in_if_unless_post_mod
4865
+ rb = "case :a\nin A if true\n :C\nin D unless false\n :E\nend"
4866
+ pt = s(:case,
4867
+ s(:lit, :a),
4868
+ s(:in,
4869
+ s(:if, s(:true).line(2), s(:const, :A).line(2), nil).line(2),
4870
+ s(:lit, :C).line(3)).line(2),
4871
+ s(:in,
4872
+ s(:if, s(:false).line(4), nil, s(:const, :D).line(4)).line(4),
4873
+ s(:lit, :E).line(5)).line(4),
4874
+ nil)
4875
+
4876
+ assert_parse rb, pt
4877
+ end
4878
+
4879
+ def test_case_in_multiple
4880
+ rb = "case :a\nin A::B\n :C\nin D::E\n :F\nend"
4881
+ pt = s(:case,
4882
+ s(:lit, :a),
4883
+ s(:in,
4884
+ s(:const, s(:colon2, s(:const, :A).line(2), :B).line(2)).line(2),
4885
+ s(:lit, :C).line(3)).line(2),
4886
+ s(:in,
4887
+ s(:const, s(:colon2, s(:const, :D).line(4), :E).line(4)).line(4),
4888
+ s(:lit, :F).line(5)).line(4),
4889
+ nil)
4890
+
4891
+ assert_parse rb, pt
4892
+ end
4893
+
4894
+ def test_case_in_or
4895
+ rb = "case :a\nin B | C\n :d\nend\n"
4896
+ pt = s(:case, s(:lit, :a),
4897
+ s(:in,
4898
+ s(:or,
4899
+ s(:const, :B).line(2),
4900
+ s(:const, :C).line(2)).line(2),
4901
+ s(:lit, :d).line(3)).line(2),
4902
+ nil)
4903
+
4904
+ assert_parse rb, pt
4905
+ end
4906
+
4907
+ def test_in_expr_no_case
4908
+ rb = "'woot' in String"
4909
+ pt = s(:case, s(:str, "woot"),
4910
+ s(:in, s(:const, :String),
4911
+ nil),
4912
+ nil)
4913
+
4914
+ assert_parse rb, pt
4915
+ end
4916
+
4917
+ def test_parse_pattern_019
4918
+ rb = <<~RUBY
4919
+ case 0
4920
+ in -1..1
4921
+ true
4922
+ end
4923
+ RUBY
4924
+
4925
+ pt = s(:case,
4926
+ s(:lit, 0),
4927
+ s(:in, s(:dot2, s(:lit, -1).line(2), s(:lit, 1).line(2)).line(2),
4928
+ s(:true).line(3)).line(2),
4929
+ nil)
4930
+
4931
+ assert_parse rb, pt
4932
+ end
4933
+
4934
+ def test_parse_pattern_044
4935
+ rb = <<~RUBY
4936
+ case obj
4937
+ in Object[]
4938
+ true
4939
+ end
4940
+ RUBY
4941
+ pt = s(:case,
4942
+ s(:call, nil, :obj),
4943
+ s(:in, s(:array_pat, s(:const, :Object).line(2)).line(2),
4944
+ s(:true).line(3)).line(2),
4945
+ nil)
4946
+
4947
+ assert_parse rb, pt
4948
+ end
4949
+
4950
+ def test_parse_pattern_051
4951
+ rb = <<~RUBY
4952
+ case [0, 1, 2]
4953
+ in [0, 1,]
4954
+ true
4955
+ end
4956
+ RUBY
4957
+ pt = s(:case,
4958
+ s(:array,
4959
+ s(:lit, 0),
4960
+ s(:lit, 1),
4961
+ s(:lit, 2)),
4962
+ s(:in,
4963
+ s(:array_pat,
4964
+ nil,
4965
+ s(:lit, 0).line(2),
4966
+ s(:lit, 1).line(2),
4967
+ :*).line(666),
4968
+ s(:true).line(3)).line(2),
4969
+ nil)
4970
+
4971
+ assert_parse rb, pt
4972
+ end
4973
+
4974
+ def test_parse_pattern_058
4975
+ rb = <<~RUBY
4976
+ case {a: 0}
4977
+ in {a:, **rest}
4978
+ [a, rest]
4979
+ end
4980
+ RUBY
4981
+ pt = s(:case,
4982
+ s(:hash,
4983
+ s(:lit, :a),
4984
+ s(:lit, 0)),
4985
+ s(:in,
4986
+ s(:hash_pat, nil, s(:lit, :a).line(2), nil,
4987
+ s(:kwrest, :"**rest").line(2)).line(2),
4988
+ s(:array,
4989
+ s(:lvar, :a).line(3),
4990
+ s(:lvar, :rest).line(3)).line(3)).line(2),
4991
+ nil)
4992
+
4993
+ assert_parse rb, pt
4994
+ end
4995
+
4996
+ def test_parse_pattern_058_2
4997
+ rb = <<~RUBY
4998
+ case {a: 0}
4999
+ in {a:, **}
5000
+ [a]
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, :"**").line(2)).line(2),
5010
+ s(:array,
5011
+ s(:lvar, :a).line(3)).line(3)).line(2),
5012
+ nil)
5013
+
5014
+ assert_parse rb, pt
5015
+ end
5016
+
5017
+ def test_parse_pattern_069
5018
+ rb = <<~RUBY
5019
+ case :a
5020
+ in Object[b: 1]
5021
+ 1
5022
+ end
5023
+ RUBY
5024
+ pt = s(:case,
5025
+ s(:lit, :a),
5026
+ s(:in,
5027
+ s(:hash_pat, s(:const, :Object).line(2),
5028
+ s(:lit, :b).line(2), s(:lit, 1).line(2)).line(2),
5029
+ s(:lit, 1).line(3)).line(2),
5030
+ nil)
5031
+
5032
+
5033
+ assert_parse rb, pt
5034
+ end
5035
+
5036
+ def test_parse_pattern_076
5037
+ rb = <<~RUBY
5038
+ case {a: 1}
5039
+ in {a: 1, **nil}
5040
+ true
5041
+ end
5042
+ RUBY
5043
+ pt = s(:case,
5044
+ s(:hash, s(:lit, :a), s(:lit, 1)),
5045
+ s(:in,
5046
+ s(:hash_pat, nil,
5047
+ s(:lit, :a).line(2), s(:lit, 1).line(2),
5048
+ s(:kwrest, :"**nil").line(2)).line(2),
5049
+ s(:true).line(3)).line(2),
5050
+ nil)
5051
+
5052
+ assert_parse rb, pt
5053
+ end
5054
+
5055
+ # def test_case_in_TEMPLATE
5056
+ # rb = "case :a\nin XXX then\n YYY\nend\n"
5057
+ # pt = s(:case, s(:lit, :a),
5058
+ # s(:in,
5059
+ # ZZZ,
5060
+ # WWW).line(2),
5061
+ # nil)
5062
+ #
5063
+ # assert_parse rb, pt
5064
+ # end
5065
+ end
5066
+
5067
+ module TestPatternMatching30
5068
+ def test_case_in_20
5069
+ assert_case_in("Symbol(*lhs, x, *rhs)",
5070
+ s(:find_pat,
5071
+ s(:const, :Symbol).line(2),
5072
+ :"*lhs",
5073
+ s(:array_pat, s(:lvar, :x).line(2)).line(2),
5074
+ :"*rhs").line(2))
5075
+ end
5076
+
5077
+ def test_case_in_22
5078
+ assert_case_in("Symbol[*lhs, x, *rhs]",
5079
+ s(:find_pat, s(:const, :Symbol).line(2),
5080
+ :"*lhs",
5081
+ s(:array_pat, s(:lvar, :x).line(2)).line(2),
5082
+ :"*rhs").line(2))
5083
+ end
5084
+ end
5085
+
5086
+ module TestRubyParserShared27Plus
5087
+ include TestRubyParserShared26Plus
5088
+ include TestPatternMatching
5089
+
5090
+ def test_block_args_kwargs
5091
+ rb = "f { |**kwargs| kwargs }"
5092
+ pt = s(:iter,
5093
+ s(:call, nil, :f),
5094
+ s(:args, :"**kwargs"),
5095
+ s(:lvar, :kwargs))
5096
+
5097
+ assert_parse rb, pt
5098
+ end
5099
+
5100
+ def test_block_args_no_kwargs
5101
+ rb = "f { |**nil| }"
5102
+ pt = s(:iter,
5103
+ s(:call, nil, :f),
5104
+ s(:args, :"**nil"))
5105
+
5106
+ assert_parse rb, pt
5107
+ end
5108
+
5109
+ def test_defn_forward_args
5110
+ rb = "def a(...); b(...); end"
5111
+ pt = s(:defn, :a, s(:args, s(:forward_args)),
5112
+ s(:call, nil, :b, s(:forward_args)))
5113
+
5114
+ assert_parse rb, pt
5115
+ end
5116
+
5117
+ def test_defn_arg_forward_args
5118
+ rb = "def a(x, ...); b(x, ...); end"
5119
+ pt = s(:defn, :a, s(:args, :x, s(:forward_args)),
5120
+ s(:call, nil, :b, s(:lvar, :x), s(:forward_args)))
5121
+
5122
+ assert_parse rb, pt
5123
+ end
5124
+
5125
+ def test_defn_args_forward_args
5126
+ rb = "def a(x, y, z, ...); b(:get, z, ...); end"
5127
+ pt = s(:defn, :a, s(:args, :x, :y, :z, s(:forward_args)),
5128
+ s(:call, nil, :b, s(:lit, :get), s(:lvar, :z),
5129
+ s(:forward_args)))
5130
+
5131
+ assert_parse rb, pt
5132
+ end
5133
+
5134
+ def test_defn_no_kwargs
5135
+ # def x(**nil)
5136
+ # end
5137
+ #
5138
+ # def y(**kw)
5139
+ # end
5140
+ #
5141
+ # def z()
5142
+ # end
5143
+ #
5144
+ # x arg: 42 # $!: no keywords accepted (ArgumentError)
5145
+ # y arg: 42 # fine
5146
+ # z arg: 42 # $!: wrong number of arguments (given 1, expected 0) (ArgumentError)
5147
+
5148
+ rb = "def x(**nil); end"
5149
+ pt = s(:defn, :x, s(:args, :"**nil"),
5150
+ s(:nil))
5151
+
5152
+ assert_parse rb, pt
5153
+ end
5154
+
5155
+ def test_call_forward_args_outside_method_definition
5156
+ rb = "b(...)"
5157
+
5158
+ assert_syntax_error rb, "Unexpected ..."
5159
+ end
5160
+
5161
+ def test_call_arg_forward_args_outside_method_definition
5162
+ rb = "b(x, ...)"
5163
+
5164
+ assert_syntax_error rb, "Unexpected ..."
5165
+ end
5166
+
5167
+ def test_mlhs_rescue
5168
+ # same:
5169
+ # a = (24 rescue 42)
5170
+ # a = 24 rescue 42
5171
+
5172
+ # same:
5173
+ # a, b = (f rescue 42)
5174
+ # a, b = f rescue 42
5175
+
5176
+ rb = "a, b = f rescue 42"
5177
+ pt = s(:masgn,
5178
+ s(:array, s(:lasgn, :a), s(:lasgn, :b)),
5179
+ s(:to_ary,
5180
+ s(:rescue,
5181
+ s(:call, nil, :f),
5182
+ s(:resbody, s(:array),
5183
+ s(:lit, 42)))))
5184
+
5185
+ assert_parse rb, pt
5186
+ end
5187
+ end
5188
+
5189
+ module TestRubyParserShared30Plus
5190
+ include TestRubyParserShared27Plus
5191
+ include TestPatternMatching30
5192
+
5193
+ def test_rhs_asgn
5194
+ rb = "42 => n"
5195
+ pt = s(:case,
5196
+ s(:lit, 42),
5197
+ s(:in, s(:lvar, :n), nil), nil)
5198
+
5199
+ assert_parse rb, pt
5200
+ end
5201
+
5202
+ def test_case_in_find
5203
+ rb = "case :a\n in *a, :+, *b\nend"
5204
+ pt = s(:case,
5205
+ s(:lit, :a),
5206
+ s(:in,
5207
+ s(:find_pat, nil,
5208
+ :"*a",
5209
+ s(:array_pat, s(:lit, :+).line(2)).line(2),
5210
+ :"*b").line(2),
5211
+ nil).line(2),
5212
+ nil)
5213
+
5214
+ assert_parse rb, pt
5215
+ end
5216
+
5217
+ def test_case_in_find_array
5218
+ rb = "case :a\nin [*, :b, c, *]\nend"
5219
+ pt = s(:case,
5220
+ s(:lit, :a),
5221
+ s(:in,
5222
+ s(:find_pat, nil,
5223
+ :*,
5224
+ s(:array_pat, s(:lit, :b).line(2), s(:lvar, :c).line(2)).line(2),
5225
+ :*).line(2),
5226
+ nil).line(2),
5227
+ nil)
5228
+
5229
+ assert_parse rb, pt
5230
+ end
5231
+
5232
+ def test_defn_oneliner
5233
+ rb = "def exec(cmd) = system(cmd)"
5234
+ pt = s(:defn, :exec, s(:args, :cmd),
5235
+ s(:call, nil, :system, s(:lvar, :cmd)))
5236
+
5237
+ assert_parse rb, pt
5238
+ end
5239
+
5240
+ def test_defn_oneliner_noargs_parentheses
5241
+ rb = "def exec() = system"
5242
+ pt = s(:defn, :exec, s(:args),
5243
+ s(:call, nil, :system))
5244
+
5245
+ assert_parse rb, pt
5246
+ end
5247
+
5248
+ def test_defn_oneliner_noargs
5249
+ rb = "def exec = system"
5250
+ pt = s(:defn, :exec, s(:args),
5251
+ s(:call, nil, :system))
5252
+
5253
+ assert_parse rb, pt
5254
+ end
5255
+
5256
+ def test_defn_oneliner_rescue
5257
+ rb = "def exec(cmd)\n system(cmd)\nrescue\n nil\nend\n"
5258
+ pt = s(:defn, :exec, s(:args, :cmd),
5259
+ s(:rescue,
5260
+ s(:call, nil, :system, s(:lvar, :cmd).line(2)).line(2),
5261
+ s(:resbody, s(:array).line(3),
5262
+ s(:nil).line(4)).line(3)).line(2))
5263
+
5264
+ assert_parse rb, pt
5265
+
5266
+ rb = "def exec(cmd)\n system(cmd) rescue nil\nend\n"
5267
+ assert_parse rb, pt.deep_each { |s| s.line = 2 if s.line && s.line > 1 }
5268
+
5269
+ rb = "def exec(cmd) = system(cmd) rescue nil"
5270
+ assert_parse rb, pt.deep_each { |s| s.line = 1 }
5271
+ end
5272
+
5273
+ def test_defs_oneliner
5274
+ rb = "def self.exec(cmd) = system(cmd)"
5275
+ pt = s(:defs, s(:self), :exec, s(:args, :cmd),
5276
+ s(:call, nil, :system, s(:lvar, :cmd)))
5277
+
5278
+ assert_parse rb, pt
5279
+ end
5280
+
5281
+ def test_defs_oneliner_rescue
5282
+ rb = "def self.exec(cmd)\n system(cmd)\nrescue\n nil\nend\n"
5283
+ pt = s(:defs, s(:self), :exec, s(:args, :cmd),
5284
+ s(:rescue,
5285
+ s(:call, nil, :system, s(:lvar, :cmd).line(2)).line(2),
5286
+ s(:resbody, s(:array).line(3), s(:nil).line(4)).line(3)).line(2))
5287
+ assert_parse rb, pt
5288
+
5289
+ rb = "def self.exec(cmd)\n system(cmd) rescue nil\nend\n"
5290
+ assert_parse rb, pt.deep_each { |s| s.line = 2 if s.line && s.line > 1 }
5291
+
5292
+ rb = "def self.exec(cmd) = system(cmd) rescue nil"
5293
+ assert_parse rb, pt.deep_each { |s| s.line = 1 }
5294
+ end
5295
+
5296
+ def test_defn_oneliner_setter
5297
+ rb = "class X\n def x=(o) = 42\nend"
5298
+
5299
+ assert_syntax_error rb, /setter method cannot be defined/
5300
+ end
5301
+
5302
+ def test_defs_oneliner_setter
5303
+ rb = "class X\n def self.x= = 42\nend"
5304
+
5305
+ assert_syntax_error rb, /setter method cannot be defined/
5306
+ end
5307
+ end
5308
+
5309
+ class Minitest::Test
5310
+ def skip s = "blah"
5311
+ warn "ignoring skip for %s: %s" % [name, s]
5312
+ end
5313
+ end if ENV["NOSKIP"]
5314
+
5315
+ class TestRubyParser < Minitest::Test
5316
+ def test_cls_version
5317
+ assert_equal 23, RubyParser::V23.version
5318
+ assert_equal 24, RubyParser::V24.version
5319
+ assert_equal 24, Ruby24Parser.version
5320
+ refute RubyParser::Parser.version
5321
+ end
5322
+
5323
+ def test_parse
5324
+ processor = RubyParser.new
5325
+
5326
+ rb = "a.()"
5327
+ pt = s(:call, s(:call, nil, :a), :call)
4152
5328
 
4153
5329
  assert_equal pt, processor.parse(rb)
4154
5330
 
@@ -4159,7 +5335,7 @@ class TestRubyParser < Minitest::Test
4159
5335
  end
4160
5336
  end
4161
5337
 
4162
- assert_includes e.message, 'parse error on value false ($end)'
5338
+ assert_includes e.message, 'parse error on value "$" ($end)'
4163
5339
  end
4164
5340
 
4165
5341
  def test_parse_error_from_first
@@ -4172,7 +5348,7 @@ class TestRubyParser < Minitest::Test
4172
5348
  end
4173
5349
 
4174
5350
  # This is a 2.x error, will fail on 1.8/1.9.
4175
- assert_includes e.message, 'parse error on value false ($end)'
5351
+ assert_includes e.message, 'parse error on value "$" ($end)'
4176
5352
  end
4177
5353
  end
4178
5354
 
@@ -4194,8 +5370,18 @@ class RubyParserTestCase < ParseTreeTestCase
4194
5370
  super
4195
5371
  end
4196
5372
 
5373
+ attr_accessor :assert_parse_ran
5374
+
4197
5375
  def assert_parse rb, pt
4198
- self.result = processor.parse rb
5376
+ self.processor.reset if assert_parse_ran # allows multiple calls
5377
+ self.assert_parse_ran = true
5378
+
5379
+ timeout = (ENV["RP_TIMEOUT"] || 10).to_i
5380
+
5381
+ pt.deep_each { |s| s.line ||= 1 }
5382
+ pt.line ||= 1
5383
+
5384
+ self.result = processor.parse rb, "(string)", timeout
4199
5385
  assert_equal pt, result
4200
5386
  end
4201
5387
 
@@ -4214,25 +5400,20 @@ class RubyParserTestCase < ParseTreeTestCase
4214
5400
  end
4215
5401
  end
4216
5402
 
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
5403
+ def assert_syntax_error rb, emsg, klass = RubyParser::SyntaxError
4228
5404
  e = nil
4229
5405
  assert_silent do
4230
- e = assert_raises RubyParser::SyntaxError do
5406
+ e = assert_raises klass do
4231
5407
  processor.parse rb
4232
5408
  end
4233
5409
  end
4234
5410
 
4235
- assert_equal emsg, e.message
5411
+ case emsg
5412
+ when String
5413
+ assert_equal emsg, e.message
5414
+ else
5415
+ assert_match emsg, e.message
5416
+ end
4236
5417
  end
4237
5418
 
4238
5419
  def refute_parse rb
@@ -4249,17 +5430,6 @@ class TestRubyParserV20 < RubyParserTestCase
4249
5430
 
4250
5431
  self.processor = RubyParser::V20.new
4251
5432
  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
5433
  end
4264
5434
 
4265
5435
  class TestRubyParserV21 < RubyParserTestCase
@@ -4318,7 +5488,7 @@ class TestRubyParserV24 < RubyParserTestCase
4318
5488
 
4319
5489
  assert_parse rb, pt
4320
5490
 
4321
- assert_parse_error "a(b rescue c)", /parse error on value ..rescue/
5491
+ assert_parse_error "a(b rescue c)", /parse error on value .rescue/
4322
5492
  end
4323
5493
  end
4324
5494
 
@@ -4335,11 +5505,10 @@ class TestRubyParserV25 < RubyParserTestCase
4335
5505
  rb = "proc do\n :begin\nensure\n :ensure\nend.call"
4336
5506
  pt = s(:call,
4337
5507
  s(:iter,
4338
- s(:call, nil, :proc),
4339
- 0,
5508
+ s(:call, nil, :proc), 0,
4340
5509
  s(:ensure,
4341
- s(:lit, :begin),
4342
- s(:lit, :ensure))),
5510
+ s(:lit, :begin).line(2),
5511
+ s(:lit, :ensure).line(4)).line(2)),
4343
5512
  :call)
4344
5513
 
4345
5514
  assert_parse rb, pt
@@ -4348,16 +5517,14 @@ class TestRubyParserV25 < RubyParserTestCase
4348
5517
  def test_rescue_do_end_no_raise
4349
5518
  rb = "tap do\n :begin\nrescue\n :rescue\nelse\n :else\nensure\n :ensure\nend"
4350
5519
  pt = s(:iter,
4351
- s(:call, nil, :tap),
4352
- 0,
5520
+ s(:call, nil, :tap), 0,
4353
5521
  s(:ensure,
4354
5522
  s(:rescue,
4355
- s(:lit, :begin),
4356
- s(:resbody,
4357
- s(:array),
4358
- s(:lit, :rescue)),
4359
- s(:lit, :else)),
4360
- s(:lit, :ensure)))
5523
+ s(:lit, :begin).line(2),
5524
+ s(:resbody, s(:array).line(3),
5525
+ s(:lit, :rescue).line(4)).line(3),
5526
+ s(:lit, :else).line(6)).line(2),
5527
+ s(:lit, :ensure).line(8)).line(2))
4361
5528
 
4362
5529
  assert_parse rb, pt
4363
5530
  end
@@ -4365,11 +5532,10 @@ class TestRubyParserV25 < RubyParserTestCase
4365
5532
  def test_rescue_do_end_raised
4366
5533
  rb = "tap do\n raise\nensure\n :ensure\nend"
4367
5534
  pt = s(:iter,
4368
- s(:call, nil, :tap),
4369
- 0,
5535
+ s(:call, nil, :tap), 0,
4370
5536
  s(:ensure,
4371
- s(:call, nil, :raise),
4372
- s(:lit, :ensure)))
5537
+ s(:call, nil, :raise).line(2),
5538
+ s(:lit, :ensure).line(4)).line(2))
4373
5539
 
4374
5540
  assert_parse rb, pt
4375
5541
  end
@@ -4381,12 +5547,12 @@ class TestRubyParserV25 < RubyParserTestCase
4381
5547
  0,
4382
5548
  s(:ensure,
4383
5549
  s(:rescue,
4384
- s(:call, nil, :raise),
5550
+ s(:call, nil, :raise).line(2),
4385
5551
  s(:resbody,
4386
- s(:array),
4387
- s(:lit, :rescue)),
4388
- s(:lit, :else)),
4389
- s(:lit, :ensure)))
5552
+ s(:array).line(3),
5553
+ s(:lit, :rescue).line(4)).line(3),
5554
+ s(:lit, :else).line(6)).line(2),
5555
+ s(:lit, :ensure).line(8)).line(2))
4390
5556
 
4391
5557
  assert_parse rb, pt
4392
5558
  end
@@ -4394,9 +5560,11 @@ class TestRubyParserV25 < RubyParserTestCase
4394
5560
  def test_rescue_in_block
4395
5561
  rb = "blah do\nrescue\n stuff\nend"
4396
5562
  pt = s(:iter,
4397
- s(:call, nil, :blah),
4398
- 0,
4399
- s(:rescue, s(:resbody, s(:array), s(:call, nil, :stuff))))
5563
+ s(:call, nil, :blah), 0,
5564
+ s(:rescue,
5565
+ s(:resbody, s(:array).line(2),
5566
+ s(:call, nil, :stuff).line(3)).line(2)).line(2))
5567
+
4400
5568
  assert_parse rb, pt
4401
5569
  end
4402
5570
  end
@@ -4413,26 +5581,27 @@ class TestRubyParserV26 < RubyParserTestCase
4413
5581
  def test_parse_line_dot2_open
4414
5582
  rb = "0..\n; a..\n; c"
4415
5583
  pt = s(:block,
4416
- s(:dot2, s(:lit, 0).line(1), nil).line(1),
5584
+ s(:dot2, s(:lit, 0), nil),
4417
5585
  s(:dot2, s(:call, nil, :a).line(2), nil).line(2),
4418
- s(:call, nil, :c).line(3)).line(1)
5586
+ s(:call, nil, :c).line(3))
4419
5587
 
4420
- assert_parse_line rb, pt, 1
5588
+ assert_parse rb, pt
4421
5589
  end
4422
5590
 
4423
5591
  def test_parse_line_dot3_open
4424
5592
  rb = "0...\n; a...\n; c"
4425
5593
  pt = s(:block,
4426
- s(:dot3, s(:lit, 0).line(1), nil).line(1),
5594
+ s(:dot3, s(:lit, 0), nil),
4427
5595
  s(:dot3, s(:call, nil, :a).line(2), nil).line(2),
4428
- s(:call, nil, :c).line(3)).line(1)
5596
+ s(:call, nil, :c).line(3))
4429
5597
 
4430
- assert_parse_line rb, pt, 1
5598
+ assert_parse rb, pt
4431
5599
  end
4432
-
4433
5600
  end
4434
5601
 
4435
5602
  class TestRubyParserV27 < RubyParserTestCase
5603
+ make_my_diffs_pretty!
5604
+
4436
5605
  include TestRubyParserShared27Plus
4437
5606
 
4438
5607
  def setup
@@ -4440,8 +5609,37 @@ class TestRubyParserV27 < RubyParserTestCase
4440
5609
 
4441
5610
  self.processor = RubyParser::V27.new
4442
5611
  end
5612
+
5613
+ def test_bdot2
5614
+ rb = "..10\n; ..a\n; c"
5615
+ pt = s(:block,
5616
+ s(:dot2, nil, s(:lit, 10)),
5617
+ s(:dot2, nil, s(:call, nil, :a).line(2)).line(2),
5618
+ s(:call, nil, :c).line(3))
5619
+
5620
+ assert_parse rb, pt
5621
+ end
5622
+
5623
+ def test_bdot3
5624
+ rb = "...10\n; ...a\n; c"
5625
+ pt = s(:block,
5626
+ s(:dot3, nil, s(:lit, 10)),
5627
+ s(:dot3, nil, s(:call, nil, :a).line(2)).line(2),
5628
+ s(:call, nil, :c).line(3))
5629
+
5630
+ assert_parse rb, pt
5631
+ end
4443
5632
  end
4444
5633
 
5634
+ class TestRubyParserV30 < RubyParserTestCase
5635
+ include TestRubyParserShared30Plus
5636
+
5637
+ def setup
5638
+ super
5639
+
5640
+ self.processor = RubyParser::V30.new
5641
+ end
5642
+ end
4445
5643
 
4446
5644
  RubyParser::VERSIONS.each do |klass|
4447
5645
  v = klass.version