1# frozen_string_literal: true
2begin
3  require_relative 'dummyparser'
4  require 'test/unit'
5  ripper_test = true
6  module TestRipper; end
7rescue LoadError
8end
9
10class TestRipper::ParserEvents < Test::Unit::TestCase
11
12  def test_event_coverage
13    dispatched = Ripper::PARSER_EVENTS
14    tested = self.class.instance_methods(false).grep(/\Atest_(\w+)/) {$1.intern}
15    assert_empty dispatched-tested
16  end
17
18  def parse(str, nm = nil, &bl)
19    dp = DummyParser.new(str)
20    dp.hook(*nm, &bl) if nm
21    dp.parse.to_s
22  end
23
24  def compile_error(str)
25    parse(str, :compile_error) {|e, msg| return msg}
26  end
27
28  def warning(str)
29    parse(str, :warning) {|e, *args| return args}
30  end
31
32  def warn(str)
33    parse(str, :warn) {|e, *args| return args}
34  end
35
36  def test_program
37    thru_program = false
38    assert_equal '[void()]', parse('', :on_program) {thru_program = true}
39    assert_equal true, thru_program
40  end
41
42  def test_stmts_new
43    assert_equal '[void()]', parse('')
44  end
45
46  def test_stmts_add
47    assert_equal '[ref(nil)]', parse('nil')
48    assert_equal '[ref(nil),ref(nil)]', parse('nil;nil')
49    assert_equal '[ref(nil),ref(nil),ref(nil)]', parse('nil;nil;nil')
50  end
51
52  def test_void_stmt
53    assert_equal '[void()]', parse('')
54    assert_equal '[void()]', parse('; ;')
55  end
56
57  def test_var_ref
58    assert_equal '[assign(var_field(a),ref(a))]', parse('a=a')
59    assert_equal '[ref(nil)]', parse('nil')
60    assert_equal '[ref(true)]', parse('true')
61  end
62
63  def test_vcall
64    assert_equal '[vcall(a)]', parse('a')
65  end
66
67  def test_BEGIN
68    assert_equal '[BEGIN([void()])]', parse('BEGIN{}')
69    assert_equal '[BEGIN([ref(nil)])]', parse('BEGIN{nil}')
70  end
71
72  def test_END
73    assert_equal '[END([void()])]', parse('END{}')
74    assert_equal '[END([ref(nil)])]', parse('END{nil}')
75  end
76
77  def test_alias
78    assert_equal '[alias(symbol_literal(a),symbol_literal(b))]', parse('alias a b')
79  end
80
81  def test_var_alias
82    assert_equal '[valias($a,$g)]', parse('alias $a $g')
83  end
84
85  def test_alias_error
86    assert_equal '[aliaserr(valias($a,$1))]', parse('alias $a $1')
87  end
88
89  def test_arglist
90    assert_equal '[fcall(m,[])]', parse('m()')
91    assert_equal '[fcall(m,[1])]', parse('m(1)')
92    assert_equal '[fcall(m,[1,2])]', parse('m(1,2)')
93    assert_equal '[fcall(m,[*vcall(r)])]', parse('m(*r)')
94    assert_equal '[fcall(m,[1,*vcall(r)])]', parse('m(1,*r)')
95    assert_equal '[fcall(m,[1,2,*vcall(r)])]', parse('m(1,2,*r)')
96    assert_equal '[fcall(m,[&vcall(r)])]', parse('m(&r)')
97    assert_equal '[fcall(m,[1,&vcall(r)])]', parse('m(1,&r)')
98    assert_equal '[fcall(m,[1,2,&vcall(r)])]', parse('m(1,2,&r)')
99    assert_equal '[fcall(m,[*vcall(a),&vcall(b)])]', parse('m(*a,&b)')
100    assert_equal '[fcall(m,[1,*vcall(a),&vcall(b)])]', parse('m(1,*a,&b)')
101    assert_equal '[fcall(m,[1,2,*vcall(a),&vcall(b)])]', parse('m(1,2,*a,&b)')
102  end
103
104  def test_args_add
105    thru_args_add = false
106    parse('m(a)', :on_args_add) {thru_args_add = true}
107    assert_equal true, thru_args_add
108  end
109
110  def test_args_add_block
111    thru_args_add_block = false
112    parse('m(&b)', :on_args_add_block) {thru_args_add_block = true}
113    assert_equal true, thru_args_add_block
114  end
115
116  def test_args_add_star
117    thru_args_add_star = false
118    parse('m(*a)', :on_args_add_star) {thru_args_add_star = true}
119    assert_equal true, thru_args_add_star
120    thru_args_add_star = false
121    parse('m(*a, &b)', :on_args_add_star) {thru_args_add_star = true}
122    assert_equal true, thru_args_add_star
123  end
124
125  def test_args_new
126    thru_args_new = false
127    parse('m()', :on_args_new) {thru_args_new = true}
128    assert_equal true, thru_args_new
129  end
130
131  def test_arg_paren
132    # FIXME
133  end
134
135  def test_aref
136    assert_equal '[aref(vcall(v),[1])]', parse('v[1]')
137    assert_equal '[aref(vcall(v),[1,2])]', parse('v[1,2]')
138  end
139
140  def test_assoclist_from_args
141    thru_assoclist_from_args = false
142    parse('{a=>b}', :on_assoclist_from_args) {thru_assoclist_from_args = true}
143    assert_equal true, thru_assoclist_from_args
144  end
145
146  def test_assocs
147    assert_equal '[fcall(m,[assocs(assoc(1,2))])]', parse('m(1=>2)')
148    assert_equal '[fcall(m,[assocs(assoc(1,2),assoc(3,4))])]', parse('m(1=>2,3=>4)')
149    assert_equal '[fcall(m,[3,assocs(assoc(1,2))])]', parse('m(3,1=>2)')
150  end
151
152  def test_assoc_new
153    thru_assoc_new = false
154    parse('{a=>b}', :on_assoc_new) {thru_assoc_new = true}
155    assert_equal true, thru_assoc_new
156  end
157
158  def test_assoc_splat
159    thru_assoc_splat = false
160    parse('m(**h)', :on_assoc_splat) {thru_assoc_splat = true}
161    assert_equal true, thru_assoc_splat
162  end
163
164  def test_aref_field
165    assert_equal '[assign(aref_field(vcall(a),[1]),2)]', parse('a[1]=2')
166  end
167
168  def test_arg_ambiguous
169    thru_arg_ambiguous = false
170    parse('m //', :on_arg_ambiguous) {thru_arg_ambiguous = true}
171    assert_equal true, thru_arg_ambiguous
172  end
173
174  def test_operator_ambiguous
175    thru_operator_ambiguous = false
176    token = syntax = nil
177    parse('a=1; a %[]', :on_operator_ambiguous) {|*a|
178      thru_operator_ambiguous = true
179      _, token, syntax = *a
180    }
181    assert_equal true, thru_operator_ambiguous
182    assert_equal :%, token
183    assert_equal "string literal", syntax
184  end
185
186  def test_array   # array literal
187    assert_equal '[array([1,2,3])]', parse('[1,2,3]')
188    assert_equal '[array([abc,def])]', parse('%w[abc def]')
189    assert_equal '[array([abc,def])]', parse('%W[abc def]')
190  end
191
192  def test_assign   # generic assignment
193    assert_equal '[assign(var_field(v),1)]', parse('v=1')
194  end
195
196  def test_assign_error
197    thru_assign_error = false
198    result = parse('self = 1', :on_assign_error) {thru_assign_error = true}
199    assert_equal true, thru_assign_error
200    assert_equal '[assign(assign_error(var_field(self)),1)]', result
201  end
202
203  def test_assign_error_backref
204    thru_assign_error = false
205    result =
206      parse('$` = 1', :on_assign_error) {thru_assign_error = true}
207    assert_equal true, thru_assign_error
208    assert_equal '[assign(assign_error(var_field($`)),1)]', result
209
210    thru_assign_error = false
211    result =
212      parse('$`, _ = 1', :on_assign_error) {thru_assign_error = true}
213    assert_equal true, thru_assign_error
214    assert_equal '[massign([assign_error(var_field($`)),var_field(_)],1)]', result
215  end
216
217  def test_assign_error_const_qualified
218    thru_assign_error = false
219    result =
220      parse('self::X = 1', :on_assign_error) {thru_assign_error = true}
221    assert_equal false, thru_assign_error
222    assert_equal "[assign(const_path_field(ref(self),X),1)]", result
223
224    thru_assign_error = false
225    result =
226      parse("def m\n self::X = 1\nend", :on_assign_error) {thru_assign_error = true}
227    assert_equal true, thru_assign_error
228    assert_include result, "assign_error(const_path_field(ref(self),X))"
229
230    thru_assign_error = false
231    result =
232      parse("def m\n self::X, a = 1, 2\nend", :on_assign_error) {thru_assign_error = true}
233    assert_equal true, thru_assign_error
234    assert_include result, "assign_error(const_path_field(ref(self),X))"
235  end
236
237  def test_assign_error_const
238    thru_assign_error = false
239    result = parse('X = 1', :on_assign_error) {thru_assign_error = true}
240    assert_equal false, thru_assign_error
241    assert_equal "[assign(var_field(X),1)]", result
242
243    thru_assign_error = false
244    result = parse('X, a = 1, 2', :on_assign_error) {thru_assign_error = true}
245    assert_equal false, thru_assign_error
246    assert_include result, "massign([var_field(X),var_field(a)],"
247
248    result = parse("def m\n X = 1\nend", :on_assign_error) {thru_assign_error = true}
249    assert_equal true, thru_assign_error
250    assert_include result, "assign_error(var_field(X))"
251    thru_assign_error = false
252    result = parse("def m\n X, a = 1, 2\nend", :on_assign_error) {thru_assign_error = true}
253    assert_equal true, thru_assign_error
254    assert_include result, "assign_error(var_field(X))"
255  end
256
257  def test_assign_error_const_toplevel
258    thru_assign_error = false
259    parse('::X = 1', :on_assign_error) {thru_assign_error = true}
260    assert_equal false, thru_assign_error
261    parse("def m\n ::X = 1\nend", :on_assign_error) {thru_assign_error = true}
262    assert_equal true, thru_assign_error
263    thru_assign_error = false
264    parse("def m\n ::X, a = 1, 2\nend", :on_assign_error) {thru_assign_error = true}
265    assert_equal true, thru_assign_error
266  end
267
268  def test_bare_assoc_hash
269    thru_bare_assoc_hash = false
270    parse('x[a=>b]', :on_bare_assoc_hash) {thru_bare_assoc_hash = true}
271    assert_equal true, thru_bare_assoc_hash
272    thru_bare_assoc_hash = false
273    parse('x[1, a=>b]', :on_bare_assoc_hash) {thru_bare_assoc_hash = true}
274    assert_equal true, thru_bare_assoc_hash
275    thru_bare_assoc_hash = false
276    parse('x(a=>b)', :on_bare_assoc_hash) {thru_bare_assoc_hash = true}
277    assert_equal true, thru_bare_assoc_hash
278    thru_bare_assoc_hash = false
279    parse('x(1, a=>b)', :on_bare_assoc_hash) {thru_bare_assoc_hash = true}
280    assert_equal true, thru_bare_assoc_hash
281  end
282
283  def test_begin
284    thru_begin = false
285    parse('begin end', :on_begin) {thru_begin = true}
286    assert_equal true, thru_begin
287  end
288
289  %w"and or + - * / % ** | ^ & <=> > >= < <= == === != =~ !~ << >> && ||".each do |op|
290    define_method("test_binary(#{op})") do
291      thru_binary = false
292      parse("a #{op} b", :on_binary) {thru_binary = true}
293      assert_equal true, thru_binary
294    end
295  end
296
297  def test_blockarg
298    thru_blockarg = false
299    parse("def a(&b) end", :on_blockarg) {thru_blockarg = true}
300    assert_equal true, thru_blockarg
301    thru_blockarg = false
302    parse("def a(x, &b) end", :on_blockarg) {thru_blockarg = true}
303    assert_equal true, thru_blockarg
304
305    thru_blockarg = false
306    parse("proc{|&b|}", :on_blockarg) {thru_blockarg = true}
307    assert_equal true, thru_blockarg
308    thru_blockarg = false
309    parse("proc{|x, &b|}", :on_blockarg) {thru_blockarg = true}
310    assert_equal true, thru_blockarg
311    thru_blockarg = false
312    parse("proc{|&b;y|}", :on_blockarg) {thru_blockarg = true}
313    assert_equal true, thru_blockarg
314    thru_blockarg = false
315    parse("proc{|&b,x;y|}", :on_blockarg) {thru_blockarg = true}
316    assert_equal true, thru_blockarg
317
318    thru_blockarg = false
319    parse("proc do |&b| end", :on_blockarg) {thru_blockarg = true}
320    assert_equal true, thru_blockarg
321    thru_blockarg = false
322    parse("proc do |&b, x| end", :on_blockarg) {thru_blockarg = true}
323    assert_equal true, thru_blockarg
324    thru_blockarg = false
325    parse("proc do |&b;y| end", :on_blockarg) {thru_blockarg = true}
326    assert_equal true, thru_blockarg
327    thru_blockarg = false
328    parse("proc do |&b, x;y| end", :on_blockarg) {thru_blockarg = true}
329    assert_equal true, thru_blockarg
330  end
331
332  def test_block_var
333    thru_block_var = false
334    parse("proc{||}", :on_block_var) {thru_block_var = true}
335    assert_equal true, thru_block_var
336    thru_block_var = false
337    parse("proc{| |}", :on_block_var) {thru_block_var = true}
338    assert_equal true, thru_block_var
339    thru_block_var = false
340    parse("proc{|x|}", :on_block_var) {thru_block_var = true}
341    assert_equal true, thru_block_var
342    thru_block_var = false
343    parse("proc{|;y|}", :on_block_var) {thru_block_var = true}
344    assert_equal true, thru_block_var
345    thru_block_var = false
346    parse("proc{|x;y|}", :on_block_var) {thru_block_var = true}
347    assert_equal true, thru_block_var
348
349    thru_block_var = false
350    parse("proc do || end", :on_block_var) {thru_block_var = true}
351    assert_equal true, thru_block_var
352    thru_block_var = false
353    parse("proc do | | end", :on_block_var) {thru_block_var = true}
354    assert_equal true, thru_block_var
355    thru_block_var = false
356    parse("proc do |x| end", :on_block_var) {thru_block_var = true}
357    assert_equal true, thru_block_var
358    thru_block_var = false
359    parse("proc do |;y| end", :on_block_var) {thru_block_var = true}
360    assert_equal true, thru_block_var
361    thru_block_var = false
362    parse("proc do |x;y| end", :on_block_var) {thru_block_var = true}
363    assert_equal true, thru_block_var
364  end
365
366  def test_block_var_add_block
367    # not used
368  end
369
370  def test_block_var_add_star
371    # not used
372  end
373
374  def test_bodystmt
375    thru_bodystmt = false
376    parse("class X\nend", :on_bodystmt) {thru_bodystmt = true}
377    assert_equal true, thru_bodystmt
378  end
379
380  def test_call
381    bug2233 = '[ruby-core:26165]'
382    tree = nil
383
384    thru_call = false
385    assert_nothing_raised {
386      tree = parse("self.foo", :on_call) {thru_call = true}
387    }
388    assert_equal true, thru_call
389    assert_equal "[call(ref(self),.,foo)]", tree
390
391    thru_call = false
392    assert_nothing_raised {
393      tree = parse("self.foo()", :on_call) {thru_call = true}
394    }
395    assert_equal true, thru_call
396    assert_equal "[call(ref(self),.,foo,[])]", tree
397
398    thru_call = false
399    assert_nothing_raised(bug2233) {
400      tree = parse("foo.()", :on_call) {thru_call = true}
401    }
402    assert_equal true, thru_call
403    assert_equal "[call(vcall(foo),.,call,[])]", tree
404
405    thru_call = false
406    assert_nothing_raised {
407      tree = parse("self::foo", :on_call) {thru_call = true}
408    }
409    assert_equal true, thru_call
410    assert_equal "[call(ref(self),::,foo)]", tree
411
412    thru_call = false
413    assert_nothing_raised {
414      tree = parse("self::foo()", :on_call) {thru_call = true}
415    }
416    assert_equal true, thru_call
417    assert_equal "[call(ref(self),::,foo,[])]", tree
418
419    thru_call = false
420    assert_nothing_raised(bug2233) {
421      tree = parse("foo::()", :on_call) {thru_call = true}
422    }
423    assert_equal true, thru_call
424    assert_equal "[call(vcall(foo),::,call,[])]", tree
425
426    thru_call = false
427    tree = parse("self&.foo", :on_call) {thru_call = true}
428    assert_equal true, thru_call
429    assert_equal "[call(ref(self),&.,foo)]", tree
430
431    thru_call = false
432    tree = parse("self&.foo()", :on_call) {thru_call = true}
433    assert_equal true, thru_call
434    assert_equal "[call(ref(self),&.,foo,[])]", tree
435  end
436
437  def test_excessed_comma
438    thru_excessed_comma = false
439    parse("proc{|x,|}", :on_excessed_comma) {thru_excessed_comma = true}
440    assert_equal true, thru_excessed_comma
441    thru_excessed_comma = false
442    parse("proc{|x,y,|}", :on_excessed_comma) {thru_excessed_comma = true}
443    assert_equal true, thru_excessed_comma
444
445    thru_excessed_comma = false
446    parse("proc do |x,| end", :on_excessed_comma) {thru_excessed_comma = true}
447    assert_equal true, thru_excessed_comma
448    thru_excessed_comma = false
449    parse("proc do |x,y,| end", :on_excessed_comma) {thru_excessed_comma = true}
450    assert_equal true, thru_excessed_comma
451  end
452
453  def test_heredoc
454    bug1921 = '[ruby-core:24855]'
455    thru_heredoc_beg = false
456    tree = parse("<""<EOS\nheredoc\nEOS\n", :on_heredoc_beg) {thru_heredoc_beg = true}
457    assert_equal true, thru_heredoc_beg
458    assert_match(/string_content\(\),heredoc\n/, tree, bug1921)
459    heredoc = nil
460    parse("<""<EOS\nheredoc1\nheredoc2\nEOS\n", :on_string_add) {|e, n, s| heredoc = s}
461    assert_equal("heredoc1\nheredoc2\n", heredoc, bug1921)
462    heredoc = nil
463    parse("<""<-EOS\nheredoc1\nheredoc2\n\tEOS\n", :on_string_add) {|e, n, s| heredoc = s}
464    assert_equal("heredoc1\nheredoc2\n", heredoc, bug1921)
465  end
466
467  def test_heredoc_dedent
468    thru_heredoc_dedent = false
469    str = width = nil
470    tree = parse("<""<~EOS\n heredoc\nEOS\n", :on_heredoc_dedent) {|e, s, w|
471      thru_heredoc_dedent = true
472      str = s
473      width = w
474    }
475    assert_equal true, thru_heredoc_dedent
476    assert_match(/string_content\(\), heredoc\n/, tree)
477    assert_equal(1, width)
478  end
479
480  def test_massign
481    thru_massign = false
482    parse("a, b = 1, 2", :on_massign) {thru_massign = true}
483    assert_equal true, thru_massign
484  end
485
486  def test_mlhs_add
487    thru_mlhs_add = false
488    parse("a, b = 1, 2", :on_mlhs_add) {thru_mlhs_add = true}
489    assert_equal true, thru_mlhs_add
490  end
491
492  def test_mlhs_add_star
493    bug2232 = '[ruby-core:26163]'
494    bug4364 = '[ruby-core:35078]'
495
496    thru_mlhs_add_star = false
497    tree = parse("a, *b = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true}
498    assert_equal true, thru_mlhs_add_star
499    assert_include(tree, "massign([var_field(a),*var_field(b)]")
500    thru_mlhs_add_star = false
501    tree = parse("a, *b, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true}
502    assert_equal true, thru_mlhs_add_star
503    assert_include(tree, "massign([var_field(a),*var_field(b),var_field(c)]", bug2232)
504    thru_mlhs_add_star = false
505    tree = parse("a, *, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true}
506    assert_equal true, thru_mlhs_add_star
507    assert_include(tree, "massign([var_field(a),*,var_field(c)]", bug4364)
508    thru_mlhs_add_star = false
509    tree = parse("*b, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true}
510    assert_equal true, thru_mlhs_add_star
511    assert_include(tree, "massign([*var_field(b),var_field(c)]", bug4364)
512    thru_mlhs_add_star = false
513    tree = parse("*, c = 1, 2", :on_mlhs_add_star) {thru_mlhs_add_star = true}
514    assert_equal true, thru_mlhs_add_star
515    assert_include(tree, "massign([*,var_field(c)],", bug4364)
516  end
517
518  def test_mlhs_add_post
519    thru_mlhs_add_post = false
520    tree = parse("a, *b = 1, 2", :on_mlhs_add_post) {thru_mlhs_add_post = true}
521    assert_equal false, thru_mlhs_add_post
522    assert_include(tree, "massign([var_field(a),*var_field(b)],")
523    thru_massign_add_post = false
524    tree = parse("a, *b, c = 1, 2", :on_mlhs_add_post) {thru_mlhs_add_post = true}
525    assert_equal true, thru_mlhs_add_post
526    assert_include(tree, "massign([var_field(a),*var_field(b),var_field(c)],")
527    thru_mlhs_add_post = false
528    tree = parse("a, *, c = 1, 2", :on_mlhs_add_post) {thru_mlhs_add_post = true}
529    assert_equal true, thru_mlhs_add_post
530    assert_include(tree, "massign([var_field(a),*,var_field(c)],")
531    thru_mlhs_add_post = false
532    tree = parse("*b, c = 1, 2", :on_mlhs_add_post) {thru_mlhs_add_post = true}
533    assert_equal true, thru_mlhs_add_post
534    assert_include(tree, "massign([*var_field(b),var_field(c)],")
535    thru_mlhs_add_post = false
536    tree = parse("*, c = 1, 2", :on_mlhs_add_post) {thru_mlhs_add_post = true}
537    assert_equal true, thru_mlhs_add_post
538    assert_include(tree, "massign([*,var_field(c)],")
539  end
540
541  def test_mlhs_new
542    thru_mlhs_new = false
543    parse("a, b = 1, 2", :on_mlhs_new) {thru_mlhs_new = true}
544    assert_equal true, thru_mlhs_new
545  end
546
547  def test_mlhs_paren
548    thru_mlhs_paren = false
549    parse("a, b = 1, 2", :on_mlhs_paren) {thru_mlhs_paren = true}
550    assert_equal false, thru_mlhs_paren
551    thru_mlhs_paren = false
552    parse("(a, b) = 1, 2", :on_mlhs_paren) {thru_mlhs_paren = true}
553    assert_equal true, thru_mlhs_paren
554  end
555
556  def test_brace_block
557    thru_brace_block = false
558    parse('proc {}', :on_brace_block) {thru_brace_block = true}
559    assert_equal true, thru_brace_block
560  end
561
562  def test_break
563    thru_break = false
564    parse('proc {break}', :on_break) {thru_break = true}
565    assert_equal true, thru_break
566  end
567
568  def test_case
569    thru_case = false
570    parse('case foo when true; end', :on_case) {thru_case = true}
571    assert_equal true, thru_case
572  end
573
574  def test_class
575    thru_class = false
576    parse('class Foo; end', :on_class) {thru_class = true}
577    assert_equal true, thru_class
578  end
579
580  def test_class_name_error
581    thru_class_name_error = false
582    parse('class foo; end', :on_class_name_error) {thru_class_name_error = true}
583    assert_equal true, thru_class_name_error
584  end
585
586  def test_command
587    thru_command = false
588    parse('foo a b', :on_command) {thru_command = true}
589    assert_equal true, thru_command
590  end
591
592  def test_command_call
593    thru_command_call = false
594    parse('foo.bar a, b', :on_command_call) {thru_command_call = true}
595    assert_equal true, thru_command_call
596  end
597
598  def test_const_ref
599    thru_const_ref = false
600    parse('class A;end', :on_const_ref) {thru_const_ref = true}
601    assert_equal true, thru_const_ref
602    thru_const_ref = false
603    parse('module A;end', :on_const_ref) {thru_const_ref = true}
604    assert_equal true, thru_const_ref
605  end
606
607  def test_const_path_field
608    thru_const_path_field = false
609    parse('foo::X = 1', :on_const_path_field) {thru_const_path_field = true}
610    assert_equal true, thru_const_path_field
611  end
612
613  def test_const_path_ref
614    thru_const_path_ref = false
615    parse('foo::X', :on_const_path_ref) {thru_const_path_ref = true}
616    assert_equal true, thru_const_path_ref
617  end
618
619  def test_def
620    thru_def = false
621    parse('def foo; end', :on_def) {
622      thru_def = true
623    }
624    assert_equal true, thru_def
625    assert_equal '[def(foo,[],bodystmt([void()]))]', parse('def foo ;end')
626  end
627
628  def test_defined
629    thru_defined = false
630    parse('defined?(x)', :on_defined) {thru_defined = true}
631    assert_equal true, thru_defined
632  end
633
634  def test_defs
635    thru_defs = false
636    tree = parse('def foo.bar; end', :on_defs) {thru_defs = true}
637    assert_equal true, thru_defs
638    assert_equal("[defs(vcall(foo),.,bar,[],bodystmt([void()]))]", tree)
639
640    thru_parse_error = false
641    tree = parse('def foo&.bar; end', :on_parse_error) {thru_parse_error = true}
642    assert_equal(true, thru_parse_error)
643  end
644
645  def test_do_block
646    thru_do_block = false
647    parse('proc do end', :on_do_block) {thru_do_block = true}
648    assert_equal true, thru_do_block
649  end
650
651  def test_dot2
652    thru_dot2 = false
653    parse('a..b', :on_dot2) {thru_dot2 = true}
654    assert_equal true, thru_dot2
655  end
656
657  def test_dot3
658    thru_dot3 = false
659    parse('a...b', :on_dot3) {thru_dot3 = true}
660    assert_equal true, thru_dot3
661  end
662
663  def test_dyna_symbol
664    thru_dyna_symbol = false
665    parse(':"#{foo}"', :on_dyna_symbol) {thru_dyna_symbol = true}
666    assert_equal true, thru_dyna_symbol
667
668    thru_dyna_symbol = false
669    parse('{"#{foo}": 1}', :on_dyna_symbol) {thru_dyna_symbol = true}
670    assert_equal true, thru_dyna_symbol
671  end
672
673  def test_else
674    thru_else = false
675    parse('if foo; bar else zot end', :on_else) {thru_else = true}
676    assert_equal true, thru_else
677  end
678
679  def test_elsif
680    thru_elsif = false
681    parse('if foo; bar elsif qux; zot end', :on_elsif) {thru_elsif = true}
682    assert_equal true, thru_elsif
683  end
684
685  def test_ensure
686    thru_ensure = false
687    parse('begin foo ensure bar end', :on_ensure) {thru_ensure = true}
688    assert_equal true, thru_ensure
689  end
690
691  def test_fcall
692    thru_fcall = false
693    parse('foo()', :on_fcall) {thru_fcall = true}
694    assert_equal true, thru_fcall
695  end
696
697  def test_field
698    thru_field = false
699    parse('foo.x = 1', :on_field) {thru_field = true}
700    assert_equal true, thru_field
701  end
702
703  def test_for
704    thru_for = false
705    parse('for i in foo; end', :on_for) {thru_for = true}
706    assert_equal true, thru_for
707  end
708
709  def test_hash
710    thru_hash = false
711    parse('{1=>2}', :on_hash) {thru_hash = true}
712    assert_equal true, thru_hash
713    thru_hash = false
714    parse('{a: 2}', :on_hash) {thru_hash = true}
715    assert_equal true, thru_hash
716  end
717
718  def test_if
719    thru_if = false
720    parse('if false; end', :on_if) {thru_if = true}
721    assert_equal true, thru_if
722  end
723
724  def test_if_mod
725    thru_if_mod = false
726    parse('nil if nil', :on_if_mod) {thru_if_mod = true}
727    assert_equal true, thru_if_mod
728  end
729
730  def test_ifop
731    thru_ifop = false
732    parse('a ? b : c', :on_ifop) {thru_ifop = true}
733    assert_equal true, thru_ifop
734  end
735
736  def test_lambda
737    thru_lambda = false
738    parse('->{}', :on_lambda) {thru_lambda = true}
739    assert_equal true, thru_lambda
740  end
741
742  def test_magic_comment
743    thru_magic_comment = false
744    parse('# -*- bug-5753: ruby-dev:44984 -*-', :on_magic_comment) {|*x|thru_magic_comment = x}
745    assert_equal [:on_magic_comment, "bug_5753", "ruby-dev:44984"], thru_magic_comment
746  end
747
748  def test_method_add_block
749    thru_method_add_block = false
750    parse('a {}', :on_method_add_block) {thru_method_add_block = true}
751    assert_equal true, thru_method_add_block
752    thru_method_add_block = false
753    parse('a do end', :on_method_add_block) {thru_method_add_block = true}
754    assert_equal true, thru_method_add_block
755  end
756
757  def test_method_add_arg
758    thru_method_add_arg = false
759    parse('a()', :on_method_add_arg) {thru_method_add_arg = true}
760    assert_equal true, thru_method_add_arg
761    thru_method_add_arg = false
762    parse('a {}', :on_method_add_arg) {thru_method_add_arg = true}
763    assert_equal true, thru_method_add_arg
764    thru_method_add_arg = false
765    parse('a.b(1)', :on_method_add_arg) {thru_method_add_arg = true}
766    assert_equal true, thru_method_add_arg
767    thru_method_add_arg = false
768    parse('a::b(1)', :on_method_add_arg) {thru_method_add_arg = true}
769    assert_equal true, thru_method_add_arg
770  end
771
772  def test_module
773    thru_module = false
774    parse('module A; end', :on_module) {thru_module = true}
775    assert_equal true, thru_module
776  end
777
778  def test_mrhs_add
779    thru_mrhs_add = false
780    parse('a = a, b', :on_mrhs_add) {thru_mrhs_add = true}
781    assert_equal true, thru_mrhs_add
782  end
783
784  def test_mrhs_add_star
785    thru_mrhs_add_star = false
786    parse('a = a, *b', :on_mrhs_add_star) {thru_mrhs_add_star = true}
787    assert_equal true, thru_mrhs_add_star
788  end
789
790  def test_mrhs_new
791    thru_mrhs_new = false
792    parse('a = *a', :on_mrhs_new) {thru_mrhs_new = true}
793    assert_equal true, thru_mrhs_new
794  end
795
796  def test_mrhs_new_from_args
797    thru_mrhs_new_from_args = false
798    parse('a = a, b', :on_mrhs_new_from_args) {thru_mrhs_new_from_args = true}
799    assert_equal true, thru_mrhs_new_from_args
800  end
801
802  def test_next
803    thru_next = false
804    parse('a {next}', :on_next) {thru_next = true}
805    assert_equal true, thru_next
806  end
807
808  def test_opassign
809    thru_opassign = false
810    tree = parse('a += b', :on_opassign) {thru_opassign = true}
811    assert_equal true, thru_opassign
812    assert_equal "[opassign(var_field(a),+=,vcall(b))]", tree
813    thru_opassign = false
814    tree = parse('a -= b', :on_opassign) {thru_opassign = true}
815    assert_equal true, thru_opassign
816    assert_equal "[opassign(var_field(a),-=,vcall(b))]", tree
817    thru_opassign = false
818    tree = parse('a *= b', :on_opassign) {thru_opassign = true}
819    assert_equal true, thru_opassign
820    assert_equal "[opassign(var_field(a),*=,vcall(b))]", tree
821    thru_opassign = false
822    tree = parse('a /= b', :on_opassign) {thru_opassign = true}
823    assert_equal true, thru_opassign
824    assert_equal "[opassign(var_field(a),/=,vcall(b))]", tree
825    thru_opassign = false
826    tree = parse('a %= b', :on_opassign) {thru_opassign = true}
827    assert_equal true, thru_opassign
828    assert_equal "[opassign(var_field(a),%=,vcall(b))]", tree
829    thru_opassign = false
830    tree = parse('a **= b', :on_opassign) {thru_opassign = true}
831    assert_equal true, thru_opassign
832    assert_equal "[opassign(var_field(a),**=,vcall(b))]", tree
833    thru_opassign = false
834    tree = parse('a &= b', :on_opassign) {thru_opassign = true}
835    assert_equal true, thru_opassign
836    assert_equal "[opassign(var_field(a),&=,vcall(b))]", tree
837    thru_opassign = false
838    tree = parse('a |= b', :on_opassign) {thru_opassign = true}
839    assert_equal "[opassign(var_field(a),|=,vcall(b))]", tree
840    assert_equal true, thru_opassign
841    thru_opassign = false
842    tree = parse('a <<= b', :on_opassign) {thru_opassign = true}
843    assert_equal true, thru_opassign
844    assert_equal "[opassign(var_field(a),<<=,vcall(b))]", tree
845    thru_opassign = false
846    tree = parse('a >>= b', :on_opassign) {thru_opassign = true}
847    assert_equal true, thru_opassign
848    assert_equal "[opassign(var_field(a),>>=,vcall(b))]", tree
849    thru_opassign = false
850    tree = parse('a &&= b', :on_opassign) {thru_opassign = true}
851    assert_equal true, thru_opassign
852    assert_equal "[opassign(var_field(a),&&=,vcall(b))]", tree
853    thru_opassign = false
854    tree = parse('a ||= b', :on_opassign) {thru_opassign = true}
855    assert_equal true, thru_opassign
856    assert_equal "[opassign(var_field(a),||=,vcall(b))]", tree
857    thru_opassign = false
858    tree = parse('a::X ||= c 1', :on_opassign) {thru_opassign = true}
859    assert_equal true, thru_opassign
860    assert_equal "[opassign(const_path_field(vcall(a),X),||=,command(c,[1]))]", tree
861
862    thru_opassign = false
863    tree = parse("self.foo += 1", :on_opassign) {thru_opassign = true}
864    assert_equal true, thru_opassign
865    assert_equal "[opassign(field(ref(self),.,foo),+=,1)]", tree
866
867    thru_opassign = false
868    tree = parse("self&.foo += 1", :on_opassign) {thru_opassign = true}
869    assert_equal true, thru_opassign
870    assert_equal "[opassign(field(ref(self),&.,foo),+=,1)]", tree
871  end
872
873  def test_opassign_error
874    thru_opassign = []
875    events = [:on_opassign]
876    parse('$~ ||= 1', events) {|a,*b|
877      thru_opassign << a
878    }
879    assert_equal events, thru_opassign
880  end
881
882  def test_param_error
883    thru_param_error = false
884    parse('def foo(A) end', :on_param_error) {thru_param_error = true}
885    assert_equal true, thru_param_error
886    thru_param_error = false
887    parse('def foo($a) end', :on_param_error) {thru_param_error = true}
888    assert_equal true, thru_param_error
889    thru_param_error = false
890    parse('def foo(@a) end', :on_param_error) {thru_param_error = true}
891    assert_equal true, thru_param_error
892    thru_param_error = false
893    parse('def foo(@@a) end', :on_param_error) {thru_param_error = true}
894    assert_equal true, thru_param_error
895  end
896
897  def test_params
898    arg = nil
899    thru_params = false
900    parse('a {||}', :on_params) {|_, *v| thru_params = true; arg = v}
901    assert_equal true, thru_params
902    assert_equal [nil, nil, nil, nil, nil, nil, nil], arg
903    thru_params = false
904    parse('a {|x|}', :on_params) {|_, *v| thru_params = true; arg = v}
905    assert_equal true, thru_params
906    assert_equal [["x"], nil, nil, nil, nil, nil, nil], arg
907    thru_params = false
908    parse('a {|*x|}', :on_params) {|_, *v| thru_params = true; arg = v}
909    assert_equal true, thru_params
910    assert_equal [nil, nil, "*x", nil, nil, nil, nil], arg
911    thru_params = false
912    parse('a {|x: 1|}', :on_params) {|_, *v| thru_params = true; arg = v}
913    assert_equal true, thru_params
914    assert_equal [nil, nil, nil, nil, [["x:", "1"]], nil, nil], arg
915    thru_params = false
916    parse('a {|x:|}', :on_params) {|_, *v| thru_params = true; arg = v}
917    assert_equal true, thru_params
918    assert_equal [nil, nil, nil, nil, [["x:", false]], nil, nil], arg
919    thru_params = false
920    parse('a {|**x|}', :on_params) {|_, *v| thru_params = true; arg = v}
921    assert_equal true, thru_params
922    assert_equal [nil, nil, nil, nil, nil, "**x", nil], arg
923  end
924
925  def test_params_mlhs
926    thru_mlhs = false
927    tree = parse("proc {|(a, b)|}", :on_mlhs_paren) {thru_mlhs = true}
928    assert_equal true, thru_mlhs
929    assert_include(tree, "[mlhs([a,b])]")
930  end
931
932  def test_params_mlhs_add
933    thru_mlhs_add = false
934    tree = parse("proc {|(a, b)|}", :on_mlhs_add) {thru_mlhs_add = true}
935    assert_equal true, thru_mlhs_add
936    assert_include(tree, "[mlhs([a,b])]")
937  end
938
939  def test_params_mlhs_add_star
940    thru_mlhs_add_star = false
941    tree = parse("proc {|(a, *b)|}", :on_mlhs_add_star) {thru_mlhs_add_star = true}
942    assert_equal true, thru_mlhs_add_star
943    assert_include(tree, "[mlhs([a,*b])]")
944    thru_mlhs_add_star = false
945    tree = parse("proc {|(a, *b, c)|}", :on_mlhs_add_star) {thru_mlhs_add_star = true}
946    assert_equal true, thru_mlhs_add_star
947    assert_include(tree, "[mlhs([a,*b,c])]")
948    thru_mlhs_add_star = false
949    tree = parse("proc {|(a, *, c)|}", :on_mlhs_add_star) {thru_mlhs_add_star = true}
950    assert_equal true, thru_mlhs_add_star
951    assert_include(tree, "[mlhs([a,*,c])]")
952    thru_mlhs_add_star = false
953    tree = parse("proc {|(*b, c)|}", :on_mlhs_add_star) {thru_mlhs_add_star = true}
954    assert_equal true, thru_mlhs_add_star
955    assert_include(tree, "[mlhs([*b,c])]")
956    thru_mlhs_add_star = false
957    tree = parse("proc {|(*b)|}", :on_mlhs_add_star) {thru_mlhs_add_star = true}
958    assert_equal true, thru_mlhs_add_star
959    assert_include(tree, "[mlhs([*b])]")
960  end
961
962  def test_params_mlhs_add_post
963    thru_mlhs_add_post = false
964    tree = parse("proc {|(a, *b)|}", :on_mlhs_add_post) {thru_mlhs_add_post = true}
965    assert_equal false, thru_mlhs_add_post
966    assert_include(tree, "mlhs([a,*b])")
967    thru_mlhs_add_post = false
968    tree = parse("proc {|(a, *b, c)|}", :on_mlhs_add_post) {thru_mlhs_add_post = true}
969    assert_equal true, thru_mlhs_add_post
970    assert_include(tree, "mlhs([a,*b,c])")
971    thru_mlhs_add_post = false
972    tree = parse("proc {|(a, *, c)|}", :on_mlhs_add_post) {thru_mlhs_add_post = true}
973    assert_equal true, thru_mlhs_add_post
974    assert_include(tree, "mlhs([a,*,c])")
975    thru_mlhs_add_post = false
976    tree = parse("proc {|(*b, c)|}", :on_mlhs_add_post) {thru_mlhs_add_post = true}
977    assert_equal true, thru_mlhs_add_post
978    assert_include(tree, "mlhs([*b,c])")
979    thru_mlhs_add_post = false
980    tree = parse("proc {|(*, c)|}", :on_mlhs_add_post) {thru_mlhs_add_post = true}
981    assert_equal true, thru_mlhs_add_post
982    assert_include(tree, "mlhs([*,c])")
983  end
984
985  def test_params_mlhs_new
986    thru_mlhs_new = false
987    tree = parse("proc {|(a, b)|}", :on_mlhs_new) {thru_mlhs_new = true}
988    assert_equal true, thru_mlhs_new
989    assert_include(tree, "[mlhs([a,b])]")
990  end
991
992  def test_params_mlhs_paren
993    thru_mlhs_paren = 0
994    tree = parse("proc {|(a, b)|}", :on_mlhs_paren) {thru_mlhs_paren += 1}
995    assert_equal 1, thru_mlhs_paren
996    assert_include(tree, "[mlhs([a,b])]")
997    thru_mlhs_paren = 0
998    tree = parse("proc {|((a, b))|}", :on_mlhs_paren) {thru_mlhs_paren += 1}
999    assert_equal 2, thru_mlhs_paren
1000    assert_include(tree, "[mlhs([a,b])]")
1001  end
1002
1003  def test_paren
1004    thru_paren = false
1005    parse('()', :on_paren) {thru_paren = true}
1006    assert_equal true, thru_paren
1007  end
1008
1009  def test_parse_error
1010    thru_parse_error = false
1011    parse('<>', :on_parse_error) {thru_parse_error = true}
1012    assert_equal true, thru_parse_error
1013  end
1014
1015  def test_qwords_add
1016    thru_qwords_add = false
1017    tree = parse('%w[a]', :on_qwords_add) {thru_qwords_add = true}
1018    assert_equal true, thru_qwords_add
1019    assert_equal '[array([a])]', tree
1020    thru_qwords_add = false
1021    tree = parse('%w[ a ]', :on_qwords_add) {thru_qwords_add = true}
1022    assert_equal true, thru_qwords_add
1023    assert_equal '[array([a])]', tree
1024  end
1025
1026  def test_qsymbols_add
1027    thru_qsymbols_add = false
1028    tree = parse('%i[a]', :on_qsymbols_add) {thru_qsymbols_add = true}
1029    assert_equal true, thru_qsymbols_add
1030    assert_equal '[array([:a])]', tree
1031    thru_qsymbols_add = false
1032    tree = parse('%i[ a ]', :on_qsymbols_add) {thru_qsymbols_add = true}
1033    assert_equal true, thru_qsymbols_add
1034    assert_equal '[array([:a])]', tree
1035  end
1036
1037  def test_symbols_add
1038    thru_symbols_add = false
1039    tree = parse('%I[a]', :on_symbols_add) {thru_symbols_add = true}
1040    assert_equal true, thru_symbols_add
1041    assert_equal '[array([:a])]', tree
1042    thru_symbols_add = false
1043    tree = parse('%I[ a ]', :on_symbols_add) {thru_symbols_add = true}
1044    assert_equal true, thru_symbols_add
1045    assert_equal '[array([:a])]', tree
1046  end
1047
1048  def test_qwords_new
1049    thru_qwords_new = false
1050    parse('%w[]', :on_qwords_new) {thru_qwords_new = true}
1051    assert_equal true, thru_qwords_new
1052  end
1053
1054  def test_qsymbols_new
1055    thru_qsymbols_new = false
1056    parse('%i[]', :on_qsymbols_new) {thru_qsymbols_new = true}
1057    assert_equal true, thru_qsymbols_new
1058  end
1059
1060  def test_symbols_new
1061    thru_symbols_new = false
1062    parse('%I[]', :on_symbols_new) {thru_symbols_new = true}
1063    assert_equal true, thru_symbols_new
1064  end
1065
1066  def test_redo
1067    thru_redo = false
1068    parse('redo', :on_redo) {thru_redo = true}
1069    assert_equal true, thru_redo
1070  end
1071
1072  def test_regexp_add
1073    thru_regexp_add = false
1074    parse('/foo/', :on_regexp_add) {thru_regexp_add = true}
1075    assert_equal true, thru_regexp_add
1076  end
1077
1078  def test_regexp_literal
1079    thru_regexp_literal = false
1080    parse('//', :on_regexp_literal) {thru_regexp_literal = true}
1081    assert_equal true, thru_regexp_literal
1082  end
1083
1084  def test_regexp_new
1085    thru_regexp_new = false
1086    parse('//', :on_regexp_new) {thru_regexp_new = true}
1087    assert_equal true, thru_regexp_new
1088  end
1089
1090  def test_rescue
1091    thru_rescue = false
1092    parsed = parse('begin; 1; rescue => e; 2; end', :on_rescue) {thru_rescue = true}
1093    assert_equal true, thru_rescue
1094    assert_match(/1.*rescue/, parsed)
1095    assert_match(/rescue\(,var_field\(e\),\[2\]\)/, parsed)
1096  end
1097
1098  def test_rescue_class
1099    thru_rescue = false
1100    parsed = parse('begin; 1; rescue RuntimeError => e; 2; end', :on_rescue) {thru_rescue = true}
1101    assert_equal true, thru_rescue
1102    assert_match(/1.*rescue/, parsed)
1103    assert_match(/rescue\(\[ref\(RuntimeError\)\],var_field\(e\),\[2\]\)/, parsed)
1104  end
1105
1106  def test_rescue_mod
1107    thru_rescue_mod = false
1108    parsed = parse('1 rescue 2', :on_rescue_mod) {thru_rescue_mod = true}
1109    assert_equal true, thru_rescue_mod
1110    bug4716 = '[ruby-core:36248]'
1111    assert_equal "[rescue_mod(1,2)]", parsed, bug4716
1112  end
1113
1114  def test_rest_param
1115    thru_rest_param = false
1116    parse('def a(*) end', :on_rest_param) {thru_rest_param = true}
1117    assert_equal true, thru_rest_param
1118    thru_rest_param = false
1119    parse('def a(*x) end', :on_rest_param) {thru_rest_param = true}
1120    assert_equal true, thru_rest_param
1121  end
1122
1123  def test_kwrest_param
1124    thru_kwrest = false
1125    parse('def a(**) end', :on_kwrest_param) {|n, val| thru_kwrest = val}
1126    assert_equal nil, thru_kwrest
1127    thru_kwrest = false
1128    parse('def a(**x) end', :on_kwrest_param) {|n, val| thru_kwrest = val}
1129    assert_equal "x", thru_kwrest
1130  end
1131
1132  def test_retry
1133    thru_retry = false
1134    parse('retry', :on_retry) {thru_retry = true}
1135    assert_equal true, thru_retry
1136  end
1137
1138  def test_return
1139    thru_return = false
1140    parse('return a', :on_return) {thru_return = true}
1141    assert_equal true, thru_return
1142  end
1143
1144  def test_return0
1145    thru_return0 = false
1146    parse('return', :on_return0) {thru_return0 = true}
1147    assert_equal true, thru_return0
1148  end
1149
1150  def test_sclass
1151    thru_sclass = false
1152    parse('class << a; end', :on_sclass) {thru_sclass = true}
1153    assert_equal true, thru_sclass
1154  end
1155
1156  def test_string_add
1157    thru_string_add = false
1158    parse('"aa"', :on_string_add) {thru_string_add = true}
1159    assert_equal true, thru_string_add
1160  end
1161
1162  def test_string_concat
1163    thru_string_concat = false
1164    parse('"a" "b"', :on_string_concat) {thru_string_concat = true}
1165    assert_equal true, thru_string_concat
1166  end
1167
1168  def test_string_content
1169    thru_string_content = false
1170    parse('""', :on_string_content) {thru_string_content = true}
1171    assert_equal true, thru_string_content
1172    thru_string_content = false
1173    parse('"a"', :on_string_content) {thru_string_content = true}
1174    assert_equal true, thru_string_content
1175    thru_string_content = false
1176    parse('%[a]', :on_string_content) {thru_string_content = true}
1177    assert_equal true, thru_string_content
1178    thru_string_content = false
1179    parse('\'a\'', :on_string_content) {thru_string_content = true}
1180    assert_equal true, thru_string_content
1181    thru_string_content = false
1182    parse('%<a>', :on_string_content) {thru_string_content = true}
1183    assert_equal true, thru_string_content
1184    thru_string_content = false
1185    parse('%!a!', :on_string_content) {thru_string_content = true}
1186    assert_equal true, thru_string_content
1187    thru_string_content = false
1188    parse('%q!a!', :on_string_content) {thru_string_content = true}
1189    assert_equal true, thru_string_content
1190    thru_string_content = false
1191    parse('%Q!a!', :on_string_content) {thru_string_content = true}
1192    assert_equal true, thru_string_content
1193  end
1194
1195  def test_string_dvar
1196    thru_string_dvar = false
1197    parse('"#$a"', :on_string_dvar) {thru_string_dvar = true}
1198    assert_equal true, thru_string_dvar
1199    thru_string_dvar = false
1200    parse('\'#$a\'', :on_string_dvar) {thru_string_dvar = true}
1201    assert_equal false, thru_string_dvar
1202    thru_string_dvar = false
1203    parse('"#@a"', :on_string_dvar) {thru_string_dvar = true}
1204    assert_equal true, thru_string_dvar
1205    thru_string_dvar = false
1206    parse('\'#@a\'', :on_string_dvar) {thru_string_dvar = true}
1207    assert_equal false, thru_string_dvar
1208    thru_string_dvar = false
1209    parse('"#@@a"', :on_string_dvar) {thru_string_dvar = true}
1210    assert_equal true, thru_string_dvar
1211    thru_string_dvar = false
1212    parse('\'#@@a\'', :on_string_dvar) {thru_string_dvar = true}
1213    assert_equal false, thru_string_dvar
1214    thru_string_dvar = false
1215    parse('"#$1"', :on_string_dvar) {thru_string_dvar = true}
1216    assert_equal true, thru_string_dvar
1217    thru_string_dvar = false
1218    parse('\'#$1\'', :on_string_dvar) {thru_string_dvar = true}
1219    assert_equal false, thru_string_dvar
1220  end
1221
1222  def test_string_embexpr
1223    thru_string_embexpr = false
1224    parse('"#{}"', :on_string_embexpr) {thru_string_embexpr = true}
1225    assert_equal true, thru_string_embexpr
1226    thru_string_embexpr = false
1227    parse('\'#{}\'', :on_string_embexpr) {thru_string_embexpr = true}
1228    assert_equal false, thru_string_embexpr
1229  end
1230
1231  def test_string_literal
1232    thru_string_literal = false
1233    parse('""', :on_string_literal) {thru_string_literal = true}
1234    assert_equal true, thru_string_literal
1235  end
1236
1237  def test_super
1238    thru_super = false
1239    parse('super()', :on_super) {thru_super = true}
1240    assert_equal true, thru_super
1241  end
1242
1243  def test_symbol
1244    thru_symbol = false
1245    parse(':a', :on_symbol) {thru_symbol = true}
1246    assert_equal true, thru_symbol
1247    thru_symbol = false
1248    parse(':$a', :on_symbol) {thru_symbol = true}
1249    assert_equal true, thru_symbol
1250    thru_symbol = false
1251    parse(':@a', :on_symbol) {thru_symbol = true}
1252    assert_equal true, thru_symbol
1253    thru_symbol = false
1254    parse(':@@a', :on_symbol) {thru_symbol = true}
1255    assert_equal true, thru_symbol
1256    thru_symbol = false
1257    parse(':==', :on_symbol) {thru_symbol = true}
1258    assert_equal true, thru_symbol
1259  end
1260
1261  def test_symbol_literal
1262    thru_symbol_literal = false
1263    parse(':a', :on_symbol_literal) {thru_symbol_literal = true}
1264    assert_equal true, thru_symbol_literal
1265  end
1266
1267  def test_top_const_field
1268    thru_top_const_field = false
1269    parse('::A=1', :on_top_const_field) {thru_top_const_field = true}
1270    assert_equal true, thru_top_const_field
1271  end
1272
1273  def test_top_const_ref
1274    thru_top_const_ref = false
1275    parse('::A', :on_top_const_ref) {thru_top_const_ref = true}
1276    assert_equal true, thru_top_const_ref
1277  end
1278
1279  def test_unary
1280    thru_unary = false
1281    parse('not a 1, 2', :on_unary) {thru_unary = true}
1282    assert_equal true, thru_unary
1283    thru_unary = false
1284    parse('not (a)', :on_unary) {thru_unary = true}
1285    assert_equal true, thru_unary
1286    thru_unary = false
1287    parse('!a', :on_unary) {thru_unary = true}
1288    assert_equal true, thru_unary
1289    thru_unary = false
1290    parse('-10', :on_unary) {thru_unary = true}
1291    assert_equal true, thru_unary
1292    thru_unary = false
1293    parse('-10*2', :on_unary) {thru_unary = true}
1294    assert_equal true, thru_unary
1295    thru_unary = false
1296    parse('-10.1', :on_unary) {thru_unary = true}
1297    assert_equal true, thru_unary
1298    thru_unary = false
1299    parse('-10.1*2', :on_unary) {thru_unary = true}
1300    assert_equal true, thru_unary
1301    thru_unary = false
1302    parse('-a', :on_unary) {thru_unary = true}
1303    assert_equal true, thru_unary
1304    thru_unary = false
1305    parse('+a', :on_unary) {thru_unary = true}
1306    assert_equal true, thru_unary
1307    thru_unary = false
1308    parse('~a', :on_unary) {thru_unary = true}
1309    assert_equal true, thru_unary
1310    thru_unary = false
1311    parse('not()', :on_unary) {thru_unary = true}
1312    assert_equal true, thru_unary
1313  end
1314
1315  def test_undef
1316    thru_undef = false
1317    parse('undef a', :on_undef) {thru_undef = true}
1318    assert_equal true, thru_undef
1319    thru_undef = false
1320    parse('undef <=>', :on_undef) {thru_undef = true}
1321    assert_equal true, thru_undef
1322    thru_undef = false
1323    parse('undef a, b', :on_undef) {thru_undef = true}
1324    assert_equal true, thru_undef
1325  end
1326
1327  def test_unless
1328    thru_unless = false
1329    parse('unless a; end', :on_unless) {thru_unless = true}
1330    assert_equal true, thru_unless
1331  end
1332
1333  def test_unless_mod
1334    thru_unless_mod = false
1335    parse('nil unless a', :on_unless_mod) {thru_unless_mod = true}
1336    assert_equal true, thru_unless_mod
1337  end
1338
1339  def test_until
1340    thru_until = false
1341    parse('until a; end', :on_until) {thru_until = true}
1342    assert_equal true, thru_until
1343  end
1344
1345  def test_until_mod
1346    thru_until_mod = false
1347    parse('nil until a', :on_until_mod) {thru_until_mod = true}
1348    assert_equal true, thru_until_mod
1349  end
1350
1351  def test_var_field
1352    thru_var_field = false
1353    parse('a = 1', :on_var_field) {thru_var_field = true}
1354    assert_equal true, thru_var_field
1355    thru_var_field = false
1356    parse('a += 1', :on_var_field) {thru_var_field = true}
1357    assert_equal true, thru_var_field
1358  end
1359
1360  def test_when
1361    thru_when = false
1362    parse('case a when b; end', :on_when) {thru_when = true}
1363    assert_equal true, thru_when
1364    thru_when = false
1365    parse('case when a; end', :on_when) {thru_when = true}
1366    assert_equal true, thru_when
1367  end
1368
1369  def test_while
1370    thru_while = false
1371    parse('while a; end', :on_while) {thru_while = true}
1372    assert_equal true, thru_while
1373  end
1374
1375  def test_while_mod
1376    thru_while_mod = false
1377    parse('nil while a', :on_while_mod) {thru_while_mod = true}
1378    assert_equal true, thru_while_mod
1379  end
1380
1381  def test_word_add
1382    thru_word_add = false
1383    parse('%W[a]', :on_word_add) {thru_word_add = true}
1384    assert_equal true, thru_word_add
1385  end
1386
1387  def test_word_new
1388    thru_word_new = false
1389    parse('%W[a]', :on_word_new) {thru_word_new = true}
1390    assert_equal true, thru_word_new
1391  end
1392
1393  def test_words_add
1394    thru_words_add = false
1395    tree = parse('%W[a]', :on_words_add) {thru_words_add = true}
1396    assert_equal true, thru_words_add
1397    assert_equal '[array([a])]', tree
1398    thru_words_add = false
1399    tree = parse('%W[ a ]', :on_words_add) {thru_words_add = true}
1400    assert_equal true, thru_words_add
1401    assert_equal '[array([a])]', tree
1402  end
1403
1404  def test_words_new
1405    thru_words_new = false
1406    parse('%W[]', :on_words_new) {thru_words_new = true}
1407    assert_equal true, thru_words_new
1408  end
1409
1410  def test_xstring_add
1411    thru_xstring_add = false
1412    parse('`x`', :on_xstring_add) {thru_xstring_add = true}
1413    assert_equal true, thru_xstring_add
1414  end
1415
1416  def test_xstring_literal
1417    thru_xstring_literal = false
1418    parse('``', :on_xstring_literal) {thru_xstring_literal = true}
1419    assert_equal true, thru_xstring_literal
1420  end
1421
1422  def test_xstring_new
1423    thru_xstring_new = false
1424    parse('``', :on_xstring_new) {thru_xstring_new = true}
1425    assert_equal true, thru_xstring_new
1426  end
1427
1428  def test_yield
1429    thru_yield = false
1430    parse('yield a', :on_yield) {thru_yield = true}
1431    assert_equal true, thru_yield
1432  end
1433
1434  def test_yield0
1435    thru_yield0 = false
1436    parse('yield', :on_yield0) {thru_yield0 = true}
1437    assert_equal true, thru_yield0
1438  end
1439
1440  def test_zsuper
1441    thru_zsuper = false
1442    parse('super', :on_zsuper) {thru_zsuper = true}
1443    assert_equal true, thru_zsuper
1444  end
1445
1446  def test_local_variables
1447    cmd = 'command(w,[regexp_literal(regexp_add(regexp_new(),25 # ),/)])'
1448    div = 'binary(ref(w),/,25)'
1449    bug1939 = '[ruby-core:24923]'
1450
1451    assert_equal("[#{cmd}]", parse('w /25 # /'), bug1939)
1452    assert_equal("[assign(var_field(w),1),#{div}]", parse("w = 1; w /25 # /"), bug1939)
1453    assert_equal("[fcall(p,[],&block([w],[#{div}]))]", parse("p{|w|w /25 # /\n}"), bug1939)
1454    assert_equal("[def(p,[w],bodystmt([#{div}]))]", parse("def p(w)\nw /25 # /\nend"), bug1939)
1455  end
1456
1457  def test_block_variables
1458    assert_equal("[fcall(proc,[],&block([],[void()]))]", parse("proc{|;y|}"))
1459    if defined?(Process::RLIMIT_AS)
1460      dir = File.dirname(__FILE__)
1461      as = (RubyVM::MJIT.enabled? ? 150 : 100) * 1024 * 1024
1462      assert_in_out_err(%W(-I#{dir} -rdummyparser),
1463                        "Process.setrlimit(Process::RLIMIT_AS,#{as}); "\
1464                        "puts DummyParser.new('proc{|;y|!y}').parse",
1465                        ["[fcall(proc,[],&block([],[unary(!,ref(y))]))]"], [], '[ruby-dev:39423]')
1466    end
1467  end
1468
1469  def test_unterminated_regexp
1470    assert_equal("unterminated regexp meets end of file", compile_error('/'))
1471  end
1472
1473  def test_invalid_instance_variable_name
1474    assert_equal("`@1' is not allowed as an instance variable name", compile_error('@1'))
1475    assert_equal("`@%' is not allowed as an instance variable name", compile_error('@%'))
1476    assert_equal("`@' without identifiers is not allowed as an instance variable name", compile_error('@'))
1477  end
1478
1479  def test_invalid_class_variable_name
1480    assert_equal("`@@1' is not allowed as a class variable name", compile_error('@@1'))
1481    assert_equal("`@@%' is not allowed as a class variable name", compile_error('@@%'))
1482    assert_equal("`@@' without identifiers is not allowed as a class variable name", compile_error('@@'))
1483  end
1484
1485  def test_invalid_global_variable_name
1486    assert_equal("`$%' is not allowed as a global variable name", compile_error('$%'))
1487    assert_equal("`$' without identifiers is not allowed as a global variable name", compile_error('$'))
1488  end
1489
1490  def test_warning_ignored_magic_comment
1491    fmt, *args = warning("1; #-*- frozen-string-literal: true -*-")
1492    assert_match(/ignored after any tokens/, fmt)
1493    assert_equal("frozen_string_literal", args[0])
1494  end
1495
1496  def test_warn_cr_in_middle
1497    fmt = nil
1498    assert_warn("") {fmt, = warn("\r;")}
1499    assert_match(/encountered/, fmt)
1500  end
1501
1502  def test_warn_mismatched_indentations
1503    fmt, tokend, tokbeg, line = assert_warning("") {break warn("if true\n  end\n")}
1504    assert_match(/mismatched indentations/, fmt)
1505    assert_equal(["if", "end", 1], [tokbeg, tokend, line])
1506  end
1507end if ripper_test
1508