ripper_ruby_parser 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
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