nodewrap 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +59 -0
- data/LEGAL +6 -0
- data/LGPL +515 -0
- data/LICENSE +6 -0
- data/README +31 -0
- data/TODO +9 -0
- data/example/README +5 -0
- data/example/simple_client.rb +12 -0
- data/example/simple_server.rb +11 -0
- data/example/triangle_client.rb +7 -0
- data/example/triangle_server.rb +24 -0
- data/ext/MANIFEST +11 -0
- data/ext/builtins.h +25 -0
- data/ext/cached/ruby-1.6.3/COPYING +340 -0
- data/ext/cached/ruby-1.6.3/README +3 -0
- data/ext/cached/ruby-1.6.3/classpath.c +3 -0
- data/ext/cached/ruby-1.6.3/classpath.h +8 -0
- data/ext/cached/ruby-1.6.3/evalinfo.h +62 -0
- data/ext/cached/ruby-1.6.3/global_entry.h +15 -0
- data/ext/cached/ruby-1.6.3/insns_info.c +40 -0
- data/ext/cached/ruby-1.6.3/insns_info.h +19 -0
- data/ext/cached/ruby-1.6.3/node_type_descrip.c +150 -0
- data/ext/cached/ruby-1.6.3/nodeinfo.c +3182 -0
- data/ext/cached/ruby-1.6.3/nodeinfo.h +66 -0
- data/ext/cached/ruby-1.6.4/COPYING +340 -0
- data/ext/cached/ruby-1.6.4/README +3 -0
- data/ext/cached/ruby-1.6.4/classpath.c +3 -0
- data/ext/cached/ruby-1.6.4/classpath.h +8 -0
- data/ext/cached/ruby-1.6.4/evalinfo.h +62 -0
- data/ext/cached/ruby-1.6.4/global_entry.h +15 -0
- data/ext/cached/ruby-1.6.4/insns_info.c +40 -0
- data/ext/cached/ruby-1.6.4/insns_info.h +19 -0
- data/ext/cached/ruby-1.6.4/node_type_descrip.c +150 -0
- data/ext/cached/ruby-1.6.4/nodeinfo.c +3182 -0
- data/ext/cached/ruby-1.6.4/nodeinfo.h +66 -0
- data/ext/cached/ruby-1.6.5/COPYING +56 -0
- data/ext/cached/ruby-1.6.5/GPL +340 -0
- data/ext/cached/ruby-1.6.5/LEGAL +325 -0
- data/ext/cached/ruby-1.6.5/LGPL +504 -0
- data/ext/cached/ruby-1.6.5/README +3 -0
- data/ext/cached/ruby-1.6.5/classpath.c +3 -0
- data/ext/cached/ruby-1.6.5/classpath.h +8 -0
- data/ext/cached/ruby-1.6.5/evalinfo.h +63 -0
- data/ext/cached/ruby-1.6.5/global_entry.h +15 -0
- data/ext/cached/ruby-1.6.5/insns_info.c +40 -0
- data/ext/cached/ruby-1.6.5/insns_info.h +19 -0
- data/ext/cached/ruby-1.6.5/node_type_descrip.c +150 -0
- data/ext/cached/ruby-1.6.5/nodeinfo.c +3182 -0
- data/ext/cached/ruby-1.6.5/nodeinfo.h +66 -0
- data/ext/cached/ruby-1.6.7/COPYING +56 -0
- data/ext/cached/ruby-1.6.7/GPL +340 -0
- data/ext/cached/ruby-1.6.7/LEGAL +308 -0
- data/ext/cached/ruby-1.6.7/LGPL +504 -0
- data/ext/cached/ruby-1.6.7/README +3 -0
- data/ext/cached/ruby-1.6.7/classpath.c +3 -0
- data/ext/cached/ruby-1.6.7/classpath.h +8 -0
- data/ext/cached/ruby-1.6.7/evalinfo.h +63 -0
- data/ext/cached/ruby-1.6.7/global_entry.h +15 -0
- data/ext/cached/ruby-1.6.7/insns_info.c +40 -0
- data/ext/cached/ruby-1.6.7/insns_info.h +19 -0
- data/ext/cached/ruby-1.6.7/node_type_descrip.c +150 -0
- data/ext/cached/ruby-1.6.7/nodeinfo.c +3182 -0
- data/ext/cached/ruby-1.6.7/nodeinfo.h +66 -0
- data/ext/cached/ruby-1.6.8/COPYING +56 -0
- data/ext/cached/ruby-1.6.8/GPL +340 -0
- data/ext/cached/ruby-1.6.8/LEGAL +308 -0
- data/ext/cached/ruby-1.6.8/LGPL +504 -0
- data/ext/cached/ruby-1.6.8/README +3 -0
- data/ext/cached/ruby-1.6.8/classpath.c +3 -0
- data/ext/cached/ruby-1.6.8/classpath.h +8 -0
- data/ext/cached/ruby-1.6.8/evalinfo.h +63 -0
- data/ext/cached/ruby-1.6.8/global_entry.h +15 -0
- data/ext/cached/ruby-1.6.8/insns_info.c +40 -0
- data/ext/cached/ruby-1.6.8/insns_info.h +19 -0
- data/ext/cached/ruby-1.6.8/node_type_descrip.c +150 -0
- data/ext/cached/ruby-1.6.8/nodeinfo.c +3182 -0
- data/ext/cached/ruby-1.6.8/nodeinfo.h +66 -0
- data/ext/cached/ruby-1.8.0/COPYING +56 -0
- data/ext/cached/ruby-1.8.0/GPL +340 -0
- data/ext/cached/ruby-1.8.0/LEGAL +371 -0
- data/ext/cached/ruby-1.8.0/LGPL +504 -0
- data/ext/cached/ruby-1.8.0/README +3 -0
- data/ext/cached/ruby-1.8.0/classpath.c +27 -0
- data/ext/cached/ruby-1.8.0/classpath.h +14 -0
- data/ext/cached/ruby-1.8.0/evalinfo.h +65 -0
- data/ext/cached/ruby-1.8.0/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.0/insns_info.c +40 -0
- data/ext/cached/ruby-1.8.0/insns_info.h +19 -0
- data/ext/cached/ruby-1.8.0/node_type_descrip.c +150 -0
- data/ext/cached/ruby-1.8.0/nodeinfo.c +3199 -0
- data/ext/cached/ruby-1.8.0/nodeinfo.h +66 -0
- data/ext/cached/ruby-1.8.1/COPYING +56 -0
- data/ext/cached/ruby-1.8.1/GPL +340 -0
- data/ext/cached/ruby-1.8.1/LEGAL +371 -0
- data/ext/cached/ruby-1.8.1/LGPL +504 -0
- data/ext/cached/ruby-1.8.1/README +3 -0
- data/ext/cached/ruby-1.8.1/classpath.c +27 -0
- data/ext/cached/ruby-1.8.1/classpath.h +14 -0
- data/ext/cached/ruby-1.8.1/evalinfo.h +59 -0
- data/ext/cached/ruby-1.8.1/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.1/insns_info.c +40 -0
- data/ext/cached/ruby-1.8.1/insns_info.h +19 -0
- data/ext/cached/ruby-1.8.1/node_type_descrip.c +150 -0
- data/ext/cached/ruby-1.8.1/nodeinfo.c +3199 -0
- data/ext/cached/ruby-1.8.1/nodeinfo.h +66 -0
- data/ext/cached/ruby-1.8.2/COPYING +56 -0
- data/ext/cached/ruby-1.8.2/GPL +340 -0
- data/ext/cached/ruby-1.8.2/LEGAL +371 -0
- data/ext/cached/ruby-1.8.2/LGPL +504 -0
- data/ext/cached/ruby-1.8.2/README +3 -0
- data/ext/cached/ruby-1.8.2/classpath.c +45 -0
- data/ext/cached/ruby-1.8.2/classpath.h +17 -0
- data/ext/cached/ruby-1.8.2/evalinfo.h +60 -0
- data/ext/cached/ruby-1.8.2/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.2/insns_info.c +40 -0
- data/ext/cached/ruby-1.8.2/insns_info.h +19 -0
- data/ext/cached/ruby-1.8.2/node_type_descrip.c +150 -0
- data/ext/cached/ruby-1.8.2/nodeinfo.c +3199 -0
- data/ext/cached/ruby-1.8.2/nodeinfo.h +66 -0
- data/ext/cached/ruby-1.8.3/COPYING +56 -0
- data/ext/cached/ruby-1.8.3/GPL +340 -0
- data/ext/cached/ruby-1.8.3/LEGAL +370 -0
- data/ext/cached/ruby-1.8.3/LGPL +504 -0
- data/ext/cached/ruby-1.8.3/README +3 -0
- data/ext/cached/ruby-1.8.3/classpath.c +45 -0
- data/ext/cached/ruby-1.8.3/classpath.h +17 -0
- data/ext/cached/ruby-1.8.3/evalinfo.h +61 -0
- data/ext/cached/ruby-1.8.3/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.3/insns_info.c +40 -0
- data/ext/cached/ruby-1.8.3/insns_info.h +19 -0
- data/ext/cached/ruby-1.8.3/node_type_descrip.c +150 -0
- data/ext/cached/ruby-1.8.3/nodeinfo.c +3199 -0
- data/ext/cached/ruby-1.8.3/nodeinfo.h +66 -0
- data/ext/cached/ruby-1.8.4/COPYING +56 -0
- data/ext/cached/ruby-1.8.4/GPL +340 -0
- data/ext/cached/ruby-1.8.4/LEGAL +370 -0
- data/ext/cached/ruby-1.8.4/LGPL +504 -0
- data/ext/cached/ruby-1.8.4/README +3 -0
- data/ext/cached/ruby-1.8.4/classpath.c +45 -0
- data/ext/cached/ruby-1.8.4/classpath.h +17 -0
- data/ext/cached/ruby-1.8.4/evalinfo.h +61 -0
- data/ext/cached/ruby-1.8.4/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.4/insns_info.c +40 -0
- data/ext/cached/ruby-1.8.4/insns_info.h +19 -0
- data/ext/cached/ruby-1.8.4/node_type_descrip.c +150 -0
- data/ext/cached/ruby-1.8.4/nodeinfo.c +3199 -0
- data/ext/cached/ruby-1.8.4/nodeinfo.h +66 -0
- data/ext/cached/ruby-1.8.5/COPYING +56 -0
- data/ext/cached/ruby-1.8.5/GPL +340 -0
- data/ext/cached/ruby-1.8.5/LEGAL +370 -0
- data/ext/cached/ruby-1.8.5/LGPL +504 -0
- data/ext/cached/ruby-1.8.5/README +3 -0
- data/ext/cached/ruby-1.8.5/classpath.c +45 -0
- data/ext/cached/ruby-1.8.5/classpath.h +17 -0
- data/ext/cached/ruby-1.8.5/evalinfo.h +61 -0
- data/ext/cached/ruby-1.8.5/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.5/insns_info.c +40 -0
- data/ext/cached/ruby-1.8.5/insns_info.h +19 -0
- data/ext/cached/ruby-1.8.5/node_type_descrip.c +150 -0
- data/ext/cached/ruby-1.8.5/nodeinfo.c +3187 -0
- data/ext/cached/ruby-1.8.5/nodeinfo.h +64 -0
- data/ext/cached/ruby-1.8.6/COPYING +56 -0
- data/ext/cached/ruby-1.8.6/GPL +340 -0
- data/ext/cached/ruby-1.8.6/LEGAL +370 -0
- data/ext/cached/ruby-1.8.6/LGPL +504 -0
- data/ext/cached/ruby-1.8.6/README +3 -0
- data/ext/cached/ruby-1.8.6/classpath.c +45 -0
- data/ext/cached/ruby-1.8.6/classpath.h +17 -0
- data/ext/cached/ruby-1.8.6/evalinfo.h +61 -0
- data/ext/cached/ruby-1.8.6/global_entry.h +10 -0
- data/ext/cached/ruby-1.8.6/insns_info.c +40 -0
- data/ext/cached/ruby-1.8.6/insns_info.h +19 -0
- data/ext/cached/ruby-1.8.6/node_type_descrip.c +150 -0
- data/ext/cached/ruby-1.8.6/nodeinfo.c +3187 -0
- data/ext/cached/ruby-1.8.6/nodeinfo.h +64 -0
- data/ext/classpath.c +42 -0
- data/ext/classpath.c.rpp +28 -0
- data/ext/classpath.h +17 -0
- data/ext/classpath.h.rpp +35 -0
- data/ext/evalinfo.h +21 -0
- data/ext/evalinfo.h.rpp +49 -0
- data/ext/extconf.rb +68 -0
- data/ext/generate.rb +201 -0
- data/ext/generate_cached.rb +49 -0
- data/ext/global_entry.h +10 -0
- data/ext/global_entry.h.rpp +25 -0
- data/ext/insns_info.c +6079 -0
- data/ext/insns_info.c.rpp +210 -0
- data/ext/insns_info.h +819 -0
- data/ext/insns_info.h.rpp +50 -0
- data/ext/node_type_descrip.c +148 -0
- data/ext/node_type_descrip.c.rpp +72 -0
- data/ext/node_type_descrip.h +17 -0
- data/ext/node_type_descrip.rb +169 -0
- data/ext/nodeinfo.c +3164 -0
- data/ext/nodeinfo.c.rpp +519 -0
- data/ext/nodeinfo.h +67 -0
- data/ext/nodeinfo.h.rpp +27 -0
- data/ext/nodewrap.c +2576 -0
- data/ext/nodewrap.h +20 -0
- data/ext/read_node_h.rb +19 -0
- data/ext/ruby_source_dir.rb +15 -0
- data/ext/ruby_version.h +12 -0
- data/ext/ruby_version_code.rb +16 -0
- data/ext/rubypp.rb +97 -0
- data/ext/test.rb +15 -0
- data/generate_rdoc.rb +33 -0
- data/install.rb +1022 -0
- data/lib/as_code.rb +347 -0
- data/lib/as_expression.rb +657 -0
- data/lib/bytedecoder.rb +848 -0
- data/lib/classtree.rb +54 -0
- data/lib/methodsig.rb +266 -0
- data/lib/node_to_a.rb +34 -0
- data/lib/nodepp.rb +71 -0
- data/lib/nwdebug.rb +18 -0
- data/lib/nwdump.rb +53 -0
- data/lib/nwobfusc.rb +57 -0
- data/lib/procsig.rb +182 -0
- data/lib/test.rb +8 -0
- data/metaconfig +10 -0
- data/post-config.rb +53 -0
- data/post-setup.rb +9 -0
- data/pre-config.rb +1 -0
- data/run_tests.rb +48 -0
- data/test/expression_samples.rb +158 -0
- data/test/node_samples.rb +122 -0
- data/test/test.rb +39 -0
- data/test/test2.rb +7 -0
- data/test/test3.rb +5 -0
- data/test/test4.rb +5 -0
- data/test/test_as_code.rb +249 -0
- data/test/test_as_expression.rb +222 -0
- data/test/test_methodsig.rb +189 -0
- data/test/test_nodewrap.rb +369 -0
- metadata +286 -0
data/lib/classtree.rb
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'nodewrap'
|
|
2
|
+
|
|
3
|
+
class Object
|
|
4
|
+
def classtree(s = '', prefix = '', obj=self, graphed={})
|
|
5
|
+
# if Module == obj.class.class then
|
|
6
|
+
# s << "included module "
|
|
7
|
+
# elsif obj.singleton? then
|
|
8
|
+
# s << "singleton class "
|
|
9
|
+
# elsif Class === obj then
|
|
10
|
+
# s << "class "
|
|
11
|
+
# end
|
|
12
|
+
s << "#{obj}"
|
|
13
|
+
if graphed[obj] then
|
|
14
|
+
s << " (*)\n"
|
|
15
|
+
return s
|
|
16
|
+
end
|
|
17
|
+
s << "\n"
|
|
18
|
+
graphed[obj] = true
|
|
19
|
+
return if Kernel == obj
|
|
20
|
+
subtree = (Module === obj) && (obj.real_superclass)
|
|
21
|
+
s << "#{prefix}#{subtree ? '|-' : '+-'}class = "
|
|
22
|
+
classtree(s, prefix + (subtree ? '| ' : ' '), obj.real_class, graphed)
|
|
23
|
+
if subtree then
|
|
24
|
+
s << "#{prefix}+-super = "
|
|
25
|
+
classtree(s, prefix + ' ', obj.real_superclass, graphed)
|
|
26
|
+
end
|
|
27
|
+
return s
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
if __FILE__ == $0 then
|
|
32
|
+
module M
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class Foo
|
|
36
|
+
class << self; end
|
|
37
|
+
include M
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
class Bar < Foo
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class Baz
|
|
44
|
+
class << self; @foo = 1; end
|
|
45
|
+
def self.foo; end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
b = Bar.new
|
|
49
|
+
b.classtree($stderr)
|
|
50
|
+
|
|
51
|
+
b = Baz.new
|
|
52
|
+
b.classtree($stderr)
|
|
53
|
+
end
|
|
54
|
+
|
data/lib/methodsig.rb
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
require 'nodewrap'
|
|
2
|
+
require 'as_expression'
|
|
3
|
+
|
|
4
|
+
module MethodSig
|
|
5
|
+
# Return the names of the arguments this method takes, in the order in
|
|
6
|
+
# which they appear in the argument list.
|
|
7
|
+
def argument_names
|
|
8
|
+
if self.body.respond_to?(:tbl) then
|
|
9
|
+
# pre-YARV
|
|
10
|
+
return self.body.tbl || []
|
|
11
|
+
else
|
|
12
|
+
# YARV
|
|
13
|
+
iseq = self.body.body
|
|
14
|
+
local_vars = iseq.local_table
|
|
15
|
+
has_rest_arg = iseq.arg_rest != -1
|
|
16
|
+
has_block_arg = iseq.arg_block != -1
|
|
17
|
+
num_args = \
|
|
18
|
+
iseq.argc + \
|
|
19
|
+
iseq.arg_opt_table.size + \
|
|
20
|
+
(has_rest_arg ? 1 : 0) + \
|
|
21
|
+
(has_block_arg ? 1 : 0)
|
|
22
|
+
return local_vars[0...num_args]
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def args_node
|
|
27
|
+
if self.body.respond_to?(:next)
|
|
28
|
+
# pre-YARV
|
|
29
|
+
if self.body.next.class == Node::ARGS then
|
|
30
|
+
return self.body.next
|
|
31
|
+
elsif self.body.next.head.class == Node::ARGS then
|
|
32
|
+
return self.body.next.head
|
|
33
|
+
else
|
|
34
|
+
raise "Could not find method arguments"
|
|
35
|
+
end
|
|
36
|
+
else
|
|
37
|
+
# YARV
|
|
38
|
+
return nil
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
private :args_node
|
|
42
|
+
|
|
43
|
+
# If this method has a "rest" argument, that is, it has an argument
|
|
44
|
+
# that is preceded by an asterisk (*) in the argument list, then
|
|
45
|
+
# return its index, otherwise return nil.
|
|
46
|
+
def rest_arg
|
|
47
|
+
args_node = args_node()
|
|
48
|
+
if args_node then
|
|
49
|
+
# pre-YARV
|
|
50
|
+
rest = args_node.rest()
|
|
51
|
+
if rest.class == Node::LASGN then
|
|
52
|
+
# subtract 2 to account for implicit vars
|
|
53
|
+
return rest.cnt - 2
|
|
54
|
+
elsif not rest
|
|
55
|
+
return nil
|
|
56
|
+
else
|
|
57
|
+
return rest > 0 ? rest - 2 : nil
|
|
58
|
+
end
|
|
59
|
+
else
|
|
60
|
+
# YARV
|
|
61
|
+
rest = self.body.body.arg_rest
|
|
62
|
+
return rest >= 0 ? rest - 1: nil
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# If this method has a "block" argument, that is, it has an argument
|
|
67
|
+
# that is preceded by an ampersand (&) in the argument list, then
|
|
68
|
+
# return its index, otherwise return nil.
|
|
69
|
+
def block_arg
|
|
70
|
+
if self.body.respond_to?(:next) then
|
|
71
|
+
# pre-YARV
|
|
72
|
+
block = self.body.next
|
|
73
|
+
if block.class == Node::BLOCK and
|
|
74
|
+
block.next.head.class == Node::BLOCK_ARG then
|
|
75
|
+
# subtract 2 to account for implicit vars
|
|
76
|
+
return block.next.head.cnt - 2
|
|
77
|
+
else
|
|
78
|
+
return nil
|
|
79
|
+
end
|
|
80
|
+
else
|
|
81
|
+
# YARV
|
|
82
|
+
arg_block = self.body.body.arg_block
|
|
83
|
+
return arg_block >= 0 ? arg_block - 1 : nil
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def set_optional_arg_info(info, args_node, names)
|
|
88
|
+
if args_node then
|
|
89
|
+
# pre-YARV
|
|
90
|
+
opt = args_node.opt
|
|
91
|
+
while opt do
|
|
92
|
+
head = opt.head
|
|
93
|
+
if head.class == Node::LASGN then
|
|
94
|
+
info[head.vid] = "#{head.vid}=#{head.value.as_expression}"
|
|
95
|
+
else
|
|
96
|
+
raise "Unexpected node type: #{opt.class}"
|
|
97
|
+
end
|
|
98
|
+
opt = opt.next
|
|
99
|
+
end
|
|
100
|
+
else
|
|
101
|
+
# YARV
|
|
102
|
+
iseq = self.body.body
|
|
103
|
+
opt_pc = iseq.opt_pc
|
|
104
|
+
env = Nodewrap::ByteDecoder::Environment.new(iseq.local_table())
|
|
105
|
+
iseq.bytedecode(env, 0, opt_pc)
|
|
106
|
+
expressions = env.expressions + env.stack
|
|
107
|
+
expressions.sort!
|
|
108
|
+
opt_table = self.body.body.arg_opt_table
|
|
109
|
+
opt_table.pop
|
|
110
|
+
first_opt_idx =
|
|
111
|
+
names.size -
|
|
112
|
+
opt_table.size -
|
|
113
|
+
(self.rest_arg ? 1 : 0) -
|
|
114
|
+
(self.block_arg ? 1 : 0)
|
|
115
|
+
opt_table.each_with_index do |pc, idx|
|
|
116
|
+
name = names[first_opt_idx + idx]
|
|
117
|
+
expr = expressions.find { |e| e.pc >= pc }
|
|
118
|
+
info[name] = "#{name}=#{expr.rhs}"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
private :set_optional_arg_info
|
|
123
|
+
|
|
124
|
+
# Return a hash mapping each argument name to a description of that
|
|
125
|
+
# argument.
|
|
126
|
+
def argument_info
|
|
127
|
+
names = self.argument_names()
|
|
128
|
+
block_arg = self.block_arg()
|
|
129
|
+
|
|
130
|
+
info = {}
|
|
131
|
+
names.each do |name|
|
|
132
|
+
info[name] = name.to_s
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Optional args
|
|
136
|
+
args_node = args_node()
|
|
137
|
+
set_optional_arg_info(info, args_node, names)
|
|
138
|
+
|
|
139
|
+
# Rest arg
|
|
140
|
+
if self.rest_arg then
|
|
141
|
+
rest_name = names[rest_arg]
|
|
142
|
+
info[rest_name] = "*#{rest_name}"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Block arg
|
|
146
|
+
if block_arg then
|
|
147
|
+
block_name = names[block_arg]
|
|
148
|
+
info[block_name] = "&#{block_name}"
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
return info
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# An abstraction for a method signature.
|
|
155
|
+
class Signature
|
|
156
|
+
attr_reader :origin_class, :name, :arg_names, :arg_info
|
|
157
|
+
|
|
158
|
+
def initialize(origin_class, name, arg_names, arg_info)
|
|
159
|
+
@origin_class = origin_class
|
|
160
|
+
@name = name
|
|
161
|
+
@arg_names = arg_names
|
|
162
|
+
@arg_info = arg_info
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def to_s
|
|
166
|
+
params = @arg_names.map{ |n| arg_info[n] }
|
|
167
|
+
return "#{@origin_class}\##{@name}(#{param_list})"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def param_list
|
|
171
|
+
params = @arg_names.map{ |n| arg_info[n] }
|
|
172
|
+
return params.join(', ')
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# An abstraction for a method origin.
|
|
177
|
+
class Origin
|
|
178
|
+
attr_reader :file, :line
|
|
179
|
+
|
|
180
|
+
def initialize(file, line)
|
|
181
|
+
@file = file
|
|
182
|
+
@line = line
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def to_s
|
|
186
|
+
return "#{file}:#{line}"
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Return a Method::Origin representing where the method was defined.
|
|
191
|
+
def origin
|
|
192
|
+
block = body().next
|
|
193
|
+
return Origin.new(block.nd_file, block.nd_line)
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
class Method
|
|
198
|
+
include MethodSig
|
|
199
|
+
|
|
200
|
+
# Return a String representing the method's signature.
|
|
201
|
+
def signature
|
|
202
|
+
return Signature.new(
|
|
203
|
+
origin_class() || attached_class(),
|
|
204
|
+
method_oid().to_s,
|
|
205
|
+
argument_names(),
|
|
206
|
+
argument_info)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
class UnboundMethod
|
|
211
|
+
include MethodSig
|
|
212
|
+
|
|
213
|
+
# Return a String representing the method's signature.
|
|
214
|
+
def signature
|
|
215
|
+
return Signature.new(
|
|
216
|
+
nil,
|
|
217
|
+
method_oid().to_s,
|
|
218
|
+
argument_names(),
|
|
219
|
+
argument_info)
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
if __FILE__ == $0 then
|
|
224
|
+
require 'nodewrap'
|
|
225
|
+
|
|
226
|
+
def foo(); end
|
|
227
|
+
puts method(:foo).signature
|
|
228
|
+
|
|
229
|
+
def foo(foo); end
|
|
230
|
+
puts method(:foo).signature
|
|
231
|
+
|
|
232
|
+
def foo(foo, bar); end
|
|
233
|
+
puts method(:foo).signature
|
|
234
|
+
|
|
235
|
+
def foo(foo=42, bar=10); end
|
|
236
|
+
puts method(:foo).signature
|
|
237
|
+
|
|
238
|
+
def foo(*args); end
|
|
239
|
+
puts method(:foo).signature
|
|
240
|
+
|
|
241
|
+
def foo(foo, bar=42, *args, &block); end
|
|
242
|
+
puts method(:foo).signature
|
|
243
|
+
puts method(:foo).origin
|
|
244
|
+
|
|
245
|
+
def foo(foo, bar=obj.foo(1, 2, foo(10)), *args, &block); end
|
|
246
|
+
puts method(:foo).signature
|
|
247
|
+
|
|
248
|
+
def foo(foo, bar=obj.foo(1 + 1), *args, &block); end
|
|
249
|
+
puts method(:foo).signature
|
|
250
|
+
|
|
251
|
+
def foo(foo, bar=true ? false : 0, *args, &block); end
|
|
252
|
+
puts method(:foo).signature
|
|
253
|
+
|
|
254
|
+
def foo(foo, bar=true, *args, &block); end
|
|
255
|
+
puts method(:foo).signature
|
|
256
|
+
|
|
257
|
+
def foo(foo, bar=nil, *args, &block); end
|
|
258
|
+
puts method(:foo).signature
|
|
259
|
+
|
|
260
|
+
def foo(foo, bar={1=>2}, *args, &block); end
|
|
261
|
+
puts method(:foo).signature
|
|
262
|
+
|
|
263
|
+
def foo(foo, bar=[1,2], *args, &block); end
|
|
264
|
+
puts method(:foo).signature
|
|
265
|
+
end
|
|
266
|
+
|
data/lib/node_to_a.rb
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
class Node
|
|
2
|
+
|
|
3
|
+
class ARRAY < Node
|
|
4
|
+
def to_a
|
|
5
|
+
a = []
|
|
6
|
+
e = self
|
|
7
|
+
while e do
|
|
8
|
+
a << e.head
|
|
9
|
+
e = e.next
|
|
10
|
+
end
|
|
11
|
+
a
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
class ZARRAY < Node
|
|
16
|
+
def to_a
|
|
17
|
+
[]
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class BLOCK < Node
|
|
22
|
+
def to_a
|
|
23
|
+
a = []
|
|
24
|
+
e = self
|
|
25
|
+
while e do
|
|
26
|
+
a << e.head
|
|
27
|
+
e = e.next
|
|
28
|
+
end
|
|
29
|
+
a
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
|
data/lib/nodepp.rb
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Require this file to get a node pretty-printer.
|
|
2
|
+
#
|
|
3
|
+
|
|
4
|
+
require 'nodewrap'
|
|
5
|
+
require 'pp'
|
|
6
|
+
|
|
7
|
+
module Noex
|
|
8
|
+
# Return a string representing the given integer as a noex value.
|
|
9
|
+
#
|
|
10
|
+
def stringify(noex)
|
|
11
|
+
Noex.constants.each do |constant|
|
|
12
|
+
return constant.to_s if const_get(constant) == noex
|
|
13
|
+
end
|
|
14
|
+
return noex.to_s
|
|
15
|
+
end
|
|
16
|
+
module_function :stringify
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class Node
|
|
20
|
+
# Return a string containing an ascii-art tree of the node's
|
|
21
|
+
# structure.
|
|
22
|
+
#
|
|
23
|
+
def tree(s = '', prefix = '')
|
|
24
|
+
s << "NODE_#{self.nd_type.to_s} at #{self.nd_file}:#{self.nd_line}\n"
|
|
25
|
+
self.members.each_with_index do |member, idx|
|
|
26
|
+
last = (idx == self.members.size-1)
|
|
27
|
+
s << "#{prefix}#{(last ? '+-' : '|-')}#{member} = "
|
|
28
|
+
value = self[member]
|
|
29
|
+
if Node === value then
|
|
30
|
+
value.tree(s, prefix + (last ? ' ' : '| '))
|
|
31
|
+
elsif Object.const_defined?(:VM) and
|
|
32
|
+
VM.const_defined?(:InstructionSequence) and
|
|
33
|
+
VM::InstructionSequence === value then
|
|
34
|
+
s << "<ISeq:#{value.self.name}@#{value.self.filename}>\n"
|
|
35
|
+
d = value.disasm
|
|
36
|
+
lines = d.split("\n")
|
|
37
|
+
lines.each_with_index do |line, idx|
|
|
38
|
+
if line =~ /^== disasm: (.*?)=/ then line = $1; end
|
|
39
|
+
if line =~ /(.*)\s+\(\s*\d+\)/ then line = $1; end
|
|
40
|
+
next if line =~ /^\|-----/
|
|
41
|
+
last_line = (idx == lines.size-1)
|
|
42
|
+
s << "#{prefix}#{last ? ' ' : '| '}#{(last_line ? '+-' : '|-')}#{line}\n"
|
|
43
|
+
end
|
|
44
|
+
# p value.local_table
|
|
45
|
+
elsif member == 'noex' then
|
|
46
|
+
s << Noex.stringify(value) + "\n"
|
|
47
|
+
else
|
|
48
|
+
s << value.inspect + "\n"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
return s
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Pretty-print node using Node#tree onto s, which can be a String or
|
|
55
|
+
# IO.
|
|
56
|
+
#
|
|
57
|
+
def pretty_print(pp)
|
|
58
|
+
pp.text(tree())
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
if __FILE__ == $0 then
|
|
63
|
+
def foo # :nodoc:
|
|
64
|
+
1 + 1
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
m = method(:foo)
|
|
68
|
+
n = m.body
|
|
69
|
+
puts n.pretty_print
|
|
70
|
+
end
|
|
71
|
+
|
data/lib/nwdebug.rb
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'nodewrap'
|
|
2
|
+
require 'as_expression'
|
|
3
|
+
|
|
4
|
+
require 'pp'
|
|
5
|
+
require 'nodepp'
|
|
6
|
+
|
|
7
|
+
module Nodewrap
|
|
8
|
+
def printdebug(&block)
|
|
9
|
+
puts "#{caller[0]}: #{block.body.as_expression} => #{block.call}"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
if __FILE__ == $0 then
|
|
14
|
+
include Nodewrap
|
|
15
|
+
a = 41
|
|
16
|
+
printdebug { a + 1 }
|
|
17
|
+
end
|
|
18
|
+
|
data/lib/nwdump.rb
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# This is a script similar to the Pragmatic Programmers' NodeDump.so.
|
|
2
|
+
# You can use it similarly, e.g.:
|
|
3
|
+
#
|
|
4
|
+
# $ cat test.rb
|
|
5
|
+
# def foo
|
|
6
|
+
# 1+1
|
|
7
|
+
# end
|
|
8
|
+
#
|
|
9
|
+
# $ ruby -rnwdump test.rb
|
|
10
|
+
# NODE_NEWLINE at test.rb:1
|
|
11
|
+
# |-nth = 1
|
|
12
|
+
# +-next = NODE_DEFN at test.rb:1
|
|
13
|
+
# |-defn = NODE_SCOPE at test.rb:3
|
|
14
|
+
# | |-rval = false
|
|
15
|
+
# | |-tbl = nil
|
|
16
|
+
# | +-next = NODE_BLOCK at test.rb:1
|
|
17
|
+
# | |-next = NODE_BLOCK at test.rb:3
|
|
18
|
+
# | | |-next = false
|
|
19
|
+
# | | +-head = NODE_NEWLINE at test.rb:2
|
|
20
|
+
# | | |-nth = 2
|
|
21
|
+
# | | +-next = NODE_CALL at test.rb:2
|
|
22
|
+
# | | |-recv = NODE_LIT at test.rb:2
|
|
23
|
+
# | | | +-lit = 1
|
|
24
|
+
# | | |-args = NODE_ARRAY at test.rb:2
|
|
25
|
+
# | | | |-alen = 1
|
|
26
|
+
# | | | |-head = NODE_LIT at test.rb:2
|
|
27
|
+
# | | | | +-lit = 1
|
|
28
|
+
# | | | +-next = false
|
|
29
|
+
# | | +-mid = :+
|
|
30
|
+
# | +-head = NODE_ARGS at test.rb:1
|
|
31
|
+
# | |-cnt = 0
|
|
32
|
+
# | |-rest = -1
|
|
33
|
+
# | +-opt = false
|
|
34
|
+
# |-mid = :foo
|
|
35
|
+
# +-noex = PRIVATE
|
|
36
|
+
|
|
37
|
+
require 'nodepp'
|
|
38
|
+
|
|
39
|
+
set_trace_func proc {
|
|
40
|
+
begin
|
|
41
|
+
n = $ruby_eval_tree
|
|
42
|
+
if defined?($ruby_eval_tree_begin) and $ruby_eval_tree_begin then
|
|
43
|
+
pp $ruby_eval_tree_begin, $stderr
|
|
44
|
+
end
|
|
45
|
+
if n then
|
|
46
|
+
PP.pp n, $stderr
|
|
47
|
+
exit!
|
|
48
|
+
end
|
|
49
|
+
rescue Exception
|
|
50
|
+
p $!, $!.backtrace
|
|
51
|
+
end
|
|
52
|
+
}
|
|
53
|
+
|