ruby_parser 3.17.0 → 3.18.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -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, /'/)
@@ -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
@@ -881,6 +888,29 @@ module TestRubyParserShared
881
888
  assert_parse rb, pt
882
889
  end
883
890
 
891
+ def test_heredoc_lineno
892
+ rb = "c = <<'CCC'\nline2\nline3\nline4\nCCC\n\nd = 42"
893
+ pt = s(:block,
894
+ s(:lasgn, :c, s(:str, "line2\nline3\nline4\n").line(1)).line(1),
895
+ s(:lasgn, :d, s(:lit, 42).line(7)).line(7)).line(1)
896
+
897
+ assert_parse rb, pt
898
+ end
899
+
900
+ def test_pctW_lineno
901
+ rb = "%W(a\\nb\nc\ d\ne\\\nf\ng\y h\\y i\\\y)"
902
+ pt = s(:array,
903
+ s(:str, "a\nb").line(1),
904
+ s(:str, "c").line(2),
905
+ s(:str, "d").line(2),
906
+ s(:str, "e\nf").line(3),
907
+ s(:str, "gy").line(5),
908
+ s(:str, "hy").line(5),
909
+ s(:str, "iy").line(5)).line(1)
910
+
911
+ assert_parse rb, pt
912
+ end
913
+
884
914
  def test_heredoc_bad_oct_escape
885
915
  rb = "s = <<-EOS\na\\247b\ncöd\nEOS\n"
886
916
  pt = s(:lasgn, :s, s(:str, "a\xa7b\nc\xc3\xb6d\n".b))
@@ -1057,7 +1087,7 @@ module TestRubyParserShared
1057
1087
  s(:array,
1058
1088
  s(:str, "a").line(2),
1059
1089
  s(:str, "b").line(3)).line(1),
1060
- s(:lit, 1).line(5))
1090
+ s(:lit, 1).line(5)).line(1)
1061
1091
  assert_parse rb, pt
1062
1092
  end
1063
1093
 
@@ -1433,7 +1463,7 @@ module TestRubyParserShared
1433
1463
  s(:array,
1434
1464
  s(:str, "a").line(2),
1435
1465
  s(:str, "b").line(3)).line(1),
1436
- s(:lit, 1).line(5))
1466
+ s(:lit, 1).line(5)).line(1)
1437
1467
  assert_parse rb, pt
1438
1468
  end
1439
1469
 
@@ -1635,7 +1665,7 @@ module TestRubyParserShared
1635
1665
 
1636
1666
  def test_parse_line_defn_no_parens_args
1637
1667
  rb = "def f a\nend"
1638
- pt = s(:defn, :f, s(:args, :a).line(1), s(:nil).line(2)).line(1)
1668
+ pt = s(:defn, :f, s(:args, :a).line(1), s(:nil).line(1)).line(1)
1639
1669
 
1640
1670
  assert_parse_line rb, pt, 1
1641
1671
  end
@@ -1656,7 +1686,7 @@ module TestRubyParserShared
1656
1686
  end
1657
1687
 
1658
1688
  def test_parse_line_defn_no_parens
1659
- pt = s(:defn, :f, s(:args).line(1), s(:nil)).line(1)
1689
+ pt = s(:defn, :f, s(:args).line(1), s(:nil).line(1)).line(1)
1660
1690
 
1661
1691
  rb = "def f\nend"
1662
1692
  assert_parse_line rb, pt, 1
@@ -1691,17 +1721,21 @@ module TestRubyParserShared
1691
1721
  assert_parse_line rb, pt, 1
1692
1722
  end
1693
1723
 
1694
- def test_parse_line_dstr_newline
1695
- rb = <<-'CODE'
1696
- "a\n#{
1697
- }"
1698
- true
1699
- CODE
1700
-
1724
+ def test_parse_line_dstr_escaped_newline
1725
+ rb = "\"a\\n\#{\n}\"\ntrue"
1701
1726
  pt = s(:block,
1702
1727
  s(:dstr, "a\n",
1703
- s(:evstr)).line(1),
1704
- s(:true).line(3))
1728
+ s(:evstr).line(1)).line(1),
1729
+ s(:true).line(3)).line(1)
1730
+
1731
+ assert_parse rb, pt
1732
+ end
1733
+
1734
+ def test_parse_line_dstr_soft_newline
1735
+ rb = "\"a\n#\{\n}\"\ntrue"
1736
+ pt = s(:block,
1737
+ s(:dstr, "a\n", s(:evstr).line(2)).line(1),
1738
+ s(:true).line(4)).line(1)
1705
1739
 
1706
1740
  assert_parse rb, pt
1707
1741
  end
@@ -1726,7 +1760,7 @@ module TestRubyParserShared
1726
1760
 
1727
1761
  def test_parse_line_heredoc
1728
1762
  rb = <<-CODE
1729
- string = <<-HEREDOC
1763
+ string = <<-HEREDOC.strip
1730
1764
  very long string
1731
1765
  HEREDOC
1732
1766
  puts string
@@ -1734,20 +1768,23 @@ module TestRubyParserShared
1734
1768
 
1735
1769
  pt = s(:block,
1736
1770
  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)
1771
+ s(:call,
1772
+ s(:str, " very long string\n").line(1),
1773
+ :strip).line(1),
1774
+ ).line(1),
1775
+ s(:call, nil, :puts,
1776
+ s(:lvar, :string).line(4)).line(4)
1777
+ ).line(1)
1739
1778
 
1740
1779
  assert_parse rb, pt
1741
1780
  end
1742
1781
 
1743
1782
  def test_parse_line_heredoc_evstr
1744
- skip "heredoc line numbers are just gonna be screwed for a while..."
1745
-
1746
1783
  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)
1784
+ pt = s(:dstr,
1785
+ "a\n",
1786
+ s(:evstr, s(:call, nil, :b).line(3)).line(3), s(:str, "\n").line(3)
1787
+ ).line(1)
1751
1788
 
1752
1789
  assert_parse rb, pt
1753
1790
  end
@@ -2055,13 +2092,13 @@ module TestRubyParserShared
2055
2092
  assert_parse rb, pt
2056
2093
  end
2057
2094
 
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
2095
+ def test_str_pct_nested_nested
2096
+ rb = "%{ { #\{ \"#\{1}\" } } }"
2097
+ assert_equal " { 1 } ", eval(rb)
2098
+ pt = s(:dstr, " { ", s(:evstr, s(:lit, 1)), s(:str, " } "))
2099
+
2100
+ assert_parse rb, pt
2101
+ end
2065
2102
 
2066
2103
  def test_str_pct_Q_nested
2067
2104
  rb = "%Q[before [#\{nest}] after]"
@@ -2077,6 +2114,60 @@ module TestRubyParserShared
2077
2114
  assert_parse rb, pt
2078
2115
  end
2079
2116
 
2117
+ def test_str_single_newline
2118
+ rp = "a '\n';b"
2119
+ pt = s(:block,
2120
+ s(:call, nil, :a, s(:str, "\n").line(1)).line(1),
2121
+ s(:call, nil, :b).line(2)).line(1)
2122
+
2123
+ assert_parse rp, pt
2124
+ end
2125
+
2126
+ def test_str_single_escaped_newline
2127
+ rp = "a '\\n';b"
2128
+ pt = s(:block,
2129
+ s(:call, nil, :a, s(:str, "\\n").line(1)).line(1),
2130
+ s(:call, nil, :b).line(1)).line(1)
2131
+
2132
+ assert_parse rp, pt
2133
+ end
2134
+
2135
+ def test_str_single_double_escaped_newline
2136
+ rp = "a '\\\\n';b"
2137
+ pt = s(:block,
2138
+ s(:call, nil, :a, s(:str, "\\n").line(1)).line(1),
2139
+ s(:call, nil, :b).line(1)).line(1)
2140
+
2141
+ assert_parse rp, pt
2142
+ end
2143
+
2144
+ def test_str_double_newline
2145
+ rp = "a \"\n\";b"
2146
+ pt = s(:block,
2147
+ s(:call, nil, :a, s(:str, "\n").line(1)).line(1),
2148
+ s(:call, nil, :b).line(2)).line(1)
2149
+
2150
+ assert_parse rp, pt
2151
+ end
2152
+
2153
+ def test_str_double_escaped_newline
2154
+ rp = "a \"\\n\";b"
2155
+ pt = s(:block,
2156
+ s(:call, nil, :a, s(:str, "\n").line(1)).line(1),
2157
+ s(:call, nil, :b).line(1)).line(1)
2158
+
2159
+ assert_parse rp, pt
2160
+ end
2161
+
2162
+ def test_str_double_double_escaped_newline
2163
+ rp = "a \"\\\\n\";b"
2164
+ pt = s(:block,
2165
+ s(:call, nil, :a, s(:str, "\\n").line(1)).line(1),
2166
+ s(:call, nil, :b).line(1)).line(1)
2167
+
2168
+ assert_parse rp, pt
2169
+ end
2170
+
2080
2171
  def test_str_str
2081
2172
  rb = "\"a #\{'b'}\""
2082
2173
  pt = s(:str, "a b")
@@ -2632,7 +2723,7 @@ module TestRubyParserShared19Plus
2632
2723
  rb = "def m arg = false\nend"
2633
2724
  pt = s(:defn, :m,
2634
2725
  s(:args, s(:lasgn, :arg, s(:false).line(1)).line(1)).line(1),
2635
- s(:nil).line(2)).line(1)
2726
+ s(:nil).line(1)).line(1)
2636
2727
 
2637
2728
  assert_parse rb, pt
2638
2729
  end
@@ -3079,9 +3170,32 @@ module TestRubyParserShared19Plus
3079
3170
  assert_parse rb, pt
3080
3171
  end
3081
3172
 
3082
- def test_motherfuckin_leading_dots
3083
- skip if processor.class.version >= 27
3173
+ def test_call_leading_dots
3174
+ rb = "a\n.b\n.c"
3175
+ pt = s(:call, s(:call, s(:call, nil, :a), :b), :c)
3176
+
3177
+ assert_parse rb, pt
3178
+ end
3179
+
3180
+ def test_call_leading_dots_comment
3181
+ rb = "a\n.b\n#.c\n.d"
3182
+ pt = s(:call,
3183
+ s(:call,
3184
+ s(:call, nil, :a).line(1),
3185
+ :b).line(1),
3186
+ :d).line(1) # TODO: fix linenos: 1, 2, 4
3187
+
3188
+ assert_parse rb, pt
3189
+ end
3084
3190
 
3191
+ def test_call_trailing_dots
3192
+ rb = "a.\nb.\nc"
3193
+ pt = s(:call, s(:call, s(:call, nil, :a), :b), :c)
3194
+
3195
+ assert_parse rb, pt
3196
+ end
3197
+
3198
+ def test_motherfuckin_leading_dots
3085
3199
  rb = "a\n.b"
3086
3200
  pt = s(:call, s(:call, nil, :a), :b)
3087
3201
 
@@ -3089,11 +3203,15 @@ module TestRubyParserShared19Plus
3089
3203
  end
3090
3204
 
3091
3205
  def test_motherfuckin_leading_dots2
3092
- skip if processor.class.version >= 27
3093
-
3094
- rb = "a\n..b"
3206
+ rb = "1\n..3"
3207
+ pt = s(:block, s(:lit, 1).line(1),
3208
+ s(:dot2, nil, s(:lit, 3).line(2)).line(2)).line(1)
3095
3209
 
3096
- assert_parse_error rb, '(string):2 :: parse error on value ".." (tDOT2)'
3210
+ if processor.class.version >= 27
3211
+ assert_parse rb, pt
3212
+ else
3213
+ assert_parse_error rb, '(string):2 :: parse error on value ".." (tDOT2)'
3214
+ end
3097
3215
  end
3098
3216
 
3099
3217
  def test_multiline_hash_declaration
@@ -3372,6 +3490,98 @@ end
3372
3490
  module TestRubyParserShared20Plus
3373
3491
  include TestRubyParserShared19Plus
3374
3492
 
3493
+ def test_read_escape_unicode_h4
3494
+ rb = '?\u00a0'
3495
+ pt = s(:str, ?\u00a0)
3496
+
3497
+ assert_parse rb, pt
3498
+ end
3499
+
3500
+ def test_read_escape_unicode_curlies
3501
+ rb = '?\u{00a0}'
3502
+ pt = s(:str, ?\u00a0)
3503
+
3504
+ assert_parse rb, pt
3505
+ end
3506
+
3507
+ def test_regexp_unicode_curlies
3508
+ rb = '/\u{df}/'
3509
+ pt = s(:lit, /\u{df}/)
3510
+
3511
+ assert_parse rb, pt
3512
+
3513
+ rb = '/\u{c0de babe}/'
3514
+ pt = s(:lit, /\u{c0de babe}/)
3515
+
3516
+ assert_parse rb, pt
3517
+ end
3518
+
3519
+ def test_qw_escape
3520
+ rb = "%q(\1\\\')"
3521
+ pt = s(:str, "\001\\'")
3522
+
3523
+ assert_parse rb, pt
3524
+ end
3525
+
3526
+ def test_pct_nl
3527
+ rb = "x = %\n\n"
3528
+ pt = s(:lasgn, :x, s(:str, ""))
3529
+
3530
+ assert_parse rb, pt
3531
+ end
3532
+
3533
+ def test_regexp_esc_C_slash
3534
+ rb = "/\\cC\\d/"
3535
+ pt = s(:lit, /\cC\d/)
3536
+
3537
+ assert_parse rb, pt
3538
+ end
3539
+
3540
+ def test_heredoc_wtf_I_hate_you
3541
+ rb = "p <<-END+'b\n a\n END\n c'+'d'"
3542
+ pt = s(:call, nil, :p,
3543
+ s(:call,
3544
+ s(:call, s(:str, " a\n"), :+,
3545
+ s(:str, "b\n c")),
3546
+ :+, s(:str, "d")))
3547
+
3548
+ assert_parse rb, pt
3549
+ end
3550
+
3551
+ def test_heredoc_nested
3552
+ rb = "[<<A,\n\#{<<B}\nb\nB\na\nA\n0]"
3553
+ pt = s(:array, s(:str, "b\n\na\n").line(1),
3554
+ s(:lit, 0).line(7)).line(1)
3555
+
3556
+ assert_parse rb, pt
3557
+ end
3558
+
3559
+ def test_pct_w_heredoc_interp_nested
3560
+ rb = "%W( 1 \#{<<A} 3\n2\nA\n 4 5 )"
3561
+ pt = s(:array,
3562
+ s(:str, "1"),
3563
+ s(:str, "2\n"),
3564
+ s(:str, "3"),
3565
+ s(:str, "4"),
3566
+ s(:str, "5"))
3567
+
3568
+ assert_parse rb, pt
3569
+ end
3570
+
3571
+ def test_regexp_esc_u
3572
+ rb = "/[\\u0021-\\u0027]/"
3573
+ pt = s(:lit, /[\u0021-\u0027]/)
3574
+
3575
+ assert_parse rb, pt
3576
+ end
3577
+
3578
+ def test_qw_escape_term
3579
+ rb = "%q|blah blah \\| blah blah|"
3580
+ pt = s(:str, "blah blah | blah blah")
3581
+
3582
+ assert_parse rb, pt
3583
+ end
3584
+
3375
3585
  def test_args_kw_block
3376
3586
  rb = "def f(a: 1, &b); end"
3377
3587
  pt = s(:defn, :f, s(:args, s(:kwarg, :a, s(:lit, 1)), :"&b"), s(:nil))
@@ -3379,6 +3589,49 @@ module TestRubyParserShared20Plus
3379
3589
  assert_parse rb, pt
3380
3590
  end
3381
3591
 
3592
+ def test_heredoc_backslash_nl
3593
+ rb = %Q(" why would someone do this? \\\n blah\n")
3594
+ pt = s(:str, " why would someone do this? blah\n")
3595
+
3596
+ assert_parse rb, pt
3597
+
3598
+ rb = "<<-DESC\n why would someone do this? \\\n blah\nDESC"
3599
+
3600
+ assert_parse rb, pt
3601
+ end
3602
+
3603
+ def test_heredoc_comma_arg
3604
+ rb = "[\" some text\n\",]"
3605
+ pt = s(:array, s(:str, " some text\n"))
3606
+
3607
+ assert_parse rb, pt
3608
+
3609
+ rb = "[<<-FILE,\n some text\nFILE\n]"
3610
+
3611
+ assert_parse rb, pt
3612
+ end
3613
+
3614
+ def test_heredoc_trailing_slash_continued_call
3615
+ rb = "<<END\\\nblah\nEND\n.strip"
3616
+ pt = s(:call, s(:str, "blah\n"), :strip)
3617
+
3618
+ assert_parse rb, pt
3619
+ end
3620
+
3621
+ def test_pct_q_backslash_nl
3622
+ rb = "%q{ \\\n}"
3623
+ pt = s(:str, " \\\n")
3624
+
3625
+ assert_parse rb, pt
3626
+ end
3627
+
3628
+ def test_pct_Q_backslash_nl
3629
+ rb = "%Q{ \\\n}"
3630
+ pt = s(:str, " ")
3631
+
3632
+ assert_parse rb, pt
3633
+ end
3634
+
3382
3635
  def test_block_arg_kwsplat
3383
3636
  rb = "a { |**b| }"
3384
3637
  pt = s(:iter, s(:call, nil, :a), s(:args, :"**b"))
@@ -3623,19 +3876,22 @@ module TestRubyParserShared20Plus
3623
3876
  s(:array,
3624
3877
  s(:lit, :a).line(2),
3625
3878
  s(:lit, :b).line(3)).line(1),
3626
- s(:lit, 1).line(5))
3879
+ s(:lit, 1).line(5)).line(1)
3627
3880
  assert_parse rb, pt
3628
3881
  end
3629
3882
 
3630
3883
  def test_iter_array_curly
3631
- skip if processor.class.version >= 25
3632
-
3633
3884
  rb = "f :a, [:b] { |c, d| }" # yes, this is bad code... that's their problem
3634
3885
  pt = s(:iter,
3635
3886
  s(:call, nil, :f, s(:lit, :a), s(:array, s(:lit, :b))),
3636
3887
  s(:args, :c, :d))
3637
3888
 
3638
- assert_parse rb, pt
3889
+ if processor.class.version >= 25 then
3890
+ msg = /parse error on value "\{" \(tLCURLY\)/
3891
+ assert_syntax_error rb, msg, Racc::ParseError
3892
+ else
3893
+ assert_parse rb, pt
3894
+ end
3639
3895
  end
3640
3896
 
3641
3897
  def test_iter_kwarg
@@ -3749,6 +4005,17 @@ end
3749
4005
  module TestRubyParserShared21Plus
3750
4006
  include TestRubyParserShared20Plus
3751
4007
 
4008
+ def test_array_lits_trailing_calls
4009
+ rb = "[].b"
4010
+ pt = s(:call, s(:array), :b)
4011
+
4012
+ assert_parse rb, pt
4013
+
4014
+ rb = "%w[].b"
4015
+
4016
+ assert_parse rb, pt
4017
+ end
4018
+
3752
4019
  def test_block_kw
3753
4020
  rb = "blah { |k:42| }"
3754
4021
  pt = s(:iter, s(:call, nil, :blah), s(:args, s(:kwarg, :k, s(:lit, 42))))
@@ -3771,7 +4038,7 @@ module TestRubyParserShared21Plus
3771
4038
 
3772
4039
  def test_bug162__21plus
3773
4040
  rb = %q(<<E\nfoo\nE\rO)
3774
- emsg = "can't match /E(\\r*\\n|\\z)/ anywhere in . near line 1: \"\""
4041
+ emsg = "can't match /E(?=\\r?\\n|\\z)/ anywhere in . near line 1: \"\""
3775
4042
 
3776
4043
  assert_syntax_error rb, emsg
3777
4044
  end
@@ -3967,6 +4234,27 @@ module TestRubyParserShared23Plus
3967
4234
  assert_parse rb, pt
3968
4235
  end
3969
4236
 
4237
+ def test_heredoc_squiggly_blank_lines
4238
+ rb = "a = <<~EOF\n x\n\n z\nEOF\n\n"
4239
+ pt = s(:lasgn, :a, s(:str, "x\n\nz\n"))
4240
+
4241
+ assert_parse rb, pt
4242
+ end
4243
+
4244
+ def test_heredoc_squiggly_visually_blank_lines
4245
+ rb = "a = <<~EOF\n x\n \n z\nEOF\n\n"
4246
+ pt = s(:lasgn, :a, s(:str, "x\n\nz\n"))
4247
+
4248
+ assert_parse rb, pt
4249
+ end
4250
+
4251
+ def test_heredoc_squiggly_empty
4252
+ rb = "<<~A\nA"
4253
+ pt = s(:str, "")
4254
+
4255
+ assert_parse rb, pt
4256
+ end
4257
+
3970
4258
  def test_integer_with_if_modifier
3971
4259
  rb = "1_234if true"
3972
4260
  pt = s(:if, s(:true), s(:lit, 1234), nil)
@@ -4056,7 +4344,7 @@ module TestRubyParserShared23Plus
4056
4344
  end
4057
4345
 
4058
4346
  def test_safe_op_asgn
4059
- rb = "a&.b += x 1\n"
4347
+ rb = "a&.b += x 1"
4060
4348
  pt = s(:safe_op_asgn, s(:call, nil, :a), s(:call, nil, :x, s(:lit, 1)), :b, :+).line(1)
4061
4349
 
4062
4350
  assert_parse rb, pt
@@ -4119,6 +4407,18 @@ module TestRubyParserShared26Plus
4119
4407
  assert_parse rb, pt
4120
4408
  end
4121
4409
 
4410
+ def test_begin_else_return_value # overrides above, warns < 2.6
4411
+ rb = "begin; else 2; end"
4412
+
4413
+ assert_syntax_error rb, "else without rescue is useless"
4414
+ end
4415
+
4416
+ def test_bug_begin_else # overrides above, warns < 2.6
4417
+ rb = "begin 1; else; 2 end"
4418
+
4419
+ assert_syntax_error rb, "else without rescue is useless"
4420
+ end
4421
+
4122
4422
  def test_dot3_nil__26
4123
4423
  rb = "a..."
4124
4424
  pt = s(:dot3, s(:call, nil, :a), nil)
@@ -4136,53 +4436,855 @@ module TestRubyParserShared26Plus
4136
4436
  end
4137
4437
  end
4138
4438
 
4139
- module TestRubyParserShared27Plus
4140
- include TestRubyParserShared26Plus
4439
+ module TestPatternMatching
4440
+ def rip rb
4441
+ require "ripper"
4442
+ puts
4443
+ pp Sexp.from_array Ripper.sexp rb
4444
+ end
4141
4445
 
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)))
4446
+ def assert_case_in lit, exp_pt
4447
+ rb = "case :a\nin #{lit}\nend"
4146
4448
 
4147
- assert_parse_line rb, pt, 1
4449
+ if ENV["VERBOSE_TEST"] then
4450
+ puts
4451
+ puts rb
4452
+ end
4453
+
4454
+ pt = s(:case, s(:lit, :a).line(1),
4455
+ s(:in, exp_pt, nil).line(2),
4456
+ nil).line(1)
4457
+
4458
+ assert_parse rb, pt
4148
4459
  end
4149
4460
 
4150
- def test_defn_arg_forward_args
4151
- rb = "def a(x, ...); b(x, ...); end"
4152
- pt = s(:defn, :a, s(:args, :x, s(:forward_args)),
4153
- s(:call, nil, :b, s(:lvar, :x), s(:forward_args)))
4461
+ def test_case_in_09
4462
+ assert_case_in(":b, [:c]",
4463
+ s(:array_pat, nil,
4464
+ s(:lit, :b).line(2),
4465
+ s(:array_pat, nil, s(:lit, :c).line(2)).line(2)).line(2))
4466
+ end
4154
4467
 
4155
- assert_parse_line rb, pt, 1
4468
+ def test_case_in_10
4469
+ assert_case_in "nil, nil, nil", s(:array_pat,
4470
+ nil,
4471
+ s(:nil).line(2),
4472
+ s(:nil).line(2),
4473
+ s(:nil).line(2)).line(2)
4156
4474
  end
4157
4475
 
4158
- def test_defn_args_forward_args
4159
- rb = "def a(x, y, z, ...); b(:get, z, ...); end"
4160
- pt = s(:defn, :a, s(:args, :x, :y, :z, s(:forward_args)),
4161
- s(:call, nil, :b, s(:lit, :get), s(:lvar, :z),
4162
- s(:forward_args)))
4476
+ def test_case_in_21
4477
+ assert_case_in "Symbol()", s(:array_pat, s(:const, :Symbol).line(2)).line(2)
4478
+ end
4163
4479
 
4164
- assert_parse_line rb, pt, 1
4480
+ def test_case_in_26
4481
+ assert_case_in "(42)", s(:lit, 42).line(2)
4165
4482
  end
4166
4483
 
4167
- def test_call_forward_args_outside_method_definition
4168
- rb = "b(...)"
4484
+ def test_case_in_27
4485
+ assert_case_in("[A, *, B]",
4486
+ s(:array_pat, nil,
4487
+ s(:const, :A).line(2),
4488
+ :*,
4489
+ s(:const, :B).line(2)).line(2))
4490
+ end
4169
4491
 
4170
- assert_syntax_error rb, "Unexpected ..."
4492
+ def test_case_in_28_2
4493
+ assert_case_in '{ "b": }', s(:hash_pat, nil, s(:lit, :b).line(2), nil).line(2)
4171
4494
  end
4172
4495
 
4173
- def test_call_arg_forward_args_outside_method_definition
4174
- rb = "b(x, ...)"
4496
+ def test_case_in_28
4497
+ assert_case_in "[]", s(:array_pat).line(2)
4498
+ end
4175
4499
 
4176
- assert_syntax_error rb, "Unexpected ..."
4500
+ def test_case_in_29
4501
+ assert_case_in "**nil", s(:hash_pat, nil, s(:kwrest, :"**nil").line(2)).line(2)
4177
4502
  end
4178
- end
4179
4503
 
4180
- module TestRubyParserShared30Plus
4181
- include TestRubyParserShared27Plus
4182
- end
4504
+ def test_case_in_30
4505
+ assert_case_in "{}", s(:hash_pat, nil).line(2)
4506
+ end
4183
4507
 
4184
- class TestRubyParser < Minitest::Test
4185
- def test_cls_version
4508
+ def test_case_in_31?
4509
+ rb = "case :a\nin [:b, *c]\n :d\nend"
4510
+ pt = s(:case, s(:lit, :a).line(1),
4511
+ s(:in,
4512
+ s(:array_pat, nil, s(:lit, :b).line(2), :"*c").line(2),
4513
+ s(:lit, :d).line(3)).line(2),
4514
+ nil).line(1)
4515
+
4516
+ assert_parse rb, pt
4517
+ end
4518
+
4519
+ def test_case_in_32
4520
+ assert_case_in "(1...3)", s(:dot3, s(:lit, 1).line(2), s(:lit, 3).line(2)).line(2)
4521
+ end
4522
+
4523
+ def test_case_in_33
4524
+ assert_case_in "(1...)", s(:dot3, s(:lit, 1).line(2), nil).line(2)
4525
+ end
4526
+
4527
+ def test_case_in_34
4528
+ assert_case_in "(..10)", s(:dot2, nil, s(:lit, 10).line(2)).line(2)
4529
+ end
4530
+
4531
+ def test_case_in_35
4532
+ assert_case_in "(...10)", s(:dot3, nil, s(:lit, 10).line(2)).line(2)
4533
+ end
4534
+
4535
+ def test_case_in_36
4536
+ rb = "[:a, b, c, [:d, *e, nil]]"
4537
+ pt = s(:array_pat,
4538
+ nil,
4539
+ s(:lit, :a).line(2),
4540
+ s(:lvar, :b).line(2),
4541
+ s(:lvar, :c).line(2),
4542
+ s(:array_pat,
4543
+ nil,
4544
+ s(:lit, :d).line(2),
4545
+ :"*e",
4546
+ s(:nil).line(2)).line(2)).line(2)
4547
+
4548
+ assert_case_in rb, pt
4549
+ end
4550
+
4551
+ def test_case_in_37
4552
+ rb = "case :a\nin { b: [Hash, *] }\n :c\nend"
4553
+ pt = s(:case, s(:lit, :a).line(1),
4554
+ s(:in,
4555
+ s(:hash_pat,
4556
+ nil,
4557
+ s(:lit, :b).line(2),
4558
+ s(:array_pat, nil, s(:const, :Hash).line(2), :"*").line(2)
4559
+ ).line(2),
4560
+ s(:lit, :c).line(3)).line(2),
4561
+ nil).line(1)
4562
+
4563
+ assert_parse rb, pt
4564
+ end
4565
+
4566
+ def test_case_in_42
4567
+ rb = "case :a\nin :b, *_ then nil\nend"
4568
+ pt = s(:case, s(:lit, :a).line(1),
4569
+ s(:in,
4570
+ s(:array_pat,
4571
+ nil,
4572
+ s(:lit, :b).line(2),
4573
+ :"*_",
4574
+ ).line(2),
4575
+ s(:nil).line(2)).line(2),
4576
+ nil).line(1)
4577
+
4578
+ assert_parse rb, pt
4579
+ end
4580
+
4581
+ def test_case_in_42_2
4582
+ rb = "case :a\nin A(*list) then nil\nend"
4583
+ pt = s(:case, s(:lit, :a).line(1),
4584
+ s(:in,
4585
+ s(:array_pat,
4586
+ s(:const, :A).line(2),
4587
+ :"*list").line(2),
4588
+ s(:nil).line(2)).line(2),
4589
+ nil).line(1)
4590
+
4591
+ assert_parse rb, pt
4592
+ end
4593
+
4594
+ def test_case_in_42_3
4595
+ assert_case_in ":b, *_, :c", s(:array_pat, nil,
4596
+ s(:lit, :b).line(2),
4597
+ :"*_",
4598
+ s(:lit, :c).line(2)).line(2)
4599
+ end
4600
+
4601
+
4602
+ def test_case_in_47
4603
+ rb = "case :a\nin [*, :b, :c]\n :d\nend"
4604
+ pt = s(:case, s(:lit, :a).line(1),
4605
+ s(:in,
4606
+ s(:array_pat, nil, :*,
4607
+ s(:lit, :b).line(2), s(:lit, :c).line(2)).line(2),
4608
+ s(:lit, :d).line(3)).line(2),
4609
+ nil).line(1)
4610
+
4611
+ assert_parse rb, pt
4612
+ end
4613
+
4614
+ def test_case_in_67
4615
+ rb = "case :a\nin 1.. then nil\nend"
4616
+ pt = s(:case,
4617
+ s(:lit, :a).line(1),
4618
+ s(:in, s(:dot2, s(:lit, 1).line(2), nil).line(2),
4619
+ s(:nil).line(2)).line(2),
4620
+ nil).line(1)
4621
+
4622
+ assert_parse rb, pt
4623
+ end
4624
+
4625
+ def test_case_in_76
4626
+ assert_case_in "`echo hi`", s(:xstr, "echo hi").line(2)
4627
+ end
4628
+
4629
+ def test_case_in_77
4630
+ assert_case_in "/regexp/", s(:lit, /regexp/).line(2)
4631
+ end
4632
+
4633
+ def test_case_in_78
4634
+ assert_case_in "%W[a b]", s(:array, s(:str, "a").line(2), s(:str, "b").line(2)).line(2)
4635
+ end
4636
+
4637
+ def test_case_in_79
4638
+ assert_case_in "%w[a b]", s(:array, s(:str, "a").line(2), s(:str, "b").line(2)).line(2)
4639
+ end
4640
+
4641
+ def test_case_in_80
4642
+ assert_case_in "%I[a b]", s(:array, s(:lit, :a).line(2), s(:lit, :b).line(2)).line(2)
4643
+ end
4644
+
4645
+ def test_case_in_81
4646
+ assert_case_in "%i[a b]", s(:array, s(:lit, :a).line(2), s(:lit, :b).line(2)).line(2)
4647
+ end
4648
+
4649
+ def test_case_in_83
4650
+ rb = "[->(b) { true }, c]"
4651
+ pt = s(:array_pat, nil,
4652
+ s(:iter, s(:lambda).line(2), s(:args, :b).line(2),
4653
+ s(:true).line(2)).line(2),
4654
+ s(:lvar, :c).line(2)).line(2)
4655
+
4656
+ assert_case_in rb, pt
4657
+ end
4658
+
4659
+ def test_case_in_85
4660
+ rb = "[[:b, c], [:d, ^e]]"
4661
+ pt = s(:array_pat, nil,
4662
+ s(:array_pat, nil,
4663
+ s(:lit, :b).line(2),
4664
+ s(:lvar, :c).line(2)).line(2),
4665
+ s(:array_pat,
4666
+ nil,
4667
+ s(:lit, :d).line(2),
4668
+ s(:lvar, :e).line(2)).line(2),
4669
+ ).line(2)
4670
+
4671
+ assert_case_in rb, pt
4672
+ end
4673
+
4674
+ def test_case_in_86
4675
+ rb = "case [:a, :b]\nin ::NilClass, * then nil\nend"
4676
+ pt = s(:case,
4677
+ s(:array, s(:lit, :a).line(1), s(:lit, :b).line(1)).line(1),
4678
+ s(:in,
4679
+ s(:array_pat,
4680
+ nil,
4681
+ s(:colon3, :NilClass).line(2),
4682
+ :*).line(2),
4683
+ s(:nil).line(2)).line(2),
4684
+ nil).line(1)
4685
+
4686
+ assert_parse rb, pt
4687
+ end
4688
+
4689
+ def test_case_in_86_2
4690
+ rb = "case [:a, :b]\nin *, ::NilClass then nil\nend"
4691
+ pt = s(:case,
4692
+ s(:array, s(:lit, :a).line(1), s(:lit, :b).line(1)).line(1),
4693
+ s(:in,
4694
+ s(:array_pat,
4695
+ nil,
4696
+ :*,
4697
+ s(:colon3, :NilClass).line(2)).line(2),
4698
+ s(:nil).line(2)).line(2),
4699
+ nil).line(1)
4700
+
4701
+ assert_parse rb, pt
4702
+ end
4703
+
4704
+ def test_case_in_array_pat_const
4705
+ rb = "case :a\nin B[c]\n :d\nend"
4706
+ pt = s(:case, s(:lit, :a).line(1),
4707
+ s(:in,
4708
+ s(:array_pat,
4709
+ s(:const, :B).line(2),
4710
+ s(:lvar, :c).line(2)).line(2),
4711
+ s(:lit, :d).line(3)).line(2),
4712
+ nil).line(1)
4713
+
4714
+ assert_parse rb, pt
4715
+ end
4716
+
4717
+ def test_case_in_array_pat_const2
4718
+ rb = "case :a\nin B::C[d]\n :e\nend"
4719
+ pt = s(:case, s(:lit, :a).line(1),
4720
+ s(:in,
4721
+ s(:array_pat,
4722
+ s(:const, s(:colon2, s(:const, :B).line(2), :C).line(2)).line(2),
4723
+ s(:lvar, :d).line(2)).line(2),
4724
+ s(:lit, :e).line(3)).line(2),
4725
+ nil).line(1)
4726
+
4727
+ assert_parse rb, pt
4728
+ end
4729
+
4730
+ def test_case_in_array_pat_paren_assign
4731
+ rb = "case :a\nin B(C => d)\n :d\nend"
4732
+ pt = s(:case, s(:lit, :a).line(1),
4733
+ s(:in,
4734
+ s(:array_pat,
4735
+ s(:const, :B).line(2),
4736
+ s(:lasgn, :d, s(:const, :C).line(2)).line(2)).line(2),
4737
+ s(:lit, :d).line(3)).line(2),
4738
+ nil).line(1)
4739
+
4740
+ assert_parse rb, pt
4741
+ end
4742
+
4743
+ def test_case_in_const
4744
+ rb = "case Array\nin Class\n :b\nend"
4745
+ pt = s(:case, s(:const, :Array).line(1),
4746
+ s(:in, s(:const, :Class).line(2),
4747
+ s(:lit, :b).line(3)).line(2),
4748
+ nil).line 1
4749
+
4750
+ assert_parse rb, pt
4751
+ end
4752
+
4753
+ def test_case_in_else
4754
+ rb = "case Array\nin Class\n :b\nelse\n :c\nend\n"
4755
+ pt = s(:case, s(:const, :Array).line(1),
4756
+ s(:in, s(:const, :Class).line(2),
4757
+ s(:lit, :b).line(3)).line(2),
4758
+ s(:lit, :c).line(5)).line 1
4759
+
4760
+ assert_parse rb, pt
4761
+ end
4762
+
4763
+ def test_case_in_hash_pat
4764
+ rb = "case :a\nin { b: 'c', d: \"e\" } then\n :f\nend\n"
4765
+ pt = s(:case, s(:lit, :a).line(1),
4766
+ s(:in,
4767
+ s(:hash_pat,
4768
+ nil,
4769
+ s(:lit, :b).line(2), s(:str, "c").line(2),
4770
+ s(:lit, :d).line(2), s(:str, "e").line(2)).line(2),
4771
+ s(:lit, :f).line(3)
4772
+ ).line(2),
4773
+ nil).line(1)
4774
+
4775
+ assert_parse rb, pt
4776
+ end
4777
+
4778
+ def test_case_in_hash_pat_assign
4779
+ rb = "case :a\nin { b: Integer => x, d: \"e\", f: } then\n :g\nend"
4780
+ pt = s(:case, s(:lit, :a).line(1),
4781
+ s(:in,
4782
+ s(:hash_pat,
4783
+ nil,
4784
+ s(:lit, :b).line(2), # =>
4785
+ s(:lasgn, :x, s(:const, :Integer).line(2)).line(2),
4786
+ s(:lit, :d).line(2), s(:str, "e").line(2),
4787
+ s(:lit, :f).line(2), nil).line(2),
4788
+ s(:lit, :g).line(3)).line(2),
4789
+ nil).line(1)
4790
+
4791
+ assert_parse rb, pt
4792
+ end
4793
+
4794
+ def test_case_in_hash_pat_paren_assign
4795
+ rb = "case :a\nin B(a: 42)\n :d\nend"
4796
+ pt = s(:case, s(:lit, :a).line(1),
4797
+ s(:in,
4798
+ s(:hash_pat,
4799
+ s(:const, :B).line(2),
4800
+ s(:lit, :a).line(2), s(:lit, 42).line(2)).line(2),
4801
+ s(:lit, :d).line(3)).line(2),
4802
+ nil).line(1)
4803
+
4804
+ assert_parse rb, pt
4805
+ end
4806
+
4807
+ def test_case_in_hash_pat_paren_true
4808
+ rb = "case :a\nin b: true then\n :c\nend\n"
4809
+ pt = s(:case, s(:lit, :a).line(1),
4810
+ s(:in,
4811
+ s(:hash_pat,
4812
+ nil,
4813
+ s(:lit, :b).line(2), s(:true).line(2)).line(2),
4814
+ s(:lit, :c).line(3)).line(2),
4815
+ nil).line(1)
4816
+
4817
+ assert_parse rb, pt
4818
+ end
4819
+
4820
+ def test_case_in_hash_pat_rest
4821
+ rb = "case :a\nin b: c, **rest then :d\nend"
4822
+ pt = s(:case,
4823
+ s(:lit, :a).line(1),
4824
+ s(:in,
4825
+ s(:hash_pat,
4826
+ nil,
4827
+ s(:lit, :b).line(2),
4828
+ s(:lvar, :c).line(2),
4829
+ s(:kwrest, :"**rest").line(2)).line(2),
4830
+ s(:lit, :d).line(2)).line(2),
4831
+ nil).line(1)
4832
+
4833
+ assert_parse rb, pt
4834
+ end
4835
+
4836
+ def test_case_in_hash_pat_rest_solo
4837
+ rb = "case :a\nin **rest then :d\nend"
4838
+ pt = s(:case,
4839
+ s(:lit, :a).line(1),
4840
+ s(:in,
4841
+ s(:hash_pat,
4842
+ nil,
4843
+ s(:kwrest, :"**rest").line(2)).line(2),
4844
+ s(:lit, :d).line(2)).line(2),
4845
+ nil).line(1)
4846
+
4847
+ assert_parse rb, pt
4848
+ end
4849
+
4850
+ def test_case_in_if_unless_post_mod
4851
+ rb = "case :a\nin A if true\n :C\nin D unless false\n :E\nend"
4852
+ pt = s(:case,
4853
+ s(:lit, :a).line(1),
4854
+ s(:in,
4855
+ s(:if, s(:true).line(2), s(:const, :A).line(2), nil).line(2),
4856
+ s(:lit, :C).line(3)).line(2),
4857
+ s(:in,
4858
+ s(:if, s(:false).line(4), nil, s(:const, :D).line(4)).line(4),
4859
+ s(:lit, :E).line(5)).line(4),
4860
+ nil).line(1)
4861
+
4862
+ assert_parse rb, pt
4863
+ end
4864
+
4865
+ def test_case_in_multiple
4866
+ rb = "case :a\nin A::B\n :C\nin D::E\n :F\nend"
4867
+ pt = s(:case,
4868
+ s(:lit, :a).line(1),
4869
+ s(:in,
4870
+ s(:const, s(:colon2, s(:const, :A).line(2), :B).line(2)).line(2),
4871
+ s(:lit, :C).line(3)).line(2),
4872
+ s(:in,
4873
+ s(:const, s(:colon2, s(:const, :D).line(4), :E).line(4)).line(4),
4874
+ s(:lit, :F).line(5)).line(4),
4875
+ nil).line(1)
4876
+
4877
+ assert_parse rb, pt
4878
+ end
4879
+
4880
+ def test_case_in_or
4881
+ rb = "case :a\nin B | C\n :d\nend\n"
4882
+ pt = s(:case, s(:lit, :a).line(1),
4883
+ s(:in,
4884
+ s(:or,
4885
+ s(:const, :B).line(2),
4886
+ s(:const, :C).line(2)).line(2),
4887
+ s(:lit, :d).line(3)).line(2),
4888
+ nil).line(1)
4889
+
4890
+ assert_parse rb, pt
4891
+ end
4892
+
4893
+ def test_in_expr_no_case
4894
+ rb = "'woot' in String"
4895
+ pt = s(:case, s(:str, "woot").line(1),
4896
+ s(:in, s(:const, :String).line(1),
4897
+ nil).line(1),
4898
+ nil).line(1)
4899
+
4900
+ assert_parse rb, pt
4901
+ end
4902
+
4903
+ def test_parse_pattern_019
4904
+ rb = <<~RUBY
4905
+ case 0
4906
+ in -1..1
4907
+ true
4908
+ end
4909
+ RUBY
4910
+
4911
+ pt = s(:case,
4912
+ s(:lit, 0).line(1),
4913
+ s(:in, s(:dot2, s(:lit, -1).line(2), s(:lit, 1).line(2)).line(2),
4914
+ s(:true).line(3)).line(2),
4915
+ nil).line(1)
4916
+
4917
+ assert_parse rb, pt
4918
+ end
4919
+
4920
+ def test_parse_pattern_044
4921
+ rb = <<~RUBY
4922
+ case obj
4923
+ in Object[]
4924
+ true
4925
+ end
4926
+ RUBY
4927
+ pt = s(:case,
4928
+ s(:call, nil, :obj).line(1),
4929
+ s(:in, s(:array_pat, s(:const, :Object).line(2)).line(2),
4930
+ s(:true).line(3)).line(2),
4931
+ nil).line(1)
4932
+
4933
+ assert_parse rb, pt
4934
+ end
4935
+
4936
+ def test_parse_pattern_051
4937
+ rb = <<~RUBY
4938
+ case [0, 1, 2]
4939
+ in [0, 1,]
4940
+ true
4941
+ end
4942
+ RUBY
4943
+ pt = s(:case,
4944
+ s(:array,
4945
+ s(:lit, 0).line(1),
4946
+ s(:lit, 1).line(1),
4947
+ s(:lit, 2).line(1)).line(1),
4948
+ s(:in,
4949
+ s(:array_pat,
4950
+ nil,
4951
+ s(:lit, 0).line(2),
4952
+ s(:lit, 1).line(2),
4953
+ :*).line(666),
4954
+ s(:true).line(3)).line(2),
4955
+ nil).line(1)
4956
+
4957
+ assert_parse rb, pt
4958
+ end
4959
+
4960
+ def test_parse_pattern_058
4961
+ rb = <<~RUBY
4962
+ case {a: 0}
4963
+ in {a:, **rest}
4964
+ [a, rest]
4965
+ end
4966
+ RUBY
4967
+ pt = s(:case,
4968
+ s(:hash,
4969
+ s(:lit, :a).line(1),
4970
+ s(:lit, 0).line(1)).line(1),
4971
+ s(:in,
4972
+ s(:hash_pat, nil, s(:lit, :a).line(2), nil,
4973
+ s(:kwrest, :"**rest").line(2)).line(2),
4974
+ s(:array,
4975
+ s(:lvar, :a).line(3),
4976
+ s(:lvar, :rest).line(3)).line(3)).line(2),
4977
+ nil).line(1)
4978
+
4979
+ assert_parse rb, pt
4980
+ end
4981
+
4982
+ def test_parse_pattern_058_2
4983
+ rb = <<~RUBY
4984
+ case {a: 0}
4985
+ in {a:, **}
4986
+ [a]
4987
+ end
4988
+ RUBY
4989
+ pt = s(:case,
4990
+ s(:hash,
4991
+ s(:lit, :a).line(1),
4992
+ s(:lit, 0).line(1)).line(1),
4993
+ s(:in,
4994
+ s(:hash_pat, nil, s(:lit, :a).line(2), nil,
4995
+ s(:kwrest, :"**").line(2)).line(2),
4996
+ s(:array,
4997
+ s(:lvar, :a).line(3)).line(3)).line(2),
4998
+ nil).line(1)
4999
+
5000
+ assert_parse rb, pt
5001
+ end
5002
+
5003
+ def test_parse_pattern_069
5004
+ rb = <<~RUBY
5005
+ case :a
5006
+ in Object[b: 1]
5007
+ 1
5008
+ end
5009
+ RUBY
5010
+ pt = s(:case,
5011
+ s(:lit, :a).line(1),
5012
+ s(:in,
5013
+ s(:hash_pat, s(:const, :Object).line(2),
5014
+ s(:lit, :b).line(2), s(:lit, 1).line(2)).line(2),
5015
+ s(:lit, 1).line(3)).line(2),
5016
+ nil).line(1)
5017
+
5018
+
5019
+ assert_parse rb, pt
5020
+ end
5021
+
5022
+ def test_parse_pattern_076
5023
+ rb = <<~RUBY
5024
+ case {a: 1}
5025
+ in {a: 1, **nil}
5026
+ true
5027
+ end
5028
+ RUBY
5029
+ pt = s(:case,
5030
+ s(:hash, s(:lit, :a).line(1), s(:lit, 1).line(1)).line(1),
5031
+ s(:in,
5032
+ s(:hash_pat, nil,
5033
+ s(:lit, :a).line(2), s(:lit, 1).line(2),
5034
+ s(:kwrest, :"**nil").line(2)).line(2),
5035
+ s(:true).line(3)).line(2),
5036
+ nil).line(1)
5037
+
5038
+ assert_parse rb, pt
5039
+ end
5040
+
5041
+ # def test_case_in_TEMPLATE
5042
+ # rb = "case :a\nin XXX then\n YYY\nend\n"
5043
+ # pt = s(:case, s(:lit, :a).line(1),
5044
+ # s(:in,
5045
+ # ZZZ,
5046
+ # WWW).line(2),
5047
+ # nil).line(1)
5048
+ #
5049
+ # assert_parse rb, pt
5050
+ # end
5051
+ end
5052
+
5053
+ module TestPatternMatching30
5054
+ def test_case_in_20
5055
+ assert_case_in("Symbol(*lhs, x, *rhs)",
5056
+ s(:find_pat,
5057
+ s(:const, :Symbol).line(2),
5058
+ :"*lhs",
5059
+ s(:array_pat, s(:lvar, :x).line(2)).line(2),
5060
+ :"*rhs").line(2))
5061
+ end
5062
+
5063
+ def test_case_in_22
5064
+ assert_case_in("Symbol[*lhs, x, *rhs]",
5065
+ s(:find_pat, s(:const, :Symbol).line(2),
5066
+ :"*lhs",
5067
+ s(:array_pat, s(:lvar, :x).line(2)).line(2),
5068
+ :"*rhs").line(2))
5069
+ end
5070
+ end
5071
+
5072
+ module TestRubyParserShared27Plus
5073
+ include TestRubyParserShared26Plus
5074
+ include TestPatternMatching
5075
+
5076
+ def test_block_args_kwargs
5077
+ rb = "f { |**kwargs| kwargs }"
5078
+ pt = s(:iter,
5079
+ s(:call, nil, :f),
5080
+ s(:args, :"**kwargs"),
5081
+ s(:lvar, :kwargs))
5082
+
5083
+ assert_parse rb, pt
5084
+ end
5085
+
5086
+ def test_block_args_no_kwargs
5087
+ rb = "f { |**nil| }"
5088
+ pt = s(:iter,
5089
+ s(:call, nil, :f),
5090
+ s(:args, :"**nil"))
5091
+
5092
+ assert_parse_line rb, pt, 1
5093
+ end
5094
+
5095
+ def test_defn_forward_args
5096
+ rb = "def a(...); b(...); end"
5097
+ pt = s(:defn, :a, s(:args, s(:forward_args)),
5098
+ s(:call, nil, :b, s(:forward_args)))
5099
+
5100
+ assert_parse_line rb, pt, 1
5101
+ end
5102
+
5103
+ def test_defn_arg_forward_args
5104
+ rb = "def a(x, ...); b(x, ...); end"
5105
+ pt = s(:defn, :a, s(:args, :x, s(:forward_args)),
5106
+ s(:call, nil, :b, s(:lvar, :x), s(:forward_args)))
5107
+
5108
+ assert_parse_line rb, pt, 1
5109
+ end
5110
+
5111
+ def test_defn_args_forward_args
5112
+ rb = "def a(x, y, z, ...); b(:get, z, ...); end"
5113
+ pt = s(:defn, :a, s(:args, :x, :y, :z, s(:forward_args)),
5114
+ s(:call, nil, :b, s(:lit, :get), s(:lvar, :z),
5115
+ s(:forward_args)))
5116
+
5117
+ assert_parse_line rb, pt, 1
5118
+ end
5119
+
5120
+ def test_defn_no_kwargs
5121
+ # def x(**nil)
5122
+ # end
5123
+ #
5124
+ # def y(**kw)
5125
+ # end
5126
+ #
5127
+ # def z()
5128
+ # end
5129
+ #
5130
+ # x arg: 42 # $!: no keywords accepted (ArgumentError)
5131
+ # y arg: 42 # fine
5132
+ # z arg: 42 # $!: wrong number of arguments (given 1, expected 0) (ArgumentError)
5133
+
5134
+ rb = "def x(**nil); end"
5135
+ pt = s(:defn, :x, s(:args, :"**nil").line(1),
5136
+ s(:nil).line(1)).line(1)
5137
+
5138
+ assert_parse_line rb, pt, 1
5139
+ end
5140
+
5141
+ def test_call_forward_args_outside_method_definition
5142
+ rb = "b(...)"
5143
+
5144
+ assert_syntax_error rb, "Unexpected ..."
5145
+ end
5146
+
5147
+ def test_call_arg_forward_args_outside_method_definition
5148
+ rb = "b(x, ...)"
5149
+
5150
+ assert_syntax_error rb, "Unexpected ..."
5151
+ end
5152
+
5153
+ def test_mlhs_rescue
5154
+ # same:
5155
+ # a = (24 rescue 42)
5156
+ # a = 24 rescue 42
5157
+
5158
+ # same:
5159
+ # a, b = (f rescue 42)
5160
+ # a, b = f rescue 42
5161
+
5162
+ rb = "a, b = f rescue 42"
5163
+ pt = s(:masgn,
5164
+ s(:array, s(:lasgn, :a), s(:lasgn, :b)),
5165
+ s(:to_ary,
5166
+ s(:rescue,
5167
+ s(:call, nil, :f),
5168
+ s(:resbody, s(:array),
5169
+ s(:lit, 42)))))
5170
+
5171
+ assert_parse rb, pt
5172
+ end
5173
+ end
5174
+
5175
+ module TestRubyParserShared30Plus
5176
+ include TestRubyParserShared27Plus
5177
+ include TestPatternMatching30
5178
+
5179
+ def test_rhs_asgn
5180
+ rb = "42 => n"
5181
+ pt = s(:case,
5182
+ s(:lit, 42).line(1),
5183
+ s(:in, s(:lvar, :n).line(1), nil).line(1), nil).line(1)
5184
+
5185
+ assert_parse rb, pt
5186
+ end
5187
+
5188
+ def test_case_in_find
5189
+ rb = "case :a\n in *a, :+, *b\nend"
5190
+ pt = s(:case,
5191
+ s(:lit, :a).line(1),
5192
+ s(:in,
5193
+ s(:find_pat, nil,
5194
+ :"*a",
5195
+ s(:array_pat, s(:lit, :+).line(2)).line(2),
5196
+ :"*b").line(2),
5197
+ nil).line(2),
5198
+ nil).line(1)
5199
+
5200
+ assert_parse rb, pt
5201
+ end
5202
+
5203
+ def test_case_in_find_array
5204
+ rb = "case :a\nin [*, :b, c, *]\nend"
5205
+ pt = s(:case,
5206
+ s(:lit, :a).line(1),
5207
+ s(:in,
5208
+ s(:find_pat, nil,
5209
+ :*,
5210
+ s(:array_pat, s(:lit, :b).line(2), s(:lvar, :c).line(2)).line(2),
5211
+ :*).line(2),
5212
+ nil).line(2),
5213
+ nil).line(1)
5214
+
5215
+ assert_parse rb, pt
5216
+ end
5217
+
5218
+ def test_defn_oneliner
5219
+ rb = "def exec(cmd) = system(cmd)"
5220
+ pt = s(:defn, :exec, s(:args, :cmd).line(1),
5221
+ s(:call, nil, :system, s(:lvar, :cmd).line(1)).line(1)).line(1)
5222
+
5223
+ assert_parse rb, pt
5224
+ end
5225
+
5226
+ def test_defn_oneliner_rescue
5227
+ rb = "def exec(cmd)\n system(cmd)\nrescue\n nil\nend\n"
5228
+ pt = s(:defn, :exec, s(:args, :cmd),
5229
+ s(:rescue,
5230
+ s(:call, nil, :system, s(:lvar, :cmd)),
5231
+ s(:resbody, s(:array), s(:nil))))
5232
+ assert_parse rb, pt
5233
+
5234
+ rb = "def exec(cmd)\n system(cmd) rescue nil\nend\n"
5235
+ assert_parse rb, pt
5236
+
5237
+ rb = "def exec(cmd) = system(cmd) rescue nil"
5238
+ assert_parse rb, pt
5239
+ end
5240
+
5241
+ def test_defs_oneliner
5242
+ rb = "def self.exec(cmd) = system(cmd)"
5243
+ pt = s(:defs,
5244
+ s(:self).line(1),
5245
+ :exec,
5246
+ s(:args, :cmd).line(1),
5247
+ s(:call, nil, :system, s(:lvar, :cmd).line(1)).line(1)).line(1)
5248
+
5249
+ assert_parse rb, pt
5250
+ end
5251
+
5252
+ def test_defs_oneliner_rescue
5253
+ rb = "def self.exec(cmd)\n system(cmd)\nrescue\n nil\nend\n"
5254
+ pt = s(:defs, s(:self), :exec, s(:args, :cmd),
5255
+ s(:rescue,
5256
+ s(:call, nil, :system, s(:lvar, :cmd)),
5257
+ s(:resbody, s(:array), s(:nil))))
5258
+ assert_parse rb, pt
5259
+
5260
+ rb = "def self.exec(cmd)\n system(cmd) rescue nil\nend\n"
5261
+ assert_parse rb, pt
5262
+
5263
+ rb = "def self.exec(cmd) = system(cmd) rescue nil"
5264
+ assert_parse rb, pt
5265
+ end
5266
+
5267
+ def test_defn_oneliner_setter
5268
+ rb = "class X\n def x=(o) = 42\nend"
5269
+
5270
+ assert_syntax_error rb, /setter method cannot be defined/
5271
+ end
5272
+
5273
+ def test_defs_oneliner_setter
5274
+ rb = "class X\n def self.x= = 42\nend"
5275
+
5276
+ assert_syntax_error rb, /setter method cannot be defined/
5277
+ end
5278
+ end
5279
+
5280
+ class Minitest::Test
5281
+ def skip s = "blah"
5282
+ warn "ignoring skip for %s: %s" % [name, s]
5283
+ end
5284
+ end if ENV["NOSKIP"]
5285
+
5286
+ class TestRubyParser < Minitest::Test
5287
+ def test_cls_version
4186
5288
  assert_equal 23, RubyParser::V23.version
4187
5289
  assert_equal 24, RubyParser::V24.version
4188
5290
  assert_equal 24, Ruby24Parser.version
@@ -4204,7 +5306,7 @@ class TestRubyParser < Minitest::Test
4204
5306
  end
4205
5307
  end
4206
5308
 
4207
- assert_includes e.message, 'parse error on value false ($end)'
5309
+ assert_includes e.message, 'parse error on value "$" ($end)'
4208
5310
  end
4209
5311
 
4210
5312
  def test_parse_error_from_first
@@ -4217,7 +5319,7 @@ class TestRubyParser < Minitest::Test
4217
5319
  end
4218
5320
 
4219
5321
  # This is a 2.x error, will fail on 1.8/1.9.
4220
- assert_includes e.message, 'parse error on value false ($end)'
5322
+ assert_includes e.message, 'parse error on value "$" ($end)'
4221
5323
  end
4222
5324
  end
4223
5325
 
@@ -4240,7 +5342,14 @@ class RubyParserTestCase < ParseTreeTestCase
4240
5342
  end
4241
5343
 
4242
5344
  def assert_parse rb, pt
4243
- self.result = processor.parse rb
5345
+ timeout = (ENV["RP_TIMEOUT"] || 10).to_i
5346
+
5347
+ if ENV["RP_LINES"] then # TODO: make default once tests cleaned up
5348
+ pt.deep_each { |s| s.line ||= 1 }
5349
+ pt.line ||= 1
5350
+ end
5351
+
5352
+ self.result = processor.parse rb, "(string)", timeout
4244
5353
  assert_equal pt, result
4245
5354
  end
4246
5355
 
@@ -4269,15 +5378,20 @@ class RubyParserTestCase < ParseTreeTestCase
4269
5378
  ENV["VERBOSE"] = old_env
4270
5379
  end
4271
5380
 
4272
- def assert_syntax_error rb, emsg
5381
+ def assert_syntax_error rb, emsg, klass = RubyParser::SyntaxError
4273
5382
  e = nil
4274
5383
  assert_silent do
4275
- e = assert_raises RubyParser::SyntaxError do
5384
+ e = assert_raises klass do
4276
5385
  processor.parse rb
4277
5386
  end
4278
5387
  end
4279
5388
 
4280
- assert_equal emsg, e.message
5389
+ case emsg
5390
+ when String
5391
+ assert_equal emsg, e.message
5392
+ else
5393
+ assert_match emsg, e.message
5394
+ end
4281
5395
  end
4282
5396
 
4283
5397
  def refute_parse rb
@@ -4294,17 +5408,6 @@ class TestRubyParserV20 < RubyParserTestCase
4294
5408
 
4295
5409
  self.processor = RubyParser::V20.new
4296
5410
  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
5411
  end
4309
5412
 
4310
5413
  class TestRubyParserV21 < RubyParserTestCase
@@ -4363,7 +5466,7 @@ class TestRubyParserV24 < RubyParserTestCase
4363
5466
 
4364
5467
  assert_parse rb, pt
4365
5468
 
4366
- assert_parse_error "a(b rescue c)", /parse error on value ..rescue/
5469
+ assert_parse_error "a(b rescue c)", /parse error on value .rescue/
4367
5470
  end
4368
5471
  end
4369
5472
 
@@ -4477,6 +5580,8 @@ class TestRubyParserV26 < RubyParserTestCase
4477
5580
  end
4478
5581
 
4479
5582
  class TestRubyParserV27 < RubyParserTestCase
5583
+ make_my_diffs_pretty!
5584
+
4480
5585
  include TestRubyParserShared27Plus
4481
5586
 
4482
5587
  def setup