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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -1
  3. data/README.md +41 -9
  4. data/Rakefile +2 -0
  5. data/lib/ripper_ruby_parser.rb +2 -0
  6. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +23 -45
  7. data/lib/ripper_ruby_parser/parser.rb +11 -1
  8. data/lib/ripper_ruby_parser/sexp_handlers.rb +2 -6
  9. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +49 -35
  10. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +78 -39
  11. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +16 -15
  12. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +19 -15
  13. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +138 -30
  14. data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +10 -6
  15. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +59 -14
  16. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +56 -32
  17. data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +20 -27
  18. data/lib/ripper_ruby_parser/sexp_processor.rb +40 -10
  19. data/lib/ripper_ruby_parser/syntax_error.rb +2 -0
  20. data/lib/ripper_ruby_parser/unescape.rb +32 -11
  21. data/lib/ripper_ruby_parser/version.rb +3 -1
  22. data/test/end_to_end/comments_test.rb +2 -0
  23. data/test/end_to_end/comparison_test.rb +2 -0
  24. data/test/end_to_end/lib_comparison_test.rb +2 -0
  25. data/test/end_to_end/line_numbering_test.rb +2 -0
  26. data/test/end_to_end/samples_comparison_test.rb +5 -29
  27. data/test/end_to_end/test_comparison_test.rb +2 -0
  28. data/test/pt_testcase/pt_test.rb +2 -0
  29. data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +16 -2
  30. data/test/ripper_ruby_parser/parser_test.rb +17 -688
  31. data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +459 -26
  32. data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +152 -82
  33. data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +91 -0
  34. data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +331 -24
  35. data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +88 -0
  36. data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +58 -5
  37. data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +392 -0
  38. data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +174 -12
  39. data/test/ripper_ruby_parser/sexp_processor_test.rb +8 -18
  40. data/test/ripper_ruby_parser/version_test.rb +2 -0
  41. data/test/samples/comments.rb +13 -0
  42. data/test/samples/conditionals.rb +23 -0
  43. data/test/samples/loops.rb +36 -0
  44. data/test/samples/misc.rb +157 -5
  45. data/test/samples/number.rb +7 -0
  46. data/test/samples/strings.rb +39 -0
  47. data/test/test_helper.rb +22 -1
  48. metadata +18 -12
  49. data/lib/ripper_ruby_parser/sexp_handlers/arguments.rb +0 -29
  50. data/lib/ripper_ruby_parser/sexp_handlers/arrays.rb +0 -21
  51. 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
- stmts = stmt.first || s()
11
- make_iter call, args, stmts
12
- end
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
- convert_special_args names
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
- convert_empty_to_nil_symbol(body)
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 = map_process_sexp_body_compact(block)
58
+ rescue_block = map_process_list_compact block.sexp_body
60
59
  rescue_block << nil if rescue_block.empty?
61
60
 
62
- arr = []
63
- if eclass
64
- if eclass.first.is_a? Symbol
65
- arr += process(eclass).sexp_body
66
- else
67
- arr << process(eclass[0])
68
- end
69
- end
70
-
71
- arr << create_assignment_sub_type(process(evar), s(:gvar, :$!)) if evar
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, s(:array, *arr), *rescue_block),
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 map_process_sexp_body_compact(main)
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 = convert_special_args(process(args))
136
- args = 0 if args == s(:args) && old_type == :params
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
- defaults.map { |sym, val| s(:lasgn, process(sym)[1], process(val)) }
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)[1]
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
- handle_operator_argument(truepart),
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
- handle_operator_argument(truepart))
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 = handle_argument_list values
65
+ values = process(values).sexp_body
65
66
 
66
- truepart = map_process_sexp_body_compact(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
- if (cond.sexp_type == :lit) && cond[1].is_a?(Regexp)
85
- s(:match, cond)
86
- elsif cond.sexp_type == :dot2
87
- s(:flip2, *cond[1..-1])
88
- elsif cond.sexp_type == :dot3
89
- s(:flip3, *cond[1..-1])
90
- else
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
- _, ident, = exp.shift 3
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 map_process_sexp_body_compact(list)
48
- reject_void_stmt map_process_sexp_body list
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 handle_argument_list(exp)
72
- process(exp).tap(&:shift)
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 = handle_argument_list(arglist)
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, except hash and array 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, '', s(:evstr))
34
+ s(:dstr, s(:evstr))
33
35
  else
34
- s(:dstr, '', s(:evstr, val))
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, '', s(:evstr, val))
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
- string, rest = process(content).sexp_body
77
+ content = process(content)
76
78
  numflags = character_flags_to_numerical flags
77
79
 
78
- if rest.empty?
79
- s(:lit, Regexp.new(string, numflags))
80
- else
81
- rest << numflags if numflags > 0
82
- sexp_type = if flags =~ /o/
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(:regexp, string, rest)
90
+ s(:dregx, string, *rest)
95
91
  end
96
92
 
97
93
  def process_symbol_literal(exp)
98
94
  _, symbol = exp.shift 2
99
- process(symbol)
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
- _, string, = exp.shift 3
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 = map_process_list list
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[1]
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/ and numflags |= Regexp::MULTILINE
149
- flags =~ /x/ and numflags |= Regexp::EXTENDED
150
- flags =~ /i/ and numflags |= Regexp::IGNORECASE
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/ and numflags |= Regexp::NOENCODING
153
- flags =~ /[ues]/ and numflags |= Regexp::FIXEDENCODING
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
- with_position_from_node_symbol(node) { |sym| s(:lit, sym) }
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[1] + right[1]
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