ripper_ruby_parser 1.4.2 → 1.5.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 +33 -1
- data/README.md +41 -9
- data/Rakefile +2 -0
- data/lib/ripper_ruby_parser.rb +2 -0
- data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +23 -45
- data/lib/ripper_ruby_parser/parser.rb +11 -1
- data/lib/ripper_ruby_parser/sexp_handlers.rb +2 -6
- data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +49 -35
- data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +78 -39
- data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +16 -15
- data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +19 -15
- data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +138 -30
- data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +10 -6
- data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +59 -14
- data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +56 -32
- data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +20 -27
- data/lib/ripper_ruby_parser/sexp_processor.rb +40 -10
- data/lib/ripper_ruby_parser/syntax_error.rb +2 -0
- data/lib/ripper_ruby_parser/unescape.rb +32 -11
- data/lib/ripper_ruby_parser/version.rb +3 -1
- data/test/end_to_end/comments_test.rb +2 -0
- data/test/end_to_end/comparison_test.rb +2 -0
- data/test/end_to_end/lib_comparison_test.rb +2 -0
- data/test/end_to_end/line_numbering_test.rb +2 -0
- data/test/end_to_end/samples_comparison_test.rb +5 -29
- data/test/end_to_end/test_comparison_test.rb +2 -0
- data/test/pt_testcase/pt_test.rb +2 -0
- data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +16 -2
- data/test/ripper_ruby_parser/parser_test.rb +17 -688
- data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +459 -26
- data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +152 -82
- data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +91 -0
- data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +331 -24
- data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +88 -0
- data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +58 -5
- data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +392 -0
- data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +174 -12
- data/test/ripper_ruby_parser/sexp_processor_test.rb +8 -18
- data/test/ripper_ruby_parser/version_test.rb +2 -0
- data/test/samples/comments.rb +13 -0
- data/test/samples/conditionals.rb +23 -0
- data/test/samples/loops.rb +36 -0
- data/test/samples/misc.rb +157 -5
- data/test/samples/number.rb +7 -0
- data/test/samples/strings.rb +39 -0
- data/test/test_helper.rb +22 -1
- metadata +18 -12
- data/lib/ripper_ruby_parser/sexp_handlers/arguments.rb +0 -29
- data/lib/ripper_ruby_parser/sexp_handlers/arrays.rb +0 -21
- data/lib/ripper_ruby_parser/sexp_handlers/hashes.rb +0 -48
@@ -1,29 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RipperRubyParser
|
2
4
|
module SexpHandlers
|
3
5
|
# Sexp handlers for blocks and related constructs
|
4
6
|
module Blocks
|
5
7
|
def process_method_add_block(exp)
|
6
8
|
_, call, block = exp.shift 3
|
7
|
-
block = process(block)
|
8
9
|
_, args, stmt = block
|
9
10
|
call = process(call)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
def process_brace_block(exp)
|
15
|
-
handle_generic_block exp
|
16
|
-
end
|
17
|
-
|
18
|
-
def process_do_block(exp)
|
19
|
-
handle_generic_block exp
|
11
|
+
args = process(args)
|
12
|
+
kwrest = kwrest_param(args) if args
|
13
|
+
stmt = with_block_kwrest(kwrest) { process(stmt) }
|
14
|
+
make_iter call, args, safe_unwrap_void_stmt(stmt)
|
20
15
|
end
|
21
16
|
|
22
17
|
def process_params(exp)
|
23
18
|
_, normal, defaults, splat, rest, kwargs, doublesplat, block = exp.shift 8
|
24
19
|
|
25
|
-
args =
|
26
|
-
args += handle_normal_arguments normal
|
20
|
+
args = handle_normal_arguments normal
|
27
21
|
args += handle_default_arguments defaults
|
28
22
|
args += handle_splat splat
|
29
23
|
args += handle_normal_arguments rest
|
@@ -34,6 +28,11 @@ module RipperRubyParser
|
|
34
28
|
s(:args, *args)
|
35
29
|
end
|
36
30
|
|
31
|
+
def process_rest_param(exp)
|
32
|
+
_, ident = exp.shift 2
|
33
|
+
s(:splat, process(ident))
|
34
|
+
end
|
35
|
+
|
37
36
|
def process_kwrest_param(exp)
|
38
37
|
_, sym, = exp.shift 3
|
39
38
|
process(sym)
|
@@ -44,34 +43,41 @@ module RipperRubyParser
|
|
44
43
|
|
45
44
|
names = process(args)
|
46
45
|
|
47
|
-
|
46
|
+
convert_block_args names
|
48
47
|
end
|
49
48
|
|
50
49
|
def process_begin(exp)
|
51
50
|
_, body = exp.shift 2
|
52
51
|
|
53
|
-
body = process(body)
|
54
|
-
|
52
|
+
body = convert_empty_to_nil_symbol process(body)
|
53
|
+
s(:begin, body)
|
55
54
|
end
|
56
55
|
|
57
56
|
def process_rescue(exp)
|
58
57
|
_, eclass, evar, block, after = exp.shift 5
|
59
|
-
rescue_block =
|
58
|
+
rescue_block = map_process_list_compact block.sexp_body
|
60
59
|
rescue_block << nil if rescue_block.empty?
|
61
60
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
61
|
+
capture = if eclass
|
62
|
+
if eclass.first.is_a? Symbol
|
63
|
+
eclass = process(eclass)
|
64
|
+
body = eclass.sexp_body
|
65
|
+
if eclass.sexp_type == :mrhs
|
66
|
+
body.first
|
67
|
+
else
|
68
|
+
s(:array, *body)
|
69
|
+
end
|
70
|
+
else
|
71
|
+
s(:array, process(eclass.first))
|
72
|
+
end
|
73
|
+
else
|
74
|
+
s(:array)
|
75
|
+
end
|
76
|
+
|
77
|
+
capture << create_assignment_sub_type(process(evar), s(:gvar, :$!)) if evar
|
72
78
|
|
73
79
|
s(
|
74
|
-
s(:resbody,
|
80
|
+
s(:resbody, capture, *rescue_block),
|
75
81
|
*process(after))
|
76
82
|
end
|
77
83
|
|
@@ -80,7 +86,7 @@ module RipperRubyParser
|
|
80
86
|
|
81
87
|
body = s()
|
82
88
|
|
83
|
-
main = wrap_in_block
|
89
|
+
main = wrap_in_block map_process_list_compact main.sexp_body
|
84
90
|
body << main if main
|
85
91
|
|
86
92
|
if rescue_block
|
@@ -132,8 +138,8 @@ module RipperRubyParser
|
|
132
138
|
def process_lambda(exp)
|
133
139
|
_, args, statements = exp.shift 3
|
134
140
|
old_type = args.sexp_type
|
135
|
-
args =
|
136
|
-
args =
|
141
|
+
args = convert_method_args(process(args))
|
142
|
+
args = nil if args == s(:args) && old_type == :params
|
137
143
|
make_iter(s(:call, nil, :lambda),
|
138
144
|
args,
|
139
145
|
safe_unwrap_void_stmt(process(statements)))
|
@@ -141,20 +147,20 @@ module RipperRubyParser
|
|
141
147
|
|
142
148
|
private
|
143
149
|
|
144
|
-
def handle_generic_block(exp)
|
145
|
-
type, args, stmts = exp.shift 3
|
146
|
-
args = process(args)
|
147
|
-
s(type, args, s(unwrap_nil(process(stmts))))
|
148
|
-
end
|
149
|
-
|
150
150
|
def handle_normal_arguments(normal)
|
151
151
|
return [] unless normal
|
152
|
+
|
152
153
|
map_process_list normal
|
153
154
|
end
|
154
155
|
|
155
156
|
def handle_default_arguments(defaults)
|
156
157
|
return [] unless defaults
|
157
|
-
|
158
|
+
|
159
|
+
defaults.map do |sym, val|
|
160
|
+
s(:lasgn,
|
161
|
+
extract_node_symbol(process(sym)),
|
162
|
+
process(val))
|
163
|
+
end
|
158
164
|
end
|
159
165
|
|
160
166
|
def handle_splat(splat)
|
@@ -167,8 +173,9 @@ module RipperRubyParser
|
|
167
173
|
|
168
174
|
def handle_kwargs(kwargs)
|
169
175
|
return [] unless kwargs
|
176
|
+
|
170
177
|
kwargs.map do |sym, val|
|
171
|
-
symbol = process(sym)
|
178
|
+
symbol = extract_node_symbol process(sym)
|
172
179
|
if val
|
173
180
|
s(:kwarg, symbol, process(val))
|
174
181
|
else
|
@@ -179,11 +186,13 @@ module RipperRubyParser
|
|
179
186
|
|
180
187
|
def handle_double_splat(doublesplat)
|
181
188
|
return [] unless doublesplat
|
189
|
+
|
182
190
|
[s(:dsplat, process(doublesplat))]
|
183
191
|
end
|
184
192
|
|
185
193
|
def handle_block_argument(block)
|
186
194
|
return [] unless block
|
195
|
+
|
187
196
|
[process(block)]
|
188
197
|
end
|
189
198
|
|
@@ -197,6 +206,7 @@ module RipperRubyParser
|
|
197
206
|
end
|
198
207
|
|
199
208
|
def make_iter(call, args, stmt)
|
209
|
+
args.pop if args && args.last == s(:excessed_comma)
|
200
210
|
args ||= 0
|
201
211
|
if stmt.empty?
|
202
212
|
s(:iter, call, args)
|
@@ -215,6 +225,35 @@ module RipperRubyParser
|
|
215
225
|
s(:block, *statements)
|
216
226
|
end
|
217
227
|
end
|
228
|
+
|
229
|
+
def convert_block_args(args)
|
230
|
+
args.map! do |item|
|
231
|
+
if item.is_a? Symbol
|
232
|
+
item
|
233
|
+
else
|
234
|
+
case item.sexp_type
|
235
|
+
when :lvar
|
236
|
+
item.last
|
237
|
+
when :masgn
|
238
|
+
args = item[1]
|
239
|
+
args.shift
|
240
|
+
s(:masgn, *convert_block_args(args))
|
241
|
+
when :lasgn
|
242
|
+
if item.length == 2
|
243
|
+
item[1]
|
244
|
+
else
|
245
|
+
item
|
246
|
+
end
|
247
|
+
when *Methods::SPECIAL_ARG_MARKER.keys
|
248
|
+
marker = Methods::SPECIAL_ARG_MARKER[item.sexp_type]
|
249
|
+
name = extract_node_symbol item[1]
|
250
|
+
:"#{marker}#{name}"
|
251
|
+
else
|
252
|
+
item
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
218
257
|
end
|
219
258
|
end
|
220
259
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RipperRubyParser
|
2
4
|
module SexpHandlers
|
3
5
|
# Sexp handlers for conditionals
|
@@ -14,7 +16,7 @@ module RipperRubyParser
|
|
14
16
|
_, cond, truepart, falsepart = exp.shift 4
|
15
17
|
|
16
18
|
s(:if,
|
17
|
-
process(cond),
|
19
|
+
unwrap_begin(process(cond)),
|
18
20
|
handle_consequent(truepart),
|
19
21
|
handle_consequent(falsepart))
|
20
22
|
end
|
@@ -23,7 +25,7 @@ module RipperRubyParser
|
|
23
25
|
_, cond, truepart = exp.shift 3
|
24
26
|
|
25
27
|
construct_conditional(handle_condition(cond),
|
26
|
-
|
28
|
+
process(truepart),
|
27
29
|
nil)
|
28
30
|
end
|
29
31
|
|
@@ -40,7 +42,7 @@ module RipperRubyParser
|
|
40
42
|
|
41
43
|
construct_conditional(handle_condition(cond),
|
42
44
|
nil,
|
43
|
-
|
45
|
+
process(truepart))
|
44
46
|
end
|
45
47
|
|
46
48
|
def process_case(exp)
|
@@ -59,11 +61,10 @@ module RipperRubyParser
|
|
59
61
|
elsif falsepart.first.is_a? Symbol
|
60
62
|
falsepart = s(falsepart)
|
61
63
|
end
|
62
|
-
falsepart = [nil] if falsepart.empty?
|
63
64
|
|
64
|
-
values =
|
65
|
+
values = process(values).sexp_body
|
65
66
|
|
66
|
-
truepart =
|
67
|
+
truepart = map_process_list_compact truepart.sexp_body
|
67
68
|
truepart = [nil] if truepart.empty?
|
68
69
|
|
69
70
|
s(s(:when,
|
@@ -80,16 +81,16 @@ module RipperRubyParser
|
|
80
81
|
private
|
81
82
|
|
82
83
|
def handle_condition(cond)
|
83
|
-
cond = process(cond)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
cond
|
84
|
+
cond = unwrap_begin process(cond)
|
85
|
+
case cond.sexp_type
|
86
|
+
when :lit
|
87
|
+
return s(:match, cond) if cond.last.is_a?(Regexp)
|
88
|
+
when :dot2
|
89
|
+
return s(:flip2, *cond.sexp_body)
|
90
|
+
when :dot3
|
91
|
+
return s(:flip3, *cond.sexp_body)
|
92
92
|
end
|
93
|
+
cond
|
93
94
|
end
|
94
95
|
|
95
96
|
def handle_consequent(exp)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RipperRubyParser
|
2
4
|
module SexpHandlers
|
3
5
|
# Utility methods used in several of the sexp handler modules
|
@@ -9,7 +11,9 @@ module RipperRubyParser
|
|
9
11
|
|
10
12
|
def extract_node_symbol(exp)
|
11
13
|
return nil if exp.nil?
|
12
|
-
|
14
|
+
raise "Unexpected number of children: #{exp.length}" if exp.length != 2
|
15
|
+
|
16
|
+
_, ident = exp.shift 2
|
13
17
|
ident.to_sym
|
14
18
|
end
|
15
19
|
|
@@ -32,7 +36,7 @@ module RipperRubyParser
|
|
32
36
|
def generic_add_star(exp)
|
33
37
|
_, args, splatarg, *rest = shift_all exp
|
34
38
|
items = process args
|
35
|
-
items.push s(:splat, process(splatarg))
|
39
|
+
items.push s(:splat, unwrap_begin(process(splatarg)))
|
36
40
|
items.push(*map_process_list(rest))
|
37
41
|
end
|
38
42
|
|
@@ -44,18 +48,18 @@ module RipperRubyParser
|
|
44
48
|
body.reject { |sub_exp| sub_exp.sexp_type == :void_stmt }
|
45
49
|
end
|
46
50
|
|
47
|
-
def
|
48
|
-
reject_void_stmt
|
49
|
-
end
|
50
|
-
|
51
|
-
def map_process_sexp_body(list)
|
52
|
-
map_process_list(list.sexp_body)
|
51
|
+
def map_process_list_compact(list)
|
52
|
+
reject_void_stmt map_unwrap_begin_list map_process_list list
|
53
53
|
end
|
54
54
|
|
55
55
|
def map_process_list(list)
|
56
56
|
list.map { |exp| process(exp) }
|
57
57
|
end
|
58
58
|
|
59
|
+
def map_unwrap_begin_list(list)
|
60
|
+
list.map { |exp| unwrap_begin(exp) }
|
61
|
+
end
|
62
|
+
|
59
63
|
def unwrap_nil(exp)
|
60
64
|
if exp.sexp_type == :void_stmt
|
61
65
|
nil
|
@@ -68,12 +72,16 @@ module RipperRubyParser
|
|
68
72
|
unwrap_nil(exp) || s()
|
69
73
|
end
|
70
74
|
|
71
|
-
def
|
72
|
-
|
75
|
+
def unwrap_begin(exp)
|
76
|
+
if exp.sexp_type == :begin
|
77
|
+
exp[1]
|
78
|
+
else
|
79
|
+
exp
|
80
|
+
end
|
73
81
|
end
|
74
82
|
|
75
83
|
def handle_return_argument_list(arglist)
|
76
|
-
args =
|
84
|
+
args = process(arglist).sexp_body
|
77
85
|
|
78
86
|
case args.length
|
79
87
|
when 0
|
@@ -90,10 +98,6 @@ module RipperRubyParser
|
|
90
98
|
end
|
91
99
|
end
|
92
100
|
|
93
|
-
def handle_array_elements(elems)
|
94
|
-
process(elems).sexp_body
|
95
|
-
end
|
96
|
-
|
97
101
|
def shift_all(exp)
|
98
102
|
[].tap do |result|
|
99
103
|
result << exp.shift until exp.empty?
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RipperRubyParser
|
2
4
|
module SexpHandlers
|
3
|
-
# Sexp handlers for literals
|
5
|
+
# Sexp handlers for literals
|
4
6
|
module Literals
|
5
7
|
def process_string_literal(exp)
|
6
8
|
_, content = exp.shift 2
|
@@ -29,16 +31,16 @@ module RipperRubyParser
|
|
29
31
|
when :str
|
30
32
|
val
|
31
33
|
when :void_stmt
|
32
|
-
s(:dstr,
|
34
|
+
s(:dstr, s(:evstr))
|
33
35
|
else
|
34
|
-
s(:dstr,
|
36
|
+
s(:dstr, s(:evstr, val))
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
38
40
|
def process_string_dvar(exp)
|
39
41
|
_, list = exp.shift 2
|
40
42
|
val = process(list)
|
41
|
-
s(:dstr,
|
43
|
+
s(:dstr, s(:evstr, val))
|
42
44
|
end
|
43
45
|
|
44
46
|
def process_string_concat(exp)
|
@@ -72,31 +74,25 @@ module RipperRubyParser
|
|
72
74
|
def process_regexp_literal(exp)
|
73
75
|
_, content, (_, flags,) = exp.shift 3
|
74
76
|
|
75
|
-
|
77
|
+
content = process(content)
|
76
78
|
numflags = character_flags_to_numerical flags
|
77
79
|
|
78
|
-
if
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
:dregx_once
|
84
|
-
else
|
85
|
-
:dregx
|
86
|
-
end
|
87
|
-
s(sexp_type, string, *rest)
|
88
|
-
end
|
80
|
+
return s(:lit, Regexp.new(content.last, numflags)) if content.length == 2
|
81
|
+
|
82
|
+
content.sexp_type = :dregx_once if flags =~ /o/
|
83
|
+
content << numflags unless numflags == 0
|
84
|
+
content
|
89
85
|
end
|
90
86
|
|
91
87
|
def process_regexp(exp)
|
92
88
|
_, *rest = shift_all exp
|
93
89
|
string, rest = extract_string_parts(rest)
|
94
|
-
s(:
|
90
|
+
s(:dregx, string, *rest)
|
95
91
|
end
|
96
92
|
|
97
93
|
def process_symbol_literal(exp)
|
98
94
|
_, symbol = exp.shift 2
|
99
|
-
|
95
|
+
handle_symbol_content(symbol)
|
100
96
|
end
|
101
97
|
|
102
98
|
def process_symbol(exp)
|
@@ -121,20 +117,70 @@ module RipperRubyParser
|
|
121
117
|
s(:symbols, *items)
|
122
118
|
end
|
123
119
|
|
120
|
+
INTERPOLATING_HEREDOC = /^<<[-~]?[^-~']/.freeze
|
121
|
+
NON_INTERPOLATING_HEREDOC = /^<<[-~]?'/.freeze
|
122
|
+
INTERPOLATING_STRINGS = ['"', '`', ':"', /^%Q.$/, /^%.$/].freeze
|
123
|
+
NON_INTERPOLATING_STRINGS = ["'", ":'", /^%q.$/].freeze
|
124
|
+
INTERPOLATING_WORD_LIST = /^%[WI].$/.freeze
|
125
|
+
NON_INTERPOLATING_WORD_LIST = /^%[wi].$/.freeze
|
126
|
+
REGEXP_LITERALS = ['/', /^%r.$/].freeze
|
127
|
+
|
124
128
|
def process_at_tstring_content(exp)
|
125
|
-
_,
|
129
|
+
_, content, _, delim = exp.shift 4
|
130
|
+
string = handle_string_unescaping(content, delim)
|
131
|
+
string = handle_string_encoding(string, delim)
|
126
132
|
s(:str, string)
|
127
133
|
end
|
128
134
|
|
135
|
+
def process_array(exp)
|
136
|
+
_, elems = exp.shift 2
|
137
|
+
return s(:array) if elems.nil?
|
138
|
+
|
139
|
+
process(elems).tap { |arr| arr.sexp_type = :array }
|
140
|
+
end
|
141
|
+
|
142
|
+
# Handle hash literals sexps. These can be either empty, or contain a
|
143
|
+
# nested :assoclist_from_args Sexp.
|
144
|
+
#
|
145
|
+
# @example Empty hash
|
146
|
+
# s(:hash, nil)
|
147
|
+
# @example Hash with contents
|
148
|
+
# s(:hash, s(:assoclist_from_args, ...))
|
149
|
+
def process_hash(exp)
|
150
|
+
_, body = exp.shift 2
|
151
|
+
return s(:hash) unless body
|
152
|
+
|
153
|
+
_, elems = body
|
154
|
+
s(:hash, *make_hash_items(elems))
|
155
|
+
end
|
156
|
+
|
157
|
+
# @example
|
158
|
+
# s(:assoc_splat, s(:vcall, s(:@ident, "bar")))
|
159
|
+
def process_assoc_splat(exp)
|
160
|
+
_, param = exp.shift 2
|
161
|
+
s(:kwsplat, process(param))
|
162
|
+
end
|
163
|
+
|
129
164
|
private
|
130
165
|
|
131
166
|
def extract_string_parts(list)
|
132
|
-
parts =
|
167
|
+
parts = []
|
168
|
+
|
169
|
+
unless list.empty?
|
170
|
+
parts << process(list.shift)
|
171
|
+
list.each do |item|
|
172
|
+
parts << if extra_compatible && item.sexp_type == :@tstring_content
|
173
|
+
alternative_process_at_tstring_content(item)
|
174
|
+
else
|
175
|
+
process(item)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
133
179
|
|
134
180
|
string = ''
|
135
181
|
while !parts.empty? && parts.first.sexp_type == :str
|
136
182
|
str = parts.shift
|
137
|
-
string += str
|
183
|
+
string += str.last
|
138
184
|
end
|
139
185
|
|
140
186
|
rest = parts.map { |se| se.sexp_type == :dstr ? se.last : se }
|
@@ -142,15 +188,27 @@ module RipperRubyParser
|
|
142
188
|
return string, rest
|
143
189
|
end
|
144
190
|
|
191
|
+
def alternative_process_at_tstring_content(exp)
|
192
|
+
_, content, _, delim = exp.shift 4
|
193
|
+
string = case delim
|
194
|
+
when *INTERPOLATING_STRINGS
|
195
|
+
unescape(content)
|
196
|
+
else
|
197
|
+
content
|
198
|
+
end
|
199
|
+
string.force_encoding('ascii-8bit') if string == "\0"
|
200
|
+
s(:str, string)
|
201
|
+
end
|
202
|
+
|
145
203
|
def character_flags_to_numerical(flags)
|
146
204
|
numflags = 0
|
147
205
|
|
148
|
-
flags =~ /m/
|
149
|
-
flags =~ /x/
|
150
|
-
flags =~ /i/
|
206
|
+
numflags = Regexp::MULTILINE if flags =~ /m/
|
207
|
+
numflags |= Regexp::EXTENDED if flags =~ /x/
|
208
|
+
numflags |= Regexp::IGNORECASE if flags =~ /i/
|
151
209
|
|
152
|
-
flags =~ /n/
|
153
|
-
flags =~ /[ues]/
|
210
|
+
numflags |= Regexp::NOENCODING if flags =~ /n/
|
211
|
+
numflags |= Regexp::FIXEDENCODING if flags =~ /[ues]/
|
154
212
|
|
155
213
|
numflags
|
156
214
|
end
|
@@ -162,17 +220,22 @@ module RipperRubyParser
|
|
162
220
|
s(:lit, body.first.to_sym)
|
163
221
|
when :dstr, :dxstr
|
164
222
|
s(:dsym, *body)
|
165
|
-
else
|
166
|
-
raise type.to_s
|
167
223
|
end
|
168
224
|
end
|
169
225
|
|
170
226
|
def handle_symbol_content(node)
|
171
|
-
|
227
|
+
if node.sexp_type == :'@kw'
|
228
|
+
symbol, position = extract_node_symbol_with_position(node)
|
229
|
+
else
|
230
|
+
processed = process(node)
|
231
|
+
symbol = processed.last.to_sym
|
232
|
+
position = processed.line
|
233
|
+
end
|
234
|
+
with_line_number(position, s(:lit, symbol))
|
172
235
|
end
|
173
236
|
|
174
237
|
def merge_left_into_right(left, right)
|
175
|
-
right[1] = left
|
238
|
+
right[1] = left.last + right[1]
|
176
239
|
right
|
177
240
|
end
|
178
241
|
|
@@ -185,6 +248,51 @@ module RipperRubyParser
|
|
185
248
|
left.push(*rest)
|
186
249
|
end
|
187
250
|
end
|
251
|
+
|
252
|
+
def handle_string_unescaping(content, delim)
|
253
|
+
case delim
|
254
|
+
when INTERPOLATING_HEREDOC, *INTERPOLATING_STRINGS
|
255
|
+
unescape(content)
|
256
|
+
when INTERPOLATING_WORD_LIST
|
257
|
+
unescape_wordlist_word(content)
|
258
|
+
when *NON_INTERPOLATING_STRINGS
|
259
|
+
simple_unescape(content)
|
260
|
+
when *REGEXP_LITERALS
|
261
|
+
unescape_regexp(content)
|
262
|
+
when NON_INTERPOLATING_WORD_LIST
|
263
|
+
simple_unescape_wordlist_word(content)
|
264
|
+
else
|
265
|
+
content
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def handle_string_encoding(string, delim)
|
270
|
+
case delim
|
271
|
+
when INTERPOLATING_HEREDOC, INTERPOLATING_WORD_LIST
|
272
|
+
if extra_compatible
|
273
|
+
string
|
274
|
+
else
|
275
|
+
fix_encoding string
|
276
|
+
end
|
277
|
+
when *INTERPOLATING_STRINGS
|
278
|
+
fix_encoding string
|
279
|
+
else
|
280
|
+
string
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
# Process list of items that can be either :assoc_new or :assoc_splat
|
285
|
+
def make_hash_items(elems)
|
286
|
+
result = s()
|
287
|
+
elems.each do |sub_exp|
|
288
|
+
if sub_exp.sexp_type == :assoc_new
|
289
|
+
sub_exp.sexp_body.each { |elem| result << process(elem) }
|
290
|
+
else # :assoc_splat
|
291
|
+
result << process(sub_exp)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
result
|
295
|
+
end
|
188
296
|
end
|
189
297
|
end
|
190
298
|
end
|