redparse 0.8.4 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -0
- data/COPYING.LGPL +503 -158
- data/History.txt +192 -0
- data/Makefile +9 -0
- data/README.txt +72 -39
- data/bin/redparse +108 -14
- data/lib/miniredparse.rb +1543 -0
- data/lib/redparse.rb +971 -105
- data/lib/redparse/ReduceWithsFor_RedParse_1_8.rb +17412 -0
- data/lib/redparse/ReduceWithsFor_RedParse_1_9.rb +17633 -0
- data/lib/redparse/babynodes.rb +17 -0
- data/lib/redparse/babyparser.rb +17 -0
- data/lib/redparse/cache.rb +290 -6
- data/lib/redparse/compile.rb +6 -97
- data/lib/redparse/decisiontree.rb +1 -1
- data/lib/redparse/float_accurate_to_s.rb +30 -6
- data/lib/redparse/generate.rb +18 -0
- data/lib/redparse/node.rb +415 -124
- data/lib/redparse/parse_tree_server.rb +20 -2
- data/lib/redparse/problemfiles.rb +1 -1
- data/lib/redparse/pthelper.rb +17 -31
- data/lib/redparse/reg_more_sugar.rb +1 -1
- data/lib/redparse/replacing/parse_tree.rb +30 -0
- data/lib/redparse/replacing/ripper.rb +20 -0
- data/lib/redparse/replacing/ruby_parser.rb +28 -0
- data/lib/redparse/ripper.rb +393 -0
- data/lib/redparse/ripper_sexp.rb +153 -0
- data/lib/redparse/stackableclasses.rb +113 -0
- data/lib/redparse/version.rb +18 -1
- data/redparse.gemspec +29 -9
- data/rplt.txt +31 -0
- data/test/data/hd_with_blank_string.rb +3 -0
- data/test/data/pt_known_output.rb +13273 -0
- data/test/data/wp.pp +0 -0
- data/test/generate_parse_tree_server_rc.rb +17 -0
- data/test/rp-locatetest.rb +2 -2
- data/test/test_1.9.rb +338 -35
- data/test/test_all.rb +22 -3
- data/test/test_part.rb +32 -0
- data/test/test_redparse.rb +396 -74
- data/test/test_xform_tree.rb +18 -0
- data/test/unparse_1.9_exceptions.txt +85 -0
- data/test/unparse_1.9_exceptions.txt.old +81 -0
- metadata +71 -46
- data/Rakefile +0 -35
data/test/test_all.rb
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
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
|
data/test/test_part.rb
ADDED
@@ -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
|
+
|
data/test/test_redparse.rb
CHANGED
@@ -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
|
144
|
+
@@known_errors<<x
|
46
145
|
else
|
47
|
-
@@known_errors=
|
48
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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}
|
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",
|
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=/((
|
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}
|
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}: #{
|
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
|
4179
|
+
@@known_ruby_bugs<<x
|
3847
4180
|
else
|
3848
|
-
|
3849
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
4004
|
-
|
4005
|
-
|
4006
|
-
|
4007
|
-
|
4008
|
-
|
4009
|
-
|
4010
|
-
|
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
|
-
|
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
|
-
|
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
|