ruby_parser-legacy 1.0.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.

Potentially problematic release.


This version of ruby_parser-legacy might be problematic. Click here for more details.

@@ -0,0 +1,3951 @@
1
+ # encoding: utf-8
2
+
3
+ # ENV['VERBOSE'] = "1"
4
+
5
+ require "minitest/autorun"
6
+ require "ruby_parser/legacy/ruby_parser"
7
+
8
+ require "pt_testcase"
9
+
10
+ class Sexp
11
+ alias oldeq2 ==
12
+ # TODO: push up to Sexp
13
+ def ==(obj) # :nodoc:
14
+ if obj.class == self.class then
15
+ super and
16
+ (self.line.nil? or obj.line.nil? or self.line == obj.line)
17
+ else
18
+ false
19
+ end
20
+ end
21
+ end
22
+
23
+ module TestRubyParserShared
24
+ def setup
25
+ super
26
+ # p :test => [self.class, __name__]
27
+ end
28
+
29
+ BLOCK_DUP_MSG = "Both block arg and actual block given."
30
+
31
+ def test_double_block_error_01
32
+ assert_syntax_error "a(1, &b) { }", BLOCK_DUP_MSG
33
+ end
34
+
35
+ def test_double_block_error_02
36
+ assert_syntax_error "a(1, &b) do end", BLOCK_DUP_MSG
37
+ end
38
+
39
+ def test_double_block_error_03
40
+ assert_syntax_error "a 1, &b do end", BLOCK_DUP_MSG
41
+ end
42
+
43
+ def test_double_block_error_04
44
+ assert_syntax_error "m.a(1, &b) { }", BLOCK_DUP_MSG
45
+ end
46
+
47
+ def test_double_block_error_05
48
+ assert_syntax_error "m.a(1, &b) do end", BLOCK_DUP_MSG
49
+ end
50
+
51
+ def test_double_block_error_06
52
+ assert_syntax_error "m.a 1, &b do end", BLOCK_DUP_MSG
53
+ end
54
+
55
+ def test_double_block_error_07
56
+ assert_syntax_error "m::a(1, &b) { }", BLOCK_DUP_MSG
57
+ end
58
+
59
+ def test_double_block_error_08
60
+ assert_syntax_error "m::a(1, &b) do end", BLOCK_DUP_MSG
61
+ end
62
+
63
+ def test_double_block_error_09
64
+ assert_syntax_error "m::a 1, &b do end", BLOCK_DUP_MSG
65
+ end
66
+
67
+ def test_wtf_7
68
+ rb = "a.b (1) {c}"
69
+ pt = s(:iter,
70
+ s(:call, s(:call, nil, :a), :b, s(:lit, 1)),
71
+ 0,
72
+ s(:call, nil, :c))
73
+
74
+ assert_parse rb, pt
75
+ end
76
+
77
+ def test_wtf_8
78
+ rb = "a::b (1) {c}"
79
+ pt = s(:iter,
80
+ s(:call, s(:call, nil, :a), :b, s(:lit, 1)),
81
+ 0,
82
+ s(:call, nil, :c))
83
+
84
+ assert_parse rb, pt
85
+ end
86
+
87
+ def test_attrasgn_array_lhs
88
+ rb = '[1, 2, 3, 4][from .. to] = ["a", "b", "c"]'
89
+ pt = s(:attrasgn,
90
+ s(:array, s(:lit, 1), s(:lit, 2), s(:lit, 3), s(:lit, 4)),
91
+ :[]=,
92
+ s(:dot2,
93
+ s(:call, nil, :from),
94
+ s(:call, nil, :to)),
95
+ s(:array, s(:str, "a"), s(:str, "b"), s(:str, "c")))
96
+
97
+ assert_parse rb, pt
98
+ end
99
+
100
+ def test_attrasgn_array_arg
101
+ rb = "a[[1, 2]] = 3"
102
+ pt = s(:attrasgn,
103
+ s(:call, nil, :a),
104
+ :[]=,
105
+ s(:array,
106
+ s(:lit, 1),
107
+ s(:lit, 2)),
108
+ s(:lit, 3))
109
+
110
+ assert_parse rb, pt
111
+ end
112
+
113
+ def test_block_append
114
+ head = s(:args)
115
+ tail = s(:zsuper)
116
+ expected = s(:block, s(:args), s(:zsuper))
117
+ assert_equal expected, processor.block_append(head, tail)
118
+ end
119
+
120
+ def test_block_append_begin_begin
121
+ head = s(:begin, s(:args))
122
+ tail = s(:begin, s(:args))
123
+ expected = s(:block, s(:args), s(:begin, s(:args)))
124
+ assert_equal expected, processor.block_append(head, tail)
125
+ end
126
+
127
+ def test_block_append_block
128
+ head = s(:block, s(:args))
129
+ tail = s(:zsuper)
130
+ expected = s(:block, s(:args), s(:zsuper))
131
+ assert_equal expected, processor.block_append(head, tail)
132
+ end
133
+
134
+ def test_block_append_nil_head
135
+ head = nil
136
+ tail = s(:zsuper)
137
+ expected = s(:zsuper)
138
+ assert_equal expected, processor.block_append(head, tail)
139
+ end
140
+
141
+ def test_block_append_nil_tail
142
+ head = s(:args)
143
+ tail = nil
144
+ expected = s(:args)
145
+ assert_equal expected, processor.block_append(head, tail)
146
+ end
147
+
148
+ def test_block_append_tail_block
149
+ head = s(:call, nil, :f1)
150
+ tail = s(:block, s(:undef, s(:lit, :x)), s(:undef, s(:lit, :y)))
151
+ expected = s(:block,
152
+ s(:call, nil, :f1),
153
+ s(:block, s(:undef, s(:lit, :x)), s(:undef, s(:lit, :y))))
154
+ assert_equal expected, processor.block_append(head, tail)
155
+ end
156
+
157
+ def test_call_array_arg
158
+ rb = "1 == [:b, :c]"
159
+ pt = s(:call, s(:lit, 1), :==, s(:array, s(:lit, :b), s(:lit, :c)))
160
+
161
+ assert_parse rb, pt
162
+ end
163
+
164
+ def test_call_env
165
+ processor.env[:a] = :lvar
166
+ rb = "a.happy"
167
+ pt = s(:call, s(:lvar, :a), :happy)
168
+
169
+ assert_parse rb, pt
170
+ end
171
+
172
+ def test_call_self_brackets
173
+ rb = "self[1]"
174
+ pt = s(:call, s(:self), :[], s(:lit, 1))
175
+
176
+ assert_parse rb, pt
177
+ end
178
+
179
+ def test_dasgn_icky2
180
+ rb = "a do\n v = nil\n begin\n yield\n rescue Exception => v\n break\n end\nend"
181
+ pt = s(:iter,
182
+ s(:call, nil, :a),
183
+ 0,
184
+ s(:block,
185
+ s(:lasgn, :v, s(:nil)),
186
+ s(:rescue,
187
+ s(:yield),
188
+ s(:resbody,
189
+ s(:array, s(:const, :Exception), s(:lasgn, :v, s(:gvar, :$!))),
190
+ s(:break)))))
191
+
192
+ assert_parse rb, pt
193
+ end
194
+
195
+ def test_class_comments
196
+ rb = "# blah 1\n# blah 2\n\nclass X\n # blah 3\n def blah\n # blah 4\n end\nend"
197
+ pt = s(:class, :X, nil,
198
+ s(:defn, :blah, s(:args), s(:nil)))
199
+
200
+ assert_parse rb, pt
201
+
202
+ assert_equal "# blah 1\n# blah 2\n\n", result.comments
203
+ assert_equal "# blah 3\n", result.defn.comments
204
+ end
205
+
206
+ def test_module_comments
207
+ rb = "# blah 1\n \n # blah 2\n\nmodule X\n # blah 3\n def blah\n # blah 4\n end\nend"
208
+ pt = s(:module, :X,
209
+ s(:defn, :blah, s(:args), s(:nil)))
210
+
211
+ assert_parse rb, pt
212
+ assert_equal "# blah 1\n\n# blah 2\n\n", result.comments
213
+ assert_equal "# blah 3\n", result.defn.comments
214
+ end
215
+
216
+ def test_defn_comments
217
+ rb = "# blah 1\n# blah 2\n\ndef blah\nend"
218
+ pt = s(:defn, :blah, s(:args), s(:nil))
219
+
220
+ assert_parse rb, pt
221
+ assert_equal "# blah 1\n# blah 2\n\n", result.comments
222
+ end
223
+
224
+ def test_defs_comments
225
+ rb = "# blah 1\n# blah 2\n\ndef self.blah\nend"
226
+ pt = s(:defs, s(:self), :blah, s(:args), s(:nil))
227
+
228
+ assert_parse rb, pt
229
+ assert_equal "# blah 1\n# blah 2\n\n", result.comments
230
+ end
231
+
232
+ def test_do_bug # TODO: rename
233
+ rb = "a 1\na.b do |c|\n # do nothing\nend"
234
+ pt = s(:block,
235
+ s(:call, nil, :a, s(:lit, 1)),
236
+ s(:iter,
237
+ s(:call, s(:call, nil, :a), :b),
238
+ s(:args, :c)))
239
+
240
+ assert_parse rb, pt
241
+ end
242
+
243
+ def test_bug_begin_else
244
+ skip if ruby18 or ruby19
245
+
246
+ rb = "begin 1; else; 2 end"
247
+
248
+ assert_syntax_error rb, "else without rescue is useless"
249
+ end
250
+
251
+ def test_begin_else_return_value
252
+ skip if ruby18 or ruby19
253
+
254
+ rb = "begin; else 2; end"
255
+
256
+ assert_syntax_error rb, "else without rescue is useless"
257
+ end
258
+
259
+ def test_bug_comment_eq_begin
260
+ rb = "\n\n#\n=begin\nblah\n=end\n\n"
261
+ exp = rb.strip + "\n"
262
+
263
+ refute_parse rb
264
+ assert_equal exp, processor.lexer.comments
265
+ end
266
+
267
+ def test_eq_begin_why_wont_people_use_their_spacebar?
268
+ rb = "h[k]=begin\n 42\n end"
269
+ pt = s(:attrasgn, s(:call, nil, :h), :[]=, s(:call, nil, :k), s(:lit, 42))
270
+
271
+ assert_parse rb, pt
272
+ end
273
+
274
+ def test_eq_begin_line_numbers
275
+ rb = "1\n=begin\ncomment\ncomment\n=end\n2"
276
+ pt = s(:block,
277
+ s(:lit, 1).line(1),
278
+ s(:lit, 2).line(6))
279
+
280
+ assert_parse rb, pt
281
+ end
282
+
283
+ def test_bug_call_arglist_parens
284
+ rb = 'g ( 1), 2'
285
+ pt = s(:call, nil, :g, s(:lit, 1), s(:lit, 2))
286
+
287
+ assert_parse rb, pt
288
+
289
+ rb = <<-CODE
290
+ def f
291
+ g ( 1), 2
292
+ end
293
+ CODE
294
+
295
+ pt = s(:defn, :f, s(:args),
296
+ s(:call, nil, :g, s(:lit, 1), s(:lit, 2)))
297
+
298
+ assert_parse rb, pt
299
+
300
+ rb = <<-CODE
301
+ def f()
302
+ g (1), 2
303
+ end
304
+ CODE
305
+
306
+ assert_parse rb, pt
307
+ end
308
+
309
+ def test_dstr_evstr
310
+ rb = "\"#\{'a'}#\{b}\""
311
+ pt = s(:dstr, "a", s(:evstr, s(:call, nil, :b)))
312
+
313
+ assert_parse rb, pt
314
+ end
315
+
316
+ def test_dstr_str
317
+ rb = "\"#\{'a'} b\""
318
+ pt = s(:str, "a b")
319
+
320
+ assert_parse rb, pt
321
+ end
322
+
323
+ def test_empty
324
+ refute_parse ""
325
+ end
326
+
327
+ def test_evstr_evstr
328
+ rb = "\"#\{a}#\{b}\""
329
+ pt = s(:dstr, "", s(:evstr, s(:call, nil, :a)), s(:evstr, s(:call, nil, :b)))
330
+
331
+ assert_parse rb, pt
332
+ end
333
+
334
+ def test_evstr_str
335
+ rb = "\"#\{a} b\""
336
+ pt = s(:dstr, "", s(:evstr, s(:call, nil, :a)), s(:str, " b"))
337
+
338
+ assert_parse rb, pt
339
+ end
340
+
341
+ def test_lasgn_env
342
+ rb = "a = 42"
343
+ pt = s(:lasgn, :a, s(:lit, 42))
344
+ expected_env = { :a => :lvar }
345
+
346
+ assert_parse rb, pt
347
+ assert_equal expected_env, processor.env.all
348
+ end
349
+
350
+ def test_lasgn_ivar_env
351
+ rb = "@a = 42"
352
+ pt = s(:iasgn, :@a, s(:lit, 42))
353
+
354
+ assert_parse rb, pt
355
+ assert_empty processor.env.all
356
+ end
357
+
358
+ def test_list_append
359
+ a = s(:lit, 1)
360
+ b = s(:lit, 2)
361
+ c = s(:lit, 3)
362
+
363
+ result = processor.list_append(s(:array, b.dup), c.dup)
364
+
365
+ assert_equal s(:array, b, c), result
366
+
367
+ result = processor.list_append(b.dup, c.dup)
368
+
369
+ assert_equal s(:array, b, c), result
370
+
371
+ result = processor.list_append(result, a.dup)
372
+
373
+ assert_equal s(:array, b, c, a), result
374
+
375
+ lhs, rhs = s(:array, s(:lit, :iter)), s(:when, s(:const, :BRANCHING), nil)
376
+ expected = s(:array, s(:lit, :iter), s(:when, s(:const, :BRANCHING), nil))
377
+
378
+ assert_equal expected, processor.list_append(lhs, rhs)
379
+ end
380
+
381
+ def test_list_prepend
382
+ a = s(:lit, 1)
383
+ b = s(:lit, 2)
384
+ c = s(:lit, 3)
385
+
386
+ result = processor.list_prepend(b.dup, s(:array, c.dup))
387
+
388
+ assert_equal s(:array, b, c), result
389
+
390
+ result = processor.list_prepend(b.dup, c.dup)
391
+
392
+ assert_equal s(:array, b, c), result
393
+
394
+ result = processor.list_prepend(a.dup, result)
395
+
396
+ assert_equal s(:array, a, b, c), result
397
+ end
398
+
399
+ def test_literal_concat_dstr_dstr
400
+ lhs = s(:dstr, "Failed to download spec ",
401
+ s(:evstr, s(:call, nil, :spec_name)),
402
+ s(:str, " from "),
403
+ s(:evstr, s(:call, nil, :source_uri)),
404
+ s(:str, ":\n"))
405
+ rhs = s(:dstr, "\t",
406
+ s(:evstr, s(:call, s(:ivar, :@fetch_error), :message)))
407
+ expected = s(:dstr, "Failed to download spec ",
408
+ s(:evstr, s(:call, nil, :spec_name)),
409
+ s(:str, " from "),
410
+ s(:evstr, s(:call, nil, :source_uri)),
411
+ s(:str, ":\n"),
412
+ s(:str, "\t"),
413
+ s(:evstr, s(:call, s(:ivar, :@fetch_error), :message)))
414
+
415
+ assert_equal expected, processor.literal_concat(lhs, rhs)
416
+ end
417
+
418
+ def test_literal_concat_dstr_evstr
419
+ lhs, rhs = s(:dstr, "a"), s(:evstr, s(:call, nil, :b))
420
+ expected = s(:dstr, "a", s(:evstr, s(:call, nil, :b)))
421
+
422
+ assert_equal expected, processor.literal_concat(lhs, rhs)
423
+ end
424
+
425
+ def test_literal_concat_evstr_evstr
426
+ lhs, rhs = s(:evstr, s(:lit, 1)), s(:evstr, s(:lit, 2))
427
+ expected = s(:dstr, "", s(:evstr, s(:lit, 1)), s(:evstr, s(:lit, 2)))
428
+
429
+ assert_equal expected, processor.literal_concat(lhs, rhs)
430
+ end
431
+
432
+ def test_literal_concat_str_evstr
433
+ lhs, rhs = s(:str, ""), s(:evstr, s(:str, "blah"))
434
+
435
+ assert_equal s(:str, "blah"), processor.literal_concat(lhs, rhs)
436
+ end
437
+
438
+ def test_logical_op_12
439
+ lhs = s(:lit, 1)
440
+ rhs = s(:lit, 2)
441
+ exp = s(:and, s(:lit, 1), s(:lit, 2))
442
+
443
+ assert_equal exp, processor.logical_op(:and, lhs, rhs)
444
+ end
445
+
446
+ def test_logical_op_1234_5
447
+ lhs = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:and, s(:lit, 3), s(:lit, 4))))
448
+ rhs = s(:lit, 5)
449
+ exp = s(:and,
450
+ s(:lit, 1),
451
+ s(:and,
452
+ s(:lit, 2),
453
+ s(:and,
454
+ s(:lit, 3),
455
+ s(:and,
456
+ s(:lit, 4),
457
+ s(:lit, 5)))))
458
+
459
+ assert_equal exp, processor.logical_op(:and, lhs, rhs)
460
+ end
461
+
462
+ def test_logical_op_123_4
463
+ lhs = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:lit, 3)))
464
+ rhs = s(:lit, 4)
465
+ exp = s(:and,
466
+ s(:lit, 1),
467
+ s(:and,
468
+ s(:lit, 2),
469
+ s(:and,
470
+ s(:lit, 3),
471
+ s(:lit, 4))))
472
+
473
+ assert_equal exp, processor.logical_op(:and, lhs, rhs)
474
+ end
475
+
476
+ def test_logical_op_12_3
477
+ lhs = s(:and, s(:lit, 1), s(:lit, 2))
478
+ rhs = s(:lit, 3)
479
+ exp = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:lit, 3)))
480
+
481
+ assert_equal exp, processor.logical_op(:and, lhs, rhs)
482
+ end
483
+
484
+ def test_logical_op_nested_mix
485
+ lhs = s(:or, s(:call, nil, :a), s(:call, nil, :b))
486
+ rhs = s(:and, s(:call, nil, :c), s(:call, nil, :d))
487
+ exp = s(:or,
488
+ s(:or, s(:call, nil, :a), s(:call, nil, :b)),
489
+ s(:and, s(:call, nil, :c), s(:call, nil, :d)))
490
+
491
+ lhs.paren = true
492
+ rhs.paren = true
493
+
494
+ assert_equal exp, processor.logical_op(:or, lhs, rhs)
495
+ end
496
+
497
+ def test_str_evstr
498
+ rb = "\"a #\{b}\""
499
+ pt = s(:dstr, "a ", s(:evstr, s(:call, nil, :b)))
500
+
501
+ assert_parse rb, pt
502
+ end
503
+
504
+ def test_dsym_to_sym
505
+ pt = s(:alias, s(:lit, :<<), s(:lit, :>>))
506
+
507
+ rb = "alias :<< :>>"
508
+ assert_parse rb, pt
509
+
510
+ rb = 'alias :"<<" :">>"'
511
+ assert_parse rb, pt
512
+ end
513
+
514
+ def test_regexp
515
+ regexps = {
516
+ "/wtf/" => /wtf/,
517
+ "/wtf/n" => /wtf/n,
518
+ "/wtf/m" => /wtf/m,
519
+ "/wtf/nm" => /wtf/nm,
520
+ "/wtf/nmnmnmnm" => /wtf/nm,
521
+ }
522
+
523
+ regexps.each do |rb, lit|
524
+ assert_parse rb, s(:lit, lit)
525
+ end
526
+
527
+ # TODO: add more including interpolation etc
528
+ end
529
+
530
+ def test_label_vs_string
531
+ rb = "_buf << ':\n'"
532
+ pt = s(:call, s(:call, nil, :_buf), :<<, s(:str, ":\n"))
533
+
534
+ assert_parse rb, pt
535
+ end
536
+
537
+ def test_str_backslashes
538
+ long_string = '\n' * 100
539
+ rb = "x '#{long_string}'"
540
+ pt = s(:call, nil, :x, s(:str, long_string))
541
+
542
+ assert_parse rb, pt
543
+ end
544
+
545
+ def test_str_pct_Q_nested
546
+ rb = "%Q[before [#\{nest}] after]"
547
+ pt = s(:dstr, "before [", s(:evstr, s(:call, nil, :nest)), s(:str, "] after"))
548
+
549
+ assert_parse rb, pt
550
+ end
551
+
552
+ def test_str_pct_q
553
+ rb = "%q{a b c}"
554
+ pt = s(:str, "a b c")
555
+
556
+ assert_parse rb, pt
557
+ end
558
+
559
+ # def test_str_pct_nested_nested
560
+ # rb = "%{ { #\{ \"#\{1}\" } } }"
561
+ # assert_equal " { 1 } ", eval(rb)
562
+ # pt = s(:dstr, " { ", s(:evstr, s(:lit, 1)), s(:str, " } "))
563
+ #
564
+ # assert_parse rb, pt
565
+ # end
566
+
567
+ def test_str_str
568
+ rb = "\"a #\{'b'}\""
569
+ pt = s(:str, "a b")
570
+
571
+ assert_parse rb, pt
572
+ end
573
+
574
+ def test_str_str_str
575
+ rb = "\"a #\{'b'} c\""
576
+ pt = s(:str, "a b c")
577
+
578
+ assert_parse rb, pt
579
+ end
580
+
581
+ def test_str_newline_hash_line_number
582
+ rb = "\"\\n\\n\\n\\n#\"\n1"
583
+ pt = s(:block, s(:str, "\n\n\n\n#").line(1),
584
+ s(:lit, 1).line(2))
585
+
586
+ assert_parse rb, pt
587
+ end
588
+
589
+ def after_process_hook klass, node, data, input_name, output_name
590
+ assert_equal 1, @result.line, "should have proper line number"
591
+ end
592
+
593
+ def test_parse_line_block
594
+ rb = "a = 42\np a"
595
+ pt = s(:block,
596
+ s(:lasgn, :a, s(:lit, 42)),
597
+ s(:call, nil, :p, s(:lvar, :a)))
598
+
599
+ assert_parse_line rb, pt, 1
600
+ assert_equal 1, result.lasgn.line, "lasgn should have line number"
601
+ assert_equal 2, result.call.line, "call should have line number"
602
+
603
+ expected = "(string)"
604
+ assert_equal expected, result.file
605
+ assert_equal expected, result.lasgn.file
606
+ assert_equal expected, result.call.file
607
+
608
+ assert_same result.file, result.lasgn.file
609
+ assert_same result.file, result.call.file
610
+ end
611
+
612
+ def test_parse_line_block_inline_comment
613
+ rb = "a\nb # comment\nc"
614
+ pt = s(:block,
615
+ s(:call, nil, :a).line(1),
616
+ s(:call, nil, :b).line(2),
617
+ s(:call, nil, :c).line(3))
618
+
619
+ assert_parse rb, pt
620
+ end
621
+
622
+ def test_parse_line_block_inline_multiline_comment
623
+ rb = "a\nb # comment\n# another comment\nc"
624
+ pt = s(:block,
625
+ s(:call, nil, :a).line(1),
626
+ s(:call, nil, :b).line(2),
627
+ s(:call, nil, :c).line(4)).line(1)
628
+
629
+ assert_parse rb, pt
630
+ end
631
+
632
+ def test_parse_line_block_inline_comment_leading_newlines
633
+ rb = "\n\n\na\nb # comment\n# another comment\nc"
634
+ pt = s(:block,
635
+ s(:call, nil, :a).line(4),
636
+ s(:call, nil, :b).line(5),
637
+ s(:call, nil, :c).line(7)).line(4)
638
+
639
+ assert_parse rb, pt
640
+ end
641
+
642
+ def test_parse_line_call_no_args
643
+ rb = "f do |x, y|\n x + y\nend"
644
+
645
+ pt = s(:iter,
646
+ s(:call, nil, :f),
647
+ s(:args, :x, :y),
648
+ s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
649
+
650
+ assert_parse_line rb, pt, 1
651
+ assert_equal 1, result[1].line, "call should have line number"
652
+ assert_equal 1, result[2].line, "masgn should have line number"
653
+ assert_equal 2, result[3].line, "call should have line number"
654
+ end
655
+
656
+ def test_parse_line_call_ivar_line_break_paren
657
+ rb = "a(@b\n)"
658
+ pt = s(:call, nil, :a, s(:ivar, :@b).line(1)).line(1)
659
+
660
+ assert_parse rb, pt
661
+ end
662
+
663
+ def test_parse_line_call_ivar_arg_no_parens_line_break
664
+ rb = "a @b\n"
665
+ pt = s(:call, nil, :a, s(:ivar, :@b).line(1)).line(1)
666
+
667
+ assert_parse rb, pt
668
+ end
669
+
670
+ def test_parse_line_defn_no_parens
671
+ pt = s(:defn, :f, s(:args), s(:nil))
672
+
673
+ rb = "def f\nend"
674
+ assert_parse_line rb, pt, 1
675
+
676
+ processor.reset
677
+
678
+ rb = "def f\n\nend"
679
+ assert_parse_line rb, pt, 1
680
+ end
681
+
682
+ def test_parse_line_defn_complex
683
+ rb = "def x(y)\n p(y)\n y *= 2\n return y;\nend" # TODO: remove () & ;
684
+ pt = s(:defn, :x, s(:args, :y),
685
+ s(:call, nil, :p, s(:lvar, :y)),
686
+ s(:lasgn, :y, s(:call, s(:lvar, :y), :*, s(:lit, 2))),
687
+ s(:return, s(:lvar, :y)))
688
+
689
+ assert_parse_line rb, pt, 1
690
+
691
+ body = result
692
+ assert_equal 2, body.call.line, "call should have line number"
693
+ assert_equal 3, body.lasgn.line, "lasgn should have line number"
694
+ assert_equal 4, body.return.line, "return should have line number"
695
+ end
696
+
697
+ def test_parse_line_evstr_after_break
698
+ rb = "\"a\"\\\n\"\#{b}\""
699
+ pt = s(:dstr, "a",
700
+ s(:evstr,
701
+ s(:call, nil, :b).line(2)).line(2)).line(1)
702
+
703
+ assert_parse rb, pt
704
+ end
705
+
706
+ def test_parse_line_dstr_newline
707
+ skip "dstr line numbers are just gonna be screwed for a while..."
708
+
709
+ rb = <<-'CODE'
710
+ "a\n#{
711
+ }"
712
+ true
713
+ CODE
714
+
715
+ pt = s(:block,
716
+ s(:dstr, "a\n",
717
+ s(:evstr)).line(1),
718
+ s(:true).line(3))
719
+
720
+ assert_parse rb, pt
721
+ end
722
+
723
+ def test_parse_line_hash_lit
724
+ rb = "{\n:s1 => 1,\n}"
725
+ pt = s(:hash,
726
+ s(:lit, :s1).line(2), s(:lit, 1).line(2),
727
+ ).line(1)
728
+
729
+ assert_parse rb, pt
730
+ end
731
+
732
+ def test_parse_line_heredoc_evstr
733
+ skip "heredoc line numbers are just gonna be screwed for a while..."
734
+
735
+ rb = "<<-A\na\n\#{b}\nA"
736
+ pt = s(:dstr, "a\n",
737
+ s(:evstr,
738
+ s(:call, nil, :b).line(3)),
739
+ s(:str, "\n")).line(1)
740
+
741
+ assert_parse rb, pt
742
+ end
743
+
744
+ def test_parse_line_multiline_str
745
+ rb = "\"a\nb\"\n1"
746
+ pt = s(:block,
747
+ s(:str, "a\nb").line(1),
748
+ s(:lit, 1).line(3)).line(1)
749
+
750
+ assert_parse rb, pt
751
+ end
752
+
753
+ def test_parse_line_multiline_str_literal_n
754
+ rb = "\"a\\nb\"\n1"
755
+ pt = s(:block,
756
+ s(:str, "a\nb").line(1),
757
+ s(:lit, 1).line(2)).line(1)
758
+
759
+ assert_parse rb, pt
760
+ end
761
+
762
+ def test_parse_line_iter_call_parens
763
+ rb = "f(a) do |x, y|\n x + y\nend"
764
+
765
+ pt = s(:iter,
766
+ s(:call, nil, :f, s(:call, nil, :a)),
767
+ s(:args, :x, :y),
768
+ s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
769
+
770
+ assert_parse_line rb, pt, 1
771
+
772
+ assert_equal 1, result[1].line, "call should have line number"
773
+ assert_equal 1, result[2].line, "masgn should have line number"
774
+ assert_equal 2, result[3].line, "call should have line number"
775
+ end
776
+
777
+ def test_parse_line_iter_call_no_parens
778
+ rb = "f a do |x, y|\n x + y\nend"
779
+
780
+ pt = s(:iter,
781
+ s(:call, nil, :f, s(:call, nil, :a).line(1)).line(1),
782
+ s(:args, :x, :y).line(1),
783
+ s(:call, s(:lvar, :x).line(2), :+,
784
+ s(:lvar, :y).line(2)).line(2)).line(1)
785
+
786
+ assert_parse rb, pt
787
+ end
788
+
789
+ def test_parse_line_heredoc
790
+ rb = <<-CODE
791
+ string = <<-HEREDOC
792
+ very long string
793
+ HEREDOC
794
+ puts string
795
+ CODE
796
+
797
+ pt = s(:block,
798
+ s(:lasgn, :string,
799
+ s(:str, " very long string\n").line(1)).line(1),
800
+ s(:call, nil, :puts, s(:lvar, :string).line(4)).line(4)).line(1)
801
+
802
+ assert_parse rb, pt
803
+ end
804
+
805
+ def test_parse_line_heredoc_regexp_chars
806
+ rb = <<-CODE
807
+ string = <<-"^D"
808
+ very long string
809
+ ^D
810
+ puts string
811
+ CODE
812
+
813
+ pt = s(:block,
814
+ s(:lasgn, :string,
815
+ s(:str, " very long string\n").line(1)).line(1),
816
+ s(:call, nil, :puts, s(:lvar, :string).line(4)).line(4)).line(1)
817
+
818
+ assert_parse rb, pt
819
+ end
820
+
821
+ def test_parse_line_newlines
822
+ rb = "true\n\n"
823
+ pt = s(:true)
824
+
825
+ assert_parse_line rb, pt, 1
826
+ end
827
+
828
+ def test_parse_line_rescue
829
+ rb = "begin\n a\n rescue\n b\n rescue\n c\n end\n"
830
+ pt = s(:rescue,
831
+ s(:call, nil, :a).line(2),
832
+ s(:resbody, s(:array).line(3),
833
+ s(:call, nil, :b).line(4)).line(3),
834
+ s(:resbody, s(:array).line(5),
835
+ s(:call, nil, :c).line(6)).line(5)).line(1)
836
+
837
+ assert_parse_line rb, pt, 1
838
+ end
839
+
840
+ def test_parse_line_return
841
+ rb = <<-RUBY
842
+ def blah
843
+ if true then
844
+ return 42
845
+ end
846
+ end
847
+ RUBY
848
+
849
+ pt = s(:defn, :blah, s(:args),
850
+ s(:if, s(:true),
851
+ s(:return, s(:lit, 42)),
852
+ nil))
853
+
854
+ assert_parse_line rb, pt, 1
855
+
856
+ assert_equal 3, result.if.return.line
857
+ assert_equal 3, result.if.return.lit.line
858
+ end
859
+
860
+ def test_parse_line_str_with_newline_escape
861
+ rb = 'a("\n", true)'
862
+ pt = s(:call, nil, :a,
863
+ s(:str, "\n").line(1),
864
+ s(:true).line(1))
865
+
866
+ assert_parse rb, pt
867
+ end
868
+
869
+ def test_parse_line_trailing_newlines
870
+ rb = "a \nb"
871
+ pt = s(:block,
872
+ s(:call, nil, :a).line(1),
873
+ s(:call, nil, :b).line(2)).line(1)
874
+
875
+ assert_parse rb, pt
876
+ end
877
+
878
+ def test_bug_and
879
+ rb = "true and []"
880
+ pt = s(:and, s(:true), s(:array))
881
+
882
+ assert_parse rb, pt
883
+
884
+ rb = "true and\ntrue"
885
+ pt = s(:and, s(:true), s(:true))
886
+
887
+ assert_parse rb, pt
888
+ end
889
+
890
+ def test_bug_cond_pct
891
+ rb = "case; when %r%blahblah%; end"
892
+ pt = s(:case, nil, s(:when, s(:array, s(:lit, /blahblah/)), nil), nil)
893
+
894
+ assert_parse rb, pt
895
+ end
896
+
897
+ # according to 2.3.1 parser -- added: ON 1.8 only:
898
+ # rp.process("f { |(a,b),c| }") == rp.process("f { |((a,b),c)| }")
899
+
900
+ # ruby18 -e "p lambda { |(a,b)| }.arity" # => 2
901
+ # ruby19 -e "p lambda { |(a,b)| }.arity" # => 1
902
+ # ruby18 -e "p lambda { |(a,b),c| }.arity" # => 2
903
+ # ruby19 -e "p lambda { |(a,b),c| }.arity" # => 2
904
+ # ruby18 -e "p lambda { |((a,b),c)| }.arity" # => 2
905
+ # ruby19 -e "p lambda { |((a,b),c)| }.arity" # => 1
906
+
907
+ def test_bug_args_masgn
908
+ rb = "f { |(a, b), c| }"
909
+ pt = s(:iter,
910
+ s(:call, nil, :f),
911
+ s(:args, s(:masgn, :a, :b), :c))
912
+
913
+ assert_parse rb, pt.dup
914
+ end
915
+
916
+ def test_bug_args_masgn2
917
+ rb = "f { |((a, b), c), d| }"
918
+ pt = s(:iter,
919
+ s(:call, nil, :f),
920
+ s(:args, s(:masgn, s(:masgn, :a, :b), :c), :d))
921
+
922
+ assert_parse rb, pt
923
+ end
924
+
925
+ def ruby18
926
+ RubyParser::V18 === self.processor
927
+ end
928
+
929
+ def ruby19
930
+ RubyParser::V19 === self.processor
931
+ end
932
+
933
+ def test_bug_comma
934
+ val = if ruby18 then
935
+ s(:lit, 100)
936
+ else
937
+ s(:str, "d")
938
+ end
939
+
940
+ rb = "if test ?d, dir then end"
941
+ pt = s(:if,
942
+ s(:call, nil, :test, val, s(:call, nil, :dir)),
943
+ nil,
944
+ nil)
945
+
946
+ assert_parse rb, pt
947
+ end
948
+
949
+ def test_bug_case_when_regexp
950
+ rb = "case :x; when /x/ then end"
951
+ pt = s(:case, s(:lit, :x),
952
+ s(:when, s(:array, s(:lit, /x/)), nil),
953
+ nil)
954
+
955
+ assert_parse rb, pt
956
+ end
957
+
958
+ def test_bug_masgn_right
959
+ rb = "f { |a, (b, c)| }"
960
+ pt = s(:iter,
961
+ s(:call, nil, :f),
962
+ s(:args, :a, s(:masgn, :b, :c)))
963
+
964
+ assert_parse rb, pt
965
+ end
966
+
967
+ def test_when_splat
968
+ rb = "case a; when *b then; end"
969
+ pt = s(:case, s(:call, nil, :a),
970
+ s(:when, s(:array, s(:splat, s(:call, nil, :b))), nil),
971
+ nil)
972
+
973
+ assert_parse rb, pt
974
+ end
975
+
976
+ def test_if_symbol
977
+ rb = "if f :x; end"
978
+ pt = s(:if, s(:call, nil, :f, s(:lit, :x)), nil, nil)
979
+
980
+ assert_parse rb, pt
981
+ end
982
+
983
+
984
+ def test_bug_not_parens
985
+ rb = "not(a)"
986
+ pt = if ruby18 then
987
+ s(:not, s(:call, nil, :a))
988
+ else
989
+ s(:call, s(:call, nil, :a), :"!")
990
+ end
991
+
992
+ assert_parse rb, pt
993
+ end
994
+
995
+ def test_pipe_space
996
+ rb = "a.b do | | end"
997
+ pt = s(:iter, s(:call, s(:call, nil, :a), :b), s(:args))
998
+
999
+ assert_parse rb, pt
1000
+ end
1001
+
1002
+ def test_cond_unary_minus
1003
+ rb = "if -1; end"
1004
+ pt = s(:if, s(:lit, -1), nil, nil)
1005
+
1006
+ assert_parse rb, pt
1007
+ end
1008
+
1009
+ def test_bug_op_asgn_rescue
1010
+ skip if ruby18 || ruby19
1011
+
1012
+ rb = "a ||= b rescue nil"
1013
+ pt = s(:rescue,
1014
+ s(:op_asgn_or, s(:lvar, :a), s(:lasgn, :a, s(:call, nil, :b))),
1015
+ s(:resbody, s(:array), s(:nil)))
1016
+
1017
+ # TODO: HRM: this seems more correct IMO. Check against other versions
1018
+ pt = s(:op_asgn_or,
1019
+ s(:lvar, :a),
1020
+ s(:lasgn, :a,
1021
+ s(:rescue,
1022
+ s(:call, nil, :b),
1023
+ s(:resbody, s(:array), s(:nil)))))
1024
+
1025
+ assert_parse rb, pt
1026
+ end
1027
+
1028
+ def test_magic_encoding_comment
1029
+ rb = "# encoding: utf-8\nclass ExampleUTF8ClassNameVarietà; def self.è; così = :però; end\nend\n"
1030
+
1031
+ rb.force_encoding "ASCII-8BIT" if rb.respond_to? :force_encoding
1032
+
1033
+ # TODO: class vars
1034
+ # TODO: odd-ternary: a ?bb : c
1035
+ # TODO: globals
1036
+
1037
+ pt = s(:class, :"ExampleUTF8ClassNameVariet\303\240", nil,
1038
+ s(:defs, s(:self), :"\303\250", s(:args),
1039
+ s(:lasgn, :"cos\303\254", s(:lit, :"per\303\262"))))
1040
+
1041
+ err = RUBY_VERSION =~ /^1\.8/ ? "Skipping magic encoding comment\n" : ""
1042
+
1043
+ assert_output "", err do
1044
+ assert_parse rb, pt
1045
+ end
1046
+ end
1047
+
1048
+ def test_iter_args_1
1049
+ rb = "f { |a,b| }"
1050
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, :b))
1051
+
1052
+ assert_parse rb, pt
1053
+ end
1054
+
1055
+ def test_iter_args_3
1056
+ rb = "f { |a, (b, c), d| }"
1057
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, s(:masgn, :b, :c), :d))
1058
+
1059
+ assert_parse rb, pt
1060
+ end
1061
+
1062
+ def test_str_heredoc_interp
1063
+ rb = "<<\"\"\n\#{x}\nblah2\n\n"
1064
+ pt = s(:dstr, "", s(:evstr, s(:call, nil, :x)), s(:str, "\nblah2\n"))
1065
+
1066
+ assert_parse rb, pt
1067
+ end
1068
+
1069
+ def test_i_fucking_hate_line_numbers
1070
+ rb = <<-END.gsub(/^ {6}/, '')
1071
+ if true
1072
+ p 1
1073
+ a.b 2
1074
+ c.d 3, 4
1075
+ e.f 5
1076
+ g.h 6, 7
1077
+ p(1)
1078
+ a.b(2)
1079
+ c.d(3, 4)
1080
+ e.f(5)
1081
+ g.h(6, 7)
1082
+ end
1083
+ END
1084
+
1085
+ pt = s(:if, s(:true).line(1),
1086
+ s(:block,
1087
+ s(:call, nil, :p, s(:lit, 1).line(2)).line(2),
1088
+ s(:call, s(:call, nil, :a).line(3), :b,
1089
+ s(:lit, 2).line(3)).line(3),
1090
+ s(:call, s(:call, nil, :c).line(4), :d,
1091
+ s(:lit, 3).line(4), s(:lit, 4).line(4)).line(4),
1092
+ s(:call, s(:call, nil, :e).line(5), :f,
1093
+ s(:lit, 5).line(5)).line(5),
1094
+ s(:call, s(:call, nil, :g).line(6), :h,
1095
+ s(:lit, 6).line(6), s(:lit, 7).line(6)).line(6),
1096
+ s(:call, nil, :p, s(:lit, 1).line(7)).line(7),
1097
+ s(:call, s(:call, nil, :a).line(8), :b,
1098
+ s(:lit, 2).line(8)).line(8),
1099
+ s(:call, s(:call, nil, :c).line(9), :d,
1100
+ s(:lit, 3).line(9), s(:lit, 4).line(9)).line(9),
1101
+ s(:call, s(:call, nil, :e).line(10), :f,
1102
+ s(:lit, 5).line(10)).line(10),
1103
+ s(:call, s(:call, nil, :g).line(11), :h,
1104
+ s(:lit, 6).line(11), s(:lit, 7).line(11)).line(11)).line(2),
1105
+ nil).line(1)
1106
+
1107
+ assert_parse rb, pt
1108
+ end
1109
+
1110
+ def test_i_fucking_hate_line_numbers2
1111
+ rb = <<-EOM.gsub(/^ {6}/, '')
1112
+ if true then
1113
+ p('a')
1114
+ b = 1
1115
+ p b
1116
+ c =1
1117
+ end
1118
+ a
1119
+ EOM
1120
+
1121
+ pt = s(:block,
1122
+ s(:if, s(:true).line(1),
1123
+ s(:block,
1124
+ s(:call, nil, :p, s(:str, "a").line(2)).line(2),
1125
+ s(:lasgn, :b, s(:lit, 1).line(3)).line(3),
1126
+ s(:call, nil, :p, s(:lvar, :b).line(4)).line(4),
1127
+ s(:lasgn, :c, s(:lit, 1).line(5)).line(5)).line(2),
1128
+ nil).line(1),
1129
+ s(:call, nil, :a).line(7)).line(1)
1130
+
1131
+ assert_parse rb, pt
1132
+ end
1133
+
1134
+ def test_parse_comments
1135
+ p = RubyParser.new
1136
+ sexp = p.parse <<-CODE
1137
+ # class comment
1138
+ class Inline
1139
+ def show
1140
+ # woot
1141
+ end
1142
+
1143
+ # Returns a list of things
1144
+ def list
1145
+ # woot
1146
+ end
1147
+ end
1148
+ CODE
1149
+
1150
+ assert_equal "# class comment\n", sexp.comments
1151
+ act = sexp.find_nodes(:defn).map(&:comments)
1152
+ exp = ["", "# Returns a list of things\n"]
1153
+
1154
+ assert_equal exp, act
1155
+ assert_equal [], processor.comments
1156
+ assert_equal "", processor.lexer.comments
1157
+ end
1158
+
1159
+ def test_call_pipe
1160
+ rb = "1 | 2"
1161
+ pt = s(:call, s(:lit, 1), :|, s(:lit, 2))
1162
+
1163
+ assert_parse rb, pt
1164
+ end
1165
+
1166
+ def test_lasgn_command
1167
+ rb = "a = b.c 1"
1168
+ pt = s(:lasgn, :a, s(:call, s(:call, nil, :b), :c, s(:lit, 1)))
1169
+
1170
+ assert_parse rb, pt
1171
+ end
1172
+
1173
+ def test_call_args_command
1174
+ rb = "a.b c.d 1"
1175
+ pt = s(:call, s(:call, nil, :a), :b,
1176
+ s(:call, s(:call, nil, :c), :d,
1177
+ s(:lit, 1)))
1178
+
1179
+ assert_parse rb, pt
1180
+ end
1181
+
1182
+ def test_defined_eh_parens
1183
+ rb = "defined?(42)"
1184
+ pt = s(:defined, s(:lit, 42))
1185
+
1186
+ assert_parse rb, pt
1187
+ end
1188
+
1189
+ def test_if_elsif
1190
+ rb = "if 1; elsif 2; end"
1191
+ pt = s(:if, s(:lit, 1), nil, s(:if, s(:lit, 2), nil, nil))
1192
+
1193
+ assert_parse rb, pt
1194
+ end
1195
+
1196
+ def test_call_gt
1197
+ rb = "1 > 2"
1198
+ pt = s(:call, s(:lit, 1), :>, s(:lit, 2))
1199
+
1200
+ assert_parse rb, pt
1201
+ end
1202
+
1203
+ def test_call_lt
1204
+ rb = "1 < 2"
1205
+ pt = s(:call, s(:lit, 1), :<, s(:lit, 2))
1206
+
1207
+ assert_parse rb, pt
1208
+ end
1209
+
1210
+ def test_call_lte
1211
+ rb = "1 <= 2"
1212
+ pt = s(:call, s(:lit, 1), :<=, s(:lit, 2))
1213
+
1214
+ assert_parse rb, pt
1215
+ end
1216
+
1217
+ def test_call_spaceship
1218
+ rb = "1 <=> 2"
1219
+ pt = s(:call, s(:lit, 1), :<=>, s(:lit, 2))
1220
+
1221
+ assert_parse rb, pt
1222
+ end
1223
+
1224
+ def test_call_and
1225
+ rb = "1 & 2"
1226
+ pt = s(:call, s(:lit, 1), :&, s(:lit, 2))
1227
+
1228
+ assert_parse rb, pt
1229
+ end
1230
+
1231
+ def test_call_star2
1232
+ rb = "1 ** 2"
1233
+ pt = s(:call, s(:lit, 1), :"**", s(:lit, 2))
1234
+
1235
+ assert_parse rb, pt
1236
+ end
1237
+
1238
+ def test_call_colon2
1239
+ rb = "A::b"
1240
+ pt = s(:call, s(:const, :A), :b)
1241
+
1242
+ assert_parse rb, pt
1243
+ end
1244
+
1245
+ def test_call_star
1246
+ rb = "1 * 2"
1247
+ pt = s(:call, s(:lit, 1), :"*", s(:lit, 2))
1248
+
1249
+ assert_parse rb, pt
1250
+ end
1251
+
1252
+ def test_yield_arg
1253
+ rb = "yield 42"
1254
+ pt = s(:yield, s(:lit, 42))
1255
+
1256
+ assert_parse rb, pt
1257
+ end
1258
+
1259
+ def test_call_div
1260
+ rb = "1 / 2"
1261
+ pt = s(:call, s(:lit, 1), :/, s(:lit, 2))
1262
+
1263
+ assert_parse rb, pt
1264
+ end
1265
+
1266
+ def test_call_eq3
1267
+ rb = "1 === 2"
1268
+ pt = s(:call, s(:lit, 1), :===, s(:lit, 2))
1269
+
1270
+ assert_parse rb, pt
1271
+ end
1272
+
1273
+ def test_call_carat
1274
+ rb = "1 ^ 2"
1275
+ pt = s(:call, s(:lit, 1), :^, s(:lit, 2))
1276
+
1277
+ assert_parse rb, pt
1278
+ end
1279
+
1280
+ def test_call_rshift
1281
+ rb = "1 >> 2"
1282
+ pt = s(:call, s(:lit, 1), :>>, s(:lit, 2))
1283
+
1284
+ assert_parse rb, pt
1285
+ end
1286
+
1287
+ def test_lasgn_arg_rescue_arg
1288
+ rb = "a = 1 rescue 2"
1289
+ pt = s(:lasgn, :a, s(:rescue, s(:lit, 1), s(:resbody, s(:array), s(:lit, 2))))
1290
+
1291
+ assert_parse rb, pt
1292
+ end
1293
+
1294
+ def test_call_bang_squiggle
1295
+ rb = "1 !~ 2"
1296
+ pt = s(:not, s(:call, s(:lit, 1), :=~, s(:lit, 2))) # TODO: check for 1.9+
1297
+
1298
+ assert_parse rb, pt
1299
+ end
1300
+
1301
+ def test_super_arg
1302
+ rb = "super 42"
1303
+ pt = s(:super, s(:lit, 42))
1304
+
1305
+ assert_parse rb, pt
1306
+ end
1307
+
1308
+ def test_defns_reserved
1309
+ rb = "def self.return; end"
1310
+ pt = s(:defs, s(:self), :return, s(:args), s(:nil))
1311
+
1312
+ assert_parse rb, pt
1313
+ end
1314
+
1315
+ def test_unary_minus
1316
+ rb = "-a"
1317
+ pt = s(:call, s(:call, nil, :a), :"-@")
1318
+
1319
+ assert_parse rb, pt
1320
+ end
1321
+
1322
+ def test_masgn_command_call
1323
+ rb = "a, = b.c 1"
1324
+ pt = s(:masgn,
1325
+ s(:array, s(:lasgn, :a)),
1326
+ s(:to_ary, s(:call, s(:call, nil, :b), :c, s(:lit, 1))))
1327
+
1328
+ assert_parse rb, pt
1329
+ end
1330
+
1331
+ def test_uminus_float
1332
+ rb = "-0.0"
1333
+ pt = s(:lit, -0.0)
1334
+
1335
+ assert_parse rb, pt
1336
+ end
1337
+
1338
+ def test_op_asgn_command_call
1339
+ rb = "a ||= b.c 2"
1340
+ pt = s(:op_asgn_or,
1341
+ s(:lvar, :a),
1342
+ s(:lasgn, :a, s(:call, s(:call, nil, :b), :c, s(:lit, 2))))
1343
+
1344
+ assert_parse rb, pt
1345
+ end
1346
+
1347
+ def test_masgn_paren
1348
+ rb = "(a, b) = c.d"
1349
+ pt = s(:masgn,
1350
+ s(:array, s(:lasgn, :a), s(:lasgn, :b)),
1351
+ s(:to_ary, s(:call, s(:call, nil, :c), :d)))
1352
+
1353
+ assert_parse rb, pt
1354
+ end
1355
+
1356
+ def test_unary_tilde
1357
+ rb = "~a"
1358
+ pt = s(:call, s(:call, nil, :a), :~)
1359
+
1360
+ assert_parse rb, pt
1361
+ end
1362
+
1363
+ def test_unary_plus
1364
+ rb = "+a"
1365
+ pt = s(:call, s(:call, nil, :a), :+@)
1366
+
1367
+ assert_parse rb, pt
1368
+ end
1369
+
1370
+ def test_qwords_empty
1371
+ rb = "%w()"
1372
+ pt = s(:array)
1373
+
1374
+ assert_parse rb, pt
1375
+ end
1376
+
1377
+ def test_array_line_breaks
1378
+ # It seems like arrays are roughly created when a certain element is created
1379
+ # In ruby > 1.9 it seems like that is after the last element, so the array
1380
+ # itself is assigned line 3 (since the last element is on line 3) and for
1381
+ # ruby <= 1.9 it seems to get created after the first element, so the array
1382
+ # itself is assigned line 2 (since the first element is on line 2).
1383
+ # This seems to happen since arrays like this are created with a line in
1384
+ # ruby_parser.yy like `result = s(:array, val[0])`. So, the array is not
1385
+ # created by itself. The creation of the array itself is deferred until there
1386
+ # is an element to create it with. That seems to mess up line numbers
1387
+ # for the array. Luckily, the arary elements all seemt to get the correct
1388
+ # line number.
1389
+ start_line = self.class.to_s =~ /1[89]/ ? 2 : 3
1390
+ rb = "[\n'a',\n'b']\n1"
1391
+ pt = s(:block,
1392
+ s(:array,
1393
+ s(:str, "a").line(2),
1394
+ s(:str, "b").line(3)).line(start_line),
1395
+ s(:lit, 1).line(4))
1396
+ assert_parse rb, pt
1397
+ end
1398
+
1399
+ def test_non_interpolated_word_array_line_breaks
1400
+
1401
+ rb = "%w(\na\nb\n)\n1"
1402
+ pt = s(:block,
1403
+ s(:array,
1404
+ s(:str, "a").line(2),
1405
+ s(:str, "b").line(3)).line(1),
1406
+ s(:lit, 1).line(5))
1407
+ assert_parse rb, pt
1408
+ end
1409
+
1410
+ def test_interpolated_word_array_line_breaks
1411
+
1412
+ rb = "%W(\na\nb\n)\n1"
1413
+ pt = s(:block,
1414
+ s(:array,
1415
+ s(:str, "a").line(2),
1416
+ s(:str, "b").line(3)).line(1),
1417
+ s(:lit, 1).line(5))
1418
+ assert_parse rb, pt
1419
+ end
1420
+
1421
+ def test_qWords_space
1422
+ rb = "%W( )"
1423
+ pt = s(:array)
1424
+
1425
+ assert_parse rb, pt
1426
+ end
1427
+
1428
+ def test_attr_asgn_colon_id
1429
+ rb = "A::b = 1"
1430
+ pt = s(:attrasgn, s(:const, :A), :b=, s(:lit, 1))
1431
+
1432
+ assert_parse rb, pt
1433
+ end
1434
+
1435
+ def test_aref_args_assocs
1436
+ rb = "[1 => 2]"
1437
+ pt = s(:array, s(:hash, s(:lit, 1), s(:lit, 2)))
1438
+
1439
+ assert_parse rb, pt
1440
+ end
1441
+
1442
+ def test_BEGIN
1443
+ rb = "BEGIN { 42 }"
1444
+ pt = s(:iter, s(:preexe), 0, s(:lit, 42))
1445
+
1446
+ assert_parse rb, pt
1447
+ end
1448
+
1449
+ def test_attrasgn_primary_dot_constant
1450
+ rb = "a.B = 1"
1451
+ pt = s(:attrasgn, s(:call, nil, :a), :"B=", s(:lit, 1))
1452
+
1453
+ assert_parse rb, pt
1454
+ end
1455
+
1456
+ def test_op_asgn_primary_colon_identifier
1457
+ rb = "A::b += 1"
1458
+ pt = s(:op_asgn, s(:const, :A), s(:lit, 1), :b, :+) # TODO: check? looks wack
1459
+
1460
+ assert_parse rb, pt
1461
+ end
1462
+
1463
+ def test_words_interp
1464
+ rb = '%W(#{1}b)'
1465
+ pt = s(:array, s(:dstr, "", s(:evstr, s(:lit, 1)), s(:str, "b")))
1466
+
1467
+ assert_parse rb, pt
1468
+ end
1469
+
1470
+ def test_op_asgn_index_command_call
1471
+ rb = "a[:b] ||= c 1, 2"
1472
+ pt = s(:op_asgn1, s(:call, nil, :a), s(:array, s(:lit, :b)),
1473
+ :"||",
1474
+ s(:call, nil, :c, s(:lit, 1), s(:lit, 2)))
1475
+
1476
+ assert_parse rb, pt
1477
+ end
1478
+
1479
+ def test_op_asgn_val_dot_ident_command_call
1480
+ rb = "a.b ||= c 1"
1481
+ pt = s(:op_asgn, s(:call, nil, :a), s(:call, nil, :c, s(:lit, 1)), :b, :"||")
1482
+
1483
+ assert_parse rb, pt
1484
+ end
1485
+
1486
+ def test_yield_empty_parens
1487
+ rb = "yield()"
1488
+ pt = s(:yield)
1489
+
1490
+ assert_parse rb, pt
1491
+ end
1492
+
1493
+ def test_masgn_lhs_splat
1494
+ rb = "*a = 1, 2, 3"
1495
+ pt = s(:masgn,
1496
+ s(:array, s(:splat, s(:lasgn, :a))),
1497
+ s(:array, s(:lit, 1), s(:lit, 2), s(:lit, 3)))
1498
+
1499
+ assert_parse rb, pt
1500
+ end
1501
+
1502
+ def test_masgn_arg_ident
1503
+ rb = "a, b.C = d"
1504
+ pt = s(:masgn,
1505
+ s(:array, s(:lasgn, :a), s(:attrasgn, s(:call, nil, :b), :"C=")),
1506
+ s(:to_ary, s(:call, nil, :d)))
1507
+
1508
+ assert_parse rb, pt
1509
+ end
1510
+
1511
+ def test_masgn_arg_colon_arg
1512
+ rb = "a, b::c = d"
1513
+ pt = s(:masgn,
1514
+ s(:array, s(:lasgn, :a), s(:attrasgn, s(:call, nil, :b), :c=)),
1515
+ s(:to_ary, s(:call, nil, :d)))
1516
+
1517
+ assert_parse rb, pt
1518
+ end
1519
+
1520
+ def test_masgn_star
1521
+ rb = "* = 1"
1522
+ pt = s(:masgn,
1523
+ s(:array, s(:splat)),
1524
+ s(:to_ary, s(:lit, 1)))
1525
+
1526
+ assert_parse rb, pt
1527
+ end
1528
+
1529
+ def test_op_asgn_dot_ident_command_call
1530
+ rb = "A.B ||= c 1"
1531
+ pt = s(:op_asgn, s(:const, :A), s(:call, nil, :c, s(:lit, 1)), :B, :"||")
1532
+
1533
+ assert_parse rb, pt
1534
+ end
1535
+
1536
+ def test_block_decomp_splat
1537
+ skip "not that smart yet" if ruby18 # HACK
1538
+
1539
+ rb = "f { |(*a)| }"
1540
+ pt = s(:iter, s(:call, nil, :f), s(:args, s(:masgn, :"*a")))
1541
+
1542
+ assert_parse rb, pt
1543
+ end
1544
+
1545
+ def test_masgn_colon3
1546
+ rb = "::A, ::B = 1, 2"
1547
+ pt = s(:masgn,
1548
+ s(:array, s(:const, nil, s(:colon3, :A)), s(:const, s(:colon3, :B))),
1549
+ s(:array, s(:lit, 1), s(:lit, 2)))
1550
+
1551
+ assert_parse rb, pt
1552
+ end
1553
+
1554
+ def test_masgn_colon2
1555
+ rb = "a, b::C = 1, 2"
1556
+ pt = s(:masgn,
1557
+ s(:array, s(:lasgn, :a), s(:const, s(:colon2, s(:call, nil, :b), :C))),
1558
+ s(:array, s(:lit, 1), s(:lit, 2)))
1559
+
1560
+ assert_parse rb, pt
1561
+ end
1562
+
1563
+ def test_alias_resword
1564
+ rb = "alias in out"
1565
+ pt = s(:alias, s(:lit, :in), s(:lit, :out))
1566
+
1567
+ assert_parse rb, pt
1568
+ end
1569
+
1570
+ def test_alias_gvar_backref
1571
+ rb = "alias $MATCH $&"
1572
+ pt = s(:valias, :$MATCH, :$&)
1573
+
1574
+ assert_parse rb, pt
1575
+ end
1576
+
1577
+ def test_heredoc_broken_windows_theory_applies_to_microsoft_more_than_anything
1578
+ rb = "<<EOS\r\r\nEOS\r\r\n"
1579
+ pt = s(:str, "")
1580
+
1581
+ assert_parse rb, pt
1582
+ end
1583
+
1584
+ def test_heredoc_unicode
1585
+ rb = "<<OOTPÜT\n.\nOOTPÜT\n"
1586
+ pt = s(:str, ".\n")
1587
+
1588
+ assert_parse rb, pt
1589
+ end
1590
+
1591
+ def test_masgn_double_paren
1592
+ rb = "((a,b))=c" # TODO: blog
1593
+ pt = s(:masgn,
1594
+ s(:array, s(:masgn, s(:array, s(:lasgn, :a), s(:lasgn, :b)))),
1595
+ s(:to_ary, s(:call, nil, :c)))
1596
+
1597
+ assert_parse rb, pt
1598
+ end
1599
+
1600
+ def test_index_0_opasgn
1601
+ rb = "a[] += b"
1602
+ pt = s(:op_asgn1, s(:call, nil, :a), nil, :+, s(:call, nil, :b))
1603
+
1604
+ assert_parse rb, pt
1605
+ end
1606
+
1607
+ def test___ENCODING__
1608
+ rb = "__ENCODING__"
1609
+ pt = if RubyParser::V18 === processor then
1610
+ s(:call, nil, :__ENCODING__)
1611
+ else
1612
+ if defined? Encoding then
1613
+ if RubyParser::V18 === processor then
1614
+ s(:call, nil, :__ENCODING__)
1615
+ else
1616
+ s(:colon2, s(:const, :Encoding), :UTF_8)
1617
+ end
1618
+ else
1619
+ s(:str, "Unsupported!")
1620
+ end
1621
+ end
1622
+
1623
+ assert_parse rb, pt
1624
+ end
1625
+
1626
+ def test_dstr_evstr_empty_end
1627
+ rb = ':"#{field}"'
1628
+ pt = s(:dsym, "", s(:evstr, s(:call, nil, :field)))
1629
+
1630
+ assert_parse rb, pt
1631
+ end
1632
+
1633
+ def test_fubar_nesting
1634
+ err = "class definition in method body"
1635
+
1636
+ assert_syntax_error "def a; class B; end; end", err
1637
+ assert_syntax_error "def a; def b; end; class B; end; end", err
1638
+ end
1639
+
1640
+ def test_call_not
1641
+ rb = "not 42"
1642
+ pt = s(:not, s(:lit, 42))
1643
+
1644
+ assert_parse rb, pt
1645
+ end
1646
+
1647
+ def test_call_bang_command_call
1648
+ rb = "! a.b 1"
1649
+ pt = s(:not, s(:call, s(:call, nil, :a), :b, s(:lit, 1)))
1650
+
1651
+ assert_parse rb, pt
1652
+ end
1653
+
1654
+ def test_call_unary_bang
1655
+ rb = "!1"
1656
+ pt = s(:not, s(:lit, 1))
1657
+
1658
+ assert_parse rb, pt
1659
+ end
1660
+
1661
+ def test_bang_eq
1662
+ rb = "1 != 2"
1663
+ pt = s(:not, s(:call, s(:lit, 1), :"==", s(:lit, 2)))
1664
+
1665
+ assert_parse rb, pt
1666
+ end
1667
+
1668
+ def test_flip2_env_lvar
1669
+ rb = "if a..b then end"
1670
+ pt = s(:if, s(:flip2, s(:call, nil, :a), s(:call, nil, :b)), nil, nil)
1671
+
1672
+ assert_parse rb, pt
1673
+
1674
+ top_env = processor.env.env.first
1675
+
1676
+ assert_kind_of Hash, top_env
1677
+
1678
+ flip = top_env.find { |k,v| k =~ /^flip/ }
1679
+
1680
+ assert flip
1681
+ assert_equal :lvar, flip.last
1682
+ end
1683
+
1684
+ def test_parse_until_not_canonical
1685
+ rb = "until not var.nil?\n 'foo'\nend"
1686
+
1687
+ pt = s(:while,
1688
+ s(:call, s(:call, nil, :var), :nil?),
1689
+ s(:str, "foo"), true)
1690
+
1691
+ assert_parse rb, pt
1692
+ end
1693
+
1694
+ def test_parse_until_not_noncanonical
1695
+ rb = "until not var.nil?\n 'foo'\nend"
1696
+ pt = s(:until,
1697
+ s(:not, s(:call, s(:call, nil, :var), :nil?)),
1698
+ s(:str, "foo"), true)
1699
+
1700
+ processor.canonicalize_conditions = false
1701
+
1702
+ assert_parse rb, pt
1703
+ end
1704
+
1705
+ def test_parse_if_not_canonical
1706
+ rb = "if not var.nil? then 'foo' else 'bar'\nend"
1707
+ pt = s(:if,
1708
+ s(:call, s(:call, nil, :var), :nil?),
1709
+ s(:str, "bar"),
1710
+ s(:str, "foo"))
1711
+
1712
+ assert_parse rb, pt
1713
+ end
1714
+
1715
+ def test_parse_if_not_noncanonical
1716
+ rb = "if not var.nil? then 'foo' else 'bar'\nend"
1717
+ pt = s(:if,
1718
+ s(:not, s(:call, s(:call, nil, :var), :nil?)),
1719
+ s(:str, "foo"),
1720
+ s(:str, "bar"))
1721
+
1722
+ processor.canonicalize_conditions = false
1723
+
1724
+ assert_parse rb, pt
1725
+ end
1726
+
1727
+ def test_parse_while_not_canonical
1728
+ rb = "while not var.nil?\n 'foo'\nend"
1729
+ pt = s(:until,
1730
+ s(:call, s(:call, nil, :var), :nil?),
1731
+ s(:str, "foo"), true)
1732
+
1733
+ assert_parse rb, pt
1734
+ end
1735
+
1736
+ def test_parse_while_not_noncanonical
1737
+ rb = "while not var.nil?\n 'foo'\nend"
1738
+ pt = s(:while,
1739
+ s(:not, s(:call, s(:call, nil, :var), :nil?)),
1740
+ s(:str, "foo"), true)
1741
+
1742
+ processor.canonicalize_conditions = false
1743
+
1744
+ assert_parse rb, pt
1745
+ end
1746
+
1747
+ def test_defs_as_arg_with_do_block_inside
1748
+ rb = "p def self.b; x.y do; end; end"
1749
+ pt = s(:call,
1750
+ nil,
1751
+ :p,
1752
+ s(:defs, s(:self), :b, s(:args),
1753
+ s(:iter, s(:call, s(:call, nil, :x), :y), 0)))
1754
+
1755
+ assert_parse rb, pt
1756
+ end
1757
+ end
1758
+
1759
+ module TestRubyParserShared19Plus
1760
+ include TestRubyParserShared
1761
+
1762
+ def test_aref_args_lit_assocs
1763
+ rb = "[1, 2 => 3]"
1764
+ pt = s(:array, s(:lit, 1), s(:hash, s(:lit, 2), s(:lit, 3)))
1765
+
1766
+ assert_parse rb, pt
1767
+ end
1768
+
1769
+ def test_block_decomp_arg_splat
1770
+ rb = "a { |(b, *)| }"
1771
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:masgn, :b, :*)))
1772
+
1773
+ assert_parse rb, pt
1774
+ end
1775
+
1776
+ def test_block_call_operation_dot
1777
+ rb = "a.b c do end.d"
1778
+ pt = s(:call,
1779
+ s(:iter,
1780
+ s(:call, s(:call, nil, :a), :b, s(:call, nil, :c)), 0),
1781
+ :d)
1782
+
1783
+ assert_parse rb, pt
1784
+ end
1785
+
1786
+ def test_block_call_operation_colon
1787
+ rb = "a.b c do end::d"
1788
+ pt = s(:call,
1789
+ s(:iter,
1790
+ s(:call, s(:call, nil, :a), :b, s(:call, nil, :c)), 0),
1791
+ :d)
1792
+
1793
+ assert_parse rb, pt
1794
+ end
1795
+
1796
+ def test_block_command_operation_dot
1797
+ rb = "a :b do end.c :d"
1798
+ pt = s(:call,
1799
+ s(:iter, s(:call, nil, :a, s(:lit, :b)), 0),
1800
+ :c,
1801
+ s(:lit, :d))
1802
+
1803
+ assert_parse rb, pt
1804
+ end
1805
+
1806
+ def test_block_command_operation_colon
1807
+ rb = "a :b do end::c :d"
1808
+ pt = s(:call,
1809
+ s(:iter, s(:call, nil, :a, s(:lit, :b)), 0),
1810
+ :c,
1811
+ s(:lit, :d))
1812
+
1813
+ assert_parse rb, pt
1814
+ end
1815
+
1816
+ def test_block_optarg
1817
+ rb = "a { |b = :c| }"
1818
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:lasgn, :b, s(:lit, :c))))
1819
+
1820
+ assert_parse rb, pt
1821
+ end
1822
+
1823
+ def test_block_reg_optarg
1824
+ rb = "a { |b, c = :d| }"
1825
+ pt = s(:iter, s(:call, nil, :a), s(:args, :b, s(:lasgn, :c, s(:lit, :d))))
1826
+
1827
+ assert_parse rb, pt
1828
+ end
1829
+
1830
+ def test_block_return
1831
+ rb = "return foo arg do |bar| end"
1832
+ pt = s(:return,
1833
+ s(:iter,
1834
+ s(:call, nil, :foo, s(:call, nil, :arg)),
1835
+ s(:args, :bar)))
1836
+
1837
+ assert_parse rb, pt
1838
+ end
1839
+
1840
+ def test_block_next
1841
+ rb = "next foo arg do |bar| end"
1842
+ pt = s(:next,
1843
+ s(:iter,
1844
+ s(:call, nil, :foo, s(:call, nil, :arg)),
1845
+ s(:args, :bar)))
1846
+
1847
+ assert_parse rb, pt
1848
+ end
1849
+
1850
+ def test_block_yield
1851
+ rb = "yield foo arg do |bar| end"
1852
+ pt = s(:yield,
1853
+ s(:iter,
1854
+ s(:call, nil, :foo, s(:call, nil, :arg)),
1855
+ s(:args, :bar)))
1856
+
1857
+ assert_parse rb, pt
1858
+ end
1859
+
1860
+ def test_block_break
1861
+ rb = "break foo arg do |bar| end"
1862
+ pt = s(:break,
1863
+ s(:iter,
1864
+ s(:call, nil, :foo, s(:call, nil, :arg)),
1865
+ s(:args, :bar)))
1866
+
1867
+ assert_parse rb, pt
1868
+ end
1869
+
1870
+ def test_block_splat_reg
1871
+ rb = "a { |*b, c| }"
1872
+ pt = s(:iter, s(:call, nil, :a), s(:args, :"*b", :c))
1873
+
1874
+ assert_parse rb, pt
1875
+ end
1876
+
1877
+ def test_bug_187
1878
+ rb = "private def f\na.b do end\nend"
1879
+ pt = s(:call,
1880
+ nil,
1881
+ :private,
1882
+ s(:defn, :f, s(:args),
1883
+ s(:iter, s(:call, s(:call, nil, :a), :b), 0)))
1884
+
1885
+ assert_parse rb, pt
1886
+ end
1887
+
1888
+ def test_defn_opt_reg
1889
+ rb = "def f(a=nil, b) end"
1890
+ pt = s(:defn, :f, s(:args, s(:lasgn, :a, s(:nil)), :b), s(:nil))
1891
+
1892
+ assert_parse rb, pt
1893
+ end
1894
+
1895
+ def test_defn_reg_opt_reg
1896
+ rb = "def f(a, b = :c, d) end"
1897
+ pt = s(:defn, :f, s(:args, :a, s(:lasgn, :b, s(:lit, :c)), :d), s(:nil))
1898
+
1899
+ assert_parse rb, pt
1900
+ end
1901
+
1902
+ def test_defn_splat_arg
1903
+ rb = "def f(*, a) end"
1904
+ pt = s(:defn, :f, s(:args, :*, :a), s(:nil))
1905
+
1906
+ assert_parse rb, pt
1907
+ end
1908
+
1909
+ def test_defn_arg_asplat_arg
1910
+ rb = "def call(interp, *, args) end"
1911
+ pt = s(:defn, :call, s(:args, :interp, :*, :args), s(:nil))
1912
+
1913
+ assert_parse rb, pt
1914
+ end
1915
+
1916
+ def test_block_arg_scope
1917
+ rb = "a { |b; c| }"
1918
+ pt = s(:iter, s(:call, nil, :a), s(:args, :b, s(:shadow, :c)))
1919
+
1920
+ assert_parse rb, pt
1921
+ end
1922
+
1923
+ def test_block_arg_scope2
1924
+ rb = "a {|b; c, d| }"
1925
+ pt = s(:iter, s(:call, nil, :a), s(:args, :b, s(:shadow, :c, :d)))
1926
+
1927
+ assert_parse rb, pt
1928
+ end
1929
+
1930
+ def test_block_arg_splat_arg
1931
+ rb = "a { |b, *c, d| }"
1932
+ pt = s(:iter, s(:call, nil, :a), s(:args, :b, :"*c", :d))
1933
+
1934
+ assert_parse rb, pt
1935
+ end
1936
+
1937
+ def test_stabby_proc_scope
1938
+ rb = "->(a; b) {}"
1939
+ pt = s(:iter, s(:call, nil, :lambda), s(:args, :a, s(:shadow, :b)))
1940
+
1941
+ assert_parse rb, pt
1942
+ end
1943
+
1944
+ def test_stabby_arg_opt_splat_arg_block_omfg
1945
+ rb = "->(b, c=1, *d, e, &f){}"
1946
+ pt = s(:iter,
1947
+ s(:call, nil, :lambda),
1948
+ s(:args, :b, s(:lasgn, :c, s(:lit, 1)), :"*d", :e, :"&f"))
1949
+
1950
+ assert_parse rb, pt
1951
+ end
1952
+
1953
+ def test_block_arg_opt_splat_arg_block_omfg
1954
+ rb = "a { |b, c=1, *d, e, &f| }"
1955
+ pt = s(:iter,
1956
+ s(:call, nil, :a),
1957
+ s(:args, :b, s(:lasgn, :c, s(:lit, 1)), :"*d", :e, :"&f"))
1958
+
1959
+ assert_parse rb, pt
1960
+ end
1961
+
1962
+ def test_block_arg_opt_splat
1963
+ rb = "a { |b, c = 1, *d| }"
1964
+ pt = s(:iter, s(:call, nil, :a), s(:args, :b, s(:lasgn, :c, s(:lit, 1)), :"*d"))
1965
+
1966
+ assert_parse rb, pt
1967
+ end
1968
+
1969
+ def test_block_opt_splat
1970
+ rb = "a { |b = 1, *c| }"
1971
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:lasgn, :b, s(:lit, 1)), :"*c"))
1972
+
1973
+ assert_parse rb, pt
1974
+ end
1975
+
1976
+ def test_block_arg_opt_arg_block
1977
+ rb = "a { |b, c=1, d, &e| }"
1978
+ pt = s(:iter, s(:call, nil, :a), s(:args, :b, s(:lasgn, :c, s(:lit, 1)), :d, :"&e"))
1979
+
1980
+ assert_parse rb, pt
1981
+ end
1982
+
1983
+ def test_block_opt_arg
1984
+ rb = "a { |b=1, c| }"
1985
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:lasgn, :b, s(:lit, 1)), :c))
1986
+
1987
+ assert_parse rb, pt
1988
+ end
1989
+
1990
+ def test_defn_opt_splat_arg
1991
+ rb = "def f (a = 1, *b, c) end"
1992
+ pt = s(:defn, :f, s(:args, s(:lasgn, :a, s(:lit, 1)), :"*b", :c), s(:nil))
1993
+
1994
+ assert_parse rb, pt
1995
+ end
1996
+
1997
+ def test_block_opt_splat_arg_block_omfg
1998
+ rb = "a { |b=1, *c, d, &e| }"
1999
+ pt = s(:iter,
2000
+ s(:call, nil, :a),
2001
+ s(:args, s(:lasgn, :b, s(:lit, 1)), :"*c", :d, :"&e"))
2002
+
2003
+ assert_parse rb, pt
2004
+ end
2005
+
2006
+ def test_block_scope
2007
+ rb = "a { |;b| }"
2008
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:shadow, :b)))
2009
+
2010
+ assert_parse rb, pt
2011
+ end
2012
+
2013
+ def test_call_unary_bang
2014
+ rb = "!1"
2015
+ pt = s(:call, s(:lit, 1), :"!")
2016
+
2017
+ assert_parse rb, pt
2018
+ end
2019
+
2020
+ def test_assoc_label
2021
+ rb = "a(b:1)"
2022
+ pt = s(:call, nil, :a, s(:hash, s(:lit, :b), s(:lit, 1)))
2023
+
2024
+ assert_parse rb, pt
2025
+ end
2026
+
2027
+ def test_bang_eq
2028
+ rb = "1 != 2"
2029
+ pt = s(:call, s(:lit, 1), :"!=", s(:lit, 2))
2030
+
2031
+ assert_parse rb, pt
2032
+ end
2033
+
2034
+ def test_call_not
2035
+ rb = "not 42"
2036
+ pt = s(:call, s(:lit, 42), :"!")
2037
+
2038
+ assert_parse rb, pt
2039
+ end
2040
+
2041
+ def test_call_bang_command_call
2042
+ rb = "! a.b 1"
2043
+ pt = s(:call, s(:call, s(:call, nil, :a), :b, s(:lit, 1)), :"!")
2044
+
2045
+ assert_parse rb, pt
2046
+ end
2047
+
2048
+ def test_stabby_arg_no_paren
2049
+ rb = "->a{}"
2050
+ pt = s(:iter, s(:call, nil, :lambda), s(:args, :a))
2051
+
2052
+ assert_parse rb, pt
2053
+ end
2054
+
2055
+ def test_call_stabby_with_braces_block
2056
+ rb = "a -> {} do\nend"
2057
+ pt = s(:iter, s(:call, nil, :a, s(:iter, s(:call, nil, :lambda), 0)), 0)
2058
+
2059
+ assert_parse rb, pt
2060
+ end
2061
+
2062
+ def test_call_stabby_do_end_with_block
2063
+ rb = "a -> do end do end"
2064
+ pt = s(:iter, s(:call, nil, :a, s(:iter, s(:call, nil, :lambda), 0)), 0)
2065
+
2066
+ assert_parse rb, pt
2067
+ end
2068
+
2069
+ def test_call_trailing_comma
2070
+ rb = "f(1,)"
2071
+ pt = s(:call, nil, :f, s(:lit, 1))
2072
+
2073
+ assert_parse rb, pt
2074
+ end
2075
+
2076
+ def test_method_call_trailing_comma
2077
+ rb = "a.f(1,)"
2078
+ pt = s(:call, s(:call, nil, :a), :f, s(:lit, 1))
2079
+
2080
+ assert_parse rb, pt
2081
+ end
2082
+
2083
+ def test_call_assoc_trailing_comma
2084
+ rb = "f(1=>2,)"
2085
+ pt = s(:call, nil, :f, s(:hash, s(:lit, 1), s(:lit, 2)))
2086
+
2087
+ assert_parse rb, pt
2088
+ end
2089
+
2090
+ def test_method_call_assoc_trailing_comma
2091
+ rb = "a.f(1=>2,)"
2092
+ pt = s(:call, s(:call, nil, :a), :f, s(:hash, s(:lit, 1), s(:lit, 2)))
2093
+
2094
+ assert_parse rb, pt
2095
+ end
2096
+
2097
+ def test_call_args_assoc_trailing_comma
2098
+ rb = "f(1, 2=>3,)"
2099
+ pt = s(:call, nil, :f, s(:lit, 1), s(:hash, s(:lit, 2), s(:lit, 3)))
2100
+
2101
+ assert_parse rb, pt
2102
+ end
2103
+
2104
+ def test_call_arg_assoc
2105
+ rb = "f(1, 2=>3)"
2106
+ pt = s(:call, nil, :f, s(:lit, 1), s(:hash, s(:lit, 2), s(:lit, 3)))
2107
+
2108
+ assert_parse rb, pt
2109
+ end
2110
+
2111
+ def test_call_assoc
2112
+ rb = "f(2=>3)"
2113
+ pt = s(:call, nil, :f, s(:hash, s(:lit, 2), s(:lit, 3)))
2114
+
2115
+ assert_parse rb, pt
2116
+ end
2117
+
2118
+ def test_return_call_assocs
2119
+ rb = "return y(z:1)"
2120
+ pt = s(:return, s(:call, nil, :y, s(:hash, s(:lit, :z), s(:lit, 1))))
2121
+
2122
+ assert_parse rb, pt
2123
+
2124
+ rb = "return y z:1"
2125
+ pt = s(:return, s(:call, nil, :y, s(:hash, s(:lit, :z), s(:lit, 1))))
2126
+
2127
+ assert_parse rb, pt
2128
+
2129
+ rb = "return y(z=>1)"
2130
+ pt = s(:return, s(:call, nil, :y, s(:hash, s(:call, nil, :z), s(:lit, 1))))
2131
+
2132
+ assert_parse rb, pt
2133
+
2134
+ rb = "return y :z=>1"
2135
+ pt = s(:return, s(:call, nil, :y, s(:hash, s(:lit, :z), s(:lit, 1))))
2136
+
2137
+ assert_parse rb, pt
2138
+
2139
+ rb = "return 1, :z => 1"
2140
+ pt = s(:return,
2141
+ s(:array,
2142
+ s(:lit, 1),
2143
+ s(:hash, s(:lit, :z), s(:lit, 1))))
2144
+
2145
+ assert_parse rb, pt
2146
+
2147
+ rb = "return 1, :z => 1, :w => 2"
2148
+ pt = s(:return,
2149
+ s(:array,
2150
+ s(:lit, 1),
2151
+ s(:hash, s(:lit, :z), s(:lit, 1), s(:lit, :w), s(:lit, 2))))
2152
+
2153
+ assert_parse rb, pt
2154
+ end
2155
+
2156
+ def test_yield_call_assocs
2157
+ rb = "yield y(z:1)"
2158
+ pt = s(:yield, s(:call, nil, :y, s(:hash, s(:lit, :z), s(:lit, 1))))
2159
+
2160
+ assert_parse rb, pt
2161
+
2162
+ rb = "yield y z:1"
2163
+ pt = s(:yield, s(:call, nil, :y, s(:hash, s(:lit, :z), s(:lit, 1))))
2164
+
2165
+ assert_parse rb, pt
2166
+
2167
+ rb = "yield y(z=>1)"
2168
+ pt = s(:yield, s(:call, nil, :y, s(:hash, s(:call, nil, :z), s(:lit, 1))))
2169
+
2170
+ assert_parse rb, pt
2171
+
2172
+ rb = "yield y :z=>1"
2173
+ pt = s(:yield, s(:call, nil, :y, s(:hash, s(:lit, :z), s(:lit, 1))))
2174
+
2175
+ assert_parse rb, pt
2176
+
2177
+ rb = "yield 1, :z => 1"
2178
+ pt = s(:yield,
2179
+ s(:lit, 1),
2180
+ s(:hash, s(:lit, :z), s(:lit, 1)))
2181
+
2182
+ assert_parse rb, pt
2183
+
2184
+ rb = "yield 1, :z => 1, :w => 2"
2185
+ pt = s(:yield,
2186
+ s(:lit, 1),
2187
+ s(:hash, s(:lit, :z), s(:lit, 1), s(:lit, :w), s(:lit, 2)))
2188
+
2189
+ assert_parse rb, pt
2190
+ end
2191
+
2192
+ def test_call_assoc_new
2193
+ rb = "f(a:3)"
2194
+ pt = s(:call, nil, :f, s(:hash, s(:lit, :a), s(:lit, 3)))
2195
+
2196
+ assert_parse rb, pt
2197
+ end
2198
+
2199
+ def test_call_assoc_new_if_multiline
2200
+ rb = "a(b: if :c\n1\nelse\n2\nend)"
2201
+ pt = s(:call, nil, :a, s(:hash, s(:lit, :b), s(:if, s(:lit, :c), s(:lit, 1), s(:lit, 2))))
2202
+
2203
+ assert_parse rb, pt
2204
+ end
2205
+
2206
+ def test_do_lambda
2207
+ rb = "->() do end"
2208
+ pt = s(:iter, s(:call, nil, :lambda), s(:args))
2209
+
2210
+ assert_parse rb, pt
2211
+ end
2212
+
2213
+ def test_call_dot_parens
2214
+ rb = "1.()"
2215
+ pt = s(:call, s(:lit, 1), :call)
2216
+
2217
+ assert_parse rb, pt
2218
+ end
2219
+
2220
+ def test_call_colon_parens
2221
+ rb = "1::()"
2222
+ pt = s(:call, s(:lit, 1), :call)
2223
+
2224
+ assert_parse rb, pt
2225
+ end
2226
+
2227
+ def test_block_args_opt2
2228
+ rb = "a { | b=1, c=2 | }"
2229
+ pt = s(:iter,
2230
+ s(:call, nil, :a),
2231
+ s(:args, s(:lasgn, :b, s(:lit, 1)), s(:lasgn, :c, s(:lit, 2))))
2232
+
2233
+ assert_parse rb, pt
2234
+ end
2235
+
2236
+ def test_block_paren_splat # TODO: rename # TODO: should work on 1.8
2237
+ rb = "a { |(b, *c)| }"
2238
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:masgn, :b, :"*c")))
2239
+
2240
+ assert_parse rb, pt
2241
+ end
2242
+
2243
+ def test_masgn_anon_splat_arg
2244
+ rb = "*, a = b"
2245
+ pt = s(:masgn,
2246
+ s(:array, s(:splat), s(:lasgn, :a)),
2247
+ s(:to_ary, s(:call, nil, :b)))
2248
+
2249
+ assert_parse rb, pt
2250
+ end
2251
+
2252
+ def test_masgn_splat_arg
2253
+ rb = "*a, b = c"
2254
+ pt = s(:masgn,
2255
+ s(:array, s(:splat, s(:lasgn, :a)), s(:lasgn, :b)),
2256
+ s(:to_ary, s(:call, nil, :c)))
2257
+
2258
+ assert_parse rb, pt
2259
+ end
2260
+
2261
+ def test_lasgn_lasgn_command_call
2262
+ rb = "a = b = c 1"
2263
+ pt = s(:lasgn, :a, s(:lasgn, :b, s(:call, nil, :c, s(:lit, 1))))
2264
+
2265
+ assert_parse rb, pt
2266
+ end
2267
+
2268
+ def test_masgn_arg_splat_arg
2269
+ rb = "a, *b, c = d"
2270
+ pt = s(:masgn,
2271
+ s(:array, s(:lasgn, :a), s(:splat, s(:lasgn, :b)), s(:lasgn, :c)),
2272
+ s(:to_ary, s(:call, nil, :d)))
2273
+
2274
+ assert_parse rb, pt
2275
+ end
2276
+
2277
+ def test_masgn_splat_arg_arg
2278
+ rb = "*a, b, c = d"
2279
+ pt = s(:masgn,
2280
+ s(:array, s(:splat, s(:lasgn, :a)), s(:lasgn, :b), s(:lasgn, :c)),
2281
+ s(:to_ary, s(:call, nil, :d)))
2282
+
2283
+ assert_parse rb, pt
2284
+ end
2285
+
2286
+ def test_block_decomp_anon_splat_arg
2287
+ rb = "f { |(*, a)| }"
2288
+ pt = s(:iter, s(:call, nil, :f), s(:args, s(:masgn, :*, :a)))
2289
+
2290
+ assert_parse rb, pt
2291
+ end
2292
+
2293
+ def test_block_decomp_arg_splat_arg
2294
+ rb = "f { |(a, *b, c)| }"
2295
+ pt = s(:iter, s(:call, nil, :f), s(:args, s(:masgn, :a, :"*b", :c)))
2296
+
2297
+ assert_parse rb, pt
2298
+ end
2299
+
2300
+ def test_symbol_empty
2301
+ skip "can't do this in ruby 1.8" if RUBY_VERSION < "1.9"
2302
+
2303
+ rb = ":''"
2304
+ pt = s(:lit, "".to_sym)
2305
+
2306
+ assert_parse rb, pt
2307
+ end
2308
+
2309
+ def test_masgn_var_star_var
2310
+ rb = "a, *, b = c" # TODO: blog
2311
+ pt = s(:masgn,
2312
+ s(:array, s(:lasgn, :a), s(:splat), s(:lasgn, :b)),
2313
+ s(:to_ary, s(:call, nil, :c)))
2314
+
2315
+ assert_parse rb, pt
2316
+ end
2317
+
2318
+ def test_mlhs_keyword
2319
+ rb = "a.!=(true, true)"
2320
+ pt = s(:call, s(:call, nil, :a), :"!=", s(:true), s(:true))
2321
+
2322
+ assert_parse rb, pt
2323
+ end
2324
+
2325
+ def test_call_array_lit_inline_hash
2326
+ rb = "a([:b, :c => 1])"
2327
+ pt = s(:call, nil, :a, s(:array, s(:lit, :b), s(:hash, s(:lit, :c), s(:lit, 1))))
2328
+
2329
+ assert_parse rb, pt
2330
+ end
2331
+
2332
+ def test_multiline_hash_declaration
2333
+ pt = s(:call, nil, :f, s(:hash, s(:lit, :state), s(:hash)))
2334
+
2335
+ assert_parse "f(state: {})", pt
2336
+ assert_parse "f(state: {\n})", pt
2337
+ assert_parse "f(state:\n {\n})", pt
2338
+ end
2339
+
2340
+ def test_mlhs_back_splat
2341
+ rb = "a, b, c, *s = f"
2342
+ pt = s(:masgn,
2343
+ s(:array,
2344
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
2345
+ s(:splat, s(:lasgn, :s))),
2346
+ s(:to_ary, s(:call, nil, :f)))
2347
+
2348
+ assert_parse rb, pt
2349
+ end
2350
+
2351
+ def test_mlhs_back_anonsplat
2352
+ rb = "a, b, c, * = f"
2353
+ pt = s(:masgn,
2354
+ s(:array,
2355
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
2356
+ s(:splat)),
2357
+ s(:to_ary, s(:call, nil, :f)))
2358
+
2359
+ assert_parse rb, pt
2360
+ end
2361
+
2362
+ def test_mlhs_mid_splat
2363
+ rb = "a, b, c, *s, x, y, z = f"
2364
+ pt = s(:masgn,
2365
+ s(:array,
2366
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
2367
+ s(:splat, s(:lasgn, :s)),
2368
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
2369
+ s(:to_ary, s(:call, nil, :f)))
2370
+
2371
+ assert_parse rb, pt
2372
+ end
2373
+
2374
+ def test_mlhs_mid_anonsplat
2375
+ rb = "a, b, c, *, x, y, z = f"
2376
+ pt = s(:masgn,
2377
+ s(:array, s(:lasgn, :a), s(:splat), s(:lasgn, :z)),
2378
+ s(:to_ary, s(:call, nil, :f)))
2379
+ pt = s(:masgn,
2380
+ s(:array,
2381
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
2382
+ s(:splat),
2383
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
2384
+ s(:to_ary, s(:call, nil, :f)))
2385
+
2386
+ assert_parse rb, pt
2387
+ end
2388
+
2389
+ def test_mlhs_front_splat
2390
+ rb = "*s, x, y, z = f"
2391
+ pt = s(:masgn,
2392
+ s(:array, s(:splat, s(:lasgn, :s)), s(:lasgn, :z)),
2393
+ s(:to_ary, s(:call, nil, :f)))
2394
+ pt = s(:masgn,
2395
+ s(:array,
2396
+ s(:splat, s(:lasgn, :s)),
2397
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
2398
+ s(:to_ary, s(:call, nil, :f)))
2399
+
2400
+ assert_parse rb, pt
2401
+ end
2402
+
2403
+ def test_mlhs_front_anonsplat
2404
+ rb = "*, x, y, z = f"
2405
+ pt = s(:masgn,
2406
+ s(:array,
2407
+ s(:splat),
2408
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
2409
+ s(:to_ary, s(:call, nil, :f)))
2410
+
2411
+ assert_parse rb, pt
2412
+ end
2413
+
2414
+ def test_expr_not_bang
2415
+ rb = "! a b"
2416
+ pt = s(:call, s(:call, nil, :a, s(:call, nil, :b)), :"!")
2417
+
2418
+ assert_parse rb, pt
2419
+ end
2420
+
2421
+ def test_do_colon_19
2422
+ rb = "while false : 42 end"
2423
+
2424
+ assert_parse_error rb, "(string):1 :: parse error on value \":\" (tCOLON)"
2425
+ end
2426
+
2427
+ def test_assoc_list_19
2428
+ rb = "{1, 2, 3, 4}"
2429
+
2430
+ assert_parse_error rb, "(string):1 :: parse error on value \",\" (tCOMMA)"
2431
+ end
2432
+
2433
+ def test_case_then_colon_19
2434
+ rb = <<-EOM
2435
+ case x
2436
+ when Fixnum : # need the space to not hit new hash arg syntax
2437
+ 42
2438
+ end
2439
+ EOM
2440
+
2441
+ assert_parse_error rb, "(string):2 :: parse error on value \":\" (tCOLON)"
2442
+ end
2443
+
2444
+ def test_parse_def_xxx1
2445
+ rb = 'def f(a, *b, c = nil) end'
2446
+
2447
+ assert_parse_error rb, '(string):1 :: parse error on value "=" (tEQL)'
2448
+ end
2449
+
2450
+ def test_parse_def_xxx2
2451
+ rb = 'def f(a = nil, *b, c = nil) end'
2452
+
2453
+ assert_parse_error rb, '(string):1 :: parse error on value "=" (tEQL)'
2454
+ end
2455
+
2456
+ def test_parse_def_special_name
2457
+ rb = 'def next; end'
2458
+ pt = s(:defn, :next, s(:args), s(:nil))
2459
+
2460
+ assert_parse rb, pt
2461
+ end
2462
+
2463
+ def test_parse_until_not_canonical
2464
+ rb = "until not var.nil?\n 'foo'\nend"
2465
+ pt = s(:until,
2466
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
2467
+ s(:str, "foo"), true)
2468
+
2469
+ assert_parse rb, pt
2470
+ end
2471
+
2472
+ def test_parse_until_not_noncanonical
2473
+ rb = "until not var.nil?\n 'foo'\nend"
2474
+ pt = s(:until,
2475
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
2476
+ s(:str, "foo"), true)
2477
+
2478
+ processor.canonicalize_conditions = false
2479
+
2480
+ assert_parse rb, pt
2481
+ end
2482
+
2483
+ def test_parse_if_not_canonical
2484
+ rb = "if not var.nil? then 'foo' else 'bar'\nend"
2485
+ pt = s(:if,
2486
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
2487
+ s(:str, "foo"),
2488
+ s(:str, "bar"))
2489
+
2490
+ assert_parse rb, pt
2491
+ end
2492
+
2493
+ def test_parse_if_not_noncanonical
2494
+ rb = "if not var.nil? then 'foo' else 'bar'\nend"
2495
+ pt = s(:if,
2496
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
2497
+ s(:str, "foo"),
2498
+ s(:str, "bar"))
2499
+
2500
+ processor.canonicalize_conditions = false
2501
+
2502
+ assert_parse rb, pt
2503
+ end
2504
+
2505
+ def test_parse_while_not_canonical
2506
+ rb = "while not var.nil?\n 'foo'\nend"
2507
+ pt = s(:while,
2508
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
2509
+ s(:str, "foo"), true)
2510
+
2511
+ assert_parse rb, pt
2512
+ end
2513
+
2514
+ def test_parse_while_not_noncanonical
2515
+ rb = "while not var.nil?\n 'foo'\nend"
2516
+ pt = s(:while,
2517
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
2518
+ s(:str, "foo"), true)
2519
+
2520
+ processor.canonicalize_conditions = false
2521
+
2522
+ assert_parse rb, pt
2523
+ end
2524
+
2525
+ def test_parse_opt_call_args_assocs_comma
2526
+ rb = "1[2=>3,]"
2527
+ pt = s(:call, s(:lit, 1), :[], s(:hash, s(:lit, 2), s(:lit, 3)))
2528
+
2529
+ assert_parse rb, pt
2530
+ end
2531
+
2532
+ def test_parse_opt_call_args_lit_comma
2533
+ rb = "1[2,]"
2534
+ pt = s(:call, s(:lit, 1), :[], s(:lit, 2))
2535
+
2536
+ assert_parse rb, pt
2537
+ end
2538
+
2539
+ def test_bug_hash_args
2540
+ rb = "foo(:bar, baz: nil)"
2541
+ pt = s(:call, nil, :foo,
2542
+ s(:lit, :bar),
2543
+ s(:hash, s(:lit, :baz), s(:nil)))
2544
+
2545
+ assert_parse rb, pt
2546
+ end
2547
+
2548
+ def test_bug_hash_args_trailing_comma
2549
+ rb = "foo(:bar, baz: nil,)"
2550
+ pt = s(:call, nil, :foo, # NOTE: same sexp as test_bug_hash_args
2551
+ s(:lit, :bar),
2552
+ s(:hash, s(:lit, :baz), s(:nil)))
2553
+
2554
+ assert_parse rb, pt
2555
+ end
2556
+
2557
+ def test_block_arg_optional
2558
+ rb = "a { |b = 1| }"
2559
+ pt = s(:iter,
2560
+ s(:call, nil, :a),
2561
+ s(:args, s(:lasgn, :b, s(:lit, 1))))
2562
+
2563
+ assert_parse rb, pt
2564
+ end
2565
+
2566
+ def test_zomg_sometimes_i_hate_this_project
2567
+ rb = <<-RUBY
2568
+ {
2569
+ a: lambda { b ? c() : d },
2570
+ e: nil,
2571
+ }
2572
+ RUBY
2573
+
2574
+ pt = s(:hash,
2575
+ s(:lit, :a),
2576
+ s(:iter,
2577
+ s(:call, nil, :lambda),
2578
+ 0,
2579
+ s(:if, s(:call, nil, :b), s(:call, nil, :c), s(:call, nil, :d))),
2580
+
2581
+ s(:lit, :e),
2582
+ s(:nil))
2583
+
2584
+ assert_parse rb, pt
2585
+ end
2586
+
2587
+ def test_pipe_semicolon
2588
+ skip "not yet"
2589
+
2590
+ rb = "a.b do | ; c | end"
2591
+ pt = s(:iter, s(:call, s(:call, nil, :a), :b), 0)
2592
+
2593
+ assert_parse rb, pt
2594
+ end
2595
+
2596
+ def test_wtf
2597
+ # lambda -> f_larglist lambda_body
2598
+ # f_larglist -> f_args opt_bv_decl
2599
+ # opt_bv_decl
2600
+ # bv_decls
2601
+ # bvar
2602
+
2603
+ rb = "->(a, b=nil) { p [a, b] }"
2604
+ pt = s(:iter,
2605
+ s(:call, nil, :lambda),
2606
+ s(:args, :a, s(:lasgn, :b, s(:nil))),
2607
+ s(:call, nil, :p, s(:array, s(:lvar, :a), s(:lvar, :b))))
2608
+
2609
+ assert_parse rb, pt
2610
+
2611
+ # rb = "->(a; b) { p [a, b] }"
2612
+ #
2613
+ # assert_parse rb, pt
2614
+ end
2615
+
2616
+ def test_block_args_opt1
2617
+ rb = "f { |a, b = 42| [a, b] }"
2618
+ pt = s(:iter,
2619
+ s(:call, nil, :f),
2620
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42))),
2621
+ s(:array, s(:lvar, :a), s(:lvar, :b)))
2622
+
2623
+ assert_parse rb, pt
2624
+ end
2625
+
2626
+ def test_block_args_opt2_2
2627
+ rb = "f { |a, b = 42, c = 24| [a, b, c] }"
2628
+ pt = s(:iter,
2629
+ s(:call, nil, :f),
2630
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), s(:lasgn, :c, s(:lit, 24))),
2631
+ s(:array, s(:lvar, :a), s(:lvar, :b), s(:lvar, :c)))
2632
+
2633
+ assert_parse rb, pt
2634
+ end
2635
+
2636
+ def test_block_args_opt3
2637
+ rb = "f { |a, b = 42, c = 24, &d| [a, b, c, d] }"
2638
+ pt = s(:iter,
2639
+ s(:call, nil, :f),
2640
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), s(:lasgn, :c, s(:lit, 24)), :"&d"),
2641
+ s(:array, s(:lvar, :a), s(:lvar, :b), s(:lvar, :c), s(:lvar, :d)))
2642
+
2643
+ assert_parse rb, pt
2644
+ end
2645
+
2646
+ def test_i_have_no_freakin_clue
2647
+ rb = "1 ? b('') : 2\na d: 3"
2648
+ pt = s(:block,
2649
+ s(:if, s(:lit, 1), s(:call, nil, :b, s(:str, "")), s(:lit, 2)),
2650
+ s(:call, nil, :a, s(:hash, s(:lit, :d), s(:lit, 3))))
2651
+
2652
+ assert_parse rb, pt
2653
+ end
2654
+
2655
+ def test_motherfuckin_leading_dots
2656
+ rb = "a\n.b"
2657
+ pt = s(:call, s(:call, nil, :a), :b)
2658
+
2659
+ assert_parse rb, pt
2660
+ end
2661
+
2662
+ def test_motherfuckin_leading_dots2
2663
+ rb = "a\n..b"
2664
+
2665
+ assert_parse_error rb, '(string):2 :: parse error on value ".." (tDOT2)'
2666
+ end
2667
+
2668
+ def test_kill_me
2669
+ rb = "f { |a, (b, *c)| }"
2670
+ pt = s(:iter,
2671
+ s(:call, nil, :f),
2672
+ s(:args, :a, s(:masgn, :b, :"*c")))
2673
+
2674
+ assert_parse rb, pt
2675
+ end
2676
+
2677
+ def test_kill_me2
2678
+ rb = "f { |*a, b| }"
2679
+ pt = s(:iter, s(:call, nil, :f), s(:args, :"*a", :b))
2680
+
2681
+ assert_parse rb, pt
2682
+ end
2683
+
2684
+ def test_kill_me3
2685
+ rb = "f { |*a, b, &c| }"
2686
+ pt = s(:iter, s(:call, nil, :f), s(:args, :"*a", :b, :"&c"))
2687
+
2688
+ assert_parse rb, pt
2689
+ end
2690
+
2691
+ def test_kill_me4
2692
+ rb = "a=b ? true: false"
2693
+ pt = s(:lasgn, :a, s(:if, s(:call, nil, :b), s(:true), s(:false)))
2694
+
2695
+ assert_parse rb, pt
2696
+ end
2697
+
2698
+ def test_kill_me5
2699
+ skip "not yet"
2700
+
2701
+ rb = "f ->() { g do end }"
2702
+ pt = 42
2703
+
2704
+ assert_parse rb, pt
2705
+ end
2706
+
2707
+ def test_iter_args_4
2708
+ rb = "f { |a, *b, c| }"
2709
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, :"*b", :c))
2710
+
2711
+ assert_parse rb, pt
2712
+ end
2713
+
2714
+ def test_iter_args_5
2715
+ skip "not yet"
2716
+
2717
+ rb = "f { |a, &b| }"
2718
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, :"&b"))
2719
+
2720
+ assert_parse rb, pt
2721
+ end
2722
+
2723
+ def test_iter_args_6
2724
+ rb = "f { |a, b=42, c| }"
2725
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :c))
2726
+
2727
+ assert_parse rb, pt
2728
+ end
2729
+
2730
+ # In 1.8, block args with an outer set of parens are superfluous.
2731
+ # In 1.9, outer set of parens are NOT... they are an explicit extra masgn.
2732
+
2733
+ def test_iter_args_2__19
2734
+ rb = "f { |(a, b)| }"
2735
+ pt = s(:iter, s(:call, nil, :f), s(:args, s(:masgn, :a, :b)))
2736
+
2737
+ assert_parse rb, pt
2738
+ end
2739
+
2740
+ def test_bug_args__19
2741
+ rb = "f { |(a, b)| d }"
2742
+ pt = s(:iter, s(:call, nil, :f),
2743
+ s(:args, s(:masgn, :a, :b)),
2744
+ s(:call, nil, :d))
2745
+
2746
+ assert_parse rb, pt
2747
+ end
2748
+
2749
+ def test_bug_args_masgn_outer_parens__19
2750
+ rb = "f { |((k, v), i)| }"
2751
+ pt = s(:iter, # NOTE: same sexp as test_bug_args_masgn
2752
+ s(:call, nil, :f),
2753
+ s(:args, s(:masgn, s(:masgn, :k, :v), :i)))
2754
+
2755
+ assert_parse rb, pt.dup
2756
+ end
2757
+
2758
+ def test_iter_args_7_1
2759
+ rb = "f { |a = 42, *b| }"
2760
+ pt = s(:iter, s(:call, nil, :f),
2761
+ s(:args, s(:lasgn, :a, s(:lit, 42)), :"*b"))
2762
+
2763
+ assert_parse rb, pt
2764
+ end
2765
+
2766
+ def test_iter_args_7_2
2767
+ rb = "f { |a = 42, *b, &c| }"
2768
+ pt = s(:iter, s(:call, nil, :f),
2769
+ s(:args, s(:lasgn, :a, s(:lit, 42)), :"*b", :"&c"))
2770
+
2771
+ assert_parse rb, pt
2772
+ end
2773
+
2774
+ def test_iter_args_8_1
2775
+ rb = "f { |a = 42, *b, c| }"
2776
+ pt = s(:iter, s(:call, nil, :f),
2777
+ s(:args, s(:lasgn, :a, s(:lit, 42)), :"*b", :c))
2778
+
2779
+ assert_parse rb, pt
2780
+ end
2781
+
2782
+ def test_iter_args_8_2
2783
+ rb = "f { |a = 42, *b, c, &d| }"
2784
+ pt = s(:iter, s(:call, nil, :f),
2785
+ s(:args, s(:lasgn, :a, s(:lit, 42)), :"*b", :c, :"&d"))
2786
+
2787
+ assert_parse rb, pt
2788
+ end
2789
+
2790
+ def test_iter_args_9_1
2791
+ rb = "f { |a = 42, b| }"
2792
+ pt = s(:iter, s(:call, nil, :f),
2793
+ s(:args, s(:lasgn, :a, s(:lit, 42)), :b))
2794
+
2795
+ assert_parse rb, pt
2796
+ end
2797
+
2798
+ def test_iter_args_9_2
2799
+ rb = "f { |a = 42, b, &c| }"
2800
+ pt = s(:iter, s(:call, nil, :f),
2801
+ s(:args, s(:lasgn, :a, s(:lit, 42)), :b, :"&c"))
2802
+
2803
+ assert_parse rb, pt
2804
+ end
2805
+
2806
+ def test_iter_args_10_1
2807
+ rb = "f { |a, b = 42, *c| }"
2808
+ pt = s(:iter, s(:call, nil, :f),
2809
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c"))
2810
+
2811
+ assert_parse rb, pt
2812
+ end
2813
+
2814
+ def test_iter_args_10_2
2815
+ rb = "f { |a, b = 42, *c, &d| }"
2816
+ pt = s(:iter, s(:call, nil, :f),
2817
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :"&d"))
2818
+
2819
+ assert_parse rb, pt
2820
+ end
2821
+
2822
+ def test_iter_args_11_1
2823
+ rb = "f { |a, b = 42, *c, d| }"
2824
+ pt = s(:iter, s(:call, nil, :f),
2825
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :d))
2826
+
2827
+ assert_parse rb, pt
2828
+ end
2829
+
2830
+ def test_iter_args_11_2
2831
+ rb = "f { |a, b = 42, *c, d, &e| }"
2832
+ pt = s(:iter, s(:call, nil, :f),
2833
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :d, :"&e"))
2834
+
2835
+ assert_parse rb, pt
2836
+ end
2837
+
2838
+ def test_kill_me_6
2839
+ # | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
2840
+ rb = "f { |a, (b, *c, d)| }"
2841
+ pt = s(:iter,
2842
+ s(:call, nil, :f),
2843
+ s(:args, :a, s(:masgn, :b, :"*c", :d)))
2844
+
2845
+ assert_parse rb, pt
2846
+ end
2847
+
2848
+ def test_kill_me_7
2849
+ # | f_marg_list tCOMMA tSTAR
2850
+ rb = "f { |a, (b, *)| }"
2851
+ pt = s(:iter,
2852
+ s(:call, nil, :f),
2853
+ s(:args, :a, s(:masgn, :b, :*)))
2854
+
2855
+ assert_parse rb, pt
2856
+ end
2857
+
2858
+ def test_kill_me_8
2859
+ # | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
2860
+ rb = "f { |a, (b, *, c)| }"
2861
+ pt = s(:iter,
2862
+ s(:call, nil, :f),
2863
+ s(:args, :a, s(:masgn, :b, :*, :c)))
2864
+
2865
+ assert_parse rb, pt
2866
+ end
2867
+
2868
+ def test_kill_me_9
2869
+ # | tSTAR f_norm_arg
2870
+ rb = "f { |a, (*b)| }"
2871
+ pt = s(:iter,
2872
+ s(:call, nil, :f),
2873
+ s(:args, :a, s(:masgn, :"*b")))
2874
+
2875
+ assert_parse rb, pt
2876
+ end
2877
+
2878
+ def test_kill_me_10
2879
+ # | tSTAR f_norm_arg tCOMMA f_marg_list
2880
+ rb = "f { |a, (*b, c)| }"
2881
+ pt = s(:iter,
2882
+ s(:call, nil, :f),
2883
+ s(:args, :a, s(:masgn, :"*b", :c)))
2884
+
2885
+ assert_parse rb, pt
2886
+ end
2887
+
2888
+ def test_kill_me_11
2889
+ # | tSTAR
2890
+ rb = "f { |a, (*)| }"
2891
+ pt = s(:iter,
2892
+ s(:call, nil, :f),
2893
+ s(:args, :a, s(:masgn, :*)))
2894
+
2895
+ assert_parse rb, pt
2896
+ end
2897
+
2898
+ def test_kill_me_12
2899
+ # | tSTAR tCOMMA f_marg_list
2900
+ rb = "f { |a, (*, b)| }"
2901
+ pt = s(:iter,
2902
+ s(:call, nil, :f),
2903
+ s(:args, :a, s(:masgn, :*, :b)))
2904
+
2905
+ assert_parse rb, pt
2906
+ end
2907
+
2908
+ def test_index_0
2909
+ rb = "a[] = b"
2910
+ pt = s(:attrasgn, s(:call, nil, :a), :[]=, s(:call, nil, :b))
2911
+
2912
+ assert_parse rb, pt
2913
+ end
2914
+
2915
+ def test_lambda_do_vs_brace
2916
+ pt = s(:call, nil, :f, s(:iter, s(:call, nil, :lambda), s(:args)))
2917
+
2918
+ rb = "f ->() {}"
2919
+ assert_parse rb, pt
2920
+
2921
+ rb = "f ->() do end"
2922
+ assert_parse rb, pt
2923
+
2924
+ pt = s(:call, nil, :f, s(:iter, s(:call, nil, :lambda), 0))
2925
+
2926
+ rb = "f -> {}"
2927
+ assert_parse rb, pt
2928
+
2929
+ rb = "f -> do end"
2930
+ assert_parse rb, pt
2931
+ end
2932
+
2933
+ def test_thingy
2934
+ pt = s(:call, s(:call, nil, :f), :call, s(:lit, 42))
2935
+
2936
+ rb = "f.(42)"
2937
+ assert_parse rb, pt
2938
+
2939
+ rb = "f::(42)"
2940
+ assert_parse rb, pt
2941
+ end
2942
+
2943
+ def test_unary_plus_on_literal
2944
+ rb = "+:a"
2945
+ pt = s(:call, s(:lit, :a), :+@)
2946
+
2947
+ assert_parse rb, pt
2948
+ end
2949
+ end
2950
+
2951
+ module TestRubyParserShared20Plus
2952
+ include TestRubyParserShared19Plus
2953
+
2954
+ def test_non_interpolated_symbol_array_line_breaks
2955
+
2956
+ rb = "%i(\na\nb\n)\n1"
2957
+ pt = s(:block,
2958
+ s(:array,
2959
+ s(:lit, :a).line(2),
2960
+ s(:lit, :b).line(3)).line(1),
2961
+ s(:lit, 1).line(5))
2962
+ assert_parse rb, pt
2963
+ end
2964
+
2965
+ def test_interpolated_symbol_array_line_breaks
2966
+
2967
+ rb = "%I(\na\nb\n)\n1"
2968
+ pt = s(:block,
2969
+ s(:array,
2970
+ s(:lit, :a).line(2),
2971
+ s(:lit, :b).line(3)).line(1),
2972
+ s(:lit, 1).line(5))
2973
+ assert_parse rb, pt
2974
+ end
2975
+
2976
+ def test_defs_kwarg
2977
+ rb = "def self.a b: 1\nend"
2978
+ pt = s(:defs, s(:self), :a, s(:args, s(:kwarg, :b, s(:lit, 1))), s(:nil))
2979
+
2980
+ assert_parse rb, pt
2981
+ end
2982
+
2983
+ def test_defn_kwarg_kwsplat
2984
+ rb = "def a(b: 1, **c) end"
2985
+ pt = s(:defn, :a, s(:args, s(:kwarg, :b, s(:lit, 1)), :"**c"), s(:nil))
2986
+
2987
+ assert_parse rb, pt
2988
+ end
2989
+
2990
+ def test_defn_kwarg_kwsplat_anon
2991
+ rb = "def a(b: 1, **) end"
2992
+ pt = s(:defn, :a, s(:args, s(:kwarg, :b, s(:lit, 1)), :"**"), s(:nil))
2993
+
2994
+ assert_parse rb, pt
2995
+ end
2996
+
2997
+ def test_defn_kwarg_env
2998
+ rb = "def test(**testing) test_splat(**testing) end"
2999
+ pt = s(:defn, :test, s(:args, :"**testing"),
3000
+ s(:call, nil, :test_splat, s(:hash, s(:kwsplat, s(:lvar, :testing)))))
3001
+
3002
+ assert_parse rb, pt
3003
+ end
3004
+
3005
+ def test_dstr_lex_state
3006
+ rb = '"#{p:a}"'
3007
+ pt = s(:dstr, "", s(:evstr, s(:call, nil, :p, s(:lit, :a))))
3008
+
3009
+ assert_parse rb, pt
3010
+ end
3011
+
3012
+ def test_call_arg_kwsplat
3013
+ rb = "a(b, **1)"
3014
+ pt = s(:call, nil, :a, s(:call, nil, :b), s(:hash, s(:kwsplat, s(:lit, 1))))
3015
+
3016
+ assert_parse rb, pt
3017
+ end
3018
+
3019
+ def test_call_arg_assoc_kwsplat
3020
+ rb = "f(1, kw: 2, **3)"
3021
+ pt = s(:call, nil, :f,
3022
+ s(:lit, 1),
3023
+ s(:hash, s(:lit, :kw), s(:lit, 2), s(:kwsplat, s(:lit, 3))))
3024
+
3025
+ assert_parse rb, pt
3026
+ end
3027
+
3028
+ def test_call_kwsplat
3029
+ rb = "a(**1)"
3030
+ pt = s(:call, nil, :a, s(:hash, s(:kwsplat, s(:lit, 1))))
3031
+
3032
+ assert_parse rb, pt
3033
+ end
3034
+
3035
+ def test_iter_kwarg
3036
+ rb = "a { |b: 1| }"
3037
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:kwarg, :b, s(:lit, 1))))
3038
+
3039
+ assert_parse rb, pt
3040
+ end
3041
+
3042
+ def test_iter_kwarg_kwsplat
3043
+ rb = "a { |b: 1, **c| }"
3044
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:kwarg, :b, s(:lit, 1)), :"**c"))
3045
+
3046
+ assert_parse rb, pt
3047
+ end
3048
+
3049
+ def test_block_kwarg_lvar
3050
+ rb = "bl { |kw: :val| kw }"
3051
+ pt = s(:iter, s(:call, nil, :bl), s(:args, s(:kwarg, :kw, s(:lit, :val))),
3052
+ s(:lvar, :kw))
3053
+
3054
+ assert_parse rb, pt
3055
+ end
3056
+
3057
+ def test_block_kwarg_lvar_multiple
3058
+ rb = "bl { |kw: :val, kw2: :val2 | kw }"
3059
+ pt = s(:iter, s(:call, nil, :bl),
3060
+ s(:args,
3061
+ s(:kwarg, :kw, s(:lit, :val)),
3062
+ s(:kwarg, :kw2, s(:lit, :val2))),
3063
+ s(:lvar, :kw))
3064
+
3065
+ assert_parse rb, pt
3066
+ end
3067
+
3068
+ def test_stabby_block_iter_call
3069
+ rb = "x -> () do\na.b do\nend\nend"
3070
+ pt = s(:call, nil, :x,
3071
+ s(:iter,
3072
+ s(:call, nil, :lambda),
3073
+ s(:args),
3074
+ s(:iter, s(:call, s(:call, nil, :a), :b), 0)))
3075
+
3076
+ assert_parse rb, pt
3077
+ end
3078
+
3079
+ def test_stabby_block_iter_call_no_target_with_arg
3080
+ rb = "x -> () do\na(1) do\nend\nend"
3081
+ pt = s(:call, nil, :x,
3082
+ s(:iter,
3083
+ s(:call, nil, :lambda),
3084
+ s(:args),
3085
+ s(:iter,
3086
+ s(:call, nil, :a,
3087
+ s(:lit, 1)), 0)))
3088
+
3089
+ assert_parse rb, pt
3090
+ end
3091
+
3092
+ def test_block_call_dot_op2_brace_block
3093
+ rb = "a.b c() do d end.e do |f| g end"
3094
+ pt = s(:iter,
3095
+ s(:call,
3096
+ s(:iter,
3097
+ s(:call, s(:call, nil, :a), :b, s(:call, nil, :c)),
3098
+ 0,
3099
+ s(:call, nil, :d)),
3100
+ :e),
3101
+ s(:args, :f),
3102
+ s(:call, nil, :g))
3103
+
3104
+
3105
+ assert_parse rb, pt
3106
+ end
3107
+
3108
+ def test_block_call_dot_op2_cmd_args_do_block
3109
+ rb = "a.b c() do d end.e f do |g| h end"
3110
+ pt = s(:iter,
3111
+ s(:call,
3112
+ s(:iter,
3113
+ s(:call, s(:call, nil, :a), :b, s(:call, nil, :c)),
3114
+ 0,
3115
+ s(:call, nil, :d)),
3116
+ :e,
3117
+ s(:call, nil, :f)),
3118
+ s(:args, :g),
3119
+ s(:call, nil, :h))
3120
+
3121
+ assert_parse rb, pt
3122
+ end
3123
+
3124
+ def test_defn_kwarg_val
3125
+ rb = "def f(a, b:1) end"
3126
+ pt = s(:defn, :f, s(:args, :a, s(:kwarg, :b, s(:lit, 1))), s(:nil))
3127
+
3128
+ assert_parse rb, pt
3129
+ end
3130
+
3131
+ def test_args_kw_block
3132
+ rb = "def f(a: 1, &b); end"
3133
+ pt = s(:defn, :f, s(:args, s(:kwarg, :a, s(:lit, 1)), :"&b"), s(:nil))
3134
+
3135
+ assert_parse rb, pt
3136
+ end
3137
+
3138
+ def test_defn_kwarg_kwarg
3139
+ rb = "def f(a, b: 1, c: 2) end"
3140
+ pt = s(:defn, :f, s(:args, :a,
3141
+ s(:kwarg, :b, s(:lit, 1)),
3142
+ s(:kwarg, :c, s(:lit, 2))),
3143
+ s(:nil))
3144
+
3145
+ assert_parse rb, pt
3146
+ end
3147
+
3148
+ def test_defn_kwarg_lvar
3149
+ rb = "def fun(kw: :val); kw; end"
3150
+ pt = s(:defn, :fun, s(:args, s(:kwarg, :kw, s(:lit, :val))), s(:lvar, :kw))
3151
+
3152
+ assert_parse rb, pt
3153
+ end
3154
+
3155
+ def test_defn_kwarg_no_parens
3156
+ rb = "def f a: 1\nend"
3157
+ pt = s(:defn, :f, s(:args, s(:kwarg, :a, s(:lit, 1))), s(:nil))
3158
+
3159
+ assert_parse rb, pt
3160
+ end
3161
+
3162
+ def test_defn_powarg
3163
+ rb = "def f(**opts) end"
3164
+ pt = s(:defn, :f, s(:args, :"**opts"), s(:nil))
3165
+
3166
+ assert_parse rb, pt
3167
+ end
3168
+
3169
+ def test_block_arg_kwsplat
3170
+ rb = "a { |**b| }"
3171
+ pt = s(:iter, s(:call, nil, :a), s(:args, :"**b"))
3172
+
3173
+ assert_parse rb, pt
3174
+ end
3175
+
3176
+ def test_symbols
3177
+ rb = "%i(a b c)"
3178
+ pt = s(:array, s(:lit, :a), s(:lit, :b), s(:lit, :c))
3179
+
3180
+ assert_parse rb, pt
3181
+ end
3182
+
3183
+ def test_symbols_interp
3184
+ rb = '%i(a b#{1+1} c)'
3185
+ pt = s(:array, s(:lit, :a), s(:lit, :'b#{1+1}'), s(:lit, :c))
3186
+
3187
+ assert_parse rb, pt
3188
+ end
3189
+
3190
+ def test_symbols_empty_space
3191
+ rb = "%i( )"
3192
+ pt = s(:array)
3193
+
3194
+ assert_parse rb, pt
3195
+ end
3196
+
3197
+ def test_symbols_empty
3198
+ rb = "%i()"
3199
+ pt = s(:array)
3200
+
3201
+ assert_parse rb, pt
3202
+ end
3203
+
3204
+ def test_qsymbols
3205
+ rb = "%I(a b c)"
3206
+ pt = s(:array, s(:lit, :a), s(:lit, :b), s(:lit, :c))
3207
+
3208
+ assert_parse rb, pt
3209
+ end
3210
+
3211
+ def test_qsymbols_interp
3212
+ rb = '%I(a b#{1+1} c)'
3213
+ pt = s(:array,
3214
+ s(:lit, :a),
3215
+ s(:dsym, "b", s(:evstr, s(:call, s(:lit, 1), :+, s(:lit, 1)))),
3216
+ s(:lit, :c))
3217
+
3218
+ assert_parse rb, pt
3219
+ end
3220
+
3221
+ def test_qsymbols_empty
3222
+ rb = "%I()"
3223
+ pt = s(:array)
3224
+
3225
+ assert_parse rb, pt
3226
+ end
3227
+
3228
+ def test_qsymbols_empty_space
3229
+ rb = "%I( )"
3230
+ pt = s(:array)
3231
+
3232
+ assert_parse rb, pt
3233
+ end
3234
+
3235
+ def test_iter_array_curly
3236
+ rb = "f :a, [:b] { |c, d| }" # yes, this is bad code... that's their problem
3237
+ pt = s(:iter,
3238
+ s(:call, nil, :f, s(:lit, :a), s(:array, s(:lit, :b))),
3239
+ s(:args, :c, :d))
3240
+
3241
+ assert_parse rb, pt
3242
+ end
3243
+
3244
+ def test_bug_249
3245
+ rb = "mount (Class.new do\ndef initialize\nend\n end).new, :at => 'endpoint'"
3246
+ pt = s(:call, nil, :mount,
3247
+ s(:call,
3248
+ s(:iter,
3249
+ s(:call, s(:const, :Class), :new),
3250
+ 0,
3251
+ s(:defn, :initialize, s(:args), s(:nil))),
3252
+ :new),
3253
+ s(:hash, s(:lit, :at), s(:str, "endpoint")))
3254
+
3255
+ assert_parse rb, pt
3256
+ end
3257
+ end
3258
+
3259
+ module TestRubyParserShared21Plus
3260
+ include TestRubyParserShared20Plus
3261
+
3262
+ def test_defn_unary_not
3263
+ rb = "def !@; true; end" # I seriously HATE this
3264
+ pt = s(:defn, :"!@", s(:args), s(:true))
3265
+
3266
+ assert_parse rb, pt
3267
+ end
3268
+
3269
+ def test_f_kw
3270
+ rb = "def x k:42; end"
3271
+ pt = s(:defn, :x, s(:args, s(:kwarg, :k, s(:lit, 42))), s(:nil))
3272
+
3273
+ assert_parse rb, pt
3274
+ end
3275
+
3276
+ def test_f_kw__required
3277
+ rb = "def x k:; end"
3278
+ pt = s(:defn, :x, s(:args, s(:kwarg, :k)), s(:nil))
3279
+
3280
+ assert_parse rb, pt
3281
+ end
3282
+
3283
+ def test_block_kw
3284
+ rb = "blah { |k:42| }"
3285
+ pt = s(:iter, s(:call, nil, :blah), s(:args, s(:kwarg, :k, s(:lit, 42))))
3286
+
3287
+ assert_parse rb, pt
3288
+
3289
+ rb = "blah { |k:42| }"
3290
+ assert_parse rb, pt
3291
+ end
3292
+
3293
+ def test_block_kw__required
3294
+ rb = "blah do |k:| end"
3295
+ pt = s(:iter, s(:call, nil, :blah), s(:args, s(:kwarg, :k)))
3296
+
3297
+ assert_parse rb, pt
3298
+
3299
+ rb = "blah do |k:| end"
3300
+ assert_parse rb, pt
3301
+ end
3302
+
3303
+ def test_stabby_block_kw
3304
+ rb = "-> (k:42) { }"
3305
+ pt = s(:iter, s(:call, nil, :lambda), s(:args, s(:kwarg, :k, s(:lit, 42))))
3306
+
3307
+ assert_parse rb, pt
3308
+ end
3309
+
3310
+ def test_stabby_block_kw__required
3311
+ rb = "-> (k:) { }"
3312
+ pt = s(:iter, s(:call, nil, :lambda), s(:args, s(:kwarg, :k)))
3313
+
3314
+ assert_parse rb, pt
3315
+ end
3316
+
3317
+ def test_parse_line_heredoc_hardnewline
3318
+ skip "not yet"
3319
+
3320
+ rb = <<-'CODE'.gsub(/^ /, '')
3321
+ <<-EOFOO
3322
+ \n\n\n\n\n\n\n\n\n
3323
+ EOFOO
3324
+
3325
+ class Foo
3326
+ end
3327
+ CODE
3328
+
3329
+ pt = s(:block,
3330
+ s(:str, "\n\n\n\n\n\n\n\n\n\n").line(1),
3331
+ s(:class, :Foo, nil).line(5)).line(1)
3332
+
3333
+ assert_parse rb, pt
3334
+ end
3335
+ end
3336
+
3337
+ module TestRubyParserShared22Plus
3338
+ include TestRubyParserShared21Plus
3339
+
3340
+ def test_call_args_assoc_quoted
3341
+ pt = s(:call, nil, :x, s(:hash, s(:lit, :k), s(:lit, 42)))
3342
+
3343
+ rb = "x 'k':42"
3344
+ assert_parse rb, pt
3345
+
3346
+ rb = 'x "k":42'
3347
+ assert_parse rb, pt
3348
+
3349
+ rb = 'x "#{k}":42'
3350
+ pt = s(:call, nil, :x, s(:hash, s(:dsym, "", s(:evstr, s(:call, nil, :k))), s(:lit, 42)))
3351
+
3352
+ assert_parse rb, pt
3353
+ end
3354
+
3355
+ def test_bug191
3356
+ pt = s(:if, s(:call, nil, :a), s(:str, ""), s(:call, nil, :b))
3357
+
3358
+ rb = "a ? '': b"
3359
+ assert_parse rb, pt
3360
+
3361
+ rb = "a ? \"\": b"
3362
+ assert_parse rb, pt
3363
+ end
3364
+
3365
+ def test_quoted_symbol_keys
3366
+ rb = "{ 'a': :b }"
3367
+ pt = s(:hash, s(:lit, :a), s(:lit, :b))
3368
+
3369
+ assert_parse rb, pt
3370
+ end
3371
+
3372
+ def test_quoted_symbol_hash_arg
3373
+ rb = "puts 'a': {}"
3374
+ pt = s(:call, nil, :puts, s(:hash, s(:lit, :a), s(:hash)))
3375
+
3376
+ assert_parse rb, pt
3377
+ end
3378
+ end
3379
+
3380
+ module TestRubyParserShared23Plus
3381
+ include TestRubyParserShared22Plus
3382
+
3383
+ def test_safe_call
3384
+ rb = "a&.b"
3385
+ pt = s(:safe_call, s(:call, nil, :a), :b)
3386
+
3387
+ assert_parse rb, pt
3388
+ end
3389
+
3390
+ def test_safe_call_newline
3391
+ rb = "a&.b\n"
3392
+ pt = s(:safe_call, s(:call, nil, :a), :b)
3393
+
3394
+ assert_parse rb, pt
3395
+ end
3396
+
3397
+ def test_safe_call_rhs_newline
3398
+ rb = "c = a&.b\n"
3399
+ pt = s(:lasgn, :c, s(:safe_call, s(:call, nil, :a), :b))
3400
+
3401
+ assert_parse rb, pt
3402
+ end
3403
+
3404
+ def test_safe_call_after_newline
3405
+ rb = "a\n&.b"
3406
+ pt = s(:safe_call, s(:call, nil, :a), :b)
3407
+
3408
+ assert_parse rb, pt
3409
+ end
3410
+
3411
+ def test_safe_calls
3412
+ rb = "a&.b&.c(1)"
3413
+ pt = s(:safe_call, s(:safe_call, s(:call, nil, :a), :b), :c, s(:lit, 1))
3414
+
3415
+ assert_parse rb, pt
3416
+ end
3417
+
3418
+ def test_safe_attrasgn
3419
+ rb = "a&.b = 1"
3420
+ pt = s(:safe_attrasgn, s(:call, nil, :a), :"b=", s(:lit, 1))
3421
+
3422
+ assert_parse rb, pt
3423
+ end
3424
+
3425
+ def test_safe_attrasgn_constant
3426
+ rb = "a&.B = 1"
3427
+ pt = s(:safe_attrasgn, s(:call, nil, :a), :"B=", s(:lit, 1))
3428
+
3429
+ assert_parse rb, pt
3430
+ end
3431
+
3432
+ def test_safe_call_dot_parens
3433
+ rb = "a&.()"
3434
+ pt = s(:safe_call, s(:call, nil, :a), :call)
3435
+
3436
+ assert_parse rb, pt
3437
+ end
3438
+
3439
+ def test_safe_call_operator
3440
+ rb = "a&.> 1"
3441
+ pt = s(:safe_call, s(:call, nil, :a), :>, s(:lit, 1)).line(1)
3442
+
3443
+ assert_parse rb, pt
3444
+ end
3445
+
3446
+ def test_safe_op_asgn
3447
+ rb = "a&.b += x 1\n"
3448
+ pt = s(:safe_op_asgn, s(:call, nil, :a), s(:call, nil, :x, s(:lit, 1)), :b, :+).line(1)
3449
+
3450
+ assert_parse rb, pt
3451
+ end
3452
+
3453
+ def test_safe_op_asgn2
3454
+ rb = "a&.b ||=\nx;"
3455
+ pt = s(:safe_op_asgn2, s(:call, nil, :a), :b=, :"||", s(:call, nil, :x)).line(1)
3456
+
3457
+ assert_parse rb, pt
3458
+ end
3459
+
3460
+ def test_ruby21_numbers
3461
+ rb = "[1i, 2r, 3ri]"
3462
+ pt = s(:array, s(:lit, Complex(0, 1)), s(:lit, Rational(2)), s(:lit, Complex(0, Rational(3))))
3463
+
3464
+ assert_parse rb, pt
3465
+ end
3466
+
3467
+ def test_float_with_if_modifier
3468
+ rb = "1.0if true"
3469
+ pt = s(:if, s(:true), s(:lit, 1.0), nil)
3470
+
3471
+ assert_parse rb, pt
3472
+ end
3473
+
3474
+ def test_integer_with_if_modifier
3475
+ rb = "1_234if true"
3476
+ pt = s(:if, s(:true), s(:lit, 1234), nil)
3477
+
3478
+ assert_parse rb, pt
3479
+ end
3480
+
3481
+ def test_heredoc_squiggly
3482
+ rb = "a = <<~\"EOF\"\n blah blah\n EOF\n\n"
3483
+ pt = s(:lasgn, :a, s(:str, "blah blah\n"))
3484
+
3485
+ assert_parse rb, pt
3486
+ end
3487
+
3488
+ def test_required_kwarg_no_value
3489
+ rb = "def x a:, b:\nend"
3490
+ pt = s(:defn, :x,
3491
+ s(:args,
3492
+ s(:kwarg, :a),
3493
+ s(:kwarg, :b)),
3494
+ s(:nil))
3495
+
3496
+ assert_parse rb, pt
3497
+ end
3498
+
3499
+ def test_slashy_newlines_within_string
3500
+ rb = %(puts "hello\\
3501
+ my\\
3502
+ dear\\
3503
+ friend"
3504
+
3505
+ a + b
3506
+ )
3507
+
3508
+ pt = s(:block,
3509
+ s(:call, nil, :puts, s(:str, "hello my dear friend").line(1)).line(1),
3510
+ s(:call, s(:call, nil, :a).line(6),
3511
+ :+,
3512
+ s(:call, nil, :b).line(6)).line(6)
3513
+ ).line(1)
3514
+
3515
+ assert_parse rb, pt
3516
+ end
3517
+ end
3518
+
3519
+ module TestRubyParserShared24Plus
3520
+ include TestRubyParserShared23Plus
3521
+
3522
+ # ...version specific tests to go here...
3523
+ end
3524
+
3525
+ module TestRubyParserShared25Plus
3526
+ include TestRubyParserShared24Plus
3527
+
3528
+ # ...version specific tests to go here...
3529
+ end
3530
+
3531
+ module TestRubyParserShared26Plus
3532
+ include TestRubyParserShared25Plus
3533
+
3534
+ def test_symbol_list
3535
+ rb = '%I[#{a} #{b}]'
3536
+ pt = s(:array,
3537
+ s(:dsym, "", s(:evstr, s(:call, nil, :a))),
3538
+ s(:dsym, "", s(:evstr, s(:call, nil, :b))))
3539
+
3540
+ assert_parse rb, pt
3541
+ end
3542
+
3543
+ def test_dot2_nil__26
3544
+ rb = "a.."
3545
+ pt = s(:dot2, s(:call, nil, :a), nil)
3546
+
3547
+ assert_parse rb, pt
3548
+ end
3549
+
3550
+ def test_dot3_nil__26
3551
+ rb = "a..."
3552
+ pt = s(:dot3, s(:call, nil, :a), nil)
3553
+
3554
+ assert_parse rb, pt
3555
+ end
3556
+ end
3557
+
3558
+ class TestRubyParser < Minitest::Test
3559
+ def test_cls_version
3560
+ assert_equal 18, RubyParser::V18.version
3561
+ assert_equal 23, RubyParser::V23.version
3562
+ assert_equal 24, RubyParser::V24.version
3563
+ assert_equal 24, Ruby24Parser.version
3564
+ refute RubyParser::Parser.version
3565
+ end
3566
+
3567
+ def test_parse
3568
+ processor = RubyParser.new
3569
+
3570
+ # 1.8 only syntax
3571
+ rb = "while false : 42 end"
3572
+ pt = s(:while, s(:false), s(:lit, 42), true)
3573
+
3574
+ assert_silent do
3575
+ assert_equal pt, processor.parse(rb)
3576
+ end
3577
+
3578
+ # 1.9 only syntax
3579
+ rb = "a.()"
3580
+ pt = s(:call, s(:call, nil, :a), :call)
3581
+
3582
+ assert_equal pt, processor.parse(rb)
3583
+
3584
+ # bad syntax
3585
+ e = assert_raises Racc::ParseError do
3586
+ capture_io do
3587
+ processor.parse "a.("
3588
+ end
3589
+ end
3590
+
3591
+ assert_includes e.message, 'parse error on value "$end"'
3592
+ end
3593
+
3594
+ def test_parse_error_from_first
3595
+ processor = RubyParser.new
3596
+
3597
+ e = assert_raises Racc::ParseError do
3598
+ capture_io do
3599
+ processor.parse "a -> () {"
3600
+ end
3601
+ end
3602
+
3603
+ # This is a 2.x error, will fail on 1.8/1.9.
3604
+ assert_includes e.message, 'parse error on value "$end"'
3605
+ end
3606
+ end
3607
+
3608
+ class RubyParserTestCase < ParseTreeTestCase
3609
+ attr_accessor :result, :processor
3610
+
3611
+ make_my_diffs_pretty!
3612
+
3613
+ def self.previous key
3614
+ "Ruby"
3615
+ end
3616
+
3617
+ def self.generate_test klass, node, data, input_name, output_name
3618
+ return if node.to_s =~ /bmethod|dmethod/
3619
+ return if Array === data['Ruby']
3620
+
3621
+ output_name = "ParseTree"
3622
+
3623
+ super
3624
+ end
3625
+
3626
+ def assert_parse rb, pt
3627
+ self.result = processor.parse rb
3628
+ assert_equal pt, result
3629
+ end
3630
+
3631
+ def refute_parse rb
3632
+ self.result = processor.parse rb
3633
+ assert_nil result
3634
+ end
3635
+
3636
+ def assert_syntax_error rb, emsg
3637
+ e = nil
3638
+ assert_silent do
3639
+ e = assert_raises RubyParser::SyntaxError do
3640
+ processor.parse rb
3641
+ end
3642
+ end
3643
+
3644
+ assert_equal emsg, e.message
3645
+ end
3646
+
3647
+ def assert_parse_error rb, emsg
3648
+ e = nil
3649
+ assert_silent do
3650
+ e = assert_raises Racc::ParseError do
3651
+ processor.parse rb
3652
+ end
3653
+ end
3654
+
3655
+ assert_equal emsg, e.message
3656
+ end
3657
+
3658
+ def assert_parse_line rb, pt, line
3659
+ old_env = ENV["VERBOSE"]
3660
+ ENV["VERBOSE"] = "1"
3661
+
3662
+ assert_parse rb, pt
3663
+ assert_equal line, result.line, "call should have line number"
3664
+ ensure
3665
+ ENV["VERBOSE"] = old_env
3666
+ end
3667
+ end
3668
+
3669
+ class TestRubyParserV18 < RubyParserTestCase
3670
+ include TestRubyParserShared
3671
+
3672
+ def setup
3673
+ super
3674
+
3675
+ self.processor = RubyParser::V18.new
3676
+ end
3677
+
3678
+ def test_assoc_list_18
3679
+ rb = "{1, 2, 3, 4}"
3680
+ pt = s(:hash, s(:lit, 1), s(:lit, 2), s(:lit, 3), s(:lit, 4))
3681
+
3682
+ assert_parse rb, pt
3683
+ end
3684
+
3685
+ def test_case_then_colon_18
3686
+ rb = "case x; when Fixnum: 42; end"
3687
+ pt = s(:case,
3688
+ s(:call, nil, :x),
3689
+ s(:when, s(:array, s(:const, :Fixnum)), s(:lit, 42)),
3690
+ nil)
3691
+
3692
+ assert_parse rb, pt
3693
+ end
3694
+
3695
+ def test_do_colon_18
3696
+ rb = "while false : 42 end"
3697
+ pt = s(:while, s(:false), s(:lit, 42), true)
3698
+
3699
+ assert_parse rb, pt
3700
+ end
3701
+
3702
+ def test_call_space_before_paren_args_18
3703
+ rb = "a (:b, :c, :d => :e)"
3704
+ pt = s(:call, nil, :a,
3705
+ s(:lit, :b),
3706
+ s(:lit, :c),
3707
+ s(:hash, s(:lit, :d), s(:lit, :e)))
3708
+
3709
+ assert_parse rb, pt
3710
+ end
3711
+
3712
+ # In 1.8, block args with an outer set of parens are superfluous.
3713
+ # In 1.9, outer set of parens are NOT... they are an explicit extra masgn.
3714
+
3715
+ def test_iter_args_2_18
3716
+ rb = "f { |(a, b)| }"
3717
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, :b))
3718
+
3719
+ assert_parse rb, pt
3720
+ end
3721
+
3722
+ def test_bug_args__18
3723
+ rb = "f { |(a, b)| }"
3724
+ pt = s(:iter, s(:call, nil, :f),
3725
+ s(:args, :a, :b))
3726
+
3727
+ assert_parse rb, pt
3728
+ end
3729
+
3730
+ def test_bug_args_masgn_outer_parens__18
3731
+ rb = "f { |((a, b), c)| }"
3732
+ pt = s(:iter, # NOTE: same sexp as test_bug_args_masgn
3733
+ s(:call, nil, :f),
3734
+ s(:args, s(:masgn, :a, :b), :c))
3735
+
3736
+ assert_parse rb, pt.dup
3737
+ end
3738
+
3739
+ def test_double_block_error_10
3740
+ assert_syntax_error "a.b (&b) {}", BLOCK_DUP_MSG
3741
+ end
3742
+
3743
+ def test_double_block_error_11
3744
+ assert_syntax_error "a (1, &b) { }", BLOCK_DUP_MSG
3745
+ end
3746
+
3747
+ def test_double_block_error_12
3748
+ assert_syntax_error "a (1, &b) do end", BLOCK_DUP_MSG
3749
+ end
3750
+
3751
+ def test_double_block_error_13
3752
+ assert_syntax_error "m.a (1, &b) { }", BLOCK_DUP_MSG
3753
+ end
3754
+
3755
+ def test_double_block_error_14
3756
+ assert_syntax_error "m.a (1, &b) do end", BLOCK_DUP_MSG
3757
+ end
3758
+
3759
+ def test_double_block_error_15
3760
+ assert_syntax_error "m::a (1, &b) { }", BLOCK_DUP_MSG
3761
+ end
3762
+
3763
+ def test_double_block_error_16
3764
+ assert_syntax_error "m::a (1, &b) do end", BLOCK_DUP_MSG
3765
+ end
3766
+ end
3767
+
3768
+ class TestRubyParserV19 < RubyParserTestCase
3769
+ include TestRubyParserShared19Plus
3770
+
3771
+ def setup
3772
+ super
3773
+
3774
+ self.processor = RubyParser::V19.new
3775
+ end
3776
+ end
3777
+
3778
+ class TestRubyParserV20 < RubyParserTestCase
3779
+ include TestRubyParserShared20Plus
3780
+
3781
+ def setup
3782
+ super
3783
+
3784
+ self.processor = RubyParser::V20.new
3785
+ end
3786
+ end
3787
+
3788
+ class TestRubyParserV21 < RubyParserTestCase
3789
+ include TestRubyParserShared21Plus
3790
+
3791
+ def setup
3792
+ super
3793
+
3794
+ self.processor = RubyParser::V21.new
3795
+ end
3796
+ end
3797
+
3798
+ class TestRubyParserV22 < RubyParserTestCase
3799
+ include TestRubyParserShared22Plus
3800
+
3801
+ def setup
3802
+ super
3803
+
3804
+ self.processor = RubyParser::V22.new
3805
+ end
3806
+ end
3807
+
3808
+ class TestRubyParserV23 < RubyParserTestCase
3809
+ include TestRubyParserShared23Plus
3810
+
3811
+ def setup
3812
+ super
3813
+
3814
+ self.processor = RubyParser::V23.new
3815
+ end
3816
+ end
3817
+
3818
+ class TestRubyParserV24 < RubyParserTestCase
3819
+ include TestRubyParserShared24Plus
3820
+
3821
+ def setup
3822
+ super
3823
+
3824
+ self.processor = RubyParser::V24.new
3825
+ end
3826
+ end
3827
+
3828
+ class TestRubyParserV25 < RubyParserTestCase
3829
+ include TestRubyParserShared25Plus
3830
+
3831
+ def setup
3832
+ super
3833
+
3834
+ self.processor = RubyParser::V25.new
3835
+ end
3836
+
3837
+ def test_rescue_in_block
3838
+ rb = "blah do\nrescue\n stuff\nend"
3839
+ pt = s(:iter,
3840
+ s(:call, nil, :blah),
3841
+ 0,
3842
+ s(:rescue, s(:resbody, s(:array), s(:call, nil, :stuff))))
3843
+ assert_parse rb, pt
3844
+ end
3845
+
3846
+ def test_rescue_do_end_raised
3847
+ rb = "tap do\n raise\nensure\n :ensure\nend"
3848
+ pt = s(:iter,
3849
+ s(:call, nil, :tap),
3850
+ 0,
3851
+ s(:ensure,
3852
+ s(:call, nil, :raise),
3853
+ s(:lit, :ensure)))
3854
+
3855
+ assert_parse rb, pt
3856
+ end
3857
+
3858
+ def test_rescue_do_end_rescued
3859
+ rb = "tap do\n raise\nrescue\n :rescue\nelse\n :else\nensure\n :ensure\nend"
3860
+ pt = s(:iter,
3861
+ s(:call, nil, :tap),
3862
+ 0,
3863
+ s(:ensure,
3864
+ s(:rescue,
3865
+ s(:call, nil, :raise),
3866
+ s(:resbody,
3867
+ s(:array),
3868
+ s(:lit, :rescue)),
3869
+ s(:lit, :else)),
3870
+ s(:lit, :ensure)))
3871
+
3872
+ assert_parse rb, pt
3873
+ end
3874
+
3875
+ def test_rescue_do_end_no_raise
3876
+ rb = "tap do\n :begin\nrescue\n :rescue\nelse\n :else\nensure\n :ensure\nend"
3877
+ pt = s(:iter,
3878
+ s(:call, nil, :tap),
3879
+ 0,
3880
+ s(:ensure,
3881
+ s(:rescue,
3882
+ s(:lit, :begin),
3883
+ s(:resbody,
3884
+ s(:array),
3885
+ s(:lit, :rescue)),
3886
+ s(:lit, :else)),
3887
+ s(:lit, :ensure)))
3888
+
3889
+ assert_parse rb, pt
3890
+ end
3891
+
3892
+ def test_rescue_do_end_ensure_result
3893
+ rb = "proc do\n :begin\nensure\n :ensure\nend.call"
3894
+ pt = s(:call,
3895
+ s(:iter,
3896
+ s(:call, nil, :proc),
3897
+ 0,
3898
+ s(:ensure,
3899
+ s(:lit, :begin),
3900
+ s(:lit, :ensure))),
3901
+ :call)
3902
+
3903
+ assert_parse rb, pt
3904
+ end
3905
+ end
3906
+
3907
+ class TestRubyParserV26 < RubyParserTestCase
3908
+ include TestRubyParserShared26Plus
3909
+
3910
+ def setup
3911
+ super
3912
+
3913
+ self.processor = RubyParser::V26.new
3914
+ end
3915
+ end
3916
+
3917
+ RubyParser::VERSIONS.each do |klass|
3918
+ v = klass.version
3919
+ describe "block args arity #{v}" do
3920
+ attr_accessor :parser
3921
+
3922
+ before do
3923
+ self.parser = RubyParser.const_get("V#{v}").new
3924
+ end
3925
+
3926
+ {
3927
+ "-> { }" => s(:iter, s(:call, nil, :lambda), 0),
3928
+ "lambda { }" => s(:iter, s(:call, nil, :lambda), 0),
3929
+ "proc { }" => s(:iter, s(:call, nil, :proc), 0),
3930
+ "Proc.new { }" => s(:iter, s(:call, s(:const, :Proc), :new), 0),
3931
+
3932
+ "-> () { }" => s(:iter, s(:call, nil, :lambda), s(:args)),
3933
+ "lambda { || }" => s(:iter, s(:call, nil, :lambda), s(:args)),
3934
+ "proc { || }" => s(:iter, s(:call, nil, :proc), s(:args)),
3935
+ "Proc.new { || }" => s(:iter, s(:call, s(:const, :Proc), :new), s(:args)),
3936
+
3937
+ }.each do |input, expected|
3938
+ next if v == 18 and input =~ /->/
3939
+ next if v == 19 and input =~ /-> \(\)/
3940
+
3941
+ it "parses '#{input}'" do
3942
+ assert_equal expected, parser.parse(input)
3943
+ end
3944
+
3945
+ input = input.sub(/\{/, "do").sub(/\}/, "end")
3946
+ it "parses '#{input}'" do
3947
+ assert_equal expected, parser.parse(input)
3948
+ end
3949
+ end
3950
+ end
3951
+ end