ruby_parser 3.3.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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))
|