parser 0.9.alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1772 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ # ENV['VERBOSE'] = "1"
5
+
6
+ require 'minitest/autorun'
7
+ require 'ruby_parser'
8
+
9
+ $: << File.expand_path('~/Work/p4/zss/src/sexp_processor/dev/lib')
10
+
11
+ require 'pt_testcase'
12
+
13
+ class Sexp
14
+ alias oldeq2 ==
15
+ def ==(obj) # :nodoc:
16
+ if obj.class == self.class then
17
+ super and
18
+ (self.line.nil? or obj.line.nil? or self.line == obj.line)
19
+ else
20
+ false
21
+ end
22
+ end
23
+ end
24
+
25
+ class RubyParserTestCase < ParseTreeTestCase
26
+ attr_accessor :result, :processor
27
+
28
+ make_my_diffs_pretty!
29
+
30
+ def self.previous key
31
+ "Ruby"
32
+ end
33
+
34
+ def self.generate_test klass, node, data, input_name, output_name
35
+ return if node.to_s =~ /bmethod|dmethod/
36
+ return if Array === data['Ruby']
37
+
38
+ output_name = "ParseTree"
39
+
40
+ super
41
+ end
42
+
43
+ def assert_parse rb, pt
44
+ self.result = processor.parse rb
45
+ assert_equal pt, result
46
+ end
47
+
48
+ def assert_syntax_error rb, emsg
49
+ e = nil
50
+ assert_silent do
51
+ e = assert_raises RubyParser::SyntaxError do
52
+ processor.parse rb
53
+ end
54
+ end
55
+
56
+ assert_equal emsg, e.message
57
+ end
58
+
59
+ def assert_parse_error rb, emsg
60
+ e = nil
61
+ assert_silent do
62
+ e = assert_raises Racc::ParseError do
63
+ processor.parse rb
64
+ end
65
+ end
66
+
67
+ assert_equal emsg, e.message
68
+ end
69
+
70
+ def assert_parse_line rb, pt, line
71
+ assert_parse rb, pt
72
+ assert_equal line, result.line, "call should have line number"
73
+ end
74
+ end
75
+
76
+ module TestRubyParserShared
77
+ def setup
78
+ super
79
+ # p :test => [self.class, __name__]
80
+ end
81
+
82
+ BLOCK_DUP_MSG = "Both block arg and actual block given."
83
+
84
+ def test_double_block_error_01
85
+ assert_syntax_error "a(1, &b) { }", BLOCK_DUP_MSG
86
+ end
87
+
88
+ def test_double_block_error_02
89
+ assert_syntax_error "a(1, &b) do end", BLOCK_DUP_MSG
90
+ end
91
+
92
+ def test_double_block_error_03
93
+ assert_syntax_error "a 1, &b do end", BLOCK_DUP_MSG
94
+ end
95
+
96
+ def test_double_block_error_04
97
+ assert_syntax_error "m.a(1, &b) { }", BLOCK_DUP_MSG
98
+ end
99
+
100
+ def test_double_block_error_05
101
+ assert_syntax_error "m.a(1, &b) do end", BLOCK_DUP_MSG
102
+ end
103
+
104
+ def test_double_block_error_06
105
+ assert_syntax_error "m.a 1, &b do end", BLOCK_DUP_MSG
106
+ end
107
+
108
+ def test_double_block_error_07
109
+ assert_syntax_error "m::a(1, &b) { }", BLOCK_DUP_MSG
110
+ end
111
+
112
+ def test_double_block_error_08
113
+ assert_syntax_error "m::a(1, &b) do end", BLOCK_DUP_MSG
114
+ end
115
+
116
+ def test_double_block_error_09
117
+ assert_syntax_error "m::a 1, &b do end", BLOCK_DUP_MSG
118
+ end
119
+
120
+ def test_wtf_7
121
+ rb = "a.b (1) {c}"
122
+ pt = s(:iter,
123
+ s(:call, s(:call, nil, :a), :b, s(:lit, 1)),
124
+ s(:args),
125
+ s(:call, nil, :c))
126
+
127
+ assert_parse rb, pt
128
+ end
129
+
130
+ def test_wtf_8
131
+ rb = "a::b (1) {c}"
132
+ pt = s(:iter,
133
+ s(:call, s(:call, nil, :a), :b, s(:lit, 1)),
134
+ s(:args),
135
+ s(:call, nil, :c))
136
+
137
+ assert_parse rb, pt
138
+ end
139
+
140
+ def test_attrasgn_array_lhs
141
+ rb = '[1, 2, 3, 4][from .. to] = ["a", "b", "c"]'
142
+ pt = s(:attrasgn,
143
+ s(:array, s(:lit, 1), s(:lit, 2), s(:lit, 3), s(:lit, 4)),
144
+ :[]=,
145
+ s(:dot2,
146
+ s(:call, nil, :from),
147
+ s(:call, nil, :to)),
148
+ s(:array, s(:str, "a"), s(:str, "b"), s(:str, "c")))
149
+
150
+ assert_parse rb, pt
151
+ end
152
+
153
+ def test_block_append
154
+ head = s(:args)
155
+ tail = s(:zsuper)
156
+ expected = s(:block, s(:args), s(:zsuper))
157
+ assert_equal expected, processor.block_append(head, tail)
158
+ end
159
+
160
+ def test_block_append_begin_begin
161
+ head = s(:begin, s(:args))
162
+ tail = s(:begin, s(:args))
163
+ expected = s(:block, s(:args), s(:begin, s(:args)))
164
+ assert_equal expected, processor.block_append(head, tail)
165
+ end
166
+
167
+ def test_block_append_block
168
+ head = s(:block, s(:args))
169
+ tail = s(:zsuper)
170
+ expected = s(:block, s(:args), s(:zsuper))
171
+ assert_equal expected, processor.block_append(head, tail)
172
+ end
173
+
174
+ def test_block_append_nil_head
175
+ head = nil
176
+ tail = s(:zsuper)
177
+ expected = s(:zsuper)
178
+ assert_equal expected, processor.block_append(head, tail)
179
+ end
180
+
181
+ def test_block_append_nil_tail
182
+ head = s(:args)
183
+ tail = nil
184
+ expected = s(:args)
185
+ assert_equal expected, processor.block_append(head, tail)
186
+ end
187
+
188
+ def test_block_append_tail_block
189
+ head = s(:call, nil, :f1)
190
+ tail = s(:block, s(:undef, s(:lit, :x)), s(:undef, s(:lit, :y)))
191
+ expected = s(:block,
192
+ s(:call, nil, :f1),
193
+ s(:block, s(:undef, s(:lit, :x)), s(:undef, s(:lit, :y))))
194
+ assert_equal expected, processor.block_append(head, tail)
195
+ end
196
+
197
+ def test_call_array_arg
198
+ rb = "1 == [:b, :c]"
199
+ pt = s(:call, s(:lit, 1), :==, s(:array, s(:lit, :b), s(:lit, :c)))
200
+
201
+ assert_parse rb, pt
202
+ end
203
+
204
+ def test_call_env
205
+ processor.env[:a] = :lvar
206
+ rb = "a.happy"
207
+ pt = s(:call, s(:lvar, :a), :happy)
208
+
209
+ assert_parse rb, pt
210
+ end
211
+
212
+ def test_dasgn_icky2
213
+ rb = "a do\n v = nil\n begin\n yield\n rescue Exception => v\n break\n end\nend"
214
+ pt = s(:iter,
215
+ s(:call, nil, :a),
216
+ s(:args),
217
+ s(:block,
218
+ s(:lasgn, :v, s(:nil)),
219
+ s(:rescue,
220
+ s(:yield),
221
+ s(:resbody,
222
+ s(:array, s(:const, :Exception), s(:lasgn, :v, s(:gvar, :$!))),
223
+ s(:break)))))
224
+
225
+ assert_parse rb, pt
226
+ end
227
+
228
+ def test_class_comments
229
+ rb = "# blah 1\n# blah 2\n\nclass X\n # blah 3\n def blah\n # blah 4\n end\nend"
230
+ pt = s(:class, :X, nil,
231
+ s(:defn, :blah, s(:args), s(:nil)))
232
+
233
+ assert_parse rb, pt
234
+
235
+ assert_equal "# blah 1\n# blah 2\n", result.comments
236
+ assert_equal "# blah 3\n", result.defn.comments
237
+ end
238
+
239
+ def test_module_comments
240
+ rb = "# blah 1\n \n # blah 2\n\nmodule X\n # blah 3\n def blah\n # blah 4\n end\nend"
241
+ pt = s(:module, :X,
242
+ s(:defn, :blah, s(:args), s(:nil)))
243
+
244
+ assert_parse rb, pt
245
+ assert_equal "# blah 1\n# blah 2\n", result.comments
246
+ assert_equal "# blah 3\n", result.defn.comments
247
+ end
248
+
249
+ def test_defn_comments
250
+ rb = "# blah 1\n# blah 2\n\ndef blah\nend"
251
+ pt = s(:defn, :blah, s(:args), s(:nil))
252
+
253
+ assert_parse rb, pt
254
+ assert_equal "# blah 1\n# blah 2\n", result.comments
255
+ end
256
+
257
+ def test_defs_comments
258
+ rb = "# blah 1\n# blah 2\n\ndef self.blah\nend"
259
+ pt = s(:defs, s(:self), :blah, s(:args))
260
+
261
+ assert_parse rb, pt
262
+ assert_equal "# blah 1\n# blah 2\n", result.comments
263
+ end
264
+
265
+ def test_do_bug # TODO: rename
266
+ rb = "a 1\na.b do |c|\n # do nothing\nend"
267
+ pt = s(:block,
268
+ s(:call, nil, :a, s(:lit, 1)),
269
+ s(:iter,
270
+ s(:call, s(:call, nil, :a), :b),
271
+ s(:args, :c)))
272
+
273
+ assert_parse rb, pt
274
+ end
275
+
276
+ def test_bug_comment_eq_begin
277
+ rb = "\n\n#\n=begin\nblah\n=end\n\n"
278
+ pt = nil
279
+ exp = rb.strip + "\n"
280
+
281
+ assert_parse rb, pt
282
+ assert_equal exp, processor.lexer.comments
283
+ end
284
+
285
+ def test_bug_call_arglist_parens
286
+ rb = 'g ( 1), 2'
287
+ pt = s(:call, nil, :g, s(:lit, 1), s(:lit, 2))
288
+
289
+ assert_parse rb, pt
290
+
291
+ rb = <<-CODE
292
+ def f
293
+ g ( 1), 2
294
+ end
295
+ CODE
296
+
297
+ pt = s(:defn, :f, s(:args),
298
+ s(:call, nil, :g, s(:lit, 1), s(:lit, 2)))
299
+
300
+ assert_parse rb, pt
301
+
302
+ rb = <<-CODE
303
+ def f()
304
+ g (1), 2
305
+ end
306
+ CODE
307
+
308
+ assert_parse rb, pt
309
+ end
310
+
311
+ def test_dstr_evstr
312
+ rb = "\"#\{'a'}#\{b}\""
313
+ pt = s(:dstr, "a", s(:evstr, s(:call, nil, :b)))
314
+
315
+ assert_parse rb, pt
316
+ end
317
+
318
+ def test_dstr_str
319
+ rb = "\"#\{'a'} b\""
320
+ pt = s(:str, "a b")
321
+
322
+ assert_parse rb, pt
323
+ end
324
+
325
+ def test_empty
326
+ rb = ""
327
+ pt = nil
328
+
329
+ assert_parse rb, pt
330
+ end
331
+
332
+ def test_evstr_evstr
333
+ rb = "\"#\{a}#\{b}\""
334
+ pt = s(:dstr, "", s(:evstr, s(:call, nil, :a)), s(:evstr, s(:call, nil, :b)))
335
+
336
+ assert_parse rb, pt
337
+ end
338
+
339
+ def test_evstr_str
340
+ rb = "\"#\{a} b\""
341
+ pt = s(:dstr, "", s(:evstr, s(:call, nil, :a)), s(:str, " b"))
342
+
343
+ assert_parse rb, pt
344
+ end
345
+
346
+ def test_lasgn_env
347
+ rb = 'a = 42'
348
+ pt = s(:lasgn, :a, s(:lit, 42))
349
+ expected_env = { :a => :lvar }
350
+
351
+ assert_parse rb, pt
352
+ assert_equal expected_env, processor.env.all
353
+ end
354
+
355
+ def test_list_append
356
+ a = s(:lit, 1)
357
+ b = s(:lit, 2)
358
+ c = s(:lit, 3)
359
+
360
+ result = processor.list_append(s(:array, b.dup), c.dup)
361
+
362
+ assert_equal s(:array, b, c), result
363
+
364
+ result = processor.list_append(b.dup, c.dup)
365
+
366
+ assert_equal s(:array, b, c), result
367
+
368
+ result = processor.list_append(result, a.dup)
369
+
370
+ assert_equal s(:array, b, c, a), result
371
+
372
+ lhs, rhs = s(:array, s(:lit, :iter)), s(:when, s(:const, :BRANCHING), nil)
373
+ expected = s(:array, s(:lit, :iter), s(:when, s(:const, :BRANCHING), nil))
374
+
375
+ assert_equal expected, processor.list_append(lhs, rhs)
376
+ end
377
+
378
+ def test_list_prepend
379
+ a = s(:lit, 1)
380
+ b = s(:lit, 2)
381
+ c = s(:lit, 3)
382
+
383
+ result = processor.list_prepend(b.dup, s(:array, c.dup))
384
+
385
+ assert_equal s(:array, b, c), result
386
+
387
+ result = processor.list_prepend(b.dup, c.dup)
388
+
389
+ assert_equal s(:array, b, c), result
390
+
391
+ result = processor.list_prepend(a.dup, result)
392
+
393
+ assert_equal s(:array, a, b, c), result
394
+ end
395
+
396
+ def test_literal_concat_dstr_dstr
397
+ lhs = s(:dstr, "Failed to download spec ",
398
+ s(:evstr, s(:call, nil, :spec_name)),
399
+ s(:str, " from "),
400
+ s(:evstr, s(:call, nil, :source_uri)),
401
+ s(:str, ":\n"))
402
+ rhs = s(:dstr, "\t",
403
+ s(:evstr, s(:call, s(:ivar, :@fetch_error), :message)))
404
+ expected = s(:dstr, "Failed to download spec ",
405
+ s(:evstr, s(:call, nil, :spec_name)),
406
+ s(:str, " from "),
407
+ s(:evstr, s(:call, nil, :source_uri)),
408
+ s(:str, ":\n"),
409
+ s(:str, "\t"),
410
+ s(:evstr, s(:call, s(:ivar, :@fetch_error), :message)))
411
+
412
+ assert_equal expected, processor.literal_concat(lhs, rhs)
413
+ end
414
+
415
+ def test_literal_concat_dstr_evstr
416
+ lhs, rhs = s(:dstr, "a"), s(:evstr, s(:call, nil, :b))
417
+ expected = s(:dstr, "a", s(:evstr, s(:call, nil, :b)))
418
+
419
+ assert_equal expected, processor.literal_concat(lhs, rhs)
420
+ end
421
+
422
+ def test_literal_concat_evstr_evstr
423
+ lhs, rhs = s(:evstr, s(:lit, 1)), s(:evstr, s(:lit, 2))
424
+ expected = s(:dstr, "", s(:evstr, s(:lit, 1)), s(:evstr, s(:lit, 2)))
425
+
426
+ assert_equal expected, processor.literal_concat(lhs, rhs)
427
+ end
428
+
429
+ def test_literal_concat_str_evstr
430
+ lhs, rhs = s(:str, ""), s(:evstr, s(:str, "blah"))
431
+
432
+ assert_equal s(:str, "blah"), processor.literal_concat(lhs, rhs)
433
+ end
434
+
435
+ def test_logop_12
436
+ lhs = s(:lit, 1)
437
+ rhs = s(:lit, 2)
438
+ exp = s(:and, s(:lit, 1), s(:lit, 2))
439
+
440
+ assert_equal exp, processor.logop(:and, lhs, rhs)
441
+ end
442
+
443
+ def test_logop_1234_5
444
+ lhs = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:and, s(:lit, 3), s(:lit, 4))))
445
+ rhs = s(:lit, 5)
446
+ exp = s(:and,
447
+ s(:lit, 1),
448
+ s(:and,
449
+ s(:lit, 2),
450
+ s(:and,
451
+ s(:lit, 3),
452
+ s(:and,
453
+ s(:lit, 4),
454
+ s(:lit, 5)))))
455
+
456
+ assert_equal exp, processor.logop(:and, lhs, rhs)
457
+ end
458
+
459
+ def test_logop_123_4
460
+ lhs = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:lit, 3)))
461
+ rhs = s(:lit, 4)
462
+ exp = s(:and,
463
+ s(:lit, 1),
464
+ s(:and,
465
+ s(:lit, 2),
466
+ s(:and,
467
+ s(:lit, 3),
468
+ s(:lit, 4))))
469
+
470
+ assert_equal exp, processor.logop(:and, lhs, rhs)
471
+ end
472
+
473
+ def test_logop_12_3
474
+ lhs = s(:and, s(:lit, 1), s(:lit, 2))
475
+ rhs = s(:lit, 3)
476
+ exp = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:lit, 3)))
477
+
478
+ assert_equal exp, processor.logop(:and, lhs, rhs)
479
+ end
480
+
481
+ def test_logop_nested_mix
482
+ lhs = s(:or, s(:call, nil, :a), s(:call, nil, :b))
483
+ rhs = s(:and, s(:call, nil, :c), s(:call, nil, :d))
484
+ exp = s(:or,
485
+ s(:or, s(:call, nil, :a), s(:call, nil, :b)),
486
+ s(:and, s(:call, nil, :c), s(:call, nil, :d)))
487
+
488
+ lhs.paren = true
489
+ rhs.paren = true
490
+
491
+ assert_equal exp, processor.logop(:or, lhs, rhs)
492
+ end
493
+
494
+ def test_str_evstr
495
+ rb = "\"a #\{b}\""
496
+ pt = s(:dstr, "a ", s(:evstr, s(:call, nil, :b)))
497
+
498
+ assert_parse rb, pt
499
+ end
500
+
501
+ def test_dsym_to_sym
502
+ pt = s(:alias, s(:lit, :<<), s(:lit, :>>))
503
+
504
+ rb = 'alias :<< :>>'
505
+ assert_parse rb, pt
506
+
507
+ rb = 'alias :"<<" :">>"'
508
+ assert_parse rb, pt
509
+ end
510
+
511
+ def test_regexp
512
+ regexps = {
513
+ "/wtf/" => /wtf/,
514
+ "/wtf/n" => /wtf/n,
515
+ "/wtf/m" => /wtf/m,
516
+ "/wtf/nm" => /wtf/nm,
517
+ "/wtf/nmnmnmnm" => /wtf/nm,
518
+ }
519
+
520
+ regexps.each do |rb, lit|
521
+ assert_parse rb, s(:lit, lit)
522
+ end
523
+
524
+ # TODO: add more including interpolation etc
525
+ end
526
+
527
+ def test_str_pct_Q_nested
528
+ rb = "%Q[before [#\{nest}] after]"
529
+ pt = s(:dstr, "before [", s(:evstr, s(:call, nil, :nest)), s(:str, "] after"))
530
+
531
+ assert_parse rb, pt
532
+ end
533
+
534
+ def test_str_pct_nested_nested
535
+ rb = "%{ { #\{ \"#\{1}\" } } }"
536
+ assert_equal " { 1 } ", eval(rb)
537
+ pt = s(:dstr, " { ", s(:evstr, s(:lit, 1)), s(:str, " } "))
538
+
539
+ assert_parse rb, pt
540
+ end
541
+
542
+ def test_str_str
543
+ rb = "\"a #\{'b'}\""
544
+ pt = s(:str, "a b")
545
+
546
+ assert_parse rb, pt
547
+ end
548
+
549
+ def test_str_str_str
550
+ rb = "\"a #\{'b'} c\""
551
+ pt = s(:str, "a b c")
552
+
553
+ assert_parse rb, pt
554
+ end
555
+
556
+ STARTING_LINE = {
557
+ "case_no_expr" => 2, # TODO this should be 1
558
+ "structure_unused_literal_wwtt" => 3, # yes, 3... odd test
559
+ }
560
+
561
+ def after_process_hook klass, node, data, input_name, output_name
562
+ expected = STARTING_LINE[node] || 1
563
+ assert_equal expected, @result.line, "should have proper line number"
564
+ end
565
+
566
+ def test_parse_line_block
567
+ rb = "a = 42\np a"
568
+ pt = s(:block,
569
+ s(:lasgn, :a, s(:lit, 42)),
570
+ s(:call, nil, :p, s(:lvar, :a)))
571
+
572
+ assert_parse_line rb, pt, 1
573
+ assert_equal 1, result.lasgn.line, "lasgn should have line number"
574
+ assert_equal 2, result.call.line, "call should have line number"
575
+
576
+ expected = "(string)"
577
+ assert_equal expected, result.file
578
+ assert_equal expected, result.lasgn.file
579
+ assert_equal expected, result.call.file
580
+
581
+ assert_same result.file, result.lasgn.file
582
+ assert_same result.file, result.call.file
583
+ end
584
+
585
+ def test_parse_line_call_no_args
586
+ rb = "f do |x, y|\n x + y\nend"
587
+
588
+ pt = s(:iter,
589
+ s(:call, nil, :f),
590
+ s(:args, :x, :y),
591
+ s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
592
+
593
+ assert_parse_line rb, pt, 1
594
+ assert_equal 1, result[1].line, "call should have line number"
595
+ assert_equal 1, result[2].line, "masgn should have line number"
596
+ assert_equal 2, result[3].line, "call should have line number"
597
+ end
598
+
599
+ def test_parse_line_defn_no_parens
600
+ pt = s(:defn, :f, s(:args), s(:nil))
601
+
602
+ rb = "def f\nend"
603
+ assert_parse_line rb, pt, 1
604
+
605
+ rb = "def f\n\nend"
606
+ assert_parse_line rb, pt, 1
607
+ end
608
+
609
+ def test_parse_line_defn_complex
610
+ rb = "def x(y)\n p(y)\n y *= 2\n return y;\nend" # TODO: remove () & ;
611
+ pt = s(:defn, :x, s(:args, :y),
612
+ s(:call, nil, :p, s(:lvar, :y)),
613
+ s(:lasgn, :y, s(:call, s(:lvar, :y), :*, s(:lit, 2))),
614
+ s(:return, s(:lvar, :y)))
615
+
616
+ assert_parse_line rb, pt, 1
617
+
618
+ body = result
619
+ assert_equal 2, body.call.line, "call should have line number"
620
+ assert_equal 3, body.lasgn.line, "lasgn should have line number"
621
+ assert_equal 4, body.return.line, "return should have line number"
622
+ end
623
+
624
+ def test_parse_line_iter_call_parens
625
+ rb = "f(a) do |x, y|\n x + y\nend"
626
+
627
+ pt = s(:iter,
628
+ s(:call, nil, :f, s(:call, nil, :a)),
629
+ s(:args, :x, :y),
630
+ s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
631
+
632
+ assert_parse_line rb, pt, 1
633
+
634
+ assert_equal 1, result[1].line, "call should have line number"
635
+ assert_equal 1, result[2].line, "masgn should have line number"
636
+ assert_equal 2, result[3].line, "call should have line number"
637
+ end
638
+
639
+ def test_parse_line_iter_call_no_parens
640
+ rb = "f a do |x, y|\n x + y\nend"
641
+
642
+ pt = s(:iter,
643
+ s(:call, nil, :f, s(:call, nil, :a)),
644
+ s(:args, :x, :y),
645
+ s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
646
+
647
+ assert_parse_line rb, pt, 1
648
+
649
+ assert_equal 1, result[1].line, "call should have line number"
650
+ assert_equal 1, result[2].line, "masgn should have line number"
651
+ assert_equal 2, result[3].line, "call should have line number"
652
+ end
653
+
654
+ def test_parse_line_heredoc
655
+ rb = <<-CODE
656
+ string = <<-HEREDOC
657
+ very long string
658
+ HEREDOC
659
+ puts string
660
+ CODE
661
+
662
+ pt = s(:block,
663
+ s(:lasgn, :string,
664
+ s(:str, " very long string\n").line(1)).line(1),
665
+ s(:call, nil, :puts, s(:lvar, :string).line(4)).line(4)).line(1)
666
+
667
+ assert_parse rb, pt
668
+ end
669
+
670
+ def test_parse_line_newlines
671
+ rb = "true\n\n"
672
+ pt = s(:true)
673
+
674
+ assert_parse_line rb, pt, 1
675
+ end
676
+
677
+ def test_parse_line_return
678
+ rb = <<-RUBY
679
+ def blah
680
+ if true then
681
+ return 42
682
+ end
683
+ end
684
+ RUBY
685
+
686
+ pt = s(:defn, :blah, s(:args),
687
+ s(:if, s(:true),
688
+ s(:return, s(:lit, 42)),
689
+ nil))
690
+
691
+ assert_parse_line rb, pt, 1
692
+
693
+ assert_equal 3, result.if.return.line
694
+ assert_equal 3, result.if.return.lit.line
695
+ end
696
+
697
+ def test_bug_and
698
+ rb = "true and []"
699
+ pt = s(:and, s(:true), s(:array))
700
+
701
+ assert_parse rb, pt
702
+
703
+ rb = "true and\ntrue"
704
+ pt = s(:and, s(:true), s(:true))
705
+
706
+ assert_parse rb, pt
707
+ end
708
+
709
+ def test_bug_cond_pct
710
+ rb = "case; when %r%blahblah%; end"
711
+ pt = s(:case, nil, s(:when, s(:array, s(:lit, /blahblah/)), nil), nil)
712
+
713
+ assert_parse rb, pt
714
+ end
715
+
716
+ # according to 2.3.1 parser -- added: ON 1.8 only:
717
+ # rp.process("f { |(a,b),c| }") == rp.process("f { |((a,b),c)| }")
718
+
719
+ # ruby18 -e "p lambda { |(a,b)| }.arity" # => 2
720
+ # ruby19 -e "p lambda { |(a,b)| }.arity" # => 1
721
+ # ruby18 -e "p lambda { |(a,b),c| }.arity" # => 2
722
+ # ruby19 -e "p lambda { |(a,b),c| }.arity" # => 2
723
+ # ruby18 -e "p lambda { |((a,b),c)| }.arity" # => 2
724
+ # ruby19 -e "p lambda { |((a,b),c)| }.arity" # => 1
725
+
726
+ def test_bug_args_masgn
727
+ rb = "f { |(a, b), c| }"
728
+ pt = s(:iter,
729
+ s(:call, nil, :f),
730
+ s(:args, s(:masgn, :a, :b), :c))
731
+
732
+ assert_parse rb, pt.dup
733
+ end
734
+
735
+ def test_bug_args_masgn2
736
+ rb = "f { |((a, b), c), d| }"
737
+ pt = s(:iter,
738
+ s(:call, nil, :f),
739
+ s(:args, s(:masgn, s(:masgn, :a, :b), :c), :d))
740
+
741
+ assert_parse rb, pt
742
+ end
743
+
744
+ def ruby18
745
+ Ruby18Parser === self.processor
746
+ end
747
+
748
+ def ruby19
749
+ Ruby19Parser === self.processor
750
+ end
751
+
752
+ def test_bug_comma
753
+ val = if ruby18 then
754
+ s(:lit, 100)
755
+ elsif ruby19 then
756
+ s(:str, "d")
757
+ else
758
+ raise "wtf"
759
+ end
760
+
761
+ rb = "if test ?d, dir then end"
762
+ pt = s(:if,
763
+ s(:call, nil, :test, val, s(:call, nil, :dir)),
764
+ nil,
765
+ nil)
766
+
767
+ assert_parse rb, pt
768
+ end
769
+
770
+ def test_bug_case_when_regexp
771
+ rb = "case :x; when /x/ then end"
772
+ pt = s(:case, s(:lit, :x),
773
+ s(:when, s(:array, s(:lit, /x/)), nil),
774
+ nil)
775
+
776
+ assert_parse rb, pt
777
+ end
778
+
779
+ def test_bug_masgn_right
780
+ rb = "f { |a, (b, c)| }"
781
+ pt = s(:iter,
782
+ s(:call, nil, :f),
783
+ s(:args, :a, s(:masgn, :b, :c)))
784
+
785
+ assert_parse rb, pt
786
+ end
787
+
788
+ def test_when_splat
789
+ rb = "case a; when *b then; end"
790
+ pt = s(:case, s(:call, nil, :a),
791
+ s(:when, s(:array, s(:splat, s(:call, nil, :b))), nil),
792
+ nil)
793
+
794
+ assert_parse rb, pt
795
+ end
796
+
797
+ def test_if_symbol
798
+ rb = "if f :x; end"
799
+ pt = s(:if, s(:call, nil, :f, s(:lit, :x)), nil, nil)
800
+
801
+ assert_parse rb, pt
802
+ end
803
+
804
+
805
+ def test_bug_not_parens
806
+ rb = "not(a)"
807
+ pt = if ruby18 then
808
+ s(:not, s(:call, nil, :a))
809
+ elsif ruby19 then
810
+ s(:call, s(:call, nil, :a), :"!")
811
+ else
812
+ raise "wtf"
813
+ end
814
+
815
+ assert_parse rb, pt
816
+ end
817
+
818
+ def test_pipe_space
819
+ rb = "a.b do | | end"
820
+ pt = s(:iter, s(:call, s(:call, nil, :a), :b), 0)
821
+
822
+ assert_parse rb, pt
823
+ end
824
+
825
+ def test_cond_unary_minus
826
+ rb = "if -1; end"
827
+ pt = s(:if, s(:lit, -1), nil, nil)
828
+
829
+ assert_parse rb, pt
830
+ end
831
+
832
+ def test_bug_op_asgn_rescue
833
+ rb = "a ||= b rescue nil"
834
+ pt = s(:rescue,
835
+ s(:op_asgn_or, s(:lvar, :a), s(:lasgn, :a, s(:call, nil, :b))),
836
+ s(:resbody, s(:array), s(:nil)))
837
+
838
+ assert_parse rb, pt
839
+ end
840
+
841
+ def test_magic_encoding_comment
842
+ rb = "# encoding: utf-8\nclass ExampleUTF8ClassNameVarietà; def self.è; così = :però; end\nend\n"
843
+
844
+ rb.force_encoding "ASCII-8BIT" if rb.respond_to? :force_encoding
845
+
846
+ # TODO: class vars
847
+ # TODO: odd-ternary: a ?bb : c
848
+ # TODO: globals
849
+
850
+ pt = s(:class, :"ExampleUTF8ClassNameVariet\303\240", nil,
851
+ s(:defs, s(:self), :"\303\250", s(:args),
852
+ s(:lasgn, :"cos\303\254", s(:lit, :"per\303\262"))))
853
+
854
+ err = RUBY_VERSION =~ /^1\.8/ ? "Skipping magic encoding comment\n" : ""
855
+
856
+ assert_output "", err do
857
+ assert_parse rb, pt
858
+ end
859
+ end
860
+
861
+ def test_iter_args_1
862
+ rb = "f { |a,b| }"
863
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, :b))
864
+
865
+ assert_parse rb, pt
866
+ end
867
+
868
+ def test_iter_args_3
869
+ rb = "f { |a, (b, c), d| }"
870
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, s(:masgn, :b, :c), :d))
871
+
872
+ assert_parse rb, pt
873
+ end
874
+
875
+ def test_str_heredoc_interp
876
+ rb = "<<\"\"\n\#{x}\nblah2\n\n"
877
+ pt = s(:dstr, "", s(:evstr, s(:call, nil, :x)), s(:str, "\n"), s(:str, "blah2\n"))
878
+
879
+ assert_parse rb, pt
880
+ end
881
+
882
+ def test_i_fucking_hate_line_numbers
883
+ rb = <<-END.gsub(/^ {6}/, '')
884
+ if true
885
+ p 1
886
+ a.b 2
887
+ c.d 3, 4
888
+ e.f 5
889
+ g.h 6, 7
890
+ p(1)
891
+ a.b(2)
892
+ c.d(3, 4)
893
+ e.f(5)
894
+ g.h(6, 7)
895
+ end
896
+ END
897
+
898
+ pt = s(:if, s(:true).line(1),
899
+ s(:block,
900
+ s(:call, nil, :p, s(:lit, 1).line(2)).line(2),
901
+ s(:call, s(:call, nil, :a).line(3), :b,
902
+ s(:lit, 2).line(3)).line(3),
903
+ s(:call, s(:call, nil, :c).line(4), :d,
904
+ s(:lit, 3).line(4), s(:lit, 4).line(4)).line(4),
905
+ s(:call, s(:call, nil, :e).line(5), :f,
906
+ s(:lit, 5).line(5)).line(5),
907
+ s(:call, s(:call, nil, :g).line(6), :h,
908
+ s(:lit, 6).line(6), s(:lit, 7).line(6)).line(6),
909
+ s(:call, nil, :p, s(:lit, 1).line(7)).line(7),
910
+ s(:call, s(:call, nil, :a).line(8), :b,
911
+ s(:lit, 2).line(8)).line(8),
912
+ s(:call, s(:call, nil, :c).line(9), :d,
913
+ s(:lit, 3).line(9), s(:lit, 4).line(9)).line(9),
914
+ s(:call, s(:call, nil, :e).line(10), :f,
915
+ s(:lit, 5).line(10)).line(10),
916
+ s(:call, s(:call, nil, :g).line(11), :h,
917
+ s(:lit, 6).line(11), s(:lit, 7).line(11)).line(11)).line(2),
918
+ nil).line(1)
919
+
920
+ assert_parse rb, pt
921
+ end
922
+
923
+ def test_i_fucking_hate_line_numbers2
924
+ rb = <<-EOM.gsub(/^ {6}/, '')
925
+ if true then
926
+ p('a')
927
+ b = 1
928
+ p b
929
+ c =1
930
+ end
931
+ a
932
+ EOM
933
+
934
+ pt = s(:block,
935
+ s(:if, s(:true).line(1),
936
+ s(:block,
937
+ s(:call, nil, :p, s(:str, "a").line(2)).line(2),
938
+ s(:lasgn, :b, s(:lit, 1).line(3)).line(3),
939
+ s(:call, nil, :p, s(:lvar, :b).line(4)).line(4),
940
+ s(:lasgn, :c, s(:lit, 1).line(5)).line(5)).line(2), # TODO line 2?
941
+ nil).line(1),
942
+ s(:call, nil, :a).line(7)).line(1)
943
+
944
+ assert_parse rb, pt
945
+ end
946
+
947
+ def test_parse_comments
948
+ p = RubyParser.new
949
+ sexp = p.parse <<-CODE
950
+ # class comment
951
+ class Inline
952
+ def show
953
+ # woot
954
+ end
955
+
956
+ # Returns a list of things
957
+ def list
958
+ # woot
959
+ end
960
+ end
961
+ CODE
962
+
963
+ assert_equal "# class comment\n", sexp.comments
964
+ act = sexp.find_nodes(:defn).map(&:comments)
965
+ exp = ["", "# Returns a list of things\n"]
966
+
967
+ assert_equal exp, act
968
+ assert_equal [], processor.comments
969
+ assert_equal "", processor.lexer.comments
970
+ end
971
+ end
972
+
973
+ class TestRubyParser < MiniTest::Unit::TestCase
974
+ def test_parse
975
+ processor = RubyParser.new
976
+
977
+ # 1.8 only syntax
978
+ rb = "while false : 42 end"
979
+ pt = s(:while, s(:false), s(:lit, 42), true)
980
+
981
+ assert_silent do
982
+ assert_equal pt, processor.parse(rb)
983
+ end
984
+
985
+ # 1.9 only syntax
986
+ rb = "a.()"
987
+ pt = s(:call, s(:call, nil, :a), :call)
988
+
989
+ assert_equal pt, processor.parse(rb)
990
+
991
+ # bad syntax
992
+ e = assert_raises Racc::ParseError do
993
+ capture_io do
994
+ processor.parse "a.("
995
+ end
996
+ end
997
+
998
+ msg = "(string):1 :: parse error on value \"(\" (tLPAREN2)"
999
+ assert_equal msg, e.message.strip
1000
+ end
1001
+ end
1002
+
1003
+ class TestRuby18Parser < RubyParserTestCase
1004
+ include TestRubyParserShared
1005
+
1006
+ def setup
1007
+ super
1008
+
1009
+ self.processor = Ruby18Parser.new
1010
+ end
1011
+
1012
+ def test_flip2_env_lvar
1013
+ rb = "if a..b then end"
1014
+ pt = s(:if, s(:flip2, s(:call, nil, :a), s(:call, nil, :b)), nil, nil)
1015
+
1016
+ assert_parse rb, pt
1017
+
1018
+ top_env = processor.env.env.first
1019
+
1020
+ assert_kind_of Hash, top_env
1021
+
1022
+ flip = top_env.find { |k,v| k =~ /^flip/ }
1023
+
1024
+ assert flip
1025
+ assert_equal :lvar, flip.last
1026
+ end
1027
+
1028
+ def test_assoc_list_18
1029
+ rb = "{1, 2, 3, 4}"
1030
+ pt = s(:hash, s(:lit, 1), s(:lit, 2), s(:lit, 3), s(:lit, 4))
1031
+
1032
+ assert_parse rb, pt
1033
+ end
1034
+
1035
+ def test_case_then_colon_18
1036
+ rb = "case x; when Fixnum: 42; end"
1037
+ pt = s(:case,
1038
+ s(:call, nil, :x),
1039
+ s(:when, s(:array, s(:const, :Fixnum)), s(:lit, 42)),
1040
+ nil)
1041
+
1042
+ assert_parse rb, pt
1043
+ end
1044
+
1045
+ def test_do_colon_18
1046
+ rb = "while false : 42 end"
1047
+ pt = s(:while, s(:false), s(:lit, 42), true)
1048
+
1049
+ assert_parse rb, pt
1050
+ end
1051
+
1052
+ def test_parse_until_not_canonical
1053
+ rb = "until not var.nil?\n 'foo'\nend"
1054
+
1055
+ pt = s(:while,
1056
+ s(:call, s(:call, nil, :var), :nil?),
1057
+ s(:str, "foo"), true)
1058
+
1059
+ assert_parse rb, pt
1060
+ end
1061
+
1062
+ def test_parse_until_not_noncanonical
1063
+ rb = "until not var.nil?\n 'foo'\nend"
1064
+ pt = s(:until,
1065
+ s(:not, s(:call, s(:call, nil, :var), :nil?)),
1066
+ s(:str, "foo"), true)
1067
+
1068
+ processor.canonicalize_conditions = false
1069
+
1070
+ assert_parse rb, pt
1071
+ end
1072
+
1073
+ def test_parse_if_not_canonical
1074
+ rb = "if not var.nil? then 'foo' else 'bar'\nend"
1075
+ pt = s(:if,
1076
+ s(:call, s(:call, nil, :var), :nil?),
1077
+ s(:str, "bar"),
1078
+ s(:str, "foo"))
1079
+
1080
+ assert_parse rb, pt
1081
+ end
1082
+
1083
+ def test_parse_if_not_noncanonical
1084
+ rb = "if not var.nil? then 'foo' else 'bar'\nend"
1085
+ pt = s(:if,
1086
+ s(:not, s(:call, s(:call, nil, :var), :nil?)),
1087
+ s(:str, "foo"),
1088
+ s(:str, "bar"))
1089
+
1090
+ processor.canonicalize_conditions = false
1091
+
1092
+ assert_parse rb, pt
1093
+ end
1094
+
1095
+ def test_parse_while_not_canonical
1096
+ rb = "while not var.nil?\n 'foo'\nend"
1097
+ pt = s(:until,
1098
+ s(:call, s(:call, nil, :var), :nil?),
1099
+ s(:str, "foo"), true)
1100
+
1101
+ assert_parse rb, pt
1102
+ end
1103
+
1104
+ def test_parse_while_not_noncanonical
1105
+ rb = "while not var.nil?\n 'foo'\nend"
1106
+ pt = s(:while,
1107
+ s(:not, s(:call, s(:call, nil, :var), :nil?)),
1108
+ s(:str, "foo"), true)
1109
+
1110
+ processor.canonicalize_conditions = false
1111
+
1112
+ assert_parse rb, pt
1113
+ end
1114
+
1115
+ def test_double_block_error_10
1116
+ assert_syntax_error "a.b (&b) {}", BLOCK_DUP_MSG
1117
+ end
1118
+
1119
+ def test_double_block_error_11
1120
+ assert_syntax_error "a (1, &b) { }", BLOCK_DUP_MSG
1121
+ end
1122
+
1123
+ def test_double_block_error_12
1124
+ assert_syntax_error "a (1, &b) do end", BLOCK_DUP_MSG
1125
+ end
1126
+
1127
+ def test_double_block_error_13
1128
+ assert_syntax_error "m.a (1, &b) { }", BLOCK_DUP_MSG
1129
+ end
1130
+
1131
+ def test_double_block_error_14
1132
+ assert_syntax_error "m.a (1, &b) do end", BLOCK_DUP_MSG
1133
+ end
1134
+
1135
+ def test_double_block_error_15
1136
+ assert_syntax_error "m::a (1, &b) { }", BLOCK_DUP_MSG
1137
+ end
1138
+
1139
+ def test_double_block_error_16
1140
+ assert_syntax_error "m::a (1, &b) do end", BLOCK_DUP_MSG
1141
+ end
1142
+
1143
+ # In 1.8, block args with an outer set of parens are superfluous.
1144
+ # In 1.9, outer set of parens are NOT... they are an explicit extra masgn.
1145
+
1146
+ def test_iter_args_2_18
1147
+ rb = "f { |(a, b)| }"
1148
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, :b))
1149
+
1150
+ assert_parse rb, pt
1151
+ end
1152
+
1153
+ def test_bug_args__18
1154
+ rb = "f { |(a, b)| }"
1155
+ pt = s(:iter, s(:call, nil, :f),
1156
+ s(:args, :a, :b))
1157
+
1158
+ assert_parse rb, pt
1159
+ end
1160
+
1161
+ def test_bug_args_masgn_outer_parens__18
1162
+ rb = "f { |((a, b), c)| }"
1163
+ pt = s(:iter, # NOTE: same sexp as test_bug_args_masgn
1164
+ s(:call, nil, :f),
1165
+ s(:args, s(:masgn, :a, :b), :c))
1166
+
1167
+ assert_parse rb, pt.dup
1168
+ end
1169
+ end
1170
+
1171
+ class TestRuby19Parser < RubyParserTestCase
1172
+ include TestRubyParserShared
1173
+
1174
+ def setup
1175
+ super
1176
+
1177
+ self.processor = Ruby19Parser.new
1178
+ end
1179
+
1180
+ def test_mlhs_back_splat
1181
+ rb = "a, b, c, *s = f"
1182
+ pt = s(:masgn,
1183
+ s(:array,
1184
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
1185
+ s(:splat, s(:lasgn, :s))),
1186
+ s(:to_ary, s(:call, nil, :f)))
1187
+
1188
+ assert_parse rb, pt
1189
+ end
1190
+
1191
+ def test_mlhs_back_anonsplat
1192
+ rb = "a, b, c, * = f"
1193
+ pt = s(:masgn,
1194
+ s(:array,
1195
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
1196
+ s(:splat)),
1197
+ s(:to_ary, s(:call, nil, :f)))
1198
+
1199
+ assert_parse rb, pt
1200
+ end
1201
+
1202
+ def test_mlhs_mid_splat
1203
+ rb = "a, b, c, *s, x, y, z = f"
1204
+ pt = s(:masgn,
1205
+ s(:array,
1206
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
1207
+ s(:splat, s(:lasgn, :s)),
1208
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
1209
+ s(:to_ary, s(:call, nil, :f)))
1210
+
1211
+ assert_parse rb, pt
1212
+ end
1213
+
1214
+ def test_mlhs_mid_anonsplat
1215
+ rb = "a, b, c, *, x, y, z = f"
1216
+ pt = s(:masgn,
1217
+ s(:array, s(:lasgn, :a), s(:splat), s(:lasgn, :z)),
1218
+ s(:to_ary, s(:call, nil, :f)))
1219
+ pt = s(:masgn,
1220
+ s(:array,
1221
+ s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
1222
+ s(:splat),
1223
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
1224
+ s(:to_ary, s(:call, nil, :f)))
1225
+
1226
+ assert_parse rb, pt
1227
+ end
1228
+
1229
+ def test_mlhs_front_splat
1230
+ rb = "*s, x, y, z = f"
1231
+ pt = s(:masgn,
1232
+ s(:array, s(:splat, s(:lasgn, :s)), s(:lasgn, :z)),
1233
+ s(:to_ary, s(:call, nil, :f)))
1234
+ pt = s(:masgn,
1235
+ s(:array,
1236
+ s(:splat, s(:lasgn, :s)),
1237
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
1238
+ s(:to_ary, s(:call, nil, :f)))
1239
+
1240
+ assert_parse rb, pt
1241
+ end
1242
+
1243
+ def test_mlhs_front_anonsplat
1244
+ rb = "*, x, y, z = f"
1245
+ pt = s(:masgn,
1246
+ s(:array,
1247
+ s(:splat),
1248
+ s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
1249
+ s(:to_ary, s(:call, nil, :f)))
1250
+
1251
+ assert_parse rb, pt
1252
+ end
1253
+
1254
+ def test_expr_not_bang
1255
+ rb = "! a b"
1256
+ pt = s(:call, s(:call, nil, :a, s(:call, nil, :b)), :"!")
1257
+
1258
+ assert_parse rb, pt
1259
+ end
1260
+
1261
+ def test_encoding
1262
+ rb = '__ENCODING__'
1263
+ pt = if defined? Encoding then
1264
+ s(:const, Encoding::UTF_8)
1265
+ else
1266
+ s(:str, "Unsupported!")
1267
+ end
1268
+
1269
+ assert_parse rb, pt
1270
+ end
1271
+
1272
+ def test_do_colon_19
1273
+ rb = "while false : 42 end"
1274
+
1275
+ assert_parse_error rb, "(string):1 :: parse error on value \":\" (tCOLON)"
1276
+ end
1277
+
1278
+ def test_assoc_list_19
1279
+ rb = "{1, 2, 3, 4}"
1280
+
1281
+ assert_parse_error rb, "(string):1 :: parse error on value \",\" (tCOMMA)"
1282
+ end
1283
+
1284
+ def test_case_then_colon_19
1285
+ rb = <<-EOM
1286
+ case x
1287
+ when Fixnum : # need the space to not hit new hash arg syntax
1288
+ 42
1289
+ end
1290
+ EOM
1291
+
1292
+ assert_parse_error rb, "(string):2 :: parse error on value \":\" (tCOLON)"
1293
+ end
1294
+
1295
+ def test_parse_def_xxx1
1296
+ rb = 'def f(a, *b, c = nil) end'
1297
+
1298
+ assert_parse_error rb, '(string):1 :: parse error on value "=" (tEQL)'
1299
+ end
1300
+
1301
+ def test_parse_def_xxx2
1302
+ rb = 'def f(a = nil, *b, c = nil) end'
1303
+
1304
+ assert_parse_error rb, '(string):1 :: parse error on value "=" (tEQL)'
1305
+ end
1306
+
1307
+ def test_parse_until_not_canonical
1308
+ rb = "until not var.nil?\n 'foo'\nend"
1309
+ pt = s(:until,
1310
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
1311
+ s(:str, "foo"), true)
1312
+
1313
+ assert_parse rb, pt
1314
+ end
1315
+
1316
+ def test_parse_until_not_noncanonical
1317
+ rb = "until not var.nil?\n 'foo'\nend"
1318
+ pt = s(:until,
1319
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
1320
+ s(:str, "foo"), true)
1321
+
1322
+ processor.canonicalize_conditions = false
1323
+
1324
+ assert_parse rb, pt
1325
+ end
1326
+
1327
+ def test_parse_if_not_canonical
1328
+ rb = "if not var.nil? then 'foo' else 'bar'\nend"
1329
+ pt = s(:if,
1330
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
1331
+ s(:str, "foo"),
1332
+ s(:str, "bar"))
1333
+
1334
+ assert_parse rb, pt
1335
+ end
1336
+
1337
+ def test_parse_if_not_noncanonical
1338
+ rb = "if not var.nil? then 'foo' else 'bar'\nend"
1339
+ pt = s(:if,
1340
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
1341
+ s(:str, "foo"),
1342
+ s(:str, "bar"))
1343
+
1344
+ processor.canonicalize_conditions = false
1345
+
1346
+ assert_parse rb, pt
1347
+ end
1348
+
1349
+ def test_parse_while_not_canonical
1350
+ rb = "while not var.nil?\n 'foo'\nend"
1351
+ pt = s(:while,
1352
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
1353
+ s(:str, "foo"), true)
1354
+
1355
+ assert_parse rb, pt
1356
+ end
1357
+
1358
+ def test_parse_while_not_noncanonical
1359
+ rb = "while not var.nil?\n 'foo'\nend"
1360
+ pt = s(:while,
1361
+ s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
1362
+ s(:str, "foo"), true)
1363
+
1364
+ processor.canonicalize_conditions = false
1365
+
1366
+ assert_parse rb, pt
1367
+ end
1368
+
1369
+ def test_parse_opt_call_args_assocs_comma
1370
+ rb = "1[2=>3,]"
1371
+ pt = s(:call, s(:lit, 1), :[], s(:lit, 2), s(:lit, 3))
1372
+
1373
+ assert_parse rb, pt
1374
+ end
1375
+
1376
+ def test_bug_hash_args
1377
+ rb = "foo(:bar, baz: nil)"
1378
+ pt = s(:call, nil, :foo,
1379
+ s(:lit, :bar),
1380
+ s(:hash, s(:lit, :baz), s(:nil)))
1381
+
1382
+ assert_parse rb, pt
1383
+ end
1384
+
1385
+ def test_bug_hash_args_trailing_comma
1386
+ rb = "foo(:bar, baz: nil,)"
1387
+ pt = s(:call, nil, :foo, # NOTE: same sexp as test_bug_hash_args
1388
+ s(:lit, :bar),
1389
+ s(:hash, s(:lit, :baz), s(:nil)))
1390
+
1391
+ assert_parse rb, pt
1392
+ end
1393
+
1394
+ def test_block_arg_optional
1395
+ rb = "a { |b = 1| }"
1396
+ pt = s(:iter,
1397
+ s(:call, nil, :a),
1398
+ s(:args, s(:lasgn, :b, s(:lit, 1))))
1399
+
1400
+ assert_parse rb, pt
1401
+ end
1402
+
1403
+ def test_zomg_sometimes_i_hate_this_project
1404
+ rb = <<-RUBY
1405
+ {
1406
+ a: lambda { b ? c() : d },
1407
+ e: nil,
1408
+ }
1409
+ RUBY
1410
+
1411
+ pt = s(:hash,
1412
+ s(:lit, :a),
1413
+ s(:iter,
1414
+ s(:call, nil, :lambda),
1415
+ s(:args),
1416
+ s(:if, s(:call, nil, :b), s(:call, nil, :c), s(:call, nil, :d))),
1417
+
1418
+ s(:lit, :e),
1419
+ s(:nil))
1420
+
1421
+ assert_parse rb, pt
1422
+ end
1423
+
1424
+ # def test_pipe_semicolon # HACK
1425
+ # rb = "a.b do | ; c | end"
1426
+ # pt = s(:iter, s(:call, s(:call, nil, :a), :b), 0)
1427
+ #
1428
+ # assert_parse rb, pt
1429
+ # end
1430
+
1431
+ def test_wtf
1432
+ # lambda -> f_larglist lambda_body
1433
+ # f_larglist -> f_args opt_bv_decl
1434
+ # opt_bv_decl
1435
+ # bv_decls
1436
+ # bvar
1437
+
1438
+ rb = "->(a, b=nil) { p [a, b] }"
1439
+ pt = s(:iter,
1440
+ s(:call, nil, :lambda),
1441
+ s(:args, :a, s(:lasgn, :b, s(:nil))),
1442
+ s(:call, nil, :p, s(:array, s(:lvar, :a), s(:lvar, :b))))
1443
+
1444
+ assert_parse rb, pt
1445
+
1446
+ # rb = "->(a; b) { p [a, b] }"
1447
+ #
1448
+ # assert_parse rb, pt
1449
+ end
1450
+
1451
+ def test_block_args_opt1
1452
+ rb = "f { |a, b = 42| [a, b] }"
1453
+ pt = s(:iter,
1454
+ s(:call, nil, :f),
1455
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42))),
1456
+ s(:array, s(:lvar, :a), s(:lvar, :b)))
1457
+
1458
+ assert_parse rb, pt
1459
+ end
1460
+
1461
+ def test_block_args_opt2
1462
+ rb = "f { |a, b = 42, c = 24| [a, b, c] }"
1463
+ pt = s(:iter,
1464
+ s(:call, nil, :f),
1465
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), s(:lasgn, :c, s(:lit, 24))),
1466
+ s(:array, s(:lvar, :a), s(:lvar, :b), s(:lvar, :c)))
1467
+
1468
+ assert_parse rb, pt
1469
+ end
1470
+
1471
+ def test_block_args_opt3
1472
+ rb = "f { |a, b = 42, c = 24, &d| [a, b, c, d] }"
1473
+ pt = s(:iter,
1474
+ s(:call, nil, :f),
1475
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), s(:lasgn, :c, s(:lit, 24)), :"&d"),
1476
+ s(:array, s(:lvar, :a), s(:lvar, :b), s(:lvar, :c), s(:lvar, :d)))
1477
+
1478
+ assert_parse rb, pt
1479
+ end
1480
+
1481
+ def test_i_have_no_freakin_clue
1482
+ rb = "1 ? b('') : 2\na d: 3"
1483
+ pt = s(:block,
1484
+ s(:if, s(:lit, 1), s(:call, nil, :b, s(:str, "")), s(:lit, 2)),
1485
+ s(:call, nil, :a, s(:hash, s(:lit, :d), s(:lit, 3))))
1486
+
1487
+ assert_parse rb, pt
1488
+ end
1489
+
1490
+ def test_motherfuckin_leading_dots
1491
+ rb = "a\n.b"
1492
+ pt = s(:call, s(:call, nil, :a), :b)
1493
+
1494
+ assert_parse rb, pt
1495
+ end
1496
+
1497
+ def test_motherfuckin_leading_dots2
1498
+ rb = "a\n..b"
1499
+
1500
+ assert_parse_error rb, '(string):2 :: parse error on value ".." (tDOT2)'
1501
+ end
1502
+
1503
+ def test_kill_me
1504
+ rb = "f { |a, (b, *c)| }"
1505
+ pt = s(:iter,
1506
+ s(:call, nil, :f),
1507
+ s(:args, :a, s(:masgn, :b, :"*c")))
1508
+
1509
+ assert_parse rb, pt
1510
+ end
1511
+
1512
+ def test_kill_me2
1513
+ rb = "f { |*a, b| }"
1514
+ pt = s(:iter, s(:call, nil, :f), s(:args, :"*a", :b))
1515
+
1516
+ assert_parse rb, pt
1517
+ end
1518
+
1519
+ def test_kill_me3
1520
+ rb = "f { |*a, b, &c| }"
1521
+ pt = s(:iter, s(:call, nil, :f), s(:args, :"*a", :b, :"&c"))
1522
+
1523
+ assert_parse rb, pt
1524
+ end
1525
+
1526
+ def test_kill_me4
1527
+ rb = "a=b ? true: false"
1528
+ pt = s(:lasgn, :a, s(:if, s(:call, nil, :b), s(:true), s(:false)))
1529
+
1530
+ assert_parse rb, pt
1531
+ end
1532
+
1533
+ # def test_kill_me5
1534
+ # rb = "f ->() { g do end }"
1535
+ # pt = 42
1536
+ #
1537
+ # assert_parse rb, pt
1538
+ # end
1539
+
1540
+ def test_iter_args_4
1541
+ rb = "f { |a, *b, c| }"
1542
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, :"*b", :c))
1543
+
1544
+ assert_parse rb, pt
1545
+ end
1546
+
1547
+ def test_iter_args_5
1548
+ rb = "f { |a, &b| }"
1549
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, :"&b"))
1550
+
1551
+ assert_parse rb, pt
1552
+ end
1553
+
1554
+ def test_iter_args_6
1555
+ rb = "f { |a, b=42, c| }"
1556
+ pt = s(:iter, s(:call, nil, :f), s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :c))
1557
+
1558
+ assert_parse rb, pt
1559
+ end
1560
+
1561
+ # In 1.8, block args with an outer set of parens are superfluous.
1562
+ # In 1.9, outer set of parens are NOT... they are an explicit extra masgn.
1563
+
1564
+ def test_iter_args_2__19
1565
+ rb = "f { |(a, b)| }"
1566
+ pt = s(:iter, s(:call, nil, :f), s(:args, s(:masgn, :a, :b)))
1567
+
1568
+ assert_parse rb, pt
1569
+ end
1570
+
1571
+ def test_bug_args__19
1572
+ rb = "f { |(a, b)| d }"
1573
+ pt = s(:iter, s(:call, nil, :f),
1574
+ s(:args, s(:masgn, :a, :b)),
1575
+ s(:call, nil, :d))
1576
+
1577
+ assert_parse rb, pt
1578
+ end
1579
+
1580
+ def test_bug_args_masgn_outer_parens__19
1581
+ rb = "f { |((k, v), i)| }"
1582
+ pt = s(:iter, # NOTE: same sexp as test_bug_args_masgn
1583
+ s(:call, nil, :f),
1584
+ s(:args, s(:masgn, s(:masgn, :k, :v), :i)))
1585
+
1586
+ assert_parse rb, pt.dup
1587
+ end
1588
+
1589
+ def test_iter_args_7_1
1590
+ rb = "f { |a = 42, *b| }"
1591
+ pt = s(:iter, s(:call, nil, :f),
1592
+ s(:args, s(:lasgn, :a, s(:lit, 42)), :"*b"))
1593
+
1594
+ assert_parse rb, pt
1595
+ end
1596
+
1597
+ def test_iter_args_7_2
1598
+ rb = "f { |a = 42, *b, &c| }"
1599
+ pt = s(:iter, s(:call, nil, :f),
1600
+ s(:args, s(:lasgn, :a, s(:lit, 42)), :"*b", :"&c"))
1601
+
1602
+ assert_parse rb, pt
1603
+ end
1604
+
1605
+ def test_iter_args_8_1
1606
+ rb = "f { |a = 42, *b, c| }"
1607
+ pt = s(:iter, s(:call, nil, :f),
1608
+ s(:args, s(:lasgn, :a, s(:lit, 42)), :"*b", :c))
1609
+
1610
+ assert_parse rb, pt
1611
+ end
1612
+
1613
+ def test_iter_args_8_2
1614
+ rb = "f { |a = 42, *b, c, &d| }"
1615
+ pt = s(:iter, s(:call, nil, :f),
1616
+ s(:args, s(:lasgn, :a, s(:lit, 42)), :"*b", :c, :"&d"))
1617
+
1618
+ assert_parse rb, pt
1619
+ end
1620
+
1621
+ def test_iter_args_9_1
1622
+ rb = "f { |a = 42, b| }"
1623
+ pt = s(:iter, s(:call, nil, :f),
1624
+ s(:args, s(:lasgn, :a, s(:lit, 42)), :b))
1625
+
1626
+ assert_parse rb, pt
1627
+ end
1628
+
1629
+ def test_iter_args_9_2
1630
+ rb = "f { |a = 42, b, &c| }"
1631
+ pt = s(:iter, s(:call, nil, :f),
1632
+ s(:args, s(:lasgn, :a, s(:lit, 42)), :b, :"&c"))
1633
+
1634
+ assert_parse rb, pt
1635
+ end
1636
+
1637
+ def test_iter_args_10_1
1638
+ rb = "f { |a, b = 42, *c| }"
1639
+ pt = s(:iter, s(:call, nil, :f),
1640
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c"))
1641
+
1642
+ assert_parse rb, pt
1643
+ end
1644
+
1645
+ def test_iter_args_10_2
1646
+ rb = "f { |a, b = 42, *c, &d| }"
1647
+ pt = s(:iter, s(:call, nil, :f),
1648
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :"&d"))
1649
+
1650
+ assert_parse rb, pt
1651
+ end
1652
+
1653
+ def test_iter_args_11_1
1654
+ rb = "f { |a, b = 42, *c, d| }"
1655
+ pt = s(:iter, s(:call, nil, :f),
1656
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :d))
1657
+
1658
+ assert_parse rb, pt
1659
+ end
1660
+
1661
+ def test_iter_args_11_2
1662
+ rb = "f { |a, b = 42, *c, d, &e| }"
1663
+ pt = s(:iter, s(:call, nil, :f),
1664
+ s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :d, :"&e"))
1665
+
1666
+ assert_parse rb, pt
1667
+ end
1668
+
1669
+ def test_kill_me_6
1670
+ # | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1671
+ rb = "f { |a, (b, *c, d)| }"
1672
+ pt = s(:iter,
1673
+ s(:call, nil, :f),
1674
+ s(:args, :a, s(:masgn, :b, :"*c", :d)))
1675
+
1676
+ assert_parse rb, pt
1677
+ end
1678
+
1679
+ def test_kill_me_7
1680
+ # | f_marg_list tCOMMA tSTAR
1681
+ rb = "f { |a, (b, *)| }"
1682
+ pt = s(:iter,
1683
+ s(:call, nil, :f),
1684
+ s(:args, :a, s(:masgn, :b, :*)))
1685
+
1686
+ assert_parse rb, pt
1687
+ end
1688
+
1689
+ def test_kill_me_8
1690
+ # | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1691
+ rb = "f { |a, (b, *, c)| }"
1692
+ pt = s(:iter,
1693
+ s(:call, nil, :f),
1694
+ s(:args, :a, s(:masgn, :b, :*, :c)))
1695
+
1696
+ assert_parse rb, pt
1697
+ end
1698
+
1699
+ def test_kill_me_9
1700
+ # | tSTAR f_norm_arg
1701
+ rb = "f { |a, (*b)| }"
1702
+ pt = s(:iter,
1703
+ s(:call, nil, :f),
1704
+ s(:args, :a, s(:masgn, :"*b")))
1705
+
1706
+ assert_parse rb, pt
1707
+ end
1708
+
1709
+ def test_kill_me_10
1710
+ # | tSTAR f_norm_arg tCOMMA f_marg_list
1711
+ rb = "f { |a, (*b, c)| }"
1712
+ pt = s(:iter,
1713
+ s(:call, nil, :f),
1714
+ s(:args, :a, s(:masgn, :"*b", :c)))
1715
+
1716
+ assert_parse rb, pt
1717
+ end
1718
+
1719
+ def test_kill_me_11
1720
+ # | tSTAR
1721
+ rb = "f { |a, (*)| }"
1722
+ pt = s(:iter,
1723
+ s(:call, nil, :f),
1724
+ s(:args, :a, s(:masgn, :*)))
1725
+
1726
+ assert_parse rb, pt
1727
+ end
1728
+
1729
+ def test_kill_me_12
1730
+ # | tSTAR tCOMMA f_marg_list
1731
+ rb = "f { |a, (*, b)| }"
1732
+ pt = s(:iter,
1733
+ s(:call, nil, :f),
1734
+ s(:args, :a, s(:masgn, :*, :b)))
1735
+
1736
+ assert_parse rb, pt
1737
+ end
1738
+
1739
+ def test_index_0
1740
+ rb = "a[] = b"
1741
+ pt = s(:attrasgn, s(:call, nil, :a), :[]=, s(:call, nil, :b))
1742
+
1743
+ assert_parse rb, pt
1744
+ end
1745
+
1746
+ def test_lambda_do_vs_brace
1747
+ pt = s(:call, nil, :f, s(:iter, s(:call, nil, :lambda), 0))
1748
+
1749
+ rb = "f ->() {}"
1750
+ assert_parse rb, pt
1751
+
1752
+ rb = "f ->() do end"
1753
+ assert_parse rb, pt
1754
+ end
1755
+
1756
+ def test_thingy
1757
+ pt = s(:call, s(:call, nil, :f), :call, s(:lit, 42))
1758
+
1759
+ rb = "f.(42)"
1760
+ assert_parse rb, pt
1761
+
1762
+ rb = "f::(42)"
1763
+ assert_parse rb, pt
1764
+ end
1765
+
1766
+ def test_unary_plus_on_literal
1767
+ rb = "+:a"
1768
+ pt = s(:call, s(:lit, :a), :+@)
1769
+
1770
+ assert_parse rb, pt
1771
+ end
1772
+ end