ripper_ruby_parser 1.4.1 → 1.4.2
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
- data/CHANGELOG.md +12 -1
- data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +10 -2
- data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +2 -2
- data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +2 -2
- data/lib/ripper_ruby_parser/unescape.rb +78 -27
- data/lib/ripper_ruby_parser/version.rb +1 -1
- data/test/end_to_end/comparison_test.rb +0 -74
- data/test/end_to_end/test_comparison_test.rb +1 -1
- data/test/ripper_ruby_parser/parser_test.rb +0 -48
- data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +121 -3
- data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +66 -0
- data/test/samples/misc.rb +49 -0
- data/test/samples/operators.rb +18 -0
- data/test/samples/strings.rb +71 -0
- metadata +8 -4
- data/test/samples/inline.rb +0 -704
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab036613dacd6865ca8103db78c67273d6fad340e3a6a7ed1fe5450c5511cc05
|
4
|
+
data.tar.gz: 182feec3370738d6d5516e5615022a045ed717edf489cc694ac02eda97e6e6bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c5f17c00265aaf9df0741c5afee3b90f000141d4285bce067953bb1feac645779c8e4b9db2319baa9a3f6822b46a9f6edbeef87af1177b22a03cd437fecad51
|
7
|
+
data.tar.gz: 7001633d0756ab5afb2b2813572550f3cea1df75c11e82fe8117e4243aaa6cf4386512b3a7754b76f0a5a8be7c4b49f8b1e5a0148b4465e7aa72658b7c951acc
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.4.2 / 2018-04-03
|
4
|
+
|
5
|
+
* Fix handling of strings delimited by %()
|
6
|
+
* Handle line continuations in stringlike literals
|
7
|
+
- Handle line continuations in string and regexp literals
|
8
|
+
- Handle escaped line continuations
|
9
|
+
- Hanlde line continuations in word and symbol list literals
|
10
|
+
* Force encoding of string literals to UTF-8 if the result is valid
|
11
|
+
* Fix handling of range operators with float literals
|
12
|
+
|
3
13
|
## 1.4.1 / 2018-03-31
|
4
14
|
|
5
15
|
* Properly pop delimiter stack after parsing a symbol
|
@@ -7,7 +17,8 @@
|
|
7
17
|
## 1.4.0 / 2018-03-30
|
8
18
|
|
9
19
|
* Handle begin..end blocks with postfix conditionals
|
10
|
-
*
|
20
|
+
* Match RubyParser's handling of string literals that do not allow escape
|
21
|
+
sequences
|
11
22
|
|
12
23
|
## 1.3.0 / 2018-02-17
|
13
24
|
|
@@ -179,10 +179,18 @@ module RipperRubyParser
|
|
179
179
|
|
180
180
|
def on_tstring_content(content)
|
181
181
|
content = case @delimiter_stack.last
|
182
|
-
when
|
182
|
+
when /^<</
|
183
183
|
Unescape.unescape(content)
|
184
|
-
when "'
|
184
|
+
when '"', '`', ':"', /^%Q.$/, /^%.$/
|
185
|
+
Unescape.fix_encoding(Unescape.unescape(content))
|
186
|
+
when /^%[WI].$/
|
187
|
+
Unescape.fix_encoding(Unescape.unescape_wordlist_word(content))
|
188
|
+
when "'", ":'", /^%q.$/
|
185
189
|
Unescape.simple_unescape(content)
|
190
|
+
when '/', /^%r.$/
|
191
|
+
Unescape.unescape_regexp(content)
|
192
|
+
when /^%[wi].$/
|
193
|
+
Unescape.simple_unescape_wordlist_word(content)
|
186
194
|
else
|
187
195
|
content
|
188
196
|
end
|
@@ -46,7 +46,7 @@ module RipperRubyParser
|
|
46
46
|
_, left, right = exp.shift 3
|
47
47
|
left = process(left)
|
48
48
|
right = process(right)
|
49
|
-
if
|
49
|
+
if integer_literal?(left) && integer_literal?(right)
|
50
50
|
s(:lit, Range.new(left[1], right[1]))
|
51
51
|
else
|
52
52
|
s(:dot2, left, right)
|
@@ -57,7 +57,7 @@ module RipperRubyParser
|
|
57
57
|
_, left, right = exp.shift 3
|
58
58
|
left = process(left)
|
59
59
|
right = process(right)
|
60
|
-
if
|
60
|
+
if integer_literal?(left) && integer_literal?(right)
|
61
61
|
s(:lit, Range.new(left[1], right[1], true))
|
62
62
|
else
|
63
63
|
s(:dot3, left, right)
|
@@ -5,6 +5,22 @@ module RipperRubyParser
|
|
5
5
|
module Unescape
|
6
6
|
module_function
|
7
7
|
|
8
|
+
ESCAPE_SEQUENCE_REGEXP =
|
9
|
+
/\\(
|
10
|
+
[0-7]{1,3} | # octal character
|
11
|
+
x[0-9a-fA-F]{1,2} | # hex byte
|
12
|
+
u[0-9a-fA-F]{4} | # unicode character
|
13
|
+
M-\\C-. | # meta-ctrl
|
14
|
+
C-\\M-. | # ctrl-meta
|
15
|
+
M-\\c. | # meta-ctrl (shorthand)
|
16
|
+
c\\M-. | # ctrl-meta (shorthand)
|
17
|
+
C-. | # control (regular)
|
18
|
+
c. | # control (shorthand)
|
19
|
+
M-. | # meta
|
20
|
+
\n | # line continuation
|
21
|
+
. # single-character
|
22
|
+
)/x
|
23
|
+
|
8
24
|
SINGLE_LETTER_ESCAPES = {
|
9
25
|
'a' => "\a",
|
10
26
|
'b' => "\b",
|
@@ -29,40 +45,75 @@ module RipperRubyParser
|
|
29
45
|
end
|
30
46
|
end
|
31
47
|
|
32
|
-
def
|
48
|
+
def simple_unescape_wordlist_word(string)
|
33
49
|
string.gsub(/\\(
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
M-\\C-. | # meta-ctrl
|
38
|
-
C-\\M-. | # ctrl-meta
|
39
|
-
M-\\c. | # meta-ctrl (shorthand)
|
40
|
-
c\\M-. | # ctrl-meta (shorthand)
|
41
|
-
C-. | # control (regular)
|
42
|
-
c. | # control (shorthand)
|
43
|
-
M-. | # meta
|
44
|
-
. # single-character
|
50
|
+
' | # single quote
|
51
|
+
\\ | # backslash
|
52
|
+
\n # newline
|
45
53
|
)/x) do
|
54
|
+
Regexp.last_match[1]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def unescape(string)
|
59
|
+
string.gsub(ESCAPE_SEQUENCE_REGEXP) do
|
60
|
+
bare = Regexp.last_match[1]
|
61
|
+
if bare == "\n"
|
62
|
+
''
|
63
|
+
else
|
64
|
+
unescaped_value(bare)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def unescape_wordlist_word(string)
|
70
|
+
string.gsub(ESCAPE_SEQUENCE_REGEXP) do
|
71
|
+
bare = Regexp.last_match[1]
|
72
|
+
unescaped_value(bare)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def fix_encoding(string)
|
77
|
+
unless string.encoding == Encoding::UTF_8
|
78
|
+
dup = string.dup.force_encoding Encoding::UTF_8
|
79
|
+
return dup if dup.valid_encoding?
|
80
|
+
end
|
81
|
+
string
|
82
|
+
end
|
83
|
+
|
84
|
+
def unescape_regexp(string)
|
85
|
+
string.gsub(/\\(\n|\\)/) do
|
46
86
|
bare = Regexp.last_match[1]
|
47
87
|
case bare
|
48
|
-
when
|
49
|
-
|
50
|
-
when /^x/
|
51
|
-
bare[1..-1].to_i(16).chr
|
52
|
-
when /^u/
|
53
|
-
bare[1..-1].to_i(16).chr(Encoding::UTF_8)
|
54
|
-
when /^(c|C-).$/
|
55
|
-
(bare[-1].ord & 0b1001_1111).chr
|
56
|
-
when /^M-.$/
|
57
|
-
(bare[-1].ord | 0b1000_0000).chr
|
58
|
-
when /^(M-\\C-|C-\\M-|M-\\c|c\\M-).$/
|
59
|
-
(bare[-1].ord & 0b1001_1111 | 0b1000_0000).chr
|
60
|
-
when /^[0-7]+/
|
61
|
-
bare.to_i(8).chr
|
88
|
+
when "\n"
|
89
|
+
''
|
62
90
|
else
|
63
|
-
|
91
|
+
'\\\\'
|
64
92
|
end
|
65
93
|
end
|
66
94
|
end
|
95
|
+
|
96
|
+
def unescaped_value(bare)
|
97
|
+
case bare
|
98
|
+
when SINGLE_LETTER_ESCAPES_REGEXP
|
99
|
+
SINGLE_LETTER_ESCAPES[bare]
|
100
|
+
when /^x/
|
101
|
+
bare[1..-1].to_i(16).chr
|
102
|
+
when /^u/
|
103
|
+
bare[1..-1].to_i(16).chr(Encoding::UTF_8)
|
104
|
+
when /^(c|C-).$/
|
105
|
+
(bare[-1].ord & 0b1001_1111).chr
|
106
|
+
when /^M-.$/
|
107
|
+
(bare[-1].ord | 0b1000_0000).chr
|
108
|
+
when /^(M-\\C-|C-\\M-|M-\\c|c\\M-).$/
|
109
|
+
(bare[-1].ord & 0b1001_1111 | 0b1000_0000).chr
|
110
|
+
when /^[0-7]+/
|
111
|
+
bare.to_i(8).chr
|
112
|
+
when "\n"
|
113
|
+
bare
|
114
|
+
else
|
115
|
+
bare
|
116
|
+
end
|
117
|
+
end
|
67
118
|
end
|
68
119
|
end
|
@@ -99,78 +99,4 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
99
99
|
program.must_be_parsed_as_before
|
100
100
|
end
|
101
101
|
end
|
102
|
-
|
103
|
-
describe 'for an example with regular expressions with different encoding flags' do
|
104
|
-
it 'gives the same result' do
|
105
|
-
program = <<-END
|
106
|
-
regular = /foo/
|
107
|
-
noenc = /foo/n
|
108
|
-
utf8 = /foo/u
|
109
|
-
euc = /foo/e
|
110
|
-
sjis = /foo/s
|
111
|
-
|
112
|
-
regular = /foo\#{bar}/
|
113
|
-
noenc = /foo\#{bar}/n
|
114
|
-
utf8 = /foo\#{bar}/u
|
115
|
-
euc = /foo\#{bar}/e
|
116
|
-
sjis = /foo\#{bar}/s
|
117
|
-
END
|
118
|
-
|
119
|
-
program.must_be_parsed_as_before
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
describe 'for an example with __ENCODING__' do
|
124
|
-
it 'gives the same result' do
|
125
|
-
program = 'foo = __ENCODING__'
|
126
|
-
program.must_be_parsed_as_before
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
|
-
describe 'for an example with self[]' do
|
131
|
-
# https://github.com/seattlerb/ruby_parser/issues/250
|
132
|
-
it 'gives the same result' do
|
133
|
-
program = 'self[:foo]'
|
134
|
-
program.must_be_parsed_as_before
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
describe 'for an example with required keyword arguments and no parentheses' do
|
139
|
-
# https://github.com/seattlerb/ruby_parser/pull/254
|
140
|
-
let(:program) do
|
141
|
-
<<-END
|
142
|
-
def foo a:, b:
|
143
|
-
# body
|
144
|
-
end
|
145
|
-
END
|
146
|
-
end
|
147
|
-
|
148
|
-
it 'gives the same result' do
|
149
|
-
program.must_be_parsed_as_before
|
150
|
-
end
|
151
|
-
end
|
152
|
-
|
153
|
-
describe 'for an example combining begin..end and diverse operators' do
|
154
|
-
let(:program) do
|
155
|
-
<<-END
|
156
|
-
begin end
|
157
|
-
begin; foo; end
|
158
|
-
begin; foo; bar; end
|
159
|
-
- begin; foo; end
|
160
|
-
begin; bar; end + foo
|
161
|
-
foo + begin; bar; end
|
162
|
-
begin; foo; end ? bar : baz
|
163
|
-
foo ? begin; bar; end : baz
|
164
|
-
foo ? bar : begin; baz; end
|
165
|
-
begin; bar; end and foo
|
166
|
-
foo and begin; bar; end
|
167
|
-
begin; foo; end if bar
|
168
|
-
begin; foo; end unless bar
|
169
|
-
END
|
170
|
-
end
|
171
|
-
|
172
|
-
it 'gives the same result' do
|
173
|
-
program.must_be_parsed_as_before
|
174
|
-
end
|
175
|
-
end
|
176
102
|
end
|
@@ -845,54 +845,6 @@ describe RipperRubyParser::Parser do
|
|
845
845
|
must_be_parsed_as s(:call, s(:lit, 1), :!)
|
846
846
|
end
|
847
847
|
|
848
|
-
it 'handles the range operator with positive number literals' do
|
849
|
-
'1..2'.
|
850
|
-
must_be_parsed_as s(:lit, 1..2)
|
851
|
-
end
|
852
|
-
|
853
|
-
it 'handles the range operator with negative number literals' do
|
854
|
-
'-1..-2'.
|
855
|
-
must_be_parsed_as s(:lit, -1..-2)
|
856
|
-
end
|
857
|
-
|
858
|
-
it 'handles the range operator with string literals' do
|
859
|
-
"'a'..'z'".
|
860
|
-
must_be_parsed_as s(:dot2,
|
861
|
-
s(:str, 'a'),
|
862
|
-
s(:str, 'z'))
|
863
|
-
end
|
864
|
-
|
865
|
-
it 'handles the range operator with non-literals' do
|
866
|
-
'foo..bar'.
|
867
|
-
must_be_parsed_as s(:dot2,
|
868
|
-
s(:call, nil, :foo),
|
869
|
-
s(:call, nil, :bar))
|
870
|
-
end
|
871
|
-
|
872
|
-
it 'handles the exclusive range operator with positive number literals' do
|
873
|
-
'1...2'.
|
874
|
-
must_be_parsed_as s(:lit, 1...2)
|
875
|
-
end
|
876
|
-
|
877
|
-
it 'handles the exclusive range operator with negative number literals' do
|
878
|
-
'-1...-2'.
|
879
|
-
must_be_parsed_as s(:lit, -1...-2)
|
880
|
-
end
|
881
|
-
|
882
|
-
it 'handles the exclusive range operator with string literals' do
|
883
|
-
"'a'...'z'".
|
884
|
-
must_be_parsed_as s(:dot3,
|
885
|
-
s(:str, 'a'),
|
886
|
-
s(:str, 'z'))
|
887
|
-
end
|
888
|
-
|
889
|
-
it 'handles the exclusive range operator with non-literals' do
|
890
|
-
'foo...bar'.
|
891
|
-
must_be_parsed_as s(:dot3,
|
892
|
-
s(:call, nil, :foo),
|
893
|
-
s(:call, nil, :bar))
|
894
|
-
end
|
895
|
-
|
896
848
|
it 'handles the ternary operator' do
|
897
849
|
'foo ? bar : baz'.
|
898
850
|
must_be_parsed_as s(:if,
|
@@ -46,6 +46,23 @@ describe RipperRubyParser::Parser do
|
|
46
46
|
result.inspect.must_equal s(:lit, /foo/n).inspect
|
47
47
|
end
|
48
48
|
|
49
|
+
it 'works with line continuation' do
|
50
|
+
"/foo\\\nbar/".
|
51
|
+
must_be_parsed_as s(:lit, /foobar/)
|
52
|
+
end
|
53
|
+
|
54
|
+
describe 'for a %r-delimited regex literal' do
|
55
|
+
it 'works for the simple case with escape sequences' do
|
56
|
+
'%r[foo\nbar]'.
|
57
|
+
must_be_parsed_as s(:lit, /foo\nbar/)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'works with odd delimiters and escape sequences' do
|
61
|
+
'%r_foo\nbar_'.
|
62
|
+
must_be_parsed_as s(:lit, /foo\nbar/)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
49
66
|
describe 'with interpolations' do
|
50
67
|
it 'works for a simple interpolation' do
|
51
68
|
'/foo#{bar}baz/'.
|
@@ -139,6 +156,16 @@ describe RipperRubyParser::Parser do
|
|
139
156
|
result[1].encoding.to_s.must_equal 'UTF-8'
|
140
157
|
end
|
141
158
|
|
159
|
+
it 'handles line continuation with double-quoted strings' do
|
160
|
+
"\"foo\\\nbar\"".
|
161
|
+
must_be_parsed_as s(:str, 'foobar')
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'escapes line continuation with double-quoted strings' do
|
165
|
+
"\"foo\\\\\nbar\"".
|
166
|
+
must_be_parsed_as s(:str, "foo\\\nbar")
|
167
|
+
end
|
168
|
+
|
142
169
|
describe 'with double-quoted strings with escape sequences' do
|
143
170
|
it 'works for strings with escape sequences' do
|
144
171
|
'"\\n"'.
|
@@ -213,6 +240,17 @@ describe RipperRubyParser::Parser do
|
|
213
240
|
it 'works with unicode escapes (unlike RubyParser)' do
|
214
241
|
'"foo\\u273bbar"'.must_be_parsed_as s(:str, 'foo✻bar')
|
215
242
|
end
|
243
|
+
|
244
|
+
it 'converts to unicode if possible' do
|
245
|
+
'"2\302\275"'.must_be_parsed_as s(:str, '2½')
|
246
|
+
end
|
247
|
+
|
248
|
+
it 'does not convert to unicode if result is not valid' do
|
249
|
+
parser = RipperRubyParser::Parser.new
|
250
|
+
result = parser.parse '"2\x82\302\275"'
|
251
|
+
expected = s(:str, "2\x82\xC2\xBD".force_encoding(Encoding::US_ASCII))
|
252
|
+
result.inspect.must_equal expected.inspect
|
253
|
+
end
|
216
254
|
end
|
217
255
|
|
218
256
|
describe 'with interpolations' do
|
@@ -332,6 +370,11 @@ describe RipperRubyParser::Parser do
|
|
332
370
|
"'foo\\\\\\abar'".
|
333
371
|
must_be_parsed_as s(:str, 'foo\\\\abar')
|
334
372
|
end
|
373
|
+
|
374
|
+
it 'does not process line continuation' do
|
375
|
+
"'foo\\\nbar'".
|
376
|
+
must_be_parsed_as s(:str, "foo\\\nbar")
|
377
|
+
end
|
335
378
|
end
|
336
379
|
|
337
380
|
describe 'with %Q-delimited strings' do
|
@@ -344,6 +387,28 @@ describe RipperRubyParser::Parser do
|
|
344
387
|
'%Q[foo\\nbar]'.
|
345
388
|
must_be_parsed_as s(:str, "foo\nbar")
|
346
389
|
end
|
390
|
+
|
391
|
+
it 'handles line continuation' do
|
392
|
+
"%Q[foo\\\nbar]".
|
393
|
+
must_be_parsed_as s(:str, 'foobar')
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
describe 'with %-delimited strings' do
|
398
|
+
it 'works for the simple case' do
|
399
|
+
'%(bar)'.
|
400
|
+
must_be_parsed_as s(:str, 'bar')
|
401
|
+
end
|
402
|
+
|
403
|
+
it 'works for escape sequences' do
|
404
|
+
'%(foo\nbar)'.
|
405
|
+
must_be_parsed_as s(:str, "foo\nbar")
|
406
|
+
end
|
407
|
+
|
408
|
+
it 'works for odd delimiters' do
|
409
|
+
'%!foo\nbar!'.
|
410
|
+
must_be_parsed_as s(:str, "foo\nbar")
|
411
|
+
end
|
347
412
|
end
|
348
413
|
|
349
414
|
describe 'with string concatenation' do
|
@@ -406,16 +471,45 @@ describe RipperRubyParser::Parser do
|
|
406
471
|
"<<FOO\nbar\\tbaz\nFOO".
|
407
472
|
must_be_parsed_as s(:str, "bar\tbaz\n")
|
408
473
|
end
|
474
|
+
|
475
|
+
it 'handles line continuation' do
|
476
|
+
"<<FOO\nbar\\\nbaz\nFOO".
|
477
|
+
must_be_parsed_as s(:str, "barbaz\n")
|
478
|
+
end
|
479
|
+
|
480
|
+
it 'escapes line continuation' do
|
481
|
+
"<<FOO\nbar\\\\\nbaz\nFOO".
|
482
|
+
must_be_parsed_as s(:str, "bar\\\nbaz\n")
|
483
|
+
end
|
484
|
+
|
485
|
+
it 'does not convert to unicode even if possible' do
|
486
|
+
parser = RipperRubyParser::Parser.new
|
487
|
+
result = parser.parse "<<FOO\n2\\302\\275\nFOO"
|
488
|
+
expected = s(:str, "2\xC2\xBD\n".force_encoding(Encoding::US_ASCII))
|
489
|
+
result.inspect.must_equal expected.inspect
|
490
|
+
end
|
409
491
|
end
|
410
492
|
end
|
411
493
|
|
412
|
-
describe 'for word list literals' do
|
413
|
-
it 'works for the simple case
|
494
|
+
describe 'for word list literals with %w delimiter' do
|
495
|
+
it 'works for the simple case' do
|
414
496
|
'%w(foo bar)'.
|
415
497
|
must_be_parsed_as s(:array, s(:str, 'foo'), s(:str, 'bar'))
|
416
498
|
end
|
417
499
|
|
418
|
-
it '
|
500
|
+
it 'does not perform interpolation' do
|
501
|
+
'%w(foo\\nbar baz)'.
|
502
|
+
must_be_parsed_as s(:array, s(:str, 'foo\\nbar'), s(:str, 'baz'))
|
503
|
+
end
|
504
|
+
|
505
|
+
it 'handles line continuation' do
|
506
|
+
"%w(foo\\\nbar baz)".
|
507
|
+
must_be_parsed_as s(:array, s(:str, "foo\nbar"), s(:str, 'baz'))
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
describe 'for word list literals with %W delimiter' do
|
512
|
+
it 'works for the simple case' do
|
419
513
|
'%W(foo bar)'.
|
420
514
|
must_be_parsed_as s(:array, s(:str, 'foo'), s(:str, 'bar'))
|
421
515
|
end
|
@@ -452,6 +546,13 @@ describe RipperRubyParser::Parser do
|
|
452
546
|
s(:str, "foo\nbar"),
|
453
547
|
s(:str, 'baz'))
|
454
548
|
end
|
549
|
+
|
550
|
+
it 'correctly handles line continuation' do
|
551
|
+
"%W(foo\\\nbar baz)".
|
552
|
+
must_be_parsed_as s(:array,
|
553
|
+
s(:str, "foo\nbar"),
|
554
|
+
s(:str, 'baz'))
|
555
|
+
end
|
455
556
|
end
|
456
557
|
|
457
558
|
describe 'for symbol list literals with %i delimiter' do
|
@@ -459,6 +560,16 @@ describe RipperRubyParser::Parser do
|
|
459
560
|
'%i(foo bar)'.
|
460
561
|
must_be_parsed_as s(:array, s(:lit, :foo), s(:lit, :bar))
|
461
562
|
end
|
563
|
+
|
564
|
+
it 'does not perform interpolation' do
|
565
|
+
'%i(foo\\nbar baz)'.
|
566
|
+
must_be_parsed_as s(:array, s(:lit, :"foo\\nbar"), s(:lit, :baz))
|
567
|
+
end
|
568
|
+
|
569
|
+
it 'handles line continuation' do
|
570
|
+
"%i(foo\\\nbar baz)".
|
571
|
+
must_be_parsed_as s(:array, s(:lit, :"foo\nbar"), s(:lit, :baz))
|
572
|
+
end
|
462
573
|
end
|
463
574
|
|
464
575
|
describe 'for symbol list literals with %I delimiter' do
|
@@ -491,6 +602,13 @@ describe RipperRubyParser::Parser do
|
|
491
602
|
s(:evstr, s(:call, nil, :bar)),
|
492
603
|
s(:str, 'baz')))
|
493
604
|
end
|
605
|
+
|
606
|
+
it 'correctly handles line continuation' do
|
607
|
+
"%I(foo\\\nbar baz)".
|
608
|
+
must_be_parsed_as s(:array,
|
609
|
+
s(:lit, :"foo\nbar"),
|
610
|
+
s(:lit, :baz))
|
611
|
+
end
|
494
612
|
end
|
495
613
|
|
496
614
|
describe 'for character literals' do
|