ripper_ruby_parser 1.7.0 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +76 -0
  3. data/README.md +6 -4
  4. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +24 -12
  5. data/lib/ripper_ruby_parser/sexp_handlers.rb +2 -0
  6. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +9 -4
  7. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +40 -52
  8. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +17 -19
  9. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +35 -2
  10. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +15 -242
  11. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +9 -5
  12. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +22 -17
  13. data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +3 -3
  14. data/lib/ripper_ruby_parser/sexp_handlers/string_literals.rb +256 -0
  15. data/lib/ripper_ruby_parser/sexp_processor.rb +12 -56
  16. data/lib/ripper_ruby_parser/unescape.rb +89 -43
  17. data/lib/ripper_ruby_parser/version.rb +1 -1
  18. metadata +125 -76
  19. data/Rakefile +0 -33
  20. data/test/end_to_end/comments_test.rb +0 -59
  21. data/test/end_to_end/comparison_test.rb +0 -104
  22. data/test/end_to_end/lib_comparison_test.rb +0 -29
  23. data/test/end_to_end/line_numbering_test.rb +0 -31
  24. data/test/end_to_end/samples_comparison_test.rb +0 -13
  25. data/test/end_to_end/test_comparison_test.rb +0 -32
  26. data/test/pt_testcase/pt_test.rb +0 -44
  27. data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +0 -200
  28. data/test/ripper_ruby_parser/parser_test.rb +0 -553
  29. data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +0 -613
  30. data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +0 -679
  31. data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +0 -536
  32. data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +0 -1106
  33. data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +0 -209
  34. data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +0 -267
  35. data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +0 -421
  36. data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +0 -399
  37. data/test/ripper_ruby_parser/sexp_processor_test.rb +0 -303
  38. data/test/ripper_ruby_parser/version_test.rb +0 -7
  39. data/test/samples/assignment.rb +0 -17
  40. data/test/samples/comments.rb +0 -13
  41. data/test/samples/conditionals.rb +0 -23
  42. data/test/samples/lambdas.rb +0 -5
  43. data/test/samples/loops.rb +0 -36
  44. data/test/samples/misc.rb +0 -281
  45. data/test/samples/number.rb +0 -7
  46. data/test/samples/operators.rb +0 -18
  47. data/test/samples/strings.rb +0 -147
  48. data/test/test_helper.rb +0 -107
@@ -41,7 +41,7 @@ module RipperRubyParser
41
41
  end
42
42
 
43
43
  def integer_literal?(exp)
44
- exp.sexp_type == :lit && exp[1].is_a?(Integer)
44
+ exp && exp.sexp_type == :lit && exp[1].is_a?(Integer)
45
45
  end
46
46
 
47
47
  def reject_void_stmt(body)
@@ -81,13 +81,46 @@ module RipperRubyParser
81
81
  end
82
82
 
83
83
  def unwrap_block(exp)
84
- if exp.sexp_type == :block
84
+ case exp.sexp_type
85
+ when :block
85
86
  exp.sexp_body
87
+ when :void_stmt
88
+ [nil]
86
89
  else
87
90
  [exp]
88
91
  end
89
92
  end
90
93
 
94
+ def wrap_in_block(statements, line)
95
+ case statements.length
96
+ when 0
97
+ s(:void_stmt).line(line)
98
+ when 1
99
+ statements.first
100
+ else
101
+ first = statements.shift
102
+ s(:block, *unwrap_block(first), *statements)
103
+ end
104
+ end
105
+
106
+ def convert_void_stmt_to_nil_symbol(block)
107
+ case block.sexp_type
108
+ when :void_stmt
109
+ s(:nil)
110
+ else
111
+ block
112
+ end
113
+ end
114
+
115
+ def convert_empty_to_nil_symbol(block)
116
+ case block.length
117
+ when 0
118
+ s(:nil)
119
+ else
120
+ block
121
+ end
122
+ end
123
+
91
124
  def handle_return_argument_list(arglist)
92
125
  args = process(arglist).sexp_body
93
126
 
@@ -4,134 +4,10 @@ module RipperRubyParser
4
4
  module SexpHandlers
5
5
  # Sexp handlers for literals
6
6
  module Literals
7
- def process_string_literal(exp)
8
- _, content = exp.shift 2
9
- process(content)
10
- end
11
-
12
- def process_string_content(exp)
13
- _, *rest = shift_all exp
14
- line, string, rest = extract_string_parts(rest)
15
-
16
- if rest.empty?
17
- with_line_number(line, s(:str, string))
18
- else
19
- s(:dstr, string, *rest)
20
- end
21
- end
22
-
23
- alias process_word process_string_content
24
-
25
- def process_string_embexpr(exp)
26
- _, list = exp.shift 2
27
-
28
- val = process(list.sexp_body.first)
29
-
30
- case val.sexp_type
31
- when :str, :dstr
32
- val
33
- when :void_stmt
34
- s(:dstr, "", s(:evstr))
35
- else
36
- s(:dstr, "", s(:evstr, val))
37
- end
38
- end
39
-
40
- def process_string_dvar(exp)
41
- _, list = exp.shift 2
42
- val = process(list)
43
- s(:dstr, "", s(:evstr, val))
44
- end
45
-
46
- def process_string_concat(exp)
47
- _, left, right = exp.shift 3
48
-
49
- left = process(left)
50
- right = process(right)
51
-
52
- if left.sexp_type == :str
53
- merge_left_into_right(left, right)
54
- else
55
- merge_right_into_left(left, right)
56
- end
57
- end
58
-
59
- def process_xstring_literal(exp)
60
- _, content = exp.shift 2
61
- process(content)
62
- end
63
-
64
- def process_xstring(exp)
65
- _, *rest = shift_all exp
66
- line, string, rest = extract_string_parts(rest)
67
- if rest.empty?
68
- s(:xstr, string).line(line)
69
- else
70
- s(:dxstr, string, *rest)
71
- end
72
- end
73
-
74
- def process_regexp_literal(exp)
75
- _, content, (_, flags,) = exp.shift 3
76
-
77
- content = process(content)
78
- numflags = character_flags_to_numerical flags
79
-
80
- if content.length == 2
81
- return with_line_number(content.line, s(:lit, Regexp.new(content.last, numflags)))
82
- end
83
-
84
- content.sexp_type = :dregx_once if /o/.match?(flags)
85
- content << numflags unless numflags == 0
86
- content
87
- end
88
-
89
- def process_regexp(exp)
90
- _, *rest = shift_all exp
91
- line, string, rest = extract_string_parts(rest)
92
- with_line_number(line, s(:dregx, string, *rest))
93
- end
94
-
95
- def process_symbol_literal(exp)
96
- _, symbol = exp.shift 2
97
- handle_symbol_content(symbol)
98
- end
99
-
100
- def process_symbol(exp)
101
- _, node = exp.shift 2
102
- handle_symbol_content(node)
103
- end
104
-
105
- def process_dyna_symbol(exp)
106
- _, node = exp.shift 2
107
- handle_dyna_symbol_content(node)
108
- end
109
-
110
- def process_qsymbols(exp)
111
- _, *items = shift_all(exp)
112
- items = items.map { |item| handle_symbol_content(item) }
113
- s(:qsymbols, *items)
114
- end
115
-
116
- def process_symbols(exp)
117
- _, *items = shift_all(exp)
118
- items = items.map { |item| handle_dyna_symbol_content(item) }
119
- s(:symbols, *items)
120
- end
121
-
122
- INTERPOLATING_HEREDOC = /^<<[-~]?[^-~']/.freeze
123
- NON_INTERPOLATING_HEREDOC = /^<<[-~]?'/.freeze
124
- INTERPOLATING_STRINGS = ['"', "`", ':"', /^%Q.$/, /^%.$/].freeze
125
- NON_INTERPOLATING_STRINGS = ["'", ":'", /^%q.$/].freeze
126
- INTERPOLATING_WORD_LIST = /^%[WI].$/.freeze
127
- NON_INTERPOLATING_WORD_LIST = /^%[wi].$/.freeze
128
- REGEXP_LITERALS = ["/", /^%r.$/].freeze
129
-
130
- def process_at_tstring_content(exp)
131
- _, content, pos, delim = exp.shift 4
132
- string = handle_string_unescaping(content, delim)
133
- string = handle_string_encoding(string, delim)
134
- with_position(pos, s(:str, string))
7
+ # character literals
8
+ def process_at_CHAR(exp)
9
+ _, val, pos = exp.shift 3
10
+ with_position(pos, s(:str, fix_encoding(unescape(val[1..-1]))))
135
11
  end
136
12
 
137
13
  def process_array(exp)
@@ -163,134 +39,31 @@ module RipperRubyParser
163
39
  s(:kwsplat, process(param))
164
40
  end
165
41
 
166
- private
167
-
168
- def extract_string_parts(list)
169
- return nil, "", [] if list.empty?
170
-
171
- list = merge_raw_string_literals list
172
- list = map_process_list list
173
-
174
- parts = list.flat_map do |item|
175
- type, val, *rest = item
176
- if type == :dstr
177
- if val.empty?
178
- rest
179
- else
180
- [s(:str, val), *rest]
181
- end
182
- else
183
- [item]
184
- end
185
- end
186
-
187
- string = ""
188
- while parts.first&.sexp_type == :str
189
- str = parts.shift
190
- line ||= str.line
191
- string += str.last
192
- end
193
-
194
- return line, string, parts
195
- end
196
-
197
- def merge_raw_string_literals(list)
198
- chunks = list.chunk { |it| it.sexp_type == :@tstring_content }
199
- chunks.flat_map do |is_simple, items|
200
- if is_simple && items.count > 1
201
- head = items.first
202
- contents = items.map { |it| it[1] }.join
203
- [s(:@tstring_content, contents, head[2], head[3])]
204
- else
205
- items
206
- end
207
- end
208
- end
209
-
210
- def character_flags_to_numerical(flags)
211
- numflags = 0
212
-
213
- numflags = Regexp::MULTILINE if /m/.match?(flags)
214
- numflags |= Regexp::EXTENDED if /x/.match?(flags)
215
- numflags |= Regexp::IGNORECASE if /i/.match?(flags)
216
-
217
- numflags |= Regexp::NOENCODING if /n/.match?(flags)
218
- numflags |= Regexp::FIXEDENCODING if /[ues]/.match?(flags)
219
-
220
- numflags
221
- end
222
-
223
- def handle_dyna_symbol_content(node)
224
- type, *body = *process(node)
225
- case type
226
- when :str, :xstr
227
- s(:lit, body.first.to_sym)
228
- when :dstr, :dxstr
229
- s(:dsym, *body)
230
- end
42
+ # number literals
43
+ def process_at_int(exp)
44
+ make_literal(exp) { |val| Integer(val) }
231
45
  end
232
46
 
233
- def handle_symbol_content(node)
234
- if node.sexp_type == :'@kw'
235
- symbol, position = extract_node_symbol_with_position(node)
236
- with_position(position, s(:lit, symbol))
237
- else
238
- processed = process(node)
239
- symbol = processed.last.to_sym
240
- line = processed.line
241
- with_line_number(line, s(:lit, symbol))
242
- end
47
+ def process_at_float(exp)
48
+ make_literal(exp, &:to_f)
243
49
  end
244
50
 
245
- def merge_left_into_right(left, right)
246
- right[1] = left.last + right[1]
247
- right
51
+ def process_at_rational(exp)
52
+ make_literal(exp, &:to_r)
248
53
  end
249
54
 
250
- def merge_right_into_left(left, right)
251
- if right.sexp_type == :str
252
- left.push right
253
- else
254
- _, first, *rest = right
255
- left.push s(:str, first) unless first.empty?
256
- left.push(*rest)
257
- end
55
+ def process_at_imaginary(exp)
56
+ make_literal(exp, &:to_c)
258
57
  end
259
58
 
260
- def handle_string_unescaping(content, delim)
261
- case delim
262
- when INTERPOLATING_HEREDOC
263
- unescape(content)
264
- when *INTERPOLATING_STRINGS
265
- unescape(content)
266
- when INTERPOLATING_WORD_LIST
267
- unescape_wordlist_word(content)
268
- when *NON_INTERPOLATING_STRINGS
269
- simple_unescape(content)
270
- when *REGEXP_LITERALS
271
- unescape_regexp(content)
272
- when NON_INTERPOLATING_WORD_LIST
273
- simple_unescape_wordlist_word(content)
274
- else
275
- content
276
- end
277
- end
278
-
279
- def handle_string_encoding(string, delim)
280
- case delim
281
- when INTERPOLATING_HEREDOC, INTERPOLATING_WORD_LIST, *INTERPOLATING_STRINGS
282
- fix_encoding string
283
- else
284
- string
285
- end
286
- end
59
+ private
287
60
 
288
61
  # Process list of items that can be either :assoc_new or :assoc_splat
289
62
  def make_hash_items(elems)
290
63
  result = s()
291
64
  elems.each do |sub_exp|
292
65
  if sub_exp.sexp_type == :assoc_new
293
- sub_exp.sexp_body.each { |elem| result << process(elem) }
66
+ result += process(sub_exp).sexp_body
294
67
  else # :assoc_splat
295
68
  result << process(sub_exp)
296
69
  end
@@ -17,7 +17,7 @@ module RipperRubyParser
17
17
 
18
18
  def process_arg_paren(exp)
19
19
  _, args = exp.shift 2
20
- return s() if args.nil?
20
+ return s(:arglist) if args.nil?
21
21
 
22
22
  process(args)
23
23
  end
@@ -26,7 +26,11 @@ module RipperRubyParser
26
26
  _, call, parens = exp.shift 3
27
27
  call = process(call)
28
28
  parens = process(parens)
29
- call.push(*parens.sexp_body)
29
+ if parens.sexp_type == :forward_args
30
+ call.push(parens)
31
+ else
32
+ call.push(*parens.sexp_body)
33
+ end
30
34
  end
31
35
 
32
36
  # Handle implied hashes, such as at the end of argument lists.
@@ -36,9 +40,9 @@ module RipperRubyParser
36
40
  end
37
41
 
38
42
  CALL_OP_MAP = {
39
- '.': :call,
40
- '::': :call,
41
- '&.': :safe_call
43
+ ".": :call,
44
+ "::": :call,
45
+ "&.": :safe_call
42
46
  }.freeze
43
47
 
44
48
  def process_call(exp)
@@ -72,6 +72,11 @@ module RipperRubyParser
72
72
  s(:alias, process(left), process(right))
73
73
  end
74
74
 
75
+ def process_args_forward(exp)
76
+ _ = exp.shift
77
+ s(:forward_args)
78
+ end
79
+
75
80
  private
76
81
 
77
82
  def in_method
@@ -83,8 +88,8 @@ module RipperRubyParser
83
88
 
84
89
  def method_body(exp)
85
90
  block = process exp
86
- case block.length
87
- when 0
91
+ case block.sexp_type
92
+ when :void_stmt
88
93
  [s(:nil).line(block.line)]
89
94
  else
90
95
  unwrap_block block
@@ -98,21 +103,21 @@ module RipperRubyParser
98
103
  }.freeze
99
104
 
100
105
  def convert_arguments(args)
101
- args.map! do |item|
102
- if item.is_a? Symbol
103
- item
104
- else
105
- case item.sexp_type
106
- when :lvar
107
- item.last
108
- when *SPECIAL_ARG_MARKER.keys
109
- convert_marked_argument(item)
110
- when :masgn
111
- convert_masgn_argument(item)
112
- else
113
- item
114
- end
115
- end
106
+ args.line ||= args.sexp_body.first&.line
107
+ args.sexp_body = args.sexp_body.map { |item| convert_argument item }
108
+ args
109
+ end
110
+
111
+ def convert_argument(item)
112
+ case item.sexp_type
113
+ when :lvar
114
+ item.last
115
+ when *SPECIAL_ARG_MARKER.keys
116
+ convert_marked_argument(item)
117
+ when :masgn
118
+ convert_masgn_argument(item)
119
+ else
120
+ item
116
121
  end
117
122
  end
118
123
 
@@ -5,8 +5,8 @@ module RipperRubyParser
5
5
  # Sexp handlers for operators
6
6
  module Operators
7
7
  BINARY_OPERATOR_MAP = {
8
- '&&': :and,
9
- '||': :or,
8
+ "&&": :and,
9
+ "||": :or,
10
10
  and: :and,
11
11
  or: :or
12
12
  }.freeze
@@ -16,7 +16,7 @@ module RipperRubyParser
16
16
  }.freeze
17
17
 
18
18
  NEGATED_BINARY_OPERATOR_MAP = {
19
- '!~': :=~
19
+ "!~": :=~
20
20
  }.freeze
21
21
 
22
22
  SHIFT_OPERATORS = [:<<, :>>].freeze