ruby_parser 3.14.2 → 3.15.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 +0 -0
- data/History.rdoc +35 -0
- data/Manifest.txt +2 -0
- data/Rakefile +28 -9
- data/bin/ruby_parse_extract_error +8 -3
- data/compare/normalize.rb +43 -3
- data/debugging.md +39 -0
- data/lib/ruby20_parser.rb +2722 -2702
- data/lib/ruby20_parser.y +91 -58
- data/lib/ruby21_parser.rb +2603 -2576
- data/lib/ruby21_parser.y +91 -58
- data/lib/ruby22_parser.rb +2729 -2715
- data/lib/ruby22_parser.y +91 -58
- data/lib/ruby23_parser.rb +2698 -2686
- data/lib/ruby23_parser.y +91 -58
- data/lib/ruby24_parser.rb +2699 -2670
- data/lib/ruby24_parser.y +91 -58
- data/lib/ruby25_parser.rb +2699 -2670
- data/lib/ruby25_parser.y +91 -58
- data/lib/ruby26_parser.rb +2699 -2670
- data/lib/ruby26_parser.y +91 -58
- data/lib/ruby27_parser.rb +7224 -0
- data/lib/ruby27_parser.y +2657 -0
- data/lib/ruby_lexer.rb +72 -40
- data/lib/ruby_lexer.rex +5 -6
- data/lib/ruby_lexer.rex.rb +6 -8
- data/lib/ruby_parser.rb +2 -0
- data/lib/ruby_parser.yy +93 -58
- data/lib/ruby_parser_extras.rb +49 -16
- data/test/test_ruby_lexer.rb +32 -16
- data/test/test_ruby_parser.rb +204 -3
- data/tools/munge.rb +9 -4
- metadata +12 -7
- 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.15.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[
|
@@ -493,6 +499,8 @@ module RubyParserStuff
|
|
493
499
|
str.encode! Encoding::UTF_8
|
494
500
|
break
|
495
501
|
end
|
502
|
+
rescue ArgumentError # unknown encoding name
|
503
|
+
# do nothing
|
496
504
|
rescue Encoding::InvalidByteSequenceError
|
497
505
|
# do nothing
|
498
506
|
rescue Encoding::UndefinedConversionError
|
@@ -532,7 +540,7 @@ module RubyParserStuff
|
|
532
540
|
header.map! { |s| s.force_encoding "ASCII-8BIT" } if has_enc
|
533
541
|
|
534
542
|
first = header.first || ""
|
535
|
-
encoding, str = "utf-8", str[3..-1] if first =~ /\A\xEF\xBB\xBF/
|
543
|
+
encoding, str = "utf-8", str.b[3..-1] if first =~ /\A\xEF\xBB\xBF/
|
536
544
|
|
537
545
|
encoding = $1.strip if header.find { |s|
|
538
546
|
s[/^#.*?-\*-.*?coding:\s*([^ ;]+).*?-\*-/, 1] ||
|
@@ -592,7 +600,9 @@ module RubyParserStuff
|
|
592
600
|
case ttype
|
593
601
|
when :str then
|
594
602
|
if htype == :str
|
595
|
-
head.last
|
603
|
+
a, b = head.last, tail.last
|
604
|
+
b = b.dup.force_encoding a.encoding unless Encoding.compatible?(a, b)
|
605
|
+
a << b
|
596
606
|
elsif htype == :dstr and head.size == 2 then
|
597
607
|
head.last << tail.last
|
598
608
|
else
|
@@ -696,6 +706,15 @@ module RubyParserStuff
|
|
696
706
|
result
|
697
707
|
end
|
698
708
|
|
709
|
+
def new_begin val
|
710
|
+
_, lineno, body, _ = val
|
711
|
+
|
712
|
+
result = body ? s(:begin, body) : s(:nil)
|
713
|
+
result.line lineno
|
714
|
+
|
715
|
+
result
|
716
|
+
end
|
717
|
+
|
699
718
|
def new_body val
|
700
719
|
body, resbody, elsebody, ensurebody = val
|
701
720
|
|
@@ -723,7 +742,10 @@ module RubyParserStuff
|
|
723
742
|
result = block_append(result, elsebody)
|
724
743
|
end
|
725
744
|
|
726
|
-
|
745
|
+
if ensurebody
|
746
|
+
lineno = (result || ensurebody).line
|
747
|
+
result = s(:ensure, result, ensurebody).compact.line lineno
|
748
|
+
end
|
727
749
|
|
728
750
|
result
|
729
751
|
end
|
@@ -843,14 +865,17 @@ module RubyParserStuff
|
|
843
865
|
end
|
844
866
|
|
845
867
|
def new_defs val
|
846
|
-
recv,
|
847
|
-
|
868
|
+
_, recv, _, _, name, (_in_def, line), args, body, _ = val
|
869
|
+
|
848
870
|
body ||= s(:nil).line line
|
849
871
|
|
850
872
|
args.line line
|
851
873
|
|
852
874
|
result = s(:defs, recv, name.to_sym, args)
|
853
875
|
|
876
|
+
# TODO: remove_begin
|
877
|
+
# TODO: reduce_nodes
|
878
|
+
|
854
879
|
if body then
|
855
880
|
if body.sexp_type == :block then
|
856
881
|
result.push(*body.sexp_body)
|
@@ -875,7 +900,9 @@ module RubyParserStuff
|
|
875
900
|
end
|
876
901
|
|
877
902
|
def new_hash val
|
878
|
-
|
903
|
+
_, line, assocs = val
|
904
|
+
|
905
|
+
s(:hash).line(line).concat assocs.values
|
879
906
|
end
|
880
907
|
|
881
908
|
def new_if c, t, f
|
@@ -1134,6 +1161,7 @@ module RubyParserStuff
|
|
1134
1161
|
def new_string val
|
1135
1162
|
str, = val
|
1136
1163
|
str.force_encoding("UTF-8")
|
1164
|
+
# TODO: remove:
|
1137
1165
|
str.force_encoding("ASCII-8BIT") unless str.valid_encoding?
|
1138
1166
|
result = s(:str, str).line lexer.lineno
|
1139
1167
|
self.lexer.fixup_lineno str.count("\n")
|
@@ -1228,20 +1256,23 @@ module RubyParserStuff
|
|
1228
1256
|
result
|
1229
1257
|
end
|
1230
1258
|
|
1231
|
-
def new_xstring
|
1232
|
-
|
1233
|
-
|
1259
|
+
def new_xstring val
|
1260
|
+
_, node = val
|
1261
|
+
|
1262
|
+
node ||= s(:str, "").line lexer.lineno
|
1263
|
+
|
1264
|
+
if node then
|
1265
|
+
case node.sexp_type
|
1234
1266
|
when :str
|
1235
|
-
|
1267
|
+
node.sexp_type = :xstr
|
1236
1268
|
when :dstr
|
1237
|
-
|
1269
|
+
node.sexp_type = :dxstr
|
1238
1270
|
else
|
1239
|
-
|
1271
|
+
node = s(:dxstr, "", node).line node.line
|
1240
1272
|
end
|
1241
|
-
str
|
1242
|
-
else
|
1243
|
-
s(:xstr, "")
|
1244
1273
|
end
|
1274
|
+
|
1275
|
+
node
|
1245
1276
|
end
|
1246
1277
|
|
1247
1278
|
def new_yield args = nil
|
@@ -1262,6 +1293,7 @@ module RubyParserStuff
|
|
1262
1293
|
token = self.lexer.next_token
|
1263
1294
|
|
1264
1295
|
if token and token.first != RubyLexer::EOF then
|
1296
|
+
self.last_token_type = token
|
1265
1297
|
return token
|
1266
1298
|
else
|
1267
1299
|
return [false, false]
|
@@ -1320,6 +1352,7 @@ module RubyParserStuff
|
|
1320
1352
|
self.in_single = 0
|
1321
1353
|
self.env.reset
|
1322
1354
|
self.comments.clear
|
1355
|
+
self.last_token_type = nil
|
1323
1356
|
end
|
1324
1357
|
|
1325
1358
|
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
|
@@ -720,7 +719,7 @@ class TestRubyLexer < Minitest::Test
|
|
720
719
|
|
721
720
|
assert_lex3("do 42 end",
|
722
721
|
nil,
|
723
|
-
:
|
722
|
+
:kDO, "do", EXPR_BEG,
|
724
723
|
:tINTEGER, 42, EXPR_NUM,
|
725
724
|
:kEND, "end", EXPR_END)
|
726
725
|
end
|
@@ -926,6 +925,14 @@ class TestRubyLexer < Minitest::Test
|
|
926
925
|
assert_lex3("$1234", nil, :tGVAR, "$1234", EXPR_END)
|
927
926
|
end
|
928
927
|
|
928
|
+
def test_yylex_global_I_have_no_words
|
929
|
+
assert_lex3("$x\xE2\x80\x8B = 42", # zero width space?!?!?
|
930
|
+
nil,
|
931
|
+
:tGVAR, "$x\xE2\x80\x8B", EXPR_END,
|
932
|
+
:tEQL, "=", EXPR_BEG,
|
933
|
+
:tINTEGER, 42, EXPR_NUM)
|
934
|
+
end
|
935
|
+
|
929
936
|
def test_yylex_global_other
|
930
937
|
assert_lex3("[$~, $*, $$, $?, $!, $@, $/, $\\, $;, $,, $., $=, $:, $<, $>, $\"]",
|
931
938
|
nil,
|
@@ -1109,11 +1116,11 @@ class TestRubyLexer < Minitest::Test
|
|
1109
1116
|
:tEQL, "=", EXPR_BEG,
|
1110
1117
|
:tSTRING_BEG, "\"", EXPR_BEG,
|
1111
1118
|
:tSTRING_CONTENT, "#x a ", EXPR_BEG,
|
1112
|
-
:tSTRING_DVAR, "
|
1119
|
+
:tSTRING_DVAR, "#", EXPR_BEG,
|
1113
1120
|
:tSTRING_CONTENT, "@a b ", EXPR_BEG, # HUH?
|
1114
|
-
:tSTRING_DVAR, "
|
1121
|
+
:tSTRING_DVAR, "#", EXPR_BEG,
|
1115
1122
|
:tSTRING_CONTENT, "$b c ", EXPR_BEG, # HUH?
|
1116
|
-
:tSTRING_DVAR, "
|
1123
|
+
:tSTRING_DVAR, "#", EXPR_BEG,
|
1117
1124
|
:tSTRING_CONTENT, "@@d ", EXPR_BEG, # HUH?
|
1118
1125
|
:tSTRING_DBEG, "\#{", EXPR_BEG,
|
1119
1126
|
:tSTRING_CONTENT, "3} \n", EXPR_BEG,
|
@@ -2099,6 +2106,10 @@ class TestRubyLexer < Minitest::Test
|
|
2099
2106
|
assert_lex3("?\\M-\\C-a", nil, :tSTRING, "\M-\C-a", EXPR_END)
|
2100
2107
|
end
|
2101
2108
|
|
2109
|
+
def test_yylex_question_control_escape
|
2110
|
+
assert_lex3('?\C-\]', nil, :tSTRING, ?\C-\], EXPR_END)
|
2111
|
+
end
|
2112
|
+
|
2102
2113
|
def test_yylex_question_ws
|
2103
2114
|
assert_lex3("? ", nil, :tEH, "?", EXPR_BEG)
|
2104
2115
|
assert_lex3("?\n", nil, :tEH, "?", EXPR_BEG)
|
@@ -2549,11 +2560,7 @@ class TestRubyLexer < Minitest::Test
|
|
2549
2560
|
end
|
2550
2561
|
|
2551
2562
|
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)
|
2563
|
+
refute_lex("\"\\c\\\"", :tSTRING_BEG, '"')
|
2557
2564
|
end
|
2558
2565
|
|
2559
2566
|
def test_yylex_string_double_escape_c_escape
|
@@ -2847,6 +2854,15 @@ class TestRubyLexer < Minitest::Test
|
|
2847
2854
|
:tSTRING_END, '"')
|
2848
2855
|
end
|
2849
2856
|
|
2857
|
+
def test_yylex_string_utf8_bad_encoding_with_escapes
|
2858
|
+
str = "\"\\xBADπ\""
|
2859
|
+
exp = "\xBADπ".b
|
2860
|
+
|
2861
|
+
assert_lex(str,
|
2862
|
+
s(:str, exp),
|
2863
|
+
:tSTRING, exp, EXPR_END)
|
2864
|
+
end
|
2865
|
+
|
2850
2866
|
def test_yylex_string_utf8_complex_trailing_hex
|
2851
2867
|
chr = [0x3024].pack("U")
|
2852
2868
|
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, :"||")
|
@@ -3288,6 +3397,76 @@ module TestRubyParserShared20Plus
|
|
3288
3397
|
assert_parse rb, pt
|
3289
3398
|
end
|
3290
3399
|
|
3400
|
+
def test_call_array_block_call
|
3401
|
+
rb = "a [ nil, b do end ]"
|
3402
|
+
pt = s(:call, nil, :a,
|
3403
|
+
s(:array,
|
3404
|
+
s(:nil),
|
3405
|
+
s(:iter, s(:call, nil, :b), 0)))
|
3406
|
+
|
3407
|
+
assert_parse rb, pt
|
3408
|
+
end
|
3409
|
+
|
3410
|
+
def test_block_call_paren_call_block_call
|
3411
|
+
rb = "a (b)\nc.d do end"
|
3412
|
+
pt = s(:block,
|
3413
|
+
s(:call, nil, :a, s(:call, nil, :b)),
|
3414
|
+
s(:iter, s(:call, s(:call, nil, :c), :d), 0))
|
3415
|
+
|
3416
|
+
|
3417
|
+
assert_parse rb, pt
|
3418
|
+
end
|
3419
|
+
|
3420
|
+
def test_block_call_defn_call_block_call
|
3421
|
+
rb = "a def b(c)\n d\n end\n e.f do end"
|
3422
|
+
pt = s(:block,
|
3423
|
+
s(:call, nil, :a,
|
3424
|
+
s(:defn, :b, s(:args, :c), s(:call, nil, :d))),
|
3425
|
+
s(:iter, s(:call, s(:call, nil, :e), :f), 0))
|
3426
|
+
|
3427
|
+
assert_parse rb, pt
|
3428
|
+
end
|
3429
|
+
|
3430
|
+
def test_call_array_lambda_block_call
|
3431
|
+
rb = "a [->() {}] do\nend"
|
3432
|
+
pt = s(:iter,
|
3433
|
+
s(:call, nil, :a,
|
3434
|
+
s(:array, s(:iter, s(:lambda), s(:args)))),
|
3435
|
+
0)
|
3436
|
+
|
3437
|
+
assert_parse rb, pt
|
3438
|
+
end
|
3439
|
+
|
3440
|
+
def test_call_begin_call_block_call
|
3441
|
+
rb = "a begin\nb.c do end\nend"
|
3442
|
+
pt = s(:call, nil, :a,
|
3443
|
+
s(:iter, s(:call, s(:call, nil, :b), :c), 0))
|
3444
|
+
|
3445
|
+
assert_parse rb, pt
|
3446
|
+
end
|
3447
|
+
|
3448
|
+
def test_messy_op_asgn_lineno
|
3449
|
+
rb = "a (B::C *= d e)"
|
3450
|
+
pt = s(:call, nil, :a,
|
3451
|
+
s(:op_asgn, s(:const, :B),
|
3452
|
+
s(:call, nil, :d, s(:call, nil, :e)),
|
3453
|
+
:C,
|
3454
|
+
:*)).line(1)
|
3455
|
+
|
3456
|
+
assert_parse rb, pt
|
3457
|
+
end
|
3458
|
+
|
3459
|
+
def test_str_lit_concat_bad_encodings
|
3460
|
+
rb = '"\xE3\xD3\x8B\xE3\x83\xBC\x83\xE3\x83\xE3\x82\xB3\xA3\x82\x99" \
|
3461
|
+
"\xE3\x83\xB3\xE3\x83\x8F\xE3\x82\x9A\xC3\xBD;foo@bar.com"'.b
|
3462
|
+
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)
|
3463
|
+
|
3464
|
+
assert_parse rb, pt
|
3465
|
+
|
3466
|
+
sexp = processor.parse rb
|
3467
|
+
assert_equal Encoding::ASCII_8BIT, sexp.last.encoding
|
3468
|
+
end
|
3469
|
+
|
3291
3470
|
def test_block_call_dot_op2_cmd_args_do_block
|
3292
3471
|
rb = "a.b c() do d end.e f do |g| h end"
|
3293
3472
|
pt = s(:iter,
|
@@ -3588,7 +3767,7 @@ module TestRubyParserShared21Plus
|
|
3588
3767
|
|
3589
3768
|
def test_bug162__21plus
|
3590
3769
|
rb = %q(<<E\nfoo\nE\rO)
|
3591
|
-
emsg = "can't match /E(
|
3770
|
+
emsg = "can't match /E(\\r*\\n|\\z)/ anywhere in . near line 1: \"\""
|
3592
3771
|
|
3593
3772
|
assert_syntax_error rb, emsg
|
3594
3773
|
end
|
@@ -3738,6 +3917,13 @@ module TestRubyParserShared23Plus
|
|
3738
3917
|
assert_parse rb, pt
|
3739
3918
|
end
|
3740
3919
|
|
3920
|
+
def test_heredoc__backslash_dos_format
|
3921
|
+
rb = "str = <<-XXX\r\nbefore\\\r\nafter\r\nXXX\r\n"
|
3922
|
+
pt = s(:lasgn, :str, s(:str, "before\nafter\n"))
|
3923
|
+
|
3924
|
+
assert_parse rb, pt
|
3925
|
+
end
|
3926
|
+
|
3741
3927
|
def test_heredoc_squiggly
|
3742
3928
|
rb = "a = <<~\"EOF\"\n x\n y\n z\n EOF\n\n"
|
3743
3929
|
pt = s(:lasgn, :a, s(:str, "x\ny\nz\n"))
|
@@ -3946,6 +4132,10 @@ module TestRubyParserShared26Plus
|
|
3946
4132
|
end
|
3947
4133
|
end
|
3948
4134
|
|
4135
|
+
module TestRubyParserShared27Plus
|
4136
|
+
include TestRubyParserShared26Plus
|
4137
|
+
end
|
4138
|
+
|
3949
4139
|
class TestRubyParser < Minitest::Test
|
3950
4140
|
def test_cls_version
|
3951
4141
|
assert_equal 23, RubyParser::V23.version
|
@@ -4242,6 +4432,17 @@ class TestRubyParserV26 < RubyParserTestCase
|
|
4242
4432
|
|
4243
4433
|
end
|
4244
4434
|
|
4435
|
+
class TestRubyParserV27 < RubyParserTestCase
|
4436
|
+
include TestRubyParserShared27Plus
|
4437
|
+
|
4438
|
+
def setup
|
4439
|
+
super
|
4440
|
+
|
4441
|
+
self.processor = RubyParser::V27.new
|
4442
|
+
end
|
4443
|
+
end
|
4444
|
+
|
4445
|
+
|
4245
4446
|
RubyParser::VERSIONS.each do |klass|
|
4246
4447
|
v = klass.version
|
4247
4448
|
describe "block args arity #{v}" do
|