ripper_ruby_parser 1.6.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/README.md +8 -25
  4. data/lib/ripper_ruby_parser.rb +2 -2
  5. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +54 -23
  6. data/lib/ripper_ruby_parser/parser.rb +3 -3
  7. data/lib/ripper_ruby_parser/sexp_handlers.rb +11 -9
  8. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +10 -11
  9. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +48 -63
  10. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +17 -19
  11. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +35 -2
  12. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +15 -242
  13. data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +4 -2
  14. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +1 -1
  15. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +24 -24
  16. data/lib/ripper_ruby_parser/sexp_handlers/string_literals.rb +266 -0
  17. data/lib/ripper_ruby_parser/sexp_processor.rb +47 -78
  18. data/lib/ripper_ruby_parser/unescape.rb +79 -50
  19. data/lib/ripper_ruby_parser/version.rb +1 -1
  20. metadata +115 -78
  21. data/Rakefile +0 -33
  22. data/test/end_to_end/comments_test.rb +0 -59
  23. data/test/end_to_end/comparison_test.rb +0 -104
  24. data/test/end_to_end/lib_comparison_test.rb +0 -29
  25. data/test/end_to_end/line_numbering_test.rb +0 -64
  26. data/test/end_to_end/samples_comparison_test.rb +0 -13
  27. data/test/end_to_end/test_comparison_test.rb +0 -32
  28. data/test/pt_testcase/pt_test.rb +0 -44
  29. data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +0 -190
  30. data/test/ripper_ruby_parser/parser_test.rb +0 -469
  31. data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +0 -649
  32. data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +0 -661
  33. data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +0 -536
  34. data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +0 -1117
  35. data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +0 -209
  36. data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +0 -267
  37. data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +0 -427
  38. data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +0 -399
  39. data/test/ripper_ruby_parser/sexp_processor_test.rb +0 -303
  40. data/test/ripper_ruby_parser/version_test.rb +0 -7
  41. data/test/samples/assignment.rb +0 -17
  42. data/test/samples/comments.rb +0 -13
  43. data/test/samples/conditionals.rb +0 -23
  44. data/test/samples/loops.rb +0 -36
  45. data/test/samples/misc.rb +0 -278
  46. data/test/samples/number.rb +0 -7
  47. data/test/samples/operators.rb +0 -18
  48. data/test/samples/strings.rb +0 -140
  49. data/test/test_helper.rb +0 -79
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cc516bb8bd2fd0f9fd310f848dbf272481d6c15a8ee3aeecba41ac8e24a7b8c3
4
- data.tar.gz: 2d79ba2d094e3694993f48e92565c7424121331aad653bd6cb5fad51a7f9ea75
3
+ metadata.gz: 799011b06831426c0ebecad641082d58bfaa8da0aea9359a3a2d152ea01bd196
4
+ data.tar.gz: eec3804031490d2382f59ddc450af14f73b696b9e14f0d2919b64a3df3557853
5
5
  SHA512:
6
- metadata.gz: 2d521a088a674f96b3639d624de7ababb6dbea93965fee1185b6a14f8a289ef88566a87cc5918004d3765f19de7ea0a15d99cfb30792ff519e1d8426555bb162
7
- data.tar.gz: 0a79e0832ce26282bacb13d534dde0460f33b677e7a07c23bde4d530848228bda65460ce2c229a97ddc25c5f12cc0aa75ea176f09e3959fcbf78e34536fa6bcd
6
+ metadata.gz: eab6dc676f7c5806bcd09f9adf87e5b67dd5320e043c07370014fdfc8e5ca1dffbaa9583754ac74bc354a30c6b27392c3310a7172b20699d475d9122e9dae748
7
+ data.tar.gz: b776c9d833e7808c7b2ac17ec6bb5a358a93cb1bb925ee94199aeddf85c0cca2e102cdcdfff17ca8d17ac406e0f76c4b981b640085fbd02d2868bca36fdd840d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,64 @@
1
1
  # Changelog
2
2
 
3
+ Notable changes to this project will be documented in this file.
4
+
5
+ This project adheres to [Semantic Versioning 2.0.0][1].
6
+
7
+ This document is formatted based on [Keep A CHANGELOG][2].
8
+
9
+ ## 1.8.0 / 2021-05-18
10
+
11
+ ### Changes
12
+
13
+ * Drop support for Ruby 2.4 ([2cf6b4050] and [#145])
14
+ * Update RubyParser compatibility target to 3.15.0 ([#105])
15
+ * Fix handling of dedented heredoc ([#106])
16
+ * Add support for running on Ruby 3.0 ([#123])
17
+ * Various code improvements and other internal changes
18
+
19
+ ## 1.7.2 / 2020-02-28
20
+
21
+ ### Bug fixes
22
+
23
+ * Support imaginary number literals ([#100])
24
+ * Handle anonymous kwrest arguments ([#95])
25
+
26
+ ### Internal changes
27
+
28
+ * Update tests ([#101])
29
+ * Prepare for testing on Ruby 2.7 ([#99])
30
+ * Various improvements ([#98])
31
+ * Split long module ([#97])
32
+
33
+ ## 1.7.1 / 2019-11-03
34
+
35
+ * Handle unicode escapes with five or six hex digits ([#94])
36
+ * Handle safe attribute assignment ([#92])
37
+ * Handle endless ranges on Ruby 2.6+ ([#90])
38
+ * Add preliminary support for Ruby 2.7 ([#89])
39
+ * Improve line number handling for stabby lambdas ([#88])
40
+
41
+ ## 1.7.0 / 2019-11-01
42
+
43
+ * Make results compatible with RubyParser 3.14.0 ([#85])
44
+ - Remove obsolete extra-compatible behavior
45
+ - Parse stabby lambda as :lambda-typed sexp
46
+ - Emit nil argument for block arguments with trailing comma
47
+ * Require Ruby 2.4 or higher ([#86])
48
+
49
+ ## 1.6.1 / 2019-04-22
50
+
51
+ * Improve line numbering for some block structures ([#82])
52
+ - Fix line numbering for empty method bodies
53
+ - Assign correct line numbers to END blocks
54
+ - Assign correct line numbers to begin blocks
55
+ - Assign correct line numbers to BEGIN blocks
56
+ * Fix line numbering for several literals ([#80])
57
+ - Fix line numbering for plain regexp literals
58
+ - Fix line numbering for backtick literals
59
+ - Fix line numbering for simple string literals
60
+ - Fix line numbering for keyword-like symbols
61
+
3
62
  ## 1.6.0 / 2019-04-12
4
63
 
5
64
  * Fix line numbering for range literals ([#79])
@@ -158,6 +217,25 @@
158
217
  * Initial release
159
218
 
160
219
  <!-- Pull request links -->
220
+ [#145]: https://github.com/mvz/ripper_ruby_parser/pull/145
221
+ [#123]: https://github.com/mvz/ripper_ruby_parser/pull/123
222
+ [#106]: https://github.com/mvz/ripper_ruby_parser/pull/106
223
+ [#105]: https://github.com/mvz/ripper_ruby_parser/pull/105
224
+ [#101]: https://github.com/mvz/ripper_ruby_parser/pull/101
225
+ [#100]: https://github.com/mvz/ripper_ruby_parser/pull/100
226
+ [#99]: https://github.com/mvz/ripper_ruby_parser/pull/99
227
+ [#98]: https://github.com/mvz/ripper_ruby_parser/pull/98
228
+ [#97]: https://github.com/mvz/ripper_ruby_parser/pull/97
229
+ [#95]: https://github.com/mvz/ripper_ruby_parser/pull/95
230
+ [#94]: https://github.com/mvz/ripper_ruby_parser/pull/94
231
+ [#92]: https://github.com/mvz/ripper_ruby_parser/pull/92
232
+ [#90]: https://github.com/mvz/ripper_ruby_parser/pull/90
233
+ [#89]: https://github.com/mvz/ripper_ruby_parser/pull/89
234
+ [#88]: https://github.com/mvz/ripper_ruby_parser/pull/88
235
+ [#86]: https://github.com/mvz/ripper_ruby_parser/pull/86
236
+ [#85]: https://github.com/mvz/ripper_ruby_parser/pull/85
237
+ [#82]: https://github.com/mvz/ripper_ruby_parser/pull/82
238
+ [#80]: https://github.com/mvz/ripper_ruby_parser/pull/80
161
239
  [#79]: https://github.com/mvz/ripper_ruby_parser/pull/79
162
240
  [#78]: https://github.com/mvz/ripper_ruby_parser/pull/78
163
241
  [#77]: https://github.com/mvz/ripper_ruby_parser/pull/77
@@ -173,3 +251,11 @@
173
251
  [#67]: https://github.com/mvz/ripper_ruby_parser/pull/67
174
252
  [#66]: https://github.com/mvz/ripper_ruby_parser/pull/66
175
253
  [#65]: https://github.com/mvz/ripper_ruby_parser/pull/65
254
+
255
+ <!-- Git sha links -->
256
+ [2cf6b4050]: https://github.com/mvz/ripper_ruby_parser/commit/2cf6b40501576003b916196e23222276b51aa53c
257
+
258
+ <!-- Other links -->
259
+
260
+ [1]: https://semver.org/spec/v2.0.0.html
261
+ [2]: https://keepachangelog.com/en/1.0.0/
data/README.md CHANGED
@@ -10,28 +10,18 @@ Parse with Ripper, produce sexps that are compatible with RubyParser.
10
10
 
11
11
  * Drop-in replacement for RubyParser
12
12
  * Should handle 1.9 and later syntax gracefully
13
- * Requires MRI 2.3 or higher
14
- * Compatible with RubyParser 3.13.1
13
+ * Requires Ruby 2.5 or higher
14
+ * Compatible with RubyParser 3.15.0
15
15
 
16
16
  ## Known incompatibilities
17
17
 
18
- RipperRubyParser has some incompatibilities with RubyParser. For some of these,
19
- the behavior can be changed by turning on extra-compatible mode.
20
-
21
- The following incompatibilities cannot be changed:
18
+ RipperRubyParser has a few incompatibilities with RubyParser.
22
19
 
23
20
  * RipperRubyParser won't handle non-UTF-8 files without an encoding comment,
24
21
  just like regular Ruby
25
- * RipperRubyParser does not attempt to match RubyParser's line numbering bugs
26
- * RipperRubyParser correctly dedents heredocs with interpolations
27
-
28
- The following incompatibilities can be made compatible by turning on
29
- extra-compatible mode:
30
-
31
- * Operator assignment of a method call without parentheses to a collection
32
- element uses and `:array` S-expression instead of `:arglist`
33
- * RipperRubyParser keeps carriage return characters in heredocs that include
34
- them
22
+ * RipperRubyParser does not always match RubyParser's line numbering
23
+ * RipperRubyParser dedents auto-dedenting heredocs
24
+ * RipperRubyParser does not include postfix comments
35
25
 
36
26
  ## Install
37
27
 
@@ -50,18 +40,11 @@ parser.parse "foo[bar] += baz qux"
50
40
  # s(:arglist, s(:call, nil, :bar)),
51
41
  # :+,
52
42
  # s(:call, nil, :baz, s(:call, nil, :qux)))
53
- parser.extra_compatible = true
54
-
55
- parser.parse "foo[bar] += baz qux"
56
- # => s(:op_asgn1, s(:call, nil, :foo),
57
- # s(:array, s(:call, nil, :bar)),
58
- # :+,
59
- # s(:call, nil, :baz, s(:call, nil, :qux)))
60
43
  ```
61
44
 
62
45
  ## Requirements
63
46
 
64
- * Ruby 2.3 or higher
47
+ * Ruby 2.5 or higher
65
48
  * `sexp_processor`
66
49
 
67
50
  ## Hacking and contributing
@@ -81,7 +64,7 @@ If you want to send pull requests or patches, please:
81
64
 
82
65
  (The MIT License)
83
66
 
84
- Copyright (c) 2012, 2014-2019 Matijs van Zuijlen
67
+ Copyright (c) 2012, 2014-2020 Matijs van Zuijlen
85
68
 
86
69
  Permission is hereby granted, free of charge, to any person obtaining
87
70
  a copy of this software and associated documentation files (the
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ripper_ruby_parser/version'
4
- require 'ripper_ruby_parser/parser'
3
+ require "ripper_ruby_parser/version"
4
+ require "ripper_ruby_parser/parser"
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ripper'
4
- require 'ripper_ruby_parser/syntax_error'
5
- require 'ripper_ruby_parser/unescape'
3
+ require "ripper"
4
+ require "ripper_ruby_parser/syntax_error"
5
+ require "ripper_ruby_parser/unescape"
6
6
 
7
7
  module RipperRubyParser
8
8
  # Variant of Ripper's SexpBuilder parser class that inserts comments as
@@ -12,7 +12,7 @@ module RipperRubyParser
12
12
  class CommentingRipperParser < Ripper::SexpBuilder
13
13
  def initialize(*args)
14
14
  super
15
- @comment = ''
15
+ @comment = ""
16
16
  @comment_stack = []
17
17
  @delimiter_stack = []
18
18
  @space_before = false
@@ -22,16 +22,27 @@ module RipperRubyParser
22
22
 
23
23
  def parse
24
24
  result = super
25
- raise 'Ripper parse failed.' unless result
25
+ raise "Ripper parse failed." unless result
26
26
 
27
27
  Sexp.from_array(result)
28
28
  end
29
29
 
30
+ private
31
+
30
32
  def on_backtick(delimiter)
31
33
  @delimiter_stack.push delimiter
32
34
  super
33
35
  end
34
36
 
37
+ def on_begin(*args)
38
+ commentize(:begin, super)
39
+ end
40
+
41
+ def on_void_stmt
42
+ result = super
43
+ result << [lineno, column]
44
+ end
45
+
35
46
  def on_comment(tok)
36
47
  @comment += tok
37
48
  end
@@ -49,14 +60,15 @@ module RipperRubyParser
49
60
  end
50
61
 
51
62
  def on_kw(tok)
63
+ result = super
52
64
  case tok
53
- when 'class', 'def', 'module'
65
+ when "class", "def", "module", "BEGIN", "begin", "END"
54
66
  unless @in_symbol
55
- @comment_stack.push [tok.to_sym, @comment]
56
- @comment = ''
67
+ @comment_stack.push [result, @comment]
68
+ @comment = ""
57
69
  end
58
70
  end
59
- super
71
+ result
60
72
  end
61
73
 
62
74
  def on_module(*args)
@@ -91,6 +103,18 @@ module RipperRubyParser
91
103
  @delimiter_stack.push delimiter
92
104
  end
93
105
 
106
+ def on_heredoc_dedent(val, width)
107
+ next_dedent = true
108
+ val.map! do |e|
109
+ if e.is_a?(Array) && e[0] == :@tstring_content
110
+ e = dedent_element(e, width) if next_dedent
111
+ next_dedent = e[1].end_with? "\n"
112
+ end
113
+ e
114
+ end
115
+ val
116
+ end
117
+
94
118
  def on_heredoc_end(_delimiter)
95
119
  @delimiter_stack.pop
96
120
  end
@@ -245,7 +269,7 @@ module RipperRubyParser
245
269
  def on_unary(operator, value)
246
270
  if !@space_before && operator == :-@ && NUMBER_LITERAL_TYPES.include?(value.first)
247
271
  type, literal, lines = value
248
- if literal[0] == '-'
272
+ if literal[0] == "-"
249
273
  super
250
274
  else
251
275
  [type, "-#{literal}", lines]
@@ -275,31 +299,38 @@ module RipperRubyParser
275
299
  super
276
300
  end
277
301
 
278
- def on_parse_error(*args)
279
- raise SyntaxError, *args
302
+ def on_BEGIN(*args)
303
+ commentize(:BEGIN, super)
280
304
  end
281
305
 
282
- def on_class_name_error(*args)
283
- raise SyntaxError, *args
306
+ def on_END(*args)
307
+ commentize(:END, super)
284
308
  end
285
309
 
286
- def on_alias_error(*args)
287
- raise SyntaxError, *args
310
+ def on_parse_error(message)
311
+ raise SyntaxError, message
288
312
  end
289
313
 
290
- def on_assign_error(*args)
291
- raise SyntaxError, *args
314
+ def on_class_name_error(message, *)
315
+ raise SyntaxError, message
292
316
  end
293
317
 
294
- def on_param_error(*args)
295
- raise SyntaxError, *args
318
+ def on_alias_error(message, *)
319
+ raise SyntaxError, message
296
320
  end
297
321
 
298
- private
322
+ def on_assign_error(message, *)
323
+ raise SyntaxError, message
324
+ end
325
+
326
+ def on_param_error(message, *)
327
+ raise SyntaxError, message
328
+ end
299
329
 
300
330
  def commentize(_name, exp)
301
- _tok, comment = @comment_stack.pop
302
- @comment = ''
331
+ (_, _kw, loc), comment = @comment_stack.pop
332
+ @comment = ""
333
+ exp.push loc
303
334
  [:comment, comment, exp]
304
335
  end
305
336
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ripper_ruby_parser/commenting_ripper_parser'
4
- require 'ripper_ruby_parser/sexp_processor'
3
+ require "ripper_ruby_parser/commenting_ripper_parser"
4
+ require "ripper_ruby_parser/sexp_processor"
5
5
 
6
6
  module RipperRubyParser
7
7
  # Main parser class. Brings together Ripper and our
@@ -13,7 +13,7 @@ module RipperRubyParser
13
13
  @extra_compatible = false
14
14
  end
15
15
 
16
- def parse(source, filename = '(string)', lineno = 1)
16
+ def parse(source, filename = "(string)", lineno = 1)
17
17
  parser = CommentingRipperParser.new(source, filename, lineno)
18
18
  exp = parser.parse
19
19
 
@@ -1,15 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ripper_ruby_parser/sexp_handlers/helper_methods'
3
+ require "ripper_ruby_parser/sexp_handlers/helper_methods"
4
4
 
5
- require 'ripper_ruby_parser/sexp_handlers/assignment'
6
- require 'ripper_ruby_parser/sexp_handlers/blocks'
7
- require 'ripper_ruby_parser/sexp_handlers/conditionals'
8
- require 'ripper_ruby_parser/sexp_handlers/literals'
9
- require 'ripper_ruby_parser/sexp_handlers/loops'
10
- require 'ripper_ruby_parser/sexp_handlers/method_calls'
11
- require 'ripper_ruby_parser/sexp_handlers/methods'
12
- require 'ripper_ruby_parser/sexp_handlers/operators'
5
+ require "ripper_ruby_parser/sexp_handlers/assignment"
6
+ require "ripper_ruby_parser/sexp_handlers/blocks"
7
+ require "ripper_ruby_parser/sexp_handlers/conditionals"
8
+ require "ripper_ruby_parser/sexp_handlers/literals"
9
+ require "ripper_ruby_parser/sexp_handlers/loops"
10
+ require "ripper_ruby_parser/sexp_handlers/method_calls"
11
+ require "ripper_ruby_parser/sexp_handlers/methods"
12
+ require "ripper_ruby_parser/sexp_handlers/operators"
13
+ require "ripper_ruby_parser/sexp_handlers/string_literals"
13
14
 
14
15
  module RipperRubyParser
15
16
  # Umbrella module for handlers of particular sexp types
@@ -28,6 +29,7 @@ module RipperRubyParser
28
29
  include MethodCalls
29
30
  include Methods
30
31
  include Operators
32
+ include StringLiterals
31
33
  end
32
34
  end
33
35
  end
@@ -96,11 +96,10 @@ module RipperRubyParser
96
96
  _, lvalue, (_, operator,), value = exp.shift 4
97
97
 
98
98
  lvalue = process(lvalue)
99
- original_value_type = value.sexp_type
100
99
  value = process(value)
101
100
  operator = operator.chop.to_sym
102
101
 
103
- create_operator_assignment_sub_type lvalue, value, operator, original_value_type
102
+ create_operator_assignment_sub_type lvalue, value, operator
104
103
  end
105
104
 
106
105
  private
@@ -123,16 +122,11 @@ module RipperRubyParser
123
122
  '&&': :op_asgn_and
124
123
  }.freeze
125
124
 
126
- def create_operator_assignment_sub_type(lvalue, value, operator, original_value_type)
125
+ def create_operator_assignment_sub_type(lvalue, value, operator)
127
126
  case lvalue.sexp_type
128
127
  when :aref_field
129
128
  _, arr, arglist = lvalue
130
- arglist.sexp_type = if extra_compatible &&
131
- [:command, :command_call].include?(original_value_type)
132
- :array
133
- else
134
- :arglist
135
- end
129
+ arglist.sexp_type = :arglist
136
130
  s(:op_asgn1, arr, arglist, operator, value)
137
131
  when :field
138
132
  _, obj, _, (_, field) = lvalue
@@ -156,8 +150,13 @@ module RipperRubyParser
156
150
  arglist.shift
157
151
  s(:attrasgn, arr, :[]=, *arglist)
158
152
  when :field
159
- _, obj, _, (_, field) = lvalue
160
- s(:attrasgn, obj, :"#{field}=", value)
153
+ _, obj, call_op, (_, field) = lvalue
154
+ case call_op
155
+ when :"&.", s(:op, :"&.") # Handle both 2.5 and 2.6 style ops
156
+ s(:safe_attrasgn, obj, :"#{field}=", value)
157
+ else
158
+ s(:attrasgn, obj, :"#{field}=", value)
159
+ end
161
160
  else
162
161
  create_assignment_sub_type lvalue, value
163
162
  end
@@ -17,13 +17,14 @@ module RipperRubyParser
17
17
  def process_params(exp)
18
18
  _, normal, defaults, splat, rest, kwargs, doublesplat, block = exp.shift 8
19
19
 
20
- args = handle_normal_arguments normal
21
- args += handle_default_arguments defaults
22
- args += handle_splat splat
23
- args += handle_normal_arguments rest
24
- args += handle_kwargs kwargs
25
- args += handle_double_splat doublesplat
26
- args += handle_block_argument block
20
+ args =
21
+ handle_normal_arguments(normal) +
22
+ handle_default_arguments(defaults) +
23
+ handle_splat(splat) +
24
+ handle_normal_arguments(rest) +
25
+ handle_kwargs(kwargs) +
26
+ handle_double_splat(doublesplat) +
27
+ handle_block_argument(block)
27
28
 
28
29
  s(:args, *args)
29
30
  end
@@ -35,7 +36,7 @@ module RipperRubyParser
35
36
 
36
37
  def process_kwrest_param(exp)
37
38
  _, sym, = exp.shift 3
38
- process(sym)
39
+ process(sym) || s(:lvar, :"")
39
40
  end
40
41
 
41
42
  def process_block_var(exp)
@@ -47,10 +48,10 @@ module RipperRubyParser
47
48
  end
48
49
 
49
50
  def process_begin(exp)
50
- _, body = exp.shift 2
51
+ _, body, pos = exp.shift 3
51
52
 
52
- body = convert_empty_to_nil_symbol process(body)
53
- s(:begin, body)
53
+ body = convert_void_stmt_to_nil_symbol process(body)
54
+ with_position pos, s(:begin, body)
54
55
  end
55
56
 
56
57
  def process_rescue(exp)
@@ -58,51 +59,32 @@ module RipperRubyParser
58
59
  rescue_block = map_process_list_compact block.sexp_body
59
60
  rescue_block << nil if rescue_block.empty?
60
61
 
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
62
+ capture = handle_rescue_class_list eclass
76
63
 
77
64
  capture << create_assignment_sub_type(process(evar), s(:gvar, :$!)) if evar
78
65
 
79
- s(
80
- s(:resbody, capture, *rescue_block),
81
- *process(after))
66
+ s(s(:resbody, capture, *rescue_block), *process(after))
82
67
  end
83
68
 
84
69
  def process_bodystmt(exp)
85
70
  _, main, rescue_block, else_block, ensure_block = exp.shift 5
86
71
 
87
- body = s()
72
+ body_list = []
88
73
 
89
- main = wrap_in_block map_process_list_compact main.sexp_body
90
- body << main if main
74
+ main_block = process(main)
75
+ line = main_block.line
76
+ body_list << main_block if main_block.sexp_type != :void_stmt
91
77
 
92
- if rescue_block
93
- body.push(*process(rescue_block))
94
- body << process(else_block) if else_block
95
- body = s(s(:rescue, *body))
96
- elsif else_block
97
- body << process(else_block)
98
- end
78
+ body_list.push(*process(rescue_block)) if rescue_block
79
+ body_list << process(else_block) if else_block
80
+ body_list = [s(:rescue, *body_list)] if rescue_block
99
81
 
100
82
  if ensure_block
101
- body << process(ensure_block)
102
- body = s(s(:ensure, *body))
83
+ body_list << process(ensure_block)
84
+ body_list = [s(:ensure, *body_list)]
103
85
  end
104
86
 
105
- wrap_in_block(body) || s()
87
+ wrap_in_block(body_list, line)
106
88
  end
107
89
 
108
90
  def process_rescue_mod(exp)
@@ -138,12 +120,16 @@ module RipperRubyParser
138
120
 
139
121
  def process_lambda(exp)
140
122
  _, args, statements = exp.shift 3
123
+
141
124
  old_type = args.sexp_type
142
125
  args = convert_arguments(process(args))
126
+ statements = process(statements)
127
+ line = args.line || statements.line
143
128
  args = nil if args == s(:args) && old_type == :params
144
- make_iter(s(:call, nil, :lambda),
145
- args,
146
- safe_unwrap_void_stmt(process(statements)))
129
+ call = s(:lambda)
130
+ call.line = line
131
+
132
+ make_iter call, args, safe_unwrap_void_stmt(statements)
147
133
  end
148
134
 
149
135
  private
@@ -165,7 +151,10 @@ module RipperRubyParser
165
151
  end
166
152
 
167
153
  def handle_splat(splat)
168
- if splat && splat != 0
154
+ if splat == 0
155
+ # Only relevant for Ruby < 2.6
156
+ [s(:excessed_comma)]
157
+ elsif splat
169
158
  [process(splat)]
170
159
  else
171
160
  []
@@ -197,17 +186,24 @@ module RipperRubyParser
197
186
  [process(block)]
198
187
  end
199
188
 
200
- def convert_empty_to_nil_symbol(block)
201
- case block.length
202
- when 0
203
- s(:nil)
189
+ def handle_rescue_class_list(eclass)
190
+ if eclass.nil?
191
+ s(:array)
192
+ elsif eclass.first.is_a? Symbol
193
+ eclass = process(eclass)
194
+ body = eclass.sexp_body
195
+ if eclass.sexp_type == :mrhs
196
+ body.first
197
+ else
198
+ s(:array, *body)
199
+ end
204
200
  else
205
- block
201
+ s(:array, process(eclass.first))
206
202
  end
207
203
  end
208
204
 
209
205
  def make_iter(call, args, stmt)
210
- args.pop if args && args.last == s(:excessed_comma)
206
+ args[-1] = nil if args && args.last == s(:excessed_comma)
211
207
  args ||= 0
212
208
  if stmt.empty?
213
209
  s(:iter, call, args)
@@ -215,17 +211,6 @@ module RipperRubyParser
215
211
  s(:iter, call, args, stmt)
216
212
  end
217
213
  end
218
-
219
- def wrap_in_block(statements)
220
- case statements.length
221
- when 0
222
- nil
223
- when 1
224
- statements.first
225
- else
226
- s(:block, *statements)
227
- end
228
- end
229
214
  end
230
215
  end
231
216
  end