ripper_ruby_parser 1.10.0 → 1.12.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 +4 -4
- data/CHANGELOG.md +64 -0
- data/README.md +9 -5
- data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +71 -20
- data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +46 -19
- data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +16 -8
- data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +89 -0
- data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +11 -2
- data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +5 -1
- data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +13 -9
- data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +29 -15
- data/lib/ripper_ruby_parser/sexp_handlers/string_literals.rb +23 -16
- data/lib/ripper_ruby_parser/sexp_processor.rb +5 -14
- data/lib/ripper_ruby_parser/unescape.rb +7 -3
- data/lib/ripper_ruby_parser/version.rb +1 -1
- metadata +16 -33
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e017d6c1dff36a5f33a74676c9ff3d9d069ad2210bc8e8049b26ddff56d8961b
|
|
4
|
+
data.tar.gz: 76ba1cc8e225478f4679ed0b801c69387f5c350b57fda365a6316f42c0800bba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c22fb29374df4cde3de294f1fd7f7e7b529b7a67d69522f5779ff2cb1ec83f8ea8acfdc6eb0750bf9246094989df59b586a1bb96ff3c7c6227aa51be49d8e121
|
|
7
|
+
data.tar.gz: 2d3988eebde86cc80dbcd8079941e00cd3edc4263a105590d608cb37622284cb96bf9cff923b8514d31fd8b4cddaaafdbab270f077d49f0326960c6645577f3b
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,68 @@ 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.12.0 / 2025-10-25
|
|
10
|
+
|
|
11
|
+
* Target compatibility with `ruby_parser` 3.21 ([#256] by [mvz])
|
|
12
|
+
* Support Ruby 3.2 through 3.4, dropping support for Ruby 3.0 and 3.1
|
|
13
|
+
([#255] and [#260] by [mvz])
|
|
14
|
+
|
|
15
|
+
[#255]: https://github.com/mvz/ripper_ruby_parser/pull/255
|
|
16
|
+
[#256]: https://github.com/mvz/ripper_ruby_parser/pull/256
|
|
17
|
+
[#260]: https://github.com/mvz/ripper_ruby_parser/pull/260
|
|
18
|
+
|
|
19
|
+
## 1.11.0 / 2024-01-05
|
|
20
|
+
|
|
21
|
+
* Support Ruby 3.0 through 3.3, dropping support for Ruby 2.6 and 2.7
|
|
22
|
+
([#218], [#219], [#233] and [#246] by [mvz])
|
|
23
|
+
* Target compatibility with `ruby_parser` version 3.20.2
|
|
24
|
+
([#199], [#216] and [#230] by [mvz])
|
|
25
|
+
* Support single-line pattern matching ([#188] by [mvz])
|
|
26
|
+
* Support rightward assignment ([#189] by [mvz])
|
|
27
|
+
* Support endless methods with Ruby 3.0 syntax ([#191] by [mvz])
|
|
28
|
+
* Support arguments without parentheses in endless method body ([#193] by [mvz])
|
|
29
|
+
* Add support for pattern matching ([#172] by [mvz])
|
|
30
|
+
* Add tentative support for numbered parameters ([#163] by [mvz])
|
|
31
|
+
* Support several new Ruby 3.1 syntax features ([#196] by [mvz])
|
|
32
|
+
* Support negative rational and imaginary literals ([#197] by [mvz])
|
|
33
|
+
* Correctly handle match operator with regexp literals in parentheses
|
|
34
|
+
([#200] by [mvz])
|
|
35
|
+
* Improve operator assignment handling ([#201] by [mvz])
|
|
36
|
+
* Handle literal Ctrl-? (DEL) character correctly ([#202] by [mvz])
|
|
37
|
+
* Handle method names that are keywords in method definitions ([#204] by [mvz])
|
|
38
|
+
* Improve dsym handling compatibility ([#203], [#210] by [mvz])
|
|
39
|
+
* Add support for Ruby 3.2's splat and kwsplat argument forwarding ([#231] by [mvz])
|
|
40
|
+
* Improve handling of the case .. in construction ([#234] by [mvz])
|
|
41
|
+
|
|
42
|
+
[mvz]: https://github.com/mvz
|
|
43
|
+
|
|
44
|
+
[#163]: https://github.com/mvz/ripper_ruby_parser/pull/163
|
|
45
|
+
[#172]: https://github.com/mvz/ripper_ruby_parser/pull/172
|
|
46
|
+
[#188]: https://github.com/mvz/ripper_ruby_parser/pull/188
|
|
47
|
+
[#189]: https://github.com/mvz/ripper_ruby_parser/pull/189
|
|
48
|
+
[#191]: https://github.com/mvz/ripper_ruby_parser/pull/191
|
|
49
|
+
[#193]: https://github.com/mvz/ripper_ruby_parser/pull/193
|
|
50
|
+
[#196]: https://github.com/mvz/ripper_ruby_parser/pull/196
|
|
51
|
+
[#197]: https://github.com/mvz/ripper_ruby_parser/pull/197
|
|
52
|
+
[#199]: https://github.com/mvz/ripper_ruby_parser/pull/199
|
|
53
|
+
[#200]: https://github.com/mvz/ripper_ruby_parser/pull/200
|
|
54
|
+
[#201]: https://github.com/mvz/ripper_ruby_parser/pull/201
|
|
55
|
+
[#202]: https://github.com/mvz/ripper_ruby_parser/pull/202
|
|
56
|
+
[#203]: https://github.com/mvz/ripper_ruby_parser/pull/203
|
|
57
|
+
[#204]: https://github.com/mvz/ripper_ruby_parser/pull/204
|
|
58
|
+
[#205]: https://github.com/mvz/ripper_ruby_parser/pull/205
|
|
59
|
+
[#210]: https://github.com/mvz/ripper_ruby_parser/pull/210
|
|
60
|
+
[#216]: https://github.com/mvz/ripper_ruby_parser/pull/216
|
|
61
|
+
[#218]: https://github.com/mvz/ripper_ruby_parser/pull/218
|
|
62
|
+
[#219]: https://github.com/mvz/ripper_ruby_parser/pull/219
|
|
63
|
+
[#230]: https://github.com/mvz/ripper_ruby_parser/pull/230
|
|
64
|
+
[#231]: https://github.com/mvz/ripper_ruby_parser/pull/231
|
|
65
|
+
[#232]: https://github.com/mvz/ripper_ruby_parser/pull/232
|
|
66
|
+
[#233]: https://github.com/mvz/ripper_ruby_parser/pull/233
|
|
67
|
+
[#234]: https://github.com/mvz/ripper_ruby_parser/pull/234
|
|
68
|
+
[#235]: https://github.com/mvz/ripper_ruby_parser/pull/235
|
|
69
|
+
[#246]: https://github.com/mvz/ripper_ruby_parser/pull/246
|
|
70
|
+
|
|
9
71
|
## 1.10.0 / 2022-03-13
|
|
10
72
|
|
|
11
73
|
* Handle shadow arguments ([#161])
|
|
@@ -233,6 +295,8 @@ This document is formatted based on [Keep A CHANGELOG][2].
|
|
|
233
295
|
|
|
234
296
|
<!-- Pull request links -->
|
|
235
297
|
[#180]: https://github.com/mvz/ripper_ruby_parser/pull/180
|
|
298
|
+
[#172]: https://github.com/mvz/ripper_ruby_parser/pull/172
|
|
299
|
+
[#163]: https://github.com/mvz/ripper_ruby_parser/pull/163
|
|
236
300
|
[#165]: https://github.com/mvz/ripper_ruby_parser/pull/165
|
|
237
301
|
[#161]: https://github.com/mvz/ripper_ruby_parser/pull/161
|
|
238
302
|
[#155]: https://github.com/mvz/ripper_ruby_parser/pull/155
|
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
|
|
14
|
-
* Compatible with RubyParser 3.
|
|
13
|
+
* Requires Ruby 3.2 or higher
|
|
14
|
+
* Compatible with RubyParser 3.21.0
|
|
15
15
|
|
|
16
16
|
## Known incompatibilities
|
|
17
17
|
|
|
@@ -22,10 +22,14 @@ RipperRubyParser has a few incompatibilities with RubyParser.
|
|
|
22
22
|
* RipperRubyParser does not always match RubyParser's line numbering
|
|
23
23
|
* RipperRubyParser dedents auto-dedenting heredocs
|
|
24
24
|
* RipperRubyParser does not include postfix comments
|
|
25
|
+
* With Ruby 3.4, RipperRubyParser parses variables assigned by regular
|
|
26
|
+
expressions as local variables
|
|
25
27
|
|
|
26
28
|
## Install
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
```bash
|
|
31
|
+
gem install ripper_ruby_parser
|
|
32
|
+
```
|
|
29
33
|
|
|
30
34
|
## Synopsis
|
|
31
35
|
|
|
@@ -44,7 +48,7 @@ parser.parse "foo[bar] += baz qux"
|
|
|
44
48
|
|
|
45
49
|
## Requirements
|
|
46
50
|
|
|
47
|
-
* Ruby 2
|
|
51
|
+
* Ruby 3.2 or higher
|
|
48
52
|
* `sexp_processor`
|
|
49
53
|
|
|
50
54
|
## Hacking and contributing
|
|
@@ -64,7 +68,7 @@ If you want to send pull requests or patches, please:
|
|
|
64
68
|
|
|
65
69
|
(The MIT License)
|
|
66
70
|
|
|
67
|
-
Copyright (c) 2012, 2014-
|
|
71
|
+
Copyright (c) 2012, 2014-2025 Matijs van Zuijlen
|
|
68
72
|
|
|
69
73
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
70
74
|
a copy of this software and associated documentation files (the
|
|
@@ -8,6 +8,7 @@ module RipperRubyParser
|
|
|
8
8
|
# Variant of Ripper's SexpBuilder parser class that inserts comments as
|
|
9
9
|
# Sexps into the built parse tree.
|
|
10
10
|
#
|
|
11
|
+
# rubocop: disable Metrics/ClassLength
|
|
11
12
|
# @api private
|
|
12
13
|
class CommentingRipperParser < Ripper::SexpBuilder
|
|
13
14
|
def initialize(*args)
|
|
@@ -35,7 +36,16 @@ module RipperRubyParser
|
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def on_begin(*args)
|
|
38
|
-
|
|
39
|
+
result = super
|
|
40
|
+
|
|
41
|
+
# Some begin blocks are not created by the 'begin' keyword. Skip
|
|
42
|
+
# commenting for those kinds of blocks.
|
|
43
|
+
(_, kw,), = @comment_stack.last
|
|
44
|
+
if kw == "begin"
|
|
45
|
+
commentize("begin", result)
|
|
46
|
+
else
|
|
47
|
+
result
|
|
48
|
+
end
|
|
39
49
|
end
|
|
40
50
|
|
|
41
51
|
def on_void_stmt
|
|
@@ -60,35 +70,39 @@ module RipperRubyParser
|
|
|
60
70
|
end
|
|
61
71
|
|
|
62
72
|
def on_kw(tok)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
super.tap do |result|
|
|
74
|
+
next if @in_symbol
|
|
75
|
+
|
|
76
|
+
case tok
|
|
77
|
+
when "class", "def", "module", "BEGIN", "begin", "END"
|
|
67
78
|
@comment_stack.push [result, @comment]
|
|
68
79
|
@comment = ""
|
|
80
|
+
when "end"
|
|
81
|
+
@comment = "" if @comment_stack.any?
|
|
69
82
|
end
|
|
70
83
|
end
|
|
71
|
-
result
|
|
72
84
|
end
|
|
73
85
|
|
|
74
86
|
def on_module(*args)
|
|
75
|
-
commentize(
|
|
87
|
+
commentize("module", super)
|
|
76
88
|
end
|
|
77
89
|
|
|
78
90
|
def on_class(*args)
|
|
79
|
-
commentize(
|
|
91
|
+
commentize("class", super)
|
|
80
92
|
end
|
|
81
93
|
|
|
82
94
|
def on_sclass(*args)
|
|
83
|
-
commentize(
|
|
95
|
+
commentize("class", super)
|
|
84
96
|
end
|
|
85
97
|
|
|
86
|
-
def on_def(*args)
|
|
87
|
-
|
|
98
|
+
def on_def(name, *args)
|
|
99
|
+
(_, _, loc) = name
|
|
100
|
+
commentize("def", super, loc)
|
|
88
101
|
end
|
|
89
102
|
|
|
90
|
-
def on_defs(*
|
|
91
|
-
|
|
103
|
+
def on_defs(receiver, period, name, *rest)
|
|
104
|
+
(_, _, loc) = name
|
|
105
|
+
commentize("def", super, loc)
|
|
92
106
|
end
|
|
93
107
|
|
|
94
108
|
def on_args_new
|
|
@@ -209,7 +223,7 @@ module RipperRubyParser
|
|
|
209
223
|
end
|
|
210
224
|
|
|
211
225
|
def on_tstring_content(content)
|
|
212
|
-
super
|
|
226
|
+
super << @delimiter_stack.last
|
|
213
227
|
end
|
|
214
228
|
|
|
215
229
|
def on_tstring_end(delimiter)
|
|
@@ -254,6 +268,11 @@ module RipperRubyParser
|
|
|
254
268
|
@seen_space = true
|
|
255
269
|
end
|
|
256
270
|
|
|
271
|
+
def on_imaginary(_token)
|
|
272
|
+
@space_before = @seen_space
|
|
273
|
+
super
|
|
274
|
+
end
|
|
275
|
+
|
|
257
276
|
def on_int(_token)
|
|
258
277
|
@space_before = @seen_space
|
|
259
278
|
super
|
|
@@ -264,7 +283,13 @@ module RipperRubyParser
|
|
|
264
283
|
super
|
|
265
284
|
end
|
|
266
285
|
|
|
267
|
-
|
|
286
|
+
def on_rational(_token)
|
|
287
|
+
@space_before = @seen_space
|
|
288
|
+
super
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
NUMBER_LITERAL_TYPES = [:@imaginary, :@int, :@float, :@rational].freeze
|
|
292
|
+
private_constant :NUMBER_LITERAL_TYPES
|
|
268
293
|
|
|
269
294
|
def on_unary(operator, value)
|
|
270
295
|
if !@space_before && operator == :-@ && NUMBER_LITERAL_TYPES.include?(value.first)
|
|
@@ -299,16 +324,32 @@ module RipperRubyParser
|
|
|
299
324
|
super
|
|
300
325
|
end
|
|
301
326
|
|
|
327
|
+
def on_case(*args)
|
|
328
|
+
@comment = ""
|
|
329
|
+
super
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def on_ident(*args)
|
|
333
|
+
@comment = ""
|
|
334
|
+
super
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def on_string_content(*args)
|
|
338
|
+
@comment = ""
|
|
339
|
+
super
|
|
340
|
+
end
|
|
341
|
+
|
|
302
342
|
def on_BEGIN(*args)
|
|
303
|
-
commentize(
|
|
343
|
+
commentize("BEGIN", super)
|
|
304
344
|
end
|
|
305
345
|
|
|
306
346
|
def on_END(*args)
|
|
307
|
-
commentize(
|
|
347
|
+
commentize("END", super)
|
|
308
348
|
end
|
|
309
349
|
|
|
310
350
|
def on_parse_error(message)
|
|
311
|
-
|
|
351
|
+
super
|
|
352
|
+
raise SyntaxError, message if message.start_with?("syntax error,")
|
|
312
353
|
end
|
|
313
354
|
|
|
314
355
|
def on_class_name_error(message, *)
|
|
@@ -327,11 +368,21 @@ module RipperRubyParser
|
|
|
327
368
|
raise SyntaxError, message
|
|
328
369
|
end
|
|
329
370
|
|
|
330
|
-
def commentize(
|
|
331
|
-
|
|
371
|
+
def commentize(name, exp, target_loc = nil)
|
|
372
|
+
raise "Non-empty comment in progress: #{@comment}" unless @comment.empty?
|
|
373
|
+
|
|
374
|
+
if target_loc
|
|
375
|
+
(_, kw, loc), comment = @comment_stack.pop until (loc <=> target_loc) == -1
|
|
376
|
+
else
|
|
377
|
+
(_, kw, loc), comment = @comment_stack.pop
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
raise "Comment stack mismatch: expected #{kw} to equal #{name}" unless kw == name
|
|
381
|
+
|
|
332
382
|
@comment = ""
|
|
333
383
|
exp.push loc
|
|
334
384
|
[:comment, comment, exp]
|
|
335
385
|
end
|
|
336
386
|
end
|
|
387
|
+
# rubocop: enable Metrics/ClassLength
|
|
337
388
|
end
|
|
@@ -95,50 +95,75 @@ module RipperRubyParser
|
|
|
95
95
|
def process_opassign(exp)
|
|
96
96
|
_, lvalue, (_, operator,), value = exp.shift 4
|
|
97
97
|
|
|
98
|
+
value_type = value.sexp_type
|
|
99
|
+
|
|
98
100
|
lvalue = process(lvalue)
|
|
99
101
|
value = process(value)
|
|
100
102
|
operator = operator.chop.to_sym
|
|
101
103
|
|
|
102
|
-
|
|
104
|
+
case lvalue.sexp_type
|
|
105
|
+
when :aref_field
|
|
106
|
+
create_aref_operator_assignment_sub_type(lvalue, value, operator)
|
|
107
|
+
when :field
|
|
108
|
+
create_field_operator_assignment_sub_type(lvalue, value, operator, value_type)
|
|
109
|
+
else
|
|
110
|
+
create_regular_operator_assignment_sub_type(lvalue, value, operator)
|
|
111
|
+
end
|
|
103
112
|
end
|
|
104
113
|
|
|
105
114
|
private
|
|
106
115
|
|
|
107
116
|
def create_multiple_assignment_sub_types(sexp_list)
|
|
108
117
|
sexp_list.map! do |item|
|
|
109
|
-
|
|
118
|
+
create_valueless_regular_assignment_sub_type item
|
|
110
119
|
end
|
|
111
120
|
end
|
|
112
121
|
|
|
113
|
-
def
|
|
122
|
+
def create_valueless_regular_assignment_sub_type(item)
|
|
114
123
|
item = with_line_number(item.line,
|
|
115
124
|
create_regular_assignment_sub_type(item, nil))
|
|
116
125
|
item.pop
|
|
117
126
|
item
|
|
118
127
|
end
|
|
119
128
|
|
|
129
|
+
def create_valueless_assignment_sub_type(item)
|
|
130
|
+
item = with_line_number(item.line,
|
|
131
|
+
create_assignment_sub_type(item, nil))
|
|
132
|
+
item.pop
|
|
133
|
+
item
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def create_aref_operator_assignment_sub_type(lvalue, value, operator)
|
|
137
|
+
_, arr, arglist = lvalue
|
|
138
|
+
arglist.sexp_type = :arglist
|
|
139
|
+
s(:op_asgn1, arr, arglist, operator, value)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def create_field_operator_assignment_sub_type(lvalue, value, operator, value_type)
|
|
143
|
+
# Structure of lvalue will be something like this:
|
|
144
|
+
# s(:field, receiver, s(:period, "."), s(:lvar, field))
|
|
145
|
+
_, receiver, _, (_, field) = lvalue
|
|
146
|
+
case value_type
|
|
147
|
+
when :command, :command_call
|
|
148
|
+
s(:op_asgn, receiver, value, field, operator)
|
|
149
|
+
else
|
|
150
|
+
s(:op_asgn2, receiver, :"#{field}=", operator, value)
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
120
154
|
OPERATOR_ASSIGNMENT_MAP = {
|
|
121
155
|
"||": :op_asgn_or,
|
|
122
156
|
"&&": :op_asgn_and
|
|
123
157
|
}.freeze
|
|
158
|
+
private_constant :OPERATOR_ASSIGNMENT_MAP
|
|
124
159
|
|
|
125
|
-
def
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
arglist.sexp_type = :arglist
|
|
130
|
-
s(:op_asgn1, arr, arglist, operator, value)
|
|
131
|
-
when :field
|
|
132
|
-
_, obj, _, (_, field) = lvalue
|
|
133
|
-
s(:op_asgn2, obj, :"#{field}=", operator, value)
|
|
160
|
+
def create_regular_operator_assignment_sub_type(lvalue, value, operator)
|
|
161
|
+
value = unwrap_begin(value)
|
|
162
|
+
if (mapped = OPERATOR_ASSIGNMENT_MAP[operator])
|
|
163
|
+
s(mapped, lvalue, create_assignment_sub_type(lvalue, value))
|
|
134
164
|
else
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
s(mapped, lvalue, create_assignment_sub_type(lvalue, value))
|
|
138
|
-
else
|
|
139
|
-
operator_call = s(:call, lvalue, operator, value)
|
|
140
|
-
create_assignment_sub_type lvalue, operator_call
|
|
141
|
-
end
|
|
165
|
+
operator_call = s(:call, lvalue, operator, value)
|
|
166
|
+
create_assignment_sub_type lvalue, operator_call
|
|
142
167
|
end
|
|
143
168
|
end
|
|
144
169
|
|
|
@@ -174,6 +199,8 @@ module RipperRubyParser
|
|
|
174
199
|
cvar: :cvasgn
|
|
175
200
|
}.freeze
|
|
176
201
|
|
|
202
|
+
private_constant :ASSIGNMENT_SUB_TYPE_MAP, :ASSIGNMENT_IN_METHOD_SUB_TYPE_MAP
|
|
203
|
+
|
|
177
204
|
def create_assignment_sub_type(lvalue, value)
|
|
178
205
|
lvalue_type, lvalue_value = lvalue
|
|
179
206
|
s(map_assignment_lvalue_type(lvalue_type), lvalue_value, value)
|
|
@@ -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 =
|
|
13
|
+
stmt = with_new_lvar_scope(kwrest) { process(stmt) }
|
|
14
14
|
make_iter call, args, safe_unwrap_void_stmt(stmt)
|
|
15
15
|
end
|
|
16
16
|
|
|
@@ -153,16 +153,13 @@ module RipperRubyParser
|
|
|
153
153
|
|
|
154
154
|
defaults.map do |sym, val|
|
|
155
155
|
s(:lasgn,
|
|
156
|
-
|
|
156
|
+
make_symbol(process(sym)),
|
|
157
157
|
process(val))
|
|
158
158
|
end
|
|
159
159
|
end
|
|
160
160
|
|
|
161
161
|
def handle_splat(splat)
|
|
162
|
-
if splat
|
|
163
|
-
# Only relevant for Ruby < 2.6
|
|
164
|
-
[s(:excessed_comma)]
|
|
165
|
-
elsif splat
|
|
162
|
+
if splat
|
|
166
163
|
[process(splat)]
|
|
167
164
|
else
|
|
168
165
|
[]
|
|
@@ -173,7 +170,7 @@ module RipperRubyParser
|
|
|
173
170
|
return [] unless kwargs
|
|
174
171
|
|
|
175
172
|
kwargs.map do |sym, val|
|
|
176
|
-
symbol =
|
|
173
|
+
symbol = make_symbol process(sym)
|
|
177
174
|
if val
|
|
178
175
|
s(:kwarg, symbol, process(val))
|
|
179
176
|
else
|
|
@@ -217,15 +214,26 @@ module RipperRubyParser
|
|
|
217
214
|
end
|
|
218
215
|
end
|
|
219
216
|
|
|
217
|
+
LVAR_MATCHER = Sexp::Matcher.new(:lvar, Sexp._)
|
|
218
|
+
NUMBERED_PARAMS = (1..9).map { |num| :"_#{num}" }.freeze
|
|
219
|
+
private_constant :LVAR_MATCHER, :NUMBERED_PARAMS
|
|
220
|
+
|
|
220
221
|
def make_iter(call, args, stmt)
|
|
221
222
|
args[-1] = nil if args && args.last == s(:excessed_comma)
|
|
222
|
-
|
|
223
|
+
|
|
224
|
+
args ||= count_numbered_lvars(stmt)
|
|
225
|
+
|
|
223
226
|
if stmt.empty?
|
|
224
227
|
s(:iter, call, args)
|
|
225
228
|
else
|
|
226
229
|
s(:iter, call, args, stmt)
|
|
227
230
|
end
|
|
228
231
|
end
|
|
232
|
+
|
|
233
|
+
def count_numbered_lvars(stmt)
|
|
234
|
+
lvar_names = (LVAR_MATCHER / stmt).map { |match| match[1] }
|
|
235
|
+
(NUMBERED_PARAMS & lvar_names).length
|
|
236
|
+
end
|
|
229
237
|
end
|
|
230
238
|
end
|
|
231
239
|
end
|
|
@@ -64,11 +64,78 @@ module RipperRubyParser
|
|
|
64
64
|
*falsepart)
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
+
def process_in(exp)
|
|
68
|
+
_, pattern, truepart, falsepart = exp.shift 4
|
|
69
|
+
|
|
70
|
+
falsepart = process(falsepart)
|
|
71
|
+
falsepart = if falsepart.nil?
|
|
72
|
+
[nil]
|
|
73
|
+
else
|
|
74
|
+
falsepart.sexp_body
|
|
75
|
+
end
|
|
76
|
+
pattern = process(pattern)
|
|
77
|
+
adjust_rightward_assignment_pattern(pattern)
|
|
78
|
+
|
|
79
|
+
truepart = process(truepart)
|
|
80
|
+
truepart = unwrap_nil(truepart) if truepart
|
|
81
|
+
|
|
82
|
+
s(:case_body,
|
|
83
|
+
s(:in, pattern, truepart),
|
|
84
|
+
*falsepart)
|
|
85
|
+
end
|
|
86
|
+
|
|
67
87
|
def process_else(exp)
|
|
68
88
|
_, body = exp.shift 2
|
|
69
89
|
process(body)
|
|
70
90
|
end
|
|
71
91
|
|
|
92
|
+
def process_aryptn(exp)
|
|
93
|
+
_, _, body, rest, = exp.shift 5
|
|
94
|
+
|
|
95
|
+
elements = body.map do |elem|
|
|
96
|
+
if elem.sexp_type == :var_field
|
|
97
|
+
create_valueless_assignment_sub_type process(elem)
|
|
98
|
+
else
|
|
99
|
+
unwrap_begin process(elem)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
if rest
|
|
103
|
+
rest_var = handle_pattern(rest)
|
|
104
|
+
elements << convert_marked_argument(s(:splat, rest_var))
|
|
105
|
+
end
|
|
106
|
+
s(:array_pat, nil, *elements)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def process_hshptn(exp)
|
|
110
|
+
_, _, body, = exp.shift 4
|
|
111
|
+
|
|
112
|
+
elements = body.flat_map do |key, value|
|
|
113
|
+
if value
|
|
114
|
+
[process(key), process(value)]
|
|
115
|
+
else
|
|
116
|
+
[handle_pattern(key), nil]
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
s(:hash_pat, nil, *elements)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def process_fndptn(exp)
|
|
123
|
+
_, wrapper, before, patterns, after = exp.shift 5
|
|
124
|
+
|
|
125
|
+
wrapper = process(wrapper)
|
|
126
|
+
before = make_splat process(before)
|
|
127
|
+
after = make_splat process(after)
|
|
128
|
+
patterns = patterns.map do |elem|
|
|
129
|
+
if elem.sexp_type == :var_field
|
|
130
|
+
create_valueless_assignment_sub_type process(elem)
|
|
131
|
+
else
|
|
132
|
+
unwrap_begin process(elem)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
s(:find_pat, wrapper, before, *patterns, after)
|
|
137
|
+
end
|
|
138
|
+
|
|
72
139
|
private
|
|
73
140
|
|
|
74
141
|
def handle_condition(cond)
|
|
@@ -88,6 +155,24 @@ module RipperRubyParser
|
|
|
88
155
|
unwrap_nil process(exp) if exp
|
|
89
156
|
end
|
|
90
157
|
|
|
158
|
+
def handle_pattern(exp)
|
|
159
|
+
pattern = process(exp)
|
|
160
|
+
case pattern.sexp_type
|
|
161
|
+
when :lvar, :lit
|
|
162
|
+
@local_variables << pattern[1]
|
|
163
|
+
end
|
|
164
|
+
pattern
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def adjust_rightward_assignment_pattern(exp)
|
|
168
|
+
case exp.sexp_type
|
|
169
|
+
when :lvar
|
|
170
|
+
exp.sexp_type = :lasgn
|
|
171
|
+
when :lasgn
|
|
172
|
+
adjust_rightward_assignment_pattern(exp.sexp_body.last)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
91
176
|
def construct_conditional(cond, truepart, falsepart)
|
|
92
177
|
if cond.sexp_type == :not
|
|
93
178
|
_, inner = cond
|
|
@@ -107,6 +192,10 @@ module RipperRubyParser
|
|
|
107
192
|
[exp]
|
|
108
193
|
end
|
|
109
194
|
end
|
|
195
|
+
|
|
196
|
+
def make_splat(exp)
|
|
197
|
+
:"*#{exp[1]}"
|
|
198
|
+
end
|
|
110
199
|
end
|
|
111
200
|
end
|
|
112
201
|
end
|
|
@@ -4,12 +4,17 @@ module RipperRubyParser
|
|
|
4
4
|
module SexpHandlers
|
|
5
5
|
# Utility methods used in several of the sexp handler modules
|
|
6
6
|
module HelperMethods
|
|
7
|
+
def extract_node_symbol(exp)
|
|
8
|
+
ident, = extract_node_symbol_with_position(exp)
|
|
9
|
+
ident
|
|
10
|
+
end
|
|
11
|
+
|
|
7
12
|
def extract_node_symbol_with_position(exp)
|
|
8
13
|
_, ident, pos = exp.shift 3
|
|
9
14
|
return ident.to_sym, pos
|
|
10
15
|
end
|
|
11
16
|
|
|
12
|
-
def
|
|
17
|
+
def make_symbol(exp)
|
|
13
18
|
return nil if exp.nil?
|
|
14
19
|
raise "Unexpected number of children: #{exp.length}" if exp.length != 2
|
|
15
20
|
|
|
@@ -36,7 +41,11 @@ module RipperRubyParser
|
|
|
36
41
|
def generic_add_star(exp)
|
|
37
42
|
_, args, splatarg, *rest = shift_all exp
|
|
38
43
|
items = process args
|
|
39
|
-
|
|
44
|
+
if splatarg
|
|
45
|
+
items.push s(:splat, unwrap_begin(process(splatarg)))
|
|
46
|
+
else
|
|
47
|
+
items.push s(:splat)
|
|
48
|
+
end
|
|
40
49
|
items.push(*map_process_list(rest))
|
|
41
50
|
end
|
|
42
51
|
|
|
@@ -36,7 +36,11 @@ module RipperRubyParser
|
|
|
36
36
|
# s(:assoc_splat, s(:vcall, s(:@ident, "bar")))
|
|
37
37
|
def process_assoc_splat(exp)
|
|
38
38
|
_, param = exp.shift 2
|
|
39
|
-
|
|
39
|
+
if param
|
|
40
|
+
s(:kwsplat, process(param))
|
|
41
|
+
else
|
|
42
|
+
s(:kwsplat)
|
|
43
|
+
end
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
# number literals
|
|
@@ -7,12 +7,12 @@ module RipperRubyParser
|
|
|
7
7
|
def process_def(exp)
|
|
8
8
|
_, ident, params, body, pos = exp.shift 5
|
|
9
9
|
|
|
10
|
-
ident
|
|
10
|
+
ident = extract_node_symbol ident
|
|
11
11
|
|
|
12
12
|
in_method do
|
|
13
13
|
params = convert_arguments(process(params))
|
|
14
14
|
kwrest = kwrest_param(params)
|
|
15
|
-
body =
|
|
15
|
+
body = with_new_lvar_scope(kwrest) { method_body(body) }
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
with_position(pos, s(:defn, ident, params, *body))
|
|
@@ -21,12 +21,12 @@ module RipperRubyParser
|
|
|
21
21
|
def process_defs(exp)
|
|
22
22
|
_, receiver, _, ident, params, body, = exp.shift 7
|
|
23
23
|
|
|
24
|
-
ident
|
|
24
|
+
ident = extract_node_symbol ident
|
|
25
25
|
|
|
26
26
|
in_method do
|
|
27
27
|
params = convert_arguments(process(params))
|
|
28
28
|
kwrest = kwrest_param(params)
|
|
29
|
-
body =
|
|
29
|
+
body = with_new_lvar_scope(kwrest) { method_body(body) }
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
s(:defs, process(receiver), ident, params, *body)
|
|
@@ -101,8 +101,11 @@ module RipperRubyParser
|
|
|
101
101
|
dsplat: "**",
|
|
102
102
|
blockarg: "&"
|
|
103
103
|
}.freeze
|
|
104
|
+
private_constant :SPECIAL_ARG_MARKER
|
|
104
105
|
|
|
105
106
|
def convert_arguments(args)
|
|
107
|
+
return s(:args) if args.nil?
|
|
108
|
+
|
|
106
109
|
args.line ||= args.sexp_body.first&.line
|
|
107
110
|
args.sexp_body = args.sexp_body.map { |item| convert_argument item }
|
|
108
111
|
args
|
|
@@ -123,7 +126,7 @@ module RipperRubyParser
|
|
|
123
126
|
|
|
124
127
|
def convert_marked_argument(item)
|
|
125
128
|
marker = SPECIAL_ARG_MARKER[item.sexp_type]
|
|
126
|
-
name =
|
|
129
|
+
name = make_symbol item.last
|
|
127
130
|
:"#{marker}#{name}"
|
|
128
131
|
end
|
|
129
132
|
|
|
@@ -151,15 +154,16 @@ module RipperRubyParser
|
|
|
151
154
|
Regexp.last_match[1].to_sym if found
|
|
152
155
|
end
|
|
153
156
|
|
|
154
|
-
def
|
|
155
|
-
@
|
|
157
|
+
def with_new_lvar_scope(extra_variable)
|
|
158
|
+
old_lvars = @local_variables.dup
|
|
159
|
+
@local_variables.push extra_variable if extra_variable
|
|
156
160
|
result = yield
|
|
157
|
-
@
|
|
161
|
+
@local_variables = old_lvars
|
|
158
162
|
result
|
|
159
163
|
end
|
|
160
164
|
|
|
161
165
|
def kwrest_arg?(method)
|
|
162
|
-
@
|
|
166
|
+
@local_variables.include?(method)
|
|
163
167
|
end
|
|
164
168
|
end
|
|
165
169
|
end
|
|
@@ -11,27 +11,28 @@ module RipperRubyParser
|
|
|
11
11
|
or: :or
|
|
12
12
|
}.freeze
|
|
13
13
|
|
|
14
|
+
BINARY_LOGICAL_OPERATORS = BINARY_OPERATOR_MAP.keys.freeze
|
|
15
|
+
|
|
14
16
|
UNARY_OPERATOR_MAP = {
|
|
15
17
|
not: :!
|
|
16
18
|
}.freeze
|
|
17
19
|
|
|
18
|
-
NEGATED_BINARY_OPERATOR_MAP = {
|
|
19
|
-
"!~": :=~
|
|
20
|
-
}.freeze
|
|
21
|
-
|
|
22
20
|
SHIFT_OPERATORS = [:<<, :>>].freeze
|
|
23
21
|
|
|
24
22
|
def process_binary(exp)
|
|
25
23
|
_, left, op, right = exp.shift 4
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
case op
|
|
26
|
+
when :=~
|
|
28
27
|
make_regexp_match_operator(left, op, right)
|
|
29
|
-
|
|
30
|
-
s(:not, make_regexp_match_operator(left,
|
|
31
|
-
|
|
32
|
-
make_boolean_operator(left,
|
|
33
|
-
|
|
28
|
+
when :!~
|
|
29
|
+
s(:not, make_regexp_match_operator(left, :=~, right))
|
|
30
|
+
when *BINARY_LOGICAL_OPERATORS
|
|
31
|
+
make_boolean_operator(left, op, right)
|
|
32
|
+
when *SHIFT_OPERATORS
|
|
34
33
|
s(:call, unwrap_begin(process(left)), op, unwrap_begin(process(right)))
|
|
34
|
+
when :"=>"
|
|
35
|
+
make_rightward_assignment(left, right)
|
|
35
36
|
else
|
|
36
37
|
s(:call, process(left), op, process(right))
|
|
37
38
|
end
|
|
@@ -77,20 +78,33 @@ module RipperRubyParser
|
|
|
77
78
|
private
|
|
78
79
|
|
|
79
80
|
def make_boolean_operator(left, operator, right)
|
|
81
|
+
operator = BINARY_OPERATOR_MAP[operator]
|
|
80
82
|
_, left, _, right = rebalance_binary(left, operator, right)
|
|
81
83
|
s(operator, unwrap_begin(process(left)), process(right))
|
|
82
84
|
end
|
|
83
85
|
|
|
84
86
|
def make_regexp_match_operator(left, operator, right)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
left = process(left)
|
|
88
|
+
right = process(right)
|
|
89
|
+
|
|
90
|
+
if regexp? left
|
|
91
|
+
s(:match2, left, right)
|
|
92
|
+
elsif regexp? right
|
|
93
|
+
s(:match3, right, left)
|
|
89
94
|
else
|
|
90
|
-
s(:call,
|
|
95
|
+
s(:call, left, operator, right)
|
|
91
96
|
end
|
|
92
97
|
end
|
|
93
98
|
|
|
99
|
+
def regexp?(exp)
|
|
100
|
+
exp.sexp_type == :dregx ||
|
|
101
|
+
exp.sexp_type == :lit && exp.sexp_body.first.is_a?(Regexp)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def make_rightward_assignment(left, right)
|
|
105
|
+
s(:lasgn, process(right)[1], process(left))
|
|
106
|
+
end
|
|
107
|
+
|
|
94
108
|
def rebalance_binary(left, operator, right)
|
|
95
109
|
if BINARY_OPERATOR_MAP[operator] == BINARY_OPERATOR_MAP[left[2]]
|
|
96
110
|
_, left, _, middle = rebalance_binary(*left.sexp_body)
|
|
@@ -83,7 +83,7 @@ module RipperRubyParser
|
|
|
83
83
|
return with_line_number(content.line, s(:lit, Regexp.new(content.last, numflags)))
|
|
84
84
|
end
|
|
85
85
|
|
|
86
|
-
content.sexp_type = :dregx_once if
|
|
86
|
+
content.sexp_type = :dregx_once if flags.include?("o")
|
|
87
87
|
content << numflags unless numflags == 0
|
|
88
88
|
content
|
|
89
89
|
end
|
|
@@ -123,7 +123,7 @@ module RipperRubyParser
|
|
|
123
123
|
|
|
124
124
|
def process_at_tstring_content(exp)
|
|
125
125
|
_, content, pos, delim = exp.shift 4
|
|
126
|
-
string =
|
|
126
|
+
string = handle_string_unescaping(content, delim)
|
|
127
127
|
with_position(pos, s(:str, string))
|
|
128
128
|
end
|
|
129
129
|
|
|
@@ -139,11 +139,11 @@ module RipperRubyParser
|
|
|
139
139
|
end
|
|
140
140
|
|
|
141
141
|
def merge_raw_string_literals(list)
|
|
142
|
-
chunks = list.chunk { |
|
|
142
|
+
chunks = list.chunk { |lit| lit.sexp_type == :@tstring_content }
|
|
143
143
|
chunks.flat_map do |is_simple, items|
|
|
144
144
|
if is_simple && items.count > 1
|
|
145
145
|
head = items.first
|
|
146
|
-
contents = items.map { |
|
|
146
|
+
contents = items.map { |lit| lit[1] }.join
|
|
147
147
|
[s(:@tstring_content, contents, head[2], head[3])]
|
|
148
148
|
else
|
|
149
149
|
items
|
|
@@ -180,11 +180,11 @@ module RipperRubyParser
|
|
|
180
180
|
def character_flags_to_numerical(flags)
|
|
181
181
|
numflags = 0
|
|
182
182
|
|
|
183
|
-
numflags = Regexp::MULTILINE if
|
|
184
|
-
numflags |= Regexp::EXTENDED if
|
|
185
|
-
numflags |= Regexp::IGNORECASE if
|
|
183
|
+
numflags = Regexp::MULTILINE if flags.include?("m")
|
|
184
|
+
numflags |= Regexp::EXTENDED if flags.include?("x")
|
|
185
|
+
numflags |= Regexp::IGNORECASE if flags.include?("i")
|
|
186
186
|
|
|
187
|
-
numflags |= Regexp::NOENCODING if
|
|
187
|
+
numflags |= Regexp::NOENCODING if flags.include?("n")
|
|
188
188
|
numflags |= Regexp::FIXEDENCODING if /[ues]/.match?(flags)
|
|
189
189
|
|
|
190
190
|
numflags
|
|
@@ -227,22 +227,29 @@ module RipperRubyParser
|
|
|
227
227
|
end
|
|
228
228
|
end
|
|
229
229
|
|
|
230
|
-
INTERPOLATING_HEREDOC = /^<<[-~]?[^-~']
|
|
231
|
-
NON_INTERPOLATING_HEREDOC = /^<<[-~]?'
|
|
232
|
-
INTERPOLATING_STRINGS = ['"', "`",
|
|
230
|
+
INTERPOLATING_HEREDOC = /^<<[-~]?[^-~']/
|
|
231
|
+
NON_INTERPOLATING_HEREDOC = /^<<[-~]?'/
|
|
232
|
+
INTERPOLATING_STRINGS = ['"', "`", /^%Q.$/, /^%.$/].freeze
|
|
233
|
+
INTERPOLATING_DSYM = ':"'
|
|
233
234
|
NON_INTERPOLATING_STRINGS = ["'", ":'", /^%q.$/].freeze
|
|
234
|
-
INTERPOLATING_WORD_LIST = /^%[WI]
|
|
235
|
-
NON_INTERPOLATING_WORD_LIST = /^%[wi]
|
|
235
|
+
INTERPOLATING_WORD_LIST = /^%[WI].$/
|
|
236
|
+
NON_INTERPOLATING_WORD_LIST = /^%[wi].$/
|
|
236
237
|
REGEXP_LITERALS = ["/", /^%r.$/].freeze
|
|
237
238
|
|
|
239
|
+
private_constant :INTERPOLATING_HEREDOC, :NON_INTERPOLATING_HEREDOC,
|
|
240
|
+
:INTERPOLATING_STRINGS, :NON_INTERPOLATING_STRINGS,
|
|
241
|
+
:INTERPOLATING_DSYM,
|
|
242
|
+
:INTERPOLATING_WORD_LIST, :NON_INTERPOLATING_WORD_LIST,
|
|
243
|
+
:REGEXP_LITERALS
|
|
244
|
+
|
|
238
245
|
def handle_string_unescaping(content, delim)
|
|
239
246
|
case delim
|
|
240
|
-
when INTERPOLATING_HEREDOC, *INTERPOLATING_STRINGS
|
|
247
|
+
when INTERPOLATING_HEREDOC, INTERPOLATING_DSYM, *INTERPOLATING_STRINGS
|
|
241
248
|
unescape(content)
|
|
242
249
|
when INTERPOLATING_WORD_LIST
|
|
243
|
-
unescape_wordlist_word(content)
|
|
250
|
+
fix_encoding unescape_wordlist_word(content)
|
|
244
251
|
when *NON_INTERPOLATING_STRINGS
|
|
245
|
-
simple_unescape(content, delim)
|
|
252
|
+
fix_encoding simple_unescape(content, delim)
|
|
246
253
|
when *REGEXP_LITERALS
|
|
247
254
|
unescape_regexp(content)
|
|
248
255
|
when NON_INTERPOLATING_WORD_LIST
|
|
@@ -17,9 +17,7 @@ module RipperRubyParser
|
|
|
17
17
|
super()
|
|
18
18
|
|
|
19
19
|
public_methods.each do |name|
|
|
20
|
-
if name =~ /^process_at_(.*)/
|
|
21
|
-
@processors["@#{Regexp.last_match(1)}".to_sym] = name.to_sym
|
|
22
|
-
end
|
|
20
|
+
@processors[:"@#{Regexp.last_match(1)}"] = name.to_sym if name =~ /^process_at_(.*)/
|
|
23
21
|
end
|
|
24
22
|
|
|
25
23
|
@filename = filename
|
|
@@ -28,10 +26,7 @@ module RipperRubyParser
|
|
|
28
26
|
@errors = []
|
|
29
27
|
|
|
30
28
|
@in_method_body = false
|
|
31
|
-
@
|
|
32
|
-
@block_kwrest = []
|
|
33
|
-
|
|
34
|
-
@kept_comment = nil
|
|
29
|
+
@local_variables = []
|
|
35
30
|
end
|
|
36
31
|
|
|
37
32
|
include SexpHandlers
|
|
@@ -77,7 +72,7 @@ module RipperRubyParser
|
|
|
77
72
|
|
|
78
73
|
def process_var_field(exp)
|
|
79
74
|
_, contents = exp.shift 2
|
|
80
|
-
process(contents)
|
|
75
|
+
process(contents) || s(:lvar, nil)
|
|
81
76
|
end
|
|
82
77
|
|
|
83
78
|
def process_var_alias(exp)
|
|
@@ -92,7 +87,7 @@ module RipperRubyParser
|
|
|
92
87
|
|
|
93
88
|
def process_const_path_ref(exp)
|
|
94
89
|
_, left, right = exp.shift 3
|
|
95
|
-
s(:colon2, process(left),
|
|
90
|
+
s(:colon2, process(left), make_symbol(process(right)))
|
|
96
91
|
end
|
|
97
92
|
|
|
98
93
|
def process_const_path_field(exp)
|
|
@@ -106,7 +101,7 @@ module RipperRubyParser
|
|
|
106
101
|
|
|
107
102
|
def process_top_const_ref(exp)
|
|
108
103
|
_, ref = exp.shift 2
|
|
109
|
-
s(:colon3,
|
|
104
|
+
s(:colon3, make_symbol(process(ref)))
|
|
110
105
|
end
|
|
111
106
|
|
|
112
107
|
def process_top_const_field(exp)
|
|
@@ -121,14 +116,10 @@ module RipperRubyParser
|
|
|
121
116
|
|
|
122
117
|
def process_comment(exp)
|
|
123
118
|
_, comment, inner = exp.shift 3
|
|
124
|
-
comment = @kept_comment + comment if @kept_comment
|
|
125
|
-
@kept_comment = nil
|
|
126
119
|
sexp = process(inner)
|
|
127
120
|
case sexp.sexp_type
|
|
128
121
|
when :defs, :defn, :module, :class, :sclass
|
|
129
122
|
sexp.comments = comment
|
|
130
|
-
else
|
|
131
|
-
@kept_comment = comment
|
|
132
123
|
end
|
|
133
124
|
sexp
|
|
134
125
|
end
|
|
@@ -20,7 +20,7 @@ module RipperRubyParser
|
|
|
20
20
|
M-. | # meta
|
|
21
21
|
\n | # line break
|
|
22
22
|
. # other single character
|
|
23
|
-
)/x
|
|
23
|
+
)/x
|
|
24
24
|
|
|
25
25
|
SINGLE_LETTER_ESCAPES = {
|
|
26
26
|
"a" => "\a",
|
|
@@ -74,7 +74,7 @@ module RipperRubyParser
|
|
|
74
74
|
def unescape(string)
|
|
75
75
|
string = string.dup if string.frozen?
|
|
76
76
|
string.force_encoding("ASCII-8BIT")
|
|
77
|
-
string.gsub(ESCAPE_SEQUENCE_REGEXP) do
|
|
77
|
+
result = string.gsub(ESCAPE_SEQUENCE_REGEXP) do
|
|
78
78
|
bare = Regexp.last_match[1]
|
|
79
79
|
if bare == "\n"
|
|
80
80
|
""
|
|
@@ -82,6 +82,7 @@ module RipperRubyParser
|
|
|
82
82
|
unescaped_value(bare).force_encoding("ASCII-8BIT")
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
|
+
fix_encoding result
|
|
85
86
|
end
|
|
86
87
|
|
|
87
88
|
def unescape_wordlist_word(string)
|
|
@@ -169,6 +170,9 @@ module RipperRubyParser
|
|
|
169
170
|
end
|
|
170
171
|
|
|
171
172
|
def control(val)
|
|
173
|
+
# Special case the \C-? or DEL sequence
|
|
174
|
+
return 127 if val == 63
|
|
175
|
+
|
|
172
176
|
val & 0b1001_1111
|
|
173
177
|
end
|
|
174
178
|
|
|
@@ -179,7 +183,7 @@ module RipperRubyParser
|
|
|
179
183
|
def delimiter_regexp_pattern(delimiter)
|
|
180
184
|
delimiter = delimiter[-1]
|
|
181
185
|
delimiters = DELIMITER_PAIRS.fetch(delimiter, delimiter)
|
|
182
|
-
delimiters.each_char.map { |
|
|
186
|
+
delimiters.each_char.map { |char| Regexp.escape char }.join(" | ")
|
|
183
187
|
end
|
|
184
188
|
end
|
|
185
189
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ripper_ruby_parser
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matijs van Zuijlen
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: sexp_processor
|
|
@@ -58,20 +57,6 @@ dependencies:
|
|
|
58
57
|
- - ">="
|
|
59
58
|
- !ruby/object:Gem::Version
|
|
60
59
|
version: 1.3.1
|
|
61
|
-
- !ruby/object:Gem::Dependency
|
|
62
|
-
name: pry
|
|
63
|
-
requirement: !ruby/object:Gem::Requirement
|
|
64
|
-
requirements:
|
|
65
|
-
- - "~>"
|
|
66
|
-
- !ruby/object:Gem::Version
|
|
67
|
-
version: 0.14.0
|
|
68
|
-
type: :development
|
|
69
|
-
prerelease: false
|
|
70
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
71
|
-
requirements:
|
|
72
|
-
- - "~>"
|
|
73
|
-
- !ruby/object:Gem::Version
|
|
74
|
-
version: 0.14.0
|
|
75
60
|
- !ruby/object:Gem::Dependency
|
|
76
61
|
name: rake
|
|
77
62
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -106,70 +91,70 @@ dependencies:
|
|
|
106
91
|
requirements:
|
|
107
92
|
- - "~>"
|
|
108
93
|
- !ruby/object:Gem::Version
|
|
109
|
-
version: '1.
|
|
94
|
+
version: '1.79'
|
|
110
95
|
type: :development
|
|
111
96
|
prerelease: false
|
|
112
97
|
version_requirements: !ruby/object:Gem::Requirement
|
|
113
98
|
requirements:
|
|
114
99
|
- - "~>"
|
|
115
100
|
- !ruby/object:Gem::Version
|
|
116
|
-
version: '1.
|
|
101
|
+
version: '1.79'
|
|
117
102
|
- !ruby/object:Gem::Dependency
|
|
118
103
|
name: rubocop-minitest
|
|
119
104
|
requirement: !ruby/object:Gem::Requirement
|
|
120
105
|
requirements:
|
|
121
106
|
- - "~>"
|
|
122
107
|
- !ruby/object:Gem::Version
|
|
123
|
-
version: 0.
|
|
108
|
+
version: 0.38.0
|
|
124
109
|
type: :development
|
|
125
110
|
prerelease: false
|
|
126
111
|
version_requirements: !ruby/object:Gem::Requirement
|
|
127
112
|
requirements:
|
|
128
113
|
- - "~>"
|
|
129
114
|
- !ruby/object:Gem::Version
|
|
130
|
-
version: 0.
|
|
115
|
+
version: 0.38.0
|
|
131
116
|
- !ruby/object:Gem::Dependency
|
|
132
117
|
name: rubocop-packaging
|
|
133
118
|
requirement: !ruby/object:Gem::Requirement
|
|
134
119
|
requirements:
|
|
135
120
|
- - "~>"
|
|
136
121
|
- !ruby/object:Gem::Version
|
|
137
|
-
version: 0.
|
|
122
|
+
version: 0.6.0
|
|
138
123
|
type: :development
|
|
139
124
|
prerelease: false
|
|
140
125
|
version_requirements: !ruby/object:Gem::Requirement
|
|
141
126
|
requirements:
|
|
142
127
|
- - "~>"
|
|
143
128
|
- !ruby/object:Gem::Version
|
|
144
|
-
version: 0.
|
|
129
|
+
version: 0.6.0
|
|
145
130
|
- !ruby/object:Gem::Dependency
|
|
146
131
|
name: rubocop-performance
|
|
147
132
|
requirement: !ruby/object:Gem::Requirement
|
|
148
133
|
requirements:
|
|
149
134
|
- - "~>"
|
|
150
135
|
- !ruby/object:Gem::Version
|
|
151
|
-
version: '1.
|
|
136
|
+
version: '1.25'
|
|
152
137
|
type: :development
|
|
153
138
|
prerelease: false
|
|
154
139
|
version_requirements: !ruby/object:Gem::Requirement
|
|
155
140
|
requirements:
|
|
156
141
|
- - "~>"
|
|
157
142
|
- !ruby/object:Gem::Version
|
|
158
|
-
version: '1.
|
|
143
|
+
version: '1.25'
|
|
159
144
|
- !ruby/object:Gem::Dependency
|
|
160
145
|
name: ruby_parser
|
|
161
146
|
requirement: !ruby/object:Gem::Requirement
|
|
162
147
|
requirements:
|
|
163
148
|
- - "~>"
|
|
164
149
|
- !ruby/object:Gem::Version
|
|
165
|
-
version:
|
|
150
|
+
version: 3.21.0
|
|
166
151
|
type: :development
|
|
167
152
|
prerelease: false
|
|
168
153
|
version_requirements: !ruby/object:Gem::Requirement
|
|
169
154
|
requirements:
|
|
170
155
|
- - "~>"
|
|
171
156
|
- !ruby/object:Gem::Version
|
|
172
|
-
version:
|
|
157
|
+
version: 3.21.0
|
|
173
158
|
- !ruby/object:Gem::Dependency
|
|
174
159
|
name: sexp_processor
|
|
175
160
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -190,14 +175,14 @@ dependencies:
|
|
|
190
175
|
requirements:
|
|
191
176
|
- - "~>"
|
|
192
177
|
- !ruby/object:Gem::Version
|
|
193
|
-
version: 0.
|
|
178
|
+
version: 0.22.0
|
|
194
179
|
type: :development
|
|
195
180
|
prerelease: false
|
|
196
181
|
version_requirements: !ruby/object:Gem::Requirement
|
|
197
182
|
requirements:
|
|
198
183
|
- - "~>"
|
|
199
184
|
- !ruby/object:Gem::Version
|
|
200
|
-
version: 0.
|
|
185
|
+
version: 0.22.0
|
|
201
186
|
description: |
|
|
202
187
|
RipperRubyParser is a parser for Ruby based on Ripper that aims to be a
|
|
203
188
|
drop-in replacement for RubyParser.
|
|
@@ -236,7 +221,6 @@ metadata:
|
|
|
236
221
|
source_code_uri: https://github.com/mvz/ripper_ruby_parser
|
|
237
222
|
changelog_uri: https://github.com/mvz/ripper_ruby_parser/blob/master/CHANGELOG.md
|
|
238
223
|
rubygems_mfa_required: 'true'
|
|
239
|
-
post_install_message:
|
|
240
224
|
rdoc_options:
|
|
241
225
|
- "--main"
|
|
242
226
|
- README.md
|
|
@@ -246,15 +230,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
246
230
|
requirements:
|
|
247
231
|
- - ">="
|
|
248
232
|
- !ruby/object:Gem::Version
|
|
249
|
-
version: 2.
|
|
233
|
+
version: 3.2.0
|
|
250
234
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
251
235
|
requirements:
|
|
252
236
|
- - ">="
|
|
253
237
|
- !ruby/object:Gem::Version
|
|
254
238
|
version: '0'
|
|
255
239
|
requirements: []
|
|
256
|
-
rubygems_version: 3.2
|
|
257
|
-
signing_key:
|
|
240
|
+
rubygems_version: 3.7.2
|
|
258
241
|
specification_version: 4
|
|
259
242
|
summary: Parse with Ripper, produce sexps that are compatible with RubyParser.
|
|
260
243
|
test_files: []
|