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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16ae34997256487e8611f1c1128bfa3f0ededad4befbdcba5cae435e957e4382
4
- data.tar.gz: 9751a46aeaa42e05bc52587fa0fee46b64e0b45204b9cbf651f7492d7e6bde90
3
+ metadata.gz: 4e4ee66b4ce6abf5b0eeacd55fd137dd7217bf728bc59f1ad6bdf0b197011f86
4
+ data.tar.gz: a35a48bfa5178c5a9cec64017842246a4acb8b10a0c09fba2749de9aa650772c
5
5
  SHA512:
6
- metadata.gz: c31670a8b6d911f7679096feb5d1b01e2c67a7aec7694eb7f4ac932c2f335f24e5996074bd0857614e8f508c093f639d644f3ab4555de97c68f1ea601f4fd586
7
- data.tar.gz: 2668135d139b2c4c5cb3da3f036bc7653896239a48846bbae4fe18056bb751f21e00618c8b2d7b90f3de3e504f4dfb959e442f3f302b253bcf777a0232329950
6
+ metadata.gz: 0574addabb87b0f843c2a72a3e5c03b6ffff2461a9f1fa551412ee706841a2baeb354c1decd3ca7c902e1e78c2c2b7c4a346784ebb6c5b1064211b4ca08b8039
7
+ data.tar.gz: cffd4a9f013b443e82b3b4d6149719b02119f182aafe86fc2984d81b131bc047bd1143ca5b06cd28dc32e71876cbb67452c9db47979a50d766e28ea7b7f590a2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,52 @@
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.9.0 / 2021-08-10
10
+
11
+ * Fix escape sequence handling in non-interpolating strings and word lists
12
+ ([#152])
13
+ * Handle strings with mixed valid and invalid utf8 ([#153])
14
+ * Handle argument forwarding, updating the RubyParser compatibility target to
15
+ 3.17.0 ([#154])
16
+ * Fix encoding for non-interpolating strings as well ([#155])
17
+
18
+ ## 1.8.0 / 2021-05-18
19
+
20
+ ### Changes
21
+
22
+ * Drop support for Ruby 2.4 ([2cf6b4050] and [#145])
23
+ * Update RubyParser compatibility target to 3.15.0 ([#105])
24
+ * Fix handling of dedented heredoc ([#106])
25
+ * Add support for running on Ruby 3.0 ([#123])
26
+ * Various code improvements and other internal changes
27
+
28
+ ## 1.7.2 / 2020-02-28
29
+
30
+ ### Bug fixes
31
+
32
+ * Support imaginary number literals ([#100])
33
+ * Handle anonymous kwrest arguments ([#95])
34
+
35
+ ### Internal changes
36
+
37
+ * Update tests ([#101])
38
+ * Prepare for testing on Ruby 2.7 ([#99])
39
+ * Various improvements ([#98])
40
+ * Split long module ([#97])
41
+
42
+ ## 1.7.1 / 2019-11-03
43
+
44
+ * Handle unicode escapes with five or six hex digits ([#94])
45
+ * Handle safe attribute assignment ([#92])
46
+ * Handle endless ranges on Ruby 2.6+ ([#90])
47
+ * Add preliminary support for Ruby 2.7 ([#89])
48
+ * Improve line number handling for stabby lambdas ([#88])
49
+
3
50
  ## 1.7.0 / 2019-11-01
4
51
 
5
52
  * Make results compatible with RubyParser 3.14.0 ([#85])
@@ -179,6 +226,27 @@
179
226
  * Initial release
180
227
 
181
228
  <!-- Pull request links -->
229
+ [#155]: https://github.com/mvz/ripper_ruby_parser/pull/155
230
+ [#154]: https://github.com/mvz/ripper_ruby_parser/pull/154
231
+ [#153]: https://github.com/mvz/ripper_ruby_parser/pull/153
232
+ [#152]: https://github.com/mvz/ripper_ruby_parser/pull/152
233
+ [#145]: https://github.com/mvz/ripper_ruby_parser/pull/145
234
+ [#123]: https://github.com/mvz/ripper_ruby_parser/pull/123
235
+ [#106]: https://github.com/mvz/ripper_ruby_parser/pull/106
236
+ [#105]: https://github.com/mvz/ripper_ruby_parser/pull/105
237
+ [#101]: https://github.com/mvz/ripper_ruby_parser/pull/101
238
+ [#100]: https://github.com/mvz/ripper_ruby_parser/pull/100
239
+ [#99]: https://github.com/mvz/ripper_ruby_parser/pull/99
240
+ [#98]: https://github.com/mvz/ripper_ruby_parser/pull/98
241
+ [#97]: https://github.com/mvz/ripper_ruby_parser/pull/97
242
+ [#95]: https://github.com/mvz/ripper_ruby_parser/pull/95
243
+ [#94]: https://github.com/mvz/ripper_ruby_parser/pull/94
244
+ [#92]: https://github.com/mvz/ripper_ruby_parser/pull/92
245
+ [#90]: https://github.com/mvz/ripper_ruby_parser/pull/90
246
+ [#89]: https://github.com/mvz/ripper_ruby_parser/pull/89
247
+ [#88]: https://github.com/mvz/ripper_ruby_parser/pull/88
248
+ [#86]: https://github.com/mvz/ripper_ruby_parser/pull/86
249
+ [#85]: https://github.com/mvz/ripper_ruby_parser/pull/85
182
250
  [#82]: https://github.com/mvz/ripper_ruby_parser/pull/82
183
251
  [#80]: https://github.com/mvz/ripper_ruby_parser/pull/80
184
252
  [#79]: https://github.com/mvz/ripper_ruby_parser/pull/79
@@ -196,3 +264,11 @@
196
264
  [#67]: https://github.com/mvz/ripper_ruby_parser/pull/67
197
265
  [#66]: https://github.com/mvz/ripper_ruby_parser/pull/66
198
266
  [#65]: https://github.com/mvz/ripper_ruby_parser/pull/65
267
+
268
+ <!-- Git sha links -->
269
+ [2cf6b4050]: https://github.com/mvz/ripper_ruby_parser/commit/2cf6b40501576003b916196e23222276b51aa53c
270
+
271
+ <!-- Other links -->
272
+
273
+ [1]: https://semver.org/spec/v2.0.0.html
274
+ [2]: https://keepachangelog.com/en/1.0.0/
data/README.md CHANGED
@@ -10,8 +10,8 @@ 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 Ruby 2.4 or higher
14
- * Compatible with RubyParser 3.14.0
13
+ * Requires Ruby 2.5 or higher
14
+ * Compatible with RubyParser 3.17.0
15
15
 
16
16
  ## Known incompatibilities
17
17
 
@@ -20,6 +20,8 @@ RipperRubyParser has a few incompatibilities with RubyParser.
20
20
  * RipperRubyParser won't handle non-UTF-8 files without an encoding comment,
21
21
  just like regular Ruby
22
22
  * RipperRubyParser does not always match RubyParser's line numbering
23
+ * RipperRubyParser dedents auto-dedenting heredocs
24
+ * RipperRubyParser does not include postfix comments
23
25
 
24
26
  ## Install
25
27
 
@@ -42,7 +44,7 @@ parser.parse "foo[bar] += baz qux"
42
44
 
43
45
  ## Requirements
44
46
 
45
- * Ruby 2.3 or higher
47
+ * Ruby 2.5 or higher
46
48
  * `sexp_processor`
47
49
 
48
50
  ## Hacking and contributing
@@ -62,7 +64,7 @@ If you want to send pull requests or patches, please:
62
64
 
63
65
  (The MIT License)
64
66
 
65
- Copyright (c) 2012, 2014-2019 Matijs van Zuijlen
67
+ Copyright (c) 2012, 2014-2020 Matijs van Zuijlen
66
68
 
67
69
  Permission is hereby granted, free of charge, to any person obtaining
68
70
  a copy of this software and associated documentation files (the
@@ -27,6 +27,8 @@ module RipperRubyParser
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
@@ -101,6 +103,18 @@ module RipperRubyParser
101
103
  @delimiter_stack.push delimiter
102
104
  end
103
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
+
104
118
  def on_heredoc_end(_delimiter)
105
119
  @delimiter_stack.pop
106
120
  end
@@ -293,28 +307,26 @@ module RipperRubyParser
293
307
  commentize(:END, super)
294
308
  end
295
309
 
296
- def on_parse_error(*args)
297
- raise SyntaxError, *args
310
+ def on_parse_error(message)
311
+ raise SyntaxError, message
298
312
  end
299
313
 
300
- def on_class_name_error(*args)
301
- raise SyntaxError, *args
314
+ def on_class_name_error(message, *)
315
+ raise SyntaxError, message
302
316
  end
303
317
 
304
- def on_alias_error(*args)
305
- raise SyntaxError, *args
318
+ def on_alias_error(message, *)
319
+ raise SyntaxError, message
306
320
  end
307
321
 
308
- def on_assign_error(*args)
309
- raise SyntaxError, *args
322
+ def on_assign_error(message, *)
323
+ raise SyntaxError, message
310
324
  end
311
325
 
312
- def on_param_error(*args)
313
- raise SyntaxError, *args
326
+ def on_param_error(message, *)
327
+ raise SyntaxError, message
314
328
  end
315
329
 
316
- private
317
-
318
330
  def commentize(_name, exp)
319
331
  (_, _kw, loc), comment = @comment_stack.pop
320
332
  @comment = ""
@@ -10,6 +10,7 @@ require "ripper_ruby_parser/sexp_handlers/loops"
10
10
  require "ripper_ruby_parser/sexp_handlers/method_calls"
11
11
  require "ripper_ruby_parser/sexp_handlers/methods"
12
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
@@ -118,8 +118,8 @@ module RipperRubyParser
118
118
  end
119
119
 
120
120
  OPERATOR_ASSIGNMENT_MAP = {
121
- '||': :op_asgn_or,
122
- '&&': :op_asgn_and
121
+ "||": :op_asgn_or,
122
+ "&&": :op_asgn_and
123
123
  }.freeze
124
124
 
125
125
  def create_operator_assignment_sub_type(lvalue, value, operator)
@@ -150,8 +150,13 @@ module RipperRubyParser
150
150
  arglist.shift
151
151
  s(:attrasgn, arr, :[]=, *arglist)
152
152
  when :field
153
- _, obj, _, (_, field) = lvalue
154
- 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
155
160
  else
156
161
  create_assignment_sub_type lvalue, value
157
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)
@@ -49,7 +50,7 @@ module RipperRubyParser
49
50
  def process_begin(exp)
50
51
  _, body, pos = exp.shift 3
51
52
 
52
- body = convert_empty_to_nil_symbol process(body)
53
+ body = convert_void_stmt_to_nil_symbol process(body)
53
54
  with_position pos, s(:begin, body)
54
55
  end
55
56
 
@@ -58,19 +59,7 @@ 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.nil?
62
- s(:array)
63
- elsif eclass.first.is_a? Symbol
64
- eclass = process(eclass)
65
- body = eclass.sexp_body
66
- if eclass.sexp_type == :mrhs
67
- body.first
68
- else
69
- s(:array, *body)
70
- end
71
- else
72
- s(:array, process(eclass.first))
73
- end
62
+ capture = handle_rescue_class_list eclass
74
63
 
75
64
  capture << create_assignment_sub_type(process(evar), s(:gvar, :$!)) if evar
76
65
 
@@ -80,23 +69,22 @@ module RipperRubyParser
80
69
  def process_bodystmt(exp)
81
70
  _, main, rescue_block, else_block, ensure_block = exp.shift 5
82
71
 
83
- body = s()
72
+ body_list = []
84
73
 
85
- main_list = map_unwrap_begin_list map_process_list main.sexp_body
86
- line = main_list.first.line
87
- main = wrap_in_block reject_void_stmt main_list
88
- 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
89
77
 
90
- body.push(*process(rescue_block)) if rescue_block
91
- body << process(else_block) if else_block
92
- body = s(s(:rescue, *body)) if rescue_block
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
93
81
 
94
82
  if ensure_block
95
- body << process(ensure_block)
96
- body = s(s(:ensure, *body))
83
+ body_list << process(ensure_block)
84
+ body_list = [s(:ensure, *body_list)]
97
85
  end
98
86
 
99
- wrap_in_block(body) || s().line(line)
87
+ wrap_in_block(body_list, line)
100
88
  end
101
89
 
102
90
  def process_rescue_mod(exp)
@@ -132,12 +120,16 @@ module RipperRubyParser
132
120
 
133
121
  def process_lambda(exp)
134
122
  _, args, statements = exp.shift 3
123
+
135
124
  old_type = args.sexp_type
136
125
  args = convert_arguments(process(args))
126
+ statements = process(statements)
127
+ line = args.line || statements.line
137
128
  args = nil if args == s(:args) && old_type == :params
138
- make_iter(s(:lambda),
139
- args,
140
- 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)
141
133
  end
142
134
 
143
135
  private
@@ -194,12 +186,19 @@ module RipperRubyParser
194
186
  [process(block)]
195
187
  end
196
188
 
197
- def convert_empty_to_nil_symbol(block)
198
- case block.length
199
- when 0
200
- 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
201
200
  else
202
- block
201
+ s(:array, process(eclass.first))
203
202
  end
204
203
  end
205
204
 
@@ -212,17 +211,6 @@ module RipperRubyParser
212
211
  s(:iter, call, args, stmt)
213
212
  end
214
213
  end
215
-
216
- def wrap_in_block(statements)
217
- case statements.length
218
- when 0
219
- nil
220
- when 1
221
- statements.first
222
- else
223
- s(:block, *statements)
224
- end
225
- end
226
214
  end
227
215
  end
228
216
  end
@@ -47,33 +47,20 @@ module RipperRubyParser
47
47
 
48
48
  def process_case(exp)
49
49
  _, expr, clauses = exp.shift 3
50
- s(:case, process(expr), *process(clauses))
50
+ s(:case, process(expr), *process(clauses).sexp_body)
51
51
  end
52
52
 
53
53
  def process_when(exp)
54
54
  _, values, truepart, falsepart = exp.shift 4
55
55
 
56
- falsepart = process(falsepart)
57
- falsepart = unwrap_nil falsepart if falsepart
58
-
59
- if falsepart.nil?
60
- falsepart = [nil]
61
- elsif falsepart.first.is_a? Symbol
62
- falsepart = s(falsepart)
63
- end
56
+ falsepart ||= s(:void_stmt)
64
57
 
58
+ falsepart = unwrap_case_body process(falsepart)
65
59
  values = process(values).sexp_body
60
+ truepart = unwrap_block process(truepart)
66
61
 
67
- truepart = map_process_list_compact truepart.sexp_body
68
- truepart = if truepart.empty?
69
- [nil]
70
- else
71
- unwrap_block(truepart.shift) + truepart
72
- end
73
-
74
- s(s(:when,
75
- s(:array, *values),
76
- *truepart),
62
+ s(:case_body,
63
+ s(:when, s(:array, *values), *truepart),
77
64
  *falsepart)
78
65
  end
79
66
 
@@ -109,6 +96,17 @@ module RipperRubyParser
109
96
  s(:if, cond, truepart, falsepart)
110
97
  end
111
98
  end
99
+
100
+ def unwrap_case_body(exp)
101
+ case exp.sexp_type
102
+ when :case_body
103
+ exp.sexp_body
104
+ when :void_stmt
105
+ [nil]
106
+ else
107
+ [exp]
108
+ end
109
+ end
112
110
  end
113
111
  end
114
112
  end