ripper_ruby_parser 1.5.1 → 1.6.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.
@@ -113,8 +113,7 @@ module RipperRubyParser
113
113
  private
114
114
 
115
115
  def replace_kwrest_arg_call?(method)
116
- method_kwrest_arg?(method) ||
117
- !extra_compatible && block_kwrest_arg?(method)
116
+ kwrest_arg?(method)
118
117
  end
119
118
  end
120
119
  end
@@ -10,7 +10,7 @@ module RipperRubyParser
10
10
  ident, pos = extract_node_symbol_with_position ident
11
11
 
12
12
  in_method do
13
- params = convert_method_args(process(params))
13
+ params = convert_arguments(process(params))
14
14
  kwrest = kwrest_param(params)
15
15
  body = with_kwrest(kwrest) { method_body(body) }
16
16
  end
@@ -24,7 +24,7 @@ module RipperRubyParser
24
24
  ident, = extract_node_symbol_with_position ident
25
25
 
26
26
  in_method do
27
- params = convert_method_args(process(params))
27
+ params = convert_arguments(process(params))
28
28
  kwrest = kwrest_param(params)
29
29
  body = with_kwrest(kwrest) { method_body(body) }
30
30
  end
@@ -87,11 +87,7 @@ module RipperRubyParser
87
87
  when 0
88
88
  [s(:nil)]
89
89
  else
90
- if block.sexp_type == :block
91
- block.sexp_body
92
- else
93
- [block]
94
- end
90
+ unwrap_block block
95
91
  end
96
92
  end
97
93
 
@@ -101,7 +97,7 @@ module RipperRubyParser
101
97
  blockarg: '&'
102
98
  }.freeze
103
99
 
104
- def convert_method_args(args)
100
+ def convert_arguments(args)
105
101
  args.map! do |item|
106
102
  if item.is_a? Symbol
107
103
  item
@@ -110,9 +106,9 @@ module RipperRubyParser
110
106
  when :lvar
111
107
  item.last
112
108
  when *SPECIAL_ARG_MARKER.keys
113
- marker = SPECIAL_ARG_MARKER[item.sexp_type]
114
- name = extract_node_symbol item.last
115
- :"#{marker}#{name}"
109
+ convert_marked_argument(item)
110
+ when :masgn
111
+ convert_masgn_argument(item)
116
112
  else
117
113
  item
118
114
  end
@@ -120,6 +116,31 @@ module RipperRubyParser
120
116
  end
121
117
  end
122
118
 
119
+ def convert_marked_argument(item)
120
+ marker = SPECIAL_ARG_MARKER[item.sexp_type]
121
+ name = extract_node_symbol item.last
122
+ :"#{marker}#{name}"
123
+ end
124
+
125
+ def convert_masgn_argument(item)
126
+ args = item[1]
127
+ args.shift
128
+ s(:masgn, *convert_destructuring_arguments(args))
129
+ end
130
+
131
+ def convert_destructuring_arguments(args)
132
+ args.map! do |item|
133
+ case item.sexp_type
134
+ when :splat
135
+ convert_marked_argument(item)
136
+ when :masgn
137
+ convert_masgn_argument(item)
138
+ when :lasgn
139
+ item[1]
140
+ end
141
+ end
142
+ end
143
+
123
144
  def kwrest_param(params)
124
145
  found = params.find { |param| param.to_s =~ /^\*\*(.+)/ }
125
146
  Regexp.last_match[1].to_sym if found
@@ -132,20 +153,9 @@ module RipperRubyParser
132
153
  result
133
154
  end
134
155
 
135
- def with_block_kwrest(kwrest)
136
- @block_kwrest.push kwrest
137
- result = yield
138
- @block_kwrest.pop
139
- result
140
- end
141
-
142
- def method_kwrest_arg?(method)
156
+ def kwrest_arg?(method)
143
157
  @kwrest.include?(method)
144
158
  end
145
-
146
- def block_kwrest_arg?(method)
147
- @block_kwrest.include?(method)
148
- end
149
159
  end
150
160
  end
151
161
  end
@@ -49,7 +49,7 @@ module RipperRubyParser
49
49
  left = process(left)
50
50
  right = process(right)
51
51
  if integer_literal?(left) && integer_literal?(right)
52
- s(:lit, Range.new(left[1], right[1]))
52
+ with_line_number(left.line, s(:lit, Range.new(left[1], right[1])))
53
53
  else
54
54
  s(:dot2, left, right)
55
55
  end
@@ -60,7 +60,7 @@ module RipperRubyParser
60
60
  left = process(left)
61
61
  right = process(right)
62
62
  if integer_literal?(left) && integer_literal?(right)
63
- s(:lit, Range.new(left[1], right[1], true))
63
+ with_line_number(left.line, s(:lit, Range.new(left[1], right[1], true)))
64
64
  else
65
65
  s(:dot3, left, right)
66
66
  end
@@ -31,6 +31,8 @@ module RipperRubyParser
31
31
  @processors[:@kw] = :process_at_kw
32
32
  @processors[:@op] = :process_at_op
33
33
  @processors[:@backref] = :process_at_backref
34
+
35
+ @processors[:@backtick] = :process_at_backtick
34
36
  @processors[:@period] = :process_at_period
35
37
 
36
38
  @processors[:@tstring_content] = :process_at_tstring_content
@@ -83,12 +85,7 @@ module RipperRubyParser
83
85
  statements.first
84
86
  else
85
87
  first = statements.shift
86
- if first.sexp_type == :block
87
- first.shift
88
- s(:block, *first, *statements)
89
- else
90
- s(:block, first, *statements)
91
- end
88
+ s(:block, *unwrap_block(first), *statements)
92
89
  end
93
90
  end
94
91
 
@@ -150,7 +147,7 @@ module RipperRubyParser
150
147
  def process_BEGIN(exp)
151
148
  _, body = exp.shift 2
152
149
  body = reject_void_stmt map_process_list body.sexp_body
153
- s(:iter, s(:preexe), s(:args), *body)
150
+ s(:iter, s(:preexe), 0, *body)
154
151
  end
155
152
 
156
153
  def process_END(exp)
@@ -200,19 +197,17 @@ module RipperRubyParser
200
197
  end
201
198
 
202
199
  def process_at_ident(exp)
203
- with_position_from_node_symbol(exp) do |ident|
204
- if replace_kwrest_arg_lvar? ident
205
- s(:call, nil, ident)
206
- else
207
- s(:lvar, ident)
208
- end
209
- end
200
+ make_identifier(:lvar, exp)
210
201
  end
211
202
 
212
203
  def process_at_op(exp)
213
204
  make_identifier(:op, exp)
214
205
  end
215
206
 
207
+ def process_at_backtick(exp)
208
+ make_identifier(:backtick, exp)
209
+ end
210
+
216
211
  def process_at_kw(exp)
217
212
  sym, pos = extract_node_symbol_with_position(exp)
218
213
  result = case sym
@@ -259,11 +254,7 @@ module RipperRubyParser
259
254
 
260
255
  return body if body.empty?
261
256
 
262
- if body.sexp_type == :block
263
- body.sexp_body
264
- else
265
- [body]
266
- end
257
+ unwrap_block body
267
258
  end
268
259
 
269
260
  def make_identifier(type, exp)
@@ -276,9 +267,5 @@ module RipperRubyParser
276
267
  _, val, pos = exp.shift 3
277
268
  with_position(pos, s(:lit, yield(val)))
278
269
  end
279
-
280
- def replace_kwrest_arg_lvar?(ident)
281
- extra_compatible && @block_kwrest.include?(ident)
282
- end
283
270
  end
284
271
  end
@@ -106,8 +106,7 @@ module RipperRubyParser
106
106
  when /^u\{/
107
107
  hex_to_unicode_char(bare[2..-2])
108
108
  when /^u/
109
- hex_to_unicode_char(bare[1..4]) +
110
- (extra_compatible ? '' : bare[5..-1])
109
+ hex_to_unicode_char(bare[1..4]) + bare[5..-1]
111
110
  when /^(c|C-).$/
112
111
  control(bare[-1].ord).chr
113
112
  when /^M-.$/
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RipperRubyParser
4
- VERSION = '1.5.1'
4
+ VERSION = '1.6.0'
5
5
  end
@@ -9,7 +9,7 @@ describe 'Using RipperRubyParser and RubyParser' do
9
9
  end
10
10
 
11
11
  let :oldparser do
12
- RubyParser.new
12
+ RubyParser.for_current_ruby
13
13
  end
14
14
 
15
15
  describe 'for a program with quite some comments' do
@@ -9,7 +9,7 @@ describe 'Using RipperRubyParser and RubyParser' do
9
9
  end
10
10
 
11
11
  let :oldparser do
12
- RubyParser.new
12
+ RubyParser.for_current_ruby
13
13
  end
14
14
 
15
15
  Dir.glob('lib/**/*.rb').each do |file|
@@ -25,7 +25,7 @@ describe 'Using RipperRubyParser and RubyParser' do
25
25
  end
26
26
 
27
27
  let :oldparser do
28
- RubyParser.new
28
+ RubyParser.for_current_ruby
29
29
  end
30
30
 
31
31
  describe 'for a multi-line program' do
@@ -9,7 +9,7 @@ describe 'Using RipperRubyParser and RubyParser' do
9
9
  end
10
10
 
11
11
  let :oldparser do
12
- RubyParser.new
12
+ RubyParser.for_current_ruby
13
13
  end
14
14
 
15
15
  Dir.glob('test/ripper_ruby_parser/**/*.rb').each do |file|
@@ -148,12 +148,12 @@ describe RipperRubyParser::Parser do
148
148
  describe 'for the BEGIN keyword' do
149
149
  it 'converts to a :preexe iterator' do
150
150
  'BEGIN { foo }'.
151
- must_be_parsed_as s(:iter, s(:preexe), s(:args), s(:call, nil, :foo))
151
+ must_be_parsed_as s(:iter, s(:preexe), 0, s(:call, nil, :foo))
152
152
  end
153
153
 
154
154
  it 'works with an empty block' do
155
155
  'BEGIN { }'.
156
- must_be_parsed_as s(:iter, s(:preexe), s(:args))
156
+ must_be_parsed_as s(:iter, s(:preexe), 0)
157
157
  end
158
158
  end
159
159
 
@@ -376,6 +376,16 @@ describe RipperRubyParser::Parser do
376
376
  result.line.must_equal 1
377
377
  end
378
378
 
379
+ it 'works for a range literal' do
380
+ result = parser.parse '0..4'
381
+ result.line.must_equal 1
382
+ end
383
+
384
+ it 'works for an exclusive range literal' do
385
+ result = parser.parse '0...4'
386
+ result.line.must_equal 1
387
+ end
388
+
379
389
  it 'works for a regular expression back reference' do
380
390
  result = parser.parse '$1'
381
391
  result.line.must_equal 1
@@ -210,6 +210,35 @@ describe RipperRubyParser::Parser do
210
210
  'foo = Bar.baz qux rescue quuz'.
211
211
  must_be_parsed_as expected
212
212
  end
213
+
214
+ it 'works with a method call with argument without brackets' do
215
+ expected = if RUBY_VERSION < '2.4.0'
216
+ s(:rescue,
217
+ s(:lasgn, :foo, s(:call, nil, :bar, s(:call, nil, :baz))),
218
+ s(:resbody, s(:array), s(:call, nil, :qux)))
219
+ else
220
+ s(:lasgn, :foo,
221
+ s(:rescue,
222
+ s(:call, nil, :bar, s(:call, nil, :baz)),
223
+ s(:resbody, s(:array), s(:call, nil, :qux))))
224
+ end
225
+ 'foo = bar baz rescue qux'.must_be_parsed_as expected
226
+ end
227
+
228
+ it 'works with a class method call with argument without brackets' do
229
+ expected = if RUBY_VERSION < '2.4.0'
230
+ s(:rescue,
231
+ s(:lasgn, :foo, s(:call, s(:const, :Bar), :baz, s(:call, nil, :qux))),
232
+ s(:resbody, s(:array), s(:call, nil, :quuz)))
233
+ else
234
+ s(:lasgn, :foo,
235
+ s(:rescue,
236
+ s(:call, s(:const, :Bar), :baz, s(:call, nil, :qux)),
237
+ s(:resbody, s(:array), s(:call, nil, :quuz))))
238
+ end
239
+ 'foo = Bar.baz qux rescue quuz'.
240
+ must_be_parsed_as expected
241
+ end
213
242
  end
214
243
 
215
244
  it 'sets the correct line numbers' do
@@ -244,6 +273,13 @@ describe RipperRubyParser::Parser do
244
273
  s(:to_ary, s(:call, nil, :baz)))
245
274
  end
246
275
 
276
+ it 'works with blocks' do
277
+ 'foo, bar = begin; baz; end'.
278
+ must_be_parsed_as s(:masgn,
279
+ s(:array, s(:lasgn, :foo), s(:lasgn, :bar)),
280
+ s(:to_ary, s(:call, nil, :baz)))
281
+ end
282
+
247
283
  it 'works with a rescue modifier' do
248
284
  'foo, bar = baz rescue qux'.
249
285
  must_be_parsed_as s(:rescue,
@@ -314,6 +350,17 @@ describe RipperRubyParser::Parser do
314
350
  s(:call, nil, :quuz)))))
315
351
  end
316
352
 
353
+ it 'works with destructuring with multiple levels' do
354
+ '((foo, bar)) = baz'.
355
+ must_be_parsed_as s(:masgn,
356
+ s(:array,
357
+ s(:masgn,
358
+ s(:array,
359
+ s(:lasgn, :foo),
360
+ s(:lasgn, :bar)))),
361
+ s(:to_ary, s(:call, nil, :baz)))
362
+ end
363
+
317
364
  it 'works with instance variables' do
318
365
  '@foo, @bar = baz'.
319
366
  must_be_parsed_as s(:masgn,
@@ -455,7 +502,45 @@ describe RipperRubyParser::Parser do
455
502
  s(:call, nil, :bar)))
456
503
  end
457
504
 
458
- it 'works when assigning to a collection element' do
505
+ it 'works with boolean operators' do
506
+ 'foo &&= bar'.
507
+ must_be_parsed_as s(:op_asgn_and,
508
+ s(:lvar, :foo), s(:lasgn, :foo, s(:call, nil, :bar)))
509
+ end
510
+
511
+ it 'works with boolean operators and blocks' do
512
+ 'foo &&= begin; bar; end'.
513
+ must_be_parsed_as s(:op_asgn_and,
514
+ s(:lvar, :foo), s(:lasgn, :foo, s(:call, nil, :bar)))
515
+ end
516
+
517
+ it 'works with arithmetic operators and blocks' do
518
+ 'foo += begin; bar; end'.
519
+ must_be_parsed_as s(:lasgn, :foo,
520
+ s(:call, s(:lvar, :foo), :+, s(:call, nil, :bar)))
521
+ end
522
+ end
523
+
524
+ describe 'for operator assignment to an attribute' do
525
+ it 'works with +=' do
526
+ 'foo.bar += baz'.
527
+ must_be_parsed_as s(:op_asgn2,
528
+ s(:call, nil, :foo),
529
+ :bar=, :+,
530
+ s(:call, nil, :baz))
531
+ end
532
+
533
+ it 'works with ||=' do
534
+ 'foo.bar ||= baz'.
535
+ must_be_parsed_as s(:op_asgn2,
536
+ s(:call, nil, :foo),
537
+ :bar=, :'||',
538
+ s(:call, nil, :baz))
539
+ end
540
+ end
541
+
542
+ describe 'for operator assignment to a collection element' do
543
+ it 'works with +=' do
459
544
  'foo[bar] += baz'.
460
545
  must_be_parsed_as s(:op_asgn1,
461
546
  s(:call, nil, :foo),
@@ -464,7 +549,7 @@ describe RipperRubyParser::Parser do
464
549
  s(:call, nil, :baz))
465
550
  end
466
551
 
467
- it 'works with ||= when assigning to a collection element' do
552
+ it 'works with ||=' do
468
553
  'foo[bar] ||= baz'.
469
554
  must_be_parsed_as s(:op_asgn1,
470
555
  s(:call, nil, :foo),
@@ -473,100 +558,90 @@ describe RipperRubyParser::Parser do
473
558
  s(:call, nil, :baz))
474
559
  end
475
560
 
476
- it 'works when assigning to an attribute' do
477
- 'foo.bar += baz'.
478
- must_be_parsed_as s(:op_asgn2,
561
+ it 'handles multiple indices' do
562
+ 'foo[bar, baz] += qux'.
563
+ must_be_parsed_as s(:op_asgn1,
479
564
  s(:call, nil, :foo),
480
- :bar=, :+,
481
- s(:call, nil, :baz))
565
+ s(:arglist,
566
+ s(:call, nil, :bar),
567
+ s(:call, nil, :baz)),
568
+ :+,
569
+ s(:call, nil, :qux))
482
570
  end
483
571
 
484
- it 'works with ||= when assigning to an attribute' do
485
- 'foo.bar ||= baz'.
486
- must_be_parsed_as s(:op_asgn2,
572
+ it 'works with a function call without parentheses' do
573
+ 'foo[bar] += baz qux'.
574
+ must_be_parsed_as s(:op_asgn1,
487
575
  s(:call, nil, :foo),
488
- :bar=, :'||',
489
- s(:call, nil, :baz))
576
+ s(:arglist, s(:call, nil, :bar)),
577
+ :+,
578
+ s(:call, nil, :baz, s(:call, nil, :qux)))
490
579
  end
491
580
 
492
- describe 'assigning to a collection element' do
493
- it 'handles multiple indices' do
494
- 'foo[bar, baz] += qux'.
495
- must_be_parsed_as s(:op_asgn1,
496
- s(:call, nil, :foo),
497
- s(:arglist,
498
- s(:call, nil, :bar),
499
- s(:call, nil, :baz)),
500
- :+,
501
- s(:call, nil, :qux))
502
- end
503
-
504
- it 'works with boolean operators' do
505
- 'foo &&= bar'.
506
- must_be_parsed_as s(:op_asgn_and,
507
- s(:lvar, :foo), s(:lasgn, :foo, s(:call, nil, :bar)))
508
- end
509
-
510
- it 'works with boolean operators and blocks' do
511
- 'foo &&= begin; bar; end'.
512
- must_be_parsed_as s(:op_asgn_and,
513
- s(:lvar, :foo), s(:lasgn, :foo, s(:call, nil, :bar)))
514
- end
515
-
516
- it 'works with arithmetic operators and blocks' do
517
- 'foo += begin; bar; end'.
518
- must_be_parsed_as s(:lasgn, :foo,
519
- s(:call, s(:lvar, :foo), :+, s(:call, nil, :bar)))
520
- end
581
+ it 'works with a function call with parentheses' do
582
+ 'foo[bar] += baz(qux)'.
583
+ must_be_parsed_as s(:op_asgn1,
584
+ s(:call, nil, :foo),
585
+ s(:arglist, s(:call, nil, :bar)),
586
+ :+,
587
+ s(:call, nil, :baz, s(:call, nil, :qux)))
521
588
  end
522
- end
523
589
 
524
- describe 'when extra compatibility is turned on' do
525
- it 'works with a bare method call' do
526
- 'foo = bar'.
527
- must_be_parsed_as s(:lasgn, :foo, s(:call, nil, :bar)),
528
- extra_compatible: true
590
+ it 'works with a method call without parentheses' do
591
+ 'foo[bar] += baz.qux quuz'.
592
+ must_be_parsed_as s(:op_asgn1,
593
+ s(:call, nil, :foo),
594
+ s(:arglist, s(:call, nil, :bar)),
595
+ :+,
596
+ s(:call, s(:call, nil, :baz), :qux, s(:call, nil, :quuz)))
529
597
  end
530
598
 
531
- it 'works with a literal' do
532
- 'foo = 0'.
533
- must_be_parsed_as s(:lasgn, :foo, s(:lit, 0)),
534
- extra_compatible: true
599
+ it 'works with a method call with parentheses' do
600
+ 'foo[bar] += baz.qux(quuz)'.
601
+ must_be_parsed_as s(:op_asgn1,
602
+ s(:call, nil, :foo),
603
+ s(:arglist, s(:call, nil, :bar)),
604
+ :+,
605
+ s(:call, s(:call, nil, :baz), :qux, s(:call, nil, :quuz)))
535
606
  end
536
607
 
537
- it 'works with a bare method call with rescue modifier' do
538
- 'foo = bar rescue baz'.
539
- must_be_parsed_as s(:lasgn, :foo,
540
- s(:rescue,
541
- s(:call, nil, :bar),
542
- s(:resbody, s(:array), s(:call, nil, :baz)))),
608
+ it 'works with a function call without parentheses in extra compatible mode' do
609
+ 'foo[bar] += baz qux'.
610
+ must_be_parsed_as s(:op_asgn1,
611
+ s(:call, nil, :foo),
612
+ s(:array, s(:call, nil, :bar)),
613
+ :+,
614
+ s(:call, nil, :baz, s(:call, nil, :qux))),
543
615
  extra_compatible: true
544
616
  end
545
617
 
546
- it 'works with a method call with argument with bracket with rescue modifier' do
547
- 'foo = bar(baz) rescue qux'.
548
- must_be_parsed_as s(:lasgn, :foo,
549
- s(:rescue,
550
- s(:call, nil, :bar, s(:call, nil, :baz)),
551
- s(:resbody, s(:array), s(:call, nil, :qux)))),
618
+ it 'works with a function call with parentheses in extra compatible mode' do
619
+ 'foo[bar] += baz(qux)'.
620
+ must_be_parsed_as s(:op_asgn1,
621
+ s(:call, nil, :foo),
622
+ s(:arglist, s(:call, nil, :bar)),
623
+ :+,
624
+ s(:call, nil, :baz, s(:call, nil, :qux))),
552
625
  extra_compatible: true
553
626
  end
554
627
 
555
- it 'works with a method call with argument without bracket with rescue modifier' do
556
- 'foo = bar baz rescue qux'.
557
- must_be_parsed_as s(:rescue,
558
- s(:lasgn, :foo, s(:call, nil, :bar, s(:call, nil, :baz))),
559
- s(:resbody, s(:array), s(:call, nil, :qux))),
628
+ it 'works with a method call without parentheses in extra compatible mode' do
629
+ 'foo[bar] += baz.qux quuz'.
630
+ must_be_parsed_as s(:op_asgn1,
631
+ s(:call, nil, :foo),
632
+ s(:array, s(:call, nil, :bar)),
633
+ :+,
634
+ s(:call, s(:call, nil, :baz), :qux, s(:call, nil, :quuz))),
560
635
  extra_compatible: true
561
636
  end
562
637
 
563
- it 'works with a class method call with argument without bracket with rescue modifier' do
564
- 'foo = Bar.baz qux rescue quuz'.
565
- must_be_parsed_as s(:rescue,
566
- s(:lasgn,
567
- :foo,
568
- s(:call, s(:const, :Bar), :baz, s(:call, nil, :qux))),
569
- s(:resbody, s(:array), s(:call, nil, :quuz))),
638
+ it 'works with a method call with parentheses in extra compatible mode' do
639
+ 'foo[bar] += baz.qux(quuz)'.
640
+ must_be_parsed_as s(:op_asgn1,
641
+ s(:call, nil, :foo),
642
+ s(:arglist, s(:call, nil, :bar)),
643
+ :+,
644
+ s(:call, s(:call, nil, :baz), :qux, s(:call, nil, :quuz))),
570
645
  extra_compatible: true
571
646
  end
572
647
  end