ripper_ruby_parser 1.5.1 → 1.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bad890447c64972884e94b2470b0fcb8114aad1af6e9b44c27d05f1187a789d3
4
- data.tar.gz: ea2965906b883f6b8f1d7481cd04d89c3d1dcc57c8bba022adfc27b1af01df1a
3
+ metadata.gz: cc516bb8bd2fd0f9fd310f848dbf272481d6c15a8ee3aeecba41ac8e24a7b8c3
4
+ data.tar.gz: 2d79ba2d094e3694993f48e92565c7424121331aad653bd6cb5fad51a7f9ea75
5
5
  SHA512:
6
- metadata.gz: c4ef6f13a7914774863c9503dfd27dd099e5adf1f122c7f7f38105b9b7570a7dfe5b51ac744a2a7a200b6c7012937477a933f2651b7e48e7b41b70a81f6bb7dc
7
- data.tar.gz: c28f34964b94a8d7bd28fb47924d8ffd7f99104bb22ce90de48ed6b9ac2c1b32b789bf5c5059bc02c7d29ae5d98622cfc72f0d41d6eba6fc77f177e65679917e
6
+ metadata.gz: 2d521a088a674f96b3639d624de7ababb6dbea93965fee1185b6a14f8a289ef88566a87cc5918004d3765f19de7ea0a15d99cfb30792ff519e1d8426555bb162
7
+ data.tar.gz: 0a79e0832ce26282bacb13d534dde0460f33b677e7a07c23bde4d530848228bda65460ce2c229a97ddc25c5f12cc0aa75ea176f09e3959fcbf78e34536fa6bcd
@@ -1,9 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.6.0 / 2019-04-12
4
+
5
+ * Fix line numbering for range literals ([#79])
6
+ * Match handling of carriage returns in heredocs in extra-compatible mode
7
+ ([#77], [#78])
8
+ * Match RubyParser behavior for current Ruby rather than latest Ruby ([#76])
9
+ - Adjust integration tests to compare against `RubyParser.for_current_ruby`
10
+ - Remove extra-compatible handling of `rescue` modifier
11
+ * Handle directly nested parentheses in destructuring ([#75])
12
+ * Make results compatible with RubyParser 3.13.1 ([#74])
13
+ - Remove extra-compatible handling of string literals
14
+ * Improve compatibility for when clauses containing `begin..end` blocks ([#73])
15
+ * Handle use of backtick as a symbol ([#72])
16
+ * Improve string handling compatibility ([#71])
17
+ - Interpolation with `__FILE__` keyword
18
+ - Line continuation after interpolation for indentable heredocs
19
+ - Nested interpolations
20
+ * Handle method argument destructuring ([#70])
21
+ * Improve compatibility of operator assignment ([#69])
22
+ * Handle multiple assignment with RHS that is a block ([#68])
23
+ * Improve compatibility of handling escaped line-endings ([#67])
24
+ * Make results compatible with RubyParser 3.13.0 ([#65])
25
+ - Change result for `BEGIN { foo }`
26
+ - Remove extra-compatible handling of rescue modifier
27
+
3
28
  ## 1.5.1 / 2019-03-21
4
29
 
5
30
  * Fix handling of singleton methods whose names are keywords
6
- ([#66](https://github.com/mvz/ripper_ruby_parser/pull/66))
31
+ ([#66])
7
32
 
8
33
  ## 1.5.0 / 2019-03-18
9
34
 
@@ -131,3 +156,20 @@
131
156
  ## 0.0.1 / 2012-03-11
132
157
 
133
158
  * Initial release
159
+
160
+ <!-- Pull request links -->
161
+ [#79]: https://github.com/mvz/ripper_ruby_parser/pull/79
162
+ [#78]: https://github.com/mvz/ripper_ruby_parser/pull/78
163
+ [#77]: https://github.com/mvz/ripper_ruby_parser/pull/77
164
+ [#76]: https://github.com/mvz/ripper_ruby_parser/pull/76
165
+ [#75]: https://github.com/mvz/ripper_ruby_parser/pull/75
166
+ [#74]: https://github.com/mvz/ripper_ruby_parser/pull/74
167
+ [#73]: https://github.com/mvz/ripper_ruby_parser/pull/73
168
+ [#72]: https://github.com/mvz/ripper_ruby_parser/pull/72
169
+ [#71]: https://github.com/mvz/ripper_ruby_parser/pull/71
170
+ [#70]: https://github.com/mvz/ripper_ruby_parser/pull/70
171
+ [#69]: https://github.com/mvz/ripper_ruby_parser/pull/69
172
+ [#68]: https://github.com/mvz/ripper_ruby_parser/pull/68
173
+ [#67]: https://github.com/mvz/ripper_ruby_parser/pull/67
174
+ [#66]: https://github.com/mvz/ripper_ruby_parser/pull/66
175
+ [#65]: https://github.com/mvz/ripper_ruby_parser/pull/65
data/README.md CHANGED
@@ -11,7 +11,7 @@ Parse with Ripper, produce sexps that are compatible with RubyParser.
11
11
  * Drop-in replacement for RubyParser
12
12
  * Should handle 1.9 and later syntax gracefully
13
13
  * Requires MRI 2.3 or higher
14
- * Compatible with RubyParser 3.12.0
14
+ * Compatible with RubyParser 3.13.1
15
15
 
16
16
  ## Known incompatibilities
17
17
 
@@ -22,22 +22,16 @@ The following incompatibilities cannot be changed:
22
22
 
23
23
  * RipperRubyParser won't handle non-UTF-8 files without an encoding comment,
24
24
  just like regular Ruby
25
- * RipperRubyParser keeps carriage return characters in heredocs that include them
26
25
  * RipperRubyParser does not attempt to match RubyParser's line numbering bugs
26
+ * RipperRubyParser correctly dedents heredocs with interpolations
27
27
 
28
28
  The following incompatibilities can be made compatible by turning on
29
29
  extra-compatible mode:
30
30
 
31
- * RipperRubyParser handles unicode escapes without braces correctly, while
32
- RubyParser absorbs trailing hexadecimal characters
33
- * RipperRubyParser handles the rescue modifier correctly, while RubyParser
34
- still contains a bug that was fixed in Ruby 2.4. See RubyParser
35
- [issue #227](https://github.com/seattlerb/ruby_parser/issues/227).
36
- * RubyParser handles byte sequences in second and further literal parts of a
37
- strings with interpolations differently. RipperRubyParser will convert these
38
- to unicode if possible.
39
- * RubyParser handles byte sequences in heredocs and interpolating word lists
40
- differently. RipperRubyParser will convert these to unicode if possible.
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
41
35
 
42
36
  ## Install
43
37
 
@@ -45,23 +39,29 @@ extra-compatible mode:
45
39
 
46
40
  ## Synopsis
47
41
 
48
- require 'ripper_ruby_parser'
49
-
50
- parser = RipperRubyParser::Parser.new
51
- parser.parse "puts 'Hello World'"
52
- # => s(:call, nil, :puts, s(:arglist, s(:str, "Hello World!")))
53
-
54
- parser.parse '"foo\u273bbar"'
55
- # => s(:str, "foo✻bar")
56
-
57
- parser.extra_compatible = true
58
-
59
- parser.parse '"foo\u273bbar"'
60
- # => s(:str, "foo✻r")
42
+ ```ruby
43
+ require 'ripper_ruby_parser'
44
+
45
+ parser = RipperRubyParser::Parser.new
46
+ parser.parse "puts 'Hello World'"
47
+ # => s(:call, nil, :puts, s(:str, "Hello World!"))
48
+ parser.parse "foo[bar] += baz qux"
49
+ # => s(:op_asgn1, s(:call, nil, :foo),
50
+ # s(:arglist, s(:call, nil, :bar)),
51
+ # :+,
52
+ # 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
+ ```
61
61
 
62
62
  ## Requirements
63
63
 
64
- * Ruby 2.2 or higher
64
+ * Ruby 2.3 or higher
65
65
  * `sexp_processor`
66
66
 
67
67
  ## Hacking and contributing
@@ -81,7 +81,7 @@ If you want to send pull requests or patches, please:
81
81
 
82
82
  (The MIT License)
83
83
 
84
- Copyright (c) 2012, 2014-2018 Matijs van Zuijlen
84
+ Copyright (c) 2012, 2014-2019 Matijs van Zuijlen
85
85
 
86
86
  Permission is hereby granted, free of charge, to any person obtaining
87
87
  a copy of this software and associated documentation files (the
@@ -29,6 +29,7 @@ module RipperRubyParser
29
29
 
30
30
  def on_backtick(delimiter)
31
31
  @delimiter_stack.push delimiter
32
+ super
32
33
  end
33
34
 
34
35
  def on_comment(tok)
@@ -6,11 +6,6 @@ module RipperRubyParser
6
6
  module Assignment
7
7
  def process_assign(exp)
8
8
  _, lvalue, value = exp.shift 3
9
- if extra_compatible && value.sexp_type == :rescue_mod
10
- if [:command, :command_call].include? value[1].sexp_type
11
- return process s(:rescue_mod, s(:assign, lvalue, value[1]), value[2])
12
- end
13
- end
14
9
 
15
10
  lvalue = process(lvalue)
16
11
  value = process(value)
@@ -40,7 +35,7 @@ module RipperRubyParser
40
35
  when :mrhs
41
36
  _, right = right
42
37
  else
43
- right = s(:to_ary, right)
38
+ right = s(:to_ary, unwrap_begin(right))
44
39
  end
45
40
 
46
41
  s(:masgn, left, right)
@@ -83,7 +78,11 @@ module RipperRubyParser
83
78
  def process_mlhs_paren(exp)
84
79
  _, contents = exp.shift 2
85
80
 
86
- process(contents)
81
+ if contents.sexp_type == :mlhs_paren
82
+ s(:masgn, s(:array, process(contents)))
83
+ else
84
+ process(contents)
85
+ end
87
86
  end
88
87
 
89
88
  def process_mlhs(exp)
@@ -97,10 +96,11 @@ module RipperRubyParser
97
96
  _, lvalue, (_, operator,), value = exp.shift 4
98
97
 
99
98
  lvalue = process(lvalue)
99
+ original_value_type = value.sexp_type
100
100
  value = process(value)
101
101
  operator = operator.chop.to_sym
102
102
 
103
- create_operator_assignment_sub_type lvalue, value, operator
103
+ create_operator_assignment_sub_type lvalue, value, operator, original_value_type
104
104
  end
105
105
 
106
106
  private
@@ -123,11 +123,16 @@ module RipperRubyParser
123
123
  '&&': :op_asgn_and
124
124
  }.freeze
125
125
 
126
- def create_operator_assignment_sub_type(lvalue, value, operator)
126
+ def create_operator_assignment_sub_type(lvalue, value, operator, original_value_type)
127
127
  case lvalue.sexp_type
128
128
  when :aref_field
129
129
  _, arr, arglist = lvalue
130
- arglist.sexp_type = :arglist
130
+ arglist.sexp_type = if extra_compatible &&
131
+ [:command, :command_call].include?(original_value_type)
132
+ :array
133
+ else
134
+ :arglist
135
+ end
131
136
  s(:op_asgn1, arr, arglist, operator, value)
132
137
  when :field
133
138
  _, obj, _, (_, field) = lvalue
@@ -10,7 +10,7 @@ module RipperRubyParser
10
10
  call = process(call)
11
11
  args = process(args)
12
12
  kwrest = kwrest_param(args) if args
13
- stmt = with_block_kwrest(kwrest) { process(stmt) }
13
+ stmt = with_kwrest(kwrest) { process(stmt) }
14
14
  make_iter call, args, safe_unwrap_void_stmt(stmt)
15
15
  end
16
16
 
@@ -43,7 +43,7 @@ module RipperRubyParser
43
43
 
44
44
  names = process(args)
45
45
 
46
- convert_block_args names
46
+ convert_arguments names
47
47
  end
48
48
 
49
49
  def process_begin(exp)
@@ -107,6 +107,7 @@ module RipperRubyParser
107
107
 
108
108
  def process_rescue_mod(exp)
109
109
  _, scary, safe = exp.shift 3
110
+
110
111
  s(:rescue, process(scary), s(:resbody, s(:array), process(safe)))
111
112
  end
112
113
 
@@ -138,7 +139,7 @@ module RipperRubyParser
138
139
  def process_lambda(exp)
139
140
  _, args, statements = exp.shift 3
140
141
  old_type = args.sexp_type
141
- args = convert_method_args(process(args))
142
+ args = convert_arguments(process(args))
142
143
  args = nil if args == s(:args) && old_type == :params
143
144
  make_iter(s(:call, nil, :lambda),
144
145
  args,
@@ -225,35 +226,6 @@ module RipperRubyParser
225
226
  s(:block, *statements)
226
227
  end
227
228
  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
257
229
  end
258
230
  end
259
231
  end
@@ -65,7 +65,11 @@ module RipperRubyParser
65
65
  values = process(values).sexp_body
66
66
 
67
67
  truepart = map_process_list_compact truepart.sexp_body
68
- truepart = [nil] if truepart.empty?
68
+ truepart = if truepart.empty?
69
+ [nil]
70
+ else
71
+ unwrap_block(truepart.shift) + truepart
72
+ end
69
73
 
70
74
  s(s(:when,
71
75
  s(:array, *values),
@@ -80,6 +80,14 @@ module RipperRubyParser
80
80
  end
81
81
  end
82
82
 
83
+ def unwrap_block(exp)
84
+ if exp.sexp_type == :block
85
+ exp.sexp_body
86
+ else
87
+ [exp]
88
+ end
89
+ end
90
+
83
91
  def handle_return_argument_list(arglist)
84
92
  args = process(arglist).sexp_body
85
93
 
@@ -28,19 +28,19 @@ module RipperRubyParser
28
28
  val = process(list.sexp_body.first)
29
29
 
30
30
  case val.sexp_type
31
- when :str
31
+ when :str, :dstr
32
32
  val
33
33
  when :void_stmt
34
- s(:dstr, s(:evstr))
34
+ s(:dstr, '', s(:evstr))
35
35
  else
36
- s(:dstr, s(:evstr, val))
36
+ s(:dstr, '', s(:evstr, val))
37
37
  end
38
38
  end
39
39
 
40
40
  def process_string_dvar(exp)
41
41
  _, list = exp.shift 2
42
42
  val = process(list)
43
- s(:dstr, s(:evstr, val))
43
+ s(:dstr, '', s(:evstr, val))
44
44
  end
45
45
 
46
46
  def process_string_concat(exp)
@@ -164,40 +164,44 @@ module RipperRubyParser
164
164
  private
165
165
 
166
166
  def extract_string_parts(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
167
+ return '', [] if list.empty?
168
+
169
+ list = merge_raw_string_literals list
170
+ list = map_process_list list
171
+
172
+ parts = list.flat_map do |item|
173
+ type, val, *rest = item
174
+ if type == :dstr
175
+ if val.empty?
176
+ rest
177
+ else
178
+ [s(:str, val), *rest]
179
+ end
180
+ else
181
+ [item]
177
182
  end
178
183
  end
179
184
 
180
185
  string = ''
181
- while !parts.empty? && parts.first.sexp_type == :str
186
+ while parts.first&.sexp_type == :str
182
187
  str = parts.shift
183
188
  string += str.last
184
189
  end
185
190
 
186
- rest = parts.map { |se| se.sexp_type == :dstr ? se.last : se }
187
-
188
- return string, rest
191
+ return string, parts
189
192
  end
190
193
 
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)
194
+ def merge_raw_string_literals(list)
195
+ chunks = list.chunk { |it| it.sexp_type == :@tstring_content }
196
+ chunks.flat_map do |is_simple, items|
197
+ if is_simple && items.count > 1
198
+ head = items.first
199
+ contents = items.map { |it| it[1] }.join
200
+ [s(:@tstring_content, contents, head[2], head[3])]
201
+ else
202
+ items
203
+ end
204
+ end
201
205
  end
202
206
 
203
207
  def character_flags_to_numerical(flags)
@@ -251,7 +255,13 @@ module RipperRubyParser
251
255
 
252
256
  def handle_string_unescaping(content, delim)
253
257
  case delim
254
- when INTERPOLATING_HEREDOC, *INTERPOLATING_STRINGS
258
+ when INTERPOLATING_HEREDOC
259
+ if extra_compatible
260
+ unescape(content).delete("\r")
261
+ else
262
+ unescape(content)
263
+ end
264
+ when *INTERPOLATING_STRINGS
255
265
  unescape(content)
256
266
  when INTERPOLATING_WORD_LIST
257
267
  unescape_wordlist_word(content)
@@ -268,13 +278,7 @@ module RipperRubyParser
268
278
 
269
279
  def handle_string_encoding(string, delim)
270
280
  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
281
+ when INTERPOLATING_HEREDOC, INTERPOLATING_WORD_LIST, *INTERPOLATING_STRINGS
278
282
  fix_encoding string
279
283
  else
280
284
  string