ruby_parser 3.14.2 → 3.17.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 +0 -0
- data/History.rdoc +60 -0
- data/Manifest.txt +4 -0
- data/Rakefile +83 -16
- data/bin/ruby_parse_extract_error +8 -3
- data/compare/normalize.rb +45 -5
- data/debugging.md +172 -0
- data/lib/ruby20_parser.rb +2953 -2924
- data/lib/ruby20_parser.y +99 -59
- data/lib/ruby21_parser.rb +3008 -2977
- data/lib/ruby21_parser.y +99 -59
- data/lib/ruby22_parser.rb +3011 -2976
- data/lib/ruby22_parser.y +99 -59
- data/lib/ruby23_parser.rb +2955 -2923
- data/lib/ruby23_parser.y +99 -59
- data/lib/ruby24_parser.rb +3024 -2984
- data/lib/ruby24_parser.y +99 -59
- data/lib/ruby25_parser.rb +3023 -2984
- data/lib/ruby25_parser.y +99 -59
- data/lib/ruby26_parser.rb +2954 -2913
- data/lib/ruby26_parser.y +100 -59
- data/lib/ruby27_parser.rb +7393 -0
- data/lib/ruby27_parser.y +2715 -0
- data/lib/ruby30_parser.rb +7393 -0
- data/lib/ruby30_parser.y +2715 -0
- data/lib/ruby_lexer.rb +90 -39
- data/lib/ruby_lexer.rex +6 -7
- data/lib/ruby_lexer.rex.rb +7 -9
- data/lib/ruby_parser.rb +4 -0
- data/lib/ruby_parser.yy +164 -59
- data/lib/ruby_parser_extras.rb +57 -18
- data/test/test_ruby_lexer.rb +64 -16
- data/test/test_ruby_parser.rb +277 -3
- data/tools/munge.rb +9 -4
- metadata +55 -36
- metadata.gz.sig +0 -0
data/lib/ruby_parser_extras.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: ASCII-8BIT
|
2
|
+
# TODO: remove
|
2
3
|
|
3
4
|
require "sexp"
|
4
5
|
require "ruby_lexer"
|
@@ -28,7 +29,7 @@ class Sexp
|
|
28
29
|
end
|
29
30
|
|
30
31
|
module RubyParserStuff
|
31
|
-
VERSION = "3.
|
32
|
+
VERSION = "3.16.0"
|
32
33
|
|
33
34
|
attr_accessor :lexer, :in_def, :in_single, :file
|
34
35
|
attr_accessor :in_kwarg
|
@@ -45,6 +46,11 @@ module RubyParserStuff
|
|
45
46
|
|
46
47
|
attr_accessor :canonicalize_conditions
|
47
48
|
|
49
|
+
##
|
50
|
+
# The last token type returned from #next_token
|
51
|
+
|
52
|
+
attr_accessor :last_token_type
|
53
|
+
|
48
54
|
$good20 = []
|
49
55
|
|
50
56
|
%w[
|
@@ -109,7 +115,7 @@ module RubyParserStuff
|
|
109
115
|
def initialize(options = {})
|
110
116
|
super()
|
111
117
|
|
112
|
-
v = self.class.name[/
|
118
|
+
v = self.class.name[/[23]\d/]
|
113
119
|
raise "Bad Class name #{self.class}" unless v
|
114
120
|
|
115
121
|
self.lexer = RubyLexer.new v && v.to_i
|
@@ -154,6 +160,12 @@ module RubyParserStuff
|
|
154
160
|
case arg.sexp_type
|
155
161
|
when :args, :block, :array, :call_args then # HACK call_args mismatch
|
156
162
|
result.concat arg.sexp_body
|
163
|
+
when :forward_args then
|
164
|
+
self.env[:*] = :lvar # TODO: arg_var(p, idFWD_REST) ?
|
165
|
+
self.env[:**] = :lvar
|
166
|
+
self.env[:&] = :lvar
|
167
|
+
|
168
|
+
result << arg
|
157
169
|
when :block_arg then
|
158
170
|
result << :"&#{arg.last}"
|
159
171
|
when :shadow then
|
@@ -305,7 +317,7 @@ module RubyParserStuff
|
|
305
317
|
end
|
306
318
|
when Symbol then
|
307
319
|
result << arg
|
308
|
-
when ",", nil then
|
320
|
+
when ",", nil, "(" then
|
309
321
|
# ignore
|
310
322
|
else
|
311
323
|
raise "unhandled: #{arg.inspect} in #{args.inspect}"
|
@@ -493,6 +505,8 @@ module RubyParserStuff
|
|
493
505
|
str.encode! Encoding::UTF_8
|
494
506
|
break
|
495
507
|
end
|
508
|
+
rescue ArgumentError # unknown encoding name
|
509
|
+
# do nothing
|
496
510
|
rescue Encoding::InvalidByteSequenceError
|
497
511
|
# do nothing
|
498
512
|
rescue Encoding::UndefinedConversionError
|
@@ -532,7 +546,7 @@ module RubyParserStuff
|
|
532
546
|
header.map! { |s| s.force_encoding "ASCII-8BIT" } if has_enc
|
533
547
|
|
534
548
|
first = header.first || ""
|
535
|
-
encoding, str = "utf-8", str[3..-1] if first =~ /\A\xEF\xBB\xBF/
|
549
|
+
encoding, str = "utf-8", str.b[3..-1] if first =~ /\A\xEF\xBB\xBF/
|
536
550
|
|
537
551
|
encoding = $1.strip if header.find { |s|
|
538
552
|
s[/^#.*?-\*-.*?coding:\s*([^ ;]+).*?-\*-/, 1] ||
|
@@ -592,7 +606,9 @@ module RubyParserStuff
|
|
592
606
|
case ttype
|
593
607
|
when :str then
|
594
608
|
if htype == :str
|
595
|
-
head.last
|
609
|
+
a, b = head.last, tail.last
|
610
|
+
b = b.dup.force_encoding a.encoding unless Encoding.compatible?(a, b)
|
611
|
+
a << b
|
596
612
|
elsif htype == :dstr and head.size == 2 then
|
597
613
|
head.last << tail.last
|
598
614
|
else
|
@@ -696,6 +712,15 @@ module RubyParserStuff
|
|
696
712
|
result
|
697
713
|
end
|
698
714
|
|
715
|
+
def new_begin val
|
716
|
+
_, lineno, body, _ = val
|
717
|
+
|
718
|
+
result = body ? s(:begin, body) : s(:nil)
|
719
|
+
result.line lineno
|
720
|
+
|
721
|
+
result
|
722
|
+
end
|
723
|
+
|
699
724
|
def new_body val
|
700
725
|
body, resbody, elsebody, ensurebody = val
|
701
726
|
|
@@ -723,7 +748,10 @@ module RubyParserStuff
|
|
723
748
|
result = block_append(result, elsebody)
|
724
749
|
end
|
725
750
|
|
726
|
-
|
751
|
+
if ensurebody
|
752
|
+
lineno = (result || ensurebody).line
|
753
|
+
result = s(:ensure, result, ensurebody).compact.line lineno
|
754
|
+
end
|
727
755
|
|
728
756
|
result
|
729
757
|
end
|
@@ -843,14 +871,17 @@ module RubyParserStuff
|
|
843
871
|
end
|
844
872
|
|
845
873
|
def new_defs val
|
846
|
-
recv,
|
847
|
-
|
874
|
+
_, recv, _, _, name, (_in_def, line), args, body, _ = val
|
875
|
+
|
848
876
|
body ||= s(:nil).line line
|
849
877
|
|
850
878
|
args.line line
|
851
879
|
|
852
880
|
result = s(:defs, recv, name.to_sym, args)
|
853
881
|
|
882
|
+
# TODO: remove_begin
|
883
|
+
# TODO: reduce_nodes
|
884
|
+
|
854
885
|
if body then
|
855
886
|
if body.sexp_type == :block then
|
856
887
|
result.push(*body.sexp_body)
|
@@ -875,7 +906,9 @@ module RubyParserStuff
|
|
875
906
|
end
|
876
907
|
|
877
908
|
def new_hash val
|
878
|
-
|
909
|
+
_, line, assocs = val
|
910
|
+
|
911
|
+
s(:hash).line(line).concat assocs.values
|
879
912
|
end
|
880
913
|
|
881
914
|
def new_if c, t, f
|
@@ -1134,6 +1167,7 @@ module RubyParserStuff
|
|
1134
1167
|
def new_string val
|
1135
1168
|
str, = val
|
1136
1169
|
str.force_encoding("UTF-8")
|
1170
|
+
# TODO: remove:
|
1137
1171
|
str.force_encoding("ASCII-8BIT") unless str.valid_encoding?
|
1138
1172
|
result = s(:str, str).line lexer.lineno
|
1139
1173
|
self.lexer.fixup_lineno str.count("\n")
|
@@ -1228,20 +1262,23 @@ module RubyParserStuff
|
|
1228
1262
|
result
|
1229
1263
|
end
|
1230
1264
|
|
1231
|
-
def new_xstring
|
1232
|
-
|
1233
|
-
|
1265
|
+
def new_xstring val
|
1266
|
+
_, node = val
|
1267
|
+
|
1268
|
+
node ||= s(:str, "").line lexer.lineno
|
1269
|
+
|
1270
|
+
if node then
|
1271
|
+
case node.sexp_type
|
1234
1272
|
when :str
|
1235
|
-
|
1273
|
+
node.sexp_type = :xstr
|
1236
1274
|
when :dstr
|
1237
|
-
|
1275
|
+
node.sexp_type = :dxstr
|
1238
1276
|
else
|
1239
|
-
|
1277
|
+
node = s(:dxstr, "", node).line node.line
|
1240
1278
|
end
|
1241
|
-
str
|
1242
|
-
else
|
1243
|
-
s(:xstr, "")
|
1244
1279
|
end
|
1280
|
+
|
1281
|
+
node
|
1245
1282
|
end
|
1246
1283
|
|
1247
1284
|
def new_yield args = nil
|
@@ -1262,6 +1299,7 @@ module RubyParserStuff
|
|
1262
1299
|
token = self.lexer.next_token
|
1263
1300
|
|
1264
1301
|
if token and token.first != RubyLexer::EOF then
|
1302
|
+
self.last_token_type = token
|
1265
1303
|
return token
|
1266
1304
|
else
|
1267
1305
|
return [false, false]
|
@@ -1320,6 +1358,7 @@ module RubyParserStuff
|
|
1320
1358
|
self.in_single = 0
|
1321
1359
|
self.env.reset
|
1322
1360
|
self.comments.clear
|
1361
|
+
self.last_token_type = nil
|
1323
1362
|
end
|
1324
1363
|
|
1325
1364
|
def ret_args node
|
data/test/test_ruby_lexer.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
# encoding: US-ASCII
|
2
|
-
|
3
|
-
# TODO: work this out
|
4
|
-
|
5
1
|
require "minitest/autorun"
|
6
2
|
require "ruby_lexer"
|
7
3
|
require "ruby_parser"
|
@@ -84,10 +80,12 @@ class TestRubyLexer < Minitest::Test
|
|
84
80
|
assert_in_epsilon value, act_value, 0.001, msg
|
85
81
|
when NilClass then
|
86
82
|
assert_nil act_value, msg
|
83
|
+
when String then
|
84
|
+
assert_equal value, act_value.b.force_encoding(value.encoding), msg
|
87
85
|
else
|
88
86
|
assert_equal value, act_value, msg
|
89
87
|
end
|
90
|
-
|
88
|
+
assert_match state, @lex.lex_state, msg if state
|
91
89
|
assert_equal paren, @lex.paren_nest, msg if paren
|
92
90
|
assert_equal brace, @lex.brace_nest, msg if brace
|
93
91
|
end
|
@@ -98,7 +96,8 @@ class TestRubyLexer < Minitest::Test
|
|
98
96
|
|
99
97
|
def assert_read_escape expected, input
|
100
98
|
@lex.ss.string = input.dup
|
101
|
-
|
99
|
+
enc = expected.encoding
|
100
|
+
assert_equal expected, @lex.read_escape.b.force_encoding(enc), input
|
102
101
|
end
|
103
102
|
|
104
103
|
def assert_read_escape_bad input # TODO: rename refute_read_escape
|
@@ -146,7 +145,7 @@ class TestRubyLexer < Minitest::Test
|
|
146
145
|
yield
|
147
146
|
|
148
147
|
lexer.lex_state = EXPR_ENDARG
|
149
|
-
assert_next_lexeme :tSTRING_DEND, "}", EXPR_END, 0
|
148
|
+
assert_next_lexeme :tSTRING_DEND, "}", EXPR_END|EXPR_ENDARG, 0
|
150
149
|
|
151
150
|
lexer.lex_strterm = lex_strterm
|
152
151
|
lexer.lex_state = EXPR_BEG
|
@@ -479,6 +478,22 @@ class TestRubyLexer < Minitest::Test
|
|
479
478
|
assert_lex3("!~", nil, :tNMATCH, "!~", EXPR_BEG)
|
480
479
|
end
|
481
480
|
|
481
|
+
def test_yylex_bdot2
|
482
|
+
assert_lex3("..42",
|
483
|
+
nil, # TODO: s(:dot2, nil, s(:lit, 42)),
|
484
|
+
|
485
|
+
:tBDOT2, "..", EXPR_BEG,
|
486
|
+
:tINTEGER, 42, EXPR_END|EXPR_ENDARG)
|
487
|
+
end
|
488
|
+
|
489
|
+
def test_yylex_bdot3
|
490
|
+
assert_lex3("...42",
|
491
|
+
nil, # TODO: s(:dot2, nil, s(:lit, 42)),
|
492
|
+
|
493
|
+
:tBDOT3, "...", EXPR_BEG,
|
494
|
+
:tINTEGER, 42, EXPR_END|EXPR_ENDARG)
|
495
|
+
end
|
496
|
+
|
482
497
|
def test_yylex_block_bug_1
|
483
498
|
assert_lex3("a do end",
|
484
499
|
s(:iter, s(:call, nil, :a), 0),
|
@@ -720,7 +735,7 @@ class TestRubyLexer < Minitest::Test
|
|
720
735
|
|
721
736
|
assert_lex3("do 42 end",
|
722
737
|
nil,
|
723
|
-
:
|
738
|
+
:kDO, "do", EXPR_BEG,
|
724
739
|
:tINTEGER, 42, EXPR_NUM,
|
725
740
|
:kEND, "end", EXPR_END)
|
726
741
|
end
|
@@ -750,10 +765,26 @@ class TestRubyLexer < Minitest::Test
|
|
750
765
|
end
|
751
766
|
|
752
767
|
def test_yylex_dot2
|
768
|
+
assert_lex3("1..2",
|
769
|
+
s(:lit, 1..2),
|
770
|
+
|
771
|
+
:tINTEGER, 1, EXPR_END|EXPR_ENDARG,
|
772
|
+
:tDOT2, "..", EXPR_BEG,
|
773
|
+
:tINTEGER, 2, EXPR_END|EXPR_ENDARG)
|
774
|
+
|
775
|
+
self.lex_state = EXPR_END|EXPR_ENDARG
|
753
776
|
assert_lex3("..", nil, :tDOT2, "..", EXPR_BEG)
|
754
777
|
end
|
755
778
|
|
756
779
|
def test_yylex_dot3
|
780
|
+
assert_lex3("1...2",
|
781
|
+
s(:lit, 1...2),
|
782
|
+
|
783
|
+
:tINTEGER, 1, EXPR_END|EXPR_ENDARG,
|
784
|
+
:tDOT3, "...", EXPR_BEG,
|
785
|
+
:tINTEGER, 2, EXPR_END|EXPR_ENDARG)
|
786
|
+
|
787
|
+
self.lex_state = EXPR_END|EXPR_ENDARG
|
757
788
|
assert_lex3("...", nil, :tDOT3, "...", EXPR_BEG)
|
758
789
|
end
|
759
790
|
|
@@ -926,6 +957,14 @@ class TestRubyLexer < Minitest::Test
|
|
926
957
|
assert_lex3("$1234", nil, :tGVAR, "$1234", EXPR_END)
|
927
958
|
end
|
928
959
|
|
960
|
+
def test_yylex_global_I_have_no_words
|
961
|
+
assert_lex3("$x\xE2\x80\x8B = 42", # zero width space?!?!?
|
962
|
+
nil,
|
963
|
+
:tGVAR, "$x\xE2\x80\x8B", EXPR_END,
|
964
|
+
:tEQL, "=", EXPR_BEG,
|
965
|
+
:tINTEGER, 42, EXPR_NUM)
|
966
|
+
end
|
967
|
+
|
929
968
|
def test_yylex_global_other
|
930
969
|
assert_lex3("[$~, $*, $$, $?, $!, $@, $/, $\\, $;, $,, $., $=, $:, $<, $>, $\"]",
|
931
970
|
nil,
|
@@ -1109,11 +1148,11 @@ class TestRubyLexer < Minitest::Test
|
|
1109
1148
|
:tEQL, "=", EXPR_BEG,
|
1110
1149
|
:tSTRING_BEG, "\"", EXPR_BEG,
|
1111
1150
|
:tSTRING_CONTENT, "#x a ", EXPR_BEG,
|
1112
|
-
:tSTRING_DVAR, "
|
1151
|
+
:tSTRING_DVAR, "#", EXPR_BEG,
|
1113
1152
|
:tSTRING_CONTENT, "@a b ", EXPR_BEG, # HUH?
|
1114
|
-
:tSTRING_DVAR, "
|
1153
|
+
:tSTRING_DVAR, "#", EXPR_BEG,
|
1115
1154
|
:tSTRING_CONTENT, "$b c ", EXPR_BEG, # HUH?
|
1116
|
-
:tSTRING_DVAR, "
|
1155
|
+
:tSTRING_DVAR, "#", EXPR_BEG,
|
1117
1156
|
:tSTRING_CONTENT, "@@d ", EXPR_BEG, # HUH?
|
1118
1157
|
:tSTRING_DBEG, "\#{", EXPR_BEG,
|
1119
1158
|
:tSTRING_CONTENT, "3} \n", EXPR_BEG,
|
@@ -2099,6 +2138,10 @@ class TestRubyLexer < Minitest::Test
|
|
2099
2138
|
assert_lex3("?\\M-\\C-a", nil, :tSTRING, "\M-\C-a", EXPR_END)
|
2100
2139
|
end
|
2101
2140
|
|
2141
|
+
def test_yylex_question_control_escape
|
2142
|
+
assert_lex3('?\C-\]', nil, :tSTRING, ?\C-\], EXPR_END)
|
2143
|
+
end
|
2144
|
+
|
2102
2145
|
def test_yylex_question_ws
|
2103
2146
|
assert_lex3("? ", nil, :tEH, "?", EXPR_BEG)
|
2104
2147
|
assert_lex3("?\n", nil, :tEH, "?", EXPR_BEG)
|
@@ -2549,11 +2592,7 @@ class TestRubyLexer < Minitest::Test
|
|
2549
2592
|
end
|
2550
2593
|
|
2551
2594
|
def test_yylex_string_double_escape_c_backslash
|
2552
|
-
|
2553
|
-
nil,
|
2554
|
-
:tSTRING_BEG, "\"", EXPR_BEG,
|
2555
|
-
:tSTRING_CONTENT, "\034", EXPR_BEG,
|
2556
|
-
:tSTRING_END, "\"", EXPR_LIT)
|
2595
|
+
refute_lex("\"\\c\\\"", :tSTRING_BEG, '"')
|
2557
2596
|
end
|
2558
2597
|
|
2559
2598
|
def test_yylex_string_double_escape_c_escape
|
@@ -2847,6 +2886,15 @@ class TestRubyLexer < Minitest::Test
|
|
2847
2886
|
:tSTRING_END, '"')
|
2848
2887
|
end
|
2849
2888
|
|
2889
|
+
def test_yylex_string_utf8_bad_encoding_with_escapes
|
2890
|
+
str = "\"\\xBADπ\""
|
2891
|
+
exp = "\xBADπ".b
|
2892
|
+
|
2893
|
+
assert_lex(str,
|
2894
|
+
s(:str, exp),
|
2895
|
+
:tSTRING, exp, EXPR_END)
|
2896
|
+
end
|
2897
|
+
|
2850
2898
|
def test_yylex_string_utf8_complex_trailing_hex
|
2851
2899
|
chr = [0x3024].pack("U")
|
2852
2900
|
str = "#{chr}abz"
|
data/test/test_ruby_parser.rb
CHANGED
@@ -185,6 +185,57 @@ module TestRubyParserShared
|
|
185
185
|
assert_syntax_error rb, "else without rescue is useless"
|
186
186
|
end
|
187
187
|
|
188
|
+
def test_begin_ensure_no_bodies
|
189
|
+
rb = "begin\nensure\nend"
|
190
|
+
pt = s(:ensure, s(:nil).line(2)).line(2)
|
191
|
+
|
192
|
+
assert_parse rb, pt
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_begin_rescue_ensure_no_bodies
|
196
|
+
rb = "begin\nrescue\nensure\nend"
|
197
|
+
pt = s(:ensure,
|
198
|
+
s(:rescue,
|
199
|
+
s(:resbody, s(:array).line(2),
|
200
|
+
nil).line(2)
|
201
|
+
).line(2),
|
202
|
+
s(:nil).line(3)
|
203
|
+
).line(2)
|
204
|
+
|
205
|
+
assert_parse rb, pt
|
206
|
+
end
|
207
|
+
|
208
|
+
def test_begin_rescue_else_ensure_bodies
|
209
|
+
rb = "begin\n 1\nrescue\n 2\nelse\n 3\nensure\n 4\nend"
|
210
|
+
pt = s(:ensure,
|
211
|
+
s(:rescue,
|
212
|
+
s(:lit, 1).line(2),
|
213
|
+
s(:resbody, s(:array).line(3),
|
214
|
+
s(:lit, 2).line(4)).line(3),
|
215
|
+
s(:lit, 3).line(6)).line(2),
|
216
|
+
s(:lit, 4).line(8)).line(2)
|
217
|
+
|
218
|
+
s(:ensure, s(:rescue, s(:resbody, s(:array), nil)), s(:nil))
|
219
|
+
|
220
|
+
assert_parse rb, pt
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_begin_rescue_else_ensure_no_bodies
|
224
|
+
rb = "begin\n\nrescue\n\nelse\n\nensure\n\nend"
|
225
|
+
pt = s(:ensure,
|
226
|
+
s(:rescue,
|
227
|
+
s(:resbody, s(:array).line(3),
|
228
|
+
# TODO: s(:nil)
|
229
|
+
nil
|
230
|
+
).line(3),
|
231
|
+
).line(3),
|
232
|
+
s(:nil).line(7)).line(3)
|
233
|
+
|
234
|
+
s(:ensure, s(:rescue, s(:resbody, s(:array), nil)), s(:nil))
|
235
|
+
|
236
|
+
assert_parse rb, pt
|
237
|
+
end
|
238
|
+
|
188
239
|
def test_block_append
|
189
240
|
head = s(:args).line 1
|
190
241
|
tail = s(:zsuper).line 2
|
@@ -290,7 +341,7 @@ module TestRubyParserShared
|
|
290
341
|
def test_bug190
|
291
342
|
skip "not ready for this yet"
|
292
343
|
|
293
|
-
rb = %{%r'
|
344
|
+
rb = %{%r'\\\''} # stupid emacs
|
294
345
|
|
295
346
|
assert_parse rb, :FUCK
|
296
347
|
assert_syntax_error rb, "FUCK"
|
@@ -872,6 +923,13 @@ module TestRubyParserShared
|
|
872
923
|
assert_parse rb, pt
|
873
924
|
end
|
874
925
|
|
926
|
+
def test_heredoc_with_extra_carriage_horrible_mix?
|
927
|
+
rb = "<<'eot'\r\nbody\r\neot\n"
|
928
|
+
pt = s(:str, "body\r\n")
|
929
|
+
|
930
|
+
assert_parse rb, pt
|
931
|
+
end
|
932
|
+
|
875
933
|
def test_heredoc_with_interpolation_and_carriage_return_escapes
|
876
934
|
rb = "<<EOS\nfoo\\r\#@bar\nEOS\n"
|
877
935
|
pt = s(:dstr, "foo\r", s(:evstr, s(:ivar, :@bar)), s(:str, "\n"))
|
@@ -900,6 +958,13 @@ module TestRubyParserShared
|
|
900
958
|
assert_parse rb, pt
|
901
959
|
end
|
902
960
|
|
961
|
+
def test_heredoc_with_not_global_interpolation
|
962
|
+
rb = "<<-HEREDOC\n#${\nHEREDOC"
|
963
|
+
pt = s(:str, "\#${\n")
|
964
|
+
|
965
|
+
assert_parse rb, pt
|
966
|
+
end
|
967
|
+
|
903
968
|
def test_i_fucking_hate_line_numbers
|
904
969
|
rb = <<-END.gsub(/^ {6}/, "")
|
905
970
|
if true
|
@@ -1252,6 +1317,20 @@ module TestRubyParserShared
|
|
1252
1317
|
end
|
1253
1318
|
end
|
1254
1319
|
|
1320
|
+
def test_magic_encoding_comment__bad
|
1321
|
+
rb = "#encoding: bunk\n0"
|
1322
|
+
pt = s(:lit, 0)
|
1323
|
+
|
1324
|
+
assert_parse rb, pt
|
1325
|
+
end
|
1326
|
+
|
1327
|
+
def test_utf8_bom
|
1328
|
+
rb = "\xEF\xBB\xBF#!/usr/bin/env ruby -w\np 0\n"
|
1329
|
+
pt = s(:call, nil, :p, s(:lit, 0))
|
1330
|
+
|
1331
|
+
assert_parse rb, pt
|
1332
|
+
end
|
1333
|
+
|
1255
1334
|
def test_masgn_arg_colon_arg
|
1256
1335
|
rb = "a, b::c = d"
|
1257
1336
|
pt = s(:masgn,
|
@@ -1383,13 +1462,43 @@ module TestRubyParserShared
|
|
1383
1462
|
assert_parse rb, pt
|
1384
1463
|
end
|
1385
1464
|
|
1386
|
-
def
|
1465
|
+
def test_op_asgn_primary_colon_identifier1
|
1387
1466
|
rb = "A::b += 1"
|
1388
1467
|
pt = s(:op_asgn, s(:const, :A), s(:lit, 1), :b, :+) # TODO: check? looks wack
|
1389
1468
|
|
1390
1469
|
assert_parse rb, pt
|
1391
1470
|
end
|
1392
1471
|
|
1472
|
+
def test_lasgn_middle_splat
|
1473
|
+
rb = "a = b, *c, d"
|
1474
|
+
pt = s(:lasgn, :a,
|
1475
|
+
s(:svalue,
|
1476
|
+
s(:array,
|
1477
|
+
s(:call, nil, :b),
|
1478
|
+
s(:splat, s(:call, nil, :c)),
|
1479
|
+
s(:call, nil, :d))))
|
1480
|
+
|
1481
|
+
assert_parse rb, pt
|
1482
|
+
end
|
1483
|
+
|
1484
|
+
def test_op_asgn_primary_colon_const_command_call
|
1485
|
+
rb = "A::B *= c d"
|
1486
|
+
pt = s(:op_asgn, s(:const, :A),
|
1487
|
+
s(:call, nil, :c, s(:call, nil, :d)),
|
1488
|
+
:B, :*)
|
1489
|
+
|
1490
|
+
assert_parse rb, pt
|
1491
|
+
end
|
1492
|
+
|
1493
|
+
def test_op_asgn_primary_colon_identifier_command_call
|
1494
|
+
rb = "A::b *= c d"
|
1495
|
+
pt = s(:op_asgn, s(:const, :A),
|
1496
|
+
s(:call, nil, :c, s(:call, nil, :d)),
|
1497
|
+
:b, :*)
|
1498
|
+
|
1499
|
+
assert_parse rb, pt
|
1500
|
+
end
|
1501
|
+
|
1393
1502
|
def test_op_asgn_val_dot_ident_command_call
|
1394
1503
|
rb = "a.b ||= c 1"
|
1395
1504
|
pt = s(:op_asgn, s(:call, nil, :a), s(:call, nil, :c, s(:lit, 1)), :b, :"||")
|
@@ -2971,6 +3080,8 @@ module TestRubyParserShared19Plus
|
|
2971
3080
|
end
|
2972
3081
|
|
2973
3082
|
def test_motherfuckin_leading_dots
|
3083
|
+
skip if processor.class.version >= 27
|
3084
|
+
|
2974
3085
|
rb = "a\n.b"
|
2975
3086
|
pt = s(:call, s(:call, nil, :a), :b)
|
2976
3087
|
|
@@ -2978,6 +3089,8 @@ module TestRubyParserShared19Plus
|
|
2978
3089
|
end
|
2979
3090
|
|
2980
3091
|
def test_motherfuckin_leading_dots2
|
3092
|
+
skip if processor.class.version >= 27
|
3093
|
+
|
2981
3094
|
rb = "a\n..b"
|
2982
3095
|
|
2983
3096
|
assert_parse_error rb, '(string):2 :: parse error on value ".." (tDOT2)'
|
@@ -3288,6 +3401,76 @@ module TestRubyParserShared20Plus
|
|
3288
3401
|
assert_parse rb, pt
|
3289
3402
|
end
|
3290
3403
|
|
3404
|
+
def test_call_array_block_call
|
3405
|
+
rb = "a [ nil, b do end ]"
|
3406
|
+
pt = s(:call, nil, :a,
|
3407
|
+
s(:array,
|
3408
|
+
s(:nil),
|
3409
|
+
s(:iter, s(:call, nil, :b), 0)))
|
3410
|
+
|
3411
|
+
assert_parse rb, pt
|
3412
|
+
end
|
3413
|
+
|
3414
|
+
def test_block_call_paren_call_block_call
|
3415
|
+
rb = "a (b)\nc.d do end"
|
3416
|
+
pt = s(:block,
|
3417
|
+
s(:call, nil, :a, s(:call, nil, :b)),
|
3418
|
+
s(:iter, s(:call, s(:call, nil, :c), :d), 0))
|
3419
|
+
|
3420
|
+
|
3421
|
+
assert_parse rb, pt
|
3422
|
+
end
|
3423
|
+
|
3424
|
+
def test_block_call_defn_call_block_call
|
3425
|
+
rb = "a def b(c)\n d\n end\n e.f do end"
|
3426
|
+
pt = s(:block,
|
3427
|
+
s(:call, nil, :a,
|
3428
|
+
s(:defn, :b, s(:args, :c), s(:call, nil, :d))),
|
3429
|
+
s(:iter, s(:call, s(:call, nil, :e), :f), 0))
|
3430
|
+
|
3431
|
+
assert_parse rb, pt
|
3432
|
+
end
|
3433
|
+
|
3434
|
+
def test_call_array_lambda_block_call
|
3435
|
+
rb = "a [->() {}] do\nend"
|
3436
|
+
pt = s(:iter,
|
3437
|
+
s(:call, nil, :a,
|
3438
|
+
s(:array, s(:iter, s(:lambda), s(:args)))),
|
3439
|
+
0)
|
3440
|
+
|
3441
|
+
assert_parse rb, pt
|
3442
|
+
end
|
3443
|
+
|
3444
|
+
def test_call_begin_call_block_call
|
3445
|
+
rb = "a begin\nb.c do end\nend"
|
3446
|
+
pt = s(:call, nil, :a,
|
3447
|
+
s(:iter, s(:call, s(:call, nil, :b), :c), 0))
|
3448
|
+
|
3449
|
+
assert_parse rb, pt
|
3450
|
+
end
|
3451
|
+
|
3452
|
+
def test_messy_op_asgn_lineno
|
3453
|
+
rb = "a (B::C *= d e)"
|
3454
|
+
pt = s(:call, nil, :a,
|
3455
|
+
s(:op_asgn, s(:const, :B),
|
3456
|
+
s(:call, nil, :d, s(:call, nil, :e)),
|
3457
|
+
:C,
|
3458
|
+
:*)).line(1)
|
3459
|
+
|
3460
|
+
assert_parse rb, pt
|
3461
|
+
end
|
3462
|
+
|
3463
|
+
def test_str_lit_concat_bad_encodings
|
3464
|
+
rb = '"\xE3\xD3\x8B\xE3\x83\xBC\x83\xE3\x83\xE3\x82\xB3\xA3\x82\x99" \
|
3465
|
+
"\xE3\x83\xB3\xE3\x83\x8F\xE3\x82\x9A\xC3\xBD;foo@bar.com"'.b
|
3466
|
+
pt = s(:str, "\xE3\xD3\x8B\xE3\x83\xBC\x83\xE3\x83\xE3\x82\xB3\xA3\x82\x99\xE3\x83\xB3\xE3\x83\x8F\xE3\x82\x9A\xC3\xBD;foo@bar.com".b)
|
3467
|
+
|
3468
|
+
assert_parse rb, pt
|
3469
|
+
|
3470
|
+
sexp = processor.parse rb
|
3471
|
+
assert_equal Encoding::ASCII_8BIT, sexp.last.encoding
|
3472
|
+
end
|
3473
|
+
|
3291
3474
|
def test_block_call_dot_op2_cmd_args_do_block
|
3292
3475
|
rb = "a.b c() do d end.e f do |g| h end"
|
3293
3476
|
pt = s(:iter,
|
@@ -3588,7 +3771,7 @@ module TestRubyParserShared21Plus
|
|
3588
3771
|
|
3589
3772
|
def test_bug162__21plus
|
3590
3773
|
rb = %q(<<E\nfoo\nE\rO)
|
3591
|
-
emsg = "can't match /E(
|
3774
|
+
emsg = "can't match /E(\\r*\\n|\\z)/ anywhere in . near line 1: \"\""
|
3592
3775
|
|
3593
3776
|
assert_syntax_error rb, emsg
|
3594
3777
|
end
|
@@ -3738,6 +3921,13 @@ module TestRubyParserShared23Plus
|
|
3738
3921
|
assert_parse rb, pt
|
3739
3922
|
end
|
3740
3923
|
|
3924
|
+
def test_heredoc__backslash_dos_format
|
3925
|
+
rb = "str = <<-XXX\r\nbefore\\\r\nafter\r\nXXX\r\n"
|
3926
|
+
pt = s(:lasgn, :str, s(:str, "before\nafter\n"))
|
3927
|
+
|
3928
|
+
assert_parse rb, pt
|
3929
|
+
end
|
3930
|
+
|
3741
3931
|
def test_heredoc_squiggly
|
3742
3932
|
rb = "a = <<~\"EOF\"\n x\n y\n z\n EOF\n\n"
|
3743
3933
|
pt = s(:lasgn, :a, s(:str, "x\ny\nz\n"))
|
@@ -3946,6 +4136,51 @@ module TestRubyParserShared26Plus
|
|
3946
4136
|
end
|
3947
4137
|
end
|
3948
4138
|
|
4139
|
+
module TestRubyParserShared27Plus
|
4140
|
+
include TestRubyParserShared26Plus
|
4141
|
+
|
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)))
|
4146
|
+
|
4147
|
+
assert_parse_line rb, pt, 1
|
4148
|
+
end
|
4149
|
+
|
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)))
|
4154
|
+
|
4155
|
+
assert_parse_line rb, pt, 1
|
4156
|
+
end
|
4157
|
+
|
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)))
|
4163
|
+
|
4164
|
+
assert_parse_line rb, pt, 1
|
4165
|
+
end
|
4166
|
+
|
4167
|
+
def test_call_forward_args_outside_method_definition
|
4168
|
+
rb = "b(...)"
|
4169
|
+
|
4170
|
+
assert_syntax_error rb, "Unexpected ..."
|
4171
|
+
end
|
4172
|
+
|
4173
|
+
def test_call_arg_forward_args_outside_method_definition
|
4174
|
+
rb = "b(x, ...)"
|
4175
|
+
|
4176
|
+
assert_syntax_error rb, "Unexpected ..."
|
4177
|
+
end
|
4178
|
+
end
|
4179
|
+
|
4180
|
+
module TestRubyParserShared30Plus
|
4181
|
+
include TestRubyParserShared27Plus
|
4182
|
+
end
|
4183
|
+
|
3949
4184
|
class TestRubyParser < Minitest::Test
|
3950
4185
|
def test_cls_version
|
3951
4186
|
assert_equal 23, RubyParser::V23.version
|
@@ -4239,7 +4474,46 @@ class TestRubyParserV26 < RubyParserTestCase
|
|
4239
4474
|
|
4240
4475
|
assert_parse_line rb, pt, 1
|
4241
4476
|
end
|
4477
|
+
end
|
4478
|
+
|
4479
|
+
class TestRubyParserV27 < RubyParserTestCase
|
4480
|
+
include TestRubyParserShared27Plus
|
4242
4481
|
|
4482
|
+
def setup
|
4483
|
+
super
|
4484
|
+
|
4485
|
+
self.processor = RubyParser::V27.new
|
4486
|
+
end
|
4487
|
+
|
4488
|
+
def test_bdot2
|
4489
|
+
rb = "..10\n; ..a\n; c"
|
4490
|
+
pt = s(:block,
|
4491
|
+
s(:dot2, nil, s(:lit, 10).line(1)).line(1),
|
4492
|
+
s(:dot2, nil, s(:call, nil, :a).line(2)).line(2),
|
4493
|
+
s(:call, nil, :c).line(3)).line(1)
|
4494
|
+
|
4495
|
+
assert_parse_line rb, pt, 1
|
4496
|
+
end
|
4497
|
+
|
4498
|
+
def test_bdot3
|
4499
|
+
rb = "...10\n; ...a\n; c"
|
4500
|
+
pt = s(:block,
|
4501
|
+
s(:dot3, nil, s(:lit, 10).line(1)).line(1),
|
4502
|
+
s(:dot3, nil, s(:call, nil, :a).line(2)).line(2),
|
4503
|
+
s(:call, nil, :c).line(3)).line(1)
|
4504
|
+
|
4505
|
+
assert_parse_line rb, pt, 1
|
4506
|
+
end
|
4507
|
+
end
|
4508
|
+
|
4509
|
+
class TestRubyParserV30 < RubyParserTestCase
|
4510
|
+
include TestRubyParserShared30Plus
|
4511
|
+
|
4512
|
+
def setup
|
4513
|
+
super
|
4514
|
+
|
4515
|
+
self.processor = RubyParser::V30.new
|
4516
|
+
end
|
4243
4517
|
end
|
4244
4518
|
|
4245
4519
|
RubyParser::VERSIONS.each do |klass|
|