ruby_parser 3.17.0 → 3.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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