ripper_ruby_parser 1.4.2 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|