ruby_parser 3.8.4 → 3.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,16 +2,16 @@
2
2
 
3
3
  # ENV['VERBOSE'] = "1"
4
4
 
5
- require 'rubygems'
6
- require 'minitest/autorun'
7
- require 'ruby_parser'
5
+ require "minitest/autorun"
6
+ require "ruby_parser"
8
7
 
9
- $: << File.expand_path('~/Work/p4/zss/src/sexp_processor/dev/lib')
8
+ $: << File.expand_path("~/Work/p4/zss/src/sexp_processor/dev/lib")
10
9
 
11
- require 'pt_testcase'
10
+ require "pt_testcase"
12
11
 
13
12
  class Sexp
14
13
  alias oldeq2 ==
14
+ # TODO: push up to Sexp
15
15
  def ==(obj) # :nodoc:
16
16
  if obj.class == self.class then
17
17
  super and
@@ -22,62 +22,6 @@ class Sexp
22
22
  end
23
23
  end
24
24
 
25
- class RubyParserTestCase < ParseTreeTestCase
26
- attr_accessor :result, :processor
27
-
28
- make_my_diffs_pretty!
29
-
30
- def self.previous key
31
- "Ruby"
32
- end
33
-
34
- def self.generate_test klass, node, data, input_name, output_name
35
- return if node.to_s =~ /bmethod|dmethod/
36
- return if Array === data['Ruby']
37
-
38
- output_name = "ParseTree"
39
-
40
- super
41
- end
42
-
43
- def assert_parse rb, pt
44
- self.result = processor.parse rb
45
- assert_equal pt, result
46
- end
47
-
48
- def refute_parse rb
49
- self.result = processor.parse rb
50
- assert_nil result
51
- end
52
-
53
- def assert_syntax_error rb, emsg
54
- e = nil
55
- assert_silent do
56
- e = assert_raises RubyParser::SyntaxError do
57
- processor.parse rb
58
- end
59
- end
60
-
61
- assert_equal emsg, e.message
62
- end
63
-
64
- def assert_parse_error rb, emsg
65
- e = nil
66
- assert_silent do
67
- e = assert_raises Racc::ParseError do
68
- processor.parse rb
69
- end
70
- end
71
-
72
- assert_equal emsg, e.message
73
- end
74
-
75
- def assert_parse_line rb, pt, line
76
- assert_parse rb, pt
77
- assert_equal line, result.line, "call should have line number"
78
- end
79
- end
80
-
81
25
  module TestRubyParserShared
82
26
  def setup
83
27
  super
@@ -388,7 +332,7 @@ module TestRubyParserShared
388
332
  end
389
333
 
390
334
  def test_lasgn_env
391
- rb = 'a = 42'
335
+ rb = "a = 42"
392
336
  pt = s(:lasgn, :a, s(:lit, 42))
393
337
  expected_env = { :a => :lvar }
394
338
 
@@ -397,7 +341,7 @@ module TestRubyParserShared
397
341
  end
398
342
 
399
343
  def test_lasgn_ivar_env
400
- rb = '@a = 42'
344
+ rb = "@a = 42"
401
345
  pt = s(:iasgn, :@a, s(:lit, 42))
402
346
 
403
347
  assert_parse rb, pt
@@ -484,15 +428,15 @@ module TestRubyParserShared
484
428
  assert_equal s(:str, "blah"), processor.literal_concat(lhs, rhs)
485
429
  end
486
430
 
487
- def test_logop_12
431
+ def test_logical_op_12
488
432
  lhs = s(:lit, 1)
489
433
  rhs = s(:lit, 2)
490
434
  exp = s(:and, s(:lit, 1), s(:lit, 2))
491
435
 
492
- assert_equal exp, processor.logop(:and, lhs, rhs)
436
+ assert_equal exp, processor.logical_op(:and, lhs, rhs)
493
437
  end
494
438
 
495
- def test_logop_1234_5
439
+ def test_logical_op_1234_5
496
440
  lhs = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:and, s(:lit, 3), s(:lit, 4))))
497
441
  rhs = s(:lit, 5)
498
442
  exp = s(:and,
@@ -505,10 +449,10 @@ module TestRubyParserShared
505
449
  s(:lit, 4),
506
450
  s(:lit, 5)))))
507
451
 
508
- assert_equal exp, processor.logop(:and, lhs, rhs)
452
+ assert_equal exp, processor.logical_op(:and, lhs, rhs)
509
453
  end
510
454
 
511
- def test_logop_123_4
455
+ def test_logical_op_123_4
512
456
  lhs = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:lit, 3)))
513
457
  rhs = s(:lit, 4)
514
458
  exp = s(:and,
@@ -519,18 +463,18 @@ module TestRubyParserShared
519
463
  s(:lit, 3),
520
464
  s(:lit, 4))))
521
465
 
522
- assert_equal exp, processor.logop(:and, lhs, rhs)
466
+ assert_equal exp, processor.logical_op(:and, lhs, rhs)
523
467
  end
524
468
 
525
- def test_logop_12_3
469
+ def test_logical_op_12_3
526
470
  lhs = s(:and, s(:lit, 1), s(:lit, 2))
527
471
  rhs = s(:lit, 3)
528
472
  exp = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:lit, 3)))
529
473
 
530
- assert_equal exp, processor.logop(:and, lhs, rhs)
474
+ assert_equal exp, processor.logical_op(:and, lhs, rhs)
531
475
  end
532
476
 
533
- def test_logop_nested_mix
477
+ def test_logical_op_nested_mix
534
478
  lhs = s(:or, s(:call, nil, :a), s(:call, nil, :b))
535
479
  rhs = s(:and, s(:call, nil, :c), s(:call, nil, :d))
536
480
  exp = s(:or,
@@ -540,7 +484,7 @@ module TestRubyParserShared
540
484
  lhs.paren = true
541
485
  rhs.paren = true
542
486
 
543
- assert_equal exp, processor.logop(:or, lhs, rhs)
487
+ assert_equal exp, processor.logical_op(:or, lhs, rhs)
544
488
  end
545
489
 
546
490
  def test_str_evstr
@@ -553,7 +497,7 @@ module TestRubyParserShared
553
497
  def test_dsym_to_sym
554
498
  pt = s(:alias, s(:lit, :<<), s(:lit, :>>))
555
499
 
556
- rb = 'alias :<< :>>'
500
+ rb = "alias :<< :>>"
557
501
  assert_parse rb, pt
558
502
 
559
503
  rb = 'alias :"<<" :">>"'
@@ -761,6 +705,15 @@ module TestRubyParserShared
761
705
  assert_parse rb, pt
762
706
  end
763
707
 
708
+ def test_parse_line_hash_lit
709
+ rb = "{\n:s1 => 1,\n}"
710
+ pt = s(:hash,
711
+ s(:lit, :s1).line(2), s(:lit, 1).line(2),
712
+ ).line(1)
713
+
714
+ assert_parse rb, pt
715
+ end
716
+
764
717
  def test_parse_line_heredoc_evstr
765
718
  skip "heredoc line numbers are just gonna be screwed for a while..."
766
719
 
@@ -857,6 +810,19 @@ module TestRubyParserShared
857
810
  assert_parse_line rb, pt, 1
858
811
  end
859
812
 
813
+ def test_parse_line_rescue
814
+ skip "not yet"
815
+ rb = "begin\n a\n rescue\n b\n rescue\n c\n end\n"
816
+ pt = s(:rescue,
817
+ s(:call, nil, :a).line(2),
818
+ s(:resbody, s(:array).line(3),
819
+ s(:call, nil, :b).line(4)).line(3),
820
+ s(:resbody, s(:array).line(5),
821
+ s(:call, nil, :c).line(6)).line(5)).line(1)
822
+
823
+ assert_parse_line rb, pt, 1
824
+ end
825
+
860
826
  def test_parse_line_return
861
827
  rb = <<-RUBY
862
828
  def blah
@@ -943,27 +909,7 @@ module TestRubyParserShared
943
909
  end
944
910
 
945
911
  def ruby18
946
- Ruby18Parser === self.processor
947
- end
948
-
949
- def ruby19
950
- Ruby19Parser === self.processor
951
- end
952
-
953
- def ruby20
954
- Ruby20Parser === self.processor
955
- end
956
-
957
- def ruby21
958
- Ruby21Parser === self.processor
959
- end
960
-
961
- def ruby22
962
- Ruby22Parser === self.processor
963
- end
964
-
965
- def ruby23
966
- Ruby23Parser === self.processor
912
+ RubyParser::V18 === self.processor
967
913
  end
968
914
 
969
915
  def test_bug_comma
@@ -1021,10 +967,8 @@ module TestRubyParserShared
1021
967
  rb = "not(a)"
1022
968
  pt = if ruby18 then
1023
969
  s(:not, s(:call, nil, :a))
1024
- elsif ruby19 or ruby20 or ruby21 or ruby22 or ruby23 then
1025
- s(:call, s(:call, nil, :a), :"!")
1026
970
  else
1027
- raise "wtf"
971
+ s(:call, s(:call, nil, :a), :"!")
1028
972
  end
1029
973
 
1030
974
  assert_parse rb, pt
@@ -1627,11 +1571,11 @@ module TestRubyParserShared
1627
1571
 
1628
1572
  def test___ENCODING__
1629
1573
  rb = "__ENCODING__"
1630
- pt = if Ruby18Parser === processor then
1574
+ pt = if RubyParser::V18 === processor then
1631
1575
  s(:call, nil, :__ENCODING__)
1632
1576
  else
1633
1577
  if defined? Encoding then
1634
- if Ruby18Parser === processor then
1578
+ if RubyParser::V18 === processor then
1635
1579
  s(:call, nil, :__ENCODING__)
1636
1580
  else
1637
1581
  s(:colon2, s(:const, :Encoding), :UTF_8)
@@ -1657,9 +1601,117 @@ module TestRubyParserShared
1657
1601
  assert_syntax_error "def a; class B; end; end", err
1658
1602
  assert_syntax_error "def a; def b; end; class B; end; end", err
1659
1603
  end
1604
+
1605
+ def test_call_not
1606
+ rb = "not 42"
1607
+ pt = s(:not, s(:lit, 42))
1608
+
1609
+ assert_parse rb, pt
1610
+ end
1611
+
1612
+ def test_call_bang_command_call
1613
+ rb = "! a.b 1"
1614
+ pt = s(:not, s(:call, s(:call, nil, :a), :b, s(:lit, 1)))
1615
+
1616
+ assert_parse rb, pt
1617
+ end
1618
+
1619
+ def test_call_unary_bang
1620
+ rb = "!1"
1621
+ pt = s(:not, s(:lit, 1))
1622
+
1623
+ assert_parse rb, pt
1624
+ end
1625
+
1626
+ def test_bang_eq
1627
+ rb = "1 != 2"
1628
+ pt = s(:not, s(:call, s(:lit, 1), :"==", s(:lit, 2)))
1629
+
1630
+ assert_parse rb, pt
1631
+ end
1632
+
1633
+ def test_flip2_env_lvar
1634
+ rb = "if a..b then end"
1635
+ pt = s(:if, s(:flip2, s(:call, nil, :a), s(:call, nil, :b)), nil, nil)
1636
+
1637
+ assert_parse rb, pt
1638
+
1639
+ top_env = processor.env.env.first
1640
+
1641
+ assert_kind_of Hash, top_env
1642
+
1643
+ flip = top_env.find { |k,v| k =~ /^flip/ }
1644
+
1645
+ assert flip
1646
+ assert_equal :lvar, flip.last
1647
+ end
1648
+
1649
+ def test_parse_until_not_canonical
1650
+ rb = "until not var.nil?\n 'foo'\nend"
1651
+
1652
+ pt = s(:while,
1653
+ s(:call, s(:call, nil, :var), :nil?),
1654
+ s(:str, "foo"), true)
1655
+
1656
+ assert_parse rb, pt
1657
+ end
1658
+
1659
+ def test_parse_until_not_noncanonical
1660
+ rb = "until not var.nil?\n 'foo'\nend"
1661
+ pt = s(:until,
1662
+ s(:not, s(:call, s(:call, nil, :var), :nil?)),
1663
+ s(:str, "foo"), true)
1664
+
1665
+ processor.canonicalize_conditions = false
1666
+
1667
+ assert_parse rb, pt
1668
+ end
1669
+
1670
+ def test_parse_if_not_canonical
1671
+ rb = "if not var.nil? then 'foo' else 'bar'\nend"
1672
+ pt = s(:if,
1673
+ s(:call, s(:call, nil, :var), :nil?),
1674
+ s(:str, "bar"),
1675
+ s(:str, "foo"))
1676
+
1677
+ assert_parse rb, pt
1678
+ end
1679
+
1680
+ def test_parse_if_not_noncanonical
1681
+ rb = "if not var.nil? then 'foo' else 'bar'\nend"
1682
+ pt = s(:if,
1683
+ s(:not, s(:call, s(:call, nil, :var), :nil?)),
1684
+ s(:str, "foo"),
1685
+ s(:str, "bar"))
1686
+
1687
+ processor.canonicalize_conditions = false
1688
+
1689
+ assert_parse rb, pt
1690
+ end
1691
+
1692
+ def test_parse_while_not_canonical
1693
+ rb = "while not var.nil?\n 'foo'\nend"
1694
+ pt = s(:until,
1695
+ s(:call, s(:call, nil, :var), :nil?),
1696
+ s(:str, "foo"), true)
1697
+
1698
+ assert_parse rb, pt
1699
+ end
1700
+
1701
+ def test_parse_while_not_noncanonical
1702
+ rb = "while not var.nil?\n 'foo'\nend"
1703
+ pt = s(:while,
1704
+ s(:not, s(:call, s(:call, nil, :var), :nil?)),
1705
+ s(:str, "foo"), true)
1706
+
1707
+ processor.canonicalize_conditions = false
1708
+
1709
+ assert_parse rb, pt
1710
+ end
1711
+
1660
1712
  end
1661
1713
 
1662
- module TestRubyParserShared19to22
1714
+ module TestRubyParserShared19Plus
1663
1715
  def test_aref_args_lit_assocs
1664
1716
  rb = "[1, 2 => 3]"
1665
1717
  pt = s(:array, s(:lit, 1), s(:hash, s(:lit, 2), s(:lit, 3)))
@@ -2223,429 +2275,66 @@ module TestRubyParserShared19to22
2223
2275
  assert_parse "f(state: {\n})", pt
2224
2276
  assert_parse "f(state:\n {\n})", pt
2225
2277
  end
2226
- end
2227
-
2228
- module TestRubyParserShared20to22
2229
- def test_non_interpolated_symbol_array_line_breaks
2230
2278
 
2231
- rb = "%i(\na\nb\n)\n1"
2232
- pt = s(:block,
2279
+ def test_mlhs_back_splat
2280
+ rb = "a, b, c, *s = f"
2281
+ pt = s(:masgn,
2233
2282
  s(:array,
2234
- s(:lit, :a).line(2),
2235
- s(:lit, :b).line(3)).line(1),
2236
- s(:lit, 1).line(5))
2283
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
2284
+ s(:splat, s(:lasgn, :s))),
2285
+ s(:to_ary, s(:call, nil, :f)))
2286
+
2237
2287
  assert_parse rb, pt
2238
2288
  end
2239
2289
 
2240
- def test_interpolated_symbol_array_line_breaks
2241
-
2242
- rb = "%I(\na\nb\n)\n1"
2243
- pt = s(:block,
2290
+ def test_mlhs_back_anonsplat
2291
+ rb = "a, b, c, * = f"
2292
+ pt = s(:masgn,
2244
2293
  s(:array,
2245
- s(:lit, :a).line(2),
2246
- s(:lit, :b).line(3)).line(1),
2247
- s(:lit, 1).line(5))
2294
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
2295
+ s(:splat)),
2296
+ s(:to_ary, s(:call, nil, :f)))
2297
+
2248
2298
  assert_parse rb, pt
2249
2299
  end
2250
2300
 
2251
- def test_defs_kwarg
2252
- rb = "def self.a b: 1\nend"
2253
- pt = s(:defs, s(:self), :a, s(:args, s(:kwarg, :b, s(:lit, 1))), s(:nil))
2301
+ def test_mlhs_mid_splat
2302
+ rb = "a, b, c, *s, x, y, z = f"
2303
+ pt = s(:masgn,
2304
+ s(:array,
2305
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
2306
+ s(:splat, s(:lasgn, :s)),
2307
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
2308
+ s(:to_ary, s(:call, nil, :f)))
2254
2309
 
2255
2310
  assert_parse rb, pt
2256
2311
  end
2257
2312
 
2258
- def test_defn_kwarg_kwsplat
2259
- rb = "def a(b: 1, **c) end"
2260
- pt = s(:defn, :a, s(:args, s(:kwarg, :b, s(:lit, 1)), :"**c"), s(:nil))
2313
+ def test_mlhs_mid_anonsplat
2314
+ rb = "a, b, c, *, x, y, z = f"
2315
+ pt = s(:masgn,
2316
+ s(:array, s(:lasgn, :a), s(:splat), s(:lasgn, :z)),
2317
+ s(:to_ary, s(:call, nil, :f)))
2318
+ pt = s(:masgn,
2319
+ s(:array,
2320
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
2321
+ s(:splat),
2322
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
2323
+ s(:to_ary, s(:call, nil, :f)))
2261
2324
 
2262
2325
  assert_parse rb, pt
2263
2326
  end
2264
2327
 
2265
- def test_defn_kwarg_kwsplat_anon
2266
- rb = "def a(b: 1, **) end"
2267
- pt = s(:defn, :a, s(:args, s(:kwarg, :b, s(:lit, 1)), :"**"), s(:nil))
2268
-
2269
- assert_parse rb, pt
2270
- end
2271
-
2272
- def test_defn_kwarg_env
2273
- rb = "def test(**testing) test_splat(**testing) end"
2274
- pt = s(:defn, :test, s(:args, :"**testing"),
2275
- s(:call, nil, :test_splat, s(:hash, s(:kwsplat, s(:lvar, :testing)))))
2276
-
2277
- assert_parse rb, pt
2278
- end
2279
-
2280
- def test_dstr_lex_state
2281
- rb = '"#{p:a}"'
2282
- pt = s(:dstr, "", s(:evstr, s(:call, nil, :p, s(:lit, :a))))
2283
-
2284
- assert_parse rb, pt
2285
- end
2286
-
2287
- def test_call_arg_kwsplat
2288
- rb = "a(b, **1)"
2289
- pt = s(:call, nil, :a, s(:call, nil, :b), s(:hash, s(:kwsplat, s(:lit, 1))))
2290
-
2291
- assert_parse rb, pt
2292
- end
2293
-
2294
- def test_call_arg_assoc_kwsplat
2295
- rb = "f(1, kw: 2, **3)"
2296
- pt = s(:call, nil, :f,
2297
- s(:lit, 1),
2298
- s(:hash, s(:lit, :kw), s(:lit, 2), s(:kwsplat, s(:lit, 3))))
2299
-
2300
- assert_parse rb, pt
2301
- end
2302
-
2303
- def test_call_kwsplat
2304
- rb = "a(**1)"
2305
- pt = s(:call, nil, :a, s(:hash, s(:kwsplat, s(:lit, 1))))
2306
-
2307
- assert_parse rb, pt
2308
- end
2309
-
2310
- def test_iter_kwarg
2311
- rb = "a { |b: 1| }"
2312
- pt = s(:iter, s(:call, nil, :a), s(:args, s(:kwarg, :b, s(:lit, 1))))
2313
-
2314
- assert_parse rb, pt
2315
- end
2316
-
2317
- def test_iter_kwarg_kwsplat
2318
- rb = "a { |b: 1, **c| }"
2319
- pt = s(:iter, s(:call, nil, :a), s(:args, s(:kwarg, :b, s(:lit, 1)), :"**c"))
2320
-
2321
- assert_parse rb, pt
2322
- end
2323
-
2324
- def test_block_kwarg_lvar
2325
- rb = "bl { |kw: :val| kw }"
2326
- pt = s(:iter, s(:call, nil, :bl), s(:args, s(:kwarg, :kw, s(:lit, :val))),
2327
- s(:lvar, :kw))
2328
-
2329
- assert_parse rb, pt
2330
- end
2331
-
2332
- def test_block_kwarg_lvar_multiple
2333
- rb = "bl { |kw: :val, kw2: :val2 | kw }"
2334
- pt = s(:iter, s(:call, nil, :bl),
2335
- s(:args,
2336
- s(:kwarg, :kw, s(:lit, :val)),
2337
- s(:kwarg, :kw2, s(:lit, :val2))),
2338
- s(:lvar, :kw))
2339
-
2340
- assert_parse rb, pt
2341
- end
2342
- end
2343
-
2344
- class TestRubyParser < Minitest::Test
2345
- def test_parse
2346
- processor = RubyParser.new
2347
-
2348
- # 1.8 only syntax
2349
- rb = "while false : 42 end"
2350
- pt = s(:while, s(:false), s(:lit, 42), true)
2351
-
2352
- assert_silent do
2353
- assert_equal pt, processor.parse(rb)
2354
- end
2355
-
2356
- # 1.9 only syntax
2357
- rb = "a.()"
2358
- pt = s(:call, s(:call, nil, :a), :call)
2359
-
2360
- assert_equal pt, processor.parse(rb)
2361
-
2362
- # bad syntax
2363
- e = assert_raises Racc::ParseError do
2364
- capture_io do
2365
- processor.parse "a.("
2366
- end
2367
- end
2368
-
2369
- msg = "(string):1 :: parse error on value \"(\" (tLPAREN2)"
2370
- assert_equal msg, e.message.strip
2371
- end
2372
- end
2373
-
2374
- class TestRuby18Parser < RubyParserTestCase
2375
- include TestRubyParserShared
2376
-
2377
- def setup
2378
- super
2379
-
2380
- self.processor = Ruby18Parser.new
2381
- end
2382
-
2383
- def test_call_space_before_paren_args
2384
- rb = "a (:b, :c, :d => :e)"
2385
- pt = s(:call, nil, :a,
2386
- s(:lit, :b),
2387
- s(:lit, :c),
2388
- s(:hash, s(:lit, :d), s(:lit, :e)))
2389
-
2390
- assert_parse rb, pt
2391
- end
2392
-
2393
- def test_flip2_env_lvar
2394
- rb = "if a..b then end"
2395
- pt = s(:if, s(:flip2, s(:call, nil, :a), s(:call, nil, :b)), nil, nil)
2396
-
2397
- assert_parse rb, pt
2398
-
2399
- top_env = processor.env.env.first
2400
-
2401
- assert_kind_of Hash, top_env
2402
-
2403
- flip = top_env.find { |k,v| k =~ /^flip/ }
2404
-
2405
- assert flip
2406
- assert_equal :lvar, flip.last
2407
- end
2408
-
2409
- def test_assoc_list_18
2410
- rb = "{1, 2, 3, 4}"
2411
- pt = s(:hash, s(:lit, 1), s(:lit, 2), s(:lit, 3), s(:lit, 4))
2412
-
2413
- assert_parse rb, pt
2414
- end
2415
-
2416
- def test_case_then_colon_18
2417
- rb = "case x; when Fixnum: 42; end"
2418
- pt = s(:case,
2419
- s(:call, nil, :x),
2420
- s(:when, s(:array, s(:const, :Fixnum)), s(:lit, 42)),
2421
- nil)
2422
-
2423
- assert_parse rb, pt
2424
- end
2425
-
2426
- def test_do_colon_18
2427
- rb = "while false : 42 end"
2428
- pt = s(:while, s(:false), s(:lit, 42), true)
2429
-
2430
- assert_parse rb, pt
2431
- end
2432
-
2433
- def test_parse_until_not_canonical
2434
- rb = "until not var.nil?\n 'foo'\nend"
2435
-
2436
- pt = s(:while,
2437
- s(:call, s(:call, nil, :var), :nil?),
2438
- s(:str, "foo"), true)
2439
-
2440
- assert_parse rb, pt
2441
- end
2442
-
2443
- def test_parse_until_not_noncanonical
2444
- rb = "until not var.nil?\n 'foo'\nend"
2445
- pt = s(:until,
2446
- s(:not, s(:call, s(:call, nil, :var), :nil?)),
2447
- s(:str, "foo"), true)
2448
-
2449
- processor.canonicalize_conditions = false
2450
-
2451
- assert_parse rb, pt
2452
- end
2453
-
2454
- def test_parse_if_not_canonical
2455
- rb = "if not var.nil? then 'foo' else 'bar'\nend"
2456
- pt = s(:if,
2457
- s(:call, s(:call, nil, :var), :nil?),
2458
- s(:str, "bar"),
2459
- s(:str, "foo"))
2460
-
2461
- assert_parse rb, pt
2462
- end
2463
-
2464
- def test_parse_if_not_noncanonical
2465
- rb = "if not var.nil? then 'foo' else 'bar'\nend"
2466
- pt = s(:if,
2467
- s(:not, s(:call, s(:call, nil, :var), :nil?)),
2468
- s(:str, "foo"),
2469
- s(:str, "bar"))
2470
-
2471
- processor.canonicalize_conditions = false
2472
-
2473
- assert_parse rb, pt
2474
- end
2475
-
2476
- def test_parse_while_not_canonical
2477
- rb = "while not var.nil?\n 'foo'\nend"
2478
- pt = s(:until,
2479
- s(:call, s(:call, nil, :var), :nil?),
2480
- s(:str, "foo"), true)
2481
-
2482
- assert_parse rb, pt
2483
- end
2484
-
2485
- def test_parse_while_not_noncanonical
2486
- rb = "while not var.nil?\n 'foo'\nend"
2487
- pt = s(:while,
2488
- s(:not, s(:call, s(:call, nil, :var), :nil?)),
2489
- s(:str, "foo"), true)
2490
-
2491
- processor.canonicalize_conditions = false
2492
-
2493
- assert_parse rb, pt
2494
- end
2495
-
2496
- def test_double_block_error_10
2497
- assert_syntax_error "a.b (&b) {}", BLOCK_DUP_MSG
2498
- end
2499
-
2500
- def test_double_block_error_11
2501
- assert_syntax_error "a (1, &b) { }", BLOCK_DUP_MSG
2502
- end
2503
-
2504
- def test_double_block_error_12
2505
- assert_syntax_error "a (1, &b) do end", BLOCK_DUP_MSG
2506
- end
2507
-
2508
- def test_double_block_error_13
2509
- assert_syntax_error "m.a (1, &b) { }", BLOCK_DUP_MSG
2510
- end
2511
-
2512
- def test_double_block_error_14
2513
- assert_syntax_error "m.a (1, &b) do end", BLOCK_DUP_MSG
2514
- end
2515
-
2516
- def test_double_block_error_15
2517
- assert_syntax_error "m::a (1, &b) { }", BLOCK_DUP_MSG
2518
- end
2519
-
2520
- def test_double_block_error_16
2521
- assert_syntax_error "m::a (1, &b) do end", BLOCK_DUP_MSG
2522
- end
2523
-
2524
- # In 1.8, block args with an outer set of parens are superfluous.
2525
- # In 1.9, outer set of parens are NOT... they are an explicit extra masgn.
2526
-
2527
- def test_iter_args_2_18
2528
- rb = "f { |(a, b)| }"
2529
- pt = s(:iter, s(:call, nil, :f), s(:args, :a, :b))
2530
-
2531
- assert_parse rb, pt
2532
- end
2533
-
2534
- def test_bug_args__18
2535
- rb = "f { |(a, b)| }"
2536
- pt = s(:iter, s(:call, nil, :f),
2537
- s(:args, :a, :b))
2538
-
2539
- assert_parse rb, pt
2540
- end
2541
-
2542
- def test_bug_args_masgn_outer_parens__18
2543
- rb = "f { |((a, b), c)| }"
2544
- pt = s(:iter, # NOTE: same sexp as test_bug_args_masgn
2545
- s(:call, nil, :f),
2546
- s(:args, s(:masgn, :a, :b), :c))
2547
-
2548
- assert_parse rb, pt.dup
2549
- end
2550
-
2551
- def test_call_unary_bang
2552
- rb = "!1"
2553
- pt = s(:not, s(:lit, 1))
2554
-
2555
- assert_parse rb, pt
2556
- end
2557
-
2558
- def test_bang_eq
2559
- rb = "1 != 2"
2560
- pt = s(:not, s(:call, s(:lit, 1), :"==", s(:lit, 2)))
2561
-
2562
- assert_parse rb, pt
2563
- end
2564
-
2565
- def test_call_not
2566
- rb = "not 42"
2567
- pt = s(:not, s(:lit, 42))
2568
-
2569
- assert_parse rb, pt
2570
- end
2571
-
2572
- def test_call_bang_command_call
2573
- rb = "! a.b 1"
2574
- pt = s(:not, s(:call, s(:call, nil, :a), :b, s(:lit, 1)))
2575
-
2576
- assert_parse rb, pt
2577
- end
2578
- end
2579
-
2580
- class TestRuby19Parser < RubyParserTestCase
2581
- include TestRubyParserShared
2582
- include TestRubyParserShared19to22
2583
-
2584
- def setup
2585
- super
2586
-
2587
- self.processor = Ruby19Parser.new
2588
- end
2589
-
2590
- def test_mlhs_back_splat
2591
- rb = "a, b, c, *s = f"
2592
- pt = s(:masgn,
2593
- s(:array,
2594
- s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
2595
- s(:splat, s(:lasgn, :s))),
2596
- s(:to_ary, s(:call, nil, :f)))
2597
-
2598
- assert_parse rb, pt
2599
- end
2600
-
2601
- def test_mlhs_back_anonsplat
2602
- rb = "a, b, c, * = f"
2603
- pt = s(:masgn,
2604
- s(:array,
2605
- s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
2606
- s(:splat)),
2607
- s(:to_ary, s(:call, nil, :f)))
2608
-
2609
- assert_parse rb, pt
2610
- end
2611
-
2612
- def test_mlhs_mid_splat
2613
- rb = "a, b, c, *s, x, y, z = f"
2614
- pt = s(:masgn,
2615
- s(:array,
2616
- s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
2617
- s(:splat, s(:lasgn, :s)),
2618
- s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
2619
- s(:to_ary, s(:call, nil, :f)))
2620
-
2621
- assert_parse rb, pt
2622
- end
2623
-
2624
- def test_mlhs_mid_anonsplat
2625
- rb = "a, b, c, *, x, y, z = f"
2626
- pt = s(:masgn,
2627
- s(:array, s(:lasgn, :a), s(:splat), s(:lasgn, :z)),
2628
- s(:to_ary, s(:call, nil, :f)))
2629
- pt = s(:masgn,
2630
- s(:array,
2631
- s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
2632
- s(:splat),
2633
- s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
2634
- s(:to_ary, s(:call, nil, :f)))
2635
-
2636
- assert_parse rb, pt
2637
- end
2638
-
2639
- def test_mlhs_front_splat
2640
- rb = "*s, x, y, z = f"
2641
- pt = s(:masgn,
2642
- s(:array, s(:splat, s(:lasgn, :s)), s(:lasgn, :z)),
2643
- s(:to_ary, s(:call, nil, :f)))
2644
- pt = s(:masgn,
2645
- s(:array,
2646
- s(:splat, s(:lasgn, :s)),
2647
- s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
2648
- s(:to_ary, s(:call, nil, :f)))
2328
+ def test_mlhs_front_splat
2329
+ rb = "*s, x, y, z = f"
2330
+ pt = s(:masgn,
2331
+ s(:array, s(:splat, s(:lasgn, :s)), s(:lasgn, :z)),
2332
+ s(:to_ary, s(:call, nil, :f)))
2333
+ pt = s(:masgn,
2334
+ s(:array,
2335
+ s(:splat, s(:lasgn, :s)),
2336
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
2337
+ s(:to_ary, s(:call, nil, :f)))
2649
2338
 
2650
2339
  assert_parse rb, pt
2651
2340
  end
@@ -2866,7 +2555,7 @@ class TestRuby19Parser < RubyParserTestCase
2866
2555
  assert_parse rb, pt
2867
2556
  end
2868
2557
 
2869
- def test_block_args_opt2
2558
+ def test_block_args_opt2_2
2870
2559
  rb = "f { |a, b = 42, c = 24| [a, b, c] }"
2871
2560
  pt = s(:iter,
2872
2561
  s(:call, nil, :f),
@@ -3062,144 +2751,341 @@ class TestRuby19Parser < RubyParserTestCase
3062
2751
  assert_parse rb, pt
3063
2752
  end
3064
2753
 
3065
- def test_iter_args_11_1
3066
- rb = "f { |a, b = 42, *c, d| }"
3067
- pt = s(:iter, s(:call, nil, :f),
3068
- s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :d))
2754
+ def test_iter_args_11_1
2755
+ rb = "f { |a, b = 42, *c, d| }"
2756
+ pt = s(:iter, s(:call, nil, :f),
2757
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :d))
2758
+
2759
+ assert_parse rb, pt
2760
+ end
2761
+
2762
+ def test_iter_args_11_2
2763
+ rb = "f { |a, b = 42, *c, d, &e| }"
2764
+ pt = s(:iter, s(:call, nil, :f),
2765
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :d, :"&e"))
2766
+
2767
+ assert_parse rb, pt
2768
+ end
2769
+
2770
+ def test_kill_me_6
2771
+ # | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
2772
+ rb = "f { |a, (b, *c, d)| }"
2773
+ pt = s(:iter,
2774
+ s(:call, nil, :f),
2775
+ s(:args, :a, s(:masgn, :b, :"*c", :d)))
2776
+
2777
+ assert_parse rb, pt
2778
+ end
2779
+
2780
+ def test_kill_me_7
2781
+ # | f_marg_list tCOMMA tSTAR
2782
+ rb = "f { |a, (b, *)| }"
2783
+ pt = s(:iter,
2784
+ s(:call, nil, :f),
2785
+ s(:args, :a, s(:masgn, :b, :*)))
2786
+
2787
+ assert_parse rb, pt
2788
+ end
2789
+
2790
+ def test_kill_me_8
2791
+ # | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
2792
+ rb = "f { |a, (b, *, c)| }"
2793
+ pt = s(:iter,
2794
+ s(:call, nil, :f),
2795
+ s(:args, :a, s(:masgn, :b, :*, :c)))
2796
+
2797
+ assert_parse rb, pt
2798
+ end
2799
+
2800
+ def test_kill_me_9
2801
+ # | tSTAR f_norm_arg
2802
+ rb = "f { |a, (*b)| }"
2803
+ pt = s(:iter,
2804
+ s(:call, nil, :f),
2805
+ s(:args, :a, s(:masgn, :"*b")))
2806
+
2807
+ assert_parse rb, pt
2808
+ end
2809
+
2810
+ def test_kill_me_10
2811
+ # | tSTAR f_norm_arg tCOMMA f_marg_list
2812
+ rb = "f { |a, (*b, c)| }"
2813
+ pt = s(:iter,
2814
+ s(:call, nil, :f),
2815
+ s(:args, :a, s(:masgn, :"*b", :c)))
2816
+
2817
+ assert_parse rb, pt
2818
+ end
2819
+
2820
+ def test_kill_me_11
2821
+ # | tSTAR
2822
+ rb = "f { |a, (*)| }"
2823
+ pt = s(:iter,
2824
+ s(:call, nil, :f),
2825
+ s(:args, :a, s(:masgn, :*)))
2826
+
2827
+ assert_parse rb, pt
2828
+ end
2829
+
2830
+ def test_kill_me_12
2831
+ # | tSTAR tCOMMA f_marg_list
2832
+ rb = "f { |a, (*, b)| }"
2833
+ pt = s(:iter,
2834
+ s(:call, nil, :f),
2835
+ s(:args, :a, s(:masgn, :*, :b)))
2836
+
2837
+ assert_parse rb, pt
2838
+ end
2839
+
2840
+ def test_index_0
2841
+ rb = "a[] = b"
2842
+ pt = s(:attrasgn, s(:call, nil, :a), :[]=, s(:call, nil, :b))
2843
+
2844
+ assert_parse rb, pt
2845
+ end
2846
+
2847
+ def test_lambda_do_vs_brace
2848
+ pt = s(:call, nil, :f, s(:iter, s(:call, nil, :lambda), s(:args)))
2849
+
2850
+ rb = "f ->() {}"
2851
+ assert_parse rb, pt
2852
+
2853
+ rb = "f ->() do end"
2854
+ assert_parse rb, pt
2855
+
2856
+ pt = s(:call, nil, :f, s(:iter, s(:call, nil, :lambda), 0))
2857
+
2858
+ rb = "f -> {}"
2859
+ assert_parse rb, pt
2860
+
2861
+ rb = "f -> do end"
2862
+ assert_parse rb, pt
2863
+ end
2864
+
2865
+ def test_thingy
2866
+ pt = s(:call, s(:call, nil, :f), :call, s(:lit, 42))
2867
+
2868
+ rb = "f.(42)"
2869
+ assert_parse rb, pt
2870
+
2871
+ rb = "f::(42)"
2872
+ assert_parse rb, pt
2873
+ end
2874
+
2875
+ def test_unary_plus_on_literal
2876
+ rb = "+:a"
2877
+ pt = s(:call, s(:lit, :a), :+@)
2878
+
2879
+ assert_parse rb, pt
2880
+ end
2881
+ end
2882
+
2883
+ module TestRubyParserShared21Plus
2884
+ def test_f_kw
2885
+ rb = "def x k:42; end"
2886
+ pt = s(:defn, :x, s(:args, s(:kwarg, :k, s(:lit, 42))), s(:nil))
2887
+
2888
+ assert_parse rb, pt
2889
+ end
2890
+
2891
+ def test_f_kw__required
2892
+ rb = "def x k:; end"
2893
+ pt = s(:defn, :x, s(:args, s(:kwarg, :k)), s(:nil))
2894
+
2895
+ assert_parse rb, pt
2896
+ end
2897
+
2898
+ def test_block_kw
2899
+ rb = "blah { |k:42| }"
2900
+ pt = s(:iter, s(:call, nil, :blah), s(:args, s(:kwarg, :k, s(:lit, 42))))
2901
+
2902
+ assert_parse rb, pt
2903
+
2904
+ rb = "blah { |k:42| }"
2905
+ assert_parse rb, pt
2906
+ end
2907
+
2908
+ def test_block_kw__required
2909
+ rb = "blah do |k:| end"
2910
+ pt = s(:iter, s(:call, nil, :blah), s(:args, s(:kwarg, :k)))
2911
+
2912
+ assert_parse rb, pt
2913
+
2914
+ rb = "blah do |k:| end"
2915
+ assert_parse rb, pt
2916
+ end
2917
+
2918
+ def test_stabby_block_kw
2919
+ rb = "-> (k:42) { }"
2920
+ pt = s(:iter, s(:call, nil, :lambda), s(:args, s(:kwarg, :k, s(:lit, 42))))
2921
+
2922
+ assert_parse rb, pt
2923
+ end
2924
+
2925
+ def test_stabby_block_kw__required
2926
+ rb = "-> (k:) { }"
2927
+ pt = s(:iter, s(:call, nil, :lambda), s(:args, s(:kwarg, :k)))
3069
2928
 
3070
2929
  assert_parse rb, pt
3071
2930
  end
3072
2931
 
3073
- def test_iter_args_11_2
3074
- rb = "f { |a, b = 42, *c, d, &e| }"
3075
- pt = s(:iter, s(:call, nil, :f),
3076
- s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :d, :"&e"))
2932
+ def test_parse_line_heredoc_hardnewline
2933
+ skip "not yet"
2934
+
2935
+ rb = <<-'CODE'.gsub(/^ /, '')
2936
+ <<-EOFOO
2937
+ \n\n\n\n\n\n\n\n\n
2938
+ EOFOO
2939
+
2940
+ class Foo
2941
+ end
2942
+ CODE
2943
+
2944
+ pt = s(:block,
2945
+ s(:str, "\n\n\n\n\n\n\n\n\n\n").line(1),
2946
+ s(:class, :Foo, nil).line(5)).line(1)
3077
2947
 
3078
2948
  assert_parse rb, pt
3079
2949
  end
2950
+ end
3080
2951
 
3081
- def test_kill_me_6
3082
- # | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
3083
- rb = "f { |a, (b, *c, d)| }"
3084
- pt = s(:iter,
3085
- s(:call, nil, :f),
3086
- s(:args, :a, s(:masgn, :b, :"*c", :d)))
2952
+ module TestRubyParserShared20Plus
2953
+ def test_non_interpolated_symbol_array_line_breaks
3087
2954
 
2955
+ rb = "%i(\na\nb\n)\n1"
2956
+ pt = s(:block,
2957
+ s(:array,
2958
+ s(:lit, :a).line(2),
2959
+ s(:lit, :b).line(3)).line(1),
2960
+ s(:lit, 1).line(5))
3088
2961
  assert_parse rb, pt
3089
2962
  end
3090
2963
 
3091
- def test_kill_me_7
3092
- # | f_marg_list tCOMMA tSTAR
3093
- rb = "f { |a, (b, *)| }"
3094
- pt = s(:iter,
3095
- s(:call, nil, :f),
3096
- s(:args, :a, s(:masgn, :b, :*)))
2964
+ def test_interpolated_symbol_array_line_breaks
3097
2965
 
2966
+ rb = "%I(\na\nb\n)\n1"
2967
+ pt = s(:block,
2968
+ s(:array,
2969
+ s(:lit, :a).line(2),
2970
+ s(:lit, :b).line(3)).line(1),
2971
+ s(:lit, 1).line(5))
3098
2972
  assert_parse rb, pt
3099
2973
  end
3100
2974
 
3101
- def test_kill_me_8
3102
- # | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
3103
- rb = "f { |a, (b, *, c)| }"
3104
- pt = s(:iter,
3105
- s(:call, nil, :f),
3106
- s(:args, :a, s(:masgn, :b, :*, :c)))
2975
+ def test_defs_kwarg
2976
+ rb = "def self.a b: 1\nend"
2977
+ pt = s(:defs, s(:self), :a, s(:args, s(:kwarg, :b, s(:lit, 1))), s(:nil))
3107
2978
 
3108
2979
  assert_parse rb, pt
3109
2980
  end
3110
2981
 
3111
- def test_kill_me_9
3112
- # | tSTAR f_norm_arg
3113
- rb = "f { |a, (*b)| }"
3114
- pt = s(:iter,
3115
- s(:call, nil, :f),
3116
- s(:args, :a, s(:masgn, :"*b")))
2982
+ def test_defn_kwarg_kwsplat
2983
+ rb = "def a(b: 1, **c) end"
2984
+ pt = s(:defn, :a, s(:args, s(:kwarg, :b, s(:lit, 1)), :"**c"), s(:nil))
3117
2985
 
3118
2986
  assert_parse rb, pt
3119
2987
  end
3120
2988
 
3121
- def test_kill_me_10
3122
- # | tSTAR f_norm_arg tCOMMA f_marg_list
3123
- rb = "f { |a, (*b, c)| }"
3124
- pt = s(:iter,
3125
- s(:call, nil, :f),
3126
- s(:args, :a, s(:masgn, :"*b", :c)))
2989
+ def test_defn_kwarg_kwsplat_anon
2990
+ rb = "def a(b: 1, **) end"
2991
+ pt = s(:defn, :a, s(:args, s(:kwarg, :b, s(:lit, 1)), :"**"), s(:nil))
3127
2992
 
3128
2993
  assert_parse rb, pt
3129
2994
  end
3130
2995
 
3131
- def test_kill_me_11
3132
- # | tSTAR
3133
- rb = "f { |a, (*)| }"
3134
- pt = s(:iter,
3135
- s(:call, nil, :f),
3136
- s(:args, :a, s(:masgn, :*)))
2996
+ def test_defn_kwarg_env
2997
+ rb = "def test(**testing) test_splat(**testing) end"
2998
+ pt = s(:defn, :test, s(:args, :"**testing"),
2999
+ s(:call, nil, :test_splat, s(:hash, s(:kwsplat, s(:lvar, :testing)))))
3137
3000
 
3138
3001
  assert_parse rb, pt
3139
3002
  end
3140
3003
 
3141
- def test_kill_me_12
3142
- # | tSTAR tCOMMA f_marg_list
3143
- rb = "f { |a, (*, b)| }"
3144
- pt = s(:iter,
3145
- s(:call, nil, :f),
3146
- s(:args, :a, s(:masgn, :*, :b)))
3004
+ def test_dstr_lex_state
3005
+ rb = '"#{p:a}"'
3006
+ pt = s(:dstr, "", s(:evstr, s(:call, nil, :p, s(:lit, :a))))
3147
3007
 
3148
3008
  assert_parse rb, pt
3149
3009
  end
3150
3010
 
3151
- def test_index_0
3152
- rb = "a[] = b"
3153
- pt = s(:attrasgn, s(:call, nil, :a), :[]=, s(:call, nil, :b))
3011
+ def test_call_arg_kwsplat
3012
+ rb = "a(b, **1)"
3013
+ pt = s(:call, nil, :a, s(:call, nil, :b), s(:hash, s(:kwsplat, s(:lit, 1))))
3154
3014
 
3155
3015
  assert_parse rb, pt
3156
3016
  end
3157
3017
 
3158
- def test_lambda_do_vs_brace
3159
- pt = s(:call, nil, :f, s(:iter, s(:call, nil, :lambda), s(:args)))
3018
+ def test_call_arg_assoc_kwsplat
3019
+ rb = "f(1, kw: 2, **3)"
3020
+ pt = s(:call, nil, :f,
3021
+ s(:lit, 1),
3022
+ s(:hash, s(:lit, :kw), s(:lit, 2), s(:kwsplat, s(:lit, 3))))
3160
3023
 
3161
- rb = "f ->() {}"
3162
3024
  assert_parse rb, pt
3025
+ end
3026
+
3027
+ def test_call_kwsplat
3028
+ rb = "a(**1)"
3029
+ pt = s(:call, nil, :a, s(:hash, s(:kwsplat, s(:lit, 1))))
3163
3030
 
3164
- rb = "f ->() do end"
3165
3031
  assert_parse rb, pt
3032
+ end
3166
3033
 
3167
- pt = s(:call, nil, :f, s(:iter, s(:call, nil, :lambda), 0))
3034
+ def test_iter_kwarg
3035
+ rb = "a { |b: 1| }"
3036
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:kwarg, :b, s(:lit, 1))))
3168
3037
 
3169
- rb = "f -> {}"
3170
3038
  assert_parse rb, pt
3039
+ end
3040
+
3041
+ def test_iter_kwarg_kwsplat
3042
+ rb = "a { |b: 1, **c| }"
3043
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:kwarg, :b, s(:lit, 1)), :"**c"))
3171
3044
 
3172
- rb = "f -> do end"
3173
3045
  assert_parse rb, pt
3174
3046
  end
3175
3047
 
3176
- def test_thingy
3177
- pt = s(:call, s(:call, nil, :f), :call, s(:lit, 42))
3048
+ def test_block_kwarg_lvar
3049
+ rb = "bl { |kw: :val| kw }"
3050
+ pt = s(:iter, s(:call, nil, :bl), s(:args, s(:kwarg, :kw, s(:lit, :val))),
3051
+ s(:lvar, :kw))
3178
3052
 
3179
- rb = "f.(42)"
3180
3053
  assert_parse rb, pt
3054
+ end
3055
+
3056
+ def test_block_kwarg_lvar_multiple
3057
+ rb = "bl { |kw: :val, kw2: :val2 | kw }"
3058
+ pt = s(:iter, s(:call, nil, :bl),
3059
+ s(:args,
3060
+ s(:kwarg, :kw, s(:lit, :val)),
3061
+ s(:kwarg, :kw2, s(:lit, :val2))),
3062
+ s(:lvar, :kw))
3181
3063
 
3182
- rb = "f::(42)"
3183
3064
  assert_parse rb, pt
3184
3065
  end
3185
3066
 
3186
- def test_unary_plus_on_literal
3187
- rb = "+:a"
3188
- pt = s(:call, s(:lit, :a), :+@)
3067
+ def test_stabby_block_iter_call
3068
+ rb = "x -> () do\na.b do\nend\nend"
3069
+ pt = s(:call, nil, :x,
3070
+ s(:iter,
3071
+ s(:call, nil, :lambda),
3072
+ s(:args),
3073
+ s(:iter, s(:call, s(:call, nil, :a), :b), 0)))
3189
3074
 
3190
3075
  assert_parse rb, pt
3191
3076
  end
3192
- end
3193
-
3194
- class TestRuby20Parser < RubyParserTestCase
3195
- include TestRubyParserShared
3196
- include TestRubyParserShared20to22
3197
- include TestRubyParserShared19to22
3198
3077
 
3199
- def setup
3200
- super
3078
+ def test_stabby_block_iter_call_no_target_with_arg
3079
+ rb = "x -> () do\na(1) do\nend\nend"
3080
+ pt = s(:call, nil, :x,
3081
+ s(:iter,
3082
+ s(:call, nil, :lambda),
3083
+ s(:args),
3084
+ s(:iter,
3085
+ s(:call, nil, :a,
3086
+ s(:lit, 1)), 0)))
3201
3087
 
3202
- self.processor = Ruby20Parser.new
3088
+ assert_parse rb, pt
3203
3089
  end
3204
3090
 
3205
3091
  def test_block_call_dot_op2_brace_block
@@ -3345,113 +3231,17 @@ class TestRuby20Parser < RubyParserTestCase
3345
3231
  assert_parse rb, pt
3346
3232
  end
3347
3233
 
3348
- def test_defn_unary_not
3349
- rb = "def !@; true; end" # I seriously HATE this
3350
- pt = s(:defn, :"!@", s(:args), s(:true))
3351
-
3352
- assert_parse rb, pt
3353
- end
3354
-
3355
3234
  def test_iter_array_curly
3356
3235
  rb = "f :a, [:b] { |c, d| }" # yes, this is bad code... that's their problem
3357
3236
  pt = s(:iter,
3358
3237
  s(:call, nil, :f, s(:lit, :a), s(:array, s(:lit, :b))),
3359
3238
  s(:args, :c, :d))
3360
3239
 
3361
- assert_parse rb, pt
3362
- end
3363
- end
3364
-
3365
- class TestRuby21Parser < RubyParserTestCase
3366
- include TestRubyParserShared
3367
- include TestRubyParserShared19to22
3368
- include TestRubyParserShared20to22
3369
-
3370
- def setup
3371
- super
3372
-
3373
- self.processor = Ruby21Parser.new
3374
- end
3375
-
3376
- def test_f_kw
3377
- rb = "def x k:42; end"
3378
- pt = s(:defn, :x, s(:args, s(:kwarg, :k, s(:lit, 42))), s(:nil))
3379
-
3380
- assert_parse rb, pt
3381
- end
3382
-
3383
- def test_f_kw__required
3384
- rb = "def x k:; end"
3385
- pt = s(:defn, :x, s(:args, s(:kwarg, :k)), s(:nil))
3386
-
3387
- assert_parse rb, pt
3388
- end
3389
-
3390
- def test_block_kw
3391
- rb = "blah { |k:42| }"
3392
- pt = s(:iter, s(:call, nil, :blah), s(:args, s(:kwarg, :k, s(:lit, 42))))
3393
-
3394
- assert_parse rb, pt
3395
-
3396
- rb = "blah { |k:42| }"
3397
- assert_parse rb, pt
3398
- end
3399
-
3400
- def test_block_kw__required
3401
- rb = "blah do |k:| end"
3402
- pt = s(:iter, s(:call, nil, :blah), s(:args, s(:kwarg, :k)))
3403
-
3404
- assert_parse rb, pt
3405
-
3406
- rb = "blah do |k:| end"
3407
- assert_parse rb, pt
3408
- end
3409
-
3410
- def test_stabby_block_kw
3411
- rb = "-> (k:42) { }"
3412
- pt = s(:iter, s(:call, nil, :lambda), s(:args, s(:kwarg, :k, s(:lit, 42))))
3413
-
3414
- assert_parse rb, pt
3415
- end
3416
-
3417
- def test_stabby_block_kw__required
3418
- rb = "-> (k:) { }"
3419
- pt = s(:iter, s(:call, nil, :lambda), s(:args, s(:kwarg, :k)))
3420
-
3421
- assert_parse rb, pt
3422
- end
3423
-
3424
- def test_parse_line_heredoc_hardnewline
3425
- skip "not yet"
3426
-
3427
- rb = <<-'CODE'.gsub(/^ /, '')
3428
- <<-EOFOO
3429
- \n\n\n\n\n\n\n\n\n
3430
- EOFOO
3431
-
3432
- class Foo
3433
- end
3434
- CODE
3435
-
3436
- pt = s(:block,
3437
- s(:str, "\n\n\n\n\n\n\n\n\n\n").line(1),
3438
- s(:class, :Foo, nil).line(5)).line(1)
3439
-
3440
- assert_parse rb, pt
3441
- end
3442
- end
3443
-
3444
- class TestRuby22Parser < RubyParserTestCase
3445
- include TestRubyParserShared
3446
- include TestRubyParserShared19to22
3447
- include TestRubyParserShared20to22
3448
-
3449
- def setup
3450
- super
3451
-
3452
- self.processor = Ruby22Parser.new
3240
+ assert_parse rb, pt
3453
3241
  end
3242
+ end
3454
3243
 
3244
+ module TestRubyParserShared22Plus
3455
3245
  def test_call_args_assoc_quoted
3456
3246
  pt = s(:call, nil, :x, s(:hash, s(:lit, :k), s(:lit, 42)))
3457
3247
 
@@ -3492,17 +3282,7 @@ class TestRuby22Parser < RubyParserTestCase
3492
3282
  end
3493
3283
  end
3494
3284
 
3495
- class TestRuby23Parser < RubyParserTestCase
3496
- include TestRubyParserShared
3497
- include TestRubyParserShared19to22
3498
- include TestRubyParserShared20to22
3499
-
3500
- def setup
3501
- super
3502
-
3503
- self.processor = Ruby23Parser.new
3504
- end
3505
-
3285
+ module TestRubyParserShared23Plus
3506
3286
  def test_safe_call
3507
3287
  rb = "a&.b"
3508
3288
  pt = s(:safe_call, s(:call, nil, :a), :b)
@@ -3524,6 +3304,13 @@ class TestRuby23Parser < RubyParserTestCase
3524
3304
  assert_parse rb, pt
3525
3305
  end
3526
3306
 
3307
+ def test_safe_call_after_newline
3308
+ rb = "a\n&.b"
3309
+ pt = s(:safe_call, s(:call, nil, :a), :b)
3310
+
3311
+ assert_parse rb, pt
3312
+ end
3313
+
3527
3314
  def test_safe_calls
3528
3315
  rb = "a&.b&.c(1)"
3529
3316
  pt = s(:safe_call, s(:safe_call, s(:call, nil, :a), :b), :c, s(:lit, 1))
@@ -3604,22 +3391,311 @@ a + b
3604
3391
  )
3605
3392
 
3606
3393
  pt = s(:block,
3607
- s(:call, nil, :puts, s(:str, "hello my dear friend").line(1)).line(1),
3608
- s(:call, s(:call, nil, :a).line(6),
3609
- :+,
3610
- s(:call, nil, :b).line(6)).line(6)
3394
+ s(:call, nil, :puts, s(:str, "hello my dear friend").line(1)).line(1),
3395
+ s(:call, s(:call, nil, :a).line(6),
3396
+ :+,
3397
+ s(:call, nil, :b).line(6)).line(6)
3611
3398
  ).line(1)
3612
3399
 
3613
3400
  assert_parse rb, pt
3614
3401
  end
3615
3402
  end
3616
3403
 
3617
- [18, 19, 20, 21, 22, 23].each do |v|
3404
+ module TestRubyParserShared24Plus
3405
+ # ...version specific tests to go here...
3406
+ end
3407
+
3408
+ class TestRubyParser < Minitest::Test
3409
+ def test_cls_version
3410
+ assert_equal 18, RubyParser::V18.version
3411
+ assert_equal 23, RubyParser::V23.version
3412
+ refute RubyParser::Parser.version
3413
+ end
3414
+
3415
+ def test_parse
3416
+ processor = RubyParser.new
3417
+
3418
+ # 1.8 only syntax
3419
+ rb = "while false : 42 end"
3420
+ pt = s(:while, s(:false), s(:lit, 42), true)
3421
+
3422
+ assert_silent do
3423
+ assert_equal pt, processor.parse(rb)
3424
+ end
3425
+
3426
+ # 1.9 only syntax
3427
+ rb = "a.()"
3428
+ pt = s(:call, s(:call, nil, :a), :call)
3429
+
3430
+ assert_equal pt, processor.parse(rb)
3431
+
3432
+ # bad syntax
3433
+ e = assert_raises Racc::ParseError do
3434
+ capture_io do
3435
+ processor.parse "a.("
3436
+ end
3437
+ end
3438
+
3439
+ msg = "(string):1 :: parse error on value \"(\" (tLPAREN2)"
3440
+ assert_equal msg, e.message.strip
3441
+ end
3442
+ end
3443
+
3444
+ class RubyParserTestCase < ParseTreeTestCase
3445
+ attr_accessor :result, :processor
3446
+
3447
+ make_my_diffs_pretty!
3448
+
3449
+ def self.previous key
3450
+ "Ruby"
3451
+ end
3452
+
3453
+ def self.generate_test klass, node, data, input_name, output_name
3454
+ return if node.to_s =~ /bmethod|dmethod/
3455
+ return if Array === data['Ruby']
3456
+
3457
+ output_name = "ParseTree"
3458
+
3459
+ super
3460
+ end
3461
+
3462
+ def assert_parse rb, pt
3463
+ self.result = processor.parse rb
3464
+ assert_equal pt, result
3465
+ end
3466
+
3467
+ def refute_parse rb
3468
+ self.result = processor.parse rb
3469
+ assert_nil result
3470
+ end
3471
+
3472
+ def assert_syntax_error rb, emsg
3473
+ e = nil
3474
+ assert_silent do
3475
+ e = assert_raises RubyParser::SyntaxError do
3476
+ processor.parse rb
3477
+ end
3478
+ end
3479
+
3480
+ assert_equal emsg, e.message
3481
+ end
3482
+
3483
+ def assert_parse_error rb, emsg
3484
+ e = nil
3485
+ assert_silent do
3486
+ e = assert_raises Racc::ParseError do
3487
+ processor.parse rb
3488
+ end
3489
+ end
3490
+
3491
+ assert_equal emsg, e.message
3492
+ end
3493
+
3494
+ def assert_parse_line rb, pt, line
3495
+ old_env = ENV["VERBOSE"]
3496
+ ENV["VERBOSE"] = "1"
3497
+
3498
+ assert_parse rb, pt
3499
+ assert_equal line, result.line, "call should have line number"
3500
+ ensure
3501
+ ENV["VERBOSE"] = old_env
3502
+ end
3503
+ end
3504
+
3505
+ class TestRubyParserV18 < RubyParserTestCase
3506
+ include TestRubyParserShared
3507
+
3508
+ def setup
3509
+ super
3510
+
3511
+ self.processor = RubyParser::V18.new
3512
+ end
3513
+
3514
+ def test_assoc_list_18
3515
+ rb = "{1, 2, 3, 4}"
3516
+ pt = s(:hash, s(:lit, 1), s(:lit, 2), s(:lit, 3), s(:lit, 4))
3517
+
3518
+ assert_parse rb, pt
3519
+ end
3520
+
3521
+ def test_case_then_colon_18
3522
+ rb = "case x; when Fixnum: 42; end"
3523
+ pt = s(:case,
3524
+ s(:call, nil, :x),
3525
+ s(:when, s(:array, s(:const, :Fixnum)), s(:lit, 42)),
3526
+ nil)
3527
+
3528
+ assert_parse rb, pt
3529
+ end
3530
+
3531
+ def test_do_colon_18
3532
+ rb = "while false : 42 end"
3533
+ pt = s(:while, s(:false), s(:lit, 42), true)
3534
+
3535
+ assert_parse rb, pt
3536
+ end
3537
+
3538
+ def test_call_space_before_paren_args_18
3539
+ rb = "a (:b, :c, :d => :e)"
3540
+ pt = s(:call, nil, :a,
3541
+ s(:lit, :b),
3542
+ s(:lit, :c),
3543
+ s(:hash, s(:lit, :d), s(:lit, :e)))
3544
+
3545
+ assert_parse rb, pt
3546
+ end
3547
+
3548
+ # In 1.8, block args with an outer set of parens are superfluous.
3549
+ # In 1.9, outer set of parens are NOT... they are an explicit extra masgn.
3550
+
3551
+ def test_iter_args_2_18
3552
+ rb = "f { |(a, b)| }"
3553
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, :b))
3554
+
3555
+ assert_parse rb, pt
3556
+ end
3557
+
3558
+ def test_bug_args__18
3559
+ rb = "f { |(a, b)| }"
3560
+ pt = s(:iter, s(:call, nil, :f),
3561
+ s(:args, :a, :b))
3562
+
3563
+ assert_parse rb, pt
3564
+ end
3565
+
3566
+ def test_bug_args_masgn_outer_parens__18
3567
+ rb = "f { |((a, b), c)| }"
3568
+ pt = s(:iter, # NOTE: same sexp as test_bug_args_masgn
3569
+ s(:call, nil, :f),
3570
+ s(:args, s(:masgn, :a, :b), :c))
3571
+
3572
+ assert_parse rb, pt.dup
3573
+ end
3574
+
3575
+ def test_double_block_error_10
3576
+ assert_syntax_error "a.b (&b) {}", BLOCK_DUP_MSG
3577
+ end
3578
+
3579
+ def test_double_block_error_11
3580
+ assert_syntax_error "a (1, &b) { }", BLOCK_DUP_MSG
3581
+ end
3582
+
3583
+ def test_double_block_error_12
3584
+ assert_syntax_error "a (1, &b) do end", BLOCK_DUP_MSG
3585
+ end
3586
+
3587
+ def test_double_block_error_13
3588
+ assert_syntax_error "m.a (1, &b) { }", BLOCK_DUP_MSG
3589
+ end
3590
+
3591
+ def test_double_block_error_14
3592
+ assert_syntax_error "m.a (1, &b) do end", BLOCK_DUP_MSG
3593
+ end
3594
+
3595
+ def test_double_block_error_15
3596
+ assert_syntax_error "m::a (1, &b) { }", BLOCK_DUP_MSG
3597
+ end
3598
+
3599
+ def test_double_block_error_16
3600
+ assert_syntax_error "m::a (1, &b) do end", BLOCK_DUP_MSG
3601
+ end
3602
+ end
3603
+
3604
+ class TestRubyParserV19 < RubyParserTestCase
3605
+ include TestRubyParserShared
3606
+ include TestRubyParserShared19Plus
3607
+
3608
+ def setup
3609
+ super
3610
+
3611
+ self.processor = RubyParser::V19.new
3612
+ end
3613
+ end
3614
+
3615
+ class TestRubyParserV20 < RubyParserTestCase
3616
+ include TestRubyParserShared
3617
+ include TestRubyParserShared19Plus
3618
+ include TestRubyParserShared20Plus
3619
+
3620
+ def setup
3621
+ super
3622
+
3623
+ self.processor = RubyParser::V20.new
3624
+ end
3625
+
3626
+ def test_defn_unary_not
3627
+ rb = "def !@; true; end" # I seriously HATE this
3628
+ pt = s(:defn, :"!@", s(:args), s(:true))
3629
+
3630
+ assert_parse rb, pt
3631
+ end
3632
+ end
3633
+
3634
+ class TestRubyParserV21 < RubyParserTestCase
3635
+ include TestRubyParserShared
3636
+ include TestRubyParserShared19Plus
3637
+ include TestRubyParserShared20Plus
3638
+ include TestRubyParserShared21Plus
3639
+
3640
+ def setup
3641
+ super
3642
+
3643
+ self.processor = RubyParser::V21.new
3644
+ end
3645
+ end
3646
+
3647
+ class TestRubyParserV22 < RubyParserTestCase
3648
+ include TestRubyParserShared
3649
+ include TestRubyParserShared19Plus
3650
+ include TestRubyParserShared20Plus
3651
+ include TestRubyParserShared21Plus
3652
+ include TestRubyParserShared22Plus
3653
+
3654
+ def setup
3655
+ super
3656
+
3657
+ self.processor = RubyParser::V22.new
3658
+ end
3659
+ end
3660
+
3661
+ class TestRubyParserV23 < RubyParserTestCase
3662
+ include TestRubyParserShared
3663
+ include TestRubyParserShared19Plus
3664
+ include TestRubyParserShared20Plus
3665
+ include TestRubyParserShared21Plus
3666
+ include TestRubyParserShared22Plus
3667
+ include TestRubyParserShared23Plus
3668
+
3669
+ def setup
3670
+ super
3671
+
3672
+ self.processor = RubyParser::V23.new
3673
+ end
3674
+ end
3675
+
3676
+ class TestRubyParserV24 < RubyParserTestCase
3677
+ include TestRubyParserShared
3678
+ include TestRubyParserShared19Plus
3679
+ include TestRubyParserShared20Plus
3680
+ include TestRubyParserShared21Plus
3681
+ include TestRubyParserShared22Plus
3682
+ include TestRubyParserShared23Plus
3683
+ include TestRubyParserShared24Plus
3684
+
3685
+ def setup
3686
+ super
3687
+
3688
+ self.processor = RubyParser::V24.new
3689
+ end
3690
+ end
3691
+
3692
+ RubyParser::VERSIONS.each do |klass|
3693
+ v = klass.version
3618
3694
  describe "block args arity #{v}" do
3619
3695
  attr_accessor :parser
3620
3696
 
3621
3697
  before do
3622
- self.parser = Object.const_get("Ruby#{v}Parser").new
3698
+ self.parser = RubyParser.const_get("V#{v}").new
3623
3699
  end
3624
3700
 
3625
3701
  {