ripper_ruby_parser 1.3.0 → 1.4.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
- data/CHANGELOG.md +6 -1
- data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +74 -4
- data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +2 -2
- data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +25 -78
- data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +5 -5
- data/lib/ripper_ruby_parser/sexp_processor.rb +2 -1
- data/lib/ripper_ruby_parser/unescape.rb +68 -0
- data/lib/ripper_ruby_parser/version.rb +1 -1
- data/test/end_to_end/comparison_test.rb +60 -32
- data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +16 -0
- data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +85 -3
- metadata +4 -5
- data/test/samples/misc.rb +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4a4cdc97eb0ffc630d78101fbd5ec056919c03bd91571a27d5972f6b67794dbf
|
4
|
+
data.tar.gz: 192aa89ab393bfaa24690b4db77368cd608dd44de41575e2223d8936628f95c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c44761bbf0e73e5c37a14ed1744639938d1e0e50f100735937f6727677224ef3f065a81a711246375a31df55394e7f2e0dd7a996a474a8c24dc3e01319b05f1
|
7
|
+
data.tar.gz: 6fed83fa681eb454030522d362bc7d0b5904d061331b659f695f5b668cb5124f94ad5aafe1dfa7ee21387cf5d292e72403aab27aa9daa5d99b7003026e712896
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'ripper'
|
2
2
|
require 'ripper_ruby_parser/syntax_error'
|
3
|
+
require 'ripper_ruby_parser/unescape'
|
3
4
|
|
4
5
|
module RipperRubyParser
|
5
6
|
# Variant of Ripper's SexpBuilder parser class that inserts comments as
|
@@ -11,6 +12,7 @@ module RipperRubyParser
|
|
11
12
|
super
|
12
13
|
@comment = nil
|
13
14
|
@comment_stack = []
|
15
|
+
@delimiter_stack = []
|
14
16
|
@in_symbol = false
|
15
17
|
end
|
16
18
|
|
@@ -21,6 +23,11 @@ module RipperRubyParser
|
|
21
23
|
Sexp.from_array(result)
|
22
24
|
end
|
23
25
|
|
26
|
+
def on_backtick(delimiter)
|
27
|
+
@delimiter_stack.push delimiter
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
24
31
|
def on_comment(tok)
|
25
32
|
@comment ||= ''
|
26
33
|
@comment += tok
|
@@ -66,6 +73,16 @@ module RipperRubyParser
|
|
66
73
|
list << elem
|
67
74
|
end
|
68
75
|
|
76
|
+
def on_heredoc_beg(delimiter)
|
77
|
+
@delimiter_stack.push delimiter
|
78
|
+
super
|
79
|
+
end
|
80
|
+
|
81
|
+
def on_heredoc_end(delimiter)
|
82
|
+
@delimiter_stack.pop
|
83
|
+
super
|
84
|
+
end
|
85
|
+
|
69
86
|
def on_mlhs_new
|
70
87
|
[:mlhs]
|
71
88
|
end
|
@@ -86,6 +103,11 @@ module RipperRubyParser
|
|
86
103
|
list << elem
|
87
104
|
end
|
88
105
|
|
106
|
+
def on_qsymbols_beg(delimiter)
|
107
|
+
@delimiter_stack.push delimiter
|
108
|
+
super
|
109
|
+
end
|
110
|
+
|
89
111
|
def on_qsymbols_new
|
90
112
|
[:qsymbols]
|
91
113
|
end
|
@@ -94,6 +116,11 @@ module RipperRubyParser
|
|
94
116
|
list << elem
|
95
117
|
end
|
96
118
|
|
119
|
+
def on_qwords_beg(delimiter)
|
120
|
+
@delimiter_stack.push delimiter
|
121
|
+
super
|
122
|
+
end
|
123
|
+
|
97
124
|
def on_qwords_new
|
98
125
|
[:qwords]
|
99
126
|
end
|
@@ -102,6 +129,16 @@ module RipperRubyParser
|
|
102
129
|
list << elem
|
103
130
|
end
|
104
131
|
|
132
|
+
def on_regexp_beg(delimiter)
|
133
|
+
@delimiter_stack.push delimiter
|
134
|
+
super
|
135
|
+
end
|
136
|
+
|
137
|
+
def on_regexp_end(delimiter)
|
138
|
+
@delimiter_stack.pop
|
139
|
+
super
|
140
|
+
end
|
141
|
+
|
105
142
|
def on_regexp_new
|
106
143
|
[:regexp]
|
107
144
|
end
|
@@ -122,6 +159,11 @@ module RipperRubyParser
|
|
122
159
|
list << elem
|
123
160
|
end
|
124
161
|
|
162
|
+
def on_symbols_beg(delimiter)
|
163
|
+
@delimiter_stack.push delimiter
|
164
|
+
super
|
165
|
+
end
|
166
|
+
|
125
167
|
def on_symbols_new
|
126
168
|
[:symbols]
|
127
169
|
end
|
@@ -130,6 +172,28 @@ module RipperRubyParser
|
|
130
172
|
list << elem
|
131
173
|
end
|
132
174
|
|
175
|
+
def on_tstring_beg(delimiter)
|
176
|
+
@delimiter_stack.push delimiter
|
177
|
+
super
|
178
|
+
end
|
179
|
+
|
180
|
+
def on_tstring_content(content)
|
181
|
+
content = case @delimiter_stack.last
|
182
|
+
when '"', '`', ':"', /^<</, /^%I/, /^%Q/, /^%W/
|
183
|
+
Unescape.unescape(content)
|
184
|
+
when "'", ":'"
|
185
|
+
Unescape.simple_unescape(content)
|
186
|
+
else
|
187
|
+
content
|
188
|
+
end
|
189
|
+
super(content)
|
190
|
+
end
|
191
|
+
|
192
|
+
def on_tstring_end(delimiter)
|
193
|
+
@delimiter_stack.pop
|
194
|
+
super
|
195
|
+
end
|
196
|
+
|
133
197
|
def on_word_new
|
134
198
|
[:word]
|
135
199
|
end
|
@@ -138,6 +202,11 @@ module RipperRubyParser
|
|
138
202
|
list << elem
|
139
203
|
end
|
140
204
|
|
205
|
+
def on_words_beg(delimiter)
|
206
|
+
@delimiter_stack.push delimiter
|
207
|
+
super
|
208
|
+
end
|
209
|
+
|
141
210
|
def on_words_new
|
142
211
|
[:words]
|
143
212
|
end
|
@@ -176,8 +245,8 @@ module RipperRubyParser
|
|
176
245
|
|
177
246
|
NUMBER_LITERAL_TYPES = [:@int, :@float].freeze
|
178
247
|
|
179
|
-
def on_unary(
|
180
|
-
if !@space_before &&
|
248
|
+
def on_unary(operator, value)
|
249
|
+
if !@space_before && operator == :-@ && NUMBER_LITERAL_TYPES.include?(value.first)
|
181
250
|
type, literal, lines = value
|
182
251
|
if literal[0] == '-'
|
183
252
|
super
|
@@ -189,7 +258,8 @@ module RipperRubyParser
|
|
189
258
|
end
|
190
259
|
end
|
191
260
|
|
192
|
-
def on_symbeg(
|
261
|
+
def on_symbeg(delimiter)
|
262
|
+
@delimiter_stack.push delimiter
|
193
263
|
@in_symbol = true
|
194
264
|
super
|
195
265
|
end
|
@@ -199,7 +269,7 @@ module RipperRubyParser
|
|
199
269
|
super
|
200
270
|
end
|
201
271
|
|
202
|
-
def on_embexpr_beg(
|
272
|
+
def on_embexpr_beg(_delimiter)
|
203
273
|
@in_symbol = false
|
204
274
|
super
|
205
275
|
end
|
@@ -23,7 +23,7 @@ module RipperRubyParser
|
|
23
23
|
_, cond, truepart = exp.shift 3
|
24
24
|
|
25
25
|
construct_conditional(handle_condition(cond),
|
26
|
-
|
26
|
+
handle_operator_argument(truepart),
|
27
27
|
nil)
|
28
28
|
end
|
29
29
|
|
@@ -40,7 +40,7 @@ module RipperRubyParser
|
|
40
40
|
|
41
41
|
construct_conditional(handle_condition(cond),
|
42
42
|
nil,
|
43
|
-
|
43
|
+
handle_operator_argument(truepart))
|
44
44
|
end
|
45
45
|
|
46
46
|
def process_case(exp)
|
@@ -8,7 +8,8 @@ module RipperRubyParser
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def process_string_content(exp)
|
11
|
-
|
11
|
+
_, *rest = shift_all exp
|
12
|
+
string, rest = extract_string_parts(rest)
|
12
13
|
|
13
14
|
if rest.empty?
|
14
15
|
s(:str, string)
|
@@ -55,7 +56,12 @@ module RipperRubyParser
|
|
55
56
|
|
56
57
|
def process_xstring_literal(exp)
|
57
58
|
_, content = exp.shift 2
|
58
|
-
|
59
|
+
process(content)
|
60
|
+
end
|
61
|
+
|
62
|
+
def process_xstring(exp)
|
63
|
+
_, *rest = shift_all exp
|
64
|
+
string, rest = extract_string_parts(rest)
|
59
65
|
if rest.empty?
|
60
66
|
s(:xstr, string)
|
61
67
|
else
|
@@ -66,7 +72,7 @@ module RipperRubyParser
|
|
66
72
|
def process_regexp_literal(exp)
|
67
73
|
_, content, (_, flags,) = exp.shift 3
|
68
74
|
|
69
|
-
string, rest =
|
75
|
+
string, rest = process(content).sexp_body
|
70
76
|
numflags = character_flags_to_numerical flags
|
71
77
|
|
72
78
|
if rest.empty?
|
@@ -82,6 +88,12 @@ module RipperRubyParser
|
|
82
88
|
end
|
83
89
|
end
|
84
90
|
|
91
|
+
def process_regexp(exp)
|
92
|
+
_, *rest = shift_all exp
|
93
|
+
string, rest = extract_string_parts(rest)
|
94
|
+
s(:regexp, string, rest)
|
95
|
+
end
|
96
|
+
|
85
97
|
def process_symbol_literal(exp)
|
86
98
|
_, symbol = exp.shift 2
|
87
99
|
process(symbol)
|
@@ -116,8 +128,8 @@ module RipperRubyParser
|
|
116
128
|
|
117
129
|
private
|
118
130
|
|
119
|
-
def extract_string_parts(
|
120
|
-
parts =
|
131
|
+
def extract_string_parts(list)
|
132
|
+
parts = map_process_list list
|
121
133
|
|
122
134
|
string = ''
|
123
135
|
while !parts.empty? && parts.first.sexp_type == :str
|
@@ -130,74 +142,6 @@ module RipperRubyParser
|
|
130
142
|
return string, rest
|
131
143
|
end
|
132
144
|
|
133
|
-
def internal_process_string_parts(exp)
|
134
|
-
_, *rest = shift_all exp
|
135
|
-
map_process_list rest
|
136
|
-
end
|
137
|
-
|
138
|
-
def extract_unescaped_string_parts(exp)
|
139
|
-
string, rest = extract_string_parts exp
|
140
|
-
|
141
|
-
string = unescape(string)
|
142
|
-
|
143
|
-
rest.each do |sub_exp|
|
144
|
-
sub_exp[1] = unescape(sub_exp[1]) if sub_exp.sexp_type == :str
|
145
|
-
end
|
146
|
-
|
147
|
-
return string, rest
|
148
|
-
end
|
149
|
-
|
150
|
-
SINGLE_LETTER_ESCAPES = {
|
151
|
-
'a' => "\a",
|
152
|
-
'b' => "\b",
|
153
|
-
'e' => "\e",
|
154
|
-
'f' => "\f",
|
155
|
-
'n' => "\n",
|
156
|
-
'r' => "\r",
|
157
|
-
's' => "\s",
|
158
|
-
't' => "\t",
|
159
|
-
'v' => "\v"
|
160
|
-
}.freeze
|
161
|
-
|
162
|
-
SINGLE_LETTER_ESCAPES_REGEXP =
|
163
|
-
Regexp.new("^[#{SINGLE_LETTER_ESCAPES.keys.join}]$")
|
164
|
-
|
165
|
-
def unescape(string)
|
166
|
-
string.gsub(/\\(
|
167
|
-
[0-7]{1,3} | # octal character
|
168
|
-
x[0-9a-fA-F]{1,2} | # hex byte
|
169
|
-
u[0-9a-fA-F]{4} | # unicode character
|
170
|
-
M-\\C-. | # meta-ctrl
|
171
|
-
C-\\M-. | # ctrl-meta
|
172
|
-
M-\\c. | # meta-ctrl (shorthand)
|
173
|
-
c\\M-. | # ctrl-meta (shorthand)
|
174
|
-
C-. | # control (regular)
|
175
|
-
c. | # control (shorthand)
|
176
|
-
M-. | # meta
|
177
|
-
. # single-character
|
178
|
-
)/x) do
|
179
|
-
bare = Regexp.last_match[1]
|
180
|
-
case bare
|
181
|
-
when SINGLE_LETTER_ESCAPES_REGEXP
|
182
|
-
SINGLE_LETTER_ESCAPES[bare]
|
183
|
-
when /^x/
|
184
|
-
bare[1..-1].to_i(16).chr
|
185
|
-
when /^u/
|
186
|
-
bare[1..-1].to_i(16).chr(Encoding::UTF_8)
|
187
|
-
when /^(c|C-).$/
|
188
|
-
(bare[-1].ord & 0b1001_1111).chr
|
189
|
-
when /^M-.$/
|
190
|
-
(bare[-1].ord | 0b1000_0000).chr
|
191
|
-
when /^(M-\\C-|C-\\M-|M-\\c|c\\M-).$/
|
192
|
-
(bare[-1].ord & 0b1001_1111 | 0b1000_0000).chr
|
193
|
-
when /^[0-7]+/
|
194
|
-
bare.to_i(8).chr
|
195
|
-
else
|
196
|
-
bare
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
145
|
def character_flags_to_numerical(flags)
|
202
146
|
numflags = 0
|
203
147
|
|
@@ -211,12 +155,15 @@ module RipperRubyParser
|
|
211
155
|
numflags
|
212
156
|
end
|
213
157
|
|
214
|
-
def handle_dyna_symbol_content(
|
215
|
-
|
216
|
-
|
217
|
-
|
158
|
+
def handle_dyna_symbol_content(node)
|
159
|
+
type, *body = *process(node)
|
160
|
+
case type
|
161
|
+
when :str, :xstr
|
162
|
+
s(:lit, body.first.to_sym)
|
163
|
+
when :dstr, :dxstr
|
164
|
+
s(:dsym, *body)
|
218
165
|
else
|
219
|
-
|
166
|
+
raise type.to_s
|
220
167
|
end
|
221
168
|
end
|
222
169
|
|
@@ -74,18 +74,18 @@ module RipperRubyParser
|
|
74
74
|
|
75
75
|
private
|
76
76
|
|
77
|
-
def make_boolean_operator(
|
78
|
-
_, left, _, right = rebalance_binary(s(:binary, left,
|
79
|
-
s(
|
77
|
+
def make_boolean_operator(operator, left, right)
|
78
|
+
_, left, _, right = rebalance_binary(s(:binary, left, operator, right))
|
79
|
+
s(operator, process(left), handle_operator_argument(right))
|
80
80
|
end
|
81
81
|
|
82
|
-
def make_regexp_match_operator(
|
82
|
+
def make_regexp_match_operator(operator, left, right)
|
83
83
|
if left.sexp_type == :regexp_literal
|
84
84
|
s(:match2, process(left), process(right))
|
85
85
|
elsif right.sexp_type == :regexp_literal
|
86
86
|
s(:match3, process(right), process(left))
|
87
87
|
else
|
88
|
-
s(:call, process(left),
|
88
|
+
s(:call, process(left), operator, process(right))
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'sexp_processor'
|
2
2
|
require 'ripper_ruby_parser/sexp_handlers'
|
3
|
+
require 'ripper_ruby_parser/unescape'
|
3
4
|
|
4
5
|
module RipperRubyParser
|
5
6
|
# Processes the sexp created by Ripper to what RubyParser would produce.
|
@@ -160,7 +161,7 @@ module RipperRubyParser
|
|
160
161
|
# character literals
|
161
162
|
def process_at_CHAR(exp)
|
162
163
|
_, val, pos = exp.shift 3
|
163
|
-
with_position(pos, s(:str, unescape(val[1..-1])))
|
164
|
+
with_position(pos, s(:str, Unescape.unescape(val[1..-1])))
|
164
165
|
end
|
165
166
|
|
166
167
|
def process_at_label(exp)
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module RipperRubyParser
|
2
|
+
# Implements string unescaping
|
3
|
+
#
|
4
|
+
# @api private
|
5
|
+
module Unescape
|
6
|
+
module_function
|
7
|
+
|
8
|
+
SINGLE_LETTER_ESCAPES = {
|
9
|
+
'a' => "\a",
|
10
|
+
'b' => "\b",
|
11
|
+
'e' => "\e",
|
12
|
+
'f' => "\f",
|
13
|
+
'n' => "\n",
|
14
|
+
'r' => "\r",
|
15
|
+
's' => "\s",
|
16
|
+
't' => "\t",
|
17
|
+
'v' => "\v"
|
18
|
+
}.freeze
|
19
|
+
|
20
|
+
SINGLE_LETTER_ESCAPES_REGEXP =
|
21
|
+
Regexp.new("^[#{SINGLE_LETTER_ESCAPES.keys.join}]$")
|
22
|
+
|
23
|
+
def simple_unescape(string)
|
24
|
+
string.gsub(/\\(
|
25
|
+
' | # single quote
|
26
|
+
\\ # backslash
|
27
|
+
)/x) do
|
28
|
+
Regexp.last_match[1]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def unescape(string)
|
33
|
+
string.gsub(/\\(
|
34
|
+
[0-7]{1,3} | # octal character
|
35
|
+
x[0-9a-fA-F]{1,2} | # hex byte
|
36
|
+
u[0-9a-fA-F]{4} | # unicode character
|
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
|
45
|
+
)/x) do
|
46
|
+
bare = Regexp.last_match[1]
|
47
|
+
case bare
|
48
|
+
when SINGLE_LETTER_ESCAPES_REGEXP
|
49
|
+
SINGLE_LETTER_ESCAPES[bare]
|
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
|
62
|
+
else
|
63
|
+
bare
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -2,24 +2,13 @@ require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
|
|
2
2
|
require 'ruby_parser'
|
3
3
|
|
4
4
|
describe 'Using RipperRubyParser and RubyParser' do
|
5
|
-
let :newparser do
|
6
|
-
RipperRubyParser::Parser.new
|
7
|
-
end
|
8
|
-
|
9
|
-
let :oldparser do
|
10
|
-
RubyParser.new
|
11
|
-
end
|
12
|
-
|
13
5
|
describe 'for a simple well known program' do
|
14
6
|
let :program do
|
15
7
|
"puts 'Hello World'"
|
16
8
|
end
|
17
9
|
|
18
10
|
it 'gives the same result' do
|
19
|
-
|
20
|
-
imitation = newparser.parse program
|
21
|
-
|
22
|
-
imitation.must_equal original
|
11
|
+
program.must_be_parsed_as_before
|
23
12
|
end
|
24
13
|
end
|
25
14
|
|
@@ -45,10 +34,7 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
45
34
|
end
|
46
35
|
|
47
36
|
it 'gives the same result' do
|
48
|
-
|
49
|
-
imitation = newparser.parse program
|
50
|
-
|
51
|
-
imitation.must_equal original
|
37
|
+
program.must_be_parsed_as_before
|
52
38
|
end
|
53
39
|
end
|
54
40
|
|
@@ -58,10 +44,7 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
58
44
|
end
|
59
45
|
|
60
46
|
it 'gives the same result' do
|
61
|
-
|
62
|
-
imitation = newparser.parse program
|
63
|
-
|
64
|
-
imitation.must_equal original
|
47
|
+
program.must_be_parsed_as_before
|
65
48
|
end
|
66
49
|
end
|
67
50
|
|
@@ -79,10 +62,7 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
79
62
|
end
|
80
63
|
|
81
64
|
it 'gives the same result' do
|
82
|
-
|
83
|
-
imitation = newparser.parse program
|
84
|
-
|
85
|
-
formatted(imitation).must_equal formatted(original)
|
65
|
+
program.must_be_parsed_as_before
|
86
66
|
end
|
87
67
|
end
|
88
68
|
|
@@ -106,10 +86,7 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
106
86
|
end
|
107
87
|
|
108
88
|
it 'gives the same result' do
|
109
|
-
|
110
|
-
imitation = newparser.parse program
|
111
|
-
|
112
|
-
formatted(imitation).must_equal formatted(original)
|
89
|
+
program.must_be_parsed_as_before
|
113
90
|
end
|
114
91
|
end
|
115
92
|
|
@@ -119,10 +96,7 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
119
96
|
end
|
120
97
|
|
121
98
|
it 'gives the same result' do
|
122
|
-
|
123
|
-
imitation = newparser.parse program
|
124
|
-
|
125
|
-
formatted(imitation).must_equal formatted(original)
|
99
|
+
program.must_be_parsed_as_before
|
126
100
|
end
|
127
101
|
end
|
128
102
|
|
@@ -145,4 +119,58 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
145
119
|
program.must_be_parsed_as_before
|
146
120
|
end
|
147
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
|
148
176
|
end
|
@@ -201,6 +201,22 @@ describe RipperRubyParser::Parser do
|
|
201
201
|
s(:call, nil, :bar),
|
202
202
|
s(:begin, s(:call, nil, :baz)))
|
203
203
|
end
|
204
|
+
|
205
|
+
it 'keeps :begin for the truepart of a postfix if' do
|
206
|
+
'begin; foo; end if bar'.
|
207
|
+
must_be_parsed_as s(:if,
|
208
|
+
s(:call, nil, :bar),
|
209
|
+
s(:begin, s(:call, nil, :foo)),
|
210
|
+
nil)
|
211
|
+
end
|
212
|
+
|
213
|
+
it 'keeps :begin for the falsepart of a postfix unless' do
|
214
|
+
'begin; foo; end unless bar'.
|
215
|
+
must_be_parsed_as s(:if,
|
216
|
+
s(:call, nil, :bar),
|
217
|
+
nil,
|
218
|
+
s(:begin, s(:call, nil, :foo)))
|
219
|
+
end
|
204
220
|
end
|
205
221
|
|
206
222
|
describe 'for rescue/else' do
|
@@ -302,6 +302,40 @@ describe RipperRubyParser::Parser do
|
|
302
302
|
end
|
303
303
|
end
|
304
304
|
|
305
|
+
describe 'with single quoted strings' do
|
306
|
+
it 'works with escaped single quotes' do
|
307
|
+
"'foo\\'bar'".
|
308
|
+
must_be_parsed_as s(:str, "foo'bar")
|
309
|
+
end
|
310
|
+
|
311
|
+
it 'works with embedded backslashes' do
|
312
|
+
"'foo\\abar'".
|
313
|
+
must_be_parsed_as s(:str, 'foo\abar')
|
314
|
+
end
|
315
|
+
|
316
|
+
it 'works with escaped embedded backslashes' do
|
317
|
+
"'foo\\\\abar'".
|
318
|
+
must_be_parsed_as s(:str, 'foo\abar')
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'works with sequences of backslashes' do
|
322
|
+
"'foo\\\\\\abar'".
|
323
|
+
must_be_parsed_as s(:str, 'foo\\\\abar')
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
describe 'with %Q-delimited strings' do
|
328
|
+
it 'works for the simple case' do
|
329
|
+
'%Q[bar]'.
|
330
|
+
must_be_parsed_as s(:str, 'bar')
|
331
|
+
end
|
332
|
+
|
333
|
+
it 'works for escape sequences' do
|
334
|
+
'%Q[foo\\nbar]'.
|
335
|
+
must_be_parsed_as s(:str, "foo\nbar")
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
305
339
|
describe 'with string concatenation' do
|
306
340
|
it 'performs the concatenation in the case of two simple literal strings' do
|
307
341
|
'"foo" "bar"'.must_be_parsed_as s(:str, 'foobar')
|
@@ -351,6 +385,18 @@ describe RipperRubyParser::Parser do
|
|
351
385
|
end
|
352
386
|
end
|
353
387
|
end
|
388
|
+
|
389
|
+
describe 'for heredocs' do
|
390
|
+
it 'works for the simple case' do
|
391
|
+
"<<FOO\nbar\nFOO".
|
392
|
+
must_be_parsed_as s(:str, "bar\n")
|
393
|
+
end
|
394
|
+
|
395
|
+
it 'works for escape sequences' do
|
396
|
+
"<<FOO\nbar\\tbaz\nFOO".
|
397
|
+
must_be_parsed_as s(:str, "bar\tbaz\n")
|
398
|
+
end
|
399
|
+
end
|
354
400
|
end
|
355
401
|
|
356
402
|
describe 'for word list literals' do
|
@@ -389,19 +435,35 @@ describe RipperRubyParser::Parser do
|
|
389
435
|
s(:evstr, s(:call, nil, :bar)),
|
390
436
|
s(:str, 'baz')))
|
391
437
|
end
|
438
|
+
|
439
|
+
it 'correctly handles escape sequences' do
|
440
|
+
'%W(foo\nbar baz)'.
|
441
|
+
must_be_parsed_as s(:array,
|
442
|
+
s(:str, "foo\nbar"),
|
443
|
+
s(:str, 'baz'))
|
444
|
+
end
|
392
445
|
end
|
393
446
|
|
394
|
-
describe 'for symbol list literals' do
|
395
|
-
it 'works for
|
447
|
+
describe 'for symbol list literals with %i delimiter' do
|
448
|
+
it 'works for the simple case' do
|
396
449
|
'%i(foo bar)'.
|
397
450
|
must_be_parsed_as s(:array, s(:lit, :foo), s(:lit, :bar))
|
398
451
|
end
|
452
|
+
end
|
399
453
|
|
400
|
-
|
454
|
+
describe 'for symbol list literals with %I delimiter' do
|
455
|
+
it 'works for the simple case' do
|
401
456
|
'%I(foo bar)'.
|
402
457
|
must_be_parsed_as s(:array, s(:lit, :foo), s(:lit, :bar))
|
403
458
|
end
|
404
459
|
|
460
|
+
it 'correctly handles escape sequences' do
|
461
|
+
'%I(foo\nbar baz)'.
|
462
|
+
must_be_parsed_as s(:array,
|
463
|
+
s(:lit, :"foo\nbar"),
|
464
|
+
s(:lit, :baz))
|
465
|
+
end
|
466
|
+
|
405
467
|
it 'correctly handles interpolation' do
|
406
468
|
"%I(foo \#{bar} baz)".
|
407
469
|
must_be_parsed_as s(:array,
|
@@ -485,6 +547,26 @@ describe RipperRubyParser::Parser do
|
|
485
547
|
'foo',
|
486
548
|
s(:evstr, s(:call, nil, :bar)))
|
487
549
|
end
|
550
|
+
|
551
|
+
it 'works for dsyms with escape sequences' do
|
552
|
+
':"foo\nbar"'.
|
553
|
+
must_be_parsed_as s(:lit, :"foo\nbar")
|
554
|
+
end
|
555
|
+
|
556
|
+
it 'works with single quoted dsyms' do
|
557
|
+
":'foo'".
|
558
|
+
must_be_parsed_as s(:lit, :foo)
|
559
|
+
end
|
560
|
+
|
561
|
+
it 'works with single quoted dsyms with escaped single quotes' do
|
562
|
+
":'foo\\'bar'".
|
563
|
+
must_be_parsed_as s(:lit, :'foo\'bar')
|
564
|
+
end
|
565
|
+
|
566
|
+
it 'works with single quoted dsyms with embedded backslashes' do
|
567
|
+
":'foo\\abar'".
|
568
|
+
must_be_parsed_as s(:lit, :"foo\\abar")
|
569
|
+
end
|
488
570
|
end
|
489
571
|
|
490
572
|
describe 'for backtick string literals' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ripper_ruby_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matijs van Zuijlen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sexp_processor
|
@@ -111,6 +111,7 @@ files:
|
|
111
111
|
- lib/ripper_ruby_parser/sexp_handlers/operators.rb
|
112
112
|
- lib/ripper_ruby_parser/sexp_processor.rb
|
113
113
|
- lib/ripper_ruby_parser/syntax_error.rb
|
114
|
+
- lib/ripper_ruby_parser/unescape.rb
|
114
115
|
- lib/ripper_ruby_parser/version.rb
|
115
116
|
- test/end_to_end/comments_test.rb
|
116
117
|
- test/end_to_end/comparison_test.rb
|
@@ -131,7 +132,6 @@ files:
|
|
131
132
|
- test/ripper_ruby_parser/sexp_processor_test.rb
|
132
133
|
- test/ripper_ruby_parser/version_test.rb
|
133
134
|
- test/samples/inline.rb
|
134
|
-
- test/samples/misc.rb
|
135
135
|
- test/test_helper.rb
|
136
136
|
homepage: http://www.github.com/mvz/ripper_ruby_parser
|
137
137
|
licenses:
|
@@ -155,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
155
|
version: '0'
|
156
156
|
requirements: []
|
157
157
|
rubyforge_project:
|
158
|
-
rubygems_version: 2.7.
|
158
|
+
rubygems_version: 2.7.6
|
159
159
|
signing_key:
|
160
160
|
specification_version: 4
|
161
161
|
summary: Parse with Ripper, produce sexps that are compatible with RubyParser.
|
@@ -179,5 +179,4 @@ test_files:
|
|
179
179
|
- test/ripper_ruby_parser/sexp_processor_test.rb
|
180
180
|
- test/ripper_ruby_parser/version_test.rb
|
181
181
|
- test/samples/inline.rb
|
182
|
-
- test/samples/misc.rb
|
183
182
|
- test/test_helper.rb
|
data/test/samples/misc.rb
DELETED