ripper_ruby_parser 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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