redparse 0.8.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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