ripper_ruby_parser 1.8.0 → 1.9.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: 799011b06831426c0ebecad641082d58bfaa8da0aea9359a3a2d152ea01bd196
4
- data.tar.gz: eec3804031490d2382f59ddc450af14f73b696b9e14f0d2919b64a3df3557853
3
+ metadata.gz: 4e4ee66b4ce6abf5b0eeacd55fd137dd7217bf728bc59f1ad6bdf0b197011f86
4
+ data.tar.gz: a35a48bfa5178c5a9cec64017842246a4acb8b10a0c09fba2749de9aa650772c
5
5
  SHA512:
6
- metadata.gz: eab6dc676f7c5806bcd09f9adf87e5b67dd5320e043c07370014fdfc8e5ca1dffbaa9583754ac74bc354a30c6b27392c3310a7172b20699d475d9122e9dae748
7
- data.tar.gz: b776c9d833e7808c7b2ac17ec6bb5a358a93cb1bb925ee94199aeddf85c0cca2e102cdcdfff17ca8d17ac406e0f76c4b981b640085fbd02d2868bca36fdd840d
6
+ metadata.gz: 0574addabb87b0f843c2a72a3e5c03b6ffff2461a9f1fa551412ee706841a2baeb354c1decd3ca7c902e1e78c2c2b7c4a346784ebb6c5b1064211b4ca08b8039
7
+ data.tar.gz: cffd4a9f013b443e82b3b4d6149719b02119f182aafe86fc2984d81b131bc047bd1143ca5b06cd28dc32e71876cbb67452c9db47979a50d766e28ea7b7f590a2
data/CHANGELOG.md CHANGED
@@ -6,6 +6,15 @@ This project adheres to [Semantic Versioning 2.0.0][1].
6
6
 
7
7
  This document is formatted based on [Keep A CHANGELOG][2].
8
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
+
9
18
  ## 1.8.0 / 2021-05-18
10
19
 
11
20
  ### Changes
@@ -217,6 +226,10 @@ This document is formatted based on [Keep A CHANGELOG][2].
217
226
  * Initial release
218
227
 
219
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
220
233
  [#145]: https://github.com/mvz/ripper_ruby_parser/pull/145
221
234
  [#123]: https://github.com/mvz/ripper_ruby_parser/pull/123
222
235
  [#106]: https://github.com/mvz/ripper_ruby_parser/pull/106
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 Ruby 2.5 or higher
14
- * Compatible with RubyParser 3.15.0
14
+ * Compatible with RubyParser 3.17.0
15
15
 
16
16
  ## Known incompatibilities
17
17
 
@@ -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)
@@ -7,7 +7,7 @@ module RipperRubyParser
7
7
  # character literals
8
8
  def process_at_CHAR(exp)
9
9
  _, val, pos = exp.shift 3
10
- with_position(pos, s(:str, unescape(val[1..-1])))
10
+ with_position(pos, s(:str, fix_encoding(unescape(val[1..-1]))))
11
11
  end
12
12
 
13
13
  def process_array(exp)
@@ -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
@@ -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
@@ -123,8 +123,7 @@ module RipperRubyParser
123
123
 
124
124
  def process_at_tstring_content(exp)
125
125
  _, content, pos, delim = exp.shift 4
126
- string = handle_string_unescaping(content, delim)
127
- string = handle_string_encoding(string, delim)
126
+ string = fix_encoding handle_string_unescaping(content, delim)
128
127
  with_position(pos, s(:str, string))
129
128
  end
130
129
 
@@ -243,24 +242,15 @@ module RipperRubyParser
243
242
  when INTERPOLATING_WORD_LIST
244
243
  unescape_wordlist_word(content)
245
244
  when *NON_INTERPOLATING_STRINGS
246
- simple_unescape(content)
245
+ simple_unescape(content, delim)
247
246
  when *REGEXP_LITERALS
248
247
  unescape_regexp(content)
249
248
  when NON_INTERPOLATING_WORD_LIST
250
- simple_unescape_wordlist_word(content)
249
+ simple_unescape_wordlist_word(content, delim)
251
250
  else
252
251
  content
253
252
  end
254
253
  end
255
-
256
- def handle_string_encoding(string, delim)
257
- case delim
258
- when INTERPOLATING_HEREDOC, INTERPOLATING_WORD_LIST, *INTERPOLATING_STRINGS
259
- fix_encoding string
260
- else
261
- string
262
- end
263
- end
264
254
  end
265
255
  end
266
256
  end
@@ -37,25 +37,34 @@ module RipperRubyParser
37
37
  SINGLE_LETTER_ESCAPES_REGEXP =
38
38
  Regexp.new("^[#{SINGLE_LETTER_ESCAPES.keys.join}]$")
39
39
 
40
- def simple_unescape(string)
40
+ DELIMITER_PAIRS = {
41
+ "(" => "()",
42
+ "<" => "<>",
43
+ "[" => "[]",
44
+ "{" => "{}"
45
+ }.freeze
46
+
47
+ def simple_unescape(string, delimiter)
48
+ delimiters = delimiter_regexp_pattern(delimiter)
41
49
  string.gsub(/
42
50
  \\ # a backslash
43
51
  ( # followed by a
44
- ' | # single quote or
45
- \\ # backslash
52
+ #{delimiters} | # delimiter or
53
+ \\ # backslash
46
54
  )/x) do
47
55
  Regexp.last_match[1]
48
56
  end
49
57
  end
50
58
 
51
- def simple_unescape_wordlist_word(string)
59
+ def simple_unescape_wordlist_word(string, delimiter)
60
+ delimiters = delimiter_regexp_pattern(delimiter)
52
61
  string.gsub(/
53
62
  \\ # a backslash
54
63
  ( # followed by a
55
- ' | # single quote or
56
- \\ | # backslash or
57
- [ ] | # space or
58
- \n # newline
64
+ #{delimiters} | # delimiter or
65
+ \\ | # backslash or
66
+ [ ] | # space or
67
+ \n # newline
59
68
  )
60
69
  /x) do
61
70
  Regexp.last_match[1]
@@ -63,12 +72,14 @@ module RipperRubyParser
63
72
  end
64
73
 
65
74
  def unescape(string)
75
+ string = string.dup if string.frozen?
76
+ string.force_encoding("ASCII-8BIT")
66
77
  string.gsub(ESCAPE_SEQUENCE_REGEXP) do
67
78
  bare = Regexp.last_match[1]
68
79
  if bare == "\n"
69
80
  ""
70
81
  else
71
- unescaped_value(bare)
82
+ unescaped_value(bare).force_encoding("ASCII-8BIT")
72
83
  end
73
84
  end
74
85
  end
@@ -105,7 +116,7 @@ module RipperRubyParser
105
116
  def unescaped_value(bare)
106
117
  case bare
107
118
  when SINGLE_LETTER_ESCAPES_REGEXP
108
- SINGLE_LETTER_ESCAPES[bare]
119
+ SINGLE_LETTER_ESCAPES[bare].dup
109
120
  when /^x/
110
121
  unescape_hex_char bare
111
122
  when /^u/
@@ -164,5 +175,11 @@ module RipperRubyParser
164
175
  def meta(val)
165
176
  val | 0b1000_0000
166
177
  end
178
+
179
+ def delimiter_regexp_pattern(delimiter)
180
+ delimiter = delimiter[-1]
181
+ delimiters = DELIMITER_PAIRS.fetch(delimiter, delimiter)
182
+ delimiters.each_char.map { |it| Regexp.escape it }.join(" | ")
183
+ end
167
184
  end
168
185
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RipperRubyParser
4
- VERSION = "1.8.0"
4
+ VERSION = "1.9.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ripper_ruby_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matijs van Zuijlen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-18 00:00:00.000000000 Z
11
+ date: 2021-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sexp_processor
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '5.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest-focus
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.1
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.3.1
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: pry
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,28 +100,28 @@ dependencies:
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: 1.15.0
103
+ version: 1.18.0
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: 1.15.0
110
+ version: 1.18.0
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: rubocop-minitest
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: 0.12.1
117
+ version: 0.15.0
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
122
  - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: 0.12.1
124
+ version: 0.15.0
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: rubocop-performance
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +142,14 @@ dependencies:
128
142
  requirements:
129
143
  - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: 3.16.0
145
+ version: 3.17.0
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: 3.16.0
152
+ version: 3.17.0
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: sexp_processor
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -224,7 +238,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
224
238
  - !ruby/object:Gem::Version
225
239
  version: '0'
226
240
  requirements: []
227
- rubygems_version: 3.2.15
241
+ rubygems_version: 3.2.22
228
242
  signing_key:
229
243
  specification_version: 4
230
244
  summary: Parse with Ripper, produce sexps that are compatible with RubyParser.