ruby_parser 3.3.0 → 3.4.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -2
- data/.autotest +21 -14
- data/History.txt +50 -0
- data/Manifest.txt +3 -1
- data/Rakefile +20 -14
- data/bin/ruby_parse_extract_error +8 -2
- data/lib/.document +1 -0
- data/lib/ruby18_parser.rb +12 -7
- data/lib/ruby18_parser.y +12 -7
- data/lib/ruby19_parser.rb +5 -3
- data/lib/ruby19_parser.y +5 -3
- data/lib/ruby20_parser.rb +17 -5
- data/lib/ruby20_parser.y +17 -5
- data/lib/ruby_lexer.rb +502 -664
- data/lib/ruby_lexer.rex +189 -0
- data/lib/ruby_lexer.rex.rb +263 -0
- data/lib/ruby_parser_extras.rb +45 -58
- data/test/test_ruby_lexer.rb +22 -13
- data/test/test_ruby_parser.rb +85 -25
- metadata +21 -5
- metadata.gz.sig +0 -0
- data/lib/gauntlet_rubyparser.rb +0 -117
data/lib/ruby_parser_extras.rb
CHANGED
@@ -59,28 +59,8 @@ class RPStringScanner < StringScanner
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
def current_line # HAHA fuck you (HACK)
|
63
|
-
string_to_pos[/\A.*__LINE__/m].split(/\n/).size
|
64
|
-
end
|
65
|
-
|
66
|
-
def extra_lines_added
|
67
|
-
@extra_lines_added ||= 0
|
68
|
-
end
|
69
|
-
|
70
|
-
def extra_lines_added= val
|
71
|
-
@extra_lines_added = val
|
72
|
-
end
|
73
|
-
|
74
|
-
def lineno
|
75
|
-
string[0...charpos].count("\n") + 1 - extra_lines_added
|
76
|
-
end
|
77
|
-
|
78
|
-
# TODO: once we get rid of these, we can make things like
|
79
|
-
# TODO: current_line and lineno much more accurate and easy to do
|
80
|
-
|
81
62
|
def unread_many str # TODO: remove this entirely - we should not need it
|
82
63
|
warn({:unread_many => caller[0]}.inspect) if ENV['TALLY']
|
83
|
-
self.extra_lines_added += str.count("\n") - 1
|
84
64
|
begin
|
85
65
|
string[charpos, 0] = str
|
86
66
|
rescue IndexError
|
@@ -111,7 +91,7 @@ class RPStringScanner < StringScanner
|
|
111
91
|
end
|
112
92
|
|
113
93
|
module RubyParserStuff
|
114
|
-
VERSION = "3.
|
94
|
+
VERSION = "3.4.0" unless constants.include? "VERSION" # SIGH
|
115
95
|
|
116
96
|
attr_accessor :lexer, :in_def, :in_single, :file
|
117
97
|
attr_reader :env, :comments
|
@@ -148,15 +128,6 @@ module RubyParserStuff
|
|
148
128
|
raise RubyParser::SyntaxError, msg
|
149
129
|
end
|
150
130
|
|
151
|
-
def arg_add(node1, node2) # TODO: nuke
|
152
|
-
return s(:arglist, node2) unless node1
|
153
|
-
|
154
|
-
node1[0] = :arglist if node1[0] == :array
|
155
|
-
return node1 << node2 if node1[0] == :arglist
|
156
|
-
|
157
|
-
return s(:arglist, node1, node2)
|
158
|
-
end
|
159
|
-
|
160
131
|
def arg_blk_pass node1, node2 # TODO: nuke
|
161
132
|
node1 = s(:arglist, node1) unless [:arglist, :call_args, :array, :args].include? node1.first
|
162
133
|
node1 << node2 if node2
|
@@ -391,6 +362,7 @@ module RubyParserStuff
|
|
391
362
|
end
|
392
363
|
|
393
364
|
def gettable(id)
|
365
|
+
lineno = id.lineno if id.respond_to? :lineno
|
394
366
|
id = id.to_sym if String === id
|
395
367
|
|
396
368
|
result = case id.to_s
|
@@ -411,7 +383,7 @@ module RubyParserStuff
|
|
411
383
|
end
|
412
384
|
end
|
413
385
|
|
414
|
-
result.line
|
386
|
+
result.line lineno if lineno
|
415
387
|
|
416
388
|
raise "identifier #{id.inspect} is not valid" unless result
|
417
389
|
|
@@ -457,7 +429,7 @@ module RubyParserStuff
|
|
457
429
|
list
|
458
430
|
end
|
459
431
|
|
460
|
-
def literal_concat head, tail
|
432
|
+
def literal_concat head, tail # TODO: ugh. rewrite
|
461
433
|
return tail unless head
|
462
434
|
return head unless tail
|
463
435
|
|
@@ -476,8 +448,10 @@ module RubyParserStuff
|
|
476
448
|
end
|
477
449
|
when :dstr then
|
478
450
|
if htype == :str then
|
451
|
+
lineno = head.line
|
479
452
|
tail[1] = head[-1] + tail[1]
|
480
453
|
head = tail
|
454
|
+
head.line = lineno
|
481
455
|
else
|
482
456
|
tail[0] = :array
|
483
457
|
tail[1] = s(:str, tail[1])
|
@@ -563,7 +537,7 @@ module RubyParserStuff
|
|
563
537
|
end
|
564
538
|
|
565
539
|
def argl x
|
566
|
-
x = s(:arglist, x) if x and x[0]
|
540
|
+
x = s(:arglist, x) if x and x[0] == :array
|
567
541
|
x
|
568
542
|
end
|
569
543
|
|
@@ -587,12 +561,13 @@ module RubyParserStuff
|
|
587
561
|
# TODO: need a test with f(&b) to produce block_pass
|
588
562
|
# TODO: need a test with f(&b) { } to produce warning
|
589
563
|
|
590
|
-
args
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
564
|
+
if args
|
565
|
+
if [:arglist, :args, :array, :call_args].include? args.first
|
566
|
+
result.concat args.sexp_body
|
567
|
+
else
|
568
|
+
result << args
|
569
|
+
end
|
570
|
+
end
|
596
571
|
|
597
572
|
line = result.grep(Sexp).map(&:line).compact.min
|
598
573
|
result.line = line if line
|
@@ -600,9 +575,8 @@ module RubyParserStuff
|
|
600
575
|
result
|
601
576
|
end
|
602
577
|
|
603
|
-
def new_case expr, body
|
578
|
+
def new_case expr, body, line
|
604
579
|
result = s(:case, expr)
|
605
|
-
line = (expr || body).line
|
606
580
|
|
607
581
|
while body and body.node_type == :when
|
608
582
|
result << body
|
@@ -794,8 +768,14 @@ module RubyParserStuff
|
|
794
768
|
begin
|
795
769
|
Regexp.new(node[1], o)
|
796
770
|
rescue RegexpError => e
|
797
|
-
warn "
|
798
|
-
|
771
|
+
warn "WA\RNING: #{e.message} for #{node[1].inspect} #{options.inspect}"
|
772
|
+
begin
|
773
|
+
warn "WA\RNING: trying to recover with ENC_UTF8"
|
774
|
+
Regexp.new(node[1], Regexp::ENC_UTF8)
|
775
|
+
rescue RegexpError => e
|
776
|
+
warn "WA\RNING: trying to recover with ENC_NONE"
|
777
|
+
Regexp.new(node[1], Regexp::ENC_NONE)
|
778
|
+
end
|
799
779
|
end
|
800
780
|
end
|
801
781
|
when :dstr then
|
@@ -919,8 +899,10 @@ module RubyParserStuff
|
|
919
899
|
end
|
920
900
|
|
921
901
|
def next_token
|
922
|
-
|
923
|
-
|
902
|
+
token = self.lexer.next_token
|
903
|
+
|
904
|
+
if token and token.first != RubyLexer::EOF then
|
905
|
+
return token
|
924
906
|
else
|
925
907
|
return [false, '$end']
|
926
908
|
end
|
@@ -932,18 +914,13 @@ module RubyParserStuff
|
|
932
914
|
rhs = value_expr rhs
|
933
915
|
|
934
916
|
case lhs[0]
|
935
|
-
when :
|
936
|
-
lhs << rhs
|
937
|
-
when :attrasgn then
|
917
|
+
when :lasgn, :iasgn, :cdecl, :cvdecl, :gasgn, :cvasgn, :attrasgn then
|
938
918
|
lhs << rhs
|
939
|
-
when :call then
|
940
|
-
args = lhs.pop unless Symbol === lhs.last
|
941
|
-
lhs.concat arg_add(args, rhs)[1..-1]
|
942
919
|
when :const then
|
943
920
|
lhs[0] = :cdecl
|
944
921
|
lhs << rhs
|
945
922
|
else
|
946
|
-
raise "unknown lhs #{lhs.inspect}"
|
923
|
+
raise "unknown lhs #{lhs.inspect} w/ #{rhs.inspect}"
|
947
924
|
end
|
948
925
|
|
949
926
|
lhs
|
@@ -1033,10 +1010,12 @@ module RubyParserStuff
|
|
1033
1010
|
str = handle_encoding str
|
1034
1011
|
|
1035
1012
|
self.file = file.dup
|
1036
|
-
self.lexer.src = str
|
1037
1013
|
|
1038
1014
|
@yydebug = ENV.has_key? 'DEBUG'
|
1039
1015
|
|
1016
|
+
# HACK -- need to get tests passing more than have graceful code
|
1017
|
+
self.lexer.ss = RPStringScanner.new str
|
1018
|
+
|
1040
1019
|
do_parse
|
1041
1020
|
end
|
1042
1021
|
end
|
@@ -1086,7 +1065,7 @@ module RubyParserStuff
|
|
1086
1065
|
|
1087
1066
|
def s(*args)
|
1088
1067
|
result = Sexp.new(*args)
|
1089
|
-
result.line ||= lexer.lineno if lexer.
|
1068
|
+
result.line ||= lexer.lineno if lexer.ss # otherwise...
|
1090
1069
|
result.file = self.file
|
1091
1070
|
result
|
1092
1071
|
end
|
@@ -1369,6 +1348,16 @@ unless "".respond_to?(:grep) then
|
|
1369
1348
|
end
|
1370
1349
|
end
|
1371
1350
|
|
1351
|
+
class String
|
1352
|
+
##
|
1353
|
+
# This is a hack used by the lexer to sneak in line numbers at the
|
1354
|
+
# identifier level. This should be MUCH smaller than making
|
1355
|
+
# process_token return [value, lineno] and modifying EVERYTHING that
|
1356
|
+
# reduces tIDENTIFIER.
|
1357
|
+
|
1358
|
+
attr_accessor :lineno
|
1359
|
+
end
|
1360
|
+
|
1372
1361
|
class Sexp
|
1373
1362
|
attr_writer :paren
|
1374
1363
|
|
@@ -1386,12 +1375,10 @@ class Sexp
|
|
1386
1375
|
self.value.to_sym
|
1387
1376
|
end
|
1388
1377
|
|
1389
|
-
|
1390
|
-
concat x
|
1391
|
-
end
|
1378
|
+
alias :add :<<
|
1392
1379
|
|
1393
1380
|
def add_all x
|
1394
|
-
|
1381
|
+
self.concat x.sexp_body
|
1395
1382
|
end
|
1396
1383
|
|
1397
1384
|
def block_pass?
|
data/test/test_ruby_lexer.rb
CHANGED
@@ -20,7 +20,7 @@ class TestRubyLexer < Minitest::Test
|
|
20
20
|
|
21
21
|
def setup_lexer input, exp_sexp = nil
|
22
22
|
setup_new_parser
|
23
|
-
lex.
|
23
|
+
lex.ss = RPStringScanner.new(input)
|
24
24
|
lex.lex_state = self.lex_state
|
25
25
|
end
|
26
26
|
|
@@ -71,11 +71,11 @@ class TestRubyLexer < Minitest::Test
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def assert_next_lexeme token=nil, value=nil, state=nil, paren=nil, brace=nil
|
74
|
-
adv = @lex.
|
74
|
+
adv = @lex.next_token
|
75
75
|
|
76
76
|
assert adv, "no more tokens"
|
77
77
|
|
78
|
-
act_token, act_value =
|
78
|
+
act_token, act_value = adv
|
79
79
|
|
80
80
|
msg = message {
|
81
81
|
act = [act_token, act_value, @lex.lex_state,
|
@@ -98,20 +98,20 @@ class TestRubyLexer < Minitest::Test
|
|
98
98
|
end
|
99
99
|
|
100
100
|
def assert_read_escape expected, input
|
101
|
-
@lex.
|
101
|
+
@lex.ss.string = input
|
102
102
|
assert_equal expected, @lex.read_escape, input
|
103
103
|
end
|
104
104
|
|
105
105
|
def assert_read_escape_bad input # TODO: rename refute_read_escape
|
106
|
-
@lex.
|
106
|
+
@lex.ss.string = input
|
107
107
|
assert_raises RubyParser::SyntaxError do
|
108
108
|
@lex.read_escape
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
112
112
|
def refute_lexeme
|
113
|
-
x = @lex.
|
114
|
-
|
113
|
+
x = y = @lex.next_token
|
114
|
+
|
115
115
|
refute x, "not empty: #{y.inspect}"
|
116
116
|
end
|
117
117
|
|
@@ -146,10 +146,10 @@ class TestRubyLexer < Minitest::Test
|
|
146
146
|
|
147
147
|
## Tests:
|
148
148
|
|
149
|
-
def
|
150
|
-
|
151
|
-
|
152
|
-
|
149
|
+
def test_next_token
|
150
|
+
assert_equal [:tIDENTIFIER, "blah"], @lex.next_token
|
151
|
+
assert_equal [:tIDENTIFIER, "blah"], @lex.next_token
|
152
|
+
assert_nil @lex.next_token
|
153
153
|
end
|
154
154
|
|
155
155
|
def test_unicode_ident
|
@@ -834,6 +834,14 @@ class TestRubyLexer < Minitest::Test
|
|
834
834
|
:kEND, "end", :expr_end)
|
835
835
|
end
|
836
836
|
|
837
|
+
def test_yylex_is_your_spacebar_broken?
|
838
|
+
assert_lex3(":a!=:b",
|
839
|
+
nil,
|
840
|
+
:tSYMBOL, "a", :expr_end,
|
841
|
+
:tNEQ, "!=", :expr_beg,
|
842
|
+
:tSYMBOL, "b", :expr_end)
|
843
|
+
end
|
844
|
+
|
837
845
|
def test_yylex_do_cond
|
838
846
|
assert_lex3("x do 42 end",
|
839
847
|
nil,
|
@@ -2538,8 +2546,9 @@ class TestRubyLexer < Minitest::Test
|
|
2538
2546
|
end
|
2539
2547
|
|
2540
2548
|
def test_yylex_underscore_end
|
2541
|
-
|
2542
|
-
|
2549
|
+
assert_lex3("__END__\n",
|
2550
|
+
nil,
|
2551
|
+
RubyLexer::EOF, RubyLexer::EOF, nil)
|
2543
2552
|
end
|
2544
2553
|
|
2545
2554
|
def test_yylex_uplus
|
data/test/test_ruby_parser.rb
CHANGED
@@ -603,14 +603,8 @@ module TestRubyParserShared
|
|
603
603
|
assert_parse rb, pt
|
604
604
|
end
|
605
605
|
|
606
|
-
STARTING_LINE = {
|
607
|
-
"case_no_expr" => 2, # TODO this should be 1
|
608
|
-
"structure_unused_literal_wwtt" => 3, # yes, 3... odd test
|
609
|
-
}
|
610
|
-
|
611
606
|
def after_process_hook klass, node, data, input_name, output_name
|
612
|
-
|
613
|
-
assert_equal expected, @result.line, "should have proper line number"
|
607
|
+
assert_equal 1, @result.line, "should have proper line number"
|
614
608
|
end
|
615
609
|
|
616
610
|
def test_parse_line_block
|
@@ -639,13 +633,10 @@ module TestRubyParserShared
|
|
639
633
|
s(:call, nil, :b).line(2),
|
640
634
|
s(:call, nil, :c).line(3))
|
641
635
|
|
642
|
-
# see skipped test: test_parse_line_block_inline_comment2
|
643
636
|
assert_parse rb, pt
|
644
637
|
end
|
645
638
|
|
646
|
-
def
|
647
|
-
skip "I can't fix this yet. Very involved. (process_token to return lineno)"
|
648
|
-
|
639
|
+
def test_parse_line_block_inline_multiline_comment
|
649
640
|
rb = "a\nb # comment\n# another comment\nc"
|
650
641
|
pt = s(:block,
|
651
642
|
s(:call, nil, :a).line(1),
|
@@ -655,14 +646,12 @@ module TestRubyParserShared
|
|
655
646
|
assert_parse rb, pt
|
656
647
|
end
|
657
648
|
|
658
|
-
def
|
659
|
-
skip "not yet"
|
660
|
-
|
649
|
+
def test_parse_line_block_inline_comment_leading_newlines
|
661
650
|
rb = "\n\n\na\nb # comment\n# another comment\nc"
|
662
651
|
pt = s(:block,
|
663
652
|
s(:call, nil, :a).line(4),
|
664
|
-
s(:call, nil, :b).line(
|
665
|
-
s(:call, nil, :c).line(
|
653
|
+
s(:call, nil, :b).line(5),
|
654
|
+
s(:call, nil, :c).line(7)).line(4)
|
666
655
|
|
667
656
|
assert_parse rb, pt
|
668
657
|
end
|
@@ -681,6 +670,20 @@ module TestRubyParserShared
|
|
681
670
|
assert_equal 2, result[3].line, "call should have line number"
|
682
671
|
end
|
683
672
|
|
673
|
+
def test_parse_line_call_ivar_line_break_paren
|
674
|
+
rb = "a(@b\n)"
|
675
|
+
pt = s(:call, nil, :a, s(:ivar, :@b).line(1)).line(1)
|
676
|
+
|
677
|
+
assert_parse rb, pt
|
678
|
+
end
|
679
|
+
|
680
|
+
def test_parse_line_call_ivar_arg_no_parens_line_break
|
681
|
+
rb = "a @b\n"
|
682
|
+
pt = s(:call, nil, :a, s(:ivar, :@b).line(1)).line(1)
|
683
|
+
|
684
|
+
assert_parse rb, pt
|
685
|
+
end
|
686
|
+
|
684
687
|
def test_parse_line_defn_no_parens
|
685
688
|
pt = s(:defn, :f, s(:args), s(:nil))
|
686
689
|
|
@@ -708,6 +711,15 @@ module TestRubyParserShared
|
|
708
711
|
assert_equal 4, body.return.line, "return should have line number"
|
709
712
|
end
|
710
713
|
|
714
|
+
def test_parse_line_evstr_after_break
|
715
|
+
rb = "\"a\"\\\n\"\#{b}\""
|
716
|
+
pt = s(:dstr, "a",
|
717
|
+
s(:evstr,
|
718
|
+
s(:call, nil, :b).line(2)).line(2)).line(1)
|
719
|
+
|
720
|
+
assert_parse rb, pt
|
721
|
+
end
|
722
|
+
|
711
723
|
def test_parse_line_iter_call_parens
|
712
724
|
rb = "f(a) do |x, y|\n x + y\nend"
|
713
725
|
|
@@ -727,15 +739,12 @@ module TestRubyParserShared
|
|
727
739
|
rb = "f a do |x, y|\n x + y\nend"
|
728
740
|
|
729
741
|
pt = s(:iter,
|
730
|
-
s(:call, nil, :f, s(:call, nil, :a)),
|
731
|
-
s(:args, :x, :y),
|
732
|
-
s(:call, s(:lvar, :x), :+,
|
742
|
+
s(:call, nil, :f, s(:call, nil, :a).line(1)).line(1),
|
743
|
+
s(:args, :x, :y).line(1),
|
744
|
+
s(:call, s(:lvar, :x).line(2), :+,
|
745
|
+
s(:lvar, :y).line(2)).line(2)).line(1)
|
733
746
|
|
734
|
-
|
735
|
-
|
736
|
-
assert_equal 1, result[1].line, "call should have line number"
|
737
|
-
assert_equal 1, result[2].line, "masgn should have line number"
|
738
|
-
assert_equal 2, result[3].line, "call should have line number"
|
747
|
+
assert_parse rb, pt
|
739
748
|
end
|
740
749
|
|
741
750
|
def test_parse_line_heredoc
|
@@ -797,6 +806,15 @@ module TestRubyParserShared
|
|
797
806
|
assert_equal 3, result.if.return.lit.line
|
798
807
|
end
|
799
808
|
|
809
|
+
def test_parse_line_trailing_newlines
|
810
|
+
rb = "a \nb"
|
811
|
+
pt = s(:block,
|
812
|
+
s(:call, nil, :a).line(1),
|
813
|
+
s(:call, nil, :b).line(2)).line(1)
|
814
|
+
|
815
|
+
assert_parse rb, pt
|
816
|
+
end
|
817
|
+
|
800
818
|
def test_bug_and
|
801
819
|
rb = "true and []"
|
802
820
|
pt = s(:and, s(:true), s(:array))
|
@@ -1044,7 +1062,7 @@ module TestRubyParserShared
|
|
1044
1062
|
s(:call, nil, :p, s(:str, "a").line(2)).line(2),
|
1045
1063
|
s(:lasgn, :b, s(:lit, 1).line(3)).line(3),
|
1046
1064
|
s(:call, nil, :p, s(:lvar, :b).line(4)).line(4),
|
1047
|
-
s(:lasgn, :c, s(:lit, 1).line(5)).line(5)).line(2),
|
1065
|
+
s(:lasgn, :c, s(:lit, 1).line(5)).line(5)).line(2),
|
1048
1066
|
nil).line(1),
|
1049
1067
|
s(:call, nil, :a).line(7)).line(1)
|
1050
1068
|
|
@@ -2051,6 +2069,16 @@ class TestRuby18Parser < RubyParserTestCase
|
|
2051
2069
|
self.processor = Ruby18Parser.new
|
2052
2070
|
end
|
2053
2071
|
|
2072
|
+
def test_call_space_before_paren_args
|
2073
|
+
rb = "a (:b, :c, :d => :e)"
|
2074
|
+
pt = s(:call, nil, :a,
|
2075
|
+
s(:lit, :b),
|
2076
|
+
s(:lit, :c),
|
2077
|
+
s(:hash, s(:lit, :d), s(:lit, :e)))
|
2078
|
+
|
2079
|
+
assert_parse rb, pt
|
2080
|
+
end
|
2081
|
+
|
2054
2082
|
def test_flip2_env_lvar
|
2055
2083
|
rb = "if a..b then end"
|
2056
2084
|
pt = s(:if, s(:flip2, s(:call, nil, :a), s(:call, nil, :b)), nil, nil)
|
@@ -2848,6 +2876,38 @@ class TestRuby20Parser < RubyParserTestCase
|
|
2848
2876
|
self.processor = Ruby20Parser.new
|
2849
2877
|
end
|
2850
2878
|
|
2879
|
+
def test_block_call_dot_op2_brace_block
|
2880
|
+
rb = "a.b c() do d end.e do |f| g end"
|
2881
|
+
pt = s(:iter,
|
2882
|
+
s(:call,
|
2883
|
+
s(:iter,
|
2884
|
+
s(:call, s(:call, nil, :a), :b, s(:call, nil, :c)),
|
2885
|
+
s(:args),
|
2886
|
+
s(:call, nil, :d)),
|
2887
|
+
:e),
|
2888
|
+
s(:args, :f),
|
2889
|
+
s(:call, nil, :g))
|
2890
|
+
|
2891
|
+
|
2892
|
+
assert_parse rb, pt
|
2893
|
+
end
|
2894
|
+
|
2895
|
+
def test_block_call_dot_op2_cmd_args_do_block
|
2896
|
+
rb = "a.b c() do d end.e f do |g| h end"
|
2897
|
+
pt = s(:iter,
|
2898
|
+
s(:call,
|
2899
|
+
s(:iter,
|
2900
|
+
s(:call, s(:call, nil, :a), :b, s(:call, nil, :c)),
|
2901
|
+
s(:args),
|
2902
|
+
s(:call, nil, :d)),
|
2903
|
+
:e,
|
2904
|
+
s(:call, nil, :f)),
|
2905
|
+
s(:args, :g),
|
2906
|
+
s(:call, nil, :h))
|
2907
|
+
|
2908
|
+
assert_parse rb, pt
|
2909
|
+
end
|
2910
|
+
|
2851
2911
|
def test_defn_kwarg_val
|
2852
2912
|
rb = "def f(a, b:1) end"
|
2853
2913
|
pt = s(:defn, :f, s(:args, :a, s(:kwarg, :b, s(:lit, 1))), s(:nil))
|