ripper_ruby_parser 1.1.2 → 1.2.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 (40) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +19 -0
  3. data/README.md +2 -2
  4. data/Rakefile +1 -1
  5. data/lib/ripper_ruby_parser.rb +0 -7
  6. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +112 -34
  7. data/lib/ripper_ruby_parser/parser.rb +26 -12
  8. data/lib/ripper_ruby_parser/sexp_handlers.rb +4 -1
  9. data/lib/ripper_ruby_parser/sexp_handlers/arguments.rb +7 -6
  10. data/lib/ripper_ruby_parser/sexp_handlers/arrays.rb +4 -2
  11. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +39 -43
  12. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +93 -69
  13. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +30 -24
  14. data/lib/ripper_ruby_parser/sexp_handlers/hashes.rb +7 -9
  15. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +51 -71
  16. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +72 -56
  17. data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +14 -13
  18. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +19 -13
  19. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +19 -22
  20. data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +47 -35
  21. data/lib/ripper_ruby_parser/sexp_processor.rb +72 -85
  22. data/lib/ripper_ruby_parser/version.rb +1 -1
  23. data/test/end_to_end/line_numbering_test.rb +1 -1
  24. data/test/end_to_end/samples_comparison_test.rb +0 -1
  25. data/test/pt_testcase/pt_test.rb +4 -6
  26. data/test/{unit → ripper_ruby_parser}/commenting_ripper_parser_test.rb +82 -25
  27. data/test/{unit → ripper_ruby_parser}/parser_test.rb +37 -170
  28. data/test/{unit/parser_assignment_test.rb → ripper_ruby_parser/sexp_handlers/assignment_test.rb} +1 -1
  29. data/test/{unit/parser_blocks_test.rb → ripper_ruby_parser/sexp_handlers/blocks_test.rb} +267 -2
  30. data/test/{unit/parser_conditionals_test.rb → ripper_ruby_parser/sexp_handlers/conditionals_test.rb} +125 -17
  31. data/test/{unit/parser_literals_test.rb → ripper_ruby_parser/sexp_handlers/literals_test.rb} +10 -12
  32. data/test/{unit/parser_loops_test.rb → ripper_ruby_parser/sexp_handlers/loops_test.rb} +1 -1
  33. data/test/{unit/parser_method_calls_test.rb → ripper_ruby_parser/sexp_handlers/method_calls_test.rb} +10 -10
  34. data/test/{unit/parser_operators_test.rb → ripper_ruby_parser/sexp_handlers/operators_test.rb} +22 -2
  35. data/test/{unit → ripper_ruby_parser}/sexp_processor_test.rb +49 -48
  36. data/test/{unit → ripper_ruby_parser}/version_test.rb +0 -0
  37. data/test/samples/misc.rb +4 -0
  38. data/test/test_helper.rb +4 -4
  39. metadata +28 -42
  40. data/test/end_to_end/error_conditions_test.rb +0 -51
@@ -1,4 +1,4 @@
1
- require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
1
+ require File.expand_path('../../test_helper.rb', File.dirname(__FILE__))
2
2
 
3
3
  describe RipperRubyParser::Parser do
4
4
  describe '#parse' do
@@ -1,7 +1,24 @@
1
- require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
1
+ require File.expand_path('../../test_helper.rb', File.dirname(__FILE__))
2
2
 
3
3
  describe RipperRubyParser::Parser do
4
4
  describe '#parse' do
5
+ describe 'for blocks' do
6
+ it 'works with no statements in the block body' do
7
+ 'foo do; end'.
8
+ must_be_parsed_as s(:iter,
9
+ s(:call, nil, :foo),
10
+ 0)
11
+ end
12
+
13
+ it 'works with redo' do
14
+ 'foo do; redo; end'.
15
+ must_be_parsed_as s(:iter,
16
+ s(:call, nil, :foo),
17
+ 0,
18
+ s(:redo))
19
+ end
20
+ end
21
+
5
22
  describe 'for block parameters' do
6
23
  specify do
7
24
  'foo do |(bar, baz)| end'.
@@ -55,6 +72,135 @@ describe RipperRubyParser::Parser do
55
72
  s(:call, nil, :foo),
56
73
  s(:args, :bar))
57
74
  end
75
+
76
+ it 'works with zero arguments' do
77
+ 'foo do ||; end'.
78
+ must_be_parsed_as s(:iter,
79
+ s(:call, nil, :foo),
80
+ s(:args))
81
+ end
82
+
83
+ it 'works with one argument' do
84
+ 'foo do |bar|; end'.
85
+ must_be_parsed_as s(:iter,
86
+ s(:call, nil, :foo),
87
+ s(:args, :bar))
88
+ end
89
+
90
+ it 'works with multiple arguments' do
91
+ 'foo do |bar, baz|; end'.
92
+ must_be_parsed_as s(:iter,
93
+ s(:call, nil, :foo),
94
+ s(:args, :bar, :baz))
95
+ end
96
+
97
+ it 'works with a single splat argument' do
98
+ 'foo do |*bar|; end'.
99
+ must_be_parsed_as s(:iter,
100
+ s(:call, nil, :foo),
101
+ s(:args, :"*bar"))
102
+ end
103
+
104
+ it 'works with a combination of regular arguments and a splat argument' do
105
+ 'foo do |bar, *baz|; end'.
106
+ must_be_parsed_as s(:iter,
107
+ s(:call, nil, :foo),
108
+ s(:args, :bar, :"*baz"))
109
+ end
110
+ end
111
+
112
+ describe 'for begin' do
113
+ it 'works for an empty begin..end block' do
114
+ 'begin end'.must_be_parsed_as s(:nil)
115
+ end
116
+
117
+ it 'works for a simple begin..end block' do
118
+ 'begin; foo; end'.must_be_parsed_as s(:call, nil, :foo)
119
+ end
120
+
121
+ it 'works for begin..end block with more than one statement' do
122
+ 'begin; foo; bar; end'.
123
+ must_be_parsed_as s(:block,
124
+ s(:call, nil, :foo),
125
+ s(:call, nil, :bar))
126
+ end
127
+
128
+ it 'keeps :begin for the argument of a unary operator' do
129
+ '- begin; foo; end'.
130
+ must_be_parsed_as s(:call,
131
+ s(:begin, s(:call, nil, :foo)),
132
+ :-@)
133
+ end
134
+
135
+ it 'keeps :begin for the first argument of a binary operator' do
136
+ 'begin; bar; end + foo'.
137
+ must_be_parsed_as s(:call,
138
+ s(:begin, s(:call, nil, :bar)),
139
+ :+,
140
+ s(:call, nil, :foo))
141
+ end
142
+
143
+ it 'keeps :begin for the second argument of a binary operator' do
144
+ 'foo + begin; bar; end'.
145
+ must_be_parsed_as s(:call,
146
+ s(:call, nil, :foo),
147
+ :+,
148
+ s(:begin, s(:call, nil, :bar)))
149
+ end
150
+
151
+ it 'does not keep :begin for the first argument of a boolean operator' do
152
+ 'begin; bar; end and foo'.
153
+ must_be_parsed_as s(:and,
154
+ s(:call, nil, :bar),
155
+ s(:call, nil, :foo))
156
+ end
157
+
158
+ it 'keeps :begin for the second argument of a boolean operator' do
159
+ 'foo and begin; bar; end'.
160
+ must_be_parsed_as s(:and,
161
+ s(:call, nil, :foo),
162
+ s(:begin, s(:call, nil, :bar)))
163
+ end
164
+
165
+ it 'does not keep :begin for the first argument of a shift operator' do
166
+ 'begin; bar; end << foo'.
167
+ must_be_parsed_as s(:call,
168
+ s(:call, nil, :bar),
169
+ :<<,
170
+ s(:call, nil, :foo))
171
+ end
172
+
173
+ it 'does not keep :begin for the second argument of a shift operator' do
174
+ 'foo >> begin; bar; end'.
175
+ must_be_parsed_as s(:call,
176
+ s(:call, nil, :foo),
177
+ :>>,
178
+ s(:call, nil, :bar))
179
+ end
180
+
181
+ it 'keeps :begin for the first argument of a ternary operator' do
182
+ 'begin; foo; end ? bar : baz'.
183
+ must_be_parsed_as s(:if,
184
+ s(:begin, s(:call, nil, :foo)),
185
+ s(:call, nil, :bar),
186
+ s(:call, nil, :baz))
187
+ end
188
+
189
+ it 'keeps :begin for the second argument of a ternary operator' do
190
+ 'foo ? begin; bar; end : baz'.
191
+ must_be_parsed_as s(:if,
192
+ s(:call, nil, :foo),
193
+ s(:begin, s(:call, nil, :bar)),
194
+ s(:call, nil, :baz))
195
+ end
196
+
197
+ it 'keeps :begin for the third argument of a ternary operator' do
198
+ 'foo ? bar : begin; baz; end'.
199
+ must_be_parsed_as s(:if,
200
+ s(:call, nil, :foo),
201
+ s(:call, nil, :bar),
202
+ s(:begin, s(:call, nil, :baz)))
203
+ end
58
204
  end
59
205
 
60
206
  describe 'for rescue/else' do
@@ -244,6 +390,126 @@ describe RipperRubyParser::Parser do
244
390
  end
245
391
  end
246
392
 
393
+ describe 'for the next statement' do
394
+ it 'works with no arguments' do
395
+ 'foo do; next; end'.
396
+ must_be_parsed_as s(:iter,
397
+ s(:call, nil, :foo),
398
+ 0,
399
+ s(:next))
400
+ end
401
+
402
+ it 'works with one argument' do
403
+ 'foo do; next bar; end'.
404
+ must_be_parsed_as s(:iter,
405
+ s(:call, nil, :foo),
406
+ 0,
407
+ s(:next, s(:call, nil, :bar)))
408
+ end
409
+
410
+ it 'works with a splat argument' do
411
+ 'foo do; next *bar; end'.
412
+ must_be_parsed_as s(:iter,
413
+ s(:call, nil, :foo),
414
+ 0,
415
+ s(:next,
416
+ s(:svalue,
417
+ s(:splat,
418
+ s(:call, nil, :bar)))))
419
+ end
420
+
421
+ it 'works with several arguments' do
422
+ 'foo do; next bar, baz; end'.
423
+ must_be_parsed_as s(:iter,
424
+ s(:call, nil, :foo),
425
+ 0,
426
+ s(:next,
427
+ s(:array,
428
+ s(:call, nil, :bar),
429
+ s(:call, nil, :baz))))
430
+ end
431
+
432
+ it 'works with a function call with parentheses' do
433
+ 'foo do; next foo(bar); end'.
434
+ must_be_parsed_as s(:iter,
435
+ s(:call, nil, :foo),
436
+ 0,
437
+ s(:next,
438
+ s(:call, nil, :foo,
439
+ s(:call, nil, :bar))))
440
+ end
441
+
442
+ it 'works with a function call without parentheses' do
443
+ 'foo do; next foo bar; end'.
444
+ must_be_parsed_as s(:iter,
445
+ s(:call, nil, :foo),
446
+ 0,
447
+ s(:next,
448
+ s(:call, nil, :foo,
449
+ s(:call, nil, :bar))))
450
+ end
451
+ end
452
+
453
+ describe 'for the break statement' do
454
+ it 'works with break with no arguments' do
455
+ 'foo do; break; end'.
456
+ must_be_parsed_as s(:iter,
457
+ s(:call, nil, :foo),
458
+ 0,
459
+ s(:break))
460
+ end
461
+
462
+ it 'works with break with one argument' do
463
+ 'foo do; break bar; end'.
464
+ must_be_parsed_as s(:iter,
465
+ s(:call, nil, :foo),
466
+ 0,
467
+ s(:break, s(:call, nil, :bar)))
468
+ end
469
+
470
+ it 'works with a splat argument' do
471
+ 'foo do; break *bar; end'.
472
+ must_be_parsed_as s(:iter,
473
+ s(:call, nil, :foo),
474
+ 0,
475
+ s(:break,
476
+ s(:svalue,
477
+ s(:splat,
478
+ s(:call, nil, :bar)))))
479
+ end
480
+
481
+ it 'works with break with several arguments' do
482
+ 'foo do; break bar, baz; end'.
483
+ must_be_parsed_as s(:iter,
484
+ s(:call, nil, :foo),
485
+ 0,
486
+ s(:break,
487
+ s(:array,
488
+ s(:call, nil, :bar),
489
+ s(:call, nil, :baz))))
490
+ end
491
+
492
+ it 'works with break with a function call with parentheses' do
493
+ 'foo do; break foo(bar); end'.
494
+ must_be_parsed_as s(:iter,
495
+ s(:call, nil, :foo),
496
+ 0,
497
+ s(:break,
498
+ s(:call, nil, :foo,
499
+ s(:call, nil, :bar))))
500
+ end
501
+
502
+ it 'works with break with a function call without parentheses' do
503
+ 'foo do; break foo bar; end'.
504
+ must_be_parsed_as s(:iter,
505
+ s(:call, nil, :foo),
506
+ 0,
507
+ s(:break,
508
+ s(:call, nil, :foo,
509
+ s(:call, nil, :bar))))
510
+ end
511
+ end
512
+
247
513
  describe 'for lists of consecutive statments' do
248
514
  it 'removes extra blocks for grouped statements at the start of the list' do
249
515
  '(foo; bar); baz'.
@@ -304,7 +570,6 @@ describe RipperRubyParser::Parser do
304
570
  s(:call, nil, :bar),
305
571
  s(:call, nil, :baz)))
306
572
  end
307
-
308
573
  end
309
574
  end
310
575
  end
@@ -1,4 +1,4 @@
1
- require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
1
+ require File.expand_path('../../test_helper.rb', File.dirname(__FILE__))
2
2
 
3
3
  describe RipperRubyParser::Parser do
4
4
  describe '#parse' do
@@ -21,6 +21,14 @@ describe RipperRubyParser::Parser do
21
21
  nil)
22
22
  end
23
23
 
24
+ it 'works with zero statements' do
25
+ 'if foo; end'.
26
+ must_be_parsed_as s(:if,
27
+ s(:call, nil, :foo),
28
+ nil,
29
+ nil)
30
+ end
31
+
24
32
  it 'works with an else clause' do
25
33
  'if foo; bar; else; baz; end'.
26
34
  must_be_parsed_as s(:if,
@@ -29,33 +37,28 @@ describe RipperRubyParser::Parser do
29
37
  s(:call, nil, :baz))
30
38
  end
31
39
 
32
- it 'works with an elsif clause' do
33
- 'if foo; bar; elsif baz; qux; end'.
40
+ it 'works with an empty main clause' do
41
+ 'if foo; else; bar; end'.
34
42
  must_be_parsed_as s(:if,
35
43
  s(:call, nil, :foo),
36
- s(:call, nil, :bar),
37
- s(:if,
38
- s(:call, nil, :baz),
39
- s(:call, nil, :qux),
40
- nil))
44
+ nil,
45
+ s(:call, nil, :bar))
41
46
  end
42
47
 
43
- it 'handles a negative condition correctly' do
44
- 'if not foo; bar; end'.
48
+ it 'works with an empty else clause' do
49
+ 'if foo; bar; else; end'.
45
50
  must_be_parsed_as s(:if,
46
- s(:call, s(:call, nil, :foo), :!),
51
+ s(:call, nil, :foo),
47
52
  s(:call, nil, :bar),
48
53
  nil)
49
54
  end
50
55
 
51
- it 'handles a negative condition in elsif correctly' do
52
- 'if foo; bar; elsif not baz; qux; end'.
56
+ it 'handles a negative condition correctly' do
57
+ 'if not foo; bar; end'.
53
58
  must_be_parsed_as s(:if,
54
- s(:call, nil, :foo),
59
+ s(:call, s(:call, nil, :foo), :!),
55
60
  s(:call, nil, :bar),
56
- s(:if,
57
- s(:call, s(:call, nil, :baz), :!),
58
- s(:call, nil, :qux), nil))
61
+ nil)
59
62
  end
60
63
 
61
64
  it 'handles bare regex literal in condition' do
@@ -158,6 +161,24 @@ describe RipperRubyParser::Parser do
158
161
  s(:call, nil, :foo))
159
162
  end
160
163
 
164
+ it 'works with multiple statements' do
165
+ 'unless foo; bar; baz; end'.
166
+ must_be_parsed_as s(:if,
167
+ s(:call, nil, :foo),
168
+ nil,
169
+ s(:block,
170
+ s(:call, nil, :bar),
171
+ s(:call, nil, :baz)))
172
+ end
173
+
174
+ it 'works with zero statements' do
175
+ 'unless foo; end'.
176
+ must_be_parsed_as s(:if,
177
+ s(:call, nil, :foo),
178
+ nil,
179
+ nil)
180
+ end
181
+
161
182
  it 'works with an else clause' do
162
183
  'unless foo; bar; else; baz; end'.
163
184
  must_be_parsed_as s(:if,
@@ -165,6 +186,23 @@ describe RipperRubyParser::Parser do
165
186
  s(:call, nil, :baz),
166
187
  s(:call, nil, :bar))
167
188
  end
189
+
190
+ it 'works with an empty main clause' do
191
+ 'unless foo; else; bar; end'.
192
+ must_be_parsed_as s(:if,
193
+ s(:call, nil, :foo),
194
+ s(:call, nil, :bar),
195
+ nil)
196
+ end
197
+
198
+ it 'works with an empty else block' do
199
+ 'unless foo; bar; else; end'.
200
+ must_be_parsed_as s(:if,
201
+ s(:call, nil, :foo),
202
+ nil,
203
+ s(:call, nil, :bar))
204
+ end
205
+
168
206
  it 'handles bare regex literal in condition' do
169
207
  'unless /foo/; bar; end'.
170
208
  must_be_parsed_as s(:if,
@@ -224,6 +262,76 @@ describe RipperRubyParser::Parser do
224
262
  end
225
263
  end
226
264
 
265
+ describe 'for elsif' do
266
+ it 'works with a single statement' do
267
+ 'if foo; bar; elsif baz; qux; end'.
268
+ must_be_parsed_as s(:if,
269
+ s(:call, nil, :foo),
270
+ s(:call, nil, :bar),
271
+ s(:if,
272
+ s(:call, nil, :baz),
273
+ s(:call, nil, :qux),
274
+ nil))
275
+ end
276
+
277
+ it 'works with an empty consequesnt' do
278
+ 'if foo; bar; elsif baz; end'.
279
+ must_be_parsed_as s(:if,
280
+ s(:call, nil, :foo),
281
+ s(:call, nil, :bar),
282
+ s(:if,
283
+ s(:call, nil, :baz),
284
+ nil,
285
+ nil))
286
+ end
287
+
288
+ it 'works with an empty else' do
289
+ 'if foo; bar; elsif baz; qux; else; end'.
290
+ must_be_parsed_as s(:if,
291
+ s(:call, nil, :foo),
292
+ s(:call, nil, :bar),
293
+ s(:if,
294
+ s(:call, nil, :baz),
295
+ s(:call, nil, :qux),
296
+ nil))
297
+ end
298
+
299
+ it 'handles a negative condition correctly' do
300
+ 'if foo; bar; elsif not baz; qux; end'.
301
+ must_be_parsed_as s(:if,
302
+ s(:call, nil, :foo),
303
+ s(:call, nil, :bar),
304
+ s(:if,
305
+ s(:call, s(:call, nil, :baz), :!),
306
+ s(:call, nil, :qux), nil))
307
+ end
308
+
309
+ it 'does not replace :dot2 with :flip2' do
310
+ 'if foo; bar; elsif baz..qux; quuz; end'.
311
+ must_be_parsed_as s(:if,
312
+ s(:call, nil, :foo),
313
+ s(:call, nil, :bar),
314
+ s(:if,
315
+ s(:dot2, s(:call, nil, :baz), s(:call, nil, :qux)),
316
+ s(:call, nil, :quuz), nil))
317
+ end
318
+
319
+ it 'does not rewrite the negative match operator' do
320
+ 'if foo; bar; elsif baz !~ qux; quuz; end'.
321
+ must_be_parsed_as s(:if,
322
+ s(:call, nil, :foo),
323
+ s(:call, nil, :bar),
324
+ s(:if,
325
+ s(:not,
326
+ s(:call,
327
+ s(:call, nil, :baz),
328
+ :=~,
329
+ s(:call, nil, :qux))),
330
+ s(:call, nil, :quuz),
331
+ nil))
332
+ end
333
+ end
334
+
227
335
  describe 'for case block' do
228
336
  it 'works with a single when clause' do
229
337
  'case foo; when bar; baz; end'.