redparse 0.8.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -0
  2. data/COPYING.LGPL +503 -158
  3. data/History.txt +192 -0
  4. data/Makefile +9 -0
  5. data/README.txt +72 -39
  6. data/bin/redparse +108 -14
  7. data/lib/miniredparse.rb +1543 -0
  8. data/lib/redparse.rb +971 -105
  9. data/lib/redparse/ReduceWithsFor_RedParse_1_8.rb +17412 -0
  10. data/lib/redparse/ReduceWithsFor_RedParse_1_9.rb +17633 -0
  11. data/lib/redparse/babynodes.rb +17 -0
  12. data/lib/redparse/babyparser.rb +17 -0
  13. data/lib/redparse/cache.rb +290 -6
  14. data/lib/redparse/compile.rb +6 -97
  15. data/lib/redparse/decisiontree.rb +1 -1
  16. data/lib/redparse/float_accurate_to_s.rb +30 -6
  17. data/lib/redparse/generate.rb +18 -0
  18. data/lib/redparse/node.rb +415 -124
  19. data/lib/redparse/parse_tree_server.rb +20 -2
  20. data/lib/redparse/problemfiles.rb +1 -1
  21. data/lib/redparse/pthelper.rb +17 -31
  22. data/lib/redparse/reg_more_sugar.rb +1 -1
  23. data/lib/redparse/replacing/parse_tree.rb +30 -0
  24. data/lib/redparse/replacing/ripper.rb +20 -0
  25. data/lib/redparse/replacing/ruby_parser.rb +28 -0
  26. data/lib/redparse/ripper.rb +393 -0
  27. data/lib/redparse/ripper_sexp.rb +153 -0
  28. data/lib/redparse/stackableclasses.rb +113 -0
  29. data/lib/redparse/version.rb +18 -1
  30. data/redparse.gemspec +29 -9
  31. data/rplt.txt +31 -0
  32. data/test/data/hd_with_blank_string.rb +3 -0
  33. data/test/data/pt_known_output.rb +13273 -0
  34. data/test/data/wp.pp +0 -0
  35. data/test/generate_parse_tree_server_rc.rb +17 -0
  36. data/test/rp-locatetest.rb +2 -2
  37. data/test/test_1.9.rb +338 -35
  38. data/test/test_all.rb +22 -3
  39. data/test/test_part.rb +32 -0
  40. data/test/test_redparse.rb +396 -74
  41. data/test/test_xform_tree.rb +18 -0
  42. data/test/unparse_1.9_exceptions.txt +85 -0
  43. data/test/unparse_1.9_exceptions.txt.old +81 -0
  44. metadata +71 -46
  45. data/Rakefile +0 -35
@@ -1,3 +1,22 @@
1
- require 'test/test_redparse'
2
- #require 'test/test_xform_tree' #these are broken, gyaaah, not actually used
3
- #require 'test/test_1.9' #should be enabled eventually, too many broken cases for now
1
+ =begin copyright
2
+ redparse - a ruby parser written in ruby
3
+ Copyright (C) 2008,2009, 2012, 2016 Caleb Clausen
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Lesser General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public License
16
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ =end
18
+
19
+ $:.push File.expand_path(File.dirname(__FILE__))
20
+ require 'test_redparse'
21
+ #require 'test_xform_tree' #these are broken, gyaaah, not actually used
22
+ require 'test_1.9' #should be enabled eventually, too many broken cases for now
@@ -0,0 +1,32 @@
1
+ =begin copyright
2
+ redparse - a ruby parser written in ruby
3
+ Copyright (C) 2008,2009, 2012, 2016 Caleb Clausen
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Lesser General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Lesser General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Lesser General Public License
16
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ =end
18
+
19
+ $:.push File.expand_path(File.dirname(__FILE__))
20
+ require 'test_redparse'
21
+
22
+ HASH=(ENV['PART']||0).to_i
23
+ ObjectSpace.each_object(Class){|k|
24
+ next unless k<=Test::Unit::TestCase
25
+ kn=k.name
26
+ k.instance_methods.each{|m| mm=m.to_s
27
+ if /^test_/===mm and (mm+kn).hash.&(0xFF) != HASH
28
+ k.instance_eval{undef_method(m.to_sym)}
29
+ end
30
+ }
31
+ }
32
+
@@ -1,6 +1,6 @@
1
- =begin
1
+ =begin copyright
2
2
  redparse - a ruby parser written in ruby
3
- Copyright (C) 2008 Caleb Clausen
3
+ Copyright (C) 2008, 2012, 2016 Caleb Clausen
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -19,7 +19,77 @@
19
19
 
20
20
  $VERBOSE=1
21
21
  $Debug=1
22
+
22
23
  require 'test/unit'
24
+
25
+ if ENV['MULTIPROCESS'] #or ENV['MANGLE']
26
+ def (Test::Unit).run?; true end #the sense of this flag is inverted
27
+ filters=(0..0xFF).map{|h|
28
+ #exit Test::Unit::AutoRunner.run{|r| r.filters<<
29
+ proc{|tc| tc.method_name.+(tc.class.name).hash&0xFF==h} #}
30
+ }
31
+ Test::Unit::AutoRunner.run{|r| r.filters<<filters.pop }
32
+ at_exit do
33
+
34
+ workers=[]
35
+
36
+ sock2idx={}
37
+ results=[]
38
+ 10.times{
39
+ si,co=IO.pipe
40
+ so,ci=IO.pipe
41
+ sock2idx[ci]=workers.size
42
+ workers<<co
43
+ results<<ci
44
+ fork{
45
+ #co.close
46
+ #ci.close
47
+ r=si
48
+ while l=r.gets
49
+ i=l.to_i
50
+ begin
51
+ p :autorunner
52
+ Test::Unit::AutoRunner.run{|r| r.filters<<filters[i] }
53
+ rescue Exception=>e
54
+ puts "ar error!"
55
+ so.puts "error: #{e.message}\t#{e.backtrace.join(%<\t>)}".gsub("\n","\t")
56
+ else
57
+ puts "ar done"
58
+ so.puts 'done'
59
+ end
60
+ end
61
+ exit!
62
+ }
63
+ #si.close
64
+ #so.close
65
+ filters.pop
66
+ co.puts filters.size.to_s
67
+ }
68
+ until filters.empty?
69
+ readable,=IO.select(results)
70
+ p readable
71
+ readable.each{|rd|
72
+ l=rd.gets
73
+ if /\Aerror: /===l
74
+ l[0,7]=''
75
+ l.gsub!("\t","\n")
76
+ warn "exception in autorunner instance:"
77
+ warn l
78
+ elsif /\Adone\Z/===l
79
+ sockidx=sock2idx[rd]
80
+ filter=filters.pop
81
+ i=filters.size
82
+ workers[sockidx].puts i.to_s
83
+ else fail "expected done or error in: '#{l.chomp}'"
84
+ end
85
+ }
86
+ end
87
+ readable.each{|rd| rd.close}
88
+
89
+ exit
90
+ end
91
+ end
92
+
23
93
  #require 'parse_tree'
24
94
  require 'tempfile'
25
95
  begin
@@ -31,21 +101,53 @@ end
31
101
  require "redparse"
32
102
  require "redparse/pthelper"
33
103
  require "rubylexer/test/testcases"
104
+ require File.expand_path(__FILE__+"/../data/pt_known_output")
105
+ require_relative 'ptlog' if ENV['PTLOG']
34
106
 
35
107
  $VERBOSE=1
36
108
 
109
+ begin
110
+ require 'test/unit/ui/console/testrunner'
111
+ class Test::Unit::UI::Console::TestRunner
112
+ @@Extra_Summarizers=[]
113
+ alias finished__without_extra_summaries finished
114
+ def finished x
115
+ print "\nTests complete\n"
116
+ @@Extra_Summarizers.each{|sz| sz[x] }
117
+ finished__without_extra_summaries x
118
+ end
119
+ def self.extra_summary &code
120
+ @@Extra_Summarizers<<code
121
+ end
122
+ end
123
+ class Test::Unit::TestCase
124
+ def extra_summary &code
125
+ Test::Unit::UI::Console::TestRunner.extra_summary &code
126
+ end
127
+ end
128
+ rescue LoadError
129
+ class Test::Unit::TestCase
130
+ def extra_summary &code
131
+ at_exit &code
132
+ end
133
+ end
134
+ end
135
+
37
136
  class Test::Unit::TestCase
38
- def known_error
137
+ def known_error x
39
138
  from=caller.first
40
139
  from=from[/ in `.*'\Z/] || from[/\A[^:]*:[^:]*/]
41
- yield
140
+ yield x
42
141
  rescue Test::Unit::AssertionFailedError=>e
43
142
  warn "an expected error occurred in #{from}: #{e.message}"
44
143
  if defined? @@known_errors
45
- @@known_errors+=1
144
+ @@known_errors<<x
46
145
  else
47
- @@known_errors=1
48
- at_exit {warn "!!!UNFIXED KNOWN ERRORS!!!: #@@known_errors"}
146
+ @@known_errors=[x]
147
+ extra_summary {
148
+ warn "!!!UNFIXED KNOWN ERRORS!!!: #{@@known_errors.size}"
149
+ @@known_errors.each{|err| warn " "+err unless err["\n"] }
150
+ }
49
151
  end
50
152
  rescue Exception=>e
51
153
  raise
@@ -55,21 +157,21 @@ class Test::Unit::TestCase
55
157
  @@known_errors_fixed+=1
56
158
  else
57
159
  @@known_errors_fixed=1
58
- at_exit {warn "unexpectedly fixed known errors: #@@known_errors_fixed"}
160
+ extra_summary {warn "unexpectedly fixed known errors: #@@known_errors_fixed"}
59
161
  end
60
162
  end
61
163
 
62
- def known_failure
164
+ def known_failure x
63
165
  from=caller.first
64
166
  from=from[/ in `.*'\Z/] || from[/\A[^:]*:[^:]*/]
65
- yield
167
+ yield x
66
168
  rescue Exception=>e
67
169
  warn "an expected failure occurred in #{from}: #{e}"
68
170
  if defined? @@known_failures
69
171
  @@known_failures+=1
70
172
  else
71
173
  @@known_failures=1
72
- at_exit {warn "!!!UNFIXED KNOWN FAILURES!!!: #@@known_failures"}
174
+ extra_summary {warn "!!!UNFIXED KNOWN FAILURES!!!: #@@known_failures"}
73
175
  end
74
176
  else
75
177
  warn "expected failure in #{from}, but was fixed(?!)"
@@ -77,24 +179,25 @@ class Test::Unit::TestCase
77
179
  @@known_failures_fixed+=1
78
180
  else
79
181
  @@known_failures_fixed=1
80
- at_exit {warn "unexpectedly fixed known failures: #@@known_failures_fixed"}
182
+ extra_summary {warn "unexpectedly fixed known failures: #@@known_failures_fixed"}
81
183
  end
82
184
  end
83
185
 
84
- def slow
186
+ def slow x
85
187
  if ENV['SLOW']
86
- yield
188
+ yield x
87
189
  else
88
190
  if defined? @@slow_spots
89
191
  @@slow_spots+=1
90
192
  else
91
193
  @@slow_spots=1
92
- at_exit {warn "slow test code skipped in #@@slow_spots places. (set SLOW to enable)"}
194
+ extra_summary {warn "slow test code skipped in #@@slow_spots places. (set SLOW to enable)"}
93
195
  end
94
196
  end
95
197
  end
96
198
  end
97
199
 
200
+ if ENV['IMMED']
98
201
  #print output immediately on failing test (at end too....)
99
202
  begin
100
203
  require 'test/unit/ui/console/testrunner'
@@ -117,7 +220,7 @@ class MiniTest::Unit
117
220
  return result
118
221
  end
119
222
  end if defined? MiniTest::Unit
120
-
223
+ end
121
224
 
122
225
  =begin nice idea, don't work yet
123
226
  class Test::Unit::TestResult
@@ -169,7 +272,9 @@ end
169
272
  =end
170
273
 
171
274
  require 'redparse/parse_tree_server'
172
- class ParseTree
275
+ class ParseTree #todo: move this to parse_tree_server.rb.
276
+ #also, slight fork of
277
+ #parse_tree_and_warnings_leaks_stderr in bin/parsetree
173
278
  class<<self
174
279
  include ParseTreeComm
175
280
  def old_fork_server?
@@ -250,7 +355,7 @@ class ParseTree
250
355
  rescue Exception
251
356
  return nil,nil
252
357
  end
253
- raise tree if Exception===tree
358
+ #raise tree if Exception===tree
254
359
  return tree,warnings
255
360
  end
256
361
  end
@@ -296,8 +401,9 @@ class RedParseTest<Test::Unit::TestCase
296
401
  FAILURE_EXAMPLES=[
297
402
  ]
298
403
  RUBYBUG_EXAMPLES=[
299
-
300
404
  #bugs in ruby itself
405
+ "a=a i? -R",
406
+ "b=1;b p %s[jim];",
301
407
  "c do p (110).m end",
302
408
  "p = p m %(1)",
303
409
  "p = p m %(1) ,&t",
@@ -308,6 +414,7 @@ class RedParseTest<Test::Unit::TestCase
308
414
  "z{|| p (1).m}",
309
415
 
310
416
  #bugs in ParseTree
417
+ 'def a c=d=1; end',
311
418
  ' case
312
419
  when 0
313
420
  guecoding
@@ -334,12 +441,23 @@ class RedParseTest<Test::Unit::TestCase
334
441
  'c while d and /8/..2.a?(b)',
335
442
  'c while d and /8/../2.a?(b)/',
336
443
  'a if 1..2',
444
+ 'status, err_args = Documeh_status{fcgi_state = 3; docespond do doc_response =fcgi_state = 1; end }',
445
+ "case;when I; JIS;else case; when sjis__length; EJP ;else 55; end;end",
446
+ "case;when 0;ng = 'JIS';else case; when sjis__length; ding = 'EUC-JP' ;end;end",
447
+ "doc_status, err_args = Documeh_status{fcgi_state = 3; docespond do doc_response =fcgi_state = 1; end }",
337
448
 
338
449
  #not sure which, doesn't really matter anyway
339
450
  "$11111111111111111111111111111111111111111111111111111111111111111111",
451
+ "module Array ([Array]).first::E include M end",
452
+ "module Array ([Array]).first::E include M; end",
453
+ "module Array ([Array]).first::E; end",
340
454
  ]
341
455
 
342
456
  ONELINERS=[
457
+ 'TRUE'...'',
458
+ 'FALSE'...'',
459
+ 'NIL'...'',
460
+ 'n||u n'...'',
343
461
  'yield [a_i, *p] '...'',
344
462
  '0.113725'...'',
345
463
  '0.777777'...'',
@@ -356,7 +474,7 @@ class RedParseTest<Test::Unit::TestCase
356
474
  'module self::A include B; c end'...'',
357
475
  'class a.b.c.d.e.f::Quux; YYY=534 end'...'',
358
476
  'class[Array][0]::Foo; Bazz=556 end'...'',
359
- '=begin\r\nfoo\r\n=end\r\n'...'',
477
+ "=begin\r\nfoo\r\n=end\r\n"...'',
360
478
  'a!`b'...'',
361
479
  'fetch_named { {} }'...'',
362
480
  'def subject::Builder.foo; bar end'...'',
@@ -1610,7 +1728,8 @@ class RedParseTest<Test::Unit::TestCase
1610
1728
  '%W[a #{b} c]'...'',
1611
1729
 
1612
1730
  '"a b c #{d}"'...'',
1613
- '"a b c #{d}\n"'...'',
1731
+ '"a b c #{d}\\n"'...'',
1732
+ %*"a b c \#{d}\n"*...'',
1614
1733
  '"a b c #{d} "'...'',
1615
1734
  '"#{a} b c"'...'',
1616
1735
 
@@ -2856,7 +2975,91 @@ class RedParseTest<Test::Unit::TestCase
2856
2975
  "$-\v"...'',
2857
2976
  '$-[]'...'',
2858
2977
  'a,b=(*c=b,a)'...'',
2859
-
2978
+ '"__A#{a=b,c=d}"'...'',
2979
+ '"#{ * =f,g}"'...'',
2980
+ '"#{*a0 = (*a= c)}"'...'',
2981
+ '"#{*a0= begin a end rescue b0}"'...'',
2982
+ '"#{*a=b rescue c}"'...'',
2983
+ '"#{*a=b}"'...'',
2984
+ '"#{*a[*b]=c}"'...'',
2985
+ '"#{BEGIN{a}}"'...'',
2986
+ '"#{END{a}}"'...'',
2987
+ '"#{a=b,d rescue c}"'...'',
2988
+ '"#{begin begin; ync; p1; end;rr end}"'...'',
2989
+ '"1#{begin; r; t end;p (1).m}2"'...'',
2990
+ 'a=a i? -R'...'',
2991
+ 'begin; r; t end;q p'...'',
2992
+ 'begin; p (1..10).method(:each); rescue b; end.m'...'',
2993
+ 'begin; p (1..10).method(:each); rescue B=>c; end'...'',
2994
+ 'begin begin; ync; p1; end;rr end'...'',
2995
+ '"#{"#{*a0 = (*a= c)}"}"'...'',
2996
+ '"#{ * =f,g}"'...'',
2997
+ 'b=1;b p %s[jim];'...'',
2998
+ '"#{*a=b}"'...'',
2999
+ 'a0 rescue b0=b,d rescue c'...'',
3000
+ 'a0 = ~begin; a; rescue b; end rescue b0'...'',
3001
+ 'def a c=d=1; end'...'',
3002
+ '"#{a=1,2}"'...'',
3003
+ '"#{a,=1}"'...'',
3004
+ 'a0 = ("#{a=b,d rescue c}") rescue b0'...'',
3005
+ 'a.b[]=a=b,c=d'...'',
3006
+ 'a rescue begin; p (1..10).method(:each); rescue b; end.m'...'',
3007
+ 'a rescue a=1,2 rescue 4'...'',
3008
+ 'a rescue a=*b rescue c rescue d'...'',
3009
+ 'a rescue BEGIN {a}'...'',
3010
+ 'a rescue "#{a=b,d rescue c}"'...'',
3011
+ '__END__ #with a comment'...'',
3012
+ '"sdfgfg#{"dfgdh"}";g'...'',
3013
+ '+ ?c;p'...'',
3014
+ '+?c;p'...'',
3015
+ '+:s;p'...'',
3016
+ "+:'s';p"...'',
3017
+ '+/r/;p'...'',
3018
+ '+"r";p'...'',
3019
+ '+++++++++++1;p'...'',
3020
+ '+++++++++++-1;p'...'',
3021
+ '+%s{s};p'...'',
3022
+ '* =f,g rescue b and c'...'',
3023
+ '(begin; r; t end;b;c);d;e;f;(g;h;i)'...'',
3024
+ '(BEGIN {})'...'',
3025
+ '(;1;2;);p'...'',
3026
+ '(/ 1/);p'...'',
3027
+ '(mkk,(a=b,c).kk)=3'...'',
3028
+ '"#{a=b,d rescue c}"'...'',
3029
+ "\r\n\n__END__\n\r\n\r\n\r\n\r\n\r\n"...'',
3030
+ "%\n__END__\n[a]"...'',
3031
+ "?\\\n__END__\n-?"...'',
3032
+ "a0 = def a.\n__END__\n; end rescue b0"...'',
3033
+ "def a.b(c=\n__END__\n); end"...'',
3034
+ "<<x.\n 1111\nx\na0 rescue b0()\n"...'',
3035
+ 'a rescue BEGIN{b}'...'',
3036
+ 'a rescue a=*b rescue c'...'',
3037
+ 'a rescue a rescue a=1,2 rescue 4'...'',
3038
+ 'a rescue a0 = b 1 do end rescue c'...'',
3039
+ 'a0 = ~bend'...'',
3040
+ 'a,((BEGIN {})).w,c=d,e,f'...'',
3041
+ 'a,(* =f,g rescue b and c).w,c=d,e,f'...'',
3042
+ 'a,(a0 rescue b0=b,d rescue c).w=d'...'',
3043
+ 'a[*b]=a=b,c=d'...'',
3044
+ 'class<<a; begin; r; t end;c end'...'',
3045
+ 'def a0unde; undef new, ne; end'...'',
3046
+ 'def a0.a & b; end'...'',
3047
+ 'def a0.a b=c do end; hhh end'...'',
3048
+ 'def a0.a b=c,d=e do f end; end'...'',
3049
+ 'def a0.a b=c,d=e e2 do f end; end'...'',
3050
+ 'def a0.a b=c,d=e e2 e3 do f end; end'...'',
3051
+ 'def a0.a b=c,d=e e2 e3 e4 do f end; end'...'',
3052
+ 'def a0.a b=c,d=e() do f end; end'...'',
3053
+ 'def a0.a( b=c,d=e do f end ); end'...'',
3054
+ 'def a0.a( b=c,d=e() do f end ); end'...'',
3055
+ 'def a0.a*b; end'...'',
3056
+ 'def a0.a* b; end'...'',
3057
+ 'def a0.a * b; end'...'',
3058
+ 'def a0.a&b; end'...'',
3059
+ 'def a0.a& b; end'...'',
3060
+ 'def a0.a & b; end'...'',
3061
+ 'begin undef a,b;rr end'...'',
3062
+ '"foo#{"dfg#{"sdfsd"}" }"; sdfasd'...'',
2860
3063
  ]
2861
3064
 
2862
3065
 
@@ -2929,9 +3132,17 @@ class RedParseTest<Test::Unit::TestCase
2929
3132
  \\"
2930
3133
  foo
2931
3134
 
3135
+ def a1(a2= %s[\
3136
+ ]);end
2932
3137
  END
2933
3138
 
2934
3139
  STANZAS=PASSTHRU_BSLASHES_ENTIRE+%q[
3140
+ "#{p "#{<<-kekerz}#{"foob"
3141
+ zimpler
3142
+ kekerz
3143
+ }"
3144
+ }"
3145
+
2935
3146
  @@anon = Module.new
2936
3147
  class @@anon::I
2937
3148
  bindtextd
@@ -3415,8 +3626,7 @@ end
3415
3626
  assert(!$bad)
3416
3627
  s = "a string"
3417
3628
  s[0..s.size]="another string"
3418
- assert_equal("another string", s)
3419
- s = <<EOS
3629
+ assert_equal("another string", s = <<EOS
3420
3630
  #{
3421
3631
  [1,2,3].join(",")
3422
3632
  }
@@ -3660,6 +3870,92 @@ end
3660
3870
  <<-EOS<<__LINE__
3661
3871
  EOS
3662
3872
 
3873
+ def (
3874
+ __END__
3875
+ ).foo; end
3876
+
3877
+ def (a=
3878
+ __END__
3879
+ ).foo; end
3880
+
3881
+ -0.0
3882
+ __END__
3883
+ **31
3884
+
3885
+ p (M.
3886
+ __END__
3887
+ )
3888
+
3889
+ module
3890
+ __END__
3891
+ ::Foo; end
3892
+
3893
+ a,(%
3894
+ __END__
3895
+ [a]).w,c=d,e,f
3896
+
3897
+ alias :"
3898
+ __END__
3899
+ #{bar}" :"baz#{quux}"
3900
+
3901
+ undef :"
3902
+ __END__
3903
+ #{bar}"
3904
+
3905
+ p Module.
3906
+ __END__
3907
+
3908
+ p (
3909
+ __END__
3910
+ )
3911
+
3912
+ def ( def test_endblockwarn
3913
+ ruby = EnvUtil.rubybin
3914
+ # Use Tempfile to create temporary file path.
3915
+ launcher = Tempfile.new(self.class.name)
3916
+ errout = Tempfile.new(self.class.name)
3917
+ launcher << <<EOF
3918
+ errout = ARGV.shift
3919
+ STDERR.reopen(File.open(errout, "w"))
3920
+ STDERR.sync = true
3921
+ Dir.chdir(#{q(DIR)})
3922
+ cmd = "\\"#{ruby}\\" \\"endblockwarn.rb\\""
3923
+ system(cmd)
3924
+ EOF
3925
+ launcher.close
3926
+ launcherpath = launcher.path
3927
+ errout.close
3928
+ erroutpath = errout.path
3929
+ system("#{q(ruby)} #{q(launcherpath)} #{q(erroutpath)}")
3930
+ expected = <<EOW
3931
+ endblockwarn.rb:2: warning: END in method; use at_exit
3932
+ (eval):2: warning: END in method; use at_exit
3933
+ EOW
3934
+ assert_equal(expected, File.read(erroutpath))
3935
+ # expecting Tempfile to unlink launcher and errout file.
3936
+ end).foo; end
3937
+
3938
+ def ( def test_endblockwarn
3939
+ <<EOF
3940
+ irqDIR
3941
+ cmd
3942
+ EOF
3943
+ <<EOW
3944
+ endblat_exit
3945
+ EOW
3946
+ end).foo; end
3947
+
3948
+ def (
3949
+ <<EOF
3950
+ irqDIR
3951
+ cmd
3952
+ EOF
3953
+ <<EOW
3954
+ endblat_exit
3955
+ EOW
3956
+ ).foo; end
3957
+
3958
+
3663
3959
  ] ##############################END OF STANZAS#################################################
3664
3960
  ###############################################################################################
3665
3961
 
@@ -3725,6 +4021,8 @@ EOS
3725
4021
  'a rescue (...)',
3726
4022
  "((...))",
3727
4023
  'def ((...)).foo; end',
4024
+ 'def a0.(...); end',
4025
+ 'def a0.a1(a2=(...)); end',
3728
4026
  'a0 = (...) rescue b0',
3729
4027
  'a0 = ((...)) rescue b0',
3730
4028
  '(...) #with a comment',
@@ -3736,12 +4034,40 @@ EOS
3736
4034
  "b=1;b (...)",
3737
4035
  "return (...)",
3738
4036
  '"#{(...)}"',
4037
+ '"#{*(...)}"',
4038
+ '*(...)',
4039
+ '*(...)=y',
4040
+ 'a,*((...)).w=d,e,f',
4041
+ 'a,((...)).w,c=d,e,f',
4042
+ '[(...),1,2,3]',
4043
+ '{(...)=>x}',
4044
+ '{x=>(...)}',
4045
+ 'm((...))',
4046
+ 'm (...)',
3739
4047
  ]
3740
4048
  INJECTABLES=[ #take it easy with these too
3741
4049
  'p (1..10).method(:each)',
3742
4050
  'a0 rescue b0',
3743
4051
  'begin; r; t end',
3744
4052
  'a=b,c=d',
4053
+ "\n__END__\n",
4054
+ '* =f,g',
4055
+ '
4056
+ <<-foo
4057
+ xxx
4058
+ foo
4059
+ <<-bar
4060
+ yyy
4061
+ bar
4062
+ ',
4063
+ '
4064
+ <<-foo
4065
+ xxx
4066
+ foo
4067
+ ',
4068
+ 'm;n',
4069
+ 'undef rth, hty',
4070
+ 'alias rth hty',
3745
4071
  ]
3746
4072
  if ENV['MANGLE']
3747
4073
  else
@@ -3750,9 +4076,16 @@ EOS
3750
4076
  puts "warning: most data fuzzing is disabled; set MANGLE to enable"
3751
4077
  end
3752
4078
 
3753
- RUBYIDENT=/((?:$|@@?)?#{RubyLexer::LETTER}#{RubyLexer::LETTER_DIGIT}*[?!]?)/o
4079
+ RUBYIDENT=/((?:\$|@@?)?#{RubyLexer::LETTER}#{RubyLexer::LETTER_DIGIT}*[?!]?)/o
4080
+
4081
+ SEEN_SNIPPETS={}
3754
4082
 
3755
4083
  def self.snippet2testmethod(snippet,wrap=nil)
4084
+ if SEEN_SNIPPETS[snippet]
4085
+ return
4086
+ else
4087
+ SEEN_SNIPPETS[snippet]=1
4088
+ end
3756
4089
  escaped=snippet.gsub(/[\\']/){"\\"+$&}
3757
4090
  safe=escaped.gsub(/([^ -~])/){
3758
4091
  x=$1[0]
@@ -3764,7 +4097,7 @@ EOS
3764
4097
  safe.gsub! /\\\\/,"__"
3765
4098
  safe[/[^ -~]|\\\\/] and fail
3766
4099
  cp="check_parsing '#{escaped}'"
3767
- cp="#{wrap}{#{cp}}" if wrap
4100
+ cp="#{wrap}('#{escaped}'){|x| check_parsing x}" if wrap
3768
4101
  "
3769
4102
  define_method 'test_parsing_of_#{safe}' do
3770
4103
  #puts 'test_parsing_of_#{safe}'
@@ -3836,27 +4169,31 @@ EOS
3836
4169
 
3837
4170
  Test::Unit::AssertionFailedError=MiniTest::Assertion unless defined? Test::Unit::AssertionFailedError
3838
4171
 
3839
- def known_ruby_bug
4172
+ def known_ruby_bug x
3840
4173
  from=caller.first
3841
4174
  from=from[/ in `.*'\Z/] || from[/\A[^:]*:[^:]*/]
3842
- yield
4175
+ yield x
3843
4176
  rescue Test::Unit::AssertionFailedError=>e
3844
- warn "a known bug in MRI reared its head in #{from}: #{e.message}"
4177
+ warn "a known bug in ParseTree/MRI reared its head in #{from}: '#{x unless /\n./===x or x.size>65}'"
3845
4178
  if defined? @@known_ruby_bugs
3846
- @@known_ruby_bugs+=1
4179
+ @@known_ruby_bugs<<x
3847
4180
  else
3848
- @@known_ruby_bugs=1
3849
- at_exit {warn "unfixed bugs in MRI/ParseTree: #@@known_ruby_bugs"}
4181
+ warn e.message
4182
+ @@known_ruby_bugs=[x]
4183
+ extra_summary {
4184
+ warn "unfixed bugs in ParseTree/MRI: #{@@known_ruby_bugs.size}"
4185
+ @@known_ruby_bugs.each{|bug| warn " "+bug unless bug["\n"] }
4186
+ }
3850
4187
  end
3851
4188
  rescue Exception=>e
3852
4189
  raise
3853
4190
  else
3854
- warn "expected bug in MRI in #{from}, but was fixed(?!)"
4191
+ warn "expected bug in ParseTree/MRI in #{from}, but was fixed(?!)"
3855
4192
  if defined? @@known_ruby_bugs_fixed
3856
4193
  @@known_ruby_bugs_fixed+=1
3857
4194
  else
3858
4195
  @@known_ruby_bugs_fixed=1
3859
- at_exit {warn "unexpectedly fixed known MRI/ParseTree bugs: #@@known_ruby_bugs_fixed"}
4196
+ extra_summary {warn "unexpectedly fixed known ParseTree/MRI bugs: #@@known_ruby_bugs_fixed"}
3860
4197
  end
3861
4198
  end
3862
4199
 
@@ -3936,7 +4273,6 @@ EOS
3936
4273
  foo
3937
4274
  "=>[[:str, " \\\\\\\\\\\\'\n"]],
3938
4275
 
3939
-
3940
4276
  }.each_pair{|code,tree|
3941
4277
  assert_equal tree,RedParse.new(code,'-',1,[],:cache_mode=>:none).parse.to_parsetree(:quirks)
3942
4278
  }
@@ -3959,7 +4295,7 @@ EOS
3959
4295
  @@missed_syntax_errors+=1
3960
4296
  else
3961
4297
  @@missed_syntax_errors=1
3962
- at_exit{warn "missed syntax errors: #@@missed_syntax_errors"}
4298
+ extra_summary{warn "missed syntax errors: #@@missed_syntax_errors"}
3963
4299
  end
3964
4300
  #puts "warning: syntax error expected, but none was seen, expression: <<< #{xmpl} >>>" if
3965
4301
  # POWERS_OF_2[@@missed_syntax_errors]
@@ -3979,6 +4315,7 @@ EOS
3979
4315
 
3980
4316
  def ParseTree.server_running_187?
3981
4317
  #@server_running_187||=nil
4318
+ return nil if !defined? @out
3982
4319
  return @server_running_187 unless @server_running_187.nil?
3983
4320
  put :version
3984
4321
  version=get
@@ -3992,41 +4329,25 @@ EOS
3992
4329
  return @server_running_187= version=="1.8.7"
3993
4330
  end
3994
4331
 
4332
+
4333
+
4334
+ @@differed_by_begin=0
3995
4335
  def check_parsing xmpl
3996
- ParseTree.fork_server?
4336
+ xmpl.force_encoding "binary"
3997
4337
  xmpl=xmpl.dup.freeze
3998
4338
  pt_opts=[:quirks]
3999
4339
  pt_opts<<:ruby187 if ParseTree.server_running_187?
4000
4340
  /unparse/===xmpl and warn 'unparse in parser test data!'
4001
4341
  problem_exprs=problem_exprs()
4002
4342
  nodes=warnings=warnings2=nil
4003
- =begin
4004
- xmpl=<<-prefix+xmpl+<<-suffix
4005
- BEGIN{throw :never_exec_parse_data_try1,1}
4006
- BEGIN{throw :never_exec_parse_data_try2,2}
4007
- BEGIN{throw :never_exec_parse_data_try3,3}
4008
- BEGIN{raise "never_exec_parse_data_try4"}
4009
- BEGIN{raise "never_exec_parse_data_try5"}
4010
- prefix
4011
- ;0
4012
- suffix
4013
- =end
4014
- # tree=nil
4015
- # output=false
4016
- # loops=0
4017
- begin
4018
- # output=
4019
- # catch(:never_exec_parse_data_try1){
4020
- # catch(:never_exec_parse_data_try2){
4021
- # catch(:never_exec_parse_data_try3){
4022
- tree,warnings=ParseTree.parse_tree_and_warnings(xmpl)
4023
- # }
4024
- # }
4025
- # }
4026
- # break if loops+=1 > 3
4027
- rescue Interrupt; raise
4028
- rescue Exception=>e
4029
- tree=e
4343
+ if tree=$pt_known_output[xmpl]
4344
+ tree=tree.dup
4345
+ warnings=tree.pop[:warnings] if Array===tree and Hash===tree.last #+[__,+{warnings:String}]
4346
+ else
4347
+ tree,warnings=ParseTree.parse_tree_and_warnings(xmpl)
4348
+ PTLOG.record_pt_output(xmpl,tree,warnings) if ENV['PTLOG']
4349
+ end
4350
+ if Exception===tree
4030
4351
  tree2=nodes=h=nil
4031
4352
  assert_hopefully_raises_Exception(xmpl){
4032
4353
  nodes=RedParse.new(xmpl,"-",1,[],:cache_mode=>:write_only).parse
@@ -4044,8 +4365,14 @@ EOS
4044
4365
  assert true
4045
4366
  else
4046
4367
  assert_equal tree, RedParse.remove_silly_begins(tree2)
4047
- warn "parse_trees differed by a :begin in #{xmpl}"
4048
4368
  differed_by_begin=true
4369
+ if @@differed_by_begin==0 or ENV['DIFFER_BY_BEGIN']
4370
+ warn "parse_trees differed by a :begin in #{xmpl}"
4371
+ extra_summary{warn "differed by begin: #@@differed_by_begin"} unless ENV['DIFFER_BY_BEGIN']
4372
+ elsif @@differed_by_begin==1
4373
+ warn "more parse_trees differ by a :begin (set DIFFER_BY_BEGIN for details)"
4374
+ end
4375
+ @@differed_by_begin+=1
4049
4376
  end
4050
4377
  assert_equal warnings, warnings2 if ENV['WARN_PICKINESS']
4051
4378
  if warnings != warnings2
@@ -4053,7 +4380,7 @@ EOS
4053
4380
  @@mismatched_warnings+=1
4054
4381
  else
4055
4382
  @@mismatched_warnings=1
4056
- at_exit{warn "mismatched warnings: #@@mismatched_warnings (set WARN_PICKINESS for details)"}
4383
+ extra_summary{warn "mismatched warnings: #@@mismatched_warnings (set WARN_PICKINESS for details)"}
4057
4384
  end
4058
4385
  end
4059
4386
  rescue Interrupt; raise
@@ -4063,11 +4390,6 @@ EOS
4063
4390
  problem_exprs.flush
4064
4391
  end
4065
4392
  raise e
4066
- else
4067
- if false and problem_exprs and tree!=tree2
4068
- problem_exprs.write xmpl+"\n"
4069
- problem_exprs.flush
4070
- end
4071
4393
  end #rescue false
4072
4394
 
4073
4395
  end #until output.equal? tree
@@ -4078,7 +4400,7 @@ EOS
4078
4400
  assert_equal nodes,nodes2
4079
4401
 
4080
4402
  begin
4081
- unparsed=nodes.unparse
4403
+ unparsed=nodes.unparse :exact=>true, :linenum=>1
4082
4404
  if unparsed==xmpl
4083
4405
  assert true
4084
4406
  done_already=true
@@ -4095,7 +4417,7 @@ EOS
4095
4417
  @@unparse_mismatched_linenums+=1
4096
4418
  else
4097
4419
  @@unparse_mismatched_linenums=1
4098
- at_exit{warn "unparse mismatched linenums: #@@unparse_mismatched_linenums"}
4420
+ extra_summary{warn "unparse mismatched linenums: #@@unparse_mismatched_linenums"}
4099
4421
  end
4100
4422
  else
4101
4423
  assert true
@@ -4105,7 +4427,7 @@ EOS
4105
4427
  end unless done_already
4106
4428
 
4107
4429
  assert_equal nodes, Marshal.load(Marshal.dump(nodes))
4108
- assert_equal nodes, Ron.load(Ron.dump(nodes)) if defined? Ron
4430
+ #assert_equal nodes, Ron.load(Ron.dump(nodes)) if defined? Ron
4109
4431
  assert_equal nodes, nodes.deep_copy
4110
4432
 
4111
4433
  unless done_already or Exception===tree or differed_by_begin