ruby_parser 3.14.2 → 3.17.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 +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|
|