ParseTree 3.0.1 → 3.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +2 -3
- data/History.txt +14 -1
- data/README.txt +1 -18
- data/bin/parse_tree_show +6 -3
- data/lib/parse_tree.rb +42 -12
- data/lib/parse_tree_extensions.rb +4 -14
- data/lib/unified_ruby.rb +134 -75
- data/test/pt_testcase.rb +151 -55
- data/test/test_parse_tree_extensions.rb +68 -0
- data/test/test_unified_ruby.rb +43 -301
- metadata +3 -3
data/.autotest
CHANGED
@@ -6,9 +6,8 @@ Autotest.add_hook :initialize do |at|
|
|
6
6
|
at.libs << ":../../sexp_processor/dev/lib"
|
7
7
|
at.extra_files << "test/pt_testcase.rb"
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
end
|
9
|
+
at.extra_class_map["TestRawParseTree"] = "test/test_parse_tree.rb"
|
10
|
+
at.extra_class_map["R2RTestCase"] = "test/test_parse_tree_extensions.rb"
|
12
11
|
|
13
12
|
at.add_mapping(/pt_testcase/) do |f, _|
|
14
13
|
at.files_matching(/test_.*rb$/)
|
data/History.txt
CHANGED
@@ -1,6 +1,19 @@
|
|
1
|
+
=== 3.0.2 / 2008-11-04
|
2
|
+
|
3
|
+
* 1 minor enhancement:
|
4
|
+
|
5
|
+
* parse_tree_show now defaults to unified, added -U to UNunify output.
|
6
|
+
|
7
|
+
* 4 bug fixes:
|
8
|
+
|
9
|
+
* UnifiedRuby#rewrite_defn kinda sorta deals with cfunc now. Stupid rails.
|
10
|
+
* Fixed ambiguities in splatted nodes in a bunch of contexts.
|
11
|
+
* Fixed 1 arg form of parse_tree_for_proc
|
12
|
+
* KNOWN ISSUE: 0 arg form (||) of parse_tree_for_proc segfaults.
|
13
|
+
|
1
14
|
=== 3.0.1 / 2008-10-23
|
2
15
|
|
3
|
-
* 1 bug fix
|
16
|
+
* 1 bug fix:
|
4
17
|
|
5
18
|
* Fixed the dependency on sexp_processor (accidentally camelcased). thanks ez!
|
6
19
|
|
data/README.txt
CHANGED
@@ -36,9 +36,7 @@ becomes:
|
|
36
36
|
== FEATURES/PROBLEMS:
|
37
37
|
|
38
38
|
* Uses RubyInline, so it just drops in.
|
39
|
-
*
|
40
|
-
* Allows you to write very clean filters.
|
41
|
-
* Includes UnifiedRuby, allowing you to automatically rewrite ruby quirks.
|
39
|
+
* Uses UnifiedRuby by default, automatically rewriting ruby quirks.
|
42
40
|
* ParseTree#parse_tree_for_string lets you parse arbitrary strings of ruby.
|
43
41
|
* Includes parse_tree_show, which lets you quickly snoop code.
|
44
42
|
* echo "1+1" | parse_tree_show -f for quick snippet output.
|
@@ -54,19 +52,6 @@ becomes:
|
|
54
52
|
sexp_array = ParseTree.translate(klass, :method)
|
55
53
|
sexp_array = ParseTree.translate("1+1")
|
56
54
|
|
57
|
-
or:
|
58
|
-
|
59
|
-
class MyProcessor < SexpProcessor
|
60
|
-
def initialize
|
61
|
-
super
|
62
|
-
self.strict = false
|
63
|
-
end
|
64
|
-
def process_lit(exp)
|
65
|
-
val = exp.shift
|
66
|
-
return val
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
55
|
or:
|
71
56
|
|
72
57
|
% ./parse_tree_show myfile.rb
|
@@ -85,8 +70,6 @@ or:
|
|
85
70
|
|
86
71
|
== INSTALL:
|
87
72
|
|
88
|
-
* rake install_gem
|
89
|
-
* sudo rake install
|
90
73
|
* sudo gem install ParseTree
|
91
74
|
|
92
75
|
== LICENSE:
|
data/bin/parse_tree_show
CHANGED
@@ -10,9 +10,11 @@ $h ||= false
|
|
10
10
|
$n ||= false
|
11
11
|
$r ||= false
|
12
12
|
$s ||= false
|
13
|
-
$
|
13
|
+
$U ||= false
|
14
14
|
$n = $n.intern if $n
|
15
15
|
|
16
|
+
$u ||= ! $U
|
17
|
+
|
16
18
|
if $h then
|
17
19
|
puts "usage: #{File.basename $0} [options] [file...]"
|
18
20
|
puts "options:"
|
@@ -21,7 +23,8 @@ if $h then
|
|
21
23
|
puts "-n=node : only display matching nodes"
|
22
24
|
puts "-r : raw arrays, no sexps"
|
23
25
|
puts "-s : structural sexps, strip all content and show bare tree"
|
24
|
-
puts "-u : unified sexps"
|
26
|
+
puts "-u : unified sexps (now the default)"
|
27
|
+
puts "-U : UNunified sexps"
|
25
28
|
|
26
29
|
exit 1
|
27
30
|
end
|
@@ -32,7 +35,7 @@ if $u then
|
|
32
35
|
require 'sexp_processor'
|
33
36
|
require 'unified_ruby'
|
34
37
|
|
35
|
-
class Unifier
|
38
|
+
class Unifier
|
36
39
|
include UnifiedRuby
|
37
40
|
end
|
38
41
|
end
|
data/lib/parse_tree.rb
CHANGED
@@ -43,7 +43,7 @@ end
|
|
43
43
|
|
44
44
|
class RawParseTree
|
45
45
|
|
46
|
-
VERSION = '3.0.
|
46
|
+
VERSION = '3.0.2'
|
47
47
|
|
48
48
|
##
|
49
49
|
# Front end translation method.
|
@@ -258,6 +258,8 @@ class RawParseTree
|
|
258
258
|
builder.include '"st.h"'
|
259
259
|
builder.include '"env.h"'
|
260
260
|
|
261
|
+
builder.prefix '#define _sym(s) ID2SYM(rb_intern((s)))'
|
262
|
+
|
261
263
|
if RUBY_VERSION < "1.8.6" then
|
262
264
|
builder.prefix '#define RARRAY_PTR(s) (RARRAY(s)->ptr)'
|
263
265
|
builder.prefix '#define RARRAY_LEN(s) (RARRAY(s)->len)'
|
@@ -274,7 +276,8 @@ class RawParseTree
|
|
274
276
|
builder.add_compile_flags "-Wno-long-long"
|
275
277
|
|
276
278
|
# NOTE: this flag doesn't work w/ gcc 2.95.x - the FreeBSD default
|
277
|
-
|
279
|
+
builder.add_compile_flags "-Wno-strict-aliasing"
|
280
|
+
|
278
281
|
# ruby.h screws these up hardcore:
|
279
282
|
# builder.add_compile_flags "-Wundef"
|
280
283
|
# builder.add_compile_flags "-Wconversion"
|
@@ -296,12 +299,13 @@ class RawParseTree
|
|
296
299
|
static unsigned case_level = 0;
|
297
300
|
static unsigned when_level = 0;
|
298
301
|
static unsigned inside_case_args = 0;
|
302
|
+
static int masgn_level = 0;
|
299
303
|
}
|
300
304
|
|
301
305
|
builder.prefix %{
|
302
306
|
static VALUE wrap_into_node(const char * name, VALUE val) {
|
303
307
|
VALUE n = rb_ary_new();
|
304
|
-
rb_ary_push(n,
|
308
|
+
rb_ary_push(n, _sym(name));
|
305
309
|
if (val) rb_ary_push(n, val);
|
306
310
|
return n;
|
307
311
|
}
|
@@ -348,7 +352,6 @@ void add_to_parse_tree(VALUE self, VALUE ary, NODE * n, ID * locals) {
|
|
348
352
|
VALUE current;
|
349
353
|
VALUE node_name;
|
350
354
|
static VALUE node_names = Qnil;
|
351
|
-
static int masgn_level = 0;
|
352
355
|
|
353
356
|
if (NIL_P(node_names)) {
|
354
357
|
node_names = rb_const_get_at(rb_path2class("RawParseTree"),rb_intern("NODE_NAMES"));
|
@@ -368,7 +371,7 @@ again:
|
|
368
371
|
(RNODE(node)->u3.node != NULL ? "u3 " : " "));
|
369
372
|
}
|
370
373
|
} else {
|
371
|
-
node_name =
|
374
|
+
node_name = _sym("ICKY");
|
372
375
|
}
|
373
376
|
|
374
377
|
current = rb_ary_new();
|
@@ -518,6 +521,11 @@ again:
|
|
518
521
|
if (node->nd_stts)
|
519
522
|
add_to_parse_tree(self, current, node->nd_stts, locals);
|
520
523
|
|
524
|
+
// if node is newline, it is aref_args w/ a splat, eg: yield([*[1]])
|
525
|
+
if (node->nd_stts && nd_type(node->nd_stts) == NODE_NEWLINE)
|
526
|
+
rb_ary_push(current, Qtrue);
|
527
|
+
|
528
|
+
// array is an array, not list of args
|
521
529
|
if (node->nd_stts
|
522
530
|
&& (nd_type(node->nd_stts) == NODE_ARRAY
|
523
531
|
|| nd_type(node->nd_stts) == NODE_ZARRAY)
|
@@ -639,10 +647,10 @@ again:
|
|
639
647
|
#endif
|
640
648
|
switch (node->nd_mid) {
|
641
649
|
case 0:
|
642
|
-
rb_ary_push(current,
|
650
|
+
rb_ary_push(current, _sym("||"));
|
643
651
|
break;
|
644
652
|
case 1:
|
645
|
-
rb_ary_push(current,
|
653
|
+
rb_ary_push(current, _sym("&&"));
|
646
654
|
break;
|
647
655
|
default:
|
648
656
|
rb_ary_push(current, ID2SYM(node->nd_mid));
|
@@ -657,10 +665,10 @@ again:
|
|
657
665
|
|
658
666
|
switch (node->nd_next->nd_mid) {
|
659
667
|
case 0:
|
660
|
-
rb_ary_push(current,
|
668
|
+
rb_ary_push(current, _sym("||"));
|
661
669
|
break;
|
662
670
|
case 1:
|
663
|
-
rb_ary_push(current,
|
671
|
+
rb_ary_push(current, _sym("&&"));
|
664
672
|
break;
|
665
673
|
default:
|
666
674
|
rb_ary_push(current, ID2SYM(node->nd_next->nd_mid));
|
@@ -1005,8 +1013,8 @@ again:
|
|
1005
1013
|
/* Nothing to do here... we are in an iter block */
|
1006
1014
|
break;
|
1007
1015
|
|
1008
|
-
case NODE_CFUNC:
|
1009
1016
|
case NODE_IFUNC:
|
1017
|
+
case NODE_CFUNC:
|
1010
1018
|
rb_ary_push(current, INT2NUM((long)node->nd_cfnc));
|
1011
1019
|
rb_ary_push(current, INT2NUM(node->nd_argc));
|
1012
1020
|
break;
|
@@ -1040,6 +1048,28 @@ again:
|
|
1040
1048
|
}
|
1041
1049
|
@ # end of add_to_parse_tree block
|
1042
1050
|
|
1051
|
+
builder.c %Q{
|
1052
|
+
static VALUE parse_tree_for_proc(VALUE proc) {
|
1053
|
+
VALUE result = rb_ary_new();
|
1054
|
+
struct BLOCK *data;
|
1055
|
+
Data_Get_Struct(proc, struct BLOCK, data);
|
1056
|
+
|
1057
|
+
rb_ary_push(result, _sym("iter"));
|
1058
|
+
rb_ary_push(result, rb_ary_new3(4, _sym("call"), Qnil, _sym("proc"),
|
1059
|
+
rb_ary_new3(1, _sym("arglist"))));
|
1060
|
+
masgn_level++;
|
1061
|
+
if (data->var) {
|
1062
|
+
add_to_parse_tree(self, result, data->var, NULL);
|
1063
|
+
} else {
|
1064
|
+
rb_ary_push(result, Qnil);
|
1065
|
+
}
|
1066
|
+
add_to_parse_tree(self, result, data->body, NULL);
|
1067
|
+
masgn_level--;
|
1068
|
+
|
1069
|
+
return result;
|
1070
|
+
}
|
1071
|
+
}
|
1072
|
+
|
1043
1073
|
builder.c %Q{
|
1044
1074
|
static VALUE parse_tree_for_meth(VALUE klass, VALUE method, VALUE is_cls_meth) {
|
1045
1075
|
VALUE n;
|
@@ -1060,9 +1090,9 @@ static VALUE parse_tree_for_meth(VALUE klass, VALUE method, VALUE is_cls_meth) {
|
|
1060
1090
|
}
|
1061
1091
|
if (st_lookup(RCLASS(klass)->m_tbl, id, &n)) {
|
1062
1092
|
node = (NODE*)n;
|
1063
|
-
rb_ary_push(result,
|
1093
|
+
rb_ary_push(result, _sym(is_cls_meth ? "defs": "defn"));
|
1064
1094
|
if (is_cls_meth) {
|
1065
|
-
rb_ary_push(result, rb_ary_new3(1,
|
1095
|
+
rb_ary_push(result, rb_ary_new3(1, _sym("self")));
|
1066
1096
|
}
|
1067
1097
|
rb_ary_push(result, ID2SYM(id));
|
1068
1098
|
add_to_parse_tree(self, result, node->nd_body, NULL);
|
@@ -17,7 +17,7 @@ class Method
|
|
17
17
|
unifier = Unifier.new
|
18
18
|
with_class_and_method_name do |klass, method|
|
19
19
|
old_sexp = parser.parse_tree_for_method(klass, method)
|
20
|
-
unifier.process(old_sexp)
|
20
|
+
unifier.process(old_sexp)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -47,20 +47,10 @@ class UnboundMethod
|
|
47
47
|
end
|
48
48
|
|
49
49
|
class Proc
|
50
|
-
def to_method
|
51
|
-
name = ProcStoreTmp.new_name
|
52
|
-
ProcStoreTmp.send(:define_method, name, self)
|
53
|
-
ProcStoreTmp.new.method(name)
|
54
|
-
end
|
55
|
-
|
56
50
|
def to_sexp
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
args = nil if args.size == 1
|
61
|
-
body = body[1] if body.size == 2
|
62
|
-
|
63
|
-
s(:iter, s(:call, nil, :proc, s(:arglist)), args, body)
|
51
|
+
pt = ParseTree.new(false)
|
52
|
+
sexp = pt.parse_tree_for_proc(self)
|
53
|
+
Unifier.new.process(sexp)
|
64
54
|
end
|
65
55
|
|
66
56
|
def to_ruby
|
data/lib/unified_ruby.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'sexp_processor'
|
2
|
+
require 'composite_sexp_processor'
|
2
3
|
|
3
4
|
$TESTING ||= false
|
4
5
|
|
@@ -8,6 +9,17 @@ module UnifiedRuby
|
|
8
9
|
super
|
9
10
|
end
|
10
11
|
|
12
|
+
def rewrite_argscat exp
|
13
|
+
_, ary, val = exp
|
14
|
+
ary = s(:array, ary) unless ary.first == :array
|
15
|
+
ary << s(:splat, val)
|
16
|
+
end
|
17
|
+
|
18
|
+
def rewrite_argspush exp
|
19
|
+
exp[0] = :arglist
|
20
|
+
exp
|
21
|
+
end
|
22
|
+
|
11
23
|
def rewrite_attrasgn(exp)
|
12
24
|
last = exp.last
|
13
25
|
|
@@ -20,42 +32,9 @@ module UnifiedRuby
|
|
20
32
|
exp
|
21
33
|
end
|
22
34
|
|
23
|
-
def
|
24
|
-
exp
|
25
|
-
|
26
|
-
has_splat = exp.masgn.array.splat.lasgn rescue false
|
27
|
-
|
28
|
-
args =
|
29
|
-
if has_splat then
|
30
|
-
arg = exp.masgn(true).array.splat.lasgn.sexp_body
|
31
|
-
raise "nope: #{arg.size}" unless arg.size == 1
|
32
|
-
s(:args, :"*#{arg.last}")
|
33
|
-
else
|
34
|
-
args = exp.lasgn(true)
|
35
|
-
if args then
|
36
|
-
s(:args, *args.sexp_body)
|
37
|
-
else
|
38
|
-
exp.delete_at 1 # nil
|
39
|
-
s(:args)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
exp = s(:scope, s(:block, *exp.sexp_body)) unless exp.block
|
44
|
-
exp.block.insert 1, args
|
45
|
-
exp.find_and_replace_all(:dvar, :lvar)
|
46
|
-
|
47
|
-
exp
|
48
|
-
end
|
49
|
-
|
50
|
-
def rewrite_argscat exp
|
51
|
-
_, ary, val = exp
|
52
|
-
ary = s(:array, ary) unless ary.first == :array
|
53
|
-
ary << s(:splat, val)
|
54
|
-
end
|
55
|
-
|
56
|
-
def rewrite_argspush exp
|
57
|
-
exp[0] = :arglist
|
58
|
-
exp
|
35
|
+
def rewrite_begin(exp)
|
36
|
+
raise "wtf: #{exp.inspect}" if exp.size > 2
|
37
|
+
exp.last
|
59
38
|
end
|
60
39
|
|
61
40
|
def rewrite_block_pass exp
|
@@ -76,6 +55,41 @@ module UnifiedRuby
|
|
76
55
|
exp
|
77
56
|
end
|
78
57
|
|
58
|
+
def rewrite_bmethod(exp)
|
59
|
+
_, args, body = exp
|
60
|
+
|
61
|
+
args ||= s(:array)
|
62
|
+
body ||= s(:block)
|
63
|
+
|
64
|
+
args = s(:args, args) unless args[0] == :array
|
65
|
+
|
66
|
+
args = args[1] if args[1] && args[1][0] == :masgn # TODO: clean up
|
67
|
+
args = args[1] if args[1] && args[1][0] == :array
|
68
|
+
args[0] = :args
|
69
|
+
|
70
|
+
# this is ugly because rewriters are depth first.
|
71
|
+
# TODO: maybe we could come up with some way to do both forms of rewriting.
|
72
|
+
args.map! { |s|
|
73
|
+
if Sexp === s
|
74
|
+
case s[0]
|
75
|
+
when :lasgn then
|
76
|
+
s[1]
|
77
|
+
when :splat then
|
78
|
+
:"*#{s[1][1]}"
|
79
|
+
else
|
80
|
+
raise "huh?: #{s.inspect}"
|
81
|
+
end
|
82
|
+
else
|
83
|
+
s
|
84
|
+
end
|
85
|
+
}
|
86
|
+
|
87
|
+
body = s(:block, body) unless body[0] == :block
|
88
|
+
body.insert 1, args
|
89
|
+
|
90
|
+
s(:scope, body)
|
91
|
+
end
|
92
|
+
|
79
93
|
def rewrite_call(exp)
|
80
94
|
args = exp.last
|
81
95
|
case args
|
@@ -138,9 +152,11 @@ module UnifiedRuby
|
|
138
152
|
|
139
153
|
def rewrite_defn(exp)
|
140
154
|
weirdo = exp.ivar || exp.attrset
|
155
|
+
fbody = exp.fbody(true)
|
156
|
+
|
157
|
+
weirdo ||= fbody.cfunc if fbody
|
141
158
|
|
142
|
-
fbody
|
143
|
-
exp.push(fbody.scope) if fbody
|
159
|
+
exp.push(fbody.scope) if fbody unless weirdo
|
144
160
|
|
145
161
|
args = exp.scope.block.args(true) unless weirdo
|
146
162
|
exp.insert 2, args if args
|
@@ -156,6 +172,8 @@ module UnifiedRuby
|
|
156
172
|
# patch up attr_accessor methods
|
157
173
|
if weirdo then
|
158
174
|
case
|
175
|
+
when fbody && fbody.cfunc then
|
176
|
+
exp.insert 2, s(:args, :"*args")
|
159
177
|
when exp.ivar then
|
160
178
|
exp.insert 2, s(:args)
|
161
179
|
when exp.attrset then
|
@@ -174,7 +192,7 @@ module UnifiedRuby
|
|
174
192
|
# TODO: I think this would be better as rewrite_scope, but that breaks others
|
175
193
|
exp = s(exp.shift, exp.shift,
|
176
194
|
s(:scope,
|
177
|
-
s(:block, exp.scope.args))) if exp.scope.args
|
195
|
+
s(:block, exp.scope.args))) if exp.scope && exp.scope.args
|
178
196
|
|
179
197
|
result = rewrite_defn(exp)
|
180
198
|
result.insert 1, receiver
|
@@ -196,20 +214,25 @@ module UnifiedRuby
|
|
196
214
|
def rewrite_fcall(exp)
|
197
215
|
exp[0] = :call
|
198
216
|
exp.insert 1, nil
|
199
|
-
exp.push nil if exp.size <= 3
|
200
217
|
|
201
218
|
rewrite_call(exp)
|
202
219
|
end
|
203
220
|
|
204
221
|
def rewrite_masgn(exp)
|
205
|
-
raise "wtf: #{exp}" unless exp.size == 4
|
206
|
-
|
222
|
+
raise "wtf: #{exp}" unless exp.size == 4 # TODO: remove 2009-01-29
|
207
223
|
t, lhs, lhs_splat, rhs = exp
|
208
224
|
|
209
225
|
lhs ||= s(:array)
|
210
226
|
|
211
227
|
if lhs_splat then
|
212
|
-
|
228
|
+
case lhs_splat.first
|
229
|
+
when :array then
|
230
|
+
lhs_splat = lhs_splat.last if lhs_splat.last.first == :splat
|
231
|
+
when :splat then
|
232
|
+
# do nothing
|
233
|
+
else
|
234
|
+
lhs_splat = s(:splat, lhs_splat)
|
235
|
+
end
|
213
236
|
lhs << lhs_splat
|
214
237
|
end
|
215
238
|
|
@@ -221,6 +244,25 @@ module UnifiedRuby
|
|
221
244
|
exp
|
222
245
|
end
|
223
246
|
|
247
|
+
def rewrite_resbody(exp)
|
248
|
+
exp[1] ||= s(:array) # no args
|
249
|
+
|
250
|
+
body = exp[2]
|
251
|
+
if body then
|
252
|
+
case body.first
|
253
|
+
when :lasgn, :iasgn then
|
254
|
+
exp[1] << exp.delete_at(2) if body[-1] == s(:gvar, :$!)
|
255
|
+
when :block then
|
256
|
+
exp[1] << body.delete_at(1) if [:lasgn, :iasgn].include?(body[1][0]) &&
|
257
|
+
body[1][-1] == s(:gvar, :$!)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
exp << nil if exp.size == 2 # no body
|
262
|
+
|
263
|
+
exp
|
264
|
+
end
|
265
|
+
|
224
266
|
def rewrite_rescue(exp)
|
225
267
|
# SKETCHY HACK return exp if exp.size > 4
|
226
268
|
ignored = exp.shift
|
@@ -251,28 +293,16 @@ module UnifiedRuby
|
|
251
293
|
s(:rescue, body, *resbodies).compact
|
252
294
|
end
|
253
295
|
|
254
|
-
def
|
255
|
-
|
256
|
-
|
257
|
-
body = exp[2]
|
258
|
-
if body then
|
259
|
-
case body.first
|
260
|
-
when :lasgn, :iasgn then
|
261
|
-
exp[1] << exp.delete_at(2) if body[-1] == s(:gvar, :$!)
|
262
|
-
when :block then
|
263
|
-
exp[1] << body.delete_at(1) if [:lasgn, :iasgn].include?(body[1][0]) &&
|
264
|
-
body[1][-1] == s(:gvar, :$!)
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
exp << nil if exp.size == 2 # no body
|
269
|
-
|
296
|
+
def rewrite_splat(exp)
|
297
|
+
good = [:arglist, :argspush, :array, :svalue, :yield, :super].include? context.first
|
298
|
+
exp = s(:array, exp) unless good
|
270
299
|
exp
|
271
300
|
end
|
272
301
|
|
273
|
-
def
|
274
|
-
|
275
|
-
exp.last
|
302
|
+
def rewrite_super(exp)
|
303
|
+
return exp if exp.structure.flatten.first(3) == [:super, :array, :splat]
|
304
|
+
exp.push(*exp.pop[1..-1]) if exp.size == 2 && exp.last.first == :array
|
305
|
+
exp
|
276
306
|
end
|
277
307
|
|
278
308
|
def rewrite_vcall(exp)
|
@@ -281,18 +311,16 @@ module UnifiedRuby
|
|
281
311
|
end
|
282
312
|
|
283
313
|
def rewrite_yield(exp)
|
284
|
-
|
285
|
-
if exp.size == 3 and exp.pop == true then
|
286
|
-
# exp[1] = s(:arglist, exp[1])
|
287
|
-
elsif exp.size == 2 && exp.last.first == :array then
|
288
|
-
exp.push(*exp.pop[1..-1])
|
289
|
-
end
|
314
|
+
real_array = exp.pop if exp.size == 3
|
290
315
|
|
291
|
-
exp
|
292
|
-
|
316
|
+
if exp.size == 2 then
|
317
|
+
if real_array then
|
318
|
+
exp[-1] = s(:array, exp[-1]) if exp[-1][0] != :array
|
319
|
+
else
|
320
|
+
exp.push(*exp.pop[1..-1]) if exp.last.first == :array
|
321
|
+
end
|
322
|
+
end
|
293
323
|
|
294
|
-
def rewrite_super(exp)
|
295
|
-
exp.push(*exp.pop[1..-1]) if exp.size == 2 && exp.last.first == :array
|
296
324
|
exp
|
297
325
|
end
|
298
326
|
|
@@ -302,10 +330,30 @@ module UnifiedRuby
|
|
302
330
|
end
|
303
331
|
end
|
304
332
|
|
305
|
-
|
306
|
-
|
333
|
+
class PreUnifier < SexpProcessor
|
334
|
+
def initialize
|
335
|
+
super
|
336
|
+
@unsupported.delete :newline
|
337
|
+
end
|
307
338
|
|
308
|
-
|
339
|
+
def rewrite_call exp
|
340
|
+
exp << s(:arglist) if exp.size < 4
|
341
|
+
exp.last[0] = :arglist if exp.last.first == :array
|
342
|
+
exp
|
343
|
+
end
|
344
|
+
|
345
|
+
def rewrite_fcall exp
|
346
|
+
exp << s(:arglist) if exp.size < 3
|
347
|
+
if exp[-1][0] == :array then
|
348
|
+
has_splat = exp[-1].find { |s| Array === s && s.first == :splat }
|
349
|
+
exp[-1] = s(:arglist, exp[-1]) if has_splat
|
350
|
+
exp[-1][0] = :arglist
|
351
|
+
end
|
352
|
+
exp
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
class PostUnifier < SexpProcessor
|
309
357
|
include UnifiedRuby
|
310
358
|
|
311
359
|
def initialize
|
@@ -313,3 +361,14 @@ class Unifier < SexpProcessor
|
|
313
361
|
@unsupported.delete :newline
|
314
362
|
end
|
315
363
|
end
|
364
|
+
|
365
|
+
##
|
366
|
+
# Quick and easy SexpProcessor that unified the sexp structure.
|
367
|
+
|
368
|
+
class Unifier < CompositeSexpProcessor
|
369
|
+
def initialize
|
370
|
+
super
|
371
|
+
self << PreUnifier.new
|
372
|
+
self << PostUnifier.new
|
373
|
+
end
|
374
|
+
end
|
data/test/pt_testcase.rb
CHANGED
@@ -3578,24 +3578,6 @@ class ParseTreeTestCase < Test::Unit::TestCase
|
|
3578
3578
|
s(:call, nil, :c, s(:arglist)),
|
3579
3579
|
s(:call, nil, :d, s(:arglist))))))
|
3580
3580
|
|
3581
|
-
add_tests("rescue_block_body_ivar",
|
3582
|
-
"Ruby" => "begin\n a\nrescue => @e\n c\n d\nend",
|
3583
|
-
"RawParseTree" => [:begin,
|
3584
|
-
[:rescue,
|
3585
|
-
[:vcall, :a],
|
3586
|
-
[:resbody, nil,
|
3587
|
-
[:block,
|
3588
|
-
[:iasgn, :@e, [:gvar, :$!]],
|
3589
|
-
[:vcall, :c],
|
3590
|
-
[:vcall, :d]]]]],
|
3591
|
-
"ParseTree" => s(:rescue,
|
3592
|
-
s(:call, nil, :a, s(:arglist)),
|
3593
|
-
s(:resbody,
|
3594
|
-
s(:array, s(:iasgn, :@e, s(:gvar, :$!))),
|
3595
|
-
s(:block,
|
3596
|
-
s(:call, nil, :c, s(:arglist)),
|
3597
|
-
s(:call, nil, :d, s(:arglist))))))
|
3598
|
-
|
3599
3581
|
add_tests("rescue_block_body_3",
|
3600
3582
|
"Ruby" => "begin\n a\nrescue A\n b\nrescue B\n c\nrescue C\n d\nend",
|
3601
3583
|
"RawParseTree" => [:begin,
|
@@ -3616,6 +3598,24 @@ class ParseTreeTestCase < Test::Unit::TestCase
|
|
3616
3598
|
s(:resbody, s(:array, s(:const, :C)),
|
3617
3599
|
s(:call, nil, :d, s(:arglist)))))
|
3618
3600
|
|
3601
|
+
add_tests("rescue_block_body_ivar",
|
3602
|
+
"Ruby" => "begin\n a\nrescue => @e\n c\n d\nend",
|
3603
|
+
"RawParseTree" => [:begin,
|
3604
|
+
[:rescue,
|
3605
|
+
[:vcall, :a],
|
3606
|
+
[:resbody, nil,
|
3607
|
+
[:block,
|
3608
|
+
[:iasgn, :@e, [:gvar, :$!]],
|
3609
|
+
[:vcall, :c],
|
3610
|
+
[:vcall, :d]]]]],
|
3611
|
+
"ParseTree" => s(:rescue,
|
3612
|
+
s(:call, nil, :a, s(:arglist)),
|
3613
|
+
s(:resbody,
|
3614
|
+
s(:array, s(:iasgn, :@e, s(:gvar, :$!))),
|
3615
|
+
s(:block,
|
3616
|
+
s(:call, nil, :c, s(:arglist)),
|
3617
|
+
s(:call, nil, :d, s(:arglist))))))
|
3618
|
+
|
3619
3619
|
add_tests("rescue_block_nada",
|
3620
3620
|
"Ruby" => "begin\n blah\nrescue\n # do nothing\nend",
|
3621
3621
|
"RawParseTree" => [:begin,
|
@@ -3641,6 +3641,18 @@ class ParseTreeTestCase < Test::Unit::TestCase
|
|
3641
3641
|
nil)))
|
3642
3642
|
|
3643
3643
|
|
3644
|
+
add_tests("rescue_iasgn_var_empty",
|
3645
|
+
"Ruby" => "begin\n 1\nrescue => @e\n # do nothing\nend",
|
3646
|
+
"RawParseTree" => [:begin,
|
3647
|
+
[:rescue,
|
3648
|
+
[:lit, 1],
|
3649
|
+
[:resbody, nil, [:iasgn, :@e, [:gvar, :$!]]]]],
|
3650
|
+
"ParseTree" => s(:rescue,
|
3651
|
+
s(:lit, 1),
|
3652
|
+
s(:resbody,
|
3653
|
+
s(:array, s(:iasgn, :@e, s(:gvar, :$!))),
|
3654
|
+
nil)))
|
3655
|
+
|
3644
3656
|
add_tests("rescue_lasgn",
|
3645
3657
|
"Ruby" => "begin\n 1\nrescue\n var = 2\nend",
|
3646
3658
|
"RawParseTree" => [:begin,
|
@@ -3681,17 +3693,6 @@ class ParseTreeTestCase < Test::Unit::TestCase
|
|
3681
3693
|
s(:array, s(:lasgn, :e, s(:gvar, :$!))),
|
3682
3694
|
nil)))
|
3683
3695
|
|
3684
|
-
add_tests("rescue_iasgn_var_empty",
|
3685
|
-
"Ruby" => "begin\n 1\nrescue => @e\n # do nothing\nend",
|
3686
|
-
"RawParseTree" => [:begin,
|
3687
|
-
[:rescue,
|
3688
|
-
[:lit, 1],
|
3689
|
-
[:resbody, nil, [:iasgn, :@e, [:gvar, :$!]]]]],
|
3690
|
-
"ParseTree" => s(:rescue,
|
3691
|
-
s(:lit, 1),
|
3692
|
-
s(:resbody,
|
3693
|
-
s(:array, s(:iasgn, :@e, s(:gvar, :$!))),
|
3694
|
-
nil)))
|
3695
3696
|
add_tests("retry",
|
3696
3697
|
"Ruby" => "retry",
|
3697
3698
|
"RawParseTree" => [:retry],
|
@@ -3707,6 +3708,11 @@ class ParseTreeTestCase < Test::Unit::TestCase
|
|
3707
3708
|
"RawParseTree" => [:return, [:lit, 1]],
|
3708
3709
|
"ParseTree" => s(:return, s(:lit, 1)))
|
3709
3710
|
|
3711
|
+
add_tests("return_1_splatted",
|
3712
|
+
"Ruby" => "return *1",
|
3713
|
+
"RawParseTree" => [:return, [:svalue, [:splat, [:lit, 1]]]],
|
3714
|
+
"ParseTree" => s(:return, s(:svalue, s(:splat, s(:lit, 1)))))
|
3715
|
+
|
3710
3716
|
add_tests("return_n",
|
3711
3717
|
"Ruby" => "return 1, 2, 3",
|
3712
3718
|
"RawParseTree" => [:return, [:array,
|
@@ -3749,6 +3755,96 @@ class ParseTreeTestCase < Test::Unit::TestCase
|
|
3749
3755
|
s(:call, nil, :a,
|
3750
3756
|
s(:arglist, s(:splat, s(:lvar, :b))))))))
|
3751
3757
|
|
3758
|
+
add_tests("splat_array",
|
3759
|
+
"Ruby" => "[*[1]]",
|
3760
|
+
"RawParseTree" => [:splat, [:array, [:lit, 1]]],
|
3761
|
+
"ParseTree" => s(:array, s(:splat, s(:array, s(:lit, 1)))))
|
3762
|
+
|
3763
|
+
add_tests("splat_break",
|
3764
|
+
"Ruby" => "break *[1]",
|
3765
|
+
"RawParseTree" => [:break, [:svalue, [:splat, [:array, [:lit, 1]]]]],
|
3766
|
+
"ParseTree" => s(:break, s(:svalue, s(:splat, s(:array, s(:lit, 1))))))
|
3767
|
+
|
3768
|
+
add_tests("splat_break_array",
|
3769
|
+
"Ruby" => "break [*[1]]",
|
3770
|
+
"RawParseTree" => [:break, [:splat, [:array, [:lit, 1]]]],
|
3771
|
+
"ParseTree" => s(:break, s(:array, s(:splat, s(:array, s(:lit, 1))))))
|
3772
|
+
|
3773
|
+
add_tests("splat_fcall",
|
3774
|
+
"Ruby" => "meth(*[1])",
|
3775
|
+
"RawParseTree" => [:fcall, :meth,
|
3776
|
+
[:splat, [:array, [:lit, 1]]]],
|
3777
|
+
"ParseTree" => s(:call, nil, :meth,
|
3778
|
+
s(:arglist, s(:splat, s(:array, s(:lit, 1))))))
|
3779
|
+
|
3780
|
+
add_tests("splat_fcall_array",
|
3781
|
+
"Ruby" => "meth([*[1]])",
|
3782
|
+
"RawParseTree" => [:fcall, :meth,
|
3783
|
+
[:array, [:splat, [:array, [:lit, 1]]]]],
|
3784
|
+
"ParseTree" => s(:call, nil, :meth,
|
3785
|
+
s(:arglist,
|
3786
|
+
s(:array, s(:splat, s(:array, s(:lit, 1)))))))
|
3787
|
+
|
3788
|
+
add_tests("splat_lasgn",
|
3789
|
+
"Ruby" => "x = *[1]",
|
3790
|
+
"RawParseTree" => [:lasgn, :x, [:svalue, [:splat, [:array, [:lit, 1]]]]],
|
3791
|
+
"ParseTree" => s(:lasgn, :x, s(:svalue, s(:splat, s(:array, s(:lit, 1))))))
|
3792
|
+
|
3793
|
+
add_tests("splat_lasgn_array",
|
3794
|
+
"Ruby" => "x = [*[1]]",
|
3795
|
+
"RawParseTree" => [:lasgn, :x, [:splat, [:array, [:lit, 1]]]],
|
3796
|
+
"ParseTree" => s(:lasgn, :x, s(:array, s(:splat, s(:array, s(:lit, 1))))))
|
3797
|
+
|
3798
|
+
add_tests("splat_lit_1",
|
3799
|
+
"Ruby" => "[*1]",
|
3800
|
+
"RawParseTree" => [:splat, [:lit, 1]], # UGH - damn MRI
|
3801
|
+
"ParseTree" => s(:array, s(:splat, s(:lit, 1))))
|
3802
|
+
|
3803
|
+
add_tests("splat_lit_n",
|
3804
|
+
"Ruby" => "[1, *2]",
|
3805
|
+
"RawParseTree" => [:argscat, [:array, [:lit, 1]], [:lit, 2]],
|
3806
|
+
"ParseTree" => s(:array, s(:lit, 1), s(:splat, s(:lit, 2))))
|
3807
|
+
|
3808
|
+
add_tests("splat_next",
|
3809
|
+
"Ruby" => "next *[1]",
|
3810
|
+
"RawParseTree" => [:next, [:svalue, [:splat, [:array, [:lit, 1]]]]],
|
3811
|
+
"ParseTree" => s(:next, s(:svalue, s(:splat, s(:array, s(:lit, 1))))))
|
3812
|
+
|
3813
|
+
add_tests("splat_next_array",
|
3814
|
+
"Ruby" => "next [*[1]]",
|
3815
|
+
"RawParseTree" => [:next, [:splat, [:array, [:lit, 1]]]],
|
3816
|
+
"ParseTree" => s(:next, s(:array, s(:splat, s(:array, s(:lit, 1))))))
|
3817
|
+
|
3818
|
+
add_tests("splat_return",
|
3819
|
+
"Ruby" => "return *[1]",
|
3820
|
+
"RawParseTree" => [:return, [:svalue, [:splat, [:array, [:lit, 1]]]]],
|
3821
|
+
"ParseTree" => s(:return, s(:svalue, s(:splat, s(:array, s(:lit, 1))))))
|
3822
|
+
|
3823
|
+
add_tests("splat_return_array",
|
3824
|
+
"Ruby" => "return [*[1]]",
|
3825
|
+
"RawParseTree" => [:return, [:splat, [:array, [:lit, 1]]]],
|
3826
|
+
"ParseTree" => s(:return, s(:array, s(:splat, s(:array, s(:lit, 1))))))
|
3827
|
+
|
3828
|
+
add_tests("splat_super",
|
3829
|
+
"Ruby" => "super(*[1])",
|
3830
|
+
"RawParseTree" => [:super, [:splat, [:array, [:lit, 1]]]],
|
3831
|
+
"ParseTree" => s(:super, s(:splat, s(:array, s(:lit, 1)))))
|
3832
|
+
|
3833
|
+
add_tests("splat_super_array",
|
3834
|
+
"Ruby" => "super([*[1]])",
|
3835
|
+
"RawParseTree" => [:super, [:array, [:splat, [:array, [:lit, 1]]]]],
|
3836
|
+
"ParseTree" => s(:super, s(:array, s(:splat, s(:array, s(:lit, 1))))))
|
3837
|
+
|
3838
|
+
add_tests("splat_yield",
|
3839
|
+
"Ruby" => "yield(*[1])",
|
3840
|
+
"RawParseTree" => [:yield, [:splat, [:array, [:lit, 1]]]],
|
3841
|
+
"ParseTree" => s(:yield, s(:splat, s(:array, s(:lit, 1)))))
|
3842
|
+
|
3843
|
+
add_tests("splat_yield_array",
|
3844
|
+
"Ruby" => "yield([*[1]])",
|
3845
|
+
"RawParseTree" => [:yield, [:splat, [:array, [:lit, 1]]], true],
|
3846
|
+
"ParseTree" => s(:yield, s(:array, s(:splat, s(:array, s(:lit, 1))))))
|
3847
|
+
|
3752
3848
|
add_tests("str",
|
3753
3849
|
"Ruby" => '"x"',
|
3754
3850
|
"RawParseTree" => [:str, "x"],
|
@@ -3936,19 +4032,6 @@ class ParseTreeTestCase < Test::Unit::TestCase
|
|
3936
4032
|
s(:lit, 24),
|
3937
4033
|
s(:lit, 42)))))))
|
3938
4034
|
|
3939
|
-
add_tests("super_n",
|
3940
|
-
"Ruby" => "def x\n super(24, 42)\nend",
|
3941
|
-
"RawParseTree" => [:defn, :x,
|
3942
|
-
[:scope,
|
3943
|
-
[:block,
|
3944
|
-
[:args],
|
3945
|
-
[:super, [:array, [:lit, 24], [:lit, 42]]]]]],
|
3946
|
-
"ParseTree" => s(:defn, :x,
|
3947
|
-
s(:args),
|
3948
|
-
s(:scope,
|
3949
|
-
s(:block,
|
3950
|
-
s(:super, s(:lit, 24), s(:lit, 42))))))
|
3951
|
-
|
3952
4035
|
add_tests("super_block_pass",
|
3953
4036
|
"Ruby" => "super(a, &b)",
|
3954
4037
|
"RawParseTree" => [:block_pass,
|
@@ -3968,6 +4051,19 @@ class ParseTreeTestCase < Test::Unit::TestCase
|
|
3968
4051
|
s(:call, nil, :a, s(:arglist)),
|
3969
4052
|
s(:splat, s(:call, nil, :b, s(:arglist)))))
|
3970
4053
|
|
4054
|
+
add_tests("super_n",
|
4055
|
+
"Ruby" => "def x\n super(24, 42)\nend",
|
4056
|
+
"RawParseTree" => [:defn, :x,
|
4057
|
+
[:scope,
|
4058
|
+
[:block,
|
4059
|
+
[:args],
|
4060
|
+
[:super, [:array, [:lit, 24], [:lit, 42]]]]]],
|
4061
|
+
"ParseTree" => s(:defn, :x,
|
4062
|
+
s(:args),
|
4063
|
+
s(:scope,
|
4064
|
+
s(:block,
|
4065
|
+
s(:super, s(:lit, 24), s(:lit, 42))))))
|
4066
|
+
|
3971
4067
|
add_tests("svalue",
|
3972
4068
|
"Ruby" => "a = *b",
|
3973
4069
|
"RawParseTree" => [:lasgn, :a, [:svalue, [:splat, [:vcall, :b]]]],
|
@@ -4278,25 +4374,25 @@ class ParseTreeTestCase < Test::Unit::TestCase
|
|
4278
4374
|
"RawParseTree" => [:yield, [:lit, 42]],
|
4279
4375
|
"ParseTree" => s(:yield, s(:lit, 42)))
|
4280
4376
|
|
4281
|
-
add_tests("
|
4282
|
-
"Ruby" => "yield(
|
4283
|
-
"RawParseTree" => [:yield, [:
|
4284
|
-
"ParseTree" => s(:yield, s(:
|
4377
|
+
add_tests("yield_array_0",
|
4378
|
+
"Ruby" => "yield([])",
|
4379
|
+
"RawParseTree" => [:yield, [:zarray], true],
|
4380
|
+
"ParseTree" => s(:yield, s(:array)))
|
4285
4381
|
|
4286
|
-
add_tests("
|
4287
|
-
"Ruby" => "yield(
|
4288
|
-
"RawParseTree" => [:yield, [:
|
4289
|
-
"ParseTree" => s(:yield, s(:
|
4382
|
+
add_tests("yield_array_1",
|
4383
|
+
"Ruby" => "yield([42])",
|
4384
|
+
"RawParseTree" => [:yield, [:array, [:lit, 42]], true],
|
4385
|
+
"ParseTree" => s(:yield, s(:array, s(:lit, 42))))
|
4290
4386
|
|
4291
|
-
add_tests("
|
4387
|
+
add_tests("yield_array_n",
|
4292
4388
|
"Ruby" => "yield([42, 24])",
|
4293
4389
|
"RawParseTree" => [:yield, [:array, [:lit, 42], [:lit, 24]], true],
|
4294
4390
|
"ParseTree" => s(:yield, s(:array, s(:lit, 42), s(:lit, 24))))
|
4295
4391
|
|
4296
|
-
add_tests("
|
4297
|
-
"Ruby" => "yield(
|
4298
|
-
"RawParseTree" => [:yield, [:
|
4299
|
-
"ParseTree" => s(:yield, s(:
|
4392
|
+
add_tests("yield_n",
|
4393
|
+
"Ruby" => "yield(42, 24)",
|
4394
|
+
"RawParseTree" => [:yield, [:array, [:lit, 42], [:lit, 24]]],
|
4395
|
+
"ParseTree" => s(:yield, s(:lit, 42), s(:lit, 24)))
|
4300
4396
|
|
4301
4397
|
add_tests("zarray",
|
4302
4398
|
"Ruby" => "a = []",
|
@@ -13,6 +13,25 @@ class R2RTestCase < Test::Unit::TestCase
|
|
13
13
|
assert_equal 'proc { puts("something") }', block.to_ruby
|
14
14
|
end
|
15
15
|
|
16
|
+
# TODO: bus error
|
17
|
+
# def test_proc_to_ruby_args_0
|
18
|
+
# util_setup_inline
|
19
|
+
# block = proc { || puts 42 }
|
20
|
+
# assert_equal 'proc { || puts(42) }', block.to_ruby
|
21
|
+
# end
|
22
|
+
|
23
|
+
def test_proc_to_ruby_args_1
|
24
|
+
util_setup_inline
|
25
|
+
block = proc { |x| puts x }
|
26
|
+
assert_equal 'proc { |x| puts(x) }', block.to_ruby
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_proc_to_ruby_args_n
|
30
|
+
util_setup_inline
|
31
|
+
block = proc { |x| puts x }
|
32
|
+
assert_equal 'proc { |x| puts(x) }', block.to_ruby
|
33
|
+
end
|
34
|
+
|
16
35
|
def test_proc_to_sexp
|
17
36
|
util_setup_inline
|
18
37
|
p = proc { 1 + 1 }
|
@@ -23,6 +42,55 @@ class R2RTestCase < Test::Unit::TestCase
|
|
23
42
|
assert_equal s, p.to_sexp
|
24
43
|
end
|
25
44
|
|
45
|
+
# TODO: bus error
|
46
|
+
# def test_proc_to_sexp_args_0
|
47
|
+
# util_setup_inline
|
48
|
+
# p = proc { || 1 + 1 }
|
49
|
+
# s = s(:iter,
|
50
|
+
# s(:call, nil, :proc, s(:arglist)),
|
51
|
+
# nil,
|
52
|
+
# s(:call, s(:lit, 1), :+, s(:arglist, s(:lit, 1))))
|
53
|
+
# assert_equal s, p.to_sexp
|
54
|
+
# end
|
55
|
+
|
56
|
+
def test_proc_to_sexp_args_1
|
57
|
+
util_setup_inline
|
58
|
+
p = proc {|x| puts x }
|
59
|
+
s = s(:iter,
|
60
|
+
s(:call, nil, :proc, s(:arglist)),
|
61
|
+
s(:lasgn, :x),
|
62
|
+
s(:call, nil, :puts, s(:arglist, s(:lvar, :x))))
|
63
|
+
|
64
|
+
assert_equal s, p.to_sexp
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_proc_to_sexp_args_n
|
68
|
+
util_setup_inline
|
69
|
+
p = proc {|x, y| puts x + y }
|
70
|
+
s = s(:iter,
|
71
|
+
s(:call, nil, :proc, s(:arglist)),
|
72
|
+
s(:masgn, s(:array, s(:lasgn, :x), s(:lasgn, :y))),
|
73
|
+
s(:call, nil, :puts,
|
74
|
+
s(:arglist, s(:call, s(:lvar, :x), :+, s(:arglist, s(:lvar, :y))))))
|
75
|
+
|
76
|
+
assert_equal s, p.to_sexp
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_parse_tree_for_proc # TODO: move?
|
80
|
+
p = proc {|a, b, c|}
|
81
|
+
s = s(:iter,
|
82
|
+
s(:call, nil, :proc, s(:arglist)),
|
83
|
+
s(:masgn, s(:array, s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c))))
|
84
|
+
|
85
|
+
pt = ParseTree.new(false)
|
86
|
+
u = Unifier.new
|
87
|
+
sexp = pt.parse_tree_for_proc p
|
88
|
+
|
89
|
+
sexp = u.process(sexp)
|
90
|
+
|
91
|
+
assert_equal s, sexp
|
92
|
+
end
|
93
|
+
|
26
94
|
def test_unbound_method_to_ruby
|
27
95
|
util_setup_inline
|
28
96
|
r = "proc { ||\n util_setup_inline\n p = proc { (1 + 1) }\n s = s(:iter, s(:call, nil, :proc, s(:arglist)), nil, s(:call, s(:lit, 1), :+, s(:arglist, s(:lit, 1))))\n assert_equal(s, p.to_sexp)\n}"
|
data/test/test_unified_ruby.rb
CHANGED
@@ -7,309 +7,51 @@ require 'test/unit/testcase'
|
|
7
7
|
require 'sexp'
|
8
8
|
require 'sexp_processor'
|
9
9
|
require 'unified_ruby'
|
10
|
-
require 'pt_testcase'
|
11
10
|
|
12
|
-
class TestUnifier <
|
13
|
-
|
14
|
-
|
11
|
+
class TestUnifier < Test::Unit::TestCase
|
12
|
+
def test_pre_fcall
|
13
|
+
u = PreUnifier.new
|
14
|
+
|
15
|
+
input = [:fcall, :block_given?]
|
16
|
+
expect = s(:fcall, :block_given?, s(:arglist))
|
17
|
+
|
18
|
+
assert_equal expect, u.process(input)
|
19
|
+
|
20
|
+
input = [:fcall, :m, [:array, [:lit, 42]]]
|
21
|
+
expect = s(:fcall, :m, s(:arglist, s(:lit, 42)))
|
22
|
+
|
23
|
+
assert_equal expect, u.process(input)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_pre_call
|
27
|
+
u = PreUnifier.new
|
15
28
|
|
16
|
-
|
17
|
-
|
18
|
-
# 1) DONE [vf]call => call
|
19
|
-
# 2) DONE defn scope block args -> defn args scope block
|
20
|
-
# 3) DONE [bd]method/fbody => defn
|
21
|
-
# 4) rescue cleanup
|
22
|
-
# 5) defs x -> defn self.x # ON HOLD
|
23
|
-
# 6) ? :block_arg into args list?
|
29
|
+
input = [:call, [:self], :method]
|
30
|
+
expect = s(:call, s(:self), :method, s(:arglist))
|
24
31
|
|
25
|
-
|
26
|
-
# class TestUnifiedRuby < ParseTreeTestCase
|
27
|
-
# def setup
|
28
|
-
# super
|
29
|
-
# @processor = TestUnifier.new
|
30
|
-
# end
|
31
|
-
# end
|
32
|
+
assert_equal expect, u.process(input)
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
# add_test("and", :skip)
|
36
|
-
# add_test("argscat_inside", :skip)
|
37
|
-
# add_test("argscat_svalue", :skip)
|
38
|
-
# add_test("argspush", :skip)
|
39
|
-
# add_test("array", :skip)
|
40
|
-
# add_test("array_pct_W", :skip)
|
41
|
-
# add_test("attrasgn", :skip)
|
42
|
-
# add_test("attrasgn_index_equals", :skip)
|
43
|
-
# add_test("attrasgn_index_equals_space", :skip)
|
44
|
-
# add_test("attrset", :skip)
|
45
|
-
# add_test("back_ref", :skip)
|
46
|
-
# add_test("begin", :skip)
|
47
|
-
# add_test("begin_def", :skip)
|
48
|
-
# add_test("begin_rescue_ensure", :skip)
|
49
|
-
# add_test("begin_rescue_twice", :skip)
|
50
|
-
# add_test("block_lasgn", :skip)
|
51
|
-
# add_test("block_mystery_block", :skip)
|
52
|
-
# add_test("block_pass_args_and_splat", :skip)
|
53
|
-
# add_test("block_pass_call_0", :skip)
|
54
|
-
# add_test("block_pass_call_1", :skip)
|
55
|
-
# add_test("block_pass_call_n", :skip)
|
56
|
-
# add_test("block_pass_fcall_0", :skip)
|
57
|
-
# add_test("block_pass_fcall_1", :skip)
|
58
|
-
# add_test("block_pass_fcall_n", :skip)
|
59
|
-
# add_test("block_pass_omgwtf", :skip)
|
60
|
-
# add_test("block_pass_splat", :skip)
|
61
|
-
# add_test("block_pass_thingy", :skip)
|
62
|
-
# add_test("block_stmt_after", :skip)
|
63
|
-
# add_test("block_stmt_before", :skip)
|
64
|
-
# add_test("block_stmt_both", :skip)
|
65
|
-
# add_test("bmethod", :skip)
|
66
|
-
# add_test("bmethod_noargs", :skip)
|
67
|
-
# add_test("bmethod_splat", :skip)
|
68
|
-
# add_test("break", :skip)
|
69
|
-
# add_test("break_arg", :skip)
|
70
|
-
# add_test("call", :skip)
|
71
|
-
# add_test("call_arglist", :skip)
|
72
|
-
# add_test("call_arglist_hash", :skip)
|
73
|
-
# add_test("call_arglist_norm_hash", :skip)
|
74
|
-
# add_test("call_arglist_norm_hash_splat", :skip)
|
75
|
-
# add_test("call_command", :skip)
|
76
|
-
# add_test("call_expr", :skip)
|
77
|
-
# add_test("call_index", :skip)
|
78
|
-
# add_test("call_index_no_args", :skip)
|
79
|
-
# add_test("call_index_space", :skip)
|
80
|
-
# add_test("call_unary_neg", :skip)
|
81
|
-
# add_test("case", :skip)
|
82
|
-
# add_test("case_nested", :skip)
|
83
|
-
# add_test("case_nested_inner_no_expr", :skip)
|
84
|
-
# add_test("case_no_expr", :skip)
|
85
|
-
# add_test("case_splat", :skip)
|
86
|
-
# add_test("cdecl", :skip)
|
87
|
-
# add_test("class_plain", :skip)
|
88
|
-
# add_test("class_scoped", :skip)
|
89
|
-
# add_test("class_scoped3", :skip)
|
90
|
-
# add_test("class_super_array", :skip)
|
91
|
-
# add_test("class_super_expr", :skip)
|
92
|
-
# add_test("class_super_object", :skip)
|
93
|
-
# add_test("colon2", :skip)
|
94
|
-
# add_test("colon3", :skip)
|
95
|
-
# add_test("conditional1", :skip)
|
96
|
-
# add_test("conditional2", :skip)
|
97
|
-
# add_test("conditional3", :skip)
|
98
|
-
# add_test("conditional4", :skip)
|
99
|
-
# add_test("conditional5", :skip)
|
100
|
-
# add_test("conditional_post_if", :skip)
|
101
|
-
# add_test("conditional_post_if_not", :skip)
|
102
|
-
# add_test("conditional_post_unless", :skip)
|
103
|
-
# add_test("conditional_post_unless_not", :skip)
|
104
|
-
# add_test("conditional_pre_if", :skip)
|
105
|
-
# add_test("conditional_pre_if_not", :skip)
|
106
|
-
# add_test("conditional_pre_unless", :skip)
|
107
|
-
# add_test("conditional_pre_unless_not", :skip)
|
108
|
-
# add_test("const", :skip)
|
109
|
-
# add_test("constX", :skip)
|
110
|
-
# add_test("constY", :skip)
|
111
|
-
# add_test("constZ", :skip)
|
112
|
-
# add_test("cvar", :skip)
|
113
|
-
# add_test("cvasgn", :skip)
|
114
|
-
# add_test("cvasgn_cls_method", :skip)
|
115
|
-
# add_test("cvdecl", :skip)
|
116
|
-
# add_test("dasgn_0", :skip)
|
117
|
-
# add_test("dasgn_1", :skip)
|
118
|
-
# add_test("dasgn_2", :skip)
|
119
|
-
# add_test("dasgn_curr", :skip)
|
120
|
-
# add_test("dasgn_icky", :skip)
|
121
|
-
# add_test("dasgn_mixed", :skip)
|
122
|
-
# add_test("defined", :skip)
|
123
|
-
# add_test("defn_args_mand_opt_block", :skip)
|
124
|
-
# add_test("defn_args_mand_opt_splat", :skip)
|
125
|
-
# add_test("defn_args_mand_opt_splat_block", :skip)
|
126
|
-
# add_test("defn_args_mand_opt_splat_no_name", :skip)
|
127
|
-
# add_test("defn_args_opt_block", :skip)
|
128
|
-
# add_test("defn_args_opt_splat_no_name", :skip)
|
129
|
-
# add_test("defn_empty", :skip)
|
130
|
-
# add_test("defn_empty_args", :skip)
|
131
|
-
# add_test("defn_lvar_boundary", :skip)
|
132
|
-
# add_test("defn_optargs", :skip)
|
133
|
-
# add_test("defn_or", :skip)
|
134
|
-
# add_test("defn_rescue", :skip)
|
135
|
-
# add_test("defn_something_eh", :skip)
|
136
|
-
# add_test("defn_splat_no_name", :skip)
|
137
|
-
# add_test("defn_zarray", :skip)
|
138
|
-
# add_test("defs", :skip)
|
139
|
-
# add_test("defs_args_mand_opt_splat_block", :skip)
|
140
|
-
# add_test("defs_empty", :skip)
|
141
|
-
# add_test("defs_empty_args", :skip)
|
142
|
-
# add_test("dmethod", :skip)
|
143
|
-
# add_test("dot2", :skip)
|
144
|
-
# add_test("dot3", :skip)
|
145
|
-
# add_test("dregx", :skip)
|
146
|
-
# add_test("dregx_interp", :skip)
|
147
|
-
# add_test("dregx_n", :skip)
|
148
|
-
# add_test("dregx_once", :skip)
|
149
|
-
# add_test("dregx_once_n_interp", :skip)
|
150
|
-
# add_test("dstr", :skip)
|
151
|
-
# add_test("dstr_2", :skip)
|
152
|
-
# add_test("dstr_3", :skip)
|
153
|
-
# add_test("dstr_concat", :skip)
|
154
|
-
# add_test("dstr_heredoc_expand", :skip)
|
155
|
-
# add_test("dstr_heredoc_windoze_sucks", :skip)
|
156
|
-
# add_test("dstr_heredoc_yet_again", :skip)
|
157
|
-
# add_test("dstr_nest", :skip)
|
158
|
-
# add_test("dstr_str_lit_start", :skip)
|
159
|
-
# add_test("dstr_the_revenge", :skip)
|
160
|
-
# add_test("dsym", :skip)
|
161
|
-
# add_test("dxstr", :skip)
|
162
|
-
# add_test("ensure", :skip)
|
163
|
-
# add_test("false", :skip)
|
164
|
-
# add_test("fbody", :skip)
|
165
|
-
# add_test("fcall_arglist", :skip)
|
166
|
-
# add_test("fcall_arglist_hash", :skip)
|
167
|
-
# add_test("fcall_arglist_norm_hash", :skip)
|
168
|
-
# add_test("fcall_arglist_norm_hash_splat", :skip)
|
169
|
-
# add_test("fcall_block", :skip)
|
170
|
-
# add_test("fcall_index_space", :skip)
|
171
|
-
# add_test("fcall_keyword", :skip)
|
172
|
-
# add_test("flip2", :skip)
|
173
|
-
# add_test("flip2_method", :skip)
|
174
|
-
# add_test("flip3", :skip)
|
175
|
-
# add_test("for", :skip)
|
176
|
-
# add_test("for_no_body", :skip)
|
177
|
-
# add_test("gasgn", :skip)
|
178
|
-
# add_test("global", :skip)
|
179
|
-
# add_test("gvar", :skip)
|
180
|
-
# add_test("gvar_underscore", :skip)
|
181
|
-
# add_test("gvar_underscore_blah", :skip)
|
182
|
-
# add_test("hash", :skip)
|
183
|
-
# add_test("hash_rescue", :skip)
|
184
|
-
# add_test("iasgn", :skip)
|
185
|
-
# add_test("if_block_condition", :skip)
|
186
|
-
# add_test("if_lasgn_short", :skip)
|
187
|
-
# add_test("iteration1", :skip)
|
188
|
-
# add_test("iteration2", :skip)
|
189
|
-
# add_test("iteration3", :skip)
|
190
|
-
# add_test("iteration4", :skip)
|
191
|
-
# add_test("iteration5", :skip)
|
192
|
-
# add_test("iteration6", :skip)
|
193
|
-
# add_test("iteration7", :skip)
|
194
|
-
# add_test("iteration8", :skip)
|
195
|
-
# add_test("iteration9", :skip)
|
196
|
-
# add_test("iteration_dasgn_curr_dasgn_madness", :skip)
|
197
|
-
# add_test("iteration_double_var", :skip)
|
198
|
-
# add_test("iteration_masgn", :skip)
|
199
|
-
# add_test("ivar", :skip)
|
200
|
-
# add_test("lasgn_array", :skip)
|
201
|
-
# add_test("lasgn_call", :skip)
|
202
|
-
# add_test("lit_bool_false", :skip)
|
203
|
-
# add_test("lit_bool_true", :skip)
|
204
|
-
# add_test("lit_float", :skip)
|
205
|
-
# add_test("lit_long", :skip)
|
206
|
-
# add_test("lit_long_negative", :skip)
|
207
|
-
# add_test("lit_range2", :skip)
|
208
|
-
# add_test("lit_range3", :skip)
|
209
|
-
# add_test("lit_regexp", :skip)
|
210
|
-
# add_test("lit_regexp_i_wwtt", :skip)
|
211
|
-
# add_test("lit_regexp_n", :skip)
|
212
|
-
# add_test("lit_regexp_once", :skip)
|
213
|
-
# add_test("lit_sym", :skip)
|
214
|
-
# add_test("lit_sym_splat", :skip)
|
215
|
-
# add_test("lvar_def_boundary", :skip)
|
216
|
-
# add_test("masgn", :skip)
|
217
|
-
# add_test("masgn_argscat", :skip)
|
218
|
-
# add_test("masgn_attrasgn", :skip)
|
219
|
-
# add_test("masgn_iasgn", :skip)
|
220
|
-
# add_test("masgn_masgn", :skip)
|
221
|
-
# add_test("masgn_splat", :skip)
|
222
|
-
# add_test("masgn_splat_no_name_to_ary", :skip)
|
223
|
-
# add_test("masgn_splat_no_name_trailing", :skip)
|
224
|
-
# add_test("masgn_splat_to_ary", :skip)
|
225
|
-
# add_test("masgn_splat_to_ary2", :skip)
|
226
|
-
# add_test("match", :skip)
|
227
|
-
# add_test("match2", :skip)
|
228
|
-
# add_test("match3", :skip)
|
229
|
-
# add_test("module", :skip)
|
230
|
-
# add_test("module_scoped", :skip)
|
231
|
-
# add_test("module_scoped3", :skip)
|
232
|
-
# add_test("next", :skip)
|
233
|
-
# add_test("next_arg", :skip)
|
234
|
-
# add_test("not", :skip)
|
235
|
-
# add_test("nth_ref", :skip)
|
236
|
-
# add_test("op_asgn1", :skip)
|
237
|
-
# add_test("op_asgn2", :skip)
|
238
|
-
# add_test("op_asgn2_self", :skip)
|
239
|
-
# add_test("op_asgn_and", :skip)
|
240
|
-
# add_test("op_asgn_and_ivar2", :skip)
|
241
|
-
# add_test("op_asgn_or", :skip)
|
242
|
-
# add_test("op_asgn_or_block", :skip)
|
243
|
-
# add_test("op_asgn_or_ivar", :skip)
|
244
|
-
# add_test("op_asgn_or_ivar2", :skip)
|
245
|
-
# add_test("or", :skip)
|
246
|
-
# add_test("or_big", :skip)
|
247
|
-
# add_test("or_big2", :skip)
|
248
|
-
# add_test("parse_floats_as_args", :skip)
|
249
|
-
# add_test("postexe", :skip)
|
250
|
-
# add_test("proc_args_0", :skip)
|
251
|
-
# add_test("proc_args_1", :skip)
|
252
|
-
# add_test("proc_args_2", :skip)
|
253
|
-
# add_test("proc_args_no", :skip)
|
254
|
-
# add_test("redo", :skip)
|
255
|
-
# add_test("rescue", :skip)
|
256
|
-
# add_test("rescue_block_body", :skip)
|
257
|
-
# add_test("rescue_block_nada", :skip)
|
258
|
-
# add_test("rescue_exceptions", :skip)
|
259
|
-
# add_test("retry", :skip)
|
260
|
-
# add_test("return_0", :skip)
|
261
|
-
# add_test("return_1", :skip)
|
262
|
-
# add_test("return_n", :skip)
|
263
|
-
# add_test("sclass", :skip)
|
264
|
-
# add_test("sclass_trailing_class", :skip)
|
265
|
-
# add_test("splat", :skip)
|
266
|
-
# add_test("str", :skip)
|
267
|
-
# add_test("str_concat_newline", :skip)
|
268
|
-
# add_test("str_concat_space", :skip)
|
269
|
-
# add_test("str_heredoc", :skip)
|
270
|
-
# add_test("str_heredoc_call", :skip)
|
271
|
-
# add_test("str_heredoc_double", :skip)
|
272
|
-
# add_test("str_heredoc_indent", :skip)
|
273
|
-
# add_test("str_interp_file", :skip)
|
274
|
-
# add_test("structure_extra_block_for_dvar_scoping", :skip)
|
275
|
-
# add_test("structure_remove_begin_1", :skip)
|
276
|
-
# add_test("structure_remove_begin_2", :skip)
|
277
|
-
# add_test("structure_unused_literal_wwtt", :skip)
|
278
|
-
# add_test("super", :skip)
|
279
|
-
# add_test("super_block_pass", :skip)
|
280
|
-
# add_test("super_block_splat", :skip)
|
281
|
-
# add_test("super_multi", :skip)
|
282
|
-
# add_test("svalue", :skip)
|
283
|
-
# add_test("to_ary", :skip)
|
284
|
-
# add_test("true", :skip)
|
285
|
-
# add_test("undef", :skip)
|
286
|
-
# add_test("undef_2", :skip)
|
287
|
-
# add_test("undef_3", :skip)
|
288
|
-
# add_test("undef_block_1", :skip)
|
289
|
-
# add_test("undef_block_2", :skip)
|
290
|
-
# add_test("undef_block_3", :skip)
|
291
|
-
# add_test("undef_block_3_post", :skip)
|
292
|
-
# add_test("undef_block_wtf", :skip)
|
293
|
-
# add_test("until_post", :skip)
|
294
|
-
# add_test("until_post_not", :skip)
|
295
|
-
# add_test("until_pre", :skip)
|
296
|
-
# add_test("until_pre_mod", :skip)
|
297
|
-
# add_test("until_pre_not", :skip)
|
298
|
-
# add_test("until_pre_not_mod", :skip)
|
299
|
-
# add_test("valias", :skip)
|
300
|
-
# add_test("vcall", :skip)
|
301
|
-
# add_test("while_post", :skip)
|
302
|
-
# add_test("while_post_not", :skip)
|
303
|
-
# add_test("while_pre", :skip)
|
304
|
-
# add_test("while_pre_mod", :skip)
|
305
|
-
# add_test("while_pre_nil", :skip)
|
306
|
-
# add_test("while_pre_not", :skip)
|
307
|
-
# add_test("while_pre_not_mod", :skip)
|
308
|
-
# add_test("xstr", :skip)
|
309
|
-
# add_test("yield", :skip)
|
310
|
-
# add_test("yield_arg", :skip) # TODO: make it always have an argslist
|
311
|
-
# add_test("yield_args", :skip) # TODO: array -> argslist
|
312
|
-
# add_test("zarray", :skip)
|
313
|
-
# add_test("zsuper", :skip)
|
314
|
-
# end
|
34
|
+
input = [:fcall, :m, [:array, [:lit, 42]]]
|
35
|
+
expect = s(:fcall, :m, s(:arglist, s(:lit, 42)))
|
315
36
|
|
37
|
+
assert_equal expect, u.process(input)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_process_bmethod
|
41
|
+
u = Unifier.new
|
42
|
+
|
43
|
+
raw = [:defn, :myproc3,
|
44
|
+
[:bmethod,
|
45
|
+
[:masgn, [:array,
|
46
|
+
[:dasgn_curr, :a],
|
47
|
+
[:dasgn_curr, :b],
|
48
|
+
[:dasgn_curr, :c]],
|
49
|
+
nil, nil]]]
|
50
|
+
|
51
|
+
s = s(:defn, :myproc3,
|
52
|
+
s(:args, :a, :b, :c),
|
53
|
+
s(:scope, s(:block)))
|
54
|
+
|
55
|
+
assert_equal s, u.process(raw)
|
56
|
+
end
|
57
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ParseTree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Davis
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-11-04 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -102,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
102
|
requirements: []
|
103
103
|
|
104
104
|
rubyforge_project: parsetree
|
105
|
-
rubygems_version: 1.3.
|
105
|
+
rubygems_version: 1.3.1
|
106
106
|
signing_key:
|
107
107
|
specification_version: 2
|
108
108
|
summary: ParseTree is a C extension (using RubyInline) that extracts the parse tree for an entire class or a specific method and returns it as a s-expression (aka sexp) using ruby's arrays, strings, symbols, and integers
|