ruby_parser-legacy 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

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