ripper_ruby_parser 1.6.1 → 1.7.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 +8 -0
- data/README.md +4 -23
- data/Rakefile +12 -12
- data/lib/ripper_ruby_parser.rb +2 -2
- data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +9 -9
- data/lib/ripper_ruby_parser/parser.rb +3 -3
- data/lib/ripper_ruby_parser/sexp_handlers.rb +9 -9
- data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +3 -9
- data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +19 -24
- data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +14 -18
- data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +3 -3
- data/lib/ripper_ruby_parser/sexp_processor.rb +4 -4
- data/lib/ripper_ruby_parser/unescape.rb +11 -11
- data/lib/ripper_ruby_parser/version.rb +1 -1
- data/test/end_to_end/comments_test.rb +10 -10
- data/test/end_to_end/comparison_test.rb +28 -28
- data/test/end_to_end/lib_comparison_test.rb +6 -6
- data/test/end_to_end/line_numbering_test.rb +10 -10
- data/test/end_to_end/samples_comparison_test.rb +5 -5
- data/test/end_to_end/test_comparison_test.rb +6 -6
- data/test/pt_testcase/pt_test.rb +7 -7
- data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +163 -169
- data/test/ripper_ruby_parser/parser_test.rb +338 -338
- data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +475 -511
- data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +582 -564
- data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +469 -469
- data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +713 -724
- data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +155 -155
- data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +181 -181
- data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +337 -352
- data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +298 -298
- data/test/ripper_ruby_parser/sexp_processor_test.rb +119 -119
- data/test/ripper_ruby_parser/version_test.rb +2 -2
- data/test/samples/lambdas.rb +5 -0
- data/test/samples/misc.rb +3 -0
- data/test/samples/strings.rb +7 -0
- data/test/test_helper.rb +8 -6
- metadata +12 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16ae34997256487e8611f1c1128bfa3f0ededad4befbdcba5cae435e957e4382
|
4
|
+
data.tar.gz: 9751a46aeaa42e05bc52587fa0fee46b64e0b45204b9cbf651f7492d7e6bde90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c31670a8b6d911f7679096feb5d1b01e2c67a7aec7694eb7f4ac932c2f335f24e5996074bd0857614e8f508c093f639d644f3ab4555de97c68f1ea601f4fd586
|
7
|
+
data.tar.gz: 2668135d139b2c4c5cb3da3f036bc7653896239a48846bbae4fe18056bb751f21e00618c8b2d7b90f3de3e504f4dfb959e442f3f302b253bcf777a0232329950
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 1.7.0 / 2019-11-01
|
4
|
+
|
5
|
+
* Make results compatible with RubyParser 3.14.0 ([#85])
|
6
|
+
- Remove obsolete extra-compatible behavior
|
7
|
+
- Parse stabby lambda as :lambda-typed sexp
|
8
|
+
- Emit nil argument for block arguments with trailing comma
|
9
|
+
* Require Ruby 2.4 or higher ([#86])
|
10
|
+
|
3
11
|
## 1.6.1 / 2019-04-22
|
4
12
|
|
5
13
|
* Improve line numbering for some block structures ([#82])
|
data/README.md
CHANGED
@@ -10,28 +10,16 @@ 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
|
14
|
-
* Compatible with RubyParser 3.
|
13
|
+
* Requires Ruby 2.4 or higher
|
14
|
+
* Compatible with RubyParser 3.14.0
|
15
15
|
|
16
16
|
## Known incompatibilities
|
17
17
|
|
18
|
-
RipperRubyParser has
|
19
|
-
the behavior can be changed by turning on extra-compatible mode.
|
20
|
-
|
21
|
-
The following incompatibilities cannot be changed:
|
18
|
+
RipperRubyParser has a few incompatibilities with RubyParser.
|
22
19
|
|
23
20
|
* RipperRubyParser won't handle non-UTF-8 files without an encoding comment,
|
24
21
|
just like regular Ruby
|
25
|
-
* RipperRubyParser does not match RubyParser's line numbering
|
26
|
-
* RipperRubyParser correctly dedents heredocs with interpolations
|
27
|
-
|
28
|
-
The following incompatibilities can be made compatible by turning on
|
29
|
-
extra-compatible mode:
|
30
|
-
|
31
|
-
* Operator assignment of a method call without parentheses to a collection
|
32
|
-
element uses an `:array` S-expression instead of `:arglist`
|
33
|
-
* RipperRubyParser keeps carriage return characters in heredocs that include
|
34
|
-
them
|
22
|
+
* RipperRubyParser does not always match RubyParser's line numbering
|
35
23
|
|
36
24
|
## Install
|
37
25
|
|
@@ -50,13 +38,6 @@ parser.parse "foo[bar] += baz qux"
|
|
50
38
|
# s(:arglist, s(:call, nil, :bar)),
|
51
39
|
# :+,
|
52
40
|
# 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
41
|
```
|
61
42
|
|
62
43
|
## Requirements
|
data/Rakefile
CHANGED
@@ -1,33 +1,33 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "rake/clean"
|
4
|
+
require "bundler/gem_tasks"
|
5
|
+
require "rake/testtask"
|
6
6
|
|
7
7
|
namespace :test do
|
8
8
|
Rake::TestTask.new(:unit) do |t|
|
9
|
-
t.libs = [
|
10
|
-
t.test_files = FileList[
|
9
|
+
t.libs = ["lib"]
|
10
|
+
t.test_files = FileList["test/ripper_ruby_parser/**/*_test.rb"]
|
11
11
|
t.warning = true
|
12
12
|
end
|
13
13
|
|
14
14
|
Rake::TestTask.new(:end_to_end) do |t|
|
15
|
-
t.libs = [
|
16
|
-
t.test_files = FileList[
|
15
|
+
t.libs = ["lib"]
|
16
|
+
t.test_files = FileList["test/end_to_end/*_test.rb"]
|
17
17
|
t.warning = true
|
18
18
|
end
|
19
19
|
|
20
20
|
Rake::TestTask.new(:pt_testcase) do |t|
|
21
|
-
t.libs = [
|
22
|
-
t.test_files = FileList[
|
21
|
+
t.libs = ["lib"]
|
22
|
+
t.test_files = FileList["test/pt_testcase/*_test.rb"]
|
23
23
|
t.warning = true
|
24
24
|
end
|
25
25
|
|
26
|
-
desc
|
26
|
+
desc "Run all three test suites"
|
27
27
|
task run: [:unit, :end_to_end, :pt_testcase]
|
28
28
|
end
|
29
29
|
|
30
|
-
desc
|
31
|
-
task test:
|
30
|
+
desc "Alias to test:run"
|
31
|
+
task test: "test:run"
|
32
32
|
|
33
33
|
task default: :test
|
data/lib/ripper_ruby_parser.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "ripper"
|
4
|
+
require "ripper_ruby_parser/syntax_error"
|
5
|
+
require "ripper_ruby_parser/unescape"
|
6
6
|
|
7
7
|
module RipperRubyParser
|
8
8
|
# Variant of Ripper's SexpBuilder parser class that inserts comments as
|
@@ -12,7 +12,7 @@ module RipperRubyParser
|
|
12
12
|
class CommentingRipperParser < Ripper::SexpBuilder
|
13
13
|
def initialize(*args)
|
14
14
|
super
|
15
|
-
@comment =
|
15
|
+
@comment = ""
|
16
16
|
@comment_stack = []
|
17
17
|
@delimiter_stack = []
|
18
18
|
@space_before = false
|
@@ -22,7 +22,7 @@ module RipperRubyParser
|
|
22
22
|
|
23
23
|
def parse
|
24
24
|
result = super
|
25
|
-
raise
|
25
|
+
raise "Ripper parse failed." unless result
|
26
26
|
|
27
27
|
Sexp.from_array(result)
|
28
28
|
end
|
@@ -60,10 +60,10 @@ module RipperRubyParser
|
|
60
60
|
def on_kw(tok)
|
61
61
|
result = super
|
62
62
|
case tok
|
63
|
-
when
|
63
|
+
when "class", "def", "module", "BEGIN", "begin", "END"
|
64
64
|
unless @in_symbol
|
65
65
|
@comment_stack.push [result, @comment]
|
66
|
-
@comment =
|
66
|
+
@comment = ""
|
67
67
|
end
|
68
68
|
end
|
69
69
|
result
|
@@ -255,7 +255,7 @@ module RipperRubyParser
|
|
255
255
|
def on_unary(operator, value)
|
256
256
|
if !@space_before && operator == :-@ && NUMBER_LITERAL_TYPES.include?(value.first)
|
257
257
|
type, literal, lines = value
|
258
|
-
if literal[0] ==
|
258
|
+
if literal[0] == "-"
|
259
259
|
super
|
260
260
|
else
|
261
261
|
[type, "-#{literal}", lines]
|
@@ -317,7 +317,7 @@ module RipperRubyParser
|
|
317
317
|
|
318
318
|
def commentize(_name, exp)
|
319
319
|
(_, _kw, loc), comment = @comment_stack.pop
|
320
|
-
@comment =
|
320
|
+
@comment = ""
|
321
321
|
exp.push loc
|
322
322
|
[:comment, comment, exp]
|
323
323
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "ripper_ruby_parser/commenting_ripper_parser"
|
4
|
+
require "ripper_ruby_parser/sexp_processor"
|
5
5
|
|
6
6
|
module RipperRubyParser
|
7
7
|
# Main parser class. Brings together Ripper and our
|
@@ -13,7 +13,7 @@ module RipperRubyParser
|
|
13
13
|
@extra_compatible = false
|
14
14
|
end
|
15
15
|
|
16
|
-
def parse(source, filename =
|
16
|
+
def parse(source, filename = "(string)", lineno = 1)
|
17
17
|
parser = CommentingRipperParser.new(source, filename, lineno)
|
18
18
|
exp = parser.parse
|
19
19
|
|
@@ -1,15 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "ripper_ruby_parser/sexp_handlers/helper_methods"
|
4
4
|
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
5
|
+
require "ripper_ruby_parser/sexp_handlers/assignment"
|
6
|
+
require "ripper_ruby_parser/sexp_handlers/blocks"
|
7
|
+
require "ripper_ruby_parser/sexp_handlers/conditionals"
|
8
|
+
require "ripper_ruby_parser/sexp_handlers/literals"
|
9
|
+
require "ripper_ruby_parser/sexp_handlers/loops"
|
10
|
+
require "ripper_ruby_parser/sexp_handlers/method_calls"
|
11
|
+
require "ripper_ruby_parser/sexp_handlers/methods"
|
12
|
+
require "ripper_ruby_parser/sexp_handlers/operators"
|
13
13
|
|
14
14
|
module RipperRubyParser
|
15
15
|
# Umbrella module for handlers of particular sexp types
|
@@ -96,11 +96,10 @@ module RipperRubyParser
|
|
96
96
|
_, lvalue, (_, operator,), value = exp.shift 4
|
97
97
|
|
98
98
|
lvalue = process(lvalue)
|
99
|
-
original_value_type = value.sexp_type
|
100
99
|
value = process(value)
|
101
100
|
operator = operator.chop.to_sym
|
102
101
|
|
103
|
-
create_operator_assignment_sub_type lvalue, value, operator
|
102
|
+
create_operator_assignment_sub_type lvalue, value, operator
|
104
103
|
end
|
105
104
|
|
106
105
|
private
|
@@ -123,16 +122,11 @@ module RipperRubyParser
|
|
123
122
|
'&&': :op_asgn_and
|
124
123
|
}.freeze
|
125
124
|
|
126
|
-
def create_operator_assignment_sub_type(lvalue, value, operator
|
125
|
+
def create_operator_assignment_sub_type(lvalue, value, operator)
|
127
126
|
case lvalue.sexp_type
|
128
127
|
when :aref_field
|
129
128
|
_, arr, arglist = lvalue
|
130
|
-
arglist.sexp_type =
|
131
|
-
[:command, :command_call].include?(original_value_type)
|
132
|
-
:array
|
133
|
-
else
|
134
|
-
:arglist
|
135
|
-
end
|
129
|
+
arglist.sexp_type = :arglist
|
136
130
|
s(:op_asgn1, arr, arglist, operator, value)
|
137
131
|
when :field
|
138
132
|
_, obj, _, (_, field) = lvalue
|
@@ -58,27 +58,23 @@ module RipperRubyParser
|
|
58
58
|
rescue_block = map_process_list_compact block.sexp_body
|
59
59
|
rescue_block << nil if rescue_block.empty?
|
60
60
|
|
61
|
-
capture = if eclass
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
s(:array, *body)
|
69
|
-
end
|
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
|
70
68
|
else
|
71
|
-
s(:array,
|
69
|
+
s(:array, *body)
|
72
70
|
end
|
73
71
|
else
|
74
|
-
s(:array)
|
72
|
+
s(:array, process(eclass.first))
|
75
73
|
end
|
76
74
|
|
77
75
|
capture << create_assignment_sub_type(process(evar), s(:gvar, :$!)) if evar
|
78
76
|
|
79
|
-
s(
|
80
|
-
s(:resbody, capture, *rescue_block),
|
81
|
-
*process(after))
|
77
|
+
s(s(:resbody, capture, *rescue_block), *process(after))
|
82
78
|
end
|
83
79
|
|
84
80
|
def process_bodystmt(exp)
|
@@ -91,13 +87,9 @@ module RipperRubyParser
|
|
91
87
|
main = wrap_in_block reject_void_stmt main_list
|
92
88
|
body << main if main
|
93
89
|
|
94
|
-
if rescue_block
|
95
|
-
|
96
|
-
|
97
|
-
body = s(s(:rescue, *body))
|
98
|
-
elsif else_block
|
99
|
-
body << process(else_block)
|
100
|
-
end
|
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
|
101
93
|
|
102
94
|
if ensure_block
|
103
95
|
body << process(ensure_block)
|
@@ -143,7 +135,7 @@ module RipperRubyParser
|
|
143
135
|
old_type = args.sexp_type
|
144
136
|
args = convert_arguments(process(args))
|
145
137
|
args = nil if args == s(:args) && old_type == :params
|
146
|
-
make_iter(s(:
|
138
|
+
make_iter(s(:lambda),
|
147
139
|
args,
|
148
140
|
safe_unwrap_void_stmt(process(statements)))
|
149
141
|
end
|
@@ -167,7 +159,10 @@ module RipperRubyParser
|
|
167
159
|
end
|
168
160
|
|
169
161
|
def handle_splat(splat)
|
170
|
-
if splat
|
162
|
+
if splat == 0
|
163
|
+
# Only relevant for Ruby < 2.6
|
164
|
+
[s(:excessed_comma)]
|
165
|
+
elsif splat
|
171
166
|
[process(splat)]
|
172
167
|
else
|
173
168
|
[]
|
@@ -209,7 +204,7 @@ module RipperRubyParser
|
|
209
204
|
end
|
210
205
|
|
211
206
|
def make_iter(call, args, stmt)
|
212
|
-
args
|
207
|
+
args[-1] = nil if args && args.last == s(:excessed_comma)
|
213
208
|
args ||= 0
|
214
209
|
if stmt.empty?
|
215
210
|
s(:iter, call, args)
|
@@ -31,16 +31,16 @@ module RipperRubyParser
|
|
31
31
|
when :str, :dstr
|
32
32
|
val
|
33
33
|
when :void_stmt
|
34
|
-
s(:dstr,
|
34
|
+
s(:dstr, "", s(:evstr))
|
35
35
|
else
|
36
|
-
s(:dstr,
|
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,
|
43
|
+
s(:dstr, "", s(:evstr, val))
|
44
44
|
end
|
45
45
|
|
46
46
|
def process_string_concat(exp)
|
@@ -81,7 +81,7 @@ module RipperRubyParser
|
|
81
81
|
return with_line_number(content.line, s(:lit, Regexp.new(content.last, numflags)))
|
82
82
|
end
|
83
83
|
|
84
|
-
content.sexp_type = :dregx_once if
|
84
|
+
content.sexp_type = :dregx_once if /o/.match?(flags)
|
85
85
|
content << numflags unless numflags == 0
|
86
86
|
content
|
87
87
|
end
|
@@ -121,11 +121,11 @@ module RipperRubyParser
|
|
121
121
|
|
122
122
|
INTERPOLATING_HEREDOC = /^<<[-~]?[^-~']/.freeze
|
123
123
|
NON_INTERPOLATING_HEREDOC = /^<<[-~]?'/.freeze
|
124
|
-
INTERPOLATING_STRINGS = ['"',
|
124
|
+
INTERPOLATING_STRINGS = ['"', "`", ':"', /^%Q.$/, /^%.$/].freeze
|
125
125
|
NON_INTERPOLATING_STRINGS = ["'", ":'", /^%q.$/].freeze
|
126
126
|
INTERPOLATING_WORD_LIST = /^%[WI].$/.freeze
|
127
127
|
NON_INTERPOLATING_WORD_LIST = /^%[wi].$/.freeze
|
128
|
-
REGEXP_LITERALS = [
|
128
|
+
REGEXP_LITERALS = ["/", /^%r.$/].freeze
|
129
129
|
|
130
130
|
def process_at_tstring_content(exp)
|
131
131
|
_, content, pos, delim = exp.shift 4
|
@@ -166,7 +166,7 @@ module RipperRubyParser
|
|
166
166
|
private
|
167
167
|
|
168
168
|
def extract_string_parts(list)
|
169
|
-
return nil,
|
169
|
+
return nil, "", [] if list.empty?
|
170
170
|
|
171
171
|
list = merge_raw_string_literals list
|
172
172
|
list = map_process_list list
|
@@ -184,7 +184,7 @@ module RipperRubyParser
|
|
184
184
|
end
|
185
185
|
end
|
186
186
|
|
187
|
-
string =
|
187
|
+
string = ""
|
188
188
|
while parts.first&.sexp_type == :str
|
189
189
|
str = parts.shift
|
190
190
|
line ||= str.line
|
@@ -210,12 +210,12 @@ module RipperRubyParser
|
|
210
210
|
def character_flags_to_numerical(flags)
|
211
211
|
numflags = 0
|
212
212
|
|
213
|
-
numflags = Regexp::MULTILINE if
|
214
|
-
numflags |= Regexp::EXTENDED if
|
215
|
-
numflags |= Regexp::IGNORECASE if
|
213
|
+
numflags = Regexp::MULTILINE if /m/.match?(flags)
|
214
|
+
numflags |= Regexp::EXTENDED if /x/.match?(flags)
|
215
|
+
numflags |= Regexp::IGNORECASE if /i/.match?(flags)
|
216
216
|
|
217
|
-
numflags |= Regexp::NOENCODING if
|
218
|
-
numflags |= Regexp::FIXEDENCODING if
|
217
|
+
numflags |= Regexp::NOENCODING if /n/.match?(flags)
|
218
|
+
numflags |= Regexp::FIXEDENCODING if /[ues]/.match?(flags)
|
219
219
|
|
220
220
|
numflags
|
221
221
|
end
|
@@ -260,11 +260,7 @@ module RipperRubyParser
|
|
260
260
|
def handle_string_unescaping(content, delim)
|
261
261
|
case delim
|
262
262
|
when INTERPOLATING_HEREDOC
|
263
|
-
|
264
|
-
unescape(content).delete("\r")
|
265
|
-
else
|
266
|
-
unescape(content)
|
267
|
-
end
|
263
|
+
unescape(content)
|
268
264
|
when *INTERPOLATING_STRINGS
|
269
265
|
unescape(content)
|
270
266
|
when INTERPOLATING_WORD_LIST
|