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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -0
  3. data/README.md +4 -23
  4. data/Rakefile +12 -12
  5. data/lib/ripper_ruby_parser.rb +2 -2
  6. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +9 -9
  7. data/lib/ripper_ruby_parser/parser.rb +3 -3
  8. data/lib/ripper_ruby_parser/sexp_handlers.rb +9 -9
  9. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +3 -9
  10. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +19 -24
  11. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +14 -18
  12. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +3 -3
  13. data/lib/ripper_ruby_parser/sexp_processor.rb +4 -4
  14. data/lib/ripper_ruby_parser/unescape.rb +11 -11
  15. data/lib/ripper_ruby_parser/version.rb +1 -1
  16. data/test/end_to_end/comments_test.rb +10 -10
  17. data/test/end_to_end/comparison_test.rb +28 -28
  18. data/test/end_to_end/lib_comparison_test.rb +6 -6
  19. data/test/end_to_end/line_numbering_test.rb +10 -10
  20. data/test/end_to_end/samples_comparison_test.rb +5 -5
  21. data/test/end_to_end/test_comparison_test.rb +6 -6
  22. data/test/pt_testcase/pt_test.rb +7 -7
  23. data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +163 -169
  24. data/test/ripper_ruby_parser/parser_test.rb +338 -338
  25. data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +475 -511
  26. data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +582 -564
  27. data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +469 -469
  28. data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +713 -724
  29. data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +155 -155
  30. data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +181 -181
  31. data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +337 -352
  32. data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +298 -298
  33. data/test/ripper_ruby_parser/sexp_processor_test.rb +119 -119
  34. data/test/ripper_ruby_parser/version_test.rb +2 -2
  35. data/test/samples/lambdas.rb +5 -0
  36. data/test/samples/misc.rb +3 -0
  37. data/test/samples/strings.rb +7 -0
  38. data/test/test_helper.rb +8 -6
  39. metadata +12 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20d34b3ba8f1c186e8df1118334a231d2520c9ef51a36b4c7d5b12c33fe9947b
4
- data.tar.gz: 881e3286d632c0189a33a2add98dd43bddda798cf6c7c8f3fa75e1b9dfdda7e3
3
+ metadata.gz: 16ae34997256487e8611f1c1128bfa3f0ededad4befbdcba5cae435e957e4382
4
+ data.tar.gz: 9751a46aeaa42e05bc52587fa0fee46b64e0b45204b9cbf651f7492d7e6bde90
5
5
  SHA512:
6
- metadata.gz: f3a58dd16a10a8c0f64996c753e2da3c02d7b0ec074099795bf240925e388a5edb215edf680df0c70baab82c42ea77d22762d2a2b27a7a9a246aa01bb47753a1
7
- data.tar.gz: 7b360aaea5ba1fe76855a4e534d56aec13b1a470f7cc9e539d4e2c996ef0684848142ea6c4d2e522c439e84d62628ebaf571da5c993e9a44a0f9641d8e3283df
6
+ metadata.gz: c31670a8b6d911f7679096feb5d1b01e2c67a7aec7694eb7f4ac932c2f335f24e5996074bd0857614e8f508c093f639d644f3ab4555de97c68f1ea601f4fd586
7
+ data.tar.gz: 2668135d139b2c4c5cb3da3f036bc7653896239a48846bbae4fe18056bb751f21e00618c8b2d7b90f3de3e504f4dfb959e442f3f302b253bcf777a0232329950
@@ -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 MRI 2.3 or higher
14
- * Compatible with RubyParser 3.13.1
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 some incompatibilities with RubyParser. For some of these,
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 'rake/clean'
4
- require 'bundler/gem_tasks'
5
- require 'rake/testtask'
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 = ['lib']
10
- t.test_files = FileList['test/ripper_ruby_parser/**/*_test.rb']
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 = ['lib']
16
- t.test_files = FileList['test/end_to_end/*_test.rb']
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 = ['lib']
22
- t.test_files = FileList['test/pt_testcase/*_test.rb']
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 'Run all three test suites'
26
+ desc "Run all three test suites"
27
27
  task run: [:unit, :end_to_end, :pt_testcase]
28
28
  end
29
29
 
30
- desc 'Alias to test:run'
31
- task test: 'test:run'
30
+ desc "Alias to test:run"
31
+ task test: "test:run"
32
32
 
33
33
  task default: :test
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ripper_ruby_parser/version'
4
- require 'ripper_ruby_parser/parser'
3
+ require "ripper_ruby_parser/version"
4
+ require "ripper_ruby_parser/parser"
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'ripper'
4
- require 'ripper_ruby_parser/syntax_error'
5
- require 'ripper_ruby_parser/unescape'
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 'Ripper parse failed.' unless result
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 'class', 'def', 'module', 'BEGIN', 'begin', 'END'
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 'ripper_ruby_parser/commenting_ripper_parser'
4
- require 'ripper_ruby_parser/sexp_processor'
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 = '(string)', lineno = 1)
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 'ripper_ruby_parser/sexp_handlers/helper_methods'
3
+ require "ripper_ruby_parser/sexp_handlers/helper_methods"
4
4
 
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'
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, original_value_type
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, original_value_type)
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 = if extra_compatible &&
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
- if eclass.first.is_a? Symbol
63
- eclass = process(eclass)
64
- body = eclass.sexp_body
65
- if eclass.sexp_type == :mrhs
66
- body.first
67
- else
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, process(eclass.first))
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
- body.push(*process(rescue_block))
96
- body << process(else_block) if else_block
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(:call, nil, :lambda),
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 && splat != 0
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.pop if args && args.last == s(:excessed_comma)
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, '', 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)
@@ -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 flags =~ /o/
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 = ['"', '`', ':"', /^%Q.$/, /^%.$/].freeze
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 = ['/', /^%r.$/].freeze
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, '', [] if list.empty?
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 flags =~ /m/
214
- numflags |= Regexp::EXTENDED if flags =~ /x/
215
- numflags |= Regexp::IGNORECASE if flags =~ /i/
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 flags =~ /n/
218
- numflags |= Regexp::FIXEDENCODING if flags =~ /[ues]/
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
- if extra_compatible
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
@@ -92,9 +92,9 @@ module RipperRubyParser
92
92
  end
93
93
 
94
94
  SPECIAL_ARG_MARKER = {
95
- splat: '*',
96
- dsplat: '**',
97
- blockarg: '&'
95
+ splat: "*",
96
+ dsplat: "**",
97
+ blockarg: "&"
98
98
  }.freeze
99
99
 
100
100
  def convert_arguments(args)